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_64release 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/checkpointstatus/events/diff/restore controls with redacted lifecycle event counts/history and pushed active-run event notices, checkpoint lifecycle events, redacted support-bundle metadata, Web/opsrollback command guidance and direct diff/restore controls, and operator-onlycheckpoint.diff/checkpoint.restorecontrol-plane methods plus TUI/checkpoint diffand/checkpoint restore; shared checkpoint storage and filesystem rollback are owned byLemonCore.Checkpoint. JSON-RPCcheckpoint.statusalso 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_diagnosticstool, opt-inwrite/edit/patchbaseline/delta checks, redactedlsp.diagnostics.status, Web/opschecker visibility, andlsp_diagnostics.jsonin support bundles. JSON-RPClsp.diagnostics.statusalso includes recent redacted LSP proof artifacts and latest LSP proof checks, matching the Web/opspromotion view without raw proof paths, filenames, file contents, diagnostics output, or server I/O.LemonCore.LspServerManageris 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, andlsp.server.stopexpose 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 --verbosereportslsp.previewfrom 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. Seedocs/tools/lsp.mdfor checker and language-server install commands. - preview generated-media job observability through
media.status, Web/ops, Telegram/Discord/media status, andmedia_diagnostics.jsonin 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.MediaJobSupervisorowns the preview OTP worker boundary for queued/running/completed/failed media job lifecycle updates and emits redacted PubSub events for operator surfaces. JSON-RPCmedia.statusalso 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.jsonin 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 includeschannel_readiness.jsonwith 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.jsonadds the compact launch-readiness rollup used bymix 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/opsrenders 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-RPCbrowser.statusexposes 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_actionupdates 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.jsonin 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-onlymemory.statusand Web/ops. JSON-RPCmemory.statusalso 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 byusage.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.getandconfig.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 sensitiveconfig.setresponses 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, andagent.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.jsonin support bundles, read-onlyproofs.status, and Web/ops. The bundle scans.lemon/proofs/*proof*.json,.lemon/proofs/*-latest.json, andtmp/*proof*.jsonfor 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 explicitstatuskeep that status; proofs that only exposeok: true/falseare 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 aredactionmap instead of a genericcleanupmap; sharedLemonCore.Doctor.ProofLaunchGatessummary for Discord DM, Discord slash registration, Discord slash client-click, provider media, and terminal backends;proofs.status,readiness_summary.json,readiness.status, and Web/opsall 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.doctorand Web/ops. Doctor separates Telegram/Discord generated-media delivery proof from provider-backed image/TTS/STT/vision/video proof. Provider-backed failures surface only safereason_kindlabels, such asprovider_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 andproofs.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/v1smoke proof rows asopenai_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 asacp_stdio_*,acp_stdio_external_*, andacp_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 existingauto_send_filesdelivery 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-deliveryand 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/opssurface 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/goalstatus/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
kanbantool, supervised dispatcher leases, per-task git worktree worker cwd for git-backed boards, redacted Web/opsboard visibility, TUI/kanbanboard/task/archive/dispatcher controls, Telegram/kanbancommands, Discord/kanbanslash 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 putand/file getwhen Telegram file transfer is enabled- document upload auto-save when enabled by config
telegram_send_imagefor 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
/checkpointplus the/rollbackalias, Web/opsrollback 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
/goalmodel 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 andproofs.statusexpose 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
| Need | Page |
|---|---|
| Install path | Install Lemon |
| Full setup guide | Setup Guide |
| Run a local proof | Demo Lemon |
| Safety and redaction model | Safety |
| Release support matrix | Release Checklist |
| Current product gaps | Hermes-on-BEAM Readiness Plan |