@orkestrel/scaffold 0.0.101 → 0.0.103

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 (59) hide show
  1. package/dist/agents/skills/orkestrel-dispatch/scripts/brief.js +6 -14
  2. package/dist/agents/skills/orkestrel-dispatch/scripts/cite.js +41 -28
  3. package/dist/agents/skills/orkestrel-dispatch/scripts/helpers.js +5 -12
  4. package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +25 -13
  5. package/dist/agents/skills/orkestrel-dispatch/scripts/login.js +18 -25
  6. package/dist/agents/skills/orkestrel-dispatch/scripts/result.js +11 -9
  7. package/dist/agents/skills/orkestrel-harden/scripts/discovery.js +233 -232
  8. package/dist/agents/skills/orkestrel-publish/scripts/compare.js +95 -89
  9. package/dist/agents/skills/orkestrel-publish/scripts/pins.js +5 -7
  10. package/dist/agents/skills/orkestrel-publish/scripts/swap.js +1273 -0
  11. package/dist/agents/skills/orkestrel-publish/scripts/wave.js +99 -89
  12. package/dist/agents/skills/orkestrel-publish/scripts/window.js +54 -52
  13. package/dist/agents/skills/orkestrel-scout/scripts/map.js +160 -161
  14. package/dist/bin/main.js +483 -444
  15. package/dist/bin/main.js.map +1 -1
  16. package/dist/host/AGENTS.md +1 -0
  17. package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +10 -10
  18. package/dist/host/agents/skills/orkestrel-dispatch/scripts/brief.ts +8 -11
  19. package/dist/host/agents/skills/orkestrel-dispatch/scripts/cite.ts +58 -28
  20. package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +5 -10
  21. package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +31 -12
  22. package/dist/host/agents/skills/orkestrel-dispatch/scripts/login.ts +28 -23
  23. package/dist/host/agents/skills/orkestrel-dispatch/scripts/result.ts +12 -10
  24. package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +318 -237
  25. package/dist/host/agents/skills/orkestrel-journey/references/statechart.md +2 -5
  26. package/dist/host/agents/skills/orkestrel-publish/SKILL.md +7 -6
  27. package/dist/host/agents/skills/orkestrel-publish/references/release.md +12 -10
  28. package/dist/host/agents/skills/orkestrel-publish/references/wave.md +12 -5
  29. package/dist/host/agents/skills/orkestrel-publish/scripts/compare.ts +124 -82
  30. package/dist/host/agents/skills/orkestrel-publish/scripts/pins.ts +5 -7
  31. package/dist/host/agents/skills/orkestrel-publish/scripts/swap.ts +1655 -0
  32. package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +128 -97
  33. package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +70 -55
  34. package/dist/host/agents/skills/orkestrel-scout/scripts/map.ts +215 -155
  35. package/dist/host/claude/rules/architecture.md +2 -2
  36. package/dist/host/claude/rules/tests.md +8 -2
  37. package/dist/host/claude/rules/typescript.md +130 -0
  38. package/dist/host/claude/rules/workspace.md +33 -18
  39. package/dist/host/configs/helpers.ts +209 -148
  40. package/dist/host/configs/policy.ts +110 -105
  41. package/dist/host/dotfiles/oxlintrc.json +1 -11
  42. package/dist/host/guides/scaffold.md +244 -170
  43. package/dist/host/manifest.json +36 -30
  44. package/dist/host/tests/config.test.ts +1263 -687
  45. package/dist/host/tests/policy.test.ts +19 -0
  46. package/dist/host/tests/setupPolicy.ts +1699 -1026
  47. package/dist/src/core/index.cjs +1595 -1686
  48. package/dist/src/core/index.cjs.map +1 -1
  49. package/dist/src/core/index.d.cts +202 -18
  50. package/dist/src/core/index.d.ts +202 -18
  51. package/dist/src/core/index.js +1590 -1687
  52. package/dist/src/core/index.js.map +1 -1
  53. package/dist/src/server/index.cjs +448 -392
  54. package/dist/src/server/index.cjs.map +1 -1
  55. package/dist/src/server/index.d.cts +1182 -1052
  56. package/dist/src/server/index.d.ts +1182 -1052
  57. package/dist/src/server/index.js +447 -395
  58. package/dist/src/server/index.js.map +1 -1
  59. package/package.json +2 -2
@@ -482,18 +482,61 @@ function isExactCaseFile(path) {
482
482
  if (!isPhysicalFile(full)) return false;
483
483
  const root = (0, node_path.parse)(full).root;
484
484
  const segments = (0, node_path.relative)(root, full).split(node_path.sep);
485
- let parent = root;
486
- for (const segment of segments) {
485
+ return segments.every((segment, index) => {
486
+ const parent = (0, node_path.join)(root, ...segments.slice(0, index));
487
487
  const entries = (0, _orkestrel_contract.attempt)(() => (0, node_fs.readdirSync)(parent));
488
- if (entries.success) {
489
- if (!entries.value.includes(segment)) return false;
490
- } else {
491
- const actual = (0, _orkestrel_contract.attempt)(() => node_fs.realpathSync.native((0, node_path.join)(parent, segment)));
492
- if (!actual.success || (0, node_path.basename)(actual.value) !== segment) return false;
493
- }
494
- parent = (0, node_path.join)(parent, segment);
495
- }
496
- return true;
488
+ if (entries.success) return entries.value.includes(segment);
489
+ const actual = (0, _orkestrel_contract.attempt)(() => node_fs.realpathSync.native((0, node_path.join)(parent, segment)));
490
+ return actual.success && (0, node_path.basename)(actual.value) === segment;
491
+ });
492
+ }
493
+ /**
494
+ * Places each result at the index its entry names, in a fresh array.
495
+ *
496
+ * @param entries - The index and result pairs, in any order; each index a non-negative integer.
497
+ * @returns An array holding each result at its index, whose length is the highest index plus one,
498
+ * and where an index no entry names stays a hole.
499
+ *
500
+ * @remarks
501
+ * A worker pool finishes its items out of order and can skip one, so its answer is merged by
502
+ * position rather than by arrival: each index is written once into a fresh array, which needs no
503
+ * sort and keeps a skipped index absent instead of closing the gap. A repeated index keeps its last
504
+ * result.
505
+ *
506
+ * @example
507
+ * ```ts
508
+ * import { collectIndexed } from '@orkestrel/scaffold/server'
509
+ *
510
+ * collectIndexed([[0, 'first'], [2, 'third']]).length // 3
511
+ * ```
512
+ */
513
+ function collectIndexed(entries) {
514
+ return Object.assign([], Object.fromEntries(entries));
515
+ }
516
+ /**
517
+ * Lists a path followed by each directory above it, nearest first.
518
+ *
519
+ * @param path - The host path to climb from.
520
+ * @param limit - The most paths to list; every ancestor by default.
521
+ * @returns The path, then `dirname` of each result in turn, ending at the first path that is its
522
+ * own parent (`.` for a relative path, the filesystem root for an absolute one) or at `limit`.
523
+ *
524
+ * @remarks
525
+ * The climb is derived from the path text alone and reads no filesystem, so a caller bounds a walk
526
+ * by the length it asks for rather than by a counter it reassigns. The final path of an unbounded
527
+ * list is the one `dirname` leaves unchanged.
528
+ *
529
+ * @example
530
+ * ```ts
531
+ * import { listAncestors } from '@orkestrel/scaffold/server'
532
+ *
533
+ * listAncestors('notes/entry/file.md') // ['notes/entry/file.md', 'notes/entry', 'notes', '.']
534
+ * listAncestors('notes/entry/file.md', 2) // ['notes/entry/file.md', 'notes/entry']
535
+ * ```
536
+ */
537
+ function listAncestors(path, limit = Number.POSITIVE_INFINITY) {
538
+ const parent = (0, node_path.dirname)(path);
539
+ return parent === path || limit <= 1 ? [path] : [path, ...listAncestors(parent, limit - 1)];
497
540
  }
498
541
  /**
499
542
  * Tests whether a path is a physical directory this package will read or write into.
@@ -549,14 +592,15 @@ function computeFileDigest(path) {
549
592
  if (!before.isFile() || before.nlink !== 1 || before.size > _src_core.MAX_ARTIFACT_BYTES) return void 0;
550
593
  const hash = (0, node_crypto.createHash)("sha256");
551
594
  const buffer = Buffer.alloc(65536);
552
- let size = 0;
595
+ const lengths = [];
553
596
  for (;;) {
554
597
  const length = (0, node_fs.readSync)(handle, buffer, 0, buffer.byteLength, null);
555
598
  if (length === 0) break;
556
- size += length;
557
- if (size > _src_core.MAX_ARTIFACT_BYTES) return void 0;
599
+ lengths.push(length);
600
+ if ((0, _src_core.computeTotal)(lengths) > _src_core.MAX_ARTIFACT_BYTES) return void 0;
558
601
  hash.update(buffer.subarray(0, length));
559
602
  }
603
+ const size = (0, _src_core.computeTotal)(lengths);
560
604
  const after = (0, node_fs.fstatSync)(handle);
561
605
  if (size !== before.size || after.size !== before.size || after.mtimeMs !== before.mtimeMs) return;
562
606
  return hash.digest("hex");
@@ -578,8 +622,8 @@ function computeFileDigest(path) {
578
622
  * yet, and a lexical answer is not enough: a link anywhere in the existing
579
623
  * prefix moves the destination somewhere the text never named. So the deepest
580
624
  * existing ancestor is resolved and the remaining segments are re-joined onto
581
- * it. The climb is bounded by the path-depth ceiling, so an adversarial path
582
- * cannot make it walk indefinitely.
625
+ * it. {@link climbRealPath} performs the climb and bounds it by the path-depth
626
+ * ceiling, so an adversarial path cannot make it walk indefinitely.
583
627
  *
584
628
  * The caller's own text is collapsed first, which is what `resolve` does with a
585
629
  * `..` the caller wrote: it cancels the segment before it as text, before any
@@ -613,32 +657,50 @@ function computeFileDigest(path) {
613
657
  * ```
614
658
  */
