@inerrata-corporation/errata 2.0.0-dev.82 → 2.0.0-dev.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/errata.mjs +119 -2
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -21604,7 +21604,14 @@ var init_client = __esm({
21604
21604
  "GET",
21605
21605
  `/v2/projects/${encodeURIComponent(projectId)}/priors?limit=${String(limit)}`
21606
21606
  );
21607
- return this.toCastalia(res);
21607
+ const { nodes, edges } = this.toCastalia(res);
21608
+ const anchorEdges = (res.anchorEdges ?? []).map((a) => ({
21609
+ from: a.fromCanonicalId,
21610
+ toSymbolId: a.toSymbolId,
21611
+ type: a.type,
21612
+ attrs: a.attrs ?? {}
21613
+ }));
21614
+ return { nodes, edges, anchorEdges, symbolIds: res.symbolIds ?? [] };
21608
21615
  }
21609
21616
  /** Pull cloud-induced skills + the session-bootstrap prime payload. `seed` is the
21610
21617
  * canonical ids of the agent's recent problems — the cloud ranks the skills whose
@@ -37988,6 +37995,9 @@ function buildWebUi(deps) {
37988
37995
  stack: deps.profile.stack,
37989
37996
  nodes: deps.store.nodeCount(),
37990
37997
  edges: deps.store.edgeCount(),
37998
+ // Ontology-gate refusals since daemon start (local EDGE_RULES at
37999
+ // mergeEdge, #1153) — a misbehaving extractor shows here, never silently.
38000
+ rejectedEdges: deps.store.rejectedEdgeCount,
37991
38001
  pendingReview: pendingCount(deps.paths),
37992
38002
  daemonVersion: deps.daemonVersion,
37993
38003
  endpoints: [
@@ -38019,6 +38029,7 @@ function buildWebUi(deps) {
38019
38029
  workspace: deps.profile.id,
38020
38030
  nodes: deps.store.nodeCount(),
38021
38031
  edges: deps.store.edgeCount(),
38032
+ rejectedEdges: deps.store.rejectedEdgeCount,
38022
38033
  pendingReview: pendingCount(deps.paths),
38023
38034
  daemonVersion: deps.daemonVersion
38024
38035
  })
@@ -43522,7 +43533,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
43522
43533
  }
43523
43534
 
43524
43535
  // src/engine.ts
43525
- var DAEMON_VERSION = true ? "2.0.0-dev.82" : "2.0.0-alpha.0";
43536
+ var DAEMON_VERSION = true ? "2.0.0-dev.84" : "2.0.0-alpha.0";
43526
43537
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
43527
43538
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
43528
43539
  var GIT_OP_MUTE_MS = 4e3;
@@ -45596,6 +45607,91 @@ async function hydrateProject(opts) {
45596
45607
  }
45597
45608
  }
45598
45609
 
45610
+ // src/project-reanchor.ts
45611
+ init_src();
45612
+ init_src11();
45613
+ var DEFAULT_LIMIT2 = 50;
45614
+ var ANCHOR_SYMBOL_KINDS = [
45615
+ "Function",
45616
+ "Class",
45617
+ "Method",
45618
+ "Module",
45619
+ "Interface",
45620
+ "Const",
45621
+ "Enum",
45622
+ "TypeAlias",
45623
+ "Namespace",
45624
+ "Property"
45625
+ ];
45626
+ function buildReverseSymbolMap(opts) {
45627
+ const { store, salt, projectId } = opts;
45628
+ const reverse = /* @__PURE__ */ new Map();
45629
+ for (const kind of ANCHOR_SYMBOL_KINDS) {
45630
+ for (const n of store.findNodesByLabel(kind)) {
45631
+ const relPath = n.attrs["relPath"];
45632
+ const qname = n.attrs["qname"];
45633
+ if (typeof relPath !== "string" || typeof qname !== "string") continue;
45634
+ const sym = projectSymbolId(salt, projectId, relPath, qname, n.label);
45635
+ if (!reverse.has(sym)) reverse.set(sym, n.id);
45636
+ }
45637
+ }
45638
+ return reverse;
45639
+ }
45640
+ async function reanchorProject(opts) {
45641
+ const { root, profile, store, cloud, salt } = opts;
45642
+ if (!profile.projectId) return { reanchored: false, reason: "no-project" };
45643
+ if (profile.projectReanchoredAt) return { reanchored: false, reason: "already-reanchored" };
45644
+ if (!profile.projectHydratedAt) return { reanchored: false, reason: "not-hydrated" };
45645
+ const reverse = buildReverseSymbolMap({ store, salt, projectId: profile.projectId });
45646
+ if (reverse.size === 0) return { reanchored: false, reason: "no-local-symbols" };
45647
+ try {
45648
+ const res = await cloud.getProjectPriors(profile.projectId, opts.limit ?? DEFAULT_LIMIT2);
45649
+ const now = Date.now();
45650
+ let anchors = 0;
45651
+ let dropped = 0;
45652
+ for (const a of res.anchorEdges) {
45653
+ const localTo = reverse.get(a.toSymbolId);
45654
+ if (!localTo) {
45655
+ dropped++;
45656
+ continue;
45657
+ }
45658
+ if (!store.getNode(a.from)) {
45659
+ dropped++;
45660
+ continue;
45661
+ }
45662
+ const id = edgeId(a.from, "ANCHORED_AT", localTo);
45663
+ if (store.getEdge(id)) continue;
45664
+ const edge2 = {
45665
+ id,
45666
+ from: a.from,
45667
+ to: localTo,
45668
+ type: "ANCHORED_AT",
45669
+ confidence: typeof a.attrs["confidence"] === "number" ? Math.max(0, Math.min(1, a.attrs["confidence"])) : 0.5,
45670
+ extractionSource: "agent-observed",
45671
+ createdAt: now,
45672
+ lastSeenAt: now,
45673
+ navSuccesses: 0,
45674
+ navFailures: 0,
45675
+ // Tagged `source: 'cloud'` (C7 — never re-shipped outward). GUARDRAIL 2 holds
45676
+ // by construction: we merge the EDGE onto the LOCAL node id, never the `sym_`
45677
+ // Symbol node — that stayed a translation key and never enters the store.
45678
+ attrs: { ...a.attrs, source: "cloud" }
45679
+ };
45680
+ store.mergeEdge(edge2);
45681
+ anchors++;
45682
+ }
45683
+ profile.projectReanchoredAt = Date.now();
45684
+ saveProfile(root, profile);
45685
+ return { reanchored: true, anchors, dropped };
45686
+ } catch (err2) {
45687
+ return {
45688
+ reanchored: false,
45689
+ reason: "error",
45690
+ detail: err2 instanceof Error ? err2.message : String(err2)
45691
+ };
45692
+ }
45693
+ }
45694
+
45599
45695
  // src/adopt.ts
