@orkestrel/scaffold 0.0.30 → 0.0.32

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.
@@ -16,10 +16,10 @@ Require a bounded question and an exact scope.
16
16
  ## Model
17
17
 
18
18
  ```text
19
- CURSOR_GROK_MODEL=cursor-grok-4.5-high
19
+ CURSOR_GROK_MODEL=cursor-grok-4.6-high
20
20
  ```
21
21
 
22
- That id was read from `agent models` on 2026-08-09. Resolve the model from the variable at
22
+ That id was read from `agent models` on 2026-08-13. Resolve the model from the variable at
23
23
  dispatch. Re-read `agent models` and update this line when the id changes. Never guess or
24
24
  substitute a model id.
25
25
 
@@ -27,12 +27,20 @@ substitute a model id.
27
27
 
28
28
  Resolve the CLI in this order, verifying with `--version` before first use:
29
29
 
30
- 1. bare `agent`;
31
- 2. `agent.cmd` Windows installs ship only `.cmd` and `.ps1` shims, so bare `agent` does
32
- not resolve in Bash;
33
- 3. the absolute `"$LOCALAPPDATA/cursor-agent/agent.cmd"`.
30
+ 1. bare `agent`, on a POSIX host;
31
+ 2. on Windows, the versioned entry under `"$LOCALAPPDATA/cursor-agent/versions/"` take the
32
+ newest directory and invoke its own `node.exe` against its `index.js` directly.
34
33
 
35
- If none responds the bench is dark. Stop with a deviation naming the fallback: hand the
34
+ Launch an unattended run through the versioned entry, never through `agent`, `agent.cmd`, or
35
+ `agent.ps1` on Windows. Those shims delegate to `cursor-agent.ps1`, which sets the console window
36
+ title and can abort with Win32 `0xE9` when no console is attached. The failure is intermittent, so a
37
+ shim that answered once does not clear it, and when it does fire it leaves only a PowerShell
38
+ `SetConsoleWindowTitle` trace — which reads as a bench that returned nothing rather than as a launch
39
+ that never happened. The versioned entry has no console dependency and no such failure mode.
40
+
41
+ Read an empty shim run as a launch failure until its log is checked for that trace.
42
+
43
+ If nothing responds the bench is dark. Stop with a deviation naming the fallback: hand the
36
44
  reading to the Orchestrator, `planner`, or `analyst` directly. Never install or authenticate.
37
45
 
38
46
  Create `tmp/cursor/` first. Write any brief longer than a couple of sentences to
@@ -40,7 +48,10 @@ Create `tmp/cursor/` first. Write any brief longer than a couple of sentences to
40
48
  fragile shell arguments. Every run journals its output, so the user can tail progress live
41
49
  and an interrupted run leaves its partial distillate on disk:
42
50
 
43
- `<agent-cli> -p --trust --mode=ask --model "$CURSOR_GROK_MODEL" "<brief or pointer>" | tee tmp/cursor/<unit>.log`
51
+ `<resolved-entry> -p --trust --mode=ask --model "$CURSOR_GROK_MODEL" "<brief or pointer>" | tee tmp/cursor/<unit>.log`
52
+
53
+ Write that chain to `tmp/cursor/run.sh` and run the file, so the resolution, the model, and the
54
+ journalling are one artifact the next run reuses.
44
55
 
45
56
  Run that yourself only for a short bounded ask finishing in about two minutes. For anything
46
57
  longer your job ends at drafting: return the brief path, the exact resolved command, the
@@ -49,6 +49,7 @@ Use only the centralized files an environment needs.
49
49
  - Extract local declarations by kind. “Only used here” and “not exported” are not exemptions.
50
50
  - Every declaration in a centralized file is exported. Fold away a trivial single-use declaration or export/test it; never leave it hidden.
51
51
  - The only permitted non-exported module-scope declarations are in a runtime entrypoint that must be self-contained and cannot import siblings, such as raw source loaded in a worker. Explain that necessity in a comment.
