@orkestrel/scaffold 0.0.107 → 0.0.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/skills/orkestrel-dispatch/scripts/bench.js +326 -91
- package/dist/agents/skills/orkestrel-dispatch/scripts/brief.js +110 -14
- package/dist/agents/skills/orkestrel-dispatch/scripts/chain.js +280 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/cite.js +188 -26
- package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +142 -43
- package/dist/agents/skills/orkestrel-dispatch/scripts/login.js +240 -62
- package/dist/agents/skills/orkestrel-dispatch/scripts/patch.js +323 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/result.js +169 -32
- package/dist/agents/skills/orkestrel-dispatch/scripts/sweep.js +368 -27
- package/dist/agents/skills/orkestrel-falsify/scripts/mutate.js +560 -0
- package/dist/agents/skills/orkestrel-harden/scripts/discovery.js +1052 -205
- package/dist/agents/skills/orkestrel-harden/scripts/measure.js +361 -0
- package/dist/agents/skills/orkestrel-harden/scripts/titles.js +455 -80
- package/dist/agents/skills/orkestrel-parallel/scripts/cases.js +327 -0
- package/dist/agents/skills/orkestrel-publish/scripts/compare.js +298 -51
- package/dist/agents/skills/orkestrel-publish/scripts/pins.js +170 -13
- package/dist/agents/skills/orkestrel-publish/scripts/swap.js +956 -191
- package/dist/agents/skills/orkestrel-publish/scripts/wave.js +707 -112
- package/dist/agents/skills/orkestrel-publish/scripts/window.js +235 -41
- package/dist/agents/skills/orkestrel-scout/scripts/map.js +341 -54
- package/dist/agents/templates/brief.md +1 -1
- package/dist/bin/main.js +51 -46
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +26 -20
- package/dist/host/agents/orchestration.md +98 -58
- package/dist/host/agents/platforms/posix.md +15 -0
- package/dist/host/agents/platforms/windows.md +37 -0
- package/dist/host/agents/skills/orkestrel-align/SKILL.md +10 -13
- package/dist/host/agents/skills/orkestrel-align/references/fleet.md +4 -10
- package/dist/host/agents/skills/orkestrel-align/references/integration.md +1 -1
- package/dist/host/agents/skills/orkestrel-build/SKILL.md +16 -48
- package/dist/host/agents/skills/orkestrel-build/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +19 -16
- package/dist/host/agents/skills/orkestrel-debrief/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-debrief/references/field-testing.md +15 -28
- package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +5 -6
- package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +12 -14
- package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +36 -24
- package/dist/host/agents/skills/orkestrel-dispatch/references/launch.md +14 -11
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/bench.ts +366 -75
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/brief.ts +126 -16
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/chain.ts +323 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/cite.ts +220 -31
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +176 -33
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/login.ts +294 -59
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/patch.ts +401 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/result.ts +199 -34
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/sweep.ts +428 -27
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +10 -8
- package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +1 -5
- package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +1 -1
- package/dist/host/agents/skills/orkestrel-falsify/scripts/mutate.ts +701 -0
- package/dist/host/agents/skills/orkestrel-harden/SKILL.md +16 -12
- package/dist/host/agents/skills/orkestrel-harden/references/bindings.md +23 -81
- package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +4 -5
- package/dist/host/agents/skills/orkestrel-harden/references/contract.md +2 -0
- package/dist/host/agents/skills/orkestrel-harden/references/document.md +33 -0
- package/dist/host/agents/skills/orkestrel-harden/references/equivalence.md +6 -3
- package/dist/host/agents/skills/orkestrel-harden/references/hardening.md +8 -4
- package/dist/host/agents/skills/orkestrel-harden/references/research.md +2 -0
- package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +1272 -279
- package/dist/host/agents/skills/orkestrel-harden/scripts/measure.ts +425 -0
- package/dist/host/agents/skills/orkestrel-harden/scripts/titles.ts +603 -98
- package/dist/host/agents/skills/orkestrel-journey/SKILL.md +75 -98
- package/dist/host/agents/skills/orkestrel-journey/references/captures.md +54 -17
- package/dist/host/agents/skills/orkestrel-journey/references/decide.md +1 -20
- package/dist/host/agents/skills/orkestrel-journey/references/layer.md +21 -31
- package/dist/host/agents/skills/orkestrel-journey/references/styles.md +1 -1
- package/dist/host/agents/skills/orkestrel-parallel/SKILL.md +91 -30
- package/dist/host/agents/skills/orkestrel-parallel/agents/openai.yaml +2 -2
- package/dist/host/agents/skills/orkestrel-parallel/references/claude.md +34 -0
- package/dist/host/agents/skills/orkestrel-parallel/references/codex.md +29 -0
- package/dist/host/agents/skills/orkestrel-parallel/references/cursor.md +29 -0
- package/dist/host/agents/skills/orkestrel-parallel/references/t3.md +31 -0
- package/dist/host/agents/skills/orkestrel-parallel/scripts/cases.ts +389 -0
- package/dist/host/agents/skills/orkestrel-polish/SKILL.md +16 -20
- package/dist/host/agents/skills/orkestrel-polish/references/capture-harness.md +16 -26
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +12 -26
- package/dist/host/agents/skills/orkestrel-publish/agents/openai.yaml +2 -2
- package/dist/host/agents/skills/orkestrel-publish/references/adopt.md +23 -0
- package/dist/host/agents/skills/orkestrel-publish/references/release.md +4 -4
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +12 -10
- package/dist/host/agents/skills/orkestrel-publish/references/window.md +20 -25
- package/dist/host/agents/skills/orkestrel-publish/scripts/compare.ts +348 -59
- package/dist/host/agents/skills/orkestrel-publish/scripts/pins.ts +202 -22
- package/dist/host/agents/skills/orkestrel-publish/scripts/swap.ts +1061 -191
- package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +812 -140
- package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +280 -38
- package/dist/host/agents/skills/orkestrel-scout/SKILL.md +3 -3
- package/dist/host/agents/skills/orkestrel-scout/scripts/map.ts +428 -70
- package/dist/host/agents/templates/brief.md +1 -1
- package/dist/host/agents/transports/claude-cli.md +3 -3
- package/dist/host/agents/transports/codex.md +3 -8
- package/dist/host/agents/transports/cursor.md +2 -3
- package/dist/host/claude/AGENTS.md +7 -10
- package/dist/host/claude/agents/analyst.md +3 -3
- package/dist/host/claude/agents/astra.md +3 -3
- package/dist/host/claude/agents/builder.md +1 -1
- package/dist/host/claude/agents/checker.md +1 -1
- package/dist/host/claude/agents/distiller.md +1 -1
- package/dist/host/claude/agents/grok.md +1 -1
- package/dist/host/claude/agents/opus.md +2 -2
- package/dist/host/claude/agents/orkestrel.md +57 -90
- package/dist/host/claude/agents/researcher.md +1 -1
- package/dist/host/claude/agents/reviewer.md +4 -0
- package/dist/host/claude/agents/scout.md +1 -1
- package/dist/host/claude/agents/verifier.md +1 -1
- package/dist/host/claude/rules/application.md +14 -21
- package/dist/host/claude/rules/architecture.md +34 -44
- package/dist/host/claude/rules/browser.md +3 -4
- package/dist/host/claude/rules/campaign.md +55 -0
- package/dist/host/claude/rules/documentation.md +26 -11
- package/dist/host/claude/rules/names.md +9 -4
- package/dist/host/claude/rules/patterns.md +6 -7
- package/dist/host/claude/rules/portability.md +2 -3
- package/dist/host/claude/rules/quality.md +4 -5
- package/dist/host/claude/rules/styles.md +2 -2
- package/dist/host/claude/rules/tests.md +57 -114
- package/dist/host/claude/rules/typescript.md +8 -10
- package/dist/host/claude/rules/workspace.md +21 -19
- package/dist/host/claude/rules/writing.md +3 -3
- package/dist/host/claude/skills/orkestrel-dispatch/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-harden/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-parallel/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-publish/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-scout/SKILL.md +1 -1
- package/dist/host/codex/agents/analyst.toml +9 -3
- package/dist/host/codex/agents/astra.toml +3 -4
- package/dist/host/codex/agents/builder.toml +1 -1
- package/dist/host/codex/agents/opus.toml +3 -4
- package/dist/host/codex/agents/orkestrel.toml +1 -1
- package/dist/host/codex/agents/researcher.toml +2 -2
- package/dist/host/codex/agents/verifier.toml +1 -1
- package/dist/host/codex/config.toml +3 -3
- package/dist/host/configs/helpers.ts +21 -1
- package/dist/host/configs/policy.ts +405 -16
- package/dist/host/cursor/rules/orchestration.mdc +1 -0
- package/dist/host/dotfiles/oxlintrc.json +141 -5
- package/dist/host/guides/agent.md +111 -134
- package/dist/host/guides/capture.md +801 -0
- package/dist/host/guides/probe.md +27 -8
- package/dist/host/guides/scaffold.md +152 -19
- package/dist/host/guides/study.md +534 -440
- package/dist/host/guides/test.md +111 -44
- package/dist/host/manifest.json +199 -242
- package/dist/host/tests/config.test.ts +1558 -219
- package/dist/host/tests/policy.test.ts +127 -1
- package/dist/host/tests/setupPolicy.ts +1389 -39
- package/dist/src/core/index.cjs +239 -87
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +123 -39
- package/dist/src/core/index.d.ts +123 -39
- package/dist/src/core/index.js +234 -86
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +20 -27
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.js +21 -28
- package/dist/src/server/index.js.map +1 -1
- package/package.json +11 -11
- package/dist/agents/skills/orkestrel-dispatch/scripts/helpers.js +0 -283
- package/dist/host/agents/skills/orkestrel-dispatch/references/bench.md +0 -25
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +0 -333
- package/dist/host/agents/skills/orkestrel-parallel/references/harnesses.md +0 -19
- package/dist/host/guides/supervisor.md +0 -4890
|
@@ -18,10 +18,6 @@ description: Prove a browser application the way a person uses it — real keyst
|
|
|
18
18
|
7. The `*/types.ts` of every environment the journeys drive, plus the application's root component,
|
|
19
19
|
route entry, and store contract.
|
|
20
20
|
|
|
21
|
-
Treat a retained readiness verdict as evidence to re-verify against the current tip, never as a plan
|
|
22
|
-
to resume. Re-take every ruling it records that this run's acceptance depends on, and name the commit
|
|
23
|
-
each ruling was taken at.
|
|
24
|
-
|
|
25
21
|
## Declare the families
|
|
26
22
|
|
|
27
23
|
Declare in the browser environment's `integration.test.ts` which families that screen carries, and
|
|
@@ -82,19 +78,19 @@ start, and let it choose the capture destination, the matrix row, and the statec
|
|
|
82
78
|
browser application is born with. Its presence is the journey axis. Rename and extend the seeded
|
|
83
79
|
viewports for this application.
|
|
84
80
|
- Activate the axis in a workspace born before it: write `configs/app/vite.journey.config.ts`, run
|
|
85
|
-
`scaffold
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
`scaffold audit`, and add any missing planned dependencies it names before `scaffold repair`.
|
|
82
|
+
Then add `npm run test:journey` to the `test` script after `npm run test:app`.
|
|
83
|
+
The repair defines `appJourney` in the root configuration, emits `test:journey`, `journey`, and
|
|
84
|
+
`capture`, and excludes the journey suite from the ordinary `app:browser` project. It does not rewrite the `test`
|
|
88
85
|
chain, so the chain entry is yours to add. Add that entry before the repair instead where you
|
|
89
86
|
prefer: `test:journey` names a configuration rather than a project, so neither order blocks the
|
|
90
87
|
repair.
|
|
91
|
-
- Name each variant
|
|
92
|
-
theme from the viewport; a split writes a filename naming a combination the run did not render.
|
|
88
|
+
- Name each variant per [captures.md](references/captures.md) → Variants.
|
|
93
89
|
- Keep the provided variants as serializable `JourneyVariant` data: `name`, `width`, and `height`.
|
|
94
90
|
Compose no callback merely to pass that data to a capture.
|
|
95
|
-
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
- Keep `npm run test:journey` as the whole-suite gate in the `test` chain. Use the scoped commands
|
|
92
|
+
under Choosing what to run for iteration and stamped frames; keep the root configuration's
|
|
93
|
+
`CAPTURE === '1'` read and its `capture` provide unchanged.
|
|
98
94
|
- Keep the journeys in `tests/app/browser/integration.test.ts`, and the journeys of the `vue`
|
|
99
95
|
extension's application in `tests/app/vue/integration.test.ts`, which `npm run test:journey:vue`
|
|
100
96
|
runs. Each variant project of a mode collects that file alone, and the application's ordinary
|
|
@@ -104,19 +100,65 @@ start, and let it choose the capture destination, the matrix row, and the statec
|
|
|
104
100
|
- Render exactly one variant per run for the capture family
|
|
105
101
|
([captures.md](references/captures.md) → Variants).
|
|
106
102
|
|
|
107
|
-
`scaffold audit` reports a manifest and a wrapper that disagree as one of the
|
|
108
|
-
Settle the one it reports before trusting a green run.
|
|
103
|
+
`scaffold audit` reports a manifest and a wrapper that disagree as one of these findings. Settle the one it reports before trusting a green run.
|
|
109
104
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
| `The manifest at <target> names a Vitest configuration the plan does not emit and the target does not hold: test:journey --config configs/app/vite.journey.config.ts. Add the configuration, or remove the script that names it and its invocation from the test chain.` | Writing the wrapper and running `scaffold repair`, or removing the `test:journey` script and its chain invocation |
|
|
113
|
-
| `The manifest at <target> does not invoke npm run test:journey from its test chain. Add npm run test:journey after npm run test:app.` | Adding `npm run test:journey` to the `test` script after `npm run test:app` |
|
|
105
|
+
- The manifest names a Vitest configuration for `test:journey` that the plan does not emit and the target does not hold. Write the wrapper and run `scaffold repair`, or remove the `test:journey` script and its chain invocation.
|
|
106
|
+
- The manifest does not invoke `npm run test:journey` from its `test` chain. Add `npm run test:journey` to the `test` script after `npm run test:app`.
|
|
114
107
|
|
|
115
108
|
`scaffold audit` reports the invocation question only when no chain from `test` reaches
|
|
116
109
|
`npm run test:journey` through literal `npm run` calls, so a chain reaching it through an
|
|
117
110
|
intermediate script raises none. It reports the configuration question only for a `test:*` script
|
|
118
111
|
whose text names `vitest`, so a script naming another runner's configuration raises none either.
|
|
119
112
|
|
|
113
|
+
### Choosing what to run
|
|
114
|
+
|
|
115
|
+
- Run the installed `@orkestrel/capture` package at `node_modules/@orkestrel/capture` through
|
|
116
|
+
`npm run journey -- <selector>` (`capture journey`) for owner-selected behavior with capture
|
|
117
|
+
off, and `npm run capture -- <selector>` (`capture frames`) for capture-bearing journeys with
|
|
118
|
+
`CAPTURE=1`. Keep the commands separate; never append capture work to a behavior run.
|
|
119
|
+
- Before using scoped commands, wire the adopter-owned journey wrapper's discovery, selection
|
|
120
|
+
request, tags, portfolios, registry, and final-case records to the package protocol. Read the
|
|
121
|
+
`@orkestrel/capture` guide's Runner and Runner selection and process protocol sections; scaffold
|
|
122
|
+
seeds the commands and dependency, while the application supplies these declarations.
|
|
123
|
+
- Select `all` or a colon-delimited owner path from the wrapper's tags: `<scope>`,
|
|
124
|
+
`<scope>:<owner>`, or further declared descendants. Use the wrapper's names, never infer them
|
|
125
|
+
from filenames. Keep behavior on the positive `owner:` filter and frames on its intersection
|
|
126
|
+
with the selected capture tags; include the final case in each selection.
|
|
127
|
+
- Narrow with `--variant <name>` (repeatable) and `--case <exact-full-name>`. Use `--state <name>`
|
|
128
|
+
only with frames to resolve its declaring case from fresh evidence. Use `--config <path>` to
|
|
129
|
+
select another wrapper. Give each value-taking flag a nonempty value; use `--flag=value` when
|
|
130
|
+
the value starts with `-`. Pass no second `--` terminator to the executable.
|
|
131
|
+
- Replace the selector with `--changed <ref>` to select changed owners; use `HEAD` for uncommitted
|
|
132
|
+
work. Inspect `--changed <ref> --plan` first: discovery runs, but no execution child starts.
|
|
133
|
+
Read each path's `own`, `shared`, or `outside` classification and the exact next commands.
|
|
134
|
+
Follow a shared-input refusal's explicit whole-suite command; never widen automatically.
|
|
135
|
+
- Refuse a bare command, an unknown selector or variant, an unknown or command-inappropriate
|
|
136
|
+
flag, a repeated single-value flag, a selector beside `--changed`, and `--plan` without
|
|
137
|
+
`--changed`. Treat an empty workload as failure. Follow the reported refresh command when
|
|
138
|
+
state evidence or the accepted registry is missing, stale, or ambiguous.
|
|
139
|
+
- Read the authenticated selection request in the wrapper. Before a behavioral body writes a
|
|
140
|
+
frame, refuse a selected case that declares a state outside the selected owner; split that
|
|
141
|
+
case instead of parking its outside states. Keep the full behavioral placement proof when
|
|
142
|
+
`--state` projects only the requested written frame.
|
|
143
|
+
- Run selected journey variants together in declaration order with capture off. For frames,
|
|
144
|
+
produce the declared first variant in `narrow` before `rest`; when that variant is not
|
|
145
|
+
selected, run only `rest`. Stop after a failed stage, and add no unselected variant or owner.
|
|
146
|
+
|
|
147
|
+
Climb this ladder using only declared owner, case, and variant names:
|
|
148
|
+
|
|
149
|
+
1. One case on one variant: `npm run journey -- pages:mail --case 'mail shows the inbox' --variant light-390`.
|
|
150
|
+
2. The changed set: inspect `npm run journey -- --changed HEAD --plan`, then run
|
|
151
|
+
`npm run journey -- --changed HEAD`. For frames, inspect `npm run capture -- --changed HEAD --plan`
|
|
152
|
+
before `npm run capture -- --changed HEAD`.
|
|
153
|
+
3. A section or page: `npm run journey -- pages:mail:inbox` or `npm run journey -- pages:mail`.
|
|
154
|
+
4. A group: `npm run journey -- pages`.
|
|
155
|
+
5. `all` at the gate: `npm run journey -- all`, retaining `npm run test:journey` in the repository's
|
|
156
|
+
whole-suite test chain.
|
|
157
|
+
|
|
158
|
+
Follow a refusal's exact next commands before widening a selection. Use the matching `capture`
|
|
159
|
+
script only when the work needs frames, and apply [captures.md](references/captures.md) before
|
|
160
|
+
judging their freshness or completeness.
|
|
161
|
+
|
|
120
162
|
### Prepare the capture theme
|
|
121
163
|
|
|
122
164
|
- Where the application ships a theme control, await the theme action through that interface
|
|
@@ -182,41 +224,15 @@ await PORTFOLIO.place('home')
|
|
|
182
224
|
|
|
183
225
|
## Apply the journey laws
|
|
184
226
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
cannot be performed through the interface as a finding about the interface.
|
|
189
|
-
2. **Assert what is seen.** Quote the rendered text a person reads, which is `innerText` — a label
|
|
190
|
-
under `text-uppercase` asserts as `TRACE` where the source says `Trace`. Never let an entity
|
|
191
|
-
state read replace a perception assertion; it may only corroborate one, and
|
|
192
|
-
`.claude/rules/tests.md` fixes which entity state a test may read at all.
|
|
193
|
-
3. **Assert what the interface withholds.** Assert every refusal through the resolver's exact
|
|
194
|
-
failure voice, and distinguish an absent control from a present but humanly unreachable one.
|
|
195
|
-
4. **Keep transport and persistence proofs in their own declared block,** never inside a journey.
|
|
196
|
-
Assert every live or asynchronous fact by convergence — poll until it contains or equals — never
|
|
197
|
-
by an identity read of one frame.
|
|
198
|
-
5. **Generate the portfolio from the acceptance journeys.** Place each registered state inside the
|
|
199
|
-
journey that reaches it, and never register a state no journey reaches.
|
|
200
|
-
6. **Commit a value through an act a person performs:** `pressKeys('{Enter}')` on the focused
|
|
201
|
-
control, a Tab away, or a named button. Report a screen that commits on a timer, on an
|
|
202
|
-
unpredictable event, or only after work the person cannot observe as a screen finding, and never
|
|
203
|
-
work around it in the layer.
|
|
204
|
-
7. **Type only what a person would.** Journeys carry trusted input; inputs no person would type
|
|
205
|
-
belong to the transport family and the parser suites.
|
|
206
|
-
8. **Perform every interaction step unconditionally.** Never gate a step on whether the control it
|
|
207
|
-
is about to drive exists or is reachable, and never branch a journey on `readRefusal`. Let the
|
|
208
|
-
resolver's failure voice name what the interface withheld. A guarded step passes whether or not
|
|
209
|
-
the control was there, so the run goes green on a screen that removed the control.
|
|
227
|
+
- Write every journey under `.claude/rules/tests.md` § Journey tests.
|
|
228
|
+
- Generate the portfolio from the acceptance journeys. Place each registered state inside the
|
|
229
|
+
journey that reaches it, and never register a state no journey reaches.
|
|
210
230
|
|
|
211
231
|
## Import the journey layer
|
|
212
232
|
|
|
213
|
-
-
|
|
214
|
-
|
|
215
|
-
where those entries publish none for the act ([layer.md](references/layer.md) → Import, never
|
|
233
|
+
- Write a verb, reader, or wait of your own only where the entries `.claude/rules/tests.md`
|
|
234
|
+
§ Journey tests names publish none for the act ([layer.md](references/layer.md) → Import, never
|
|
216
235
|
implement).
|
|
217
|
-
- Send every key sequence through `pressKeys`, which refuses a sequence sent while nothing but the
|
|
218
|
-
document body holds focus. Never reach past it to the provider's own keyboard function from a
|
|
219
|
-
journey, a matrix reading, or a statechart phase.
|
|
220
236
|
- Place a helper you must write in the workspace's browser test setup module, name it for the act,
|
|
221
237
|
and export it from there under `.claude/rules/tests.md`. Never declare a resolver inside a test
|
|
222
238
|
file.
|
|
@@ -231,30 +247,8 @@ await PORTFOLIO.place('home')
|
|
|
231
247
|
|
|
232
248
|
Write one journey per user intent, named for what the person achieves rather than for the
|
|
233
249
|
components it passes through. Place them in the browser environment's `integration.test.ts`, whose
|
|
234
|
-
placement and scope `.claude/rules/tests.md` fixes.
|
|
235
|
-
|
|
236
|
-
- Enter through the real entry: mount the shipped root component with a real store and the route a
|
|
237
|
-
person lands on, and let the application load itself.
|
|
238
|
-
- Reach each screen's own controls through forward Tab traversal in at least one journey.
|
|
239
|
-
- Type keystroke by keystroke where the keystrokes are the subject; fill in one operation where the
|
|
240
|
-
text is only a payload the person pastes.
|
|
241
|
-
- Poll every fact the application produces asynchronously until it converges. Never assert one from
|
|
242
|
-
a single read after the action. A poll's predicate must be able to go false-to-true after the
|
|
243
|
-
action it observes; a predicate already true when the poll starts binds nothing.
|
|
244
|
-
- Assert the state the flow must reach, never the transient path taken to it. A criterion that bans
|
|
245
|
-
a harmless transient over-refuses and breaks on the next honest implementation.
|
|
246
|
-
- Assert the negative beside the positive whenever a value replaces another: name the arriving
|
|
247
|
-
sentence and carry the replaced one in `absent`, so the reading that resolves carries one and not
|
|
248
|
-
the other ([layer.md](references/layer.md) → The waits).
|
|
249
|
-
- Assert the state a control announces beside every drive that sets it, and on an unselected
|
|
250
|
-
sibling. A control announcing state owes this assertion whether or not the screen carries the
|
|
251
|
-
statechart family.
|
|
252
|
-
- After a confirmed destructive action, assert through trusted input that focus landed on a visible,
|
|
253
|
-
announced location.
|
|
254
|
-
- Assert the whole page's perception never matches the vocabulary the product does not speak —
|
|
255
|
-
engine, schema, and implementation words the interface is supposed to translate.
|
|
256
|
-
- Report a bare accessible name that answers for more than one reachable element on one screen as a screen
|
|
257
|
-
finding, and target through role or region until the screen is fixed.
|
|
250
|
+
placement and scope `.claude/rules/tests.md` fixes. Carry a replaced value in `absent` as
|
|
251
|
+
[layer.md](references/layer.md) → The waits shows.
|
|
258
252
|
|
|
259
253
|
### The intents every screen owes
|
|
260
254
|
|
|
@@ -352,34 +346,17 @@ Mutate each assertion class once, read the red, restore, and read the green.
|
|
|
352
346
|
|
|
353
347
|
Completion requires all of:
|
|
354
348
|
|
|
355
|
-
- every in-scope user intent reaching its outcome through the interface
|
|
356
|
-
past it;
|
|
357
|
-
- the intents every screen owes present wherever the screen has the state, each outcome taken from
|
|
358
|
-
the product guide and every missing one reported as a product finding;
|
|
359
|
-
- keyboard-only reachability proven on every screen the journeys cover;
|
|
349
|
+
- every in-scope user intent, the intents every screen owes included, reaching its outcome through the interface with no step that reaches past it, and keyboard-only reachability proven on every screen the journeys cover;
|
|
360
350
|
- a refusal family per screen, each asserting one exact failure voice;
|
|
361
|
-
- the
|
|
362
|
-
- the declared
|
|
363
|
-
- the
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
- the authored-class census and the `extractStyles` reading taken on the mounted screen, each
|
|
367
|
-
reporting the population it walked;
|
|
368
|
-
- the statechart table driven to a terminal status with no failed row, and the harness tally read
|
|
369
|
-
from the object and from its markup;
|
|
370
|
-
- the registry-times-variants filename proof and the state-placement proof green in an ordinary run;
|
|
371
|
-
- one capture run per variant writing every registered file, and the disk-membership proof green;
|
|
372
|
-
- the written artifact produced for every variant the run rendered, named by that variant;
|
|
373
|
-
- perception assertions quoting rendered text, and the vocabulary sweep green on the whole page;
|
|
374
|
-
- the browser test setup module proven by `tests/setupBrowser.test.ts` in the `setup:browser`
|
|
375
|
-
project `scaffold repair` registers;
|
|
351
|
+
- the declared families each proven, the declaration asserted, and the transport family driven through real implementations;
|
|
352
|
+
- the matrix family read once per declared variant, each style reading carrying its published control from [styles.md](references/styles.md) → The published controls, and the authored-class census and the `extractStyles` reading each reporting the population it walked;
|
|
353
|
+
- the statechart table driven to a terminal status with no failed row, and the harness tally read from the object and from its markup;
|
|
354
|
+
- the registry-times-variants filename proof and the state-placement proof green in an ordinary run, one capture run per variant writing every registered file, and the written artifact produced for every variant, named by that variant;
|
|
355
|
+
- the browser test setup module proven by `tests/setupBrowser.test.ts` in the `setup:browser` project `scaffold repair` registers;
|
|
376
356
|
- each assertion class mutated, with the red reading and the green reading recorded;
|
|
377
|
-
- the repository gates green,
|
|
357
|
+
- the repository gates green, per `.agents/orchestration.md` § Acceptance.
|
|
378
358
|
|
|
379
|
-
State the engine bound with the verdict
|
|
380
|
-
engine is unproven until a reading on that engine records it. The emitted `configs/browsers.ts` doc
|
|
381
|
-
block is the home of that limit and of the condition that reopens it. Cite that doc block, and copy
|
|
382
|
-
neither into a verdict.
|
|
359
|
+
State the engine bound with the verdict, per [styles.md](references/styles.md) → The engine bound.
|
|
383
360
|
|
|
384
361
|
Report each journey by the intent it proves, the refusals it establishes, the states it placed, the
|
|
385
362
|
variants it read, the statechart outcome it reached, and every screen finding the layer's refusals
|
|
@@ -11,7 +11,7 @@ import type { JourneyVariant } from '@orkestrel/test'
|
|
|
11
11
|
import type {
|
|
12
12
|
CaptureVariant,
|
|
13
13
|
FrameOptions,
|
|
14
|
-
|
|
14
|
+
FrameResult,
|
|
15
15
|
PortfolioInterface,
|
|
16
16
|
PortfolioOptions,
|
|
17
17
|
} from '@orkestrel/test/browser'
|
|
@@ -54,12 +54,38 @@ Declare the state names once in the journey file, and build the portfolio from t
|
|
|
54
54
|
|
|
55
55
|
- Name a state for its screen and its condition — `answer-partial`, `start-storage-failure`,
|
|
56
56
|
`case-delete-confirmation`.
|
|
57
|
-
- Register the states the design work
|
|
58
|
-
registered state
|
|
57
|
+
- Register the states the design work needs, and give every registered state a declaring case.
|
|
58
|
+
In a complete run, place every registered state; in a scoped run, place every state the cases
|
|
59
|
+
that ran declare.
|
|
59
60
|
- Place a capture state from inside the journey that reaches it, immediately after the assertion
|
|
60
61
|
that proves the screen is in the condition that state names.
|
|
61
62
|
- Record each placed name in the suite's own set in the same step that calls `place`. That set, not
|
|
62
63
|
`placements`, is what the always-on placement proof reads.
|
|
64
|
+
- Give each owner-bearing case registry-derived `owner:` tags. Declare a placing case's states in
|
|
65
|
+
`meta.states`, derive its capture scope and part tags from those states, and place only states
|
|
66
|
+
of that owner. Give behavior-only cases no capture tag.
|
|
67
|
+
- Derive variant-conditional declarations and placements from the same predicate. Keep the
|
|
68
|
+
ownerless infrastructure cases explicit, outside behavioral work counts and completeness.
|
|
69
|
+
- Store frames in their declared per-scope directories, and pass those roots to the wrapper's
|
|
70
|
+
portfolio declarations.
|
|
71
|
+
|
|
72
|
+
## Scoped commands
|
|
73
|
+
|
|
74
|
+
- Run `npm run journey -- <selector>` for behavior and `npm run capture -- <selector>` for frames.
|
|
75
|
+
Take both commands from `node_modules/@orkestrel/capture`; follow
|
|
76
|
+
[SKILL.md](../SKILL.md#choosing-what-to-run) for selector grammar, flags, refusals, and the
|
|
77
|
+
case, changed-set, section or page, group, and `all` ladder. Retain `test:journey` as the
|
|
78
|
+
whole-suite gate.
|
|
79
|
+
- Inspect the changed set with `--changed <ref> --plan` before executing it. Keep a shared-input
|
|
80
|
+
refusal explicit, and follow its next command without silently capturing the complement.
|
|
81
|
+
- Use the authenticated selection request to refuse a case whose declared states cross the
|
|
82
|
+
selected owner before any behavioral body runs. Split the case; never park the outside states.
|
|
83
|
+
- Resolve a frames-only `--state` request from fresh registry and passing case evidence. Keep the
|
|
84
|
+
declaring case's behavior and full placement proof, projecting only the written frames onto
|
|
85
|
+
the requested state. Follow the explicit refresh command when the lookup refuses.
|
|
86
|
+
- Keep each variant project on one rendered variant. Produce the selected first variant in
|
|
87
|
+
`narrow`, then the remaining selected variants in `rest`; omit `narrow` when its variant is
|
|
88
|
+
not selected and stop after a failed stage.
|
|
63
89
|
|
|
64
90
|
## Variants
|
|
65
91
|
|
|
@@ -71,37 +97,47 @@ these.
|
|
|
71
97
|
application's to set, and the presence of that file is the journey axis.
|
|
72
98
|
- Prepare the theme under [SKILL.md](../SKILL.md#prepare-the-capture-theme) before driving the
|
|
73
99
|
captured state, and use the variant list that preparation requires.
|
|
74
|
-
- Name each variant for the theme and the viewport it renders, such as `dark-390`.
|
|
75
|
-
second half of every filename the run writes, so a
|
|
76
|
-
|
|
100
|
+
- Name each variant for the theme and the viewport it renders, such as `dark-390`. Never split the
|
|
101
|
+
theme from the viewport. The name is the second half of every filename the run writes, so a
|
|
102
|
+
variant named for one alone writes a filename naming a combination the run did not render.
|
|
77
103
|
- Pass the whole declared list as `variants` and `inject('variant')` as `variant`.
|
|
78
104
|
`createPortfolio` refuses a `variant` no declared variant carries, and `files` expands the
|
|
79
105
|
registry across the whole list rather than across the one being rendered.
|
|
80
|
-
- Produce the portfolio
|
|
81
|
-
|
|
106
|
+
- Produce the complete stamped portfolio with `npm run capture -- all`, which runs the declared
|
|
107
|
+
variant projects through the capture runner. Keep `npm run test:journey` as the complete
|
|
108
|
+
behavioral gate; a bare capture-flag run supplies no manifest stamp.
|
|
82
109
|
|
|
83
110
|
## The proofs the suite owes
|
|
84
111
|
|
|
85
112
|
Write each of the following proofs into the suite. The package asserts none of them.
|
|
86
113
|
|
|
87
|
-
| Proof | Runs | Asserts
|
|
88
|
-
| -------------------- | -------------- |
|
|
89
|
-
| Filename expansion | Always | `expandCaptures(states, variants)` has one entry per state and variant, all unique
|
|
90
|
-
|
|
|
91
|
-
|
|
|
114
|
+
| Proof | Runs | Asserts |
|
|
115
|
+
| -------------------- | -------------- | ------------------------------------------------------------------------------------------------------- |
|
|
116
|
+
| Filename expansion | Always | `expandCaptures(states, variants)` has one entry per state and variant, all unique |
|
|
117
|
+
| Declaration coverage | Always | The case declarations cover the registry, are disjoint, and match the owner and capture tag definitions |
|
|
118
|
+
| Placement membership | Always | The suite's placed set equals the states declared by the cases that ran, as sets |
|
|
119
|
+
| Disk membership | Under the flag | The written filenames equal the selected expansion for this run's variant, with no orphan on disk |
|
|
92
120
|
|
|
93
121
|
- Keep the filename proof always-on, so a registry edit that introduces a duplicate or a collision
|
|
94
122
|
fails the ordinary run. Compare `expandCaptures(states, variants)` against `files` and against a
|
|
95
123
|
set built from it; a length equal to the set's size is what proves the expansion unique.
|
|
96
|
-
- Assert
|
|
124
|
+
- Assert declaration coverage even in a scoped run: fail a registered state declared nowhere,
|
|
125
|
+
overlapping declarations, or an owner or capture tag definition that differs from the registry.
|
|
126
|
+
- Assert placement as set equality against the union of the states the cases that ran declare.
|
|
127
|
+
When every case ran, require that union to equal the registry. Derive completeness from the
|
|
128
|
+
recorded cases that ran and passed, never from the selector or a task's mode alone.
|
|
97
129
|
- Read the placement proof from the suite's own set rather than from `placements`, which stays empty
|
|
98
130
|
in an ordinary run. `place` refuses an unregistered name and a second placement of one state in
|
|
99
131
|
every run, but a registered state that no journey placed reaches no refusal; the always-on
|
|
100
132
|
placement proof catches it.
|
|
101
|
-
- Under the flag, assert the written filenames equal the
|
|
133
|
+
- Under the flag, assert the written filenames equal the ran cases' declared states expanded for
|
|
134
|
+
the run's variant, or the explicit state's projection. Keep the full placement assertion in
|
|
135
|
+
that projected run, and refuse an orphan on disk while retaining untouched registered frames.
|
|
102
136
|
`captureFrame` already reads each file back and compares its bytes against the frame it shot, so
|
|
103
137
|
the path `place` returns is proof the file exists and holds that frame.
|
|
104
138
|
- Put the membership proof last in the file, after every journey that feeds its tally.
|
|
139
|
+
- At group closure, prove the union of the group's declarations and its cross-section
|
|
140
|
+
interactions. Run the whole-registry census only when complete reference coverage ran.
|
|
105
141
|
|
|
106
142
|
## Transient states
|
|
107
143
|
|
|
@@ -118,7 +154,8 @@ after the click returns.
|
|
|
118
154
|
- Take each frame after the paint settles. Reach for `waitForAnimations` on the element whose
|
|
119
155
|
transition was running ([layer.md](layer.md) → The waits); a frame shot mid-transition pictures a
|
|
120
156
|
state the interface never rests in.
|
|
121
|
-
-
|
|
122
|
-
|
|
157
|
+
- Judge only frames the capture manifest records as current: every source digest the frame
|
|
158
|
+
recorded must equal the tree's. Recapture what the staleness report names before the round.
|
|
159
|
+
Admit a portfolio assembled from several runs only when every judged frame is current.
|
|
123
160
|
- Route review of the portfolio to the `orkestrel-polish` campaign, which owns preflight,
|
|
124
161
|
verdicts, and reconciliation. This reference owns only how the journeys generate it.
|
|
@@ -26,26 +26,7 @@ follow it there rather than restating it here.
|
|
|
26
26
|
|
|
27
27
|
## The limit that decides the split
|
|
28
28
|
|
|
29
|
-
`prove` cannot serve a browser project, and the
|
|
30
|
-
rather than to a version this file names. Confirm it against the copy this workspace holds before
|
|
31
|
-
routing a rendered question, and record the version you read beside the ruling.
|
|
32
|
-
|
|
33
|
-
Read the pool pin, the project lookup, and the guide's own statement. Any of them holding is the
|
|
34
|
-
limit holding:
|
|
35
|
-
|
|
36
|
-
- **The pool pin.** Read the runtime stage in the installed server entry. Where it pins the
|
|
37
|
-
`threads` pool, a browser project's specification runs in a Node worker,
|
|
38
|
-
`@orkestrel/test/browser` imports `vitest/browser` at module scope, and the browser setup file
|
|
39
|
-
throws before the case runs.
|
|
40
|
-
- **The project lookup.** The runtime stage looks a project up by the name it infers from the test
|
|
41
|
-
path, and a browser project is instantiated under its browser-expanded name, so the lookup finds
|
|
42
|
-
nothing and the claim is refused as missing.
|
|
43
|
-
- **The guide's statement.** Read what `@orkestrel/probe`'s own guide says the stages serve. Where
|
|
44
|
-
it names no browser project, no stage claims one.
|
|
45
|
-
|
|
46
|
-
Never route a rendered question to `prove` while any of them holds. The pinned-pool refusal arrives
|
|
47
|
-
as a case failure, which reads exactly like a broken claim. Record the version, the pool pin you
|
|
48
|
-
read, and what the guide says, so the next round re-reads rather than re-deriving.
|
|
29
|
+
`prove` cannot serve a browser project. The runtime stage of `@orkestrel/probe` creates each specification with the `threads` pool (the `createSpecification` call in `node_modules/@orkestrel/probe/dist/src/server/index.js`), so a browser project's specification runs in a Node worker, where `@orkestrel/test/browser` imports `vitest/browser` and the browser setup file throws before the case runs. The refusal arrives as a case failure and reads like a broken claim. Never route a rendered question to `prove`; re-read that call in the installed copy when the package changes.
|
|
49
30
|
|
|
50
31
|
## The rendered artifact
|
|
51
32
|
|
|
@@ -153,35 +153,27 @@ act itself scrolls into view.
|
|
|
153
153
|
### The failure voices
|
|
154
154
|
|
|
155
155
|
Assert the one voice the case means. Never write an assertion that accepts more than one. This table
|
|
156
|
-
carries
|
|
157
|
-
the capture voices in [captures.md](captures.md).
|
|
158
|
-
|
|
159
|
-
| Condition | The voice thrown
|
|
160
|
-
| ------------------------------------------------------ |
|
|
161
|
-
| No element carries the name | `No interactive element has the accessible name "<name>"`
|
|
162
|
-
| Every match fails a reachability condition | `Interactive target "<name>" is not visible and focus-reachable`
|
|
163
|
-
| Several matches are reachable | `Interactive target "<name>" is ambiguous across <n> elements`
|
|
164
|
-
| Still off-viewport after being scrolled to | `Interactive target "<name>" is unreachable after scrolling`
|
|
165
|
-
| The region holds no reachable match | `Interactive target "<name>" is not reachable inside "<region>"`
|
|
166
|
-
| The region holds several reachable matches | `Interactive target "<name>" is ambiguous across <n> elements inside "<region>"`
|
|
167
|
-
| No native disclosure is reachable under the name | `Native disclosure "<name>" is not visible and focus-reachable`
|
|
168
|
-
| Several native disclosures carry the name | `Native disclosure "<name>" is ambiguous across <n> elements`
|
|
169
|
-
| Forward Tab never lands on the target | `Interactive target "<name>" is not reachable through forward Tab traversal: <trail>`
|
|
170
|
-
| The named region is hidden | `Named region "<name>" is not visible`
|
|
171
|
-
| Several named regions carry the name | `Named region "<name>" is ambiguous across <n> elements`
|
|
172
|
-
| The resolved control renders no value | `Interactive target "<name>" does not carry a value`
|
|
173
|
-
| A key sequence reached nothing | `Key sequence "<keys>" was sent with nothing focused`
|
|
174
|
-
|
|
|
175
|
-
|
|
|
176
|
-
|
|
|
177
|
-
| The sentence never arrived | `Condition "<description>" did not hold within <n>ms (waited <n>ms)` | `waitForText` |
|
|
178
|
-
| A host withholds `getItem`, `setItem`, or `removeItem` | `Access is denied for <operation> "<key>"` | `createStorage` |
|
|
179
|
-
| A host withholds `length`, `clear`, or `key` | `Access is denied for <operation>` | `createStorage` |
|
|
180
|
-
| A write ran past the declared quota | `No room is left for <key>` | `createStorage` |
|
|
181
|
-
| A style reading has no computed color | `Computed foreground color is unavailable` | `readContrast` |
|
|
182
|
-
| A class census walked nothing | `Class census walked no element` | `readCensus` |
|
|
183
|
-
| A contrast control cannot straddle its bar | `Contrast control cannot straddle the bar <bar>` | `buildContrast` |
|
|
184
|
-
| A database deletion was blocked | `IndexedDB database "<name>" is blocked by an open connection` | `removeDatabase` |
|
|
156
|
+
carries the voices a journey asserts. Read the statechart voices in [statechart.md](statechart.md),
|
|
157
|
+
the capture voices in [captures.md](captures.md), and every other voice in `guides/test.md` § Voices.
|
|
158
|
+
|
|
159
|
+
| Condition | The voice thrown | Thrown by |
|
|
160
|
+
| ------------------------------------------------------ | ------------------------------------------------------------------------------------- | ----------------------- |
|
|
161
|
+
| No element carries the name | `No interactive element has the accessible name "<name>"` | `resolveRendered` |
|
|
162
|
+
| Every match fails a reachability condition | `Interactive target "<name>" is not visible and focus-reachable` | `resolveRendered` |
|
|
163
|
+
| Several matches are reachable | `Interactive target "<name>" is ambiguous across <n> elements` | `resolveRendered` |
|
|
164
|
+
| Still off-viewport after being scrolled to | `Interactive target "<name>" is unreachable after scrolling` | `resolveAccessible` |
|
|
165
|
+
| The region holds no reachable match | `Interactive target "<name>" is not reachable inside "<region>"` | `clickAccessibleWithin` |
|
|
166
|
+
| The region holds several reachable matches | `Interactive target "<name>" is ambiguous across <n> elements inside "<region>"` | `clickAccessibleWithin` |
|
|
167
|
+
| No native disclosure is reachable under the name | `Native disclosure "<name>" is not visible and focus-reachable` | `clickDisclosure` |
|
|
168
|
+
| Several native disclosures carry the name | `Native disclosure "<name>" is ambiguous across <n> elements` | `clickDisclosure` |
|
|
169
|
+
| Forward Tab never lands on the target | `Interactive target "<name>" is not reachable through forward Tab traversal: <trail>` | `traverseAccessible` |
|
|
170
|
+
| The named region is hidden | `Named region "<name>" is not visible` | `readPerception` |
|
|
171
|
+
| Several named regions carry the name | `Named region "<name>" is ambiguous across <n> elements` | `readPerception` |
|
|
172
|
+
| The resolved control renders no value | `Interactive target "<name>" does not carry a value` | `readValue` |
|
|
173
|
+
| A key sequence reached nothing | `Key sequence "<keys>" was sent with nothing focused` | `pressKeys` |
|
|
174
|
+
| A host withholds `getItem`, `setItem`, or `removeItem` | `Access is denied for <operation> "<key>"` | `createStorage` |
|
|
175
|
+
| A host withholds `length`, `clear`, or `key` | `Access is denied for <operation>` | `createStorage` |
|
|
176
|
+
| A write ran past the declared quota | `No room is left for <key>` | `createStorage` |
|
|
185
177
|
|
|
186
178
|
- Report an absent control and a present-but-unreachable one as different findings: absence names
|
|
187
179
|
a missing control, and unreachability names the interface gating one that exists.
|
|
@@ -195,8 +187,6 @@ the capture voices in [captures.md](captures.md).
|
|
|
195
187
|
- Read a refused bound as a test defect rather than a finding. The wait family validates its budget
|
|
196
188
|
and its interval and names the argument the caller passed, under the subject `Wait` or
|
|
197
189
|
`Animation`.
|
|
198
|
-
- Read the package's own voice table before asserting a message this file does not list. A workspace
|
|
199
|
-
that transcribes a voice by memory asserts a sentence the package does not throw.
|
|
200
190
|
|
|
201
191
|
## Input and traversal
|
|
202
192
|
|