@inerrata-corporation/errata 2.0.2-dev.627 → 2.0.2-dev.631

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 +101 -13
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -22579,7 +22579,7 @@ function renderSnapshot(s) {
22579
22579
  lines.push("");
22580
22580
  lines.push("### \u270D\uFE0F CAPTURE PROTOCOL \u2014 tags are the record");
22581
22581
  lines.push(
22582
- "errata records ONLY inline tags: `[!one line]` for every problem you state, `(fix:[id])` when your edit fixed a shown problem. Untagged prose is silently lost \u2014 tag as you write (no fences), we filter downstream."
22582
+ "errata records ONLY inline tags: `[!one line]` for every problem you state, `(fix:[id])` when your edit fixed a shown problem, and to JUDGE a prior shown below \u2014 `(confirm:[id])` if it held, `(refute:[id] why)` if it's wrong or didn't hold. Untagged prose is silently lost \u2014 tag as you write (no fences), we filter downstream."
22583
22583
  );
22584
22584
  lines.push("");
22585
22585
  lines.push(SEARCH_IMPERATIVE_HEADER);
@@ -26981,6 +26981,13 @@ function linkBullet(ref) {
26981
26981
  ` \xB7 your fix vs a shown solution: (builds-on:[${ref}]) \xB7 (supersedes:[${ref}]) \xB7 (alternative:[h]) \u2014 pick one`
26982
26982
  ].join("\n");
26983
26983
  }
26984
+ function verdictBullet(ref) {
26985
+ return [
26986
+ " \u2022 judge a prior we SHOWED you \u2014 a verdict on it, not a re-use of it; this is how a",
26987
+ ` shown prior earns or loses trust: ${TAG_EXAMPLE.confirm(ref)} if it held \xB7`,
26988
+ ` ${TAG_EXAMPLE.refute(ref)} if it's wrong or didn't hold (the reason is required)`
26989
+ ].join("\n");
26990
+ }
26984
26991
  function attemptBullet() {
26985
26992
  return [
26986
26993
  ` \u2022 attempting an approach / an attempt failed \u2192 ${TAG_EXAMPLE.tried()} \xB7`,
@@ -26991,13 +26998,13 @@ function attemptBullet() {
26991
26998
  function buildAgentInstruction(opts = {}) {
26992
26999
  const signals = opts.signals ?? ["prior", "problem", "domain", "fix", "constraint", "triage", "attempt", "link"];
26993
27000
  const ref = opts.referent ?? "its-handle";
26994
- const token = (s) => s === "problem" ? TAG_EXAMPLE.problem() : s === "constraint" ? TAG_EXAMPLE.constraint() : s === "attempt" ? TAG_EXAMPLE.tried() : s === "domain" ? TAG_EXAMPLE.domain() : s === "link" ? TAG_EXAMPLE.pattern() : TAG_EXAMPLE[s](ref);
27001
+ const token = (s) => s === "problem" ? TAG_EXAMPLE.problem() : s === "constraint" ? TAG_EXAMPLE.constraint() : s === "attempt" ? TAG_EXAMPLE.tried() : s === "domain" ? TAG_EXAMPLE.domain() : s === "link" ? TAG_EXAMPLE.pattern() : s === "verdict" ? TAG_EXAMPLE.confirm(ref) : TAG_EXAMPLE[s](ref);
26995
27002
  const head2 = `We tag the priors we show you with a short handle like [${opts.handleExample ?? "chokidar-glob"}]. Tags are the ONLY signal recorded \u2014 anything you state but don't tag is silently lost. Weave each tag inline in your prose as you state it (no fences or backticks, no extra calls); tag everything, we filter downstream:`;
26996
27003
  const tail = "Mid-turn text (between tool calls) can be dropped by the harness \u2014 RESTATE every tag in your turn-final message; the final message is what reliably survives \u2014 EXCEPT one already shown above with an id: that is captured, so cite `[its-handle]` rather than retyping it (drift mints a duplicate).";
26997
27004
  return [
26998
27005
  head2,
26999
27006
  ...signals.map(
27000
- (s) => s === "triage" ? triageBullet(ref) : s === "attempt" ? attemptBullet() : s === "link" ? linkBullet(ref) : ` \u2022 ${GLOSS[s]} \u2192 ${token(s)}`
27007
+ (s) => s === "triage" ? triageBullet(ref) : s === "attempt" ? attemptBullet() : s === "link" ? linkBullet(ref) : s === "verdict" ? verdictBullet(ref) : ` \u2022 ${GLOSS[s]} \u2192 ${token(s)}`
27001
27008
  ),
27002
27009
  tail
27003
27010
  ].join("\n");
@@ -27048,7 +27055,15 @@ var init_agent_signals = __esm({
27048
27055
  // knowledge can cross to the collective.
27049
27056
  package: () => `(package: the-package-name)`,
27050
27057
  component: () => `(component: The Component)`,
27051
- aids: (ref) => `(aids:[${ref}])`
27058
+ aids: (ref) => `(aids:[${ref}])`,
27059
+ // VERDICT (VS-verdict-tags) — a judgment on a SHOWN prior, distinct from leaning on it.
27060
+ // `confirm` rides the corroborate channel (it held); `refute` the contradict channel
27061
+ // (it's wrong / didn't hold) and REQUIRES a reason. This is the inline producer the
27062
+ // evidence channels lacked — refute sat dead (contradictionPressure 0) until now, while
27063
+ // lean-on corroboration lived, because only corroboration had an inline path. Grammar
27064
+ // single-sourced with parseInlineTags' CONFIRM_PREFIX/REFUTE_PREFIX.
27065
+ confirm: (ref) => `(confirm:[${ref}])`,
27066
+ refute: (ref) => `(refute:[${ref}] one line why)`
27052
27067
  };
27053
27068
  GLOSS = {
27054
27069
  prior: "a shown prior helped, or you work in a primed language/package",
@@ -27076,7 +27091,8 @@ var init_agent_signals = __esm({
27076
27091
  // clause; the pattern convergence hook now rides here too (it fell 0/4 when it
27077
27092
  // only appeared in the link bullet's tail).
27078
27093
  domain: "a problem with no single file \u2014 name the area it's about (Title Case). Also name the general shape it instantiates: (pattern: the shape) \u2014 needs no code anchor, and two agents naming the same shape converge on one node",
27079
- link: "the problem you flagged is an instance of priors/abstractions you can name \u2014 (instance:[h1],[h2],\u2026) / (pattern: \u2026) / (aids:[h]); rendered whole via linkBullet"
27094
+ link: "the problem you flagged is an instance of priors/abstractions you can name \u2014 (instance:[h1],[h2],\u2026) / (pattern: \u2026) / (aids:[h]); rendered whole via linkBullet",
27095
+ verdict: "you can judge a prior we SHOWED you \u2014 confirm it if it held, refute it (with why) if it didn't; rendered whole via verdictBullet"
27080
27096
  };
27081
27097
  }
27082
27098
  });
@@ -51970,6 +51986,9 @@ var BUILDS_ON_PREFIX = /^\s*builds-on:(?:#([a-z][\w-]{0,63}))?\s*/i;
51970
51986
  var SUPERSEDES_PREFIX = /^\s*supersedes:(?:#([a-z][\w-]{0,63}))?\s*/i;
51971
51987
  var ALTERNATIVE_PREFIX = /^\s*alternative:(?:#([a-z][\w-]{0,63}))?\s*/i;
51972
51988
  var INSTANCE_PREFIX = /^\s*instance:\s*/i;
51989
+ var CONFIRM_PREFIX = /^\s*confirm:\s*/i;
51990
+ var REFUTE_PREFIX = /^\s*refute:\s*/i;
51991
+ var REFUTE_REASON_MIN = 4;
51973
51992
  var PATTERN_RE = /\(\s*pattern:\s*([^()\n]{3,}?)\s*\)/gi;
51974
51993
  var DOMAIN_RE = /\(\s*domain:\s*([^()\n]{3,}?)\s*\)/gi;
51975
51994
  var PACKAGE_RE = /\(\s*package:\s*([^()\n]{2,}?)\s*\)/gi;
@@ -52014,7 +52033,7 @@ function parseInlineTags(text) {
52014
52033
  const seqStart = out2.length;
52015
52034
  const sentence = raw2.replace(
52016
52035
  /`[^`]*`/g,
52017
- (m) => /\[[!?]|\((?:fix|cause|constraint|tried|failed):|\(\[/.test(m) ? " " : m
52036
+ (m) => /\[[!?]|\((?:fix|cause|constraint|tried|failed|confirm|refute):|\(\[/.test(m) ? " " : m
52018
52037
  );
52019
52038
  const sfield = sentence.replace(/\s+/g, " ").trim().slice(0, 160);
52020
52039
  const citeMatched = /* @__PURE__ */ new Set();
@@ -52029,6 +52048,8 @@ function parseInlineTags(text) {
52029
52048
  const aidsM = fixM || causeM ? null : AIDS_PREFIX.exec(content);
52030
52049
  const instM = fixM || causeM || aidsM ? null : INSTANCE_PREFIX.exec(content);
52031
52050
  const ssM = fixM || causeM || aidsM || instM ? null : BUILDS_ON_PREFIX.exec(content) && { re: BUILDS_ON_PREFIX, kind: "builds-on" } || SUPERSEDES_PREFIX.exec(content) && { re: SUPERSEDES_PREFIX, kind: "supersedes" } || ALTERNATIVE_PREFIX.exec(content) && { re: ALTERNATIVE_PREFIX, kind: "alternative" };
52051
+ const confirmM = fixM || causeM || aidsM || instM || ssM ? null : CONFIRM_PREFIX.exec(content);
52052
+ const refuteM = fixM || causeM || aidsM || instM || ssM || confirmM ? null : REFUTE_PREFIX.exec(content);
52032
52053
  const isFix = fixM !== null;
52033
52054
  const isCause = causeM !== null;
52034
52055
  if (aidsM || instM || ssM) {
@@ -52054,6 +52075,21 @@ function parseInlineTags(text) {
52054
52075
  }
52055
52076
  continue;
52056
52077
  }
52078
+ if (confirmM || refuteM) {
52079
+ const body2 = content.replace(confirmM ? CONFIRM_PREFIX : REFUTE_PREFIX, "");
52080
+ HANDLE_RE.lastIndex = 0;
52081
+ const h2 = HANDLE_RE.exec(body2);
52082
+ const handle2 = h2 ? h2[1] ?? h2[2] : void 0;
52083
+ if (handle2) {
52084
+ if (refuteM) {
52085
+ const reason = body2.replace(new RegExp(HANDLE_RE.source, "gi"), " ").replace(/\s+/g, " ").trim();
52086
+ if (reason.length >= REFUTE_REASON_MIN) out2.push({ kind: "refute", handle: handle2, statement: reason, sentence: sfield });
52087
+ } else {
52088
+ out2.push({ kind: "confirm", handle: handle2, sentence: sfield });
52089
+ }
52090
+ }
52091
+ continue;
52092
+ }
52057
52093
  const verbThread = fixM?.[1] ?? causeM?.[1] ?? void 0;
52058
52094
  if (isFix) content = content.replace(FIX_PREFIX, "");
52059
52095
  else if (isCause) content = content.replace(CAUSE_PREFIX, "");
@@ -52604,6 +52640,27 @@ function harvestInlineTags(store, text, opts) {
52604
52640
  boundStatement: b.statement
52605
52641
  });
52606
52642
  }
52643
+ } else if (tag.kind === "confirm" || tag.kind === "refute") {
52644
+ const targetId = resolveHandle(store, tag.handle, opts.handleMap);
52645
+ const target = targetId ? store.getNode(targetId) : null;
52646
+ const citedLabel = target?.label ?? opts.handleMap[tag.handle]?.label;
52647
+ if (targetId && citedLabel && CORROBORATABLE_LABELS.has(citedLabel)) {
52648
+ if (tag.kind === "confirm") {
52649
+ const witnessKey = `corrob:${targetId}:confirm:${digest({ h: tag.handle })}`.slice(0, 72);
52650
+ if (!plan.corroborations.some((c) => c.witnessKey === witnessKey)) {
52651
+ const exposure = typeof store.currentIngestSeq === "function" ? priorExposure(store, targetId, store.currentIngestSeq()) : "unshown";
52652
+ if (exposure === "shown") plan.exposureShown++;
52653
+ else if (exposure === "evicted") plan.exposureEvicted++;
52654
+ else plan.exposureUnshown++;
52655
+ plan.corroborations.push({ nodeId: targetId, witnessKey, exposure });
52656
+ }
52657
+ } else {
52658
+ const witnessKey = `refute:${targetId}:${digest({ s: tag.statement ?? "" })}`.slice(0, 72);
52659
+ if (!plan.refutes.some((r) => r.witnessKey === witnessKey)) {
52660
+ plan.refutes.push({ nodeId: targetId, witnessKey });
52661
+ }
52662
+ }
52663
+ }
52607
52664
  } else if (tag.kind === "prior") {
52608
52665
  const targetId = resolveHandle(store, tag.handle, opts.handleMap);
52609
52666
  const target = targetId ? store.getNode(targetId) : null;
@@ -54800,7 +54857,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
54800
54857
  }
54801
54858
 
54802
54859
  // src/engine.ts
54803
- var DAEMON_VERSION = true ? "2.0.2-dev.627" : "2.0.0-alpha.0";
54860
+ var DAEMON_VERSION = true ? "2.0.2-dev.631" : "2.0.0-alpha.0";
54804
54861
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
54805
54862
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
54806
54863
  var GIT_OP_MUTE_MS = 4e3;
@@ -56009,9 +56066,14 @@ function createWorkspaceEngine(opts) {
56009
56066
  });
56010
56067
  };
56011
56068
  if (typeof cloud.reportContradictions === "function") {
56069
+ const emitRefutes = plan.refutes.filter((r) => !mintedHere(r.nodeId));
56070
+ const refuteSkipped = plan.refutes.length - emitRefutes.length;
56071
+ if (refuteSkipped > 0) {
56072
+ appendWitnessLedger(paths.configDir, { ts: Date.now(), channel: "contradict", clientSelfSkipped: refuteSkipped });
56073
+ }
56012
56074
  await sendWitnesses(
56013
56075
  "contradict",
56014
- plan.refutes,
56076
+ emitRefutes,
56015
56077
  (items2, session) => cloud.reportContradictions({
56016
56078
  daemonVersion: DAEMON_VERSION,
56017
56079
  projectId: profile.id,
@@ -57331,9 +57393,12 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
57331
57393
  if (outs.length === 0) continue;
57332
57394
  const dg = digest(outs.map(({ e, wireTo }) => `${e.type}>${wireTo}`).sort());
57333
57395
  const owner = store.getNode(sourceId) ?? opts.sharedStore?.getNode(sourceId);
57334
- if (owner?.attrs["semanticEdgesContributedDigest"] === dg) continue;
57335
- semanticEdgeDigests[sourceId] = dg;
57336
- for (const { e, wireTo } of outs) edges.push({ ...e, from: wireFrom, to: wireTo, attrs: {} });
57396
+ const digestSkip = owner?.attrs["semanticEdgesContributedDigest"] === dg;
57397
+ if (!digestSkip) semanticEdgeDigests[sourceId] = dg;
57398
+ for (const { e, wireTo } of outs) {
57399
+ if (digestSkip && !shippedById.has(e.to)) continue;
57400
+ edges.push({ ...e, from: wireFrom, to: wireTo, attrs: {} });
57401
+ }
57337
57402
  }
57338
57403
  if (nodes.length === 0 && anchorEdges.length === 0 && edges.length === 0) return null;
57339
57404
  let symbolSummaries;
@@ -57358,6 +57423,29 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
57358
57423
  if (count > 0) symbolSummaries = sidecar;
57359
57424
  }
57360
57425
  edges.push(...anchorEdges);
57426
+ const bindingEndpoints = /* @__PURE__ */ new Set();
57427
+ for (const e of edges) {
57428
+ if (e.type === "CAUSED_BY" || e.type === "SOLVED_BY") {
57429
+ bindingEndpoints.add(e.from);
57430
+ bindingEndpoints.add(e.to);
57431
+ }
57432
+ }
57433
+ const heldOrphans = /* @__PURE__ */ new Set();
57434
+ for (const wn of nodes) {
57435
+ if (wn.label !== "RootCause" && wn.label !== "Solution") continue;
57436
+ const src = store.getNode(wn.id) ?? opts.sharedStore?.getNode(wn.id);
57437
+ if (typeof src?.attrs["contributedAtSeq"] === "number") continue;
57438
+ if (bindingEndpoints.has(wn.id)) continue;
57439
+ heldOrphans.add(wn.id);
57440
+ }
57441
+ const shippableNodes = heldOrphans.size === 0 ? nodes : nodes.filter((n) => !heldOrphans.has(n.id));
57442
+ const shippableEdges = heldOrphans.size === 0 ? edges : edges.filter((e) => !heldOrphans.has(e.from) && !heldOrphans.has(e.to));
57443
+ if (heldOrphans.size > 0) {
57444
+ console.warn(
57445
+ `[errata] held ${heldOrphans.size} causal-orphan node(s) \u2014 no shippable binding edge this drain (VS-orphan-gate)`
57446
+ );
57447
+ }
57448
+ if (shippableNodes.length === 0 && shippableEdges.length === 0) return null;
57361
57449
  const base = {
57362
57450
  daemonVersion,
57363
57451
  // Origin key (= project, the salted `wp_…`) — the door stamps it onto created
@@ -57369,8 +57457,8 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
57369
57457
  // Context nodes FIRST: a chunked drain (cloud-client, 25-node chunks) then
57370
57458
  // co-locates the few Language/Package stubs with the first instance chunk,
57371
57459
  // maximizing in-payload endpoint resolution.
57372
- nodes: [...contextNodes, ...nodes],
57373
- edges,
57460
+ nodes: [...contextNodes, ...shippableNodes],
57461
+ edges: shippableEdges,
57374
57462
  // Spread-if-present: an absent sidecar keeps `base` — and therefore the
57375
57463
  // payloadDigest — byte-identical to the pre-sidecar batch (backward compat).
57376
57464
  ...symbolSummaries ? { symbolSummaries } : {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.627",
3
+ "version": "2.0.2-dev.631",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {