@orkestrel/scaffold 0.0.81 → 0.0.83

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 (47) hide show
  1. package/dist/agents/skills/orkestrel-publish/scripts/wave.js +14 -3
  2. package/dist/bin/main.js +295 -13
  3. package/dist/bin/main.js.map +1 -1
  4. package/dist/host/AGENTS.md +5 -3
  5. package/dist/host/agents/orchestration.md +1 -0
  6. package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +2 -2
  7. package/dist/host/agents/skills/orkestrel-journey/SKILL.md +43 -39
  8. package/dist/host/agents/skills/orkestrel-journey/references/captures.md +3 -3
  9. package/dist/host/agents/skills/orkestrel-journey/references/decide.md +10 -9
  10. package/dist/host/agents/skills/orkestrel-journey/references/layer.md +5 -5
  11. package/dist/host/agents/skills/orkestrel-journey/references/recorded.md +77 -0
  12. package/dist/host/agents/skills/orkestrel-journey/references/statechart.md +3 -3
  13. package/dist/host/agents/skills/orkestrel-journey/references/styles.md +9 -9
  14. package/dist/host/agents/skills/orkestrel-publish/references/wave.md +4 -0
  15. package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +22 -4
  16. package/dist/host/claude/agents/orkestrel.md +10 -10
  17. package/dist/host/claude/rules/application.md +20 -6
  18. package/dist/host/claude/rules/architecture.md +2 -2
  19. package/dist/host/claude/rules/browser.md +9 -0
  20. package/dist/host/claude/rules/documentation.md +2 -1
  21. package/dist/host/claude/rules/quality.md +5 -0
  22. package/dist/host/claude/rules/styles.md +35 -12
  23. package/dist/host/claude/rules/tests.md +15 -10
  24. package/dist/host/claude/rules/workspace.md +128 -98
  25. package/dist/host/claude/skills/orkestrel-journey/SKILL.md +1 -1
  26. package/dist/host/configs/helpers.ts +157 -9
  27. package/dist/host/configs/policy.ts +64 -61
  28. package/dist/host/dotfiles/oxlintrc.json +132 -16
  29. package/dist/host/dotfiles/prettierignore +1 -1
  30. package/dist/host/guides/README.md +9 -5
  31. package/dist/host/guides/guide.md +4 -1
  32. package/dist/host/guides/scaffold.md +482 -115
  33. package/dist/host/manifest.json +38 -32
  34. package/dist/host/scripts/codex.sh +0 -0
  35. package/dist/host/scripts/cursor.sh +0 -0
  36. package/dist/host/scripts/deps.sh +0 -0
  37. package/dist/host/scripts/ollama.sh +0 -0
  38. package/dist/host/tests/config.test.ts +996 -39
  39. package/dist/host/tests/policy.test.ts +11 -0
  40. package/dist/host/tests/setupPolicy.ts +396 -22
  41. package/dist/src/core/index.cjs +1289 -164
  42. package/dist/src/core/index.cjs.map +1 -1
  43. package/dist/src/core/index.d.cts +313 -35
  44. package/dist/src/core/index.d.ts +313 -35
  45. package/dist/src/core/index.js +1268 -165
  46. package/dist/src/core/index.js.map +1 -1
  47. package/package.json +7 -6
@@ -31,7 +31,8 @@ data root states how each set is staged and how a pointer resolves.
31
31
 
32
32
  Every following code fence is illustrative. [`tests/guides.test.ts`](../tests/guides.test.ts)
33
33
  keeps the command reference aligned with the executable and transcribes the pure blueprint-default,
34
- compile-refusal, and error-narrowing fences. A trailing comment in another fence is this guide's
34
+ compile-refusal, error-narrowing, extension-parsing, and export-map fences. A trailing comment in
35
+ another fence is this guide's
35
36
  claim rather than a measured answer; the driven examples are the ones the shipped declarations
36
37
  print. Limits states what that leaves unproven and what covers it instead.
37
38
 
@@ -57,6 +58,7 @@ Exported from `@orkestrel/scaffold`, and reachable from
57
58
  | Name | Kind | Summary |
58
59
  | ------------------- | ---- | ----------------------------------------------------------------------------------------------------------- |
59
60
  | `Artifact` | type | Represents one file in a plan, discriminated by how its content is produced and what scaffold claims of it. |
61
+ | `Axis` | type | Names the workspace axis an extension occupies. |
60
62
  | `BuildFormat` | type | Names one module format a published library environment builds. |
61
63
  | `CatalogEntry` | type | Represents one package row of the fleet catalog. |
62
64
  | `CompileStage` | type | Names the compile phases, in the order they run. |
@@ -64,7 +66,9 @@ Exported from `@orkestrel/scaffold`, and reachable from
64
66
  | `HostFile` | type | Represents one vendored file read from the repository, beside the target bytes it answers for. |
65
67
  | `Drift` | type | Names how one target path compares to the artifact planned for it. |
66
68
  | `Environment` | type | Names one environment a generated workspace selects on its `src` or `app` axis. |
69
+ | `Extension` | type | Represents an extension discriminated by its surface. |
67
70
  | `Finding` | type | Represents one drift verdict against a target path. |
71
+ | `Framework` | type | Names a supported browser framework. |
68
72
  | `Group` | type | Names the artifact group a plan selects over. |
69
73
  | `Lookup` | type | Names how an upstream lookup resolved: found, missing, unmatched, or failed. |
70
74
  | `Mirror` | type | Represents one dependency guide fetched from upstream, beside the local mirror it answers for. |
@@ -74,6 +78,7 @@ Exported from `@orkestrel/scaffold`, and reachable from
74
78
  | `ScaffoldErrorCode` | type | Names the coded reasons a scaffold error is raised. |
75
79
  | `SetupRuntime` | type | Names the runtime a root setup proof requires. |
76
80
  | `Snapshot` | type | Holds exact lowercase hexadecimal target bytes keyed by artifact-relative path. |
81
+ | `Surface` | type | Names the surface an extension extends. |
77
82
 
78
83
  #### Interfaces
79
84
 
@@ -83,6 +88,7 @@ Exported from `@orkestrel/scaffold`, and reachable from
83
88
  | `ArtifactBase` | interface | Describes the fields every planned file carries. |
84
89
  | `Audit` | interface | Represents the whole comparison of a plan against a target's current content. |
85
90
  | `Blueprint` | interface | Represents the closed, JSON-serializable workspace specification. |
91
+ | `BrowserExtension` | interface | Represents a browser framework and its physically occupied axes. |
86
92
  | `CompileFailure` | interface | Represents the coded reason one compile stage failed. |
87
93
  | `CompileRecord` | interface | Holds the input and output snapshot of one compile stage. |
88
94
  | `CompilerInterface` | interface | Describes the compilation contract: pure, synchronous, and host-independent. |
@@ -90,6 +96,7 @@ Exported from `@orkestrel/scaffold`, and reachable from
90
96
  | `ContentArtifact` | interface | Represents a text file produced by the template or computed compilation path. |
91
97
  | `Dependency` | interface | Represents one runtime `@orkestrel/*` dependency of a generated workspace. |
92
98
  | `DependencyPinSet` | interface | Describes the runtime and development sections a range-writing operation may change. |
99
+ | `FrameworkDefinition` | interface | Describes the tooling and package boundaries a browser framework contributes. |
93
100
  | `HostArtifact` | interface | Represents a file byte-copied from the vendored data root, planned before its bytes are read. |
94
101
  | `HydratedArtifact` | interface | Represents a vendored file whose exact bytes have been read, so its content can be compared. |
95
102
  | `ManifestDependencySet` | interface | Describes the runtime, development, and peer sections read from an existing package manifest. |
@@ -101,20 +108,23 @@ Exported from `@orkestrel/scaffold`, and reachable from
101
108
  | `Question` | interface | Represents one validation issue raised against a blueprint or a plan. |
102
109
  | `Scaffolding` | interface | Represents the replayable outcome of one compile. |
103
110
  | `SrcDefinition` | interface | Describes the build and export settings one published `src` environment contributes. |
111
+ | `StylesExtension` | interface | Represents a named sheet face under `src/<name>`. |
104
112
  | `ViteMachinery` | interface | Names which host-specific pipelines a generated root Vite configuration carries. |
105
113
 
106
114
  #### Constants
107
115
 
108
116
  | Name | Kind | Summary |
109
117
  | --------------------------------- | ----- | ------------------------------------------------------------------------------------------------------ |
110
- | `APP_BROWSER_DEV_DEPENDENCIES` | const | Lists the development dependencies a private Vue browser application adds. |
118
+ | `APP_BROWSER_DEV_DEPENDENCIES` | const | Lists the development dependencies a private browser application adds. |
111
119
  | `APP_DEV_DEPENDENCIES` | const | Names the development dependency every private `app` environment adds. |
112
120
  | `APP_MATRIX` | const | Holds the configuration and runtime-entry settings each private `app` environment contributes, frozen. |
113
121
  | `APP_SERVER_DEV_DEPENDENCIES` | const | Lists the development dependencies a private server application adds. |
114
122
  | `ARTIFACT_TEMPLATES` | const | Holds formatter-stable template text for source, test, document, guide, and service artifacts. |
123
+ | `AXES` | const | Lists the axes a browser extension may occupy, frozen. |
115
124
  | `BASE_DEV_DEPENDENCIES` | const | Holds the tooling versions scaffold and every generated workspace share. |
116
125
  | `BIN_CONFIGS` | const | Lists the configuration files a workspace that ships its own executable adds, frozen. |
117
126
  | `BIN_ENTRY_PATH` | const | Names the executable entry whose presence makes a workspace `bin`. |
127
+ | `BROWSE_DEV_DEPENDENCIES` | const | Names the development dependency a browser or styles surface adds. |
118
128
  | `CANON_PATHS` | const | Lists the instruction-canon paths staged for reading rather than for a target, frozen. |
119
129
  | `CATALOG_AGENT_PATH` | const | Names the agent file whose marker-bounded package table the catalog verb alone owns. |
