@inerrata-corporation/errata 2.0.8-dev.2929 → 2.0.8

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.
@@ -16137,12 +16137,6 @@ CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
16137
16137
  `;
16138
16138
  var TEMPORAL_INDEX_SQL = `
16139
16139
  CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
16140
- -- Covering + partial index for labelFingerprint over the instance labels: the
16141
- -- live-push probe runs it per workspace on a timer, and each hit used to read
16142
- -- its table row. Partial, so it maintains a few thousand rows instead of adding
16143
- -- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
16144
- DROP INDEX IF EXISTS nodes_live_fingerprint;
16145
- CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause');
16146
16140
  CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
16147
16141
  CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
16148
16142
  -- Expression index on the per-node relPath (stored in attrs_json) so the
@@ -16213,7 +16207,6 @@ function rowToEdge(r) {
16213
16207
  attrs: JSON.parse(r.attrs_json)
16214
16208
  };
16215
16209
  }
16216
- var FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
16217
16210
  var SqliteGraphStore = class {
16218
16211
  db;
16219
16212
  // Typed edge lookups build their SQL from the number of types asked for, and
@@ -16690,32 +16683,6 @@ var SqliteGraphStore = class {
16690
16683
  attrs: JSON.parse(r.attrs_json)
16691
16684
  }));
16692
16685
  }
16693
- *iterateNodeIdentitiesByLabel(label, pageSize = 2e3) {
16694
- const page = this.db.prepare(
16695
- "SELECT rowid AS rid, id, json_extract(attrs_json, '$.relPath') AS relPath, json_extract(attrs_json, '$.qname') AS qname FROM nodes WHERE rowid > ? AND label = ? AND valid_to IS NULL ORDER BY rowid LIMIT ?"
16696
- );
16697
- let after = 0;
16698
- for (; ; ) {
16699
- const rows = page.all(after, label, pageSize);
16700
- for (const r of rows) {
16701
- yield {
16702
- id: r.id,
16703
- relPath: typeof r.relPath === "string" ? r.relPath : null,
16704
- qname: typeof r.qname === "string" ? r.qname : null
16705
- };
16706
- }
16707
- if (rows.length < pageSize) return;
16708
- after = rows[rows.length - 1].rid;
16709
- }
16710
- }
16711
- recentNodeIds(label, limit) {
16712
- const rows = this.db.prepare("SELECT id FROM nodes WHERE label = ? AND valid_to IS NULL ORDER BY last_updated_at DESC LIMIT ?").all(label, Math.max(0, limit));
16713
- return rows.map((r) => r.id);
16714
- }
16715
- hasLiveNodes() {
16716
- const r = this.db.prepare("SELECT EXISTS(SELECT 1 FROM nodes WHERE valid_to IS NULL) AS e").get();
16717
- return r.e === 1;
16718
- }
16719
16686
  findNodeIdentitiesByLabel(label) {
16720
16687
  const rows = this.stmts.identitiesByLabel.all(label);
16721
16688
  return rows.map((r) => ({
@@ -16863,15 +16830,6 @@ var SqliteGraphStore = class {
16863
16830
  }
16864
16831
  labelFingerprint(labels) {
16865
16832
  if (labels.length === 0) return "0";
16866
- if (labels.length === FINGERPRINT_INDEXED_LABELS.length && FINGERPRINT_INDEXED_LABELS.every((l) => labels.includes(l))) {
16867
- const r2 = this.db.prepare(
16868
- `SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
16869
- MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
16870
- FROM nodes INDEXED BY nodes_instance_fingerprint
16871
- WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
16872
- ).get();
16873
- return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
16874
- }
16875
16833
  const r = this.db.prepare(
16876
16834
  `SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
16877
16835
  MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
@@ -18216,15 +18174,6 @@ function generalize(text, opts = {}) {
18216
18174
  // src/instance-ingest.ts
18217
18175
  init_src();
18218
18176
 
18219
- // src/instance-receipts.ts
18220
- function receiptMap(attrs) {
18221
- const value = attrs["instanceReceipts"];
18222
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
18223
- }
18224
- function instanceReceipt(n, destination) {
18225
- return destination ? receiptMap(n.attrs)[destination] ?? {} : n.attrs;
18226
- }
18227
-
18228
18177
  // src/contribution-ready.ts
18229
18178
  function cosine2(a, b) {
18230
18179
  if (a.length === 0 || a.length !== b.length) return 0;
@@ -19094,8 +19043,8 @@ function stripCodebaseScope(scope) {
19094
19043
  delete s["codebase"];
19095
19044
  return s;
19096
19045
  }
19097
- function contributedWireId(n, destinationKey) {
19098
- const cloudId = instanceReceipt(n, destinationKey)["cloudNodeId"];
19046
+ function contributedWireId(n) {
19047
+ const cloudId = n.attrs["cloudNodeId"];
19099
19048
  return isMembraneSaltedId(cloudId) ? cloudId : n.id;
19100
19049
  }
19101
19050
  var WIRE_CANONICAL_ID_MIN = 6;
@@ -19239,26 +19188,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19239
19188
  fileRefsSubstituted: 0,
19240
19189
  fileRefLexiconMisses: 0
19241
19190
  };
19242
- const sharedCauses = /* @__PURE__ */ new Map();
19243
- const causalQueue = store.findNodesByLabel("Problem").filter(
19244
- (n) => n.attrs["source"] !== "cloud" && n.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE && !ignored(n.description)
19245
- ).map((n) => n.id);
19246
- const causalSeen = new Set(causalQueue);
19247
- for (let i = 0; i < causalQueue.length; i++) {
19248
- const id = causalQueue[i];
19249
- for (const e of [...store.outEdges(id, ["CAUSED_BY"]), ...opts.sharedStore?.outEdges(id, ["CAUSED_BY"]) ?? []]) {
19250
- if (causalSeen.has(e.to)) continue;
19251
- causalSeen.add(e.to);
19252
- const cause = nodeOf(e.to);
19253
- if (!cause || cause.label !== "RootCause" || cause.attrs["source"] === "cloud" || ignored(cause.description)) continue;
19254
- sharedCauses.set(cause.id, cause);
19255
- causalQueue.push(cause.id);
19256
- }
19257
- }
19258
19191
  for (const label of INSTANCE_LABELS) {
19259
19192
  const ref = [];
19260
19193
  includedByLabel.set(label, ref);
19261
- const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...sharedCauses.values()] : store.findNodesByLabel(label);
19194
+ const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...opts.sharedStore.findNodesByLabel(label)] : store.findNodesByLabel(label);
19262
19195
  for (const n of population) {
19263
19196
  if (seen.has(n.id)) continue;
19264
19197
  if (walked.has(n.id)) continue;
@@ -19276,18 +19209,18 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19276
19209
  composition.ignored++;
19277
19210
  continue;
19278
19211
  }
19279
- const contributedAtSeq = instanceReceipt(n, opts.destinationKey)["contributedAtSeq"];
19212
+ const contributedAtSeq = n.attrs["contributedAtSeq"];
19280
19213
  if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
19281
19214
  composition.watermarked++;
19282
19215
  anchorSources.add(n.id);
19283
- semanticEndpoints.set(n.id, contributedWireId(n, opts.destinationKey));
19216
+ semanticEndpoints.set(n.id, contributedWireId(n));
19284
19217
  continue;
19285
19218
  }
19286
19219
  if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) {
19287
19220
  composition.autoMint++;
19288
19221
  continue;
19289
19222
  }
19290
- if (isTerminallyRefused({ ...n, attrs: instanceReceipt(n, opts.destinationKey) })) {
19223
+ if (isTerminallyRefused(n)) {
19291
19224
  composition.terminalRefused++;
19292
19225
  continue;
19293
19226
  }
@@ -19346,9 +19279,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19346
19279
  }
19347
19280
  const dg = digest(targets.map(({ e, wireId }) => `${e.type}>${wireId}`).sort());
19348
19281
  const sourceNode = nodeOf(sourceId);
19349
- if ((sourceNode && instanceReceipt(sourceNode, opts.destinationKey)["anchorsContributedDigest"]) === dg) continue;
19282
+ if (sourceNode?.attrs["anchorsContributedDigest"] === dg) continue;
19350
19283
  anchorDigests[sourceId] = dg;
19351
- const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode, opts.destinationKey);
19284
+ const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode);
19352
19285
  for (const { e, t, wireId } of targets) {
19353
19286
  const reject = unshippableReason(wireId, t.label);
19354
19287
  if (reject) {
@@ -19377,7 +19310,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19377
19310
  for (const sourceId of anchorSources) {
19378
19311
  const source = nodeOf(sourceId);
19379
19312
  if (!source) continue;
19380
- const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source, opts.destinationKey);
19313
+ const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source);
19381
19314
  const planned = [];
19382
19315
  for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
19383
19316
  const target = nodeOf(e.to);
@@ -19412,7 +19345,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19412
19345
  const dg = digest(
19413
19346
  planned.map(({ symId, wireAttrs }) => `ANCHORED_AT>${symId}>${JSON.stringify(wireAttrs)}`).sort()
19414
19347
  );
19415
- if (instanceReceipt(source, opts.destinationKey)["projectAnchorsContributedDigest"] === dg) continue;
19348
+ if (source.attrs["projectAnchorsContributedDigest"] === dg) continue;
19416
19349
  projectAnchorDigests[sourceId] = dg;
19417
19350
  for (const { e, target, symId, wireAttrs } of planned) {
19418
19351
  if (!contextSeen.has(symId)) {
@@ -19458,7 +19391,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19458
19391
  if (outs.length === 0) continue;
19459
19392
  const dg = digest(outs.map(({ e, wireTo }) => `${e.type}>${wireTo}`).sort());
19460
19393
  const owner = nodeOf(sourceId);
19461
- const digestSkip = (owner && instanceReceipt(owner, opts.destinationKey)["semanticEdgesContributedDigest"]) === dg;
19394
+ const digestSkip = owner?.attrs["semanticEdgesContributedDigest"] === dg;
19462
19395
  if (!digestSkip) semanticEdgeDigests[sourceId] = dg;
19463
19396
  for (const { e, wireTo } of outs) {
19464
19397
  if (digestSkip && !shippedById.has(e.to)) continue;
@@ -19515,7 +19448,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
19515
19448
  for (const wn of nodes) {
19516
19449
  if (wn.label !== "RootCause" && wn.label !== "Solution") continue;
19517
19450
  const src = nodeOf(wn.id);
19518
- if (src && typeof instanceReceipt(src, opts.destinationKey)["contributedAtSeq"] === "number") continue;
19451
+ if (typeof src?.attrs["contributedAtSeq"] === "number") continue;
19519
19452
  if (bindingEndpoints.has(wn.id)) continue;
19520
19453
  heldOrphans.add(wn.id);
19521
19454
  }
@@ -19593,7 +19526,6 @@ function buildDrainInstances(store, sharedStore, input) {
19593
19526
  ...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {},
19594
19527
  workspaceRoot: input.workspaceRoot,
19595
19528
  sharedStore,
19596
- destinationKey: input.destinationKey,
19597
19529
  onComposition: (c) => {
19598
19530
  composition = c;
19599
19531
  },
package/errata.mjs CHANGED
@@ -17438,7 +17438,7 @@ function rowToEdge(r) {
17438
17438
  function openGraphStore(opts) {
17439
17439
  return new SqliteGraphStore(opts);
17440
17440
  }
17441
- var LOCAL_RULE_OVERRIDES, SCHEMA_VERSION, SCHEMA_SQL, TEMPORAL_INDEX_SQL, FINGERPRINT_INDEXED_LABELS, SqliteGraphStore;
17441
+ var LOCAL_RULE_OVERRIDES, SCHEMA_VERSION, SCHEMA_SQL, TEMPORAL_INDEX_SQL, SqliteGraphStore;
17442
17442
  var init_store = __esm({
17443
17443
  "../../packages/local-graph/src/store.ts"() {
17444
17444
  "use strict";
@@ -17559,12 +17559,6 @@ CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
17559
17559
  `;
17560
17560
  TEMPORAL_INDEX_SQL = `
17561
17561
  CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
17562
- -- Covering + partial index for labelFingerprint over the instance labels: the
17563
- -- live-push probe runs it per workspace on a timer, and each hit used to read
17564
- -- its table row. Partial, so it maintains a few thousand rows instead of adding
17565
- -- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
17566
- DROP INDEX IF EXISTS nodes_live_fingerprint;
17567
- CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause');
17568
17562
  CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
17569
17563
  CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
17570
17564
  -- Expression index on the per-node relPath (stored in attrs_json) so the
@@ -17578,7 +17572,6 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
17578
17572
  -- every edited file of every turn, and a scan parses every Problem's attrs.
17579
17573
  CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
17580
17574
  `;
17581
- FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
17582
17575
  SqliteGraphStore = class {
17583
17576
  db;
17584
17577
  // Typed edge lookups build their SQL from the number of types asked for, and
@@ -18055,32 +18048,6 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
18055
18048
  attrs: JSON.parse(r.attrs_json)
18056
18049
  }));
18057
18050
  }
18058
- *iterateNodeIdentitiesByLabel(label, pageSize = 2e3) {
18059
- const page = this.db.prepare(
18060
- "SELECT rowid AS rid, id, json_extract(attrs_json, '$.relPath') AS relPath, json_extract(attrs_json, '$.qname') AS qname FROM nodes WHERE rowid > ? AND label = ? AND valid_to IS NULL ORDER BY rowid LIMIT ?"
18061
- );
18062
- let after = 0;
18063
- for (; ; ) {
18064
- const rows = page.all(after, label, pageSize);
18065
- for (const r of rows) {
18066
- yield {
18067
- id: r.id,
18068
- relPath: typeof r.relPath === "string" ? r.relPath : null,
18069
- qname: typeof r.qname === "string" ? r.qname : null
18070
- };
18071
- }
18072
- if (rows.length < pageSize) return;
18073
- after = rows[rows.length - 1].rid;
18074
- }
18075
- }
18076
- recentNodeIds(label, limit) {
18077
- const rows = this.db.prepare("SELECT id FROM nodes WHERE label = ? AND valid_to IS NULL ORDER BY last_updated_at DESC LIMIT ?").all(label, Math.max(0, limit));
18078
- return rows.map((r) => r.id);
18079
- }
18080
- hasLiveNodes() {
18081
- const r = this.db.prepare("SELECT EXISTS(SELECT 1 FROM nodes WHERE valid_to IS NULL) AS e").get();
18082
- return r.e === 1;
18083
- }
18084
18051
  findNodeIdentitiesByLabel(label) {
18085
18052
  const rows = this.stmts.identitiesByLabel.all(label);
18086
18053
  return rows.map((r) => ({
@@ -18228,15 +18195,6 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
18228
18195
  }
18229
18196
  labelFingerprint(labels) {
18230
18197
  if (labels.length === 0) return "0";
18231
- if (labels.length === FINGERPRINT_INDEXED_LABELS.length && FINGERPRINT_INDEXED_LABELS.every((l) => labels.includes(l))) {
18232
- const r2 = this.db.prepare(
18233
- `SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
18234
- MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
18235
- FROM nodes INDEXED BY nodes_instance_fingerprint
18236
- WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
18237
- ).get();
18238
- return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
18239
- }
18240
18198
  const r = this.db.prepare(
18241
18199
  `SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
18242
18200
  MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
@@ -24020,7 +23978,6 @@ __export(src_exports2, {
24020
23978
  CODE_REACH_EDGES: () => CODE_REACH_EDGES,
24021
23979
  CREDIT_FAMILY: () => CREDIT_FAMILY,
24022
23980
  DEFAULT_MIN_COVERAGE: () => DEFAULT_MIN_COVERAGE,
24023
- FINGERPRINT_INDEXED_LABELS: () => FINGERPRINT_INDEXED_LABELS,
24024
23981
  FIX_CANDIDATE_ASK_LIMIT: () => FIX_CANDIDATE_ASK_LIMIT,
24025
23982
  FOLD_EMBED_AUTO_COSINE: () => FOLD_EMBED_AUTO_COSINE,
24026
23983
  FOLD_JUDGE_MIN_COSINE: () => FOLD_JUDGE_MIN_COSINE,
@@ -26368,8 +26325,8 @@ var init_config = __esm({
26368
26325
  "use strict";
26369
26326
  init_paths();
26370
26327
  LEGACY_CLOUD_URL = "https://inerrata-gateway.onrender.com";
26371
- DEFAULT_CLOUD_URL = true ? "https://dev.inerrata.dev" : DEV_CLOUD_URL;
26372
- DEFAULT_UPDATE_CHANNEL = false ? "latest" : "dev";
26328
+ DEFAULT_CLOUD_URL = true ? "https://inerrata.dev" : DEV_CLOUD_URL;
26329
+ DEFAULT_UPDATE_CHANNEL = true ? "latest" : "dev";
26373
26330
  }
26374
26331
  });
26375
26332
 
@@ -29174,12 +29131,6 @@ function statuslineText(sessionId, now = Date.now()) {
29174
29131
  if (!hit || now - hit.at > STATUS_CARD_TTL_MS) return IDLE_STATUS;
29175
29132
  return renderStatusCard(hit.card);
29176
29133
  }
29177
- function statuslineDir(body2) {
29178
- const ws = body2["workspace"];
29179
- const current = ws && typeof ws === "object" ? ws["current_dir"] : void 0;
29180
- if (typeof current === "string" && current) return current;
29181
- return typeof body2["cwd"] === "string" && body2["cwd"] ? body2["cwd"] : null;
29182
- }
29183
29134
  function recallCardEnabled(env2 = process.env) {
29184
29135
  const v = (env2["ERRATA_RECALL_CARD"] ?? "").trim().toLowerCase();
29185
29136
  return !(v === "0" || v === "off" || v === "false" || v === "no");
@@ -71442,7 +71393,7 @@ var init_report_render = __esm({
71442
71393
 
71443
71394
  // src/cli.ts
71444
71395
  init_src6();
71445
- import { closeSync as closeSync2, existsSync as existsSync35, openSync as openSync2, readFileSync as readFileSync36, renameSync as renameSync4, statSync as statSync10 } from "node:fs";
71396
+ import { closeSync as closeSync2, existsSync as existsSync34, openSync as openSync2, readFileSync as readFileSync35, renameSync as renameSync4, statSync as statSync10 } from "node:fs";
71446
71397
  import { join as join43, resolve as pathResolve2 } from "node:path";
71447
71398
  import { spawn as spawn5 } from "node:child_process";
71448
71399
 
@@ -72764,9 +72715,9 @@ var NodeFsHandler = class {
72764
72715
  if (this.fsw.closed) {
72765
72716
  return;
72766
72717
  }
72767
- const dirname14 = sysPath.dirname(file2);
72718
+ const dirname13 = sysPath.dirname(file2);
72768
72719
  const basename8 = sysPath.basename(file2);
72769
- const parent = this.fsw._getWatchedDir(dirname14);
72720
+ const parent = this.fsw._getWatchedDir(dirname13);
72770
72721
  let prevStats = stats;
72771
72722
  if (parent.has(basename8))
72772
72723
  return;
@@ -72793,7 +72744,7 @@ var NodeFsHandler = class {
72793
72744
  prevStats = newStats2;
72794
72745
  }
72795
72746
  } catch (error48) {
72796
- this.fsw._remove(dirname14, basename8);
72747
+ this.fsw._remove(dirname13, basename8);
72797
72748
  }
72798
72749
  } else if (parent.has(basename8)) {
72799
72750
  const at = newStats.atimeMs;
@@ -80267,7 +80218,7 @@ function createWatchBreaker(deps) {
80267
80218
  }
80268
80219
 
80269
80220
  // src/engine.ts
80270
- var DAEMON_VERSION = true ? "2.0.8-dev.2929" : "2.0.0-alpha.0";
80221
+ var DAEMON_VERSION = true ? "2.0.8" : "2.0.0-alpha.0";
80271
80222
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
80272
80223
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
80273
80224
  var GIT_OP_MUTE_MS = 4e3;
@@ -80834,7 +80785,7 @@ function createWorkspaceEngine(opts) {
80834
80785
  lastRemoteAt = now;
80835
80786
  try {
80836
80787
  const norm = normStackTokens;
80837
- const seed = store.recentNodeIds("Problem", 6);
80788
+ const seed = store.findNodesByLabel("Problem").sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 6).map((p) => p.id);
80838
80789
  const q = {
80839
80790
  stack: outboundStack(),
80840
80791
  domains: norm(profile.domains),
@@ -82713,40 +82664,6 @@ async function listenServer(fetchFn, port) {
82713
82664
  init_registry();
82714
82665
  init_identity2();
82715
82666
 
82716
- // src/instance-receipts.ts
82717
- import { createHash as createHash16 } from "node:crypto";
82718
- var FIELDS = ["contributedAtSeq", "cloudNodeId", "anchorsContributedDigest", "projectAnchorsContributedDigest", "semanticEdgesContributedDigest", "shipRefusedSinceSeq", "shipRefusedCount", "shipRefusedReason", "shipRefusedFingerprint"];
82719
- function instanceDestinationKey(input) {
82720
- return createHash16("sha256").update(JSON.stringify([
82721
- input.workspace,
82722
- input.cloudUrl.replace(/\/+$/, ""),
82723
- input.installationId ?? input.profileName ?? "default",
82724
- input.projectId ?? null,
82725
- input.writeTarget?.visibility ?? null,
82726
- input.writeTarget?.org_id ?? null,
82727
- input.writeTarget?.team_id ?? null
82728
- ])).digest("hex");
82729
- }
82730
- function receiptMap(attrs) {
82731
- const value = attrs["instanceReceipts"];
82732
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
82733
- }
82734
- function instanceReceipt(n, destination) {
82735
- return destination ? receiptMap(n.attrs)[destination] ?? {} : n.attrs;
82736
- }
82737
- function updateInstanceReceipt(n, destination, patch, mirrorLegacy) {
82738
- const receipt = { ...instanceReceipt(n, destination), ...patch };
82739
- const attrs = { ...n.attrs, instanceReceipts: { ...receiptMap(n.attrs), [destination]: receipt } };
82740
- if (mirrorLegacy) for (const field of FIELDS) {
82741
- if (field in receipt) attrs[field] = receipt[field];
82742
- else delete attrs[field];
82743
- }
82744
- return attrs;
82745
- }
82746
- function instanceReceiptSequence(n) {
82747
- return Math.max(n.lastReinforcedAtSeq ?? 0, n.createdAtSeq ?? 0);
82748
- }
82749
-
82750
82667
  // src/multi.ts
82751
82668
  init_dist();
82752
82669
  init_src5();
@@ -83151,8 +83068,8 @@ function compositionCounters(c) {
83151
83068
  ...Object.fromEntries(buckets.map((b) => [`sidecarDrop_${b}`, sidecarDropReasons[b] ?? 0]))
83152
83069
  };
83153
83070
  }
83154
- function contributedWireId(n, destinationKey) {
83155
- const cloudId = instanceReceipt(n, destinationKey)["cloudNodeId"];
83071
+ function contributedWireId(n) {
83072
+ const cloudId = n.attrs["cloudNodeId"];
83156
83073
  return isMembraneSaltedId(cloudId) ? cloudId : n.id;
83157
83074
  }
83158
83075
  var WIRE_CANONICAL_ID_MIN = 6;
@@ -83296,26 +83213,10 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83296
83213
  fileRefsSubstituted: 0,
83297
83214
  fileRefLexiconMisses: 0
83298
83215
  };
83299
- const sharedCauses = /* @__PURE__ */ new Map();
83300
- const causalQueue = store.findNodesByLabel("Problem").filter(
83301
- (n) => n.attrs["source"] !== "cloud" && n.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE && !ignored(n.description)
83302
- ).map((n) => n.id);
83303
- const causalSeen = new Set(causalQueue);
83304
- for (let i2 = 0; i2 < causalQueue.length; i2++) {
83305
- const id = causalQueue[i2];
83306
- for (const e of [...store.outEdges(id, ["CAUSED_BY"]), ...opts.sharedStore?.outEdges(id, ["CAUSED_BY"]) ?? []]) {
83307
- if (causalSeen.has(e.to)) continue;
83308
- causalSeen.add(e.to);
83309
- const cause = nodeOf(e.to);
83310
- if (!cause || cause.label !== "RootCause" || cause.attrs["source"] === "cloud" || ignored(cause.description)) continue;
83311
- sharedCauses.set(cause.id, cause);
83312
- causalQueue.push(cause.id);
83313
- }
83314
- }
83315
83216
  for (const label of INSTANCE_LABELS) {
83316
83217
  const ref = [];
83317
83218
  includedByLabel.set(label, ref);
83318
- const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...sharedCauses.values()] : store.findNodesByLabel(label);
83219
+ const population = label === "RootCause" && opts.sharedStore ? [...store.findNodesByLabel(label), ...opts.sharedStore.findNodesByLabel(label)] : store.findNodesByLabel(label);
83319
83220
  for (const n of population) {
83320
83221
  if (seen.has(n.id)) continue;
83321
83222
  if (walked.has(n.id)) continue;
@@ -83333,18 +83234,18 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83333
83234
  composition.ignored++;
83334
83235
  continue;
83335
83236
  }
83336
- const contributedAtSeq = instanceReceipt(n, opts.destinationKey)["contributedAtSeq"];
83237
+ const contributedAtSeq = n.attrs["contributedAtSeq"];
83337
83238
  if (typeof contributedAtSeq === "number" && (n.lastReinforcedAtSeq ?? 0) <= contributedAtSeq) {
83338
83239
  composition.watermarked++;
83339
83240
  anchorSources.add(n.id);
83340
- semanticEndpoints.set(n.id, contributedWireId(n, opts.destinationKey));
83241
+ semanticEndpoints.set(n.id, contributedWireId(n));
83341
83242
  continue;
83342
83243
  }
83343
83244
  if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) {
83344
83245
  composition.autoMint++;
83345
83246
  continue;
83346
83247
  }
83347
- if (isTerminallyRefused({ ...n, attrs: instanceReceipt(n, opts.destinationKey) })) {
83248
+ if (isTerminallyRefused(n)) {
83348
83249
  composition.terminalRefused++;
83349
83250
  continue;
83350
83251
  }
@@ -83403,9 +83304,9 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83403
83304
  }
83404
83305
  const dg = digest(targets.map(({ e, wireId }) => `${e.type}>${wireId}`).sort());
83405
83306
  const sourceNode = nodeOf(sourceId);
83406
- if ((sourceNode && instanceReceipt(sourceNode, opts.destinationKey)["anchorsContributedDigest"]) === dg) continue;
83307
+ if (sourceNode?.attrs["anchorsContributedDigest"] === dg) continue;
83407
83308
  anchorDigests[sourceId] = dg;
83408
- const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode, opts.destinationKey);
83309
+ const wireFrom = seen.has(sourceId) || !sourceNode ? sourceId : contributedWireId(sourceNode);
83409
83310
  for (const { e, t, wireId } of targets) {
83410
83311
  const reject = unshippableReason(wireId, t.label);
83411
83312
  if (reject) {
@@ -83434,7 +83335,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83434
83335
  for (const sourceId of anchorSources) {
83435
83336
  const source = nodeOf(sourceId);
83436
83337
  if (!source) continue;
83437
- const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source, opts.destinationKey);
83338
+ const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source);
83438
83339
  const planned = [];
83439
83340
  for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
83440
83341
  const target = nodeOf(e.to);
@@ -83469,7 +83370,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83469
83370
  const dg = digest(
83470
83371
  planned.map(({ symId, wireAttrs }) => `ANCHORED_AT>${symId}>${JSON.stringify(wireAttrs)}`).sort()
83471
83372
  );
83472
- if (instanceReceipt(source, opts.destinationKey)["projectAnchorsContributedDigest"] === dg) continue;
83373
+ if (source.attrs["projectAnchorsContributedDigest"] === dg) continue;
83473
83374
  projectAnchorDigests[sourceId] = dg;
83474
83375
  for (const { e, target, symId, wireAttrs } of planned) {
83475
83376
  if (!contextSeen.has(symId)) {
@@ -83515,7 +83416,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83515
83416
  if (outs.length === 0) continue;
83516
83417
  const dg = digest(outs.map(({ e, wireTo }) => `${e.type}>${wireTo}`).sort());
83517
83418
  const owner = nodeOf(sourceId);
83518
- const digestSkip = (owner && instanceReceipt(owner, opts.destinationKey)["semanticEdgesContributedDigest"]) === dg;
83419
+ const digestSkip = owner?.attrs["semanticEdgesContributedDigest"] === dg;
83519
83420
  if (!digestSkip) semanticEdgeDigests[sourceId] = dg;
83520
83421
  for (const { e, wireTo } of outs) {
83521
83422
  if (digestSkip && !shippedById.has(e.to)) continue;
@@ -83572,7 +83473,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
83572
83473
  for (const wn of nodes) {
83573
83474
  if (wn.label !== "RootCause" && wn.label !== "Solution") continue;
83574
83475
  const src = nodeOf(wn.id);
83575
- if (src && typeof instanceReceipt(src, opts.destinationKey)["contributedAtSeq"] === "number") continue;
83476
+ if (typeof src?.attrs["contributedAtSeq"] === "number") continue;
83576
83477
  if (bindingEndpoints.has(wn.id)) continue;
83577
83478
  heldOrphans.add(wn.id);
83578
83479
  }
@@ -83726,7 +83627,6 @@ function buildDrainInstances(store, sharedStore, input) {
83726
83627
  ...input.includePackages !== void 0 ? { includePackages: input.includePackages } : {},
83727
83628
  workspaceRoot: input.workspaceRoot,
83728
83629
  sharedStore,
83729
- destinationKey: input.destinationKey,
83730
83630
  onComposition: (c) => {
83731
83631
  composition = c;
83732
83632
  },
@@ -84224,7 +84124,7 @@ function buildReverseSymbolMap(opts) {
84224
84124
  function* reverseSymbolEntries(opts) {
84225
84125
  const { store, salt, projectId } = opts;
84226
84126
  for (const kind of ANCHOR_SYMBOL_KINDS2) {
84227
- for (const n of store.iterateNodeIdentitiesByLabel(kind)) {
84127
+ for (const n of store.findNodeIdentitiesByLabel(kind)) {
84228
84128
  const { relPath, qname } = n;
84229
84129
  if (relPath === null || qname === null) continue;
84230
84130
  const sym = projectSymbolId(salt, projectId, relPath, qname, kind);
@@ -84232,7 +84132,7 @@ function* reverseSymbolEntries(opts) {
84232
84132
  yield [projectSaltedNodeId(sym, salt), n.id];
84233
84133
  }
84234
84134
  }
84235
- for (const n of store.iterateNodeIdentitiesByLabel("File")) {
84135
+ for (const n of store.findNodeIdentitiesByLabel("File")) {
84236
84136
  if (n.relPath === null) continue;
84237
84137
  const sym = projectSymbolId(salt, projectId, n.relPath, FILE_ANCHOR_QNAME, "File");
84238
84138
  yield [sym, n.id];
@@ -84272,7 +84172,7 @@ function buildOwnKnowledgeMap(opts) {
84272
84172
  function* ownKnowledgeEntries(opts) {
84273
84173
  const { store, salt } = opts;
84274
84174
  for (const kind of ANCHOR_SOURCE_KINDS) {
84275
- for (const n of store.iterateNodeIdentitiesByLabel(kind)) {
84175
+ for (const n of store.findNodeIdentitiesByLabel(kind)) {
84276
84176
  if (n.id.startsWith("projn_")) continue;
84277
84177
  yield [projectSaltedNodeId(n.id, salt), n.id];
84278
84178
  }
@@ -85394,7 +85294,7 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
85394
85294
 
85395
85295
  // src/link-flow.ts
85396
85296
  init_cloud_auth();
85397
- import { createHash as createHash17 } from "node:crypto";
85297
+ import { createHash as createHash16 } from "node:crypto";
85398
85298
  import { execFileSync as execFileSync5 } from "node:child_process";
85399
85299
  import { existsSync as existsSync30, writeFileSync as writeFileSync23 } from "node:fs";
85400
85300
  import { join as join38 } from "node:path";
@@ -85688,7 +85588,7 @@ async function loginOAuthLoopback(opts) {
85688
85588
 
85689
85589
  // src/link-flow.ts
85690
85590
  function remoteFingerprint(locator) {
85691
- return createHash17("sha256").update(locator).digest("hex");
85591
+ return createHash16("sha256").update(locator).digest("hex");
85692
85592
  }
85693
85593
  function isDecision(value) {
85694
85594
  if (!value || typeof value !== "object") return false;
@@ -86583,7 +86483,7 @@ async function startMultiDaemon(opts = {}) {
86583
86483
  registerWorkspace(rec.engine.profile, rec.root);
86584
86484
  } catch {
86585
86485
  }
86586
- if (wakeIndexPlan(rec.engine.store.hasLiveNodes() ? 1 : 0, opts.reindexOnStart !== false) === "full-index") {
86486
+ if (wakeIndexPlan(rec.engine.store.nodeCount(), opts.reindexOnStart !== false) === "full-index") {
86587
86487
  void enqueueWakeIndex(async () => {
86588
86488
  const done = markPass(`wake-index:${rec.entry.name}`);
86589
86489
  try {
@@ -86806,15 +86706,6 @@ async function startMultiDaemon(opts = {}) {
86806
86706
  app.post("/api/context-inject", (c) => forward(c, cwdOf, { affinity: "follow" }));
86807
86707
  app.post("/api/statusline", async (c) => {
86808
86708
  const body2 = await c.req.json().catch(() => ({}));
86809
- const dir = statuslineDir(body2);
86810
- if (dir !== null) {
86811
- const d = normPath(dir);
86812
- const known = listWorkspaceEntries().some((e) => {
86813
- const root = normPath(e.path);
86814
- return d === root || d.startsWith(`${root}/`);
86815
- });
86816
- if (!known) return c.text("");
86817
- }
86818
86709
  return c.text(statuslineText(String(body2["session_id"] ?? "")));
86819
86710
  });
86820
86711
  for (const r of records) {
@@ -87405,7 +87296,6 @@ async function startMultiDaemon(opts = {}) {
87405
87296
  }
87406
87297
  const ignore2 = loadClaimIgnorePatterns(globalDir());
87407
87298
  const clientPool = /* @__PURE__ */ new Map();
87408
- const receiptContexts = /* @__PURE__ */ new Map();
87409
87299
  const poolFor = (identity) => {
87410
87300
  const k = identityKey(identity);
87411
87301
  let c = clientPool.get(k);
@@ -87548,26 +87438,7 @@ async function startMultiDaemon(opts = {}) {
87548
87438
  return res.accepted;
87549
87439
  });
87550
87440
  }
87551
- const receiptProfile = recordIdentity.profile ?? (cfg2.activeInstallationProfile ? cfg2.installationProfiles[cfg2.activeInstallationProfile] : void 0);
87552
- let receiptContext = receiptContexts.get(identityKey(recordIdentity));
87553
- if (!receiptContext) {
87554
- try {
87555
- receiptContext = await client.context();
87556
- receiptContexts.set(identityKey(recordIdentity), receiptContext);
87557
- } catch (err2) {
87558
- errors.push(`[${projectName}] instance destination unresolved: ${err2 instanceof Error ? err2.message : String(err2)}`);
87559
- continue;
87560
- }
87561
- }
87562
- const destinationKey = instanceDestinationKey({
87563
- workspace: r.id,
87564
- cloudUrl: opts.cloudUrl ?? receiptProfile?.cloudUrl ?? cfg2.cloudUrl,
87565
- installationId: receiptContext.context.installation_id ?? receiptContext.identity.credential_id,
87566
- projectId: project?.projectId,
87567
- writeTarget: project ? null : receiptContext.context.default_write_target
87568
- });
87569
87441
  const built = await buildInstanceBatch(r, {
87570
- destinationKey,
87571
87442
  profile: r.engine.profile,
87572
87443
  daemonVersion: DAEMON_VERSION,
87573
87444
  ignorePatterns: [...ignore2],
@@ -87612,6 +87483,7 @@ async function startMultiDaemon(opts = {}) {
87612
87483
  );
87613
87484
  }
87614
87485
  uploaded += res.accepted;
87486
+ const seq = store.currentIngestSeq();
87615
87487
  const cloudIdByLocal = new Map(
87616
87488
  res.result.nodes.filter((rn) => rn.nodeId).map((rn) => [rn.canonicalId, rn.nodeId])
87617
87489
  );
@@ -87620,7 +87492,6 @@ async function startMultiDaemon(opts = {}) {
87620
87492
  if (rn.decision === "rejected") rejected.set(rn.canonicalId, rn.reason ?? "no reason given");
87621
87493
  }
87622
87494
  const rejectedEdges = res.result.edges.filter((re) => re.decision === "rejected");
87623
- const edgeReceiptsComplete = rejectedEdges.length === 0 && res.result.edges.length === instances.edges.length;
87624
87495
  if (rejectedEdges.length > 0) {
87625
87496
  const byReason = /* @__PURE__ */ new Map();
87626
87497
  for (const re of rejectedEdges) {
@@ -87651,17 +87522,17 @@ async function startMultiDaemon(opts = {}) {
87651
87522
  const owner = owningStore(id);
87652
87523
  if (!owner) return;
87653
87524
  const fp = refusalFingerprint(reason, owner.n.description);
87654
- const same = instanceReceipt(owner.n, destinationKey)["shipRefusedFingerprint"] === fp;
87655
- const count = same ? Number(instanceReceipt(owner.n, destinationKey)["shipRefusedCount"] ?? 0) + 1 : 1;
87656
- if (instanceReceipt(owner.n, destinationKey)["shipRefusedSinceSeq"] !== void 0) repeat();
87525
+ const same = owner.n.attrs["shipRefusedFingerprint"] === fp;
87526
+ const count = same ? Number(owner.n.attrs["shipRefusedCount"] ?? 0) + 1 : 1;
87527
+ if (owner.n.attrs["shipRefusedSinceSeq"] !== void 0) repeat();
87657
87528
  owner.s.updateNode(id, {
87658
- attrs: updateInstanceReceipt(owner.n, destinationKey, {
87659
- ...instanceReceipt(owner.n, destinationKey),
87660
- ...same && instanceReceipt(owner.n, destinationKey)["shipRefusedSinceSeq"] !== void 0 ? {} : { shipRefusedSinceSeq: owner.s.currentIngestSeq() },
87529
+ attrs: {
87530
+ ...owner.n.attrs,
87531
+ ...same && owner.n.attrs["shipRefusedSinceSeq"] !== void 0 ? {} : { shipRefusedSinceSeq: seq },
87661
87532
  shipRefusedCount: count,
87662
87533
  shipRefusedReason: reason,
87663
87534
  shipRefusedFingerprint: fp
87664
- }, owner.s === store)
87535
+ }
87665
87536
  });
87666
87537
  if (same && count === SHIP_TERMINAL_REFUSALS && !isRetryableRefusal(reason)) {
87667
87538
  nowHeld.push({ id, reason });
@@ -87678,7 +87549,6 @@ async function startMultiDaemon(opts = {}) {
87678
87549
  const owner = owningStore(n.id);
87679
87550
  if (!owner || !["Problem", "Solution", "RootCause"].includes(owner.n.label)) return;
87680
87551
  if (blocked.has(n.id)) return;
87681
- if (!cloudIdByLocal.has(n.id)) return;
87682
87552
  if (rejected.has(n.id)) return;
87683
87553
  const cloudNodeId = cloudIdByLocal.get(n.id);
87684
87554
  const {
@@ -87687,41 +87557,37 @@ async function startMultiDaemon(opts = {}) {
87687
87557
  shipRefusedReason: _clearedReason,
87688
87558
  shipRefusedFingerprint: _clearedFp,
87689
87559
  ...carried
87690
- } = instanceReceipt(owner.n, destinationKey);
87560
+ } = owner.n.attrs;
87691
87561
  owner.s.updateNode(n.id, {
87692
- attrs: updateInstanceReceipt(owner.n, destinationKey, {
87562
+ attrs: {
87693
87563
  ...carried,
87694
- shipRefusedSinceSeq: void 0,
87695
- shipRefusedCount: void 0,
87696
- shipRefusedReason: void 0,
87697
- shipRefusedFingerprint: void 0,
87698
- contributedAtSeq: instanceReceiptSequence(n),
87699
- cloudNodeId
87700
- }, owner.s === store)
87564
+ contributedAtSeq: seq,
87565
+ ...cloudNodeId && cloudNodeId !== n.id ? { cloudNodeId } : {}
87566
+ }
87701
87567
  });
87702
87568
  });
87703
87569
  await stampBatched(Object.entries(instances.anchorDigests), ([localId, dg]) => {
87704
87570
  const owner = owningStore(localId);
87705
87571
  if (!owner) return;
87706
- if (!edgeReceiptsComplete || !instanceReceipt(owner.n, destinationKey)["cloudNodeId"] || rejected.has(localId) || blocked.has(localId)) return;
87572
+ if (rejected.has(localId) || blocked.has(localId)) return;
87707
87573
  owner.s.updateNode(localId, {
87708
- attrs: updateInstanceReceipt(owner.n, destinationKey, { anchorsContributedDigest: dg }, owner.s === store)
87574
+ attrs: { ...owner.n.attrs, anchorsContributedDigest: dg }
87709
87575
  });
87710
87576
  });
87711
87577
  await stampBatched(Object.entries(instances.projectAnchorDigests), ([localId, dg]) => {
87712
87578
  const owner = owningStore(localId);
87713
87579
  if (!owner) return;
87714
- if (!edgeReceiptsComplete || !instanceReceipt(owner.n, destinationKey)["cloudNodeId"] || rejected.has(localId) || blocked.has(localId)) return;
87580
+ if (rejected.has(localId) || blocked.has(localId)) return;
87715
87581
  owner.s.updateNode(localId, {
87716
- attrs: updateInstanceReceipt(owner.n, destinationKey, { projectAnchorsContributedDigest: dg }, owner.s === store)
87582
+ attrs: { ...owner.n.attrs, projectAnchorsContributedDigest: dg }
87717
87583
  });
87718
87584
  });
87719
87585
  await stampBatched(Object.entries(instances.semanticEdgeDigests), ([localId, dg]) => {
87720
87586
  const owner = owningStore(localId);
87721
87587
  if (!owner) return;
87722
- if (!edgeReceiptsComplete || !instanceReceipt(owner.n, destinationKey)["cloudNodeId"] || rejected.has(localId) || blocked.has(localId)) return;
87588
+ if (rejected.has(localId) || blocked.has(localId)) return;
87723
87589
  owner.s.updateNode(localId, {
87724
- attrs: updateInstanceReceipt(owner.n, destinationKey, { semanticEdgesContributedDigest: dg }, owner.s === store)
87590
+ attrs: { ...owner.n.attrs, semanticEdgesContributedDigest: dg }
87725
87591
  });
87726
87592
  });
87727
87593
  appendPassLedger(r.engine.paths.configDir, "ship", Date.now() - shipStartedAt, {
@@ -88700,10 +88566,9 @@ function consolidationGapMs(lastPassMs, policy) {
88700
88566
  }
88701
88567
 
88702
88568
  // src/claude-statusline.ts
88703
- import { existsSync as existsSync34, mkdirSync as mkdirSync10, readFileSync as readFileSync35, writeFileSync as writeFileSync26 } from "node:fs";
88704
- import { homedir as homedir8 } from "node:os";
88705
- import { dirname as dirname13, join as join42 } from "node:path";
88706
- var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
88569
+ import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync26 } from "node:fs";
88570
+ import { join as join42 } from "node:path";
88571
+ var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata install-hooks claude
88707
88572
  import { readFileSync } from 'node:fs';
88708
88573
 
88709
88574
  try {
@@ -88729,57 +88594,15 @@ function buildStatusLine(port, nodePath, relayPath) {
88729
88594
  function isErrataStatusLine(value) {
88730
88595
  return !!value && typeof value === "object" && typeof value["command"] === "string" && value["command"].includes(STATUSLINE_RELAY_FILE);
88731
88596
  }
88732
- function removeProjectStatusLine(settings) {
88733
- if (!isErrataStatusLine(settings["statusLine"])) return false;
88734
- delete settings["statusLine"];
88597
+ function installStatusLine(settings, root, port, nodePath = process.execPath) {
88598
+ if (settings["statusLine"] !== void 0 && !isErrataStatusLine(settings["statusLine"])) return false;
88599
+ const dir = join42(root, ".claude", "hooks");
88600
+ const relay = join42(dir, STATUSLINE_RELAY_FILE);
88601
+ mkdirSync10(dir, { recursive: true });
88602
+ writeFileSync26(relay, STATUSLINE_RELAY_SOURCE, "utf8");
88603
+ settings["statusLine"] = buildStatusLine(port, nodePath, relay);
88735
88604
  return true;
88736
88605
  }
88737
- function userClaudeSettingsPath() {
88738
- const base = process.env["CLAUDE_CONFIG_DIR"] ?? join42(homedir8(), ".claude");
88739
- return join42(base, "settings.json");
88740
- }
88741
- function ensureUserStatusLine(opts) {
88742
- const env2 = opts.env ?? process.env;
88743
- const off = (env2["ERRATA_STATUSLINE"] ?? "").trim().toLowerCase();
88744
- if (off === "0" || off === "off" || off === "false" || off === "no") return "disabled";
88745
- const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
88746
- let settings = {};
88747
- if (existsSync34(settingsPath)) {
88748
- try {
88749
- const parsed = JSON.parse(readFileSync35(settingsPath, "utf8"));
88750
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
88751
- settings = parsed;
88752
- } catch {
88753
- return "unreadable";
88754
- }
88755
- }
88756
- if (settings["statusLine"] !== void 0 && !isErrataStatusLine(settings["statusLine"])) return "kept-own";
88757
- const relay = join42(opts.relayDir, STATUSLINE_RELAY_FILE);
88758
- mkdirSync10(opts.relayDir, { recursive: true });
88759
- if (!existsSync34(relay) || readFileSync35(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
88760
- writeFileSync26(relay, STATUSLINE_RELAY_SOURCE, "utf8");
88761
- }
88762
- const next = buildStatusLine(opts.port, opts.nodePath ?? process.execPath, relay);
88763
- if (JSON.stringify(settings["statusLine"]) === JSON.stringify(next)) return "unchanged";
88764
- settings["statusLine"] = next;
88765
- mkdirSync10(dirname13(settingsPath), { recursive: true });
88766
- writeFileSync26(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
88767
- return "installed";
88768
- }
88769
- function describeStatusLineOutcome(outcome) {
88770
- switch (outcome) {
88771
- case "installed":
88772
- return "status line: errata recall card in colour (user settings; ERRATA_STATUSLINE=off opts out)";
88773
- case "unchanged":
88774
- return "status line: errata recall card already set up";
88775
- case "kept-own":
88776
- return "status line: kept your own \u2014 errata's recall card shows inline only";
88777
- case "disabled":
88778
- return "status line: skipped (ERRATA_STATUSLINE=off)";
88779
- case "unreadable":
88780
- return "status line: skipped \u2014 ~/.claude/settings.json is not valid JSON";
88781
- }
88782
- }
88783
88606
 
88784
88607
  // src/opencode-plugin.ts
88785
88608
  var OPENCODE_PLUGIN_MARKER = "// @inerrata opencode plugin \u2014 errata-managed (errata install-hooks opencode)";
@@ -89186,14 +89009,14 @@ async function cmdInit() {
89186
89009
  if (!skipHooks) {
89187
89010
  console.log("");
89188
89011
  console.log("installing harness hooks...");
89189
- const { existsSync: existsSync36 } = await import("node:fs");
89012
+ const { existsSync: existsSync35 } = await import("node:fs");
89190
89013
  const { join: join44 } = await import("node:path");
89191
89014
  try {
89192
89015
  await installClaudeHooks(port);
89193
89016
  } catch (err2) {
89194
89017
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
89195
89018
  }
89196
- if (existsSync36(join44(ROOT, ".cursor"))) {
89019
+ if (existsSync35(join44(ROOT, ".cursor"))) {
89197
89020
  try {
89198
89021
  await installCursorMcpConfig();
89199
89022
  } catch (err2) {
@@ -89295,7 +89118,6 @@ async function cmdStart() {
89295
89118
  await ensureProfile();
89296
89119
  const profile = loadProfile(ROOT);
89297
89120
  if (profile) registerWorkspace(profile, ROOT);
89298
- if (profile) console.log(`errata: ${ensureStatusLine(resolveHookPort())}`);
89299
89121
  const lockPath = globalDaemonLock();
89300
89122
  const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
89301
89123
  const where = profile ? `${profile.name} (${profile.id})` : ROOT;
@@ -89383,9 +89205,9 @@ async function cmdStatus() {
89383
89205
  console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
89384
89206
  console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
89385
89207
  }
89386
- console.log(` graph db: ${existsSync35(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
89387
- console.log(` event log: ${existsSync35(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
89388
- if (existsSync35(paths.castalia)) {
89208
+ console.log(` graph db: ${existsSync34(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
89209
+ console.log(` event log: ${existsSync34(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
89210
+ if (existsSync34(paths.castalia)) {
89389
89211
  try {
89390
89212
  const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
89391
89213
  const store = openGraphStore2({ path: paths.castalia });
@@ -90018,7 +89840,6 @@ async function cmdLink(args2) {
90018
89840
  process.exitCode = 1;
90019
89841
  return;
90020
89842
  }
90021
- console.log(ensureStatusLine(resolveHookPort()));
90022
89843
  delete profile.projectLinkDisabled;
90023
89844
  const remote = flag("--remote");
90024
89845
  if (remote) {
@@ -90355,11 +90176,11 @@ function cmdInstallationProfile(args2) {
90355
90176
  }
90356
90177
  async function cmdReview() {
90357
90178
  const paths = workspacePaths(ROOT);
90358
- if (!existsSync35(paths.reviewQueue)) {
90179
+ if (!existsSync34(paths.reviewQueue)) {
90359
90180
  console.log("(review queue empty)");
90360
90181
  return;
90361
90182
  }
90362
- const queue = JSON.parse(readFileSync36(paths.reviewQueue, "utf8"));
90183
+ const queue = JSON.parse(readFileSync35(paths.reviewQueue, "utf8"));
90363
90184
  if (queue.length === 0) {
90364
90185
  console.log("(review queue empty)");
90365
90186
  return;
@@ -91030,7 +90851,7 @@ async function gatherRepo(store, ws) {
91030
90851
  };
91031
90852
  }
91032
90853
  async function gatherReportData(generatedAt) {
91033
- const { existsSync: existsSync36 } = await import("node:fs");
90854
+ const { existsSync: existsSync35 } = await import("node:fs");
91034
90855
  const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
91035
90856
  const cfg = loadConfig();
91036
90857
  const outbound = cfg.consent.sync ? "auto" : "off";
@@ -91038,7 +90859,7 @@ async function gatherReportData(generatedAt) {
91038
90859
  for (const ws of listWorkspaces()) {
91039
90860
  if (ws.missing) continue;
91040
90861
  const dbPath = workspacePaths(ws.path).castalia;
91041
- if (!existsSync36(dbPath)) continue;
90862
+ if (!existsSync35(dbPath)) continue;
91042
90863
  let store = null;
91043
90864
  try {
91044
90865
  store = openGraphStore2({ path: dbPath });
@@ -91203,13 +91024,13 @@ async function cmdInstallHooks(args2) {
91203
91024
  }
91204
91025
  }
91205
91026
  async function installOpencodePlugin(port) {
91206
- const { mkdirSync: mkdirSync11, existsSync: existsSync36, readFileSync: readFileSync37, writeFileSync: writeFileSync27 } = await import("node:fs");
91027
+ const { mkdirSync: mkdirSync11, existsSync: existsSync35, readFileSync: readFileSync36, writeFileSync: writeFileSync27 } = await import("node:fs");
91207
91028
  const { join: join44 } = await import("node:path");
91208
91029
  const dir = join44(ROOT, ".opencode", "plugin");
91209
- if (!existsSync36(dir)) mkdirSync11(dir, { recursive: true });
91030
+ if (!existsSync35(dir)) mkdirSync11(dir, { recursive: true });
91210
91031
  const file2 = join44(dir, "inerrata.js");
91211
- if (existsSync36(file2)) {
91212
- const head2 = readFileSync37(file2, "utf8").split("\n")[0] ?? "";
91032
+ if (existsSync35(file2)) {
91033
+ const head2 = readFileSync36(file2, "utf8").split("\n")[0] ?? "";
91213
91034
  if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
91214
91035
  console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
91215
91036
  process.exit(2);
@@ -91218,9 +91039,9 @@ async function installOpencodePlugin(port) {
91218
91039
  writeFileSync27(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
91219
91040
  const cfgFile = join44(ROOT, "opencode.json");
91220
91041
  let cfg = { $schema: "https://opencode.ai/config.json" };
91221
- if (existsSync36(cfgFile)) {
91042
+ if (existsSync35(cfgFile)) {
91222
91043
  try {
91223
- cfg = JSON.parse(readFileSync37(cfgFile, "utf8"));
91044
+ cfg = JSON.parse(readFileSync36(cfgFile, "utf8"));
91224
91045
  } catch {
91225
91046
  console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
91226
91047
  process.exit(2);
@@ -91250,23 +91071,16 @@ function errataMcpInvocation() {
91250
91071
  const { cmd: cmd2, args: args2 } = selfArgv("mcp");
91251
91072
  return { command: cmd2, args: args2 };
91252
91073
  }
91253
- function ensureStatusLine(port) {
91254
- try {
91255
- return describeStatusLineOutcome(ensureUserStatusLine({ port, relayDir: globalDir() }));
91256
- } catch (err2) {
91257
- return `status line: not installed (${err2 instanceof Error ? err2.message : err2})`;
91258
- }
91259
- }
91260
91074
  async function installClaudeHooks(port) {
91261
- const { mkdirSync: mkdirSync11, existsSync: existsSync36, readFileSync: readFileSync37, writeFileSync: writeFileSync27 } = await import("node:fs");
91075
+ const { mkdirSync: mkdirSync11, existsSync: existsSync35, readFileSync: readFileSync36, writeFileSync: writeFileSync27 } = await import("node:fs");
91262
91076
  const { join: join44 } = await import("node:path");
91263
91077
  const dir = join44(ROOT, ".claude");
91264
- if (!existsSync36(dir)) mkdirSync11(dir, { recursive: true });
91078
+ if (!existsSync35(dir)) mkdirSync11(dir, { recursive: true });
91265
91079
  const file2 = join44(dir, "settings.json");
91266
91080
  let settings = {};
91267
- if (existsSync36(file2)) {
91081
+ if (existsSync35(file2)) {
91268
91082
  try {
91269
- settings = JSON.parse(readFileSync37(file2, "utf8"));
91083
+ settings = JSON.parse(readFileSync36(file2, "utf8"));
91270
91084
  } catch {
91271
91085
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
91272
91086
  process.exit(2);
@@ -91313,10 +91127,18 @@ async function installClaudeHooks(port) {
91313
91127
  dropErrata(list);
91314
91128
  list.push({ hooks: [{ type: "command", command: injectCmd }] });
91315
91129
  }
91316
- removeProjectStatusLine(settings);
91130
+ const { homedir: homedir8 } = await import("node:os");
91131
+ let userStatusLine;
91132
+ try {
91133
+ userStatusLine = JSON.parse(readFileSync36(join44(homedir8(), ".claude", "settings.json"), "utf8"))["statusLine"];
91134
+ } catch {
91135
+ }
91136
+ const statusLineInstalled = (userStatusLine === void 0 || isErrataStatusLine(userStatusLine)) && installStatusLine(settings, ROOT, port);
91317
91137
  writeFileSync27(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
91318
91138
  console.log(`installed Claude Code hooks \u2192 ${file2}`);
91319
- console.log(` ${ensureStatusLine(port)}`);
91139
+ console.log(
91140
+ statusLineInstalled ? " status line: errata recall card in colour (daemon env ERRATA_RECALL_CARD=off hides the cards)" : " status line: kept your own \u2014 errata's recall card shows inline only"
91141
+ );
91320
91142
  await installClaudeMcpConfig();
91321
91143
  const claudeMd = join44(ROOT, "CLAUDE.md");
91322
91144
  const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
@@ -91330,15 +91152,15 @@ async function installClaudeHooks(port) {
91330
91152
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
91331
91153
  }
91332
91154
  async function installClaudeMcpConfig() {
91333
- const { mkdirSync: mkdirSync11, existsSync: existsSync36, readFileSync: readFileSync37, writeFileSync: writeFileSync27 } = await import("node:fs");
91334
- const { join: join44, dirname: dirname14 } = await import("node:path");
91155
+ const { mkdirSync: mkdirSync11, existsSync: existsSync35, readFileSync: readFileSync36, writeFileSync: writeFileSync27 } = await import("node:fs");
91156
+ const { join: join44, dirname: dirname13 } = await import("node:path");
91335
91157
  const file2 = join44(ROOT, ".mcp.json");
91336
- const dir = dirname14(file2);
91337
- if (!existsSync36(dir)) mkdirSync11(dir, { recursive: true });
91158
+ const dir = dirname13(file2);
91159
+ if (!existsSync35(dir)) mkdirSync11(dir, { recursive: true });
91338
91160
  let cfg = {};
91339
- if (existsSync36(file2)) {
91161
+ if (existsSync35(file2)) {
91340
91162
  try {
91341
- cfg = JSON.parse(readFileSync37(file2, "utf8"));
91163
+ cfg = JSON.parse(readFileSync36(file2, "utf8"));
91342
91164
  } catch {
91343
91165
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
91344
91166
  process.exit(2);
@@ -91352,15 +91174,15 @@ async function installClaudeMcpConfig() {
91352
91174
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
91353
91175
  }
91354
91176
  async function installCursorMcpConfig() {
91355
- const { mkdirSync: mkdirSync11, existsSync: existsSync36, readFileSync: readFileSync37, writeFileSync: writeFileSync27 } = await import("node:fs");
91177
+ const { mkdirSync: mkdirSync11, existsSync: existsSync35, readFileSync: readFileSync36, writeFileSync: writeFileSync27 } = await import("node:fs");
91356
91178
  const { join: join44 } = await import("node:path");
91357
91179
  const dir = join44(ROOT, ".cursor");
91358
- if (!existsSync36(dir)) mkdirSync11(dir, { recursive: true });
91180
+ if (!existsSync35(dir)) mkdirSync11(dir, { recursive: true });
91359
91181
  const file2 = join44(dir, "mcp.json");
91360
91182
  let cfg = {};
91361
- if (existsSync36(file2)) {
91183
+ if (existsSync35(file2)) {
91362
91184
  try {
91363
- cfg = JSON.parse(readFileSync37(file2, "utf8"));
91185
+ cfg = JSON.parse(readFileSync36(file2, "utf8"));
91364
91186
  } catch {
91365
91187
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
91366
91188
  process.exit(2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.8-dev.2929",
3
+ "version": "2.0.8",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -24519,12 +24519,6 @@ CREATE UNIQUE INDEX IF NOT EXISTS edges_triple ON edges(from_id, type, to_id);
24519
24519
  `;
24520
24520
  var TEMPORAL_INDEX_SQL = `
24521
24521
  CREATE INDEX IF NOT EXISTS nodes_live ON nodes(label, valid_to);
24522
- -- Covering + partial index for labelFingerprint over the instance labels: the
24523
- -- live-push probe runs it per workspace on a timer, and each hit used to read
24524
- -- its table row. Partial, so it maintains a few thousand rows instead of adding
24525
- -- a write to every node write. Its label list is FINGERPRINT_INDEXED_LABELS.
24526
- DROP INDEX IF EXISTS nodes_live_fingerprint;
24527
- CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause');
24528
24522
  CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
24529
24523
  CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
24530
24524
  -- Expression index on the per-node relPath (stored in attrs_json) so the
@@ -24595,7 +24589,6 @@ function rowToEdge(r) {
24595
24589
  attrs: JSON.parse(r.attrs_json)
24596
24590
  };
24597
24591
  }
24598
- var FINGERPRINT_INDEXED_LABELS = ["Problem", "Solution", "RootCause"];
24599
24592
  var SqliteGraphStore = class {
24600
24593
  db;
24601
24594
  // Typed edge lookups build their SQL from the number of types asked for, and
@@ -25072,32 +25065,6 @@ var SqliteGraphStore = class {
25072
25065
  attrs: JSON.parse(r.attrs_json)
25073
25066
  }));
25074
25067
  }
25075
- *iterateNodeIdentitiesByLabel(label, pageSize = 2e3) {
25076
- const page = this.db.prepare(
25077
- "SELECT rowid AS rid, id, json_extract(attrs_json, '$.relPath') AS relPath, json_extract(attrs_json, '$.qname') AS qname FROM nodes WHERE rowid > ? AND label = ? AND valid_to IS NULL ORDER BY rowid LIMIT ?"
25078
- );
25079
- let after = 0;
25080
- for (; ; ) {
25081
- const rows = page.all(after, label, pageSize);
25082
- for (const r of rows) {
25083
- yield {
25084
- id: r.id,
25085
- relPath: typeof r.relPath === "string" ? r.relPath : null,
25086
- qname: typeof r.qname === "string" ? r.qname : null
25087
- };
25088
- }
25089
- if (rows.length < pageSize) return;
25090
- after = rows[rows.length - 1].rid;
25091
- }
25092
- }
25093
- recentNodeIds(label, limit) {
25094
- const rows = this.db.prepare("SELECT id FROM nodes WHERE label = ? AND valid_to IS NULL ORDER BY last_updated_at DESC LIMIT ?").all(label, Math.max(0, limit));
25095
- return rows.map((r) => r.id);
25096
- }
25097
- hasLiveNodes() {
25098
- const r = this.db.prepare("SELECT EXISTS(SELECT 1 FROM nodes WHERE valid_to IS NULL) AS e").get();
25099
- return r.e === 1;
25100
- }
25101
25068
  findNodeIdentitiesByLabel(label) {
25102
25069
  const rows = this.stmts.identitiesByLabel.all(label);
25103
25070
  return rows.map((r) => ({
@@ -25245,15 +25212,6 @@ var SqliteGraphStore = class {
25245
25212
  }
25246
25213
  labelFingerprint(labels) {
25247
25214
  if (labels.length === 0) return "0";
25248
- if (labels.length === FINGERPRINT_INDEXED_LABELS.length && FINGERPRINT_INDEXED_LABELS.every((l) => labels.includes(l))) {
25249
- const r2 = this.db.prepare(
25250
- `SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
25251
- MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s
25252
- FROM nodes INDEXED BY nodes_instance_fingerprint
25253
- WHERE valid_to IS NULL AND label IN ('Problem','Solution','RootCause')`
25254
- ).get();
25255
- return `${r2.n}:${r2.t ?? 0}:${r2.s ?? 0}`;
25256
- }
25257
25215
  const r = this.db.prepare(
25258
25216
  `SELECT COUNT(*) AS n, MAX(last_updated_at) AS t,
25259
25217
  MAX(COALESCE(last_reinforced_at_seq, created_at_seq, 0)) AS s