@izagood/avcs 0.1.0

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 (111) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +221 -0
  3. package/dist/api/repo.d.ts +616 -0
  4. package/dist/api/repo.d.ts.map +1 -0
  5. package/dist/api/repo.js +1772 -0
  6. package/dist/api/repo.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +660 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/concurrency/lease.d.ts +27 -0
  12. package/dist/concurrency/lease.d.ts.map +1 -0
  13. package/dist/concurrency/lease.js +63 -0
  14. package/dist/concurrency/lease.js.map +1 -0
  15. package/dist/core/canonical.d.ts +16 -0
  16. package/dist/core/canonical.d.ts.map +1 -0
  17. package/dist/core/canonical.js +66 -0
  18. package/dist/core/canonical.js.map +1 -0
  19. package/dist/core/cbor.d.ts +9 -0
  20. package/dist/core/cbor.d.ts.map +1 -0
  21. package/dist/core/cbor.js +213 -0
  22. package/dist/core/cbor.js.map +1 -0
  23. package/dist/core/clock.d.ts +18 -0
  24. package/dist/core/clock.d.ts.map +1 -0
  25. package/dist/core/clock.js +32 -0
  26. package/dist/core/clock.js.map +1 -0
  27. package/dist/core/identity.d.ts +34 -0
  28. package/dist/core/identity.d.ts.map +1 -0
  29. package/dist/core/identity.js +62 -0
  30. package/dist/core/identity.js.map +1 -0
  31. package/dist/hub/hubClient.d.ts +38 -0
  32. package/dist/hub/hubClient.d.ts.map +1 -0
  33. package/dist/hub/hubClient.js +157 -0
  34. package/dist/hub/hubClient.js.map +1 -0
  35. package/dist/hub/hubServer.d.ts +28 -0
  36. package/dist/hub/hubServer.d.ts.map +1 -0
  37. package/dist/hub/hubServer.js +365 -0
  38. package/dist/hub/hubServer.js.map +1 -0
  39. package/dist/index.d.ts +13 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +19 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/objects/types.d.ts +352 -0
  44. package/dist/objects/types.d.ts.map +1 -0
  45. package/dist/objects/types.js +17 -0
  46. package/dist/objects/types.js.map +1 -0
  47. package/dist/observe/logger.d.ts +27 -0
  48. package/dist/observe/logger.d.ts.map +1 -0
  49. package/dist/observe/logger.js +37 -0
  50. package/dist/observe/logger.js.map +1 -0
  51. package/dist/observe/metrics.d.ts +20 -0
  52. package/dist/observe/metrics.d.ts.map +1 -0
  53. package/dist/observe/metrics.js +42 -0
  54. package/dist/observe/metrics.js.map +1 -0
  55. package/dist/policy/owners.d.ts +5 -0
  56. package/dist/policy/owners.d.ts.map +1 -0
  57. package/dist/policy/owners.js +38 -0
  58. package/dist/policy/owners.js.map +1 -0
  59. package/dist/policy/reliability.d.ts +7 -0
  60. package/dist/policy/reliability.d.ts.map +1 -0
  61. package/dist/policy/reliability.js +41 -0
  62. package/dist/policy/reliability.js.map +1 -0
  63. package/dist/query/diff.d.ts +16 -0
  64. package/dist/query/diff.d.ts.map +1 -0
  65. package/dist/query/diff.js +32 -0
  66. package/dist/query/diff.js.map +1 -0
  67. package/dist/reducer/incremental.d.ts +2 -0
  68. package/dist/reducer/incremental.d.ts.map +1 -0
  69. package/dist/reducer/incremental.js +14 -0
  70. package/dist/reducer/incremental.js.map +1 -0
  71. package/dist/reducer/policy.d.ts +17 -0
  72. package/dist/reducer/policy.d.ts.map +1 -0
  73. package/dist/reducer/policy.js +143 -0
  74. package/dist/reducer/policy.js.map +1 -0
  75. package/dist/reducer/reducer.d.ts +155 -0
  76. package/dist/reducer/reducer.d.ts.map +1 -0
  77. package/dist/reducer/reducer.js +849 -0
  78. package/dist/reducer/reducer.js.map +1 -0
  79. package/dist/release/sbom.d.ts +7 -0
  80. package/dist/release/sbom.d.ts.map +1 -0
  81. package/dist/release/sbom.js +26 -0
  82. package/dist/release/sbom.js.map +1 -0
  83. package/dist/semantic/contract.d.ts +32 -0
  84. package/dist/semantic/contract.d.ts.map +1 -0
  85. package/dist/semantic/contract.js +150 -0
  86. package/dist/semantic/contract.js.map +1 -0
  87. package/dist/semantic/symbols.d.ts +45 -0
  88. package/dist/semantic/symbols.d.ts.map +1 -0
  89. package/dist/semantic/symbols.js +323 -0
  90. package/dist/semantic/symbols.js.map +1 -0
  91. package/dist/store/applyRedactions.d.ts +16 -0
  92. package/dist/store/applyRedactions.d.ts.map +1 -0
  93. package/dist/store/applyRedactions.js +60 -0
  94. package/dist/store/applyRedactions.js.map +1 -0
  95. package/dist/store/lock.d.ts +12 -0
  96. package/dist/store/lock.d.ts.map +1 -0
  97. package/dist/store/lock.js +63 -0
  98. package/dist/store/lock.js.map +1 -0
  99. package/dist/store/objectStore.d.ts +127 -0
  100. package/dist/store/objectStore.d.ts.map +1 -0
  101. package/dist/store/objectStore.js +549 -0
  102. package/dist/store/objectStore.js.map +1 -0
  103. package/dist/validation/repair.d.ts +31 -0
  104. package/dist/validation/repair.d.ts.map +1 -0
  105. package/dist/validation/repair.js +37 -0
  106. package/dist/validation/repair.js.map +1 -0
  107. package/dist/validation/runner.d.ts +20 -0
  108. package/dist/validation/runner.d.ts.map +1 -0
  109. package/dist/validation/runner.js +90 -0
  110. package/dist/validation/runner.js.map +1 -0
  111. package/package.json +83 -0