120
130
  | `CATALOG_CLOSING_MARKER` | const | Names the marker closing the package table inside `CATALOG_AGENT_PATH`. |
@@ -133,6 +143,8 @@ Exported from `@orkestrel/scaffold`, and reachable from
133
143
  | `EXTRA_RANGE_PATTERN` | const | Matches the registry-only semver subset accepted for a development extra's range. |
134
144
  | `FLOOR_RANGE_PATTERN` | const | Matches the exact `major.minor.patch` floor accepted for a foreign peer's range. |
135
145
  | `FOREIGN_NAME_PATTERN` | const | Matches the package name syntax for a dependency this package does not publish. |
146
+ | `FRAMEWORKS` | const | Lists the supported browser frameworks, frozen. |
147
+ | `FRAMEWORK_MATRIX` | const | Describes the tooling and package boundaries of each browser framework, frozen. |
136
148
  | `GLOBAL_SETUP_PATH` | const | Names the shared Vitest global-setup module whose presence makes a workspace `global`. |
137
149
  | `GROUPS` | const | Lists the `Group` values in plan order, frozen. |
138
150
  | `GUIDES_TEST_PATH` | const | Names the package-owned guide-parity entry used by `test:guides` and to select the `guides` project. |
@@ -165,57 +177,71 @@ Exported from `@orkestrel/scaffold`, and reachable from
165
177
  | `PRINT_WIDTH` | const | Caps the columns one emitted line may occupy, matching `printWidth` in `.oxfmtrc.json`. |
166
178
  | `REFERENCE_PATHS` | const | Lists the reference paths staged for offline reading, frozen. |
167
179
  | `RELEASE_PROOF_COMMAND` | const | Names the `prepublishOnly` row that runs the packed-package proof against a real registry. |
180
+ | `RESERVED_SHEET_NAMES` | const | Lists the names a styles extension cannot occupy, frozen. |
168
181
  | `SEED_GUIDE_PATHS` | const | Lists the guide paths a generated workspace starts with, frozen. |
169
182
  | `SERVICE_SCRIPT_PATH` | const | Names the inventory skeleton a workspace with declared service vendors is given once. |
170
183
  | `SERVICE_SETUP_PATH` | const | Names the live-service readiness module whose presence makes a workspace `service`. |
171
184
  | `SERVICE_TEST_INCLUDE` | const | Names the include the live-service project covers, which is a directory rather than one proof. |
185
+ | `SHEET_ENTRY_NAME` | const | Names the build entry beside each stylesheet marker. |
172
186
  | `SHOWCASE_CONFIG_PATH` | const | Names the Vite wrapper whose presence makes a workspace `showcase`. |
173
187
  | `SHOWCASE_DEV_DEPENDENCIES` | const | Names the development dependency used only by the optional single-file showcase build. |
188
+ | `SHOWCASE_PAGES_PATH` | const | Names the physical showcase output directory. |
174
189
  | `SKILLS_CONFIG_PATH` | const | Names the TypeScript wrapper whose presence makes a workspace `skills`. |
175
190
  | `SOURCE_BROWSER_DEV_DEPENDENCIES` | const | Lists the development dependencies a published browser `src` environment adds. |
176
191
  | `SRC_MATRIX` | const | Holds the build and export settings each published `src` environment contributes, frozen. |
192
+ | `STYLES_DEV_DEPENDENCIES` | const | Lists the development dependencies the styles surface adds, frozen. |
193
+ | `STYLES_ENTRY_PATH` | const | Names the base stylesheet marker. |
194
+ | `SURFACES` | const | Lists the surfaces an extension may extend, frozen. |
177
195
  | `TAB_WIDTH` | const | Sets the columns one tab occupies when the formatter measures a line, matching `tabWidth`. |
178
196
  | `TARGET_SKILL_NAMES` | const | Lists the package-facing skills a target receives pointers for, frozen and alphabetical. |
197
+ | `THEMES_BARREL_PATH` | const | Names the themes stylesheet marker. |
198
+ | `THEMES_ENTRY_PATH` | const | Names the themes build entry marker. |
179
199
  | `VERSION_PATTERN` | const | Matches the exact `major.minor.patch` version syntax a blueprint declares. |
180
200
  | `WORKSPACE_DEV_ENGINES` | const | Holds the `devEngines` record every generated manifest carries. |
181
201
  | `WORKSPACE_OWNED_PATHS` | const | Lists the vendored paths whose present bytes belong to each workspace, frozen. |
182
202
 
183
203
  #### Guards
184
204
 
185
- | Name | Kind | Summary |
186
- | ------------------- | -------- | --------------------------------------------------------------------------------- |
187
- | `isArtifact` | const | Narrows a value to an `Artifact`. |
188
- | `isAudit` | const | Narrows a value to an `Audit`. |
189
- | `isBlueprint` | const | Narrows a value to a `Blueprint`. |
190
- | `isCatalogEntry` | const | Narrows a value to a `CatalogEntry`. |
191
- | `isCollection` | function | Narrows a value to an array within the limit one public collection accepts. |
192
- | `isCompilerHooks` | const | Narrows a value to the compiler's initial listener record. |
193
- | `isCompilerOptions` | const | Narrows a value to `CompilerOptions`. |
194
- | `isContent` | const | Narrows a value to text this package will accept as one artifact's content. |
195
- | `isDependency` | const | Narrows a value to a `Dependency`. |
196
- | `isDependencyName` | const | Narrows a value to the scoped package name a runtime dependency carries. |
197
- | `isEnvironment` | const | Narrows a value to one `Environment` a workspace may select. |
198
- | `isFinding` | const | Narrows a value to a `Finding`. |
199
- | `isGroup` | const | Narrows a value to one `Group` a plan selects over. |
200
- | `isGroups` | const | Narrows a value to a bounded group selection. |
201
- | `isHex` | const | Narrows a value to exact lowercase hexadecimal bytes within one artifact's limit. |
202
- | `isManifestScript` | const | Narrows a value to a `ManifestScript`. |
203
- | `isMirror` | const | Narrows a value to a `Mirror`. |
204
- | `isOverride` | const | Narrows a value to an `Override`. |
205
- | `isPath` | function | Narrows a value to a logical target-relative path. |
206
- | `isPlan` | const | Narrows a value to a `Plan`. |
207
- | `isQuestion` | const | Narrows a value to a `Question`. |
208
- | `isScaffoldError` | function | Narrows a caught value to a `ScaffoldError`. |
209
- | `isSnapshot` | function | Narrows a value to a `Snapshot`. |
205
+ | Name | Kind | Summary |
206
+ | -------------------- | -------- | --------------------------------------------------------------------------------- |
207
+ | `isArtifact` | const | Narrows a value to an `Artifact`. |
208
+ | `isAudit` | const | Narrows a value to an `Audit`. |
209
+ | `isBlueprint` | const | Narrows a value to a `Blueprint`. |
210
+ | `isBrowserExtension` | const | Narrows a value to a supported browser framework with distinct occupied axes. |
211
+ | `isCatalogEntry` | const | Narrows a value to a `CatalogEntry`. |
212
+ | `isCollection` | function | Narrows a value to an array within the limit one public collection accepts. |
213
+ | `isCompilerHooks` | const | Narrows a value to the compiler's initial listener record. |
214
+ | `isCompilerOptions` | const | Narrows a value to `CompilerOptions`. |
215
+ | `isContent` | const | Narrows a value to text this package will accept as one artifact's content. |
216
+ | `isDependency` | const | Narrows a value to a `Dependency`. |
217
+ | `isDependencyName` | const | Narrows a value to the scoped package name a runtime dependency carries. |
218
+ | `isEnvironment` | const | Narrows a value to one `Environment` a workspace may select. |
219
+ | `isExtension` | const | Narrows a value to an extension of a supported surface. |
220
+ | `isFinding` | const | Narrows a value to a `Finding`. |
221
+ | `isGroup` | const | Narrows a value to one `Group` a plan selects over. |
222
+ | `isGroups` | const | Narrows a value to a bounded group selection. |
223
+ | `isHex` | const | Narrows a value to exact lowercase hexadecimal bytes within one artifact's limit. |
224
+ | `isManifestScript` | const | Narrows a value to a `ManifestScript`. |
225
+ | `isMirror` | const | Narrows a value to a `Mirror`. |
226
+ | `isOverride` | const | Narrows a value to an `Override`. |
227
+ | `isPath` | function | Narrows a value to a logical target-relative path. |
228
+ | `isPlan` | const | Narrows a value to a `Plan`. |
229
+ | `isQuestion` | const | Narrows a value to a `Question`. |
230
+ | `isScaffoldError` | function | Narrows a caught value to a `ScaffoldError`. |
231
+ | `isSheetName` | function | Narrows a value to a non-reserved sheet face name. |
232
+ | `isSnapshot` | function | Narrows a value to a `Snapshot`. |
233
+ | `isStylesExtension` | const | Narrows a value to a named non-reserved stylesheet face. |
234
+ | `isSurface` | const | Narrows a value to a surface an extension can extend. |
210
235
 
211
236
  #### Parsers
212
237
 
213
- | Name | Kind | Summary |
214
- | ---------------------- | -------- | ------------------------------------------------ |
215
- | `parseBlueprint` | function | Coerces an untrusted value to a `Blueprint`. |
216
- | `parseCompilerOptions` | function | Coerces an untrusted value to `CompilerOptions`. |
217
- | `parseGroups` | function | Coerces an untrusted value to a group selection. |
218
- | `parseSnapshot` | function | Coerces an untrusted value to a `Snapshot`. |
238
+ | Name | Kind | Summary |
239
+ | ---------------------- | -------- | --------------------------------------------------------------------------- |
240
+ | `parseBlueprint` | function | Coerces an untrusted value to a `Blueprint`. |
241
+ | `parseCompilerOptions` | function | Coerces an untrusted value to `CompilerOptions`. |
242
+ | `parseExtension` | function | Coerces an extension value or a `surface:name` selection into an extension. |
243
+ | `parseGroups` | function | Coerces an untrusted value to a group selection. |
244
+ | `parseSnapshot` | function | Coerces an untrusted value to a `Snapshot`. |
219
245
 
220
246
  #### Helpers
221
247
 
@@ -262,6 +288,8 @@ Exported from `@orkestrel/scaffold`, and reachable from
262
288
  | `blueprintToConfigArtifacts` | function | Compiles every artifact in the `configs` group. |
263
289
  | `blueprintToDevDependencies` | function | Projects a blueprint into the development dependencies its manifest declares. |
264
290
  | `blueprintToDocumentArtifacts` | function | Compiles the generated workspace's root documentation. |
291
+ | `blueprintToExports` | function | Projects published environments and sheets into the manifest export map. |
292
+ | `blueprintToFaces` | function | Projects a blueprint into browser extensions restricted to occupied browser axes. |
265
293
  | `blueprintToGuideArtifacts` | function | Compiles the generated workspace's guide index. |
266
294
  | `blueprintToHostArtifacts` | function | Compiles the vendored host artifacts a workspace plans. |
267
295
  | `blueprintToMachinery` | function | Derives the host-specific machinery a generated root Vite configuration carries. |
@@ -269,8 +297,10 @@ Exported from `@orkestrel/scaffold`, and reachable from
269
297
  | `blueprintToOrchestrationArtifacts` | function | Compiles the blueprint-dependent orchestration artifacts. |
270
298
  | `blueprintToQuestions` | function | Measures a blueprint against every law its own fields decide. |
271
299
  | `blueprintToRootTsconfig` | function | Compiles the root TypeScript configuration for a blueprint. |
300
+ | `blueprintToProjects` | function | Projects a blueprint into the project labels its root Vitest configuration registers. |
272
301
  | `blueprintToRootVite` | function | Compiles the root Vite and Vitest configuration for a blueprint. |
273
302
  | `blueprintToScripts` | function | Projects a blueprint into the scripts its manifest declares. |
303
+ | `blueprintToSheets` | function | Projects a blueprint into its validated sheet-face names in stable order. |
274
304
  | `blueprintToSourceArtifacts` | function | Compiles every artifact in the `source` group. |
275
305
  | `blueprintToTestArtifacts` | function | Compiles every artifact in the `tests` group that is not vendored from the host. |
276
306
  | `blueprintToWritableScripts` | function | Projects a blueprint into the manifest scripts a region write may replace. |
