@orkestrel/scaffold 0.0.59 → 0.0.61

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.
Files changed (76) hide show
  1. package/README.md +13 -10
  2. package/dist/bin/main.js +632 -320
  3. package/dist/bin/main.js.map +1 -1
  4. package/dist/host/CLAUDE.md +5 -1
  5. package/dist/host/agents/orchestration.md +44 -19
  6. package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +91 -82
  7. package/dist/host/agents/skills/enterprise-bootstrap/references/bootstrap-reference.md +5 -5
  8. package/dist/host/agents/skills/enterprise-bootstrap/references/components.md +15 -15
  9. package/dist/host/agents/skills/enterprise-bootstrap/references/inputs.md +501 -0
  10. package/dist/host/agents/skills/enterprise-bootstrap/references/inspection.md +167 -0
  11. package/dist/host/agents/skills/enterprise-bootstrap/references/utilities.md +2 -2
  12. package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +2 -2
  13. package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +10 -9
  14. package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +21 -11
  15. package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +20 -2
  16. package/dist/host/agents/skills/orkestrel-harden-package/SKILL.md +1 -1
  17. package/dist/host/agents/skills/orkestrel-harden-package/references/hardening.md +1 -1
  18. package/dist/host/agents/skills/orkestrel-harden-package/references/research.md +1 -1
  19. package/dist/host/agents/skills/orkestrel-polish-surface/SKILL.md +4 -1
  20. package/dist/host/agents/skills/orkestrel-polish-surface/references/capture-harness.md +71 -50
  21. package/dist/host/agents/skills/orkestrel-prove-journey/SKILL.md +93 -29
  22. package/dist/host/agents/skills/orkestrel-prove-journey/agents/openai.yaml +1 -1
  23. package/dist/host/agents/skills/orkestrel-prove-journey/references/captures.md +62 -38
  24. package/dist/host/agents/skills/orkestrel-prove-journey/references/decide.md +68 -0
  25. package/dist/host/agents/skills/orkestrel-prove-journey/references/layer.md +107 -79
  26. package/dist/host/agents/skills/orkestrel-prove-journey/references/statechart.md +84 -0
  27. package/dist/host/agents/skills/orkestrel-prove-journey/references/styles.md +87 -0
  28. package/dist/host/agents/templates/brief.md +16 -7
  29. package/dist/host/agents/transports/claude.md +4 -2
  30. package/dist/host/agents/transports/codex.md +4 -1
  31. package/dist/host/claude/agents/analyst.md +3 -1
  32. package/dist/host/claude/agents/application.md +1 -1
  33. package/dist/host/claude/agents/builder.md +3 -3
  34. package/dist/host/claude/agents/checker.md +5 -0
  35. package/dist/host/claude/agents/grok.md +15 -5
  36. package/dist/host/claude/agents/implementer.md +1 -1
  37. package/dist/host/claude/agents/orkestrel.md +12 -11
  38. package/dist/host/claude/agents/planner.md +10 -0
  39. package/dist/host/claude/agents/reviewer.md +14 -8
  40. package/dist/host/claude/agents/sol.md +3 -1
  41. package/dist/host/claude/agents/verifier.md +2 -4
  42. package/dist/host/claude/rules/architecture.md +7 -5
  43. package/dist/host/claude/rules/documentation.md +1 -0
  44. package/dist/host/claude/rules/names.md +23 -5
  45. package/dist/host/claude/rules/patterns.md +1 -0
  46. package/dist/host/claude/rules/quality.md +1 -1
  47. package/dist/host/claude/rules/tests.md +3 -3
  48. package/dist/host/claude/rules/typescript.md +4 -1
  49. package/dist/host/claude/rules/writing.md +2 -2
  50. package/dist/host/claude/skills/orkestrel-prove-journey/SKILL.md +1 -1
  51. package/dist/host/codex/agents/builder.toml +6 -6
  52. package/dist/host/codex/agents/checker.toml +2 -1
  53. package/dist/host/codex/agents/grok.toml +12 -5
  54. package/dist/host/codex/agents/implementer.toml +2 -2
  55. package/dist/host/codex/agents/opus.toml +6 -1
  56. package/dist/host/codex/agents/planner.toml +11 -6
  57. package/dist/host/codex/agents/reviewer.toml +8 -6
  58. package/dist/host/guides/scaffold.md +39 -14
  59. package/dist/host/manifest.json +81 -51
  60. package/dist/host/scripts/codex.sh +0 -0
  61. package/dist/host/scripts/cursor.sh +0 -0
  62. package/dist/host/scripts/deps.sh +0 -0
  63. package/dist/host/scripts/ollama.sh +0 -0
  64. package/dist/src/core/index.cjs +424 -282
  65. package/dist/src/core/index.cjs.map +1 -1
  66. package/dist/src/core/index.d.cts +361 -220
  67. package/dist/src/core/index.d.ts +361 -220
  68. package/dist/src/core/index.js +421 -283
  69. package/dist/src/core/index.js.map +1 -1
  70. package/dist/src/server/index.cjs +208 -170
  71. package/dist/src/server/index.cjs.map +1 -1
  72. package/dist/src/server/index.d.cts +276 -152
  73. package/dist/src/server/index.d.ts +276 -152
  74. package/dist/src/server/index.js +200 -172
  75. package/dist/src/server/index.js.map +1 -1
  76. package/package.json +8 -7
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: orkestrel-prove-journey
3
- description: Prove a browser application the way a person uses it — real keystrokes, clicks, and Tab/Enter against only what is visible and reachable — and generate the capture portfolio from those same journeys. Use when accepting a UI build, proving an application end to end, deciding whether a surface is reachable by keyboard alone, proving what a screen refuses as well as what it does, auditing whether the interface speaks the user's vocabulary rather than the engine's, producing the screenshots a design review judges, or whenever the only evidence a screen works is a test that drove it through JavaScript instead of through the interface.
3
+ description: Prove a browser application the way a person uses it — real keystrokes, clicks, and Tab/Enter against only what is visible and reachable — through the journey layer @orkestrel/test/browser publishes, and generate the capture portfolio, the resolved-style matrix, and the statechart outcome from those same journeys. Use when accepting a UI build, proving an application end to end, deciding whether a surface is reachable by keyboard alone, proving what a screen refuses as well as what it does, proving the styles a browser actually resolved under each theme and viewport, driving a transition table through the interface and watching it run, auditing whether the interface speaks the user's vocabulary rather than the engine's, producing the screenshots a design review judges, routing a rendered question to an artifact a model can read, or whenever the only evidence a screen works is a test that drove it through JavaScript instead of through the interface.
4
4
  ---