@@ -0,0 +1,323 @@
1
+ // Phase 2: structured (symbol-granular) view of a source file.
2
+ //
3
+ // This is the seam that turns "same file" conflicts into "same symbol" conflicts.
4
+ // A file is parsed into an ordered list of spans — named top-level symbols and the
5
+ // gaps between them (imports, blank lines). Two operations that edit *different*
6
+ // symbols of the same file then occupy different conflict keys and auto-merge (L1),
7
+ // while two edits to the *same* symbol still contend.
8
+ //
9
+ // MVP scope: a brace/line scanner for TS/JS-shaped code. It is deliberately a
10
+ // pluggable `EntityIndexer` so a Tree-sitter backend can replace it per language
11
+ // without touching the reducer. It is approximate (well-formatted code), and falls
12
+ // back to whole-file semantics when a file does not parse into named symbols.
13
+ const DECL = /^(export\s+(default\s+)?)?(async\s+)?(function|class|interface|enum|namespace|type|const|let|var)\s+([A-Za-z0-9_$]+)/;
14
+ /** Top-level declaration kinds that own a brace-delimited body. */
15
+ const BRACE_FORMS = new Set(["function", "class", "interface", "enum", "namespace"]);
16
+ /**
17
+ * Split TS/JS source into symbol + gap spans. Brace depth is tracked across the
18
+ * whole text so nested braces inside a symbol don't end it early. Strings and line
19
+ * comments are handled well enough for ordinary code.
20
+ */
21
+ function parse(content) {
22
+ const lines = content.split("\n");
23
+ const spans = [];
24
+ let gapBuf = [];
25
+ let gapIdx = 0;
26
+ const flushGap = () => {
27
+ if (gapBuf.length) {
28
+ spans.push({ kind: "gap", key: `@gap:${gapIdx++}`, text: gapBuf.join("\n") });
29
+ gapBuf = [];
30
+ }
31
+ };
32
+ let i = 0;
33
+ while (i < lines.length) {
34
+ const line = lines[i];
35
+ const m = DECL.exec(line.trim());
36
+ if (!m) {
37
+ gapBuf.push(line);
38
+ i++;
39
+ continue;
40
+ }
41
+ const keyword = m[4];
42
+ const name = m[5];
43
+ flushGap();
44
+ if (BRACE_FORMS.has(keyword) || /[{(]/.test(line)) {
45
+ // Consume lines until brace depth returns to 0 after having opened.
46
+ let depth = 0;
47
+ let opened = false;
48
+ const body = [];
49
+ while (i < lines.length) {
50
+ const l = lines[i];
51
+ body.push(l);
52
+ depth += braceDelta(l);
53
+ if (depth > 0)
54
+ opened = true;
55
+ i++;
56
+ if (opened && depth <= 0)
57
+ break;
58
+ if (!opened && /;\s*$/.test(l))
59
+ break; // e.g. `const x = 1;` with parens but no block
60
+ }
61
+ spans.push({ kind: "symbol", key: name, name, text: body.join("\n") });
62
+ }
63
+ else {
64
+ // Single-line / statement form (const/type/let), may span to a `;`.
65
+ const body = [];
66
+ while (i < lines.length) {
67
+ const l = lines[i];
68
+ body.push(l);
69
+ i++;
70
+ if (/;\s*$/.test(l) || !lines[i] || DECL.test((lines[i] ?? "").trim()))
71
+ break;
72
+ }
73
+ spans.push({ kind: "symbol", key: name, name, text: body.join("\n") });
74
+ }
75
+ }
76
+ flushGap();
77
+ return spans;
78
+ }
79
+ /** Net `{`+`(` minus `}`+`)` on a line, ignoring those in strings/line comments. */
80
+ function braceDelta(line) {
81
+ let depth = 0;
82
+ let str = null;
83
+ for (let j = 0; j < line.length; j++) {
84
+ const c = line[j];
85
+ if (str) {
86
+ if (c === "\\")
87
+ j++;
88
+ else if (c === str)
89
+ str = null;
90
+ continue;
91
+ }
92
+ if (c === '"' || c === "'" || c === "`")
93
+ str = c;
94
+ else if (c === "/" && line[j + 1] === "/")
95
+ break;
96
+ else if (c === "{")
97
+ depth++;
98
+ else if (c === "}")
99
+ depth--;
100
+ }
101
+ return depth;
102
+ }
103
+ function reassemble(spans) {
104
+ return spans.map((s) => s.text).join("\n");
105
+ }
106
+ export const tsIndexer = { language: "typescript", parse, reassemble };
107
+ /** List the symbol names in a file (stable ids), in source order. */
108
+ export function symbolNames(content, indexer = tsIndexer) {
109
+ return indexer.parse(content).filter((s) => s.kind === "symbol").map((s) => s.name);
110
+ }
111
+ /** A top-level declaration line starts at column 0 (no leading whitespace). This is the
112
+ * fallback used when the brace scanner fails to surface a symbol that nonetheless exists
113
+ * in the text — replacing its declaration in place instead of blindly appending a
114
+ * duplicate. Returns null if no top-level declaration of `name` is found. */
115
+ function replaceTopLevelDecl(content, name, newText) {
116
+ const lines = content.split("\n");
117
+ const topDeclName = (line) => {
118
+ if (!/^\S/.test(line))
119
+ return null; // must be column 0
120
+ const m = DECL.exec(line.trim());
121
+ return m && m[5] === name ? name : null;
122
+ };
123
+ let start = -1;
124
+ for (let i = 0; i < lines.length; i++)
125
+ if (topDeclName(lines[i]) === name) {
126
+ start = i;
127
+ break;
128
+ }
129
+ if (start === -1)
130
+ return null;
131
+ let end = lines.length;
132
+ for (let j = start + 1; j < lines.length; j++) {
133
+ const l = lines[j];
134
+ if (/^\S/.test(l) && DECL.test(l.trim())) {
135
+ end = j;
136
+ break;
137
+ } // next top-level decl
138
+ }
139
+ return [...lines.slice(0, start), newText, ...lines.slice(end)].join("\n");
140
+ }
141
+ /**
142
+ * Replace one symbol's text, returning the new file content. If the symbol does not
143
+ * exist, it is appended. Pure and deterministic.
144
+ *
145
+ * D5 duplicate-guard: when the brace scanner can't find the symbol as a span but a
146
+ * top-level declaration of that name DOES exist in the text (the scanner mis-parsed —
147
+ * e.g. a template literal containing `}`), blindly appending would create a SECOND
148
+ * definition of the symbol: a `set_symbol` meant to UPDATE silently duplicates instead.
149
+ * We fall back to a column-0 declaration scan and replace the existing decl in place. A
150
+ * genuinely-new symbol (no existing decl) is still appended.
151
+ */
152
+ export function spliceSymbol(content, symbolName, newText, indexer = tsIndexer) {
153
+ const spans = indexer.parse(content);
154
+ const idx = spans.findIndex((s) => s.kind === "symbol" && s.name === symbolName);
155
+ if (idx !== -1) {
156
+ spans[idx] = { kind: "symbol", key: symbolName, name: symbolName, text: newText };
157
+ return indexer.reassemble(spans);
158
+ }
159
+ // Not found as a span. Avoid a duplicate definition if the decl actually exists.
160
+ const replaced = replaceTopLevelDecl(content, symbolName, newText);
161
+ if (replaced !== null)
162
+ return replaced;
163
+ spans.push({ kind: "symbol", key: symbolName, name: symbolName, text: newText });
164
+ return indexer.reassemble(spans);
165
+ }
166
+ const isIdChar = (c) => c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "_" || c === "$";
167
+ /**
168
+ * M3 AST op: rename a top-level symbol — its declaration AND its references WITHIN
169
+ * the same file. Renames only whole-identifier occurrences in CODE, deliberately
170
+ * skipping strings, template-literal text, and comments (a regex `\bfrom\b` would
171
+ * also rewrite `from` inside a comment or a "from" string — silent corruption; D5).
172
+ * Template interpolations `${…}` are treated as code, so identifiers there ARE renamed.
173
+ * Cross-file references need real reference analysis (tree-sitter) — Track C. Pure.
174
+ */
175
+ export function renameSymbol(content, from, to) {
176
+ if (!from || !to || from === to)
177
+ return content;
178
+ const stack = [{ k: "code", interp: false, depth: 0 }];
179
+ let out = "";
180
+ let i = 0;
181
+ const n = content.length;
182
+ while (i < n) {
183
+ const m = stack[stack.length - 1];
184
+ const c = content[i];
185
+ const c2 = content[i + 1];
186
+ if (m.k === "code") {
187
+ if (c === "/" && c2 === "/") {
188
+ out += "//";
189
+ i += 2;
190
+ stack.push({ k: "line" });
191
+ continue;
192
+ }
193
+ if (c === "/" && c2 === "*") {
194
+ out += "/*";
195
+ i += 2;
196
+ stack.push({ k: "block" });
197
+ continue;
198
+ }
199
+ if (c === "'") {
200
+ out += c;
201
+ i++;
202
+ stack.push({ k: "sq" });
203
+ continue;
204
+ }
205
+ if (c === '"') {
206
+ out += c;
207
+ i++;
208
+ stack.push({ k: "dq" });
209
+ continue;
210
+ }
211
+ if (c === "`") {
212
+ out += c;
213
+ i++;
214
+ stack.push({ k: "tmpl" });
215
+ continue;
216
+ }
217
+ if (m.interp && c === "{") {
218
+ m.depth++;
219
+ out += c;
220
+ i++;
221
+ continue;
222
+ }
223
+ if (m.interp && c === "}") {
224
+ if (m.depth === 0) {
225
+ stack.pop();
226
+ out += c;
227
+ i++;
228
+ continue;
229
+ } // closes ${…} → back to tmpl
230
+ m.depth--;
231
+ out += c;
232
+ i++;
233
+ continue;
234
+ }
235
+ if (isIdChar(c) && !(c >= "0" && c <= "9")) {
236
+ let j = i;
237
+ while (j < n && isIdChar(content[j]))
238
+ j++;
239
+ const word = content.slice(i, j);
240
+ out += word === from ? to : word;
241
+ i = j;
242
+ continue;
243
+ }
244
+ if (isIdChar(c)) { // a numeric/identifier run starting with a digit — never a rename target
245
+ let j = i;
246
+ while (j < n && isIdChar(content[j]))
247
+ j++;
248
+ out += content.slice(i, j);
249
+ i = j;
250
+ continue;
251
+ }
252
+ out += c;
253
+ i++;
254
+ continue;
255
+ }
256
+ if (m.k === "line") {
257
+ out += c;
258
+ i++;
259
+ if (c === "\n")
260
+ stack.pop();
261
+ continue;
262
+ }
263
+ if (m.k === "block") {
264
+ if (c === "*" && c2 === "/") {
265
+ out += "*/";
266
+ i += 2;
267
+ stack.pop();
268
+ continue;
269
+ }
270
+ out += c;
271
+ i++;
272
+ continue;
273
+ }
274
+ if (m.k === "sq" || m.k === "dq") {
275
+ const q = m.k === "sq" ? "'" : '"';
276
+ if (c === "\\") {
277
+ out += content.slice(i, i + 2);
278
+ i += 2;
279
+ continue;
280
+ }
281
+ out += c;
282
+ i++;
283
+ if (c === q)
284
+ stack.pop();
285
+ continue;
286
+ }
287
+ // template literal
288
+ if (c === "\\") {
289
+ out += content.slice(i, i + 2);
290
+ i += 2;
291
+ continue;
292
+ }
293
+ if (c === "`") {
294
+ out += c;
295
+ i++;
296
+ stack.pop();
297
+ continue;
298
+ }
299
+ if (c === "$" && c2 === "{") {
300
+ out += "${";
301
+ i += 2;
302
+ stack.push({ k: "code", interp: true, depth: 0 });
303
+ continue;
304
+ }
305
+ out += c;
306
+ i++;
307
+ }
308
+ return out;
309
+ }
310
+ /**
311
+ * M3 AST op support: extract one top-level symbol's text and return it together with
312
+ * the file content that remains (symbol removed). Returns null if the symbol is absent.
313
+ */
314
+ export function extractSymbol(content, symbolName, indexer = tsIndexer) {
315
+ const spans = indexer.parse(content);
316
+ const idx = spans.findIndex((s) => s.kind === "symbol" && s.name === symbolName);
317
+ if (idx === -1)
318
+ return null;
319
+ const text = spans[idx].text;
320
+ const rest = indexer.reassemble(spans.filter((_, i) => i !== idx));
321
+ return { text, rest };
322
+ }
323
+ //# sourceMappingURL=symbols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/semantic/symbols.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ObjectStore } from "./objectStore.ts";
2
+ import type { Blob } from "../objects/types.ts";
3
+ export declare function redactedStub(reason: string, redactionOid: string): Blob;
4
+ /**
5
+ * Materialize every Redaction's stub AT its blob oid. A redacted blob's content no
6
+ * longer hashes to its oid, so it can't propagate through content-addressed `put`
7
+ * (which would re-address it). Instead the receiver syncs the (tiny) Redaction object
8
+ * and writes the deterministic stub in place — evicting plaintext it already had, or
9
+ * creating the stub on a fresh clone that never received the original. Idempotent.
10
+ *
11
+ * When governance is active (memberships exist), only redactions validly signed by an
12
+ * admin member are applied — a forged redaction can't be used to evict (DoS) someone
13
+ * else's blob. With no governance, all redactions apply (legacy/trust-all).
14
+ */
15
+ export declare function applyRedactions(store: ObjectStore): Promise<number>;
16
+ //# sourceMappingURL=applyRedactions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyRedactions.d.ts","sourceRoot":"","sources":["../../src/store/applyRedactions.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,IAAI,EAAyB,MAAM,qBAAqB,CAAC;AAEvE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAQvE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBzE"}
@@ -0,0 +1,60 @@
1
+ // Redaction propagation (docs/08/12 WS-E): apply every Redaction tombstone present in
2
+ // a store to its blob, evicting the bytes locally while preserving the oid. A replica
3
+ // that pulled the plaintext before the redaction calls this on pull; the hub calls it
4
+ // when it receives a redaction. The stub is deterministic (reason-derived) so all
5
+ // replicas converge to the same content.
6
+ import { Buffer } from "node:buffer";
7
+ import { verifyMessage } from "../core/identity.js";
8
+ export function redactedStub(reason, redactionOid) {
9
+ return {
10
+ type: "blob",
11
+ data: Buffer.from(`[REDACTED: ${reason}]`).toString("base64"),
12
+ encoding: "base64",
13
+ redacted: true,
14
+ redactionOid,
15
+ };
16
+ }
17
+ /**
18
+ * Materialize every Redaction's stub AT its blob oid. A redacted blob's content no
19
+ * longer hashes to its oid, so it can't propagate through content-addressed `put`
20
+ * (which would re-address it). Instead the receiver syncs the (tiny) Redaction object
21
+ * and writes the deterministic stub in place — evicting plaintext it already had, or
22
+ * creating the stub on a fresh clone that never received the original. Idempotent.
23
+ *
24
+ * When governance is active (memberships exist), only redactions validly signed by an
25
+ * admin member are applied — a forged redaction can't be used to evict (DoS) someone
26
+ * else's blob. With no governance, all redactions apply (legacy/trust-all).
27
+ */
28
+ export async function applyRedactions(store) {
29
+ const admins = new Map();
30
+ for await (const m of store.list("membership")) {
31
+ if (!m.revokedAt && m.role === "admin")
32
+ admins.set(m.actorId, m);
33
+ }
34
+ const governed = admins.size > 0 || (await first(store.list("membership"))) !== null;
35
+ const verified = (red) => {
36
+ if (!governed)
37
+ return true; // no governance → trust all
38
+ const m = admins.get(red.by);
39
+ if (!m || !red.sig)
40
+ return false;
41
+ return verifyMessage(m.publicKey, red.oid, red.sig.sig);
42
+ };
43
+ let applied = 0;
44
+ for await (const red of store.list("redaction")) {
45
+ if (!verified(red))
46
+ continue; // skip forged / non-admin redactions
47
+ const cur = (await store.has(red.blobOid)) ? await store.get(red.blobOid) : null;
48
+ if (cur?.redacted && cur.redactionOid === red.oid)
49
+ continue; // already applied
50
+ await store.overwriteAt(red.blobOid, redactedStub(red.reason, red.oid));
51
+ applied++;
52
+ }
53
+ return applied;
54
+ }
55
+ async function first(gen) {
56
+ for await (const x of gen)
57
+ return x;
58
+ return null;
59
+ }
60
+ //# sourceMappingURL=applyRedactions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyRedactions.js","sourceRoot":"","sources":["../../src/store/applyRedactions.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,sFAAsF;AACtF,sFAAsF;AACtF,kFAAkF;AAClF,yCAAyC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,YAAoB;IAC/D,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC7D,QAAQ,EAAE,QAAQ;QAClB,QAAQ,EAAE,IAAI;QACd,YAAY;KACb,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAkB;IACtD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC7C,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAa,YAAY,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;YAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,CAAa,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACjG,MAAM,QAAQ,GAAG,CAAC,GAAc,EAAW,EAAE;QAC3C,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,CAAC,4BAA4B;QACxD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QACjC,OAAO,aAAa,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,GAAa,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpE,CAAC,CAAC;IAEF,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAY,WAAW,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,qCAAqC;QACnE,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,GAAG,CAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvF,IAAI,GAAG,EAAE,QAAQ,IAAI,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,GAAG;YAAE,SAAS,CAAC,kBAAkB;QAC/E,MAAM,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAa,CAAC,CAAC,CAAC;QAClF,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,KAAK,CAAI,GAAsB;IAC5C,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface LockOptions {
2
+ /** Give up acquiring after this long. */
3
+ maxWaitMs?: number;
4
+ /** Treat a held lock older than this as abandoned and reclaim it. */
5
+ staleMs?: number;
6
+ }
7
+ /**
8
+ * Run `fn` while holding the named lock under `locksDir`. Serializes concurrent
9
+ * callers (same process or different processes) on the same name.
10
+ */
11
+ export declare function withLock<T>(locksDir: string, name: string, fn: () => Promise<T>, opts?: LockOptions): Promise<T>;
12
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/store/lock.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAyCZ"}
@@ -0,0 +1,63 @@
1
+ // Cross-process advisory lock for the few read-modify-write paths that genuinely
2
+ // race (lease acquisition). Most of the store is append-only + content-addressed
3
+ // and needs no lock; this is only for "read the current set, decide, then write".
4
+ //
5
+ // Implemented with mkdir, which is atomic create-if-not-exists on POSIX and Windows:
6
+ // exactly one caller wins the directory creation. A stale lock (holder crashed) is
7
+ // reclaimed after `staleMs`. Always released in a finally.
8
+ import { mkdir, writeFile, readFile, rm } from "node:fs/promises";
9
+ import { join } from "node:path";
10
+ function sleep(ms) {
11
+ return new Promise((r) => setTimeout(r, ms));
12
+ }
13
+ /**
14
+ * Run `fn` while holding the named lock under `locksDir`. Serializes concurrent
15
+ * callers (same process or different processes) on the same name.
16
+ */
17
+ export async function withLock(locksDir, name, fn, opts = {}) {
18
+ const maxWaitMs = opts.maxWaitMs ?? 10_000;
19
+ const staleMs = opts.staleMs ?? 30_000;
20
+ const lockPath = join(locksDir, `${name}.lock`);
21
+ const ownerFile = join(lockPath, "owner");
22
+ const start = Date.now();
23
+ for (;;) {
24
+ try {
25
+ await mkdir(lockPath); // atomic; EEXIST if already held
26
+ await writeFile(ownerFile, `${process.pid}:${Date.now()}`, "utf8");
27
+ break;
28
+ }
29
+ catch (e) {
30
+ const code = e.code;
31
+ if (code === "ENOENT") {
32
+ await mkdir(locksDir, { recursive: true }); // locks dir not there yet
33
+ continue;
34
+ }
35
+ if (code !== "EEXIST")
36
+ throw e;
37
+ // Held by someone — reclaim if stale, else back off.
38
+ let stale = false;
39
+ try {
40
+ const ts = Number((await readFile(ownerFile, "utf8")).split(":")[1] ?? "0");
41
+ if (Date.now() - ts > staleMs)
42
+ stale = true;
43
+ }
44
+ catch {
45
+ // owner file not written yet (acquire-in-progress) → treat as fresh
46
+ }
47
+ if (stale) {
48
+ await rm(lockPath, { recursive: true, force: true });
49
+ continue;
50
+ }
51
+ if (Date.now() - start > maxWaitMs)
52
+ throw new Error(`lock timeout acquiring "${name}"`);
53
+ await sleep(5 + Math.floor(Math.random() * 15)); // jittered backoff
54
+ }
55
+ }
56
+ try {
57
+ return await fn();
58
+ }
59
+ finally {
60
+ await rm(lockPath, { recursive: true, force: true });
61
+ }
62
+ }
63
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/store/lock.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,iFAAiF;AACjF,kFAAkF;AAClF,EAAE;AACF,qFAAqF;AACrF,mFAAmF;AACnF,2DAA2D;AAE3D,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC;AASD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,QAAgB,EAChB,IAAY,EACZ,EAAoB,EACpB,OAAoB,EAAE;IAEtB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,SAAS,CAAC;QACR,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,iCAAiC;YACxD,MAAM,SAAS,CAAC,SAAS,EAAE,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;YACnE,MAAM;QACR,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,GAAI,CAA2B,CAAC,IAAI,CAAC;YAC/C,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,0BAA0B;gBACtE,SAAS;YACX,CAAC;YACD,IAAI,IAAI,KAAK,QAAQ;gBAAE,MAAM,CAAC,CAAC;YAC/B,qDAAqD;YACrD,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBAC5E,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO;oBAAE,KAAK,GAAG,IAAI,CAAC;YAC9C,CAAC;YAAC,MAAM,CAAC;gBACP,oEAAoE;YACtE,CAAC;YACD,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrD,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,GAAG,CAAC,CAAC;YACxF,MAAM,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,mBAAmB;QACtE,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;AACH,CAAC"}
@@ -0,0 +1,127 @@
1
+ import { Buffer } from "node:buffer";
2
+ import { type LockOptions } from "./lock.ts";
3
+ import type { AnyObject, ObjectType } from "../objects/types.ts";
4
+ /**
5
+ * A stored object's bytes could not be decoded — bit-rot, truncation, or a torn write
6
+ * that slipped past the atomic-write guarantee (D1). Typed (not an opaque `SyntaxError`)
7
+ * and carries the offending `oid` so a decode failure deep in `materialize`/`pull` is
8
+ * actionable: the caller knows exactly which object to `fsck`/repair. F1 (docs/13).
9
+ */
10
+ export declare class CorruptObjectError extends Error {
11
+ readonly oid?: string;
12
+ constructor(message: string, opts?: {
13
+ oid?: string;
14
+ cause?: unknown;
15
+ });
16
+ }
17
+ export declare class ObjectStore {
18
+ #private;
19
+ readonly root: string;
20
+ constructor(repoDir: string);
21
+ init(): Promise<void>;
22
+ /**
23
+ * Atomically write a derived auxiliary file under the repo's `.avcs` root, reusing the
24
+ * crash-safe temp→fsync→rename→fsync-dir path (D1/D2). For repo-managed caches the
25
+ * store doesn't model as objects — e.g. the compaction snapshot. `relPath` is resolved
26
+ * under root; parent dirs are created. Crash-safe: a reader sees old-or-complete, and
27
+ * the file survives a hard crash once this returns.
28
+ */
29
+ writeAux(relPath: string, data: string | Buffer): Promise<void>;
30
+ /** Durably append a line to an auxiliary log under the repo's `.avcs` root (e.g. the
31
+ * hub audit log, E7). Reuses the fsync-file + fsync-dir append path. */
32
+ appendAux(relPath: string, line: string): Promise<void>;
33
+ /** Run a critical section under a named cross-process lock (see lock.ts). */
34
+ withLock<T>(name: string, fn: () => Promise<T>, opts?: LockOptions): Promise<T>;
35
+ appendEntityIndex(key: string, oid: string): Promise<void>;
36
+ readEntityIndex(key: string): Promise<string[]>;
37
+ static isRepo(repoDir: string): boolean;
38
+ /**
39
+ * Write an object. Returns its oid. Idempotent: writing identical content yields
40
+ * the same oid and is a no-op if already present (append-only honored).
41
+ */
42
+ put<T extends AnyObject>(obj: T): Promise<string>;
43
+ /**
44
+ * Op-log in authoring/arrival order (docs/11 A5). Returns oids of every operation ever
45
+ * written, deduped, FIRST-WRITE order preserved. May include oids of operations later
46
+ * removed by GC (the store is the source of truth — callers tolerate a missing object).
47
+ * Empty for a store created before the op-log existed; `rebuildOpLog` backfills it.
48
+ */
49
+ readOpLog(): Promise<string[]>;
50
+ /**
51
+ * Object-log in arrival order (E5): oids of EVERY object ever written, deduped,
52
+ * first-write order preserved. A store predating the log (or one that just upgraded)
53
+ * is backfilled once from a full scan — that scan order becomes this hub's stable
54
+ * append base. Append-only afterward, so an index into it is a valid sync cursor.
55
+ */
56
+ readObjLog(): Promise<string[]>;
57
+ /** Backfill the op-log from a full scan (for stores predating it, or after corruption).
58
+ * Rewrites it atomically to the current operation set in canonical oid order. */
59
+ rebuildOpLog(): Promise<number>;
60
+ /**
61
+ * Redaction exception (Phase 12): overwrite the object stored AT `oid` with new
62
+ * content that no longer hashes to it. This is the ONE place append-only/content-
63
+ * addressing yields — used only by an admin-signed Redaction to evict leaked bytes
64
+ * while keeping the oid (and every reference to it) valid.
65
+ */
66
+ overwriteAt(oid: string, obj: AnyObject): Promise<void>;
67
+ /**
68
+ * GC exception: delete an object file. Used only by `repo.gc` to reclaim objects
69
+ * that are unreachable from the authoritative graph (orphan blobs, expired
70
+ * quarantined ops). The append-only audit history of accepted ops is never removed.
71
+ */
72
+ deleteObject(oid: string): Promise<void>;
73
+ get<T extends AnyObject = AnyObject>(oid: string): Promise<T>;
74
+ has(oid: string): Promise<boolean>;
75
+ /** Stream every object of a given type — loose objects first, then packed ones (B2). */
76
+ list<T extends AnyObject = AnyObject>(type?: ObjectType): AsyncGenerator<T>;
77
+ /**
78
+ * Fold all loose NON-blob objects into a new packfile (+ index), then delete the loose
79
+ * copies. Idempotent in effect (already-packed objects have no loose file). Reads stay
80
+ * correct throughout (loose-first, then packs). Returns how many objects were packed.
81
+ */
82
+ pack(): Promise<{
83
+ packed: number;
84
+ }>;
85
+ collect<T extends AnyObject = AnyObject>(type?: ObjectType): Promise<T[]>;
86
+ setRef(name: string, oid: string): Promise<void>;
87
+ getRef(name: string): Promise<string | null>;
88
+ /** All named refs as name → oid (for hub governance distribution). */
89
+ listRefs(): Promise<Map<string, string>>;
90
+ setHead(viewName: string): Promise<void>;
91
+ getHead(): Promise<string>;
92
+ /**
93
+ * Re-derive every stored object's content address and compare it to the address it
94
+ * lives at — catching bit-rot, truncation, and a torn write that slipped past the
95
+ * atomic-write guarantee. A redacted blob is exempt: its bytes were deliberately
96
+ * overwritten by an admin Redaction and no longer hash to their oid (that's the one
97
+ * sanctioned exception to content-addressing). Also reconciles the op-log against the
98
+ * actual operation set: operation objects missing from the log are real drift (the
99
+ * fast-path could skip them); log entries with no object are GC'd/lost (informational).
100
+ * Read-only unless `rebuild` is set, which rewrites the op-log to match the object set.
101
+ */
102
+ fsck(opts?: {
103
+ rebuild?: boolean;
104
+ }): Promise<FsckReport>;
105
+ }
106
+ export interface FsckReport {
107
+ objectsChecked: number;
108
+ /** true iff no corrupt object and no operation missing from the op-log. */
109
+ ok: boolean;
110
+ /** Objects whose content no longer hashes to the address they live at. */
111
+ corrupt: {
112
+ oid: string;
113
+ reason: string;
114
+ }[];
115
+ oplogDrift: {
116
+ /** operation objects absent from the op-log — real drift (fast-path could skip them). */
117
+ opsMissingFromLog: string[];
118
+ /** op-log entries with no backing object — GC'd quarantine ops or lost (informational). */
119
+ logEntriesMissingObject: string[];
120
+ };
121
+ /** Present when `fsck({rebuild:true})` repaired op-log drift. */
122
+ repaired?: {
123
+ oplogRebuilt: boolean;
124
+ oplogEntries: number;
125
+ };
126
+ }
127
+ //# sourceMappingURL=objectStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objectStore.d.ts","sourceRoot":"","sources":["../../src/store/objectStore.ts"],"names":[],"mappings":"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"}