@inerrata-corporation/errata 2.0.21-dev.3952 → 2.0.21-dev.3993

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.
package/errata.mjs CHANGED
@@ -8591,11 +8591,11 @@ var init_nl = __esm({
8591
8591
  case "too_small": {
8592
8592
  const adj = issue2.inclusive ? ">=" : ">";
8593
8593
  const sizing = getSizing(issue2.origin);
8594
- const shortName = issue2.origin === "date" ? "vroeg" : issue2.origin === "string" ? "kort" : "klein";
8594
+ const shortName2 = issue2.origin === "date" ? "vroeg" : issue2.origin === "string" ? "kort" : "klein";
8595
8595
  if (sizing) {
8596
- return `Te ${shortName}: verwacht dat ${issue2.origin} ${adj}${issue2.minimum.toString()} ${sizing.unit} ${sizing.verb}`;
8596
+ return `Te ${shortName2}: verwacht dat ${issue2.origin} ${adj}${issue2.minimum.toString()} ${sizing.unit} ${sizing.verb}`;
8597
8597
  }
8598
- return `Te ${shortName}: verwacht dat ${issue2.origin} ${adj}${issue2.minimum.toString()} is`;
8598
+ return `Te ${shortName2}: verwacht dat ${issue2.origin} ${adj}${issue2.minimum.toString()} is`;
8599
8599
  }
8600
8600
  case "invalid_format": {
8601
8601
  const _issue = issue2;
@@ -19021,6 +19021,32 @@ var init_leiden = __esm({
19021
19021
  }
19022
19022
  });
19023
19023
 
19024
+ // ../../packages/math/src/community-floor.ts
19025
+ function communitySizeFloor(domainSize) {
19026
+ if (!(domainSize > 1)) return COMMUNITY_MIN_SIZE;
19027
+ return Math.max(COMMUNITY_MIN_SIZE, Math.ceil(COMMUNITY_FLOOR_SCALE * Math.log(domainSize)));
19028
+ }
19029
+ function communityDomain(memberDomains, domainSize) {
19030
+ const held = /* @__PURE__ */ new Map();
19031
+ for (const domains of memberDomains) for (const d of new Set(domains)) held.set(d, (held.get(d) ?? 0) + 1);
19032
+ let best = null;
19033
+ for (const [d, n] of held) {
19034
+ if (n * 2 < memberDomains.length) continue;
19035
+ const size = domainSize.get(d) ?? Infinity;
19036
+ const bestSize = best === null ? Infinity : domainSize.get(best) ?? Infinity;
19037
+ if (best === null || size < bestSize || size === bestSize && d < best) best = d;
19038
+ }
19039
+ return best;
19040
+ }
19041
+ var COMMUNITY_MIN_SIZE, COMMUNITY_FLOOR_SCALE;
19042
+ var init_community_floor = __esm({
19043
+ "../../packages/math/src/community-floor.ts"() {
19044
+ "use strict";
19045
+ COMMUNITY_MIN_SIZE = 2;
19046
+ COMMUNITY_FLOOR_SCALE = 0.5;
19047
+ }
19048
+ });
19049
+
19024
19050
  // ../../packages/math/src/spectral.ts
19025
19051
  var init_spectral = __esm({
19026
19052
  "../../packages/math/src/spectral.ts"() {
@@ -19102,7 +19128,8 @@ var init_a2_motif_quality = __esm({
19102
19128
 
19103
19129
  // ../../packages/math/src/motif-gate.ts
19104
19130
  function motifDecision(input) {
19105
- if (input.memberCount < MOTIF_MIN_MEMBERS) {
19131
+ const isIncoherent = input.coherence !== void 0 && input.coherence < MOTIF_MIN_COHERENCE;
19132
+ if (input.memberCount < MOTIF_MIN_MEMBERS || isIncoherent) {
19106
19133
  return {
19107
19134
  isCandidate: false,
19108
19135
  survivedRuns: input.priorSurvivedRuns,
@@ -19126,7 +19153,7 @@ function motifDecision(input) {
19126
19153
  motifConfidence: Math.round(a2.qualityScore * 100) / 100
19127
19154
  };
19128
19155
  }
19129
- var MOTIF_MIN_MEMBERS, MOTIF_MIN_SURVIVED;
19156
+ var MOTIF_MIN_MEMBERS, MOTIF_MIN_SURVIVED, MOTIF_MIN_COHERENCE;
19130
19157
  var init_motif_gate = __esm({
19131
19158
  "../../packages/math/src/motif-gate.ts"() {
19132
19159
  "use strict";
@@ -19134,6 +19161,7 @@ var init_motif_gate = __esm({
19134
19161
  init_a2_motif_quality();
19135
19162
  MOTIF_MIN_MEMBERS = 5;
19136
19163
  MOTIF_MIN_SURVIVED = 2;
19164
+ MOTIF_MIN_COHERENCE = 0.5;
19137
19165
  }
19138
19166
  });
19139
19167
 
@@ -19292,6 +19320,7 @@ var init_src3 = __esm({
19292
19320
  init_triage();
19293
19321
  init_relevance();
19294
19322
  init_leiden();
19323
+ init_community_floor();
19295
19324
  init_spectral();
19296
19325
  init_community_health();
19297
19326
  init_void_demand();
@@ -20404,9 +20433,9 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
20404
20433
  * absent, which is how incremental region assembly drops dead endpoints). */
20405
20434
  ranksForMany(ids) {
20406
20435
  const out2 = /* @__PURE__ */ new Map();
20407
- const CHUNK = 400;
20408
- for (let i2 = 0; i2 < ids.length; i2 += CHUNK) {
20409
- const chunk = ids.slice(i2, i2 + CHUNK);
20436
+ const CHUNK2 = 400;
20437
+ for (let i2 = 0; i2 < ids.length; i2 += CHUNK2) {
20438
+ const chunk = ids.slice(i2, i2 + CHUNK2);
20410
20439
  const placeholders = chunk.map(() => "?").join(", ");
20411
20440
  const rows = this.db.prepare(
20412
20441
  `SELECT id, page_rank FROM nodes WHERE id IN (${placeholders}) AND valid_to IS NULL`
@@ -20437,9 +20466,9 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
20437
20466
  }
20438
20467
  edgesForMany(ids, col) {
20439
20468
  const out2 = [];
20440
- const CHUNK = 400;
20441
- for (let i2 = 0; i2 < ids.length; i2 += CHUNK) {
20442
- const chunk = ids.slice(i2, i2 + CHUNK);
20469
+ const CHUNK2 = 400;
20470
+ for (let i2 = 0; i2 < ids.length; i2 += CHUNK2) {
20471
+ const chunk = ids.slice(i2, i2 + CHUNK2);
20443
20472
  const placeholders = chunk.map(() => "?").join(", ");
20444
20473
  const rows = this.db.prepare(
20445
20474
  `SELECT from_id, to_id, type FROM edges WHERE ${col} IN (${placeholders}) AND valid_to IS NULL`
@@ -20458,9 +20487,9 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
20458
20487
  }
20459
20488
  reviveReobserved(relPaths, workspaceId2, since) {
20460
20489
  let revived = 0;
20461
- const CHUNK = 400;
20462
- for (let i2 = 0; i2 < relPaths.length; i2 += CHUNK) {
20463
- const slice = relPaths.slice(i2, i2 + CHUNK);
20490
+ const CHUNK2 = 400;
20491
+ for (let i2 = 0; i2 < relPaths.length; i2 += CHUNK2) {
20492
+ const slice = relPaths.slice(i2, i2 + CHUNK2);
20464
20493
  if (slice.length === 0) continue;
20465
20494
  const r = this.db.prepare(
20466
20495
  `UPDATE nodes SET valid_to = NULL
@@ -20486,9 +20515,9 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
20486
20515
  }
20487
20516
  liveNodeIdsByCloudNodeId(cloudIds) {
20488
20517
  const out2 = /* @__PURE__ */ new Map();
20489
- const CHUNK = 900;
20490
- for (let i2 = 0; i2 < cloudIds.length; i2 += CHUNK) {
20491
- const slice = cloudIds.slice(i2, i2 + CHUNK);
20518
+ const CHUNK2 = 900;
20519
+ for (let i2 = 0; i2 < cloudIds.length; i2 += CHUNK2) {
20520
+ const slice = cloudIds.slice(i2, i2 + CHUNK2);
20492
20521
  if (slice.length === 0) continue;
20493
20522
  const rows = this.db.prepare(
20494
20523
  `SELECT id, json_extract(attrs_json, '$.cloudNodeId') AS cloud FROM nodes INDEXED BY nodes_cloud_node_id WHERE json_extract(attrs_json, '$.cloudNodeId') IN (${slice.map(() => "?").join(",")}) AND valid_to IS NULL ORDER BY id`
@@ -20499,9 +20528,9 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
20499
20528
  }
20500
20529
  liveNodeIds(ids) {
20501
20530
  const live3 = /* @__PURE__ */ new Set();
20502
- const CHUNK = 900;
20503
- for (let i2 = 0; i2 < ids.length; i2 += CHUNK) {
20504
- const slice = ids.slice(i2, i2 + CHUNK);
20531
+ const CHUNK2 = 900;
20532
+ for (let i2 = 0; i2 < ids.length; i2 += CHUNK2) {
20533
+ const slice = ids.slice(i2, i2 + CHUNK2);
20505
20534
  if (slice.length === 0) continue;
20506
20535
  const rows = this.db.prepare(
20507
20536
  `SELECT id FROM nodes WHERE valid_to IS NULL AND id IN (${slice.map(() => "?").join(",")})`
@@ -23696,9 +23725,9 @@ function migrateProjectAlias(l2, opts) {
23696
23725
  }
23697
23726
  }
23698
23727
  }
23699
- const CHUNK = 200;
23700
- for (let i2 = 0; i2 < nodeUpdates.length; i2 += CHUNK) {
23701
- const slice = nodeUpdates.slice(i2, i2 + CHUNK);
23728
+ const CHUNK2 = 200;
23729
+ for (let i2 = 0; i2 < nodeUpdates.length; i2 += CHUNK2) {
23730
+ const slice = nodeUpdates.slice(i2, i2 + CHUNK2);
23702
23731
  l2.transaction(() => {
23703
23732
  for (const u of slice) {
23704
23733
  l2.updateNode(u.id, { attrs: u.attrs, lastUpdatedAt: opts.ts });
@@ -23706,8 +23735,8 @@ function migrateProjectAlias(l2, opts) {
23706
23735
  }
23707
23736
  });
23708
23737
  }
23709
- for (let i2 = 0; i2 < edgeUpdates.length; i2 += CHUNK) {
23710
- const slice = edgeUpdates.slice(i2, i2 + CHUNK);
23738
+ for (let i2 = 0; i2 < edgeUpdates.length; i2 += CHUNK2) {
23739
+ const slice = edgeUpdates.slice(i2, i2 + CHUNK2);
23711
23740
  l2.transaction(() => {
23712
23741
  for (const u of slice) {
23713
23742
  l2.updateEdge(u.id, { attrs: u.attrs, lastSeenAt: opts.ts });
@@ -24586,17 +24615,52 @@ var init_abstraction = __esm({
24586
24615
  });
24587
24616
 
24588
24617
  // ../../packages/local-graph/src/community.ts
24618
+ function domainKey(id) {
24619
+ return id.replace(/(.)@[^@/]*$/, "$1");
24620
+ }
24621
+ function candidateDomains(store, ids, labelOf) {
24622
+ const own = /* @__PURE__ */ new Map();
24623
+ for (const id of ids) {
24624
+ const label = labelOf.get(id);
24625
+ if (label !== "Problem" && label !== "Vulnerability") continue;
24626
+ const domains = store.outEdges(id, DOMAIN_EDGES).map((e) => domainKey(e.to));
24627
+ if (domains.length > 0) own.set(id, domains);
24628
+ }
24629
+ const out2 = new Map(own);
24630
+ for (const id of ids) {
24631
+ const label = labelOf.get(id);
24632
+ if (label !== "RootCause" && label !== "Solution") continue;
24633
+ const inherited = store.inEdges(id, DOMAIN_INHERIT_EDGES).flatMap((e) => own.get(e.from) ?? []);
24634
+ if (inherited.length > 0) out2.set(id, [...new Set(inherited)]);
24635
+ }
24636
+ return out2;
24637
+ }
24589
24638
  function detectLocalCommunities(store, opts = {}) {
24590
- const minSize = opts.minCommunitySize ?? DEFAULT_MIN_COMMUNITY_SIZE;
24591
- const report = { candidates: 0, communities: 0, joint: 0, assigned: 0 };
24592
- const ids = /* @__PURE__ */ new Set();
24639
+ const report = { candidates: 0, communities: 0, joint: 0, assigned: 0, belowFloor: 0, cleared: 0 };
24640
+ const nodes = /* @__PURE__ */ new Map();
24641
+ const unowned = [];
24593
24642
  for (const label of JOINT_COMMUNITY_LABELS) {
24594
24643
  for (const n of store.findNodesByLabel(label)) {
24595
- if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
24596
- ids.add(n.id);
24644
+ if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) unowned.push(n);
24645
+ else nodes.set(n.id, n);
24597
24646
  }
24598
24647
  }
24648
+ const ids = new Set(nodes.keys());
24599
24649
  report.candidates = ids.size;
24650
+ for (const label of SEMANTIC_NODE_LABELS) {
24651
+ if (!JOINT_COMMUNITY_LABELS.includes(label)) unowned.push(...store.findNodesByLabel(label));
24652
+ }
24653
+ store.transaction(() => {
24654
+ for (const n of unowned) {
24655
+ if (n.attrs["localCommunity"] !== void 0) {
24656
+ const { localCommunity: _gone, ...rest2 } = n.attrs;
24657
+ store.updateNode(n.id, { attrs: rest2 });
24658
+ }
24659
+ if (!n.community || n.attrs["source"] === "cloud") continue;
24660
+ store.setCommunity(n.id, null);
24661
+ report.cleared++;
24662
+ }
24663
+ });
24600
24664
  if (ids.size === 0) return report;
24601
24665
  const adj = /* @__PURE__ */ new Map();
24602
24666
  const protect = [];
@@ -24608,6 +24672,7 @@ function detectLocalCommunities(store, opts = {}) {
24608
24672
  for (const id of ids) {
24609
24673
  for (const e of store.outEdges(id, [...JOINT_COMMUNITY_EDGES])) {
24610
24674
  if (!ids.has(e.to)) continue;
24675
+ if (e.type === "INSTANCE_OF" && e.extractionSource === "bko-inferred") continue;
24611
24676
  const conf = e.confidence > 0 ? e.confidence : 0.5;
24612
24677
  const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
24613
24678
  add(id, e.to, w);
@@ -24622,22 +24687,33 @@ function detectLocalCommunities(store, opts = {}) {
24622
24687
  l.push(id);
24623
24688
  members.set(c, l);
24624
24689
  }
24690
+ const domains = candidateDomains(store, ids, new Map([...nodes].map(([id, n]) => [id, n.label])));
24691
+ const domainSize = /* @__PURE__ */ new Map();
24692
+ for (const ds of domains.values()) for (const d of new Set(ds)) domainSize.set(d, (domainSize.get(d) ?? 0) + 1);
24693
+ const floorOf = (mem) => {
24694
+ if (opts.minCommunitySize !== void 0) return opts.minCommunitySize;
24695
+ const domain2 = communityDomain(mem.map((id) => domains.get(id) ?? []), domainSize);
24696
+ return communitySizeFloor(domain2 === null ? ids.size : domainSize.get(domain2));
24697
+ };
24625
24698
  store.transaction(() => {
24626
24699
  for (const [cid, mem] of members) {
24627
- const qualifies = mem.length >= minSize;
24700
+ const qualifies = mem.length >= floorOf(mem);
24701
+ if (!qualifies && mem.length >= 2) report.belowFloor++;
24628
24702
  let hasLocal = false;
24629
24703
  let hasCloud = false;
24630
24704
  for (const id of mem) {
24631
- const n = store.getNode(id);
24632
- if (!n) continue;
24705
+ const n = nodes.get(id);
24633
24706
  const pulled = n.attrs["source"] === "cloud";
24634
24707
  if (pulled) hasCloud = true;
24635
24708
  else hasLocal = true;
24636
- const nextAttrs = { ...n.attrs };
24637
- if (qualifies) nextAttrs["localCommunity"] = cid;
24638
- else delete nextAttrs["localCommunity"];
24639
- store.updateNode(id, { attrs: nextAttrs });
24640
- if (!pulled) store.setCommunity(id, qualifies ? cid : null);
24709
+ const want = qualifies ? cid : void 0;
24710
+ if (n.attrs["localCommunity"] !== want) {
24711
+ const nextAttrs = { ...n.attrs };
24712
+ if (want) nextAttrs["localCommunity"] = want;
24713
+ else delete nextAttrs["localCommunity"];
24714
+ store.updateNode(id, { attrs: nextAttrs });
24715
+ }
24716
+ if (!pulled && (n.community ?? null) !== (want ?? null)) store.setCommunity(id, want ?? null);
24641
24717
  }
24642
24718
  if (qualifies) {
24643
24719
  report.communities++;
@@ -24721,7 +24797,7 @@ function communityInductionRequests(store, opts = {}) {
24721
24797
  };
24722
24798
  }).filter((r) => r.members.length >= MIN_INDUCTION_MEMBERS).slice(0, maxCommunities);
24723
24799
  }
24724
- var JOINT_COMMUNITY_LABELS, JOINT_COMMUNITY_EDGES, DEFAULT_MIN_COMMUNITY_SIZE, MIN_INDUCTION_MEMBERS;
24800
+ var JOINT_COMMUNITY_LABELS, JOINT_COMMUNITY_EDGES, DOMAIN_EDGES, DOMAIN_INHERIT_EDGES, MIN_INDUCTION_MEMBERS;
24725
24801
  var init_community2 = __esm({
24726
24802
  "../../packages/local-graph/src/community.ts"() {
24727
24803
  "use strict";
@@ -24747,7 +24823,8 @@ var init_community2 = __esm({
24747
24823
  "CONFIRMS",
24748
24824
  "RELATES_TO"
24749
24825
  ];
24750
- DEFAULT_MIN_COMMUNITY_SIZE = 2;
24826
+ DOMAIN_EDGES = ["DEPENDS_ON", "CONCERNS", "OCCURS_IN"];
24827
+ DOMAIN_INHERIT_EDGES = ["CAUSED_BY", "SOLVED_BY", "FIXED_BY"];
24751
24828
  MIN_INDUCTION_MEMBERS = 3;
24752
24829
  }
24753
24830
  });
@@ -25715,6 +25792,16 @@ function isPassiveInjectable(node2, atCommit) {
25715
25792
  }
25716
25793
  return false;
25717
25794
  }
25795
+ function motifSeeds(snapshot, statedIntent) {
25796
+ const intent = statedIntent ?? snapshot.statedIntent;
25797
+ const said = intent ? intent.hits.map((h) => h.id) : (snapshot.workingFile?.priors?.openProblems ?? []).map((p) => p.id);
25798
+ const fresh = snapshot.recentProblems.slice(0, 3).map((r) => r.node.id);
25799
+ return [.../* @__PURE__ */ new Set([...said, ...fresh])].slice(0, MOTIF_SEEDS);
25800
+ }
25801
+ function rankMotifs(pool, signal, k = MOTIF_BAND) {
25802
+ if (!signal) return pool.slice(0, k);
25803
+ return pool.filter((m) => (signal.get(m.id) ?? 0) > 0).sort((a, b) => signal.get(b.id) - signal.get(a.id) || b.pageRank - a.pageRank).slice(0, k);
25804
+ }
25718
25805
  function buildSnapshot(opts) {
25719
25806
  const problems = [...opts.store.findNodesByLabel("Problem"), ...opts.store.findNodesByLabel("Vulnerability")].filter((p) => p.attrs["mergedInto"] === void 0 && historyReadPolicy(p, { mode: "passive", atCommit: opts.atCommit }).allow);
25720
25807
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
@@ -25745,11 +25832,12 @@ function buildSnapshot(opts) {
25745
25832
  return { node: p, ...solution ? { solution } : {} };
25746
25833
  });
25747
25834
  const recentResolved = resolvedPool.slice(0, RECENT_RESOLVED);
25748
- const motifs = [
25835
+ const motifPool = [
25749
25836
  ...opts.store.findNodesByLabel("Pattern"),
25750
25837
  ...opts.store.findNodesByLabel("Technique"),
25751
25838
  ...opts.store.findNodesByLabel("AntiPattern")
25752
- ].filter((n) => historyReadPolicy(n, { mode: "passive", atCommit: opts.atCommit }).allow).sort((a, b) => b.pageRank - a.pageRank).slice(0, 10);
25839
+ ].filter((n) => historyReadPolicy(n, { mode: "passive", atCommit: opts.atCommit }).allow).filter((n) => !(Number(n.attrs["missedRuns"] ?? 0) > 0)).sort((a, b) => b.pageRank - a.pageRank).slice(0, MOTIF_POOL).map((n) => n.embedding.length > 0 ? { ...n, embedding: [] } : n);
25840
+ const motifs = rankMotifs(motifPool, void 0);
25753
25841
  const workingFile = opts.workingFile ? sliceForFile(opts.store, opts.workingFile, opts.atCommit) : void 0;
25754
25842
  const byEpisode = /* @__PURE__ */ new Map();
25755
25843
  for (const sol of opts.store.findNodesByLabel("Solution")) {
@@ -25816,6 +25904,7 @@ function buildSnapshot(opts) {
25816
25904
  ...opts.selfCiteSkips && opts.selfCiteSkips > 0 ? { selfCiteSkips: opts.selfCiteSkips } : {},
25817
25905
  ...domainNudge ? { domainNudge } : {},
25818
25906
  motifs,
25907
+ motifPool,
25819
25908
  reviewCount: opts.reviewCount,
25820
25909
  reviewUiUrl: opts.reviewUiUrl,
25821
25910
  ...workingFile ? { workingFile } : {},
@@ -26072,7 +26161,7 @@ function renderSnapshot(s) {
26072
26161
  }
26073
26162
  lines.push("### Prior knowledge sampled from the shared graph");
26074
26163
  if (s.motifs.length === 0) {
26075
- lines.push("- _no motif matches yet \u2014 cold-start ingest pending_");
26164
+ lines.push("- _no recurring pattern reaches this work yet_");
26076
26165
  } else {
26077
26166
  for (const m of s.motifs) {
26078
26167
  lines.push(`- **${m.label}:** ${m.description}${tagOf(m)}`);
@@ -26348,6 +26437,7 @@ function assembleAgentContext(opts) {
26348
26437
  if (opts.reviewItems?.length) snapshot.reviewItems = [...opts.reviewItems];
26349
26438
  if (opts.statedIntent) snapshot.statedIntent = opts.statedIntent;
26350
26439
  if (opts.sharedPriors?.length) snapshot.sharedPriors = [...opts.sharedPriors];
26440
+ if (opts.motifSignal) snapshot.motifs = rankMotifs(snapshot.motifPool ?? snapshot.motifs, opts.motifSignal);
26351
26441
  if (opts.remote && opts.remote.length > 0) {
26352
26442
  const seen = /* @__PURE__ */ new Set();
26353
26443
  const remote = opts.remote.filter((n) => {
@@ -26399,13 +26489,16 @@ function diffRenderLedger(before, after) {
26399
26489
  for (const i2 of before) (survived.has(key(i2)) ? shown : evicted).push(i2);
26400
26490
  return { shown, evicted };
26401
26491
  }
26402
- var RECENT_OPEN, RECENT_RESOLVED, RECENT_CONSTRAINTS, SCOPE_POOL_FACTOR, RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, PROMPT_RECUE, SPAWN_SHARE_HINT, SUBAGENT_OWN_BLOCK_NOTE, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
26492
+ var MOTIF_BAND, MOTIF_POOL, MOTIF_SEEDS, RECENT_OPEN, RECENT_RESOLVED, RECENT_CONSTRAINTS, SCOPE_POOL_FACTOR, RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, PROMPT_INTENT_CUE, PROMPT_RECUE, SPAWN_SHARE_HINT, SUBAGENT_OWN_BLOCK_NOTE, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
26403
26493
  var init_render = __esm({
26404
26494
  "../../packages/context-writer/src/render.ts"() {
26405
26495
  "use strict";
26406
26496
  init_src5();
26407
26497
  init_src2();
26408
26498
  init_src();
26499
+ MOTIF_BAND = 10;
26500
+ MOTIF_POOL = 1e3;
26501
+ MOTIF_SEEDS = 8;
26409
26502
  RECENT_OPEN = 8;
26410
26503
  RECENT_RESOLVED = 4;
26411
26504
  RECENT_CONSTRAINTS = 3;
@@ -26417,7 +26510,8 @@ var init_render = __esm({
26417
26510
  ${RECALL_FIRST_BODY}`;
26418
26511
  SEARCH_IMPERATIVE_HEADER = "### \u{1F50E} PRIORS ARE SEEDS \u2014 a sample, not the whole graph";
26419
26512
  SEARCH_IMPERATIVE_BODY = "Everything below is a budgeted slice of a much larger graph, not all errata knows. New request \u2014 any task, not just a bug? Say what it is \u2014 we search on it between your tool calls and put what we find here:\n```errata-intent\nintent: <the work in hand, in your words>\n```\nNarration, not a detour: no tool call, no plan change. It is the one signal we cannot derive from your edits \u2014 everything else here is guessed from the files you touched.";
26420
- PROMPT_RECUE = "errata (context block above unchanged): new request \u2192 state it first:\n```errata-intent\nintent: <this request, in your words>\n```\nTag ALL project work, not just bugs \u2014 features, UX, refactors, research: problems you hit (even in code you just wrote) [!\u2026], decisions (constraint: why), approaches (tried: \u2026)/(failed: \u2026), the area (domain: \u2026). Restate tags in your final reply.";
26513
+ PROMPT_INTENT_CUE = "new request \u2192 state it first:\n```errata-intent\nintent: <this request, in your words>\n```\nTag ALL project work, not just bugs \u2014 features, UX, refactors, research: problems you hit (even in code you just wrote) [!\u2026], decisions (constraint: why), approaches (tried: \u2026)/(failed: \u2026), the area (domain: \u2026). Restate tags in your final reply.";
26514
+ PROMPT_RECUE = `errata (context block above unchanged): ${PROMPT_INTENT_CUE}`;
26421
26515
  SPAWN_SHARE_HINT = "_Spawning a subagent? It gets its own errata block, seeded from its task \u2014 none of the priors here. To hand it some, put this in its prompt (or `priors: all` for this whole block):_\n```errata-share\npriors: [handle], [handle]\n```";
26422
26516
  SUBAGENT_OWN_BLOCK_NOTE = "_This block is yours: seeded from the task you were given, then from what you state and touch. The agent that spawned you sees a different one._";
26423
26517
  EVICTION_ORDER = [
@@ -26600,6 +26694,99 @@ var init_select_durable_memory = __esm({
26600
26694
  }
26601
26695
  });
26602
26696
 
26697
+ // ../../packages/context-writer/src/delta.ts
26698
+ function parseSections(body2) {
26699
+ const sections = [{ heading: "", units: [] }];
26700
+ let cur = sections[0];
26701
+ let item2 = null;
26702
+ for (const line of body2.split("\n")) {
26703
+ if (line.startsWith("### ")) {
26704
+ item2 = null;
26705
+ cur = { heading: line, units: [] };
26706
+ sections.push(cur);
26707
+ } else if (ITEM_START.test(line)) {
26708
+ item2 = [line];
26709
+ cur.units.push(item2);
26710
+ } else if (item2 && (line.startsWith(" ") || line.startsWith(" "))) {
26711
+ item2.push(line);
26712
+ } else {
26713
+ item2 = null;
26714
+ cur.units.push([line]);
26715
+ }
26716
+ }
26717
+ return sections;
26718
+ }
26719
+ function itemRef(headline) {
26720
+ const handles = [...headline.matchAll(HANDLE_RE)].map((m) => m[1]);
26721
+ if (handles.length) return `[${handles[handles.length - 1]}]`;
26722
+ const tick = TICK_RE.exec(headline);
26723
+ return tick ? `\`${tick[1]}\`` : null;
26724
+ }
26725
+ function renderContextDelta(prev, next) {
26726
+ const before = parseSections(prev);
26727
+ const after = parseSections(next);
26728
+ const prevByHeading = new Map(before.map((s) => [s.heading, s]));
26729
+ const nextHeadings = new Set(after.map((s) => s.heading));
26730
+ const unchanged = [];
26731
+ const out2 = [];
26732
+ for (const sec of after) {
26733
+ const old = prevByHeading.get(sec.heading);
26734
+ if (old && sectionText(old) === sectionText(sec)) {
26735
+ if (sec.heading) unchanged.push(shortName(sec.heading));
26736
+ continue;
26737
+ }
26738
+ const oldHeadlines = new Set((old?.units ?? []).filter(isItem).map((u) => u[0]));
26739
+ const oldProse = new Set((old?.units ?? []).filter((u) => !isItem(u)).map((u) => u[0]));
26740
+ const body2 = [];
26741
+ const stillCurrent = [];
26742
+ let unnamed = 0;
26743
+ for (const u of sec.units) {
26744
+ if (!isItem(u)) {
26745
+ if (old && u[0].trim() && oldProse.has(u[0])) continue;
26746
+ body2.push(u[0]);
26747
+ continue;
26748
+ }
26749
+ const head2 = u[0];
26750
+ if (!oldHeadlines.has(head2)) {
26751
+ body2.push(...u);
26752
+ continue;
26753
+ }
26754
+ const ref = itemRef(head2);
26755
+ if (ref) stillCurrent.push(ref);
26756
+ else unnamed++;
26757
+ }
26758
+ if (stillCurrent.length || unnamed) {
26759
+ const more = unnamed ? `${stillCurrent.length ? " + " : ""}${unnamed} more as last shown` : "";
26760
+ body2.push(`- _still current, as last shown:_ ${stillCurrent.join(", ")}${more}`);
26761
+ }
26762
+ const content = body2.filter((l) => l.trim()).length ? body2 : ["- _(now empty)_"];
26763
+ if (sec.heading) out2.push(sec.heading);
26764
+ out2.push(...content);
26765
+ if (out2[out2.length - 1] !== "") out2.push("");
26766
+ }
26767
+ const retired = before.filter((s) => s.heading && !nextHeadings.has(s.heading)).map((s) => shortName(s.heading));
26768
+ if (!out2.some((l) => l.trim()) && !retired.length) return null;
26769
+ const lines = [];
26770
+ if (unchanged.length) lines.push(`_Unchanged: ${unchanged.join(" \xB7 ")}._`);
26771
+ if (retired.length) lines.push(`_No longer current: ${retired.join(" \xB7 ")}._`);
26772
+ if (lines.length) lines.push("");
26773
+ return [...lines, ...out2].join("\n").replace(/\n{3,}/g, "\n\n").trim();
26774
+ }
26775
+ var DELTA_MAX_FRACTION, DELTA_PREAMBLE, ITEM_START, HANDLE_RE, TICK_RE, isItem, sectionText, shortName;
26776
+ var init_delta = __esm({
26777
+ "../../packages/context-writer/src/delta.ts"() {
26778
+ "use strict";
26779
+ DELTA_MAX_FRACTION = 2 / 3;
26780
+ DELTA_PREAMBLE = "The errata daemon has updated your live workspace context. Only what CHANGED is below \u2014 the rest of your last errata context block still holds. Sections listed as unchanged are as last shown; in a changed section, items not listed (in full or by `[handle]`) are retired.";
26781
+ ITEM_START = /^- /;
26782
+ HANDLE_RE = /`\[([^\]`]+)\]`/g;
26783
+ TICK_RE = /`([^`\s]+)`/;
26784
+ isItem = (u) => ITEM_START.test(u[0]);
26785
+ sectionText = (s) => s.units.map((u) => u.join("\n")).join("\n").trim();
26786
+ shortName = (heading) => heading.replace(/^###\s+/, "").replace(/\s+—.*$/, "").trim();
26787
+ }
26788
+ });
26789
+
26603
26790
  // ../../packages/context-writer/src/index.ts
26604
26791
  var init_src6 = __esm({
26605
26792
  "../../packages/context-writer/src/index.ts"() {
@@ -26611,6 +26798,7 @@ var init_src6 = __esm({
26611
26798
  init_bleed_memory();
26612
26799
  init_bleed_rules();
26613
26800
  init_select_durable_memory();
26801
+ init_delta();
26614
26802
  }
26615
26803
  });
26616
26804
 
@@ -30654,6 +30842,131 @@ var init_dist = __esm({
30654
30842
  }
30655
30843
  });
30656
30844
 
30845
+ // src/context-baselines.ts
30846
+ import { closeSync, openSync, readSync, statSync } from "node:fs";
30847
+ function deliveryMarker(hash2) {
30848
+ return `<!-- errata-context ${hash2.slice(0, 16)} -->`;
30849
+ }
30850
+ function appendedSince(path2, offset, needle) {
30851
+ let fd;
30852
+ try {
30853
+ fd = openSync(path2, "r");
30854
+ } catch {
30855
+ return { found: false, turnRan: false };
30856
+ }
30857
+ try {
30858
+ const size = statSync(path2).size;
30859
+ const keep = Math.max(needle.length, MODEL_TURN.length);
30860
+ const buf = Buffer.alloc(CHUNK);
30861
+ let carry = "";
30862
+ let turnRan = false;
30863
+ for (let pos = Math.min(offset, size); pos < size; pos += CHUNK) {
30864
+ const n = readSync(fd, buf, 0, CHUNK, pos);
30865
+ const text = carry + buf.toString("utf8", 0, n);
30866
+ if (text.includes(needle)) return { found: true, turnRan: true };
30867
+ turnRan ||= text.includes(MODEL_TURN);
30868
+ carry = text.slice(-keep);
30869
+ }
30870
+ return { found: false, turnRan };
30871
+ } finally {
30872
+ closeSync(fd);
30873
+ }
30874
+ }
30875
+ function sizeOf(path2) {
30876
+ try {
30877
+ return statSync(path2).size;
30878
+ } catch {
30879
+ return 0;
30880
+ }
30881
+ }
30882
+ var CHUNK, UNVERIFIABLE_AFTER, MODEL_TURN, ContextBaselines;
30883
+ var init_context_baselines = __esm({
30884
+ "src/context-baselines.ts"() {
30885
+ "use strict";
30886
+ CHUNK = 1 << 20;
30887
+ UNVERIFIABLE_AFTER = 2;
30888
+ MODEL_TURN = '"type":"assistant"';
30889
+ ContextBaselines = class {
30890
+ /** `hashes` seeds confirmed hashes with no body (as after a daemon restart). */
30891
+ constructor(hashes = /* @__PURE__ */ new Map()) {
30892
+ this.hashes = hashes;
30893
+ }
30894
+ bodies = /* @__PURE__ */ new Map();
30895
+ pending = /* @__PURE__ */ new Map();
30896
+ /** Per key: sends confirmed so far, or a running count of unconfirmed ones while none has been. */
30897
+ track = /* @__PURE__ */ new Map();
30898
+ /** Window resets seen, by SessionStart source. */
30899
+ resets = /* @__PURE__ */ new Map();
30900
+ /** Sends checked against the transcript: arrived, or never showed up. */
30901
+ deliveries = { confirmed: 0, lost: 0 };
30902
+ /** Resolve this key's pending send against its transcript before deciding anything. */
30903
+ settle(key) {
30904
+ const p = this.pending.get(key);
30905
+ if (!p) return;
30906
+ const seen = appendedSince(p.transcript, p.offset, p.marker);
30907
+ if (!seen.found && !seen.turnRan) return;
30908
+ this.pending.delete(key);
30909
+ const t = this.track.get(key) ?? { confirmed: false, lost: 0 };
30910
+ if (seen.found) {
30911
+ this.deliveries.confirmed++;
30912
+ t.confirmed = true;
30913
+ this.confirm(key, p);
30914
+ } else {
30915
+ this.deliveries.lost++;
30916
+ t.lost++;
30917
+ if (!t.confirmed && t.lost >= UNVERIFIABLE_AFTER) this.confirm(key, p);
30918
+ }
30919
+ this.track.set(key, t);
30920
+ }
30921
+ /** What the session is taken to hold: an undecided send, else the last confirmed one. */
30922
+ hash(key) {
30923
+ return this.pending.get(key)?.hash ?? this.hashes.get(key);
30924
+ }
30925
+ body(key) {
30926
+ return this.pending.get(key)?.body ?? this.bodies.get(key);
30927
+ }
30928
+ /** A payload for `block` was sent; with a transcript it waits there to be confirmed. */
30929
+ record(key, block, transcript) {
30930
+ const t = this.track.get(key);
30931
+ if (!transcript || t && !t.confirmed && t.lost >= UNVERIFIABLE_AFTER) {
30932
+ this.pending.delete(key);
30933
+ this.confirm(key, block);
30934
+ return;
30935
+ }
30936
+ this.pending.set(key, {
30937
+ hash: block.hash,
30938
+ body: block.body,
30939
+ marker: deliveryMarker(block.hash),
30940
+ transcript,
30941
+ offset: sizeOf(transcript)
30942
+ });
30943
+ }
30944
+ /**
30945
+ * The harness dropped this session's window (`compact` / `clear` / `resume`),
30946
+ * or the session ended (`end`). Clearing or ending a session also ends its
30947
+ * subagents; a compaction leaves their own windows alone.
30948
+ */
30949
+ reset(key, source) {
30950
+ this.resets.set(source, (this.resets.get(source) ?? 0) + 1);
30951
+ this.drop(key);
30952
+ if ((source === "clear" || source === "end") && !key.includes("#")) {
30953
+ for (const k of /* @__PURE__ */ new Set([...this.hashes.keys(), ...this.pending.keys()])) if (k.startsWith(`${key}#`)) this.drop(k);
30954
+ }
30955
+ }
30956
+ confirm(key, d) {
30957
+ this.hashes.set(key, d.hash);
30958
+ this.bodies.set(key, d.body);
30959
+ }
30960
+ drop(key) {
30961
+ this.hashes.delete(key);
30962
+ this.bodies.delete(key);
30963
+ this.pending.delete(key);
30964
+ this.track.delete(key);
30965
+ }
30966
+ };
30967
+ }
30968
+ });
30969
+
30657
30970
  // ../../packages/generalizer/src/review-detector.ts
30658
30971
  function evaluateForReview(node2, prevTier) {
30659
30972
  if (node2.cumulativeSurprise >= REVIEW_SURPRISE_THRESHOLD) {
@@ -31789,11 +32102,11 @@ var init_generalizer = __esm({
31789
32102
  function layerOf(kind) {
31790
32103
  return kind === "Technique" ? "technique" : kind === "AntiPattern" ? "antipattern" : "pattern";
31791
32104
  }
31792
- function motifTitle(members, layer, instanceCount) {
31793
- const top = [...members].sort(
31794
- (a, b) => b.extractionConfidence - a.extractionConfidence
31795
- )[0];
31796
- return `${layer} \xD7${instanceCount} (exemplar): ${top?.description ?? "recurring problem cluster"}`;
32105
+ function motifTitle(exemplar, layer, instanceCount) {
32106
+ return `${layer} \xD7${instanceCount} (exemplar): ${exemplar?.description ?? "recurring problem cluster"}`;
32107
+ }
32108
+ function exemplarOf(members) {
32109
+ return [...members].sort((a, b) => b.extractionConfidence - a.extractionConfidence || a.id.localeCompare(b.id))[0];
31797
32110
  }
31798
32111
  function classifyMotif(store, instances, promoted) {
31799
32112
  if (!promoted || instances.length === 0) return "Pattern";
@@ -31802,70 +32115,141 @@ function classifyMotif(store, instances, promoted) {
31802
32115
  if (solvedShare <= 0.2) return "AntiPattern";
31803
32116
  return "Pattern";
31804
32117
  }
32118
+ function isDerived(e) {
32119
+ return e.extractionSource === "bko-inferred";
32120
+ }
32121
+ function motifCoherence(store, members, instances) {
32122
+ if (instances.length === 0) return 0;
32123
+ const types = [...JOINT_COMMUNITY_EDGES];
32124
+ const near = /* @__PURE__ */ new Map();
32125
+ const link = (a, b) => {
32126
+ const s = near.get(a) ?? /* @__PURE__ */ new Set();
32127
+ s.add(b);
32128
+ near.set(a, s);
32129
+ };
32130
+ for (const id of members) {
32131
+ for (const e of store.outEdges(id, types)) {
32132
+ if (!members.has(e.to) || isDerived(e)) continue;
32133
+ link(id, e.to);
32134
+ link(e.to, id);
32135
+ }
32136
+ }
32137
+ const isInstance = new Set(instances);
32138
+ let bound = 0;
32139
+ for (const p of instances) {
32140
+ const hop1 = near.get(p) ?? /* @__PURE__ */ new Set();
32141
+ const reached = [...hop1, ...[...hop1].flatMap((x) => [...near.get(x) ?? []])];
32142
+ if (reached.some((q) => q !== p && isInstance.has(q))) bound++;
32143
+ }
32144
+ return bound / instances.length;
32145
+ }
32146
+ function jaccard(a, b) {
32147
+ if (a.size === 0 && b.size === 0) return 0;
32148
+ let both = 0;
32149
+ for (const x of a) if (b.has(x)) both++;
32150
+ return both / (a.size + b.size - both);
32151
+ }
31805
32152
  function promoteMotifs(store, t) {
32153
+ const report = { communities: 0, candidates: 0, incoherent: 0, promoted: 0, techniques: 0, antipatterns: 0, retracted: 0, retired: 0 };
31806
32154
  const byCommunity = /* @__PURE__ */ new Map();
31807
32155
  for (const label of MEMBER_LABELS) {
31808
32156
  for (const n of store.findNodesByLabel(label)) {
31809
32157
  if (n.label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
31810
- const c = n.community;
31811
- if (!c) continue;
32158
+ const c = n.attrs["localCommunity"];
32159
+ if (typeof c !== "string") continue;
31812
32160
  const g = byCommunity.get(c) ?? [];
31813
32161
  g.push(n);
31814
32162
  byCommunity.set(c, g);
31815
32163
  }
31816
32164
  }
31817
- let candidates = 0;
31818
- let promoted = 0;
31819
- let techniques = 0;
31820
- let antipatterns = 0;
32165
+ report.communities = byCommunity.size;
32166
+ const existing = /* @__PURE__ */ new Map();
32167
+ for (const label of MOTIF_LABELS) {
32168
+ for (const node2 of store.findNodesByLabel(label)) {
32169
+ if (!node2.id.startsWith("motif_")) continue;
32170
+ const edges = store.inEdges(node2.id, ["INSTANCE_OF"]).filter(isDerived);
32171
+ const remembered = node2.attrs["memberIds"];
32172
+ const members = new Set(Array.isArray(remembered) ? remembered : edges.map((e) => e.from));
32173
+ existing.set(node2.id, { node: node2, edges, members });
32174
+ }
32175
+ }
32176
+ const pairs = [];
32177
+ for (const [cid, members] of byCommunity) {
32178
+ const instances = new Set(members.filter((m) => m.label === "Problem").map((m) => m.id));
32179
+ for (const [motifId, m] of existing) {
32180
+ const j = jaccard(instances, m.members);
32181
+ if (j >= LINEAGE_MIN_JACCARD) pairs.push({ cid, motifId, j });
32182
+ }
32183
+ }
32184
+ pairs.sort((a, b) => b.j - a.j || a.motifId.localeCompare(b.motifId));
32185
+ const motifOf = /* @__PURE__ */ new Map();
32186
+ const claimed = /* @__PURE__ */ new Set();
32187
+ for (const p of pairs) {
32188
+ if (motifOf.has(p.cid) || claimed.has(p.motifId)) continue;
32189
+ motifOf.set(p.cid, p.motifId);
32190
+ claimed.add(p.motifId);
32191
+ }
32192
+ const kept = /* @__PURE__ */ new Set();
31821
32193
  store.transaction(() => {
31822
32194
  for (const [cid, members] of byCommunity) {
31823
32195
  const instances = members.filter((m) => m.label === "Problem");
31824
32196
  const instanceCount = instances.length || members.length;
31825
- const motifId = `motif_${cid}`;
31826
- const existing = store.getNode(motifId);
32197
+ const motifId = motifOf.get(cid) ?? (claimed.has(`motif_${cid}`) ? `motif_${cid}_${digest(instances.map((m) => m.id).sort()).slice(0, 8)}` : `motif_${cid}`);
32198
+ const prior = existing.get(motifId);
32199
+ const coherence = motifCoherence(store, new Set(members.map((m) => m.id)), instances.map((m) => m.id));
31827
32200
  const d = motifDecision({
31828
- instances: members.map((m) => ({
31829
- confidence: m.extractionConfidence,
31830
- failed: false
31831
- })),
32201
+ instances: members.map((m) => ({ confidence: m.extractionConfidence, failed: false })),
31832
32202
  memberCount: members.length,
31833
32203
  instanceCount,
31834
- priorSurvivedRuns: existing?.attrs["survivedRuns"] ?? 0
32204
+ priorSurvivedRuns: prior?.node.attrs["survivedRuns"] ?? 0,
32205
+ coherence
31835
32206
  });
31836
- if (!d.isCandidate) continue;
31837
- candidates++;
32207
+ if (!d.isCandidate) {
32208
+ if (members.length >= 5) report.incoherent++;
32209
+ continue;
32210
+ }
32211
+ report.candidates++;
32212
+ kept.add(motifId);
31838
32213
  const kind = classifyMotif(store, instances, d.promoted);
32214
+ const exemplar = exemplarOf(members);
31839
32215
  const motif = {
31840
32216
  id: motifId,
31841
32217
  label: kind,
31842
32218
  // Refresh the deterministic title every run (exemplar/count/kind drift),
31843
32219
  // but never clobber a distilled one — a distillation pass owns it then.
31844
- description: existing?.attrs["titleDistilled"] === true ? existing.description : motifTitle(members, layerOf(kind), instanceCount),
32220
+ description: prior?.node.attrs["titleDistilled"] === true ? prior.node.description : motifTitle(exemplar, layerOf(kind), instanceCount),
31845
32221
  extractionConfidence: d.motifConfidence,
31846
32222
  extractionSource: "bko-inferred",
31847
- embedding: existing?.embedding ?? [],
31848
- cumulativeSurprise: existing?.cumulativeSurprise ?? 0,
31849
- peakSurprise: existing?.peakSurprise ?? 0,
32223
+ embedding: prior?.node.embedding ?? [],
32224
+ cumulativeSurprise: prior?.node.cumulativeSurprise ?? 0,
32225
+ peakSurprise: prior?.node.peakSurprise ?? 0,
31850
32226
  cumulativeHits: instanceCount,
31851
32227
  lastUpdatedAt: t,
31852
- createdAt: existing?.createdAt ?? t,
31853
- memoryTier: existing?.memoryTier ?? "short-term",
31854
- pageRank: existing?.pageRank ?? 0,
32228
+ createdAt: prior?.node.createdAt ?? t,
32229
+ memoryTier: prior?.node.memoryTier ?? "short-term",
32230
+ pageRank: prior?.node.pageRank ?? 0,
31855
32231
  isLandmark: d.promoted,
31856
- community: cid,
32232
+ // The community column belongs to the joint pass alone; a motif names
32233
+ // its community in attrs.communityId.
32234
+ community: null,
31857
32235
  stability: d.stable ? "stable" : "forming",
31858
32236
  attrs: {
32237
+ ...prior?.node.attrs ?? {},
31859
32238
  layer: layerOf(kind),
31860
32239
  communityId: cid,
31861
32240
  survivedRuns: d.survivedRuns,
31862
32241
  motifConfidence: d.motifConfidence,
31863
32242
  memberCount: members.length,
31864
32243
  instanceCount,
32244
+ coherence: Math.round(coherence * 100) / 100,
32245
+ memberIds: instances.map((m) => m.id),
32246
+ ...exemplar ? { exemplarId: exemplar.id } : {},
32247
+ missedRuns: 0,
31865
32248
  promoted: d.promoted
31866
32249
  }
31867
32250
  };
31868
32251
  store.mergeNode(motif);
32252
+ const now = new Set(instances.map((m) => m.id));
31869
32253
  for (const m of instances) {
31870
32254
  store.mergeEdge({
31871
32255
  id: `edge_${digest({ from: m.id, type: "INSTANCE_OF", to: motifId })}`.slice(0, 24),
@@ -31881,21 +32265,45 @@ function promoteMotifs(store, t) {
31881
32265
  attrs: {}
31882
32266
  });
31883
32267
  }
31884
- if (d.promoted) promoted++;
31885
- if (kind === "Technique") techniques++;
31886
- if (kind === "AntiPattern") antipatterns++;
32268
+ for (const e of prior?.edges ?? []) {
32269
+ if (now.has(e.from)) continue;
32270
+ store.closeEdge(e.id, t);
32271
+ report.retracted++;
32272
+ }
32273
+ if (d.promoted) report.promoted++;
32274
+ if (kind === "Technique") report.techniques++;
32275
+ if (kind === "AntiPattern") report.antipatterns++;
32276
+ }
32277
+ for (const [motifId, m] of existing) {
32278
+ if (kept.has(motifId)) continue;
32279
+ for (const e of m.edges) {
32280
+ store.closeEdge(e.id, t);
32281
+ report.retracted++;
32282
+ }
32283
+ const missedRuns = (m.node.attrs["missedRuns"] ?? 0) + 1;
32284
+ const evidenced = store.inEdges(motifId, ["INSTANCE_OF"]).some((e) => !isDerived(e));
32285
+ if (missedRuns >= MOTIF_MIN_SURVIVED && !evidenced) {
32286
+ for (const e of [...store.outEdges(motifId), ...store.inEdges(motifId)]) store.closeEdge(e.id, t);
32287
+ store.closeNode(motifId, t);
32288
+ report.retired++;
32289
+ } else {
32290
+ store.updateNode(motifId, { attrs: { ...m.node.attrs, missedRuns, promoted: false } });
32291
+ }
31887
32292
  }
31888
32293
  });
31889
- return { communities: byCommunity.size, candidates, promoted, techniques, antipatterns };
32294
+ return report;
31890
32295
  }
31891
- var MEMBER_LABELS;
32296
+ var MEMBER_LABELS, MOTIF_LABELS, LINEAGE_MIN_JACCARD;
31892
32297
  var init_motifs = __esm({
31893
32298
  "../../packages/generalizer/src/motifs.ts"() {
31894
32299
  "use strict";
31895
32300
  init_src2();
32301
+ init_src5();
31896
32302
  init_src3();
31897
32303
  init_src();
31898
32304
  MEMBER_LABELS = ["Problem", "RootCause", "Solution"];
32305
+ MOTIF_LABELS = ["Pattern", "Technique", "AntiPattern"];
32306
+ LINEAGE_MIN_JACCARD = 0.5;
31899
32307
  }
31900
32308
  });
31901
32309
 
@@ -32111,44 +32519,14 @@ function runFullRescore(store) {
32111
32519
  landmarkFlips++;
32112
32520
  }
32113
32521
  });
32114
- const MOTIF_LABELS = /* @__PURE__ */ new Set(["Pattern", "Technique", "AntiPattern"]);
32115
- const semanticIds = /* @__PURE__ */ new Set();
32116
- for (const label of SEMANTIC_NODE_LABELS) {
32117
- if (MOTIF_LABELS.has(label)) continue;
32118
- for (const n of store.findNodesByLabel(label)) semanticIds.add(n.id);
32119
- }
32120
- const semAdj = /* @__PURE__ */ new Map();
32121
- const protect = [];
32122
- const addAdj = (a, b, w) => {
32123
- const l = semAdj.get(a) ?? [];
32124
- l.push({ to: b, weight: w });
32125
- semAdj.set(a, l);
32126
- };
32127
- for (const id of semanticIds) {
32128
- for (const e of store.outEdges(id)) {
32129
- if (!semanticIds.has(e.to)) continue;
32130
- const conf = e.confidence > 0 ? e.confidence : 0.5;
32131
- const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
32132
- addAdj(id, e.to, w);
32133
- addAdj(e.to, id, w);
32134
- if (isCausalProtected(e.type)) protect.push([id, e.to]);
32135
- }
32136
- }
32137
- for (const { a, b, weight } of codeAnchorProjection(store, semanticIds)) {
32138
- addAdj(a, b, weight);
32139
- addAdj(b, a, weight);
32140
- }
32141
- const comm = detectCommunitiesLeiden({ nodeIds: [...semanticIds], adj: semAdj }, { protect });
32142
- store.transaction(() => {
32143
- for (const [id, c] of comm.community) store.updateNode(id, { community: c });
32144
- });
32522
+ const lc = detectLocalCommunities(store);
32145
32523
  const motifs = promoteMotifs(store, started2);
32146
32524
  return {
32147
32525
  scoredNodes: scored,
32148
32526
  iterations: result.iterations,
32149
32527
  converged: result.converged,
32150
32528
  landmarks: allLandmarks.size,
32151
- communities: comm.count,
32529
+ communities: lc.communities,
32152
32530
  motifsPromoted: motifs.promoted,
32153
32531
  techniques: motifs.techniques,
32154
32532
  antipatterns: motifs.antipatterns,
@@ -32207,28 +32585,6 @@ function runNightlyPipeline(store) {
32207
32585
  durationMs: Date.now() - started2
32208
32586
  };
32209
32587
  }
32210
- function codeAnchorProjection(store, semanticIds, opts = {}) {
32211
- const anchorToNodes = /* @__PURE__ */ new Map();
32212
- for (const id of semanticIds) {
32213
- for (const e of store.outEdges(id, ["ANCHORED_AT"])) {
32214
- if (semanticIds.has(e.to)) continue;
32215
- const l = anchorToNodes.get(e.to) ?? [];
32216
- l.push(id);
32217
- anchorToNodes.set(e.to, l);
32218
- }
32219
- }
32220
- const hubCap = opts.hubCap ?? Math.max(8, Math.floor(semanticIds.size * 0.03));
32221
- const base = opts.weight ?? 1;
32222
- const out2 = [];
32223
- for (const nodes of anchorToNodes.values()) {
32224
- if (nodes.length < 2 || nodes.length > hubCap) continue;
32225
- const w = base / Math.log2(nodes.length + 1);
32226
- for (let i2 = 0; i2 < nodes.length; i2++) {
32227
- for (let j = i2 + 1; j < nodes.length; j++) out2.push({ a: nodes[i2], b: nodes[j], weight: w });
32228
- }
32229
- }
32230
- return out2;
32231
- }
32232
32588
  var FULL_RESCORE_EVERY, INCREMENTAL_REGION_MAX_FRACTION, INCREMENTAL_HOPS;
32233
32589
  var init_nightly = __esm({
32234
32590
  "../../packages/generalizer/src/nightly.ts"() {
@@ -32606,6 +32962,59 @@ var init_relevance_rank = __esm({
32606
32962
  }
32607
32963
  });
32608
32964
 
32965
+ // ../../packages/generalizer/src/motif-signal.ts
32966
+ function motifSignal(store, seedIds, opts = {}) {
32967
+ const maxHops = opts.maxHops ?? 3;
32968
+ const nodeCap = opts.nodeCap ?? 120;
32969
+ const total = /* @__PURE__ */ new Map();
32970
+ for (const seedId of new Set(seedIds)) {
32971
+ const seed = store.getNode(seedId);
32972
+ if (!seed) continue;
32973
+ const act = /* @__PURE__ */ new Map([[seedId, 1]]);
32974
+ const hopOf = /* @__PURE__ */ new Map([[seedId, 0]]);
32975
+ const expanded = /* @__PURE__ */ new Set();
32976
+ let strongest = 0;
32977
+ while (expanded.size < nodeCap) {
32978
+ let top;
32979
+ let topA = 0;
32980
+ for (const [id, a] of act) if (!expanded.has(id) && a > topA) top = id, topA = a;
32981
+ if (top === void 0 || topA < strongest * BURST_RELATIVE_FLOOR) break;
32982
+ expanded.add(top);
32983
+ const hops = hopOf.get(top);
32984
+ if (hops >= maxHops) continue;
32985
+ const edges = [
32986
+ ...store.outEdges(top, KNOWLEDGE_EDGES).map((e) => ({ e, nb: e.to })),
32987
+ ...store.inEdges(top, KNOWLEDGE_EDGES).map((e) => ({ e, nb: e.from }))
32988
+ ];
32989
+ const damp = BURST_STEP_DAMPING / Math.sqrt(Math.max(1, edges.length));
32990
+ for (const { e, nb } of edges) {
32991
+ if (nb === seedId || expanded.has(nb)) continue;
32992
+ const a = topA * burstConductance(e, seed.label) * damp;
32993
+ if (a <= (act.get(nb) ?? 0)) continue;
32994
+ act.set(nb, a);
32995
+ hopOf.set(nb, hops + 1);
32996
+ if (a > strongest) strongest = a;
32997
+ }
32998
+ }
32999
+ act.delete(seedId);
33000
+ const labels = store.nodeLabels([...act.keys()]);
33001
+ for (const [id, a] of act) {
33002
+ if (MOTIF_LABELS2.has(labels.get(id) ?? "")) total.set(id, (total.get(id) ?? 0) + a);
33003
+ }
33004
+ }
33005
+ return total;
33006
+ }
33007
+ var MOTIF_LABELS2, KNOWLEDGE_EDGES;
33008
+ var init_motif_signal = __esm({
33009
+ "../../packages/generalizer/src/motif-signal.ts"() {
33010
+ "use strict";
33011
+ init_src5();
33012
+ init_relevance_rank();
33013
+ MOTIF_LABELS2 = /* @__PURE__ */ new Set(["Pattern", "Technique", "AntiPattern"]);
33014
+ KNOWLEDGE_EDGES = [...JOINT_COMMUNITY_EDGES, "MAY_RESOLVE", "REGRESSION_OF", "BUILDS_ON"];
33015
+ }
33016
+ });
33017
+
32609
33018
  // ../../packages/generalizer/src/index.ts
32610
33019
  var src_exports3 = {};
32611
33020
  __export(src_exports3, {
@@ -32626,7 +33035,6 @@ __export(src_exports3, {
32626
33035
  burstConductance: () => burstConductance,
32627
33036
  burstStaticConductance: () => burstStaticConductance,
32628
33037
  closeProblem: () => closeProblem,
32629
- codeAnchorProjection: () => codeAnchorProjection,
32630
33038
  commandSignature: () => commandSignature,
32631
33039
  embedCodeNodes: () => embedCodeNodes,
32632
33040
  embedSemanticNodes: () => embedSemanticNodes,
@@ -32637,6 +33045,8 @@ __export(src_exports3, {
32637
33045
  ingestErrorSignature: () => ingestErrorSignature,
32638
33046
  localBurst: () => localBurst,
32639
33047
  mergeProblemsByEmbedding: () => mergeProblemsByEmbedding,
33048
+ motifCoherence: () => motifCoherence,
33049
+ motifSignal: () => motifSignal,
32640
33050
  nemoriDecide: () => nemoriDecide,
32641
33051
  promoteMotifs: () => promoteMotifs,
32642
33052
  rankAgainstEmbedding: () => rankAgainstEmbedding,
@@ -32662,6 +33072,7 @@ var init_src8 = __esm({
32662
33072
  init_motifs();
32663
33073
  init_embed_code();
32664
33074
  init_relevance_rank();
33075
+ init_motif_signal();
32665
33076
  }
32666
33077
  });
32667
33078
 
@@ -33312,12 +33723,12 @@ var init_consent = __esm({
33312
33723
 
33313
33724
  // src/git-remote.ts
33314
33725
  import { spawnSync } from "node:child_process";
33315
- import { existsSync as existsSync10, readFileSync as readFileSync8, statSync } from "node:fs";
33726
+ import { existsSync as existsSync10, readFileSync as readFileSync8, statSync as statSync2 } from "node:fs";
33316
33727
  import { isAbsolute as isAbsolute2, join as join8, resolve as resolve2 } from "node:path";
33317
33728
  function resolveGitDir(root) {
33318
33729
  const dotGit = join8(root, ".git");
33319
33730
  try {
33320
- const st = statSync(dotGit);
33731
+ const st = statSync2(dotGit);
33321
33732
  if (st.isDirectory()) return dotGit;
33322
33733
  const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync8(dotGit, "utf8"));
33323
33734
  if (!m) return null;
@@ -35550,7 +35961,7 @@ var init_daemon_generalize_client = __esm({
35550
35961
 
35551
35962
  // ../../packages/indexer/src/parse-cache.ts
35552
35963
  import { createHash as createHash6 } from "node:crypto";
35553
- import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync14, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync11 } from "node:fs";
35964
+ import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync14, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync11 } from "node:fs";
35554
35965
  import { homedir as homedir3 } from "node:os";
35555
35966
  import { join as join12 } from "node:path";
35556
35967
  function parseCacheDir() {
@@ -35606,7 +36017,7 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
35606
36017
  for (const name2 of names) {
35607
36018
  const file2 = join12(bucketDir, name2);
35608
36019
  try {
35609
- if (now - statSync2(file2).mtimeMs > ENTRY_TTL_MS) {
36020
+ if (now - statSync3(file2).mtimeMs > ENTRY_TTL_MS) {
35610
36021
  rmSync2(file2, { force: true });
35611
36022
  removed++;
35612
36023
  }
@@ -35716,7 +36127,7 @@ function hasForkedDrift(currentHex, birthHex, maxSimRatio = DRIFT_FORK_RATIO) {
35716
36127
  if (!currentHex || !birthHex) return false;
35717
36128
  return simRatio(fromHex(currentHex), fromHex(birthHex)) < maxSimRatio;
35718
36129
  }
35719
- function jaccard(a, b) {
36130
+ function jaccard2(a, b) {
35720
36131
  if (a.size === 0 && b.size === 0) return 0;
35721
36132
  let inter = 0;
35722
36133
  for (const x of a) if (b.has(x)) inter++;
@@ -35750,7 +36161,7 @@ function score(a, b) {
35750
36161
  weighted += body2 * WEIGHTS.body;
35751
36162
  total += WEIGHTS.body;
35752
36163
  if (a.callees.size > 0 || b.callees.size > 0) {
35753
- const topo = jaccard(a.callees, b.callees);
36164
+ const topo = jaccard2(a.callees, b.callees);
35754
36165
  evidence["topology"] = round(topo);
35755
36166
  weighted += topo * WEIGHTS.topology;
35756
36167
  total += WEIGHTS.topology;
@@ -35852,7 +36263,7 @@ var init_identity3 = __esm({
35852
36263
  });
35853
36264
 
35854
36265
  // ../../packages/indexer/src/pipeline.ts
35855
- import { appendFileSync, readFileSync as readFileSync15, statSync as statSync3 } from "node:fs";
36266
+ import { appendFileSync, readFileSync as readFileSync15, statSync as statSync4 } from "node:fs";
35856
36267
  import { readdir } from "node:fs/promises";
35857
36268
  import { extname, join as join13, relative as relative2, sep } from "node:path";
35858
36269
  import { createHash as createHash7 } from "node:crypto";
@@ -36362,7 +36773,7 @@ async function runIndexer(store, opts) {
36362
36773
  }
36363
36774
  let source;
36364
36775
  try {
36365
- const st = statSync3(f.absPath);
36776
+ const st = statSync4(f.absPath);
36366
36777
  if (st.size > maxBytes) {
36367
36778
  report.filesSkipped++;
36368
36779
  continue;
@@ -36837,7 +37248,7 @@ async function scan(root, current, ignores, providers, out2) {
36837
37248
  let size = 0;
36838
37249
  let mtimeMs;
36839
37250
  try {
36840
- const st = statSync3(abs);
37251
+ const st = statSync4(abs);
36841
37252
  size = st.size;
36842
37253
  mtimeMs = st.mtimeMs;
36843
37254
  } catch {
@@ -36890,7 +37301,7 @@ function gitListFiles(root, ignores, providers) {
36890
37301
  let size;
36891
37302
  let mtimeMs;
36892
37303
  try {
36893
- const st = statSync3(abs);
37304
+ const st = statSync4(abs);
36894
37305
  size = st.size;
36895
37306
  mtimeMs = st.mtimeMs;
36896
37307
  } catch {
@@ -44325,7 +44736,7 @@ var init_src11 = __esm({
44325
44736
 
44326
44737
  // src/reconcile.ts
44327
44738
  import { execFileSync as execFileSync3 } from "node:child_process";
44328
- import { readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
44739
+ import { readdirSync as readdirSync4, statSync as statSync5 } from "node:fs";
44329
44740
  import { join as join15, relative as relative3, sep as sep2 } from "node:path";
44330
44741
  function indexerWouldScan(rel) {
44331
44742
  for (const seg of rel.split(/[\\/]/)) {
@@ -44389,7 +44800,7 @@ async function findStaleFiles(store, rootPath, workspaceId2) {
44389
44800
  for (const abs of listSourceFiles(rootPath)) {
44390
44801
  try {
44391
44802
  const rel = relative3(rootPath, abs).split(sep2).join("/");
44392
- pending.push({ abs, id: fileNodeId(workspaceId2, rel), mtimeMs: statSync4(abs).mtimeMs });
44803
+ pending.push({ abs, id: fileNodeId(workspaceId2, rel), mtimeMs: statSync5(abs).mtimeMs });
44393
44804
  } catch {
44394
44805
  }
44395
44806
  if (++scanned % SCAN_YIELD_EVERY === 0) {
@@ -54140,9 +54551,11 @@ var init_message_accumulator = __esm({
54140
54551
  // src/webui.ts
54141
54552
  var webui_exports = {};
54142
54553
  __export(webui_exports, {
54554
+ ContextBaselines: () => ContextBaselines,
54143
54555
  SUBAGENT_REFRESH_MIN_MS: () => SUBAGENT_REFRESH_MIN_MS,
54144
54556
  asFailedPostToolUse: () => asFailedPostToolUse,
54145
54557
  buildWebUi: () => buildWebUi,
54558
+ contextDeltaEnabled: () => contextDeltaEnabled,
54146
54559
  decideContextInject: () => decideContextInject,
54147
54560
  editVerdict: () => editVerdict,
54148
54561
  errorRecallTerms: () => errorRecallTerms,
@@ -54327,23 +54740,54 @@ function hookAudience(body2) {
54327
54740
  agentId
54328
54741
  };
54329
54742
  }
54743
+ function contextDeltaEnabled(env2 = process.env) {
54744
+ const v = (env2["ERRATA_CONTEXT_DELTA"] ?? "").trim().toLowerCase();
54745
+ return !(v === "0" || v === "off" || v === "false" || v === "no");
54746
+ }
54330
54747
  function decideContextInject(args2) {
54331
- const { event, sessionId, block, lastInjectedHash } = args2;
54748
+ const { event, source, sessionId, block, transcriptPath } = args2;
54332
54749
  if (!block) return null;
54750
+ const seen = args2.lastInjectedHash instanceof ContextBaselines ? args2.lastInjectedHash : null;
54751
+ const hashes = seen ? null : args2.lastInjectedHash;
54752
+ if (seen && sessionId) seen.settle(sessionId);
54753
+ const hashOf = (k) => seen ? seen.hash(k) : hashes.get(k);
54754
+ const record2 = (k) => {
54755
+ if (seen) seen.record(k, block, transcriptPath);
54756
+ else hashes.set(k, block.hash);
54757
+ };
54758
+ let additionalContext = FULL_BLOCK_PREFIX + block.body;
54333
54759
  if (event === "SessionStart" || event === "SubagentStart") {
54334
- if (sessionId) lastInjectedHash.set(sessionId, block.hash);
54335
- } else if (sessionId && lastInjectedHash.get(sessionId) === block.hash) {
54760
+ if (sessionId && seen && WINDOW_RESET_SOURCES.has(source)) seen.reset(sessionId, source);
54761
+ if (sessionId) record2(sessionId);
54762
+ } else if (sessionId && hashOf(sessionId) === block.hash) {
54336
54763
  return event === "UserPromptSubmit" ? { hookEventName: event, additionalContext: PROMPT_RECUE } : null;
54337
54764
  } else {
54338
- if (sessionId) lastInjectedHash.set(sessionId, block.hash);
54765
+ const prev = sessionId && seen && (args2.delta ?? true) ? seen.body(sessionId) : void 0;
54766
+ if (prev !== void 0) {
54767
+ const delta = renderContextDelta(prev, block.body);
54768
+ if (delta === null) {
54769
+ seen.record(sessionId, block);
54770
+ return event === "UserPromptSubmit" ? { hookEventName: event, additionalContext: PROMPT_RECUE } : null;
54771
+ }
54772
+ const cue = event === "UserPromptSubmit" ? `
54773
+
54774
+ ${PROMPT_INTENT_CUE}` : "";
54775
+ const sent = `${DELTA_PREAMBLE}
54776
+
54777
+ ${delta}${cue}`;
54778
+ if (sent.length <= DELTA_MAX_FRACTION * additionalContext.length) additionalContext = sent;
54779
+ }
54780
+ if (sessionId) record2(sessionId);
54339
54781
  }
54340
- const additionalContext = "The errata daemon has updated your live workspace context. The block below REPLACES any earlier errata context block in this conversation \u2014 treat it as the current source of truth:\n\n" + block.body;
54782
+ if (seen && sessionId && transcriptPath) additionalContext += `
54783
+
54784
+ ${deliveryMarker(block.hash)}`;
54341
54785
  return { hookEventName: event, additionalContext };
54342
54786
  }
54343
54787
  function buildWebUi(deps) {
54344
54788
  const app = new Hono2();
54345
54789
  const B = deps.basePath ?? "";
54346
- const lastInjectedHash = /* @__PURE__ */ new Map();
54790
+ const lastInjectedHash = new ContextBaselines();
54347
54791
  const fileRecallSeen = /* @__PURE__ */ new Map();
54348
54792
  const editVerdictAsked = /* @__PURE__ */ new Map();
54349
54793
  const lastSubagentInjectAt = /* @__PURE__ */ new Map();
@@ -54662,7 +55106,8 @@ function buildWebUi(deps) {
54662
55106
  source: "",
54663
55107
  sessionId: audience.contextKey,
54664
55108
  block: own,
54665
- lastInjectedHash
55109
+ lastInjectedHash,
55110
+ delta: contextDeltaEnabled()
54666
55111
  });
54667
55112
  if (decision) {
54668
55113
  lastSubagentInjectAt.set(audience.contextKey, Date.now());
@@ -54757,8 +55202,29 @@ function buildWebUi(deps) {
54757
55202
  deps.onSessionEnd({ sessionId, transcriptPath });
54758
55203
  }
54759
55204
  noteSessionFrom(c.req.header(ORIGIN_HEADER), body2, true);
55205
+ if (sessionId) lastInjectedHash.reset(sessionId, "end");
54760
55206
  return c.json({ ok: true });
54761
55207
  });
55208
+ app.post("/api/context-delta", async (c) => {
55209
+ let body2;
55210
+ try {
55211
+ body2 = await c.req.json();
55212
+ } catch {
55213
+ return c.json({});
55214
+ }
55215
+ const prev = body2["prev"];
55216
+ const next = body2["next"];
55217
+ if (typeof prev !== "string" || typeof next !== "string" || !contextDeltaEnabled()) return c.json({});
55218
+ const delta = renderContextDelta(prev, next);
55219
+ if (delta === null) return c.json({ unchanged: true });
55220
+ const cue = body2["hook_event_name"] === "UserPromptSubmit" ? `
55221
+
55222
+ ${PROMPT_INTENT_CUE}` : "";
55223
+ const sent = `${DELTA_PREAMBLE}
55224
+
55225
+ ${delta}${cue}`;
55226
+ return sent.length <= DELTA_MAX_FRACTION * next.length ? c.json({ delta: sent }) : c.json({});
55227
+ });
54762
55228
  app.post("/api/context-inject", async (c) => {
54763
55229
  let body2;
54764
55230
  try {
@@ -54800,7 +55266,10 @@ function buildWebUi(deps) {
54800
55266
  source: String(body2["source"] ?? ""),
54801
55267
  sessionId: contextKey2,
54802
55268
  block,
54803
- lastInjectedHash
55269
+ lastInjectedHash,
55270
+ delta: contextDeltaEnabled(),
55271
+ // A subagent's injections land in its own transcript, not the one posted.
55272
+ ...subagent === null && typeof body2["transcript_path"] === "string" && body2["transcript_path"] ? { transcriptPath: body2["transcript_path"] } : {}
54804
55273
  });
54805
55274
  if (decision && subagent !== null) lastSubagentInjectAt.set(contextKey2, Date.now());
54806
55275
  let systemMessage = null;
@@ -54997,11 +55466,12 @@ function proposalToIngest(p, profile, daemonVersion) {
54997
55466
  payloadDigest: p.id
54998
55467
  };
54999
55468
  }
55000
- var messageAccumulator, GENERIC_ERROR_WORDS, wsPackagesCache, WS_PACKAGES_TTL_MS, loggedToolSessions, SUBAGENT_REFRESH_MIN_MS, META_LABELS;
55469
+ var messageAccumulator, GENERIC_ERROR_WORDS, wsPackagesCache, WS_PACKAGES_TTL_MS, loggedToolSessions, SUBAGENT_REFRESH_MIN_MS, WINDOW_RESET_SOURCES, FULL_BLOCK_PREFIX, META_LABELS;
55001
55470
  var init_webui = __esm({
55002
55471
  "src/webui.ts"() {
55003
55472
  "use strict";
55004
55473
  init_dist();
55474
+ init_context_baselines();
55005
55475
  init_src6();
55006
55476
  init_src5();
55007
55477
  init_src8();
@@ -55014,6 +55484,7 @@ var init_webui = __esm({
55014
55484
  init_tool_index();
55015
55485
  init_outbox();
55016
55486
  init_message_accumulator();
55487
+ init_context_baselines();
55017
55488
  messageAccumulator = createMessageAccumulator();
55018
55489
  GENERIC_ERROR_WORDS = /* @__PURE__ */ new Set([
55019
55490
  "cannot",
@@ -55060,6 +55531,8 @@ var init_webui = __esm({
55060
55531
  WS_PACKAGES_TTL_MS = 6e4;
55061
55532
  loggedToolSessions = /* @__PURE__ */ new Set();
55062
55533
  SUBAGENT_REFRESH_MIN_MS = 6e4;
55534
+ WINDOW_RESET_SOURCES = /* @__PURE__ */ new Set(["compact", "clear", "resume"]);
55535
+ FULL_BLOCK_PREFIX = "The errata daemon has updated your live workspace context. The block below REPLACES any earlier errata context block in this conversation \u2014 treat it as the current source of truth:\n\n";
55063
55536
  META_LABELS = /* @__PURE__ */ new Set([
55064
55537
  "Pattern",
55065
55538
  "Technique",
@@ -74315,7 +74788,7 @@ var init_report_render = __esm({
74315
74788
 
74316
74789
  // src/cli.ts
74317
74790
  init_src6();
74318
- import { closeSync as closeSync2, existsSync as existsSync40, openSync as openSync2, readFileSync as readFileSync42, renameSync as renameSync7, statSync as statSync12 } from "node:fs";
74791
+ import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync42, renameSync as renameSync7, statSync as statSync13 } from "node:fs";
74319
74792
  import { join as join49, resolve as pathResolve2 } from "node:path";
74320
74793
  import { spawn as spawn5 } from "node:child_process";
74321
74794
 
@@ -74901,7 +75374,7 @@ init_lock();
74901
75374
 
74902
75375
  // src/engine.ts
74903
75376
  import { execFileSync as execFileSync5 } from "node:child_process";
74904
- import { existsSync as existsSync28, statSync as statSync8, appendFileSync as appendFileSync4, readdirSync as readdirSync10, renameSync as renameSync4, readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
75377
+ import { existsSync as existsSync28, statSync as statSync9, appendFileSync as appendFileSync4, readdirSync as readdirSync10, renameSync as renameSync4, readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
74905
75378
  import { basename as basename7, join as join35, relative as relative6, sep as sep4 } from "node:path";
74906
75379
 
74907
75380
  // src/coalesced-file-pass.ts
@@ -74946,7 +75419,7 @@ function createCoalescedFilePass(delayMs, run3, onError) {
74946
75419
 
74947
75420
  // src/source-watcher.ts
74948
75421
  import { EventEmitter as EventEmitter2 } from "node:events";
74949
- import { statSync as statSync5, watch as watch2 } from "node:fs";
75422
+ import { statSync as statSync6, watch as watch2 } from "node:fs";
74950
75423
  import { join as join20 } from "node:path";
74951
75424
 
74952
75425
  // ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
@@ -76674,7 +77147,7 @@ var NativeSourceWatcher = class extends EventEmitter2 {
76674
77147
  if (this.closed || this.handles.has(target)) return;
76675
77148
  let isDir;
76676
77149
  try {
76677
- isDir = statSync5(target).isDirectory();
77150
+ isDir = statSync6(target).isDirectory();
76678
77151
  } catch {
76679
77152
  return;
76680
77153
  }
@@ -76714,7 +77187,7 @@ var NativeSourceWatcher = class extends EventEmitter2 {
76714
77187
  if (this.closed) return;
76715
77188
  let isFile;
76716
77189
  try {
76717
- const s = statSync5(path2);
77190
+ const s = statSync6(path2);
76718
77191
  if (s.isDirectory()) return;
76719
77192
  isFile = s.isFile();
76720
77193
  } catch {
@@ -77072,6 +77545,7 @@ function createSubagentState() {
77072
77545
 
77073
77546
  // src/subagent-context.ts
77074
77547
  init_src6();
77548
+ init_src8();
77075
77549
  init_src5();
77076
77550
  init_src2();
77077
77551
  init_recall_signal();
@@ -77104,8 +77578,12 @@ function renderSubagentBlock(args2) {
77104
77578
  coverage: h.coverage
77105
77579
  })) : [];
77106
77580
  const shared = entry.share && !entry.share.all ? resolveSharedPriors(store, entry.share.priors, args2.handleMap, args2.remote) : [];
77581
+ const intent = entry.intent ? { text: entry.intent, hits } : null;
77582
+ const seeds = [.../* @__PURE__ */ new Set([...motifSeeds(snapshot, intent), ...shared.map((n) => n.id)])];
77583
+ const signal = seeds.length > 0 ? motifSignal(store, seeds) : void 0;
77107
77584
  const { body: body2, snapshot: shown } = assembleAgentContext({
77108
77585
  store,
77586
+ ...signal ? { motifSignal: signal } : {},
77109
77587
  profile: args2.profile,
77110
77588
  ...args2.atCommit ? { atCommit: args2.atCommit } : {},
77111
77589
  reviewCount: 0,
@@ -77135,7 +77613,7 @@ init_review2();
77135
77613
 
77136
77614
  // src/turn.ts
77137
77615
  init_checkout_root();
77138
- import { closeSync, existsSync as existsSync19, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync as realpathSync2, statSync as statSync6 } from "node:fs";
77616
+ import { closeSync as closeSync2, existsSync as existsSync19, fstatSync, openSync as openSync2, readdirSync as readdirSync6, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync7 } from "node:fs";
77139
77617
  import { basename as basename5, delimiter, dirname as dirname10, join as join21, normalize as normalize3 } from "node:path";
77140
77618
  import { homedir as homedir4 } from "node:os";
77141
77619
  import { createHash as createHash16 } from "node:crypto";
@@ -77152,7 +77630,7 @@ function completeJsonlPrefix(buf) {
77152
77630
  function readFrom(path2, fromByte, maxBytes) {
77153
77631
  let fd;
77154
77632
  try {
77155
- fd = openSync(path2, "r");
77633
+ fd = openSync2(path2, "r");
77156
77634
  } catch {
77157
77635
  return { text: "", nextOffset: fromByte, more: false, ioFailed: true };
77158
77636
  }
@@ -77165,7 +77643,7 @@ function readFrom(path2, fromByte, maxBytes) {
77165
77643
  for (; ; ) {
77166
77644
  const len = Math.min(cap, remaining);
77167
77645
  const buf = Buffer.allocUnsafe(len);
77168
- const read2 = readSync(fd, buf, 0, len, start2);
77646
+ const read2 = readSync2(fd, buf, 0, len, start2);
77169
77647
  if (len >= remaining || read2 < len) {
77170
77648
  const end = completeJsonlPrefix(buf.subarray(0, read2));
77171
77649
  return { text: buf.subarray(0, end).toString("utf8"), nextOffset: start2 + end, more: false, ioFailed: false };
@@ -77184,7 +77662,7 @@ function readFrom(path2, fromByte, maxBytes) {
77184
77662
  } catch {
77185
77663
  return { text: "", nextOffset: fromByte, more: false, ioFailed: true };
77186
77664
  } finally {
77187
- closeSync(fd);
77665
+ closeSync2(fd);
77188
77666
  }
77189
77667
  }
77190
77668
  function readTail(path2, maxBytes) {
@@ -77193,7 +77671,7 @@ function readTail(path2, maxBytes) {
77193
77671
  function readTailWithLosses(path2, maxBytes, completeLinesOnly = false) {
77194
77672
  let fd;
77195
77673
  try {
77196
- fd = openSync(path2, "r");
77674
+ fd = openSync2(path2, "r");
77197
77675
  } catch {
77198
77676
  return { text: "", bytesUnreachable: 0, parseStartByte: 0, ioFailed: true, nextOffset: 0 };
77199
77677
  }
@@ -77203,7 +77681,7 @@ function readTailWithLosses(path2, maxBytes, completeLinesOnly = false) {
77203
77681
  const len = size - start2;
77204
77682
  if (len <= 0) return { text: "", bytesUnreachable: 0, parseStartByte: 0, ioFailed: false, nextOffset: 0 };
77205
77683
  const buf = Buffer.allocUnsafe(len);
77206
- const read2 = readSync(fd, buf, 0, len, start2);
77684
+ const read2 = readSync2(fd, buf, 0, len, start2);
77207
77685
  const end = completeLinesOnly ? completeJsonlPrefix(buf.subarray(0, read2)) : read2;
77208
77686
  const text = buf.subarray(0, end).toString("utf8");
77209
77687
  const firstNewline = buf.indexOf(10);
@@ -77212,7 +77690,7 @@ function readTailWithLosses(path2, maxBytes, completeLinesOnly = false) {
77212
77690
  } catch {
77213
77691
  return { text: "", bytesUnreachable: 0, parseStartByte: 0, ioFailed: true, nextOffset: 0 };
77214
77692
  } finally {
77215
- closeSync(fd);
77693
+ closeSync2(fd);
77216
77694
  }
77217
77695
  }
77218
77696
  function parseDesignFlags(text) {
@@ -77542,7 +78020,7 @@ function recentTranscripts(cwd, opts = {}) {
77542
78020
  const path2 = join21(dir, name2);
77543
78021
  let mtimeMs;
77544
78022
  try {
77545
- mtimeMs = statSync6(path2).mtimeMs;
78023
+ mtimeMs = statSync7(path2).mtimeMs;
77546
78024
  } catch {
77547
78025
  continue;
77548
78026
  }
@@ -77568,7 +78046,7 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
77568
78046
  const path2 = join21(dir, name2);
77569
78047
  let mtimeMs;
77570
78048
  try {
77571
- mtimeMs = statSync6(path2).mtimeMs;
78049
+ mtimeMs = statSync7(path2).mtimeMs;
77572
78050
  } catch {
77573
78051
  continue;
77574
78052
  }
@@ -77597,7 +78075,7 @@ function readCodexRolloutIdentity(path2) {
77597
78075
  };
77598
78076
  let fd;
77599
78077
  try {
77600
- fd = openSync(path2, "r");
78078
+ fd = openSync2(path2, "r");
77601
78079
  const CAP = 1e6;
77602
78080
  const chunk = 65536;
77603
78081
  let acc = Buffer.alloc(0);
@@ -77605,7 +78083,7 @@ function readCodexRolloutIdentity(path2) {
77605
78083
  let nl = -1;
77606
78084
  while (acc.length < CAP) {
77607
78085
  const buf = Buffer.allocUnsafe(chunk);
77608
- const n = readSync(fd, buf, 0, chunk, pos);
78086
+ const n = readSync2(fd, buf, 0, chunk, pos);
77609
78087
  if (n <= 0) break;
77610
78088
  acc = acc.length === 0 ? buf.subarray(0, n) : Buffer.concat([acc, buf.subarray(0, n)]);
77611
78089
  pos += n;
@@ -77626,7 +78104,7 @@ function readCodexRolloutIdentity(path2) {
77626
78104
  return null;
77627
78105
  } finally {
77628
78106
  if (fd !== void 0) try {
77629
- closeSync(fd);
78107
+ closeSync2(fd);
77630
78108
  } catch {
77631
78109
  }
77632
78110
  }
@@ -77660,7 +78138,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
77660
78138
  const full = join21(dir, name2);
77661
78139
  let st;
77662
78140
  try {
77663
- st = statSync6(full);
78141
+ st = statSync7(full);
77664
78142
  } catch {
77665
78143
  continue;
77666
78144
  }
@@ -77717,10 +78195,10 @@ function geminiHashesFor(cwd) {
77717
78195
  function readGeminiTranscriptProjectHash(path2) {
77718
78196
  let fd;
77719
78197
  try {
77720
- fd = openSync(path2, "r");
78198
+ fd = openSync2(path2, "r");
77721
78199
  const CAP = 65536;
77722
78200
  const buf = Buffer.allocUnsafe(CAP);
77723
- const n = readSync(fd, buf, 0, CAP, 0);
78201
+ const n = readSync2(fd, buf, 0, CAP, 0);
77724
78202
  const nl = buf.indexOf(10);
77725
78203
  const firstLine = buf.toString("utf8", 0, nl >= 0 && nl < n ? nl : n);
77726
78204
  const o = JSON.parse(firstLine);
@@ -77729,7 +78207,7 @@ function readGeminiTranscriptProjectHash(path2) {
77729
78207
  return null;
77730
78208
  } finally {
77731
78209
  if (fd !== void 0) try {
77732
- closeSync(fd);
78210
+ closeSync2(fd);
77733
78211
  } catch {
77734
78212
  }
77735
78213
  }
@@ -77760,7 +78238,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
77760
78238
  const full = join21(chats, name2);
77761
78239
  let st;
77762
78240
  try {
77763
- st = statSync6(full);
78241
+ st = statSync7(full);
77764
78242
  } catch {
77765
78243
  continue;
77766
78244
  }
@@ -77784,9 +78262,9 @@ function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
77784
78262
  function readOpencodeTranscriptDirectory(path2) {
77785
78263
  let fd;
77786
78264
  try {
77787
- fd = openSync(path2, "r");
78265
+ fd = openSync2(path2, "r");
77788
78266
  const buf = Buffer.allocUnsafe(8192);
77789
- const n = readSync(fd, buf, 0, buf.length, 0);
78267
+ const n = readSync2(fd, buf, 0, buf.length, 0);
77790
78268
  const nl = buf.indexOf(10);
77791
78269
  const first = buf.toString("utf8", 0, nl >= 0 && nl < n ? nl : n);
77792
78270
  const o = JSON.parse(first);
@@ -77796,7 +78274,7 @@ function readOpencodeTranscriptDirectory(path2) {
77796
78274
  return null;
77797
78275
  } finally {
77798
78276
  if (fd !== void 0) try {
77799
- closeSync(fd);
78277
+ closeSync2(fd);
77800
78278
  } catch {
77801
78279
  }
77802
78280
  }
@@ -77823,7 +78301,7 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
77823
78301
  const full = join21(root, name2);
77824
78302
  let st;
77825
78303
  try {
77826
- st = statSync6(full);
78304
+ st = statSync7(full);
77827
78305
  } catch {
77828
78306
  continue;
77829
78307
  }
@@ -77846,7 +78324,7 @@ init_src5();
77846
78324
  import { readFileSync as readFileSync18, writeFileSync as writeFileSync14 } from "node:fs";
77847
78325
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
77848
78326
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
77849
- var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|dvuln|prob|claim|err)_[0-9a-f]{6,})/gi;
78327
+ var HANDLE_RE2 = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|dvuln|prob|claim|err)_[0-9a-f]{6,})/gi;
77850
78328
  var PLACEHOLDER_HANDLES = /* @__PURE__ */ new Set([
77851
78329
  "handle",
77852
78330
  "its-handle",
@@ -78065,7 +78543,7 @@ function splitJoinedCause(content, sentence, threadId, dispositions, out2) {
78065
78543
  if (!joined) return content;
78066
78544
  const causeBody = content.slice(joined.index + joined[0].length);
78067
78545
  const fix = content.slice(0, joined.index);
78068
- const fixed = new RegExp(HANDLE_RE.source, "i").exec(fix);
78546
+ const fixed = new RegExp(HANDLE_RE2.source, "i").exec(fix);
78069
78547
  const symptom = fixed && !/^\s*\[/.test(causeBody) ? `${fixed[0]} ` : "";
78070
78548
  const cause = parseCauseTag(`${symptom}${causeBody}`, sentence, threadId, dispositions);
78071
78549
  if (cause) out2.push(cause);
@@ -78073,7 +78551,7 @@ function splitJoinedCause(content, sentence, threadId, dispositions, out2) {
78073
78551
  }
78074
78552
  function parseCauseTag(content, sentence, threadId, dispositions) {
78075
78553
  const body2 = content.replace(/\s+/g, " ").trim();
78076
- const cited = new RegExp(HANDLE_RE.source, "i").exec(body2);
78554
+ const cited = new RegExp(HANDLE_RE2.source, "i").exec(body2);
78077
78555
  const handle2 = cited ? cited[1] ?? cited[2] : void 0;
78078
78556
  const base = { kind: "triage", sentence, ...threadId ? { threadId } : {} };
78079
78557
  if (handle2 && cited) {
@@ -78176,9 +78654,9 @@ function parseInlineTagsWithDispositions(text) {
78176
78654
  const threadMatch = ssM ? ssM.re.exec(content) : null;
78177
78655
  const body2 = content.replace(re, "");
78178
78656
  const handles = [];
78179
- HANDLE_RE.lastIndex = 0;
78657
+ HANDLE_RE2.lastIndex = 0;
78180
78658
  let hh;
78181
- while ((hh = HANDLE_RE.exec(body2)) !== null) {
78659
+ while ((hh = HANDLE_RE2.exec(body2)) !== null) {
78182
78660
  const handle2 = hh[1] ?? hh[2];
78183
78661
  if (!handle2) continue;
78184
78662
  if (isPlaceholderHandle(handle2)) {
@@ -78201,8 +78679,8 @@ function parseInlineTagsWithDispositions(text) {
78201
78679
  }
78202
78680
  if (confirmM || refuteM) {
78203
78681
  const body2 = content.replace(confirmM ? CONFIRM_PREFIX : REFUTE_PREFIX, "");
78204
- HANDLE_RE.lastIndex = 0;
78205
- const h2 = HANDLE_RE.exec(body2);
78682
+ HANDLE_RE2.lastIndex = 0;
78683
+ const h2 = HANDLE_RE2.exec(body2);
78206
78684
  let handle2 = h2 ? h2[1] ?? h2[2] : void 0;
78207
78685
  if (handle2 && isPlaceholderHandle(handle2)) {
78208
78686
  dispositions.placeholderEcho++;
@@ -78210,7 +78688,7 @@ function parseInlineTagsWithDispositions(text) {
78210
78688
  }
78211
78689
  if (handle2) {
78212
78690
  if (refuteM) {
78213
- const reason = body2.replace(new RegExp(HANDLE_RE.source, "gi"), " ").replace(/\s+/g, " ").trim();
78691
+ const reason = body2.replace(new RegExp(HANDLE_RE2.source, "gi"), " ").replace(/\s+/g, " ").trim();
78214
78692
  if (reason.length >= REFUTE_REASON_MIN) out2.push({ kind: "refute", handle: handle2, statement: reason, sentence: sfield });
78215
78693
  else dispositions.refuteTooShort++;
78216
78694
  } else {
@@ -78239,10 +78717,10 @@ function parseInlineTagsWithDispositions(text) {
78239
78717
  const r = deriveFixRationale(sentence, g.index, g.index + g[0].length);
78240
78718
  if (r.length >= FIX_RATIONALE_MIN) fixRationale = r;
78241
78719
  }
78242
- HANDLE_RE.lastIndex = 0;
78720
+ HANDLE_RE2.lastIndex = 0;
78243
78721
  let h;
78244
78722
  let emittedHandle = false;
78245
- while ((h = HANDLE_RE.exec(content)) !== null) {
78723
+ while ((h = HANDLE_RE2.exec(content)) !== null) {
78246
78724
  const handle2 = h[1] ?? h[2];
78247
78725
  if (handle2 && isPlaceholderHandle(handle2)) {
78248
78726
  dispositions.placeholderEcho++;
@@ -78285,20 +78763,20 @@ function parseInlineTagsWithDispositions(text) {
78285
78763
  continue;
78286
78764
  }
78287
78765
  const content = splitJoinedCause(lm[2], sfield, verbThread, dispositions, out2);
78288
- HANDLE_RE.lastIndex = 0;
78289
- const h = HANDLE_RE.exec(content);
78766
+ HANDLE_RE2.lastIndex = 0;
78767
+ const h = HANDLE_RE2.exec(content);
78290
78768
  let handle2 = h ? h[1] ?? h[2] : void 0;
78291
78769
  if (handle2 && isPlaceholderHandle(handle2)) {
78292
78770
  dispositions.placeholderEcho++;
78293
78771
  handle2 = void 0;
78294
78772
  }
78295
78773
  if (handle2) {
78296
- const inGroup = content.replace(new RegExp(HANDLE_RE.source, "gi"), " ").replace(/\s+/g, " ").trim();
78774
+ const inGroup = content.replace(new RegExp(HANDLE_RE2.source, "gi"), " ").replace(/\s+/g, " ").trim();
78297
78775
  const r = inGroup.length >= FIX_RATIONALE_MIN ? inGroup : deriveFixRationale(sentence, lm.index, lm.index + lm[0].length);
78298
78776
  let emitted = false;
78299
- HANDLE_RE.lastIndex = 0;
78777
+ HANDLE_RE2.lastIndex = 0;
78300
78778
  let hh;
78301
- while ((hh = HANDLE_RE.exec(content)) !== null) {
78779
+ while ((hh = HANDLE_RE2.exec(content)) !== null) {
78302
78780
  const hcap = hh[1] ?? hh[2];
78303
78781
  if (hcap) {
78304
78782
  emitted = true;
@@ -78327,8 +78805,8 @@ function parseInlineTagsWithDispositions(text) {
78327
78805
  while ((vm = pass.re.exec(sentence)) !== null) {
78328
78806
  if (citeMatched.has(vm.index)) continue;
78329
78807
  const body2 = vm[1];
78330
- HANDLE_RE.lastIndex = 0;
78331
- const h = HANDLE_RE.exec(body2);
78808
+ HANDLE_RE2.lastIndex = 0;
78809
+ const h = HANDLE_RE2.exec(body2);
78332
78810
  let handle2 = h ? h[1] ?? h[2] : void 0;
78333
78811
  if (handle2 && isPlaceholderHandle(handle2)) {
78334
78812
  dispositions.placeholderEcho++;
@@ -78339,7 +78817,7 @@ function parseInlineTagsWithDispositions(text) {
78339
78817
  continue;
78340
78818
  }
78341
78819
  if (pass.refute) {
78342
- const reason = body2.replace(new RegExp(HANDLE_RE.source, "gi"), " ").replace(/\s+/g, " ").trim();
78820
+ const reason = body2.replace(new RegExp(HANDLE_RE2.source, "gi"), " ").replace(/\s+/g, " ").trim();
78343
78821
  if (reason.length >= REFUTE_REASON_MIN) out2.push({ kind: "refute", handle: handle2, statement: reason, sentence: sfield });
78344
78822
  else dispositions.refuteTooShort++;
78345
78823
  } else {
@@ -78429,10 +78907,10 @@ function parseInlineTagsWithDispositions(text) {
78429
78907
  const isFailure = a[1].toLowerCase() === "failed";
78430
78908
  let refuteHandles;
78431
78909
  if (isFailure) {
78432
- HANDLE_RE.lastIndex = 0;
78910
+ HANDLE_RE2.lastIndex = 0;
78433
78911
  const hs = [];
78434
78912
  let hm;
78435
- while ((hm = HANDLE_RE.exec(statement)) !== null) {
78913
+ while ((hm = HANDLE_RE2.exec(statement)) !== null) {
78436
78914
  const h = hm[1] ?? hm[2];
78437
78915
  if (h && !hs.includes(h)) hs.push(h);
78438
78916
  }
@@ -78451,8 +78929,8 @@ function parseInlineTagsWithDispositions(text) {
78451
78929
  let pm;
78452
78930
  while ((pm = PATTERN_RE.exec(sentence)) !== null) {
78453
78931
  const body2 = pm[1].trim();
78454
- HANDLE_RE.lastIndex = 0;
78455
- const ph = HANDLE_RE.exec(body2);
78932
+ HANDLE_RE2.lastIndex = 0;
78933
+ const ph = HANDLE_RE2.exec(body2);
78456
78934
  const handle2 = ph ? ph[1] ?? ph[2] : void 0;
78457
78935
  if (handle2) {
78458
78936
  out2.push({ kind: "pattern", handle: handle2, sentence: sfield });
@@ -80244,7 +80722,7 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
80244
80722
  // src/retrieval-stack.ts
80245
80723
  init_src();
80246
80724
  import { execFileSync as execFileSync4 } from "node:child_process";
80247
- import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync7 } from "node:fs";
80725
+ import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync8 } from "node:fs";
80248
80726
  import { homedir as homedir6 } from "node:os";
80249
80727
  import { join as join26 } from "node:path";
80250
80728
  var RETRIEVAL_STACK_CAP = 24;
@@ -80764,7 +81242,7 @@ function readDirectDependencies(root) {
80764
81242
  const p = join26(root, c.file);
80765
81243
  if (!existsSync23(p)) continue;
80766
81244
  try {
80767
- const s = statSync7(p);
81245
+ const s = statSync8(p);
80768
81246
  stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
80769
81247
  } catch {
80770
81248
  continue;
@@ -80848,7 +81326,7 @@ function scanManifests(root) {
80848
81326
  for (const rel of paths) {
80849
81327
  const abs = join26(root, rel);
80850
81328
  try {
80851
- const s = statSync7(abs);
81329
+ const s = statSync8(abs);
80852
81330
  stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
80853
81331
  texts.set(rel, readFileSync23(abs, "utf8"));
80854
81332
  } catch {
@@ -82854,12 +83332,12 @@ function retireWitnesses(queue, channel, settledKeys) {
82854
83332
  return queue.filter((w) => !(w.channel === channel && settledKeys.has(w.witnessKey)));
82855
83333
  }
82856
83334
  var WIRE_SHIPPED_LABELS = /* @__PURE__ */ new Set(["Problem", "Vulnerability", "Solution", "RootCause"]);
82857
- var MOTIF_ID_PREFIX = "motif_community_";
83335
+ var MOTIF_ID_PREFIX = "motif_";
82858
83336
  var CANONICAL_ID_RE = /^(?:pat|sol|drc|dcause|dfix|dprob|dvuln|prob|claim|err)_[0-9a-f]{6,}$/i;
82859
83337
  function classifyWitnessTarget(nodeId, getNode) {
82860
83338
  if (nodeId.startsWith(MOTIF_ID_PREFIX)) {
82861
- const exemplar = nodeId.slice(MOTIF_ID_PREFIX.length);
82862
- if (CANONICAL_ID_RE.test(exemplar) && !exemplar.startsWith("pat_")) {
83339
+ const exemplar = getNode(nodeId)?.attrs?.["exemplarId"];
83340
+ if (typeof exemplar === "string" && CANONICAL_ID_RE.test(exemplar) && !exemplar.startsWith("pat_")) {
82863
83341
  const v = classifyWitnessTarget(exemplar, getNode);
82864
83342
  return v.kind === "deliverable" ? { kind: "translated", nodeId: v.nodeId } : v;
82865
83343
  }
@@ -83456,7 +83934,7 @@ function createWatchBreaker(deps) {
83456
83934
  }
83457
83935
 
83458
83936
  // src/engine.ts
83459
- var DAEMON_VERSION = true ? "2.0.21-dev.3952" : "2.0.0-alpha.0";
83937
+ var DAEMON_VERSION = true ? "2.0.21-dev.3993" : "2.0.0-alpha.0";
83460
83938
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
83461
83939
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
83462
83940
  var GIT_OP_MUTE_MS = 4e3;
@@ -83468,7 +83946,7 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
83468
83946
  function appendIdentityAudit(path2, record2, line) {
83469
83947
  if (!record2.accepted && record2.score <= 0) return;
83470
83948
  try {
83471
- if (existsSync28(path2) && statSync8(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
83949
+ if (existsSync28(path2) && statSync9(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
83472
83950
  renameSync4(path2, `${path2}.1`);
83473
83951
  }
83474
83952
  appendFileSync4(path2, line);
@@ -83642,7 +84120,7 @@ function createWorkspaceEngine(opts) {
83642
84120
  }
83643
84121
  let size = 0;
83644
84122
  try {
83645
- size = statSync8(path2).size;
84123
+ size = statSync9(path2).size;
83646
84124
  } catch {
83647
84125
  }
83648
84126
  lastActivityTs = Date.now();
@@ -83909,6 +84387,19 @@ function createWorkspaceEngine(opts) {
83909
84387
  return [];
83910
84388
  }
83911
84389
  };
84390
+ const motifSignals = /* @__PURE__ */ new Map();
84391
+ const motifSignalFor = (snap, intent) => {
84392
+ const seeds = motifSeeds(snap, intent);
84393
+ if (seeds.length === 0) return void 0;
84394
+ const key = `${store.mutationCount()}|${seeds.join(",")}`;
84395
+ let signal = motifSignals.get(key);
84396
+ if (!signal) {
84397
+ signal = motifSignal(store, seeds);
84398
+ if (motifSignals.size >= 32) motifSignals.delete(motifSignals.keys().next().value);
84399
+ motifSignals.set(key, signal);
84400
+ }
84401
+ return signal;
84402
+ };
83912
84403
  const statedIntentFor = (intent) => {
83913
84404
  const collective = intentRemote?.forIntent === intent ? intentRemote : null;
83914
84405
  return {
@@ -83959,10 +84450,12 @@ function createWorkspaceEngine(opts) {
83959
84450
  const liveIntent = intents.mostRecent(Date.now());
83960
84451
  maybeRefreshIntentPriors(liveIntent ?? null);
83961
84452
  const statedIntent = liveIntent ? statedIntentFor(liveIntent) : null;
84453
+ const sharedMotifSignal = motifSignalFor(sharedSnapshot, statedIntent);
83962
84454
  const { body: body2, snapshot, ledger } = assembleAgentContext({
83963
84455
  store,
83964
84456
  ...snapOpts,
83965
84457
  remote: remotePriors,
84458
+ ...sharedMotifSignal ? { motifSignal: sharedMotifSignal } : {},
83966
84459
  ...elicit ? { edgeElicitation: { instruction: PRIOR_TAG_INSTRUCTION } } : {},
83967
84460
  snapshot: sharedSnapshot,
83968
84461
  ...pendingUpdate ? { pendingUpdate } : {},
@@ -84263,14 +84756,6 @@ function createWorkspaceEngine(opts) {
84263
84756
  } catch (err2) {
84264
84757
  console.warn("[errata] problem context derivation failed:", err2);
84265
84758
  }
84266
- try {
84267
- const lc = detectLocalCommunities(store);
84268
- if (lc.communities > 0) {
84269
- console.log(`[errata] communities: ${lc.communities} detected (${lc.joint} joint local+cloud) across ${lc.assigned}/${lc.candidates} node(s)`);
84270
- }
84271
- } catch (err2) {
84272
- console.warn("[errata] joint community pass failed:", err2);
84273
- }
84274
84759
  return { report, localSkills: 0 };
84275
84760
  };
84276
84761
  const onWorkingFileChanged = (rel, sessionId, agentId) => {
@@ -84374,6 +84859,8 @@ function createWorkspaceEngine(opts) {
84374
84859
  const pendingUpdate = opts.pendingUpdate?.() ?? null;
84375
84860
  const daemonDistress = opts.daemonDistress?.() ?? null;
84376
84861
  const reviewItems = pickReviewItems();
84862
+ const sessionIntent = intent ? statedIntentFor(intent) : null;
84863
+ const sessionMotifSignal = motifSignalFor(scoped, sessionIntent);
84377
84864
  const { body: body2, snapshot } = assembleAgentContext({
84378
84865
  store,
84379
84866
  profile,
@@ -84386,7 +84873,8 @@ function createWorkspaceEngine(opts) {
84386
84873
  ...pendingUpdate ? { pendingUpdate } : {},
84387
84874
  ...daemonDistress ? { daemonDistress } : {},
84388
84875
  ...reviewItems.length ? { reviewItems } : {},
84389
- ...intent ? { statedIntent: statedIntentFor(intent) } : {}
84876
+ ...sessionIntent ? { statedIntent: sessionIntent } : {},
84877
+ ...sessionMotifSignal ? { motifSignal: sessionMotifSignal } : {}
84390
84878
  });
84391
84879
  const block = {
84392
84880
  body: body2,
@@ -91203,6 +91691,7 @@ async function startMultiDaemon(opts = {}) {
91203
91691
  app.post("/api/message", (c) => forward(c, cwdOf, { affinity: "follow" }));
91204
91692
  app.post("/api/session-end", (c) => forward(c, cwdOf, { affinity: "follow" }));
91205
91693
  app.post("/api/context-inject", (c) => forward(c, cwdOf, { affinity: "follow" }));
91694
+ app.post("/api/context-delta", (c) => forward(c, cwdOf, { affinity: "follow" }));
91206
91695
  app.post("/api/statusline", async (c) => {
91207
91696
  const body2 = await c.req.json().catch(() => ({}));
91208
91697
  const dir = statuslineDir(body2);
@@ -92804,7 +93293,7 @@ function shouldUseOAuthLogin(flags2, env2 = process.env) {
92804
93293
  import { spawnSync as spawnSync2 } from "node:child_process";
92805
93294
 
92806
93295
  // src/codex-runtime.ts
92807
- import { readdirSync as readdirSync12, statSync as statSync9 } from "node:fs";
93296
+ import { readdirSync as readdirSync12, statSync as statSync10 } from "node:fs";
92808
93297
  import { join as join42 } from "node:path";
92809
93298
  function resolveCodexExecutable(options = {}) {
92810
93299
  const platform = options.platform ?? process.platform;
@@ -92812,7 +93301,7 @@ function resolveCodexExecutable(options = {}) {
92812
93301
  if (platform !== "win32") return "codex";
92813
93302
  const fileTime = (path2) => {
92814
93303
  try {
92815
- const s = statSync9(path2);
93304
+ const s = statSync10(path2);
92816
93305
  return s.isFile() ? s.mtimeMs : null;
92817
93306
  } catch {
92818
93307
  return null;
@@ -92965,7 +93454,7 @@ async function diagnoseInstallation(cfg, dependencies) {
92965
93454
 
92966
93455
  // src/codex-doctor.ts
92967
93456
  import { spawn as spawn4 } from "node:child_process";
92968
- import { readFileSync as readFileSync37, statSync as statSync10 } from "node:fs";
93457
+ import { readFileSync as readFileSync37, statSync as statSync11 } from "node:fs";
92969
93458
  import { join as join44 } from "node:path";
92970
93459
  import { createInterface } from "node:readline";
92971
93460
 
@@ -93064,6 +93553,10 @@ try {
93064
93553
  }
93065
93554
  } catch {}
93066
93555
  let receipt = null;
93556
+ // CTX-delta: the body this session was last handed sits beside its receipt, so
93557
+ // a changed snapshot can go out as only what changed (the daemon renders it).
93558
+ const bodyPath = statePath && statePath.replace(/\.json$/, '.body.md');
93559
+ let emittedBody = null;
93067
93560
  const post = async (endpoint, relay = false) => {
93068
93561
  try {
93069
93562
  const response = await fetch('http://127.0.0.1:' + port + '/api/' + endpoint, {
@@ -93097,14 +93590,44 @@ try {
93097
93590
  // Receipt is local to this graph + session, survives daemon restarts, and
93098
93591
  // records stdout emission, not a server's intention to send a response.
93099
93592
  if (event === 'SessionStart' || previous.hash !== digest) {
93100
- contexts.push('Errata loaded the maintained local workspace context. This block REPLACES any earlier errata context block in this conversation. It is the latest saved snapshot; the daemon maintains it as work proceeds.\n\n' + body);
93101
- if (!/^(0|off|false|no)$/i.test((process.env.ERRATA_RECALL_CARD || '').trim())) {
93593
+ const normalized = body.replace(/\r\n?/g, '\n');
93594
+ // Every SessionStart (startup, resume, compact, clear) sends the whole
93595
+ // block: the window may no longer hold the last one.
93596
+ let delta = null;
93597
+ if (event !== 'SessionStart' && previous.hash && bodyPath) {
93598
+ let prior = '';
93599
+ try { prior = boundedRead(bodyPath, 512 * 1024); } catch {}
93600
+ if (prior && hash(prior).slice(0, 16) === previous.hash) {
93601
+ try {
93602
+ const response = await fetch('http://127.0.0.1:' + port + '/api/context-delta', {
93603
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
93604
+ body: JSON.stringify({ cwd: payload.cwd, hook_event_name: event, prev: prior, next: normalized }),
93605
+ signal: AbortSignal.timeout(2000),
93606
+ });
93607
+ if (response.ok) delta = await response.json();
93608
+ } catch { /* no daemon: the whole block goes, as before */ }
93609
+ }
93610
+ }
93611
+ if (delta && delta.unchanged === true) {
93612
+ // Only bookkeeping moved: nothing to send, but this snapshot is now what the window holds.
93102
93613
  try {
93103
- const card = JSON.parse(boundedRead(join(workspaceRoot, '.errata', 'context-card.json'), 128 * 1024));
93104
- if (card.hash === digest && typeof card.line === 'string' && card.line) messages.push(card.line);
93105
- } catch { /* Never show a card for a different snapshot. */ }
93614
+ mkdirSync(stateDir, { recursive: true });
93615
+ writeFileSync(statePath, JSON.stringify({ hash: digest, at: Date.now() }), { mode: 0o600 });
93616
+ writeFileSync(bodyPath, normalized, { mode: 0o600 });
93617
+ } catch { /* the next change just goes whole */ }
93618
+ } else {
93619
+ contexts.push(delta && typeof delta.delta === 'string' && delta.delta
93620
+ ? delta.delta
93621
+ : 'Errata loaded the maintained local workspace context. This block REPLACES any earlier errata context block in this conversation. It is the latest saved snapshot; the daemon maintains it as work proceeds.\n\n' + body);
93622
+ if (!/^(0|off|false|no)$/i.test((process.env.ERRATA_RECALL_CARD || '').trim())) {
93623
+ try {
93624
+ const card = JSON.parse(boundedRead(join(workspaceRoot, '.errata', 'context-card.json'), 128 * 1024));
93625
+ if (card.hash === digest && typeof card.line === 'string' && card.line) messages.push(card.line);
93626
+ } catch { /* Never show a card for a different snapshot. */ }
93627
+ }
93628
+ receipt = { hash: digest, at: Date.now() };
93629
+ emittedBody = normalized;
93106
93630
  }
93107
- receipt = { hash: digest, at: Date.now() };
93108
93631
  }
93109
93632
  } else if (event === 'SessionStart' || !previous.unavailable) {
93110
93633
  messages.push('errata: workspace priors are unavailable; run errata doctor in this checkout.');
@@ -93126,6 +93649,7 @@ try {
93126
93649
  const temp = statePath + '.' + process.pid + '.tmp';
93127
93650
  writeFileSync(temp, JSON.stringify(receipt), { mode: 0o600 });
93128
93651
  renameSync(temp, statePath);
93652
+ if (emittedBody !== null && bodyPath) writeFileSync(bodyPath, emittedBody, { mode: 0o600 });
93129
93653
  } catch { /* Read-only workspace: retry next time rather than drop context. */ }
93130
93654
  }
93131
93655
  resolve();
@@ -93212,7 +93736,7 @@ function inspectCodexContext(cwd) {
93212
93736
  const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
93213
93737
  try {
93214
93738
  const file2 = join44(root, ".errata", "context.md");
93215
- if (statSync10(file2).size <= 128 * 1024 && readFileSync37(file2, "utf8").trim()) {
93739
+ if (statSync11(file2).size <= 128 * 1024 && readFileSync37(file2, "utf8").trim()) {
93216
93740
  return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
93217
93741
  }
93218
93742
  } catch {
@@ -94353,7 +94877,7 @@ function describeStatusLineOutcome(outcome) {
94353
94877
 
94354
94878
  // src/claude-mods.ts
94355
94879
  import { createHash as createHash21 } from "node:crypto";
94356
- import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync41, readdirSync as readdirSync14, rmSync as rmSync4, statSync as statSync11, writeFileSync as writeFileSync30 } from "node:fs";
94880
+ import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync41, readdirSync as readdirSync14, rmSync as rmSync4, statSync as statSync12, writeFileSync as writeFileSync30 } from "node:fs";
94357
94881
  import { delimiter as delimiter2, dirname as dirname15, join as join48, relative as relative7, resolve as resolve9, sep as sep5 } from "node:path";
94358
94882
  import { fileURLToPath as fileURLToPath3 } from "node:url";
94359
94883
  var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
@@ -94371,7 +94895,7 @@ function listFiles(root, dir = root) {
94371
94895
  for (const name2 of readdirSync14(dir)) {
94372
94896
  const abs = join48(dir, name2);
94373
94897
  if (isEngineOwned(relative7(root, abs))) continue;
94374
- if (statSync11(abs).isDirectory()) out2.push(...listFiles(root, abs));
94898
+ if (statSync12(abs).isDirectory()) out2.push(...listFiles(root, abs));
94375
94899
  else out2.push(abs);
94376
94900
  }
94377
94901
  return out2;
@@ -96909,10 +97433,10 @@ function spawnDaemonDetached(options = {}) {
96909
97433
  try {
96910
97434
  const logPath = daemonLogPath();
96911
97435
  try {
96912
- if (statSync12(logPath).size > 5 * 1024 * 1024) renameSync7(logPath, `${logPath}.1`);
97436
+ if (statSync13(logPath).size > 5 * 1024 * 1024) renameSync7(logPath, `${logPath}.1`);
96913
97437
  } catch {
96914
97438
  }
96915
- out2 = openSync2(logPath, "a");
97439
+ out2 = openSync3(logPath, "a");
96916
97440
  } catch {
96917
97441
  }
96918
97442
  spawn5(cmd2, args2, {
@@ -96930,7 +97454,7 @@ function spawnDaemonDetached(options = {}) {
96930
97454
  NODE_OPTIONS: `${daemonEnv["NODE_OPTIONS"] ?? ""} --max-old-space-size=${DAEMON_MAX_HEAP_MB}`.trim()
96931
97455
  }
96932
97456
  }).unref();
96933
- if (out2 !== "ignore") closeSync2(out2);
97457
+ if (out2 !== "ignore") closeSync3(out2);
96934
97458
  }
96935
97459
  function ensureSingletonRunning(options = {}) {
96936
97460
  try {