@@ -549,7 +579,7 @@ a local path.
549
579
  ```text
550
580
  scaffold <verb> [options]
551
581
 
552
- scaffold new <name> [--src <list>] [--app <list>] [--bin] [--deps <list>] [--offline] [--from <path>] [--target <path>] [--json]
582
+ scaffold new <name> [--src <list>] [--app <list>] [--bin] [--styles] [--themes] [--showcase] [--extend <list>] [--deps <list>] [--offline] [--from <path>] [--target <path>] [--json]
553
583
  scaffold a workspace
554
584
  scaffold audit [--groups <list>] [--offline] [--from <path>] [--target <path>] [--json]
555
585
  report how the target compares to its plan, writing nothing
@@ -564,6 +594,10 @@ options
564
594
  --src <list> the published library environments to build: core, browser, server
565
595
  --app <list> the private application environments to build: core, browser, server
566
596
  --bin scaffold a command-line executable at src/bin/main.ts
597
+ --styles select the base styles surface
598
+ --themes select themes; requires --styles
599
+ --showcase select the showcase; requires --app browser
600
+ --extend <list> select surface:name extensions on the selected surfaces
567
601
  --deps <list> the @orkestrel/* packages the workspace depends on
568
602
  --groups <list> the artifact groups to cover; every group when absent
569
603
  --all fetch a guide for every package the organization publishes, not the declared ones alone
@@ -599,37 +633,43 @@ answers a read and grant no verb write authority that it did not already have.
599
633
  `new --app browser` command selects the journey axis, creates its birth-owned wrapper, defines
600
634
  `appJourney` in the root configuration, and excludes the browser integration suite from
601
635
  `app:browser`. Its manifest declares `test:journey` and invokes it after `npm run test:app` in
602
- `test`. A selection without a browser application emits no journey axis. Creation leaves `setup`
603
- empty. The other structural facts do not need creation flags. Add a root `tests/setup*.test.ts` proof for
604
- `setup`, `tests/guides.test.ts` for `guides`, `tests/integration.test.ts` for `integration`,
636
+ `test`. A selection without a browser application emits no journey axis. `--styles`, `--themes`,
637
+ `--showcase`, and `--extend` select the structural facts and the extensions, and Surfaces and extensions
638
+ states what each emits and what each refuses. Creation leaves `setup` empty, and the remaining
639
+ structural facts take no creation option. Add a root `tests/setup*.test.ts` proof for `setup`,
640
+ `tests/guides.test.ts` for `guides`, `tests/integration.test.ts` for `integration`,
605
641
  `tests/conformance.test.ts` for `conformance`, `tests/setupService.ts` for `service`,
606
- `tests/setupGlobal.ts` for `global`, `configs/app/vite.showcase.config.ts` for `showcase`,
607
- `configs/app/vite.journey.config.ts` for `journey`, and `configs/agents/tsconfig.skills.json` for
608
- `skills`;
609
- reading verbs detect each exact-case file and register its fixed machinery. An explicitly supplied
642
+ `tests/setupGlobal.ts` for `global`, `configs/app/vite.journey.config.ts` for `journey`, and
643
+ `configs/agents/tsconfig.skills.json` for `skills`; reading verbs detect each exact-case file and
644
+ register its fixed machinery. An explicitly supplied
610
645
  plan with `vendors` owns and protects the birth-owned `scripts/service.sh` inventory skeleton.
611
646
  Reading verbs do not infer its vendor list from edited text and cannot preserve an arbitrary present
612
647
  script on that basis.
613
648
 
614
- `distribution` is not on that list. Publishing at least one `src` environment is its whole
615
- condition, and scaffold writes `tests/distribution.test.ts` itself rather than waiting for you to.
616
- Limits states what makes that one proof generable when the others are not.
649
+ `distribution` is not on that list. Publishing at least one `src` environment or one sheet face is
650
+ its whole condition, and scaffold writes `tests/distribution.test.ts` itself rather than waiting for
651
+ you to. Limits states what makes that one proof generable when the others are not.
617
652
 
618
653
  ### Reading a target
619
654
 
620
655
  `audit`, `repair`, `catalog`, and `overwrite` derive the blueprint from the target itself. The name
621
656
  and the declared `@orkestrel/*` packages come from `package.json`. The environment axes come from
622
657
  the directories the target actually ships, because a directory is the fact and a declaration beside
623
- it could disagree. The remaining facts come from exact-case files: `src/bin/main.ts` selects `bin`,
624
- each root `tests/setup*.test.ts` match selects `setup`, `tests/guides.test.ts` selects `guides`,
625
- `tests/integration.test.ts` selects `integration`, `tests/conformance.test.ts` selects
626
- `conformance`, `tests/setupService.ts` selects `service`, `tests/setupGlobal.ts` selects `global`,
627
- `configs/app/vite.showcase.config.ts` selects `showcase`, `configs/app/vite.journey.config.ts`
628
- selects `journey`, and `configs/agents/tsconfig.skills.json` selects `skills`. A containing
629
- directory does not select the fact by itself. `tests/distribution.test.ts` selects nothing: the
630
- published `src` axis the target ships already decides the `distribution` project, and the file is
658
+ it could disagree. The styles surface, its themes target, the showcase, and every extension are
659
+ read from the markers Surfaces and extensions lists. The remaining facts come from exact-case
660
+ files: `src/bin/main.ts` selects `bin`, each root `tests/setup*.test.ts` match selects `setup`,
661
+ `tests/guides.test.ts` selects `guides`, `tests/integration.test.ts` selects `integration`,
662
+ `tests/conformance.test.ts` selects `conformance`, `tests/setupService.ts` selects `service`,
663
+ `tests/setupGlobal.ts` selects `global`, `configs/app/vite.journey.config.ts` selects `journey`,
664
+ and `configs/agents/tsconfig.skills.json` selects `skills`. A containing directory does not select
665
+ any of those facts by itself. `tests/distribution.test.ts` selects nothing: the published `src`
666
+ axis and the sheet faces the target ships already decide the `distribution` project, and the file is
631
667
  planned from that.
632
668
 
669
+ A target whose `package.json` file names the `@orkestrel/scaffold` package is this package's own
670
+ checkout, the source the vendored host is staged from. The `repair` and `overwrite` verbs refuse it
671
+ with the `TARGET` code before either writes, and the `audit` verb reads it like any other target.
672
+
633
673
  `vendors` is not reconstructed. Its artifact, `scripts/service.sh`, is a birth-owned inventory
634
674
  skeleton rather than a working installer, so edited script text is not a trustworthy declaration of
635
675
  a vendor list. A target-reading verb derives no vendor list from a present script. Only an
@@ -704,11 +744,19 @@ manifest and planned `vite.config.ts` conflict, and the option to exclude `confi
704
744
  A selection that excludes `configs` proceeds. An advisory alone does not make an aligned target
705
745
  drift.
706
746
 
747
+ A gate chain also reaches a sheet or framework face through `vitest run --config <wrapper>` when
748
+ the wrapper path belongs to that face in the planned configuration; a build invocation does not.
749
+
707
750
  Scaffold writes one part of the manifest rather than advising on it: the writable script region.
708
751
  `repair` and `overwrite` write every direct `test:<project>` script the blueprint computes,
709
752
  `test:probe`, and `test:bench`. A publishing workspace also receives `test:distribution`, `prepack`,
710
- and `prepublishOnly`. The `test` chain joins the region only as a generated predecessor: when it
711
- runs fewer steps than the planned chain and every step it runs is a planned step in the planned
753
+ and `prepublishOnly`. Each sheet face adds its `check:src:<face>` and `build:src:<face>` scripts.
754
+ Each occupied framework face adds `check:<axis>:vue` and `build:<axis>:vue`; the application face also adds `dev:vue`.
755
+ Selected showcase pages add `showcase`, `showcase:<framework>`, `build:showcase`, and `build:showcase:<framework>`; application journeys add `test:journey:<framework>`.
756
+ Its `test:src:<face>` script accepts, as its generated predecessor, the command that ran the project
757
+ without building the face first, and `build:src:styles` accepts the styles-only build as the
758
+ predecessor of the chain that builds themes after it. The `test` chain joins the region only as a
759
+ generated predecessor: when it runs fewer steps than the planned chain and every step it runs is a planned step in the planned
712
760
  order, `repair` and `overwrite` write the planned chain in its place. That write lands only when
713
761
  every step the planned chain adds runs a script the manifest declares or the region writes. The
714
762
  `test:src` and `test:app` aggregates sit outside the region, so a chain whose planned form adds an
@@ -716,7 +764,7 @@ aggregate the manifest lacks stays with the package, and the `projects` question
716
764
  `audit` reports this chain write only through the `projects` question, so a planned step that
717
765
  registers no Vitest project, such as `npm run test:guides`, lands on the next `repair` without an
718
766
  earlier advisory. A `test` chain running any other step or order stays maintainer-owned, as do the
719
- `check`, `build`, `dev`, `serve`, `show`, `format`, `lint`, `clean`, and `copy` gate chains. A
767
+ `check`, `build`, `dev`, `serve`, `format`, `lint`, `clean`, and `copy` gate chains. A
720
768
  declared value is overwritten only when it is already the value being written or is a recognized
721
769
  generated predecessor. The overwrite happens in place,
722
770
  so every byte outside the replaced ranges survives. A target's descriptions, keywords, extra
@@ -759,27 +807,32 @@ birth-owned, and the range and script regions are the only parts of it a verb re
759
807
 
760
808
  `audit` reports a further non-blocking question, on the `setup` field.
761
809
 
762
- The `setup` question fires when the target carries a filled root `tests/setup*.ts` module that is
810
+ The `setup` question fires when the target carries a filled, exporting root `tests/setup*.ts` module that is
763
811
  neither a proof itself nor one of the vendored modules every target receives, while no proof of the
764
812
  same stem covers it. A module counts as filled when its text differs from the seed this blueprint
765
813
  plans at that same path.
814
+ The export check matches a line beginning with `export `, as the policy sweep does; a hook-only
815
+ or augmentation-only module with no such line raises no question.
766
816
 
767
817
  The comparison reads the module and the seed trimmed, so surrounding whitespace decides nothing: a
768
818
  trailing newline is not authorship, and a module holding whitespace alone reads as empty rather than
769
819
  as filled. It is seed-relative rather than a test for emptiness, because the seeds differ by path:
770
- `tests/setup.ts` is seeded with the empty string and `tests/setupGlobal.ts` is seeded with a `setup`
771
- function body. A test for emptiness therefore raises the question against a freshly materialized
820
+ `tests/setup.ts` is seeded with the empty string, `tests/setupGlobal.ts` with a `setup` function
821
+ body, and a journey workspace's `tests/setupBrowser.ts` with a type augmentation and no sibling
822
+ proof. A test for emptiness therefore raises the question against a freshly materialized journey
772
823
  workspace. Holding each module to the seed the same blueprint plans at its own path reports what a
773
824
  maintainer wrote rather than what scaffold seeded.
774
825
 
775
826
  That reading carries a release-skew limit. A seeded setup module is birth-owned, so `repair` reports
776
827
  it aligned and never rewrites it. A target keeps the seed of the release that materialized it. When
777
- a release moves a planned seed, scaffold raises the question on every target materialized before it,
828
+ a release moves a planned seed, scaffold raises the question on an exporting module retained from that release,
778
829
  against a module scaffold wrote and no maintainer touched. `audit` compares each setup module only
779
- with the seed the installed release plans, and it retains no earlier seed bytes.
780
- `tests/setupGlobal.ts` is the module that can meet it, because it is the one seeded with more than
781
- the empty string. A maintainer meeting that question closes it by writing the proof it asks for, or
782
- by taking the seed the installed release plans.
830
+ with the seed the installed release plans, and it retains no earlier seed bytes. The limit reaches an
831
+ exporting module seeded with more than the empty string that no proof covers. Scaffold seeds
832
+ `tests/setupGlobal.test.ts` beside `tests/setupGlobal.ts` and `tests/setupStyles.test.ts` beside
833
+ `tests/setupStyles.ts`, so an exporting seeded module whose proof was deleted meets it.
834
+ A maintainer meeting that question closes it by writing the
835
+ proof it asks for, or by taking the seed the installed release plans.
783
836
 
784
837
  Coverage is read per module: `tests/<name>.ts` is covered by `tests/<name>.test.ts` and by nothing
785
838
  else, which is the pairing the vendored policy proof resolves. Writing one proof retires that module
@@ -788,7 +841,7 @@ proof that module wants. The question belongs to the `tests` group, so a scoped
788
841
  `tests` omits it. Scaffold does not write the proof it asks for, and the question never refuses a
789
842
  write: a writing verb reports it in the terminal audit it prints, because refusing `repair` over a
790
843
  gap no write can close would block every write. Run across a fleet, the question is the list of
791
- packages carrying a filled setup module that no proof covers.
844
+ packages carrying a filled, exporting setup module that no proof covers.
792
845
 
793
846
  `audit` reads the instruction canon as findings rather than as a question. Each `CANON_PATHS` member
794
847
  the target holds enters the comparison, by file where the member is a directory, and a path the plan
@@ -929,31 +982,36 @@ because the shape is chosen once and read afterwards: `new` refuses the advisory
929
982
  `repair` need the plan to describe and restore a target that already has that shape. A library
930
983
  caller creating a workspace holds the same refusal, and the Compile section states it.
931
984
 
932
- `bin`, `setup`, `guides`, `integration`, `conformance`, `service`, `vendors`, `global`, `showcase`,
933
- `journey`, and `skills` are structural facts. Reading verbs set each only when the workspace physically ships the directory
934
- or exact-case file that defines it, never because of the workspace's name and never because a
935
- sibling fact is set.
985
+ `bin`, `setup`, `guides`, `integration`, `conformance`, `service`, `vendors`, `global`, `styles`,
986
+ `themes`, `showcase`, `journey`, and `skills` are structural facts, and `extensions` lists the
987
+ extension faces. Reading verbs set each fact and list each extension only when the workspace
988
+ physically ships the directory or exact-case file that defines it, never because of the workspace's
989
+ name and never because a sibling fact is set.
936
990
 
937
991
  The `setup` member is a `readonly SetupRuntime[]`, empty by default. Target inference adds
938
- `browser` for the exact-case `tests/setupBrowser.test.ts` proof and `node` for every other root
939
- `tests/setup*.test.ts` match, including `tests/setup.test.ts` and `tests/setupServer.test.ts`.
940
- A nested or wrong-case match adds no runtime.
992
+ `browser` for the exact-case `tests/setupBrowser.test.ts` and `tests/setupStyles.test.ts` proofs and
993
+ `node` for every other root `tests/setup*.test.ts` match, including `tests/setup.test.ts` and
994
+ `tests/setupServer.test.ts`. A nested or wrong-case match adds no runtime.
941
995
 
942
996
  The `node` runtime registers the Node `setup` project, which loads `tests/setup.ts` and excludes
943
- `tests/setupBrowser.test.ts`. The `browser` runtime registers `setup:browser`, which collects
944
- only that browser proof and loads `tests/setup.ts` and `tests/setupBrowser.ts` through Playwright
945
- Chromium. The generated manifest emits the selected `test:setup` and `test:setup:browser` scripts
946
- and invokes them from `test`. Scaffold generates no setup proof for an empty setup seed.
997
+ both browser proofs. The `browser` runtime registers `setup:browser`, which collects only the two
998
+ browser proofs and loads `tests/setup.ts` and `tests/setupBrowser.ts` through Playwright Chromium. A
999
+ sheet face registers `setup:browser` as well, because scaffold plans `tests/setupStyles.test.ts`
1000
+ beside every sheet face. The generated manifest emits the selected `test:setup` and
1001
+ `test:setup:browser` scripts and invokes them from `test`. Scaffold generates no setup proof for an
1002
+ empty setup seed.
947
1003
 
948
1004
  A `global` workspace gives `setup:browser` the `tests/setupGlobal.ts` module as its Vitest global
949
1005
  setup, as it gives `src:browser` and `integration`. A browser proof cannot start a Node fixture from
950
1006
  inside the browser, so it reads what that module provides through the Vitest `inject` function.
951
1007
  The Node `setup` project takes no global setup.
952
1008
 
953
- When the `app` axis selects `browser`, the browser setup project also applies the Vue
954
- single-file-component transform. Your `tests/setupBrowser.ts` module and its paired proof can
955
- import and render application Vue components. A browser setup proof without `app/browser` keeps
956
- the non-Vue pipeline; selecting `src/browser` alone adds no Vue plugin or dependency.
1009
+ The browser setup project applies the Vue single-file-component transform only when the workspace
1010
+ carries the `vue` browser extension on an axis whose selection includes `browser`, and then adds
1011
+ `vue` to its `optimizeDeps.include`, so your `tests/setupBrowser.ts` module and its paired proof
1012
+ can import and render the extension's components. A browser application without that
1013
+ extension keeps the non-Vue pipeline, and a `src/browser` selection adds no Vue plugin or
1014
+ dependency.
957
1015
 
958
1016
  A structural fact is read when a verb runs, not when the file appears. Writing
959
1017
  `tests/integration.test.ts` into a workspace sets the fact, but the root configuration on disk was
@@ -971,8 +1029,9 @@ direct script, regenerates the root configuration, and registers the project. Ov
971
1029
  predecessor `test` chain, write the file and run `repair`. `audit` reports whichever piece is still
972
1030
  outstanding at each step.
973
1031
 
974
- `distribution` is not a field at all. A published `src` environment is its whole condition, read
975
- from the `src` axis the blueprint already carries. The proof packs and installs the published
1032
+ `distribution` is not a field at all. A published `src` environment or a sheet face is its whole
1033
+ condition, read from the `src` axis and the styles surface the blueprint already carries. The proof
1034
+ packs and installs the published
976
1035
  artifact, so a workspace publishing none has nothing for it to read and gets no project, no
977
1036
  `test:distribution` script, and no gate entry. A workspace publishing any gets the project, the
978
1037
  script, the `prepublishOnly` entry, and `tests/distribution.test.ts` itself. Limits states why this
@@ -1003,9 +1062,9 @@ that field so the caller who set it learns it emitted nothing.
1003
1062
  The library's `journey` flag defaults to `false`; `new` sets it when its `app` selection includes
1004
1063
  `browser`. Reading verbs infer it from the wrapper's presence. The flag requires a browser application. Without that
1005
1064
  application, it emits no journey configuration or script and raises a non-blocking `journey`
1006
- question. With that application, the content-owned root configuration defines
1007
- `appJourney(variant, variants)` and excludes `tests/app/browser/integration.test.ts` from the
1008
- ordinary `app:browser` project.
1065
+ question. With that application, the content-owned root configuration defines the `appJourney`
1066
+ factory and excludes `tests/app/browser/integration.test.ts` from the ordinary `app:browser`
1067
+ project. Surfaces and extensions states the journey of each further application mode.
1009
1068
 
1010
1069
  Edit the variant list in `configs/app/vite.journey.config.ts`. This wrapper is birth-owned:
1011
1070
  scaffold creates it when absent and preserves your edits during `repair`. It imports
@@ -1014,7 +1073,8 @@ at 1280 × 800 and `compact` at 390 × 844 without a theme. Rename and extend th
1014
1073
  your application; apply themes through the application's interface in your tests.
1015
1074
 
1016
1075
  The wrapper registers `journey:<name>` for each variant through the root factory. Each project
1017
- collects the browser integration suite alone, sets the variant viewport, and provides `variant`
1076
+ collects the integration suite of the application the Vite mode selects, sets the variant
1077
+ viewport, and provides `variant`
1018
1078
  as its name, `variants` as the declared list, and `capture` as a boolean. The root configuration
1019
1079
  reads `process.env.CAPTURE === '1'` for that boolean. The generated `test:journey` script runs
1020
1080
  `vitest run --config configs/app/vite.journey.config.ts --no-cache --reporter=dot`, and the generated
@@ -1028,6 +1088,278 @@ block states the condition that reopens engine selection, and is that condition'
1028
1088
  axis combination one this package can generate are the gate's laws, and the gate answers them with
1029
1089
  questions. A blueprint the gate will refuse is still constructible, so one law lives in one place.
1030
1090
 
1091
+ ## Surfaces and extensions
1092
+
1093
+ A surface is a part of a workspace that an extension extends, and `Surface` names the two the
1094
+ generator plans. The browser surface is the `browser` environment on the `src` and `app` axes,
1095
+ together with the journey and the showcase of the browser application. The styles surface is the
1096
+ base sheet face at `src/styles`, together with its optional themes target at `src/styles/themes`.
1097
+ An extension adds one face to one surface, and `Blueprint.extensions` lists every extension a
1098
+ workspace carries:
1099
+
1100
+ | Surface | Extension | Face |
1101
+ | --------- | ------------ | ------------------------------------------------------------ |
1102
+ | `browser` | `vue` | `src/vue` on the `src` axis, and `app/vue` on the `app` axis |
1103
+ | `styles` | a sheet name | `src/<name>`, a named sheet face beside `src/styles` |
1104
+
1105
+ `BrowserExtension.axes` lists the axes a browser extension physically occupies, so a target holding
1106
+ `app/vue` and no `src/vue` carries `axes: ['app']`. `FRAMEWORKS` holds `vue` alone. A
1107
+ `StylesExtension` name passes `isSheetName`: it matches `NAME_PATTERN` and is none of the
1108
+ `RESERVED_SHEET_NAMES` values, which are `core`, `browser`, `server`, `bin`, `styles`, `themes`, and
1109
+ `vue`.
1110
+
1111
+ `parseExtension` reads one `surface:name` entry, and `isSurface` decides whether its surface is
1112
+ one the generator plans, so `styles:print` parses and `themes:print` does not. Browser text carries
1113
+ empty axes, because the creating command supplies the browser axes it selected:
1114
+
1115
+ ```ts
1116
+ import { parseExtension } from '@orkestrel/scaffold'
1117
+
1118
+ parseExtension('browser:vue') // { surface: 'browser', name: 'vue', axes: [] }
1119
+ parseExtension('styles:print') // { surface: 'styles', name: 'print' }
1120
+ parseExtension('styles:themes') // undefined
1121
+ parseExtension('browser:react') // undefined
1122
+ ```
1123
+
1124
+ ### Select at creation
1125
+
1126
+ `new` selects each surface and each extension with its own option, as the following command shows:
1127
+
1128
+ ```sh
1129
+ npx @orkestrel/scaffold new paper --src core,browser --app core,browser --styles --themes --showcase --extend browser:vue,styles:print
1130
+ ```
1131
+
1132
+ Each option selects one part:
1133
+
1134
+ - `--styles` selects the styles surface, and `--themes` selects its themes target.
1135
+ - `--showcase` selects the showcase of the browser application.
1136
+ - `--app browser` selects the journey, and no option selects it alone.
1137
+ - `--extend` takes one comma-separated list of `surface:name` entries. A `browser:vue` entry
1138
+ occupies every axis whose selection includes `browser`, so the preceding command plans both
1139
+ `src/vue` and `app/vue`.
1140
+
1141
+ `new` refuses each of the following command lines with exit code `2` before it writes a file:
1142
+
1143
+ | Command line | Refused because |
1144
+ | -------------------------------------------------- | ---------------------------------------------------- |
1145
+ | `--themes` without `--styles` | the themes target belongs to the styles surface |
1146
+ | `--showcase` without `--app browser` | the showcase projects the browser application |
1147
+ | `--extend styles:print` without `--styles` | a named sheet extends the styles surface |
1148
+ | `--extend browser:vue` with no `browser` selection | a browser extension occupies a selected browser axis |
1149
+ | `--extend browser:react` | `vue` is the one supported framework |
1150
+ | `--extend styles:themes` | `themes` is a reserved sheet name |
1151
+ | `--extend browser:vue,browser:vue` | an entry repeats |
1152
+ | `--extend browser:vue --extend styles:print` | `--extend` takes one list |
1153
+ | `--surfaces browser` | `--surfaces` is not an option |
1154
+
1155
+ A library caller can declare an extension the workspace does not place. `blueprintToQuestions`
1156
+ raises one `extensions` question for each such entry, with the following messages:
1157
+
1158
+ - A repeated `surface:name` entry blocks the compile: `styles:print is declared more than once on extensions.`
1159
+ - A browser extension with empty `axes` raises the non-blocking `browser:vue occupies no axis.`
1160
+ - A browser extension on an axis whose selection lacks `browser` raises the non-blocking `browser:vue occupies app, whose selection lacks browser.`
1161
+ - A styles extension without the styles surface raises the non-blocking `styles:print extends a styles surface this workspace does not declare.`
1162
+
1163
+ A browser extension that occupies no axis whose selection includes `browser` adds no framework
1164
+ dependency and no framework machinery.
1165
+
1166
+ ### Read the markers
1167
+
1168
+ Every reading verb derives the structural facts and the extensions from the tree on each run, and
1169
+ no selection is stored anywhere. Each fact and each extension has its own marker:
1170
+
1171
+ | Fact or extension | Marker |
1172
+ | ------------------ | ------------------------------------------------------------------------------------------- |
1173
+ | `styles` | The exact-case `STYLES_ENTRY_PATH` file, `src/styles/index.scss` |
1174
+ | `themes` | The exact-case `THEMES_BARREL_PATH` and `THEMES_ENTRY_PATH` files under `src/styles/themes` |
1175
+ | `showcase` | The exact-case `configs/app/vite.showcase.config.ts` wrapper, or a `showcase` directory |
1176
+ | `journey` | The exact-case `configs/app/vite.journey.config.ts` wrapper |
1177
+ | `vue` | A `src/vue` or `app/vue` directory, and `axes` lists each one present |
1178
+ | A styles extension | A direct `src/<name>` directory holding the exact-case `index.scss` and `sheet.ts` files |
1179
+
1180
+ A reserved directory name is skipped, so a `src/core` directory holding both sheet files reads as no
1181
+ extension. The styles extensions follow the browser extensions, sorted by code unit. A directory
1182
+ holding both sheet files under a name `isSheetName` refuses, and two such directories whose names
1183
+ differ only by case, refuse the target with a `TARGET` error. A face missing one of its markers
1184
+ reads as absent, and Limits states what that costs.
1185
+
1186
+ ### What the styles surface emits
1187
+
1188
+ The styles surface and each styles extension are sheet faces, and every sheet face receives the
1189
+ same seed. In the following table, `<face>` is `styles` or the extension's name:
1190
+
1191
+ | Path | Ownership |
1192
+ | ----------------------------------------------------------------------------------- | ---------- |
1193
+ | `src/<face>/index.scss`, `_tokens.scss`, `_mixins.scss`, `sheet.ts`, and `index.ts` | `birth` |
1194
+ | `_index.scss` in each of `src/<face>/elements`, `components`, and `utilities` | `birth` |
1195
+ | `src/styles/themes/index.scss`, `_default.scss`, and `sheet.ts` | `birth` |
1196
+ | `tests/src/<face>/index.test.ts` and `tests/src/styles/themes/index.test.ts` | `birth` |
1197
+ | `tests/setupStyles.ts` and `tests/setupStyles.test.ts` | `birth` |
1198
+ | `configs/src/vite.<face>.config.ts` and `configs/src/tsconfig.<face>.json` | `content` |
1199
+ | `configs/src/vite.themes.config.ts` | `content` |
1200
+ | `tests/distribution.test.ts` | `presence` |
1201
+
1202
+ `sheet.ts` imports `./index.scss` and nothing else, and `index.ts` star-exports `./sheet.js`.
1203
+ `index.scss` loads `tokens` and then the `elements`, `components`, and `utilities` folder barrels
1204
+ with `@use`, and each `_index.scss` folder barrel starts empty. `_tokens.scss` holds the
1205
+ `@layer theme, reset, base, elements, components, utilities;` order statement. The themes barrel
1206
+ loads `../tokens` and then `_default.scss` with `@use`, so its first emitted rule is the order statement. The
1207
+ themes rows plan only with `themes`, and the themes target takes no TypeScript wrapper of its own.
1208
+
1209
+ Every sheet face publishes. The manifest exports `./<face>` as the compiled `index.css` and
1210
+ `./<face>/scss` as the authored `index.scss`, and themes adds `./styles/themes` and
1211
+ `./styles/themes/scss`. `files` packs the SCSS sources and leaves out each face's JavaScript build
1212
+ stub, and `sideEffects` names every CSS and SCSS file. A styles-only workspace publishes those
1213
+ subpaths and declares no `main`, `module`, or `types` field:
1214
+
1215
+ ```ts
1216
+ import { blueprintToExports, createBlueprint } from '@orkestrel/scaffold'
1217
+
1218
+ const exports = blueprintToExports(createBlueprint('paper', { styles: true, themes: true }))
1219
+
1220
+ Object.keys(exports) // ['./styles', './styles/scss', './styles/themes', './styles/themes/scss', './package.json']
1221
+ ```
1222
+
1223
+ Each sheet face adds its `check:src:<face>`, `build:src:<face>`, and `test:src:<face>` scripts, and
1224
+ `test:src:<face>` builds the face before it runs the face's project. The face's
1225
+ `tests/src/<face>/index.test.ts` imports the built `dist/src/<face>/index.css` with `?raw` by a
1226
+ path relative to the test file. With themes, `build:src:styles`
1227
+ builds the themes target after the base face. The root configuration registers each face's project
1228
+ by its wrapper, and the wrapper composes it through the root `sheetProject` factory, which runs it
1229
+ in Playwright Chromium with `isolate: false` and loads `tests/setup.ts`, `tests/setupBrowser.ts`,
1230
+ and `tests/setupStyles.ts`. The manifest declares `sass` from `STYLES_DEV_DEPENDENCIES` beside the
1231
+ Playwright pair, and the root `tsconfig.json` aliases `@src/<face>` to the face's `index.ts`.
1232
+
1233
+ ### The browser surface
1234
+
1235
+ The base browser application is framework-free. A browser application without the `vue` extension
1236
+ declares no Vue package and loads no Vue plugin, and its `app/browser/main.ts` seed renders the
1237
+ workspace name as a level-1 heading. The `vue` extension adds the `FRAMEWORK_MATRIX.vue`
1238
+ development dependencies, `@vitejs/plugin-vue`, `vue`, and `vue-tsc`, while it occupies an axis
1239
+ whose selection includes `browser`.
1240
+
1241
+ The `vue` extension gives each axis it occupies a face of its own:
1242
+
1243
+ - On the `src` axis it adds the published `src/vue` face: a barrel holding one comment line and no
1244
+ export, the `tests/src/vue/index.test.ts` entry proof, the content-owned
1245
+ `configs/src/vite.vue.config.ts` and `configs/src/tsconfig.vue.json` wrappers, the `@src/vue`
1246
+ alias, and the `./vue` ES export. The wrapper's declaration roll-up rewrites the core and browser
1247
+ specifiers to their published subpaths, so the manifest keeps a `./browser` subpath beside a
1248
+ browser root export. `check:src:vue` checks through `tsc`, `build:src:vue` builds the face, and
1249
+ `test:src:vue` runs its project.
1250
+ - On the `app` axis it adds the `app/vue` application: an empty `index.ts`, a `main.ts` that mounts
1251
+ `App.vue`, an `App.vue` arrival component that renders the same level-1 heading, `index.html`,
1252
+ the `tests/app/vue/index.test.ts` entry proof, the content-owned `configs/app/vite.vue.config.ts`
1253
+ and `configs/app/tsconfig.vue.json` wrappers, the `@app/vue` alias, `check:app:vue` through
1254
+ `vue-tsc`, `build:app:vue`, `dev:vue`, and `test:app:vue`. While `app/vue` is occupied, the root
1255
+ `check` script typechecks the whole tree through `vue-tsc` in place of `tsc`.
1256
+
1257
+ The vendored `.oxlintrc.json` holds each face to the import direction `AGENTS.md` § Project model
1258
+ fixes, and the vendored `tests/config.test.ts` drives those directions through Oxlint.
1259
+
1260
+ Every published face's build decides its externals through `resolveExternal` from the vendored
1261
+ `configs/helpers.ts`. Node builtins, `@orkestrel/*` packages, declared peers with their subpaths,
1262
+ and the sibling entries a face names stay external. The helper bundles an `@src/` or `@app/` alias
1263
+ even where it names a sibling, so the browser and server builds keep `@src/core` external ahead of
1264
+ it and name the core entry as their sibling. The `./vue` build passes `FRAMEWORK_MATRIX.vue.refused`,
1265
+ which holds `vue` and the `@vue/` scope, and the helper refuses that build with one of two messages:
1266
+
1267
+ - An import inside the refused scope reads `The import @vue/runtime-core is refused; import from vue instead of the @vue/ implementation scope.`
1268
+ for `@vue/runtime-core`, even where the manifest declares that package as a peer.
1269
+ - A refused package with no admitting peer reads `The import vue is refused; declare its public package in peerDependencies with peerDependenciesMeta marking it optional.`
1270
+ for `vue`.
1271
+
1272
+ Declare `vue` as an optional peer, and the `./vue` build leaves `vue` and its subpaths external.
1273
+
1274
+ The showcase builds one page per application mode. The base mode reads `app/browser`, and each
1275
+ app-side browser extension adds the mode of its own name. The content-owned
1276
+ `configs/app/vite.showcase.config.ts` wrapper passes the Vite mode to the root
1277
+ `appShowcase(mode, override?)` factory, which selects the application through `resolveApplication`
1278
+ from the vendored `configs/helpers.ts`. No mode, `development`, `production`, and `test` select `browser`, the
1279
+ name of a declared application selects that application, and every other mode throws before the
1280
+ build starts.
1281
+
1282
+ The factory builds into the root `showcase/` directory without emptying it, so one mode's build
1283
+ leaves every sibling page in place. It stamps the final inlined page through `stampPage` and names
1284
+ the page `showcase/<application>.html`. The manifest declares `showcase` and `build:showcase` for
1285
+ the base mode and `showcase:<framework>` and `build:showcase:<framework>` for each extension mode,
1286
+ and a publishing workspace rebuilds every page from `prepublishOnly` after `npm run build` and
1287
+ before `npm test`. The vendored `.prettierignore` lists `showcase/`, so formatting never rewrites a
1288
+ committed page.
1289
+
1290
+ `stampPage` writes one `<meta name="build-id" content="DIGEST" />` line before the line that closes
1291
+ the head, where `DIGEST` is what `computeStamp` returns for the page without that line: its SHA-256
1292
+ digest in lowercase hexadecimal. Stamping a stamped page returns it unchanged. `stampPage` refuses a
1293
+ page carrying a repeated or malformed stamp, and a page whose head does not close on its own line.
1294
+
1295
+ The journey follows the same modes. The birth-owned `configs/app/vite.journey.config.ts` wrapper
1296
+ keeps your variant list and passes the Vite mode to the root `appJourney(variant, variants, mode?)`
1297
+ factory, which selects the application through `resolveApplication` as well. Each variant project
1298
+ collects `tests/app/<application>/integration.test.ts` alone, sets the variant viewport, and
1299
+ provides `variant`, `variants`, and `capture`. The manifest runs `test:journey` for the base
1300
+ application and `test:journey:<framework>`, the same command with `--mode <framework>`, for each
1301
+ app-side browser extension, after `npm run test:app` in `test`.
1302
+
1303
+ Scaffold seeds one birth-owned arrival journey per application at
1304
+ `tests/app/<application>/integration.test.ts`. The base journey imports `app/browser/main.ts`, and
1305
+ the Vue journey mounts `App.vue`. Each resolves the level-1 heading by its role and the workspace
1306
+ name, then proves the Journey, Refusal, and Matrix families the `orkestrel-journey` skill names,
1307
+ and proves Capture as well when `CAPTURE=1` sets the `capture` value. The seeded wrapper declares
1308
+ two variants, which is what makes the journey owe Matrix. A journey workspace's
1309
+ `tests/setupBrowser.ts` seed carries the `ProvidedContext` augmentation that types the three
1310
+ provided values.
1311
+
1312
+ ### Vendored files and their refresh
1313
+
1314
+ The configuration a surface reaches is compiled or vendored, and no package-owned file sits beside
1315
+ it. `tsconfig.json`, `vite.config.ts`, every wrapper under `configs/src`, and
1316
+ `configs/app/vite.showcase.config.ts` are content-owned template artifacts, so `repair` restores a
1317
+ deleted one and replaces a stale one. `configs/app/vite.journey.config.ts` is birth-owned and keeps
1318
+ your variant list. `configs/helpers.ts`, `.oxlintrc.json`, `.prettierignore`, and
1319
+ `tests/config.test.ts` are `HOST_PATHS` members: hydration claims their bytes, so the next
1320
+ release's `repair` refreshes them, and `overwrite` adds deletions rather than a forced refresh.
1321
+ Ownership and drift states the hydration.
1322
+
1323
+ The vendored `tests/config.test.ts` proves those files in each target that holds them. It
1324
+ enumerates the sheet faces and the framework faces from the target's tree rather than from the
1325
+ emitted wrappers, requires a non-empty population only where a marker exists, loads every selected
1326
+ wrapper, and pairs each behaviour with a mutation control in a scratch copy: a deleted wrapper, a
1327
+ removed `tests/setupStyles.ts` entry, a reversed themes build order, a disabled Vue import
1328
+ restriction, and disabled declaration rewrites each fail it. Scaffold's own release gate adds a
1329
+ scratch adopter: `tests/distribution.test.ts` generates the complete selection through the packed
1330
+ executable, installs it, runs its checks, builds, projects, journey modes, showcase builds, and CSS
1331
+ export consumption, and proves that `repair` restores a deleted wrapper byte for byte and that
1332
+ `audit` reports a stale one.
1333
+
1334
+ ### The migration guard
1335
+
1336
+ Vue code belongs to the `vue` extension's faces. `repair` and `overwrite` refuse a target whose
1337
+ `app/browser` directory holds a `.vue` file with a `TARGET` error, before either writes, and the
1338
+ message names the move:
1339
+ `Move Vue components from app/browser to app/vue before regenerating this workspace.` Move the
1340
+ components to `app/vue`, then run `repair`. An `audit` that covers every group reports the same
1341
+ sentence as a non-blocking `extensions` question and keeps the exit code its findings decide, so an
1342
+ otherwise aligned target exits `0`. An `audit` scoped by `--groups` omits the question. Limits
1343
+ names the fleet targets that meet the refusal.
1344
+
1345
+ ### Root setup mirror
1346
+
1347
+ Scaffold plans each setup seed that declares an export beside its sibling proof, so the module and
1348
+ its proof arrive together under the mirror `.claude/rules/tests.md` states:
1349
+
1350
+ - `tests/setupStyles.ts` exports the CSSOM instruments every sheet proof reads and arrives with
1351
+ `tests/setupStyles.test.ts`. The emitted sheet proofs import `adoptSheet` and `readLayerNames`
1352
+ from that module, and the sibling proof drives both against sheets it builds from text.
1353
+ - `tests/setupGlobal.ts` exports the Vitest global `setup` function and arrives with
1354
+ `tests/setupGlobal.test.ts`, which imports `setup` and runs in the Node `setup` project that
1355
+ `test:setup` invokes from `test`.
1356
+
1357
+ A journey workspace's `tests/setupBrowser.ts` seed declares no top-level export, so it arrives
1358
+ without a proof. The vendored policy sweep in `tests/setupPolicy.ts` reads the same mirror in both
1359
+ directions: a root `tests/setup<Name>.test.ts` without its `tests/setup<Name>.ts` module fails
1360
+ `test:policy`, as does a root module that declares an export with neither its sibling proof nor an
1361
+ import from `tests/setup.test.ts`. A module `HOST_PATHS` vendors sits outside that population.
1362
+
1031
1363
  ## Compile
1032
1364
 
1033
1365
  The compiler is pure, synchronous, and host-independent. It runs its stages in order.
@@ -1101,7 +1433,7 @@ order is the order a plan lists its artifacts in.
1101
1433
  | --------------- | ------------------------------------------------------------------------------------------------- |
1102
1434
  | `manifest` | `package.json` |
1103
1435
  | `configs` | The root and per-target build configuration, and the root dotfiles |
1104
- | `source` | The selected environment barrels and entries |
1436
+ | `source` | The selected environment barrels and entries, and each sheet face's seed |
1105
1437
  | `tests` | The shared setup modules, the entry tests, and the policy sweep |
1106
1438
  | `guides` | The guide index and the vendored guide mirrors |
1107
1439
  | `docs` | `README.md` beside the `AGENTS.md` pointer |
@@ -1174,9 +1506,10 @@ aligned whether it is present or absent, so it neither restores missing bytes no
1174
1506
  bytes.
1175
1507
 
1176
1508
  You own `tests/setup.ts`, the selected `tests/setupBrowser.ts`, `tests/setupServer.ts`,
1177
- `tests/setupService.ts`, and `tests/setupGlobal.ts` modules, each root `tests/setup*.test.ts` proof,
1178
- the selected environment entry tests under `tests/src` and `tests/app`, the
1179
- `tests/src/bin/main.test.ts` file, and the `tests/integration.test.ts` seed. Scaffold writes those
1509
+ `tests/setupService.ts`, `tests/setupStyles.ts`, and `tests/setupGlobal.ts` modules, each root
1510
+ `tests/setup*.test.ts` proof, the selected environment and sheet-face entry tests under `tests/src`
1511
+ and `tests/app`, the `tests/src/bin/main.test.ts` file, and the `tests/integration.test.ts` seed.
1512
+ Every sheet face's seed under `src` is yours on the same terms. Scaffold writes those
1180
1513
  planned files only during materialize and leaves later edits or deletions alone. You also own the
1181
1514
  `tests/guides.test.ts`, `tests/conformance.test.ts`, and `tests/service/**/*.test.ts` proof files,
1182
1515
  each of which selects its project by being written. Scaffold content-owns `tests/setupPolicy.ts`,
@@ -1186,7 +1519,10 @@ their bytes drift or the files are missing.
1186
1519
  `tests/policy.test.ts` proves the path- and text-shaped laws, and the vendored oxlint plugin
1187
1520
  `configs/policy.ts` carries the syntax-shaped ones: `policy/no-malformed-summary` reads the doc
1188
1521
  block preceding each export, and `policy/no-banned-term` reads every comment for a term
1189
- `.claude/rules/writing.md` § Substitutions bans unconditionally. The prose sweep in
1522
+ `.claude/rules/writing.md` § Substitutions bans unconditionally. `policy/no-nested-functions`
1523
+ enforces the nested-function law of `.claude/rules/architecture.md` § Functions and orchestration,
1524
+ its callback admission included: an event map passed as an option from inside a function body
1525
+ passes the rule, and a function bound to a local name fails it. The prose sweep in
1190
1526
  `tests/setupPolicy.ts` reads every authored Markdown file for the same terms through the
1191
1527
  `POLICY_BANNED_TERMS` denylist the rule and the sweep share, and `tests/policy.test.ts` proves that
1192
1528
  denylist against the table wherever the workspace authors it. The sweep skips a top-level guide the
@@ -1433,7 +1769,9 @@ not install are seeds — `@vitejs/plugin-vue`, `vue`, `vue-tsc`, `vite-plugin-s
1433
1769
  application-server fleet packages — and each carries the newest triple its supported major served
