@inerrata-corporation/errata 2.0.22-dev.4128 → 2.0.22-dev.4135
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/consolidate-worker.mjs
CHANGED
|
@@ -17702,14 +17702,16 @@ var SqliteGraphStore = class {
|
|
|
17702
17702
|
findNodeStampsByLabel(label, attrKey) {
|
|
17703
17703
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
|
|
17704
17704
|
const rows = this.db.prepare(
|
|
17705
|
-
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
|
|
17705
|
+
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has,
|
|
17706
|
+
COALESCE(json_extract(attrs_json, '$.source') = 'cloud', 0) AS cloud
|
|
17706
17707
|
FROM nodes WHERE label = ? AND valid_to IS NULL`
|
|
17707
17708
|
).all(label);
|
|
17708
17709
|
return rows.map((r) => ({
|
|
17709
17710
|
id: r.id,
|
|
17710
17711
|
createdAt: r.created_at,
|
|
17711
17712
|
...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
|
|
17712
|
-
has: r.has === 1
|
|
17713
|
+
has: r.has === 1,
|
|
17714
|
+
cloud: r.cloud === 1
|
|
17713
17715
|
}));
|
|
17714
17716
|
}
|
|
17715
17717
|
findNodeAttrsByLabel(label) {
|
|
@@ -19764,7 +19766,14 @@ function summaryFromDoc(doc, kind) {
|
|
|
19764
19766
|
}
|
|
19765
19767
|
if (verb !== null) return null;
|
|
19766
19768
|
const noun = clipped.replace(/^(?:the|a|an)\s+/i, "");
|
|
19767
|
-
|
|
19769
|
+
const head = noun.split(/[\s-]/, 1)[0].replace(/[.,;:!?]+$/, "");
|
|
19770
|
+
return tidy(`${lead(kind)} for ${isOrdinaryCapital(head) ? noun.charAt(0).toLowerCase() + noun.slice(1) : noun}`);
|
|
19771
|
+
}
|
|
19772
|
+
var CONTRACTION_BASES = /* @__PURE__ */ new Set(["it", "that", "this", "there", "here", "what", "who", "where", "when", "why", "how", "let", "he", "she"]);
|
|
19773
|
+
function isOrdinaryCapital(word) {
|
|
19774
|
+
const contraction = /^([A-Za-z]+)['’]s$/.exec(word);
|
|
19775
|
+
if (contraction) return CONTRACTION_BASES.has(contraction[1].toLowerCase()) && /^[A-Z][a-z]*$/.test(contraction[1]);
|
|
19776
|
+
return /^[A-Z][a-z]+$/.test(word);
|
|
19768
19777
|
}
|
|
19769
19778
|
var VERB_PHRASE_KINDS = /* @__PURE__ */ new Set(["function", "method"]);
|
|
19770
19779
|
function summaryFromName(name, kind) {
|
package/errata.mjs
CHANGED
|
@@ -20458,14 +20458,16 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
|
|
|
20458
20458
|
findNodeStampsByLabel(label, attrKey) {
|
|
20459
20459
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
|
|
20460
20460
|
const rows = this.db.prepare(
|
|
20461
|
-
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
|
|
20461
|
+
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has,
|
|
20462
|
+
COALESCE(json_extract(attrs_json, '$.source') = 'cloud', 0) AS cloud
|
|
20462
20463
|
FROM nodes WHERE label = ? AND valid_to IS NULL`
|
|
20463
20464
|
).all(label);
|
|
20464
20465
|
return rows.map((r) => ({
|
|
20465
20466
|
id: r.id,
|
|
20466
20467
|
createdAt: r.created_at,
|
|
20467
20468
|
...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
|
|
20468
|
-
has: r.has === 1
|
|
20469
|
+
has: r.has === 1,
|
|
20470
|
+
cloud: r.cloud === 1
|
|
20469
20471
|
}));
|
|
20470
20472
|
}
|
|
20471
20473
|
findNodeAttrsByLabel(label) {
|
|
@@ -25748,7 +25750,9 @@ function evaluateFed(store, d) {
|
|
|
25748
25750
|
if (!d.fed) return { count: 0, total: 0, fraction: 0 };
|
|
25749
25751
|
const column2 = COLUMN_INPUTS[d.fed.attr];
|
|
25750
25752
|
const fed = d.fed;
|
|
25751
|
-
const
|
|
25753
|
+
const all = fed.labels.flatMap((label) => store.findNodeStampsByLabel ? store.findNodeStampsByLabel(label, fed.attr) : store.findNodeAttrsByLabel(label));
|
|
25754
|
+
const isCloudMirror = (n) => n.cloud ?? n.attrs?.["source"] === "cloud";
|
|
25755
|
+
const nodes = fed.localOnly ? all.filter((n) => !isCloudMirror(n)) : all;
|
|
25752
25756
|
const has = (n) => column2 ? column2(n) : n.has ?? n.attrs?.[fed.attr] !== void 0;
|
|
25753
25757
|
let window2 = nodes;
|
|
25754
25758
|
if (fed.recent !== void 0) {
|
|
@@ -25764,6 +25768,11 @@ function evaluateFed(store, d) {
|
|
|
25764
25768
|
return { count, total: window2.length, fraction: window2.length === 0 ? 0 : count / window2.length };
|
|
25765
25769
|
}
|
|
25766
25770
|
function evaluateMechanisms(store, invocations = /* @__PURE__ */ new Map(), mechanisms = MECHANISMS) {
|
|
25771
|
+
const counts = /* @__PURE__ */ new Map();
|
|
25772
|
+
const count = (label) => {
|
|
25773
|
+
if (!counts.has(label)) counts.set(label, store.countNodesByLabel(label));
|
|
25774
|
+
return counts.get(label);
|
|
25775
|
+
};
|
|
25767
25776
|
return mechanisms.map((d) => {
|
|
25768
25777
|
const fed = evaluateFed(store, d);
|
|
25769
25778
|
const inv = invocations.get(d.pass);
|
|
@@ -25776,8 +25785,11 @@ function evaluateMechanisms(store, invocations = /* @__PURE__ */ new Map(), mech
|
|
|
25776
25785
|
const span = inv?.firstTs === void 0 ? 0 : inv.lastTs - inv.firstTs;
|
|
25777
25786
|
const stalled = backlog !== void 0 && backlog > 0 && effectCount === 0 && (inv?.runs ?? 0) >= STALL_MIN_RUNS && span >= STALL_MIN_SPAN_MS && (backlogWas === void 0 || backlog >= backlogWas);
|
|
25778
25787
|
let verdict;
|
|
25779
|
-
|
|
25780
|
-
|
|
25788
|
+
const hasInput = fed.total > 0 || Boolean(d.fed?.sinceFirstStamp && d.fed.labels.some((label) => count(label) > 0));
|
|
25789
|
+
const missingRequiredNodes = d.requiresNodes?.some((label) => count(label) === 0) ?? false;
|
|
25790
|
+
if (d.configCounter && inv?.lastTotals?.[d.configCounter] === 0) verdict = "unconfigured";
|
|
25791
|
+
else if ((backlog ?? 0) === 0 && (!hasInput && !d.inputOptional || missingRequiredNodes)) verdict = "no-input";
|
|
25792
|
+
else if (!inv || inv.runs === 0) verdict = "never-invoked";
|
|
25781
25793
|
else if (fed.fraction < (d.fedEdges?.minFraction ?? d.fed?.minFraction ?? 0)) verdict = "starved";
|
|
25782
25794
|
else if (stalled) verdict = "stalled";
|
|
25783
25795
|
else if (effectCount === 0) verdict = "no-effect";
|
|
@@ -25805,11 +25817,11 @@ function formatMechanismStatus(rows, nowMs) {
|
|
|
25805
25817
|
return rows.map((r) => {
|
|
25806
25818
|
const pct = (r.fedFraction * 100).toFixed(r.fedFraction < 0.01 ? 2 : 1);
|
|
25807
25819
|
const age = r.lastInvokedMs === void 0 ? "never" : `${Math.max(0, Math.round((nowMs - r.lastInvokedMs) / 6e4))}m ago`;
|
|
25808
|
-
const mark = r.verdict === "ok" ? "ok " : r.verdict === "no-effect" ? "IDLE" : r.verdict === "unconfigured" ? "OFF" : r.verdict === "stalled" ? "STUCK" : "DEAD";
|
|
25820
|
+
const mark = r.verdict === "ok" ? "ok " : r.verdict === "no-effect" ? "IDLE" : r.verdict === "no-input" ? "WAIT" : r.verdict === "unconfigured" ? "OFF" : r.verdict === "stalled" ? "STUCK" : "DEAD";
|
|
25809
25821
|
const hours = r.spanMs === void 0 ? 0 : Math.floor(r.spanMs / 36e5);
|
|
25810
25822
|
const over = hours >= 24 ? `${Math.floor(hours / 24)}d` : `${hours}h`;
|
|
25811
25823
|
const trend = r.verdict === "stalled" && r.backlog !== void 0 ? ` \u2014 ${r.backlog} waiting${r.backlogWas !== void 0 ? ` (was ${r.backlogWas})` : ""}, none cleared in ${over}` : "";
|
|
25812
|
-
return `${mark.padEnd(6)}${r.id.padEnd(20)} invoked ${age.padEnd(9)} ` + `fed ${pct}% (${r.fedCount}/${r.fedTotal})`.padEnd(28) + `effect ${r.effectCount}` + trend + (r.verdict !== "ok" && r.note ? ` \u2014 ${r.note}` : "");
|
|
25824
|
+
return `${mark.padEnd(6)}${r.id.padEnd(20)} invoked ${age.padEnd(9)} ` + `fed ${pct}% (${r.fedCount}/${r.fedTotal})`.padEnd(28) + `effect ${r.effectCount}` + trend + (r.verdict === "no-input" ? " \u2014 no eligible input yet" : r.verdict !== "ok" && r.note ? ` \u2014 ${r.note}` : "");
|
|
25813
25825
|
});
|
|
25814
25826
|
}
|
|
25815
25827
|
function hasStarvedMechanism(rows) {
|
|
@@ -25870,6 +25882,7 @@ var init_mechanism_liveness = __esm({
|
|
|
25870
25882
|
},
|
|
25871
25883
|
{
|
|
25872
25884
|
id: "fix-candidate-ask",
|
|
25885
|
+
requiresNodes: ["Problem"],
|
|
25873
25886
|
what: "asks an agent whether an edit to a problem's anchor fixed it",
|
|
25874
25887
|
pass: "semantic-maintenance",
|
|
25875
25888
|
// markFixCandidates fails CLOSED on a File anchor with no contentChangedAt —
|
|
@@ -25921,7 +25934,12 @@ var init_mechanism_liveness = __esm({
|
|
|
25921
25934
|
// the producer was verifiably stamping every new node.
|
|
25922
25935
|
minFraction: 0.9,
|
|
25923
25936
|
recent: 200,
|
|
25924
|
-
sinceFirstStamp: true
|
|
25937
|
+
sinceFirstStamp: true,
|
|
25938
|
+
// The anchor-feed pull lands cloud mirrors by the hundreds every ten
|
|
25939
|
+
// minutes (createdAt = pull time, no local seq — stamping them would age
|
|
25940
|
+
// every local node by Δseq). On 2026-10-09 1,146 mirrors in a few hours
|
|
25941
|
+
// dragged this to 62% and toasted "ingest-sequence DEAD" with effect 41.
|
|
25942
|
+
localOnly: true
|
|
25925
25943
|
},
|
|
25926
25944
|
effectCounter: "seqAdvanced",
|
|
25927
25945
|
note: "column, not attr; measured over nodes born since the first stamp in the recent window"
|
|
@@ -26066,6 +26084,7 @@ var init_mechanism_liveness = __esm({
|
|
|
26066
26084
|
},
|
|
26067
26085
|
{
|
|
26068
26086
|
id: "liveness-watch",
|
|
26087
|
+
inputOptional: true,
|
|
26069
26088
|
what: "the daemon-side schedule of this very verdict \u2014 alarms when a mechanism stops working",
|
|
26070
26089
|
// The watcher is itself a row: a probe that only runs when a human remembers
|
|
26071
26090
|
// is how the original six defects shipped, and a scheduled watch that
|
|
@@ -35534,7 +35553,13 @@ function summaryFromDoc(doc, kind) {
|
|
|
35534
35553
|
}
|
|
35535
35554
|
if (verb !== null) return null;
|
|
35536
35555
|
const noun = clipped.replace(/^(?:the|a|an)\s+/i, "");
|
|
35537
|
-
|
|
35556
|
+
const head2 = noun.split(/[\s-]/, 1)[0].replace(/[.,;:!?]+$/, "");
|
|
35557
|
+
return tidy(`${lead(kind)} for ${isOrdinaryCapital(head2) ? noun.charAt(0).toLowerCase() + noun.slice(1) : noun}`);
|
|
35558
|
+
}
|
|
35559
|
+
function isOrdinaryCapital(word) {
|
|
35560
|
+
const contraction = /^([A-Za-z]+)['’]s$/.exec(word);
|
|
35561
|
+
if (contraction) return CONTRACTION_BASES.has(contraction[1].toLowerCase()) && /^[A-Z][a-z]*$/.test(contraction[1]);
|
|
35562
|
+
return /^[A-Z][a-z]+$/.test(word);
|
|
35538
35563
|
}
|
|
35539
35564
|
function summaryFromName(name2, kind) {
|
|
35540
35565
|
if (!NAME_DERIVED_ENABLED) return null;
|
|
@@ -35556,7 +35581,7 @@ function summaryCandidates(name2, kind, doc) {
|
|
|
35556
35581
|
if (fromName !== null && fromName !== fromDoc) candidates.push(fromName);
|
|
35557
35582
|
return candidates;
|
|
35558
35583
|
}
|
|
35559
|
-
var NAME_DERIVED_ENABLED, KIND_ARTICLE, lead, MAX_PAYLOAD_CHARS, DANGLING, VERBS, tidy, VERB_PHRASE_KINDS;
|
|
35584
|
+
var NAME_DERIVED_ENABLED, KIND_ARTICLE, lead, MAX_PAYLOAD_CHARS, DANGLING, VERBS, tidy, CONTRACTION_BASES, VERB_PHRASE_KINDS;
|
|
35560
35585
|
var init_derive_summary = __esm({
|
|
35561
35586
|
"src/derive-summary.ts"() {
|
|
35562
35587
|
"use strict";
|
|
@@ -35839,6 +35864,7 @@ var init_derive_summary = __esm({
|
|
|
35839
35864
|
"yield"
|
|
35840
35865
|
]);
|
|
35841
35866
|
tidy = (s) => s.replace(/\s+/g, " ").replace(/\s+([,.;:])/g, "$1").replace(/[\s,;:.]+$/, "").trim();
|
|
35867
|
+
CONTRACTION_BASES = /* @__PURE__ */ new Set(["it", "that", "this", "there", "here", "what", "who", "where", "when", "why", "how", "let", "he", "she"]);
|
|
35842
35868
|
VERB_PHRASE_KINDS = /* @__PURE__ */ new Set(["function", "method"]);
|
|
35843
35869
|
}
|
|
35844
35870
|
});
|
|
@@ -84772,23 +84798,25 @@ var lastFired = /* @__PURE__ */ new Map();
|
|
|
84772
84798
|
var THROTTLE_MS = 3e4;
|
|
84773
84799
|
function notifyEvent(kind, body2, opts = {}) {
|
|
84774
84800
|
try {
|
|
84775
|
-
if (process.env["ERRATA_NO_NOTIFY"]) return;
|
|
84776
|
-
if (!loadConfig().notifications) return;
|
|
84801
|
+
if (process.env["ERRATA_NO_NOTIFY"]) return false;
|
|
84802
|
+
if (!loadConfig().notifications) return false;
|
|
84777
84803
|
const k = `${kind}:${opts.key ?? ""}`;
|
|
84778
84804
|
const now = Date.now();
|
|
84779
|
-
if (now - (lastFired.get(k) ?? 0) < THROTTLE_MS) return;
|
|
84805
|
+
if (now - (lastFired.get(k) ?? 0) < THROTTLE_MS) return false;
|
|
84780
84806
|
lastFired.set(k, now);
|
|
84781
84807
|
notify(TITLES[kind], body2);
|
|
84808
|
+
return true;
|
|
84782
84809
|
} catch {
|
|
84810
|
+
return false;
|
|
84783
84811
|
}
|
|
84784
84812
|
}
|
|
84785
84813
|
function notifyOpsEvent(kind, body2, opts = {}) {
|
|
84786
84814
|
try {
|
|
84787
|
-
if (!loadConfig().opsNotices) return;
|
|
84815
|
+
if (!loadConfig().opsNotices) return false;
|
|
84788
84816
|
} catch {
|
|
84789
|
-
return;
|
|
84817
|
+
return false;
|
|
84790
84818
|
}
|
|
84791
|
-
notifyEvent(kind, body2, opts);
|
|
84819
|
+
return notifyEvent(kind, body2, opts);
|
|
84792
84820
|
}
|
|
84793
84821
|
function notifyTick(delta) {
|
|
84794
84822
|
const { problemsResolved, reviewsTriggered } = delta;
|
|
@@ -84958,24 +84986,49 @@ var ALARM_RENOTIFY_MS = 24 * 60 * 60 * 1e3;
|
|
|
84958
84986
|
function alarmStatePath(configDir) {
|
|
84959
84987
|
return join34(configDir, "liveness-alarms.json");
|
|
84960
84988
|
}
|
|
84961
|
-
function loadAlarmState(
|
|
84989
|
+
function loadAlarmState(path3) {
|
|
84962
84990
|
try {
|
|
84963
|
-
const raw2 = JSON.parse(readFileSync31(
|
|
84991
|
+
const raw2 = JSON.parse(readFileSync31(path3, "utf8"));
|
|
84964
84992
|
return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
|
|
84965
84993
|
} catch {
|
|
84966
84994
|
return /* @__PURE__ */ new Map();
|
|
84967
84995
|
}
|
|
84968
84996
|
}
|
|
84969
|
-
function saveAlarmState(
|
|
84997
|
+
function saveAlarmState(path3, state) {
|
|
84970
84998
|
try {
|
|
84971
|
-
writeFileSync22(
|
|
84999
|
+
writeFileSync22(path3, JSON.stringify(Object.fromEntries(state)));
|
|
84972
85000
|
} catch {
|
|
84973
85001
|
}
|
|
84974
85002
|
}
|
|
85003
|
+
function createAlarmToastGate(statePath) {
|
|
85004
|
+
const lastToastedAt = loadAlarmState(statePath);
|
|
85005
|
+
return {
|
|
85006
|
+
pending: (ids, nowMs) => ids.filter((id) => nowMs - (lastToastedAt.get(id) ?? 0) >= ALARM_RENOTIFY_MS),
|
|
85007
|
+
markToasted: (ids, nowMs) => {
|
|
85008
|
+
if (ids.length === 0) return;
|
|
85009
|
+
for (const id of ids) lastToastedAt.set(id, nowMs);
|
|
85010
|
+
saveAlarmState(statePath, lastToastedAt);
|
|
85011
|
+
}
|
|
85012
|
+
};
|
|
85013
|
+
}
|
|
85014
|
+
var sharedToastGates = /* @__PURE__ */ new Map();
|
|
85015
|
+
function sharedAlarmToastGate(statePath) {
|
|
85016
|
+
let gate = sharedToastGates.get(statePath);
|
|
85017
|
+
if (!gate) sharedToastGates.set(statePath, gate = createAlarmToastGate(statePath));
|
|
85018
|
+
return gate;
|
|
85019
|
+
}
|
|
85020
|
+
function toastLivenessAlarms(gate, workspace, alarms, deliver, nowMs) {
|
|
85021
|
+
const fresh = gate.pending(alarms.map((a) => a.id), nowMs);
|
|
85022
|
+
if (fresh.length === 0) return [];
|
|
85023
|
+
const body2 = fresh.length === 1 ? `${workspace.name}: ${alarms.find((a) => a.id === fresh[0]).line}` : `${workspace.name}: ${fresh.join(", ")} \u2014 see daemon.log`;
|
|
85024
|
+
if (!deliver(body2, `liveness:${workspace.root}`)) return [];
|
|
85025
|
+
gate.markToasted(fresh, nowMs);
|
|
85026
|
+
return fresh;
|
|
85027
|
+
}
|
|
84975
85028
|
function createLivenessWatch(deps) {
|
|
84976
85029
|
let lastRunAt = 0;
|
|
84977
85030
|
let running = false;
|
|
84978
|
-
const lastAlarmedAt = loadAlarmState(deps.configDir);
|
|
85031
|
+
const lastAlarmedAt = loadAlarmState(alarmStatePath(deps.configDir));
|
|
84979
85032
|
return {
|
|
84980
85033
|
async maybeRun(nowMs = Date.now()) {
|
|
84981
85034
|
if (running || nowMs - lastRunAt < LIVENESS_WATCH_INTERVAL_MS) return null;
|
|
@@ -84995,8 +85048,8 @@ function createLivenessWatch(deps) {
|
|
|
84995
85048
|
});
|
|
84996
85049
|
}
|
|
84997
85050
|
const rows = deps.evaluate ? await deps.evaluate(invocations) : evaluateMechanisms(deps.store, invocations);
|
|
84998
|
-
const workspaceActive = invocations.has("capture")
|
|
84999
|
-
const bad = workspaceActive ? rows.filter((r) => hasStarvedMechanism([r])) : [];
|
|
85051
|
+
const workspaceActive = invocations.has("capture");
|
|
85052
|
+
const bad = workspaceActive ? rows.filter((r) => r.id !== "liveness-watch" && hasStarvedMechanism([r])) : [];
|
|
85000
85053
|
const watch3 = watchCensus();
|
|
85001
85054
|
const pass = passState();
|
|
85002
85055
|
appendPassLedger(deps.configDir, "liveness-watch", Date.now() - started2, {
|
|
@@ -85021,14 +85074,17 @@ function createLivenessWatch(deps) {
|
|
|
85021
85074
|
});
|
|
85022
85075
|
if (bad.length > 0) {
|
|
85023
85076
|
const lines = formatMechanismStatus(rows, nowMs);
|
|
85077
|
+
const fresh = [];
|
|
85024
85078
|
for (const r of bad) {
|
|
85025
85079
|
const at = lastAlarmedAt.get(r.id) ?? 0;
|
|
85026
85080
|
if (nowMs - at < ALARM_RENOTIFY_MS) continue;
|
|
85027
85081
|
lastAlarmedAt.set(r.id, nowMs);
|
|
85028
|
-
saveAlarmState(deps.configDir, lastAlarmedAt);
|
|
85029
85082
|
const line = lines.find((l) => l.includes(r.id)) ?? `${r.verdict} ${r.id}`;
|
|
85030
|
-
|
|
85083
|
+
fresh.push({ id: r.id, line: `${line.trim()} \u2014 ${r.what}` });
|
|
85031
85084
|
}
|
|
85085
|
+
if (fresh.length > 0) saveAlarmState(alarmStatePath(deps.configDir), lastAlarmedAt);
|
|
85086
|
+
for (const a of fresh) deps.onAlarm(a.id, a.line);
|
|
85087
|
+
if (fresh.length > 0) deps.onAlarms?.(fresh);
|
|
85032
85088
|
}
|
|
85033
85089
|
return rows;
|
|
85034
85090
|
} catch (err2) {
|
|
@@ -85168,7 +85224,7 @@ function createWatchBreaker(deps) {
|
|
|
85168
85224
|
}
|
|
85169
85225
|
|
|
85170
85226
|
// src/engine.ts
|
|
85171
|
-
var DAEMON_VERSION = true ? "2.0.22-dev.
|
|
85227
|
+
var DAEMON_VERSION = true ? "2.0.22-dev.4135" : "2.0.0-alpha.0";
|
|
85172
85228
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
85173
85229
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
85174
85230
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -85549,9 +85605,17 @@ function createWorkspaceEngine(opts) {
|
|
|
85549
85605
|
configDir: paths.configDir,
|
|
85550
85606
|
store,
|
|
85551
85607
|
...passWorker ? { evaluate: (invocations) => passWorker.liveness(invocations) } : {},
|
|
85552
|
-
onAlarm: (
|
|
85553
|
-
console.warn(`[errata] mechanism not working: ${line}`);
|
|
85554
|
-
|
|
85608
|
+
onAlarm: (_id, line) => {
|
|
85609
|
+
console.warn(`[errata] mechanism not working (${profile.name}): ${line}`);
|
|
85610
|
+
},
|
|
85611
|
+
onAlarms: (alarms) => {
|
|
85612
|
+
toastLivenessAlarms(
|
|
85613
|
+
sharedAlarmToastGate(join35(globalDir(), "liveness-toasts.json")),
|
|
85614
|
+
{ root: opts.workspaceRoot, name: profile.name },
|
|
85615
|
+
alarms,
|
|
85616
|
+
(body2, key) => notifyEvent("mechanism-stalled", body2, { key }),
|
|
85617
|
+
Date.now()
|
|
85618
|
+
);
|
|
85555
85619
|
},
|
|
85556
85620
|
// Read through a closure, not captured once: `witnessQueue` is reassigned
|
|
85557
85621
|
// on every harvest, so a snapshot would freeze the depth at boot — which is
|
|
@@ -87672,23 +87736,20 @@ B: ${b}`,
|
|
|
87672
87736
|
ts: fjStart,
|
|
87673
87737
|
...foldJudge ? { judge: foldJudge } : {}
|
|
87674
87738
|
});
|
|
87675
|
-
|
|
87676
|
-
|
|
87677
|
-
|
|
87678
|
-
|
|
87679
|
-
|
|
87680
|
-
|
|
87681
|
-
|
|
87682
|
-
|
|
87683
|
-
|
|
87684
|
-
|
|
87685
|
-
|
|
87686
|
-
|
|
87687
|
-
});
|
|
87688
|
-
|
|
87689
|
-
console.log(`[errata] fold-judge: folded ${fj.folded} paraphrase pair(s) (${fj.foldedEmbedding} by embedding, ${fj.foldedJudge} by judge), ${fj.standing} standing`);
|
|
87690
|
-
refreshContextNow();
|
|
87691
|
-
}
|
|
87739
|
+
appendPassLedger(paths.configDir, "fold-judge", Date.now() - fjStart, {
|
|
87740
|
+
examined: fj.examined,
|
|
87741
|
+
folded: fj.folded,
|
|
87742
|
+
foldedEmbedding: fj.foldedEmbedding,
|
|
87743
|
+
foldedJudge: fj.foldedJudge,
|
|
87744
|
+
rejected: fj.rejected,
|
|
87745
|
+
standing: fj.standing,
|
|
87746
|
+
judgeErrors: fj.judgeErrors,
|
|
87747
|
+
retargeted: fj.retargeted,
|
|
87748
|
+
judgeConfigured: foldJudge ? 1 : 0
|
|
87749
|
+
});
|
|
87750
|
+
if (fj.folded > 0) {
|
|
87751
|
+
console.log(`[errata] fold-judge: folded ${fj.folded} paraphrase pair(s) (${fj.foldedEmbedding} by embedding, ${fj.foldedJudge} by judge), ${fj.standing} standing`);
|
|
87752
|
+
refreshContextNow();
|
|
87692
87753
|
}
|
|
87693
87754
|
return { embedded: sem.embedded };
|
|
87694
87755
|
} catch (err2) {
|
|
@@ -87973,6 +88034,21 @@ async function listenServer(fetchFn, port) {
|
|
|
87973
88034
|
});
|
|
87974
88035
|
}
|
|
87975
88036
|
|
|
88037
|
+
// src/capture-status.ts
|
|
88038
|
+
function captureStatusLines(capture, nowMs = Date.now()) {
|
|
88039
|
+
if (!capture) return ["no processed agent turns recorded for this workspace; machine-wide hook activity does not prove capture here"];
|
|
88040
|
+
const value = (key) => capture.totals[key] === void 0 ? "unrecorded" : String(capture.totals[key]);
|
|
88041
|
+
const age = Math.max(0, Math.floor((nowMs - capture.lastTs) / 6e4));
|
|
88042
|
+
const lines = [
|
|
88043
|
+
`${value("turns")} turns \xB7 ${value("tagsSeen")} tags seen \xB7 ${value("minted")} nodes minted across ${capture.runs} retained passes (last ${age}m ago)`
|
|
88044
|
+
];
|
|
88045
|
+
if (capture.totals.tagsSeen === 0) lines.push("turns arrived, but no knowledge tags were detected");
|
|
88046
|
+
else if ((capture.totals.tagsSeen ?? 0) > 0 && capture.totals.minted === 0) {
|
|
88047
|
+
lines.push(`${value("tagsRejected")} tags rejected \xB7 ${value("tagsRestated")} restatements; zero new nodes alone does not establish capture failure`);
|
|
88048
|
+
}
|
|
88049
|
+
return lines;
|
|
88050
|
+
}
|
|
88051
|
+
|
|
87976
88052
|
// src/cli.ts
|
|
87977
88053
|
init_registry();
|
|
87978
88054
|
init_identity2();
|
|
@@ -94690,8 +94766,8 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
94690
94766
|
checks.push(
|
|
94691
94767
|
profile ? { id: "installation_profile", status: "pass", detail: `${profileName} is selected` } : {
|
|
94692
94768
|
id: "installation_profile",
|
|
94693
|
-
status: "fail",
|
|
94694
|
-
detail: "
|
|
94769
|
+
status: profileName ? "fail" : "pass",
|
|
94770
|
+
detail: profileName ? `Selected installation profile "${profileName}" does not exist` : "Using the machine-default credential; a named installation profile is optional"
|
|
94695
94771
|
}
|
|
94696
94772
|
);
|
|
94697
94773
|
const credentialType = cfg.accessToken ? "oauth" : cfg.apiKey ? "api_key" : "none";
|
|
@@ -94702,8 +94778,8 @@ async function diagnoseInstallation(cfg, dependencies) {
|
|
|
94702
94778
|
checks.push(
|
|
94703
94779
|
authorityMatches ? {
|
|
94704
94780
|
id: "profile_authority",
|
|
94705
|
-
status: profile ? "
|
|
94706
|
-
detail: profile ? "Selected profile and active credential set match" : "
|
|
94781
|
+
status: profileName && !profile ? "warn" : "pass",
|
|
94782
|
+
detail: profile ? "Selected profile and active credential set match" : profileName ? "Selected profile is missing; authority cannot be compared" : "No named profile selected; credential authentication is checked below"
|
|
94707
94783
|
} : {
|
|
94708
94784
|
id: "profile_authority",
|
|
94709
94785
|
status: "fail",
|
|
@@ -95069,6 +95145,8 @@ function inspectCodexContext(cwd) {
|
|
|
95069
95145
|
}
|
|
95070
95146
|
return { id: "codex_context", status: "fail", detail: "No usable saved workspace context; run errata start here and check the daemon log if context.md remains unavailable" };
|
|
95071
95147
|
}
|
|
95148
|
+
var CodexRuntimeUnavailableError = class extends Error {
|
|
95149
|
+
};
|
|
95072
95150
|
function readCodexHookState(cwd, options = {}) {
|
|
95073
95151
|
return new Promise((resolve10, reject) => {
|
|
95074
95152
|
const child = spawn4(options.bin ?? resolveCodexExecutable(), options.args ?? ["app-server", "--stdio"], {
|
|
@@ -95099,7 +95177,7 @@ function readCodexHookState(cwd, options = {}) {
|
|
|
95099
95177
|
const send = (id, method, params) => {
|
|
95100
95178
|
child.stdin.write(JSON.stringify({ id, method, params }) + "\n");
|
|
95101
95179
|
};
|
|
95102
|
-
child.on("error", () => finish(new Error(`Codex could not be started for hook inspection
|
|
95180
|
+
child.on("error", (error48) => finish(error48.code === "ENOENT" ? new CodexRuntimeUnavailableError("Codex executable was not found; hook status is unverified. If you use Codex on this machine, make its runtime available and rerun errata doctor.") : new Error(`Codex could not be started for hook inspection (${error48.code ?? "launch error"}); hook trust was not checked.`)));
|
|
95103
95181
|
child.on("exit", () => finish(new Error("Codex exited before returning its hook state")));
|
|
95104
95182
|
child.stdin.on("error", () => finish(new Error("Codex hook inspection connection closed")));
|
|
95105
95183
|
child.stderr.resume();
|
|
@@ -95157,12 +95235,12 @@ function assessCodexHooks(state, platform = process.platform) {
|
|
|
95157
95235
|
}
|
|
95158
95236
|
return checks.length ? checks : check2("pass", "Codex discovers enabled, trusted Errata hooks; verify live context and capture in a session");
|
|
95159
95237
|
}
|
|
95160
|
-
async function diagnoseCodexHooks(cwd) {
|
|
95238
|
+
async function diagnoseCodexHooks(cwd, options = {}) {
|
|
95161
95239
|
const local = [inspectCodexRelay(cwd), inspectCodexContext(cwd)];
|
|
95162
95240
|
try {
|
|
95163
|
-
return [...local, ...assessCodexHooks(await readCodexHookState(cwd))];
|
|
95241
|
+
return [...local, ...assessCodexHooks(await readCodexHookState(cwd, options))];
|
|
95164
95242
|
} catch (error48) {
|
|
95165
|
-
return [...local, { id: "codex_hooks", status: "fail", detail: error48 instanceof Error ? error48.message : "Cannot verify Codex hooks" }];
|
|
95243
|
+
return [...local, { id: "codex_hooks", status: error48 instanceof CodexRuntimeUnavailableError ? "warn" : "fail", detail: error48 instanceof Error ? error48.message : "Cannot verify Codex hooks" }];
|
|
95166
95244
|
}
|
|
95167
95245
|
}
|
|
95168
95246
|
|
|
@@ -96981,6 +97059,9 @@ async function cmdStatus() {
|
|
|
96981
97059
|
}
|
|
96982
97060
|
console.log(` graph db: ${existsSync40(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
|
|
96983
97061
|
console.log(` event log: ${existsSync40(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
|
|
97062
|
+
for (const line of captureStatusLines(summarizePassLedger(paths.configDir).get("capture"))) {
|
|
97063
|
+
console.log(` capture: ${line}`);
|
|
97064
|
+
}
|
|
96984
97065
|
if (existsSync40(paths.castalia)) {
|
|
96985
97066
|
try {
|
|
96986
97067
|
const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
|
|
@@ -97067,11 +97148,11 @@ async function cmdStatus() {
|
|
|
97067
97148
|
}
|
|
97068
97149
|
if (h.lastHook !== void 0) {
|
|
97069
97150
|
if (h.lastHook === null) {
|
|
97070
|
-
console.log(` hooks: none received since the daemon started`);
|
|
97151
|
+
console.log(` hooks: none received machine-wide since the daemon started`);
|
|
97071
97152
|
} else {
|
|
97072
97153
|
const min = Math.round((Date.now() - h.lastHook.at) / 6e4);
|
|
97073
97154
|
const ago2 = min < 1 ? "just now" : min < 60 ? `${min}m ago` : `${Math.floor(min / 60)}h ${min % 60}m ago`;
|
|
97074
|
-
console.log(` hooks: last received ${ago2} (${h.lastHook.event})`);
|
|
97155
|
+
console.log(` hooks: last received machine-wide ${ago2} (${h.lastHook.event})`);
|
|
97075
97156
|
}
|
|
97076
97157
|
}
|
|
97077
97158
|
}
|
|
@@ -97101,16 +97182,16 @@ async function cmdStatus() {
|
|
|
97101
97182
|
}
|
|
97102
97183
|
const shown = reportedIdentity(cfg, workspaceEntryForPath(ROOT));
|
|
97103
97184
|
const ecfg = shown.ok ? shown.config : cfg;
|
|
97104
|
-
console.log(` profile: ${ecfg.activeInstallationProfile ?? "(
|
|
97185
|
+
console.log(` profile: ${ecfg.activeInstallationProfile ?? "(machine default; no named profile)"}`);
|
|
97105
97186
|
if (!shown.ok) console.log(` \u26A0 ${shown.reason} \u2014 this workspace's capture holds locally until fixed`);
|
|
97106
97187
|
else if (shown.note) console.log(` \u21B3 ${shown.note}`);
|
|
97107
97188
|
const who = shown.ok && shown.note ? "" : ` (${ecfg.email})`;
|
|
97108
97189
|
if (!hasCloudCredential(ecfg)) {
|
|
97109
|
-
console.log(`
|
|
97190
|
+
console.log(` credential: none`);
|
|
97110
97191
|
} else if (ecfg.accessToken) {
|
|
97111
|
-
console.log(`
|
|
97192
|
+
console.log(` credential: OAuth stored${who} \u2014 authentication checked below`);
|
|
97112
97193
|
} else {
|
|
97113
|
-
console.log(`
|
|
97194
|
+
console.log(` credential: API key stored${who} \u2014 authentication checked below`);
|
|
97114
97195
|
}
|
|
97115
97196
|
const active3 = getActiveAgent(ecfg);
|
|
97116
97197
|
console.log(
|
|
@@ -97137,7 +97218,8 @@ async function cmdStatus() {
|
|
|
97137
97218
|
const me = await c.me();
|
|
97138
97219
|
console.log(` reachable: yes \xB7 authenticated as ${me.handle} (${me.tier})`);
|
|
97139
97220
|
} catch (err2) {
|
|
97140
|
-
console.log(` reachable:
|
|
97221
|
+
console.log(` reachable: ${inspection.reachable ? `yes (${inspection.probe})` : "no"}`);
|
|
97222
|
+
console.log(` authenticated: no (${err2 instanceof Error ? err2.message : err2})`);
|
|
97141
97223
|
}
|
|
97142
97224
|
} else {
|
|
97143
97225
|
console.log(
|
package/generalize-worker.mjs
CHANGED
|
@@ -16110,14 +16110,16 @@ var SqliteGraphStore = class {
|
|
|
16110
16110
|
findNodeStampsByLabel(label, attrKey) {
|
|
16111
16111
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
|
|
16112
16112
|
const rows = this.db.prepare(
|
|
16113
|
-
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
|
|
16113
|
+
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has,
|
|
16114
|
+
COALESCE(json_extract(attrs_json, '$.source') = 'cloud', 0) AS cloud
|
|
16114
16115
|
FROM nodes WHERE label = ? AND valid_to IS NULL`
|
|
16115
16116
|
).all(label);
|
|
16116
16117
|
return rows.map((r) => ({
|
|
16117
16118
|
id: r.id,
|
|
16118
16119
|
createdAt: r.created_at,
|
|
16119
16120
|
...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
|
|
16120
|
-
has: r.has === 1
|
|
16121
|
+
has: r.has === 1,
|
|
16122
|
+
cloud: r.cloud === 1
|
|
16121
16123
|
}));
|
|
16122
16124
|
}
|
|
16123
16125
|
findNodeAttrsByLabel(label) {
|
|
@@ -17245,7 +17247,14 @@ function summaryFromDoc(doc, kind) {
|
|
|
17245
17247
|
}
|
|
17246
17248
|
if (verb !== null) return null;
|
|
17247
17249
|
const noun = clipped.replace(/^(?:the|a|an)\s+/i, "");
|
|
17248
|
-
|
|
17250
|
+
const head = noun.split(/[\s-]/, 1)[0].replace(/[.,;:!?]+$/, "");
|
|
17251
|
+
return tidy(`${lead(kind)} for ${isOrdinaryCapital(head) ? noun.charAt(0).toLowerCase() + noun.slice(1) : noun}`);
|
|
17252
|
+
}
|
|
17253
|
+
var CONTRACTION_BASES = /* @__PURE__ */ new Set(["it", "that", "this", "there", "here", "what", "who", "where", "when", "why", "how", "let", "he", "she"]);
|
|
17254
|
+
function isOrdinaryCapital(word) {
|
|
17255
|
+
const contraction = /^([A-Za-z]+)['’]s$/.exec(word);
|
|
17256
|
+
if (contraction) return CONTRACTION_BASES.has(contraction[1].toLowerCase()) && /^[A-Z][a-z]*$/.test(contraction[1]);
|
|
17257
|
+
return /^[A-Z][a-z]+$/.test(word);
|
|
17249
17258
|
}
|
|
17250
17259
|
var VERB_PHRASE_KINDS = /* @__PURE__ */ new Set(["function", "method"]);
|
|
17251
17260
|
function summaryFromName(name, kind) {
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -26969,14 +26969,16 @@ var SqliteGraphStore = class {
|
|
|
26969
26969
|
findNodeStampsByLabel(label, attrKey) {
|
|
26970
26970
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
|
|
26971
26971
|
const rows = this.db.prepare(
|
|
26972
|
-
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
|
|
26972
|
+
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has,
|
|
26973
|
+
COALESCE(json_extract(attrs_json, '$.source') = 'cloud', 0) AS cloud
|
|
26973
26974
|
FROM nodes WHERE label = ? AND valid_to IS NULL`
|
|
26974
26975
|
).all(label);
|
|
26975
26976
|
return rows.map((r) => ({
|
|
26976
26977
|
id: r.id,
|
|
26977
26978
|
createdAt: r.created_at,
|
|
26978
26979
|
...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
|
|
26979
|
-
has: r.has === 1
|
|
26980
|
+
has: r.has === 1,
|
|
26981
|
+
cloud: r.cloud === 1
|
|
26980
26982
|
}));
|
|
26981
26983
|
}
|
|
26982
26984
|
findNodeAttrsByLabel(label) {
|
|
@@ -28934,6 +28936,7 @@ var MECHANISMS = [
|
|
|
28934
28936
|
},
|
|
28935
28937
|
{
|
|
28936
28938
|
id: "fix-candidate-ask",
|
|
28939
|
+
requiresNodes: ["Problem"],
|
|
28937
28940
|
what: "asks an agent whether an edit to a problem's anchor fixed it",
|
|
28938
28941
|
pass: "semantic-maintenance",
|
|
28939
28942
|
// markFixCandidates fails CLOSED on a File anchor with no contentChangedAt —
|
|
@@ -28985,7 +28988,12 @@ var MECHANISMS = [
|
|
|
28985
28988
|
// the producer was verifiably stamping every new node.
|
|
28986
28989
|
minFraction: 0.9,
|
|
28987
28990
|
recent: 200,
|
|
28988
|
-
sinceFirstStamp: true
|
|
28991
|
+
sinceFirstStamp: true,
|
|
28992
|
+
// The anchor-feed pull lands cloud mirrors by the hundreds every ten
|
|
28993
|
+
// minutes (createdAt = pull time, no local seq — stamping them would age
|
|
28994
|
+
// every local node by Δseq). On 2026-10-09 1,146 mirrors in a few hours
|
|
28995
|
+
// dragged this to 62% and toasted "ingest-sequence DEAD" with effect 41.
|
|
28996
|
+
localOnly: true
|
|
28989
28997
|
},
|
|
28990
28998
|
effectCounter: "seqAdvanced",
|
|
28991
28999
|
note: "column, not attr; measured over nodes born since the first stamp in the recent window"
|
|
@@ -29130,6 +29138,7 @@ var MECHANISMS = [
|
|
|
29130
29138
|
},
|
|
29131
29139
|
{
|
|
29132
29140
|
id: "liveness-watch",
|
|
29141
|
+
inputOptional: true,
|
|
29133
29142
|
what: "the daemon-side schedule of this very verdict \u2014 alarms when a mechanism stops working",
|
|
29134
29143
|
// The watcher is itself a row: a probe that only runs when a human remembers
|
|
29135
29144
|
// is how the original six defects shipped, and a scheduled watch that
|
|
@@ -29161,7 +29170,9 @@ function evaluateFed(store2, d) {
|
|
|
29161
29170
|
if (!d.fed) return { count: 0, total: 0, fraction: 0 };
|
|
29162
29171
|
const column2 = COLUMN_INPUTS[d.fed.attr];
|
|
29163
29172
|
const fed = d.fed;
|
|
29164
|
-
const
|
|
29173
|
+
const all = fed.labels.flatMap((label) => store2.findNodeStampsByLabel ? store2.findNodeStampsByLabel(label, fed.attr) : store2.findNodeAttrsByLabel(label));
|
|
29174
|
+
const isCloudMirror = (n) => n.cloud ?? n.attrs?.["source"] === "cloud";
|
|
29175
|
+
const nodes = fed.localOnly ? all.filter((n) => !isCloudMirror(n)) : all;
|
|
29165
29176
|
const has = (n) => column2 ? column2(n) : n.has ?? n.attrs?.[fed.attr] !== void 0;
|
|
29166
29177
|
let window2 = nodes;
|
|
29167
29178
|
if (fed.recent !== void 0) {
|
|
@@ -29177,6 +29188,11 @@ function evaluateFed(store2, d) {
|
|
|
29177
29188
|
return { count, total: window2.length, fraction: window2.length === 0 ? 0 : count / window2.length };
|
|
29178
29189
|
}
|
|
29179
29190
|
function evaluateMechanisms(store2, invocations = /* @__PURE__ */ new Map(), mechanisms = MECHANISMS) {
|
|
29191
|
+
const counts = /* @__PURE__ */ new Map();
|
|
29192
|
+
const count = (label) => {
|
|
29193
|
+
if (!counts.has(label)) counts.set(label, store2.countNodesByLabel(label));
|
|
29194
|
+
return counts.get(label);
|
|
29195
|
+
};
|
|
29180
29196
|
return mechanisms.map((d) => {
|
|
29181
29197
|
const fed = evaluateFed(store2, d);
|
|
29182
29198
|
const inv = invocations.get(d.pass);
|
|
@@ -29189,8 +29205,11 @@ function evaluateMechanisms(store2, invocations = /* @__PURE__ */ new Map(), mec
|
|
|
29189
29205
|
const span = inv?.firstTs === void 0 ? 0 : inv.lastTs - inv.firstTs;
|
|
29190
29206
|
const stalled = backlog !== void 0 && backlog > 0 && effectCount === 0 && (inv?.runs ?? 0) >= STALL_MIN_RUNS && span >= STALL_MIN_SPAN_MS && (backlogWas === void 0 || backlog >= backlogWas);
|
|
29191
29207
|
let verdict;
|
|
29192
|
-
|
|
29193
|
-
|
|
29208
|
+
const hasInput = fed.total > 0 || Boolean(d.fed?.sinceFirstStamp && d.fed.labels.some((label) => count(label) > 0));
|
|
29209
|
+
const missingRequiredNodes = d.requiresNodes?.some((label) => count(label) === 0) ?? false;
|
|
29210
|
+
if (d.configCounter && inv?.lastTotals?.[d.configCounter] === 0) verdict = "unconfigured";
|
|
29211
|
+
else if ((backlog ?? 0) === 0 && (!hasInput && !d.inputOptional || missingRequiredNodes)) verdict = "no-input";
|
|
29212
|
+
else if (!inv || inv.runs === 0) verdict = "never-invoked";
|
|
29194
29213
|
else if (fed.fraction < (d.fedEdges?.minFraction ?? d.fed?.minFraction ?? 0)) verdict = "starved";
|
|
29195
29214
|
else if (stalled) verdict = "stalled";
|
|
29196
29215
|
else if (effectCount === 0) verdict = "no-effect";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
f0dd5b6f3e6476eba250ed306f433f9ee159a05948b36f15f1eae0ee0f59a3a2 .codex-plugin/plugin.json
|
|
2
2
|
a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
|
|
3
3
|
fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
|
|
4
4
|
73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js
|