@orkestrel/scaffold 0.0.22 → 0.0.24

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 (39) hide show
  1. package/README.md +84 -99
  2. package/dist/bin/main.js +1094 -0
  3. package/dist/bin/main.js.map +1 -0
  4. package/dist/host/CLAUDE.md +3 -1
  5. package/dist/host/agents/orchestration.md +61 -4
  6. package/dist/host/agents/skills/orkestrel-align-packages/SKILL.md +1 -1
  7. package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +7 -5
  8. package/dist/host/agents/skills/orkestrel-harden-package/SKILL.md +1 -1
  9. package/dist/host/agents/skills/orkestrel-harden-package/references/contract.md +1 -1
  10. package/dist/host/claude/agents/orkestrel.md +9 -9
  11. package/dist/host/claude/rules/architecture.md +45 -3
  12. package/dist/host/claude/rules/quality.md +4 -0
  13. package/dist/host/claude/rules/tests.md +57 -1
  14. package/dist/host/claude/rules/workspace.md +50 -17
  15. package/dist/host/codex/agents/orkestrel.toml +1 -1
  16. package/dist/host/configs/helpers.ts +762 -0
  17. package/dist/host/dotfiles/oxlintrc.json +2 -1
  18. package/dist/host/guides/scaffold.md +862 -0
  19. package/dist/host/manifest.json +40 -33
  20. package/dist/host/tests/config.test.ts +544 -0
  21. package/dist/host/tests/policy.test.ts +46 -0
  22. package/dist/host/tests/setupPolicy.ts +557 -602
  23. package/dist/src/core/index.cjs +3569 -10510
  24. package/dist/src/core/index.cjs.map +1 -1
  25. package/dist/src/core/index.d.cts +2361 -2789
  26. package/dist/src/core/index.d.ts +2361 -2789
  27. package/dist/src/core/index.js +3513 -10374
  28. package/dist/src/core/index.js.map +1 -1
  29. package/dist/src/server/index.cjs +2855 -3765
  30. package/dist/src/server/index.cjs.map +1 -1
  31. package/dist/src/server/index.d.cts +1920 -1335
  32. package/dist/src/server/index.d.ts +1920 -1335
  33. package/dist/src/server/index.js +2812 -3680
  34. package/dist/src/server/index.js.map +1 -1
  35. package/package.json +16 -23
  36. package/dist/bin/scaffold.js +0 -1896
  37. package/dist/bin/scaffold.js.map +0 -1
  38. package/dist/host/guides/src/scaffold.md +0 -2886
  39. /package/dist/host/guides/{src/guide.md → guide.md} +0 -0
@@ -21,11 +21,57 @@ paths:
21
21
  - Allow a scripted boundary stub only when it implements the real interface or protocol minimally, to drive the system under test. It never reimplements project-owned behavior and never stands in for the integration being claimed.
22
22
  - Cover happy paths, error paths, empty input, boundary values, `NaN`, positive/negative zero, cycles, and Map/Set order where relevant.
23
23
  - Test observable behavior, not implementation details.
24
+ - Assert the membership a discovered or globbed set should have, not a total that a partly empty population satisfies. A glob spanning two locations passes a size check while one of them matches nothing.
24
25
  - A regression test records the exact command and its failing count before the fix, and the same command's passing count after.
25
26
  - 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.
26
27
  - Do not create test files solely for `constants.ts`, barrels, error definitions, or `types.ts`.
27
28
  - Run the narrowest relevant Vitest project during development; do not run the entire suite casually.
28
29
 
30
+ ## Cross-cutting proofs
31
+
32
+ A proof that covers the workspace instead of one module has a fixed location, so no package invents
33
+ its own:
34
+
35
+ | Path | Proves |
36
+ | --------------------------- | -------------------------------------------------------------- |
37
+ | `tests/policy.test.ts` | Every source file obeys the syntactic coding and placement law |
38
+ | `tests/config.test.ts` | Root configuration resolves its aliases, projects, and outputs |
39
+ | `tests/guides.test.ts` | Every documented API exists and every public API is documented |
40
+ | `tests/integration.test.ts` | The built package works when installed and driven from outside |
41
+
42
+ - `.claude/rules/workspace.md` names the Vitest project each location belongs to.
43
+ - `integration.test.ts` is a reserved filename at any level. It names a scope rather than a module,
44
+ so the mirror rule does not reach it; its scope is the directory it sits in.
45
+ - Give every nested `integration.test.ts` its own exact-path project entry. A glob such as
46
+ `tests/src/**/integration.test.ts` double-claims a file another project already owns.
47
+
48
+ ## Probes
49
+
50
+ A probe is a throwaway instrument that settles one question. It is not a test and never ships.
51
+
52
+ Two kinds, split by which tool has to see the probe:
53
+
54
+ - A **type probe** is read by `tsc`, whose scoped project includes only its own environment, so it
55
+ lives in the source tree beside what it measures. Delete it before the unit returns; a leaked one
56
+ fails the placement sweep, because a probe filename is not a centralized kind file.
57
+ - A **runtime probe** is collected by a Vitest project, so it lives in `tmp/probe/` and runs through
58
+ the `probe` project. `tmp/` is ignored by git, so no probe enters a commit by accident, and every
59
+ test script names its project, so no gate runs the `probe` project.
60
+
61
+ Run a probe before relying on an unverified belief about behaviour: what a function returns, what a
62
+ configuration resolves to, whether a path is reached at all. Prefer a probe to an argument whenever
63
+ the probe is cheap.
64
+
65
+ Three rules bind every probe:
66
+
67
+ - **Prove the instrument can fail before trusting that it passed.** Pair it with a control drawn
68
+ from outside the population it covers.
69
+ - **Promote or delete.** A probe that settles a claim becomes a test in the mirrored location that
70
+ proves the real source. Delete every other probe. A probe left in the suite reports on the harness
71
+ while reading as a test.
72
+ - **Never commit a probe.** The ignore rule stops an accident, not a deliberate forced add, and a
73
+ type probe sits in tracked source with no ignore rule at all.
74
+
29
75
  ## Live-service tests
30
76
 
31
77
  Live external services/models are the deliberate exception to fast hermetic defaults:
@@ -38,6 +84,14 @@ Live external services/models are the deliberate exception to fast hermetic defa
38
84
  - Tune each request to the smallest input/context/output that proves one behavior without becoming brittle or expensive.
39
85
  - Prefer semantic bounded assertions over exact generated prose. Increase context/workload only when the scenario requires it.
40
86
 
87
+ ## Expensive proofs
88
+
89
+ A test that spawns a process, packs, installs, or drives a real build is a proof, not a unit test.
90
+
91
+ - Give it its own Vitest project with its own setup and timeout.
92
+ - Keep it out of the default run and require it in `prepublishOnly`.
93
+ - Slow and hermetic is reason enough to isolate a proof; it need not touch an external service.
94
+
41
95
  ## Shared test infrastructure
42
96
 
43
97
  Test helpers are shared infrastructure, not local test-file clutter.
@@ -45,6 +99,8 @@ Test helpers are shared infrastructure, not local test-file clutter.
45
99
  - 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.
46
100
  - Any duplicate or near-duplicate helper is a defect; consolidate it into one general form.
47
101
  - Export every reusable helper, fixture type, factory, constant, and guard from setup files.
102
+ - A setup file owns everything an assertion needs and nothing an assertion is: `describe`, `it`, and `expect` never appear in a `setup*.ts`.
103
+ - Data tables and case matrices belong in a setup file at any size; test registration does not.
48
104
  - Test files import shared infrastructure rather than declaring local fixture factories.
49
105
  - Never reimplement a framework helper in tests or fixtures; import the real parser, signer, flattener, or other helper.
50
106
  - Prefer small customizable factories/stubs that seed inert data for a real scenario over repeated inline setup.
@@ -134,7 +190,7 @@ Before acceptance:
134
190
  - prove every intended test file is discovered by the correct project;
135
191
  - inspect actual test counts and environments;
136
192
  - audit `.todo`, `.skip`, conditional skips, retries, and inflated timeouts;
137
- - confirm each assertion would fail for the defect it claims to catch;
193
+ - confirm each assertion would fail for the defect it claims to catch, and that it fails rather than passes when its population is empty;
138
194
  - confirm helpers do not reimplement production behavior;
139
195
  - confirm cleanup runs after setup or assertion failure;
140
196
  - confirm current-scope requirements have real tests rather than placeholders.
