@orkestrel/scaffold 0.0.28 → 0.0.30

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.
@@ -157,3 +157,15 @@ This governs prose everywhere: chat replies, instruction files, guides, TSDoc, c
157
157
  - Keep all substance, nuance, and precision. Cut only what makes text hard to read.
158
158
  - Present a tradeoff as option, cost, and recommendation — not as a balanced meditation.
159
159
  - Write requirements so they are specific and testable. Replace evaluative words such as "user friendly" or "hardened further" with the concrete condition that closes them.
160
+
161
+ #### Instruction files
162
+
163
+ `AGENTS.md`, `.claude/rules/*`, `.agents/*`, `.claude/agents/*`, and every skill are executed, not
164
+ read. An agent loads them mid-task and acts on them. Write them for that reader.
165
+
166
+ - Write every line as a directive: what to do, what to check, or what to refuse. Delete a line that does none of the three.
167
+ - Name the observable trigger and the required action. "When X, do Y" is actionable; "X matters" is not.
168
+ - State the finding as the rule. Never record how it was found, which session found it, what was tried first, or what a probe proved. That history belongs in the commit message.
169
+ - Cut any clause written to persuade, reassure, or explain the rule to a person. An agent needs the rule and its trigger, not agreement with it.
170
+ - Give a rule one home. Restating it elsewhere creates two copies that drift, and an agent reading the stale one is following this file.
171
+ - Keep an example only when it disambiguates the rule. Delete an example that merely illustrates it.
@@ -91,6 +91,12 @@ Record the substitution.
91
91
  - Never assign Grok to either lane in Claude Code or Codex. If the remaining native engine is also
92
92
  unavailable there, the pass cannot run: stop and report rather than substituting Grok.
93
93
  - Grok takes both lanes only in Cursor, and only when Opus 5 and Sol are both unavailable.
94
+ - Treat a lane that returns no verdicts as a lane that did not run. A bench lane reporting that its
95
+ driver executed and its engine was never reached is a dark bench, not a result. Record the bench
96
+ dark from that report, re-run the lane on the substitute engine from the table above, and name in
97
+ the routing ledger which lane ran on which engine. Never accept a round with one lane empty.
98
+ - Re-read bench liveness at dispatch, not at session start. A bench that probed live can be dark when
99
+ the lane launches.
94
100
 
95
101
  ## Tedious work goes to Grok
96
102
 
@@ -617,17 +623,25 @@ flag is what stops the gate chain running a second time inside the five minutes.
617
623
 
618
624
  ### Reaching the approval
619
625
 
620
- - **Log in first** when the session is new or a day has passed. `npm login` and `npm publish` reach
621
- the same browser approval, and a publish that has to run the login flow spends the window on it.
622
- - `npm login` backgrounded with stdin at EOF falls through to a legacy `Username:` prompt and exits
623
- **zero** without authenticating. Confirm with `npm whoami` rather than an exit code.
624
- - npm offers its browser approval only when it sees a TTY. Without one it fails `EOTP` and there is
625
- no way to answer it. Run the login, and the first publish of a layer, under
626
- `script -qfc '<command>' <log>` with stdin read from a fifo a long `sleep` holds open.
627
- - npm prints `Press ENTER to open in the browser` and does not begin polling until that is
628
- acknowledged. Send a newline into the fifo. The browser it tries to open does not exist in a
629
- headless container, which is harmless.
630
- - Surface the approval URL to the user the moment it appears in the log, and say that approving it
626
+ - Run `npm login` before any publish. `npm publish` does not open the browser flow: unauthenticated
627
+ it returns `E404` on `PUT`, which reads as a missing package rather than a missing credential.
628
+ - Pass `--browser=false` to `npm login` and to every `npm publish`. Without it npm prints
629
+ `Press ENTER to open in the browser...` and blocks. Never answer that prompt with a newline: the
630
+ web flow consumes the newline on a later read, drops to a legacy `Username:` prompt, and exits
631
+ **zero** without authenticating. With the flag npm prints the URL and polls, and stdin stays
632
+ untouched.
633
+ - Hold stdin open and write nothing to it. Use a fifo held open by a long `sleep`. EOF drops npm to
634
+ the same legacy prompt a stray newline does.
635
+ - Run the login and every publish under `script -qfc '<command>' <log>`. npm offers the approval only
636
+ when it sees a TTY; without one it fails `EOTP` with no way to answer.
637
+ - Expect two approvals. `npmjs.com/login/cli/<id>` authenticates the session; `npmjs.com/auth/cli/<id>`
638
+ authorizes the publish and opens the five-minute window. Tell the user both are coming, or the
639
+ second link reads as the first having failed.
640
+ - Confirm authentication with `npm whoami`, never with an exit code. The legacy fallthrough exits
641
+ zero.
642
+ - Re-probe `whoami` immediately before opening the window. A stored credential expires mid-session,
643
+ so a session-start answer does not hold.
644
+ - Surface each approval URL the moment it appears in the log. Say that approving the publish one
631
645
  opens a five-minute window covering the rest of the layer.
632
646
 
633
647
  ### Spending the window
@@ -36,18 +36,28 @@ paths:
36
36
  A proof that covers the workspace instead of one module has a fixed location, so no package invents