52
+ - A runtime entry—`src/bin/main.ts`, `app/browser/main.ts`, `app/server/main.ts`—is a fixed name, not a centralized kind file. Both the data rule and the function rule reach it, so it declares no module-scope constant and no module-scope function: it imports what it needs and runs. The self-contained exception above covers only an entrypoint that cannot import siblings.
52
53
  - Perform a cleanup sweep after implementation: no stray implementation-file declarations, non-exported/wrong-kind centralized declarations, prohibited nested declarations, duplicate implementations, compatibility aliases, superfluous wrappers, stale imports/barrel rows, or untested extracted functions.
53
54
 
54
55
  ## Kind purity
@@ -112,9 +113,22 @@ kind. It reads declaration syntax and file name, never meaning.
112
113
  `middlewares.ts`, `parsers.ts`, `relations.ts`, `schemas.ts`, `seeders.ts`, `shapers.ts`, and
113
114
  `validators.ts`. That list is exhaustive, a new function kind joins it, and no later version of
114
115
  the sweep claims more.
116
+ - It reports no `data` violation in `helpers.ts`. The kind rules place a camelCase namespace of
117
+ functions there, and a namespace of callables is not separable from a data table by declaration
118
+ syntax, so `DATA_EXEMPT_FILES` in `tests/setupPolicy.ts` excludes the file. Ordinary module data
119
+ there — `export const RETRIES = 3` — is unreported; the constants rule above binds regardless.
120
+ - It inspects no ambient declaration file: `.d.ts`, `.d.mts`, and `.d.cts` are all outside its
121
+ reach. An ambient declaration file is not a module in the kind table, so it sits outside the
122
+ parsed population entirely rather than being exempted from the `type` rule.
123
+ - It does not inspect class-expression members. A function assigned inside a class-expression
124
+ method is unreported; the functions rule above still binds, and cleanup and review enforce it.
115
125
  - The cleanup sweep and independent review prove kind purity across those files. A helper misfiled
116
126
  as a parser, a coercer misfiled as a guard, a compiler misfiled as a factory, and a shaper
117
127
  misfiled as a cloner are review findings, not red tests.
128
+ - It does not decide barrel membership. It parses each file alone and resolves no module, so it
129
+ cannot tell whether a declaration is reachable from its barrel. That question belongs to each
130
+ package's `tests/guides.test.ts`, which imports the barrel and gets real resolution. Do not add
131
+ module resolution here to duplicate it.
118
132
  - The kind table is mandatory whether or not a test can see the violation.
119
133
 
120
134
  ## Wrapper test
@@ -190,6 +204,8 @@ Store child managers in `#` fields and expose readonly getters typed as their in
190
204
  fixes the declaration shape checked there; it judges nothing about what a module does.
191
205
  - Never infer a function domain from a folder's name; a camelCase module inside an unregistered
192
206
  folder is misplaced.
207
+ - Register a folder only when its direct modules are camelCase single-function `.ts` modules. A
208
+ folder of PascalCase single-file components, or of entity classes, never qualifies.
193
209
  - Request a new domain through a fleet-canon change. There is no workspace-local registration path.
194
210
 
195
211
  ### Extension categories
@@ -231,6 +247,15 @@ Both obey:
231
247
  - If a declaration should not be public, make it a true local or runtime-private detail, or remove
232
248
  the capability for a substantive reason. Never leave an intentional reusable export stranded
233
249
  outside the barrel.
250
+ - One-class-per-file evicts some classes from their only caller, and `export` on such a file is
251
+ structural rather than a statement of intent. Barrel that class when a consumer can construct it
252
+ from values they already hold. Intern it — out of the barrel, and named in the package's parity
253
+ `INTERNAL` list — when its constructor requires a value only its owner produces, or when the
254
+ public value is a projection of the instance rather than the instance. A class named in a public
255
+ signature is always barrelled.
256
+ - Delete a barrel row whose class no consumer can construct, and delete its `@example` with it. A
257
+ row obliges a documented, runnable example, so a class kept public without one is drift that
258
+ parity cannot see.
234
259
  - When a symbol moves, update every import; never leave a compatibility re-export.
235
260
 
236
261
  ```ts
@@ -21,7 +21,7 @@ Documentation is an enforced contract, not explanatory decoration. The Writing r
21
21
 
22
22
  - Read the matching spec/guide before code, form the intended design, then compare implementation. Existing code is a verification target, not ground truth.
23
23
  - `AGENTS.md` and its linked rules are the sole convention source. Do not create competing instruction copies in guides.
24
- - `guides/README.md` is the map: maintain both a concept index (`spec ↔ source ↔ tests ↔ showcase`) and directory index.
24
+ - `guides/README.md` is the map: maintain both a concept index and a directory index. The concept index runs `spec ↔ source ↔ tests ↔ showcase` minus every column whose subject this workspace lacks, so an app-only workspace that publishes no library and builds no showcase still owes a full index over the columns it has.
25
25
  - `ROADMAP.md` is the sequenced plan of record. Each chunk reaches green before the next.
26
26
  - A showcase is executable proof of public API. A missing demonstration is a missing feature, detectable by parity.
27
27
  - An integration surface's guide documents the validated hookup for each supported client: the exact commands run, the authentication and approval model that client needs, and the honest limit wherever a client cannot reach part of the surface.
@@ -32,6 +32,7 @@ Documentation is an enforced contract, not explanatory decoration. The Writing r
32
32
  - Every public export is documented.
33
33
  - TypeScript, SCSS, Markdown, tests, and showcase remain aligned.
34
34
  - A parity failure identifies drift; never suppress or weaken the test.
35
+ - A vendored dependency guide is a mirror. Its relative links address the upstream tree and resolve to nothing here, so they are outside local-link parity. Refresh a mirror rather than rewriting it: a rewritten copy is a translation, and no comparison against the fetched bytes can check it.
35
36
  - Falsify a prose claim the way you falsify a code claim. The parity test proves a name exists, never that a sentence about behavior is true, so run the example and read what it returns. A `// false` beside a call that returns `true` is a defect of the same kind as a wrong return value, and it reaches every consumer who installs the package.
36
37
  - Re-read the prose last, against what actually shipped. Where a change chose to document a limit rather than close it, the sentence was often drafted for the option that lost, or written more confidently than the code earns. Code rulings survive review because a test can break them; prose rulings survive because nothing tries.
37
38
 
@@ -10,8 +10,15 @@ paths:
10
10
 
11
11
  ## Test contract
12
12
 
13
- - Mirror source/application structure:
14
- `tests/{src,app}/[environment]/[domain]/[source].test.ts`.
13
+ - Mirror module/application structure:
14
+ `tests/{src,app}/[environment]/[domain]/[module].test.ts`.
15
+ - The mirrored population is `src` and `app` alone. `configs/` is a source directory and is
16
+ deliberately not a mirrored root: its leaves produce the workspace's configuration rather than ship
17
+ in it, and they are proved from `tests/config.test.ts` beside the configuration they produce. Do
18
+ not add `tests/configs/`.
19
+ - Resolve a mirrored module through `.ts`, `.tsx`, `.mts`, `.cts`, `.vue`, `.scss`, or `.css`.
20
+ - Resolve a Sass or CSS partial through the module's leading underscore.
21
+ - Resolve a `setup*` module test against its sibling `setup*.ts` module inside `tests/`.
15
22
  - Prefer test filenames matching entrypoints: `index.test.ts` for `index.ts`, `main.test.ts` for `main.ts`.
16
23
  - Tests are deterministic: identical inputs produce identical results.
17
24
  - Keep default suites fast: timers normally use 10–50 ms and tests make no network calls.
@@ -25,6 +32,7 @@ paths:
25
32
  - Never assert an implementation against itself. Compare the answer to a declaration, a fixture, or a second mechanism that could disagree with it. Re-deriving the answer the same way the source derives it produces a test that passes for every value the source ever returns, and it reads exactly like a real one.
