refactor(core): move the command descriptor registry into its own workspace package - #2348
refactor(core): move the command descriptor registry into its own workspace package#2348thymikee wants to merge 2 commits into
Conversation
…kage The descriptor registry, its catalogs, and the two parsing leaves it owns (`wait-positionals`, `parse-timeout`) depended on nothing in root `src/`: their only imports are `@agent-device/contracts` and `@agent-device/selectors`. They were nonetheless the daemon's largest root coupling, and under R11 the reason the daemon client and the session event journal cannot become packages. They move as-is into `@agent-device/command-registry`, one exported subpath per module pointing directly at the moved source file, and every consumer switches to the owning specifier. No compatibility re-export stays behind at the old path. The `__OWNER_FILES__` build-flag declaration moves with its only consumer; the root program and the SDK examples include it from its new home. Six descriptor tests reach into root `src/` (daemon parity, ref-frame classification, the CLI-route coherence gate, the cross-surface post-action-observation gate, the timeout-policy gate, and the shutdown mechanics gate), which a package may not do, so they stay in root beside the other cross-surface suites; the rest move unchanged with their subjects. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016DkNZCMWtm1KUbseKANADi
The rules that name the registry by path follow it: R66's `COMMAND_DESCRIPTOR_MODULE`, R16's record-runtime join subject, and the Fallow `AssertTrue` totality-guard key. The two descriptor hubs leave `HUB_ENTRY_FILES` because the package manifest now publishes them — the eager-closure gate discovers them as facades, and one entry gets one rule. `command-registry` joins the ranked spine at rank 1, beside the contracts and selectors it depends on. Two illustrative paths in gate comments and a model test are re-pointed at root files that still exist. No `APPROVED_OVER_CEILING` row: rename detection carries every moved entry's merge-base baseline, so all twelve fall under the no-growth rule rather than a ceiling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016DkNZCMWtm1KUbseKANADi
|
Size Report
Startup median (7 runs, lower is better):
|
|
Android / Smoke Tests failed on The failing step is the live emulator orientation check in
This lane is also independently red on recent I have re-run the failed job once (my one allowed re-run). Every other completed check on this head is green: Lint & Format, Typecheck & Package, Integration Tests, Compatibility & Provenance, Bundle Size, Ownership and context budgets, command-docs-gate, CodeQL, and the other Smoke Tests lane. If the re-run fails the same way, that is evidence about the emulator lane, not this diff, and I will say so rather than change the PR to chase it. Generated by Claude Code |
Summary
src/core/command-descriptor/,src/command-catalog.ts,src/core/wait-positionals.tsandsrc/core/parse-timeout.tsimported nothing from rootsrc/, yet were the daemon's largest root coupling. They move as git renames into a new private package@agent-device/command-registry(deps: contracts, selectors), one subpath per module pointing straight at the moved file; noindex.ts, no re-export at the old path. Every consumer — daemon, commands, mcp, cli, cli-schema, core, root, client, ai-sdk, scripts, tests — switches to the owning specifier; contracts is untouched. Six descriptor tests that import rootsrc/stay there, which a package may not do; the rest move unchanged. The__OWNER_FILES__declaration moves with its only consumer. Enforcement edits are the finalchore(gates)commit; noAPPROVED_OVER_CEILINGrow, since rename detection carries each entry's merge-base baseline.Rename-only proof —
git diff -M90% --stat origin/main...HEAD:217 files changed, 421 insertions(+), 320 deletions(-); 42 renames, all 12 moved sources at 92–100%.Closes #2336.
Validation
pnpm check:affected --runat e18aa8f: format, lint, typecheck, layering, di-seams, fallow, mcp-metadata, build, package, integration-node, macos-coverage green. vitest-related: 9714 passed, 3 failed —durable-capture-resource, capture-kitadoption,app-log-session-resource. All three assert achmod 0500directory is unwritable, which uid 0 ignores, and fail identically onorigin/mainhere.Daemon → root
src/value edges 150 → 114 (−36, ceiling 118), both frompnpm depgraph(scripts/depgraph/build.ts): value edges fromdaemon/**into non-package, non-daemon nodes. Including type-only and dynamic edges: 174 → 134.Versioned CLI help is byte-identical: 82 sections (root help, 12 topics, 69 command usages) rendered from
src/bin.tsonorigin/mainand this head share one sha256.test/integration/smoke-cli: 5/5.🤖 Generated with Claude Code
https://claude.ai/code/session_016DkNZCMWtm1KUbseKANADi
Generated by Claude Code