@orkestrel/scaffold 0.0.60 → 0.0.62

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 (61) hide show
  1. package/README.md +13 -10
  2. package/dist/bin/main.js +632 -320
  3. package/dist/bin/main.js.map +1 -1
  4. package/dist/host/CLAUDE.md +5 -1
  5. package/dist/host/agents/orchestration.md +44 -19
  6. package/dist/host/agents/skills/enterprise-bootstrap/references/components.md +5 -5
  7. package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +2 -2
  8. package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +10 -9
  9. package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +21 -11
  10. package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +20 -2
  11. package/dist/host/agents/skills/orkestrel-harden-package/SKILL.md +1 -1
  12. package/dist/host/agents/skills/orkestrel-harden-package/references/hardening.md +1 -1
  13. package/dist/host/agents/skills/orkestrel-harden-package/references/research.md +1 -1
  14. package/dist/host/agents/templates/brief.md +16 -7
  15. package/dist/host/agents/transports/claude.md +4 -2
  16. package/dist/host/agents/transports/codex.md +4 -1
  17. package/dist/host/claude/agents/analyst.md +3 -1
  18. package/dist/host/claude/agents/application.md +1 -1
  19. package/dist/host/claude/agents/builder.md +3 -3
  20. package/dist/host/claude/agents/checker.md +5 -0
  21. package/dist/host/claude/agents/grok.md +15 -5
  22. package/dist/host/claude/agents/implementer.md +1 -1
  23. package/dist/host/claude/agents/orkestrel.md +2 -2
  24. package/dist/host/claude/agents/planner.md +10 -0
  25. package/dist/host/claude/agents/reviewer.md +14 -8
  26. package/dist/host/claude/agents/sol.md +3 -1
  27. package/dist/host/claude/agents/verifier.md +2 -4
  28. package/dist/host/claude/rules/architecture.md +7 -5
  29. package/dist/host/claude/rules/documentation.md +1 -0
  30. package/dist/host/claude/rules/names.md +23 -5
  31. package/dist/host/claude/rules/patterns.md +1 -0
  32. package/dist/host/claude/rules/quality.md +1 -1
  33. package/dist/host/claude/rules/tests.md +3 -3
  34. package/dist/host/claude/rules/typescript.md +4 -1
  35. package/dist/host/claude/rules/writing.md +2 -2
  36. package/dist/host/codex/agents/builder.toml +6 -6
  37. package/dist/host/codex/agents/checker.toml +2 -1
  38. package/dist/host/codex/agents/grok.toml +12 -5
  39. package/dist/host/codex/agents/implementer.toml +2 -2
  40. package/dist/host/codex/agents/opus.toml +6 -1
  41. package/dist/host/codex/agents/planner.toml +11 -6
  42. package/dist/host/codex/agents/reviewer.toml +8 -6
  43. package/dist/host/guides/scaffold.md +39 -14
  44. package/dist/host/manifest.json +41 -41
  45. package/dist/host/scripts/codex.sh +0 -0
  46. package/dist/host/scripts/cursor.sh +0 -0
  47. package/dist/host/scripts/deps.sh +0 -0
  48. package/dist/host/scripts/ollama.sh +0 -0
  49. package/dist/src/core/index.cjs +429 -287
  50. package/dist/src/core/index.cjs.map +1 -1
  51. package/dist/src/core/index.d.cts +361 -220
  52. package/dist/src/core/index.d.ts +361 -220
  53. package/dist/src/core/index.js +426 -288
  54. package/dist/src/core/index.js.map +1 -1
  55. package/dist/src/server/index.cjs +208 -170
  56. package/dist/src/server/index.cjs.map +1 -1
  57. package/dist/src/server/index.d.cts +276 -152
  58. package/dist/src/server/index.d.ts +276 -152
  59. package/dist/src/server/index.js +200 -172
  60. package/dist/src/server/index.js.map +1 -1
  61. package/package.json +13 -12
@@ -4,7 +4,7 @@ let _orkestrel_template = require("@orkestrel/template");
4
4
  let _orkestrel_emitter = require("@orkestrel/emitter");
