@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.
- package/dist/bin/main.js +144 -23
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/orchestration.md +48 -6
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +12 -0
- package/dist/host/claude/agents/codex.md +10 -0
- package/dist/host/claude/agents/grok.md +19 -8
- package/dist/host/claude/rules/architecture.md +25 -0
- package/dist/host/claude/rules/documentation.md +2 -1
- package/dist/host/claude/rules/tests.md +58 -21
- package/dist/host/claude/rules/workspace.md +25 -20
- package/dist/host/dotfiles/oxlintrc.json +1 -0
- package/dist/host/guides/scaffold.md +142 -67
- package/dist/host/tests/config.test.ts +45 -17
- package/dist/host/tests/policy.test.ts +254 -2
- package/dist/host/tests/setupPolicy.ts +297 -34
- package/dist/src/core/index.cjs +176 -179
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +90 -33
- package/dist/src/core/index.d.ts +90 -33
- package/dist/src/core/index.js +171 -180
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +13 -1
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.js +14 -2
- package/dist/src/server/index.js.map +1 -1
- package/package.json +6 -5
|
@@ -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.
|
|
19
|
+
CURSOR_GROK_MODEL=cursor-grok-4.6-high
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
That id was read from `agent models` on 2026-08-
|
|
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.
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
`<
|
|
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
|
|
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
|
|
14
|
-
`tests/{src,app}/[environment]/[domain]/[
|
|
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/
|
|
46
|
-
| `tests/
|
|
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.
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
-
|
|
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
|
|
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: `
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
154
|
-
|
|
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
|
|
118
|
-
|
|
|
119
|
-
| `policy`
|
|
120
|
-
| `config`
|
|
121
|
-
| `guides`
|
|
122
|
-
| `conformance`
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
-
|
|
143
|
-
is hermetic but slow — it spawns processes, packs, installs, or drives a real build.
|
|
144
|
-
-
|
|
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` |
|
|
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
|
|