37
37
  its own:
38
38
 
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 built package works when installed and driven from outside |
46
- | `tests/service/**/*.test.ts` | The live external services this package drives, driven for real |
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
47
 
48
48
  - `.claude/rules/workspace.md` names the Vitest project each location belongs to.
49
49
  - `integration.test.ts` is a reserved filename at any level. It names a scope rather than a module,
50
50
  so the mirror rule does not reach it; its scope is the directory it sits in.
51
+ - An integration test is an end-to-end test: it composes the package's own features and drives them
52
+ together, through the public API, with no part of the system under test replaced.
53
+ - Scope it by where the composition happens. `tests/integration.test.ts` drives features **across**
54
+ environments — core through server, core through browser, one environment's output consumed by
55
+ another. A nested `tests/src/<environment>/integration.test.ts` drives features **within** that one
56
+ environment.
57
+ - Do not put a packaging, install, or distribution check in an integration test. What the tarball
58
+ contains is a different question from whether the features compose.
59
+ - 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.
51
61
  - Give every nested `integration.test.ts` its own exact-path project entry. A glob such as
52
62
  `tests/src/**/integration.test.ts` double-claims a file another project already owns.
53
63
 
@@ -60,9 +60,13 @@ Define aliases in `tsconfig.json` first. `vite.config.ts` derives from `compiler
60
60
  - `*/types.ts`: public API contracts.
61
61
  - `configs/src/` and `configs/app/`: thin per-target wrappers, including optional
62
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.
63
+ - `configs/helpers.ts` and `configs/browsers.ts`: the only permitted leaves under `configs/`. Each
64
+ imports nothing from the workspace, which is what keeps it a leaf. Each `configs/src/*.config.ts`
65
+ imports the root config rather than a leaf, so shared build logic stays in one place.
66
+ - Keep `configs/helpers.ts` free of any dependency a core-only workspace does not declare. It is
67
+ vendored byte-identical to every workspace, so an import there must resolve in all of them.
68
+ `configs/browsers.ts` exists for that reason: it imports `playwright` and
69
+ `@vitest/browser-playwright`, and only a workspace with a browser environment is given it.
66
70
 
67
71
  Environment rules:
68
72
 
@@ -110,14 +114,14 @@ environment:
110
114
  The second axis is cross-cutting workspace proofs. Each one covers the whole workspace rather than
111
115
  one environment, so each is its own project:
112
116
 
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
- | `conformance` | `tests/conformance.test.ts` | Where this package drifts from the official tooling it tracks | Yes |
119
- | `integration` | `tests/integration.test.ts` | The built package works when installed and driven from outside | No |
120
- | `service` | `tests/service/**/*.test.ts` | The live external services this package drives, driven for real | No |
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 |
121
125
 
122
126
  `conformance` and `service` are two subjects, not two names for one. `conformance` measures this
123
127
  package against an official artifact it stays compatible with and drives nothing external: the
@@ -191,6 +191,7 @@ Exported from `@orkestrel/scaffold`, and reachable from
191
191
  | `matchesOrchestrationPath` | function | Test whether a path instructs or wires an agent rather than the toolchain. |
192
192
  | `matchesRange` | function | Test whether a declared range already admits a published version. |
193
193
  | `nameToGuide` | function | Derive the guide mirror path a package name answers for. |
194
+ | `nameToRewrite` | function | Derive the declaration rewrite a published face roll-up applies. |
194
195
  | `planToSummary` | function | Project a plan into its tally by artifact origin. |
195
196
  | `selectGroups` | function | Select the groups a compile covers, in plan order. |
196
197
  | `selectHostPaths` | function | Select the host paths a named workspace vendors. |
@@ -826,6 +827,17 @@ except the manifest.
826
827
  - One template artifact per configuration file the selection needs: the root `tsconfig.json` and
827
828
  `vite.config.ts`, plus a Vite config and a scoped TypeScript config per selected environment, and
828
829
  two more when `bin` is set.
830
+ - One template artifact, `configs/browsers.ts`, for a workspace selecting `browser` on either axis.
831
+ It resolves the Chromium the Playwright provider launches, and the root `vite.config.ts` calls it
832
+ once into `browserOptions` and passes that to every `playwright()` provider it configures. The
833
+ precedence is `PLAYWRIGHT_EXECUTABLE_PATH`, `PLAYWRIGHT_WS_ENDPOINT`, `PLAYWRIGHT_CHANNEL`, the
834
+ managed Playwright Chromium, the container's bundled Chromium, a verified system channel, then the
835
+ platform default. An installed pinned revision returns empty options, so Playwright keeps its own
836
+ launch defaults. A pinned revision that is not installed falls through to a `chromium` alias or a
837
+ sibling `chromium-*` revision under the same browsers directory, because a managed container ships
838
+ one usable build for many Playwright versions. It is its own file rather than a block in the
839
+ vendored `configs/helpers.ts`, which every workspace receives byte-identical while only a browser
840
+ selection declares the `playwright` this module imports.
829
841
  - One template artifact per source and test file the selection needs: an `index.ts` barrel per
830
842
  selected environment, `main.ts` and `index.html` for an application browser, `tests/setup.ts`
831
843
  plus the host setup modules the selection reaches, and one entry test per axis project.