@@ -16,23 +16,28 @@ Use only the environments a project needs, and keep the root dependency model in
16
16
 
17
17
  ## Environments
18
18
 
19
- | Path | Purpose |
20
- | -------------- | -------------------------------------------------- |
21
- | `src/core/` | Published host-independent library |
22
- | `src/browser/` | Published browser-only library |
23
- | `src/server/` | Published Node-only library |
24
- | `src/styles/` | Optional SCSS bundle producing `index.css` |
25
- | `src/bin/` | Optional executable entry; never a public barrel |
26
- | `app/core/` | Shared application logic with an `index.ts` barrel |
27
- | `app/browser/` | Browser app; `main.ts` entry, not a barrel |
28
- | `app/server/` | Node server app; `main.ts` entry |
29
- | `tests/` | Mirrors src/app environments |
30
- | `configs/` | Thin target wrappers around root configs |
19
+ | Path | Purpose |
20
+ | -------------- | ------------------------------------------------------------- |
21
+ | `src/core/` | Published host-independent library |
22
+ | `src/browser/` | Published browser-only library |
23
+ | `src/server/` | Published Node-only library |
24
+ | `src/styles/` | Optional SCSS bundle producing `index.css` |
25
+ | `src/bin/` | Optional executable; `main.ts` entry, never a public barrel |
26
+ | `app/core/` | Shared application logic with an `index.ts` barrel |
27
+ | `app/browser/` | Browser app; `main.ts` entry, not a barrel |
28
+ | `app/server/` | Node server app; `main.ts` entry |
29
+ | `tests/` | Mirrors src/app environments; root holds cross-cutting proofs |
30
+ | `configs/` | Thin target wrappers around root configs |
31
31
 
32
32
  - Dependency direction is the root project model in `AGENTS.md` and is not restated here; this file governs where the environments live and how they are configured.
33
33
  - Typical browser-app domains: `components/`, `pages/`, `composables/`, `controllers/`, `services/`, `stores/`.
34
34
  - Typical server-app domains: `handlers.ts`, `middlewares.ts`, `routes.ts`.
35
35
  - `src/styles/index.ts` is a side-effect entry importing `./index.scss`.
36
+ - `src/bin/main.ts` is the executable entry, built to `dist/bin/main.js`. The name is fixed, as it
37
+ is for `app/browser/main.ts` and `app/server/main.ts`, so every runtime entry in a workspace is
38
+ found at the same name.
39
+ - `package.json`'s `bin` key is the installed command name. The entry path is the value and does
40
+ not carry that name.
36
41
 
37
42
  ## Aliases
38
43
 
@@ -55,6 +60,9 @@ Define aliases in `tsconfig.json` first. `vite.config.ts` derives from `compiler
55
60
  - `*/types.ts`: public API contracts.
56
61
  - `configs/src/` and `configs/app/`: thin per-target wrappers, including optional
57
62
  `configs/src/*bin*` files. Shared logic remains in root configs.
63
+ - `configs/helpers.ts`: the one permitted leaf under `configs/`. It imports nothing from the
64
+ workspace, which is what keeps it a leaf. Each `configs/src/*.config.ts` imports the root config
65
+ rather than the leaf, so shared build logic stays in one place.
58
66
 
59
67
  Environment rules:
60
68
 
@@ -71,7 +79,7 @@ Environment rules:
71
79
  | `dist/src/browser` | Browser library + declarations | ES |
72
80
  | `dist/src/server` | Server library + declarations | ES and CJS |
73
81
  | `dist/src/styles` | Compiled `index.css` | ES wrapper |
74
- | `dist/bin` | Optional executable | ES with shebang |
82
+ | `dist/bin` | Optional executable `main.js` | ES with shebang |
75
83
  | `dist/app/browser` | Browser application | target-defined |
76
84
  | `dist/app/server` | Server application | CJS |
77
85
  | `dist/showcase` | Single-file `index.html` demo | self-contained |
@@ -85,7 +93,8 @@ Environment rules:
85
93
 
86
94
  ## Test project matrix
87
95
 
88
- `vite.config.ts` defines one Vitest project per src/app axis × environment:
96
+ `vite.config.ts` defines Vitest projects on two axes. The first is one project per src/app axis ×
97
+ environment:
89
98
 
90
99
  | Project | Files | Environment | Setup |
91
100
  | ------------- | ---------------------- | ------------------- | ----------------------------------------------- |
@@ -98,13 +107,37 @@ Environment rules:
98
107
  | `app:browser` | `tests/app/browser/**` | Playwright Chromium | `setup.ts`, `setupBrowser.ts` |
99
108
  | `app:server` | `tests/app/server/**` | Node | `setup.ts`, `setupServer.ts` |
100
109
 
110
+ The second axis is cross-cutting workspace proofs. Each one covers the whole workspace rather than
111
+ one environment, so each is its own project:
112
+
113
+ | Project | Files | Proves | In `test` |
114
+ | ------------- | --------------------------- | -------------------------------------------------------------- | --------- |
115
+ | `policy` | `tests/policy.test.ts` | Every source file obeys the syntactic coding and placement law | Yes |
116
+ | `config` | `tests/config.test.ts` | Root configuration resolves its aliases, projects, and outputs | Yes |
117
+ | `guides` | `tests/guides.test.ts` | Every documented API exists and every public API is documented | Yes |
118
+ | `integration` | `tests/integration.test.ts` | The built package works when installed and driven from outside | No |
119
+
120
+ One project sits on neither axis. `probe` includes `tmp/probe/**/*.test.ts` so an agent can run a
121
+ throwaway instrument against real sources, aliases and setup. Declare no proof there. Every test
122
+ script names its project, so no gate runs it; its directory is ignored by git; and
123
+ `.claude/rules/tests.md` governs what may live there.
124
+
125
+ - Define a cross-cutting project only for a proof the package actually has.
126
+ - A live-service project is the fifth kind. It is named for the service it drives, and
127
+ `.claude/rules/tests.md` governs it.
128
+ - A project leaves the default run for one of two reasons: it drives a live external service, or it
129
+ is hermetic but slow — it spawns processes, packs, installs, or drives a real build.
130
+ - Every isolated project has its own script, is excluded from `test`, and runs in `prepublishOnly`.
131
+
101
132
  Setup assets:
102
133
 
103
134
  - `tests/setup.css` declares cascade-layer order before `@import 'tailwindcss'` and its `@source`.
104
135
  - Browser setup wires `setup.css`.
105
136
  - Styles setup loads `setup.css` and the compiled cascade.
106
137
 
107
- Scope with `test:src`, `test:src:core`, `test:app`, `test:app:server`, and equivalent scripts.
138
+ Scope with `test:src`, `test:src:core`, `test:app`, `test:app:server`, and equivalent scripts. Each
139
+ cross-cutting project has its own script too: `test:policy`, `test:config`, `test:guides`,
140
+ `test:integration`.
108
141
 
109
142
  ## Typechecking and environment isolation
110
143
 
@@ -156,10 +189,10 @@ Build/check config alignment:
156
189
  | `check:<scope>` | On-demand environment-isolation pass |
157
190
  | `format` | Format all files |
158
191
  | `format:check` | Non-mutating whole-tree format gate |
159
- | `test` | Source/application projects, then guide parity |
192
+ | `test` | Environment projects plus non-isolated cross-cutting proofs |
160
193
  | `clean` | Remove `dist/` |
161
194
  | `copy <from> <to>` | Copy while creating parent directories |
162
- | `prepublishOnly` | `format:check lint:check check build test` |
195
+ | `prepublishOnly` | The gate chain in `AGENTS.md`, then every isolated project |
163
196
 
164
197
  Run `show` only **after** formatting. The committed `demo/showcase.html` is generated/minified; formatting after generation would expand its inlined bundle.
165
198
 
@@ -5,7 +5,7 @@ model_reasoning_effort = "medium"
5
5
  sandbox_mode = "read-only"
6
6
  developer_instructions = """
7
7
  Read AGENTS.md, applicable .claude/rules files, the dispatch-named skill and required
8
- references, guides/src/scaffold.md, the governing package guide, and
8
+ references, guides/scaffold.md, the governing package guide, and
9
9
  .claude/agents/orkestrel.md as the canonical ecosystem catalog and operating
10
10
  reference. Do not edit its generated catalog. Verify versions, ranges, guide parity,
11
11
  branch position, and gate results against manifests, lockfiles, exact installed