Skip to content

refactor(contracts): design spike — cut ADR-0019 declaration fan-out without weakening exact-owner facts (#1739) #1984

Description

@thymikee

Outcome

A recommendation, with a worked example on one pending Wave 5 descriptor, for reducing the
per-unit declaration fan-out that #1739 identifies as its own parallelism constraint — without
weakening exact-owner classification.

Deliberately scoped as a spike, not a repo-wide change.

The measured problem

Co-change analysis of the last 200 commits on main (2026-08-10 → 2026-08-23, HEAD d1fc80f):

  • src/core/command-descriptor/registry.ts changed in 26 commits; in 16 of those 26 it moved
    together with each of platform-{apple,android,web,harmonyos}/src/runtime.ts, and 15/26 with
    scripts/layering/runtime-command-cutover-table.ts.
  • Ten commits touch all six platform-*/src/runtime.ts in lockstep.
  • 15 of the 17 commits touching packages/contracts/src/platform-runtime-operations.ts touch
    four or more runtime owners.

The shape of one unit, measured on #1925 (focus — a single operation, focusPoint):

The change focus-runtime.ts
Forced: contracts platform-runtime-operations.ts, platform-runtime-unavailable.ts, facades/platform.ts
Forced: 8 runtime owners platform-{apple,android,web,harmonyos,linux,vega}, provider-{limrun,webdriver}
Forced: gates & fixtures runtime-command-cutover-table.ts, registry.ts, capabilities.ts, parity.test.ts, + 5 shared fixtures

40 files, 855 insertions. Comparable: #1935 (type) 64 files, #1877 (get) 75 files. With 13 Wave 5
interaction descriptors, 9 Wave 6 named units and 8 residue still ahead, that is roughly 30 more
repetitions.

This is the measured basis for #1739's own scheduling constraint: "every unit touches registry.ts,
runtime-command-cutover-table.ts, contracts/platform-runtime-operations.ts and each
platform-*/src/runtime.ts, so two in flight collide on the same four files."

Constraint the design must preserve

An earlier version of this analysis proposed defaulting the newer interaction cells (focus,
typeText, elementText) through freezeUnavailableFacts' existing orNetwork path. That is
wrong and this issue exists partly to record why
, so it is not re-proposed:

  • docs/agents/adr-0019-unit.md requires each platform package to report exact-owner facts, with
    provider ownership failing closed — missing behavior never falls through to a local owner.
  • packages/contracts/src/platform-runtime-unavailable.ts records (refactor: tighten viewport runtime facts #1873) that capture cells are
    stated by their owner and never inherited from the transport gap.

Defaulting an interaction cell to network would erase a real distinction — provider is reachable,
but this interaction is unsupported
— and let a missing classification read as a transport failure.
The required/optional split is the policy, not an oversight.

So the goal is narrow:

Reduce the declaration fan-out without weakening exact-owner classification.

Directions worth evaluating

None of these are proven by the churn evidence; the spike is to choose among them.

  • operation-family builders;
  • exhaustive composed records;
  • generated owner skeletons.

Fold in: the fixture fan-out

Five modules each restate the runtime operation surface and move with the same units:

Fixture Lines Commits
src/daemon/handlers/__tests__/session-command-harness.ts 283 18
src/daemon/handlers/__tests__/session-capabilities.fixtures.ts 162 12
src/daemon/__tests__/test-device-runtime-gateway.ts 190 12
src/daemon/handlers/__tests__/interaction-get-runtime-fixture.ts 176
src/__tests__/test-utils/runtime-operation-facts.ts 53

Derive construction, not expectations. A fixture catalog generated wholesale from the production
catalog is tautological: if production omits an operation and the expected fixtures inherit that
omission, both sides stay green. The safe shape is to centralize valid runtime-fact construction,
keep parity and denominator assertions independent of it, keep focused owner-specific overrides, and
ensure an omission still fails compilation or a completeness gate.

Deliverable

A recommendation plus a worked example on one pending Wave 5 descriptor — enough for #1739 to decide
whether to adopt it before the remaining interaction units, not a landed repo-wide refactor.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions