@inerrata-corporation/errata 2.0.21-dev.3975 → 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
@@ -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();
@@ -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_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;
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;
@@ -32009,11 +32102,11 @@ var init_generalizer = __esm({
32009
32102
  function layerOf(kind) {
32010
32103
  return kind === "Technique" ? "technique" : kind === "AntiPattern" ? "antipattern" : "pattern";
32011
32104
  }
32012
- function motifTitle(members, layer, instanceCount) {
32013
- const top = [...members].sort(
32014
- (a, b) => b.extractionConfidence - a.extractionConfidence
32015
- )[0];
32016
- 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];
32017
32110
  }
32018
32111
  function classifyMotif(store, instances, promoted) {
32019
32112
  if (!promoted || instances.length === 0) return "Pattern";
@@ -32022,70 +32115,141 @@ function classifyMotif(store, instances, promoted) {
32022
32115
  if (solvedShare <= 0.2) return "AntiPattern";
32023
32116
  return "Pattern";
32024
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
+ }
32025
32152
  function promoteMotifs(store, t) {
32153
+ const report = { communities: 0, candidates: 0, incoherent: 0, promoted: 0, techniques: 0, antipatterns: 0, retracted: 0, retired: 0 };
32026
32154
  const byCommunity = /* @__PURE__ */ new Map();
32027
32155
  for (const label of MEMBER_LABELS) {
32028
32156
  for (const n of store.findNodesByLabel(label)) {
32029
32157
  if (n.label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
32030
- const c = n.community;
32031
- if (!c) continue;
32158
+ const c = n.attrs["localCommunity"];
32159
+ if (typeof c !== "string") continue;
32032
32160
  const g = byCommunity.get(c) ?? [];
32033
32161
  g.push(n);
32034
32162
  byCommunity.set(c, g);
32035
32163
  }
32036
32164
  }
32037
- let candidates = 0;
32038
- let promoted = 0;
32039
- let techniques = 0;
32040
- 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();
32041
32193
  store.transaction(() => {
32042
32194
  for (const [cid, members] of byCommunity) {
32043
32195
  const instances = members.filter((m) => m.label === "Problem");
32044
32196
  const instanceCount = instances.length || members.length;
32045
- const motifId = `motif_${cid}`;
32046
- 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));
32047
32200
  const d = motifDecision({
32048
- instances: members.map((m) => ({
32049
- confidence: m.extractionConfidence,
32050
- failed: false
32051
- })),
32201
+ instances: members.map((m) => ({ confidence: m.extractionConfidence, failed: false })),
32052
32202
  memberCount: members.length,
32053
32203
  instanceCount,
32054
- priorSurvivedRuns: existing?.attrs["survivedRuns"] ?? 0
32204
+ priorSurvivedRuns: prior?.node.attrs["survivedRuns"] ?? 0,
32205
+ coherence
32055
32206
  });
32056
- if (!d.isCandidate) continue;
32057
- candidates++;
32207
+ if (!d.isCandidate) {
32208
+ if (members.length >= 5) report.incoherent++;
32209
+ continue;
32210
+ }
32211
+ report.candidates++;
32212
+ kept.add(motifId);
32058
32213
  const kind = classifyMotif(store, instances, d.promoted);
32214
+ const exemplar = exemplarOf(members);
32059
32215
  const motif = {
32060
32216
  id: motifId,
32061
32217
  label: kind,
32062
32218
  // Refresh the deterministic title every run (exemplar/count/kind drift),
32063
32219
  // but never clobber a distilled one — a distillation pass owns it then.
32064
- 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),
32065
32221
  extractionConfidence: d.motifConfidence,
32066
32222
  extractionSource: "bko-inferred",
32067
- embedding: existing?.embedding ?? [],
32068
- cumulativeSurprise: existing?.cumulativeSurprise ?? 0,
32069
- peakSurprise: existing?.peakSurprise ?? 0,
32223
+ embedding: prior?.node.embedding ?? [],
32224
+ cumulativeSurprise: prior?.node.cumulativeSurprise ?? 0,
32225
+ peakSurprise: prior?.node.peakSurprise ?? 0,
32070
32226
  cumulativeHits: instanceCount,
32071
32227
  lastUpdatedAt: t,
32072
- createdAt: existing?.createdAt ?? t,
32073
- memoryTier: existing?.memoryTier ?? "short-term",
32074
- pageRank: existing?.pageRank ?? 0,
32228
+ createdAt: prior?.node.createdAt ?? t,
32229
+ memoryTier: prior?.node.memoryTier ?? "short-term",
32230
+ pageRank: prior?.node.pageRank ?? 0,
32075
32231
  isLandmark: d.promoted,
32076
- community: cid,
32232
+ // The community column belongs to the joint pass alone; a motif names
32233
+ // its community in attrs.communityId.
32234
+ community: null,
32077
32235
  stability: d.stable ? "stable" : "forming",
32078
32236
  attrs: {
32237
+ ...prior?.node.attrs ?? {},
32079
32238
  layer: layerOf(kind),
32080
32239
  communityId: cid,
32081
32240
  survivedRuns: d.survivedRuns,
32082
32241
  motifConfidence: d.motifConfidence,
32083
32242
  memberCount: members.length,
32084
32243
  instanceCount,
32244
+ coherence: Math.round(coherence * 100) / 100,
32245
+ memberIds: instances.map((m) => m.id),
32246
+ ...exemplar ? { exemplarId: exemplar.id } : {},
32247
+ missedRuns: 0,
32085
32248
  promoted: d.promoted
32086
32249
  }
32087
32250
  };
32088
32251
  store.mergeNode(motif);
32252
+ const now = new Set(instances.map((m) => m.id));
32089
32253
  for (const m of instances) {
32090
32254
  store.mergeEdge({
32091
32255
  id: `edge_${digest({ from: m.id, type: "INSTANCE_OF", to: motifId })}`.slice(0, 24),
@@ -32101,21 +32265,45 @@ function promoteMotifs(store, t) {
32101
32265
  attrs: {}
32102
32266
  });
32103
32267
  }
32104
- if (d.promoted) promoted++;
32105
- if (kind === "Technique") techniques++;
32106
- 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
+ }
32107
32292
  }
32108
32293
  });
32109
- return { communities: byCommunity.size, candidates, promoted, techniques, antipatterns };
32294
+ return report;
32110
32295
  }
32111
- var MEMBER_LABELS;
32296
+ var MEMBER_LABELS, MOTIF_LABELS, LINEAGE_MIN_JACCARD;
32112
32297
  var init_motifs = __esm({
32113
32298
  "../../packages/generalizer/src/motifs.ts"() {
32114
32299
  "use strict";
32115
32300
  init_src2();
32301
+ init_src5();
32116
32302
  init_src3();
32117
32303
  init_src();
32118
32304
  MEMBER_LABELS = ["Problem", "RootCause", "Solution"];
32305
+ MOTIF_LABELS = ["Pattern", "Technique", "AntiPattern"];
32306
+ LINEAGE_MIN_JACCARD = 0.5;
32119
32307
  }
32120
32308
  });
32121
32309
 
@@ -32331,44 +32519,14 @@ function runFullRescore(store) {
32331
32519
  landmarkFlips++;
32332
32520
  }
32333
32521
  });
32334
- const MOTIF_LABELS = /* @__PURE__ */ new Set(["Pattern", "Technique", "AntiPattern"]);
32335
- const semanticIds = /* @__PURE__ */ new Set();
32336
- for (const label of SEMANTIC_NODE_LABELS) {
32337
- if (MOTIF_LABELS.has(label)) continue;
32338
- for (const n of store.findNodesByLabel(label)) semanticIds.add(n.id);
32339
- }
32340
- const semAdj = /* @__PURE__ */ new Map();
32341
- const protect = [];
32342
- const addAdj = (a, b, w) => {
32343
- const l = semAdj.get(a) ?? [];
32344
- l.push({ to: b, weight: w });
32345
- semAdj.set(a, l);
32346
- };
32347
- for (const id of semanticIds) {
32348
- for (const e of store.outEdges(id)) {
32349
- if (!semanticIds.has(e.to)) continue;
32350
- const conf = e.confidence > 0 ? e.confidence : 0.5;
32351
- const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
32352
- addAdj(id, e.to, w);
32353
- addAdj(e.to, id, w);
32354
- if (isCausalProtected(e.type)) protect.push([id, e.to]);
32355
- }
32356
- }
32357
- for (const { a, b, weight } of codeAnchorProjection(store, semanticIds)) {
32358
- addAdj(a, b, weight);
32359
- addAdj(b, a, weight);
32360
- }
32361
- const comm = detectCommunitiesLeiden({ nodeIds: [...semanticIds], adj: semAdj }, { protect });
32362
- store.transaction(() => {
32363
- for (const [id, c] of comm.community) store.updateNode(id, { community: c });
32364
- });
32522
+ const lc = detectLocalCommunities(store);
32365
32523
  const motifs = promoteMotifs(store, started2);
32366
32524
  return {
32367
32525
  scoredNodes: scored,
32368
32526
  iterations: result.iterations,
32369
32527
  converged: result.converged,
32370
32528
  landmarks: allLandmarks.size,
32371
- communities: comm.count,
32529
+ communities: lc.communities,
32372
32530
  motifsPromoted: motifs.promoted,
32373
32531
  techniques: motifs.techniques,
32374
32532
  antipatterns: motifs.antipatterns,
@@ -32427,28 +32585,6 @@ function runNightlyPipeline(store) {
32427
32585
  durationMs: Date.now() - started2
32428
32586
  };
32429
32587
  }
32430
- function codeAnchorProjection(store, semanticIds, opts = {}) {
32431
- const anchorToNodes = /* @__PURE__ */ new Map();
32432
- for (const id of semanticIds) {
32433
- for (const e of store.outEdges(id, ["ANCHORED_AT"])) {
32434
- if (semanticIds.has(e.to)) continue;
32435
- const l = anchorToNodes.get(e.to) ?? [];
32436
- l.push(id);
32437
- anchorToNodes.set(e.to, l);
32438
- }
32439
- }
32440
- const hubCap = opts.hubCap ?? Math.max(8, Math.floor(semanticIds.size * 0.03));
32441
- const base = opts.weight ?? 1;
32442
- const out2 = [];
32443
- for (const nodes of anchorToNodes.values()) {
32444
- if (nodes.length < 2 || nodes.length > hubCap) continue;
32445
- const w = base / Math.log2(nodes.length + 1);
32446
- for (let i2 = 0; i2 < nodes.length; i2++) {
32447
- for (let j = i2 + 1; j < nodes.length; j++) out2.push({ a: nodes[i2], b: nodes[j], weight: w });
32448
- }
32449
- }
32450
- return out2;
32451
- }
32452
32588
  var FULL_RESCORE_EVERY, INCREMENTAL_REGION_MAX_FRACTION, INCREMENTAL_HOPS;
32453
32589
  var init_nightly = __esm({
32454
32590
  "../../packages/generalizer/src/nightly.ts"() {
@@ -32826,6 +32962,59 @@ var init_relevance_rank = __esm({
32826
32962
  }
32827
32963
  });
32828
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
+
32829
33018
  // ../../packages/generalizer/src/index.ts
32830
33019
  var src_exports3 = {};
32831
33020
  __export(src_exports3, {
@@ -32846,7 +33035,6 @@ __export(src_exports3, {
32846
33035
  burstConductance: () => burstConductance,
32847
33036
  burstStaticConductance: () => burstStaticConductance,
32848
33037
  closeProblem: () => closeProblem,
32849
- codeAnchorProjection: () => codeAnchorProjection,
32850
33038
  commandSignature: () => commandSignature,
32851
33039
  embedCodeNodes: () => embedCodeNodes,
32852
33040
  embedSemanticNodes: () => embedSemanticNodes,
@@ -32857,6 +33045,8 @@ __export(src_exports3, {
32857
33045
  ingestErrorSignature: () => ingestErrorSignature,
32858
33046
  localBurst: () => localBurst,
32859
33047
  mergeProblemsByEmbedding: () => mergeProblemsByEmbedding,
33048
+ motifCoherence: () => motifCoherence,
33049
+ motifSignal: () => motifSignal,
32860
33050
  nemoriDecide: () => nemoriDecide,
32861
33051
  promoteMotifs: () => promoteMotifs,
32862
33052
  rankAgainstEmbedding: () => rankAgainstEmbedding,
@@ -32882,6 +33072,7 @@ var init_src8 = __esm({
32882
33072
  init_motifs();
32883
33073
  init_embed_code();
32884
33074
  init_relevance_rank();
33075
+ init_motif_signal();
32885
33076
  }
32886
33077
  });
32887
33078
 
@@ -35936,7 +36127,7 @@ function hasForkedDrift(currentHex, birthHex, maxSimRatio = DRIFT_FORK_RATIO) {
35936
36127
  if (!currentHex || !birthHex) return false;
35937
36128
  return simRatio(fromHex(currentHex), fromHex(birthHex)) < maxSimRatio;
35938
36129
  }
35939
- function jaccard(a, b) {
36130
+ function jaccard2(a, b) {
35940
36131
  if (a.size === 0 && b.size === 0) return 0;
35941
36132
  let inter = 0;
35942
36133
  for (const x of a) if (b.has(x)) inter++;
@@ -35970,7 +36161,7 @@ function score(a, b) {
35970
36161
  weighted += body2 * WEIGHTS.body;
35971
36162
  total += WEIGHTS.body;
35972
36163
  if (a.callees.size > 0 || b.callees.size > 0) {
35973
- const topo = jaccard(a.callees, b.callees);
36164
+ const topo = jaccard2(a.callees, b.callees);
35974
36165
  evidence["topology"] = round(topo);
35975
36166
  weighted += topo * WEIGHTS.topology;
35976
36167
  total += WEIGHTS.topology;
@@ -77354,6 +77545,7 @@ function createSubagentState() {
77354
77545
 
77355
77546
  // src/subagent-context.ts
77356
77547
  init_src6();
77548
+ init_src8();
77357
77549
  init_src5();
77358
77550
  init_src2();
77359
77551
  init_recall_signal();
@@ -77386,8 +77578,12 @@ function renderSubagentBlock(args2) {
77386
77578
  coverage: h.coverage
77387
77579
  })) : [];
77388
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;
77389
77584
  const { body: body2, snapshot: shown } = assembleAgentContext({
77390
77585
  store,
77586
+ ...signal ? { motifSignal: signal } : {},
77391
77587
  profile: args2.profile,
77392
77588
  ...args2.atCommit ? { atCommit: args2.atCommit } : {},
77393
77589
  reviewCount: 0,
@@ -83136,12 +83332,12 @@ function retireWitnesses(queue, channel, settledKeys) {
83136
83332
  return queue.filter((w) => !(w.channel === channel && settledKeys.has(w.witnessKey)));
83137
83333
  }
83138
83334
  var WIRE_SHIPPED_LABELS = /* @__PURE__ */ new Set(["Problem", "Vulnerability", "Solution", "RootCause"]);
83139
- var MOTIF_ID_PREFIX = "motif_community_";
83335
+ var MOTIF_ID_PREFIX = "motif_";
83140
83336
  var CANONICAL_ID_RE = /^(?:pat|sol|drc|dcause|dfix|dprob|dvuln|prob|claim|err)_[0-9a-f]{6,}$/i;
83141
83337
  function classifyWitnessTarget(nodeId, getNode) {
83142
83338
  if (nodeId.startsWith(MOTIF_ID_PREFIX)) {
83143
- const exemplar = nodeId.slice(MOTIF_ID_PREFIX.length);
83144
- 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_")) {
83145
83341
  const v = classifyWitnessTarget(exemplar, getNode);
83146
83342
  return v.kind === "deliverable" ? { kind: "translated", nodeId: v.nodeId } : v;
83147
83343
  }
@@ -83738,7 +83934,7 @@ function createWatchBreaker(deps) {
83738
83934
  }
83739
83935
 
83740
83936
  // src/engine.ts
83741
- var DAEMON_VERSION = true ? "2.0.21-dev.3975" : "2.0.0-alpha.0";
83937
+ var DAEMON_VERSION = true ? "2.0.21-dev.3993" : "2.0.0-alpha.0";
83742
83938
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
83743
83939
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
83744
83940
  var GIT_OP_MUTE_MS = 4e3;
@@ -84191,6 +84387,19 @@ function createWorkspaceEngine(opts) {
84191
84387
  return [];
84192
84388
  }
84193
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
+ };
84194
84403
  const statedIntentFor = (intent) => {
84195
84404
  const collective = intentRemote?.forIntent === intent ? intentRemote : null;
84196
84405
  return {
@@ -84241,10 +84450,12 @@ function createWorkspaceEngine(opts) {
84241
84450
  const liveIntent = intents.mostRecent(Date.now());
84242
84451
  maybeRefreshIntentPriors(liveIntent ?? null);
84243
84452
  const statedIntent = liveIntent ? statedIntentFor(liveIntent) : null;
84453
+ const sharedMotifSignal = motifSignalFor(sharedSnapshot, statedIntent);
84244
84454
  const { body: body2, snapshot, ledger } = assembleAgentContext({
84245
84455
  store,
84246
84456
  ...snapOpts,
84247
84457
  remote: remotePriors,
84458
+ ...sharedMotifSignal ? { motifSignal: sharedMotifSignal } : {},
84248
84459
  ...elicit ? { edgeElicitation: { instruction: PRIOR_TAG_INSTRUCTION } } : {},
84249
84460
  snapshot: sharedSnapshot,
84250
84461
  ...pendingUpdate ? { pendingUpdate } : {},
@@ -84545,14 +84756,6 @@ function createWorkspaceEngine(opts) {
84545
84756
  } catch (err2) {
84546
84757
  console.warn("[errata] problem context derivation failed:", err2);
84547
84758
  }
84548
- try {
84549
- const lc = detectLocalCommunities(store);
84550
- if (lc.communities > 0) {
84551
- console.log(`[errata] communities: ${lc.communities} detected (${lc.joint} joint local+cloud) across ${lc.assigned}/${lc.candidates} node(s)`);
84552
- }
84553
- } catch (err2) {
84554
- console.warn("[errata] joint community pass failed:", err2);
84555
- }
84556
84759
  return { report, localSkills: 0 };
84557
84760
  };
84558
84761
  const onWorkingFileChanged = (rel, sessionId, agentId) => {
@@ -84656,6 +84859,8 @@ function createWorkspaceEngine(opts) {
84656
84859
  const pendingUpdate = opts.pendingUpdate?.() ?? null;
84657
84860
  const daemonDistress = opts.daemonDistress?.() ?? null;
84658
84861
  const reviewItems = pickReviewItems();
84862
+ const sessionIntent = intent ? statedIntentFor(intent) : null;
84863
+ const sessionMotifSignal = motifSignalFor(scoped, sessionIntent);
84659
84864
  const { body: body2, snapshot } = assembleAgentContext({
84660
84865
  store,
84661
84866
  profile,
@@ -84668,7 +84873,8 @@ function createWorkspaceEngine(opts) {
84668
84873
  ...pendingUpdate ? { pendingUpdate } : {},
84669
84874
  ...daemonDistress ? { daemonDistress } : {},
84670
84875
  ...reviewItems.length ? { reviewItems } : {},
84671
- ...intent ? { statedIntent: statedIntentFor(intent) } : {}
84876
+ ...sessionIntent ? { statedIntent: sessionIntent } : {},
84877
+ ...sessionMotifSignal ? { motifSignal: sessionMotifSignal } : {}
84672
84878
  });
84673
84879
  const block = {
84674
84880
  body: body2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.21-dev.3975",
3
+ "version": "2.0.21-dev.3993",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -16639,7 +16639,7 @@ function hasForkedDrift(currentHex, birthHex, maxSimRatio = DRIFT_FORK_RATIO) {
16639
16639
  if (!currentHex || !birthHex) return false;
16640
16640
  return simRatio(fromHex(currentHex), fromHex(birthHex)) < maxSimRatio;
16641
16641
  }
16642
- function jaccard(a, b) {
16642
+ function jaccard2(a, b) {
16643
16643
  if (a.size === 0 && b.size === 0) return 0;
16644
16644
  let inter = 0;
16645
16645
  for (const x of a) if (b.has(x)) inter++;
@@ -16673,7 +16673,7 @@ function score(a, b) {
16673
16673
  weighted += body2 * WEIGHTS.body;
16674
16674
  total += WEIGHTS.body;
16675
16675
  if (a.callees.size > 0 || b.callees.size > 0) {
16676
- const topo = jaccard(a.callees, b.callees);
16676
+ const topo = jaccard2(a.callees, b.callees);
16677
16677
  evidence["topology"] = round(topo);
16678
16678
  weighted += topo * WEIGHTS.topology;
16679
16679
  total += WEIGHTS.topology;
@@ -25728,6 +25728,26 @@ function detectCommunitiesLeiden(input, opts = {}) {
25728
25728
  return normalize(assignment);
25729
25729
  }
25730
25730
 
25731
+ // ../../packages/math/src/community-floor.ts
25732
+ var COMMUNITY_MIN_SIZE = 2;
25733
+ var COMMUNITY_FLOOR_SCALE = 0.5;
25734
+ function communitySizeFloor(domainSize) {
25735
+ if (!(domainSize > 1)) return COMMUNITY_MIN_SIZE;
25736
+ return Math.max(COMMUNITY_MIN_SIZE, Math.ceil(COMMUNITY_FLOOR_SCALE * Math.log(domainSize)));
25737
+ }
25738
+ function communityDomain(memberDomains, domainSize) {
25739
+ const held = /* @__PURE__ */ new Map();
25740
+ for (const domains of memberDomains) for (const d of new Set(domains)) held.set(d, (held.get(d) ?? 0) + 1);
25741
+ let best = null;
25742
+ for (const [d, n] of held) {
25743
+ if (n * 2 < memberDomains.length) continue;
25744
+ const size = domainSize.get(d) ?? Infinity;
25745
+ const bestSize = best === null ? Infinity : domainSize.get(best) ?? Infinity;
25746
+ if (best === null || size < bestSize || size === bestSize && d < best) best = d;
25747
+ }
25748
+ return best;
25749
+ }
25750
+
25731
25751
  // ../../packages/math/src/void-demand.ts
25732
25752
  var DEMAND_HOT = Math.log1p(10);
25733
25753
  var DEMAND_WARM = Math.log1p(5);
@@ -25777,8 +25797,10 @@ function a2MotifQuality(input) {
25777
25797
  // ../../packages/math/src/motif-gate.ts
25778
25798
  var MOTIF_MIN_MEMBERS = 5;
25779
25799
  var MOTIF_MIN_SURVIVED = 2;
25800
+ var MOTIF_MIN_COHERENCE = 0.5;
25780
25801
  function motifDecision(input) {
25781
- if (input.memberCount < MOTIF_MIN_MEMBERS) {
25802
+ const isIncoherent = input.coherence !== void 0 && input.coherence < MOTIF_MIN_COHERENCE;
25803
+ if (input.memberCount < MOTIF_MIN_MEMBERS || isIncoherent) {
25782
25804
  return {
25783
25805
  isCandidate: false,
25784
25806
  survivedRuns: input.priorSurvivedRuns,
@@ -28300,6 +28322,137 @@ var DRIFT_VALUES = new Set(Object.values(DRIFT_KIND));
28300
28322
 
28301
28323
  // ../../packages/local-graph/src/community.ts
28302
28324
  init_src2();
28325
+ var JOINT_COMMUNITY_LABELS = [
28326
+ "Problem",
28327
+ "Vulnerability",
28328
+ "Solution",
28329
+ "RootCause",
28330
+ "Pattern"
28331
+ ];
28332
+ var JOINT_COMMUNITY_EDGES = [
28333
+ "CAUSED_BY",
28334
+ "SOLVED_BY",
28335
+ "FIXED_BY",
28336
+ "CONTRADICTS",
28337
+ "INSTANCE_OF",
28338
+ "MATCHES",
28339
+ "IMPLEMENTS",
28340
+ "TRIAGED_BY",
28341
+ "INDICATES",
28342
+ "CONFIRMS",
28343
+ "RELATES_TO"
28344
+ ];
28345
+ var DOMAIN_EDGES = ["DEPENDS_ON", "CONCERNS", "OCCURS_IN"];
28346
+ var DOMAIN_INHERIT_EDGES = ["CAUSED_BY", "SOLVED_BY", "FIXED_BY"];
28347
+ function domainKey(id) {
28348
+ return id.replace(/(.)@[^@/]*$/, "$1");
28349
+ }
28350
+ function candidateDomains(store2, ids, labelOf) {
28351
+ const own = /* @__PURE__ */ new Map();
28352
+ for (const id of ids) {
28353
+ const label = labelOf.get(id);
28354
+ if (label !== "Problem" && label !== "Vulnerability") continue;
28355
+ const domains = store2.outEdges(id, DOMAIN_EDGES).map((e) => domainKey(e.to));
28356
+ if (domains.length > 0) own.set(id, domains);
28357
+ }
28358
+ const out2 = new Map(own);
28359
+ for (const id of ids) {
28360
+ const label = labelOf.get(id);
28361
+ if (label !== "RootCause" && label !== "Solution") continue;
28362
+ const inherited = store2.inEdges(id, DOMAIN_INHERIT_EDGES).flatMap((e) => own.get(e.from) ?? []);
28363
+ if (inherited.length > 0) out2.set(id, [...new Set(inherited)]);
28364
+ }
28365
+ return out2;
28366
+ }
28367
+ function detectLocalCommunities(store2, opts = {}) {
28368
+ const report = { candidates: 0, communities: 0, joint: 0, assigned: 0, belowFloor: 0, cleared: 0 };
28369
+ const nodes = /* @__PURE__ */ new Map();
28370
+ const unowned = [];
28371
+ for (const label of JOINT_COMMUNITY_LABELS) {
28372
+ for (const n of store2.findNodesByLabel(label)) {
28373
+ if (n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) unowned.push(n);
28374
+ else nodes.set(n.id, n);
28375
+ }
28376
+ }
28377
+ const ids = new Set(nodes.keys());
28378
+ report.candidates = ids.size;
28379
+ for (const label of SEMANTIC_NODE_LABELS) {
28380
+ if (!JOINT_COMMUNITY_LABELS.includes(label)) unowned.push(...store2.findNodesByLabel(label));
28381
+ }
28382
+ store2.transaction(() => {
28383
+ for (const n of unowned) {
28384
+ if (n.attrs["localCommunity"] !== void 0) {
28385
+ const { localCommunity: _gone, ...rest } = n.attrs;
28386
+ store2.updateNode(n.id, { attrs: rest });
28387
+ }
28388
+ if (!n.community || n.attrs["source"] === "cloud") continue;
28389
+ store2.setCommunity(n.id, null);
28390
+ report.cleared++;
28391
+ }
28392
+ });
28393
+ if (ids.size === 0) return report;
28394
+ const adj = /* @__PURE__ */ new Map();
28395
+ const protect = [];
28396
+ const add = (a, b, w) => {
28397
+ const l = adj.get(a) ?? [];
28398
+ l.push({ to: b, weight: w });
28399
+ adj.set(a, l);
28400
+ };
28401
+ for (const id of ids) {
28402
+ for (const e of store2.outEdges(id, [...JOINT_COMMUNITY_EDGES])) {
28403
+ if (!ids.has(e.to)) continue;
28404
+ if (e.type === "INSTANCE_OF" && e.extractionSource === "bko-inferred") continue;
28405
+ const conf = e.confidence > 0 ? e.confidence : 0.5;
28406
+ const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
28407
+ add(id, e.to, w);
28408
+ add(e.to, id, w);
28409
+ if (isCausalProtected(e.type)) protect.push([id, e.to]);
28410
+ }
28411
+ }
28412
+ const comm = detectCommunitiesLeiden({ nodeIds: [...ids], adj }, { protect });
28413
+ const members = /* @__PURE__ */ new Map();
28414
+ for (const [id, c] of comm.community) {
28415
+ const l = members.get(c) ?? [];
28416
+ l.push(id);
28417
+ members.set(c, l);
28418
+ }
28419
+ const domains = candidateDomains(store2, ids, new Map([...nodes].map(([id, n]) => [id, n.label])));
28420
+ const domainSize = /* @__PURE__ */ new Map();
28421
+ for (const ds of domains.values()) for (const d of new Set(ds)) domainSize.set(d, (domainSize.get(d) ?? 0) + 1);
28422
+ const floorOf = (mem) => {
28423
+ if (opts.minCommunitySize !== void 0) return opts.minCommunitySize;
28424
+ const domain2 = communityDomain(mem.map((id) => domains.get(id) ?? []), domainSize);
28425
+ return communitySizeFloor(domain2 === null ? ids.size : domainSize.get(domain2));
28426
+ };
28427
+ store2.transaction(() => {
28428
+ for (const [cid, mem] of members) {
28429
+ const qualifies = mem.length >= floorOf(mem);
28430
+ if (!qualifies && mem.length >= 2) report.belowFloor++;
28431
+ let hasLocal = false;
28432
+ let hasCloud = false;
28433
+ for (const id of mem) {
28434
+ const n = nodes.get(id);
28435
+ const pulled = n.attrs["source"] === "cloud";
28436
+ if (pulled) hasCloud = true;
28437
+ else hasLocal = true;
28438
+ const want = qualifies ? cid : void 0;
28439
+ if (n.attrs["localCommunity"] !== want) {
28440
+ const nextAttrs = { ...n.attrs };
28441
+ if (want) nextAttrs["localCommunity"] = want;
28442
+ else delete nextAttrs["localCommunity"];
28443
+ store2.updateNode(id, { attrs: nextAttrs });
28444
+ }
28445
+ if (!pulled && (n.community ?? null) !== (want ?? null)) store2.setCommunity(id, want ?? null);
28446
+ }
28447
+ if (qualifies) {
28448
+ report.communities++;
28449
+ report.assigned += mem.length;
28450
+ if (hasLocal && hasCloud) report.joint++;
28451
+ }
28452
+ }
28453
+ });
28454
+ return report;
28455
+ }
28303
28456
 
28304
28457
  // ../../packages/local-graph/src/tools.ts
28305
28458
  init_src();
@@ -28707,14 +28860,16 @@ init_src2();
28707
28860
  init_src2();
28708
28861
  init_src();
28709
28862
  var MEMBER_LABELS = ["Problem", "RootCause", "Solution"];
28863
+ var MOTIF_LABELS = ["Pattern", "Technique", "AntiPattern"];
28864
+ var LINEAGE_MIN_JACCARD = 0.5;
28710
28865
  function layerOf(kind) {
28711
28866
  return kind === "Technique" ? "technique" : kind === "AntiPattern" ? "antipattern" : "pattern";
28712
28867
  }
28713
- function motifTitle(members, layer, instanceCount) {
28714
- const top = [...members].sort(
28715
- (a, b) => b.extractionConfidence - a.extractionConfidence
28716
- )[0];
28717
- return `${layer} \xD7${instanceCount} (exemplar): ${top?.description ?? "recurring problem cluster"}`;
28868
+ function motifTitle(exemplar, layer, instanceCount) {
28869
+ return `${layer} \xD7${instanceCount} (exemplar): ${exemplar?.description ?? "recurring problem cluster"}`;
28870
+ }
28871
+ function exemplarOf(members) {
28872
+ return [...members].sort((a, b) => b.extractionConfidence - a.extractionConfidence || a.id.localeCompare(b.id))[0];
28718
28873
  }
28719
28874
  function classifyMotif(store2, instances, promoted) {
28720
28875
  if (!promoted || instances.length === 0) return "Pattern";
@@ -28723,70 +28878,141 @@ function classifyMotif(store2, instances, promoted) {
28723
28878
  if (solvedShare <= 0.2) return "AntiPattern";
28724
28879
  return "Pattern";
28725
28880
  }
28881
+ function isDerived(e) {
28882
+ return e.extractionSource === "bko-inferred";
28883
+ }
28884
+ function motifCoherence(store2, members, instances) {
28885
+ if (instances.length === 0) return 0;
28886
+ const types = [...JOINT_COMMUNITY_EDGES];
28887
+ const near = /* @__PURE__ */ new Map();
28888
+ const link = (a, b) => {
28889
+ const s = near.get(a) ?? /* @__PURE__ */ new Set();
28890
+ s.add(b);
28891
+ near.set(a, s);
28892
+ };
28893
+ for (const id of members) {
28894
+ for (const e of store2.outEdges(id, types)) {
28895
+ if (!members.has(e.to) || isDerived(e)) continue;
28896
+ link(id, e.to);
28897
+ link(e.to, id);
28898
+ }
28899
+ }
28900
+ const isInstance = new Set(instances);
28901
+ let bound = 0;
28902
+ for (const p of instances) {
28903
+ const hop1 = near.get(p) ?? /* @__PURE__ */ new Set();
28904
+ const reached = [...hop1, ...[...hop1].flatMap((x) => [...near.get(x) ?? []])];
28905
+ if (reached.some((q) => q !== p && isInstance.has(q))) bound++;
28906
+ }
28907
+ return bound / instances.length;
28908
+ }
28909
+ function jaccard(a, b) {
28910
+ if (a.size === 0 && b.size === 0) return 0;
28911
+ let both = 0;
28912
+ for (const x of a) if (b.has(x)) both++;
28913
+ return both / (a.size + b.size - both);
28914
+ }
28726
28915
  function promoteMotifs(store2, t) {
28916
+ const report = { communities: 0, candidates: 0, incoherent: 0, promoted: 0, techniques: 0, antipatterns: 0, retracted: 0, retired: 0 };
28727
28917
  const byCommunity = /* @__PURE__ */ new Map();
28728
28918
  for (const label of MEMBER_LABELS) {
28729
28919
  for (const n of store2.findNodesByLabel(label)) {
28730
28920
  if (n.label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
28731
- const c = n.community;
28732
- if (!c) continue;
28921
+ const c = n.attrs["localCommunity"];
28922
+ if (typeof c !== "string") continue;
28733
28923
  const g = byCommunity.get(c) ?? [];
28734
28924
  g.push(n);
28735
28925
  byCommunity.set(c, g);
28736
28926
  }
28737
28927
  }
28738
- let candidates = 0;
28739
- let promoted = 0;
28740
- let techniques = 0;
28741
- let antipatterns = 0;
28928
+ report.communities = byCommunity.size;
28929
+ const existing = /* @__PURE__ */ new Map();
28930
+ for (const label of MOTIF_LABELS) {
28931
+ for (const node of store2.findNodesByLabel(label)) {
28932
+ if (!node.id.startsWith("motif_")) continue;
28933
+ const edges = store2.inEdges(node.id, ["INSTANCE_OF"]).filter(isDerived);
28934
+ const remembered = node.attrs["memberIds"];
28935
+ const members = new Set(Array.isArray(remembered) ? remembered : edges.map((e) => e.from));
28936
+ existing.set(node.id, { node, edges, members });
28937
+ }
28938
+ }
28939
+ const pairs = [];
28940
+ for (const [cid, members] of byCommunity) {
28941
+ const instances = new Set(members.filter((m) => m.label === "Problem").map((m) => m.id));
28942
+ for (const [motifId, m] of existing) {
28943
+ const j = jaccard(instances, m.members);
28944
+ if (j >= LINEAGE_MIN_JACCARD) pairs.push({ cid, motifId, j });
28945
+ }
28946
+ }
28947
+ pairs.sort((a, b) => b.j - a.j || a.motifId.localeCompare(b.motifId));
28948
+ const motifOf = /* @__PURE__ */ new Map();
28949
+ const claimed = /* @__PURE__ */ new Set();
28950
+ for (const p of pairs) {
28951
+ if (motifOf.has(p.cid) || claimed.has(p.motifId)) continue;
28952
+ motifOf.set(p.cid, p.motifId);
28953
+ claimed.add(p.motifId);
28954
+ }
28955
+ const kept = /* @__PURE__ */ new Set();
28742
28956
  store2.transaction(() => {
28743
28957
  for (const [cid, members] of byCommunity) {
28744
28958
  const instances = members.filter((m) => m.label === "Problem");
28745
28959
  const instanceCount = instances.length || members.length;
28746
- const motifId = `motif_${cid}`;
28747
- const existing = store2.getNode(motifId);
28960
+ const motifId = motifOf.get(cid) ?? (claimed.has(`motif_${cid}`) ? `motif_${cid}_${digest(instances.map((m) => m.id).sort()).slice(0, 8)}` : `motif_${cid}`);
28961
+ const prior = existing.get(motifId);
28962
+ const coherence = motifCoherence(store2, new Set(members.map((m) => m.id)), instances.map((m) => m.id));
28748
28963
  const d = motifDecision({
28749
- instances: members.map((m) => ({
28750
- confidence: m.extractionConfidence,
28751
- failed: false
28752
- })),
28964
+ instances: members.map((m) => ({ confidence: m.extractionConfidence, failed: false })),
28753
28965
  memberCount: members.length,
28754
28966
  instanceCount,
28755
- priorSurvivedRuns: existing?.attrs["survivedRuns"] ?? 0
28967
+ priorSurvivedRuns: prior?.node.attrs["survivedRuns"] ?? 0,
28968
+ coherence
28756
28969
  });
28757
- if (!d.isCandidate) continue;
28758
- candidates++;
28970
+ if (!d.isCandidate) {
28971
+ if (members.length >= 5) report.incoherent++;
28972
+ continue;
28973
+ }
28974
+ report.candidates++;
28975
+ kept.add(motifId);
28759
28976
  const kind = classifyMotif(store2, instances, d.promoted);
28977
+ const exemplar = exemplarOf(members);
28760
28978
  const motif = {
28761
28979
  id: motifId,
28762
28980
  label: kind,
28763
28981
  // Refresh the deterministic title every run (exemplar/count/kind drift),
28764
28982
  // but never clobber a distilled one — a distillation pass owns it then.
28765
- description: existing?.attrs["titleDistilled"] === true ? existing.description : motifTitle(members, layerOf(kind), instanceCount),
28983
+ description: prior?.node.attrs["titleDistilled"] === true ? prior.node.description : motifTitle(exemplar, layerOf(kind), instanceCount),
28766
28984
  extractionConfidence: d.motifConfidence,
28767
28985
  extractionSource: "bko-inferred",
28768
- embedding: existing?.embedding ?? [],
28769
- cumulativeSurprise: existing?.cumulativeSurprise ?? 0,
28770
- peakSurprise: existing?.peakSurprise ?? 0,
28986
+ embedding: prior?.node.embedding ?? [],
28987
+ cumulativeSurprise: prior?.node.cumulativeSurprise ?? 0,
28988
+ peakSurprise: prior?.node.peakSurprise ?? 0,
28771
28989
  cumulativeHits: instanceCount,
28772
28990
  lastUpdatedAt: t,
28773
- createdAt: existing?.createdAt ?? t,
28774
- memoryTier: existing?.memoryTier ?? "short-term",
28775
- pageRank: existing?.pageRank ?? 0,
28991
+ createdAt: prior?.node.createdAt ?? t,
28992
+ memoryTier: prior?.node.memoryTier ?? "short-term",
28993
+ pageRank: prior?.node.pageRank ?? 0,
28776
28994
  isLandmark: d.promoted,
28777
- community: cid,
28995
+ // The community column belongs to the joint pass alone; a motif names
28996
+ // its community in attrs.communityId.
28997
+ community: null,
28778
28998
  stability: d.stable ? "stable" : "forming",
28779
28999
  attrs: {
29000
+ ...prior?.node.attrs ?? {},
28780
29001
  layer: layerOf(kind),
28781
29002
  communityId: cid,
28782
29003
  survivedRuns: d.survivedRuns,
28783
29004
  motifConfidence: d.motifConfidence,
28784
29005
  memberCount: members.length,
28785
29006
  instanceCount,
29007
+ coherence: Math.round(coherence * 100) / 100,
29008
+ memberIds: instances.map((m) => m.id),
29009
+ ...exemplar ? { exemplarId: exemplar.id } : {},
29010
+ missedRuns: 0,
28786
29011
  promoted: d.promoted
28787
29012
  }
28788
29013
  };
28789
29014
  store2.mergeNode(motif);
29015
+ const now = new Set(instances.map((m) => m.id));
28790
29016
  for (const m of instances) {
28791
29017
  store2.mergeEdge({
28792
29018
  id: `edge_${digest({ from: m.id, type: "INSTANCE_OF", to: motifId })}`.slice(0, 24),
@@ -28802,12 +29028,33 @@ function promoteMotifs(store2, t) {
28802
29028
  attrs: {}
28803
29029
  });
28804
29030
  }
28805
- if (d.promoted) promoted++;
28806
- if (kind === "Technique") techniques++;
28807
- if (kind === "AntiPattern") antipatterns++;
29031
+ for (const e of prior?.edges ?? []) {
29032
+ if (now.has(e.from)) continue;
29033
+ store2.closeEdge(e.id, t);
29034
+ report.retracted++;
29035
+ }
29036
+ if (d.promoted) report.promoted++;
29037
+ if (kind === "Technique") report.techniques++;
29038
+ if (kind === "AntiPattern") report.antipatterns++;
29039
+ }
29040
+ for (const [motifId, m] of existing) {
29041
+ if (kept.has(motifId)) continue;
29042
+ for (const e of m.edges) {
29043
+ store2.closeEdge(e.id, t);
29044
+ report.retracted++;
29045
+ }
29046
+ const missedRuns = (m.node.attrs["missedRuns"] ?? 0) + 1;
29047
+ const evidenced = store2.inEdges(motifId, ["INSTANCE_OF"]).some((e) => !isDerived(e));
29048
+ if (missedRuns >= MOTIF_MIN_SURVIVED && !evidenced) {
29049
+ for (const e of [...store2.outEdges(motifId), ...store2.inEdges(motifId)]) store2.closeEdge(e.id, t);
29050
+ store2.closeNode(motifId, t);
29051
+ report.retired++;
29052
+ } else {
29053
+ store2.updateNode(motifId, { attrs: { ...m.node.attrs, missedRuns, promoted: false } });
29054
+ }
28808
29055
  }
28809
29056
  });
28810
- return { communities: byCommunity.size, candidates, promoted, techniques, antipatterns };
29057
+ return report;
28811
29058
  }
28812
29059
 
28813
29060
  // ../../packages/generalizer/src/nightly.ts
@@ -29025,44 +29272,14 @@ function runFullRescore(store2) {
29025
29272
  landmarkFlips++;
29026
29273
  }
29027
29274
  });
29028
- const MOTIF_LABELS = /* @__PURE__ */ new Set(["Pattern", "Technique", "AntiPattern"]);
29029
- const semanticIds = /* @__PURE__ */ new Set();
29030
- for (const label of SEMANTIC_NODE_LABELS) {
29031
- if (MOTIF_LABELS.has(label)) continue;
29032
- for (const n of store2.findNodesByLabel(label)) semanticIds.add(n.id);
29033
- }
29034
- const semAdj = /* @__PURE__ */ new Map();
29035
- const protect = [];
29036
- const addAdj = (a, b, w) => {
29037
- const l = semAdj.get(a) ?? [];
29038
- l.push({ to: b, weight: w });
29039
- semAdj.set(a, l);
29040
- };
29041
- for (const id of semanticIds) {
29042
- for (const e of store2.outEdges(id)) {
29043
- if (!semanticIds.has(e.to)) continue;
29044
- const conf = e.confidence > 0 ? e.confidence : 0.5;
29045
- const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
29046
- addAdj(id, e.to, w);
29047
- addAdj(e.to, id, w);
29048
- if (isCausalProtected(e.type)) protect.push([id, e.to]);
29049
- }
29050
- }
29051
- for (const { a, b, weight } of codeAnchorProjection(store2, semanticIds)) {
29052
- addAdj(a, b, weight);
29053
- addAdj(b, a, weight);
29054
- }
29055
- const comm = detectCommunitiesLeiden({ nodeIds: [...semanticIds], adj: semAdj }, { protect });
29056
- store2.transaction(() => {
29057
- for (const [id, c] of comm.community) store2.updateNode(id, { community: c });
29058
- });
29275
+ const lc = detectLocalCommunities(store2);
29059
29276
  const motifs = promoteMotifs(store2, started);
29060
29277
  return {
29061
29278
  scoredNodes: scored,
29062
29279
  iterations: result.iterations,
29063
29280
  converged: result.converged,
29064
29281
  landmarks: allLandmarks.size,
29065
- communities: comm.count,
29282
+ communities: lc.communities,
29066
29283
  motifsPromoted: motifs.promoted,
29067
29284
  techniques: motifs.techniques,
29068
29285
  antipatterns: motifs.antipatterns,
@@ -29121,28 +29338,6 @@ function runNightlyPipeline(store2) {
29121
29338
  durationMs: Date.now() - started
29122
29339
  };
29123
29340
  }
29124
- function codeAnchorProjection(store2, semanticIds, opts = {}) {
29125
- const anchorToNodes = /* @__PURE__ */ new Map();
29126
- for (const id of semanticIds) {
29127
- for (const e of store2.outEdges(id, ["ANCHORED_AT"])) {
29128
- if (semanticIds.has(e.to)) continue;
29129
- const l = anchorToNodes.get(e.to) ?? [];
29130
- l.push(id);
29131
- anchorToNodes.set(e.to, l);
29132
- }
29133
- }
29134
- const hubCap = opts.hubCap ?? Math.max(8, Math.floor(semanticIds.size * 0.03));
29135
- const base = opts.weight ?? 1;
29136
- const out2 = [];
29137
- for (const nodes of anchorToNodes.values()) {
29138
- if (nodes.length < 2 || nodes.length > hubCap) continue;
29139
- const w = base / Math.log2(nodes.length + 1);
29140
- for (let i2 = 0; i2 < nodes.length; i2++) {
29141
- for (let j = i2 + 1; j < nodes.length; j++) out2.push({ a: nodes[i2], b: nodes[j], weight: w });
29142
- }
29143
- }
29144
- return out2;
29145
- }
29146
29341
 
29147
29342
  // ../../packages/generalizer/src/embed-code.ts
29148
29343
  init_src();
@@ -29151,6 +29346,9 @@ init_src();
29151
29346
  init_src();
29152
29347
  var BURST_ANCHORED_AT_CONDUCTANCE = 1 / 3;
29153
29348
 
29349
+ // ../../packages/generalizer/src/motif-signal.ts
29350
+ var KNOWLEDGE_EDGES = [...JOINT_COMMUNITY_EDGES, "MAY_RESOLVE", "REGRESSION_OF", "BUILDS_ON"];
29351
+
29154
29352
  // ../../packages/context-writer/src/agents-md.ts
29155
29353
  init_src();
29156
29354
 
@@ -29176,6 +29374,12 @@ var AGENTS_POINTER_BODY = [
29176
29374
  // ../../packages/context-writer/src/render.ts
29177
29375
  init_src2();
29178
29376
  init_src();
29377
+ var MOTIF_BAND = 10;
29378
+ var MOTIF_POOL = 1e3;
29379
+ function rankMotifs(pool, signal, k = MOTIF_BAND) {
29380
+ if (!signal) return pool.slice(0, k);
29381
+ 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);
29382
+ }
29179
29383
  function buildSnapshot(opts) {
29180
29384
  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);
29181
29385
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
@@ -29206,11 +29410,12 @@ function buildSnapshot(opts) {
29206
29410
  return { node: p, ...solution ? { solution } : {} };
29207
29411
  });
29208
29412
  const recentResolved = resolvedPool.slice(0, RECENT_RESOLVED);
29209
- const motifs = [
29413
+ const motifPool = [
29210
29414
  ...opts.store.findNodesByLabel("Pattern"),
29211
29415
  ...opts.store.findNodesByLabel("Technique"),
29212
29416
  ...opts.store.findNodesByLabel("AntiPattern")
29213
- ].filter((n) => historyReadPolicy(n, { mode: "passive", atCommit: opts.atCommit }).allow).sort((a, b) => b.pageRank - a.pageRank).slice(0, 10);
29417
+ ].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);
29418
+ const motifs = rankMotifs(motifPool, void 0);
29214
29419
  const workingFile = opts.workingFile ? sliceForFile(opts.store, opts.workingFile, opts.atCommit) : void 0;
29215
29420
  const byEpisode = /* @__PURE__ */ new Map();
29216
29421
  for (const sol of opts.store.findNodesByLabel("Solution")) {
@@ -29277,6 +29482,7 @@ function buildSnapshot(opts) {
29277
29482
  ...opts.selfCiteSkips && opts.selfCiteSkips > 0 ? { selfCiteSkips: opts.selfCiteSkips } : {},
29278
29483
  ...domainNudge ? { domainNudge } : {},
29279
29484
  motifs,
29485
+ motifPool,
29280
29486
  reviewCount: opts.reviewCount,
29281
29487
  reviewUiUrl: opts.reviewUiUrl,
29282
29488
  ...workingFile ? { workingFile } : {},
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "errata-context",
3
- "version": "2.0.21-dev.3975",
3
+ "version": "2.0.21-dev.3993",
4
4
  "description": "A minimal 3D view of loaded Errata priors and recent graph bursts.",
5
5
  "author": {
6
6
  "name": "inErrata"
@@ -1,4 +1,4 @@
1
- a9eb62817aef08b34545572e5b3797a0f0234fd7cdd80b6bac7ccfe295b4207b .codex-plugin/plugin.json
1
+ 8027e953c11e9316a87091a5ce17afe8bd5dc0c80bca47f70e249cfdc71eac58 .codex-plugin/plugin.json
2
2
  a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
3
3
  fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
4
4
  73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js