Always signal stack

jcode — a dependency, vendored, with a small patch

The harness

jcode/ is not part of Always. It is a third-party Rust agent harness copied wholesale into the tree — 390,138 lines across 786 source files, a fifty-crate Cargo workspace, an iOS project, a Figma export and demo video. Always uses one of its twenty-five subcommands, five of its seventy request types, and adds roughly four files' worth of patch. Reading it as if it were the product is the fastest way to misunderstand this repository.

version 0.12.2 edition 2024 workspace root + 50 crates binaries 6 targets test attributes > 3,000

01 — Scale

What is actually in jcode/

The manifest describes itself, without irony, as “Possibly the greatest coding agent ever built — blazing-fast TUI, multi-model, swarm coordination, 30+ tools.” Whatever one makes of that, the shape is unambiguous: this is a full terminal coding agent with providers, a TUI, a memory subsystem, session persistence, MCP, telemetry and a mobile client, of which Always drives one headless mode.

jcode/src
308,417636 .rs files
jcode/crates
75,393136 .rs files, 50 crates
jcode/tests
5,98013 integration files
total Rust
390,138786 files
ratio to first-party
6.7×vs. 58,200 lines of Python + TS
jcode workspace topology and the slice Always uses The root jcode crate sits above four groups of member crates: shared wire and domain types, provider integrations, terminal user interface crates, and runtime and tooling crates. Alongside, a panel lists the six binary targets, three of which are gated behind a dev-bins feature. A highlighted band marks the four source files the Always patch touches, and a separate band marks the narrow slice of the harness the voice stack actually exercises: the serve subcommand, five request types and twelve event types. jcode — root crate · version 0.12.2 · edition 2024 · autobins = false src/ = 636 files, 308,417 lines · lib.rs + main.rs · agent, server, tool, tui, memory, provider, mcp, replay, telemetry release profile is tuned for iteration, not distribution: opt-level 1, codegen-units 256, incremental on. release-lto exists separately. six [[bin]] targets jcode ← src/main.rs — the only one Always runs test_api  ·  jcode-harness behind the dev-bins feature: session_memory_bench · mermaid_side_panel_probe · tui_bench default features = ["pdf"]; embeddings and jemalloc are opt-in 50 member crates, grouped by concern wire & domain types  15 protocol · message-types · session-types config-types · tool-types · task-types usage-types · background-types batch-types · ambient-types · auth-types memory-types · selfdev-types gateway-types · side-panel-types jcode-protocol is the one Always depends on: Request (~70 variants) and ServerEvent (~63) both #[serde(tag = "type")], both in one 2,114-line file providers  6 provider-core · provider-metadata provider-openai · provider-gemini provider-openrouter · azure-auth the root crate also carries a full AWS Bedrock stack as direct dependencies, and a CLI provider list naming ~35 backends Always uses none of these by name — it points the harness at an OpenAI- compatible URL on loopback terminal UI  11 tui-core · tui-render · tui-style tui-markdown · tui-messages tui-mermaid · tui-workspace tui-account-picker · tui-session-picker tui-tool-display · tui-usage-overlay entirely unreachable from Always: the voice stack never starts a TUI ratatui 0.30 + crossterm 0.29 with event-stream runtime & tooling  18 core · agent-runtime · tool-core · storage plan · swarm-core · compaction-core overnight-core · import-core · update-core embedding · pdf · notify-email terminal-launch · build-support mobile-core · mobile-sim · desktop agent-runtime holds SoftInterruptSource { User, System, BackgroundTask } — three variants, and Always added none of them the Always patch — four files src/tool/task.rs — a 4th SubagentOutputMode variant, a dispatch arm, and execute_background() src/message/notifications.rs — the subagent full-answer inline branch and its 256,000-byte cap src/tui/app/commands.rs — --output-mode / --mode parsing for the /subagent slash command src/tui/app/commands_review.rs — the output_mode field on ManualSubagentSpec what the voice stack actually exercises 1 subcommand: serve  ·  5 request types: subscribe, resume_session, message, set_model, set_reasoning_effort (+ ping) 12 event types forwarded by the worker, 11 by the ambient listener — out of roughly 63 the protocol defines
Figure 12. The workspace and the slice. Two observations follow from the shape. First, the harness's whole terminal half — eleven crates and the entire src/tui tree — is dead code from Always's point of view, yet two of the four patched files live inside it, because the slash-command parser is a TUI concern. Second, the release profile is optimised for rebuild speed rather than runtime speed, so a voice deployment built with cargo build --release is running opt-level = 1 code.
02 — How it is started

