refactor(contracts): move single-owner modules out of @agent-device/contracts
Summary
Closes #2339. Stacked on #2348 (child A) — base is claude/2336-command-registry-package, not main.
Nine modules leave @agent-device/contracts as git renames, no re-export shim at any old path. Contracts production source drops 18,218 → 16,993 lines (−1,225) across 190 → 180 files (find packages/contracts/src -name '*.ts' ! -name '*.test.ts' ! -path '*__tests__*' | xargs wc -l, base vs. HEAD). Exports map 118 → 109 subpaths, snapshot regenerated. 76 files changed; every moved module is R091–R100 under git diff -M90% --name-status origin/claude/2336-command-registry-package...HEAD.
Corrections to the issue's tables, verified against the tree:
wait-runtime-plan.tskept. A'spackages/command-registry/src/__tests__/wait-runtime-execution.test.tsimports it, so it is not root-only. Moving it would make a package import rootsrc/.snapshot-presentation.tshas 2 platform-android consumers, not 6 (snapshot-presentation.ts,ui-hierarchy-builder.ts). Still single-package; moved.- Two consequences of the moves:
android-touch-planlands astouch-plan-lowering.tsand retires the package-localtouch-plan.tsre-export barrel it fed;APPLE_OS_DISPLAY_NAMESfolds intogesture-admission.ts, its one remaining contracts caller, so both gesture refusals share one copy of the wording without a new subpath.fast-checkfollows the property tests from contracts to platform-android. replay-divergence.ts: implementation + its test tosrc/core, types stay on the/divergencesubpath.ReplayVarScrubEntryfollows the implementation — it is the sanitizer's parameter shape, not wire vocabulary. A split is not expressible as a rename.
interaction-guarantees.ts: kept. AGENTS.md names it a declaration site and points readers at that path; its non-daemon consumers are the interaction-contract test project and scripts/depgraph/affected-run.ts, i.e. repo tooling rather than a root zone. The ≥1,000-line target is met without it.
Validation
Tested SHA c83c1bbf4 — the rebased head, replayed onto A at f887766 (which now carries #2346/C's daemon/types.ts split). Three conflicts against that split were resolved as this PR's move plus C's split types, in snapshot-session.ts, session-replay-coordinator.ts and client/daemon-client-lifecycle.ts; the divergence types stay on @agent-device/contracts/divergence there, as intended. The measurement above is re-run on the rebased pair and is unchanged.
After pnpm install --frozen-lockfile && pnpm build, pnpm check:affected --run: format, lint, typecheck, layering, di-seams, fallow, mcp-metadata, build, package (R11 package-boundaries), integration-node, macos-coverage all pass. vitest-related: 9728 passed, 3 failed — app-log-session-resource, durable-capture-resource, capture-kit/durable-capture/adoption, all asserting a chmod 0500 directory is unwritable, which this container ignores because it runs as uid 0. All three are untouched by this branch and fail identically on the base.
The gates after that point were run individually and pass: replay-compat, daemon-wire-compat, affected-selector, gate-manifest, depgraph, tmpdir-leaks, coverage-model, wire-compat-model, production-exports, bundle-owner-files, command-docs, agent-guidance, xctest-selection, provider-integration, integration-progress, maestro-conformance, mutation-model, fixture-cache.
Fallow reports one pre-existing 19-line clone (src/commands/output/error.ts ↔ src/mcp/tool-error.ts), byte-identical on the base and only in scope because both files changed one import line. No gate suppressed.
The platform-apple/src/snapshot-source/native-runtime.test.ts failure seen twice on the pre-rebase head 6bf0b3d is a native xcrun clang compile exceeding its 45 s budget on a loaded macOS runner; root cause and a proposed patch are in the comment thread. It is not this PR's and is deliberately not fixed here.
🤖 Generated with Claude Code