@inerrata-corporation/errata 2.0.2-dev.455 → 2.0.2-dev.477

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.
@@ -16688,6 +16688,9 @@ init_src();
16688
16688
  init_src();
16689
16689
  init_src();
16690
16690
 
16691
+ // ../../packages/local-graph/src/intent.ts
16692
+ init_src();
16693
+
16691
16694
  // ../../packages/local-graph/src/anchor-backfill.ts
16692
16695
  init_src();
16693
16696
  init_src2();
package/errata.mjs CHANGED
@@ -19272,6 +19272,31 @@ function markFixCandidates(store, t) {
19272
19272
  }
19273
19273
  return resolved;
19274
19274
  }
19275
+ function recordRenderLedger(store, ledger, seq, ts) {
19276
+ const bump = (ids, field) => {
19277
+ let n = 0;
19278
+ for (const id of new Set(ids.map((i2) => i2.id))) {
19279
+ const node2 = store.getNode(id);
19280
+ if (!node2) continue;
19281
+ const attrs = { ...node2.attrs };
19282
+ attrs[field] = (attrs[field] ?? 0) + 1;
19283
+ if (field === "shownCount") {
19284
+ attrs["lastShownAtSeq"] = seq;
19285
+ if (attrs["firstShownAtSeq"] === void 0) attrs["firstShownAtSeq"] = seq;
19286
+ }
19287
+ store.updateNode(id, { attrs, lastUpdatedAt: node2.lastUpdatedAt });
19288
+ n++;
19289
+ }
19290
+ return n;
19291
+ };
19292
+ let shown = 0;
19293
+ let evicted = 0;
19294
+ store.transaction(() => {
19295
+ shown = bump(ledger.shown, "shownCount");
19296
+ evicted = bump(ledger.evicted, "evictedCount");
19297
+ });
19298
+ return { shown, evicted };
19299
+ }
19275
19300
  var DESIGN_PROMOTE_AT, STATEMENT_ALIAS_CAP, PATTERN_DEDUP_COSINE, PATTERN_ALIAS_CAP, DEDUP_STOPWORDS, SAME_ANCHOR_DEDUP_JACCARD, CITABLE_PRIOR_LABELS, MAX_ANCHOR_FILES, AUTO_MINT_PREFIX;
