Repository navigation
refactor: sink backend.ts's cycle-closing types; shrink the 76-file R9 cluster #1632
Description
From the 2026-08-06 architecture review (claims re-verified against current code; direction explicitly sanctioned by the #1478 checkpoint note in CONTEXT.md).
Problem
The R9 type-only cycle baseline still pins a 76-file cluster (commands 33, daemon-server 20, core 10, platforms 7, (root) 5, client 1 — scripts/layering/daemon-modularity.ts:5-12). CONTEXT.md calls it "the largest single obstacle to reading a subsystem in isolation": inside the cluster, no file has a self-contained slice.
The hubs (CONTEXT.md, by in-component dependents): runtime-contract.ts (25), commands/runtime-types.ts (21), backend.ts (15), commands/runtime-common.ts (12).
The concrete defect shape, verified at the anchor hub: src/backend.ts (612 LOC, 57 exports, the AgentDeviceBackend interface) imports its own parameter types up from the zones that depend on it:
src/backend.ts:32—import type { RepeatedInput } from './commands/command-input.ts'(root ← commands zone)src/backend.ts:33—import type { ScreenshotResultData } from './utils/screenshot-result.ts'
So the interface hub sits inside the cycle it anchors: commands-zone files type-import backend.ts back (10+ importers), daemon-server-zone files likewise (5+).
Proposed direction
Move the cycle-closing type declarations down into the kernel/contracts packages the spine already ranks at the bottom. This is R6's own prescribed remedy, verbatim from the checker: "Declare the shared type below both zones instead of adding it to TYPE_INVERSION_BASELINE." Mechanical type moves, no runtime change; lower the R9/R10 zone ceilings as members drop out (the gate reports a shrunk tree as success).
Suggested order: start at backend.ts's two upward imports (cheap, anchor-freeing), then re-measure the cluster before touching the runtime-contract.ts / runtime-types.ts hubs — each sunk declaration can strand multiple members.
Scope guards
- This is sanctioned, not contested: the refactor(daemon): extract replay, Maestro, and replay-test modules #1478 checkpoint (2026-08-04) deferred the P6 platform phases and named the command-registration hubs as the remaining R9 work (CONTEXT.md:331-334).
- No new façade/package is scaffolded — types sink into
packages/kernel/packages/contracts, which already exist with multiple consumers ("boundaries are earned" norm intact). - The 7 remaining R6 type-inversions are documented deliberate positions (AgentDeviceClient opaque handle ×4, ADR 0003 daemon descriptor ×3) — do not "fix" those as part of this.
- Public wire contracts unchanged (
PUBLIC_PLATFORMSleaf output etc.).
Acceptance criteria
-
backend.tshas no imports fromcommands/orutils/ - R9 zone ceilings lowered to match the measured post-change cluster (never raised)
-
pnpm check:layeringgreen; noTYPE_INVERSION_BASELINEadditions - A one-line note in the PR stating the new cluster size, so the next review starts from measured reality
Activity
refactor: sink backend.ts's cycle-closing types below both zones (#1632…
Merge remote-tracking branch 'origin/main' into review-1617