615
659
  function resolveRealPath(path) {
616
- if (!isFilesystemPath(path)) return void 0;
617
- let current = (0, node_path.resolve)(path);
618
- const pending = [];
619
- for (let depth = 0; depth <= 64; depth += 1) {
620
- const real = (0, _orkestrel_contract.attempt)(() => (0, node_fs.realpathSync)(current));
621
- if (real.success) {
622
- let physical = real.value;
623
- for (const segment of pending) physical = (0, node_path.join)(physical, segment);
624
- return physical;
625
- }
626
- if (!matchesMissingPath(real.error)) return void 0;
627
- const status = (0, _orkestrel_contract.attempt)(() => (0, node_fs.lstatSync)(current));
628
- if (status.success) {
629
- if (!status.value.isSymbolicLink()) return void 0;
630
- const target = (0, _orkestrel_contract.attempt)(() => (0, node_fs.readlinkSync)(current));
631
- if (!target.success) return void 0;
632
- if (target.value.split(/[\\/]/u).includes("..")) return void 0;
633
- current = (0, node_path.resolve)((0, node_path.dirname)(current), target.value);
634
- continue;
635
- }
636
- if (!matchesMissingPath(status.error)) return void 0;
637
- const parent = (0, node_path.dirname)(current);
638
- if (parent === current) return void 0;
639
- pending.unshift((0, node_path.relative)(parent, current));
640
- current = parent;
660
+ return isFilesystemPath(path) ? climbRealPath((0, node_path.resolve)(path), [], 0) : void 0;
661
+ }
662
+ /**
663
+ * Climbs from an absolute path to its deepest existing ancestor and resolves it through every link.
664
+ *
665
+ * @param current - The absolute host path the climb reads at this depth.
666
+ * @param pending - The absent segments already climbed past, outermost first.
667
+ * @param depth - The steps already taken, from 0 through `MAX_PATH_DEPTH`.
668
+ * @returns The real path of the first existing ancestor joined with `pending` and every segment the
669
+ * climb passes, or `undefined` when `depth` is not a safe integer from 0 through `MAX_PATH_DEPTH`,
670
+ * the climb reaches the root, a link target cannot be read or carries a `..` segment, an existing
671
+ * entry is not a link, or an entry cannot be read.
672
+ *
673
+ * @remarks
674
+ * Each step reads one path and moves the climb to one other: a dangling link redirects it to the
675
+ * link's target with the same suffix, and an absent name moves it to the parent with that name added
676
+ * to the suffix. One successor per step makes the climb a bounded recursion rather than a worklist,
677
+ * and the depth argument is its bound, so an adversarial path or a link cycle answers `undefined`
678
+ * after `MAX_PATH_DEPTH` steps instead of walking indefinitely. {@link resolveRealPath} starts the
679
+ * climb at depth 0 with nothing pending.
680
+ *
681
+ * @example
682
+ * ```ts
683
+ * import { resolve } from 'node:path'
684
+ * import { climbRealPath } from '@orkestrel/scaffold/server'
685
+ *
686
+ * climbRealPath(resolve('./packages/new/src'), [], 0) // the real path of packages, plus new/src
687
+ * ```
688
+ */
689
+ function climbRealPath(current, pending, depth) {
690
+ if (!Number.isSafeInteger(depth) || depth < 0 || depth > 64) return void 0;
691
+ const real = (0, _orkestrel_contract.attempt)(() => (0, node_fs.realpathSync)(current));
692
+ if (real.success) return pending.length === 0 ? real.value : (0, node_path.join)(real.value, ...pending);
693
+ if (!matchesMissingPath(real.error)) return void 0;
694
+ const status = (0, _orkestrel_contract.attempt)(() => (0, node_fs.lstatSync)(current));
695
+ if (status.success) {
696
+ if (!status.value.isSymbolicLink()) return void 0;
697
+ const target = (0, _orkestrel_contract.attempt)(() => (0, node_fs.readlinkSync)(current));
698
+ if (!target.success || target.value.split(/[\\/]/u).includes("..")) return void 0;
699
+ return climbRealPath((0, node_path.resolve)((0, node_path.dirname)(current), target.value), pending, depth + 1);
641
700
  }
701
+ if (!matchesMissingPath(status.error)) return void 0;
702
+ const parent = (0, node_path.dirname)(current);
703
+ return parent === current ? void 0 : climbRealPath(parent, [(0, node_path.relative)(parent, current), ...pending], depth + 1);
642
704
  }
643
705
  /**
644
706
  * Resolves a root-relative path and refuses one that leaves its root.
@@ -765,13 +827,12 @@ function listFiles(root) {
765
827
  });
766
828
  }
767
829
  if (!status.value.isDirectory() || status.value.isSymbolicLink()) throw new _src_core.ScaffoldError("TARGET", `Listing root is not a physical directory at ${root}`, { root });
768
- const files = [];
769
830
  const pending = [{
770
831
  full: root,
771
832
  path: "",
772
833
  depth: 0
773
834
  }];
774
- let visited = 0;
835
+ const entries = [];
775
836
  while (pending.length > 0) {
776
837
  const current = pending.pop();
777
838
  if (current === void 0) break;
@@ -786,20 +847,21 @@ function listFiles(root) {
786
847
  for (;;) {
787
848
  const entry = handle.readSync();
788
849
  if (entry === null) break;
789
- visited += 1;
790
- if (visited > 1e5) throw new _src_core.ScaffoldError("TARGET", "Listing exceeds the paths one inventory may report", {
850
+ const path = current.path === "" ? entry.name : `${current.path}/${entry.name}`;
851
+ const file = !entry.isDirectory() || entry.isSymbolicLink();
852
+ entries.push({
853
+ path,
854
+ file
855
+ });
856
+ if (entries.length > 1e5) throw new _src_core.ScaffoldError("TARGET", "Listing exceeds the paths one inventory may report", {
791
857
  root,
792
858
  limit: MAX_INVENTORY_PATHS
793
859
  });
794
- const path = current.path === "" ? entry.name : `${current.path}/${entry.name}`;
795
860
  if (!(0, _src_core.isPath)(path)) throw new _src_core.ScaffoldError("TARGET", `Listing found a path this package cannot plan at ${path}`, {
796
861
  root,
797
862
  path
798
863
  });
799
- if (!entry.isDirectory() || entry.isSymbolicLink()) {
800
- files.push(path);
801
- continue;
802
- }
864
+ if (file) continue;
803
865
  const depth = current.depth + 1;
804
866
  if (depth >= 64) throw new _src_core.ScaffoldError("TARGET", `Listing exceeds the depth one path may carry at ${path}`, {
805
867
  root,
@@ -816,7 +878,7 @@ function listFiles(root) {
816
878
  (0, _orkestrel_contract.attempt)(() => handle.closeSync());
817
879
  if (!walked.success) throw walked.error;
818
880
  }
819
- return files.sort();
881
+ return entries.filter(({ file }) => file).map(({ path }) => path).sort();
820
882
  }
821
883
  /**
822
884
  * Lists a directory's descendant directories as sorted root-relative paths.
@@ -858,13 +920,12 @@ function listDirectories(root) {
858
920
  });
859
921
  }
860
922
  if (!status.value.isDirectory() || status.value.isSymbolicLink()) throw new _src_core.ScaffoldError("TARGET", `Listing root is not a physical directory at ${root}`, { root });
861
- const directories = [];
862
923
  const pending = [{
863
924
  full: root,
864
925
  path: "",
865
926
  depth: 0
866
927
  }];
867
- let visited = 0;
928
+ const entries = [];
868
929
  while (pending.length > 0) {
869
930
  const current = pending.pop();
870
931
  if (current === void 0) break;
@@ -879,24 +940,27 @@ function listDirectories(root) {
879
940
  for (;;) {
880
941
  const entry = handle.readSync();
881
942
  if (entry === null) break;
882
- visited += 1;
883
- if (visited > 1e5) throw new _src_core.ScaffoldError("TARGET", "Listing exceeds the paths one inventory may report", {
943
+ const path = current.path === "" ? entry.name : `${current.path}/${entry.name}`;
944
+ const directory = entry.isDirectory() && !entry.isSymbolicLink();
945
+ entries.push({
946
+ path,
947
+ directory
948
+ });
949
+ if (entries.length > 1e5) throw new _src_core.ScaffoldError("TARGET", "Listing exceeds the paths one inventory may report", {
884
950
  root,
885
951
  limit: MAX_INVENTORY_PATHS
886
952
  });
887
- const path = current.path === "" ? entry.name : `${current.path}/${entry.name}`;
888
953
  if (!(0, _src_core.isPath)(path)) throw new _src_core.ScaffoldError("TARGET", `Listing found a path this package cannot plan at ${path}`, {
889
954
  root,
890
955
  path
891
956
  });
892
- if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
957
+ if (!directory) continue;
893
958
  const depth = current.depth + 1;
894
959
  if (depth >= 64) throw new _src_core.ScaffoldError("TARGET", `Listing exceeds the depth one path may carry at ${path}`, {
895
960
  root,
896
961
  path,
897
962
  limit: 64
898
963
  });
899
- directories.push(path);
900
964
  pending.push({
901
965
  full: (0, node_path.join)(current.full, entry.name),
902
966
  path,
@@ -907,7 +971,7 @@ function listDirectories(root) {
907
971
  (0, _orkestrel_contract.attempt)(() => handle.closeSync());
908
972
  if (!walked.success) throw walked.error;
909
973
  }
910
- return directories.sort();
974
+ return entries.filter(({ directory }) => directory).map(({ path }) => path).sort();
911
975
  }
912
976
  /**
913
977
  * Lists the canon paths a target holds, filtered to a plan's groups.
@@ -941,14 +1005,12 @@ function listDirectories(root) {
941
1005
  * ```
942
1006
  */
943
1007
  function listCanonPaths(target, groups) {
944
- const held = [];
945
- for (const member of _src_core.CANON_PATHS) {
1008
+ return _src_core.CANON_PATHS.flatMap((member) => {
946
1009
  const full = resolveContainedPath(target, member);
947
- if (full === void 0) continue;
948
- if (isPhysicalFile(full)) held.push(member);
949
- else if (isPhysicalDirectory(full)) for (const name of listFiles(full)) held.push(`${member}/${name}`);
950
- }
951
- return held.filter((path) => groups.includes((0, _src_core.inferGroup)(path)));
1010
+ if (full === void 0) return [];
1011
+ if (isPhysicalFile(full)) return [member];
1012
+ return isPhysicalDirectory(full) ? listFiles(full).map((name) => `${member}/${name}`) : [];
1013
+ }).filter((path) => groups.includes((0, _src_core.inferGroup)(path)));
952
1014
  }
953
1015
  /**
954
1016
  * Removes every directory one set of deletions emptied.
@@ -981,24 +1043,13 @@ function listCanonPaths(target, groups) {
981
1043
  * ```
982
1044
  */
983
1045
  function pruneEmptiedDirectories(target, removed) {
984
- const candidates = /* @__PURE__ */ new Set();
985
- for (const path of removed) {
986
- let parent = (0, node_path.dirname)(path);
987
- while (parent !== "." && parent !== (0, node_path.dirname)(parent) && !candidates.has(parent)) {
988
- candidates.add(parent);
989
- parent = (0, node_path.dirname)(parent);
990
- }
991
- }
992
- const ordered = [...candidates].sort((left, right) => (0, _orkestrel_contract.compareValues)(right.split("/").length, left.split("/").length) || (0, _orkestrel_contract.compareValues)(left, right));
993
- const pruned = [];
994
- for (const candidate of ordered) {
1046
+ return [...new Set(Iterator.from(removed).flatMap((path) => listAncestors(path).slice(1, -1)).toArray())].sort((left, right) => (0, _orkestrel_contract.compareValues)(right.split("/").length, left.split("/").length) || (0, _orkestrel_contract.compareValues)(left, right)).flatMap((candidate) => {
995
1047
  const directory = resolveContainedPath(target, candidate);
996
- if (directory === void 0 || !isPhysicalDirectory(directory)) continue;
1048
+ if (directory === void 0 || !isPhysicalDirectory(directory)) return [];
997
1049
  const entries = (0, _orkestrel_contract.attempt)(() => (0, node_fs.readdirSync)(directory));
998
- if (!entries.success || entries.value.length > 0) continue;
999
- if ((0, _orkestrel_contract.attempt)(() => (0, node_fs.rmdirSync)(directory)).success) pruned.push(candidate);
1000
- }
1001
- return pruned;
1050
+ if (!entries.success || entries.value.length > 0) return [];
1051
+ return (0, _orkestrel_contract.attempt)(() => (0, node_fs.rmdirSync)(directory)).success ? [candidate] : [];
1052
+ });
1002
1053
  }
1003
1054
  /**
1004
1055
  * Reads one contained file as its exact bytes in lowercase hexadecimal.
@@ -1046,12 +1097,15 @@ function readFileHex(root, path, limit = _src_core.MAX_ARTIFACT_BYTES) {
1046
1097
  const before = (0, node_fs.fstatSync)(handle);
1047
1098
  if (!before.isFile() || before.nlink !== 1 || before.size > limit) return void 0;
1048
1099
  const bytes = Buffer.alloc(before.size);
1049
- let offset = 0;
1050
- while (offset < bytes.byteLength) {
1051
- const length = (0, node_fs.readSync)(handle, bytes, offset, bytes.byteLength - offset, offset);
1100
+ const reads = [];
1101
+ for (;;) {
1102
+ const position = (0, _src_core.computeTotal)(reads);
1103
+ if (position >= bytes.byteLength) break;
1104
+ const length = (0, node_fs.readSync)(handle, bytes, position, bytes.byteLength - position, position);
1052
1105
  if (length === 0) break;
1053
- offset += length;
1106
+ reads.push(length);
1054
1107
  }
1108
+ const offset = (0, _src_core.computeTotal)(reads);
1055
1109
  const overflow = (0, node_fs.readSync)(handle, Buffer.alloc(1), 0, 1, offset);
1056
1110
  const after = (0, node_fs.fstatSync)(handle);
1057
1111
  if (offset !== bytes.byteLength || overflow !== 0 || after.size !== before.size || after.mtimeMs !== before.mtimeMs) return;
@@ -1123,9 +1177,7 @@ function readSnapshot(target, paths) {
1123
1177
  target,
1124
1178
  limit: _src_core.MAX_COLLECTION_ITEMS
1125
1179
  });
1126
- let remaining = _src_core.MAX_TOTAL_ARTIFACT_BYTES;
1127
- const snapshot = {};
1128
- for (const path of paths) {
1180
+ const read = Iterator.from(paths).reduce((state, path) => {
1129
1181
  const full = resolveContainedPath(target, path);
1130
1182
  if (full === void 0) throw new _src_core.ScaffoldError("INVALID", `Snapshot path leaves its target at ${path}`, {
1131
1183
  target,
@@ -1133,27 +1185,32 @@ function readSnapshot(target, paths) {
1133
1185
  });
1134
1186
  const status = (0, _orkestrel_contract.attempt)(() => (0, node_fs.lstatSync)(full));
1135
1187
  if (!status.success) {
1136
- if (matchesMissingPath(status.error)) continue;
1188
+ if (matchesMissingPath(status.error)) return state;
1137
1189
  throw new _src_core.ScaffoldError("TARGET", `Snapshot path cannot be inspected at ${path}`, {
1138
1190
  target,
1139
1191
  path,
1140
1192
  error: status.error
1141
1193
  });
1142
1194
  }
1143
- if (isPhysicalDirectory(full)) {
1144
- snapshot[path] = "";
1145
- continue;
1146
- }
1147
- const hex = readFileHex(target, path, Math.min(_src_core.MAX_ARTIFACT_BYTES, remaining));
1195
+ if (isPhysicalDirectory(full)) return {
1196
+ ...state,
1197
+ entries: [...state.entries, [path, ""]]
1198
+ };
1199
+ const hex = readFileHex(target, path, Math.min(_src_core.MAX_ARTIFACT_BYTES, _src_core.MAX_TOTAL_ARTIFACT_BYTES - (0, _src_core.computeTotal)(state.spent)));
1148
1200
  if (hex === void 0) throw new _src_core.ScaffoldError("TARGET", `Snapshot path is not a readable file at ${path}`, {
1149
1201
  target,
1150
1202
  path,
1151
1203
  limit: _src_core.MAX_TOTAL_ARTIFACT_BYTES
1152
1204
  });
1153
- remaining -= hex.length / 2;
1154
- snapshot[path] = hex;
1155
- }
1156
- return snapshot;
1205
+ return {
1206
+ entries: [...state.entries, [path, hex]],
1207
+ spent: [...state.spent, hex.length / 2]
1208
+ };
1209
+ }, {
1210
+ entries: [],
1211
+ spent: []
1212
+ });
1213
+ return Object.fromEntries(read.entries);
1157
1214
  }
1158
1215
  /**
1159
1216
  * Reads a vendored host's manifest, when it carries one.
@@ -1237,20 +1294,18 @@ function readHostFloor(root) {
1237
1294
  if (!isPhysicalDirectory(host)) throw new _src_core.ScaffoldError("TARGET", `The vendored host root is not readable at ${host}`, { host });
1238
1295
  const manifest = readHostManifest(host, source ? _src_core.HOST_INVENTORY_PATH : MANIFEST_NAME);
1239
1296
  if (manifest === void 0) throw new _src_core.ScaffoldError("TARGET", `The vendored host carries no manifest at ${host}`, { host });
1240
- const bytes = {};
1241
- for (const entry of manifest.entries) {
1242
- const path = source ? entry.destination : entry.storage;
1243
- const hex = readFileHex(host, path);
1244
- if (hex === void 0 || hexToDigest(hex) !== entry.digest) throw new _src_core.ScaffoldError("TARGET", `The vendored host cannot read the declared file at ${path}`, {
1245
- host,
1246
- path,
1247
- destination: entry.destination
1248
- });
1249
- bytes[entry.destination] = hex;
1250
- }
1251
1297
  return {
1252
1298
  manifest,
1253
- bytes
1299
+ bytes: Object.fromEntries(manifest.entries.map((entry) => {
1300
+ const path = source ? entry.destination : entry.storage;
1301
+ const hex = readFileHex(host, path);
1302
+ if (hex === void 0 || hexToDigest(hex) !== entry.digest) throw new _src_core.ScaffoldError("TARGET", `The vendored host cannot read the declared file at ${path}`, {
1303
+ host,
1304
+ path,
1305
+ destination: entry.destination
1306
+ });
1307
+ return [entry.destination, hex];
1308
+ }))
1254
1309
  };
1255
1310
  }
1256
1311
  /**
@@ -1330,24 +1385,21 @@ function readManifestEntry(destination, source) {
1330
1385
  */
1331
1386
  function filesToHost(files, floor) {
1332
1387
  const declared = new Set(floor.manifest.entries.map((entry) => entry.destination));
1333
- const held = /* @__PURE__ */ new Map();
1334
- for (const file of files) {
1335
- if (file.lookup !== "found" || !declared.has(file.path)) return void 0;
1336
- if (!(0, _src_core.isFloorPath)(file.path)) held.set(file.path, file.hex);
1337
- }
1338
- const entries = [];
1339
- const bytes = {};
1340
- for (const entry of floor.manifest.entries) {
1388
+ const rows = [...(0, _src_core.iterateAnswers)(files, (file) => file.lookup !== "found" || !declared.has(file.path) ? void 0 : (0, _src_core.isFloorPath)(file.path) ? [] : [[file.path, file.hex]])];
1389
+ if (!rows.every(_orkestrel_contract.isDefined)) return void 0;
1390
+ const held = new Map(rows.flat());
1391
+ const filled = [...(0, _src_core.iterateAnswers)(floor.manifest.entries, (entry) => {
1341
1392
  const hex = (0, _src_core.isFloorPath)(entry.destination) ? floor.bytes[entry.destination] : held.get(entry.destination);
1342
- if (hex === void 0) return void 0;
1343
- entries.push({
1393
+ return hex === void 0 ? void 0 : [{
1344
1394
  storage: entry.storage,
1345
1395
  destination: entry.destination,
1346
1396
  executable: entry.executable,
1347
1397
  digest: hexToDigest(hex)
1348
- });
1349
- bytes[entry.destination] = hex;
1350
- }
1398
+ }, hex];
1399
+ })];
1400
+ if (!filled.every(_orkestrel_contract.isDefined)) return void 0;
1401
+ const entries = filled.map(([entry]) => entry);
1402
+ const bytes = Object.fromEntries(filled.map(([entry, hex]) => [entry.destination, hex]));
1351
1403
  return {
1352
1404
  manifest: {
1353
1405
  entries,
@@ -1395,8 +1447,7 @@ function filesToHost(files, floor) {
1395
1447
  function stageBytes(host, root, destinations) {
1396
1448
  if (!isFilesystemPath(root)) throw new _src_core.ScaffoldError("INVALID", "Staging host root is not a host path", { host: root });
1397
1449
  const declared = new Map(host.manifest.entries.map((entry) => [entry.destination, entry]));
1398
- const staged = [];
1399
- for (const destination of destinations) {
1450
+ return Iterator.from(destinations).map((destination) => {
1400
1451
  const entry = declared.get(destination);
1401
1452
  const hex = host.bytes[destination];
1402
1453
  if (entry === void 0 || hex === void 0) throw new _src_core.ScaffoldError("TARGET", `The host carries no bytes for ${destination}`, {
@@ -1426,9 +1477,8 @@ function stageBytes(host, root, destinations) {
1426
1477
  host: root,
1427
1478
  storage: entry.storage
1428
1479
  });
1429
- staged.push(entry);
1430
- }
1431
- return staged;
1480
+ return entry;
1481
+ }).toArray();
1432
1482
  }
1433
1483
  /**
1434
1484
  * Stages a vendored host root from a real checkout.
@@ -1505,37 +1555,36 @@ function stageHost(checkout, host, options) {
1505
1555
  const source = (0, node_path.resolve)(checkout);
1506
1556
  if (!isPhysicalDirectory(source)) throw new _src_core.ScaffoldError("TARGET", `Staging checkout is not a physical directory at ${source}`, { checkout: source });
1507
1557
  if (!isVacant(host)) throw new _src_core.ScaffoldError("TARGET", `Staging host root is not vacant at ${host}`, { host });
1508
- const vendored = [];
1509
- const roots = [];
1510
- const missing = [];
1511
- for (const path of [
1558
+ const reads = [
1512
1559
  ..._src_core.HOST_PATHS,
1513
1560
  ..._src_core.CANON_PATHS,
1514
1561
  ..._src_core.REFERENCE_PATHS
1515
- ]) {
1562
+ ].map((path) => {
1516
1563
  const full = resolveContainedPath(source, path);
1517
1564
  if (full === void 0) throw new _src_core.ScaffoldError("INVALID", `Vendored path leaves its checkout at ${path}`, {
1518
1565
  checkout: source,
1519
1566
  path
1520
1567
  });
1521
- if (isPhysicalFile(full)) {
1522
- vendored.push(path);
1523
- continue;
1524
- }
1525
- if (!isPhysicalDirectory(full)) {
1526
- if (!_src_core.CANON_PATHS.includes(path)) missing.push(path);
1527
- continue;
1528
- }
1529
- roots.push(path);
1530
- for (const nested of listDirectories(full)) {
1531
- const rooted = `${path}/${nested}`;
1532
- if (!matchesSensitivePath(rooted)) roots.push(rooted);
1533
- }
1534
- for (const name of listFiles(full)) {
1535
- const destination = `${path}/${name}`;
1536
- if (!matchesSensitivePath(destination)) vendored.push(destination);
1537
- }
1538
- }
1568
+ if (isPhysicalFile(full)) return {
1569
+ vendored: [path],
1570
+ roots: [],
1571
+ missing: []
1572
+ };
1573
+ if (!isPhysicalDirectory(full)) return {
1574
+ vendored: [],
1575
+ roots: [],
1576
+ missing: _src_core.CANON_PATHS.includes(path) ? [] : [path]
1577
+ };
1578
+ const nested = listDirectories(full);
1579
+ return {
1580
+ vendored: listFiles(full).map((name) => `${path}/${name}`).filter((destination) => !matchesSensitivePath(destination)),
1581
+ roots: [path, ...nested.map((name) => `${path}/${name}`).filter((rooted) => !matchesSensitivePath(rooted))],
1582
+ missing: []
1583
+ };
1584
+ });
1585
+ const vendored = reads.flatMap((read) => read.vendored);
1586
+ const roots = reads.flatMap((read) => read.roots).sort();
1587
+ const missing = reads.flatMap((read) => read.missing);
1539
1588
  if (missing.length > 0) throw new _src_core.ScaffoldError("TARGET", "The checkout does not carry every vendored path", {
1540
1589
  checkout: source,
1541
1590
  missing
@@ -1555,9 +1604,8 @@ function stageHost(checkout, host, options) {
1555
1604
  path
1556
1605
  });
1557
1606
  }
1558
- const stored = /* @__PURE__ */ new Set([MANIFEST_NAME]);
1559
- const candidates = [];
1560
- for (const destination of vendored) {
1607
+ const storages = vendored.map((destination) => pathToStorage(destination));
1608
+ const candidates = vendored.map((destination, index) => {
1561
1609
  const full = resolveContainedPath(source, destination);
1562
1610
  if (full === void 0) throw new _src_core.ScaffoldError("INVALID", `Vendored path leaves its checkout at ${destination}`, {
1563
1611
  checkout: source,
@@ -1569,16 +1617,13 @@ function stageHost(checkout, host, options) {
1569
1617
  path: destination,
1570
1618
  limit: _src_core.MAX_ARTIFACT_BYTES
1571
1619
  });
1572
- if (stored.has(entry.storage)) throw new _src_core.ScaffoldError("TARGET", `Two vendored paths claim the storage name ${entry.storage}`, {
1620
+ if (entry.storage === "manifest.json" || storages.indexOf(entry.storage) < index) throw new _src_core.ScaffoldError("TARGET", `Two vendored paths claim the storage name ${entry.storage}`, {
1573
1621
  checkout: source,
1574
1622
  path: destination,
1575
1623
  storage: entry.storage
1576
1624
  });
1577
- stored.add(entry.storage);
1578
- candidates.push(entry);
1579
- }
1580
- candidates.sort((first, second) => first.storage < second.storage ? -1 : 1);
1581
- roots.sort();
1625
+ return entry;
1626
+ }).sort((first, second) => first.storage < second.storage ? -1 : 1);
1582
1627
  const baseline = resolveContainedPath(source, options?.inventory ?? _src_core.HOST_INVENTORY_PATH);
1583
1628
  if (baseline === void 0) throw new _src_core.ScaffoldError("INVALID", "Surface inventory leaves its checkout", {
1584
1629
  checkout: source,
@@ -1598,8 +1643,7 @@ function stageHost(checkout, host, options) {
1598
1643
  host: root,
1599
1644
  ...established.success ? {} : { error: established.error }
1600
1645
  });
1601
- const entries = [];
1602
- for (const entry of candidates) {
1646
+ const entries = candidates.map((entry) => {
1603
1647
  const origin = resolveContainedPath(source, entry.destination);
1604
1648
  const destination = resolveContainedPath(root, entry.storage);
1605
1649
  if (origin === void 0 || destination === void 0) throw new _src_core.ScaffoldError("INVALID", `Vendored path leaves its root at ${entry.destination}`, {
@@ -1623,17 +1667,16 @@ function stageHost(checkout, host, options) {
1623
1667
  host: root,
1624
1668
  storage: entry.storage
1625
1669
  });
1626
- entries.push({
1670
+ return {
1627
1671
  ...entry,
1628
1672
  digest
1629
- });
1630
- }
1673
+ };
1674
+ });
1631
1675
  const collisions = readSurfaceCollisions((0, node_path.join)(root, "guides"));
1632
- const growth = [];
1633
- if (published !== void 0) for (const [name, owners] of collisions) {
1676
+ const growth = published === void 0 ? [] : [...collisions].flatMap(([name, owners]) => {
1634
1677
  const record = published.get(name);
1635
- if (!(record !== void 0 && owners.every((owner) => record.includes(owner)))) growth.push(`${name} staged (${owners.join(", ")}), recorded (${record?.join(", ") ?? "absent"})`);
1636
- }
1678
+ return record !== void 0 && owners.every((owner) => record.includes(owner)) ? [] : [`${name} staged (${owners.join(", ")}), recorded (${record?.join(", ") ?? "absent"})`];
1679
+ });
1637
1680
  if (growth.length > 0) throw new _src_core.ScaffoldError("TARGET", `Staged Surface collisions differ from the inventory: ${growth.join("; ")}`, {
1638
1681
  checkout: source,
1639
1682
  host: root,
@@ -1693,26 +1736,19 @@ function readSurfaceCollisions(root) {
1693
1736
  error: loaded.error
1694
1737
  });
1695
1738
  const guide = loaded.value;
1696
- const owners = /* @__PURE__ */ new Map();
1697
- for (const path of listFiles(root)) {
1698
- if (path.includes("/") || (0, node_path.extname)(path) !== ".md" || path === "README.md") continue;
1739
+ const claims = listFiles(root).filter((path) => !path.includes("/") && (0, node_path.extname)(path) === ".md" && path !== "README.md").flatMap((path) => {
1699
1740
  const text = readFileText(root, path);
1700
1741
  if (text === void 0) throw new _src_core.ScaffoldError("TARGET", `Surface guide cannot be read at ${path}`, {
1701
1742
  root,
1702
1743
  path
1703
1744
  });
1704
- for (const symbol of guide.createGuide(text).surface()) {
1705
- const claimed = owners.get(symbol.name) ?? /* @__PURE__ */ new Set();
1706
- claimed.add((0, node_path.basename)(path, ".md"));
1707
- owners.set(symbol.name, claimed);
1708
- }
1709
- }
1710
- const collisions = /* @__PURE__ */ new Map();
1711
- for (const name of [...owners.keys()].sort()) {
1712
- const claimed = owners.get(name);
1713
- if (claimed !== void 0 && claimed.size > 1) collisions.set(name, [...claimed].sort());
1714
- }
1715
- return collisions;
1745
+ return guide.createGuide(text).surface().map((symbol) => [symbol.name, (0, node_path.basename)(path, ".md")]);
1746
+ });
1747
+ const grouped = Map.groupBy(claims, ([name]) => name);
1748
+ return new Map([...grouped.keys()].sort().flatMap((name) => {
1749
+ const owners = [...new Set((grouped.get(name) ?? []).map(([, owner]) => owner))];
1750
+ return owners.length > 1 ? [[name, owners.sort()]] : [];
1751
+ }));
1716
1752
  }
1717
1753
  /**
1718
1754
  * Reads the Surface collision baseline from a committed inventory.
@@ -2462,17 +2498,15 @@ var WriteTransaction = class {
2462
2498
  paths
2463
2499
  });
2464
2500
  this.#target = (0, node_path.resolve)(target);
2465
- const expectations = /* @__PURE__ */ new Map();
2466
- for (const path of paths) {
2501
+ this.#expectations = new Map(Array.from(paths, (path) => {
2467
2502
  const expectation = readExpectation(this.#resolve(this.#target, path));
2468
2503
  if (expectation === void 0) throw new _src_core.ScaffoldError("TARGET", `The destination at ${path} is a shape this package will not write over.`, {
2469
2504
  target: this.#target,
2470
2505
  path
2471
2506
  });
2472
- expectations.set(path, expectation);
2473
- }
2474
- this.#expectations = expectations;
2475
- const destinations = new Set([...expectations.values()].map((expectation) => expectation.path));
2507
+ return [path, expectation];
2508
+ }));
2509
+ const destinations = new Set([...this.#expectations.values()].map((expectation) => expectation.path));
2476
2510
  for (const precondition of preconditions ?? []) {
2477
2511
  if (!destinations.has(precondition.path)) throw new _src_core.ScaffoldError("INVALID", `The precondition at ${precondition.path} names no destination of this transaction.`, {
2478
2512
  target: this.#target,
@@ -2661,8 +2695,14 @@ var WriteTransaction = class {
2661
2695
  const taken = [];
2662
2696
  const applied = (0, _orkestrel_contract.attempt)(() => {
2663
2697
  this.#preflight();
2664
- for (const path of this.#staged) this.#promote(path, promoted);
2665
- for (const path of this.#taken) this.#take(path, taken);
2698
+ for (const path of this.#staged) {
2699
+ this.#promote(path);
2700
+ promoted.push(path);
2701
+ }
2702
+ for (const path of this.#taken) {
2703
+ this.#take(path);
2704
+ taken.push(path);
2705
+ }
2666
2706
  });
2667
2707
  this.#open = false;
2668
2708
  if (!applied.success) {
@@ -2719,8 +2759,7 @@ var WriteTransaction = class {
2719
2759
  path
2720
2760
  });
2721
2761
  const base = (0, node_path.resolve)(root);
2722
- let ancestor = (0, node_path.dirname)(destination);
2723
- for (let depth = 0; depth <= 64; depth += 1) {
2762
+ for (const ancestor of listAncestors(destination, 66).slice(1)) {
2724
2763
  const state = readExpectation(ancestor);
2725
2764
  if (state === void 0 || state.shape === "file") throw new _src_core.ScaffoldError("WRITE", `The path ${path} passes through a link or a file.`, {
2726
2765
  root,
@@ -2728,9 +2767,6 @@ var WriteTransaction = class {
2728
2767
  ancestor
2729
2768
  });
2730
2769
  if (ancestor === base) return destination;
2731
- const parent = (0, node_path.dirname)(ancestor);
2732
- if (parent === ancestor) break;
2733
- ancestor = parent;
2734
2770
  }
2735
2771
  throw new _src_core.ScaffoldError("INVALID", `The path ${path} does not resolve beneath its root.`, {
2736
2772
  root,
@@ -2739,41 +2775,44 @@ var WriteTransaction = class {
2739
2775
  }
2740
2776
  #establish(path) {
2741
2777
  const destination = (0, node_path.resolve)(path);
2742
- const missing = [];
2743
- let current = destination;
2744
- let anchor = readAnchor(current);
2745
- for (let depth = 0; anchor === void 0 && depth <= 64; depth += 1) {
2746
- const state = readExpectation(current);
2747
- if (state === void 0 || state.shape !== "absent") throw new _src_core.ScaffoldError("WRITE", `The directory at ${current} is not a physical directory.`, { path: destination });
2748
- missing.push(current);
2749
- const parent = (0, node_path.dirname)(current);
2750
- if (parent === current) throw new _src_core.ScaffoldError("WRITE", `The directory at ${destination} has no existing ancestor.`, { path: destination });
2751
- current = parent;
2752
- anchor = readAnchor(current);
2753
- }
2754
- if (anchor === void 0) throw new _src_core.ScaffoldError("WRITE", `The directory at ${destination} is nested past the ceiling.`, {
2755
- path: destination,
2756
- limit: 64
2757
- });
2778
+ const { anchor: located, missing } = this.#locate(destination);
2758
2779
  const created = [];
2759
2780
  for (const segment of [...missing].reverse()) {
2781
+ const anchor = created.at(-1) ?? located;
2760
2782
  if (!matchesAnchor(anchor)) throw new _src_core.ScaffoldError("WRITE", `The directory at ${anchor.path} changed while writing.`, {
2761
2783
  path: destination,
2762
2784
  ancestor: anchor.path
2763
2785
  });
2764
2786
  (0, node_fs.mkdirSync)(segment);
2765
- this.#created.push(segment);
2766
2787
  const established = readAnchor(segment);
2788
+ this.#created.push(established ?? segment);
2767
2789
  if (established === void 0) throw new _src_core.ScaffoldError("WRITE", `The directory at ${segment} changed while writing.`, { path: destination });
2768
- anchor = established;
2769
- this.#created[this.#created.length - 1] = established;
2770
2790
  created.push(established);
2771
2791
  }
2772
2792
  return {
2773
- anchor,
2793
+ anchor: created.at(-1) ?? located,
2774
2794
  created
2775
2795
  };
2776
2796
  }
2797
+ #locate(destination) {
2798
+ const missing = [];
2799
+ for (const [depth, current] of listAncestors(destination, 66).entries()) {
2800
+ const anchor = readAnchor(current);
2801
+ if (anchor !== void 0) return {
2802
+ anchor,
2803
+ missing
2804
+ };
2805
+ if (depth > 64) break;
2806
+ const state = readExpectation(current);
2807
+ if (state === void 0 || state.shape !== "absent") throw new _src_core.ScaffoldError("WRITE", `The directory at ${current} is not a physical directory.`, { path: destination });
2808
+ missing.push(current);
2809
+ if ((0, node_path.dirname)(current) === current) throw new _src_core.ScaffoldError("WRITE", `The directory at ${destination} has no existing ancestor.`, { path: destination });
2810
+ }
2811
+ throw new _src_core.ScaffoldError("WRITE", `The directory at ${destination} is nested past the ceiling.`, {
2812
+ path: destination,
2813
+ limit: 64
2814
+ });
2815
+ }
2777
2816
  #preflight() {
2778
2817
  for (const anchor of this.#created) {
2779
2818
  if ((0, _orkestrel_contract.isString)(anchor)) throw new _src_core.ScaffoldError("WRITE", `The directory at ${anchor} changed while writing.`, {
@@ -2794,7 +2833,7 @@ var WriteTransaction = class {
2794
2833
  path
2795
2834
  });
2796
2835
  }
2797
- #promote(path, promoted) {
2836
+ #promote(path) {
2798
2837
  const expectation = this.#expectation(path);
2799
2838
  if (!matchesExpectation(expectation)) throw new _src_core.ScaffoldError("WRITE", `The destination at ${path} moved while writing.`, { path });
2800
2839
  const staged = this.#resolve(this.#stage, path);
@@ -2805,23 +2844,19 @@ var WriteTransaction = class {
2805
2844
  (0, node_fs.linkSync)(expectation.path, backup);
2806
2845
  }
2807
2846
  (0, node_fs.renameSync)(staged, expectation.path);
2808
- promoted.push(path);
2809
2847
  }
2810
- #take(path, taken) {
2848
+ #take(path) {
2811
2849
  const expectation = this.#expectation(path);
2812
2850
  if (!matchesExpectation(expectation)) throw new _src_core.ScaffoldError("WRITE", `The destination at ${path} moved while writing.`, { path });
2813
2851
  const backup = this.#resolve(this.#backup, path);
2814
2852
  (0, node_fs.mkdirSync)((0, node_path.dirname)(backup), { recursive: true });
2815
2853
  (0, node_fs.renameSync)(expectation.path, backup);
2816
- taken.push(path);
2817
2854
  }
2818
2855
  #recover(promoted, taken) {
2819
- const residue = [];
2820
- for (const path of [...taken].reverse()) {
2856
+ const restoring = [...[...taken].reverse().flatMap((path) => {
2821
2857
  const restored = (0, _orkestrel_contract.attempt)(() => (0, node_fs.renameSync)(this.#resolve(this.#backup, path), this.#expectation(path).path));
2822
- if (!restored.success) residue.push(restored.error);
2823
- }
2824
- for (const path of [...promoted].reverse()) {
2858
+ return restored.success ? [] : [restored.error];
2859
+ }), ...[...promoted].reverse().flatMap((path) => {
2825
2860
  const expectation = this.#expectation(path);
2826
2861
  const restored = (0, _orkestrel_contract.attempt)(() => {
2827
2862
  if (expectation.shape === "absent") {
@@ -2830,21 +2865,23 @@ var WriteTransaction = class {
2830
2865
  }
2831
2866
  (0, node_fs.renameSync)(this.#resolve(this.#backup, path), expectation.path);
2832
2867
  });
2833
- if (!restored.success) residue.push(restored.error);
2834
- }
2835
- if (residue.length === 0) {
2836
- const cleared = (0, _orkestrel_contract.attempt)(() => (0, node_fs.rmSync)(this.#root, {
2837
- recursive: true,
2838
- force: true
2839
- }));
2840
- if (!cleared.success) residue.push(cleared.error);
2841
- }
2842
- for (const created of [...this.#created].reverse()) {
2868
+ return restored.success ? [] : [restored.error];
2869
+ })];
2870
+ const cleared = restoring.length === 0 ? (0, _orkestrel_contract.attempt)(() => (0, node_fs.rmSync)(this.#root, {
2871
+ recursive: true,
2872
+ force: true
2873
+ })) : void 0;
2874
+ const clearing = cleared === void 0 || cleared.success ? [] : [cleared.error];
2875
+ const removing = [...this.#created].reverse().flatMap((created) => {
2843
2876
  const path = (0, _orkestrel_contract.isString)(created) ? created : created.path;
2844
2877
  const removed = (0, _orkestrel_contract.attempt)(() => (0, node_fs.rmdirSync)(path));
2845
- if (!removed.success && !matchesMissingPath(removed.error)) residue.push(removed.error);
2846
- }
2847
- return residue;
2878
+ return !removed.success && !matchesMissingPath(removed.error) ? [removed.error] : [];
2879
+ });
2880
+ return [
2881
+ ...restoring,
2882
+ ...clearing,
2883
+ ...removing
2884
+ ];
2848
2885
  }
2849
2886
  #stagePath(path) {
2850
2887
  const staged = this.#resolve(this.#stage, path);
@@ -3071,18 +3108,17 @@ var Materializer = class {
3071
3108
  const derived = this.#derive(accepted, directory, hydrated);
3072
3109
  this.#reconfirm(derived.findings, preview.findings, directory);
3073
3110
  const drifted = new Map(derived.findings.map((finding) => [finding.path, finding.drift]));
3074
- const writes = [];
3075
- const skipped = [];
3076
- const preconditions = [];
3077
- for (const artifact of hydrated.artifacts) {
3078
- const drift = drifted.get(artifact.path);
3079
- if (drift !== "missing" && drift !== "stale") {
3080
- skipped.push(artifact.path);
3081
- continue;
3082
- }
3083
- preconditions.push(this.#bind(directory, artifact.path, drift === "missing"));
3084
- writes.push(artifact);
3085
- }
3111
+ const judged = hydrated.artifacts.map((artifact) => ({
3112
+ artifact,
3113
+ drift: drifted.get(artifact.path)
3114
+ }));
3115
+ const skipped = judged.flatMap(({ artifact, drift }) => drift === "missing" || drift === "stale" ? [] : [artifact.path]);
3116
+ const selected = judged.flatMap(({ artifact, drift }) => drift === "missing" || drift === "stale" ? [{
3117
+ artifact,
3118
+ missing: drift === "missing"
3119
+ }] : []);
3120
+ const preconditions = selected.map(({ artifact, missing }) => this.#bind(directory, artifact.path, missing));
3121
+ const writes = selected.map(({ artifact }) => artifact);
3086
3122
  return this.#apply(directory, writes, [], skipped, preconditions);
3087
3123
  }
3088
3124
  /**
@@ -3107,15 +3143,15 @@ var Materializer = class {
3107
3143
  const writes = [];
3108
3144
  const skipped = [];
3109
3145
  const preconditions = [];
3110
- let remaining = _src_core.MAX_TOTAL_ARTIFACT_BYTES;
3146
+ const spent = [];
3111
3147
  for (const fetched of accepted) {
3112
- const hex = fetched.lookup === "found" ? (0, _src_core.contentToHex)(fetched.content) : fetched.observed === void 0 ? this.#reference(fetched.path, remaining) : void 0;
3148
+ const hex = fetched.lookup === "found" ? (0, _src_core.contentToHex)(fetched.content) : fetched.observed === void 0 ? this.#reference(fetched.path, _src_core.MAX_TOTAL_ARTIFACT_BYTES - (0, _src_core.computeTotal)(spent)) : void 0;
3113
3149
  if (hex === void 0 || fetched.observed === hex) {
3114
3150
  skipped.push(fetched.path);
3115
3151
  continue;
3116
3152
  }
3117
- remaining -= hex.length / 2;
3118
- if (remaining < 0) throw this.#error("TARGET", "The guide mirrors exceed the total artifact byte limit.");
3153
+ spent.push(hex.length / 2);
3154
+ if ((0, _src_core.computeTotal)(spent) > _src_core.MAX_TOTAL_ARTIFACT_BYTES) throw this.#error("TARGET", "The guide mirrors exceed the total artifact byte limit.");
3119
3155
  const current = readFileHex(directory, fetched.path);
3120
3156
  if (current !== fetched.observed) throw this.#error("TARGET", `The mirror at ${fetched.path} moved since it was fetched.`, {
3121
3157
  target: directory,
@@ -3248,18 +3284,10 @@ var Materializer = class {
3248
3284
  const derived = this.#derive(accepted, directory);
3249
3285
  this.#reconfirmCandidates(derived.findings, preview.findings, directory);
3250
3286
  const tracked = new Set(state.tracked);
3251
- const removals = [];
3252
- const skipped = [];
3253
- for (const finding of derived.findings) {
3254
- if (finding.drift !== "foreign") continue;
3255
- if (!tracked.has(finding.path) || matchesProtectedPath(finding.path)) {
3256
- skipped.push(finding.path);
3257
- continue;
3258
- }
3259
- removals.push(finding.path);
3260
- }
3261
- const preconditions = [];
3262
- for (const path of removals) preconditions.push(this.#bind(directory, path, false));
3287
+ const foreign = derived.findings.filter((finding) => finding.drift === "foreign").map((finding) => finding.path);
3288
+ const skipped = foreign.filter((path) => !tracked.has(path) || matchesProtectedPath(path));
3289
+ const removals = foreign.filter((path) => tracked.has(path) && !matchesProtectedPath(path));
3290
+ const preconditions = removals.map((path) => this.#bind(directory, path, false));
3263
3291
  return this.#purge(directory, removals, skipped, preconditions);
3264
3292
  }
3265
3293
  /**
@@ -3319,49 +3347,51 @@ var Materializer = class {
3319
3347
  if (this.#entries.size !== manifest.entries.length) throw this.#error("TARGET", "The vendored host manifest maps two files to one destination.", { host: root });
3320
3348
  }
3321
3349
  #hydrate(plan) {
3322
- const artifacts = [];
3323
- let remaining = _src_core.MAX_TOTAL_ARTIFACT_BYTES;
3350
+ const groups = [];
3351
+ const spent = [];
3324
3352
  for (const artifact of plan.artifacts) {
3325
3353
  if (artifact.origin !== "host") {
3326
- remaining -= (0, _src_core.computeBytes)(artifact.content);
3327
- artifacts.push(artifact);
3354
+ spent.push((0, _src_core.computeBytes)(artifact.content));
3355
+ groups.push([artifact]);
3328
3356
  continue;
3329
3357
  }
3330
- const expanded = this.#expand(artifact, remaining);
3331
- for (const one of expanded) remaining -= one.origin === "host" ? (one.hex?.length ?? 0) / 2 : (0, _src_core.computeBytes)(one.content);
3332
- artifacts.push(...expanded);
3358
+ const expanded = this.#expand(artifact, _src_core.MAX_TOTAL_ARTIFACT_BYTES - (0, _src_core.computeTotal)(spent));
3359
+ spent.push((0, _src_core.computeTotal)(expanded.map((one) => one.origin === "host" ? (one.hex?.length ?? 0) / 2 : (0, _src_core.computeBytes)(one.content))));
3360
+ groups.push(expanded);
3333
3361
  }
3334
- if (remaining < 0) throw this.#error("TARGET", "The hydrated plan retains more bytes than one plan may.", {
3362
+ if ((0, _src_core.computeTotal)(spent) > _src_core.MAX_TOTAL_ARTIFACT_BYTES) throw this.#error("TARGET", "The hydrated plan retains more bytes than one plan may.", {
3335
3363
  host: this.#root,
3336
3364
  limit: _src_core.MAX_TOTAL_ARTIFACT_BYTES
3337
3365
  });
3338
3366
  return {
3339
3367
  blueprint: plan.blueprint,
3340
3368
  groups: plan.groups,
3341
- artifacts
3369
+ artifacts: groups.flat()
3342
3370
  };
3343
3371
  }
3344
3372
  #derive(plan, target, hydrated = this.#hydrate(plan)) {
3345
- const paths = new Set(hydrated.artifacts.map((artifact) => artifact.path));
3346
- for (const root of this.#roots(plan)) {
3347
- const directory = resolveContainedPath(target, root);
3348
- if (directory === void 0) throw this.#error("TARGET", `The owned root at ${root} leaves its target.`, {
3349
- target,
3350
- path: root
3351
- });
3352
- for (const name of listFiles(directory)) paths.add(`${root}/${name}`);
3353
- }
3354
- for (const path of listCanonPaths(target, plan.groups)) paths.add(path);
3373
+ const paths = /* @__PURE__ */ new Set([
3374
+ ...hydrated.artifacts.map((artifact) => artifact.path),
3375
+ ...this.#roots(plan).flatMap((root) => {
3376
+ const directory = resolveContainedPath(target, root);
3377
+ if (directory === void 0) throw this.#error("TARGET", `The owned root at ${root} leaves its target.`, {
3378
+ target,
3379
+ path: root
3380
+ });
3381
+ return listFiles(directory).map((name) => `${root}/${name}`);
3382
+ }),
3383
+ ...listCanonPaths(target, plan.groups)
3384
+ ]);
3355
3385
  const questions = [];
3356
3386
  if (plan.groups.includes("guides")) {
3357
3387
  const directory = resolveContainedPath(target, "guides");
3358
- let remaining = _src_core.MAX_TOTAL_ARTIFACT_BYTES;
3388
+ const spent = [];
3359
3389
  for (const file of directory === void 0 ? [] : listFiles(directory)) {
3360
3390
  const path = `guides/${file}`;
3361
3391
  if (file.includes("/") || file === "README.md" || !file.endsWith(".md") || path === (0, _src_core.nameToGuide)(plan.blueprint.name)) continue;
3362
- const hosted = this.#reference(path, remaining);
3392
+ const hosted = this.#reference(path, _src_core.MAX_TOTAL_ARTIFACT_BYTES - (0, _src_core.computeTotal)(spent));
3363
3393
  if (hosted === void 0) continue;
3364
- remaining -= hosted.length / 2;
3394
+ spent.push(hosted.length / 2);
3365
3395
  const present = readFileHex(target, path);
3366
3396
  if (present !== void 0 && present !== hosted) questions.push({
3367
3397
  field: "guides",
@@ -3386,20 +3416,15 @@ var Materializer = class {
3386
3416
  return readFileHex(this.#root, path, Math.max(0, Math.min(_src_core.MAX_ARTIFACT_BYTES, budget)));
3387
3417
  }
3388
3418
  #roots(plan) {
3389
- const roots = /* @__PURE__ */ new Set();
3390
- for (const artifact of plan.artifacts) {
3391
- if (artifact.origin !== "host") continue;
3419
+ return [...new Set(plan.artifacts.flatMap((artifact) => {
3420
+ if (artifact.origin !== "host") return [];
3392
3421
  const source = artifact.source ?? artifact.path;
3393
- if (this.#manifest?.roots.includes(source) === true) {
3394
- roots.add(artifact.path);
3395
- continue;
3396
- }
3397
- if (this.#manifest !== void 0) continue;
3422
+ if (this.#manifest?.roots.includes(source) === true) return [artifact.path];
3423
+ if (this.#manifest !== void 0) return [];
3398
3424
  const root = this.#root;
3399
3425
  const directory = root === void 0 ? void 0 : resolveContainedPath(root, source);
3400
- if (directory !== void 0 && isPhysicalDirectory(directory)) roots.add(artifact.path);
3401
- }
3402
- return [...roots];
3426
+ return directory !== void 0 && isPhysicalDirectory(directory) ? [artifact.path] : [];
3427
+ }))];
3403
3428
  }
3404
3429
  #expand(artifact, remaining) {
3405
3430
  const manifest = this.#manifest;
@@ -3412,15 +3437,15 @@ var Materializer = class {
3412
3437
  source
3413
3438
  });
3414
3439
  const expanded = [];
3415
- let budget = remaining;
3440
+ const spent = [];
3416
3441
  for (const entry of matched) {
3417
3442
  const path = this.#remap(artifact, entry.destination);
3418
3443
  if ((0, _src_core.isRetainedPath)(path)) {
3419
3444
  expanded.push(this.#presence(artifact, path, entry.destination));
3420
3445
  continue;
3421
3446
  }
3422
- const hex = this.#read(entry, budget);
3423
- budget -= hex.length / 2;
3447
+ const hex = this.#read(entry, remaining - (0, _src_core.computeTotal)(spent));
3448
+ spent.push(hex.length / 2);
3424
3449
  expanded.push(this.#hydrated(artifact, path, entry.destination, hex));
3425
3450
  }
3426
3451
  return expanded;
@@ -3441,7 +3466,7 @@ var Materializer = class {
3441
3466
  source
3442
3467
  });
3443
3468
  const expanded = [];
3444
- let budget = remaining;
3469
+ const spent = [];
3445
3470
  for (const name of listFiles(full)) {
3446
3471
  const path = `${artifact.path}/${name}`;
3447
3472
  const destination = `${source}/${name}`;
@@ -3449,8 +3474,8 @@ var Materializer = class {
3449
3474
  expanded.push(this.#presence(artifact, path, destination));
3450
3475
  continue;
3451
3476
  }
3452
- const hex = this.#readRoot(destination, budget);
3453
- budget -= hex.length / 2;
3477
+ const hex = this.#readRoot(destination, remaining - (0, _src_core.computeTotal)(spent));
3478
+ spent.push(hex.length / 2);
3454
3479
  expanded.push(this.#hydrated(artifact, path, destination, hex));
3455
3480
  }
3456
3481
  return expanded;
@@ -3458,16 +3483,15 @@ var Materializer = class {
3458
3483
  #empty(plan) {
3459
3484
  const manifest = this.#manifest;
3460
3485
  if (manifest === void 0) return [];
3461
- const directories = /* @__PURE__ */ new Set();
3462
- for (const artifact of plan.artifacts) {
3463
- if (artifact.origin !== "host") continue;
3486
+ const directories = plan.artifacts.flatMap((artifact) => {
3487
+ if (artifact.origin !== "host") return [];
3464
3488
  const source = artifact.source ?? artifact.path;
3465
- for (const root of manifest.roots) {
3466
- if (root !== source && !root.startsWith(`${source}/`)) continue;
3467
- if (!manifest.entries.some((entry) => entry.destination === root || entry.destination.startsWith(`${root}/`))) directories.add(this.#remap(artifact, root));
3468
- }
3469
- }
3470
- return [...directories].sort();
3489
+ return manifest.roots.flatMap((root) => {
3490
+ if (root !== source && !root.startsWith(`${source}/`)) return [];
3491
+ return manifest.entries.some((entry) => entry.destination === root || entry.destination.startsWith(`${root}/`)) ? [] : [this.#remap(artifact, root)];
3492
+ });
3493
+ });
3494
+ return [...new Set(directories)].sort();
3471
3495
  }
3472
3496
  #remap(artifact, destination) {
3473
3497
  const source = artifact.source ?? artifact.path;
@@ -3664,11 +3688,7 @@ var Materializer = class {
3664
3688
  #fill(writes) {
3665
3689
  const value = this.#value;
3666
3690
  if (value === void 0) return void 0;
3667
- const destinations = /* @__PURE__ */ new Set();
3668
- for (const artifact of writes) {
3669
- if (artifact.origin !== "host") continue;
3670
- destinations.add(artifact.source ?? artifact.path);
3671
- }
3691
+ const destinations = new Set(writes.flatMap((artifact) => artifact.origin === "host" ? [artifact.source ?? artifact.path] : []));
3672
3692
  if (destinations.size === 0) return void 0;
3673
3693
  const opened = (0, _orkestrel_contract.attempt)(() => (0, node_fs.mkdtempSync)((0, node_path.join)((0, node_os.tmpdir)(), "orkestrel-scaffold-fill-")));
3674
3694
  if (!opened.success) throw this.#error("WRITE", "The supplied host could not be filled into a private root.", { error: opened.error });
@@ -3738,8 +3758,7 @@ var Materializer = class {
3738
3758
  }
3739
3759
  #recatalog(entries) {
3740
3760
  const layers = (0, _src_core.catalogToLayers)(entries);
3741
- const placed = /* @__PURE__ */ new Map();
3742
- for (const [index, layer] of layers.entries()) for (const name of layer) placed.set(name, index);
3761
+ const placed = new Map(layers.flatMap((layer, index) => layer.map((name) => [name, index])));
3743
3762
  const rows = entries.map((entry) => {
3744
3763
  if (entry.lookup !== "found") return [
3745
3764
  `\`${entry.name}\``,
@@ -3766,11 +3785,7 @@ var Materializer = class {
3766
3785
  "Runtime dependencies",
3767
3786
  "Peer dependencies"
3768
3787
  ];
3769
- const widths = headers.map((header, column) => {
3770
- let width = Math.max(3, header.length);
3771
- for (const row of rows) width = Math.max(width, row[column]?.length ?? 0);
3772
- return width;
3773
- });
3788
+ const widths = headers.map((header, column) => Math.max(3, header.length, ...rows.map((row) => row[column]?.length ?? 0)));
3774
3789
  const table = [
3775
3790
  headers,
3776
3791
  widths.map((width) => "-".repeat(width)),
@@ -3826,6 +3841,66 @@ var Materializer = class {
3826
3841
  }
3827
3842
  };
3828
3843
  //#endregion
3844
+ //#region src/server/ReadAllowance.ts
3845
+ /**
3846
+ * Represents the byte allowance one upstream call spends across every read it makes.
3847
+ *
3848
+ * @remarks
3849
+ * Each call constructs its own allowance from the reader's budget, so concurrent
3850
+ * calls never spend each other's bytes. A read that brings the call exactly to
3851
+ * its budget leaves `remaining` at zero and is accepted; the next request is
3852
+ * refused before it is sent, and a body that passes the budget is refused at the
3853
+ * chunk that overshoots.
3854
+ *
3855
+ * @example
3856
+ * ```ts
3857
+ * import { ReadAllowance } from '@orkestrel/scaffold/server'
3858
+ *
3859
+ * const allowance = new ReadAllowance(1_024)
3860
+ * allowance.spend(1_000)
3861
+ * allowance.remaining // 24
3862
+ * ```
3863
+ */
3864
+ var ReadAllowance = class {
3865
+ #remaining;
3866
+ /**
3867
+ * Constructs an allowance holding the whole budget.
3868
+ *
3869
+ * @param budget - The bytes the call may read in total.
3870
+ * @throws {@link ScaffoldError} coded `INVALID` when `budget` is not a
3871
+ * non-negative safe integer.
3872
+ */
3873
+ constructor(budget) {
3874
+ if (!(0, _orkestrel_contract.isNonNegativeInteger)(budget) || !Number.isSafeInteger(budget)) throw new _src_core.ScaffoldError("INVALID", "The read budget is not a non-negative safe integer.", { field: "budget" });
3875
+ this.#remaining = budget;
3876
+ }
3877
+ /** The bytes the call has left; negative once a read overshoots the budget. */
3878
+ get remaining() {
3879
+ return this.#remaining;
3880
+ }
3881
+ /**
3882
+ * Spends bytes a read consumed from the allowance.
3883
+ *
3884
+ * @param bytes - The decoded bytes the read consumed.
3885
+ * @returns Nothing.
3886
+ * @throws {@link ScaffoldError} coded `INVALID` when `bytes` is not a
3887
+ * non-negative safe integer.
3888
+ *
3889
+ * @example
3890
+ * ```ts
3891
+ * import { ReadAllowance } from '@orkestrel/scaffold/server'
3892
+ *
3893
+ * const allowance = new ReadAllowance(10)
3894
+ * allowance.spend(12)
3895
+ * allowance.remaining // -2
3896
+ * ```
3897
+ */
3898
+ spend(bytes) {
3899
+ if (!(0, _orkestrel_contract.isNonNegativeInteger)(bytes) || !Number.isSafeInteger(bytes)) throw new _src_core.ScaffoldError("INVALID", "The spent bytes are not a non-negative safe integer.", { field: "bytes" });
3900
+ this.#remaining -= bytes;
3901
+ }
3902
+ };
3903
+ //#endregion
3829
3904
  //#region src/server/Upstream.ts
3830
3905
  /**
3831
3906
  * Represents the reading spine: one bounded, unauthenticated, redirect-free request per answer.
@@ -3856,9 +3931,9 @@ var Materializer = class {
3856
3931
  * reader's own abort signal, so {@link Upstream.destroy} cancels what is in
3857
3932
  * flight instead of waiting for it.
3858
3933
  *
3859
- * The allowance is threaded through the private reads as a mutable
3860
- * {@link ReadAllowance} carrier rather than held on the instance, because
3861
- * concurrent calls each own their own budget and must not spend each other's.
3934
+ * Each call constructs its own {@link ReadAllowance} from the reader's budget and passes it
3935
+ * through the private reads rather than holding it on the instance, because concurrent calls
3936
+ * each own a budget and must not spend each other's.
3862
3937
  *
3863
3938
  * @example
3864
3939
  * ```ts
@@ -3951,7 +4026,7 @@ var Upstream = class {
3951
4026
  async lookup(dependencies) {
3952
4027
  this.#assertAlive();
3953
4028
  const accepted = this.#accept(dependencies, isDependencies, "dependencies");
3954
- const allowance = { remaining: this.#budget };
4029
+ const allowance = new ReadAllowance(this.#budget);
3955
4030
  return this.#gather(accepted, (dependency) => this.#release(dependency, allowance));
3956
4031
  }
3957
4032
  /**
@@ -3985,7 +4060,7 @@ var Upstream = class {
3985
4060
  this.#assertAlive();
3986
4061
  const accepted = this.#accept(names, isDependencyNames, "names");
3987
4062
  const observed = this.#accept(current, _src_core.isSnapshot, "current");
3988
- const allowance = { remaining: this.#budget };
4063
+ const allowance = new ReadAllowance(this.#budget);
3989
4064
  return this.#gather(accepted, (name) => this.#mirror(name, observed, allowance));
3990
4065
  }
3991
4066
  /**
@@ -4032,7 +4107,7 @@ var Upstream = class {
4032
4107
  const accepted = this.#accept(paths, isPaths, "paths");
4033
4108
  const observed = this.#accept(current, _src_core.isSnapshot, "current");
4034
4109
  if (accepted.length === 0) return [];
4035
- const allowance = { remaining: this.#budget };
4110
+ const allowance = new ReadAllowance(this.#budget);
4036
4111
  const inventory = await this.#inventory(allowance);
4037
4112
  return this.#gather(accepted, (path) => this.#file(path, inventory, observed, allowance));
4038
4113
  }
@@ -4065,7 +4140,7 @@ var Upstream = class {
4065
4140
  */
4066
4141
  async catalog() {
4067
4142
  this.#assertAlive();
4068
- const allowance = { remaining: this.#budget };
4143
+ const allowance = new ReadAllowance(this.#budget);
4069
4144
  const names = await this.#packages(allowance);
4070
4145
  return this.#gather(names, (name) => this.#entry(name, allowance));
4071
4146
  }
@@ -4234,16 +4309,10 @@ var Upstream = class {
4234
4309
  lookup: "failed",
4235
4310
  note: `the vendored inventory at ${url} does not match its own membership digest`
4236
4311
  };
4237
- const digests = /* @__PURE__ */ new Map();
4238
- const duplicates = /* @__PURE__ */ new Set();
4239
- for (const entry of manifest.entries) {
4240
- if (digests.has(entry.destination)) duplicates.add(entry.destination);
4241
- digests.set(entry.destination, entry.digest);
4242
- }
4243
4312
  return {
4244
4313
  lookup: "found",
4245
- digests,
4246
- duplicates,
4314
+ digests: new Map(manifest.entries.map((entry) => [entry.destination, entry.digest])),
4315
+ duplicates: new Set(manifest.entries.map((entry) => entry.destination).filter((destination, index, destinations) => destinations.indexOf(destination) !== index)),
4247
4316
  note: ""
4248
4317
  };
4249
4318
  }
@@ -4272,18 +4341,10 @@ var Upstream = class {
4272
4341
  if (!(0, _orkestrel_contract.isRecord)(manifest)) return [];
4273
4342
  const declared = manifest[section];
4274
4343
  if (!(0, _orkestrel_contract.isRecord)(declared)) return [];
4275
- const edges = [];
4276
- for (const [name, range] of Object.entries(declared)) {
4277
- if (edges.length >= _src_core.MAX_COLLECTION_ITEMS) break;
4278
- if (!(0, _orkestrel_contract.isString)(range) || range.length === 0 || range.length > _src_core.MAX_RANGE_LENGTH) continue;
4279
- if (_src_core.CONTROL_CHARACTER_PATTERN.test(name) || _src_core.CONTROL_CHARACTER_PATTERN.test(range)) continue;
4280
- if (name.length === 0 || name.length > _src_core.MAX_DEPENDENCY_NAME_LENGTH) continue;
4281
- edges.push({
4282
- name,
4283
- range
4284
- });
4285
- }
4286
- return edges;
4344
+ return Object.entries(declared).flatMap(([name, range]) => !(0, _orkestrel_contract.isString)(range) || range.length === 0 || range.length > _src_core.MAX_RANGE_LENGTH || _src_core.CONTROL_CHARACTER_PATTERN.test(name) || _src_core.CONTROL_CHARACTER_PATTERN.test(range) || name.length === 0 || name.length > _src_core.MAX_DEPENDENCY_NAME_LENGTH ? [] : [{
4345
+ name,
4346
+ range
4347
+ }]).slice(0, _src_core.MAX_COLLECTION_ITEMS);
4287
4348
  }
4288
4349
  async #packages(allowance) {
4289
4350
  const url = `${this.#registryBase}/-/org/${ORKESTREL_SCOPE}/package`;
@@ -4312,11 +4373,7 @@ var Upstream = class {
4312
4373
  const parsed = (0, _orkestrel_contract.parseJSON)(content);
4313
4374
  if (!(0, _orkestrel_contract.isRecord)(parsed)) return void 0;
4314
4375
  const versions = parsed.versions;
4315
- let selected;
4316
- if ((0, _orkestrel_contract.isRecord)(versions)) for (const version of Object.keys(versions)) {
4317
- if (!this.#admits(range, version)) continue;
4318
- if (selected === void 0 || (0, _src_core.compareVersions)(version, selected) > 0) selected = version;
4319
- }
4376
+ const selected = (0, _orkestrel_contract.isRecord)(versions) ? Object.keys(versions).filter((version) => this.#admits(range, version)).reduce((highest, version) => highest === void 0 || (0, _src_core.compareVersions)(version, highest) > 0 ? version : highest, void 0) : void 0;
4320
4377
  if (selected !== void 0) return selected;
4321
4378
  const latest = this.#latest(content);
4322
4379
  return latest !== void 0 && this.#admits(range, latest) ? latest : void 0;
@@ -4344,14 +4401,12 @@ var Upstream = class {
4344
4401
  #encode(path) {
4345
4402
  return path.split("/").map((segment) => encodeURIComponent(segment)).join("/");
4346
4403
  }
4347
- async #readWithRetries(url, timeout, allowance, accept, binary = false) {
4348
- let note = "";
4349
- for (let round = 0; round <= this.#retries; round += 1) {
4350
- this.#assertAlive();
4351
- const outcome = binary ? await this.#request(url, timeout, allowance, accept, true) : await this.#request(url, timeout, allowance, accept);
4352
- if (outcome.lookup !== "failed") return outcome;
4353
- note = outcome.note;
4354
- }
4404
+ async #readWithRetries(url, timeout, allowance, accept, binary = false, attempt = 0) {
4405
+ this.#assertAlive();
4406
+ const outcome = binary ? await this.#request(url, timeout, allowance, accept, true) : await this.#request(url, timeout, allowance, accept);
4407
+ if (outcome.lookup !== "failed") return outcome;
4408
+ if (attempt < this.#retries) return binary ? this.#readWithRetries(url, timeout, allowance, accept, true, attempt + 1) : this.#readWithRetries(url, timeout, allowance, accept, false, attempt + 1);
4409
+ const note = outcome.note;
4355
4410
  this.#error("FETCH", `The upstream read at ${url} produced no answer.`, {
4356
4411
  url,
4357
4412
  note
@@ -4455,14 +4510,14 @@ var Upstream = class {
4455
4510
  const reader = body.getReader();
4456
4511
  const decoder = binary ? void 0 : new TextDecoder("utf-8", { fatal: true });
4457
4512
  const chunks = [];
4458
- let total = 0;
4513
+ const sizes = [];
4459
4514
  try {
4460
4515
  for (;;) {
4461
4516
  const chunk = await reader.read();
4462
4517
  if (chunk.done) break;
4463
- total += chunk.value.byteLength;
4464
- allowance.remaining -= chunk.value.byteLength;
4465
- if (total > this.#limit) {
4518
+ sizes.push(chunk.value.byteLength);
4519
+ allowance.spend(chunk.value.byteLength);
4520
+ if ((0, _src_core.computeTotal)(sizes) > this.#limit) {
4466
4521
  await reader.cancel();
4467
4522
  const note = `the response passed the ${String(this.#limit)}-byte response limit`;
4468
4523
  return binary ? {
@@ -4515,31 +4570,28 @@ var Upstream = class {
4515
4570
  return code === void 0 ? message : `${message} (${code})`;
4516
4571
  }
4517
4572
  async #gather(items, run) {
4518
- const results = [];
4519
- const state = {
4520
- cursor: 0,
4521
- failure: void 0
4522
- };
4523
- const workers = Array.from({ length: Math.min(this.#concurrency, items.length) }, () => this.#drain(items, run, results, state));
4524
- await Promise.allSettled(workers);
4525
- if (state.failure !== void 0) throw state.failure.error;
4526
- return results;
4573
+ const entries = items.entries();
4574
+ const failed = new AbortController();
4575
+ const workers = Array.from({ length: Math.min(this.#concurrency, items.length) }, () => this.#drain(entries, run, failed));
4576
+ const settled = await Promise.allSettled(workers);
4577
+ if (failed.signal.aborted) {
4578
+ const reason = failed.signal.reason;
4579
+ throw (0, _orkestrel_contract.isRecord)(reason) ? reason.error : reason;
4580
+ }
4581
+ return collectIndexed(settled.flatMap((worker) => worker.status === "fulfilled" ? worker.value : []));
4527
4582
  }
4528
- async #drain(items, run, results, state) {
4529
- for (;;) {
4530
- if (state.failure !== void 0) return;
4531
- const index = state.cursor;
4532
- state.cursor += 1;
4533
- if (index >= items.length) return;
4534
- const item = items[index];
4535
- if (item === void 0) return;
4583
+ async #drain(entries, run, failed) {
4584
+ const produced = [];
4585
+ for (const [index, item] of entries) {
4586
+ if (failed.signal.aborted || item === void 0) break;
4536
4587
  try {
4537
- results[index] = await run(item);
4588
+ produced.push([index, await run(item)]);
4538
4589
  } catch (error) {
4539
- state.failure ??= { error };
4540
- return;
4590
+ failed.abort(Object.freeze({ error }));
4591
+ break;
4541
4592
  }
4542
4593
  }
4594
+ return produced;
4543
4595
  }
4544
4596
  #accept(value, guard, field) {
4545
4597
  const snapshot = (0, _src_core.cloneValue)(value);
@@ -4579,10 +4631,13 @@ exports.Materializer = Materializer;
4579
4631
  exports.ORKESTREL_SCOPE = ORKESTREL_SCOPE;
4580
4632
  exports.PACKUMENT_MEDIA_TYPE = PACKUMENT_MEDIA_TYPE;
4581
4633
  exports.RESERVED_SEGMENT_PATTERN = RESERVED_SEGMENT_PATTERN;
4634
+ exports.ReadAllowance = ReadAllowance;
4582
4635
  exports.SCAFFOLD_REPOSITORY = SCAFFOLD_REPOSITORY;
4583
4636
  exports.UNREADABLE_VERSION_NOTE = UNREADABLE_VERSION_NOTE;
4584
4637
  exports.Upstream = Upstream;
4585
4638
  exports.WriteTransaction = WriteTransaction;
4639
+ exports.climbRealPath = climbRealPath;
4640
+ exports.collectIndexed = collectIndexed;
4586
4641
  exports.computeDigest = computeDigest;
4587
4642
  exports.computeFileDigest = computeFileDigest;
4588
4643
  exports.computeManifestDigest = computeManifestDigest;
@@ -4613,6 +4668,7 @@ exports.isUpstreamHooks = isUpstreamHooks;
4613
4668
  exports.isUpstreamOptions = isUpstreamOptions;
4614
4669
  exports.isVacant = isVacant;
4615
4670
  exports.isWorktree = isWorktree;
4671
+ exports.listAncestors = listAncestors;
4616
4672
  exports.listCanonPaths = listCanonPaths;
4617
4673
  exports.listDirectories = listDirectories;
4618
4674
  exports.listFiles = listFiles;