5
5
 
6
6
  # Prove an application through human journeys
@@ -12,24 +12,63 @@ Read the current files in this order:
12
12
  1. `AGENTS.md`.
13
13
  2. `.claude/rules/tests.md` for test law, real implementations, and shared test infrastructure;
14
14
  `.claude/rules/browser.md` for browser and Vue usage; `.claude/rules/application.md` for app
15
- composition and entries; `.claude/rules/documentation.md` for parity. Those rules are the
16
- contract; this skill is the workflow.
17
- 3. [layer.md](references/layer.md) before building, extending, or debugging the journey layer.
15
+ composition and entries; `.claude/rules/styles.md` for style centralization;
16
+ `.claude/rules/quality.md` for the instrument and negative-control law;
17
+ `.claude/rules/documentation.md` for parity. Those rules are the contract; this skill is the
18
+ workflow.
19
+ 3. [layer.md](references/layer.md) before importing, extending, or debugging the journey layer.
18
20
  4. [captures.md](references/captures.md) before registering a state or placing a capture.
19
- 5. `guides/README.md`, the governing guide for the surface, and `ROADMAP.md` when present.
20
- 6. The `*/types.ts` of every environment the journeys drive, plus the application's root component,
21
+ 5. [styles.md](references/styles.md) before asserting anything the browser resolved.
22
+ 6. [statechart.md](references/statechart.md) before declaring a transition or building the harness.
23
+ 7. [decide.md](references/decide.md) before routing a question to an instrument.
24
+ 8. `guides/README.md`, the governing guide for the surface, and `ROADMAP.md` when present.
25
+ 9. The `*/types.ts` of every environment the journeys drive, plus the application's root component,
21
26
  route entry, and store contract.
22
27
 
28
+ ## Declare the families
29
+
30
+ Declare in the browser environment's `integration.test.ts` which families that surface carries, and
31
+ assert in the always-on proofs that every declared family is present. A declaration names which
32
+ families a surface owes. It never switches what a declared family proves.
33
+
34
+ | Family | Declared | Proves |
35
+ | ---------- | --------------------------------------------------- | ---------------------------------------------------------------------- |
36
+ | Journey | Always | Each user intent reaches its outcome through the interface |
37
+ | Refusal | Always | Each control the surface withholds, through one exact failure voice |
38
+ | Matrix | Where the surface ships more than one variant | The values the browser resolved under each declared variant |
39
+ | Statechart | Where a journey drives a control that carries state | Each declared transition, driven through the interface where it can be |
40
+ | Transport | Where the surface persists or restarts | Persistence, restart, and storage failure through real implementations |
41
+ | Capture | Under the capture flag | The registry times the variants, each registered file written to disk |
42
+
43
+ - Refuse a declaration that omits a family whose trigger the surface meets. Report the omission as a
44
+ scope finding and stop; never prove the remaining families around it.
45
+ - Assert the declaration itself: a family listed with no proof, and a proof belonging to no listed
46
+ family, each fail the run.
47
+
48
+ ## Read the variant once
49
+
50
+ Read one `variant` value at run start, and let it choose the capture destination, the matrix row,
51
+ and the statechart run together. Never split the theme from the viewport; a split writes a filename
52
+ naming a combination the run did not render.
53
+
54
+ - Declare every variant once as a published `CaptureVariant` — its `name`, its `width`, its
55
+ `height`, and the `apply` that switches the theme — and read that list from the capture family and
56
+ the matrix family alike.
57
+ - Loop every declared variant inside one run for the matrix family
58
+ ([styles.md](references/styles.md) → Run per variant).
59
+ - Render exactly one variant per run for the capture family
60
+ ([captures.md](references/captures.md) → Variants).
61
+
23
62
  ## Apply the journey laws
24
63
 
25
- 1. **Drive only what a person can see and reach.** Target every control by its ARIA role and its
26
- accessible name as rendered. Never reach into a component instance, a store, a transport, a
27
- copied credential, or a test-only hook to make a step succeed. Report a step that cannot be
28
- performed through the interface as a finding about the interface.
64
+ 1. **Drive only what a person can see and reach.** Resolve every interactive target by its ARIA
65
+ role and its accessible name as rendered. Never reach into a component instance, a store, a
66
+ transport, a copied credential, or a test-only hook to make a step succeed. Report a step that
67
+ cannot be performed through the interface as a finding about the interface.
29
68
  2. **Assert what is seen.** Quote the rendered text a person reads, which is `innerText` — a label
30
- under `text-uppercase` asserts as `TRACE` where the source says `Trace`. Never let a state read
31
- replace a perception assertion; it may only corroborate one, and `.claude/rules/tests.md` fixes
32
- which state a test may read at all.
69
+ under `text-uppercase` asserts as `TRACE` where the source says `Trace`. Never let an entity
70
+ state read replace a perception assertion; it may only corroborate one, and
71
+ `.claude/rules/tests.md` fixes which entity state a test may read at all.
33
72
  3. **Assert what the interface withholds.** Assert every refusal through the resolver's exact
34
73
  failure voice, and distinguish an absent control from a present but humanly unreachable one.
35
74
  4. **Keep transport and persistence proofs in their own declared block,** never inside a journey.
@@ -43,17 +82,17 @@ Read the current files in this order:
43
82
  7. **Type only what a person would.** Journeys carry trusted input; adversarial payloads belong to
44
83
  the transport family and the parser suites.
45
84
 
46
- ## Build or verify the journey layer
47
-
48
- - Build the layer as shared browser test infrastructure under `.claude/rules/tests.md`: it lives in
49
- the workspace's browser test setup module, exports every helper from there, and adds a journey
50
- helper only where `@orkestrel/test` publishes none. Never declare a resolver inside a test file.
51
- - Give the layer every capability [layer.md](references/layer.md) fixes: the role-scoped resolver
52
- and its distinct failure voices, region-scoped resolution, the input and traversal verbs, the
53
- perception readers, and the capture hook.
54
- - Drive every step through the browser provider's user-event API, and never dispatch a constructed
55
- event ([layer.md](references/layer.md) → What it drives).
56
- - Re-verify the layer against what the application renders now whenever markup changes
85
+ ## Import the journey layer
86
+
87
+ - Import every journey verb, reader, and fixture builder from `@orkestrel/test/browser`. Write one
88
+ of your own only where that package publishes none for the act
89
+ ([layer.md](references/layer.md) → Import, never implement).
90
+ - Place a helper you must write in the workspace's browser test setup module, name it for the act,
91
+ and export it from there under `.claude/rules/tests.md`. Never declare a resolver inside a test
92
+ file.
93
+ - Drive every step through the published verbs, and never dispatch a constructed event
94
+ ([layer.md](references/layer.md) → What it drives).
95
+ - Re-verify every target against what the application renders now whenever markup changes
57
96
  ([layer.md](references/layer.md) → Role vocabulary).
58
97
 
59
98
  ## Derive journeys from intents
@@ -86,7 +125,7 @@ placement and scope `.claude/rules/tests.md` fixes.
86
125
  - Give every surface a refusal family: the controls a person must not reach in the state the
87
126
  journey has put the surface in.
88
127
  - Assert the exact failure voice the case means. Never write an assertion that accepts more than
89
- one voice.
128
+ one voice ([layer.md](references/layer.md) → The failure voices).
90
129
  - Cover the restrictions the interface imposes on itself: a collapsed panel's field, a verb
91
130
  belonging to another kind of object, a control disabled until its precondition lands.
92
131
  - When a refusal changes voice after a markup change, read it as a role or reachability change
@@ -103,17 +142,34 @@ placement and scope `.claude/rules/tests.md` fixes.
103
142
  that clears it.
104
143
  - Assert restart by starting a second session over the same store and polling the restored value.
105
144
 
145
+ ## Prove the styles
146
+
147
+ Follow [styles.md](references/styles.md) for the resolved-value law, the per-variant run, the
148
+ composited contrast reading and its under-bar negative control, the authored-class census, the
149
+ `extractStyles` reading, and the token comparison.
150
+
151
+ ## Prove the statechart
152
+
153
+ Follow [statechart.md](references/statechart.md) for the transition table, the scenario per
154
+ transition, the runner, the harness a person watches, and the gate that drives the harness through
155
+ the interface.
156
+
106
157
  ## Generate the portfolio
107
158
 
108
159
  Follow [captures.md](references/captures.md) for the state registry and its placement rules, the
109
160
  theme-and-viewport variant matrix, the always-on filename proof, the capture-run membership proof,
110
161
  and how a state that exists only during an activation is captured.
111
162
 
112
- When a capture and a green suite disagree, the capture is the evidence and the fixture is the
163
+ Where a capture and a green suite disagree, take the capture as the evidence and the fixture as the
113
164
  defect.
114
165
 
115
166
  Route review of the portfolio to the `orkestrel-polish-surface` campaign. Do not judge it here.
116
167
 
168
+ ## Route the question
169
+
170
+ Follow [decide.md](references/decide.md) before spending a round on a question. It fixes which
171
+ instrument judges which claim, what `prove` cannot serve, and what the run's written artifact holds.
172
+
117
173
  ## Accept
118
174
 
119
175
  Completion requires all of:
@@ -123,10 +179,18 @@ Completion requires all of:
123
179
  - keyboard-only reachability proven on every surface the journeys cover;
124
180
  - a refusal family per surface, each asserting one exact failure voice;
125
181
  - the transport family declared separately, driven through real implementations, and convergent;
182
+ - the declared families each proven, and the declaration itself asserted;
183
+ - the matrix family read once per declared variant, each style instrument carrying the negative
184
+ control that must read under its bar in the same run;
185
+ - the authored-class census and the `extractStyles` reading taken on the mounted surface, each
186
+ reporting the population it walked;
187
+ - the statechart table driven to a terminal outcome with no failed row, and the harness gate green;
126
188
  - the registry-times-variants filename proof and the state-placement proof green in an ordinary run;
127
- - one capture run per variant writing every registered file, each read back non-empty;
189
+ - one capture run per variant writing every registered file, and the disk-membership proof green;
190
+ - the written artifact produced for every variant the run rendered, named by that variant;
128
191
  - perception assertions quoting rendered text, and the vocabulary sweep green on the whole page;
129
192
  - the repository gates green, under the independent-verification law in `.agents/orchestration.md`.
130
193
 
131
- Report each journey by the intent it proves, the refusals it establishes, the states it placed, and
132
- every surface finding the layer's refusals exposed.
194
+ Report each journey by the intent it proves, the refusals it establishes, the states it placed, the
195
+ variants it read, the statechart outcome it reached, and every surface finding the layer's refusals
196
+ exposed.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: 'Prove Human Journeys'
3
3
  short_description: 'Prove an application through the interface a person uses'
4
- default_prompt: 'Use $orkestrel-prove-journey to prove this application through the interface a person uses, and generate the capture portfolio from those journeys.'
4
+ default_prompt: 'Use $orkestrel-prove-journey to prove this application through the interface a person uses, and generate the capture portfolio, the resolved-style matrix, and the statechart outcome from those journeys.'
@@ -4,64 +4,88 @@ Take every screenshot from an acceptance journey, at the moment that journey is
4
4
  picture names. Never add a test whose only purpose is a screenshot, and never stage a state for the
5
5
  camera that a journey did not reach through the interface.
6
6
 
7
- ## The capture hook
8
-
9
- ```ts
10
- capture(state: string): Promise<string | undefined>
11
- ```
12
-
13
- - Return `undefined` and do nothing when the capture flag is unset, so an ordinary run neither
14
- resizes the viewport nor writes a file.
15
- - Read one variant value that names the theme and the viewport together, and refuse a value that
16
- names no registered variant.
17
- - Apply that variant's theme and viewport inside the hook, so the run's single variant value is the
18
- only source of both.
19
- - Write one file named `<state>--<variant>.png` under the workspace's git-ignored `tmp/` tree, and
20
- return the path it wrote.
7
+ ## The hook
8
+
9
+ `createPortfolio(options)` is the capture door, and `place(state, element?)` is the hook. Build the
10
+ portfolio once per file from a `PortfolioOptions` value carrying the registry as `states`, every
11
+ declared `CaptureVariant` as `variants`, this run's `variant`, the `directory` each file is written
12
+ to, and the flag as `enabled`.
13
+
14
+ - Place a state with `place(state)` for the whole page, and `place(state, element)` where the
15
+ picture is one element.
16
+ - Leave `enabled` unset in an ordinary run. `place` then returns `undefined`, resizes nothing,
17
+ writes nothing, and records nothing.
18
+ - Read `files` for the registry expanded across every variant, `placements` for what this run placed,
19
+ and `paths` for what it wrote. Each hands back a snapshot.
20
+
21
+ The package already refuses these, so assert none of them again:
22
+
23
+ | Refusal | Raised by |
24
+ | -------------------------------------------------------------------- | --------------------- |
25
+ | `Capture variant "<name>" is not registered` | `createPortfolio` |
26
+ | `Capture state "<state>" is not registered` | `place`, when enabled |
27
+ | `Capture state "<state>" is already placed` | `place`, when enabled |
28
+ | `Capture frame at <path> is not the one this run shot` | `captureFrame` |
29
+ | `Capture frame was written to <written> where <asked> was asked for` | `captureFrame` |
21
30
 
22
31
  ## The registry
23
32
 
24
- Declare a frozen list of state names and a frozen list of variants in the journey file.
33
+ Declare the state names and the variants once in the journey file, and build the portfolio from
34
+ that declaration.
25
35
 
26
36
  - Name a state for its surface and its condition — `answer-partial`, `start-storage-failure`,
27
37
  `case-delete-confirmation`.
28
38
  - Register the states the design work actually needs, and place every registered one. Never leave a
