@inerrata-corporation/errata 2.0.2-dev.125 → 2.0.2-dev.133

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.125",
3
+ "version": "2.0.2-dev.133",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -144,7 +144,14 @@ var init_castalia = __esm({
144
144
  "SOLVED_BY",
145
145
  "MITIGATES",
146
146
  "REPORTED_FAILURE",
147
- "CONTRADICTS"
147
+ "CONTRADICTS",
148
+ // Motif twin-faces (KN-twin-faces): failure-face motif → remedy-face motif
149
+ // across layers (AntiPattern/Weakness ↔ Technique/Pattern). Same
150
+ // problem→fix direction as FIXED_BY/SOLVED_BY. Minted by the nightly LLM
151
+ // twin-face pass — these are the near-identical cross-layer pairs the
152
+ // polarity gate (finding 5) correctly refuses to FUSE; the link carries
153
+ // what fusion can't.
154
+ "REMEDIED_BY"
148
155
  ];
149
156
  CONCEPTUAL_EDGES = [
150
157
  "INSTANCE_OF",
@@ -274,6 +281,10 @@ var init_castalia = __esm({
274
281
  CAUSED_BY: 3,
275
282
  FIXED_BY: 3,
276
283
  SOLVED_BY: 3,
284
+ // Twin-face link (failure motif → remedy motif, KN-twin-faces) — causal-grade
285
+ // but a notch below witnessed FIXED_BY/SOLVED_BY: the pairing is an LLM
286
+ // judgment over descriptions, not an agent-witnessed resolution.
287
+ REMEDIED_BY: 2.5,
277
288
  MANIFESTS_AS: 2,
278
289
  ESCALATES_TO: 1.5,
279
290
  AFFECTS: 1.2,
@@ -15159,6 +15170,15 @@ var init_wire = __esm({
15159
15170
  /** Canonical human-readable description (no raw paths — daemon scrubs; server rechecks). */
15160
15171
  description: external_exports.string().min(1).max(4e3),
15161
15172
  attrs: external_exports.record(external_exports.string(), external_exports.unknown()).default({}),
15173
+ /** One-way origin key of the SESSION that minted this node (`ws_…`, a
15174
+ * truncated digest — never the raw session id). Stamped onto the created
15175
+ * node as `authoringSession`, which is the independence unit for the
15176
+ * evidence channels: the session that authored a claim may not corroborate
15177
+ * or refute it, while a DIFFERENT session on the same checkout may (alyssa,
15178
+ * 2026-07-31 — the workspace key made every witness on a single-checkout
15179
+ * deployment a self-corroboration). Optional + additive: absent leaves the
15180
+ * gate fail-open for that node, exactly today's behaviour. */
15181
+ originSession: external_exports.string().min(3).max(64).optional(),
15162
15182
  extractionSource: external_exports.enum(INGEST_EXTRACTION_SOURCES),
15163
15183
  validationSource: external_exports.enum(VALIDATION_SOURCES).optional(),
15164
15184
  /** Org-membrane (M2): the daemon's anchor tag — it owns the lockfile, so it
@@ -25134,6 +25154,9 @@ function backfillProblemContext(store2, ts) {
25134
25154
  }
25135
25155
 
25136
25156
  // ../../packages/local-graph/src/design-problem.ts
25157
+ function isConstraintProblem(node) {
25158
+ return node.attrs["kind"] === "constraint";
25159
+ }
25137
25160
  function buildNode(id, label, description, ts, attrs) {
25138
25161
  return {
25139
25162
  id,
@@ -25189,6 +25212,7 @@ function priorsForFile(store2, relPath) {
25189
25212
  }
25190
25213
  if (!file2) return null;
25191
25214
  const openProblems = [];
25215
+ const constraints = [];
25192
25216
  const seenProblem = /* @__PURE__ */ new Set();
25193
25217
  const related = /* @__PURE__ */ new Map();
25194
25218
  for (const e of store2.inEdges(file2.id, ["ANCHORED_AT"])) {
@@ -25197,14 +25221,14 @@ function priorsForFile(store2, relPath) {
25197
25221
  if (n.label === "Problem") {
25198
25222
  if (!n.attrs["resolvedAt"] && !seenProblem.has(n.id)) {
25199
25223
  seenProblem.add(n.id);
25200
- openProblems.push(n);
25224
+ (isConstraintProblem(n) ? constraints : openProblems).push(n);
25201
25225
  }
25202
25226
  } else if (CITABLE_PRIOR_LABELS.has(n.label)) {
25203
25227
  related.set(n.id, n);
25204
25228
  }
25205
25229
  }
25206
25230
  const solutionsByProblem = /* @__PURE__ */ new Map();
25207
- for (const p of openProblems) {
25231
+ for (const p of [...openProblems, ...constraints]) {
25208
25232
  for (const e of store2.outEdges(p.id, ["SOLVED_BY", "CAUSED_BY", "INSTANCE_OF"])) {
25209
25233
  const n = store2.getNode(e.to);
25210
25234
  if (n && CITABLE_PRIOR_LABELS.has(n.label)) related.set(n.id, n);
@@ -25215,9 +25239,11 @@ function priorsForFile(store2, relPath) {
25215
25239
  }
25216
25240
  }
25217
25241
  }
25218
- if (openProblems.length === 0 && related.size === 0) return null;
25219
- openProblems.sort((a, b) => (b.lastUpdatedAt ?? 0) - (a.lastUpdatedAt ?? 0));
25220
- return { file: file2, openProblems, related: [...related.values()], solutionsByProblem };
25242
+ if (openProblems.length === 0 && constraints.length === 0 && related.size === 0) return null;
25243
+ const recentFirst = (a, b) => (b.lastUpdatedAt ?? 0) - (a.lastUpdatedAt ?? 0);
25244
+ openProblems.sort(recentFirst);
25245
+ constraints.sort(recentFirst);
25246
+ return { file: file2, openProblems, constraints, related: [...related.values()], solutionsByProblem };
25221
25247
  }
25222
25248
  function recordAnchorHint(store2, problemId, relPath, provenance, ts) {
25223
25249
  const p = store2.getNode(problemId);
@@ -25228,11 +25254,13 @@ function recordAnchorHint(store2, problemId, relPath, provenance, ts) {
25228
25254
  });
25229
25255
  return true;
25230
25256
  }
25257
+ var AUTO_MINT_PREFIX = "addressed by an edit to ";
25231
25258
  function resolveDesignProblems(store2, t) {
25232
25259
  let resolved = 0;
25233
25260
  for (const p of store2.findNodesByLabel("Problem")) {
25234
25261
  if (!p.id.startsWith("dprob_")) continue;
25235
25262
  if (p.attrs["resolvedAt"]) continue;
25263
+ if (isConstraintProblem(p)) continue;
25236
25264
  let symName = "";
25237
25265
  let symRelPath;
25238
25266
  let edited = false;
@@ -25250,7 +25278,7 @@ function resolveDesignProblems(store2, t) {
25250
25278
  if (store2.outEdges(p.id, ["SOLVED_BY"]).length === 0) {
25251
25279
  const solId = `dfix_${digest({ problemId: p.id, edit: t })}`.slice(0, 56);
25252
25280
  store2.mergeNode(
25253
- buildNode(solId, "Solution", `addressed by an edit to ${symName}`, t, {
25281
+ buildNode(solId, "Solution", `${AUTO_MINT_PREFIX}${symName}`, t, {
25254
25282
  source: "convo",
25255
25283
  provisional: false,
25256
25284
  // AC-resolution-attrs: the resolving symbol/file as STRUCTURED data, not
@@ -25273,7 +25301,6 @@ function resolveDesignProblems(store2, t) {
25273
25301
  }
25274
25302
 
25275
25303
  // ../../packages/local-graph/src/anchor-backfill.ts
25276
- var AUTO_MINT_PREFIX = "addressed by an edit to ";
25277
25304
  function isLegacyAnchor(attrs) {
25278
25305
  return attrs?.["captureTime"] === true && attrs["anchorProvenance"] === void 0;
25279
25306
  }
@@ -25720,6 +25747,7 @@ function mergeDuplicateProblems(store2, opts) {
25720
25747
  if (consumed.has(b.id)) continue;
25721
25748
  const tb = tokens.get(b.id);
25722
25749
  if (Math.min(ta.size, tb.size) < minTokens) continue;
25750
+ if (isConstraintProblem(a) !== isConstraintProblem(b)) continue;
25723
25751
  if (overlap(ta, tb) >= minOverlap) {
25724
25752
  cluster.push(b);
25725
25753
  consumed.add(b.id);
@@ -26052,12 +26080,14 @@ var AGENTS_POINTER_BODY = [
26052
26080
  init_src2();
26053
26081
  function buildSnapshot(opts) {
26054
26082
  const problems = opts.store.findNodesByLabel("Problem").filter((p) => p.attrs["mergedInto"] === void 0);
26055
- const allProblems = problems.filter((p) => p.attrs["resolvedAt"] == null);
26083
+ const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
26084
+ const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
26056
26085
  allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
26057
26086
  const recent = allProblems.slice(0, 8).map((p) => ({
26058
26087
  node: p,
26059
26088
  anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
26060
26089
  }));
26090
+ const recentConstraints = stillOpen.filter((p) => isConstraintProblem(p)).sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt).slice(0, 3);
26061
26091
  const recentResolved = problems.filter((p) => p.attrs["resolvedAt"] != null && p.attrs["resolvedAs"] == null).sort((a, b) => Number(b.attrs["resolvedAt"] ?? 0) - Number(a.attrs["resolvedAt"] ?? 0)).slice(0, 4).map((p) => {
26062
26092
  const solEdge = opts.store.outEdges(p.id, ["SOLVED_BY"])[0];
26063
26093
  const solution = solEdge ? opts.store.getNode(solEdge.to) ?? void 0 : void 0;
@@ -26085,10 +26115,13 @@ function buildSnapshot(opts) {
26085
26115
  episodeId,
26086
26116
  problems: problems2
26087
26117
  }));
26088
- const needsRevisit = listNeedsRevisit(
26089
- opts.store,
26090
- (opts.now ?? /* @__PURE__ */ new Date()).getTime()
26091
- ).slice(0, 10);
26118
+ const revisitSeen = /* @__PURE__ */ new Set();
26119
+ const needsRevisit = listNeedsRevisit(opts.store, (opts.now ?? /* @__PURE__ */ new Date()).getTime()).filter((r) => {
26120
+ const key = `${r.label}:${r.description.trim().toLowerCase()}`;
26121
+ if (revisitSeen.has(key)) return false;
26122
+ revisitSeen.add(key);
26123
+ return true;
26124
+ }).slice(0, 5);
26092
26125
  const norm = (x) => x.toLowerCase().replace(/[^a-z0-9]+/g, "");
26093
26126
  const pkgBase = (x) => {
26094
26127
  const at = x.lastIndexOf("@");
@@ -26124,6 +26157,7 @@ function buildSnapshot(opts) {
26124
26157
  profileContext,
26125
26158
  recentProblems: recent,
26126
26159
  recentResolved,
26160
+ recentConstraints,
26127
26161
  ...causalNudge ? { causalNudge } : {},
26128
26162
  ...domainNudge ? { domainNudge } : {},
26129
26163
  motifs,
@@ -26176,6 +26210,7 @@ function sliceForFile(store2, relPath) {
26176
26210
  const fp = priorsForFile(store2, relPath);
26177
26211
  const priors = fp ? {
26178
26212
  openProblems: fp.openProblems.slice(0, 3).map((p) => ({ id: p.id, description: p.description })),
26213
+ constraints: fp.constraints.slice(0, 2).map((c) => ({ id: c.id, description: c.description })),
26179
26214
  related: fp.related.slice(0, 4).map((n) => ({ id: n.id, label: n.label, description: n.description })),
26180
26215
  solutionsByProblem: Object.fromEntries(
26181
26216
  fp.openProblems.slice(0, 3).map((p) => [