@inerrata-corporation/errata 2.0.6-dev.2063 → 2.0.6-dev.2081
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/errata.mjs +80 -11
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -591,6 +591,15 @@ var init_graph_events = __esm({
|
|
|
591
591
|
prefixes: ["promotion."],
|
|
592
592
|
consumer: "graph-health.mjs promotion triggers (receipt-absence floor, kCountErrors > 0) + probe:mechanism-liveness reading the durable pgboss.job.output twin"
|
|
593
593
|
},
|
|
594
|
+
"graph.mergegate": {
|
|
595
|
+
// The nightly merge gate (reconcile Phase 2 claims + dream-merge), one
|
|
596
|
+
// event per nightly run: mergegate.<lane>.{merged,refused,truncated,...}.
|
|
597
|
+
// refused is the deferred-recovery backlog (pairs above threshold the
|
|
598
|
+
// judge or a veto kept apart), measured so the recovery follow-up starts
|
|
599
|
+
// from a number.
|
|
600
|
+
prefixes: ["mergegate."],
|
|
601
|
+
consumer: "graph-health.mjs 'Graph merge gate' triggers (truncation + refused backlog, pending a live baseline) beside ingest.judge.*"
|
|
602
|
+
},
|
|
594
603
|
"graph.census": {
|
|
595
604
|
prefixes: [
|
|
596
605
|
"nodes.",
|
|
@@ -77047,7 +77056,7 @@ function createWatchBreaker(deps) {
|
|
|
77047
77056
|
}
|
|
77048
77057
|
|
|
77049
77058
|
// src/engine.ts
|
|
77050
|
-
var DAEMON_VERSION = true ? "2.0.6-dev.
|
|
77059
|
+
var DAEMON_VERSION = true ? "2.0.6-dev.2081" : "2.0.0-alpha.0";
|
|
77051
77060
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
77052
77061
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
77053
77062
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -79774,6 +79783,13 @@ var SHIP_TERMINAL_REFUSALS = 3;
|
|
|
79774
79783
|
function refusalFingerprint(reason, description) {
|
|
79775
79784
|
return digest(`${reason}\0${description}`);
|
|
79776
79785
|
}
|
|
79786
|
+
function isRetryableRefusal(reason) {
|
|
79787
|
+
return /\bretry\b/i.test(reason);
|
|
79788
|
+
}
|
|
79789
|
+
function isTerminallyRefused(n) {
|
|
79790
|
+
const reason = String(n.attrs["shipRefusedReason"] ?? "");
|
|
79791
|
+
return typeof n.attrs["shipRefusedCount"] === "number" && n.attrs["shipRefusedCount"] >= SHIP_TERMINAL_REFUSALS && !isRetryableRefusal(reason) && n.attrs["shipRefusedFingerprint"] === refusalFingerprint(reason, n.description);
|
|
79792
|
+
}
|
|
79777
79793
|
function unshippableReason(canonical, label) {
|
|
79778
79794
|
void label;
|
|
79779
79795
|
if (canonical.length < WIRE_CANONICAL_ID_MIN) {
|
|
@@ -79926,10 +79942,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
79926
79942
|
composition.autoMint++;
|
|
79927
79943
|
continue;
|
|
79928
79944
|
}
|
|
79929
|
-
if (
|
|
79930
|
-
String(n.attrs["shipRefusedReason"] ?? ""),
|
|
79931
|
-
n.description
|
|
79932
|
-
)) {
|
|
79945
|
+
if (isTerminallyRefused(n)) {
|
|
79933
79946
|
composition.terminalRefused++;
|
|
79934
79947
|
continue;
|
|
79935
79948
|
}
|
|
@@ -80013,12 +80026,14 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
80013
80026
|
}
|
|
80014
80027
|
}
|
|
80015
80028
|
const project = opts.project;
|
|
80029
|
+
const projectAnchorDigests = {};
|
|
80016
80030
|
if (project) {
|
|
80017
80031
|
const now = Date.now();
|
|
80018
80032
|
for (const sourceId of anchorSources) {
|
|
80019
80033
|
const source = store.getNode(sourceId);
|
|
80020
80034
|
if (!source) continue;
|
|
80021
80035
|
const wireFrom = seen.has(sourceId) ? sourceId : contributedWireId(source);
|
|
80036
|
+
const planned = [];
|
|
80022
80037
|
for (const e of store.outEdges(sourceId, ["ANCHORED_AT"])) {
|
|
80023
80038
|
const target = store.getNode(e.to);
|
|
80024
80039
|
if (!target) continue;
|
|
@@ -80026,7 +80041,15 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
80026
80041
|
const qname = target.attrs["qname"];
|
|
80027
80042
|
if (typeof relPath !== "string" || typeof qname !== "string") continue;
|
|
80028
80043
|
if (ignored(relPath) || ignored(qname)) continue;
|
|
80029
|
-
|
|
80044
|
+
planned.push({ e, target, symId: projectSymbolId(project.salt, project.projectId, relPath, qname, target.label) });
|
|
80045
|
+
}
|
|
80046
|
+
if (planned.length === 0) continue;
|
|
80047
|
+
const dg = digest(
|
|
80048
|
+
planned.map(({ e, symId }) => `ANCHORED_AT>${symId}>${JSON.stringify(anchorVersionAttrs(e.attrs))}`).sort()
|
|
80049
|
+
);
|
|
80050
|
+
if (source.attrs["projectAnchorsContributedDigest"] === dg) continue;
|
|
80051
|
+
projectAnchorDigests[sourceId] = dg;
|
|
80052
|
+
for (const { e, target, symId } of planned) {
|
|
80030
80053
|
if (!contextSeen.has(symId)) {
|
|
80031
80054
|
contextSeen.add(symId);
|
|
80032
80055
|
contextNodes.push({
|
|
@@ -80133,6 +80156,11 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
80133
80156
|
}
|
|
80134
80157
|
const shippableNodes = heldOrphans.size === 0 ? nodes : nodes.filter((n) => !heldOrphans.has(n.id));
|
|
80135
80158
|
const shippableEdges = heldOrphans.size === 0 ? edges : edges.filter((e) => !heldOrphans.has(e.from) && !heldOrphans.has(e.to));
|
|
80159
|
+
for (const id of heldOrphans) {
|
|
80160
|
+
delete anchorDigests[id];
|
|
80161
|
+
delete semanticEdgeDigests[id];
|
|
80162
|
+
delete projectAnchorDigests[id];
|
|
80163
|
+
}
|
|
80136
80164
|
if (heldOrphans.size > 0) {
|
|
80137
80165
|
console.warn(
|
|
80138
80166
|
`[errata] held ${heldOrphans.size} causal-orphan node(s) \u2014 no shippable binding edge this drain (VS-orphan-gate)`
|
|
@@ -80162,7 +80190,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
80162
80190
|
...symbolSummaries ? { symbolSummaries } : {}
|
|
80163
80191
|
};
|
|
80164
80192
|
opts.onComposition?.(composition);
|
|
80165
|
-
return { ...base, payloadDigest: digest(base), anchorDigests, semanticEdgeDigests, composition };
|
|
80193
|
+
return { ...base, payloadDigest: digest(base), anchorDigests, semanticEdgeDigests, projectAnchorDigests, composition };
|
|
80166
80194
|
}
|
|
80167
80195
|
|
|
80168
80196
|
// src/backfill-edges.ts
|
|
@@ -84316,7 +84344,8 @@ async function startMultiDaemon(opts = {}) {
|
|
|
84316
84344
|
// Same shape as the drained row: a first/last trend reading must not
|
|
84317
84345
|
// straddle rows where the counter is merely absent.
|
|
84318
84346
|
blockedRepeat: 0,
|
|
84319
|
-
rejectedRepeat: 0
|
|
84347
|
+
rejectedRepeat: 0,
|
|
84348
|
+
edgesRejected: 0
|
|
84320
84349
|
});
|
|
84321
84350
|
}
|
|
84322
84351
|
if (instances) {
|
|
@@ -84344,6 +84373,17 @@ async function startMultiDaemon(opts = {}) {
|
|
|
84344
84373
|
for (const rn of res.result.nodes) {
|
|
84345
84374
|
if (rn.decision === "rejected") rejected.set(rn.canonicalId, rn.reason ?? "no reason given");
|
|
84346
84375
|
}
|
|
84376
|
+
const rejectedEdges = res.result.edges.filter((re) => re.decision === "rejected");
|
|
84377
|
+
if (rejectedEdges.length > 0) {
|
|
84378
|
+
const byReason = /* @__PURE__ */ new Map();
|
|
84379
|
+
for (const re of rejectedEdges) {
|
|
84380
|
+
const why = `${re.type}: ${re.reason ?? "no reason given"}`;
|
|
84381
|
+
byReason.set(why, (byReason.get(why) ?? 0) + 1);
|
|
84382
|
+
}
|
|
84383
|
+
console.warn(
|
|
84384
|
+
`[sync\u2192cloud] [${projectName}] instances: ${rejectedEdges.length} edge(s) REJECTED by the door: ` + [...byReason.entries()].map(([why, n]) => `${n}\xD7 ${why}`).join(" | ")
|
|
84385
|
+
);
|
|
84386
|
+
}
|
|
84347
84387
|
if (rejected.size > 0) {
|
|
84348
84388
|
const sample = [...rejected.entries()].slice(0, 3).map(([id, why]) => `${store.getNode(id)?.description.slice(0, 60) ?? id}: ${why}`);
|
|
84349
84389
|
console.warn(
|
|
@@ -84359,6 +84399,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
84359
84399
|
};
|
|
84360
84400
|
let blockedRepeat = 0;
|
|
84361
84401
|
let rejectedRepeat = 0;
|
|
84402
|
+
const nowHeld = [];
|
|
84362
84403
|
const noteRefused = (id, reason, repeat) => {
|
|
84363
84404
|
const owner = owningStore(id);
|
|
84364
84405
|
if (!owner) return;
|
|
@@ -84375,9 +84416,17 @@ async function startMultiDaemon(opts = {}) {
|
|
|
84375
84416
|
shipRefusedFingerprint: fp
|
|
84376
84417
|
}
|
|
84377
84418
|
});
|
|
84419
|
+
if (same && count === SHIP_TERMINAL_REFUSALS && !isRetryableRefusal(reason)) {
|
|
84420
|
+
nowHeld.push({ id, reason });
|
|
84421
|
+
}
|
|
84378
84422
|
};
|
|
84379
84423
|
for (const id of blocked) noteRefused(id, "blocked", () => blockedRepeat++);
|
|
84380
84424
|
for (const [id, why] of rejected) noteRefused(id, why, () => rejectedRepeat++);
|
|
84425
|
+
if (nowHeld.length > 0) {
|
|
84426
|
+
console.warn(
|
|
84427
|
+
`[sync\u2192cloud] [${projectName}] instances: HOLDING ${nowHeld.length} node(s) \u2014 refused identically ${SHIP_TERMINAL_REFUSALS}\xD7 on unchanged text; not re-sent until the text changes: ` + nowHeld.map(({ id, reason }) => `${id} "${owningStore(id)?.n.description.slice(0, 60) ?? ""}": ${reason}`).join(" | ")
|
|
84428
|
+
);
|
|
84429
|
+
}
|
|
84381
84430
|
for (const n of instances.nodes) {
|
|
84382
84431
|
const owner = owningStore(n.id);
|
|
84383
84432
|
if (!owner || !["Problem", "Solution", "RootCause"].includes(owner.n.label)) continue;
|
|
@@ -84407,6 +84456,14 @@ async function startMultiDaemon(opts = {}) {
|
|
|
84407
84456
|
attrs: { ...owner.n.attrs, anchorsContributedDigest: dg }
|
|
84408
84457
|
});
|
|
84409
84458
|
}
|
|
84459
|
+
for (const [localId, dg] of Object.entries(instances.projectAnchorDigests)) {
|
|
84460
|
+
const owner = owningStore(localId);
|
|
84461
|
+
if (!owner) continue;
|
|
84462
|
+
if (rejected.has(localId) || blocked.has(localId)) continue;
|
|
84463
|
+
owner.s.updateNode(localId, {
|
|
84464
|
+
attrs: { ...owner.n.attrs, projectAnchorsContributedDigest: dg }
|
|
84465
|
+
});
|
|
84466
|
+
}
|
|
84410
84467
|
for (const [localId, dg] of Object.entries(instances.semanticEdgeDigests)) {
|
|
84411
84468
|
const owner = owningStore(localId);
|
|
84412
84469
|
if (!owner) continue;
|
|
@@ -84425,7 +84482,8 @@ async function startMultiDaemon(opts = {}) {
|
|
|
84425
84482
|
// node; flat at 1 with `blockedRepeat` 0 is a different node
|
|
84426
84483
|
// failing every pass. Same total, different bug.
|
|
84427
84484
|
blockedRepeat,
|
|
84428
|
-
rejectedRepeat
|
|
84485
|
+
rejectedRepeat,
|
|
84486
|
+
edgesRejected: rejectedEdges.length
|
|
84429
84487
|
});
|
|
84430
84488
|
return res.accepted;
|
|
84431
84489
|
});
|
|
@@ -85762,15 +85820,26 @@ async function cmdStatus() {
|
|
|
85762
85820
|
try {
|
|
85763
85821
|
let pending = 0;
|
|
85764
85822
|
let total = 0;
|
|
85823
|
+
let heldRefused = 0;
|
|
85824
|
+
let autoMint = 0;
|
|
85765
85825
|
for (const label of ["Problem", "Solution", "RootCause"]) {
|
|
85766
85826
|
for (const n of store.findNodesByLabel(label)) {
|
|
85767
85827
|
if (n.attrs["source"] === "cloud") continue;
|
|
85768
85828
|
total++;
|
|
85769
85829
|
const c = n.attrs["contributedAtSeq"];
|
|
85770
|
-
if (typeof c
|
|
85830
|
+
if (typeof c === "number" && (n.lastReinforcedAtSeq ?? 0) <= c) continue;
|
|
85831
|
+
if (label === "Solution" && n.description.startsWith(AUTO_MINT_PREFIX)) autoMint++;
|
|
85832
|
+
else if (isTerminallyRefused(n)) heldRefused++;
|
|
85833
|
+
else pending++;
|
|
85771
85834
|
}
|
|
85772
85835
|
}
|
|
85773
|
-
|
|
85836
|
+
const held = [
|
|
85837
|
+
...heldRefused > 0 ? [`${heldRefused} held after identical door refusals`] : [],
|
|
85838
|
+
...autoMint > 0 ? [`${autoMint} auto-close marker(s) that never ship`] : []
|
|
85839
|
+
];
|
|
85840
|
+
console.log(
|
|
85841
|
+
` contribute: ${pending} pending of ${total} instance node(s)${held.length > 0 ? ` \xB7 ${held.join(" \xB7 ")}` : ""}`
|
|
85842
|
+
);
|
|
85774
85843
|
const rejections = store.edgeRejections();
|
|
85775
85844
|
if (rejections.length > 0) {
|
|
85776
85845
|
const refused = rejections.reduce((n, r) => n + r.count, 0);
|