@orkestrel/scaffold 0.0.48 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/main.js +271 -53
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/orchestration.md +7 -0
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +4 -0
- package/dist/host/claude/rules/quality.md +4 -1
- package/dist/host/guides/scaffold.md +150 -65
- package/dist/host/manifest.json +217 -109
- package/dist/host/tests/config.test.ts +103 -1
- package/dist/src/core/index.cjs +32 -4
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +65 -8
- package/dist/src/core/index.d.ts +65 -8
- package/dist/src/core/index.js +31 -5
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +769 -137
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +681 -376
- package/dist/src/server/index.d.ts +681 -376
- package/dist/src/server/index.js +766 -141
- package/dist/src/server/index.js.map +1 -1
- package/package.json +3 -2
|
@@ -32,6 +32,10 @@ A round also needs something new to attack. When the previous round's claims all
|
|
|
32
32
|
been added or repaired since, and the only motive is that an auditor could still imagine an attack,
|
|
33
33
|
there is no subject — closing is the correct action and the next subject is the deliverable.
|
|
34
34
|
|
|
35
|
+
When the same class has recurred along one seam to the budget in `.claude/rules/quality.md`
|
|
36
|
+
§ Rounds and verdicts, the next move is that law's strategy switch — the breadth sweep of the
|
|
37
|
+
stream, the ruling, or the dropped moving-target claim — rather than another successor round.
|
|
38
|
+
|
|
35
39
|
## Write the brief
|
|
36
40
|
|
|
37
41
|
The brief is the instrument. A weak brief produces a confirming review no matter which auditor reads
|
|
@@ -83,7 +83,10 @@ A review that reads a diff finds what the diff shows. A review that tries to bre
|
|
|
83
83
|
- A fix that adopts the auditor's prescription verbatim may close with a mutation probe in place of a fresh audit round: disable the load-bearing line, watch the adopted pin fail, restore it, and commit the pin as the regression guard. A fix that departs from the prescription gets the cross-engine round.
|
|
84
84
|
- Let reachability bound the fix. A defect reachable through the package's own shipped code or a documented extension seam falsifies its claim and is repaired now.
|
|
85
85
|
- Document the obligation instead when a defect is reachable only through a hypothetical foreign implementation of a contract this package publishes. State it on the interface that owns it and prove the documentation. Do not build coordination machinery against a requirement nobody wrote down. Attacks are unlimited; reachable ones are not, and only the reachable set is a work list.
|
|
86
|
-
- **Three rounds at one seam is the budget.** Repeated rounds against one seam are evidence about the design, not evidence of diligence. At the third round the
|
|
86
|
+
- **Three rounds at one seam is the budget, and reaching it switches the search strategy rather than stopping the work.** Repeated rounds against one seam are evidence about the design, not evidence of diligence. At the third round, name what the audit is trying to accomplish, then pick the successor strategy from what the recurrence shows.
|
|
87
|
+
- Recurrence with a direction — each fix relocates the class along one stream, or the evidence points up a dependency chain — ends the depth search. Run one breadth round that probes the stream's stations in parallel to locate the source, in the shape `.agents/orchestration.md` § Context and decomposition prescribes, then plan the downstream work from the source and size it by the sweep's map.
|
|
88
|
+
- Recurrence with no direction makes the seam itself the question. The next unit is a ruling — on the threat model, the mechanism, or the boundary — taken with the same adversarial pass a design gets, not a fourth repair.
|
|
89
|
+
- A subject that reprices itself on every edit — a count, a census, a total over prose — has no closing condition and is not a seam. Drop the claim, or recast it as the property the tally stood in for.
|
|
87
90
|
- Write the round count down in the capability/defect matrix row that owns the seam, when the seam opens, so it is a fact rather than a feeling. A seam that has consumed more rounds than the rest of the matrix combined has already answered the question.
|
|
88
91
|
- State the ruling that ends a seam as the invariant the code will obey, the constraint bounding it against over-correction, and the interface where a consumer meets the obligation. A ruling that names only the defect it replaces produces the opposite defect next round.
|
|
89
92
|
- Give every behavioural audit the means to run its attacks. An auditor that cannot execute cannot falsify a behavioural claim: it returns derivations, and a derivation reads exactly like a verdict while being a different thing — it will confirm a claim one probe would break. Treat a report with no executed evidence as a review of the source, and label it as such.
|
|
@@ -12,11 +12,11 @@ does not work. Scaffold makes the shared set data — a vendored data root shipp
|
|
|
12
12
|
— and gives it verbs: create a workspace from it, report how a workspace differs from it, and
|
|
13
13
|
write the difference back.
|
|
14
14
|
|
|
15
|
-
Every code fence below is illustrative. [`tests/guides.test.ts`](../tests/guides.test.ts)
|
|
16
|
-
transcribes the pure blueprint-default,
|
|
17
|
-
|
|
18
|
-
answer; the driven examples are the ones the shipped declarations
|
|
19
|
-
leaves unproven and what covers it instead.
|
|
15
|
+
Every code fence below is illustrative. [`tests/guides.test.ts`](../tests/guides.test.ts) keeps the
|
|
16
|
+
command reference aligned with the executable and transcribes the pure blueprint-default,
|
|
17
|
+
compile-refusal, and error-narrowing fences. A trailing comment in another fence is this guide's
|
|
18
|
+
claim rather than a measured answer; the driven examples are the ones the shipped declarations
|
|
19
|
+
print. Limits states what that leaves unproven and what covers it instead.
|
|
20
20
|
|
|
21
21
|
```sh
|
|
22
22
|
npm install --save-dev @orkestrel/scaffold
|
|
@@ -44,11 +44,12 @@ Exported from `@orkestrel/scaffold`, and reachable from
|
|
|
44
44
|
| `CatalogEntry` | type | One package row of the fleet catalog. |
|
|
45
45
|
| `CompileStage` | type | The compile phases, in the order they run. |
|
|
46
46
|
| `CompilerEventMap` | type | The compiler's observation channel. |
|
|
47
|
+
| `HostFile` | type | One vendored file read from the repository, beside the target bytes it answers for. |
|
|
47
48
|
| `Drift` | type | How one target path compares to the artifact planned for it. |
|
|
48
49
|
| `Environment` | type | One environment a generated workspace selects on its `src` or `app` axis. |
|
|
49
50
|
| `Finding` | type | One drift verdict against a target path. |
|
|
50
51
|
| `Group` | type | The artifact group a plan selects over. |
|
|
51
|
-
| `Lookup` | type |
|
|
52
|
+
| `Lookup` | type | How an upstream lookup resolved: found, missing, unmatched, or failed. |
|
|
52
53
|
| `Mirror` | type | One dependency guide fetched from upstream, beside the local mirror it answers for. |
|
|
53
54
|
| `Origin` | type | How an artifact's content is produced. |
|
|
54
55
|
| `Ownership` | type | What scaffold claims at an artifact's path. |
|
|
@@ -112,6 +113,7 @@ Exported from `@orkestrel/scaffold`, and reachable from
|
|
|
112
113
|
| `GUIDES_TEST_PATH` | const | The guide-parity proof whose presence selects the planned `guides` project. |
|
|
113
114
|
| `HEX_PATTERN` | const | Exact lowercase hexadecimal bytes: two digits per byte, and empty content is valid. |
|
|
114
115
|
| `HOST_PATHS` | const | The paths byte-copied from the vendored data root, frozen. |
|
|
116
|
+
| `HOST_INVENTORY_PATH` | const | The repository-relative path where the committed vendored-file inventory is served. |
|
|
115
117
|
| `INTEGRATION_TEST_PATH` | const | The cross-environment composition proof whose presence makes a workspace `integration`. |
|
|
116
118
|
| `INVALID_PATH_CHARACTER_PATTERN` | const | Visible characters a target-relative path and a Markdown path cell both forbid. |
|
|
117
119
|
| `MAX_ARTIFACT_BYTES` | const | Maximum bytes accepted for one artifact. |
|
|
@@ -195,6 +197,7 @@ Exported from `@orkestrel/scaffold`, and reachable from
|
|
|
195
197
|
| `extractVersion` | function | Extract the major, minor, and patch components of an exact version. |
|
|
196
198
|
| `inferDrift` | function | Infer how one target path compares to the artifact planned for it. |
|
|
197
199
|
| `inferGroup` | function | Infer the `Group` a path belongs to. |
|
|
200
|
+
| `isDeferredPath` | function | Test whether another surface owns the vendored bytes at a path. |
|
|
198
201
|
| `manifestToDependencies` | function | Project a package manifest's text to the `@orkestrel/*` packages it declares. |
|
|
199
202
|
| `manifestToName` | function | Project a package manifest's text to its own name. |
|
|
200
203
|
| `matchesDriftReachability` | function | Test whether `inferDrift` could have produced a finding for an ownership. |
|
|
@@ -270,12 +273,13 @@ Exported from `@orkestrel/scaffold/server`, and reachable from
|
|
|
270
273
|
|
|
271
274
|
| Name | Kind | Summary |
|
|
272
275
|
| ----------------------- | --------- | ------------------------------------------------------------------------------------ |
|
|
276
|
+
| `Host` | interface | A whole vendored host supplied as a value rather than read from a directory. |
|
|
273
277
|
| `HostManifest` | interface | The complete vendored-host inventory. |
|
|
274
|
-
| `ManifestEntry` | interface | One file record of the vendored host's manifest.
|
|
278
|
+
| `ManifestEntry` | interface | One file record of the vendored host's manifest, including its exact-byte digest. |
|
|
275
279
|
| `MaterializeResult` | interface | The outcome of one mutation of a target. |
|
|
276
280
|
| `MaterializerInterface` | interface | The mutation contract: the package's only filesystem writer. |
|
|
277
281
|
| `MaterializerOptions` | interface | Options for the materializer. |
|
|
278
|
-
| `
|
|
282
|
+
| `Worktree` | interface | What git reports about a target's working tree. |
|
|
279
283
|
| `UpstreamInterface` | interface | The upstream contract: the package's only network reader, and it never writes. |
|
|
280
284
|
| `UpstreamOptions` | interface | Options for the upstream reader. |
|
|
281
285
|
| `WriteAnchor` | interface | One physical directory identity captured across a write transaction. |
|
|
@@ -287,12 +291,12 @@ Exported from `@orkestrel/scaffold/server`, and reachable from
|
|
|
287
291
|
|
|
288
292
|
| Name | Kind | Summary |
|
|
289
293
|
| ----------------------------------- | ----- | ---------------------------------------------------------------------------------------- |
|
|
290
|
-
| `BRANCH_PATTERN` | const | The Git branch syntax the
|
|
294
|
+
| `BRANCH_PATTERN` | const | The Git branch syntax the repository endpoint accepts. |
|
|
291
295
|
| `DIGEST_PATTERN` | const | The exact SHA-256 syntax a digest is stated in: sixty-four lowercase hexadecimal digits. |
|
|
292
296
|
| `DRIVE_PATTERN` | const | The drive prefix a Windows host path may open with. |
|
|
293
297
|
| `INVALID_SEGMENT_CHARACTER_PATTERN` | const | Visible characters no host path segment may carry. |
|
|
294
298
|
| `MANIFEST_NAME` | const | The reserved metadata name a staged vendored host writes at its own root. |
|
|
295
|
-
| `MAX_BRANCH_LENGTH` | const | Maximum characters one
|
|
299
|
+
| `MAX_BRANCH_LENGTH` | const | Maximum characters one repository branch may carry. |
|
|
296
300
|
| `MAX_ENDPOINT_LENGTH` | const | Maximum characters one caller-supplied upstream endpoint may carry. |
|
|
297
301
|
| `MAX_INVENTORY_PATHS` | const | Maximum paths one target's working-tree inventory may report. |
|
|
298
302
|
| `MAX_PATH_DEPTH` | const | Maximum segments one host path may carry. |
|
|
@@ -306,20 +310,22 @@ Exported from `@orkestrel/scaffold/server`, and reachable from
|
|
|
306
310
|
|
|
307
311
|
| Name | Kind | Summary |
|
|
308
312
|
| ----------------------- | -------- | ---------------------------------------------------------------------------------- |
|
|
309
|
-
| `isBranch` | const | Narrow a value to a Git branch the
|
|
313
|
+
| `isBranch` | const | Narrow a value to a Git branch the repository endpoint accepts. |
|
|
310
314
|
| `isCatalogEntries` | const | Narrow a value to a bounded list of fleet catalog rows. |
|
|
311
315
|
| `isDependencies` | const | Narrow a value to a bounded list of declared runtime dependencies. |
|
|
312
316
|
| `isDependencyNames` | const | Narrow a value to a bounded list of `@orkestrel` package names. |
|
|
313
317
|
| `isDigest` | const | Narrow a value to one exact SHA-256 digest. |
|
|
314
318
|
| `isEndpoint` | const | Narrow a value to a bounded upstream endpoint. |
|
|
315
319
|
| `isFilesystemPath` | function | Narrow a value to a path naming a location on this host. |
|
|
320
|
+
| `isHost` | const | Narrow a value to one whole vendored host supplied as a value. |
|
|
316
321
|
| `isHostManifest` | const | Narrow a value to one `HostManifest`. |
|
|
317
322
|
| `isInventory` | function | Narrow a value to a working-tree inventory within the limit one target may report. |
|
|
318
323
|
| `isManifestEntry` | const | Narrow a value to one `ManifestEntry`. |
|
|
319
324
|
| `isMaterializerHooks` | const | Narrow a value to the materializer's initial listener record. |
|
|
320
325
|
| `isMaterializerOptions` | const | Narrow a value to `MaterializerOptions`. |
|
|
321
326
|
| `isMirrors` | const | Narrow a value to a bounded list of fetched guide mirrors. |
|
|
322
|
-
| `
|
|
327
|
+
| `isPaths` | const | Narrow a value to a bounded list of target-relative paths. |
|
|
328
|
+
| `isWorktree` | const | Narrow a value to a `Worktree`. |
|
|
323
329
|
| `isTimeout` | const | Narrow a value to a per-request timeout in milliseconds. |
|
|
324
330
|
| `isUpstreamHooks` | const | Narrow a value to the upstream reader's initial listener record. |
|
|
325
331
|
| `isUpstreamOptions` | const | Narrow a value to `UpstreamOptions`. |
|
|
@@ -331,6 +337,8 @@ Exported from `@orkestrel/scaffold/server`, and reachable from
|
|
|
331
337
|
| `computeDigest` | function | Compute the SHA-256 digest of text. |
|
|
332
338
|
| `computeFileDigest` | function | Compute the SHA-256 digest of one file's exact bytes. |
|
|
333
339
|
| `computeManifestDigest` | function | Compute the digest of a vendored host's declared membership. |
|
|
340
|
+
| `filesToHost` | function | Overlay host-owned live files onto the installed vendored floor. |
|
|
341
|
+
| `hexToDigest` | function | Project exact bytes stated in hexadecimal to their SHA-256 digest. |
|
|
334
342
|
| `isExactCaseFile` | function | Test whether a physical file's path matches every on-disk segment exactly. |
|
|
335
343
|
| `isPhysicalDirectory` | function | Test whether a path is a physical directory this package will read or write into. |
|
|
336
344
|
| `isPhysicalFile` | function | Test whether a path is a physical file this package will read or replace. |
|
|
@@ -350,12 +358,15 @@ Exported from `@orkestrel/scaffold/server`, and reachable from
|
|
|
350
358
|
| `readExpectation` | function | Capture what one destination holds before a write. |
|
|
351
359
|
| `readFileHex` | function | Read one contained file as its exact bytes in lowercase hexadecimal. |
|
|
352
360
|
| `readFileText` | function | Read one contained file as bounded UTF-8 text. |
|
|
361
|
+
| `readHostFloor` | function | Read the installed vendored host floor as a verified value. |
|
|
353
362
|
| `readHostManifest` | function | Read a vendored host's manifest, when it carries one. |
|
|
354
363
|
| `readManifestEntry` | function | Derive one vendored-host manifest entry from a file in a checkout. |
|
|
355
364
|
| `readSnapshot` | function | Read a target's current bytes at the paths a plan claims. |
|
|
356
365
|
| `resolveContainedPath` | function | Resolve a root-relative path and refuse one that leaves its root. |
|
|
357
366
|
| `resolveRealPath` | function | Resolve a path through the real filesystem, keeping the part that does not exist yet. |
|
|
367
|
+
| `stageBytes` | function | Stage the named destinations of a value host into a private root. |
|
|
358
368
|
| `stageHost` | function | Stage a vendored host root from a real checkout. |
|
|
369
|
+
| `stageInventory` | function | Stage the committed vendored-file inventory from a real checkout. |
|
|
359
370
|
|
|
360
371
|
#### Classes
|
|
361
372
|
|
|
@@ -395,12 +406,13 @@ no interface and is documented directly.
|
|
|
395
406
|
|
|
396
407
|
#### `UpstreamInterface`
|
|
397
408
|
|
|
398
|
-
| Method | Summary
|
|
399
|
-
| --------- |
|
|
400
|
-
| `lookup` | Look up the newest release each declared range admits.
|
|
401
|
-
| `fetch` | Fetch each named package's guide, beside the local mirror it answers for.
|
|
402
|
-
| `
|
|
403
|
-
| `
|
|
409
|
+
| Method | Summary |
|
|
410
|
+
| --------- | ------------------------------------------------------------------------------------------ |
|
|
411
|
+
| `lookup` | Look up the newest release each declared range admits. |
|
|
412
|
+
| `fetch` | Fetch each named package's guide, beside the local mirror it answers for. |
|
|
413
|
+
| `read` | Read each named vendored file from the repository, beside the target bytes it answers for. |
|
|
414
|
+
| `catalog` | Catalog the published fleet from the registry's organization package list. |
|
|
415
|
+
| `destroy` | Tear the reader down, aborting every request in flight. |
|
|
404
416
|
|
|
405
417
|
#### `WriteTransaction`
|
|
406
418
|
|
|
@@ -426,34 +438,62 @@ option grants a write.
|
|
|
426
438
|
| `catalog` | The package table, the guide mirrors, and the ranges |
|
|
427
439
|
| `overwrite` | Everything `repair` and `catalog` write, plus deletions |
|
|
428
440
|
|
|
441
|
+
### Baselines
|
|
442
|
+
|
|
443
|
+
Every remote surface reads its live source first and falls back, whole, to the copy the installed
|
|
444
|
+
package distributes; each operation reports one baseline word per surface. A surface can select
|
|
445
|
+
`floor` only where the package distributes a copy. The registry's organization membership ships
|
|
446
|
+
nowhere, so `catalog` refuses when that read fails.
|
|
447
|
+
|
|
448
|
+
For `new`, `repair`, `catalog`, and `overwrite`, authoritative absence never selects `floor`. A
|
|
449
|
+
registry `404` or a packument with no admitted version stays a `FETCH` refusal, because writing a
|
|
450
|
+
version the registry says is absent produces an uninstallable manifest. `audit` turns release
|
|
451
|
+
absence into questions and returns its audit result. Transport faults, timeouts, rate refusals,
|
|
452
|
+
byte-bound refusals, and integrity refusals can select the floor.
|
|
453
|
+
|
|
454
|
+
The guide surface is the per-row exception to whole-surface fallback. A failed foreign guide keeps
|
|
455
|
+
the target's existing mirror as its floor, while the other guide rows can still update. When at
|
|
456
|
+
least one selected guide keeps its mirror, `provenance.guides` is `floor` for the result; it is
|
|
457
|
+
`live` only when every selected guide resolved live.
|
|
458
|
+
|
|
459
|
+
A value `Host` can carry live host-owned bytes beside installed floor bytes for deferred guide and
|
|
460
|
+
catalog paths. Each surface still contributes one baseline. Deferred paths are presence-only, and
|
|
461
|
+
repair never writes their floor bytes.
|
|
462
|
+
|
|
463
|
+
Every verb's machine-readable result carries `provenance`. The record names only the remote
|
|
464
|
+
surfaces that the verb read. A host supplied by the `--from` option is absent because it comes from
|
|
465
|
+
a local path.
|
|
466
|
+
|
|
429
467
|
`scaffold --help` prints the whole reference:
|
|
430
468
|
|
|
431
469
|
```text
|
|
432
470
|
scaffold <verb> [options]
|
|
433
471
|
|
|
434
|
-
scaffold new <name> [--src <list>] [--app <list>] [--bin] [--deps <list>] [--from <path>] [--target <path>] [--json]
|
|
472
|
+
scaffold new <name> [--src <list>] [--app <list>] [--bin] [--deps <list>] [--offline] [--from <path>] [--target <path>] [--json]
|
|
435
473
|
scaffold a workspace
|
|
436
|
-
scaffold audit [--groups <list>] [--from <path>] [--target <path>] [--json]
|
|
474
|
+
scaffold audit [--groups <list>] [--offline] [--from <path>] [--target <path>] [--json]
|
|
437
475
|
report how the target compares to its plan, writing nothing
|
|
438
|
-
scaffold repair [--groups <list>] [--from <path>] [--target <path>] [--json]
|
|
476
|
+
scaffold repair [--groups <list>] [--offline] [--from <path>] [--target <path>] [--json]
|
|
439
477
|
write each planned path the target is missing or has let drift
|
|
440
478
|
scaffold catalog [--all] [--from <path>] [--target <path>] [--json]
|
|
441
479
|
regenerate the package table and refresh the guide mirrors
|
|
442
|
-
scaffold overwrite [--groups <list>] [--dirty] [--from <path>] [--target <path>] [--json]
|
|
480
|
+
scaffold overwrite [--groups <list>] [--dirty] [--offline] [--from <path>] [--target <path>] [--json]
|
|
443
481
|
do everything repair and catalog do, then delete what the plan does not own and re-declare the dependency ranges
|
|
444
482
|
|
|
445
483
|
options
|
|
446
|
-
--src <list>
|
|
447
|
-
--app <list>
|
|
448
|
-
--bin
|
|
449
|
-
--deps <list>
|
|
450
|
-
--groups <list>
|
|
451
|
-
--all
|
|
452
|
-
--dirty
|
|
453
|
-
--
|
|
454
|
-
--
|
|
455
|
-
--
|
|
456
|
-
|
|
484
|
+
--src <list> the published library environments to build: core, browser, server
|
|
485
|
+
--app <list> the private application environments to build: core, browser, server
|
|
486
|
+
--bin scaffold a command-line executable at src/bin/main.ts
|
|
487
|
+
--deps <list> the @orkestrel/* packages the workspace depends on
|
|
488
|
+
--groups <list> the artifact groups to cover; every group when absent
|
|
489
|
+
--all fetch a guide for every package the organization publishes, not the declared ones alone
|
|
490
|
+
--dirty delete from a tree carrying uncommitted changes
|
|
491
|
+
--offline use the distributed dependency and vendored-host floors without reading upstream
|
|
492
|
+
--from <path> read the data root from a local path instead of the bundled one; catalog alone accepts it more than once
|
|
493
|
+
--target <path> the directory the verb operates on; the working directory when absent
|
|
494
|
+
--json emit one machine-readable value instead of a report
|
|
495
|
+
ORKESTREL_SCAFFOLD_REGISTRY the registry base mapped to upstream.registry.base
|
|
496
|
+
ORKESTREL_SCAFFOLD_REPOSITORY the repository base mapped to upstream.repository.base
|
|
457
497
|
|
|
458
498
|
exit codes
|
|
459
499
|
0 clean
|
|
@@ -464,13 +504,16 @@ exit codes
|
|
|
464
504
|
An option a verb does not list is refused by name rather than parsed and ignored. `--help` is the
|
|
465
505
|
one exception, because it replaces the run rather than modifying it: a command line carrying
|
|
466
506
|
`--help` anywhere prints the whole reference and exits `0` before the line is read as a command, so
|
|
467
|
-
no verb has to list it.
|
|
468
|
-
read produces no answer. Dependency floors states what each verb reads
|
|
507
|
+
no verb has to list it. Without the `--offline` option, every verb reaches the registry, and none of
|
|
508
|
+
them invents a range when the read produces no answer. Dependency floors states what each verb reads
|
|
509
|
+
and what it does then.
|
|
469
510
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
511
|
+
At their defaults, online runs contact `registry.npmjs.org` for scoped package packuments and the
|
|
512
|
+
`/-/org/orkestrel/package` membership path. They contact `raw.githubusercontent.com` for guide
|
|
513
|
+
files on `main`, the scaffold repository's `host.json` file, and changed vendored paths.
|
|
514
|
+
`ORKESTREL_SCAFFOLD_REGISTRY` replaces the registry base, and
|
|
515
|
+
`ORKESTREL_SCAFFOLD_REPOSITORY` replaces the repository base. These settings change which host
|
|
516
|
+
answers a read and grant no verb write authority that it did not already have.
|
|
474
517
|
|
|
475
518
|
`new --bin` creates the executable entry, its test, and its scoped Vite and TypeScript wrappers. The
|
|
476
519
|
other structural facts do not need creation flags. Add a root `tests/setup*.test.ts` proof for
|
|
@@ -565,13 +608,13 @@ unless `--dirty` waives that refusal. A target that is not a git repository is r
|
|
|
565
608
|
`--json` replaces the report with one JSON value on standard output. Warnings and refusals go to
|
|
566
609
|
standard error, so a piped value is never polluted.
|
|
567
610
|
|
|
568
|
-
| Verb | Value
|
|
569
|
-
| ----------- |
|
|
570
|
-
| `new` | `MaterializeResult` — `target`, `written`, `skipped`, `removed`
|
|
571
|
-
| `audit` | `Audit` — `findings` and `questions` — plus `releases`; findings carry `ownership`
|
|
572
|
-
| `repair` | `MaterializeResult` plus `audit`, the terminal audit taken after the write, and `
|
|
573
|
-
| `catalog` | `MaterializeResult` plus `entries`, `mirrors`, `dropped`, and `
|
|
574
|
-
| `overwrite` | The `catalog` value plus `audit` and `note` on a partial run
|
|
611
|
+
| Verb | Value |
|
|
612
|
+
| ----------- | -------------------------------------------------------------------------------------------------------- |
|
|
613
|
+
| `new` | `MaterializeResult` — `target`, `written`, `skipped`, `removed` — plus `provenance` |
|
|
614
|
+
| `audit` | `Audit` — `findings` and `questions` — plus `releases` and `provenance`; findings carry `ownership` |
|
|
615
|
+
| `repair` | `MaterializeResult` plus `audit`, the terminal audit taken after the write, `releases`, and `provenance` |
|
|
616
|
+
| `catalog` | `MaterializeResult` plus `entries`, `mirrors`, `dropped`, `releases`, and `provenance` |
|
|
617
|
+
| `overwrite` | The `catalog` value plus `audit` and `note` on a partial run |
|
|
575
618
|
|
|
576
619
|
Every failure reports the same envelope instead: `{ "error": { "code": …, "message": … } }`. The
|
|
577
620
|
code is a `ScaffoldErrorCode`, or `USAGE` for a command line that never became a command, or
|
|
@@ -925,18 +968,23 @@ alike.
|
|
|
925
968
|
|
|
926
969
|
### What each verb reads
|
|
927
970
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
971
|
+
`new`, `audit`, and `repair` read declared versions and the vendored host. `catalog` reads
|
|
972
|
+
organization membership, its packuments, and the selected guides. `overwrite` reads every surface
|
|
973
|
+
that `repair` and `catalog` read. A network-forced floor is drift except for a successful `new` run;
|
|
974
|
+
an explicit `--offline` floor is intentional, and the verb's result decides its exit. `catalog` has
|
|
975
|
+
no offline form. `overwrite` commits repair and removal before it starts the catalog step.
|
|
976
|
+
|
|
977
|
+
Each verb resolves a surface's complete answer before it opens that surface's write transaction, so
|
|
978
|
+
a partial answer never becomes a partial pin set. `overwrite` keeps the repair and removal work it
|
|
979
|
+
committed before a later catalog refusal and records that refusal in `note`.
|
|
935
980
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
981
|
+
| Verb | Reads live | When the network forces a floor | With `--offline` |
|
|
982
|
+
| ----------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
983
|
+
| `new` | Declared versions and the vendored host | Writes the distributed version and host floors; exits `0` after creating the workspace | Reads no upstream surface, writes the same floors, and exits `0` after creating the workspace |
|
|
984
|
+
| `audit` | Declared versions and the vendored host | Compares through the distributed floors and exits `1` | Compares through the floors; exits `0` for an aligned target or `1` for drift |
|
|
985
|
+
| `repair` | Declared versions and the vendored host | Repairs from the distributed floors and exits `1`, even when the terminal audit is aligned | Repairs from the floors; the terminal audit decides exit `0` or `1` |
|
|
986
|
+
| `catalog` | Organization membership, its packuments, and the selected guides | Refuses a membership or version failure with `FETCH` and exit `1`; preserves each failed guide's local mirror and exits `1` | Is a usage error; exits `2` and writes nothing |
|
|
987
|
+
| `overwrite` | Everything `repair` and `catalog` read | Keeps completed repair and deletion work, names each floor or refused catalog step in `note`, and exits `1` | Repairs, deletes, and writes version floors; skips `catalog`, records that refusal in `note`, and exits `1` |
|
|
940
988
|
|
|
941
989
|
A fleet row is compared exactly — `^0.1.0` is stale the moment the registry serves `0.1.2` — and
|
|
942
990
|
that inequality alone raises `audit` to exit `1`. A foreign row is compared inside its declared
|
|
@@ -964,6 +1012,23 @@ directories, the bench scripts, the shared policy register, the byte-identical r
|
|
|
964
1012
|
the guide mirrors a generated workspace starts from. `HOST_PATHS` is the candidate list; a plan
|
|
965
1013
|
carries the subset its target selects, because a workspace never mirrors its own guide.
|
|
966
1014
|
|
|
1015
|
+
The `host.json` file at the repository root is the committed live inventory. Each entry carries the
|
|
1016
|
+
SHA-256 digest of its file content, and the inventory carries a membership digest over its declared
|
|
1017
|
+
paths and file digests. Run `npm run build:inventory` whenever a vendored byte or path changes; the
|
|
1018
|
+
`config` project refuses a stale inventory. Run that gate against a quiescent checkout: its fresh and
|
|
1019
|
+
committed reads cannot distinguish stale data from a source edit made while the gate runs.
|
|
1020
|
+
|
|
1021
|
+
The installed release fixes which paths a target owns. A live inventory can update bytes only for
|
|
1022
|
+
those paths; it can neither introduce a path nor delete one. A path added upstream is invisible
|
|
1023
|
+
until a release adds it to the installed manifest. Remove a vendored path in the same change that
|
|
1024
|
+
ships the release which removes it from that manifest.
|
|
1025
|
+
|
|
1026
|
+
At the default `UpstreamOptions.retries` value, an aligned target spends one request on `host.json`,
|
|
1027
|
+
and each installed path whose live digest differs from the target adds one request for its bytes. A
|
|
1028
|
+
positive `retries` value can repeat a request after a transport fault. Raw-host propagation lag after
|
|
1029
|
+
a commit is a property of the content host. Scaffold neither creates that lag nor presents a stale
|
|
1030
|
+
response as fresher than the host served it.
|
|
1031
|
+
|
|
967
1032
|
`.claude/settings.json` is in that set, and the artifact planned for it is content-owned. `repair`
|
|
968
1033
|
and `overwrite` restore its bytes, so an edit made to it inside a target is reverted at the next
|
|
969
1034
|
visit and reported as drift until then. Put an operator grant in `.claude/settings.local.json`
|
|
@@ -982,9 +1047,10 @@ stageHost(process.cwd(), 'dist/host') // one ManifestEntry per file staged
|
|
|
982
1047
|
Each vendored path is copied to a storage name, and every dot that opens a segment comes off,
|
|
983
1048
|
because npm's own ignore rules would drop a leading-dot entry from the tarball. A dotted file at the
|
|
984
1049
|
root moves under `dotfiles/` so it cannot collide with an undotted sibling. `manifest.json` is
|
|
985
|
-
written last and declares the whole membership: one entry per file
|
|
986
|
-
|
|
987
|
-
|
|
1050
|
+
written last and declares the whole membership: one entry per file with a digest computed from the
|
|
1051
|
+
staged destination after its copy, the sorted directory inventory, and a SHA-256 digest over both.
|
|
1052
|
+
The membership digest detects an edit that did not update the manifest, and the directory inventory
|
|
1053
|
+
makes a declared empty directory survive a file walk.
|
|
988
1054
|
|
|
989
1055
|
A missing vendored path is refused rather than staged around, and the refusal names every missing
|
|
990
1056
|
path at once. That is why `guides/scaffold.md` — this file — must exist before `npm run build`
|
|
@@ -996,6 +1062,21 @@ module's own location rather than from the caller's working directory. `--from`
|
|
|
996
1062
|
else. A root carrying no manifest at all is read as a raw checkout, and artifact paths map onto it
|
|
997
1063
|
one to one.
|
|
998
1064
|
|
|
1065
|
+
### Integrity
|
|
1066
|
+
|
|
1067
|
+
HTTPS supplies Transport Layer Security (TLS) for each fetched response, and the reader applies its
|
|
1068
|
+
per-response and per-call byte budgets before it accepts content. It carries each fetched vendored
|
|
1069
|
+
response's decoded content as hexadecimal before any character decoding and verifies that content
|
|
1070
|
+
against the digest in `host.json`, then verifies the inventory against its membership digest.
|
|
1071
|
+
Transport encoding is transparent and does not enter the comparison. The path never character-
|
|
1072
|
+
decodes and re-encodes the content.
|
|
1073
|
+
|
|
1074
|
+
This posture supplies integrity, not authenticity. An attacker who can serve the files can also
|
|
1075
|
+
serve a matching inventory. The residual is direct: fetched bytes govern agent behavior in a target
|
|
1076
|
+
that has no release gate. Run `audit` to preview the change, use the `--offline` option to pin the
|
|
1077
|
+
distributed floors, and keep operator grants in `.claude/settings.local.json`; scaffold does not
|
|
1078
|
+
read or write that file.
|
|
1079
|
+
|
|
999
1080
|
## Generated workspace
|
|
1000
1081
|
|
|
1001
1082
|
A workspace's file set is a function of its axes plus its structural facts. Nothing is fixed
|
|
@@ -1082,6 +1163,10 @@ result.written // every path created
|
|
|
1082
1163
|
materializer.destroy()
|
|
1083
1164
|
```
|
|
1084
1165
|
|
|
1166
|
+
When a `Materializer` uses a value `Host`, each mutating call stages the host under a private
|
|
1167
|
+
`#fill` root in the operating system's temporary directory and removes that root in a `finally`
|
|
1168
|
+
block. A process killed during the mutation can leave the temporary root behind.
|
|
1169
|
+
|
|
1085
1170
|
`resolveContainedPath` refuses a lexical escape, a physical link out of the root, and a dangling
|
|
1086
1171
|
link whose raw target contains a `..` segment. It returns the lexical join of `root` and `path` — an
|
|
1087
1172
|
absolute path under `root` — after checking the namespace, not an open filesystem handle. Its
|
|
@@ -1096,7 +1181,7 @@ in what survives that collapse. A `..` the caller wrote cancels the segment befo
|
|
|
1096
1181
|
what `hop` points at. The collapse only ever shortens the path, so nothing reaches outside it this
|
|
1097
1182
|
way; the answer is a lexical location resolved through links, not a physical one.
|
|
1098
1183
|
|
|
1099
|
-
Read the registry and the
|
|
1184
|
+
Read the registry and the repository host:
|
|
1100
1185
|
|
|
1101
1186
|
```ts
|
|
1102
1187
|
import { Upstream } from '@orkestrel/scaffold/server'
|
|
@@ -1188,10 +1273,10 @@ What a reader will look for and not find.
|
|
|
1188
1273
|
**Guide parity has a bounded reach.** [`tests/guides.test.ts`](../tests/guides.test.ts) proves that
|
|
1189
1274
|
the Surface tables match the core and server barrels in each direction, the method tables match the
|
|
1190
1275
|
behavioral declarations, relative links resolve, and named imports in TypeScript fences resolve. It
|
|
1191
|
-
does not resolve arbitrary backticked prose spans or typecheck a whole fence. The same suite
|
|
1192
|
-
executes the transcribed pure examples for
|
|
1193
|
-
narrowing. Other trailing comments remain guide
|
|
1194
|
-
are measured are the ones a consumer hovers:
|
|
1276
|
+
does not resolve arbitrary backticked prose spans or typecheck a whole fence. The same suite keeps
|
|
1277
|
+
the command reference aligned with the executable and executes the transcribed pure examples for
|
|
1278
|
+
blueprint defaults, compile refusal, and error-code narrowing. Other trailing comments remain guide
|
|
1279
|
+
claims rather than build answers. The verdicts that are measured are the ones a consumer hovers:
|
|
1195
1280
|
[`tests/distribution.test.ts`](../tests/distribution.test.ts) drives every `@example` the built
|
|
1196
1281
|
declarations print against the installed package, scores each verdict it can read as a value, and
|
|
1197
1282
|
names exactly the ones it cannot. Executing the remaining fences would require fixtures for each
|