29
39
  registered state unplaced.
30
- - Wrap the hook in a placement helper that refuses an unregistered state name, refuses a second
31
- placement of the same state, records each written path, and refuses a filename written twice.
32
- - Place a state from inside the journey that reaches it, immediately after the assertion that
33
- proves the surface is in that state.
40
+ - Place a capture state from inside the journey that reaches it, immediately after the assertion
41
+ that proves the surface is in the condition that state names.
42
+ - Record each placed name in the suite's own set in the same step that calls `place`. That set, not
43
+ `placements`, is what the always-on placement proof reads.
34
44
 
35
45
  ## Variants
36
46
 
37
- - Name a variant as one value carrying both the theme and the viewport, such as `dark-390`. Never
38
- split them into separate selectors: a split lets a run write a filename describing a combination it
39
- did not render.
40
- - Render one variant per run, and produce the portfolio — the registry times the variants — by
41
- repeating the run once per variant.
47
+ The run axis is fixed in [SKILL.md](../SKILL.md) → Read the variant once, and the theme switch each
48
+ variant's `apply` performs is fixed in [styles.md](styles.md) → Run per variant. The capture family
49
+ adds these.
50
+
51
+ - Produce the portfolio — the registry times the variants — by repeating the run once per variant.
52
+ - Name each variant for the theme and the viewport it renders, such as `dark-390`. The name is the
53
+ second half of every filename the run writes, so a variant named for one alone produces a
54
+ portfolio nobody can tell apart.
55
+ - Pass the whole variant list as `variants` and this run's name as `variant`. `createPortfolio`
56
+ refuses a `variant` no declared variant carries, and `files` expands the registry across the whole
57
+ list rather than across the one being rendered.
58
+
59
+ ## The proofs the suite owes
42
60
 
43
- ## The proofs
61
+ The package times the registry and refuses a bad placement. It asserts nothing about either, so the
62
+ suite carries these.
44
63
 
45
- | Proof | Runs | Asserts |
46
- | -------------------- | --------------------------- | ---------------------------------------------------------------------------------------------- |
47
- | Filename expansion | Always | The registry's length and uniqueness, the variant count, and that the expansion is unique |
48
- | Portfolio membership | Always; disk under the flag | Every registered state was placed; under the flag, the files on disk are exactly the expansion |
64
+ | Proof | Runs | Asserts |
65
+ | -------------------- | -------------- | ---------------------------------------------------------------------------------- |
66
+ | Filename expansion | Always | `expandCaptures(states, variants)` has one entry per state and variant, all unique |
67
+ | Placement membership | Always | The suite's placed set equals the registry, as sets |
68
+ | Disk membership | Under the flag | The filenames on disk equal the expansion for this run's variant |
49
69
 
50
70
  - Keep the filename proof always-on, so a registry edit that introduces a duplicate or a collision
51
- fails the ordinary run.
52
- - Assert placement equality as set equality against the registry, in every run. Never assert a
53
- count: a count passes while one state is placed twice and another never.
54
- - Under the capture flag, assert the written filenames equal the registry expanded for the run's
55
- variant, then read each file back and require non-empty contents. Never treat the path a
56
- screenshot call returned as proof that a file exists.
71
+ fails the ordinary run. Compare `expandCaptures(states, variants)` against `files` and against a
72
+ set built from it; a length equal to the set's size is what proves the expansion unique.
73
+ - Assert placement as set equality against the registry, in every run. Never assert a count: a count
74
+ passes while one state is placed twice and another never.
75
+ - Read the placement proof from the suite's own set rather than from `placements`. An ordinary run's
76
+ `place` returns before it reads the registry, so `placements` is empty there and an unregistered name
77
+ reaches no refusal until a capture run. The always-on placement proof is what catches it.
78
+ - Under the flag, assert the written filenames equal the registry expanded for the run's variant.
79
+ `captureFrame` already reads each file back and compares its bytes against the frame it shot, so
80
+ the path `place` returns is proof the file exists and holds that frame.
57
81
  - Put the membership proof last in the file, after every journey that feeds its tally.
58
82
 
59
83
  ## Transient states
60
84
 
