doc map - sinrimin/harness-nexus GitHub Wiki

Harness Nexus documentation (development docs)

These are the development process docs, imported from the repository's docs/ folder (2026-09). They are the historical record of how each phase was scoped and built.

New work is issue-driven now: development is organized around GitHub issues + milestones (see the repo's CONTRIBUTING.md). Big designs start as a design-discussion issue; per-phase PRD/design docs like these are the legacy of the phase-driven era and remain the authoritative description of what shipped. User-facing feature guides are the top-level topic pages, linked from the wiki Home.

Documentation is split by type so it's clear what each file is for.

Folder What it is When to read it
prd/ Product requirements (PRD) โ€” the why and what. User stories, scope, acceptance. Written in the to-spec PRD template. To understand what a phase delivers and why, before diving into how.
design/ Technical design (the "how") โ€” data models, API surfaces, internals, wiring. The development-plan docs. Before changing a phase's implementation; the authoritative source for current behavior.
research/ Technical research โ€” option comparisons, spike notes, technology surveys done before a design. When weighing an approach for an upcoming phase.
adr/ stayed in the repository โ€” architecture decision records. When asking "why this stack/convention?".

Cross-cutting overviews: architecture.md (layering, storage contract, MCP transport) stayed in the repository next to the code; the historical roadmap.md (phase status) is here.

Machine-local, git-ignored material that is deliberately not on the wiki (the dev box holds the only copy): the UI exploration comps (docs/dev/theme-designs/01-bay/ โ€” the spec for anything skin-visible), the UI refactor's phase record (docs/dev/ui-refactor/: skeleton/content/ interaction/contract, the comp inventory, and the per-phase acceptance walks), the snapshot baselines (docs/dev/ui-baselines/), and docs/dev/test-rig.md. The durable rules those documents produced are stated in design-skin-system.md.

Legacy convention (still describes these files): each phase has a paired prd-phase-N-<topic>.md and design-phase-N-<topic>.md. The PRD was written when the phase was scoped; the design doc before implementation.

Index by phase

Phase 1 โ€” Users, roles & authentication โœ…

Phase 2.1 โ€” MCP connection config & credentials โœ…

Phase 2.2 โ€” MCP registry, proxy & profiles โœ…

Phase 2.3 โ€” Callable-function scripts โธ๏ธ on hold

Phase 2.4 โ€” proxy MCP connect & tool inspection โœ…

Phase 3 โ€” Install pipeline ๐Ÿšง (3.1, 3.2 done)

  • Research: research-phase-3-ecc-install-patterns.md โ€” the install-pipeline architecture extracted from ECC (adapter factory + plan/apply + install-state ledger; Codex ground-truth format).
  • Research: research-phase-3-plugin-targets.md โ€” per-target plugin formats (Claude Code / Hermes; ZCode superseded). Superseded on architecture by the ECC doc above.
  • Research: research-phase-3.5-marketplace-emitter-spike.md โ€” empirical spike: Claude Code consumes a plain-HTTP marketplace.json + archive (zip) plugin sources; capability-URL auth; version/SSRF constraints. Basis for the 3.5 re-plan (marketplace emission preferred over adapter writes for claude-code).
  • Design: design-phase-3.5-marketplace-emitter.md โ€” the emitter surface: PAT-in-path catalog + per-profile archive zips, plugin zip layout, MCP emission, config PUBLIC_BASE_URL.
  • PRD: prd-phase-3-install.md
  • Design: design-phase-3-install.md โ€” target adapter factory (one adapter per target: Hermes โ†’ Claude Code โ†’ Codex), plan/apply, install-state ledger. ZCode out of install scope.

Phase 4 โ€” Resource management & PAT UI โœ… (4.1โ€“4.6 done)

  • PRD: prd-phase-4-web-ui.md
  • Design: design-phase-4-web-ui.md
  • Research: research-phase-4.5-hooks.md โ€” the hook event ร— target support matrix (CC ~30 events, ZCode 7, Hermes different model); lands in packages/shared/src/hooks.ts.
  • All resource kinds shipped: sub-agent, rule, command (single-file inline), hook (hooks.json + event/target matrix), skill (inline + inline-bundle multi-file).

Phase 5 โ€” ACP bridge โžก๏ธ absorbed into Phase 8

  • Delivered by Phase 8: C1 (daemon + control channel) and C5 (ACP chat). See the Phase 8 entries below.

Phase 6 โ€” Platform features โณ

  • stdio bridge entry โ†’ resolved by Phase 8 C2 (the stdio shim IS the entry). Remaining: Channels (adjacent to Phase 8 C6), LLM-WIKI, memory/notes.

Phase 7 โ€” Skill multi-source & plugin references โœ…

  • PRD: prd-phase-7-skills.md โ€” covers all four sub-phases (7.1โ€“7.4); carries the research corrections (10 Hermes adapters, 4 trust tiers internally / 3 surfaced, CC has 4 live source kinds and no npm, category is the filter axis).
  • Design 7.1: design-phase-7.1-plugin-source.md โ€” plugin ResourceSource variant + trust/provenance labels + SkillSource port + validator/smoke flip. Zero outbound network.
  • Design 7.2: design-phase-7.2-marketplace-fetch.md โ€” the server's first outbound HTTP path: SkillCatalogService (lazy TTL cache + in-flight dedup), MARKETPLACE_ALLOWLIST, /api/skills/marketplaces/:id/plugins, fixture-injection test mode.
  • Design 7.3: design-phase-7.3-hub-ui.md โ€” the /skills/hub browse page: category/free-text filters, client-side trust badge (neutral variants, not --signal), inline save-as-skill dialog with install-warning UX.
  • Design 7.4: design-phase-7.4-multi-source.md โ€” 4 SkillSource adapters (github/well-known/url/marketplace), SkillSearchRouter (per-source timeout + identifier dedupe + trust-rank), /api/skills/search, hub dual-mode (browse + cross-source search). skills.sh/browse.sh deferred; clawhub/lobehub/hermes-index skipped (verified).
  • Research: research-phase-4.4-skills.md โ€” external skill sourcing: CC/ZCode marketplace plugin model + Hermes's SkillSource adapter model, trust tiers, provenance pinning.
  • 7.2โ€“7.4 designs to be written before each ships.

Phase 8 โ€” Harness Nexus client & agent orchestration ๐Ÿšง (C1โ€“C5 shipped)

  • PRD: prd-phase-8-client.md โ€” the vision shift (control plane / data plane), the four locked decisions (credential distributability, /mcp outlet narrowing, on-demand daemon, uniform stdio MCP), and the C1โ€“C6 scope.
  • Design: design-phase-8-client.md โ€” data model (Machine/AgentInstance/Job/AcSession), the Socket.IO-over-WSS realtime protocol (bidirectional role namespaces /ctl daemon + /app browser, event catalog, rooms, isolation layers; daemon as protocol-adaptation edge), the MCP shim process model + dial-site routing derivation, jobs/deploy, inventory/diff/import, ACP chat, security model, and the per-phase development plan.
  • Design C1: design-phase-8-c1.md โ€” the shipped C1 plan: machines storage + migration 0006, machine PATs (machine-ctl, REST-rejected), realtime v0 (/ctl handshake/hello/presence + /app push), /api/machines CRUD, hnx enroll/hnx daemon, the Machines web page, and the verification matrix (unit + integration + smoke [8 C1]).
  • Design C3: design-phase-8-c3.md โ€” the shipped C3 plan: daemon per-target scanners (claude-code/codex/hermes), normalized snapshots over /ctl (inventory:scan|report|collect|payload), latest-per-(machine,target) storage (migration 0008), the pure profile diff, and one-click import (reuse-or-create resources + McpServer rows + a new profile) with daemon-side secret redaction.
  • Design C4: design-phase-8-c4.md โ€” the shipped C4 plan: the Job state machine (queue/dispatch/ack-timeout sweep/disconnect recovery with attempt caps), remote deploy reusing the unchanged 3.3 pipeline via a machine-PAT deploy-bundle fetch, AgentInstance upserts, and the MachineDetail deployments UI.
  • Research C5: research-phase-8-c5-acp-web-demo.md โ€” the web-vibecoding-demo reference (browser โ†” portal โ†” acp-bridge โ†’ DSH): ACP as the chat payload dialect, permission optionId passthrough, session-op mutual exclusion, cancel watchdog, reconnect re-registration, the fold/StreamBuffer streaming model, and fs/terminal channel boundaries. First filled row of the C5 adapter matrix (DSH).
  • Design C2: design-phase-8-c2.md โ€” the shipped C2 plan: the normative dial-site ร— distributability matrix, migration 0007, the mcp-runtime UpstreamPool extraction (stdio included), the client-config API contract (machine-PAT exception + secret-leak rules), the hnx mcp serve stdio shim, install-adapter shim entries + the Codex adapter, and emitter emitMode (client default / server fallback).
  • Research C5: research-phase-8-c5-acp-web-demo.md โ€” the ACP web-demo reference study (chat dialect, permission/session pitfalls, fold/StreamBuffer) + the completed per-target ACP adapter matrix (claude-code/codex via official Zed adapters, hermes native, zcode deferred).
  • Design C5: design-phase-8-c5.md โ€” the shipped C5 plan: the chat:* wire protocol + ACP dialect schemas, the semantic ChatStreamEvent stream, AcSession audit rows (migration 0010, no FKs), ChatService gating/watchdogs/teardown, the daemon's ACP adapter subprocess table + JSON-RPC/stdio client, and the /chat web UI.
  • Research T1: research-phase-8-t1-deepseek-harness.md โ€” DeepSeek Harness (dsh) ground truth pinned to v0.1.2-rc.1: the ~/.dsh home + home-level cordis.patch.yml (applies to every profile, hot-reloads), the Agent-Skills format with mandatory frontmatter, dsh-mcp-client MCP rows, hook bridges/subagent providers (why they're skipped), and the native dsh --profile acp server.
  • Design T1: design-phase-8-t1-deepseek.md โ€” the shipped T1 plan: the deepseek target end to end (install adapter with frontmatter synthesis + marked-region patch surgery, C3 scanner, C5 ACP row, C4 deployability), the T-wave numbering decision (supersedes the 3.8 "other agents" bucket), the supported-harnesses list, and the registry-resilience fix the T1 smoke surfaced.

Phase 9 โ€” Harness runtime lifecycle ๐Ÿงช designed

  • Research: research-phase-9-harness-runtime.md โ€” ground truth for managing the harness software itself: per-CLI install methods (claude native/npm/brew incl. channel + auto-updater interference, codex npm/brew, dsh npm), --version shapes, install-method detection by bin path, and each harness's native provider/key config slots (CC settings.json env, codex config.toml + auth.json, dsh dsh-llm-pi-ai patch rows + apiKeyEnv).
  • Design: design-phase-9-harness-runtime.md โ€” Agent-first runtime arm on the inventory payload (the Agent is the primary object; items nest under it), AgentInstance (source: 'detected') auto-registration so any detected Agent is chatable (closes the emitter claude-code gap), capture-as-profile for default state, harness job type on the C4 pipeline (install/upgrade/pin), RuntimeConfig entity (migration 0011) referencing distributable credentials, per-target native config writers, redacted runtime:config.get viewing, waves W1โ€“W4.
  • Research W6: research-phase-9-portal-chat-ui.md โ€” the portal half of the ACP reference (~/acp-ref/portal/): session list grouped by cwd, the row-sequence fold model (user/assistant-step/tool/system/turn-tail), the disclosure tool-card registry + Read/Diff/Terminal/Search/Io blocks, and stick-to-bottom scroll policy.
  • Design W5+W6: design-phase-9-portal-ui.md โ€” the shared FormDialog modal container (create flows off the list pages) and the portal-style chat rebuild: Agent cards โ†’ session page, machine baseWorkspace + daemon-routed workspace:list directory picker, AcSession.cwd/title (migration 0013), the enriched acpToolCallView wire (toolName/rawInput/content/output), and the Signal-styled stream components.
  • Design W7: design-phase-9-w7-native-sessions.md โ€” native agent sessions (list + resume, NO platform session store; migration 0014 drops ac_sessions), the one-shape history wire with three producers, and the post-ship ยง "dsh live streaming" addendum (transcript-file tail streaming, daemon 0.10.1-p9w7).
  • Design W7.1: design-phase-9-w7.1-dsh-event-tap.md โ€” the in-process dsh cordis-plugin event tap (spawn-time --patch insert of a zero-dep plugin streaming the session/event bus back to the daemon over localhost JSON-lines), now the PRIMARY dsh streaming source with the file tail as fallback; daemon 0.11.0-p9w7.1; rig A/B numbers and the resolved implementation decisions in ยงPost-ship notes.
  • Design W8: design-phase-9-w8-sender.md โ€” shipped: the chat Sender (composer) upgrade โ€” a card-style two-row input (autogrow textarea, context-usage meter, circular send/stop toggle) shaped after the reference composer but styled per Signal, with zero wire changes; attach / permission-mode / model / effort controls enumerated as deferred stubs with the wire arms each needs. Also records the claude-acp-bridge reference-code adoption notes and the post-ship finding that the @agentclientprotocol claude wrapper reports context occupancy too.
  • Research W9: research-phase-9-w9-composer-controls.md โ€” the deferred Sender controls, grounded: ACP's standard session-config surface (modes/configOptions + session/set_mode/set_config_option + the two push updates) verified against claude wrapper 0.76.0 / codex-acp 0.16.0 / dsh 0.1.2-rc.1 (support matrix incl. per-adapter image-prompt admission and OPAQUE option values), the portal reference's optimistic-switch pattern, our wire gaps per layer, and a phased A/B/C plan (config selectors โ†’ image attach โ†’ @ file mention).
  • Design W9: design-phase-9-w9-sender-controls.md โ€” shipped: the three A/B/C wires โ€” session_config stream events (daemon-merged snapshots in the history ring) + chat:config.set + promptCapabilities on ready; the image prompt block with browser-side downscale and the +/paste/drag attach paths; the workspace files arm + FilePicker behind resource_link chips. Post-ship notes carry the rig E2E (real claude wrapper: selectors round-trip, vision verified, Read-tool file reference).
  • Design W10: design-phase-9-w10-llm-providers.md โ€” shipped: LLM provider management (cc-switch-inspired) โ€” the LlmProvider entity (migration 0015, three api kinds openai-chat/openai-responses/anthropic, per-Agent support matrix, credential-referenced keys), server-side model-list discovery (POST /api/llm-providers/query-models, the platform's second outbound HTTP surface), the provider-first machine page flow, and multi-model via RuntimeConfigSpec.models (dsh's native per-provider list; ground truth for codex/claude-code inside).
  • Design W11: design-phase-9-w11-adapter-lifecycle.md โ€” COMPLETE โ€” A + B + E + C + D + D6 shipped: B = channel snapshot + tab bar + ไธ€้”ฎๆธ…็† (server+web, hardened same-day: mount-sync catch-up, opens never close other channels, USER-scoped liveness so one window's refresh never kills another window's tabs) โ€” chat:channels per-user snapshot pushes with channels.sync, the live-channel tab strip on both chat pages, and chat:channels.closeAll (idle now, mid-turn deferred). A = the daemon adapter pid ledger (~/.hnx/adapters/, entry written at spawn inside AcpAgentConnection.start, kill paths never unlink โ€” audit/sweep own removal, boot sweep in runDaemon, initialize-failure kill; daemon 0.13.0-p9w11). E = disconnect grace + reconnect reconcile โ€” a /ctl transport blip no longer kills every channel (daemon HN_TEARDOWN_GRACE_MS + server CHAT_RECONNECT_GRACE_MS, both default 8000/=0 off; chat:reconcile {sessionIds} โ†’ daemon ack {held} โ†’ server retainOnly on every (re)connect; deliberate closes bypass the grace; daemon 0.14.0-p9w11). C = the adapter-process report (GET /api/machines/:id/adapters over adapters:report, instant daemon-side from the live sessions map) + the MachineDetail ้€‚้…ๅ™จ่ฟ›็จ‹ panel with the owner-or-admin ็ปˆๆญข path (daemon 0.15.0-p9w11; /ctl presence registration hardened synchronous along the way). D6 resolved 2026-09-15: lastActiveAt on the snapshot + 30-minute idle-age tab labels + the ๅชๆธ…็†้—ฒ็ฝฎ variant of the broom + CHAT_IDLE_TTL_MS (default off), plus two user-found fixes (resume-dedupe while establishing; closing the current channel returns the pane to its welcome state). D = the daemon-side sessions:list TTL cache (SESSIONS_CACHE_TTL_MS default 15s โ€” hits skip the adapter spawn; ?refresh=1 from the rail's manual refresh bypasses; failures never cache; concurrent requests share one spawn; daemon 0.16.0-p9w11).
  • Design W12: design-phase-9-w12-opencode.md โ€” shipped: OpenCode (SST) as a runtime-managed Agent, full surface โ€” RUNTIME_TARGETS/AgentTarget/SCANNABLE_TARGETS + harness npm jobs (opencode-ai) + native opencode acp chat row + applyOpencodeConfig (provider block + /v1-normalized baseURL + {file:} 0600 raw key) + wholesale-redacted key viewer + the ~/.config/opencode scanner (external ground truth in research-phase-9-w12-opencode.md; daemon 0.17.0-p9w12; hermes later cancelled 2026-09-17).
  • Research W13: research-phase-9-w13-multi-model-picker.md โ€” feasibility of making the session model dropdown list ONLY usable (gateway-servable) models, source-verified per adapter: claude-code via the native availableModels settings allowlist (wrapper synthesizes unknown ids verbatim), codex via a daemon-side option rewrite (set_config_option accepts raw ids; no config seam exists), opencode via an harness-nexus/-prefix filter (its registry already contains our W12 models map), dsh already shipped in W10. Recommended surface: one writer key + one daemon rewrite + one server open-hint; zero schema/web changes.
  • Design W13: design-phase-9-w13-multi-model.md โ€” shipped: the multi-model picker โ€” claude-code writer availableModels allowlist, daemon-side model-option rewrite for codex/opencode at all four admission points (establishment / live push / capture history; idempotent, empty-intersection and out-of-picker currentValue semantics), the chat:session.start modelOptions hint from the stored RuntimeConfig, deepseek untouched (W10). Daemon 0.18.0-p9w13.
  • Research W14/W15: research-phase-9-w14-w15-plan-commands.md โ€” source-verified ground truth for the ACP plan (todo) snapshots and available_commands_update catalogs across the four shipped adapters: claude-agent-acp converts TodoWrite/Task* EXCLUSIVELY into plan updates (tool calls suppressed) and pushes a rich command catalog; codex-acp maps update_plan + a builtin command list; opencode pushes Command.Info; dsh emits neither. Also: no command-invocation RPC exists (a command is a /name args prompt), and the draft subagent protocol (PR #1992) is deliberately not adopted.
  • Design W14: design-phase-9-w14-plan-todo.md โ€” shipped: the plan/todo panel โ€” a plan stream kind (full-replace snapshots, bounded), a stateless daemon arm, fold-carried state, and the TodoPanel above the composer (progress summary, status glyphs); plus the wave's verification deliverable (permissions E2E on claude/opencode, subagent Task-card path; rig truth: codex is the live plan producer today, claude's task lane dormant on CLI 2.1.263). Daemon 0.19.0-p9w14.
  • Design W15: design-phase-9-w15-commands.md โ€” shipped: slash commands in the composer โ€” a commands stream kind (the agent's advertised catalog, bounded), the /-prefix palette (first-word filter, โ†‘/โ†“ cycle, bare Enter selects + fills /name , Enter-with-args sends as a normal prompt), no fallback table (honest absence for dsh/hermes); platform-deployed plugin commands surface through the agent's own catalog. Daemon 0.20.0-p9w15.
  • Research W14.1: research-phase-9-w14.1-claude-ground-truth.md โ€” the post-W14 re-verification of the ask-user/plan surface, probe-driven: the three-layer matrix (native / ACP adapter / portal โ€” claude is the ONLY target with an adapter-side elicitation bridge), the discovery that portal claude sessions run the SDK-BUNDLED CLI (2.1.270, not the native 2.1.263), tool-existence probes (TaskCreate/TodoWrite/AskUserQuestion per env), the raw elicitation/create wire capture (top-level method, form mode, oneOf-const schema, the AskUserQuestion mapping), and the CLAUDE_CODE_ENABLE_TODO_TOOLS=1 revival that made plan snapshots flow E2E. Also corrects the W14 "claude dormant on 2.1.263" attribution.
  • Design W14.1: design-phase-9-w14.1-claude-elicitation.md โ€” shipped: Ask User for claude channels โ€” daemon advertises elicitation.form + answers the top-level elicitation/create request (bounded field view via takeElicitationView; empty fields = message-only decline/cancel card), server relays the two stream kinds + watchdog + chat:elicitation.respond routing (permission lifecycle mirrored; values verbatim as ACP content), web question cards (enum radios / multi checkboxes / text / number / boolean, required gating, settled cards vanish), plus the companion claude todo/plan revival via the adapter env (url-mode elicitation deliberately NOT advertised). Daemon 0.21.0-p9w14.1.
  • Research W16 (feasibility, not scheduled): research-phase-9-w16-pi-agent.md โ€” onboarding pi (@earendil-works/pi-coding-agent; the old @mariozechner scope is deprecated) as a runtime-managed Agent, verified against pi.dev docs + npm manifests: npm arm + Node โ‰ฅ22.19 engine, JSON-only W3/W4 surfaces with pi's api enum covering ALL THREE of our provider api kinds (first 1:1 target; !command apiKey syntax gives the 0600-keyfile pattern), plain-JSONL W7 sessions scan, no native ACP (chat = a daemon-side ACPโ†”pi-RPC bridge; community pi-acp 0.0.x as dialect reference), profile deploy partial (Agent-Skills-standard skills + prompt templates; MCP is extension-based โ€” no declarative surface; hooks/sub-agents are TS code). Companion decision recorded in the roadmap: hermes runtime management cancelled (2026-09-17).
  • Design W16: design-phase-9-w16-pi-agent.md โ€” shipped: pi onboarding with the SELF-DEVELOPED in-daemon ACP bridge โ€” the AgentConnection surface extraction (chat.ts is now dialect-agnostic) + PiRpcConnection (ACP requests โ‡„ pi --mode rpc JSONL; prompt responses HELD until agent_settled; \n-only line codec; rig-captured dialect: payload under data, deltas under assistantMessageEvent), npm runtime arm + Node โ‰ฅ22.19 warning, the W3 writer (!cat 0600 keyfile, baseUrl verbatim) + W4 files, the JSONL sessions rail + leaf-chain replay parser, the deploy adapter (skills/prompts) + scanner, and the W13 harness-nexus/<id> model-option intersect. Rig E2E: install 0.85.1 โ†’ detected card โ†’ provider push (headless PONG) โ†’ masked viewer โ†’ rail rows โ†’ streamed turn (W16OK) โ†’ live model switch to doubao. Daemon 0.22.0-p9w16.
  • Design #10 (live Sender): design-live-sender.md โ€” shipped: mid-turn config writes unlocked (web-only; server+daemon always forwarded them) + the SERVER-owned send queue (depth 1): queue_state stream event (server-emitted only, flushed distinguishes run-clear from cancel-clear), busy sends park into a chip above the composer (QUEUE_FULL beyond one), the busyโ†’idle transition flushes (chip โ†’ fold user row โ†’ forwarded prompt), chat:queue.cancel (edit = cancel + take-back-to-draft), turn cancel drops the slot, reattach replays it; daemon UNCHANGED. Rig E2E: selects live mid-turn, ๆŽ’้˜Ÿๅ‘้€+ๅœๆญข coexist, auto-flush verified end-to-end.
  • Research #10 (live Sender): research-live-sender.md โ€” source-verified per-target ground truth for mid-turn interaction: prompt-while-busy is QUEUED natively by claude-agent-acp (turnQueue), steer-joins at opencode, REJECTED by dsh (-32602) and by OUR pi faรงade; codex 0.16.0 has no rejection path (queued inferred); mid-turn config writes are accepted by every target (claude pushes to the live query, the rest pin per-prompt/next-turn; dsh+pi have NO permission modes) โ€” and the ACP spec leaves all of it implementation-defined while requiring set_mode/config to be callable "whether idle or generating". Baseline conclusion: unlock the selects now; queue in the DAEMON (uniform across targets), not client-side.

Concept notes (design/)

Decisions (adr/)

Issue-era designs (issue-driven workflow, 2026-09 onward)

New work is anchored on GitHub issues (see the repo's CONTRIBUTING.md); these are the durable design docs that came out of it.

  • Design: design-fast-session-pipeline.md โ€” issue #2, shipped: pinned adapter provisioning (~/.hnx/acp-adapters, npx fallback, kill switch), the idempotent dist patch set (skip-redundant-setmodel-on-resume on the claude wrapper), and live-channel listings (liveConnectionFor). Rig: claude listing 2.7s โ†’ 0.13s, resume-open 6.1s โ†’ ~1.2s.
  • Design: design-adapter-prewarm.md โ€” issues #3โ€“#4, shipped: the per-target, machine-scoped adapter pre-warm pool (machines.chat_prewarm, strict replace-semantics map; pool holds ONE initialized adapter per target, consumed on open, idle TTL 120s, dsh tap armed at prewarm time). Rig: dsh 1.5s โ†’ 59โ€“206ms, codex 2.3s โ†’ 199ms, claude 1.2s โ†’ 666ms, opencode 2.5s โ†’ 846โ€“887ms.
  • Design: design-ui-system.md โ€” issue #23, shipped: the console's design system as a durable contract โ€” the thesis (structure belongs to the base, materials to the skin; four extension points), the one content principle (protocol material on a Well, prose in prose; the dataโ†’device mapping table; numbers never lie: numerator/denominator + a qualifier; the accent budget of one live thing per screen), the shell geometry (30px spine + 168px plate + 56px chrome bar + readout strip; page identity in the chrome; no ruler column; below 900px drawer + navstrip), the type roles (--app-font-label, uppercase only in the label role, mono + tabular for all data), and the interaction language (four state surfaces, two-level confirmations with one name throughout, overlays designed on panel materials, four sanctioned motions + reduced-motion final states, pinned row-action column on phones with tap targets as hit AREAS). Also how a page plugs into the shell (one route declaration in nav.ts, usePageTitle + PageSlot for identity/actions/margin, the shell owns scrolling unless layout: 'panes') and the five page recipes (list / resource-kind / detail / chat / overview). Points to the skin doc for the skin axis.
  • Design: design-skin-system.md โ€” issue #23, shipped (Signal + BAY; LEDGER/NIGHTWATCH deferred): the two-axis theme model (next-themes mode axis + data-skin skin axis with pre-paint script and hnx.skin storage), the frozen token contract (scrim, inverted-surface wells, runtime font hooks --app-font-*, plus P7's density/material/lamp set), the status device (Lamp, with StateSignal as the inline mark sharing one lamp-body slot โ€” D-13), the full hook vocabulary a skin may depend on (data-region/data-slot/data-state/data-tone/data-variant/data-nav-group/data-bay-number/data-live/data-density, plus the empty marginalia slot) and the rule that an opt-out must be a variant the skin can read, the control scale (--control-h*, --row-ctl-h = "the skin's small control, never taller than the row that holds it", --touch as a hit AREA not a bigger box), addresses & navigation (English uppercase bay addresses engraved from data โ€” label vs the translated labelKey โ€” the 30px vertical spine, the navstrip phone jump bar carrying every destination, PageAction shrinking to its icon below sm), and the rule that bands and lists are composed from kit devices, never hand-rolled (the session rail, the Sender's baseline toolbar). Topology registry (constellation / plate / radar, all real), the two hard skin rules as test assertions, and the scripts/ui-snap.mjs snapshot rig (single-mode skins skip the locked mode). Layout skeleton never changes.
  • Design: design-cc-marketplace-deploy.md โ€” issue #6, shipped: claude-code profiles deploy ONE-CLICK from the machine page through the 3.5 emitter โ€” the daemon drives CC's own plugin CLI (marketplace add/update + install-or-update, state read from CC's JSON files, never CLI text); the emitter accepts machine-ctl PATs (no secret in the job payload); profile.version became editable (the publish switch โ€” CC compares versions); the web Edit dialog covers name/description/version + entry re-picking. Rig: deploy + one-click update 1.0.0โ†’1.1.0 verified.
  • Design: design-admin-scope.md โ€” issue #36, shipped: personal resources are owner-ONLY for every role (machines, jobs, inventory, workspace, runtime-config, credentials, mcp-servers, profiles, resources, llm-providers โ€” 404 existence-hiding, admin included); an admin's extras are exactly user management, the registration switch, and global-row create/modify (canManage); posture is all-self, the realtime admins room is gone.
  • Design: design-version-surfacing.md โ€” issue #37, shipped: build versions everywhere โ€” hnx --version, daemon reports its real package version (the invented 0.25.0-i6 is dead), server exposes GET /api/system/info reading shared's lockstep manifest, hello ack carries serverVersion; skew WARNS (web chip + daemon line), proto stays the gate; shared gained compareVersions.
  • Design: design-client-logbook.md โ€” issue #38, shipped: the daemon's local logbook โ€” ~/.hnx/logs/ops.log (operation trail) + comm.log (metadata-level /ctl traffic, chat:event bursts aggregate to one summary line, connect/disconnect markers; HNX_LOG_COMM=payload is the debug-only escape hatch), hard rotation 256KBร—3 / 1MBร—5, hnx logs [--tail|--bundle]. Built as a ring-buffered BUS with file sinks as subscribers โ€” the groundwork for the TUI (#39).
  • Design: design-cli-tui.md โ€” issue #39, shipped: hnx tui โ€” the daemon's live console (daemon in-process via startDaemon + a zero-dep nmon-style stacked-band renderer): metrics bar, agents/sessions pane (sessionsSnapshot + prewarmStatus), ops pane (bus op/log entries; console captured while the TUI owns stdout), comm pane (its own CommAggregator โ€” same burst collapse as the file), and a per-(target, model) token pane (UsageLedger; the usage event gained dialect-normalized cacheReadTokens/cacheWriteTokens). Single-daemon pid lock (DAEMON_LOCKED โ€” two /ctl sockets would double-run jobs). --dump/non-TTY โ†’ one-shot snapshot.
  • Design: design-dsh-client-version-gate.md โ€” issue #46, shipped: fast-moving Agent clients get NO back-compat โ€” the daemon integrates ONE ground-truth line (dsh 0.2.0-rc.2) and the connect path REFUSES out-of-range clients with an upgrade hint (adapters.ts minVersion floor + acp/version-gate.ts probe of <bin> --version; enforced at channel open BEFORE any spawn and at prewarm; HN_ACP_COMMAND_<TARGET> overrides stay ungated). Rides the same issue's session-log v4 rewrite (W7 #46 addendum) and tap v2 (W7.1 #46 addendum).
  • Design: design-service-layer.md โ€” issue #53, shipped (17 slices; blocks-unlocks #52): principal-carrying services in packages/server/src/services/ โ€” the single authorization enforcement point (#36 rules move INSIDE services; routes thin to authenticate โ†’ parse โ†’ service โ†’ reply; Principal = {userId, role} is an explicit parameter; AppError-only failures; Fastify-free, no env, realtime dispatch stays at routes). One slice per module, assistant-relevant first (resources โ†’ skills-hub โ†’ machines โ†’ system โ†’ โ€ฆ); closes only at FULL extraction (the point is consistency โ€” no permanent mixed state). Route tests pass unchanged through every slice = the regression net.
  • Design: design-provider-model-registry.md โ€” issue #51, shipped: model configs live ON the LlmProvider row (models: ProviderModelConfig[], JSON column) โ€” regular (id, type chat|embedding, displayName, contextWindow, maxOutputTokens, vision) + advanced (temperature, topP, serverTools for openai-responses, extraBody for openai-compatible); query-models demoted to a seeding button inside the provider dialog ONLY; consumer forms (runtime-config, assistant) pick from the registry โ€” one-shot cutover, no dual-track; spec snapshots become full model objects so applyPiConfig writes real contextWindow/maxTokens/name (usage contextSize unhides); advanced params apply per-consumer capability, stored-but-unused is never faked.
  • Design: design-platform-assistant.md โ€” issue #52, agreed (depends on #50+#51): a server-embedded pi-agent-core/pi-ai assistant operating the platform AS the user โ€” identity via an AsyncLocalStorage actor context feeding the root auth hook (fresh user lookup per call, viaAssistant audit marker, NO minted tokens; unforgeable from outside the process); tools = app.inject() against our own REST surface behind beforeToolCall group gates + audit rows; no delete/credential tools in v1; MCP reuses the server-side McpRegistry pool; skills inject as prompt index + read_skill (progressive disclosure); sessions are platform-owned (explicit W7 counter-exception) with pi state rebuilt per turn; streaming rides /app rooms with a new assistant:* family reusing ChatStreamEvent shapes; Chat page gains a pinned-first assistant ็ซฏ (dropdown at the old back-link, star-pinned default ็ซฏ, sender Agent+Model selects with next-turn effect); per-user multiple named assistants with a DataTable+FormDialog config page.
  • Design: design-session-delete.md โ€” issue #55, shipped (Phase A): session deletion on BOTH rails โ€” platform assistant rows (REST delete + live guard + owner push) and native agent rows (DELETE /api/agent-instances/:id/sessions/:sid โ†’ sessions:delete over /ctl, new daemon capability bit sessions-delete). Per-target arms: ACP session/delete (claude-code yes; opencode only โ‰ฅv2.0.7, capability-gated; codex rides the CLI's own codex delete --force โ€” rollout-file truth for idempotency, never unlink), dsh rm-rf of the <sessionId> dir, pi unlink (both idempotent). Live channels refuse (close first, both ends). Web: shared SessionRow (desktop hover trash + phone SwipeRow swipe-left, zero-dep) + kit ConfirmDialog.
โš ๏ธ **GitHub.com Fallback** โš ๏ธ