Repository navigation
feat: build daemon command registry from descriptors, delete the hand table — Phase 1 step 2 - #907
Conversation
Size Report
Startup median (7 runs, lower is better):
Top changed chunks:
|
|
Current blocker: Layering Guard is failing, and the failure is real rather than flaky. The job reports two forbidden daemon-to-commands imports in
This is the same architecture issue from #906: if the descriptor registry is meant to become a root consumed by daemon, it cannot live in the current |
|
Good catch — addressing the layering decision before going further, taking option 1. I'm relocating the shared descriptor registry + projections out of
Relocating across the stack (#906 → #907 → #908), re-running the Layering Guard ( |
97b88ff to
0acefbf
Compare
95ce046 to
271b173
Compare
|
Both blockers addressed. Layering fix: relocated the descriptor registry to iOS smoke (booted iPhone 17 Pro, source build of the #908 tip — the genuinely behavior-relevant checkpoint since the daemon registry + capability matrix now derive at runtime):
No regression — the derived |
… table — Phase 1 step 2
271b173 to
b0368aa
Compare
|
…ntees (#2779) `commandDescriptors` claimed to be "proven byte-equal to the live hand tables by `__tests__/parity.test.ts`". Neither operand survives the ADR 0008 migration. The test is now `src/__tests__/command-descriptor-parity.test.ts` (moved by 2ec4e91 #2348); the tables it compared were deleted by the PRs that inverted them (47abc8c #907 daemon routes, 96bc7b1 #908 capability matrix, retired by ea1d6b8 #2089, 607883d #909 batch allowlist, 8ef4e73 #1137 MCP exposure); and TIMEOUT_POLICY_BY_COMMAND, DEVICE_CLAIM_POLICY_BY_COMMAND and COMMAND_DESCRIPTOR_BY_NAME are folds over this array, so byte-equality has no second operand. Record the invariant that does hold and name the check that carries each part, so a future split of this file preserves them. Established by mutation, not by reading: duplicating a descriptor fails owner-files.test.ts, command-descriptor-parity.test.ts and device-claim-policy.test.ts, while renaming one lands on the literal pins (targetIdentityVerification, the timeout and device-claim deviating sets). No new completeness test was owed here, and the compile-time totality guard already covers required traits. Same repair for the `frameworkTier` and `targetIdentityVerification` "the parity test" pointers, the two `@internal Introspection helper used by parity tests` docblocks (whose real consumers are command-descriptor-parity.test.ts and command-surface-metadata.test.ts), the "additive single source" banner that still listed the retired capability facet, and the CommandDescriptor intro, which described the deleted tables as "today" and cited `app-switcher` as unrouted after ADR 0014 gave it a daemon facet.
…ecord the descriptor-root block (#2808) * docs(adr): retire the parity-gate claim, state press-shape refusal, record the descriptor-root block ADR 0008 still promises a class of check that no longer exists. The parity test its migration rule required lost its second operand as each hand table was inverted out (#907, #908, #909, #1084, #1137); the retirement is recorded in Status and the present-tense claims are corrected, while the migration rule itself is left intact because it was followed. ADR 0019 gains the rule that a shape of an operation is not an operation and gets no fact cell, which is what a per-shape refusal on the owning leaf mechanic rests on. ADR 0027 records, without deciding, the conflict that makes the descriptor root unshippably splitable: ADR 0008's synchronous hub and the ADR-0019 eager-closure module-count budget have no shared approval path. Measured: any decomposition of the root, even the smallest, grows eleven entry surfaces. * docs(adr): propose one runtime source for the capability-family cell vocabulary Adding an operation family edits the cell key twice in one file: once as a property of UnavailablePlatformRuntimeFacts and again as a value in UNAVAILABLE_CELLS, which cannot be derived from the type. satisfies makes drift a compile error, so this is a maintenance tax rather than a soundness hole -- but it is why a file with fan-in 6 churned 9 times in 200 commits, and why one capability still fans out across eight packages. Proposes the inversion the repo already proved on the binding axis (INTERACTOR_OPERATIONS) for the facts axis, and states what it deliberately does not grant: no default-deny baseline, because ADR 0019 requires exhaustive per-shape facts and forbids cross-family defaults in a platform package. Gated on a measurement and on eager-closure neutrality, with withdrawal as an acceptable outcome. * docs(adr): point ADR 0027 at the pushed, recoverable descriptor split
What
Phase 1 step 2 of the command-descriptor migration (ADR-0008), stacked on #906 (
feat/command-descriptor-registry).The daemon command registry now builds from the derived descriptors instead of a hand-authored literal:
src/daemon/daemon-command-registry.ts— replaced theDAEMON_COMMAND_DESCRIPTORSarray literal (plus its privatedescriptor/descriptorsbuilders and theisRecordingStartRequest/isShardedTestRequestclosures, now living indescriptor/registry.ts) with:DaemonCommandDescriptortype, the predicate accessors, andbuildDaemonCommandRegistryare unchanged and consumeDAEMON_COMMAND_DESCRIPTORSas before.src/commands/descriptor/__tests__/parity.test.ts— the slice-1 DAEMON parity assertion would now be a tautology (derived-vs-derived), so it was replaced with an invariant assertion: no duplicate command names, every descriptor has a route, and the derived command set still covers every public command (minus the two intentionally unroutedapp-switcher/install-from-source). The capability-matrix and batch-name parity tests are kept as-is (those hand tables still exist for later slices).Behaviorless
The daemon registry's routes + request-policy traits are identical — #906's parity test proved
deriveDaemonCommandDescriptors(commandDescriptors)is byte-equal to the deleted literal. No predicate accessor or consumer changed.Cycle check
No runtime import cycle:
daemon-command-registry.ts(value) →descriptor/derive.ts+descriptor/registry.ts(values); the back-edges fromderive.tsanddescriptor/types.tsto this module'sDaemonCommandDescriptorare type-only imports, erased at runtime.tsc --noEmitis clean (exit 0) and a runtimeimport()of the module loads cleanly (57 descriptors).Verification
tsc -p tsconfig.json --noEmit: exit 0oxfmt --write+oxlint --deny-warningson changed files: exit 0vitest run daemon: 94 files, 902 tests passedvitest run commands/descriptor: 1 file, 5 tests passedStacked on #906 — merge that first.