Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ jobs:
- name: Check import-direction DAG (kernel-sink, commands-floor, platforms-seam)
# Generalizes the former inline commands/-import grep into a structured
# import-direction lint over the resolved graph. See scripts/layering/check.ts
# and plans/perfect-shape.md §5.5. Invoked directly (no deps needed) so the
# job stays fast and does not require a pnpm install.
# and CONTEXT.md (Architecture: folder DAG + layering lint). Invoked directly
# (no deps needed) so the job stays fast and does not require a pnpm install.
run: node --experimental-strip-types scripts/layering/check.ts

fallow:
Expand Down
39 changes: 39 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,45 @@
- Snapshot quality verdict: structured outcome (state, backend, reason code, effective depth, collapsed leaves) computed once by the plan runner and shipped with every planned snapshot payload; the daemon and CLI render it instead of re-deriving degradation from node shapes.
- AX-unavailable target invalidation: iOS/macOS runner behavior where a root accessibility snapshot failure such as `kAXErrorIllegalArgument` marks the cached `XCUIApplication` target handle suspect. The runner fails closed for degraded interactive snapshots, clears the cached target, and lets the next command reacquire the app through normal activation.

## Architecture (perfect-shape refactor, completed 2026-07)

The perfect-shape refactor is complete and merged. Its end-state:

- Two derivation registries. One `CommandDescriptor` per command
(`src/core/command-descriptor/registry.ts`) is the single declaration site from which the public
catalog, capability matrix, daemon command registry, batch allowlist, MCP tools, CLI schema, and
the Node client surface are *derived* by parity-tested projection; the dispatch `switch` became a
total map keyed on the command-name union (a missing handler is a compile error). One
`PlatformPlugin` per platform family (`src/core/platform-plugin/`) stops core/daemon from branching
on platform, with the Apple plugin the first instance. See
[ADR 0008](docs/adr/0008-command-descriptor-registry.md).
- Typed result spine. Per-command typed results and a `TypedError` replaced the ad-hoc
`Record`-typed returns across the daemon/dispatch path.
- Apple platform model. Internally `Platform` is `apple` (plus `android`/`linux`/`web`) with an
`appleOs` discriminant (`ios | ipados | tvos | watchos | visionos | macos`); the shared Apple
engine lives under `src/platforms/apple/core/` with per-OS leaves under
`src/platforms/apple/os/<os>/`. The public wire stays non-breaking: `PUBLIC_PLATFORMS`
(`src/kernel/device.ts`) still emits `ios`/`macos` leaf output. See
[ADR 0009](docs/adr/0009-apple-platform-consolidation.md).
- Folder DAG + layering lint. `kernel`/`remote`/`metro`/`client`/`snapshot`/`screenshot-diff`/
`replay`/`cli-parser`/`daemon-client`+`server`/`sdk` are arranged as an import-direction DAG
(imports point down toward the kernel sink), enforced in CI by `scripts/layering/check.ts`.
- Agent-cost. Responses carry a cost block and MCP `outputSchema`, rendered through a leveled
`ResponseView`.

### Deferred / next-minor

The refactor is substantively done; these follow-ups are intentionally deferred, not lost:

- Phase 2c — narrow the ~15 remaining `Record`-typed client methods in
`src/client/client-types.ts` to their existing typed contracts (a semver-relevant public-API
narrowing; not yet done).
- b.3 recording/providers facets — the two risky `PlatformPlugin` daemon facets (`providers`,
`recording`) remain on their daemon branch as source of truth (#974 closed).
- Strict DAG back-edge inversion — the layering lint enforces the achievable subset; the full
zero-back-edge DAG (e.g. `commands` → `cli`/`client`) is not done.
- Legacy alias drops — ~175 LOC of legacy aliases/barrels remain, gated to the next major.

## Selector Capture Reliability Contract

Selector capture is allowed to optimize transport, helper reuse, and polling, but it must preserve
Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0003-daemon-command-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ owns the rationale so future changes do not need to infer it from agent instruct

## Update (2026-06): single-declaration / derivation model

A later proposal (the `CommandDescriptor` direction in `plans/perfect-shape.md`) unifies a command's
A later proposal (the `CommandDescriptor` direction, now [ADR 0008](0008-command-descriptor-registry.md)) unifies a command's
declarations so the public catalog, capability matrix, CLI/MCP projections, batch allowlist, and this
daemon registry are *derived* from one registration site, to remove the cross-table drift that several
of these surfaces are kept aligned against by convention.
Expand Down
3 changes: 2 additions & 1 deletion docs/adr/0008-command-descriptor-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ has ~95 importers and the family facet currently imports `AgentDeviceClient`, so
own the `Input`/`Result` types and the client must be derived as a view type, enforced by a lint boundary.
Until this lands and the registry tests pin it, the hand-authored tables remain the source of truth.

`plans/perfect-shape.md` (§5.2) holds the prototype; this ADR owns the decision and its constraints.
This ADR owns the decision and its constraints; the roadmap that prototyped it has been retired, with
the delivered end-state recorded in [CONTEXT.md](../../CONTEXT.md) (Architecture).
3 changes: 2 additions & 1 deletion docs/adr/0009-apple-platform-consolidation.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ Model Apple OSes with an **`AppleOS` discriminant** (`ios | ipados | tvos | watc
under a single `apple` Platform — **not** six `Platform` literals. The OS-agnostic Apple engine consolidates
under `src/platforms/apple/core/`, with genuinely per-OS code in `src/platforms/apple/os/<os>/` leaves;
the Apple plugin is the first instance of the platform-plugin registry (the platform axis of the
`perfect-shape` plan). Per-OS capability differences become data keyed by `AppleOS`. The additive,
completed perfect-shape refactor; see [CONTEXT.md](../../CONTEXT.md) Architecture). Per-OS capability
differences become data keyed by `AppleOS`. The additive,
non-breaking `appleOs` discriminant — the groundwork for this — shipped in #896.

## Alternatives Considered
Expand Down
Loading
Loading