Skip to content

refactor(daemon): implement ADR 0019 through the adoption checkpoint #1696

Description

@thymikee

Outcome

Implement ADR 0019 so daemon commands consume contracts-owned, request-bound platform runtimes while platform-specific mechanics live in private, implementation-lazy @agent-device/platform-* workspace packages.

This is the canonical implementation tracker and checkpoint record. Do not split later migration slices into worker issues until the pre-substrate baseline has fixed their denominator and dependencies.

Blocked by: #1697

Start condition: ADR 0019 is accepted and merged. Branch every implementation unit from the latest main.

Why now

HarmonyOS makes the shallow PlatformPlugin wrapper insufficient: the daemon no longer merely selects among Apple and Android paths; it owns an expanding platform-to-implementation map across six canonical families (apple, android, harmonyos, vega, linux, web). This resumes the platform-packaging direction deferred at the checkpoint in #1490 and replaces, command by command, the shallow consolidation completed in #972. It also supplies the platform boundary deferred by #1478.

Locked architecture

  • Neutral inventory, runtime, operation, lifecycle, result, error, and durable-resource contracts live in @agent-device/contracts.
  • Private @agent-device/platform-<family> packages contain only family-specific implementations. They do not import root src/**, daemon-private types, or sibling platform packages.
  • src/platform-runtime.ts is the only concrete composition root. Registration is metadata-eager and implementation-lazy; heavy family code loads only for selected discovery or first bind.
  • A descriptor has exactly one platform-execution shape: legacy adapter, inventory-backed adapter, or device-runtime-backed adapter. ADR 0003's daemon route and request-policy projection remain unchanged.
  • Cutovers are one command across every existing local/provider support cell. Admission and execution migrate together; no dual route, success fallback, or daemon-side tag map remains.
  • Process helpers are process-lived, bindings are request-lived, and only explicitly adopted neutral resource handles may become session-lived. Binding disposal must never terminate kept-hot helpers.
  • Persisted durable descriptors are versioned, exact-owner, fenced, decoded from unknown, and fail closed. Recovery manifests are authoritative before any new persistence structure; diagnostics/session events are observation-only.
  • The substrate and every command unit must be reviewed from a clean committed tree. Structural gates get planted red cases and no migration allowlists.

Checkpoint scope

  • Record, before substrate work, the exact command inventory, independent legacy parity matrix, Apple leaf/provider denominator, validation commands and thresholds, cold-start/lazy-load probes, daemon platform import/branch/tag counts, and current R7/R10/R9 baselines.
  • Land a behavior-neutral, independently revertible contracts/registry/gate substrate that routes no production descriptor on its own.
  • Cut over devices completely through the inventory gateway across all six local family sources and every provider inventory source.
  • Cut over logs completely through request-bound runtime contracts.
  • Cut over network completely and prove the app-log durable-resource lifecycle: partial-start rollback, pending-transfer guard, adoption, normal finish(), forced idempotent cleanup, exact-owner reattachment/cleanup, fencing, and primary-error precedence.
  • Record checkpoint evidence and change ADR 0019 Status to exactly one of continue, revise, or stop.

No further command migration may begin until Status records continue, and continue is legal only when every hard checkpoint item passes. Generic session teardown may call the migrated app-log handle's neutral cleanup contract without migrating close's legacy platform adapter; if another descriptor's platform adapter must change, amend the checkpoint scope before substrate work.

Acceptance evidence

  • Zero old capability closures, platform branches, tags/maps, or concrete native imports remain for each migrated descriptor, with a strict net decrease in measured daemon platform coupling.
  • Every canonical family/provider cell and applicable Apple leaf is implemented or explicitly unsupported with parity-preserving hints; every formerly supported cell has a contract scenario.
  • packages/platform-* build and emit declarations independently, remain lazily evaluated, and have zero prohibited back-edges. Package edits select their contract/provider scenarios through check:affected.
  • Runtime requirements narrow handler types without casts, non-null assertions, any, or sibling-operation leakage; planted violations prove the enforcement gates red.
  • Request binding disposal preserves process helpers. Partial acquisition and the start-to-adoption cancellation gap cannot leak resources.
  • SessionState changes satisfy the ADR's per-unit R7/R10 checklist; equality-pinned baselines do not grow, external daemon/types.ts importers do not grow, and cycle ceilings follow their existing growth-only policy.
  • Provider-first behavior, Apple leaf restrictions, startup baselines, and available-command/unsupported-hint parity remain green.

Stop or revise at the checkpoint if satisfying the pilot requires a daemon-side tag map, dual/fallback route, eager native loading, a package back-edge, concrete platform values in daemon live state, an unclassifiable support cell, a second recovery truth, or increased daemon ownership/coupling.

Validation per implementation unit

  • pnpm check:affected --run
  • pnpm check for the broad substrate/architecture changes
  • The descriptor-derived parity, contract, provider, leaf-coverage, lifecycle, lazy-load, and structural planted-red scenarios introduced by that unit

The merge request must state which physical module moves are complete and which legacy consumers intentionally remain in place; shared mechanics move only when all consumers can move or through a neutral injected lower-level port.

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