@izagood/avcs 0.1.0 → 0.1.1

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.
@@ -37,7 +37,7 @@ export interface Blob extends BaseObject {
37
37
  redactionOid?: string;
38
38
  }
39
39
  export type IntentKind = "feature" | "bugfix" | "refactor" | "formatting" | "generated";
40
- /** A symbol/file/glob scope the intent is allowed to touch. */
40
+ /** A file/glob scope the intent is allowed to touch. */
41
41
  export type ScopeRef = string;
42
42
  /** Machine-checkable invariants. `constraints` (NL) is human prose; these are enforced. */
43
43
  export type ConstraintKind = "forbid_public_api_break" | "forbid_behavior_change" | "require_tests";
@@ -65,25 +65,24 @@ export interface Session extends BaseObject {
65
65
  toolCalls: string[];
66
66
  startedAt: string;
67
67
  }
68
- export type OperationKind = "put_file" | "delete_file" | "rename_file" | "set_symbol" | "rename_symbol" | "move_symbol" | "note";
68
+ export type OperationKind = "put_file" | "edit_file" | "delete_file" | "rename_file" | "note";
69
69
  export interface OperationTarget {
70
70
  /** What conceptual entity this op changes. */
71
- entityKind: "file" | "symbol" | "contract" | "config" | "test";
72
- /** Stable entity id. file: the path. symbol: `<path>#<symbolName>`. */
71
+ entityKind: "file" | "contract" | "config" | "test";
72
+ /** Stable entity id for files, the path. */
73
73
  entityId: string;
74
74
  }
75
75
  export interface OperationBody {
76
76
  kind: OperationKind;
77
- /** put_file / rename_file / set_symbol destination path. */
77
+ /** put_file / edit_file / rename_file destination path. */
78
78
  path?: string;
79
79
  /** rename_file source path. */
80
80
  fromPath?: string;
81
- /** put_file content, or set_symbol's new symbol text. */
81
+ /** put_file / edit_file new full file content (blob oid). */
82
82
  blobOid?: string;
83
- /** set_symbol / rename_symbol: the top-level symbol name (the OLD name for rename). */
84
- symbolName?: string;
85
- /** rename_symbol: the new symbol name. */
86
- newName?: string;
83
+ /** edit_file: the blob this edit was derived from — the 3-way merge base.
84
+ * Empty/absent ⇒ base is the empty file. */
85
+ baseBlobOid?: string;
87
86
  }