61
- Capture a state that exists only while an activation is in flight from inside that activation,
62
- never after the click returns.
85
+ Capture a state that exists only while an activation is in flight from inside that activation, never
86
+ after the click returns.
63
87
 
64
- - Attach a one-shot listener to the resolved control, place the capture from inside it, then click
88
+ - Attach a one-shot listener to the resolved control, call `place` from inside it, then click
65
89
  through the normal verb and await the promise the listener recorded.
66
90
  - Fail the step when the listener never ran.
67
91
 
@@ -0,0 +1,68 @@
1
+ # Routing a question
2
+
3
+ Route a question by what judges the claim, before spending a round on it. Report a question no
4
+ instrument here answers as open, and never answer it with the nearest instrument instead.
5
+
6
+ | The claim is judged by | Route it to |
7
+ | -------------------------------------- | -------------------------------------------- |
8
+ | A compiler, a linter, or a Node runner | The `prove` tool, with its negative control |
9
+ | A person's eye | The run's written artifact, named by variant |
10
+ | A person watching a widget move | A statechart harness deep link |
11
+ | The browser's own resolved value | The matrix family ([styles.md](styles.md)) |
12
+
13
+ Never ask `prove` about pixels, and never ask a screenshot about types.
14
+
15
+ ## The receipt half
16
+
17
+ A claim a compiler, a linter, or a Node runner judges goes to `prove`. Supply its workspace project,
18
+ its case, its negative control, and the stage that negative control must break at.
19
+ `.claude/rules/quality.md` § Instruments owns that rule and the receipt line every report quotes;
20
+ follow it there rather than restating it here.
21
+
22
+ - Route the control-to-affordance table, the declared class allowlist's own declaration, the variant
23
+ expansion, and the glyph registry here. Each supplies a project, a case, and a negative control.
24
+ - Read a `no receipt` line as the claim unproved, and report the stage that refused.
25
+
26
+ ## The limit that decides the split
27
+
28
+ `prove` cannot serve a browser project in `@orkestrel/probe` 0.0.11. The following refusals are each
29
+ reproduced:
30
+
31
+ - The runtime stage looks a project up by the name it infers, and a browser project is instantiated
32
+ under its browser-expanded name, so the lookup finds nothing and the claim is refused as missing.
33
+ - The runtime stage pins the `threads` pool, so a browser project's specification runs in a Node
34
+ worker. `@orkestrel/test/browser` imports `vitest/browser` at module scope, so the browser setup
35
+ file throws before the case runs and the failure reads as the claim's.
36
+
37
+ Never route a rendered question to `prove` while that holds. The pinned-pool refusal arrives as a
38
+ case failure, which reads exactly like a broken claim.
39
+
40
+ ## The rendered artifact
41
+
42
+ Write one text file per variant under the workspace's git-ignored `tmp/` tree, named for the variant,
43
+ so a decision cites the exact file and reads it in one call.
44
+
45
+ Compose each file from what the run already holds:
46
+
47
+ - `describeTree` of the mounted surface, for the roles, names, and states a person meets.
48
+ - `describeFocus` of the mounted surface, for the focus order the keyboard walk took.
49
+ - The resolved-style rows the matrix family read for that variant — the property, the element, and
50
+ the value the browser returned.
51
+ - The journal's `steps` and `output`, for what the run did and what the page said while it did it.
52
+ - The capture filenames this run wrote, so the artifact and the portfolio name the same states.
53
+
54
+ Rules the artifact obeys:
55
+
56
+ - Name each file for the variant that produced it. An artifact that names no variant describes a
57
+ combination nobody can reproduce.
58
+ - Write one file per variant, never one file per journey. A decision is taken per variant, and a
59
+ reader opening one file per journey pays a round trip per journey.
60
+ - Regenerate the whole set after any surface change. Never judge a round against a set that is part
61
+ old and part new.
62
+ - Keep it out of version control.
63
+
64
+ ## The harness link
65
+
66
+ Send a look a person decides on to a statechart harness deep link rather than to a file. Name the
67
+ exact link in the round, and let the person watch the widget move rather than read a still of it
68
+ ([statechart.md](statechart.md) → Build the harness a person watches).