jcode serve, and nothing else

The worker's _build_serve_command() constructs the process line and nothing about it is guessed — every flag below is a global flag on the root clap parser, and the three flags that serve itself defines are all marked hide = true and are internal to temporary-server lifetimes. There are no public serve options; the socket location comes from the global --socket or the JCODE_SOCKET environment variable.

the agent process, exactly as the worker spawns it — jcode_voice_worker.py:288
$ pgrep -a -f 'jcode serve'
3184240 /home/user/.local/bin/jcode serve --no-update --quiet \
        --socket /home/user/.hermes/voice-daemon/jcode-server.sock \
        -C /home/user -p openai-compatible -m qwen3.6-35b

# with JCODE_VOICE_PROVIDER_PROFILE set, --provider-profile replaces -p entirely:
3184240 /home/user/.local/bin/jcode serve --no-update --quiet \
        --socket …/jcode-server.sock -C /home/user \
        --provider-profile bifrost -m qwen3.6-35b

# the one-shot path, used for slash commands the model cannot emit as tool calls:
$ jcode debug --socket …/jcode-server.sock --no-update --quiet -C /home/user \
      -S <session_id> -w message '/subagent --output-mode background …'


# the process is spawned under a PTY, not a pipe:
$ ls -l /proc/3184240/fd/0
lrwx------ 1 ianflow ianflow 64 … /proc/3184240/fd/0 -> /dev/pts/7
Every flag here is verbatim from the clap definitions in jcode/src/cli/args.rs: --no-update (“Skip the automatic update check”), --quiet (“Suppress non-error CLI/status output for scripting and wrappers”), --socket, -C/--cwd, -p/--provider, --provider-profile, -m/--model; and on debug, -S/--session and -w/--wait. Process ids differ per run.

The PTY is deliberate. pty.openpty() is called before subprocess.Popen and all three standard streams are attached to the slave descriptor, with start_new_session=True. A drain thread consumes the master. The worker also prefers not to spawn at all: _attach_existing_server() runs first, and if both the server socket and its sibling debug socket already exist it reuses them and records owns_server = False — which means stop_server() will not kill a process it did not start.

Readiness is polled, not signalled

After spawning, the worker polls _server_ready() every 0.2 s against a 15-second deadline, and on failure raises TimeoutError("server did not publish debug socket"). If the child exits during startup it re-attempts _attach_existing_server() once, to cover the race where two workers start simultaneously and one loses.

03 — The wire

Two enums, one file, 2,114 lines

Both halves of the socket protocol are serde-tagged enums in crates/jcode-protocol/src/lib.rs: Request (client to server, roughly seventy variants, every one carrying a u64 id) and ServerEvent (server to client, roughly sixty-three). More than half of Request is multi-agent coordination — comm_share, comm_propose_plan, comm_assign_task and forty-odd siblings — none of which Always touches.

The protocol surface Always uses, out of ~133 defined message types
DirectionWire typeSent / consumed byWhy
subscribechat client, ambient listenerfirst message on any new connection
resume_sessionchat client, ambient listenerattach to an existing conversation; must complete before message
messagechat client onlyone user turn
set_modelchat clientsent fire-and-forget; the protocol emits no acknowledgement
set_reasoning_effortchat clientone of none, low, medium, high, xhigh; waited on for up to 15 s
pingJcodeServerClient.ping()on a throwaway socket, expects pong with a matching id
text_deltaboth readersthe answer, and the ambient narration
message_endboth readersambient flush trigger
tool_call / tool_call_start / tool_use / tool_result / tool_call_endboth readersrendered as activity in the browser
swarm_statuschat clientfallback session-id discovery when exactly one member is present
tokenschat clientinput / output / cache-read counts
soft_interrupt_injectedambient listener onlylogged as a marker; not narrated
done / errorchat clientterminate the drain loop for a given id

One event the Python code forwards does not exist

Both the worker's FORWARDED set and the listener's DEFAULT_FORWARDED set include reasoning_delta, and the gateway has a browser frame type for it. grep for reasoning_delta, ReasoningDelta or Thinking in crates/jcode-protocol/src/lib.rs returns nothing — the enum has no such variant. Reasoning appears in the protocol only as the reasoning_effort_changed configuration event. The forwarding entry is inert.

04 — The patched command

/subagent --output-mode background

The model does not need this flag — an LLM-driven subagent call emits a JSON tool input with output_mode set directly. The slash command exists so the mode can be triggered by hand from the TUI or, as the ambient smoke test does, through jcode debug. Its parser is a hand-written token loop, and its rejection messages are exact:

the slash-command parser — jcode/src/tui/app/commands.rs:553
> /subagent --output-mode backgruond --model local/qwen27 count to five
Invalid --output-mode `backgruond`. Expected one of: answer, compact, full_transcript, background.

> /subagent --depth 3 count to five
Unknown flag `--depth`.

> /subagent --type research
Missing prompt. Add text after `/subagent`.

> /subagent --output-mode
Missing value for `--output-mode`.

> /subagent --mode background --model local/qwen27 count from 1 to 5 slowly
Subagent started in background.

Task ID: 184177a3f9
Name: count from 1 to 5 (@general subagent · local/qwen27)
Output file: /tmp/jcode-bg-tasks/184177a3f9.output
Status file: /tmp/jcode-bg-tasks/184177a3f9.status.json

The host will be woken automatically when the subagent completes;
the final answer is auto-injected into the next turn.
To poll early: use `bg` with action="status" and task_id="184177a3f9".
The four error strings are verbatim format! templates from the parser. The success block is the ToolOutput body built at src/tool/task.rs:387; only the task id and the derived display name vary. Task ids are ten characters — six digits of the millisecond timestamp plus four from a 36-character alphabet. The directory is std::env::temp_dir().join("jcode-bg-tasks").
Flags accepted by the /subagent slash command, verbatim from the token loop
FlagDefaultEffect
--type <name>"general"subagent type, used in the display title
--model <id>inheritedresolution order: explicit, then existing, then parent, then provider default
--continue <session>nonerun inside an existing child session
--output-mode, --modeanswerone of answer, compact, full_transcript, background
everything else beginning --rejected; the first non-flag token starts the prompt and consumes the rest of the line

One detail in execute_background is easy to miss and matters for safety: before forking, it copies the registry's tool names and removes subagent, task, todo, todowrite and todoread. A background subagent therefore cannot spawn another background subagent, and the fork depth is capped at one by construction rather than by a counter.

Failures are results, not errors

The spawned closure never returns Err. A child agent that fails writes a payload beginning “Subagent failed: …” — followed by the same <subagent_metadata> block carrying session id, model and duration — and returns TaskResult::failed(Some(1), …). The status file always reaches a terminal state, the notification always formats, and the host is always woken. A failed delegation is reported to you out loud rather than vanishing.

05 — Coverage

Three thousand tests, none on the patch

The harness is heavily tested by attribute count: over 3,000 #[test] and #[tokio::test] functions across src, crates and tests. The background-task machinery Always leans on has real coverage of its own — six async tests in src/background/tests.rs exercising delivery flags, progress persistence and the three wait() exit conditions, plus three in src/server/tests.rs that drive dispatch_background_task_completion directly, including one named background_task_notify_without_wake_does_not_queue_soft_interrupt.

What has no coverage is precisely the Always-specific part:

  • execute_background — no test in the tree constructs SubagentOutputMode::Background. The subagent test module imports five symbols and the enum variant is not among the ones it exercises.
  • The full-answer inline branchsrc/message/tests.rs has five tests for format_background_task_notification_markdown, covering the preview, the empty case, failure highlighting, superseded status and the progress variant. None passes tool_name == "subagent".
  • The 256,000-byte cap — inherits the same gap, and the literal appears exactly once in the whole tree.

The end-to-end check that was written for this feature is scripts/test_ambient_drain.py, on the Python side, and it can no longer pass. See Drift.