1434
1770
  when it was written.
1435
1771
  [`tests/src/core/constants.test.ts`](../tests/src/core/constants.test.ts) names that seeded set, so a
1436
- row entering or leaving the manifest moves a test rather than passing unnoticed.
1772
+ row entering or leaving the manifest moves a test rather than passing unnoticed. `sass`, the one row
1773
+ of `STYLES_DEV_DEPENDENCIES`, is a seed as well: it carries the `^1.105.1` range the
1774
+ `@orkestrel/veneer` checkout declared on 2026-09-30, and that test names it in the seeded set.
1437
1775
 
1438
1776
  A newer major is never crossed for you. `audit` reports one as a non-blocking `dependencies`
1439
1777
  question, and a person decides whether the generated toolchain supports it. Inside the declared
@@ -1703,8 +2041,8 @@ read or write that file.
1703
2041
 
1704
2042
  ## Generated workspace
1705
2043
 
1706
- A workspace's file set is a function of its axes plus its structural facts. Nothing is fixed
1707
- except the manifest.
2044
+ A workspace's file set is a function of its axes, its structural facts, and its extensions.
2045
+ Nothing is fixed except the manifest.
1708
2046
 
1709
2047
  - One computed artifact: `package.json`, with the entry points, `exports` map, scripts, and
1710
2048
  development dependencies its selection implies. In publishing workspaces, the emitted `prepack`
@@ -1739,9 +2077,15 @@ except the manifest.
1739
2077
  integration selection also emits a birth-owned `tests/integration.test.ts` seed that imports each
1740
2078
  selected public barrel and records its initial empty exports for the consumer to replace with an
1741
2079
  observable cross-environment flow.
2080
+ - One set of template artifacts per sheet face, and one for the themes target: the birth-owned
2081
+ seed, the content-owned wrappers, and the birth-owned entry proof, beside the birth-owned
2082
+ `tests/setupStyles.ts` module and its proof. Surfaces and extensions lists each path.
2083
+ - One set of template artifacts per axis the `vue` extension occupies, and one birth-owned arrival
2084
+ journey per application of a journey workspace. Surfaces and extensions lists each face.
1742
2085
  - One template artifact, `tests/distribution.test.ts`, for a workspace publishing any `src`
1743
- environment. It is the packed-package proof, and it is claimed by presence rather than birth, so a
1744
- workspace that replaces it keeps its replacement. A published browser environment adds the
2086
+ environment or sheet face. It is the packed-package proof, and it is claimed by presence rather
2087
+ than birth, so a workspace that replaces it keeps its replacement. A published browser environment
2088
+ adds the
1745
2089
  real-browser stage to it: the stage bundles the installed package with the workspace's own
