Skip to content

feat(adr-0026): schema daemon CLI verb + runtime (slice 4b)#5

Merged
farchanjo merged 1 commit intomainfrom
feat/adr-0026-daemon-runtime
Apr 27, 2026
Merged

feat(adr-0026): schema daemon CLI verb + runtime (slice 4b)#5
farchanjo merged 1 commit intomainfrom
feat/adr-0026-daemon-runtime

Conversation

@farchanjo
Copy link
Copy Markdown
Owner

Summary

ADR-0026 slice 4b. The shared multi-project daemon now runs end-to-end against a registry. Production still defaults to ADR-0019 per-project units until slice 5 (template collapse) and slice 6 (canary E2E gate) ship.

  • schema daemon subcommand — no --config flag; reads Registry::default_path().
  • run_daemon: 1× FastembedEmbedder (the workstation-level ONNX baseline), env-driven LLM provider, Daemon::wire.
  • serve_daemon: bind 127.0.0.1:0, per-slot startup, multi-tenant router, axum::serve until SIGTERM, then cleanup every endpoint.toml.
  • startup_each_slot: initial delta-sync, spawn watcher, write endpoint.toml (url=http://127.0.0.1:<port>/mcp/<project_id>, token=slot's UUIDv4, mode 0600).
  • resolve_llm_provider_for_daemon: env-driven (SCHEMA_LLM_PROVIDER / SCHEMA_LLM_MODEL); the registry has no [llm] section by design (would conflict if two projects pinned different providers).
  • Templates / cli/install.rs untouched — slice 5's job.

Test plan

  • cargo clippy --all-features --all-targets --workspace -- -D warnings exits 0
  • cargo fmt --all -- --check clean
  • cargo test --all-features — 115 passed (110 unit + 5 integration); no regressions in single-project paths
  • schema daemon --help shows the new verb; schema --help lists it
  • No new dependency, no unsafe, no cache layout change, no embedding model change
  • ADR-0026 Evidence entry appended (closes arch-first loop)
  • CI lint job green on PR commit
  • Slice 5 (templates) and slice 6 (canary E2E) follow before flipping the operator-facing path
  • Real-runtime smoke (manual): start schema daemon against a 2-project registry, verify per-project endpoint.toml files appear with paths + tokens, hit /health and one /mcp/<project_id> route — deferred to operator's box (CI can't do localhost-bind reliably from a sandboxed runner)

🤖 Generated with Claude Code

…slice 4b)

ADR-0026 slice 4b: shared daemon now runs end-to-end against a registry.
Per-project ADR-0019 / ADR-0020 deployment still ships in production until
slice 5 (template collapse) and slice 6 (canary E2E gate) flip the
operator-facing path.

* `schema daemon` subcommand — no `--config` flag (the registry is the
  source of truth per ADR-0026 amendment to ADR-0020).
* `run_daemon`: load registry from `Registry::default_path()`, build one
  `FastembedEmbedder` (the ~1.7 GB BGE-M3 ONNX workstation baseline that
  ADR-0026 is built around), resolve the LLM provider from env
  (`SCHEMA_LLM_PROVIDER` / `SCHEMA_LLM_MODEL` / `*_API_KEY`), call
  `Daemon::wire`. Empty registry logs a warning but still serves /health.
* `serve_daemon` binds `127.0.0.1:0`, runs per-slot startup side effects,
  builds the multi-tenant router, runs `axum::serve` with the shared
  `CancellationToken` so a single SIGTERM drains every project's in-flight
  sessions in parallel, then unlinks every `endpoint.toml` it wrote.
* `startup_each_slot` for each `ProjectSlot`: runs initial delta-sync, spawns
  the per-project `NotifyWatcher` (ADR-0010), and writes
  `~/.cache/schema/projects/<project_id>/endpoint.toml` with
  `url = "http://127.0.0.1:<port>/mcp/<project_id>"` and the slot's UUIDv4
  bearer (still `0600` per ADR-0021). URL includes the project path so
  consumers can paste it directly into `.mcp.json`.
* `resolve_llm_provider_for_daemon` reads from env (`SCHEMA_LLM_PROVIDER`
  defaults to `auto`); the registry has no `[llm]` section because that
  knob is per-project today and would conflict if two projects pinned
  different providers. Daemon's shared provider is workstation-level by
  construction.
* Templates (`launchd.plist.template`, `systemd.service.template`) and
  `cli/install.rs` are untouched — slice 5 collapses them to a single
  workstation-level unit invoking `schema daemon`.

ADR-0026 Evidence and amendments entry appended for slice 4b including
follow-up scope (slice 4c hot-reload admin endpoint, slice 5 templates,
slice 6 canary E2E gate) — closes the arch-first loop per CLAUDE.md.

Strict-lint gate: cargo clippy --all-features --all-targets --workspace
-- -D warnings exits 0. cargo fmt --all -- --check clean. cargo test
--all-features 115 passed (110 unit + 5 integration; no new tests —
real-Embedder paths are exercised by slice 6 E2E).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@farchanjo farchanjo merged commit 45fddb7 into main Apr 27, 2026
1 check passed
@farchanjo farchanjo deleted the feat/adr-0026-daemon-runtime branch April 27, 2026 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant