@inerrata-corporation/errata 2.0.0-dev.24 → 2.0.0-dev.25

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.
@@ -15701,6 +15701,7 @@ var SqliteGraphStore = class {
15701
15701
  // cheaper (one bound column, no COALESCE evaluation per row).
15702
15702
  setPageRank: this.db.prepare("UPDATE nodes SET page_rank = :v WHERE id = :id"),
15703
15703
  setLandmark: this.db.prepare("UPDATE nodes SET is_landmark = :v WHERE id = :id"),
15704
+ setCommunity: this.db.prepare("UPDATE nodes SET community = :v WHERE id = :id"),
15704
15705
  updateNode: this.db.prepare(`
15705
15706
  UPDATE nodes SET
15706
15707
  description = COALESCE(:description, description),
@@ -15941,6 +15942,9 @@ var SqliteGraphStore = class {
15941
15942
  setLandmark(id, isLandmark) {
15942
15943
  this.stmts.setLandmark.run({ id, v: isLandmark ? 1 : 0 });
15943
15944
  }
15945
+ setCommunity(id, community) {
15946
+ this.stmts.setCommunity.run({ id, v: community });
15947
+ }
15944
15948
  mergeEdge(edge) {
15945
15949
  this.mutations++;
15946
15950
  this.stmts.insertEdge.run({
@@ -16660,6 +16664,9 @@ function revisitContradictedPrinciples(l2, ts) {
16660
16664
  return report;
16661
16665
  }
16662
16666
 
16667
+ // ../../packages/local-graph/src/community.ts
16668
+ init_src2();
16669
+
16663
16670
  // ../../packages/local-graph/src/triage.ts
16664
16671
  init_src();
16665
16672
  init_src();
package/errata.mjs CHANGED
@@ -15790,6 +15790,7 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
15790
15790
  // cheaper (one bound column, no COALESCE evaluation per row).
15791
15791
  setPageRank: this.db.prepare("UPDATE nodes SET page_rank = :v WHERE id = :id"),
15792
15792
  setLandmark: this.db.prepare("UPDATE nodes SET is_landmark = :v WHERE id = :id"),
15793
+ setCommunity: this.db.prepare("UPDATE nodes SET community = :v WHERE id = :id"),
15793
15794
  updateNode: this.db.prepare(`
15794
15795
  UPDATE nodes SET
15795
15796
  description = COALESCE(:description, description),
@@ -16030,6 +16031,9 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
16030
16031
  setLandmark(id, isLandmark) {
16031
16032
  this.stmts.setLandmark.run({ id, v: isLandmark ? 1 : 0 });
16032
16033
  }
16034
+ setCommunity(id, community) {
16035
+ this.stmts.setCommunity.run({ id, v: community });
16036
+ }
16033
16037
  mergeEdge(edge2) {
16034
16038
  this.mutations++;
16035
16039
  this.stmts.insertEdge.run({
@@ -18721,6 +18725,137 @@ var init_abstraction = __esm({
18721
18725
  }
18722
18726
  });
18723
18727
 
18728
+ // ../../packages/local-graph/src/community.ts
18729
+ function detectLocalCommunities(store, opts = {}) {
18730
+ const minSize = opts.minCommunitySize ?? DEFAULT_MIN_COMMUNITY_SIZE;
18731
+ const report = { candidates: 0, communities: 0, joint: 0, assigned: 0 };
18732
+ const ids = /* @__PURE__ */ new Set();
18733
+ for (const label of JOINT_COMMUNITY_LABELS) {
18734
+ for (const n of store.findNodesByLabel(label)) {
18735
+ if (label === "Problem" && n.attrs["resolvedAs"] === PROBLEM_RESOLUTION.FALSE_POSITIVE) continue;
18736
+ ids.add(n.id);
18737
+ }
18738
+ }
18739
+ report.candidates = ids.size;
18740
+ if (ids.size === 0) return report;
18741
+ const adj = /* @__PURE__ */ new Map();
18742
+ const protect = [];
18743
+ const add = (a, b, w) => {
18744
+ const l = adj.get(a) ?? [];
18745
+ l.push({ to: b, weight: w });
18746
+ adj.set(a, l);
18747
+ };
18748
+ for (const id of ids) {
18749
+ for (const e of store.outEdges(id, [...JOINT_COMMUNITY_EDGES])) {
18750
+ if (!ids.has(e.to)) continue;
18751
+ const conf = e.confidence > 0 ? e.confidence : 0.5;
18752
+ const w = Math.max(EDGE_WEIGHT[e.type] ?? 1, 0.1) * conf;
18753
+ add(id, e.to, w);
18754
+ add(e.to, id, w);
18755
+ if (isCausalProtected(e.type)) protect.push([id, e.to]);
18756
+ }
18757
+ }
18758
+ const comm = detectCommunitiesLeiden({ nodeIds: [...ids], adj }, { protect });
18759
+ const members = /* @__PURE__ */ new Map();
18760
+ for (const [id, c] of comm.community) {
18761
+ const l = members.get(c) ?? [];
18762
+ l.push(id);
18763
+ members.set(c, l);
18764
+ }
18765
+ store.transaction(() => {
18766
+ for (const [cid, mem] of members) {
18767
+ const qualifies = mem.length >= minSize;
18768
+ let hasLocal = false;
18769
+ let hasCloud = false;
18770
+ for (const id of mem) {
18771
+ const n = store.getNode(id);
18772
+ if (!n) continue;
18773
+ const pulled = n.attrs["source"] === "cloud";
18774
+ if (pulled) hasCloud = true;
18775
+ else hasLocal = true;
18776
+ const nextAttrs = { ...n.attrs };
18777
+ if (qualifies) nextAttrs["localCommunity"] = cid;
18778
+ else delete nextAttrs["localCommunity"];
18779
+ store.updateNode(id, { attrs: nextAttrs });
18780
+ if (!pulled) store.setCommunity(id, qualifies ? cid : null);
18781
+ }
18782
+ if (qualifies) {
18783
+ report.communities++;
18784
+ report.assigned += mem.length;
18785
+ if (hasLocal && hasCloud) report.joint++;
18786
+ }
18787
+ }
18788
+ });
18789
+ return report;
18790
+ }
18791
+ function communitySeeds(store, opts = {}) {
18792
+ const maxCommunities = opts.maxCommunities ?? 4;
18793
+ const maxSeeds = opts.maxSeeds ?? 32;
18794
+ const byCommunity = /* @__PURE__ */ new Map();
18795
+ for (const label of JOINT_COMMUNITY_LABELS) {
18796
+ for (const n of store.findNodesByLabel(label)) {
18797
+ const cid = n.attrs["localCommunity"];
18798
+ if (typeof cid !== "string") continue;
18799
+ const cloudId = n.attrs["cloudNodeId"];
18800
+ const l = byCommunity.get(cid) ?? [];
18801
+ l.push({
18802
+ id: n.id,
18803
+ pulled: n.attrs["source"] === "cloud",
18804
+ cloudId: typeof cloudId === "string" && cloudId !== n.id ? cloudId : null,
18805
+ ts: n.lastUpdatedAt
18806
+ });
18807
+ byCommunity.set(cid, l);
18808
+ }
18809
+ }
18810
+ if (byCommunity.size === 0) return [];
18811
+ const ranked = [...byCommunity.entries()].map(([cid, mem]) => ({ cid, mem, fresh: Math.max(...mem.map((m) => m.ts)) })).sort((a, b) => b.fresh - a.fresh).slice(0, maxCommunities);
18812
+ const seeds = [];
18813
+ const seen = /* @__PURE__ */ new Set();
18814
+ const push = (id) => {
18815
+ if (seeds.length >= maxSeeds || seen.has(id)) return;
18816
+ seen.add(id);
18817
+ seeds.push(id);
18818
+ };
18819
+ for (const { mem } of ranked) {
18820
+ const ordered = [...mem].sort(
18821
+ (a, b) => a.pulled === b.pulled ? b.ts - a.ts : a.pulled ? -1 : 1
18822
+ );
18823
+ for (const m of ordered) {
18824
+ push(m.id);
18825
+ if (m.cloudId) push(m.cloudId);
18826
+ }
18827
+ }
18828
+ return seeds;
18829
+ }
18830
+ var JOINT_COMMUNITY_LABELS, JOINT_COMMUNITY_EDGES, DEFAULT_MIN_COMMUNITY_SIZE;
18831
+ var init_community2 = __esm({
18832
+ "../../packages/local-graph/src/community.ts"() {
18833
+ "use strict";
18834
+ init_src2();
18835
+ init_src3();
18836
+ JOINT_COMMUNITY_LABELS = [
18837
+ "Problem",
18838
+ "Solution",
18839
+ "RootCause",
18840
+ "Pattern"
18841
+ ];
18842
+ JOINT_COMMUNITY_EDGES = [
18843
+ "CAUSED_BY",
18844
+ "SOLVED_BY",
18845
+ "FIXED_BY",
18846
+ "CONTRADICTS",
18847
+ "INSTANCE_OF",
18848
+ "MATCHES",
18849
+ "IMPLEMENTS",
18850
+ "TRIAGED_BY",
18851
+ "INDICATES",
18852
+ "CONFIRMS",
18853
+ "RELATES_TO"
18854
+ ];
18855
+ DEFAULT_MIN_COMMUNITY_SIZE = 2;
18856
+ }
18857
+ });
18858
+
18724
18859
  // ../../packages/local-graph/src/triage.ts
18725
18860
  function semNode(id, label, description, ts, attrs) {
18726
18861
  return {
@@ -19339,6 +19474,8 @@ __export(src_exports, {
19339
19474
  CITABLE_PRIOR_LABELS: () => CITABLE_PRIOR_LABELS,
19340
19475
  CODE_REACH_EDGES: () => CODE_REACH_EDGES,
19341
19476
  CREDIT_FAMILY: () => CREDIT_FAMILY,
19477
+ JOINT_COMMUNITY_EDGES: () => JOINT_COMMUNITY_EDGES,
19478
+ JOINT_COMMUNITY_LABELS: () => JOINT_COMMUNITY_LABELS,
19342
19479
  MAX_ANCHOR_FILES: () => MAX_ANCHOR_FILES,
19343
19480
  PERCOLATING_DRIFT_EDGES: () => PERCOLATING_DRIFT_EDGES,
19344
19481
  PERCOLATING_EDGES: () => PERCOLATING_EDGES,
@@ -19359,12 +19496,14 @@ __export(src_exports, {
19359
19496
  causalChain: () => causalChain,
19360
19497
  claimId: () => claimId,
19361
19498
  clearRevisit: () => clearRevisit,
19499
+ communitySeeds: () => communitySeeds,
19362
19500
  compareSemver: () => compareSemver,
19363
19501
  corroborateClaim: () => corroborateClaim,
19364
19502
  creditAssignment: () => creditAssignment,
19365
19503
  crystallize: () => crystallize,
19366
19504
  deriveContextFromAnchors: () => deriveContextFromAnchors,
19367
19505
  designProblemId: () => designProblemId,
19506
+ detectLocalCommunities: () => detectLocalCommunities,
19368
19507
  edgeConductance: () => edgeConductance,
19369
19508
  evaluateDependency: () => evaluateDependency,
19370
19509
  findOrCreatePackage: () => findOrCreatePackage,
@@ -19424,6 +19563,7 @@ var init_src4 = __esm({
19424
19563
  init_design_problem();
19425
19564
  init_percolate();
19426
19565
  init_abstraction();
19566
+ init_community2();
19427
19567
  init_triage2();
19428
19568
  init_problem_dedup();
19429
19569
  init_problem_package_link();
@@ -41091,7 +41231,7 @@ function maybeFlushDigests() {
41091
41231
  }
41092
41232
 
41093
41233
  // src/engine.ts
41094
- var DAEMON_VERSION = true ? "2.0.0-dev.24" : "2.0.0-alpha.0";
41234
+ var DAEMON_VERSION = true ? "2.0.0-dev.25" : "2.0.0-alpha.0";
41095
41235
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
41096
41236
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
41097
41237
  var GIT_OP_MUTE_MS = 4e3;
@@ -41449,6 +41589,14 @@ function createWorkspaceEngine(opts) {
41449
41589
  } catch (err2) {
41450
41590
  console.warn("[errata] problem context derivation failed:", err2);
41451
41591
  }
41592
+ try {
41593
+ const lc = detectLocalCommunities(store);
41594
+ if (lc.communities > 0) {
41595
+ console.log(`[errata] communities: ${lc.communities} detected (${lc.joint} joint local+cloud) across ${lc.assigned}/${lc.candidates} node(s)`);
41596
+ }
41597
+ } catch (err2) {
41598
+ console.warn("[errata] joint community pass failed:", err2);
41599
+ }
41452
41600
  return { report, localSkills: 0 };
41453
41601
  };
41454
41602
  const onWorkingFileChanged = (rel, sessionId) => {
@@ -41889,7 +42037,8 @@ function createWorkspaceEngine(opts) {
41889
42037
  });
41890
42038
  }
41891
42039
  const pullSkills = () => {
41892
- const skillSeed = store.findNodesByLabel("Problem").sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 6).flatMap((p) => {
42040
+ const communitySeed = communitySeeds(store);
42041
+ const skillSeed = communitySeed.length > 0 ? communitySeed : store.findNodesByLabel("Problem").sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 6).flatMap((p) => {
41893
42042
  const cloudId = p.attrs["cloudNodeId"];
41894
42043
  return typeof cloudId === "string" && cloudId !== p.id ? [p.id, cloudId] : [p.id];
41895
42044
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.0-dev.24",
3
+ "version": "2.0.0-dev.25",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -23961,6 +23961,7 @@ var SqliteGraphStore = class {
23961
23961
  // cheaper (one bound column, no COALESCE evaluation per row).
23962
23962
  setPageRank: this.db.prepare("UPDATE nodes SET page_rank = :v WHERE id = :id"),
23963
23963
  setLandmark: this.db.prepare("UPDATE nodes SET is_landmark = :v WHERE id = :id"),
23964
+ setCommunity: this.db.prepare("UPDATE nodes SET community = :v WHERE id = :id"),
23964
23965
  updateNode: this.db.prepare(`
23965
23966
  UPDATE nodes SET
23966
23967
  description = COALESCE(:description, description),
@@ -24201,6 +24202,9 @@ var SqliteGraphStore = class {
24201
24202
  setLandmark(id, isLandmark) {
24202
24203
  this.stmts.setLandmark.run({ id, v: isLandmark ? 1 : 0 });
24203
24204
  }
24205
+ setCommunity(id, community) {
24206
+ this.stmts.setCommunity.run({ id, v: community });
24207
+ }
24204
24208
  mergeEdge(edge) {
24205
24209
  this.mutations++;
24206
24210
  this.stmts.insertEdge.run({
@@ -25167,6 +25171,9 @@ function motifDecision(input) {
25167
25171
  };
25168
25172
  }
25169
25173
 
25174
+ // ../../packages/local-graph/src/community.ts
25175
+ init_src2();
25176
+
25170
25177
  // ../../packages/local-graph/src/triage.ts
25171
25178
  init_src();
25172
25179
  init_src();