26
33
  - Probe a host-varying property at runtime, on the host the test is running on, and assert against what the probe returned. Filesystem case folding, path separators, permission bits, and rename semantics differ per host, so a fixture built on one host describes that host and silently measures something else on the next.
27
34
  - Assert a runtime-chosen result as the property it must have, not as the number one run produced. Compression, timing, and buffer sizing are the runtime's choice, so pin the relationship the test depends on — that the encoded form is larger, that the second call is faster — and let the assertion fail when the input drifts out of the range where that relationship holds.
35
+ - Measure an elapsed interval with `performance.now()`, never `Date.now()`. `Date.now()` returns whole milliseconds, so an interval built from two of its readings truncates at both ends and can under-report by a millisecond — enough to fail a boundary assertion against a timer that behaved correctly. `performance.now()` is monotonic and sub-millisecond, and it does not move when the wall clock does.
28
36
  - Give a conditional skip the mechanism that makes it inapplicable, cited, not the platform name alone. A test skipped on a platform is a test nobody re-examines; a test skipped because a named API rejects a named case is one anybody can re-check.
29
37
  - A regression test records the exact command and its failing count before the fix, and the same command's passing count after.
30
38
  - Use `it.todo()` only for explicitly out-of-scope roadmap work, never to complete the current request. Every `.skip` or conditional skip has a narrow verifiable applicability reason.
@@ -36,16 +44,20 @@ paths:
36
44
  A proof that covers the workspace instead of one module has a fixed location, so no package invents
37
45
  its own:
38
46
 
39
- | Path | Proves |
40
- | ---------------------------- | ------------------------------------------------------------------- |
41
- | `tests/policy.test.ts` | Every source file obeys the syntactic coding and placement law |
42
- | `tests/config.test.ts` | Root configuration resolves its aliases, projects, and outputs |
43
- | `tests/guides.test.ts` | Every documented API exists and every public API is documented |
44
- | `tests/conformance.test.ts` | Where this package drifts from the official tooling it tracks |
45
- | `tests/integration.test.ts` | The package's features work together end to end across environments |
46
- | `tests/service/**/*.test.ts` | The live external services this package drives, driven for real |
47
+ | Path | Proves |
48
+ | ---------------------------- | ----------------------------------------------------------------------------------------------------- |
49
+ | `tests/policy.test.ts` | Every source file obeys the syntactic coding and placement law |
50
+ | `tests/config.test.ts` | Root configuration resolves its aliases, projects, and outputs, and the `configs/` leaves behind them |
51
+ | `tests/guides.test.ts` | Every documented API exists and every public API is documented |
52
+ | `tests/conformance.test.ts` | Where this package drifts from the official tooling it tracks |
53
+ | `tests/distribution.test.ts` | The packed package installs and resolves through its public exports |
54
+ | `tests/integration.test.ts` | The package's features work together end to end across environments |
55
+ | `tests/service/**/*.test.ts` | The live external services this package drives, driven for real |
47
56
 
48
57
  - `.claude/rules/workspace.md` names the Vitest project each location belongs to.
58
+ - The `guides` project runs in Node with the browser disabled. Its subject is
59
+ documented-name-to-real-export. A proof that renders a component and compares it against a
60
+ definition is a composition and belongs in an `integration.test.ts` scoped to its directory.
49
61
  - `integration.test.ts` is a reserved filename at any level. It names a scope rather than a module,
50
62
  so the mirror rule does not reach it; its scope is the directory it sits in.
51
63
  - An integration test is an end-to-end test: it composes the package's own features and drives them
@@ -57,9 +69,13 @@ its own:
57
69
  - Do not put a packaging, install, or distribution check in an integration test. What the tarball
58
70
  contains is a different question from whether the features compose.
59
71
  - A test the mirror rule flags is a misplaced test until its placement is checked. Move it to the
60
- location its scope names. Never widen the rule to accept it.
61
- - Give every nested `integration.test.ts` its own exact-path project entry. A glob such as
62
- `tests/src/**/integration.test.ts` double-claims a file another project already owns.
72
+ location its scope names. Widen the rule only when that check shows the test already sits at the
73
+ location its scope names and the rule's population omits a module this ruleset mandates, and then
74
+ widen the population rather than admitting the individual case.
75
+ - A nested `tests/{src,app}/<environment>/**/integration.test.ts` runs in that environment's project,
76
+ whose existing glob collects it exactly once. Give it a separate exact-path project entry only when
77
+ the proof needs different setup or a different runtime, and exclude that exact path from the
78
+ environment project when you do.
63
79
 
64
80
  ## Probes
65
81
 
@@ -95,7 +111,8 @@ Live external services/models are the deliberate exception to fast hermetic defa
95
111
  - Put them in the `service` project, under `tests/service/`, with `tests/setupService.ts` for setup
96
112
  and a longer timeout. That module's presence is what registers the project, so a live proof with
97
113
  no readiness setup is a project nothing configures.
98
- - Keep them out of the default run.
114
+ - `.claude/rules/workspace.md` fixes which gate runs the `service` project, and that gate is not the
115
+ same one in a publishing and a `private: true` workspace.
99
116
  - Warm and verify service readiness in `tests/setupService.ts`.
100
117
  - Hard-require readiness: throw loudly; never silently skip.
101
118
  - Verify service-dependent logic through that service's project, not unrelated module tests or scattered conditional skips.
@@ -107,7 +124,13 @@ Live external services/models are the deliberate exception to fast hermetic defa
107
124
  A test that spawns a process, packs, installs, or drives a real build is a proof, not a unit test.
108
125
 
109
126
  - Give it its own Vitest project with its own setup and timeout.
110
- - Keep it out of the default run and require it in `prepublishOnly`.
127
+ - Keep it out of the default run where the workspace has a gate that can hold it.
128
+ `.claude/rules/workspace.md` fixes which gate each isolated project runs from, and that placement
129
+ differs between a publishing and a `private: true` workspace.
130
+ - The fixed expensive-proof projects are `distribution` and `service`.
131
+ - A `distribution` proof reads `import.meta.env.MODE` and fails, rather than skips, on an unreachable
132
+ registry under `--mode release`. The publish gate invokes it that way, so a proof that skips there
133
+ passes the gate without ever proving the artifact installs. An ordinary local run may still skip.
111
134
  - Slow and hermetic is reason enough to isolate a proof; it need not touch an external service.
112
135
  - Where such a proof stays in a shared project, size its budget from a full contended run rather than from an isolated one. A budget that clears the isolated cost by a thin margin turns contention into a red gate reporting a timeout, which carries no diagnostic about the code and costs a full investigation to dismiss.
113
136
 
@@ -115,6 +138,8 @@ A test that spawns a process, packs, installs, or drives a real build is a proof
115
138
 
116
139
  Test helpers are shared infrastructure, not local test-file clutter.
117
140
 
141
+ `@orkestrel/test` owns the helpers every workspace repeats: the call recorder, the real delay, the JSON and async collectors, and the owned scratch directory. Import them from `@orkestrel/test`, and its Node-only helpers from `@orkestrel/test/server`. Write a helper of your own only where the package exports none for the job. The shapes below are the contract a workspace codes against, not source to copy.
142
+
118
143
  - Extract a fixture, recorder, event factory, async wait, renderer, scenario/data builder, protocol fixture, or DOM builder as soon as it could serve another test.
119
144
  - Any duplicate or near-duplicate helper is a defect; consolidate it into one general form.
120
145
  - Export every reusable helper, fixture type, factory, constant, and guard from setup files.
@@ -123,7 +148,7 @@ Test helpers are shared infrastructure, not local test-file clutter.
123
148
  - Test files import shared infrastructure rather than declaring local fixture factories.
124
149
  - Never reimplement a framework helper in tests or fixtures; import the real parser, signer, flattener, or other helper.
125
150
  - Prefer small customizable factories/stubs that seed inert data for a real scenario over repeated inline setup.
