|
1 | 1 | # AGENTS.md |
2 | 2 |
|
3 | | -`agent-device` is a CLI and daemon for automating Apple, Android, HarmonyOS, Vega, Linux, and web |
4 | | -targets. A long-lived daemon owns sessions; registry-derived commands route to platform runtimes. |
| 3 | +`agent-device` is a CLI and daemon for automating devices and web targets. |
| 4 | +The daemon owns sessions. Registry declarations route commands to platform runtimes. |
5 | 5 |
|
6 | 6 | ## Task routing |
7 | 7 |
|
8 | | -Load only the procedures relevant to the task: |
| 8 | +Read only the row for your current task. Follow further links only when they apply. |
9 | 9 |
|
10 | 10 | | When the task involves | Read | |
11 | 11 | | --- | --- | |
12 | 12 | | Domain vocabulary | `CONTEXT.md`, `docs/agents/domain.md` | |
13 | 13 | | Architecture decisions | `docs/adr/README.md` | |
14 | | -| Tests or gate selection | `docs/agents/testing.md` | |
15 | | -| Writing, auditing, or sweeping tests; dispatching test-audit subagents | `docs/agents/test-audit.md` | |
16 | | -| Selector capture, polling, or interaction fast paths | `docs/agents/selector-capture.md` | |
| 14 | +| Source changes, package boundaries, routing, diagnostics | `docs/agents/code-ownership.md` | |
| 15 | +| Running checks or diagnosing a failed gate | `docs/agents/testing.md` | |
| 16 | +| Writing or changing tests | `docs/agents/test-authoring.md` | |
| 17 | +| Auditing or deleting tests | `docs/agents/test-audit.md` | |
| 18 | +| Mutation experiments or base comparisons | `docs/agents/test-experiments.md` | |
| 19 | +| Changing gate selection, fuzzing, or mutation harnesses | `docs/agents/gates.md` | |
| 20 | +| Selector capture, polling, interaction fast paths, replay | `docs/agents/selector-capture.md` | |
17 | 21 | | Adding or changing a CLI flag | `docs/agents/cli-flags.md` | |
18 | | -| Opening or reviewing a PR | `docs/agents/pull-requests.md` | |
19 | | -| Apple runner changes or manual device verification | `docs/agents/device-verification.md` | |
| 22 | +| Opening or updating a PR | `docs/agents/pull-requests.md` | |
| 23 | +| Reviewing a change | `docs/agents/review.md` | |
| 24 | +| Device-facing changes or manual device verification | `docs/agents/device-verification.md` | |
20 | 25 | | Writing issues or PRDs, and triage labels | `docs/agents/issue-tracker.md`, `docs/agents/triage-labels.md` | |
21 | 26 | | Web backend setup or diagnostics | `docs/agents/web-backend.md` | |
22 | 27 |
|
23 | | -Versioned CLI help owns command semantics. Read the relevant topic when behavior is unclear; |
24 | | -normal app-driving startup follows the skill's routing card. |
| 28 | +Device-facing changes affect live device behavior: dispatch, capture, interaction, app lifecycle, or native execution. |
| 29 | +A daemon edit that changes none of these needs no device run. |
25 | 30 |
|
26 | | -## Incident-derived principles |
| 31 | +Versioned CLI help owns command semantics. For app-driving startup, use the skill's routing card. |
27 | 32 |
|
28 | | -- Classify interaction dispatch paths in `packages/contracts/src/interaction-guarantees.ts` and |
29 | | - verify each claim against the native implementation. |
30 | | -- Delegation on error proves no success-path parity. A fast path may succeed on a candidate the |
31 | | - shared rules would refuse. |
32 | | -- Prove both paths are reachable before measuring a fast path against its baseline. |
33 | | -- Repair recurring failures at the owning type, registry, or construction path; do not add guards |
34 | | - that reconstruct another source of truth. |
35 | | -- Keep control-flow narration and review history out of implementation comments. Encode invariants |
36 | | - in names, types, boundaries, and tests; reserve comments for public API docs, tool directives, |
37 | | - and non-obvious constraints that cannot be encoded. |
38 | | -- Key behavior on typed reasons and details, never error text; do not copy existing message sniffs. |
39 | | -- A claim about a platform family in code, help, or docs holds for every backend in it (Appium as |
40 | | - well as ADB on Android), or names the backends it covers. |
41 | | -- Keep metadata at response level when it applies to the whole snapshot. Append warnings through |
42 | | - the shared response builder; never replace prior warnings. |
43 | | -- Before preserving a compatibility shape, run `git tag --contains <commit>`. Unreleased API has no |
44 | | - external compatibility obligation. |
| 33 | +## Working rules |
45 | 34 |
|
46 | | -## Declaration sites and enforcement |
| 35 | +- Keep edits within the requested command family or module group. Inspect other platforms only when the task requires it. |
| 36 | +- Fix recurring failures at the owning type, registry, or construction path. Do not reconstruct another owner's state. |
| 37 | +- Use typed reasons and details for behavior. Never match error text. |
| 38 | +- Add compatibility or fallback behavior only when explicitly requested or approved. Remove superseded paths during migrations. |
| 39 | +- Encode invariants in names, types, and boundaries. Comments explain public APIs, tool directives, or constraints code cannot express. |
| 40 | +- Resolve gate failures at the reported invariant. Do not suppress them or add an allowlist to get a pass. |
| 41 | +- Use `@agent-device/selectors` for selector parsing and matching. See `docs/agents/code-ownership.md` for other shared owners. |
| 42 | +- Keep skills as routing cards. Keep `CONTEXT.md` glossary-only. Update owning help and user docs when behavior changes. |
47 | 43 |
|
48 | | -Read the declaration rather than maintaining a prose copy: |
| 44 | +## Worktree setup |
49 | 45 |
|
50 | | -- commands and their surface, runtime-use, batch, and timeout traits: |
51 | | - `packages/command-registry/src/registry.ts` |
52 | | -- daemon route ownership and request-policy traits: `packages/daemon/src/core/daemon-command-registry.ts` |
53 | | -- interaction paths and guarantees: `packages/contracts/src/interaction-guarantees.ts` |
54 | | -- canonical command names: `packages/command-registry/src/catalog.ts` |
55 | | -- device runtime-use declarations and fact admission: |
56 | | - `packages/command-registry/src/registry.ts`, `packages/daemon/src/core/runtime-admission.ts`, and |
57 | | - `src/platform-runtime-gateway.ts` |
58 | | -- common command input fields, and which surface may write an input key (model, operator, retired): |
59 | | - `src/commands/common-input-fields.ts` and `src/commands/input-audience.ts` |
| 46 | +- Use `pnpm`. Use OXC for lint and format. Run `pnpm format` repository-wide. |
| 47 | +- In a fresh worktree, run `pnpm install --frozen-lockfile && pnpm build` before testing. |
| 48 | +- Preserve other worktrees, devices, sessions, dirty files, and experiments. |
| 49 | +- Never copy `.env` into a worktree. For host credentials, source the main checkout's file by absolute path. |
| 50 | +- Give parallel workers disjoint files and distinct devices. `pnpm check:affected --run` and `pnpm check` serialize automatically. |
| 51 | +- The layering scan reads tracked files. Stage new modules before trusting its result. |
| 52 | +- Move a path's Fallow baseline entry when renaming its file. Do not regenerate unrelated baselines. |
60 | 53 |
|
61 | | -Shared selector parsing and matching belongs in `@agent-device/selectors`; daemon-side request |
62 | | -cancellation and progress in `@agent-device/host-kit/request`, and the caller's per-call abort guard |
63 | | -beside the transports it serves in `src/daemon-client/daemon-client-transport.ts`; cross-layer |
64 | | -contracts in `packages/contracts/src`; CLI flags in `src/commands/cli-grammar`; cross-surface schema |
65 | | -composition in `src/commands/schema`. |
| 54 | +The validation lock reclaims provably dead owners automatically. Unknown owners remain blocking. |
| 55 | +If waiting times out, report the printed owner and lock state; do not remove it by hand. |
66 | 56 |
|
67 | | -Resolve registry completeness failures at the missing declaration. Diagnose other gate failures |
68 | | -at their reported invariant; do not suppress them or add an allowlist to get a pass. Build interaction |
69 | | -responses through `buildInteractionResponseData`; change cross-language rules through golden tables |
70 | | -under `contracts/fixtures/`. |
| 57 | +## Agent docs |
71 | 58 |
|
72 | | -## Hard repository rules |
73 | | - |
74 | | -- Plain `.mjs` packaging fixtures that cannot import TypeScript execution helpers keep child-process |
75 | | - use local and prefer `execFile`. |
76 | | -- Apple target changes keep the kernel device model, runtime-fact admission, dispatch resolution, |
77 | | - Apple discovery, and xctestrun preparation in sync. |
78 | | -- iOS simulator-set scoping must never hide the host macOS desktop target. |
79 | | -- Skills stay minimal routing cards. |
80 | | -- Add compatibility or fallback behavior only when explicitly requested or approved. Otherwise, |
81 | | - complete the migration and remove superseded paths. |
82 | | -- Keep changes within one command family or module group unless the task explicitly crosses a |
83 | | - boundary. Platform-neutral work does not license inspecting every platform implementation. |
84 | | - |
85 | | -## Module and test topology |
86 | | - |
87 | | -- Name modules for the domain question they answer and colocate machine-readable claims with their |
88 | | - enforcement. Internal barrels are legacy; add barrels only at package boundaries. |
89 | | -- Files past 1,000 lines are architecture debt; split them before adding behavior, unless they |
90 | | - are generated or fixture data. |
91 | | -- Tests mirror source topology one-to-one. Split a source module and its test together; do not add to |
92 | | - the legacy `interaction.test.ts` or platform `index.test.ts` aggregations. Pure moves carry their |
93 | | - tests unchanged; rename-only hunks owe no new coverage. |
94 | | -- A test sits beside the module it is named for: `<module>.test.ts` or `<module>-<aspect>.test.ts` |
95 | | - (R84). Cross-module package tests are `index-<aspect>.test.ts` beside `index.ts`; repo-level guards on |
96 | | - Swift sources, manifests, docs or scripts live in `test/repo-guards/`. |
97 | | -- Add no package `exports` entry that points at test support; R83 only lets the legacy count fall. A |
98 | | - fixture one package uses stays inside it, imported relatively; helpers shared across packages live only in `@agent-device/test-kit`, a |
99 | | - `devDependency` production source never imports and that never depends on `platform-*`, |
100 | | - `provider-*`, the daemon or root. |
101 | | - |
102 | | -## Toolchain and worktree traps |
103 | | - |
104 | | -- Use `pnpm`; never add `package-lock.json`. OXC owns lint and format. Run `pnpm format` |
105 | | - repository-wide, not path-scoped. |
106 | | -- A fresh worktree requires `pnpm install --frozen-lockfile && pnpm build`. Until then package and |
107 | | - optional-peer resolution may point at another checkout and produce false failures. |
108 | | -- Worktrees never receive `.env`; no repo code reads it. When a command needs a host credential, |
109 | | - source the main checkout's copy by absolute path (`set -a && . /path/to/main/checkout/.env && set +a`) |
110 | | - instead of copying it in or writing it into the worktree. |
111 | | -- Parallel work needs disjoint edit ownership and distinct devices. Run one full gate per host; |
112 | | - concurrent subprocess-backed suites can produce contention timeouts. |
113 | | -- The layering scan reads tracked files only. Stage a new module before trusting its result. |
114 | | -- Fallow baselines are path-keyed. Move the matching baseline entry when renaming a file; never bulk |
115 | | - regenerate baselines to accept unrelated findings. |
116 | | - |
117 | | -## Runtime and diagnostics seams |
118 | | - |
119 | | -Diagnostics use `@agent-device/host-kit/diagnostics`. Request diagnostics belong in the session request log; |
120 | | -session artifact paths come from `packages/daemon-contracts/src/session-artifact-paths.ts`. App/device logs remain in `app.log`; |
121 | | -Apple runner and xcodebuild output remains in `runner.log`. |
122 | | - |
123 | | -Normalize failures with `normalizeError` and preserve `hint`, `diagnosticId`, `logPath`, and typed |
124 | | -`details`. An interaction taking five seconds or more is a daemon-log question: inspect runner |
125 | | -restart, stale-session recovery, accessibility failure, transport retry, and timeout evidence. |
126 | | - |
127 | | -Optional probes and caches are best-effort only when the feature contract says so. Their budgets |
128 | | -must be shorter than the required operation they precede. |
129 | | - |
130 | | -## Selector and replay invariants |
131 | | - |
132 | | -Element interactions support selector and `@ref`, then record a selector chain after resolution. |
133 | | -Replay failures may re-resolve that chain only to produce a ranked divergence suggestion; ADR 0012 |
134 | | -retired silent script rewriting. |
135 | | - |
136 | | -Selector keys stay centralized in `@agent-device/selectors`; `is` predicates use |
137 | | -`evaluateIsPredicate`. On macOS, snapshot rectangles are absolute in window space and point actions |
138 | | -translate through the interaction root frame. Prefer selector or ref tests over raw coordinates. |
139 | | - |
140 | | -## Documentation ownership |
141 | | - |
142 | | -Keep this file to repository traps and routing. Put task procedures in `docs/agents/`, decisions in |
143 | | -ADRs, and command semantics in versioned help. Link to executable registries instead of duplicating |
144 | | -their rules. `CONTEXT.md` is glossary-only: no implementation paths, decisions, or migration status. |
145 | | - |
146 | | -Behavior changes update owning help/metadata and user docs. Report docs or skill changes when relevant. |
| 59 | +Write short instructions with one action per sentence. Put the condition before its action. |
| 60 | +Use the same term for the same concept. Keep commands and domain terms exact. |
| 61 | +Route specialized rules to their task document. Delete duplicate or enforced rules before adding reminders. |
0 commit comments