audit-tools 0.30.6 → 0.30.7

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.
@@ -5,6 +5,13 @@
5
5
  * it submits the candidate paths to `routeAmendmentRequest`. Unowned paths are
6
6
  * granted unilaterally; owned or contended paths are routed back through the
7
7
  * seam detect+resolve protocol.
8
+ *
9
+ * Grant-time disjointness (INV-SOO-06 / CE-001): `registry.claimAmendment`
10
+ * additionally refuses a scope-widening grant onto a file another node holds as a
11
+ * live in-flight scheduling claim, so the in-flight owned-file union can never
12
+ * become non-disjoint via a post-admission amendment. Such a path is routed as a
13
+ * `contended` seam (queued until the holder's file frees), exactly like a
14
+ * sibling-amendment contention.
8
15
  */
9
16
  import type { OwnershipRegistry } from "./ownershipRegistry.js";
10
17
  /** Discriminated union for the outcome of a single amendment claim attempt. */
@@ -1 +1 @@
1
- {"version":3,"file":"amendmentClaim.d.ts","sourceRoot":"","sources":["../../../src/remediate/dispatch/amendmentClaim.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,+EAA+E;AAC/E,MAAM,MAAM,oBAAoB,GAC5B;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EAAE,GACvB;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,oBAAoB,CAAA;KAAE,CAAC,CAAC;CACpE,CAgDA"}
1
+ {"version":3,"file":"amendmentClaim.d.ts","sourceRoot":"","sources":["../../../src/remediate/dispatch/amendmentClaim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,+EAA+E;AAC/E,MAAM,MAAM,oBAAoB,GAC5B;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EAAE,GACvB;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,oBAAoB,CAAA;KAAE,CAAC,CAAC;CACpE,CAgDA"}
@@ -5,6 +5,13 @@
5
5
  * it submits the candidate paths to `routeAmendmentRequest`. Unowned paths are
6
6
  * granted unilaterally; owned or contended paths are routed back through the
7
7
  * seam detect+resolve protocol.
8
+ *
9
+ * Grant-time disjointness (INV-SOO-06 / CE-001): `registry.claimAmendment`
10
+ * additionally refuses a scope-widening grant onto a file another node holds as a
11
+ * live in-flight scheduling claim, so the in-flight owned-file union can never
12
+ * become non-disjoint via a post-admission amendment. Such a path is routed as a
13
+ * `contended` seam (queued until the holder's file frees), exactly like a
14
+ * sibling-amendment contention.
8
15
  */
9
16
  /**
10
17
  * Route a worker's requested amendment paths into granted vs seam-routed.
@@ -1 +1 @@
1
- {"version":3,"file":"amendmentClaim.js","sourceRoot":"","sources":["../../../src/remediate/dispatch/amendmentClaim.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAA2B,EAC3B,MAAc,EACd,cAAwB;IAKxB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,WAAW,GAA0D,EAAE,CAAC;IAE9E,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEtD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QAED,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;YAChE,MAAM,KAAK,GAAyB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;YAC9E,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CAAC;gBACb,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,MAAM;gBACf,IAAI;gBACJ,OAAO,EAAE,OAAO;gBAChB,aAAa;gBACb,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aAC7B,CAAC,GAAG,IAAI,CACV,CAAC;YACF,SAAS;QACX,CAAC;QAED,YAAY;QACZ,MAAM,eAAe,GAAG,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QACtE,MAAM,KAAK,GAAyB,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;QACpF,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CAAC;YACb,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE,MAAM;YACf,IAAI;YACJ,OAAO,EAAE,WAAW;YACpB,eAAe;YACf,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC7B,CAAC,GAAG,IAAI,CACV,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"amendmentClaim.js","sourceRoot":"","sources":["../../../src/remediate/dispatch/amendmentClaim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAA2B,EAC3B,MAAc,EACd,cAAwB;IAKxB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,WAAW,GAA0D,EAAE,CAAC;IAE9E,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;QAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEtD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QAED,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;YAChE,MAAM,KAAK,GAAyB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;YAC9E,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CAAC;gBACb,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,uBAAuB;gBAC9B,OAAO,EAAE,MAAM;gBACf,IAAI;gBACJ,OAAO,EAAE,OAAO;gBAChB,aAAa;gBACb,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aAC7B,CAAC,GAAG,IAAI,CACV,CAAC;YACF,SAAS;QACX,CAAC;QAED,YAAY;QACZ,MAAM,eAAe,GAAG,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QACtE,MAAM,KAAK,GAAyB,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;QACpF,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CAAC;YACb,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE,MAAM;YACf,IAAI;YACJ,OAAO,EAAE,WAAW;YACpB,eAAe;YACf,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC7B,CAAC,GAAG,IAAI,CACV,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAClC,CAAC"}
@@ -10,6 +10,28 @@
10
10
  * Stale in-flight claims (node ID not in the current implementation DAG) are
11
11
  * purged on load.
12
12
  */
13
+ /**
14
+ * The single-sourced path canonicalization for ownership identity (INV-SOO-09).
15
+ *
16
+ * Resolves a path to a stable physical-file key: absolute (against `root` when
17
+ * supplied, else cwd), `..`/`.`-collapsed (via `resolve`), separators normalized
18
+ * to `/`, and case-folded on a case-insensitive filesystem. All spellings of one
19
+ * file therefore collide, closing the rel/abs/case/`..` mismatch (CE-004).
20
+ *
21
+ * Symlink identity is a RECORDED RESIDUAL, not silently treated as disjoint
22
+ * (INV-SOO-09 / fail-3): when `resolveSymlinks` is set and the path exists, the
23
+ * realpath is folded in so `link.ts → x.ts` collides; when realpath is
24
+ * unavailable (path absent, or FS symlink resolution out of scope) the lexical
25
+ * canonical key is used and the unresolved case degrades to the downstream merge
26
+ * guard rather than being asserted disjoint here.
27
+ *
28
+ * This is the ONLY normalization scheme for ownership identity — callers must
29
+ * not introduce a second one (failure-mode: path-identity mismatch).
30
+ */
31
+ export declare function canonicalizeFilePath(path: string, opts?: {
32
+ root?: string;
33
+ resolveSymlinks?: boolean;
34
+ }): string;
13
35
  export interface OwnershipRegistryJson {
14
36
  /** nodeId → set of paths from that node's original contract scope */
15
37
  contractScopes: Record<string, string[]>;
@@ -36,10 +58,22 @@ export declare class OwnershipRegistry {
36
58
  * claimed this path via an amendment.
37
59
  */
38
60
  private amendmentClaims;
61
+ /**
62
+ * canonical path → nodeId: scheduling-time in-flight WRITER claim. Lifted from
63
+ * the merge-time amendment signal into scheduling-time admission (INV-SOO):
64
+ * the rolling scheduler holds at most one in-flight writer per canonical path,
65
+ * so same-file nodes serialize while different-file nodes parallelize. Keyed by
66
+ * `canonicalizeFilePath` so all spellings of one file collide (INV-SOO-09).
67
+ */
68
+ private inFlightClaims;
39
69
  /** Optional path for checkpoint persistence. When provided, every mutation
40
70
  * atomically writes the registry state to this path. */
41
71
  private checkpointPath;
42
- constructor(checkpointPath?: string);
72
+ /** Repo root for canonicalizing relative scope/claim paths to physical identity. */
73
+ private root;
74
+ constructor(checkpointPath?: string, root?: string);
75
+ /** Canonicalize a path to physical-file identity under this registry's root. */
76
+ private canon;
43
77
  /**
44
78
  * Initialize the registry from the implementation DAG nodes. Each node's
45
79
  * `affected_files` (or `write_paths`) constitutes its contract scope.
@@ -60,6 +94,10 @@ export declare class OwnershipRegistry {
60
94
  * - `'contended'` — path has been claimed by a live parallel sibling; routes to seam protocol.
61
95
  */
62
96
  claimAmendment(nodeId: string, path: string): "granted" | "owned" | "contended";
97
+ /** The node holding an amendment claim whose canonical key matches `canonicalKey`. */
98
+ private _amendmentClaimantByCanonical;
99
+ /** Whether a contract-scope set contains a path with the given canonical key. */
100
+ private _scopeHasCanonical;
63
101
  /**
64
102
  * Release all amendment claims for `nodeId`. Call when a node finishes
65
103
  * (merge or triage). Makes the previously claimed files available again.
@@ -78,9 +116,57 @@ export declare class OwnershipRegistry {
78
116
  contractOwner(path: string): string | undefined;
79
117
  /**
80
118
  * Return the node ID that has an in-flight amendment claim for this path, or
81
- * undefined if uncontended.
119
+ * undefined if uncontended. Canonical identity (INV-SOO-09).
82
120
  */
83
121
  amendmentClaimant(path: string): string | undefined;
122
+ /**
123
+ * Canonical write-scope of a node for scheduling: its contract scope ∪ live
124
+ * amendment claims, each canonicalized to physical-file identity (INV-SOO-09).
125
+ */
126
+ canonicalScope(nodeId: string): Set<string>;
127
+ /**
128
+ * The union of canonical file paths owned by currently in-flight nodes (their
129
+ * scheduling claims). The scheduling-time complement of the merge-time owner
130
+ * signal — a path in this set has a live writer, so a same-file node must wait
131
+ * (INV-SOO-01).
132
+ */
133
+ filesClaimedByInFlight(): Set<string>;
134
+ /** The node holding the in-flight scheduling claim on `path`, or undefined. */
135
+ inFlightOwner(path: string): string | undefined;
136
+ /**
137
+ * Whether `nodeId`'s declared write-scope is file-ownership-DISJOINT from the
138
+ * current in-flight set — i.e. it shares no canonical path with any OTHER
139
+ * in-flight node, so it can be admitted without two in-flight writers per file
140
+ * (INV-SOO-01).
141
+ *
142
+ * Conservative empty-scope gating (INV-SOO-01 / CE-008): a node whose declared
143
+ * scope canonicalizes to the EMPTY set (unresolved/undeclared) is treated as
144
+ * NON-disjoint — it is NOT admitted as vacuously-disjoint, because an
145
+ * under-declared writer could collide with anything. Such a node admits only
146
+ * when no other node is in flight (`requireSoloWhenEmpty`).
147
+ */
148
+ isFileOwnershipDisjoint(nodeId: string, declaredScope: Iterable<string>): boolean;
149
+ /**
150
+ * Record `nodeId`'s scheduling-time in-flight WRITER claim over `paths`
151
+ * (declared scope, canonicalized). Idempotent for a node re-claiming its own
152
+ * paths (a rate-limited re-queue). Call BEFORE dispatching the node.
153
+ */
154
+ claimInFlight(nodeId: string, paths: Iterable<string>): void;
155
+ /**
156
+ * Release `nodeId`'s scheduling-time in-flight claims (and any amendment claims
157
+ * it holds). Call on a RELEASING disposition (INV-SOO-10):
158
+ * blocked-final / abandoned / merged / failed-no-retry / no-op-satisfied. A
159
+ * blocked-PENDING-triage node is still live and must NOT call this — it retains.
160
+ */
161
+ releaseInFlight(nodeId: string): void;
162
+ /**
163
+ * Atomic triage-retry claim hand-off A→A' (INV-SOO-07): transfer all of the
164
+ * failed node's in-flight + amendment claims to its successor in one step, so
165
+ * there is no observable window in which both hold the file, nor one in which a
166
+ * foreign same-file node is admitted between release and re-claim. A no-op when
167
+ * `fromNodeId === toNodeId`.
168
+ */
169
+ handoffInFlight(fromNodeId: string, toNodeId: string): void;
84
170
  /** Serialize to a plain JSON-safe object. */
85
171
  serialize(): OwnershipRegistryJson;
86
172
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ownershipRegistry.d.ts","sourceRoot":"","sources":["../../../src/remediate/dispatch/ownershipRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,iFAAiF;IACjF,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAiB;IAC5B,6DAA6D;IAC7D,OAAO,CAAC,cAAc,CAAuC;IAE7D;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAkC;IAEzD;4DACwD;IACxD,OAAO,CAAC,cAAc,CAAqB;gBAE/B,cAAc,CAAC,EAAE,MAAM;IAInC;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,GAAG,IAAI;IAUtG;;;;;;;;OAQG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW;IAoB/E;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAavC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAWlC;;;OAGG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAO/C;;;OAGG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAInD,6CAA6C;IAC7C,SAAS,IAAI,qBAAqB;IAkBlC;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CACb,IAAI,EAAE,qBAAqB,EAC3B,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,EACzB,cAAc,CAAC,EAAE,MAAM,GACtB,iBAAiB;IAqBpB,0DAA0D;IAC1D,OAAO,CAAC,QAAQ;IAqBhB,mGAAmG;IACnG,MAAM,CAAC,kBAAkB,CACvB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,iBAAiB,GAAG,SAAS;CAuBjC"}
1
+ {"version":3,"file":"ownershipRegistry.d.ts","sourceRoot":"","sources":["../../../src/remediate/dispatch/ownershipRegistry.ts"],"names":[],"mappings":"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"}
@@ -10,8 +10,51 @@
10
10
  * Stale in-flight claims (node ID not in the current implementation DAG) are
11
11
  * purged on load.
12
12
  */
13
- import { writeFileSync, readFileSync, mkdirSync } from "node:fs";
14
- import { dirname } from "node:path";
13
+ import { writeFileSync, readFileSync, mkdirSync, realpathSync } from "node:fs";
14
+ import { dirname, isAbsolute, resolve, sep } from "node:path";
15
+ /**
16
+ * Whether the host filesystem is case-insensitive for path identity. win32 and
17
+ * darwin default to case-insensitive volumes; linux is case-sensitive. Used so
18
+ * `src/A.ts` and `src/a.ts` collide on a Windows/macOS volume (one physical
19
+ * file) but stay distinct on Linux — INV-SOO-09 canonical physical-file identity.
20
+ */
21
+ const CASE_INSENSITIVE_FS = process.platform === "win32" || process.platform === "darwin";
22
+ /**
23
+ * The single-sourced path canonicalization for ownership identity (INV-SOO-09).
24
+ *
25
+ * Resolves a path to a stable physical-file key: absolute (against `root` when
26
+ * supplied, else cwd), `..`/`.`-collapsed (via `resolve`), separators normalized
27
+ * to `/`, and case-folded on a case-insensitive filesystem. All spellings of one
28
+ * file therefore collide, closing the rel/abs/case/`..` mismatch (CE-004).
29
+ *
30
+ * Symlink identity is a RECORDED RESIDUAL, not silently treated as disjoint
31
+ * (INV-SOO-09 / fail-3): when `resolveSymlinks` is set and the path exists, the
32
+ * realpath is folded in so `link.ts → x.ts` collides; when realpath is
33
+ * unavailable (path absent, or FS symlink resolution out of scope) the lexical
34
+ * canonical key is used and the unresolved case degrades to the downstream merge
35
+ * guard rather than being asserted disjoint here.
36
+ *
37
+ * This is the ONLY normalization scheme for ownership identity — callers must
38
+ * not introduce a second one (failure-mode: path-identity mismatch).
39
+ */
40
+ export function canonicalizeFilePath(path, opts = {}) {
41
+ const { root, resolveSymlinks = false } = opts;
42
+ let abs = isAbsolute(path)
43
+ ? resolve(path)
44
+ : resolve(root ?? process.cwd(), path);
45
+ if (resolveSymlinks) {
46
+ try {
47
+ abs = realpathSync(abs);
48
+ }
49
+ catch {
50
+ // Symlink/realpath unavailable (path absent or FS resolution out of scope):
51
+ // keep the lexical key — the unresolved symlink case is a recorded residual
52
+ // handled by the downstream merge guard, never asserted disjoint here.
53
+ }
54
+ }
55
+ const slashed = abs.split(sep).join("/");
56
+ return CASE_INSENSITIVE_FS ? slashed.toLowerCase() : slashed;
57
+ }
15
58
  /**
16
59
  * OwnershipRegistry tracks write-scope ownership per DAG node.
17
60
  *
@@ -32,11 +75,26 @@ export class OwnershipRegistry {
32
75
  * claimed this path via an amendment.
33
76
  */
34
77
  amendmentClaims = new Map();
78
+ /**
79
+ * canonical path → nodeId: scheduling-time in-flight WRITER claim. Lifted from
80
+ * the merge-time amendment signal into scheduling-time admission (INV-SOO):
81
+ * the rolling scheduler holds at most one in-flight writer per canonical path,
82
+ * so same-file nodes serialize while different-file nodes parallelize. Keyed by
83
+ * `canonicalizeFilePath` so all spellings of one file collide (INV-SOO-09).
84
+ */
85
+ inFlightClaims = new Map();
35
86
  /** Optional path for checkpoint persistence. When provided, every mutation
36
87
  * atomically writes the registry state to this path. */
37
88
  checkpointPath;
38
- constructor(checkpointPath) {
89
+ /** Repo root for canonicalizing relative scope/claim paths to physical identity. */
90
+ root;
91
+ constructor(checkpointPath, root) {
39
92
  this.checkpointPath = checkpointPath;
93
+ this.root = root;
94
+ }
95
+ /** Canonicalize a path to physical-file identity under this registry's root. */
96
+ canon(path) {
97
+ return canonicalizeFilePath(path, { root: this.root });
40
98
  }
41
99
  /**
42
100
  * Initialize the registry from the implementation DAG nodes. Each node's
@@ -62,22 +120,48 @@ export class OwnershipRegistry {
62
120
  * - `'contended'` — path has been claimed by a live parallel sibling; routes to seam protocol.
63
121
  */
64
122
  claimAmendment(nodeId, path) {
65
- // Check if path is in any OTHER node's contract scope.
123
+ const key = this.canon(path);
124
+ // Check if path is in any OTHER node's contract scope (canonical identity).
66
125
  for (const [scopeNodeId, scopePaths] of this.contractScopes) {
67
- if (scopeNodeId !== nodeId && scopePaths.has(path)) {
126
+ if (scopeNodeId !== nodeId && this._scopeHasCanonical(scopePaths, key)) {
68
127
  return "owned";
69
128
  }
70
129
  }
71
- // Check if path has already been amendment-claimed by a live parallel sibling.
72
- const existingClaimant = this.amendmentClaims.get(path);
130
+ // Check if path has already been amendment-claimed by a live parallel sibling
131
+ // (canonical identity, so a differently-spelled same file collides).
132
+ const existingClaimant = this._amendmentClaimantByCanonical(key);
73
133
  if (existingClaimant !== undefined && existingClaimant !== nodeId) {
74
134
  return "contended";
75
135
  }
76
- // Grant: record the claim.
136
+ // Grant-time disjointness (INV-SOO-06 / CE-001): refuse a scope-widening grant
137
+ // onto a file another in-flight node is actively writing, so a post-admission
138
+ // grant can never make the in-flight owned-file union non-disjoint.
139
+ const inFlightOwner = this.inFlightClaims.get(key);
140
+ if (inFlightOwner !== undefined && inFlightOwner !== nodeId) {
141
+ return "contended";
142
+ }
143
+ // Grant: record the claim under the ORIGINAL spelling (merge attribution reads
144
+ // the raw path); canonical identity is applied on comparison, not on storage.
77
145
  this.amendmentClaims.set(path, nodeId);
78
146
  this._persist();
79
147
  return "granted";
80
148
  }
149
+ /** The node holding an amendment claim whose canonical key matches `canonicalKey`. */
150
+ _amendmentClaimantByCanonical(canonicalKey) {
151
+ for (const [p, claimant] of this.amendmentClaims) {
152
+ if (this.canon(p) === canonicalKey)
153
+ return claimant;
154
+ }
155
+ return undefined;
156
+ }
157
+ /** Whether a contract-scope set contains a path with the given canonical key. */
158
+ _scopeHasCanonical(scopePaths, canonicalKey) {
159
+ for (const p of scopePaths) {
160
+ if (this.canon(p) === canonicalKey)
161
+ return true;
162
+ }
163
+ return false;
164
+ }
81
165
  /**
82
166
  * Release all amendment claims for `nodeId`. Call when a node finishes
83
167
  * (merge or triage). Makes the previously claimed files available again.
@@ -114,18 +198,147 @@ export class OwnershipRegistry {
114
198
  * the path is unowned.
115
199
  */
116
200
  contractOwner(path) {
201
+ const key = this.canon(path);
117
202
  for (const [nodeId, scopePaths] of this.contractScopes) {
118
- if (scopePaths.has(path))
203
+ if (this._scopeHasCanonical(scopePaths, key))
119
204
  return nodeId;
120
205
  }
121
206
  return undefined;
122
207
  }
123
208
  /**
124
209
  * Return the node ID that has an in-flight amendment claim for this path, or
125
- * undefined if uncontended.
210
+ * undefined if uncontended. Canonical identity (INV-SOO-09).
126
211
  */
127
212
  amendmentClaimant(path) {
128
- return this.amendmentClaims.get(path);
213
+ // Exact-spelling hit first (cheap), else canonical match.
214
+ return (this.amendmentClaims.get(path) ??
215
+ this._amendmentClaimantByCanonical(this.canon(path)));
216
+ }
217
+ // ── Scheduling-time file-ownership queries (INV-SOO) ───────────────────────
218
+ /**
219
+ * Canonical write-scope of a node for scheduling: its contract scope ∪ live
220
+ * amendment claims, each canonicalized to physical-file identity (INV-SOO-09).
221
+ */
222
+ canonicalScope(nodeId) {
223
+ const out = new Set();
224
+ for (const p of this.contractScopes.get(nodeId) ?? [])
225
+ out.add(this.canon(p));
226
+ for (const [key, claimant] of this.amendmentClaims) {
227
+ if (claimant === nodeId)
228
+ out.add(key);
229
+ }
230
+ return out;
231
+ }
232
+ /**
233
+ * The union of canonical file paths owned by currently in-flight nodes (their
234
+ * scheduling claims). The scheduling-time complement of the merge-time owner
235
+ * signal — a path in this set has a live writer, so a same-file node must wait
236
+ * (INV-SOO-01).
237
+ */
238
+ filesClaimedByInFlight() {
239
+ return new Set(this.inFlightClaims.keys());
240
+ }
241
+ /** The node holding the in-flight scheduling claim on `path`, or undefined. */
242
+ inFlightOwner(path) {
243
+ return this.inFlightClaims.get(this.canon(path));
244
+ }
245
+ /**
246
+ * Whether `nodeId`'s declared write-scope is file-ownership-DISJOINT from the
247
+ * current in-flight set — i.e. it shares no canonical path with any OTHER
248
+ * in-flight node, so it can be admitted without two in-flight writers per file
249
+ * (INV-SOO-01).
250
+ *
251
+ * Conservative empty-scope gating (INV-SOO-01 / CE-008): a node whose declared
252
+ * scope canonicalizes to the EMPTY set (unresolved/undeclared) is treated as
253
+ * NON-disjoint — it is NOT admitted as vacuously-disjoint, because an
254
+ * under-declared writer could collide with anything. Such a node admits only
255
+ * when no other node is in flight (`requireSoloWhenEmpty`).
256
+ */
257
+ isFileOwnershipDisjoint(nodeId, declaredScope) {
258
+ const scope = new Set();
259
+ for (const p of declaredScope)
260
+ scope.add(this.canon(p));
261
+ if (scope.size === 0) {
262
+ // Empty/unresolved scope: disjoint only if nothing else is in flight.
263
+ for (const owner of this.inFlightClaims.values()) {
264
+ if (owner !== nodeId)
265
+ return false;
266
+ }
267
+ return true;
268
+ }
269
+ for (const key of scope) {
270
+ const owner = this.inFlightClaims.get(key);
271
+ if (owner !== undefined && owner !== nodeId)
272
+ return false;
273
+ }
274
+ return true;
275
+ }
276
+ /**
277
+ * Record `nodeId`'s scheduling-time in-flight WRITER claim over `paths`
278
+ * (declared scope, canonicalized). Idempotent for a node re-claiming its own
279
+ * paths (a rate-limited re-queue). Call BEFORE dispatching the node.
280
+ */
281
+ claimInFlight(nodeId, paths) {
282
+ let changed = false;
283
+ for (const p of paths) {
284
+ const key = this.canon(p);
285
+ const existing = this.inFlightClaims.get(key);
286
+ if (existing === nodeId)
287
+ continue;
288
+ // Caller guarantees disjointness via isFileOwnershipDisjoint; a foreign
289
+ // owner here is a precondition violation, surfaced rather than overwritten.
290
+ if (existing !== undefined && existing !== nodeId) {
291
+ throw new Error(`OwnershipRegistry.claimInFlight: ${key} already in-flight by ${existing}, ` +
292
+ `cannot claim for ${nodeId} (file-ownership-disjoint precondition violated).`);
293
+ }
294
+ this.inFlightClaims.set(key, nodeId);
295
+ changed = true;
296
+ }
297
+ if (changed)
298
+ this._persist();
299
+ }
300
+ /**
301
+ * Release `nodeId`'s scheduling-time in-flight claims (and any amendment claims
302
+ * it holds). Call on a RELEASING disposition (INV-SOO-10):
303
+ * blocked-final / abandoned / merged / failed-no-retry / no-op-satisfied. A
304
+ * blocked-PENDING-triage node is still live and must NOT call this — it retains.
305
+ */
306
+ releaseInFlight(nodeId) {
307
+ let changed = false;
308
+ for (const [key, owner] of this.inFlightClaims) {
309
+ if (owner === nodeId) {
310
+ this.inFlightClaims.delete(key);
311
+ changed = true;
312
+ }
313
+ }
314
+ if (changed)
315
+ this._persist();
316
+ }
317
+ /**
318
+ * Atomic triage-retry claim hand-off A→A' (INV-SOO-07): transfer all of the
319
+ * failed node's in-flight + amendment claims to its successor in one step, so
320
+ * there is no observable window in which both hold the file, nor one in which a
321
+ * foreign same-file node is admitted between release and re-claim. A no-op when
322
+ * `fromNodeId === toNodeId`.
323
+ */
324
+ handoffInFlight(fromNodeId, toNodeId) {
325
+ if (fromNodeId === toNodeId)
326
+ return;
327
+ let changed = false;
328
+ for (const [key, owner] of this.inFlightClaims) {
329
+ if (owner === fromNodeId) {
330
+ this.inFlightClaims.set(key, toNodeId);
331
+ changed = true;
332
+ }
333
+ }
334
+ for (const [key, owner] of this.amendmentClaims) {
335
+ if (owner === fromNodeId) {
336
+ this.amendmentClaims.set(key, toNodeId);
337
+ changed = true;
338
+ }
339
+ }
340
+ if (changed)
341
+ this._persist();
129
342
  }
130
343
  /** Serialize to a plain JSON-safe object. */
131
344
  serialize() {
@@ -1 +1 @@
1
- {"version":3,"file":"ownershipRegistry.js","sourceRoot":"","sources":["../../../src/remediate/dispatch/ownershipRegistry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ownershipRegistry.js","sourceRoot":"","sources":["../../../src/remediate/dispatch/ownershipRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * File-ownership-disjoint admission scheduling (INV-SOO-01..10).
3
+ *
4
+ * The rolling engine dispatches an eligible dependency LEVEL (deps verified-
5
+ * complete, INV-RS-01). Within a level the previous scheduler ordered nodes only
6
+ * by `block_id.localeCompare`, which let two same-file nodes run concurrently and
7
+ * collide at merge (the lost-update-guard-lands-1-rejects-N-1 starved-tail bug).
8
+ *
9
+ * This module replaces that numeric ordering with file-ownership-DISJOINT
10
+ * admission: a level is admitted in SUB-WAVES, each a maximal pairwise-file-
11
+ * disjoint subset of the still-pending nodes, chosen by a deterministic
12
+ * block_id tie-break AFTER the disjointness filter (INV-SOO-08). Same-file nodes
13
+ * therefore land in successive sub-waves (serialize, INV-SOO-01/02) while
14
+ * different-file nodes share a sub-wave (parallelize up to the quota cap the
15
+ * dispatcher itself enforces, INV-SOO-03/05). Path identity is the single
16
+ * canonical key from `canonicalizeFilePath` (INV-SOO-09); an empty/unresolved
17
+ * scope is conservatively NON-disjoint so it never batches with a peer
18
+ * (INV-SOO-01 / CE-008).
19
+ *
20
+ * Pure and deterministic — no I/O, no Set/Map iteration-order leak — so the
21
+ * admission order is reproducible and unit-testable against a precomputed level.
22
+ */
23
+ /** A node as the ownership scheduler sees it: an id + its declared write-scope. */
24
+ export interface OwnershipSchedulerNode {
25
+ block_id: string;
26
+ /** Declared write-scope paths (repo-relative or absolute); empty ⇒ unresolved. */
27
+ write_paths: string[];
28
+ }
29
+ /**
30
+ * Canonicalize a node's declared write-scope to physical-file identity keys.
31
+ * Empty input ⇒ empty set (handled conservatively by the disjointness gate).
32
+ */
33
+ export declare function canonicalScopeKeys(node: OwnershipSchedulerNode, root?: string): Set<string>;
34
+ /**
35
+ * Partition a single eligible LEVEL into ordered file-ownership-disjoint
36
+ * SUB-WAVES. Each sub-wave is a maximal set of nodes whose canonical write-scopes
37
+ * are pairwise disjoint AND disjoint from a node with an empty scope only when it
38
+ * is alone (conservative empty-scope gating). Nodes are considered in ascending
39
+ * `block_id` order (the deterministic tie-break, INV-SOO-08), so the admitted
40
+ * subset of each sub-wave is identical across two runs over identical state.
41
+ *
42
+ * A node with an EMPTY canonical scope (unresolved/undeclared) is treated as
43
+ * conservatively NON-disjoint: it only enters a sub-wave by itself (it blocks and
44
+ * is blocked-by every peer), so it never batches with another writer
45
+ * (INV-SOO-01 / CE-008).
46
+ */
47
+ export declare function ownershipSubWaves(level: OwnershipSchedulerNode[], root?: string): OwnershipSchedulerNode[][];
48
+ //# sourceMappingURL=ownershipScheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownershipScheduler.d.ts","sourceRoot":"","sources":["../../../src/remediate/dispatch/ownershipScheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,mFAAmF;AACnF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,sBAAsB,EAC5B,IAAI,CAAC,EAAE,MAAM,GACZ,GAAG,CAAC,MAAM,CAAC,CAIb;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,EAAE,EAC/B,IAAI,CAAC,EAAE,MAAM,GACZ,sBAAsB,EAAE,EAAE,CAwD5B"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * File-ownership-disjoint admission scheduling (INV-SOO-01..10).
3
+ *
4
+ * The rolling engine dispatches an eligible dependency LEVEL (deps verified-
5
+ * complete, INV-RS-01). Within a level the previous scheduler ordered nodes only
6
+ * by `block_id.localeCompare`, which let two same-file nodes run concurrently and
7
+ * collide at merge (the lost-update-guard-lands-1-rejects-N-1 starved-tail bug).
8
+ *
9
+ * This module replaces that numeric ordering with file-ownership-DISJOINT
10
+ * admission: a level is admitted in SUB-WAVES, each a maximal pairwise-file-
11
+ * disjoint subset of the still-pending nodes, chosen by a deterministic
12
+ * block_id tie-break AFTER the disjointness filter (INV-SOO-08). Same-file nodes
13
+ * therefore land in successive sub-waves (serialize, INV-SOO-01/02) while
14
+ * different-file nodes share a sub-wave (parallelize up to the quota cap the
15
+ * dispatcher itself enforces, INV-SOO-03/05). Path identity is the single
16
+ * canonical key from `canonicalizeFilePath` (INV-SOO-09); an empty/unresolved
17
+ * scope is conservatively NON-disjoint so it never batches with a peer
18
+ * (INV-SOO-01 / CE-008).
19
+ *
20
+ * Pure and deterministic — no I/O, no Set/Map iteration-order leak — so the
21
+ * admission order is reproducible and unit-testable against a precomputed level.
22
+ */
23
+ import { canonicalizeFilePath } from "./ownershipRegistry.js";
24
+ /**
25
+ * Canonicalize a node's declared write-scope to physical-file identity keys.
26
+ * Empty input ⇒ empty set (handled conservatively by the disjointness gate).
27
+ */
28
+ export function canonicalScopeKeys(node, root) {
29
+ const out = new Set();
30
+ for (const p of node.write_paths)
31
+ out.add(canonicalizeFilePath(p, { root }));
32
+ return out;
33
+ }
34
+ /**
35
+ * Partition a single eligible LEVEL into ordered file-ownership-disjoint
36
+ * SUB-WAVES. Each sub-wave is a maximal set of nodes whose canonical write-scopes
37
+ * are pairwise disjoint AND disjoint from a node with an empty scope only when it
38
+ * is alone (conservative empty-scope gating). Nodes are considered in ascending
39
+ * `block_id` order (the deterministic tie-break, INV-SOO-08), so the admitted
40
+ * subset of each sub-wave is identical across two runs over identical state.
41
+ *
42
+ * A node with an EMPTY canonical scope (unresolved/undeclared) is treated as
43
+ * conservatively NON-disjoint: it only enters a sub-wave by itself (it blocks and
44
+ * is blocked-by every peer), so it never batches with another writer
45
+ * (INV-SOO-01 / CE-008).
46
+ */
47
+ export function ownershipSubWaves(level, root) {
48
+ const ordered = [...level].sort((a, b) => a.block_id.localeCompare(b.block_id));
49
+ const scopeOf = new Map();
50
+ for (const n of ordered)
51
+ scopeOf.set(n.block_id, canonicalScopeKeys(n, root));
52
+ const remaining = [...ordered];
53
+ const subWaves = [];
54
+ while (remaining.length > 0) {
55
+ const wave = [];
56
+ const claimed = new Set();
57
+ let waveHasEmptyScopeNode = false;
58
+ const leftover = [];
59
+ for (const node of remaining) {
60
+ const scope = scopeOf.get(node.block_id);
61
+ const isEmpty = scope.size === 0;
62
+ // Empty-scope node admits only into an otherwise-empty sub-wave (solo).
63
+ if (isEmpty) {
64
+ if (wave.length === 0) {
65
+ wave.push(node);
66
+ waveHasEmptyScopeNode = true;
67
+ }
68
+ else {
69
+ leftover.push(node);
70
+ }
71
+ continue;
72
+ }
73
+ // A real-scope node cannot share a wave with an empty-scope node, nor with
74
+ // any node it shares a canonical path with.
75
+ if (waveHasEmptyScopeNode) {
76
+ leftover.push(node);
77
+ continue;
78
+ }
79
+ let overlaps = false;
80
+ for (const key of scope) {
81
+ if (claimed.has(key)) {
82
+ overlaps = true;
83
+ break;
84
+ }
85
+ }
86
+ if (overlaps) {
87
+ leftover.push(node);
88
+ continue;
89
+ }
90
+ for (const key of scope)
91
+ claimed.add(key);
92
+ wave.push(node);
93
+ }
94
+ subWaves.push(wave);
95
+ remaining.length = 0;
96
+ remaining.push(...leftover);
97
+ }
98
+ return subWaves;
99
+ }
100
+ //# sourceMappingURL=ownershipScheduler.js.map