19276
19301
  var init_design_problem = __esm({
19277
19302
  "../../packages/local-graph/src/design-problem.ts"() {
@@ -19322,6 +19347,61 @@ var init_design_problem = __esm({
19322
19347
  }
19323
19348
  });
19324
19349
 
19350
+ // ../../packages/local-graph/src/intent.ts
19351
+ function parseIntentFences(text) {
19352
+ const out2 = [];
19353
+ const block = /```errata-intent[^\n]*\n([\s\S]*?)```/g;
19354
+ let m;
19355
+ while ((m = block.exec(text)) !== null) {
19356
+ const lines = m[1].split(/\r?\n/);
19357
+ const parts2 = [];
19358
+ for (const line of lines) {
19359
+ const kv = /^\s*intent\s*:\s*(.+?)\s*$/i.exec(line);
19360
+ if (kv) parts2.push(kv[1].trim());
19361
+ else if (parts2.length > 0 && line.trim()) parts2.push(line.trim());
19362
+ }
19363
+ const intent = parts2.join(" ").trim();
19364
+ if (intent) out2.push({ intent });
19365
+ }
19366
+ return out2;
19367
+ }
19368
+ function searchByIntent(store, intent, opts) {
19369
+ const limit = opts?.limit ?? 5;
19370
+ const minCoverage = opts?.minCoverage ?? 0.25;
19371
+ const want = new Set(conceptTokens(intent));
19372
+ if (want.size < MIN_INTENT_TOKENS) return [];
19373
+ const hits = [];
19374
+ for (const label of RECALLABLE) {
19375
+ for (const node2 of store.findNodesByLabel(label)) {
19376
+ if (node2.attrs["mergedInto"] !== void 0) continue;
19377
+ if (label === "Problem" && node2.attrs["resolvedAt"] != null && !isConstraintProblem(node2)) {
19378
+ continue;
19379
+ }
19380
+ const bag = conceptTokens(node2.description ?? "");
19381
+ if (bag.length === 0) continue;
19382
+ const matched = bag.filter((t) => want.has(t));
19383
+ if (matched.length === 0) continue;
19384
+ const coverage = matched.length / want.size;
19385
+ if (coverage < minCoverage) continue;
19386
+ hits.push({ node: node2, coverage, matched });
19387
+ }
19388
+ }
19389
+ hits.sort(
19390
+ (a, b) => b.coverage - a.coverage || (a.node.description?.length ?? 0) - (b.node.description?.length ?? 0)
19391
+ );
19392
+ return hits.slice(0, limit);
19393
+ }
19394
+ var RECALLABLE, MIN_INTENT_TOKENS;
19395
+ var init_intent = __esm({
19396
+ "../../packages/local-graph/src/intent.ts"() {
19397
+ "use strict";
19398
+ init_src();
19399
+ init_design_problem();
19400
+ RECALLABLE = ["Problem", "Solution", "RootCause", "Pattern"];
19401
+ MIN_INTENT_TOKENS = 2;
19402
+ }
19403
+ });
19404
+
19325
19405
  // ../../packages/local-graph/src/anchor-backfill.ts
19326
19406
  function isLegacyAnchor(attrs) {
19327
19407
  return attrs?.["captureTime"] === true && attrs["anchorProvenance"] === void 0;
@@ -19329,6 +19409,7 @@ function isLegacyAnchor(attrs) {
19329
19409
  function repairLegacyAnchorsFromStatement(store, ts) {
19330
19410
  const report = {
19331
19411
  repaired: [],
19412
+ retiredGuesses: 0,
19332
19413
  noPathNamed: 0,
19333
19414
  pathUnknown: 0,
19334
19415
  alreadyCorrect: 0
@@ -19351,7 +19432,22 @@ function repairLegacyAnchorsFromStatement(store, ts) {
19351
19432
  const anchors = store.outEdges(p.id, ["ANCHORED_AT"]);
19352
19433
  const legacy = anchors.filter((e) => e.attrs?.["anchorProvenance"] === "legacy");
19353
19434
  if (legacy.length === 0) continue;
19354
- if (anchors.some((e) => e.attrs?.["anchorProvenance"] === "restated")) continue;
19435
+ const better = anchors.filter((e) => {
19436
+ const prov = e.attrs?.["anchorProvenance"];
19437
+ return prov === "restated" || prov === "witnessed" || prov === "edited";
19438
+ });
19439
+ if (better.length > 0) {
19440
+ const betterTargets = new Set(better.map((e) => e.to));
19441
+ let retired = 0;
19442
+ for (const e of legacy) {
19443
+ if (!betterTargets.has(e.to)) {
19444
+ store.closeEdge(e.id, ts);
19445
+ retired++;
19446
+ }
19447
+ }
19448
+ report.retiredGuesses += retired;
19449
+ continue;
19450
+ }
19355
19451
  const named = [...String(p.description ?? "").matchAll(STATEMENT_PATH_RE)].map((m) => m[0]);
19356
19452
  if (named.length === 0) {
19357
19453
  report.noPathNamed++;
@@ -19389,6 +19485,10 @@ function repairLegacyAnchorsFromStatement(store, ts) {
19389
19485
  restatedAt: ts
19390
19486
  }
19391
19487
  });
19488
+ for (const e of legacy) {
19489
+ if (e.to !== target.id) store.closeEdge(e.id, ts);
19490
+ }
19491
+ report.retiredGuesses += legacy.filter((e) => e.to !== target.id).length;
19392
19492
  report.repaired.push({
19393
19493
  problemId: p.id,
19394
19494
  problem: p.description,
@@ -21566,6 +21666,7 @@ __export(src_exports2, {
21566
21666
  JOINT_COMMUNITY_EDGES: () => JOINT_COMMUNITY_EDGES,
21567
21667
  JOINT_COMMUNITY_LABELS: () => JOINT_COMMUNITY_LABELS,
21568
21668
  MAX_ANCHOR_FILES: () => MAX_ANCHOR_FILES,
21669
+ MIN_INTENT_TOKENS: () => MIN_INTENT_TOKENS,
21569
21670
  PATTERN_DEDUP_COSINE: () => PATTERN_DEDUP_COSINE,
21570
21671
  PERCOLATING_DRIFT_EDGES: () => PERCOLATING_DRIFT_EDGES,
21571
21672
  PERCOLATING_EDGES: () => PERCOLATING_EDGES,
@@ -21638,6 +21739,7 @@ __export(src_exports2, {
21638
21739
  openGraphStore: () => openGraphStore,
21639
21740
  osNodeId: () => osNodeId,
21640
21741
  parseAbstractionFences: () => parseAbstractionFences,
21742
+ parseIntentFences: () => parseIntentFences,
21641
21743
  parseSemver: () => parseSemver,
21642
21744
  parseTriageFences: () => parseTriageFences,
21643
21745
  pendingAbstractions: () => pendingAbstractions,
@@ -21652,6 +21754,7 @@ __export(src_exports2, {
21652
21754
  recordCauseChainLink: () => recordCauseChainLink,
21653
21755
  recordClaim: () => recordClaim,
21654
21756
  recordMisreadPrior: () => recordMisreadPrior,
21757
+ recordRenderLedger: () => recordRenderLedger,
21655
21758
  recordTriageObservation: () => recordTriageObservation,
21656
21759
  reinforceSameAnchorProblem: () => reinforceSameAnchorProblem,
21657
21760
  relateClaims: () => relateClaims,
@@ -21664,6 +21767,7 @@ __export(src_exports2, {
21664
21767
  retractDesignProblemByStatement: () => retractDesignProblemByStatement,
21665
21768
  revisitContradictedPrinciples: () => revisitContradictedPrinciples,
21666
21769
  revisitStaleRoutes: () => revisitStaleRoutes,
21770
+ searchByIntent: () => searchByIntent,
21667
21771
  solutionForProblem: () => solutionForProblem,
21668
21772
  splittingAxis: () => splittingAxis,
21669
21773
  stampObservedOs: () => stampObservedOs,
@@ -21686,6 +21790,7 @@ var init_src5 = __esm({
21686
21790
  init_crystallize();
21687
21791
  init_aggregate();
21688
21792
  init_design_problem();
21793
+ init_intent();
21689
21794
  init_anchor_backfill();
21690
21795
  init_percolate();
21691
21796
  init_abstraction();
@@ -22183,14 +22288,42 @@ function assembleAgentContext(opts) {
22183
22288
  }
22184
22289
  snapshot.skills = [...snapshot.skills].sort((a, b) => b.confidence - a.confidence);
22185
22290
  const maxChars = opts.maxChars ?? DEFAULT_AGENT_CONTEXT_BUDGET;
22291
+ const candidates = snapshotImpressions(snapshot);
22186
22292
  const dropped = budgetSnapshot(snapshot, maxChars);
22293
+ const ledger = diffRenderLedger(candidates, snapshotImpressions(snapshot));
22187
22294
  let body2 = renderSnapshot(snapshot);
22188
22295
  if (dropped > 0) {
22189
22296
  body2 += `
22190
22297
 
22191
22298
  _${dropped} lower-priority item${dropped === 1 ? "" : "s"} omitted to fit the passive-context budget \u2014 the full graph is in the errata dashboard._`;
22192
22299
  }
22193
- return { body: body2, snapshot, dropped };
22300
+ return { body: body2, snapshot, dropped, ledger };
22301
+ }
22302
+ function snapshotImpressions(s) {
22303
+ const out2 = [];
22304
+ const push = (band, ids) => {
22305
+ for (const id of ids) if (id) out2.push({ id, band });
22306
+ };
22307
+ push("recentProblems", s.recentProblems.map((p) => p.node.id));
22308
+ push("recentResolved", s.recentResolved.map((r) => r.node.id));
22309
+ push("recentConstraints", s.recentConstraints.map((c) => c.id));
22310
+ push("motifs", s.motifs.map((m) => m.id));
22311
+ push("remote", (s.remote ?? []).map((r) => r.id));
22312
+ push("needsRevisit", s.needsRevisit.map((r) => r.id));
22313
+ push(
22314
+ "reviewItems",
22315
+ (s.reviewItems ?? []).map((r) => r.kind === "abstraction" ? r.candidate : r.route)
22316
+ );
22317
+ push("workingFile", s.workingFile?.priors?.openProblems.map((p) => p.id) ?? []);
22318
+ return out2;
22319
+ }
22320
+ function diffRenderLedger(before, after) {
22321
+ const key = (i2) => `${i2.band}\0${i2.id}`;
22322
+ const survived = new Set(after.map(key));
22323
+ const shown = [];
22324
+ const evicted = [];
22325
+ for (const i2 of before) (survived.has(key(i2)) ? shown : evicted).push(i2);
22326
+ return { shown, evicted };
22194
22327
  }
22195
22328
  var RECALL_FIRST_HEADER, RECALL_FIRST_BODY, RECALL_FIRST_BLOCK, SEARCH_IMPERATIVE_HEADER, SEARCH_IMPERATIVE_BODY, EVICTION_ORDER, MOTIF_FLOOR, REMOTE_FLOOR, PROBLEM_FLOOR, REVIEW_ITEM_FLOOR, DEFAULT_AGENT_CONTEXT_BUDGET;
22196
22329
  var init_render = __esm({
@@ -22204,7 +22337,7 @@ var init_render = __esm({
22204
22337
 
22205
22338
  ${RECALL_FIRST_BODY}`;
22206
22339
  SEARCH_IMPERATIVE_HEADER = "### \u{1F50E} PRIORS ARE SEEDS \u2014 a sample, not the whole graph";
22207
- SEARCH_IMPERATIVE_BODY = "Everything below is a budgeted, top-of-head slice of a much larger graph. Any prior id below is a live burst seed: `errata.burst` it (or read `.errata/g/burst/<id>`) to pull its wider neighborhood \u2014 causes, fixes, siblings. When a prior is adjacent-but-not-quite, or none fit, that gap is exactly when to search deeper before solving cold: a stuck search is itself a signal that routes help to you.";
22340
+ SEARCH_IMPERATIVE_BODY = "Everything below is a budgeted slice of a much larger graph, not all errata knows. Starting a piece of work? Say what it is \u2014 we search on it between your tool calls and put what we find here:\n```errata-intent\nintent: <the work in hand, in your words>\n```\nNarration, not a detour: no tool call, no plan change. It is the one signal we cannot derive from your edits \u2014 everything else here is guessed from the files you touched.";
22208
22341
  EVICTION_ORDER = [
22209
22342
  "skills",
22210
22343
  // Review items beyond the floor drop immediately after skills — one naming
@@ -53498,7 +53631,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
53498
53631
  }
53499
53632
 
53500
53633
  // src/engine.ts
53501
- var DAEMON_VERSION = true ? "2.0.2-dev.455" : "2.0.0-alpha.0";
53634
+ var DAEMON_VERSION = true ? "2.0.2-dev.477" : "2.0.0-alpha.0";
53502
53635
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
53503
53636
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
53504
53637
  var GIT_OP_MUTE_MS = 4e3;
@@ -53869,7 +54002,7 @@ function createWorkspaceEngine(opts) {
53869
54002
  const doneRender = prebuilt ? null : markPass(`context-render-inline:${profile.name}`);
53870
54003
  const pendingUpdate = opts.pendingUpdate?.() ?? null;
53871
54004
  const reviewItems = pickReviewItems();
53872
- const { body: body2, snapshot } = assembleAgentContext({
54005
+ const { body: body2, snapshot, ledger } = assembleAgentContext({
53873
54006
  store,
53874
54007
  ...snapOpts,
53875
54008
  remote: remotePriors,
@@ -53879,6 +54012,12 @@ function createWorkspaceEngine(opts) {
53879
54012
  ...reviewItems.length ? { reviewItems } : {}
53880
54013
  });
53881
54014
  doneRender?.();
54015
+ try {
54016
+ const seq = store.currentIngestSeq();
54017
+ recordRenderLedger(store, ledger, seq, Date.now());
54018
+ } catch (err2) {
54019
+ console.warn("[errata] render ledger failed:", err2.message?.slice(0, 120));
54020
+ }
53882
54021
  writeContextFile(opts.workspaceRoot, body2);
53883
54022
  const target = join26(opts.workspaceRoot, "AGENTS.md");
53884
54023
  writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.455",
3
+ "version": "2.0.2-dev.477",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -25555,6 +25555,9 @@ function markFixCandidates(store2, t) {
25555
25555
  return resolved;
25556
25556
  }
25557
25557
 
25558
+ // ../../packages/local-graph/src/intent.ts
25559
+ init_src();
25560
+
25558
25561
  // ../../packages/local-graph/src/anchor-backfill.ts
25559
25562
  init_src();
25560
25563
  init_src2();
@@ -25568,6 +25571,7 @@ var STATEMENT_PATH_RE = new RegExp(
25568
25571
  function repairLegacyAnchorsFromStatement(store2, ts) {
25569
25572
  const report = {
25570
25573
  repaired: [],
25574
+ retiredGuesses: 0,
25571
25575
  noPathNamed: 0,
25572
25576
  pathUnknown: 0,
25573
25577
  alreadyCorrect: 0
@@ -25590,7 +25594,22 @@ function repairLegacyAnchorsFromStatement(store2, ts) {
25590
25594
  const anchors = store2.outEdges(p.id, ["ANCHORED_AT"]);
25591
25595
  const legacy = anchors.filter((e) => e.attrs?.["anchorProvenance"] === "legacy");
25592
25596
  if (legacy.length === 0) continue;
25593
- if (anchors.some((e) => e.attrs?.["anchorProvenance"] === "restated")) continue;
25597
+ const better = anchors.filter((e) => {
25598
+ const prov = e.attrs?.["anchorProvenance"];
25599
+ return prov === "restated" || prov === "witnessed" || prov === "edited";
25600
+ });
25601
+ if (better.length > 0) {
25602
+ const betterTargets = new Set(better.map((e) => e.to));
25603
+ let retired = 0;
25604
+ for (const e of legacy) {
25605
+ if (!betterTargets.has(e.to)) {
25606
+ store2.closeEdge(e.id, ts);
25607
+ retired++;
25608
+ }
25609
+ }
25610
+ report.retiredGuesses += retired;
25611
+ continue;
25612
+ }
25594
25613
  const named = [...String(p.description ?? "").matchAll(STATEMENT_PATH_RE)].map((m) => m[0]);
25595
25614
  if (named.length === 0) {
25596
25615
  report.noPathNamed++;
@@ -25628,6 +25647,10 @@ function repairLegacyAnchorsFromStatement(store2, ts) {
25628
25647
  restatedAt: ts
25629
25648
  }
25630
25649
  });
25650
+ for (const e of legacy) {
25651
+ if (e.to !== target.id) store2.closeEdge(e.id, ts);
25652
+ }
25653
+ report.retiredGuesses += legacy.filter((e) => e.to !== target.id).length;
25631
25654
  report.repaired.push({
25632
25655
  problemId: p.id,
25633
25656
  problem: p.description,