5
5
  var package_default = {
6
6
  name: "@orkestrel/scaffold",
7
- version: "0.0.60",
7
+ version: "0.0.62",
8
8
  description: "Scaffold workspaces with five commands: new, audit, repair, catalog, and overwrite.",
9
9
  keywords: [
10
10
  "audit",
@@ -59,7 +59,7 @@ var package_default = {
59
59
  "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
60
60
  "copy": "node -e \"const fs=require('node:fs'),p=require('node:path'),a=process.argv[1],b=process.argv[2];fs.mkdirSync(p.dirname(b),{recursive:true});fs.cpSync(a,b,{force:true});console.log('Copied: '+a+' to '+b)\"",
61
61
  "scaffold": "node ./dist/bin/main.js",
62
- "lint": "oxlint --config .oxlintrc.json --fix --deny-warnings .",
62
+ "lint": "oxlint --config .oxlintrc.json --fix .",
63
63
  "check": "tsc --noEmit --project tsconfig.json && npm run check:src",
64
64
  "check:src": "npm run check:src:core && npm run check:src:server && npm run check:src:bin",
65
65
  "check:src:core": "tsc --noEmit -p configs/src/tsconfig.core.json",
@@ -68,7 +68,7 @@ var package_default = {
68
68
  "format": "oxfmt --config .oxfmtrc.json --write .",
69
69
  "format:check": "oxfmt --config .oxfmtrc.json --check .",
70
70
  "lint:check": "oxlint --config .oxlintrc.json --deny-warnings .",
71
- "test": "npm run test:src:core && npm run test:src:server && npm run test:src:bin && npm run test:policy && npm run test:config && npm run test:guides",
71
+ "test": "npm run test:src:core && npm run test:src:server && npm run test:src:bin && npm run test:policy && npm run test:config && npm run test:setup && npm run test:guides",
72
72
  "test:src:core": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
73
73
  "test:src:server": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:server",
74
74
  "test:src:bin": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:bin",
@@ -78,6 +78,7 @@ var package_default = {
78
78
  "test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
79
79
  "test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
80
80
  "test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
81
+ "test:setup": "vitest run --config vite.config.ts --no-cache --reporter=dot --project setup",
81
82
  "build": "npm run clean && npm run build:src && npm run build:host && npm run build:inventory",
82
83
  "build:src": "npm run build:src:core && npm run build:src:server && npm run build:src:bin",
83
84
  "build:src:core": "vite build --config configs/src/vite.core.config.ts && npm run copy dist/src/core/index.d.ts dist/src/core/index.d.cts",
@@ -89,19 +90,19 @@ var package_default = {
89
90
  "prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test && npm run test:distribution -- --mode release"
90
91
  },
91
92
  dependencies: {
92
- "@orkestrel/console": "^0.0.11",
93
- "@orkestrel/contract": "^0.0.15",
94
- "@orkestrel/emitter": "^0.0.8",
95
- "@orkestrel/markdown": "^0.0.12",
96
- "@orkestrel/process": "^0.0.9",
97
- "@orkestrel/template": "^0.0.5"
93
+ "@orkestrel/console": "^0.0.12",
94
+ "@orkestrel/contract": "^0.0.16",
95
+ "@orkestrel/emitter": "^0.0.9",
96
+ "@orkestrel/markdown": "^0.0.13",
97
+ "@orkestrel/process": "^0.0.10",
98
+ "@orkestrel/template": "^0.0.6"
98
99
  },
99
100
  devDependencies: {
100
101
  "@microsoft/api-extractor": "^7.59.0",
101
- "@orkestrel/guide": "^0.0.15",
102
- "@orkestrel/html": "^0.0.7",
102
+ "@orkestrel/guide": "^0.0.16",
103
+ "@orkestrel/html": "^0.0.8",
103
104
  "@orkestrel/probe": "^0.0.11",
104
- "@orkestrel/test": "^0.0.12",
105
+ "@orkestrel/test": "^0.0.13",
105
106
  "@types/node": "^26.4.0",
106
107
  "@vitest/browser-playwright": "^4.1.11",
107
108
  "oxfmt": "^0.65.0",
@@ -117,7 +118,7 @@ var package_default = {
117
118
  //#endregion
118
119
  //#region src/core/constants.ts
119
120
  /**
120
- * The `Environment` values, frozen.
121
+ * Lists the `Environment` values, frozen.
121
122
  *
122
123
  * @remarks
123
124
  * A blueprint's `src` and `app` axes are caller-supplied, so the gate measures
@@ -131,7 +132,7 @@ var ENVIRONMENTS = Object.freeze([
131
132
  "server"
132
133
  ]);
133
134
  /**
134
- * The `Group` values in plan order, frozen.
135
+ * Lists the `Group` values in plan order, frozen.
135
136
  *
136
137
  * @remarks
137
138
  * A compile that names no groups covers every one of them, so this list is the
@@ -148,7 +149,7 @@ var GROUPS = Object.freeze([
148
149
  "orchestration"
149
150
  ]);
150
151
  /**
151
- * The build and export settings each published `src` environment contributes, frozen.
152
+ * Holds the build and export settings each published `src` environment contributes, frozen.
152
153
  *
153
154
  * @remarks
154
155
  * Per environment: the thin configuration files it adds under `configs/src`,
@@ -178,7 +179,8 @@ var SRC_MATRIX = Object.freeze({
178
179
  })
179
180
  });
180
181
  /**
181
- * The configuration and runtime-entry settings each private `app` environment contributes, frozen.
182
+ * Holds the configuration and runtime-entry settings each private `app` environment
183
+ * contributes, frozen.
182
184
  *
183
185
  * @remarks
184
186
  * An application environment declares no exports, so it carries a runtime
@@ -201,24 +203,25 @@ var APP_MATRIX = Object.freeze({
201
203
  entry: "app/server/main.ts"
202
204
  })
203
205
  });
204
- /** The configuration files a workspace that ships its own executable adds, frozen. */
206
+ /** Lists the configuration files a workspace that ships its own executable adds, frozen. */
205
207
  var BIN_CONFIGS = Object.freeze(["configs/src/vite.bin.config.ts", "configs/src/tsconfig.bin.json"]);
206
- /** The executable entry whose presence makes a workspace `bin`. */
208
+ /** Names the executable entry whose presence makes a workspace `bin`. */
207
209
  var BIN_ENTRY_PATH = "src/bin/main.ts";
208
210
  /**
209
- * The paths a target receives from the vendored data root, frozen.
211
+ * Lists the paths a target receives from the vendored data root, frozen.
210
212
  *
211
213
  * @remarks
212
- * These are the files the fleet shares verbatim and every target holds a copy
213
- * of: the licence, the harness permission file, the session hook scripts, the
214
- * shared policy register, the byte-identical root dotfiles, and the guide
215
- * mirrors a generated workspace starts from. A directory entry vendors
216
- * everything beneath it.
214
+ * These are the files the fleet shares verbatim, and each target holds a copy
215
+ * of the paths it selects: the licence, the harness permission file, the
216
+ * session-start hooks, the shared policy register, the shared policy proof,
217
+ * the shared policy plugin, the shared configuration leaf and its proof, the
218
+ * byte-identical root dotfiles, and the guide mirrors a generated workspace
219
+ * starts from. A directory entry vendors everything beneath it.
217
220
  *
218
221
  * A plan carries the subset its target selects, which is why the list is a
219
222
  * candidate set rather than a plan: a workspace never mirrors its own guide.
220
223
  *
221
- * Neither the instruction canon nor the harness wiring is here. A target reads
224
+ * Neither the instruction canon nor the bench and MCP wiring is here. A target reads
222
225
  * its rules, its skills, its agent roles, its bench configuration, and its MCP
223
226
  * registrations from {@link CANON_PATHS} inside the installed package, so no
224
227
  * file scaffold leaves in a target names a path the target does not hold.
@@ -248,7 +251,7 @@ var HOST_PATHS = Object.freeze([
248
251
  "guides/scaffold.md"
249
252
  ]);
250
253
  /**
251
- * The instruction-canon paths staged for reading rather than for a target, frozen.
254
+ * Lists the instruction-canon paths staged for reading rather than for a target, frozen.
252
255
  *
253
256
  * @remarks
254
257
  * The root instruction documents, the orchestration contract every harness
@@ -294,10 +297,10 @@ var CANON_PATHS = Object.freeze([
294
297
  ".cursor/mcp.json",
295
298
  ".cursor/rules"
296
299
  ]);
297
- /** The repository-relative path where the committed vendored-file inventory is served. */
300
+ /** Names the repository-relative path where the committed vendored-file inventory is served. */
298
301
  var HOST_INVENTORY_PATH = "host.json";
299
302
  /**
300
- * The vendored paths whose present bytes belong to each workspace, frozen.
303
+ * Lists the vendored paths whose present bytes belong to each workspace, frozen.
301
304
  *
302
305
  * @remarks
303
306
  * These paths are copied into a workspace when absent and are never compared
@@ -307,7 +310,7 @@ var HOST_INVENTORY_PATH = "host.json";
307
310
  */
308
311
  var WORKSPACE_OWNED_PATHS = Object.freeze([".gitignore"]);
309
312
  /**
310
- * The vendored paths a target receives with its executable bit set, frozen.
313
+ * Lists the vendored paths a target receives with its executable bit set, frozen.
311
314
  *
312
315
  * @remarks
313
316
  * Declared rather than read from the staging host's filesystem, because that
@@ -326,7 +329,7 @@ var EXECUTABLE_PATHS = Object.freeze([
326
329
  "scripts/ollama.sh"
327
330
  ]);
328
331
  /**
329
- * The path prefixes whose contents instruct or wire an agent, frozen.
332
+ * Lists the path prefixes whose contents instruct or wire an agent, frozen.
330
333
  *
331
334
  * @remarks
332
335
  * A path is grouped by what it governs rather than by where it sits: anything
@@ -344,7 +347,7 @@ var ORCHESTRATION_PATH_PREFIXES = Object.freeze([
344
347
  "scripts/"
345
348
  ]);
346
349
  /**
347
- * The exact root filenames that wire an agent bench rather than the toolchain, frozen.
350
+ * Lists the exact root filenames that wire an agent bench rather than the toolchain, frozen.
348
351
  *
349
352
  * @remarks
350
353
  * `.mcp.json` registers MCP servers for the harness. It sits among the root
@@ -352,7 +355,7 @@ var ORCHESTRATION_PATH_PREFIXES = Object.freeze([
352
355
  */
353
356
  var ORCHESTRATION_PATH_NAMES = Object.freeze([".mcp.json"]);
354
357
  /**
355
- * The agent file whose marker-bounded package table the catalog verb alone owns.
358
+ * Names the agent file whose marker-bounded package table the catalog verb alone owns.
356
359
  *
357
360
  * @remarks
358
361
  * A plan claims it at a canon path, because the catalog verb refuses a target
@@ -366,16 +369,34 @@ var ORCHESTRATION_PATH_NAMES = Object.freeze([".mcp.json"]);
366
369
  * inside the markers.
367
370
  */
368
371
  var CATALOG_AGENT_PATH = ".claude/agents/orkestrel.md";
369
- /** The provisioner skeleton a workspace with declared service vendors is given once. */
372
+ /**
373
+ * Names the marker opening the package table inside {@link CATALOG_AGENT_PATH}.
374
+ *
375
+ * @remarks
376
+ * The catalog verb rewrites the region between this marker and
377
+ * {@link CATALOG_CLOSING_MARKER} and leaves every other byte of the file alone,
378
+ * so the writer and every proof that reads the rendered file read the pair from
379
+ * here rather than repeating a literal that only agrees by inspection.
380
+ */
381
+ var CATALOG_OPENING_MARKER = "<!-- orkestrel:catalog -->";
382
+ /**
383
+ * Names the marker closing the package table inside {@link CATALOG_AGENT_PATH}.
384
+ *
385
+ * @remarks
386
+ * It pairs with {@link CATALOG_OPENING_MARKER}; a file missing either marker is
387
+ * refused rather than rewritten.
388
+ */
389
+ var CATALOG_CLOSING_MARKER = "<!-- /orkestrel:catalog -->";
390
+ /** Names the provisioner skeleton a workspace with declared service vendors is given once. */
370
391
  var SERVICE_SCRIPT_PATH = "scripts/service.sh";
371
- /** The shared Vitest global-setup module whose presence makes a workspace `global`. */
392
+ /** Names the shared Vitest global-setup module whose presence makes a workspace `global`. */
372
393
  var GLOBAL_SETUP_PATH = "tests/setupGlobal.ts";
373
- /** The guide-parity proof whose presence selects the planned `guides` project. */
394
+ /** Names the guide-parity proof whose presence selects the planned `guides` project. */
374
395
  var GUIDES_TEST_PATH = "tests/guides.test.ts";
375
- /** The generated packed-package proof every publishing workspace is planned at. */
396
+ /** Names the generated packed-package proof every publishing workspace is planned at. */
376
397
  var DISTRIBUTION_TEST_PATH = "tests/distribution.test.ts";
377
398
  /**
378
- * The `prepublishOnly` row that runs the packed-package proof against a real registry.
399
+ * Names the `prepublishOnly` row that runs the packed-package proof against a real registry.
379
400
  *
380
401
  * @remarks
381
402
  * The proof reads `import.meta.env.MODE`, so without `--mode release` it passes
@@ -383,22 +404,28 @@ var DISTRIBUTION_TEST_PATH = "tests/distribution.test.ts";
383
404
  * and both the script compiler and the manifest region writer read it from here.
384
405
  */
385
406
  var RELEASE_PROOF_COMMAND = "npm run test:distribution -- --mode release";
386
- /** The cross-environment composition proof whose presence makes a workspace `integration`. */
407
+ /**
408
+ * Names the cross-environment composition proof whose presence makes a workspace
409
+ * `integration`.
410
+ */
387
411
  var INTEGRATION_TEST_PATH = "tests/integration.test.ts";
388
- /** The manifest path every compiler plan emits with birth ownership. */
412
+ /** Names the manifest path every compiler plan emits with birth ownership. */
389
413
  var MANIFEST_PATH = "package.json";
390
- /** The official-tooling drift proof whose presence makes a workspace `conformance`. */
414
+ /** Names the official-tooling drift proof whose presence makes a workspace `conformance`. */
391
415
  var CONFORMANCE_TEST_PATH = "tests/conformance.test.ts";
392
- /** The live-service readiness module whose presence makes a workspace `service`. */
416
+ /** Names the live-service readiness module whose presence makes a workspace `service`. */
393
417
  var SERVICE_SETUP_PATH = "tests/setupService.ts";
394
- /** The include the live-service project covers, which is a directory rather than one proof. */
418
+ /**
419
+ * Names the include the live-service project covers, which is a directory rather than
420
+ * one proof.
421
+ */
395
422
  var SERVICE_TEST_INCLUDE = "tests/service/**/*.test.ts";
396
- /** The Vite wrapper whose presence makes a workspace `showcase`. */
423
+ /** Names the Vite wrapper whose presence makes a workspace `showcase`. */
397
424
  var SHOWCASE_CONFIG_PATH = "configs/app/vite.showcase.config.ts";
398
- /** The bare workspace name syntax: lowercase alphanumeric with hyphens, letter first. */
425
+ /** Matches the bare workspace name syntax: lowercase alphanumeric with hyphens, letter first. */
399
426
  var NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
400
427
  /**
401
- * The runtime dependency name syntax: the `@orkestrel` scope and a bare name.
428
+ * Matches the runtime dependency name syntax: the `@orkestrel` scope and a bare name.
402
429
  *
403
430
  * @remarks
404
431
  * A dependency name reaches a path, because a workspace's guide mirror is
@@ -408,7 +435,7 @@ var NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
408
435
  */
409
436
  var DEPENDENCY_NAME_PATTERN = /^@orkestrel\/[a-z][a-z0-9-]*$/;
410
437
  /**
411
- * The package name syntax for a dependency this package does not publish.
438
+ * Matches the package name syntax for a dependency this package does not publish.
412
439
  *
413
440
  * @remarks
414
441
  * A foreign package is one this package does not publish, so its name reaches
@@ -418,10 +445,10 @@ var DEPENDENCY_NAME_PATTERN = /^@orkestrel\/[a-z][a-z0-9-]*$/;
418
445
  * is admitted, so the shape cannot express a traversal.
419
446
  */
420
447
  var FOREIGN_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
421
- /** The exact `major.minor.patch` version syntax a blueprint declares. */
448
+ /** Matches the exact `major.minor.patch` version syntax a blueprint declares. */
422
449
  var VERSION_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
423
450
  /**
424
- * The exact caret-pinned pre-1.0 range accepted for an `@orkestrel/*` runtime dependency.
451
+ * Matches the exact caret-pinned pre-1.0 range accepted for an `@orkestrel/*` runtime dependency.
425
452
  *
426
453
  * @remarks
427
454
  * Pre-1.0 means any `0.x`, not `0.0.x`. The narrower form would refuse the first
@@ -430,10 +457,10 @@ var VERSION_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
430
457
  * workspace that had already been pinned to it.
431
458
  */
432
459
  var ORKESTREL_RANGE_PATTERN = /^\^0\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
433
- /** The registry-only semver subset accepted for a development extra's range. */
460
+ /** Matches the registry-only semver subset accepted for a development extra's range. */
434
461
  var EXTRA_RANGE_PATTERN = /^(?:\^|~)?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?$/;
435
462
  /**
436
- * The exact `major.minor.patch` floor accepted for a foreign peer's range.
463
+ * Matches the exact `major.minor.patch` floor accepted for a foreign peer's range.
437
464
  *
438
465
  * @remarks
439
466
  * This is independent from {@link ENGINES_PATTERN}. An engine floors the Node
@@ -441,44 +468,47 @@ var EXTRA_RANGE_PATTERN = /^(?:\^|~)?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\
441
468
  * supplies. Either obligation may change without changing the other.
442
469
  */
443
470
  var FLOOR_RANGE_PATTERN = /^>=(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
444
- /** The minimum-Node engine syntax a blueprint declares. */
471
+ /** Matches the minimum-Node engine syntax a blueprint declares. */
445
472
  var ENGINES_PATTERN = /^>=(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
446
- /** Exact lowercase hexadecimal bytes: two digits per byte, and empty content is valid. */
473
+ /** Matches exact lowercase hexadecimal bytes: two digits per byte, and empty content is valid. */
447
474
  var HEX_PATTERN = /^(?:[0-9a-f]{2})*$/;
448
- /** Unicode controls, formatting controls, and line and paragraph separators rejected in text. */
475
+ /**
476
+ * Matches the Unicode controls, formatting controls, and line and paragraph separators
477
+ * rejected in text.
478
+ */
449
479
  var CONTROL_CHARACTER_PATTERN = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;
450
- /** Visible characters a target-relative path and a Markdown path cell both forbid. */
480
+ /** Matches the visible characters a target-relative path and a Markdown path cell both forbid. */
451
481
  var INVALID_PATH_CHARACTER_PATTERN = /[<>:"|?*\\]/;
452
482
  /**
453
- * Maximum bare workspace name length.
483
+ * Caps the bare workspace name length.
454
484
  *
455
485
  * @remarks
456
486
  * The registry caps a whole package name at 214 characters and the generated
457
487
  * scope `@orkestrel/` spends 11 of them.
458
488
  */
459
489
  var MAX_NAME_LENGTH = 203;
460
- /** Maximum dependency package name length, scope included, as the registry caps it. */
490
+ /** Sets the maximum dependency package name length, scope included, as the registry caps it. */
461
491
  var MAX_DEPENDENCY_NAME_LENGTH = 214;
462
- /** Maximum length of one declared package range. */
492
+ /** Caps the length of one declared package range. */
463
493
  var MAX_RANGE_LENGTH = 2048;
464
- /** Maximum length of one manifest script name or command. */
494
+ /** Caps the length of one manifest script name or command. */
465
495
  var MAX_SCRIPT_LENGTH = 4096;
466
- /** Maximum length of one path, matching the longest a supported filesystem accepts. */
496
+ /** Caps the length of one path, matching the longest a supported filesystem accepts. */
467
497
  var MAX_PATH_LENGTH = 32767;
468
- /** Maximum items accepted in one public collection. */
498
+ /** Caps the items accepted in one public collection. */
469
499
  var MAX_COLLECTION_ITEMS = 1e3;
470
- /** Columns one emitted line may occupy, matching `printWidth` in `.oxfmtrc.json`. */
500
+ /** Caps the columns one emitted line may occupy, matching `printWidth` in `.oxfmtrc.json`. */
471
501
  var PRINT_WIDTH = 100;
472
- /** Columns one tab occupies when the formatter measures a line, matching `tabWidth`. */
502
+ /** Sets the columns one tab occupies when the formatter measures a line, matching `tabWidth`. */
473
503
  var TAB_WIDTH = 2;
474
- /** Maximum findings one audit can produce from a bounded plan and snapshot. */
504
+ /** Caps the findings one audit can produce from a bounded plan and snapshot. */
475
505
  var MAX_AUDIT_FINDINGS = MAX_COLLECTION_ITEMS * 2;
476
- /** Maximum bytes accepted for one artifact. */
506
+ /** Caps the bytes accepted for one artifact. */
477
507
  var MAX_ARTIFACT_BYTES = 5242880;
478
- /** Maximum length of the hexadecimal string carrying one artifact's bytes. */
508
+ /** Caps the length of the hexadecimal string carrying one artifact's bytes. */
479
509
  var MAX_ARTIFACT_HEX_LENGTH = MAX_ARTIFACT_BYTES * 2;
480
510
  /**
481
- * Maximum decoded bytes accepted from one registry response.
511
+ * Caps the decoded bytes accepted from one registry response.
482
512
  *
483
513
  * @remarks
484
514
  * The 2026-08-21 abbreviated-packument measurements were 8,647,138 bytes for
@@ -488,24 +518,24 @@ var MAX_ARTIFACT_HEX_LENGTH = MAX_ARTIFACT_BYTES * 2;
488
518
  */
489
519
  var MAX_REGISTRY_BYTES = 33554432;
490
520
  /**
491
- * Maximum decoded bytes accepted across one registry-reading call.
521
+ * Caps the decoded bytes accepted across one registry-reading call.
492
522
  *
493
523
  * @remarks
494
524
  * The 2026-08-21 browser-workspace registry set measured about 24 MiB. The
495
525
  * bound leaves headroom for that set to grow without making a call unbounded.
496
526
  */
497
527
  var MAX_TOTAL_REGISTRY_BYTES = 100663296;
498
- /** Maximum bytes accepted for one package or vendored-host manifest. */
528
+ /** Caps the bytes accepted for one package or vendored-host manifest. */
499
529
  var MAX_MANIFEST_BYTES = 1048576;
500
- /** Maximum bytes retained across one whole plan or audit. */
530
+ /** Caps the bytes retained across one whole plan or audit. */
501
531
  var MAX_TOTAL_ARTIFACT_BYTES = 104857600;
502
- /** The oldest Node version the generated toolchain supports. */
532
+ /** Names the oldest Node version the generated toolchain supports. */
503
533
  var MINIMUM_NODE_VERSION = "22.12.0";
504
- /** The version a workspace starts at. */
534
+ /** Names the version a workspace starts at. */
505
535
  var DEFAULT_VERSION = "0.0.1";
506
- /** The `engines.node` range a workspace starts with. */
536
+ /** Names the `engines.node` range a workspace starts with. */
507
537
  var DEFAULT_ENGINES = `>=${MINIMUM_NODE_VERSION}`;
508
- /** The tooling versions scaffold and every generated workspace share. */
538
+ /** Holds the tooling versions scaffold and every generated workspace share. */
509
539
  var BASE_DEV_DEPENDENCIES = Object.freeze({
510
540
  "@orkestrel/guide": package_default.devDependencies["@orkestrel/guide"],
511
541
  "@orkestrel/probe": package_default.devDependencies["@orkestrel/probe"],
@@ -518,19 +548,22 @@ var BASE_DEV_DEPENDENCIES = Object.freeze({
518
548
  vite: package_default.devDependencies.vite,
519
549
  vitest: package_default.devDependencies.vitest
520
550
  });
521
- /** The development dependencies that emit declarations for published source or an executable. */
551
+ /**
552
+ * Lists the development dependencies that emit declarations for published source or an
553
+ * executable.
554
+ */
522
555
  var DECLARATION_DEV_DEPENDENCIES = Object.freeze({
523
556
  "@microsoft/api-extractor": package_default.devDependencies["@microsoft/api-extractor"],
524
557
  "vite-plugin-dts": package_default.devDependencies["vite-plugin-dts"]
525
558
  });
526
- /** The development dependencies a published browser `src` environment adds. */
559
+ /** Lists the development dependencies a published browser `src` environment adds. */
527
560
  var SOURCE_BROWSER_DEV_DEPENDENCIES = Object.freeze({
528
561
  "@vitest/browser-playwright": package_default.devDependencies["@vitest/browser-playwright"],
529
562
  playwright: package_default.devDependencies.playwright
530
563
  });
531
- /** The development dependency every private `app` environment adds. */
564
+ /** Names the development dependency every private `app` environment adds. */
532
565
  var APP_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/contract": package_default.dependencies["@orkestrel/contract"] });
533
- /** The development dependencies a private Vue browser application adds. */
566
+ /** Lists the development dependencies a private Vue browser application adds. */
534
567
  var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
535
568
  ...SOURCE_BROWSER_DEV_DEPENDENCIES,
536
569
  "@orkestrel/html": package_default.devDependencies["@orkestrel/html"],
@@ -539,7 +572,7 @@ var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
539
572
  "vue-tsc": "^3.3.7"
540
573
  });
541
574
  /**
542
- * The development dependency used only by the optional single-file showcase build.
575
+ * Names the development dependency used only by the optional single-file showcase build.
543
576
  *
544
577
  * @example
545
578
  * ```ts
@@ -549,7 +582,7 @@ var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
549
582
  * ```
550
583
  */
551
584
  var SHOWCASE_DEV_DEPENDENCIES = Object.freeze({ "vite-plugin-singlefile": "^2.3.3" });
552
- /** The development dependencies a private server application adds. */
585
+ /** Lists the development dependencies a private server application adds. */
553
586
  var APP_SERVER_DEV_DEPENDENCIES = Object.freeze({
554
587
  "@orkestrel/emitter": package_default.dependencies["@orkestrel/emitter"],
555
588
  "@orkestrel/middleware": "^0.0.16",
@@ -559,7 +592,7 @@ var APP_SERVER_DEV_DEPENDENCIES = Object.freeze({
559
592
  //#endregion
560
593
  //#region src/core/templates.ts
561
594
  /**
562
- * Formatter-stable template text for every configuration artifact.
595
+ * Holds formatter-stable template text for every configuration artifact.
563
596
  *
564
597
  * @remarks
565
598
  * Builders in `compilers.ts` fill these definitions through
@@ -1230,8 +1263,8 @@ import { accessSync, constants as FS_CONSTANTS, globSync, readdirSync, statSync
1230
1263
  import { basename, dirname, join, resolve as resolvePath } from 'node:path'
1231
1264
 
1232
1265
  /**
1233
- * Chromium executable layouts inside a \`chromium-<revision>\` browsers-directory entry, per
1234
- * platform.
1266
+ * Lists the Chromium executable layouts inside a \`chromium-<revision>\` browsers-directory
1267
+ * entry, per platform.
1235
1268
  *
1236
1269
  * @remarks
1237
1270
  * The current Playwright build ships Chrome for Testing on macOS. The trailing \`Chromium.app\`
@@ -1249,17 +1282,17 @@ export const CHROMIUM_LAYOUTS = Object.freeze([
1249
1282
  'chrome-mac-arm64/Chromium.app/Contents/MacOS/Chromium',
1250
1283
  ])
1251
1284
 
1252
- /** The \`chromium-<revision>\` entry name Playwright installs one managed build into. */
1285
+ /** Matches the \`chromium-<revision>\` entry name Playwright installs one managed build into. */
1253
1286
  export const CHROMIUM_ENTRY_PATTERN = /^chromium-\\d+$/
1254
1287
 
1255
- /** The revision number carried by any path containing a \`chromium-<revision>\` segment. */
1288
+ /** Matches the revision number carried by any path containing a \`chromium-<revision>\` segment. */
1256
1289
  export const CHROMIUM_REVISION_PATTERN = /chromium-(\\d+)/
1257
1290
 
1258
- /** The directory a managed Linux container installs its bundled Playwright browsers into. */
1291
+ /** Names the directory a managed Linux container installs its bundled Playwright browsers into. */
1259
1292
  export const BUNDLED_BROWSERS_ROOT = '/opt/pw-browsers'
1260
1293
 
1261
1294
  /**
1262
- * Bundled Chromium layouts under the managed-container browsers root, as glob patterns.
1295
+ * Lists the bundled Chromium layouts under the managed-container browsers root, as glob patterns.
1263
1296
  *
1264
1297
  * @remarks
1265
1298
  * The revision directory and its inner layout both drift across Playwright builds, and the
@@ -1271,7 +1304,7 @@ export const BUNDLED_CHROMIUM_LAYOUTS = Object.freeze([
1271
1304
  'chromium-*/chrome-linux/chrome',
1272
1305
  ])
1273
1306
 
1274
- /** Stable Playwright Chromium channels and their standard executable layouts. */
1307
+ /** Lists the stable Playwright Chromium channels and their standard executable layouts. */
1275
1308
  export const SYSTEM_BROWSER_CHANNELS = Object.freeze([
1276
1309
  Object.freeze({
1277
1310
  channel: 'chrome',
@@ -1292,10 +1325,10 @@ export const SYSTEM_BROWSER_CHANNELS = Object.freeze([
1292
1325
  ])
1293
1326
 
1294
1327
  /**
1295
- * Determine whether a path identifies an executable regular file.
1328
+ * Determines whether a path identifies an executable regular file.
1296
1329
  *
1297
1330
  * @param path - The filesystem path to inspect.
1298
- * @returns Whether the path is a regular file with execute access.
1331
+ * @returns True if the path is a regular file with execute access; false otherwise.
1299
1332
  *
1300
1333
  * @example
1301
1334
  * \`\`\`ts
@@ -1313,7 +1346,7 @@ export function isBrowserExecutable(path: string): boolean {
1313
1346
  }
1314
1347
 
1315
1348
  /**
1316
- * Order two Chromium paths so the highest revision sorts first.
1349
+ * Orders two Chromium paths so the highest revision sorts first.
1317
1350
  *
1318
1351
  * @param left - The first path or directory entry to compare.
1319
1352
  * @param right - The second path or directory entry to compare.
@@ -1336,7 +1369,7 @@ export function compareRevisions(left: string, right: string): number {
1336
1369
  }
1337
1370
 
1338
1371
  /**
1339
- * Read the executable path of Playwright's pinned Chromium revision.
1372
+ * Reads the executable path of Playwright's pinned Chromium revision.
1340
1373
  *
1341
1374
  * @returns The pinned executable path, or \`undefined\` when this platform has none.
1342
1375
  *
@@ -1359,7 +1392,7 @@ export function resolvePinnedBrowser(): string | undefined {
1359
1392
  }
1360
1393
 
1361
1394
  /**
1362
- * Resolve a launchable Playwright-managed Chromium executable: the pinned revision when installed,
1395
+ * Resolves a launchable Playwright-managed Chromium executable: the pinned revision when installed,
1363
1396
  * otherwise a \`chromium\` / \`chromium.exe\` alias or any other \`chromium-*\` revision under the same
1364
1397
  * Playwright browsers directory. A pinned-revision miss is not Chromium absence — managed
1365
1398
  * containers ship one usable build, often behind a revision-agnostic alias, for many Playwright
@@ -1406,7 +1439,7 @@ export function resolveManagedBrowser(pinned: string): string | undefined {
1406
1439
  }
1407
1440
 
1408
1441
  /**
1409
- * Resolve the Chromium a managed Linux container bundles outside the Playwright cache.
1442
+ * Resolves the Chromium a managed Linux container bundles outside the Playwright cache.
1410
1443
  *
1411
1444
  * @param platform - The Node platform the container runs on.
1412
1445
  * @param root - The bundled browsers directory to search.
@@ -1435,7 +1468,7 @@ export function resolveBundledBrowser(platform: NodeJS.Platform, root: string):
1435
1468
  }
1436
1469
 
1437
1470
  /**
1438
- * Resolve the first installed stable system Chromium channel.
1471
+ * Resolves the first installed stable system Chromium channel.
1439
1472
  *
1440
1473
  * @param platform - The Node platform whose standard layouts this call probes.
1441
1474
  * @param environment - The process environment supplying Windows installation roots.
@@ -1479,7 +1512,7 @@ export function resolveSystemBrowser(
1479
1512
  }
1480
1513
 
1481
1514
  /**
1482
- * Resolve Playwright provider options for whatever browser this host can actually launch.
1515
+ * Resolves Playwright provider options for whatever browser this host can actually launch.
1483
1516
  *
1484
1517
  * @param pinned - The executable path for Playwright's pinned Chromium revision, when it has one.
1485
1518
  * @param platform - The Node platform whose standard layouts this call probes.
@@ -1534,7 +1567,7 @@ export function resolveBrowser(
1534
1567
  `
1535
1568
  });
1536
1569
  /**
1537
- * Formatter-stable template text for source, test, document, guide, and service artifacts.
1570
+ * Holds formatter-stable template text for source, test, document, guide, and service artifacts.
1538
1571
  *
1539
1572
  * @remarks
1540
1573
  * Builders in `compilers.ts` fill every varying span through
@@ -2628,7 +2661,7 @@ printf '%s\\n' \\
2628
2661
  //#endregion
2629
2662
  //#region src/core/errors.ts
2630
2663
  /**
2631
- * The one error this package throws, carrying the coded reason it was raised.
2664
+ * Represents the one error this package throws, carrying the coded reason it was raised.
2632
2665
  *
2633
2666
  * @remarks
2634
2667
  * Each code names one cause: `INVALID` for off-contract input, `DESTROYED` for
@@ -2665,7 +2698,7 @@ var ScaffoldError = class extends Error {
2665
2698
  code;
2666
2699
  context;
2667
2700
  /**
2668
- * Construct a coded scaffold error.
2701
+ * Constructs a coded scaffold error.
2669
2702
  *
2670
2703
  * @param code - The coded reason the error is raised.
2671
2704
  * @param message - What went wrong, in one sentence.
@@ -2679,10 +2712,10 @@ var ScaffoldError = class extends Error {
2679
2712
  }
2680
2713
  };
2681
2714
  /**
2682
- * Narrow a caught value to a {@link ScaffoldError}.
2715
+ * Narrows a caught value to a {@link ScaffoldError}.
2683
2716
  *
2684
2717
  * @param value - The caught value to narrow.
2685
- * @returns `true` when `value` is a {@link ScaffoldError}.
2718
+ * @returns True if `value` is a {@link ScaffoldError}; false otherwise.
2686
2719
  *
2687
2720
  * @example
2688
2721
  * ```ts
@@ -2698,11 +2731,11 @@ function isScaffoldError(value) {
2698
2731
  //#endregion
2699
2732
  //#region src/core/validators.ts
2700
2733
  /**
2701
- * Narrow a value to a logical target-relative path.
2734
+ * Narrows a value to a logical target-relative path.
2702
2735
  *
2703
2736
  * @param value - The candidate path.
2704
- * @returns `true` for a bounded relative path with no traversal, empty segment,
2705
- * control character, or reserved syntax character.
2737
+ * @returns True if the value is a bounded relative path with no traversal, empty
2738
+ * segment, control character, or reserved syntax character; false otherwise.
2706
2739
  *
2707
2740
  * @remarks
2708
2741
  * Every path this package reads or writes passes here, so one law covers a
@@ -2731,7 +2764,7 @@ function isPath(value) {
2731
2764
  });
2732
2765
  }
2733
2766
  /**
2734
- * Narrow a value to exact lowercase hexadecimal bytes within one artifact's limit.
2767
+ * Narrows a value to exact lowercase hexadecimal bytes within one artifact's limit.
2735
2768
  *
2736
2769
  * @remarks
2737
2770
  * Two digits per byte, so an odd length is refused and empty content is valid.
@@ -2751,7 +2784,7 @@ var isHex = (0, _orkestrel_contract.stringOf)({
2751
2784
  pattern: HEX_PATTERN
2752
2785
  });
2753
2786
  /**
2754
- * Narrow a value to text this package will accept as one artifact's content.
2787
+ * Narrows a value to text this package will accept as one artifact's content.
2755
2788
  *
2756
2789
  * @remarks
2757
2790
  * The bound is a code-unit ceiling rather than a byte count, because a string
@@ -2762,10 +2795,11 @@ var isHex = (0, _orkestrel_contract.stringOf)({
2762
2795
  */
2763
2796
  var isContent = (0, _orkestrel_contract.stringOf)({ max: MAX_ARTIFACT_BYTES });
2764
2797
  /**
2765
- * Narrow a value to an array within the limit one public collection accepts.
2798
+ * Narrows a value to an array within the limit one public collection accepts.
2766
2799
  *
2767
2800
  * @param value - The candidate collection.
2768
- * @returns `true` for an array of no more than `MAX_COLLECTION_ITEMS` items.
2801
+ * @returns True if the value is an array of no more than
2802
+ * `MAX_COLLECTION_ITEMS` items; false otherwise.
2769
2803
  *
2770
2804
  * @remarks
2771
2805
  * Compose this ahead of an element guard so the item count is settled before
@@ -2784,7 +2818,7 @@ function isCollection(value) {
2784
2818
  return (0, _orkestrel_contract.holds)(() => (0, _orkestrel_contract.isArray)(value) && value.length <= 1e3);
2785
2819
  }
2786
2820
  /**
2787
- * Narrow a value to one {@link Environment} a workspace may select.
2821
+ * Narrows a value to one {@link Environment} a workspace may select.
2788
2822
  *
2789
2823
  * @example
2790
2824
  * ```ts
@@ -2796,7 +2830,7 @@ function isCollection(value) {
2796
2830
  */
2797
2831
  var isEnvironment = (0, _orkestrel_contract.literalOf)(ENVIRONMENTS);
2798
2832
  /**
2799
- * Narrow a value to one {@link Group} a plan selects over.
2833
+ * Narrows a value to one {@link Group} a plan selects over.
2800
2834
  *
2801
2835
  * @example
2802
2836
  * ```ts
@@ -2807,10 +2841,10 @@ var isEnvironment = (0, _orkestrel_contract.literalOf)(ENVIRONMENTS);
2807
2841
  * ```
2808
2842
  */
2809
2843
  var isGroup = (0, _orkestrel_contract.literalOf)(GROUPS);
2810
- /** Narrow a value to a bounded group selection. */
2844
+ /** Narrows a value to a bounded group selection. */
2811
2845
  var isGroups = (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isGroup));
2812
2846
  /**
2813
- * Narrow a value to the scoped package name a runtime dependency carries.
2847
+ * Narrows a value to the scoped package name a runtime dependency carries.
2814
2848
  *
2815
2849
  * @remarks
2816
2850
  * A dependency name reaches a path, because a workspace's guide mirror is
@@ -2832,7 +2866,7 @@ var isDependencyName = (0, _orkestrel_contract.stringOf)({
2832
2866
  pattern: DEPENDENCY_NAME_PATTERN
2833
2867
  });
2834
2868
  /**
2835
- * Narrow a value to a {@link Dependency}.
2869
+ * Narrows a value to a {@link Dependency}.
2836
2870
  *
2837
2871
  * @remarks
2838
2872
  * Structural and bounded: which names and ranges a blueprint may declare is a
@@ -2859,7 +2893,7 @@ var isDependency = (0, _orkestrel_contract.recordOf)({
2859
2893
  optional: _orkestrel_contract.isBoolean
2860
2894
  }, ["optional"]);
2861
2895
  /**
2862
- * Narrow a value to a {@link ManifestScript}.
2896
+ * Narrows a value to a {@link ManifestScript}.
2863
2897
  *
2864
2898
  * @remarks
2865
2899
  * Structural and bounded, exactly as {@link isDependency} is: a script name
@@ -2890,7 +2924,7 @@ var isManifestScript = (0, _orkestrel_contract.recordOf)({
2890
2924
  })))
2891
2925
  });
2892
2926
  /**
2893
- * Narrow a value to an {@link Override}.
2927
+ * Narrows a value to an {@link Override}.
2894
2928
  *
2895
2929
  * @remarks
2896
2930
  * Whether the path names a planned artifact is a gate law; whether it names a
@@ -2908,7 +2942,7 @@ var isOverride = (0, _orkestrel_contract.recordOf)({
2908
2942
  content: isContent
2909
2943
  });
2910
2944
  /**
2911
- * Narrow a value to a {@link Blueprint}.
2945
+ * Narrows a value to a {@link Blueprint}.
2912
2946
  *
2913
2947
  * @remarks
2914
2948
  * The whole closed record, its literal axes, and the count and length bounds
@@ -2949,7 +2983,7 @@ var isBlueprint = (0, _orkestrel_contract.recordOf)({
2949
2983
  showcase: _orkestrel_contract.isBoolean
2950
2984
  }, ["description"]);
2951
2985
  /**
2952
- * Narrow a value to an {@link Artifact}.
2986
+ * Narrows a value to an {@link Artifact}.
2953
2987
  *
2954
2988
  * @remarks
2955
2989
  * One branch per way content is produced, discriminated by `origin` and
@@ -2989,7 +3023,7 @@ var isArtifact = (0, _orkestrel_contract.unionOf)((0, _orkestrel_contract.record
2989
3023
  content: isContent
2990
3024
  }, ["environment"]));
2991
3025
  /**
2992
- * Narrow a value to a {@link Plan}.
3026
+ * Narrows a value to a {@link Plan}.
2993
3027
  *
2994
3028
  * @remarks
2995
3029
  * A plan reaches the writer, and the writer has no question channel, so this
@@ -3005,7 +3039,7 @@ var isPlan = (0, _orkestrel_contract.andOf)((0, _orkestrel_contract.recordOf)({
3005
3039
  hash: isHex
3006
3040
  }, ["hash"]), (plan) => plan.artifacts.every((artifact) => artifact.path !== "package.json" || artifact.ownership === "birth"));
3007
3041
  /**
3008
- * Narrow a value to a {@link Question}.
3042
+ * Narrows a value to a {@link Question}.
3009
3043
  *
3010
3044
  * @example
3011
3045
  * ```ts
@@ -3021,7 +3055,7 @@ var isQuestion = (0, _orkestrel_contract.recordOf)({
3021
3055
  candidates: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isString))
3022
3056
  }, ["candidates"]);
3023
3057
  /**
3024
- * Narrow a value to a {@link Finding}.
3058
+ * Narrows a value to a {@link Finding}.
3025
3059
  *
3026
3060
  * @remarks
3027
3061
  * `observed` is required exactly where the mutation it precedes is held to it,
@@ -3058,7 +3092,7 @@ var isFinding = (0, _orkestrel_contract.unionOf)((0, _orkestrel_contract.recordO
3058
3092
  observed: isHex
3059
3093
  }, ["observed"]));
3060
3094
  /**
3061
- * Narrow a value to an {@link Audit}.
3095
+ * Narrows a value to an {@link Audit}.
3062
3096
  *
3063
3097
  * @remarks
3064
3098
  * An audit reaches the writer and the destructive verb, so it is guarded as
@@ -3070,7 +3104,7 @@ var isAudit = (0, _orkestrel_contract.recordOf)({
3070
3104
  questions: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isQuestion))
3071
3105
  });
3072
3106
  /**
3073
- * Narrow a value to a {@link Mirror}.
3107
+ * Narrows a value to a {@link Mirror}.
3074
3108
  *
3075
3109
  * @remarks
3076
3110
  * `content` is the fetched guide text and `observed` is the local mirror's
@@ -3091,7 +3125,7 @@ var isMirror = (0, _orkestrel_contract.unionOf)((0, _orkestrel_contract.recordOf
3091
3125
  observed: isHex
3092
3126
  }, ["observed"]));
3093
3127
  /**
3094
- * Narrow a value to a {@link CatalogEntry}.
3128
+ * Narrows a value to a {@link CatalogEntry}.
3095
3129
  *
3096
3130
  * @remarks
3097
3131
  * A row that found no version carries the cause instead, and neither branch may
@@ -3108,11 +3142,11 @@ var isCatalogEntry = (0, _orkestrel_contract.unionOf)((0, _orkestrel_contract.re
3108
3142
  note: _orkestrel_contract.isString
3109
3143
  }));
3110
3144
  /**
3111
- * Narrow a value to a {@link Snapshot}.
3145
+ * Narrows a value to a {@link Snapshot}.
3112
3146
  *
3113
3147
  * @param value - The candidate target snapshot.
3114
- * @returns `true` for a bounded plain record whose every key is a path and
3115
- * whose every value is exact lowercase hexadecimal bytes.
3148
+ * @returns True if the value is a bounded plain record whose every key is a path and
3149
+ * whose every value is exact lowercase hexadecimal bytes; false otherwise.
3116
3150
  *
3117
3151
  * @remarks
3118
3152
  * Read through the shared total key lens, so a hostile `ownKeys` trap and a
@@ -3138,7 +3172,7 @@ function isSnapshot(value) {
3138
3172
  });
3139
3173
  }
3140
3174
  /**
3141
- * Narrow a value to the compiler's initial listener record.
3175
+ * Narrows a value to the compiler's initial listener record.
3142
3176
  *
3143
3177
  * @remarks
3144
3178
  * Every event is optional and every declared value is a function. A key outside
@@ -3153,7 +3187,7 @@ var isCompilerHooks = (0, _orkestrel_contract.recordOf)({
3153
3187
  destroy: _orkestrel_contract.isFunction
3154
3188
  }, true);
3155
3189
  /**
3156
- * Narrow a value to {@link CompilerOptions}.
3190
+ * Narrows a value to {@link CompilerOptions}.
3157
3191
  *
3158
3192
  * @example
3159
3193
  * ```ts
@@ -3170,7 +3204,7 @@ var isCompilerOptions = (0, _orkestrel_contract.recordOf)({
3170
3204
  //#endregion
3171
3205
  //#region src/core/cloners.ts
3172
3206
  /**
3173
- * Snapshot an untrusted value into exact JSON data the caller owns.
3207
+ * Snapshots an untrusted value into exact JSON data the caller owns.
3174
3208
  *
3175
3209
  * @param value - The untrusted value to take ownership of.
3176
3210
  * @returns A deeply frozen copy sharing nothing with `value`, or `undefined`
@@ -3218,7 +3252,7 @@ function cloneValue(value) {
3218
3252
  //#endregion
3219
3253
  //#region src/core/parsers.ts
3220
3254
  /**
3221
- * Coerce an untrusted value to a {@link Blueprint}.
3255
+ * Coerces an untrusted value to a {@link Blueprint}.
3222
3256
  *
3223
3257
  * @param value - The value to parse.
3224
3258
  * @returns The blueprint, or `undefined` when the value is not one.
@@ -3240,7 +3274,7 @@ function parseBlueprint(value) {
3240
3274
  return isBlueprint(value) ? value : void 0;
3241
3275
  }
3242
3276
  /**
3243
- * Coerce an untrusted value to a group selection.
3277
+ * Coerces an untrusted value to a group selection.
3244
3278
  *
3245
3279
  * @param value - The value to parse.
3246
3280
  * @returns The selection, or `undefined` when the value is not one.
@@ -3262,7 +3296,7 @@ function parseGroups(value) {
3262
3296
  return isGroups(value) ? value : void 0;
3263
3297
  }
3264
3298
  /**
3265
- * Coerce an untrusted value to a {@link Snapshot}.
3299
+ * Coerces an untrusted value to a {@link Snapshot}.
3266
3300
  *
3267
3301
  * @param value - The value to parse.
3268
3302
  * @returns The snapshot, or `undefined` when the value is not one.
@@ -3282,7 +3316,7 @@ function parseSnapshot(value) {
3282
3316
  return isSnapshot(value) ? value : void 0;
3283
3317
  }
3284
3318
  /**
3285
- * Coerce an untrusted value to {@link CompilerOptions}.
3319
+ * Coerces an untrusted value to {@link CompilerOptions}.
3286
3320
  *
3287
3321
  * @param value - The value to parse.
3288
3322
  * @returns The options, or `undefined` when the value is not an option bag.
@@ -3306,7 +3340,7 @@ function parseCompilerOptions(value) {
3306
3340
  //#endregion
3307
3341
  //#region src/core/helpers.ts
3308
3342
  /**
3309
- * Encode bytes as exact lowercase hexadecimal text.
3343
+ * Encodes bytes as exact lowercase hexadecimal text.
3310
3344
  *
3311
3345
  * @param bytes - The bytes to encode.
3312
3346
  * @returns Two lowercase hexadecimal digits per input byte, and `''` for no bytes.
@@ -3330,7 +3364,7 @@ function bytesToHex(bytes) {
3330
3364
  return hex;
3331
3365
  }
3332
3366
  /**
3333
- * Encode text as the exact lowercase hexadecimal form of its UTF-8 bytes.
3367
+ * Encodes text as the exact lowercase hexadecimal form of its UTF-8 bytes.
3334
3368
  *
3335
3369
  * @param content - The text to encode.
3336
3370
  * @returns The hexadecimal form of the text's exact UTF-8 bytes.
@@ -3352,7 +3386,7 @@ function contentToHex(content) {
3352
3386
  return bytesToHex(new TextEncoder().encode(content));
3353
3387
  }
3354
3388
  /**
3355
- * Count the UTF-8 bytes text encodes to.
3389
+ * Counts the UTF-8 bytes text encodes to.
3356
3390
  *
3357
3391
  * @param content - The text to measure.
3358
3392
  * @returns The exact number of UTF-8 bytes.
@@ -3380,7 +3414,7 @@ function computeBytes(content) {
3380
3414
  return bytes;
3381
3415
  }
3382
3416
  /**
3383
- * Compute the deterministic content identity of text.
3417
+ * Computes the deterministic content identity of text.
3384
3418
  *
3385
3419
  * @param text - The text to digest.
3386
3420
  * @returns Sixteen lowercase hexadecimal digits.
@@ -3409,11 +3443,11 @@ function computeHash(text) {
3409
3443
  return hash.toString(16).padStart(16, "0");
3410
3444
  }
3411
3445
  /**
3412
- * Test whether a path instructs or wires an agent rather than the toolchain.
3446
+ * Tests whether a path instructs or wires an agent rather than the toolchain.
3413
3447
  *
3414
3448
  * @param path - The target-relative path to test.
3415
- * @returns `true` when the path is beneath a harness directory or is one of the
3416
- * exact root filenames that wires an agent bench.
3449
+ * @returns True if the path is beneath a harness directory or is one of the exact
3450
+ * root filenames that wires an agent bench; false otherwise.
3417
3451
  *
3418
3452
  * @remarks
3419
3453
  * The one home of the orchestration membership rule. A vendored path and a
@@ -3438,8 +3472,8 @@ function matchesOrchestrationPath(path) {
3438
3472
  * Checks whether another surface owns the vendored bytes at a path.
3439
3473
  *
3440
3474
  * @param path - The target-relative vendored path to test.
3441
- * @returns `true` for the catalog agent file and for a Markdown guide mirror;
3442
- * `false` otherwise.
3475
+ * @returns True if the path is the catalog agent file or a Markdown guide
3476
+ * mirror; false otherwise.
3443
3477
  *
3444
3478
  * @remarks
3445
3479
  * The materializer keeps these paths presence-owned because the catalog or
@@ -3461,8 +3495,8 @@ function isDeferredPath(path) {
3461
3495
  * Checks whether a path belongs to the instruction canon a target reads rather than holds.
3462
3496
  *
3463
3497
  * @param path - The target-relative path to test.
3464
- * @returns `true` for a {@link CANON_PATHS} member and for any path beneath a
3465
- * member that is a directory; `false` otherwise.
3498
+ * @returns True if the path is a {@link CANON_PATHS} member or sits beneath a
3499
+ * member that is a directory; false otherwise.
3466
3500
  *
3467
3501
  * @remarks
3468
3502
  * The one reading of canon membership, so the live overlay and the executable's
@@ -3487,7 +3521,57 @@ function isCanonPath(path) {
3487
3521
  return CANON_PATHS.some((canon) => path === canon || path.startsWith(`${canon}/`));
3488
3522
  }
3489
3523
  /**
3490
- * Infer the {@link Group} a path belongs to.
3524
+ * Checks whether a target's present bytes at a path are owned by another surface.
3525
+ *
3526
+ * @param path - The target-relative path to test.
3527
+ * @returns True if the path is a {@link WORKSPACE_OWNED_PATHS} member or a
3528
+ * deferred path; false otherwise.
3529
+ *
3530
+ * @remarks
3531
+ * The one reading of presence ownership. A workspace-owned path carries bytes
3532
+ * the consumer's own workspace writes, and a deferred path carries bytes the
3533
+ * catalog or mirror surface writes, so a vendored expansion plans either by
3534
+ * presence rather than reading and claiming its content.
3535
+ *
3536
+ * @example
3537
+ * ```ts
3538
+ * import { isRetainedPath } from '@orkestrel/scaffold'
3539
+ *
3540
+ * isRetainedPath('.gitignore') // true
3541
+ * isRetainedPath('LICENSE') // false
3542
+ * ```
3543
+ */
3544
+ function isRetainedPath(path) {
3545
+ return WORKSPACE_OWNED_PATHS.includes(path) || isDeferredPath(path);
3546
+ }
3547
+ /**
3548
+ * Checks whether a destination's floor bytes survive a live overlay.
3549
+ *
3550
+ * @param path - The target-relative destination to test.
3551
+ * @returns True if the path is deferred or belongs to the instruction
3552
+ * canon; false otherwise.
3553
+ *
3554
+ * @remarks
3555
+ * The one reading of what a live fill does not replace, so the overlay assembler
3556
+ * and the executable's fetch list never disagree about a destination. A deferred
3557
+ * path's bytes belong to the catalog or mirror verb, and a canon destination is
3558
+ * staged for reading rather than for a target, so the installed floor's bytes
3559
+ * stand for both. A reader that requested either would spend a round trip on
3560
+ * bytes the overlay would not take.
3561
+ *
3562
+ * @example
3563
+ * ```ts
3564
+ * import { isFloorPath } from '@orkestrel/scaffold'
3565
+ *
3566
+ * isFloorPath('AGENTS.md') // true
3567
+ * isFloorPath('scripts/codex.sh') // false
3568
+ * ```
3569
+ */
3570
+ function isFloorPath(path) {
3571
+ return isDeferredPath(path) || isCanonPath(path);
3572
+ }
3573
+ /**
3574
+ * Infers the {@link Group} a path belongs to.
3491
3575
  *
3492
3576
  * @param path - The target-relative path to classify.
3493
3577
  * @returns The group that owns the path.
@@ -3522,7 +3606,7 @@ function inferGroup(path) {
3522
3606
  return "configs";
3523
3607
  }
3524
3608
  /**
3525
- * Serialize one string as a single-quoted TypeScript literal.
3609
+ * Serializes one string as a single-quoted TypeScript literal.
3526
3610
  *
3527
3611
  * @param value - The string to serialize.
3528
3612
  * @returns A complete single-quoted literal with line-breaking and delimiter
@@ -3565,7 +3649,7 @@ function serializeTypeScriptString(value) {
3565
3649
  return `${serialized}'`;
3566
3650
  }
3567
3651
  /**
3568
- * Derive the guide mirror path a package name answers for.
3652
+ * Derives the guide mirror path a package name answers for.
3569
3653
  *
3570
3654
  * @param name - A bare or `@orkestrel`-scoped package name.
3571
3655
  * @returns The mirror path, `guides/<bare name>.md`.
@@ -3590,10 +3674,10 @@ function nameToGuide(name) {
3590
3674
  return `guides/${name.slice(name.lastIndexOf("/") + 1)}.md`;
3591
3675
  }
3592
3676
  /**
3593
- * Test whether one emitted line fits the vendored formatter width.
3677
+ * Tests whether one emitted line fits the vendored formatter width.
3594
3678
  *
3595
3679
  * @param line - One emitted line, leading tabs included.
3596
- * @returns `true` when the expanded line fits.
3680
+ * @returns True if the expanded line fits; false otherwise.
3597
3681
  *
3598
3682
  * @remarks
3599
3683
  * A generator writes source the formatter then reads back, so a line packed
@@ -3614,7 +3698,7 @@ function matchesPrintWidth(line) {
3614
3698
  return line.replaceAll(" ", " ".repeat(2)).length <= 100;
3615
3699
  }
3616
3700
  /**
3617
- * Derive the declaration rewrite a published face's `beforeWriteFile` applies.
3701
+ * Derives the declaration rewrite a published face's `beforeWriteFile` applies.
3618
3702
  *
3619
3703
  * @param name - The workspace's own bare package name.
3620
3704
  * @returns The ternary consequent an emitted `vite.{browser,server}.config.ts`
@@ -3654,7 +3738,34 @@ function nameToRewrite(name) {
3654
3738
  ].join("\n");
3655
3739
  }
3656
3740
  /**
3657
- * Select the host paths a named workspace vendors.
3741
+ * Selects the single published environment a package root points at.
3742
+ *
3743
+ * @param src - The declared published environments.
3744
+ * @returns That environment, or `undefined` when the selection declares none or
3745
+ * several.
3746
+ *
3747
+ * @remarks
3748
+ * A workspace publishing exactly one environment puts it at the package root,
3749
+ * so its entry fields and its `'.'` export condition both name that
3750
+ * environment's build. A workspace publishing several puts core at the root and
3751
+ * gives every other environment a subpath, so there is no single root to name.
3752
+ * Both callers read the same answer, which is why the branch is decided once
3753
+ * here rather than twice.
3754
+ *
3755
+ * @example
3756
+ * ```ts
3757
+ * import { srcToRoot } from '@orkestrel/scaffold'
3758
+ *
3759
+ * srcToRoot(['browser']) // 'browser'
3760
+ * srcToRoot(['core', 'server']) // undefined
3761
+ * ```
3762
+ */
3763
+ function srcToRoot(src) {
3764
+ if (src.length !== 1) return void 0;
3765
+ return src[0];
3766
+ }
3767
+ /**
3768
+ * Selects the host paths a named workspace vendors.
3658
3769
  *
3659
3770
  * @param paths - The candidate host paths, in their declared order.
3660
3771
  * @param name - The target workspace's own bare package name.
@@ -3677,7 +3788,7 @@ function selectHostPaths(paths, name) {
3677
3788
  return paths.filter((path) => path !== guide);
3678
3789
  }
3679
3790
  /**
3680
- * Select the groups a compile covers, in plan order.
3791
+ * Selects the groups a compile covers, in plan order.
3681
3792
  *
3682
3793
  * @param groups - The requested selection; every group when absent.
3683
3794
  * @returns The requested groups in `GROUPS` order, without repeats.
@@ -3702,7 +3813,7 @@ function selectGroups(groups) {
3702
3813
  return GROUPS.filter((group) => selection.includes(group));
3703
3814
  }
3704
3815
  /**
3705
- * Project an artifact to the exact bytes it claims, as hexadecimal.
3816
+ * Projects an artifact to the exact bytes it claims, as hexadecimal.
3706
3817
  *
3707
3818
  * @param artifact - The planned artifact to read.
3708
3819
  * @returns The claimed bytes, or `undefined` when the artifact claims none.
@@ -3731,7 +3842,7 @@ function artifactToHex(artifact) {
3731
3842
  return artifact.hex;
3732
3843
  }
3733
3844
  /**
3734
- * Infer how one target path compares to the artifact planned for it.
3845
+ * Infers how one target path compares to the artifact planned for it.
3735
3846
  *
3736
3847
  * @param artifact - The planned artifact.
3737
3848
  * @param observed - The destination's exact bytes as hexadecimal; absent when
@@ -3773,16 +3884,99 @@ function inferDrift(artifact, observed) {
3773
3884
  return observed === artifactToHex(artifact) ? "aligned" : "stale";
3774
3885
  }
3775
3886
  /**
3776
- * Test whether {@link inferDrift} could have produced a finding for an ownership.
3887
+ * Projects one planned artifact and the bytes found at its path into a verdict.
3888
+ *
3889
+ * @param artifact - The planned artifact.
3890
+ * @param observed - The destination's exact bytes as hexadecimal; absent when
3891
+ * the destination holds no file.
3892
+ * @returns The finding, carrying the artifact's ownership and `observed`
3893
+ * exactly where bytes were read.
3894
+ *
3895
+ * @remarks
3896
+ * The comparison itself is {@link inferDrift}'s, so ownership decides it here
3897
+ * exactly as it does everywhere else. This adds only the shape: a missing
3898
+ * destination has no bytes to record, and every other verdict records the bytes
3899
+ * it was given, which is the precondition the mutation that follows is held to.
3900
+ * Ownership is copied rather than inferred from drift because aligned findings
3901
+ * span every ownership tier.
3902
+ *
3903
+ * `foreign` is not answerable here, because it describes a path no artifact was
3904
+ * planned for.
3905
+ *
3906
+ * @example
3907
+ * ```ts
3908
+ * import { artifactToFinding } from '@orkestrel/scaffold'
3909
+ *
3910
+ * artifactToFinding(
3911
+ * { path: 'README.md', group: 'docs', ownership: 'content', origin: 'computed', content: 'hi\n' },
3912
+ * '6279650a',
3913
+ * ) // { path: 'README.md', group: 'docs', ownership: 'content', drift: 'stale', observed: '6279650a' }
3914
+ * ```
3915
+ */
3916
+ function artifactToFinding(artifact, observed) {
3917
+ const path = artifact.path;
3918
+ const group = artifact.group;
3919
+ const ownership = artifact.ownership;
3920
+ if (observed === void 0) return inferDrift(artifact) === "aligned" ? {
3921
+ path,
3922
+ group,
3923
+ ownership,
3924
+ drift: "aligned"
3925
+ } : {
3926
+ path,
3927
+ group,
3928
+ ownership,
3929
+ drift: "missing"
3930
+ };
3931
+ return inferDrift(artifact, observed) === "stale" ? {
3932
+ path,
3933
+ group,
3934
+ ownership,
3935
+ drift: "stale",
3936
+ observed
3937
+ } : {
3938
+ path,
3939
+ group,
3940
+ ownership,
3941
+ drift: "aligned",
3942
+ observed
3943
+ };
3944
+ }
3945
+ /**
3946
+ * Tests whether {@link inferDrift} could have produced a finding for an ownership.
3777
3947
  *
3778
3948
  * @param ownership - What scaffold claims at the planned path.
3779
3949
  * @param finding - The audit verdict to test.
3780
- * @returns Whether the ownership and verdict are reachable through {@link inferDrift}.
3950
+ * @returns True if the ownership and verdict are reachable through
3951
+ * {@link inferDrift}; false otherwise.
3781
3952
  *
3782
3953
  * @remarks
3783
3954
  * This predicate keeps the comparison law beside the reachability law it
3784
3955
  * restates. A mutation uses it so a refusal can distinguish an impossible
3785
3956
  * verdict from a target that genuinely moved after its audit.
3957
+ *
3958
+ * @example
3959
+ * ```ts
3960
+ * import type { Finding } from '@orkestrel/scaffold'
3961
+ * import { matchesDriftReachability } from '@orkestrel/scaffold'
3962
+ *
3963
+ * const aligned: Finding = {
3964
+ * path: 'README.md',
3965
+ * group: 'docs',
3966
+ * ownership: 'birth',
3967
+ * drift: 'aligned',
3968
+ * }
3969
+ * const stale: Finding = {
3970
+ * path: 'README.md',
3971
+ * group: 'docs',
3972
+ * ownership: 'birth',
3973
+ * drift: 'stale',
3974
+ * observed: '6279650a',
3975
+ * }
3976
+ *
3977
+ * matchesDriftReachability('birth', aligned) // true
3978
+ * matchesDriftReachability('birth', stale) // false
3979
+ * ```
3786
3980
  */
3787
3981
  function matchesDriftReachability(ownership, finding) {
3788
3982
  if (finding.drift === "aligned") return ownership === "birth" || finding.observed !== void 0;
@@ -3790,7 +3984,7 @@ function matchesDriftReachability(ownership, finding) {
3790
3984
  return finding.drift === "stale" && ownership === "content";
3791
3985
  }
3792
3986
  /**
3793
- * Project a catalog into the layers it publishes in.
3987
+ * Projects a catalog into the layers it publishes in.
3794
3988
  *
3795
3989
  * @param entries - The catalog rows to order.
3796
3990
  * @returns One layer per round, each holding the names publishable together,
@@ -3838,7 +4032,7 @@ function catalogToLayers(entries) {
3838
4032
  return layers;
3839
4033
  }
3840
4034
  /**
3841
- * Project a plan into its tally by artifact origin.
4035
+ * Projects a plan into its tally by artifact origin.
3842
4036
  *
3843
4037
  * @param plan - The plan to summarize.
3844
4038
  * @returns The workspace's name, both environment axes, the covered groups, and
@@ -3875,7 +4069,7 @@ function planToSummary(plan) {
3875
4069
  };
3876
4070
  }
3877
4071
  /**
3878
- * Extract the major, minor, and patch components of an exact version.
4072
+ * Extracts the major, minor, and patch components of an exact version.
3879
4073
  *
3880
4074
  * @param version - The candidate version text.
3881
4075
  * @returns The major, minor, and patch numbers, or `undefined` when the text is
@@ -3905,7 +4099,7 @@ function extractVersion(version) {
3905
4099
  ];
3906
4100
  }
3907
4101
  /**
3908
- * Extract the major component of an admitted dependency range.
4102
+ * Extracts the major component of an admitted dependency range.
3909
4103
  *
3910
4104
  * @param range - The candidate range text.
3911
4105
  * @returns The major number, or `undefined` when the text is not a canonical
@@ -3931,7 +4125,7 @@ function extractRangeMajor(range) {
3931
4125
  return major === void 0 ? void 0 : Number(major);
3932
4126
  }
3933
4127
  /**
3934
- * Compare two versions by their numeric components.
4128
+ * Compares two versions by their numeric components.
3935
4129
  *
3936
4130
  * @param left - The version ordered first when it compares lower.
3937
4131
  * @param right - The version compared against.
@@ -3966,11 +4160,11 @@ function compareVersions(left, right) {
3966
4160
  return 0;
3967
4161
  }
3968
4162
  /**
3969
- * Test whether a declared range already admits a published version.
4163
+ * Tests whether a declared range already admits a published version.
3970
4164
  *
3971
4165
  * @param range - The declared dependency range.
3972
4166
  * @param latest - The version the registry reported as latest.
3973
- * @returns `true` when the range admits that version.
4167
+ * @returns True if the range admits that version; false otherwise.
3974
4168
  *
3975
4169
  * @remarks
3976
4170
  * The one place this comparison is made. A `Release` records the declared range
@@ -4023,11 +4217,11 @@ function matchesRange(range, latest) {
4023
4217
  return compareVersions(latest, declared) >= 0;
4024
4218
  }
4025
4219
  /**
4026
- * Test whether a declared engines floor is at or above the supported minimum.
4220
+ * Tests whether a declared engines floor is at or above the supported minimum.
4027
4221
  *
4028
4222
  * @param engines - The declared `engines.node` range.
4029
- * @returns `true` when the range is the accepted syntax and its floor is at or
4030
- * above `MINIMUM_NODE_VERSION`.
4223
+ * @returns True if the range is the accepted syntax and its floor is at or above
4224
+ * `MINIMUM_NODE_VERSION`; false otherwise.
4031
4225
  *
4032
4226
  * @remarks
4033
4227
  * The declaration states a floor, so the comparison is against the oldest Node
@@ -4048,7 +4242,7 @@ function matchesEngines(engines) {
4048
4242
  return compareVersions(engines.slice(2), MINIMUM_NODE_VERSION) >= 0;
4049
4243
  }
4050
4244
  /**
4051
- * Project a package manifest's text to its own name.
4245
+ * Projects a package manifest's text to its own name.
4052
4246
  *
4053
4247
  * @param manifest - The `package.json` text.
4054
4248
  * @returns The declared name, or `undefined` when the text is oversized,
@@ -4076,7 +4270,8 @@ function manifestToName(manifest) {
4076
4270
  return name;
4077
4271
  }
4078
4272
  /**
4079
- * Project a package manifest's text to the `@orkestrel/*` packages each dependency section declares.
4273
+ * Projects a package manifest's text to the `@orkestrel/*` packages each dependency
4274
+ * section declares.
4080
4275
  *
4081
4276
  * @param manifest - The `package.json` text.
4082
4277
  * @returns The runtime, development, and peer declarations as separate lists.
@@ -4148,34 +4343,7 @@ function manifestToDependencies(manifest) {
4148
4343
  //#endregion
4149
4344
  //#region src/core/compilers.ts
4150
4345
  /**
4151
- * Select the single published environment a package root points at.
4152
- *
4153
- * @param src - The declared published environments.
4154
- * @returns That environment, or `undefined` when the selection declares none or
4155
- * several.
4156
- *
4157
- * @remarks
4158
- * A workspace publishing exactly one environment puts it at the package root,
4159
- * so its entry fields and its `'.'` export condition both name that
4160
- * environment's build. A workspace publishing several puts core at the root and
4161
- * gives every other environment a subpath, so there is no single root to name.
4162
- * Both callers read the same answer, which is why the branch is decided once
4163
- * here rather than twice.
4164
- *
4165
- * @example
4166
- * ```ts
4167
- * import { srcToRoot } from '@orkestrel/scaffold'
4168
- *
4169
- * srcToRoot(['browser']) // 'browser'
4170
- * srcToRoot(['core', 'server']) // undefined
4171
- * ```
4172
- */
4173
- function srcToRoot(src) {
4174
- if (src.length !== 1) return void 0;
4175
- return src[0];
4176
- }
4177
- /**
4178
- * Build one `exports` condition block for a built environment.
4346
+ * Builds one `exports` condition block for a built environment.
4179
4347
  *
4180
4348
  * @param path - The extensionless `dist` path both conditions point at.
4181
4349
  * @param formats - The module formats that environment builds.
@@ -4211,7 +4379,7 @@ function pathToCondition(path, formats) {
4211
4379
  };
4212
4380
  }
4213
4381
  /**
4214
- * Project a published selection into the manifest's entry fields.
4382
+ * Projects a published selection into the manifest's entry fields.
4215
4383
  *
4216
4384
  * @param src - The declared published environments.
4217
4385
  * @returns The `main` and `module` fields, plus `types` when one environment
@@ -4248,7 +4416,7 @@ function srcToEntry(src) {
4248
4416
  };
4249
4417
  }
4250
4418
  /**
4251
- * Project a published selection into the manifest's `exports` map.
4419
+ * Projects a published selection into the manifest's `exports` map.
4252
4420
  *
4253
4421
  * @param src - The declared published environments.
4254
4422
  * @returns The map, keyed by subpath in `ENVIRONMENTS` order.
@@ -4285,7 +4453,7 @@ function srcToExports(src) {
4285
4453
  return map;
4286
4454
  }
4287
4455
  /**
4288
- * Project a blueprint into the development dependencies its manifest declares.
4456
+ * Projects a blueprint into the development dependencies its manifest declares.
4289
4457
  *
4290
4458
  * @param blueprint - The workspace specification.
4291
4459
  * @returns The merged set, sorted by package name.
@@ -4337,7 +4505,7 @@ function blueprintToDevDependencies(blueprint) {
4337
4505
  return Object.fromEntries(Object.entries(merged).filter(([name]) => name !== own && !runtime.has(name)).sort(([left], [right]) => (0, _orkestrel_contract.compareValues)(left, right)));
4338
4506
  }
4339
4507
  /**
4340
- * Project a blueprint into the scripts its manifest declares.
4508
+ * Projects a blueprint into the scripts its manifest declares.
4341
4509
  *
4342
4510
  * @param blueprint - The workspace specification.
4343
4511
  * @returns The scripts, in the order the manifest lists them.
@@ -4474,7 +4642,7 @@ function blueprintToScripts(blueprint) {
4474
4642
  return scripts;
4475
4643
  }
4476
4644
  /**
4477
- * Project a blueprint into the manifest scripts a region write may replace.
4645
+ * Projects a blueprint into the manifest scripts a region write may replace.
4478
4646
  *
4479
4647
  * @param blueprint - The workspace specification.
4480
4648
  * @returns One entry per writable script.
@@ -4531,7 +4699,7 @@ function blueprintToWritableScripts(blueprint) {
4531
4699
  return writable;
4532
4700
  }
4533
4701
  /**
4534
- * Compile a blueprint into its `package.json` content.
4702
+ * Compiles a blueprint into its `package.json` content.
4535
4703
  *
4536
4704
  * @param blueprint - The workspace specification.
4537
4705
  * @returns The manifest text, newline-terminated.
@@ -4617,7 +4785,7 @@ function blueprintToManifest(blueprint) {
4617
4785
  return `${JSON.stringify(manifest, void 0, " ")}\n`;
4618
4786
  }
4619
4787
  /**
4620
- * Derive the host-specific machinery a generated root Vite configuration carries.
4788
+ * Derives the host-specific machinery a generated root Vite configuration carries.
4621
4789
  *
4622
4790
  * @param blueprint - The workspace specification.
4623
4791
  * @returns The pipelines the generated configuration selects.
@@ -4653,7 +4821,7 @@ function blueprintToMachinery(blueprint) {
4653
4821
  };
4654
4822
  }
4655
4823
  /**
4656
- * Compile the root TypeScript configuration for a blueprint.
4824
+ * Compiles the root TypeScript configuration for a blueprint.
4657
4825
  *
4658
4826
  * @param blueprint - The workspace specification.
4659
4827
  * @returns Formatter-stable `tsconfig.json` text.
@@ -4675,7 +4843,7 @@ function blueprintToRootTsconfig(blueprint) {
4675
4843
  return (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.root.tsconfig, { paths });
4676
4844
  }
4677
4845
  /**
4678
- * Compile the root Vite and Vitest configuration for a blueprint.
4846
+ * Compiles the root Vite and Vitest configuration for a blueprint.
4679
4847
  *
4680
4848
  * @param blueprint - The workspace specification.
4681
4849
  * @returns Formatter-stable `vite.config.ts` text.
@@ -4866,7 +5034,7 @@ ${projects.map((project) => `\t\t\t${project},`).join("\n")}
4866
5034
  });
4867
5035
  }
4868
5036
  /**
4869
- * Compile every artifact in the `configs` group.
5037
+ * Compiles every artifact in the `configs` group.
4870
5038
  *
4871
5039
  * @param blueprint - The workspace specification.
4872
5040
  * @returns Root and selected wrapper artifacts in matrix order.
@@ -4976,7 +5144,7 @@ ${paths.join("\n")}
4976
5144
  return artifacts;
4977
5145
  }
4978
5146
  /**
4979
- * Compile every artifact in the `source` group.
5147
+ * Compiles every artifact in the `source` group.
4980
5148
  *
4981
5149
  * @param blueprint - The workspace specification.
4982
5150
  * @returns Empty published barrels, selected application entries, and the optional bin entry.
@@ -5051,7 +5219,7 @@ function blueprintToSourceArtifacts(blueprint) {
5051
5219
  return artifacts;
5052
5220
  }
5053
5221
  /**
5054
- * Compile every artifact in the `tests` group that is not vendored from the host.
5222
+ * Compiles every artifact in the `tests` group that is not vendored from the host.
5055
5223
  *
5056
5224
  * @param blueprint - The workspace specification.
5057
5225
  * @returns Shared setup modules, axis tests, and the optional integration seed.
@@ -5207,10 +5375,19 @@ function blueprintToTestArtifacts(blueprint) {
5207
5375
  return artifacts;
5208
5376
  }
5209
5377
  /**
5210
- * Compile the generated workspace's guide index.
5378
+ * Compiles the generated workspace's guide index.
5211
5379
  *
5212
5380
  * @param blueprint - The workspace specification.
5213
5381
  * @returns One birth-owned guide index carrying the concept and directory views.
5382
+ *
5383
+ * @example
5384
+ * ```ts
5385
+ * import { blueprintToGuideArtifacts, createBlueprint } from '@orkestrel/scaffold'
5386
+ *
5387
+ * const blueprint = createBlueprint('router', { src: ['core'] })
5388
+ *
5389
+ * blueprintToGuideArtifacts(blueprint)[0]?.path // 'guides/README.md'
5390
+ * ```
5214
5391
  */
5215
5392
  function blueprintToGuideArtifacts(blueprint) {
5216
5393
  const source = [];
@@ -5246,7 +5423,7 @@ function blueprintToGuideArtifacts(blueprint) {
5246
5423
  }];
5247
5424
  }
5248
5425
  /**
5249
- * Compile the generated workspace's root documentation.
5426
+ * Compiles the generated workspace's root documentation.
5250
5427
  *
5251
5428
  * @param blueprint - The workspace specification.
5252
5429
  * @returns The birth-owned package front page and the content-owned `AGENTS.md`
@@ -5265,6 +5442,15 @@ function blueprintToGuideArtifacts(blueprint) {
5265
5442
  * Neither pointer carries a varying span, so neither is filled: a workspace's
5266
5443
  * name never reaches the text, and the paths a reader follows are the same in
5267
5444
  * every target.
5445
+ *
5446
+ * @example
5447
+ * ```ts
5448
+ * import { blueprintToDocumentArtifacts, createBlueprint } from '@orkestrel/scaffold'
5449
+ *
5450
+ * const blueprint = createBlueprint('router', { src: ['core'] })
5451
+ *
5452
+ * blueprintToDocumentArtifacts(blueprint).map((artifact) => artifact.path) // ['README.md', 'AGENTS.md', 'CLAUDE.md']
5453
+ * ```
5268
5454
  */
5269
5455
  function blueprintToDocumentArtifacts(blueprint) {
5270
5456
  const publishes = blueprint.src.length > 0;
@@ -5298,7 +5484,7 @@ function blueprintToDocumentArtifacts(blueprint) {
5298
5484
  ];
5299
5485
  }
5300
5486
  /**
5301
- * Compile the blueprint-dependent orchestration artifacts.
5487
+ * Compiles the blueprint-dependent orchestration artifacts.
5302
5488
  *
5303
5489
  * @param blueprint - The workspace specification.
5304
5490
  * @returns A vendor inventory script when vendors are declared, otherwise none.
@@ -5307,6 +5493,17 @@ function blueprintToDocumentArtifacts(blueprint) {
5307
5493
  * A vendor name does not describe startup, readiness, or cleanup. The script
5308
5494
  * therefore records only the declared inventory and does not invent a service
5309
5495
  * runner or test project.
5496
+ *
5497
+ * @example
5498
+ * ```ts
5499
+ * import { blueprintToOrchestrationArtifacts, createBlueprint } from '@orkestrel/scaffold'
5500
+ *
5501
+ * const plain = createBlueprint('router', { src: ['core'] })
5502
+ * const served = createBlueprint('router', { src: ['core'], vendors: ['ollama'] })
5503
+ *
5504
+ * blueprintToOrchestrationArtifacts(plain) // []
5505
+ * blueprintToOrchestrationArtifacts(served)[0]?.path // 'scripts/service.sh'
5506
+ * ```
5310
5507
  */
5311
5508
  function blueprintToOrchestrationArtifacts(blueprint) {
5312
5509
  if (blueprint.vendors.length === 0) return [];
@@ -5320,7 +5517,7 @@ function blueprintToOrchestrationArtifacts(blueprint) {
5320
5517
  }];
5321
5518
  }
5322
5519
  /**
5323
- * Compile the vendored host artifacts a named workspace plans.
5520
+ * Compiles the vendored host artifacts a named workspace plans.
5324
5521
  *
5325
5522
  * @param name - The target workspace's own bare package name.
5326
5523
  * @returns One artifact per vendored path in `HOST_PATHS` order, then the
@@ -5365,7 +5562,7 @@ function nameToHostArtifacts(name) {
5365
5562
  }));
5366
5563
  }
5367
5564
  /**
5368
- * Replace the content of every drafted artifact an override names.
5565
+ * Replaces the content of every drafted artifact an override names.
5369
5566
  *
5370
5567
  * @param artifacts - The drafted artifacts.
5371
5568
  * @param overrides - The blueprint's overrides.
@@ -5400,7 +5597,7 @@ function applyOverrides(artifacts, overrides) {
5400
5597
  });
5401
5598
  }
5402
5599
  /**
5403
- * Replace declared dependency ranges in package manifest text.
5600
+ * Replaces declared dependency ranges in package manifest text.
5404
5601
  *
5405
5602
  * @param manifest - The manifest text to compile.
5406
5603
  * @param pins - The runtime and development names and replacement ranges.
@@ -5581,7 +5778,7 @@ function replaceManifestRanges(manifest, pins) {
5581
5778
  return declaredRuntime && declaredDevelopment ? compiled : void 0;
5582
5779
  }
5583
5780
  /**
5584
- * Replace named script values in package manifest text.
5781
+ * Replaces named script values in package manifest text.
5585
5782
  *
5586
5783
  * @param manifest - The manifest text to compile.
5587
5784
  * @param scripts - The scripts to write, each with the predecessors it accepts.
@@ -5809,7 +6006,7 @@ function replaceManifestScripts(manifest, scripts) {
5809
6006
  return compiled;
5810
6007
  }
5811
6008
  /**
5812
- * Replace dependency ranges in a plan's manifest and recompute its identity.
6009
+ * Replaces dependency ranges in a plan's manifest and recomputes its identity.
5813
6010
  *
5814
6011
  * @param plan - The plan carrying the manifest artifact to compile.
5815
6012
  * @param pins - The runtime and development names and replacement ranges.
@@ -5857,7 +6054,7 @@ function replacePlanRanges(plan, pins) {
5857
6054
  };
5858
6055
  }
5859
6056
  /**
5860
- * Compute a plan's content identity.
6057
+ * Computes a plan's content identity.
5861
6058
  *
5862
6059
  * @param plan - The plan to identify.
5863
6060
  * @returns Sixteen lowercase hexadecimal digits, or `undefined` when the plan
@@ -5894,66 +6091,7 @@ function planToHash(plan) {
5894
6091
  return computeHash(outcome.value);
5895
6092
  }
5896
6093
  /**
5897
- * Project one planned artifact and the bytes found at its path into a verdict.
5898
- *
5899
- * @param artifact - The planned artifact.
5900
- * @param observed - The destination's exact bytes as hexadecimal; absent when
5901
- * the destination holds no file.
5902
- * @returns The finding, carrying the artifact's ownership and `observed`
5903
- * exactly where bytes were read.
5904
- *
5905
- * @remarks
5906
- * The comparison itself is {@link inferDrift}'s, so ownership decides it here
5907
- * exactly as it does everywhere else. This adds only the shape: a missing
5908
- * destination has no bytes to record, and every other verdict records the bytes
5909
- * it was given, which is the precondition the mutation that follows is held to.
5910
- * Ownership is copied rather than inferred from drift because aligned findings
5911
- * span every ownership tier.
5912
- *
5913
- * `foreign` is not answerable here, because it describes a path no artifact was
5914
- * planned for.
5915
- *
5916
- * @example
5917
- * ```ts
5918
- * import { artifactToFinding } from '@orkestrel/scaffold'
5919
- *
5920
- * artifactToFinding(
5921
- * { path: 'README.md', group: 'docs', ownership: 'content', origin: 'computed', content: 'hi\n' },
5922
- * '6279650a',
5923
- * ) // { path: 'README.md', group: 'docs', ownership: 'content', drift: 'stale', observed: '6279650a' }
5924
- * ```
5925
- */
5926
- function artifactToFinding(artifact, observed) {
5927
- const path = artifact.path;
5928
- const group = artifact.group;
5929
- const ownership = artifact.ownership;
5930
- if (observed === void 0) return inferDrift(artifact) === "aligned" ? {
5931
- path,
5932
- group,
5933
- ownership,
5934
- drift: "aligned"
5935
- } : {
5936
- path,
5937
- group,
5938
- ownership,
5939
- drift: "missing"
5940
- };
5941
- return inferDrift(artifact, observed) === "stale" ? {
5942
- path,
5943
- group,
5944
- ownership,
5945
- drift: "stale",
5946
- observed
5947
- } : {
5948
- path,
5949
- group,
5950
- ownership,
5951
- drift: "aligned",
5952
- observed
5953
- };
5954
- }
5955
- /**
5956
- * Compare a plan against a target's current content.
6094
+ * Compares a plan against a target's current content.
5957
6095
  *
5958
6096
  * @param plan - The compiled plan.
5959
6097
  * @param current - The target's exact bytes, keyed by artifact-relative path.
@@ -5999,7 +6137,7 @@ function planToFindings(plan, current) {
5999
6137
  return findings;
6000
6138
  }
6001
6139
  /**
6002
- * Measure one declared package list against the name and range syntax it accepts.
6140
+ * Measures one declared package list against the name and range syntax it accepts.
6003
6141
  *
6004
6142
  * @param dependencies - The declared list.
6005
6143
  * @param field - The blueprint field the list came from, reported on each question.
@@ -6056,7 +6194,7 @@ function dependenciesToQuestions(dependencies, field, name, range) {
6056
6194
  return questions;
6057
6195
  }
6058
6196
  /**
6059
- * Measure a blueprint against every law its own fields decide.
6197
+ * Measures a blueprint against every law its own fields decide.
6060
6198
  *
6061
6199
  * @param blueprint - The workspace specification.
6062
6200
  * @returns One question per rejected field, in blueprint field order, with the
@@ -6196,7 +6334,7 @@ function blueprintToQuestions(blueprint) {
6196
6334
  return questions;
6197
6335
  }
6198
6336
  /**
6199
- * Measure a drafted artifact list against the laws a whole plan decides.
6337
+ * Measures a drafted artifact list against the laws a whole plan decides.
6200
6338
  *
6201
6339
  * @param artifacts - The drafted artifacts.
6202
6340
  * @returns One blocking question per colliding path and per exceeded ceiling.
@@ -6253,7 +6391,7 @@ function artifactsToQuestions(artifacts) {
6253
6391
  return questions;
6254
6392
  }
6255
6393
  /**
6256
- * Measure a blueprint's overrides against the artifacts drafted for it.
6394
+ * Measures a blueprint's overrides against the artifacts drafted for it.
6257
6395
  *
6258
6396
  * @param overrides - The blueprint's overrides.
6259
6397
  * @param artifacts - The drafted artifacts, before overrides are applied.
@@ -6317,7 +6455,7 @@ function overridesToQuestions(overrides, artifacts) {
6317
6455
  //#endregion
6318
6456
  //#region src/core/factories.ts
6319
6457
  /**
6320
- * Construct a {@link Blueprint} from a name and the fields that differ from the defaults.
6458
+ * Constructs a {@link Blueprint} from a name and the fields that differ from the defaults.
6321
6459
  *
6322
6460
  * @param name - The bare workspace name.
6323
6461
  * @param input - The fields to set; every omitted field takes its default.
@@ -6382,7 +6520,7 @@ function createBlueprint(name, input) {
6382
6520
  //#endregion
6383
6521
  //#region src/core/Compiler.ts
6384
6522
  /**
6385
- * The compile spine: draft, gate, pin, run in that order over a blueprint.
6523
+ * Represents the compile spine: draft, gate, pin, run in that order over a blueprint.
6386
6524
  *
6387
6525
  * @remarks
6388
6526
  * The draft stage assembles the artifacts the selected groups cover. The gate
@@ -6426,7 +6564,7 @@ var Compiler = class {
6426
6564
  #emitter;
6427
6565
  #destroyed = false;
6428
6566
  /**
6429
- * Construct a compiler.
6567
+ * Constructs a compiler.
6430
6568
  *
6431
6569
  * @param options - The initial listeners and the listener-error handler.
6432
6570
  * @throws {@link ScaffoldError} coded `INVALID` when `options` is present but
@@ -6446,12 +6584,12 @@ var Compiler = class {
6446
6584
  ...accepted?.error === void 0 ? {} : { error: accepted.error }
6447
6585
  });
6448
6586
  }
6449
- /** The compiler's observation channel. */
6587
+ /** Exposes the compiler's observation channel. */
6450
6588
  get emitter() {
6451
6589
  return this.#emitter;
6452
6590
  }
6453
6591
  /**
6454
- * Compile a blueprint into a plan through the draft, gate, and pin stages.
6592
+ * Compiles a blueprint into a plan through the draft, gate, and pin stages.
6455
6593
  *
6456
6594
  * @param blueprint - The workspace specification to compile.
6457
6595
  * @param groups - The artifact groups to cover; every group when absent.
@@ -6490,7 +6628,7 @@ var Compiler = class {
6490
6628
  return scaffolding;
6491
6629
  }
6492
6630
  /**
6493
- * Compile a blueprint and compare its plan to a target's current content.
6631
+ * Compiles a blueprint and compares its plan to a target's current content.
6494
6632
  *
6495
6633
  * @param blueprint - The workspace specification to compile.
6496
6634
  * @param current - The target's exact bytes, keyed by artifact-relative path.
@@ -6533,7 +6671,7 @@ var Compiler = class {
6533
6671
  return result;
6534
6672
  }
6535
6673
  /**
6536
- * Tear the compiler down. Every later call throws, and teardown is idempotent.
6674
+ * Tears the compiler down. Every later call throws, and teardown is idempotent.
6537
6675
  *
6538
6676
  * @returns Nothing.
6539
6677
  *
@@ -6691,6 +6829,8 @@ exports.BIN_CONFIGS = BIN_CONFIGS;
6691
6829
  exports.BIN_ENTRY_PATH = BIN_ENTRY_PATH;
6692
6830
  exports.CANON_PATHS = CANON_PATHS;
6693
6831
  exports.CATALOG_AGENT_PATH = CATALOG_AGENT_PATH;
6832
+ exports.CATALOG_CLOSING_MARKER = CATALOG_CLOSING_MARKER;
6833
+ exports.CATALOG_OPENING_MARKER = CATALOG_OPENING_MARKER;
6694
6834
  exports.CONFIG_TEMPLATES = CONFIG_TEMPLATES;
6695
6835
  exports.CONFORMANCE_TEST_PATH = CONFORMANCE_TEST_PATH;
6696
6836
  exports.CONTROL_CHARACTER_PATTERN = CONTROL_CHARACTER_PATTERN;
@@ -6791,6 +6931,7 @@ exports.isDependency = isDependency;
6791
6931
  exports.isDependencyName = isDependencyName;
6792
6932
  exports.isEnvironment = isEnvironment;
6793
6933
  exports.isFinding = isFinding;
6934
+ exports.isFloorPath = isFloorPath;
6794
6935
  exports.isGroup = isGroup;
6795
6936
  exports.isGroups = isGroups;
6796
6937
  exports.isHex = isHex;
@@ -6800,6 +6941,7 @@ exports.isOverride = isOverride;
6800
6941
  exports.isPath = isPath;
6801
6942
  exports.isPlan = isPlan;
6802
6943
  exports.isQuestion = isQuestion;
6944
+ exports.isRetainedPath = isRetainedPath;
6803
6945
  exports.isScaffoldError = isScaffoldError;
6804
6946
  exports.isSnapshot = isSnapshot;
6805
6947
  exports.manifestToDependencies = manifestToDependencies;