126
- - Helper names follow module-helper naming: `createRecorder`, `buildElement`, `appendItems`, `renderRows`, `waitForDelay`, `extractDetail`.
151
+ - Helper names follow module-helper naming: `createFixtureServer`, `buildElement`, `appendItems`, `renderRows`, `waitForReady`, `extractDetail`.
127
152
 
128
153
  Place helpers by environment:
129
154
 
@@ -134,10 +159,10 @@ Place helpers by environment:
134
159
 
135
160
  ### Recorder
136
161
 
137
- Use a real recorder callback instead of a framework spy when only calls/arguments matter:
162
+ Import `createRecorder` from `@orkestrel/test` instead of a framework spy when only calls and arguments matter. It returns:
138
163
 
139
164
  ```ts
140
- interface TestRecorderInterface<TArgs extends readonly unknown[]> {
165
+ interface RecorderInterface<TArgs extends readonly unknown[]> {
141
166
  readonly calls: readonly TArgs[]
142
167
  readonly count: number
143
168
  readonly handler: (...args: TArgs) => void
@@ -147,11 +172,23 @@ interface TestRecorderInterface<TArgs extends readonly unknown[]> {
147
172
 
148
173
  ### Delay
149
174
 
150
- Use the shared delay helper; never repeat inline timeout promises:
175
+ Import `waitForDelay` from `@orkestrel/test`; never repeat an inline timeout promise. It waits for one host timer and defaults to `0`:
176
+
177
+ ```ts
178
+ function waitForDelay(ms?: number): Promise<void>
179
+ ```
180
+
181
+ ### Scratch
182
+
183
+ Import `createScratch` from `@orkestrel/test/server` when a proof needs real files. It allocates a temporary directory it owns, contains every path against escape, and removes the directory on `destroy`:
151
184
 
152
185
  ```ts
