Support

May 20, 2026 ยท View on GitHub

Last reviewed: 2026-05-17

Lemon support is designed around reproducible local diagnostics. Before opening an issue, run doctor and include the install path, version or commit, operating system, interface, and redacted support bundle when relevant.

Supported for 1.0

Initial stable 1.0 support targets:

  • source installs on machines with supported Elixir and Erlang/OTP versions
  • Linux x86_64 release tarballs published by the Lemon release workflow
  • provider setup through documented configuration and secrets commands
  • runtime startup through ./bin/lemon, ./bin/lemon-dev, and release scripts
  • Web health and operations pages
  • first-party text web tools such as web search/fetch when used from supported agent runs
  • doctor diagnostics and redacted support bundles
  • preview checkpoint diagnostics through checkpoint.status, Web /ops, Telegram/Discord /checkpoint status/events/diff/restore controls with redacted lifecycle event counts/history and pushed active-run event notices, checkpoint lifecycle events, redacted support-bundle metadata, Web /ops rollback command guidance and direct diff/restore controls, and operator-only checkpoint.diff / checkpoint.restore control-plane methods plus TUI /checkpoint diff and /checkpoint restore; shared checkpoint storage and filesystem rollback are owned by LemonCore.Checkpoint. JSON-RPC checkpoint.status also exposes redacted checkpoint lifecycle event counts and recent event summaries filtered by run, session, and agent without raw checkpoint paths, file contents, raw event payloads, or raw session ids. Channel checkpoint output is redacted and restore requires an explicit confirmation token or slash-command boolean.
  • preview LSP diagnostics through the model-facing lsp_diagnostics tool, opt-in write/edit/patch baseline/delta checks, redacted lsp.diagnostics.status, Web /ops checker visibility, and lsp_diagnostics.json in support bundles. JSON-RPC lsp.diagnostics.status also includes recent redacted LSP proof artifacts and latest LSP proof checks, matching the Web /ops promotion view without raw proof paths, filenames, file contents, diagnostics output, or server I/O. LemonCore.LspServerManager is a supervised BEAM status, stdio session, initialize, JSON-RPC framing, and diagnostic-notification manager for the known language-server registry. lsp.server.start, lsp.server.initialize, lsp.document.open, lsp.document.change, lsp.document.close, lsp.server.request, and lsp.server.stop expose operator session lifecycle, document-sync notifications, and request controls through the control plane. The preview reports checker/server capability, redacted session health, redacted document URI hashes/counters, and redacted diagnostic batch counts only; support bundles omit file paths, executable paths, raw session ids, file contents, workspace roots, diagnostic output, and server I/O. mix lemon.doctor --verbose reports lsp.preview from the redacted project-fixture and real-repo fixture proof artifacts, and final readiness audit blocks LSP preview promotion unless both full registered-server proof artifacts are current. See docs/tools/lsp.md for checker and language-server install commands.
  • preview generated-media job observability through media.status, Web /ops, Telegram/Discord /media status, and media_diagnostics.json in support bundles. The preview reports job type/status counts, artifact counts/bytes, cleanup policy, prompt hashes, and artifact path hashes only; support surfaces omit prompts, raw artifact paths, generated bytes, provider responses, channel message bodies, and API credentials. LemonCore.MediaJobSupervisor owns the preview OTP worker boundary for queued/running/completed/failed media job lifecycle updates and emits redacted PubSub events for operator surfaces. JSON-RPC media.status also includes redacted provider-backed media proof lane state for image, TTS, STT, vision, and video with safe reason kinds, proof hashes, rerun commands, and bounded next actions but no provider responses, prompts, API keys, or artifact bytes.
  • Telegram/Discord setup diagnostics through channel_diagnostics.json in support bundles. The bundle reports enabled/configured state, binding counts, topic binding counts, file-transfer settings, generated-file auto-send settings, Telegram voice-transcription shape, Discord bot-message policy, Discord DM readiness, Discord free-response readiness, Discord inbound-replay readiness, Discord slash-command readiness, and allowlist counts without raw bot tokens, secret names, chat IDs, channel IDs, guild IDs, or message bodies. The same bundle includes channel_readiness.json with shared Telegram and Discord launch-gate status, gate counts, safe reason kinds, and bounded next actions without raw ids, tokens, proof paths, proof details, or message bodies. readiness_summary.json adds the compact launch-readiness rollup used by mix lemon.readiness: doctor counts, channel gate counts, provider-media state, proof totals, unresolved gates, and cleanup flags without raw ids, prompts, provider responses, proof paths, proof details, or secret values. Web /ops renders the same compact readiness summary so support operators can inspect launch status, unresolved gate labels, and cleanup flags without leaving the browser.
  • browser operator diagnostics in Web /ops. The browser panel shows local driver session timestamps, pending/buffered request counters, a hashed driver process id, safe capability labels, operator guidance, artifact counts, and cleanup policy without embedding screenshot bytes, page contents, cookie values, or raw driver logs. JSON-RPC browser.status exposes the same live browser proof state, latest browser proof checks, and browser proof cleanup booleans for non-Web operator clients without raw proof paths, filenames, page data, screenshots, or provider responses.
  • browser tool progress status. Browser requests emit redacted current_action updates for Web/TUI/Telegram/Discord status surfaces with method, phase, timeout, safe counts, artifact flags, and hashed host metadata only; raw URLs, selectors, typed text, cookie values, page text, screenshot bytes, and artifact paths are omitted.
  • memory-provider diagnostics through memory_diagnostics.json in support bundles. The bundle reports provider count, enabled provider count, provider ids, source labels, supported scopes, timeout shape, and module-load state without memory document contents, raw provider config, secret values, prompts, tool output, or provider error payloads. The same provider shape is visible to operators through read-only memory.status and Web /ops. JSON-RPC memory.status also summarizes provider health, enabled/disabled counts, loaded/missing module counts, searchable scopes, and per-scope provider counts without reading or returning memory contents.
  • skill readiness diagnostics through read-only skills.status. The response preserves each skill's activation state, readiness boolean, platform compatibility, missing binary/config/env/tool names, disabled flag, and error string, then summarizes activation states, sources, ready/not-ready counts, and missing-requirement counts without returning skill file paths or secret values.
  • secrets-store diagnostics through read-only secrets.status. The response reports whether the encrypted store is configured and healthy, safe source and fallback booleans, safe keychain error kind, owner, count, and cleanup flags without returning secret values, raw key material, or raw keychain error text.
  • BEAM runtime capacity diagnostics through root status. The response includes process, port, atom, and run-queue counters plus limits so operators can distinguish Lemon runtime pressure from provider or channel issues; missing optional supervisors fail closed to zero counts instead of crashing status.
  • legacy transport diagnostics through read-only transports.status. The response reports registry loaded/running state, configured/enabled/disabled counts, module load counts, and cleanup flags without returning credential values, raw config, or secret names.
  • TTS control-plane diagnostics through read-only tts.status. The response preserves explicit stored configuration values, reports active-provider known/available booleans, summarizes provider readiness counts, and includes cleanup flags without returning secret values, raw key material, or raw provider errors.
  • usage diagnostics through read-only usage.status. The response reads the same current summary maintained by usage.cost, reports run/token/cost counts, per-provider request/token/cost rows, quota status, remaining quota estimates, and cleanup flags without returning prompts, responses, or secret values.
  • voicewake diagnostics through read-only voicewake.get. The response preserves explicit stored configuration values, reports configured/enabled status and backend summary, and includes cleanup flags without returning audio samples or secret values.
  • config diagnostics through config.get and config.set. Stored config keys that look like API keys, tokens, passwords, secrets, credentials, or private keys are returned as bounded redaction objects in single-key and full-config reads, and sensitive config.set responses do not echo the submitted value.
  • model catalog diagnostics through read-only models.list. The response includes provider/capability counts, source metadata, and cleanup flags while omitting credential and secret values.
  • agent directory diagnostics through agent.directory.list, agents.list, and agent.targets.list. These responses include compact agent/session/target summaries and cleanup flags without returning message bodies, credentials, or secret values.
  • proof-artifact diagnostics through proof_diagnostics.json in support bundles, read-only proofs.status, and Web /ops. The bundle scans .lemon/proofs/*proof*.json, .lemon/proofs/*-latest.json, and tmp/*proof*.json for redacted proof status, pass/fail/skip counts, generated timestamps, provider/model labels when already present in proof metadata, and safe failure reason kinds. Proofs with explicit status keep that status; proofs that only expose ok: true/false are classified as completed or failed. It reports only reason-kind counts, safe proof-scope counts, safe check-name counts, latest redacted check status with proof-object labels when present, safe proof object/provider-path labels on recent proofs, safe coverage counts/booleans for Discord slash and live-matrix artifacts, media-directive delivery/leak booleans on Web /ops, file/proof hashes, cleanup booleans, and explicit proof-level redaction booleans for proof artifacts that use a redaction map instead of a generic cleanup map; shared LemonCore.Doctor.ProofLaunchGates summary for Discord DM, Discord slash registration, Discord slash client-click, provider media, and terminal backends; proofs.status, readiness_summary.json, readiness.status, and Web /ops all consume that same redacted proof-gate view so operators can show bounded launch blockers without raw proof rows; support surfaces omit raw file paths, filenames, proof details, prompts, provider responses, proof file contents, and generated artifacts.
  • channel failure drilldown in Web /ops. The panel joins redacted channel diagnostics with safe proof counts so operators can see whether Telegram voice transcription plus Discord DM, free-response, reconnect replay, and slash client-click promotion are blocked, seeded, proven, or still waiting for live proof without exposing chat IDs, channel IDs, guild IDs, message bodies, or raw proof files.
  • channel readiness checks in mix lemon.doctor. Doctor reports Telegram and Discord credential shape, Telegram local voice transcription proof status, plus Discord DM, free-response, reconnect, slash registration, deterministic slash, and real slash client-click proof gates from the same redacted diagnostics/proof inventory used by support bundles and Web /ops.
  • media readiness checks in mix lemon.doctor and Web /ops. Doctor separates Telegram/Discord generated-media delivery proof from provider-backed image/TTS/STT/vision/video proof. Provider-backed failures surface only safe reason_kind labels, such as provider_http_error, in doctor summaries and remediation hints so operators can distinguish failed, skipped, missing, permission-denied, billing/quota, and payment-required proof lanes without exposing provider responses, prompts, or raw artifact metadata. image/TTS/STT/vision/video proof, so local channel delivery can be promoted while missing live provider credentials or quota remains an explicit warning.
  • terminal backend readiness checks in mix lemon.doctor. Doctor consumes the same redacted terminal backend proof rows as support bundles and proofs.status, passes when local, local PTY, Docker, and SSH preview backends have completed rows, warns on failed or missing rows, and never includes command text, environment values, process output, raw SSH targets, or raw proof paths.
  • OpenAI-compatible API preview readiness checks in mix lemon.doctor. Doctor consumes the redacted /v1 smoke proof rows as openai_compat_* checks, passes when health/capabilities, Chat Completions, Responses, streaming, stored response, cancellation, image metadata/pass-through/rejection/policy, external fetch, OpenAI Node SDK, and OpenAI Python SDK rows are complete, and never includes raw prompts, answers, API keys, run events, or provider responses.
  • ACP preview readiness checks in mix lemon.doctor. Doctor consumes the deterministic stdio, external Node client, and official ACP SDK proof rows as acp_stdio_*, acp_stdio_external_*, and acp_official_sdk_* checks, passes when all three proof artifacts are complete, and never includes raw prompts, answers, API keys, run events, session ids, child stderr, file contents, or file paths.
  • Hermes-compatible final-answer MEDIA:<project-relative-path> directives for Telegram and Discord. Lemon resolves these at router finalization time into the existing auto_send_files delivery path only when the target is an existing regular file inside the run working directory; symlink escapes, missing files, and out-of-project paths are ignored, and the directive line is stripped from the channel-facing text. Live matrix proof harnesses are available through Telegram --topic-media-directive-delivery and Discord --wait-media-directive-delivery; sanitized proof artifacts expose only coverage, marker/document or attachment status, directive-leak status, and hashed channel/topic identifiers. Doctor, support bundles, proofs.status, and Web /ops surface the MEDIA directive coverage and leak-status booleans without exposing the local directive path or raw channel message body.
  • preview durable goal status, one-shot continuation, one supervised judge tick, max-continuation budgets, bounded operator-started goal loops, and opt-in persisted auto-loop scheduling through goal.set, goal.status, goal.pause, goal.resume, goal.continue, goal.loop.once, goal.loop.start, goal.loop.status, goal.loop.stop, goal.clear, TUI /goal, Telegram/Discord /goal status/set/continue/loop controls, Web /ops, goal lifecycle events, and redacted support-bundle metadata. This is bounded supervised loop plumbing with a dev/prod router-backed judge default, deterministic proof through the real router run process, persisted-auto scheduler proof through the same path, and provider-backed live model-judge proof. Richer channel-visible loop behavior remains preview before full persistent-goal parity.
  • preview durable kanban board/task state, JSON-RPC board/task/archive/dispatcher methods, model-facing kanban tool, supervised dispatcher leases, per-task git worktree worker cwd for git-backed boards, redacted Web /ops board visibility, TUI /kanban board/task/archive/dispatcher controls, Telegram /kanban commands, Discord /kanban slash commands, and redacted support-bundle diagnostics.
  • bugs with reproduction steps on supported source or release-runtime paths

Channel Support

Telegram and Discord are stable 1.0 remote chat channels for text-first agent runs. The TUI, Web UI, and control plane are stable first-party local interfaces. In control-plane mode, the TUI renders approval events as notifications; MCP OAuth approval requests include the authorization URL plus resource, scope, and redirect context so operators can complete login without opening Web /ops, and MCP sampling approval requests include redacted request hash, model, token, message, role, and content-kind metadata. Operators can resolve pending approvals from the terminal with /approval approve|once|session|agent|global|deny <approval-id>, using the same exec.approval.resolve path as Web /ops; /approval and /approval list refresh the current pending approval snapshot through exec.approvals.get. Approval timeouts also arrive as exec.approval.resolved notifications with decision: "timeout" so terminal operators see when a pending request expired.

JSON-RPC channels.status combines registered channel-adapter status with the same redacted Telegram/Discord diagnostics used by support bundles and Web /ops, including binding counts, file-transfer shape, Telegram voice settings, Discord DM/free-response/replay/slash-command readiness, bot-message policy, and cleanup booleans without bot tokens, secret names, chat ids, channel ids, guild ids, or message bodies. It also exposes recent redacted Telegram/Discord proof artifacts and latest channel proof checks without raw proof paths, filenames, prompts, provider responses, or proof file contents. The top-level summary includes compact launchGateStatuses and launchGateReasonKinds maps so operator clients can read specific Telegram/Discord gates without scanning the full readiness list.

Discord support is bounded to the live-proven path: mention-triggered text prompts in the configured Lemonade Stand channel, markdown/code rendering, long-output chunking, tool success/failure status rendering, text-file attachment delivery, public-thread prompt/reply, and free-response unmentioned thread prompts after /trigger all. The DM live matrix now records redacted setup failures classified as discord_dm_setup_refused, but Discord DMs, client-click slash interactions, and voice remain preview until separate live matrices promote them. Slash-command diagnostics list the expected Lemon commands and proof sources, and the deterministic slash proof covers 34 local inventory/decoder/response checks across the 16 in-repo command names. Safe coverage counts from that proof are exposed through support bundles, proofs.status, and Web /ops. Doctor now distinguishes all-command registration proof from narrower /media registration proof, but broad Discord slash parity still requires real client-click evidence. The Discord runtime now passively records redacted lemon.discord_slash_client_click proof artifacts when a real slash-command interaction arrives with live Discord fields and Lemon emits a safe interaction response, so an operator can promote that gate by clicking a command after the runtime is deployed or hot reloaded and then running scripts/live_discord_matrix.py --wait-slash-client-click-proof --channel-id <channel-id> --proof-path .lemon/proofs/discord-slash-client-click-check-latest.json. The wait mode posts a concrete operator instruction, polls the runtime proof artifact, and rejects stale artifacts generated before the watcher started. The validator emits stable reason kinds for missing, invalid, and non-promotable artifacts so doctor, support bundles, and Web /ops can tell operators whether they need to capture the first real click, replace a bad artifact, or rerun after a non-promotable click response. Inbound-replay diagnostics distinguish deterministic transport-restart dedupe proof from live gateway reconnect proof. The latest live gateway reconnect proof passed after a deliberate runtime restart with no duplicate replay and a fresh post-restart response. Live Discord matrix runs can now write a second, sanitized proof artifact with --proof-path for proofs.status, support bundles, doctor gates, and Web /ops; keep --result-path for operator handoff data such as nonces and message ids. The sanitized proof preserves only coverage counts/booleans such as whether DM, free-response, restart-verify, generated-media, file-delivery, or slash-registration checks were present, including contains_rollback_slash_registration, plus reason kinds and cleanup assertions. Free-response Discord support requires the privileged Discord Message Content Intent and a passing external-sender proof. The latest live unmentioned second-bot matrix passed in a per-check public thread and wrote .lemon/proofs/discord-free-response-latest.json with message_content_intent_declared: true, trigger mode all, cleanup mode clear, and redacted proof metadata. The live failure that preceded it exposed a thread-shape bug: Discord can deliver thread MESSAGE_CREATE events with the thread id as channel_id and no parent-channel context, so the transport now falls back to the stored {thread, thread} trigger-mode key. mix lemon.doctor now reports channels.discord.free_response as passing when this proof is current. X/Twitter, XMTP, SMS, voice, and other channel adapters are preview or experimental unless a release note explicitly promotes a narrower path. Bugs in preview channels can be filed with reproduction steps and support bundles, but they do not carry the same release-blocking support promise as Telegram, Discord, TUI, Web, and the control plane.

Cron support bundles include redacted cron_diagnostics.json. Use MIX_ENV=test mix run scripts/live_cron_diagnostics_smoke.exs to prove the diagnostics and support-bundle redaction boundary. Use MIX_ENV=dev mix run --no-start scripts/live_cron_runtime_restart_smoke.exs for the full-runtime restart proof; it boots :runtime_full twice against an isolated durable store and writes .lemon/proofs/cron-runtime-restart-latest.json after observing a scheduled run before restart, persisted job/run history after restart, and a fresh scheduled run after restart. Use MIX_ENV=test mix run scripts/live_cron_channel_origin_smoke.exs for the channel-origin delivery proof; it registers proof-only Telegram and Discord plugins, completes channel-peer cron runs through the BEAM manager/outbox path, and writes .lemon/proofs/cron-channel-origin-latest.json with hashed cron IDs and safe channel-shape metadata. mix lemon.doctor --verbose reports cron.preview from those three proof artifacts, and final readiness audit blocks cron preview promotion unless all three artifacts are complete and redacted.

Active cron runs can be aborted by cron run id through the control-plane cron.abort method, the model-facing cron tool abort action, Web /ops, or TUI /cron abort <run-id>. Abort routes to the underlying Lemon run cancellation when that run is still alive, persists the cron run as aborted, and does not retry the run.

Web /ops and control-plane cron.status also surface cron scheduler health as aggregate counters for active run locks, retry runs, suppressed scheduled slots, stale-run recoveries, and scheduled retries, plus next/last run timestamps and status/trigger/audit count maps. Those counters come from the same durable run and audit stores used by support bundles, so operators can see when BEAM scheduling is intentionally holding a slot instead of launching a duplicate run.

Cron lifecycle actions also write durable operator audit events to :cron_audit_events. The control-plane cron.audit read method returns raw operator IDs for authorized clients, Web /ops shows the most recent lifecycle audit entries, and the WebSocket event bridge emits cron.audit updates. Support bundles include only redacted audit counts, action counts, recent action shape, reason hashes, ID hashes, and changed-field names.

Cron creation and updates accept 5-field cron expressions plus supported operator shorthands such as every 30m, hourly, every 2h, daily at 9am, weekdays at 09:30, and weekly monday at 8am. Lemon stores the normalized 5-field cron expression. Interval shorthands must divide the enclosing cron field exactly, and unsupported free-form schedule text is rejected through the normal cron validation path.

Control-plane operators can create no-agent command cron jobs with command instead of agentId/sessionKey/prompt. These jobs run as supervised local shell commands under CronManager, persist output/error in cron run history, and do not create LemonRouter runs or channel summaries. cron.update preserves the original target type: command jobs can update command, cwd, and env, while prompt jobs can update prompt. The model-facing cron tool remains prompt-job scoped.

Web, Browser, and Media Tools

Stable 1.0 support covers first-party text web search/fetch behavior when the run is reproducible on a supported source or release-runtime install. Browser automation is now a preview first-party surface through supervised browser_* coding-agent tools backed by the local Node/Playwright driver. mix lemon.doctor --verbose reports browser.preview from the redacted .lemon/proofs/browser-smoke-latest.json artifact, and final readiness audit blocks browser preview promotion unless the live smoke proves the local driver, CDP attach, route guardrails, page interaction, upload/download, screenshots, cookies/state reset, progress redaction, and browser-to-media vision boundary. Visual generated media, image analysis, and voice or TTS behavior remain preview or out of scope unless a release note explicitly promotes a narrower path. The generated-media support foundation records redacted media job metadata and artifact summaries through LemonCore.MediaJobs; generated final-answer files that pass through the router auto-send path are recorded before channel dispatch. This is observability for generated media, not a stable provider-generation claim. Telegram /media status and Discord /media status expose the same redacted counts to channel operators without raw prompts, paths, bytes, captions, or provider responses. The live Discord API proof confirms Zeebot has the in-repo /media status application-command schema registered. Live generated-SVG and generated-audio delivery are proven for Telegram and Discord through the normal generated-file auto-send path; support artifacts record only safe booleans such as generated-audio coverage, Telegram document delivery, Discord attachment count, marker status, and sender shape. mix lemon.doctor reports this channel delivery as media.channel_delivery, and separately reports media.provider_live for provider-backed image, TTS, STT, vision, and video proof. At this snapshot provider-backed STT and vision are proven, while image, TTS, and video remain blocked or skipped until LEMON_TEST_ALLOW_LIVE_CREDENTIALS=1 and usable provider credentials/quota are available. Image proof may be satisfied by either openai_image or vertex_imagen; the current Vertex proof reaches Google and fails with the safe reason vertex_imagen_http_error:permission_denied. TTS proof may be satisfied by OpenAI, ElevenLabs, or google_tts; the current Google proof reaches Cloud Text-to-Speech and fails with the safe reason google_tts_http_error:permission_denied. Video proof may be satisfied by OpenAI or vertex_veo; the current Vertex Veo proof reaches Google and fails with the safe reason vertex_veo_create_http_error:permission_denied. Doctor remediation includes copy-ready MIX_ENV=test mix run --no-start scripts/live_media_*_smoke.exs --proof-path .lemon/proofs/media-*-smoke-latest.json commands for the incomplete providers, adds the target --provider flag when a failed/skipped multi-provider lane identifies the safe provider id, and includes bounded hints for permission-denied, billing/quota, payment-required, and request-shape failures, matching the Web /ops provider-media proof rows. Web /ops also exposes the secret-backed variant with --api-key-secret SECRET_NAME for release-candidate operators who keep provider keys in Lemon's encrypted secret store instead of exporting raw API keys. The provider-prefixed OpenAI-compatible routing handoff is proven only on the media vision path; image, TTS, STT, and video proof scripts report provider_prefixed_model_not_supported_for_media_type if called with a provider:model value, and compatible endpoint checks should use --base-url with an unprefixed model. The final readiness audit also prints safe reason_kind labels from incomplete provider-media proof artifacts, such as credential_preflight_skipped, openai_image_http_error:billing_limit_user_error, vertex_imagen_http_error:permission_denied, google_tts_http_error:permission_denied, vertex_veo_create_http_error:permission_denied, openai_tts_http_error:invalid_request_error, or elevenlabs_tts_http_error:payment_required, while continuing to block raw provider responses, prompts, keys, transcripts, and media bytes from support surfaces. When those incomplete proofs identify a safe provider id for a multi-provider lane, the audit also prints a copy-ready rerun command with the matching --provider flag. Provider-backed STT can be satisfied by the completed deepgram_transcribe proof as well as OpenAI transcription proof.

Lemon 1.0 does not claim OpenAI-compatible API server behavior, OpenAI-compatible Chat Completions/Responses API support, ACP editor integration, third-party frontend compatibility, autonomous persistent goal continuation loops, kanban dispatcher/worktree/UI parity, LSP semantic diagnostics, checkpointing for destructive shell commands, or multi-backend terminal parity unless a release note explicitly promotes a narrower path. The stable API surface is the documented Lemon control plane and first-party Web/TUI interfaces.

For web-tool bugs, include the prompt, tool name, target URL when shareable, interface, runtime mode, and whether the issue is plain text fetch/search or browser behavior. For browser bugs, include whether clients/lemon-browser-node was built, the Chrome/Chromium executable used, and any screenshot artifact path under .lemon/browser-artifacts/.

Automation and Cron

Cron and scheduled automation are preview surfaces for stable 1.0. The supported boundary is operator-controlled scheduling from the Web operations UI or first-party control-plane/runtime paths, with reproducible failures covered as setup or runtime bugs.

Support bundles include redacted cron diagnostics for those reproducible bugs: counts, status/trigger shape, timestamps, hashed job/run/session/agent/prompt metadata, retry policy/lineage shape, redacted lifecycle audit shape, and cleanup flags. The regression proof is:

MIX_ENV=test mix run scripts/live_cron_diagnostics_smoke.exs
MIX_ENV=test mix run scripts/live_cron_channel_origin_smoke.exs

Passing that smoke means the bundle contains cron_diagnostics.json and omits raw prompts, outputs, errors, session ids, agent ids, memory paths, and metadata values, including retry lineage ids and raw audit ids.

Stable 1.0 does not support presenting cron as an unrestricted model-facing tool. Scheduled agent runs are expected to run in isolated forked sessions, carry their prior-run memory context, and block recursive cron management through model tool policy. Operator-controlled pause/resume/run-now/abort are supported first through the first-party runtime surfaces. Operator-controlled audit history is available through cron.audit, Web /ops, and cron.audit WebSocket events. Treat advanced automation workflows, external scheduler integrations, and production SLA-style scheduling guarantees as post-1.0 work.

Telegram Rendering and Media

Telegram is supported as a remote chat interface for text-first agent runs. Stable 1.0 behavior includes:

  • plain text delivery with Telegram entities for headings, bold, italic, inline code, fenced code blocks, links, lists, blockquotes, and simple markdown tables rendered as pipe-delimited text
  • progress/status messages, cancellation controls, approval buttons, and concise run-failure messages
  • /file put and /file get when Telegram file transfer is enabled
  • document upload auto-save when enabled by config
  • telegram_send_image for image files that already exist inside the active project or workspace roots
  • optional generated-file auto-send, bounded by configured file count and size limits
  • image batches through Telegram media groups when the Bot API accepts them, with sequential image/document fallback
  • Discord finalized-run attachment delivery and optional generated-file auto-send, bounded by configured [gateway.discord.files] count and size limits

Not stable for 1.0:

  • arbitrary rich media generation as a product feature
  • image analysis as a Telegram interface feature
  • provider-backed TTS or voice reply generation under production quota
  • guarantees that every markdown extension renders visually identical to GitHub Markdown
  • sending files from outside the active project or workspace roots

For Telegram or Discord media bugs, include the interface, command or tool used, file type, file size, relevant [gateway.telegram.files] or [gateway.discord.files] config, and whether the issue was manual file transfer, generated-file auto-send, or telegram_send_image.

The detailed support matrix lives in Release Checklist and Support Policy.

Not Supported for 1.0

These are outside the initial stable support boundary:

  • native Windows installs outside WSL experimentation
  • hosted Lemon service operation
  • Discord behavior outside the text-first and file-delivery boundary, including voice, broad slash-command parity, and unproven DM workflows
  • stable support guarantees for X/Twitter, XMTP, SMS, voice, or other preview channel adapters unless explicitly promoted in release notes
  • production-grade scheduling guarantees for cron or scheduled automation
  • first-class browser automation as a stable support guarantee, generated media, image analysis, or TTS/voice behavior unless explicitly promoted in release notes
  • OpenAI-compatible API server behavior, ACP editor integration, or drop-in support for third-party OpenAI-compatible frontends
  • production support for third-party plugins or external plugin hosts
  • Web/TUI/channel rollback controls or support guarantees beyond the preview checkpoint boundary. Preview checkpoints cover file-tool snapshots, configured risky-shell snapshots, redacted lifecycle events, redacted diagnostic metadata, Telegram/Discord redacted checkpoint status/events with lifecycle event counts/history, pushed active-run event notices, and diff/restore actions through /checkpoint plus the /rollback alias, Web /ops rollback command guidance/actions, and operator-only control-plane and TUI diff/restore methods. Chat checkpoint output does not expose raw file paths, file contents, raw session ids, or arbitrary file browsing.
  • live production proof for persistent /goal model judging beyond the preview status/set/pause/resume/continue/loop controls
  • live production proof for real multi-worker kanban execution beyond the deterministic bounded-concurrency/crash/reclaim dispatcher proof
  • stable Hermes-style LSP semantic diagnostics beyond the current preview checker/server/session status surface
  • production-grade terminal container fleet parity beyond the current Docker/SSH preview boundary. The preview boundary includes local, local PTY, Docker, and SSH execution plus Docker hardening proof for read-only rootfs, no-exec /tmp, dropped capabilities, no-new-privileges, no-network default, and cgroup-observed CPU/memory/pids policy. Support bundles and proofs.status expose these as safe booleans and policy values only, without command text or output.
  • provider routing, fallback providers, credential pools, and profile distribution parity
  • production support for third-party plugins or unofficial MCP servers
  • arbitrary local shell, provider, or OS customization issues
  • old commits that are not the current stable release, preview build, or a requested diagnostic commit
  • user-provided secrets, private prompts, memory contents, or tool outputs shared as part of an issue

Before Opening a Bug

Run:

mix lemon.doctor

For source-dev installs, generate a reviewed redacted bundle:

mix lemon.doctor --bundle

From the Web operations UI, use:

http://127.0.0.1:4080/ops/support-bundle

For release-runtime installs, generate:

bin/lemon_runtime_full eval 'LemonCore.Doctor.CLI.bundle!()'

Review the zip before sharing it. The bundle is designed to exclude secrets and private data, but users remain responsible for checking attachments before posting them publicly.

The bundle manifest includes the Lemon app version, release name/version, release channel when available, source/release runtime mode, git commit/branch state, Elixir/OTP versions, OS, and CPU architecture.

For browser automation bugs, the bundle also includes browser_diagnostics.json with local driver lifecycle counters, the browser artifact directory, artifact count/byte totals, oldest/newest artifact timestamps, managed cleanup policy, and recent screenshot artifact metadata. It does not include screenshot bytes, page HTML, page text, cookies, private prompts, or tool outputs.

For generated-media bugs, the bundle includes media_diagnostics.json with the media job metadata directory, artifact directory, redacted job counts, type and status counts, artifact count/byte totals, cleanup policy, and recent job metadata. It also includes a redacted provider_live summary for the image/TTS/STT/vision/video launch lanes with completed count, safe provider labels, safe reason_kind labels, default proof paths, and copy-ready rerun commands. When a failed or skipped multi-provider lane identifies a safe target provider, the support bundle includes the same --provider rerun flag that doctor, Web /ops, and the final readiness audit use. It does not include prompts, raw artifact paths, generated bytes, provider responses, channel message bodies, or API credentials.

For provider setup bugs, the bundle includes provider_diagnostics.json with the default provider, default-model presence, configured provider count, credential-reference counts, ambient-provider presence booleans, routing fallback shape, credential-pool shape, and per-provider redacted configuration shape. It does not include API keys, secret names, raw base URLs, env var names, provider responses, or model prompts.

mix lemon.doctor also includes a providers.routing check. It reports when fallback routing is disabled, absent, configured without any credential-ready fallback, or able to rescue a not-ready default provider through a credential-ready fallback. The check only reports provider labels and counts; it does not expose key material, secret names, endpoint URLs, prompts, or provider responses.

Web /ops also shows the latest redacted provider fallback proof summary from local proof artifacts, including proof status, primary/fallback/final provider labels, proof object, proof hash, modified timestamp, next action, and explicit cleanup flags. It does not expose prompts, answers, raw API keys, secret names, base URLs, env var names, or provider response bodies. JSON-RPC providers.status exposes the same redacted live fallback proof status for non-Web clients alongside credential readiness and route preview.

For cron and scheduled-automation bugs, the bundle includes cron_diagnostics.json with job/run counts, enabled/disabled counts, active/failed run counts, status and trigger counts, next/last run timestamps, recent job shape, retry policy, recent run retry-lineage shape, lifecycle audit counts, audit action counts, and recent audit event shape. It hashes job/run ids, audit ids, agent ids, session keys, prompts, outputs, errors, schedules, names, memory-file paths, retry parent/root ids, and audit reasons; it records metadata keys and changed-field names only. It does not include raw prompts, outputs, errors, session ids, agent ids, memory paths, retry lineage ids, audit ids, audit reasons, or metadata values.

For Telegram and Discord setup bugs, the bundle includes channel_diagnostics.json with redacted transport enablement, credential-shape booleans, binding counts, file-transfer controls, generated-file auto-send shape, Telegram voice-transcription shape, and Discord free-response readiness shape including whether Message Content Intent has been operator-declared. It also reports Discord bot-message policy: self messages and webhooks are ignored, while external bot messages are accepted only when normal trigger policy allows them and still require live proof before broad support promotion. It does not include bot tokens, secret names, raw chat IDs, raw channel IDs, raw guild IDs, or message bodies.

The bundle also includes channel_readiness.json, a shared launch-gate summary for promoted Telegram and Discord support. It reports total/passed/warning/ blocked/skipped gate counts, safe reason kinds, cleanup flags, and copy-ready next actions for unresolved gates such as Discord DM setup or slash client-click wait mode. It does not include bot tokens, secret names, raw chat IDs, raw channel IDs, raw guild IDs, message bodies, raw proof paths, or raw proof details.

readiness_summary.json is the support-bundle version of mix lemon.readiness and ./bin/lemon readiness. It consolidates doctor summary state, Telegram/Discord launch-gate counts, provider-media proof state, proof-artifact totals, unresolved gate labels, safe unresolved-gate reason kinds, and cleanup flags into one compact triage document. It does not include bot tokens, secret names, raw chat IDs, raw channel IDs, raw guild IDs, message bodies, raw proof paths, raw proof details, raw prompts, provider responses, or secret values. It also includes the shared proof-gate summary for Discord DM, Discord slash registration, Discord slash client-click, provider media, and terminal backends from LemonCore.Doctor.ProofLaunchGates. JSON-RPC readiness.status exposes the same compact launch-readiness shape for operator clients, using lowerCamelCase cleanup keys, top-level summary proof-gate counts/statuses, and a top-level summary list of unresolved gate reason kinds. Web /ops consumes the shared LemonCore.Doctor.ReadinessSummary payload too, keeping browser support views, CLI output, JSON-RPC clients, and support bundles aligned on the same launch gate counts and redaction boundary. The human-readable mix lemon.readiness output includes the same proof-gate status counts and unresolved-gate reason labels so source-install support does not require JSON parsing for the main launch blockers. The source-install and release-runtime verifiers also inspect support-bundle readiness_summary.json for the shared proof-gate status/count shape and required launch-gate ids, so release artifacts cannot pass while omitting the operator-visible launch-gate summary. The provider-media unresolved gate also carries bounded reason_kinds from the shared proof-gate lanes, and Web /ops requests enough unresolved readiness rows to include that provider-media gate.

mix lemon.doctor also includes channel and media readiness checks. Telegram and Discord config checks report only whether each enabled transport has a bot token or secret reference. Discord proof checks report whether DM, free-response, live reconnect, slash registration, deterministic slash, and real slash client-click promotion gates are proven, blocked, or waiting for operator action. These checks use redacted proof reason kinds, safe proof scopes, and safe coverage counts; they do not include Discord IDs, message bodies, raw proof paths, bot tokens, or secret names. Current expected pre-promotion warnings include discord_dm_setup_refused for closed DM targets and missing real slash client-click proof artifacts. Free-response should now pass when .lemon/proofs/discord-free-response-latest.json is current and the local Message Content Intent declaration remains true. The final readiness audit echoes bounded reason-kind labels from incomplete Discord DM, free-response, and slash client-click proof artifacts without printing Discord IDs, interaction tokens, or message bodies. Media checks report generated Telegram/Discord delivery separately from provider-backed image/TTS/STT/vision/video proof; missing or skipped provider proofs remain warnings until live credential proofs pass. Doctor and Web /ops both show the default redacted provider proof paths for reruns. Restart seed without verify is still a warning if only the seed artifact exists, but the latest restart verify proof has passed.

mix lemon.doctor also includes terminal.backends_live. It reports whether the latest terminal backend smoke proof has completed rows for the local, local PTY, Docker, and SSH preview backends, warns on failed or missing rows, and skips when no proof has been generated. The remediation uses MIX_ENV=test mix run scripts/live_terminal_backend_smoke.exs and the canonical .lemon/proofs/terminal-backend-latest.json artifact; diagnostics stay limited to safe status labels and redacted proof metadata. Control-plane terminal.backends.status includes the same terminal live-proof state plus the redacted Docker hardening summary, so non-Web clients can confirm read-only rootfs, no-exec tmpfs, dropped capabilities, no-new-privileges, cgroup limits, pull policy, and network mode without reading proof JSON.

mix lemon.doctor also includes openai_compat.api_preview. It reports whether the latest local OpenAI-compatible API smoke has completed the /v1 preview rows for health/capabilities, Chat Completions, Responses, streaming, stored response, cancellation, image metadata/pass-through/rejection/policy, external fetch, OpenAI Node SDK, and OpenAI Python SDK clients. The remediation uses MIX_ENV=test mix run scripts/live_openai_compat_smoke.exs; diagnostics stay limited to safe status labels, proof hashes, and redacted metadata.

mix lemon.doctor also includes acp.preview. It reports whether the latest ACP deterministic stdio smoke, external Node stdio client proof, and official ACP SDK client proof are all complete. The remediation uses MIX_ENV=test mix run scripts/live_acp_stdio_smoke.exs, node scripts/live_acp_stdio_external_client.mjs, and node scripts/live_acp_official_sdk_client.mjs; diagnostics stay limited to safe status labels, proof hashes, and redacted metadata.

mix lemon.doctor also includes mcp.preview. It reports whether the latest MCP stdio, Streamable HTTP, and legacy SSE smoke proofs are all complete. The remediation uses MIX_ENV=test mix run scripts/live_mcp_stdio_smoke.exs, MIX_ENV=test mix run scripts/live_mcp_http_smoke.exs, and MIX_ENV=test mix run scripts/live_mcp_sse_smoke.exs; diagnostics stay limited to safe status labels, proof hashes, and redacted metadata.

For extension/plugin setup bugs, the bundle includes extension_diagnostics.json with global, project, and configured extension directory existence, extension-file counts, extension-manifest valid/invalid counts, aggregate manifest capability/provider/host/distribution/audit shape, nested library-file counts, and file/path hashes. It does not load extension code and does not include raw source paths, file contents, manifest contents, distribution URLs, plugin names, provider names, or load-error messages.

The same redacted directory shape is visible in Web /ops through the Extensions panel. Use read-only extensions.status when you need the deeper loaded-extension, tool-conflict, provider-registration, or WASM status view. Generic proof diagnostics and JSON-RPC proofs.status also preserve extension/WASM proof-level redaction maps on recent proof summaries, so support bundles, Web /ops, and external clients can show that lifecycle, telemetry, policy, host, and registry proof artifacts omit raw paths, cwd, session ids, params, manifest contents, distribution URLs, and tool payloads without treating those fields as generic cleanup policy. The JSON-RPC response formats those redaction keys as lowerCamelCase for API clients while keeping support-bundle and Web internal summaries tied to the proof artifact vocabulary. The same response includes a lowerCamelCase launchGates summary for Discord DM, Discord slash registration, Discord slash client-click, provider media, and terminal backend promotion gates.

Logs

By default, source-dev runs write logs to stdout/stderr. Increase verbosity with:

LEMON_LOG_LEVEL=debug ./bin/lemon

File logging is opt-in through ~/.lemon/config.toml:

[logging]
file = "~/.lemon/log/lemon.log"
level = "debug"

For release-runtime installs, stdout/stderr depends on how the runtime is started. CI release-smoke failures upload release logs from _build/prod/rel/<profile>/tmp/log/. When filing issues, include only relevant log excerpts and remove secrets, tokens, private prompts, memory contents, and tool outputs.

What to Include

Use the bug report template and include:

  • install path: source-dev or release-runtime
  • operating system and architecture
  • Lemon commit, tag, or release artifact name
  • interface: TUI, Web, Telegram, Discord, CLI, release runtime, or control plane
  • command that failed
  • expected behavior
  • actual behavior
  • relevant logs with secrets removed
  • support bundle command output or attached reviewed bundle

Security Reports

Do not open public issues for suspected vulnerabilities or secret leaks. Use the security reporting path in the repository SECURITY.md and the safety guidance in Lemon Safety.

Useful Pages

NeedPage
Install pathInstall Lemon
Full setup guideSetup Guide
Run a local proofDemo Lemon
Safety and redaction modelSafety
Release support matrixRelease Checklist
Current product gapsHermes-on-BEAM Readiness Plan