45600
45696
  import { existsSync as existsSync22 } from "node:fs";
45601
45697
  import { dirname as dirname8, join as join25 } from "node:path";
@@ -46051,6 +46147,27 @@ async function startMultiDaemon(opts = {}) {
46051
46147
  } else if (hyd.reason === "error") {
46052
46148
  console.warn(`[errata] project prime failed for ${r.engine.profile.name}: ${hyd.detail}`);
46053
46149
  }
46150
+ if (r.engine.profile.projectId) {
46151
+ try {
46152
+ const { salt } = await resolveProjectSymbolSalt(client, r.engine.profile.projectId);
46153
+ const re = await reanchorProject({
46154
+ root: r.root,
46155
+ profile: r.engine.profile,
46156
+ store: r.engine.store,
46157
+ cloud: client,
46158
+ salt
46159
+ });
46160
+ if (re.reanchored) {
46161
+ r.engine.markContextDirty();
46162
+ console.log(
46163
+ `[errata] reanchored ${r.engine.profile.name} \u2014 ${re.anchors} anchors onto local code (${re.dropped} unresolved, dropped)`
46164
+ );
46165
+ } else if (re.reason === "error") {
46166
+ console.warn(`[errata] project reanchor failed for ${r.engine.profile.name}: ${re.detail}`);
46167
+ }
46168
+ } catch {
46169
+ }
46170
+ }
46054
46171
  }
46055
46172
  };
46056
46173
  void ambientLinkAll();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.0-dev.82",
3
+ "version": "2.0.0-dev.84",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {