@orkestrel/scaffold 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/scaffold.js +90 -41
- package/dist/bin/scaffold.js.map +1 -1
- package/dist/host/codex/config.toml +2 -0
- package/dist/host/guides/src/scaffold.md +234 -101
- package/dist/src/core/index.cjs +478 -298
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +167 -31
- package/dist/src/core/index.d.ts +167 -31
- package/dist/src/core/index.js +469 -299
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +45 -14
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +16 -6
- package/dist/src/server/index.d.ts +16 -6
- package/dist/src/server/index.js +46 -16
- package/dist/src/server/index.js.map +1 -1
- package/package.json +4 -3
|
@@ -134,6 +134,7 @@ From [`types.ts`](../../src/core/types.ts).
|
|
|
134
134
|
| `SrcDefinition` | interface |
|
|
135
135
|
| `AppDefinition` | interface |
|
|
136
136
|
| `ViteMachinery` | interface |
|
|
137
|
+
| `ViteAxes` | interface |
|
|
137
138
|
| `ViteProjectRegistration` | interface |
|
|
138
139
|
| `Origin` | type |
|
|
139
140
|
| `Group` | type |
|
|
@@ -191,6 +192,9 @@ single-file-component, HTML, and development-server machinery an application bro
|
|
|
191
192
|
needs, and `output` for build-output containment. It never selects a boundary guarantee — those ship
|
|
192
193
|
in every shape, as the compilers section sets out.
|
|
193
194
|
|
|
195
|
+
`ViteAxes` is the optional structural-project slice shared by every root Vite compiler:
|
|
196
|
+
`bin`, `integration`, and `service` each select their matching standalone project when `true`.
|
|
197
|
+
|
|
194
198
|
`ViteProjectRegistration` carries one generated project factory identifier and its optional browser
|
|
195
199
|
label. Root configuration renderers preserve that browser ownership as data through registration
|
|
196
200
|
instead of inferring it from a project identifier.
|
|
@@ -210,19 +214,44 @@ interface Blueprint {
|
|
|
210
214
|
readonly version: string
|
|
211
215
|
readonly engines: string
|
|
212
216
|
readonly overrides: readonly Override[]
|
|
213
|
-
readonly
|
|
217
|
+
readonly bin: boolean
|
|
218
|
+
readonly integration: boolean
|
|
219
|
+
readonly service: boolean
|
|
214
220
|
}
|
|
215
221
|
```
|
|
216
222
|
|
|
217
|
-
`src` selects published library environments under `src`; `app` selects private runtime
|
|
218
|
-
`app`. The two axes are independent, so library-only, application-only, and
|
|
219
|
-
all first class. `dependencies` and `peers` are runtime `@orkestrel/*`
|
|
220
|
-
`optional` also gets a `peerDependenciesMeta` entry. `extras` are
|
|
221
|
-
dependencies merged over the generated baseline, and may carry any
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
`
|
|
223
|
+
`src` selects published library environments under `src`; `app` selects private runtime
|
|
224
|
+
environments under `app`. The two axes are independent, so library-only, application-only, and
|
|
225
|
+
mixed workspaces are all first class. `dependencies` and `peers` are runtime `@orkestrel/*`
|
|
226
|
+
packages — a peer flagged `optional` also gets a `peerDependenciesMeta` entry. `extras` are
|
|
227
|
+
package-specific development dependencies merged over the generated baseline, and may carry any
|
|
228
|
+
valid npm package name.
|
|
229
|
+
|
|
230
|
+
`bin`, `integration`, and `service` are the three structural axes, and they obey one law: each is
|
|
231
|
+
`true` only when the workspace physically ships the directory that defines it — never because of
|
|
232
|
+
the workspace's name, and never because a sibling axis is set. `deriveBlueprint` probes exactly
|
|
233
|
+
those directories, so a fresh compile and an audit of a mature repository agree on what the
|
|
234
|
+
workspace is.
|
|
235
|
+
|
|
236
|
+
- **`bin`** — `src/bin/` exists. It alone turns on the self-hosting extras: the manifest's `bin`
|
|
237
|
+
entry, the `scaffold` script pointed at the built executable, the bin check, test, and build
|
|
238
|
+
scripts, `build:host`, the `configs/src/tsconfig.bin.json` and `configs/src/vite.bin.config.ts`
|
|
239
|
+
artifacts, and the `src:bin` test project.
|
|
240
|
+
- **`integration`** — `tests/integration/` exists. It records a slow, opt-in proof project over the
|
|
241
|
+
workspace's own built output, outside the default run: the generated root configuration registers
|
|
242
|
+
a standalone `integration` project including `tests/integration/**/*.test.ts`, and the manifest
|
|
243
|
+
emits `test:integration`.
|
|
244
|
+
- **`service`** — `tests/service/` exists. It records a slow, opt-in proof project against a foreign
|
|
245
|
+
running process, outside the default run: a standalone `service` project including
|
|
246
|
+
`tests/service/**/*.test.ts`, with `tests/setupService.ts` after the shared setup, and the
|
|
247
|
+
isolated `test:service` script.
|
|
248
|
+
|
|
249
|
+
A service workspace owes two companion files beside that directory, and derivation requires both
|
|
250
|
+
physically present: `tests/setupService.ts` and `scripts/service.sh`. Either missing companion is a
|
|
251
|
+
coded `TARGET` failure naming the missing path rather than a silent `service: false`. This package
|
|
252
|
+
emits neither: both are consumer-owned seams, and the generated-workspace section sets out what
|
|
253
|
+
each owes its workspace and which proof runs in which gate. Nothing here is inferred — the
|
|
254
|
+
executable axis turns on neither proof project, and neither proof project turns on the other.
|
|
226
255
|
|
|
227
256
|
`Override` replaces a rendered artifact's content at a path, never partially merges it. `Member` is
|
|
228
257
|
one declared public export of the scaffolded workspace, derived rather than authored.
|
|
@@ -327,8 +356,10 @@ From [`constants.ts`](../../src/core/constants.ts).
|
|
|
327
356
|
| `FRESHNESS` | const |
|
|
328
357
|
| `COMPILE_STAGES` | const |
|
|
329
358
|
| `SRC_MATRIX` | const |
|
|
359
|
+
| `BIN_CONFIGS` | const |
|
|
330
360
|
| `APP_MATRIX` | const |
|
|
331
361
|
| `HOST_PATHS` | const |
|
|
362
|
+
| `SERVICE_SCRIPT_PATH` | const |
|
|
332
363
|
| `NAME_PATTERN` | const |
|
|
333
364
|
| `MAX_NAME_LENGTH` | const |
|
|
334
365
|
| `MAX_DEPENDENCY_NAME_LENGTH` | const |
|
|
@@ -373,11 +404,13 @@ From [`constants.ts`](../../src/core/constants.ts).
|
|
|
373
404
|
`ENVIRONMENTS`, `ORIGINS`, `GROUPS`, `CATEGORIES`, `FRESHNESS`, and `COMPILE_STAGES` are the frozen
|
|
374
405
|
value lists behind their literal unions. `SRC_MATRIX` is the `src` environment matrix as
|
|
375
406
|
data — each environment's `configs/src` files, test-project label, `exports` subpath, and build
|
|
376
|
-
formats. `APP_MATRIX` is its application sibling, adding the runtime entry where an environment
|
|
377
|
-
one (`app/browser/index.html`, `app/server/main.ts`). `
|
|
378
|
-
|
|
407
|
+
formats. `APP_MATRIX` is its application sibling, adding the runtime entry where an environment
|
|
408
|
+
produces one (`app/browser/index.html`, `app/server/main.ts`). `BIN_CONFIGS` is the executable
|
|
409
|
+
axis's computed `tsconfig` and Vite wrapper pair. `HOST_PATHS` is the ordered list of byte-copied
|
|
410
|
+
host artifacts, and it is the staging manifest rather than the per-plan carried set:
|
|
379
411
|
`stageHost` vendors every path on it, while each plan carries the subset `selectHostPaths` selects
|
|
380
|
-
for that one workspace.
|
|
412
|
+
for that one workspace. `SERVICE_SCRIPT_PATH` names the consumer-owned provisioner a service
|
|
413
|
+
workspace's audit expects.
|
|
381
414
|
|
|
382
415
|
The bounds are public because they are part of the contract, not implementation trivia.
|
|
383
416
|
`MAX_ARTIFACT_BYTES` caps one artifact at 5 MiB and `MAX_TOTAL_ARTIFACT_BYTES` caps one blueprint,
|
|
@@ -831,6 +864,7 @@ From [`helpers.ts`](../../src/server/helpers.ts).
|
|
|
831
864
|
| Name | Kind |
|
|
832
865
|
| -------------------------- | -------- |
|
|
833
866
|
| `isRealDirectory` | function |
|
|
867
|
+
| `isRealFile` | function |
|
|
834
868
|
| `digestFile` | function |
|
|
835
869
|
| `digestHex` | function |
|
|
836
870
|
| `digestText` | function |
|
|
@@ -893,7 +927,7 @@ so a file swapped mid-read is a failure rather than a silent wrong digest. `read
|
|
|
893
927
|
strictly, rejecting invalid UTF-8. Manifest reads stop at `MAX_MANIFEST_BYTES`; catalog guide reads
|
|
894
928
|
stop at `MAX_GUIDE_BYTES`. `listFiles` and `listDirectories` walk a real, unlinked root under the
|
|
895
929
|
entry and depth bounds, returning sorted POSIX-relative paths and `[]` for an absent root.
|
|
896
|
-
`isRealDirectory`
|
|
930
|
+
`isRealDirectory` and `isRealFile` are the physical path predicates they all lean on.
|
|
897
931
|
|
|
898
932
|
The write-transaction helpers are the fail-closed mutation path. `createWriteDirectory` establishes
|
|
899
933
|
a directory one segment at a time behind captured identities; `validateWriteAnchor`,
|
|
@@ -915,14 +949,17 @@ omitting an absent path entirely. `readManifest` reads `package.json` text, and
|
|
|
915
949
|
|
|
916
950
|
`deriveBlueprint` is the faithful inverse an audit needs: it reconstructs a blueprint from an
|
|
917
951
|
existing workspace so a mature package is diffed against its own would-be scaffold rather than a
|
|
918
|
-
dependency-less stand-in. Environments come from `src/<environment>/` and `app/<environment
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
952
|
+
dependency-less stand-in. Environments come from `src/<environment>/` and `app/<environment>/`, and
|
|
953
|
+
the three structural axes from the directory probes and the service companion law the blueprint
|
|
954
|
+
section states — every one of them a reading of the filesystem, never of the name. Dependencies and
|
|
955
|
+
peers come from the manifest's scoped entries, with an optional peer recovered from
|
|
956
|
+
`peerDependenciesMeta`; and `extras` is every development dependency minus the complete set
|
|
957
|
+
`devDependenciesFor` emits for those environments and structural axes, and minus anything already
|
|
958
|
+
declared as a dependency or peer. An axis-emitted dependency is therefore never double-counted,
|
|
959
|
+
while a hand-added development dependency round-trips and stays audit-clean. Derivation yields no
|
|
960
|
+
`overrides`: they are caller-time inputs, not repository state. A computed artifact that must differ
|
|
961
|
+
reveals a gap in the canon; the blueprint grows an axis for that distinction rather than the
|
|
962
|
+
repository forking the file.
|
|
926
963
|
|
|
927
964
|
`storagePath`, `stageHost`, `readHostManifest`, `locateHostSource`, `remapArtifactPath`, and
|
|
928
965
|
`hydratePlan` are the vendored-host path. `storagePath` maps a repo-relative path to its un-dotted
|
|
@@ -961,44 +998,52 @@ ordered guide and version outcomes.
|
|
|
961
998
|
|
|
962
999
|
From [`compilers.ts`](../../src/core/compilers.ts).
|
|
963
1000
|
|
|
964
|
-
| Name
|
|
965
|
-
|
|
|
966
|
-
| `hostGroup`
|
|
967
|
-
| `fillArtifact`
|
|
968
|
-
| `srcVariant`
|
|
969
|
-
| `entryFields`
|
|
970
|
-
| `dualCondition`
|
|
971
|
-
| `exportsMap`
|
|
972
|
-
| `compareCodeUnit`
|
|
973
|
-
| `devDependenciesFor`
|
|
974
|
-
| `packageManifest`
|
|
975
|
-
| `rootTsconfig`
|
|
976
|
-
| `viteMachinery`
|
|
977
|
-
| `renderViteTest`
|
|
978
|
-
| `viteHeader`
|
|
979
|
-
| `policyViteProject`
|
|
980
|
-
| `
|
|
981
|
-
| `
|
|
982
|
-
| `
|
|
983
|
-
| `
|
|
984
|
-
| `
|
|
985
|
-
| `
|
|
986
|
-
| `
|
|
987
|
-
| `
|
|
988
|
-
| `
|
|
989
|
-
| `
|
|
990
|
-
| `
|
|
991
|
-
| `
|
|
992
|
-
| `
|
|
993
|
-
| `
|
|
994
|
-
| `
|
|
995
|
-
| `
|
|
996
|
-
| `
|
|
997
|
-
| `
|
|
998
|
-
| `
|
|
999
|
-
| `
|
|
1000
|
-
| `
|
|
1001
|
-
| `
|
|
1001
|
+
| Name | Kind |
|
|
1002
|
+
| -------------------------- | -------- |
|
|
1003
|
+
| `hostGroup` | function |
|
|
1004
|
+
| `fillArtifact` | function |
|
|
1005
|
+
| `srcVariant` | function |
|
|
1006
|
+
| `entryFields` | function |
|
|
1007
|
+
| `dualCondition` | function |
|
|
1008
|
+
| `exportsMap` | function |
|
|
1009
|
+
| `compareCodeUnit` | function |
|
|
1010
|
+
| `devDependenciesFor` | function |
|
|
1011
|
+
| `packageManifest` | function |
|
|
1012
|
+
| `rootTsconfig` | function |
|
|
1013
|
+
| `viteMachinery` | function |
|
|
1014
|
+
| `renderViteTest` | function |
|
|
1015
|
+
| `viteHeader` | function |
|
|
1016
|
+
| `policyViteProject` | function |
|
|
1017
|
+
| `guidesViteProject` | function |
|
|
1018
|
+
| `binViteProject` | function |
|
|
1019
|
+
| `integrationViteProject` | function |
|
|
1020
|
+
| `serviceViteProject` | function |
|
|
1021
|
+
| `viteProjectRegistrations` | function |
|
|
1022
|
+
| `viteProjectDefinitions` | function |
|
|
1023
|
+
| `singleSrcViteConfig` | function |
|
|
1024
|
+
| `rootViteConfig` | function |
|
|
1025
|
+
| `applicationViteConfig` | function |
|
|
1026
|
+
| `coreTsconfig` | function |
|
|
1027
|
+
| `coreViteConfig` | function |
|
|
1028
|
+
| `srcTsconfig` | function |
|
|
1029
|
+
| `srcViteConfig` | function |
|
|
1030
|
+
| `binTsconfig` | function |
|
|
1031
|
+
| `binViteConfig` | function |
|
|
1032
|
+
| `appTsconfig` | function |
|
|
1033
|
+
| `appViteConfig` | function |
|
|
1034
|
+
| `ciWorkflow` | function |
|
|
1035
|
+
| `configArtifacts` | function |
|
|
1036
|
+
| `sourceArtifacts` | function |
|
|
1037
|
+
| `applicationArtifacts` | function |
|
|
1038
|
+
| `paritySpecifiers` | function |
|
|
1039
|
+
| `testArtifacts` | function |
|
|
1040
|
+
| `guideMemberTable` | function |
|
|
1041
|
+
| `guideUsage` | function |
|
|
1042
|
+
| `guideMethods` | function |
|
|
1043
|
+
| `guideTests` | function |
|
|
1044
|
+
| `guideArtifacts` | function |
|
|
1045
|
+
| `applyOverrides` | function |
|
|
1046
|
+
| `blueprintToPlan` | function |
|
|
1002
1047
|
|
|
1003
1048
|
`blueprintToPlan` is the whole pure compilation: draft each selected group's artifacts, append the
|
|
1004
1049
|
host set, apply overrides, and pin. Everything above it is an exported leaf of that drafting, each
|
|
@@ -1008,10 +1053,11 @@ independently callable and independently tested.
|
|
|
1008
1053
|
several. `entryFields`, `dualCondition`, and `exportsMap` build the manifest entry fields and the
|
|
1009
1054
|
`exports` map from that variant; a browser-only package exports a single module condition, while
|
|
1010
1055
|
core and server src get dual import and require conditions with matching declaration files.
|
|
1011
|
-
`devDependenciesFor`
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1056
|
+
`devDependenciesFor` emits the blueprint's complete development dependency set: the shared
|
|
1057
|
+
baseline, package extras, dev-installed peers, selected browser toolchains, and the bin axis's
|
|
1058
|
+
browser test provider. Extras and peers are sorted by `compareCodeUnit` so ordering is stable across
|
|
1059
|
+
locales. `packageManifest` assembles the whole file — name, publication mode, files, scripts,
|
|
1060
|
+
dependencies, peers and their optional metadata, and engines.
|
|
1015
1061
|
|
|
1016
1062
|
`rootTsconfig` emits the root compiler options and one path alias per declared environment;
|
|
1017
1063
|
`coreTsconfig`, `srcTsconfig`, and `appTsconfig` emit the scoped configurations that remove the
|
|
@@ -1047,17 +1093,36 @@ along the three `ViteMachinery` axes:
|
|
|
1047
1093
|
An application of `app/core` alone is the sole shape that builds nothing, so it is the sole shape
|
|
1048
1094
|
without output containment — and it still carries every boundary guarantee above.
|
|
1049
1095
|
|
|
1050
|
-
`renderViteTest` is the single root-project renderer. It consumes ordered
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
`
|
|
1056
|
-
|
|
1057
|
-
|
|
1096
|
+
`renderViteTest` is the single root-project renderer. It consumes ordered `ViteProjectRegistration`
|
|
1097
|
+
data and emits either the plain project list or the browser gate, keeping source and application
|
|
1098
|
+
root configurations byte-consistent without reconstructing browser ownership.
|
|
1099
|
+
`viteProjectRegistrations` is the one registration derivation every root shape consumes: it derives
|
|
1100
|
+
the selected source and application projects from the canonical environment order, then appends
|
|
1101
|
+
`policy`, `guides`, and the optional `srcBin`, `integration`, and `service` projects.
|
|
1102
|
+
`viteProjectDefinitions` renders the standalone proof and structural-axis definitions in that same
|
|
1103
|
+
order with one blank line between declarations. Both consume `ViteAxes`, so each optional project is
|
|
1104
|
+
controlled only by its matching `bin`, `integration`, or `service` blueprint axis.
|
|
1105
|
+
|
|
1106
|
+
`coreViteConfig`, `srcViteConfig`, `binViteConfig`, and `appViteConfig` emit the thin per-target
|
|
1107
|
+
wrappers, while `binTsconfig` emits the executable declaration scope; `rootViteConfig`,
|
|
1108
|
+
`singleSrcViteConfig`, and `applicationViteConfig` emit the root configuration for a library-only,
|
|
1109
|
+
single non-core `src` environment, and application-bearing workspace respectively; and
|
|
1110
|
+
`policyViteProject`, `guidesViteProject`, `integrationViteProject`, and `serviceViteProject` emit
|
|
1111
|
+
the standalone Node proof projects, with `binViteProject` the single executable-project emitter. A
|
|
1112
|
+
proof project is structurally derived from the directory holding its tests and never wraps a source
|
|
1113
|
+
or application environment project. The guides project therefore uses only `tests/setup.ts`, never
|
|
1114
|
+
`setupServer.ts`, `setupBrowser.ts`, or `setupService.ts`; and its `tests/src/**/*.test.ts` and
|
|
1115
|
+
`tests/app/**/*.test.ts` exclude rows are uniform across all root shapes by design, including
|
|
1116
|
+
core-only workspaces where one row cannot currently match. Integration and service use 120-second
|
|
1117
|
+
test and hook timeouts with file parallelism disabled, and service alone layers
|
|
1118
|
+
`tests/setupService.ts` onto the shared setup. Where a bin workspace also ships the integration
|
|
1119
|
+
project, that project wires `tests/setupIntegration.ts` as its global setup for the shared
|
|
1120
|
+
template-registry harness; bin-less integration workspaces do not.
|
|
1058
1121
|
|
|
1059
1122
|
`configArtifacts`, `sourceArtifacts`, `applicationArtifacts`, `testArtifacts`, and `guideArtifacts`
|
|
1060
|
-
are the per-group drafters. `
|
|
1123
|
+
are the per-group drafters. When `bin` is selected, `configArtifacts` includes
|
|
1124
|
+
`configs/src/tsconfig.bin.json` and `configs/src/vite.bin.config.ts` beside the declared environment
|
|
1125
|
+
configuration pairs. `paritySpecifiers` computes the self-specifier and module map the
|
|
1061
1126
|
generated parity suite resolves fence imports through. `guideMemberTable`, `guideUsage`,
|
|
1062
1127
|
`guideMethods`, and `guideTests` render the generated guide's member tables, usage examples, method
|
|
1063
1128
|
contract, and test inventory. `fillArtifact` fills one template entry into a `template`-origin
|
|
@@ -1286,13 +1351,13 @@ Audit semantics follow directly from that.
|
|
|
1286
1351
|
- A target file the plan does not own is `foreign`, and `inferGroup` classifies it by its leading
|
|
1287
1352
|
path segment.
|
|
1288
1353
|
|
|
1289
|
-
The same ownership boundary is what makes mutation safe. **`
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
`.github/workflows/ci.yml` is a **computed** artifact,
|
|
1294
|
-
|
|
1295
|
-
|
|
1354
|
+
The same ownership boundary is what makes mutation safe. **`fleet` and default `repair` both scope
|
|
1355
|
+
the compiled plan to host origin before hydrating, diffing, or applying.** `--generated` widens that
|
|
1356
|
+
scoped plan to generated canon except `package.json`; template artifacts remain birth-only in
|
|
1357
|
+
either mode. A mature workspace's hand-written source, tests, guides, and manifest are therefore
|
|
1358
|
+
never overwritten with a stub. The generated `.github/workflows/ci.yml` is a **computed** artifact,
|
|
1359
|
+
so user-owned CI stands by default but is intentionally restored when `--generated` is passed.
|
|
1360
|
+
Audit always compares it because computed artifacts are content-aware canon. A legitimate
|
|
1296
1361
|
difference that the blueprint cannot express is a canon gap: add the missing blueprint axis rather
|
|
1297
1362
|
than forking the computed file in one repository.
|
|
1298
1363
|
|
|
@@ -1324,12 +1389,20 @@ An audit is a pure function of a plan and a snapshot, so the same engine that cr
|
|
|
1324
1389
|
checks one. `readTarget` supplies the snapshot as exact bytes; `diffPlan` returns findings as data;
|
|
1325
1390
|
`auditToReview` renders them for a human. Nothing in that path writes.
|
|
1326
1391
|
|
|
1392
|
+
The executable's physical unexpected-file scan treats exactly `scripts/service.sh` as an expected
|
|
1393
|
+
consumer-owned seam when the derived blueprint has `service: true`. That exclusion is warranted
|
|
1394
|
+
because a service blueprint cannot derive without the physical file: the companion-file law raises
|
|
1395
|
+
a `TARGET` failure first, so the scan removes a false positive and can never mask an absent
|
|
1396
|
+
provisioner. A non-service workspace still reports the same path as foreign.
|
|
1397
|
+
|
|
1327
1398
|
`repair` turns those findings back into the narrowest possible write. It re-reads the target,
|
|
1328
1399
|
re-diffs it, and refuses to proceed if the findings changed since the preview it was given — a
|
|
1329
1400
|
target that moved under the caller is a `TARGET` failure, not a race to win. It then derives a write
|
|
1330
1401
|
precondition per artifact from the audit itself: a `missing` finding requires the destination to
|
|
1331
1402
|
still be absent, a `stale` finding requires it to still carry exactly the bytes that were observed.
|
|
1332
1403
|
Those preconditions are checked again inside the write transaction before any promotion.
|
|
1404
|
+
An interactive audit repair hand-off forwards `--generated` into the repair invocation when the
|
|
1405
|
+
flag was present on `audit`.
|
|
1333
1406
|
|
|
1334
1407
|
`prune` is the deletion arm, and it is deliberately narrow. Its candidate set comes from
|
|
1335
1408
|
`pruneTargets`, which is also what the executable's audit and preview read, so what is reported and
|
|
@@ -1400,24 +1473,65 @@ configuration, and ships `dist/src` plus its README. An application-only workspa
|
|
|
1400
1473
|
that builds its own executable additionally ships `dist/bin` and `dist/host`. Scripts are emitted in
|
|
1401
1474
|
a fixed, interleaved order so aggregates sit immediately before their per-environment members:
|
|
1402
1475
|
|
|
1403
|
-
- `clean`, `copy`, `scaffold`
|
|
1404
|
-
- `lint` and `lint:check`, `format` and `format:check`
|
|
1476
|
+
- `clean`, `copy`, `scaffold`, `lint`
|
|
1405
1477
|
- `check`, then `check:src` with one `check:src:<environment>` per published environment, then
|
|
1406
1478
|
`check:app` with one `check:app:<environment>` per app environment — the browser app scope uses the
|
|
1407
1479
|
Vue typechecker, every other scope uses plain `tsc`
|
|
1408
|
-
- `
|
|
1409
|
-
|
|
1410
|
-
`test:
|
|
1480
|
+
- `format`, `format:check`, `lint:check`
|
|
1481
|
+
- `test`, then `test:src` and its per-environment scopes, the optional `test:integration`,
|
|
1482
|
+
`test:equivalence`, and `test:service` proofs, `test:app` and its per-environment scopes, then
|
|
1483
|
+
`test:policy` and `test:guides`
|
|
1411
1484
|
- `build`, then `build:src` and its per-environment targets, `build:app` and its runtime targets, and
|
|
1412
|
-
`build:host` for
|
|
1485
|
+
`build:host` for a bin workspace
|
|
1413
1486
|
- `dev` when a browser application is selected; `serve` and `serve:build` when a server application
|
|
1414
1487
|
is selected
|
|
1415
|
-
- `prepublishOnly` chaining `format:check → lint:check → check → build → test`, followed by
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1488
|
+
- `prepublishOnly` chaining `format:check → lint:check → check → build → test`, followed by
|
|
1489
|
+
`test:integration` when the integration axis is selected
|
|
1490
|
+
|
|
1491
|
+
**Proof gating.** The opt-in proofs are predictable from the axes alone. `test:integration` rides
|
|
1492
|
+
the `integration` axis and `test:service` the `service` axis, while `test:equivalence` is emitted
|
|
1493
|
+
only where `bin` and `integration` are both set:
|
|
1494
|
+
|
|
1495
|
+
| Proof | `npm test` | `prepublishOnly` | CI |
|
|
1496
|
+
| ------------------ | ---------- | ---------------- | -------------------------- |
|
|
1497
|
+
| `test:integration` | no | yes, last | after the standard gates |
|
|
1498
|
+
| `test:equivalence` | no | no | no |
|
|
1499
|
+
| `test:service` | no | never | after `scripts/service.sh` |
|
|
1500
|
+
|
|
1501
|
+
No proof joins the default chain: `npm test` runs the source, application, policy, and guide
|
|
1502
|
+
projects, and nothing there needs a build artifact or a foreign process. Publication is the one
|
|
1503
|
+
asymmetry — `prepublishOnly` appends `test:integration`, because a package about to be published
|
|
1504
|
+
should prove itself against its own built output, while `test:service` is never in that chain.
|
|
1505
|
+
Neither default testing nor publication starts or requires a foreign process.
|
|
1506
|
+
|
|
1507
|
+
When a prerequisite is absent the proof fails rather than skipping. `test:integration` reads the
|
|
1508
|
+
workspace's own built output, so it belongs after `build` — which is exactly where `prepublishOnly`
|
|
1509
|
+
and CI put it. `test:service` refuses to start against an unprovisioned service: its setup throws at
|
|
1510
|
+
module load, which is why CI runs `bash scripts/service.sh` immediately before it. And a script the
|
|
1511
|
+
axes do not emit is simply not there: `test:equivalence` in a workspace that is not both `bin` and
|
|
1512
|
+
`integration` is an unknown script rather than a quietly passing one.
|
|
1513
|
+
|
|
1514
|
+
The equivalence proof is a dual-path re-run rather than a separate suite. Run
|
|
1515
|
+
`npm run test:equivalence` after changing the persistent boundary build driver; it invokes the
|
|
1419
1516
|
integration project in dual-path mode and proves each programmatic driver verdict against the
|
|
1420
|
-
spawned npm-script reference
|
|
1517
|
+
spawned npm-script reference. Ordinary integration runs keep the faster driver-only path.
|
|
1518
|
+
|
|
1519
|
+
**Consumer-owned service seams.** The service axis is the one place canon stops at the boundary:
|
|
1520
|
+
there is no template for a proof project and neither companion path is on `HOST_PATHS`, so a
|
|
1521
|
+
service workspace owns both of its seams outright. They come as a pair.
|
|
1522
|
+
|
|
1523
|
+
- `tests/setupService.ts` is the readiness seam. It probes the foreign process and warms it before
|
|
1524
|
+
any test runs, and throws at module load — naming the `service` project — when that process is
|
|
1525
|
+
unreachable, so an unprovisioned run fails loudly instead of passing an empty suite. Only the
|
|
1526
|
+
`service` project loads it.
|
|
1527
|
+
- `scripts/service.sh` is the provisioning seam, named once by `SERVICE_SCRIPT_PATH`. It brings that
|
|
1528
|
+
process up idempotently — a second run against an already-provisioned service is a no-op rather
|
|
1529
|
+
than a second instance — and exits nonzero when it cannot, which is what makes CI's
|
|
1530
|
+
`bash scripts/service.sh` step a gate rather than a hint.
|
|
1531
|
+
|
|
1532
|
+
The audit expects the script rather than reporting it foreign, on the derive-time warrant the audit
|
|
1533
|
+
section gives. Repair pruning applies the same exclusion, so it never proposes or removes that
|
|
1534
|
+
required consumer-owned provisioner.
|
|
1421
1535
|
|
|
1422
1536
|
**Environment isolation.** Scoped TypeScript projects remove the wrong host's globals from each
|
|
1423
1537
|
environment: core scopes carry the WHATWG web-interop surface and no host at all — no DOM, no Node,
|
|
@@ -1575,7 +1689,8 @@ Node `22.12.0` and `26`** with fail-fast disabled. Checkout and Node setup are p
|
|
|
1575
1689
|
action commits, and checkout does not persist credentials. Dependencies install with
|
|
1576
1690
|
`npm ci --ignore-scripts`; Chromium is installed only when the workspace selects a browser environment
|
|
1577
1691
|
or builds its own executable. The gates then run in order: `format:check`, `lint:check`, `check`,
|
|
1578
|
-
`build`, `test
|
|
1692
|
+
`build`, `test`, and the workspace's selected proofs follow as their own named steps, in the order
|
|
1693
|
+
the proof-gating table gives them.
|
|
1579
1694
|
|
|
1580
1695
|
**Agent orchestration files.** The session hooks in the generated `.claude/settings.json` run the
|
|
1581
1696
|
dependency, model, and external-tool readiness scripts at session start. The **`Stop` hook runs only
|
|
@@ -1604,7 +1719,7 @@ no module API of its own. Six verbs:
|
|
|
1604
1719
|
| `new` | scaffold a workspace into `./<name>` |
|
|
1605
1720
|
| `pull` | refresh vendored guides and versions, report drift |
|
|
1606
1721
|
| `audit` | whole-plan conformance report |
|
|
1607
|
-
| `repair` | restore
|
|
1722
|
+
| `repair` | restore host-owned files and optional generated canon |
|
|
1608
1723
|
| `fleet` | audit or repair every workspace under the cwd's children |
|
|
1609
1724
|
| `catalog` | regenerate the fleet package-catalog table |
|
|
1610
1725
|
|
|
@@ -1625,8 +1740,10 @@ declared dependency mirror is considered.
|
|
|
1625
1740
|
`--groups a,b` scopes an audit to artifact groups. `--live` adds an upstream freshness check to an
|
|
1626
1741
|
audit. `--strict` makes a pull throw on a network fault. `--offline` restricts a catalog to local
|
|
1627
1742
|
sources. `--prune` opts a repair or fleet run into deleting unexpected files under the three prune
|
|
1628
|
-
directories. `--
|
|
1629
|
-
|
|
1743
|
+
directories. `--generated` opts a repair or fleet run into restoring generated canon except
|
|
1744
|
+
`package.json`; on `audit`, it is inherited if the interactive repair hand-off is accepted.
|
|
1745
|
+
`--json` emits one machine-readable value. `--apply` writes, `--yes` skips the confirmation, and
|
|
1746
|
+
`-h` or `--help` prints usage.
|
|
1630
1747
|
|
|
1631
1748
|
**Safety model.** Every verb is a dry run by default. On a terminal a write asks for confirmation
|
|
1632
1749
|
first, defaulting to no; in a script, `--apply` writes and `--yes` skips the question. Every write is
|
|
@@ -1636,8 +1753,9 @@ non-interactive session without `--apply` or `--yes` skips pruning rather than g
|
|
|
1636
1753
|
operates on the immediate children of the working directory and never on the directory itself, and
|
|
1637
1754
|
it has no root flag at all — `repair` is the single-workspace tool.
|
|
1638
1755
|
|
|
1639
|
-
|
|
1640
|
-
in
|
|
1756
|
+
`fleet` and default `repair` are scoped to host-origin artifacts. `repair` states its selected scope
|
|
1757
|
+
in the output; `--generated` widens both verbs to generated files while still excluding starter
|
|
1758
|
+
files and `package.json`.
|
|
1641
1759
|
|
|
1642
1760
|
**Catalog markers.** `catalog` rewrites the block between `<!-- catalog:start -->` and
|
|
1643
1761
|
`<!-- catalog:end -->` in `.claude/agents/orkestrel.md`. **Ambiguous markers fail before any
|
|
@@ -1990,7 +2108,7 @@ srcVariant(['core', 'server']) // 'multi'
|
|
|
1990
2108
|
entryFields(['browser']).main // './dist/src/browser/index.js'
|
|
1991
2109
|
dualCondition('./dist/src/core/index')
|
|
1992
2110
|
exportsMap(['core'])['.']
|
|
1993
|
-
devDependenciesFor(spec
|
|
2111
|
+
devDependenciesFor(spec).typescript
|
|
1994
2112
|
packageManifest(spec) // the whole manifest, newline-terminated
|
|
1995
2113
|
|
|
1996
2114
|
configArtifacts(spec).length
|
|
@@ -2020,17 +2138,23 @@ import {
|
|
|
2020
2138
|
appTsconfig,
|
|
2021
2139
|
appViteConfig,
|
|
2022
2140
|
applicationViteConfig,
|
|
2141
|
+
binViteProject,
|
|
2023
2142
|
coreTsconfig,
|
|
2024
2143
|
coreViteConfig,
|
|
2144
|
+
guidesViteProject,
|
|
2145
|
+
integrationViteProject,
|
|
2025
2146
|
policyViteProject,
|
|
2026
2147
|
renderViteTest,
|
|
2027
2148
|
rootTsconfig,
|
|
2028
2149
|
rootViteConfig,
|
|
2150
|
+
serviceViteProject,
|
|
2029
2151
|
singleSrcViteConfig,
|
|
2030
2152
|
srcTsconfig,
|
|
2031
2153
|
srcViteConfig,
|
|
2032
2154
|
viteHeader,
|
|
2033
2155
|
viteMachinery,
|
|
2156
|
+
viteProjectDefinitions,
|
|
2157
|
+
viteProjectRegistrations,
|
|
2034
2158
|
} from '@orkestrel/scaffold'
|
|
2035
2159
|
|
|
2036
2160
|
rootTsconfig(['core'], ['core', 'server'])
|
|
@@ -2046,8 +2170,15 @@ coreViteConfig()
|
|
|
2046
2170
|
srcViteConfig('browser')
|
|
2047
2171
|
appViteConfig('server')
|
|
2048
2172
|
policyViteProject()
|
|
2049
|
-
|
|
2050
|
-
|
|
2173
|
+
guidesViteProject()
|
|
2174
|
+
binViteProject()
|
|
2175
|
+
integrationViteProject({ bin: true, integration: true })
|
|
2176
|
+
serviceViteProject()
|
|
2177
|
+
viteProjectDefinitions({ integration: true }).includes('export const integration =') // true
|
|
2178
|
+
viteProjectRegistrations(['core'], [], { integration: true }).map(({ project }) => project)
|
|
2179
|
+
// ['srcCore', 'policy', 'guides', 'integration']
|
|
2180
|
+
|
|
2181
|
+
rootViteConfig(['core', 'server'], { bin: true })
|
|
2051
2182
|
singleSrcViteConfig('server').includes('srcServer') // true
|
|
2052
2183
|
applicationViteConfig([], ['core', 'server']).includes('appServer') // true
|
|
2053
2184
|
```
|
|
@@ -2152,6 +2283,7 @@ import {
|
|
|
2152
2283
|
discoverPackages,
|
|
2153
2284
|
guideToDescription,
|
|
2154
2285
|
isRealDirectory,
|
|
2286
|
+
isRealFile,
|
|
2155
2287
|
listDirectories,
|
|
2156
2288
|
listFiles,
|
|
2157
2289
|
pruneTargets,
|
|
@@ -2166,6 +2298,7 @@ deriveBlueprint('./packages/router') // the faithful inverse an audit diffs agai
|
|
|
2166
2298
|
selectOrkestrelEntries({ '@orkestrel/contract': '^0.0.7', vite: '^8.1.5' })
|
|
2167
2299
|
|
|
2168
2300
|
isRealDirectory('./packages/router')
|
|
2301
|
+
isRealFile('./packages/router/package.json')
|
|
2169
2302
|
listFiles('./packages/router/.claude/agents')
|
|
2170
2303
|
listDirectories('./packages/router/.claude')
|
|
2171
2304
|
|