88
87
  export interface Operation extends BaseObject {
89
88
  type: "operation";
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/objects/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/objects/types.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { Decision, Evidence, Intent, Operation, OperationStatus, Policy } from "../objects/types.ts";
2
+ import { type ConflictRegion } from "../merge/merge3.ts";
2
3
  export interface ConflictOption {
3
4
  opOid: string;
4
5
  actor: string;
@@ -19,18 +20,6 @@ export interface Conflict {
19
20
  /** Actor ids that own this scope and should make the call (Phase 5). */
20
21
  requiredOwners?: string[];
21
22
  }
22
- /**
23
- * A merge that is text-clean but meaning-broken: one op changed a public contract
24
- * while another depends on the old one. Detected (and escalated) by the repo's
25
- * semantic pass, not the core grouping.
26
- */
27
- export interface SemanticConflict {
28
- kind: "contract_break";
29
- symbol: string;
30
- breakingOp: string;
31
- dependentOps: string[];
32
- reason: string;
33
- }
34
23
  /** A contest the policy resolved by itself — recorded so auto-merges are auditable. */
35
24
  export interface AutoDecision {
36
25
  key: string;
@@ -47,15 +36,16 @@ export interface ReductionResult {
47
36
  statuses: Map<string, OperationStatus>;
48
37
  conflicts: Conflict[];
49
38
  autoDecisions: AutoDecision[];
50
- /** Text-clean but meaning-broken merges, escalated by the repo's semantic pass. */
51
- semanticConflicts: SemanticConflict[];
39
+ /** Line-level text merge conflicts among concurrent edit_file ops, filled by the repo's
40
+ * post-reduce pass (detectFileConflicts). reduce() itself leaves this empty. */
41
+ fileConflicts: FileConflict[];
52
42
  /** Frontier op ids: accepted ops that no other accepted op descends from. */
53
43
  headOps: string[];
54
44
  /**
55
- * Content for blob oids synthesized during reduction (symbol-level merges produce
56
- * file content that is not any single stored blob). oid → content. The caller
57
- * persists or writes these directly. Synthetic oids are content-derived, so the
58
- * treeHash that references them stays deterministic.
45
+ * Content for blob oids synthesized during reduction (a 3-way text merge produces file
46
+ * content that is not any single stored blob). oid → content. The caller persists or
47
+ * writes these directly. Synthetic oids are content-derived, so the treeHash that
48
+ * references them stays deterministic.
59
49
  */
60
50
  synthBlobs: Map<string, string>;
61
51
  }
@@ -67,7 +57,7 @@ export interface ReduceInput {
67
57
  policy: Policy;
68
58
  /** Which statuses get projected into the tree. Default: accepted only. */
69
59
  materializeStatuses?: OperationStatus[];
70
- /** blob oid → content, for ops that need file text (set_symbol). */
60
+ /** blob oid → content, for ops that need file text (edit_file 3-way merge). */
71
61
  blobContent?: Map<string, string>;
72
62
  /** actorId → bounded reliability nudge (Phase 5 trust learning). */
73
63
  reliability?: Map<string, number>;
@@ -81,20 +71,23 @@ export interface ReduceInput {
81
71
  */
82
72
  export declare function keysOf(op: Operation): string[];
83
73
  export declare function conflictIdFor(key: string): string;
84
- export interface CrossConflict {
74
+ /** A file whose concurrent edits overlapped at the line level — a genuine text merge
75
+ * conflict. Language-neutral: detected purely by merge3 over the file's content. */
76
+ export interface FileConflict {
85
77
  file: string;
86
78
  ops: string[];
79
+ regions: ConflictRegion[];
87
80
  }
88
81
  /**
89
- * A whole-file op (put_file/delete/rename) and a set_symbol on the SAME file are keyed
90
- * differently (file:… vs symbol:…#…), so the reducer's grouping never makes them
91
- * contend. When they are CONCURRENT (neither a causal ancestor of the other), letting
92
- * both apply makes the result depend on kahnOrder's lamport (authoring-order) tie-break
93
- * — non-deterministic. This finds those pairs among ACCEPTED ops so the repo can hold
94
- * them back (re-reduce) and surface a conflict. Ancestor relations (scaffold→edit) are
95
- * intentionally not flagged.
82
+ * Detect line-level merge conflicts among CONCURRENT accepted edit_file ops on the same
83
+ * file. The reducer's grouping accepts all such ops (their disjoint hunks compose); this
84
+ * pass runs the authoritative N-way `merge3` over the file's concurrent frontier to find
85
+ * the ones whose hunks actually OVERLAP, so the repo can surface a Conflict / hold back.
86
+ *
87
+ * No language knowledge merge3 compares lines. Ancestor relations (an edit built on a
88
+ * prior edit) are not concurrent and never flagged. Deterministic over canonical order.
96
89
  */
97
- export declare function detectCrossGranularity(ops: Operation[], result: ReductionResult): CrossConflict[];
90
+ export declare function detectFileConflicts(ops: Operation[], result: ReductionResult, blobContent: Map<string, string>): FileConflict[];
98
91
  /** A single group's locally-decided statuses + the conflicts/autoDecisions it emitted. */
99
92
  export interface PerKeyDecision {
100
93
  local: Map<string, OperationStatus>;
@@ -1 +1 @@
1
- {"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/reducer/reducer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/reducer/reducer.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@
11
11
  // Phase-2 AST upgrade only swaps `keysOf` (the unit of contention) and `applyOp`.
12
12
  import { sha256hex, canonicalize } from "../core/canonical.js";
13
13
  import { evaluateOp } from "./policy.js";
14
- import { spliceSymbol, renameSymbol, extractSymbol } from "../semantic/symbols.js";
14
+ import { merge3 } from "../merge/merge3.js";
15
15
  import { ownersFor } from "../policy/owners.js";
16
16
  // Status precedence when an op belongs to several contended keys (rename touches
17
17
  // two). The strictest verdict across its groups wins.
@@ -36,20 +36,13 @@ export function keysOf(op) {
36
36
  const b = op.body;
37
37
  switch (b.kind) {
38
38
  case "put_file":
39
- return [`file:${b.path ?? op.target.entityId}`];
39
+ case "edit_file":
40
40
  case "delete_file":
41
+ // Every file op contends on the file. Concurrent edit_file ops on the same file
42
+ // are 3-way text-merged at materialization; only overlapping line ranges conflict.
41
43
  return [`file:${b.path ?? op.target.entityId}`];
42
44
  case "rename_file":
43
45
  return [`file:${b.fromPath ?? op.target.entityId}`, `file:${b.path ?? op.target.entityId}`];
44
- case "set_symbol":
45
- // Symbol-granular: two edits to different symbols of the same file auto-merge.
46
- return [`symbol:${b.path}#${b.symbolName}`];
47
- case "rename_symbol":
48
- // Contends on both the old and new symbol names within the file.
49
- return [`symbol:${b.path}#${b.symbolName}`, `symbol:${b.path}#${b.newName}`];
50
- case "move_symbol":
51
- // Contends on the symbol at its source and its destination.
52
- return [`symbol:${b.fromPath}#${b.symbolName}`, `symbol:${b.path}#${b.symbolName}`];
53
46
  case "note":
54
47
  return [];
55
48
  }
@@ -123,53 +116,42 @@ export function conflictIdFor(key) {
123
116
  return `conflict_${sha256hex(key).slice(0, 24)}`;
124
117
  }
125
118
  /**
126
- * A whole-file op (put_file/delete/rename) and a set_symbol on the SAME file are keyed
127
- * differently (file:… vs symbol:…#…), so the reducer's grouping never makes them
128
- * contend. When they are CONCURRENT (neither a causal ancestor of the other), letting
129
- * both apply makes the result depend on kahnOrder's lamport (authoring-order) tie-break
130
- * — non-deterministic. This finds those pairs among ACCEPTED ops so the repo can hold
131
- * them back (re-reduce) and surface a conflict. Ancestor relations (scaffold→edit) are
132
- * intentionally not flagged.
119
+ * Detect line-level merge conflicts among CONCURRENT accepted edit_file ops on the same
120
+ * file. The reducer's grouping accepts all such ops (their disjoint hunks compose); this
121
+ * pass runs the authoritative N-way `merge3` over the file's concurrent frontier to find
122
+ * the ones whose hunks actually OVERLAP, so the repo can surface a Conflict / hold back.
123
+ *
124
+ * No language knowledge merge3 compares lines. Ancestor relations (an edit built on a
125
+ * prior edit) are not concurrent and never flagged. Deterministic over canonical order.
133
126
  */
134
- export function detectCrossGranularity(ops, result) {
127
+ export function detectFileConflicts(ops, result, blobContent) {
135
128
  const anc = ancestry(ops);
136
- const fileOf = (o) => {
137
- const b = o.body;
138
- if (b.kind === "put_file" || b.kind === "delete_file")
139
- return b.path ?? o.target.entityId;
140
- if (b.kind === "rename_file")
141
- return b.fromPath ?? o.target.entityId;
142
- if (b.kind === "set_symbol")
143
- return b.path ?? null;
144
- return null;
145
- };
146
- const isWhole = (o) => o.body.kind === "put_file" || o.body.kind === "delete_file" || o.body.kind === "rename_file";
129
+ const resolve = (oid) => (oid ? blobContent.get(oid) ?? "" : "");
147
130
  const byFile = new Map();
148
131
  for (const o of ops) {
132
+ if (o.body.kind !== "edit_file")
133
+ continue;
149
134
  if (result.statuses.get(o.oid) !== "accepted")
150
135
  continue;
151
- const f = fileOf(o);
152
- if (f)
153
- (byFile.get(f) ?? byFile.set(f, []).get(f)).push(o);
136
+ const f = o.body.path ?? o.target.entityId;
137
+ (byFile.get(f) ?? byFile.set(f, []).get(f)).push(o);
154
138
  }
155
139
  const out = [];
156
140
  for (const [file, fops] of byFile) {
157
- const whole = fops.filter(isWhole);
158
- const syms = fops.filter((o) => o.body.kind === "set_symbol");
159
- if (!whole.length || !syms.length)
160
- continue;
161
- const involved = new Set();
162
- for (const w of whole)
163
- for (const s of syms) {
164
- const wId = w.oid;
165
- const sId = s.oid;
166
- if (!anc.get(wId)?.has(sId) && !anc.get(sId)?.has(wId)) {
167
- involved.add(wId);
168
- involved.add(sId);
169
- }
170
- }
171
- if (involved.size)
172
- out.push({ file, ops: [...involved].sort() });
141
+ // Concurrent frontier: ops not a causal ancestor of another edit on this file.
142
+ const frontier = fops.filter((o) => !fops.some((p) => p !== o && anc.get(p.oid)?.has(o.oid)));
143
+ if (frontier.length < 2)
144
+ continue; // linear chain ⇒ no concurrency ⇒ no conflict
145
+ const ordered = [...frontier].sort((a, b) => a.lamport - b.lamport || cmp(a.oid, b.oid));
146
+ // Common 3-way base: the content all variants were derived from. Use the shared
147
+ // baseBlobOid when they agree (the normal case); else the lexically-first for a
148
+ // deterministic, conservative comparison.
149
+ const baseOid = [...new Set(ordered.map((o) => o.body.baseBlobOid ?? ""))].sort()[0] ?? "";
150
+ const base = resolve(baseOid);
151
+ const variants = ordered.map((o) => resolve(o.body.blobOid));
152
+ const m = merge3(base, variants);
153
+ if (!m.clean)
154
+ out.push({ file, ops: ordered.map((o) => o.oid), regions: m.conflicts });
173
155
  }
174
156
  return out;
175
157
  }
@@ -203,21 +185,18 @@ function pathsOf(op) {
203
185
  const b = op.body;
204
186
  switch (b.kind) {
205
187
  case "put_file":
188
+ case "edit_file":
206
189
  case "delete_file":
207
- case "set_symbol":
208
- case "rename_symbol":
209
190
  return [b.path ?? op.target.entityId];
210
191
  case "rename_file":
211
192
  return [b.fromPath ?? op.target.entityId, b.path ?? op.target.entityId];
212
- case "move_symbol":
213
- return [b.fromPath ?? op.target.entityId, b.path ?? op.target.entityId];
214
193
  case "note":
215
194
  return [];
216
195
  }
217
196
  }
218
- /** rename_file/move_symbol read a SOURCE path's live content, coupling two paths. */
197
+ /** rename_file reads a SOURCE path's live content, coupling two paths. */
219
198
  function isCrossPath(op) {
220
- return op.body.kind === "rename_file" || op.body.kind === "move_symbol";
199
+ return op.body.kind === "rename_file";
221
200
  }
222
201
  /** Keep only the synth-blob entries the final tree actually references (drops the
223
202
  * intermediate splices that get overwritten). Makes synthBlobs a pure function of the
@@ -340,7 +319,7 @@ export function snapshotReduce(input) {
340
319
  if (keysOf(o).length === 0 && statuses.get(o.oid) === "proposed")
341
320
  statuses.set(o.oid, "accepted");
342
321
  const { tree, treeHash, headOps, synthBlobs } = materializeProjection(ops, statuses, anc, materializeStatuses, input.blobContent ?? new Map());
343
- const result = { tree, treeHash, statuses, conflicts, autoDecisions, semanticConflicts: [], headOps, synthBlobs };
322
+ const result = { tree, treeHash, statuses, conflicts, autoDecisions, fileConflicts: [], headOps, synthBlobs };
344
323
  const stats = { groupsTotal: groups.size, groupsRecomputed: groups.size, groupsReused: 0, dirtyKeys: groups.size };
345
324
  return { input, result, perKey, groupOrder, groupMembers, stats };
346
325
  }
@@ -569,7 +548,7 @@ export function reduceIncremental(snap, next) {
569
548
  dirtyPaths.add(p);
570
549
  }
571
550
  const { tree, treeHash, headOps, synthBlobs } = materializeIncremental(ops, statuses, anc, materializeStatuses, next.blobContent ?? new Map(), snap.result, dirtyPaths);
572
- const result = { tree, treeHash, statuses, conflicts, autoDecisions, semanticConflicts: [], headOps, synthBlobs };
551
+ const result = { tree, treeHash, statuses, conflicts, autoDecisions, fileConflicts: [], headOps, synthBlobs };
573
552
  const stats = { groupsTotal: groups.size, groupsRecomputed: recomputed, groupsReused: reused, dirtyKeys: dirty.size };
574
553
  return { input: next, result, perKey, groupOrder, groupMembers, stats };
575
554
  }
@@ -595,7 +574,7 @@ export function serializeSnapshot(snap) {
595
574
  statuses: mapToEntries(r.statuses),
596
575
  conflicts: r.conflicts,
597
576
  autoDecisions: r.autoDecisions,
598
- semanticConflicts: r.semanticConflicts,
577
+ fileConflicts: r.fileConflicts,
599
578
  headOps: r.headOps,
600
579
  synthBlobs: mapToEntries(r.synthBlobs),
601
580
  },
@@ -626,7 +605,7 @@ export function deserializeSnapshot(raw) {
626
605
  statuses: entriesToMap(r.statuses),
627
606
  conflicts: r.conflicts,
628
607
  autoDecisions: r.autoDecisions,
629
- semanticConflicts: r.semanticConflicts,
608
+ fileConflicts: r.fileConflicts,
630
609
  headOps: r.headOps,
631
610
  synthBlobs: entriesToMap(r.synthBlobs),
632
611
  };
@@ -683,6 +662,16 @@ function decideGroup(key, groupOps, anc, verdicts, evalOf, policy, conflicts, au
683
662
  out.set(o.oid, "rejected");
684
663
  const viable = remaining.filter((o) => !blocked.includes(o));
685
664
  const needsHuman = viable.some((o) => evalOf(o, inConflict).requiresHuman);
665
+ // Concurrent TEXT edits (all edit_file) auto-merge: accept all. Their disjoint line
666
+ // hunks compose deterministically (merge3); an actual line overlap is surfaced by
667
+ // detectFileConflicts over the full op set, NOT resolved by dropping a sibling here.
668
+ // (A winner-pick would silently lose the loser's non-overlapping changes.) When a
669
+ // human is required (e.g. declared API break) we still fall through to escalation.
670
+ if (viable.length > 1 && !needsHuman && viable.every((o) => o.body.kind === "edit_file")) {
671
+ for (const o of viable)
672
+ out.set(o.oid, "accepted");
673
+ return out;
674
+ }
686
675
  const ranked = [...viable].sort((a, b) => {
687
676
  const d = evalOf(b, inConflict).score - evalOf(a, inConflict).score;
688
677
  if (d !== 0)
@@ -783,6 +772,23 @@ function applyOp(tree, op, blobContent, synthBlobs) {
783
772
  if (b.path && b.blobOid)
784
773
  tree.set(b.path, b.blobOid);
785
774
  break;
775
+ case "edit_file": {
776
+ if (!b.path || !b.blobOid)
777
+ break;
778
+ const opNew = resolve(b.blobOid);
779
+ const opBase = b.baseBlobOid ? resolve(b.baseBlobOid) : "";
780
+ const currentOid = tree.get(b.path);
781
+ const current = currentOid !== undefined ? resolve(currentOid) : opBase;
782
+ // Apply this op's patch (opBase→opNew) onto the accumulated content. Disjoint
783
+ // line changes compose (order-independent); an overlap with a prior concurrent op
784
+ // keeps `current` (deterministic incumbent) — the overlap is reported separately
785
+ // by detectFileConflicts over the full op set. Language-neutral: pure text.
786
+ const m = merge3(opBase, [current, opNew], { onConflict: "first" });
787
+ const synthOid = `blob_${sha256hex(m.merged).slice(0, 32)}`;
788
+ synthBlobs.set(synthOid, m.merged);
789
+ tree.set(b.path, synthOid);
790
+ break;
791
+ }
786
792
  case "delete_file":
787
793
  tree.delete(b.path ?? op.target.entityId);
788
794
  break;
@@ -795,48 +801,6 @@ function applyOp(tree, op, blobContent, synthBlobs) {
795
801
  }
796
802
  }
797
803
  break;
798
- case "set_symbol": {
799
- if (!b.path || !b.symbolName || !b.blobOid)
800
- break;
801
- const currentOid = tree.get(b.path);
802
- const current = currentOid !== undefined ? resolve(currentOid) : "";
803
- const merged = spliceSymbol(current, b.symbolName, resolve(b.blobOid));
804
- const synthOid = `blob_${sha256hex(merged).slice(0, 32)}`;
805
- synthBlobs.set(synthOid, merged);
806
- tree.set(b.path, synthOid);
807
- break;
808
- }
809
- case "rename_symbol": {
810
- if (!b.path || !b.symbolName || !b.newName)
811
- break;
812
- const currentOid = tree.get(b.path);
813
- if (currentOid === undefined)
814
- break;
815
- const renamed = renameSymbol(resolve(currentOid), b.symbolName, b.newName);
816
- const synthOid = `blob_${sha256hex(renamed).slice(0, 32)}`;
817
- synthBlobs.set(synthOid, renamed);
818
- tree.set(b.path, synthOid);
819
- break;
820
- }
821
- case "move_symbol": {
822
- if (!b.fromPath || !b.path || !b.symbolName)
823
- break;
824
- const fromOid = tree.get(b.fromPath);
825
- if (fromOid === undefined)
826
- break;
827
- const extracted = extractSymbol(resolve(fromOid), b.symbolName);
828
- if (!extracted)
829
- break;
830
- const toContent = tree.get(b.path) !== undefined ? resolve(tree.get(b.path)) : "";
831
- const newTo = spliceSymbol(toContent, b.symbolName, extracted.text);
832
- const fromSynth = `blob_${sha256hex(extracted.rest).slice(0, 32)}`;
833
- const toSynth = `blob_${sha256hex(newTo).slice(0, 32)}`;
834
- synthBlobs.set(fromSynth, extracted.rest);
835
- synthBlobs.set(toSynth, newTo);
836
- tree.set(b.fromPath, fromSynth);
837
- tree.set(b.path, toSynth);
838
- break;
839
- }
840
804
  case "note":
841
805
  break;
842
806
  }