1746
2090
  `configs/browsers.ts` resolution, serves the bundle over a loopback server, and drives it in
1747
2091
  Playwright Chromium.
@@ -1962,7 +2306,12 @@ the Surface tables match the core and server barrels in each direction, the meth
1962
2306
  behavioral declarations, relative links resolve, and named imports in TypeScript fences resolve. It
1963
2307
  does not resolve arbitrary backticked prose spans or typecheck a whole fence. The same suite keeps
1964
2308
  the command reference aligned with the executable and executes the transcribed pure examples for
1965
- blueprint defaults, compile refusal, and error-code narrowing. Other trailing comments remain guide
2309
+ blueprint defaults, compile refusal, error-code narrowing, extension parsing, and the styles-only
2310
+ export map. It also drives the marker, creation, advisory, styles-surface, Vue-face, showcase,
2311
+ stamp, journey, setup-seed, external-resolution, and migration-guard claims of Surfaces and
2312
+ extensions through the compilers, the vendored `configs/helpers.ts`, scratch trees, and the
2313
+ executable. The page stamp is driven on page text, so no showcase build runs there; the scratch
2314
+ adopter in `tests/distribution.test.ts` runs the builds. Other trailing comments remain guide
1966
2315
  claims rather than build answers. The verdicts that are measured are the ones a consumer hovers:
1967
2316
  [`tests/distribution.test.ts`](../tests/distribution.test.ts) drives every `@example` the built
1968
2317
  declarations print against the installed package, scores each verdict it can read as a value, and
@@ -2011,10 +2360,18 @@ filename that legally contains a backslash — `weird\..\name` — is therefore
2011
2360
  segments rather than admitted as one name. That is one separator law with a conservative side, not a
2012
2361
  host-dependent second one.
2013
2362
 
2014
- **Scaffold emits no styles axis.** `SRC_MATRIX` is exactly `core`, `browser`, and `server`, and
2015
- `Blueprint` carries no styles field. A workspace that needs `src/styles/` adds the directory, its
2016
- configuration, and its Vitest project by hand. `.claude/rules/workspace.md` describes styles as an
2017
- environment because the fleet has one; scaffold does not generate it.
2363
+ **A face missing one of its markers reads as absent.** Derivation reads a sheet face only from its
2364
+ complete marker set: `src/styles/index.scss` for the base face, both themes files for the themes
2365
+ target, and both `index.scss` and `sheet.ts` for a styles extension. A face that lost one of them
2366
+ reads as no face at all, so the plan carries none of its artifacts, `repair` restores none of them,
2367
+ and the regenerated root configuration registers no project for it. Restore the missing marker by
2368
+ hand, then run `repair`.
2369
+
2370
+ **A fleet target holding Vue code under `app/browser` cannot repair.** On 2026-09-30 the
2371
+ `elements`, `mailbox`, `roughnotes`, and `supervisor` checkouts each held `.vue` files under
2372
+ `app/browser`, read by a recursive count in each local checkout. The migration guard refuses
2373
+ `repair` and `overwrite` in each of them until its components move to `app/vue`, so each moves them
2374
+ in its own change before it adopts the release that carries the guard.
2018
2375
 
2019
2376
  **No host path is normalized before it is guarded.** `isFilesystemPath` refuses an empty segment, so
2020
2377
  `packages//router` is off contract. A trailing separator does not produce one: it terminates a
@@ -2033,7 +2390,10 @@ implementation that conforms to it, then export both from the barrel — the ord
2033
2390
  is what separates them, and it is the whole rule. Generating a file is not the same as writing one:
2034
2391
  scaffold also writes `tests/policy.test.ts` and `tests/config.test.ts` into a target, byte for byte
2035
2392
  from the shared file set, and the distribution proof is the one it derives from the workspace it is
2036
- writing into.
2393
+ writing into. A seed is not generation either: scaffold writes `tests/setupStyles.test.ts`,
2394
+ `tests/setupGlobal.test.ts`, and each arrival journey at creation, as birth-owned template bytes
2395
+ that prove the modules and applications it seeds beside them. After creation those files are the
2396
+ workspace's, so no verb compares or restores them.
2037
2397
 
2038
2398
  A distribution proof's every assertion derives from the artifact the workspace installs: the
2039
2399
  `exports` map the packed tarball declares, the built declarations beside it, and the module objects
@@ -2041,7 +2401,7 @@ a Node import, a CommonJS require, and a real browser hand back from that instal
2041
2401
  there has to be named, so one generated file measures every publishing workspace, and it stays true
2042
2402
  as that workspace's published surface moves.
2043
2403
 
2044
- A guide, conformance, live-service, or setup proof asserts something scaffold cannot read: the API a
2404
+ A guide, conformance, live-service, or authored setup proof asserts something scaffold cannot read: the API a
2045
2405
  guide fence claims, the official runner a conformance check measures against, the service a live
2046
2406
  proof drives, and what a setup module does. That subject is what no generated file can reach, and
2047
2407
  the claim here is about the subject rather than about every property those files have. A structural
@@ -2049,17 +2409,16 @@ property of the same files can be derivable — whether each root `tests/setup*.
2049
2409
  reachable from the root configuration is one — and a file asserting it would still leave the
2050
2410
  module's behavior unmeasured. A generated file there would read as a proof while measuring nothing,
2051
2411
  which is worse than an absent one. So the file a consumer writes is what selects each of those
2052
- projects, and `tests/distribution.test.ts` is the one proof scaffold generates for you.
2412
+ projects. Scaffold also seeds proofs for its own setup modules, as Root setup mirror describes.
2053
2413
 
2054
2414
  Registration follows the same split. Scaffold registers `conformance` and `service` when their
2055
2415
  structural facts are set, and registers `distribution` whenever the workspace publishes at least one
2056
- `src` environment. In a publishing workspace, `distribution` and `service` run from `prepublishOnly`
2416
+ `src` environment or sheet face. In a publishing workspace, `distribution` and `service` run from `prepublishOnly`
2057
2417
  and `conformance` stays in `test`. In a `private: true` workspace, `distribution` is absent,
2058
- `service` runs from `test`, and there is no `prepublishOnly` at all. One gap the project set cannot
2059
- show, `audit` reports directly: a filled `tests/setup*.ts` module that no `tests/setup*.test.ts`
2060
- proof covers raises the non-blocking `setup` question, which names the modules and the proof to add.
2061
- Scaffold generates nothing there either, because what that proof asserts is those modules' own
2062
- behavior, which only the workspace that wrote them can state.
2418
+ `service` runs from `test`, and there is no `prepublishOnly` at all. The `policy` project reports an exporting root setup module that lacks its sibling proof or an import from `tests/setup.test.ts`.
2419
+ Separately, a filled, exporting `tests/setup*.ts` module that no `tests/setup*.test.ts`
2420
+ proof covers raises the non-blocking `setup` question in `audit`, which names the modules and the proof to add.
2421
+ For setup modules the workspace authors, the workspace supplies the behavior proof; the setup modules scaffold seeds arrive with their sibling proofs.
2063
2422
 
2064
2423
  The generated proof partitions the installed `exports` map rather than sampling it. Every published
2065
2424
  subpath lands in exactly one of driven, undeclared, or excluded, and a totality assertion holds that
@@ -2178,7 +2537,8 @@ The generated distribution proof takes its release contract from the outside. Th
2178
2537
  The project factories the root configuration registers receive the invocation record, and each of
2179
2538
  their projects runs in the invocation's mode. Vitest runs a project whose factory returns no mode in
2180
2539
  Vitest's own `test` mode, where the proof skips. A journey project is such a project: its
2181
- birth-owned wrapper drops the record, so it runs in `test` whatever mode the run names.
2540
+ birth-owned wrapper reads the run's mode only to select the application, and the factory it hands
2541
+ each project takes no record, so the project runs in `test` whatever mode the run names.
2182
2542
  An ordinary local run skips that case, because a developer offline is not a defect; a release run
2183
2543
  does not, because skipping there passes the publish gate without ever proving the artifact installs.
2184
2544
  A workspace that replaces the generated proof takes that contract with it: presence ownership leaves
@@ -2208,6 +2568,8 @@ port, so the run drives nothing external and stays in `test`.
2208
2568
 
2209
2569
  ## Tests
2210
2570
 
2571
+ The generated guide index lists each occupied Vue face with its source, tests, and directory entry, and each selected showcase page.
2572
+
2211
2573
  - [`tests/src/core/Compiler.test.ts`](../tests/src/core/Compiler.test.ts) — the compile stages, the
2212
2574
  fail-closed rule, off-contract input, and teardown.
2213
2575
  - [`tests/src/core/compilers.test.ts`](../tests/src/core/compilers.test.ts) — every projection from
@@ -2241,13 +2603,18 @@ port, so the run drives nothing external and stays in `test`.
2241
2603
  rendering, and the failure envelope.
2242
2604
  - [`tests/src/bin/main.test.ts`](../tests/src/bin/main.test.ts) — the process entry point.
2243
2605
  - [`tests/policy.test.ts`](../tests/policy.test.ts) — the path- and text-shaped policy laws:
2244
- mirrors, suppressions, the rule map, filenames, manifest scripts, skills, bridges, and the prose
2245
- sweep over every authored Markdown file. The syntax-shaped laws are the rules of the vendored
2246
- oxlint plugin `configs/policy.ts`, proven in `tests/config.test.ts`.
2606
+ mirrors, the root setup mirror, suppressions, the rule map, filenames, manifest scripts, skills,
2607
+ bridges, and the prose sweep over every authored Markdown file. The syntax-shaped laws are the
2608
+ rules of the vendored oxlint plugin `configs/policy.ts`, proven in `tests/config.test.ts`.
2247
2609
  - [`tests/config.test.ts`](../tests/config.test.ts) — the root configuration's aliases, projects,
2248
2610
  and outputs, every plugin rule against a case pair drawn from inside and outside its membership
2249
- boundary, and the declaration roll-up over a real face.
2250
- - [`tests/guides.test.ts`](../tests/guides.test.ts) — this guide's bijection with the barrels.
2611
+ boundary, the declaration roll-up over a real face, and the sheet and framework faces enumerated
2612
+ from the tree with a mutation control per behaviour.
2613
+ - [`tests/distribution.test.ts`](../tests/distribution.test.ts) — the packed package installed and
2614
+ resolved through its public exports, and the scratch adopter that generates, installs, builds,
2615
+ and repairs the complete selection.
2616
+ - [`tests/guides.test.ts`](../tests/guides.test.ts) — this guide's bijection with the barrels, its
2617
+ transcribed fences, and the executed behaviour behind its prose claims.
2251
2618
 
2252
2619
  ## See also
2253
2620