153
- export function waitForDelay(ms = 0): Promise<void> {
154
- return new Promise((resolve) => setTimeout(resolve, ms))
186
+ interface ScratchInterface {
187
+ readonly path: string
188
+ write(target: string, text: string): void
189
+ read(target: string): string | undefined
190
+ exists(target: string): boolean
191
+ destroy(): void
155
192
  }
156
193
  ```
157
194
 
@@ -114,21 +114,26 @@ environment:
114
114
  The second axis is cross-cutting workspace proofs. Each one covers the whole workspace rather than
115
115
  one environment, so each is its own project:
116
116
 
117
- | Project | Files | Proves | In `test` |
118
- | ------------- | ---------------------------- | ------------------------------------------------------------------- | --------- |
119
- | `policy` | `tests/policy.test.ts` | Every source file obeys the syntactic coding and placement law | Yes |
120
- | `config` | `tests/config.test.ts` | Root configuration resolves its aliases, projects, and outputs | Yes |
121
- | `guides` | `tests/guides.test.ts` | Every documented API exists and every public API is documented | Yes |
122
- | `conformance` | `tests/conformance.test.ts` | Where this package drifts from the official tooling it tracks | Yes |
123
- | `integration` | `tests/integration.test.ts` | The package's features work together end to end across environments | No |
124
- | `service` | `tests/service/**/*.test.ts` | The live external services this package drives, driven for real | No |
125
-
126
- `conformance` and `service` are two subjects, not two names for one. `conformance` measures this
127
- package against an official artifact it stays compatible with and drives nothing external: the
128
- tooling it measures against is installed, and any server it drives is one the proof starts itself.
129
- That is what makes it hermetic and keeps it in `test`. `service` drives the real thing, so it takes
130
- `tests/setupService.ts` for readiness, longer timeouts, and no file parallelism, and it leaves
131
- `test` for `prepublishOnly`.
117
+ | Project | Files | Proves | Gate |
118
+ | -------------- | ---------------------------- | ------------------------------------------------------------------- | ------------------------------------- |
119
+ | `policy` | `tests/policy.test.ts` | Every source file obeys the syntactic coding and placement law | `test` |
120
+ | `config` | `tests/config.test.ts` | Root configuration resolves its aliases, projects, and outputs | `test` |
121
+ | `guides` | `tests/guides.test.ts` | Every documented API exists and every public API is documented | `test` |
122
+ | `conformance` | `tests/conformance.test.ts` | Where this package drifts from the official tooling it tracks | `test` |
123
+ | `distribution` | `tests/distribution.test.ts` | The packed package installs and resolves through its public exports | `prepublishOnly`; absent when private |
124
+ | `integration` | `tests/integration.test.ts` | The package's features work together end to end across environments | `test` |
125
+ | `service` | `tests/service/**/*.test.ts` | The live external services this package drives, driven for real | `prepublishOnly`; `test` when private |
126
+
127
+ `conformance`, `integration`, `distribution`, and `service` are four subjects, not four names for
128
+ one.
129
+ Keep `conformance` in `test`: measure this package against an installed official artifact, and start
130
+ any server the proof drives itself. Keep `integration` in `test`: compose the workspace's public
131
+ surfaces without packing, installing, or driving an external service. In a publishing workspace,
132
+ run `distribution` and `service` from `prepublishOnly`: pack and install the package in
133
+ `distribution`, and drive the real service with `tests/setupService.ts`, longer timeouts, and no file
134
+ parallelism in `service`. In a `private: true` workspace, never declare `prepublishOnly`; omit
135
+ `distribution`, reach `service` from `test`, and retain the service project's isolated
136
+ configuration.
132
137
 
133
138
  One project sits on neither axis. `probe` includes `tmp/probe/**/*.test.ts` so an agent can run a
134
139
  throwaway instrument against real sources, aliases and setup. Declare no proof there. Every test
@@ -139,9 +144,9 @@ script names its project, so no gate runs it; its directory is ignored by git; a
139
144
  - A live-service project is the fifth kind. It is the `service` project above, `scripts/service.sh`
140
145
  provisions what it drives, and `.claude/rules/tests.md` governs it. Name it `service` whatever it
141
146
  drives.
142
- - A project leaves the default run for one of two reasons: it drives a live external service, or it
143
- is hermetic but slow — it spawns processes, packs, installs, or drives a real build.
144
- - Every isolated project has its own script, is excluded from `test`, and runs in `prepublishOnly`.
147
+ - In a publishing workspace, a project leaves the default run when it drives a live external
148
+ service or is hermetic but slow — it spawns processes, packs, installs, or drives a real build.
149
+ - Give every isolated project its own script, and place that script by the paragraph above.
145
150
 
146
151
  Setup assets:
147
152
 
@@ -151,7 +156,7 @@ Setup assets:
151
156
 
152
157
  Scope with `test:src`, `test:src:core`, `test:app`, `test:app:server`, and equivalent scripts. Each
153
158
  cross-cutting project has its own script too: `test:policy`, `test:config`, `test:guides`,
154
- `test:conformance`, `test:integration`, `test:service`.
159
+ `test:conformance`, `test:distribution`, `test:integration`, `test:service`.
155
160
 
156
161
  ## Typechecking and environment isolation
157
162
 
@@ -206,7 +211,7 @@ Build/check config alignment:
206
211
  | `test` | Environment projects plus non-isolated cross-cutting proofs |
207
212
  | `clean` | Remove `dist/` |
208
213
  | `copy <from> <to>` | Copy while creating parent directories |
209
- | `prepublishOnly` | The gate chain in `AGENTS.md`, then every isolated project |
214
+ | `prepublishOnly` | Publishing workspaces only: the gate chain, then isolated proofs |
210
215
 
211
216
  Run `show` only **after** formatting. The committed `demo/showcase.html` is generated/minified; formatting after generation would expand its inlined bundle.
212
217
 
@@ -49,6 +49,7 @@
49
49
  "no-debugger": "error",
50
50
  "no-underscore-dangle": "warn",
51
51
 
52
+ "vitest/no-alias-methods": "error",
52
53
  "vitest/warn-todo": "off"
53
54
  },
54
55
  "categories": {