clearotron 0.3.2-beta.7 → 0.3.2-beta.8
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/.env.example +24 -23
- package/INSTALL.md +142 -75
- package/README.md +3 -3
- package/bin/onboard.mjs +637 -216
- package/bin/start.mjs +133 -23
- package/bin/update.mjs +58 -11
- package/build-info.json +2 -2
- package/docs/architecture/04-configuration-reference.md +26 -11
- package/docs/architecture/05-config-governance.md +17 -7
- package/driver/CHANGELOG.md +76 -0
- package/driver/band-size.mjs +59 -0
- package/driver/config-inventory.mjs +112 -9
- package/driver/contract-arm2-baseline.json +1 -3
- package/driver/contract-e3-backlog.mjs +26 -26
- package/driver/contract-vocabulary.mjs +44 -10
- package/driver/door-gates.mjs +41 -7
- package/driver/driver.config.mjs +272 -59
- package/driver/engine/CONTRACT.md +10 -3
- package/driver/engine/README.md +2 -2
- package/driver/engine/anthropic-agent.mjs +77 -21
- package/driver/engine/auth.mjs +129 -10
- package/driver/engine/jx-turn.mjs +7 -6
- package/driver/engine/mcp/recording-server.mjs +13 -0
- package/driver/engine/openai-agent.mjs +4 -2
- package/driver/engine/probe.mjs +110 -23
- package/driver/findings-model.mjs +1 -1
- package/driver/flag-snapshot.mjs +28 -5
- package/driver/gateway.mjs +24 -18
- package/driver/jx-lanes.mjs +21 -2
- package/driver/jx-units.mjs +6 -3
- package/driver/jx.mjs +4 -2
- package/driver/matter-frame-record.mjs +90 -1
- package/driver/named-band.mjs +34 -2
- package/driver/package.json +1 -1
- package/driver/pipeline.mjs +200 -23
- package/driver/portal-config-view.mjs +30 -1
- package/driver/portal-report.mjs +15 -1
- package/driver/portal-service.mjs +46 -6
- package/driver/predelivery-lint.mjs +12 -2
- package/driver/publish/index.mjs +46 -5
- package/driver/publish/knockout.mjs +10 -1
- package/driver/publish/render-knockout.mjs +69 -7
- package/driver/publish/render.mjs +170 -59
- package/driver/publish/report-data.mjs +4 -1
- package/driver/publish/report-topbar.mjs +58 -0
- package/driver/publish/templates/report.css +18 -1
- package/driver/publish/xlsx.mjs +13 -1
- package/driver/register-availability.mjs +2 -2
- package/driver/register-coverage.mjs +94 -1
- package/driver/register-digest-record.mjs +236 -11
- package/driver/register-plan.mjs +170 -0
- package/driver/result-noun-fields.mjs +2 -2
- package/driver/run-economics.mjs +41 -10
- package/driver/run-requirements.mjs +173 -9
- package/driver/runner.mjs +3 -3
- package/driver/stages.mjs +12 -8
- package/driver/suite-census.json +142 -64
- package/driver/systemd/README.md +7 -4
- package/driver/terminal-clamp.mjs +107 -1
- package/driver/tokens.mjs +169 -3
- package/driver/unit-environment.mjs +42 -15
- package/driver/unit-inventory.mjs +19 -2
- package/driver/verify.mjs +27 -0
- package/mcp-server/CHANGELOG.md +4 -0
- package/mcp-server/package.json +1 -1
- package/mcp-server/server.mjs +15 -1
- package/package.json +1 -1
- package/portal-ui/dist/assets/{index-5UyqAyNM.js → index-6jzO9HiX.js} +155 -79
- package/portal-ui/dist/index.html +1 -1
- package/portal-ui/package.json +1 -1
- package/providers/jx/README.md +2 -1
- package/providers/jx/src/turn-envelope.mjs +8 -3
- package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/uspto-local/README.md +1 -1
- package/scripts/authority-boundary-probe.mjs +4 -2
- package/scripts/env-audit.mjs +12 -6
- package/scripts/freeze-example-run.mjs +49 -16
- package/scripts/generated-files-are-current.mjs +69 -4
- package/scripts/settings-render-check.mjs +75 -2
- package/scripts/test-full.mjs +96 -3
- package/scripts/test-run.mjs +10 -0
- package/shared/deployment-box.mjs +7 -2
- package/shared/driver-dir.mjs +1 -1
- package/shared/names-in-force.mjs +1 -1
package/driver/band-size.mjs
CHANGED
|
@@ -64,3 +64,62 @@ export function bandSizeForStage(stage, paths, io) {
|
|
|
64
64
|
if (!BAND_READING_STAGES.has(stage)) return undefined;
|
|
65
65
|
return bandSizeAtDispatch(paths, io);
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
// ── A STAGE'S TIME LIMIT IS DERIVED FROM WHAT IT IS HANDED, NEVER A FIXED CONSTANT ────────────────
|
|
69
|
+
//
|
|
70
|
+
// THE DEFECT. The two stages that read the register band carried per-stage constants — numbers chosen
|
|
71
|
+
// once, against a band nobody recorded beside them. On a dense matter both died at their wall having
|
|
72
|
+
// written nothing: the placement attempt at 2,765s against a 2,700s budget, the digest at 2,470s
|
|
73
|
+
// against 2,400s. Both sat exactly AT the ceiling, so what ended them was the budget expiring rather
|
|
74
|
+
// than any guard firing; the stall guards had half an hour of quiet to fire in and could not, because
|
|
75
|
+
// tokens were still moving. Nothing malfunctioned. The number was simply sized for a different matter.
|
|
76
|
+
//
|
|
77
|
+
// THE TWO MEASUREMENTS THESE CONSTANTS ARE SET AGAINST, named here because a budget without the band
|
|
78
|
+
// it was measured at is the thing being fixed:
|
|
79
|
+
// · 2026-09-16, the dense matter: an 8 MB merged band; the placement attempt needed more than 2,765s
|
|
80
|
+
// and was killed at 2,700s. The derived limit at that size must exceed what the attempt took.
|
|
81
|
+
// · Every ordinary matter before it: a band at or under REFERENCE_MB, where 2,700s was sufficient and
|
|
82
|
+
// is what those runs are verified at. At or below that size the derivation must return the base
|
|
83
|
+
// unchanged, so no existing run's budget moves and no archived verdict is re-decided.
|
|
84
|
+
export const LIMIT_REFERENCE_MB = 2;
|
|
85
|
+
export const LIMIT_GROWTH_PER_MB = 0.03;
|
|
86
|
+
// The band size above which a stage is refused at dispatch rather than started. A limit past this is
|
|
87
|
+
// not a budget, it is a prediction that the stage will die: the 177 MB band measured on an earlier
|
|
88
|
+
// round would derive past an hour and a half, and starting it spends that hour and a half to arrive
|
|
89
|
+
// where the refusal already is. Refusing NAMES the size, which is the finding; being killed does not.
|
|
90
|
+
export const LIMIT_CEILING_SEC = 5400;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* The time limit for this dispatch, derived from the band it is handed. PURE.
|
|
94
|
+
*
|
|
95
|
+
* ABOVE THE REFERENCE SIZE ONLY. A band at or under the reference returns the stage's own base
|
|
96
|
+
* unchanged — that is what every run before this is verified at, and a derivation that moved those
|
|
97
|
+
* numbers would re-decide archived verdicts to fix a defect they never had.
|
|
98
|
+
*
|
|
99
|
+
* AN UNMEASURABLE BAND RETURNS THE BASE, and says so through `basis`. The alternatives are worse in
|
|
100
|
+
* both directions: guessing a bigger number spends a client's money on an input nobody measured, and
|
|
101
|
+
* guessing a smaller one kills a stage for a band that might have been ordinary. The base is what the
|
|
102
|
+
* run would have used anyway, so an absent measurement changes nothing rather than changing something
|
|
103
|
+
* arbitrary.
|
|
104
|
+
*/
|
|
105
|
+
export function derivedLimitSec(baseSec, bandSize) {
|
|
106
|
+
const base = Number.isFinite(baseSec) && baseSec > 0 ? baseSec : null;
|
|
107
|
+
if (base === null) return { sec: null, inputBytes: null, basis: "no base for this stage" };
|
|
108
|
+
const bytes = Number.isFinite(bandSize?.bytes) ? bandSize.bytes : null;
|
|
109
|
+
if (bytes === null) return { sec: base, inputBytes: null, basis: bandSize?.absent ? `band unmeasured: ${bandSize.absent}` : "no band for this stage" };
|
|
110
|
+
const mb = bytes / (1024 * 1024);
|
|
111
|
+
const over = Math.max(0, mb - LIMIT_REFERENCE_MB);
|
|
112
|
+
const sec = Math.round(base * (1 + LIMIT_GROWTH_PER_MB * over));
|
|
113
|
+
return { sec, inputBytes: bytes, basis: over > 0 ? `derived from ${mb.toFixed(1)} MB` : `at or under the ${LIMIT_REFERENCE_MB} MB reference` };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Is this derived limit past the point where starting the stage only buys a later kill? PURE. */
|
|
117
|
+
export function limitExceedsCeiling(sec) {
|
|
118
|
+
return Number.isFinite(sec) && sec > LIMIT_CEILING_SEC;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** The refusal a dispatch past the ceiling carries — it NAMES the size, which is the finding. PURE. */
|
|
122
|
+
export function ceilingRefusal(stage, derived) {
|
|
123
|
+
const mb = Number.isFinite(derived?.inputBytes) ? (derived.inputBytes / (1024 * 1024)).toFixed(1) : "an unmeasured";
|
|
124
|
+
return `stage_input_over_ceiling:${stage} was handed a ${mb} MB band, which derives a ${derived?.sec}s limit against a ${LIMIT_CEILING_SEC}s ceiling — the stage is refused at dispatch rather than started, because a limit past the ceiling is a prediction that it will be killed and starting it spends the whole budget to arrive at the same place. The band size is the finding: a band this size is the defect, not the budget`;
|
|
125
|
+
}
|
|
@@ -42,7 +42,10 @@ import {
|
|
|
42
42
|
DEFAULT_ENGINE_ID, ENGINE_BINARIES, PROVIDERS, RESEARCH_PROVIDERS, SERP_PROVIDERS,
|
|
43
43
|
missingCredentials, preflightEngineBinary, providerIdFrom,
|
|
44
44
|
} from "./driver.config.mjs";
|
|
45
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
resolveAuthMode, billingMode, cloudsSwitchedOn, BILLING_MODES, CLOUD_SWITCH, CLOUD_CREDENTIAL_CHECK,
|
|
47
|
+
} from "./engine/auth.mjs";
|
|
48
|
+
import { billingRefusalWords } from "./run-requirements.mjs"; // — a refusal that quotes the billing word says it by name
|
|
46
49
|
import { CASELAW_BRIDGES } from "./engine/mcp/gather-config.mjs"; // — the list that decides what is spawned
|
|
47
50
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
48
51
|
import { join } from "node:path";
|
|
@@ -60,7 +63,9 @@ const shown = (names) => names.map((n) => n);
|
|
|
60
63
|
* absent, because the alternative is silently billing a subscription the operator thought they had
|
|
61
64
|
* stopped using (engine/auth.mjs's opening argument). A writer that caught that and recorded "unknown"
|
|
62
65
|
* would erase precisely the misconfiguration a staff config page exists to surface, so it is caught and
|
|
63
|
-
* recorded AS ITSELF: mode `api-key`, `apiBilled: false`, and a fault naming the variable to set.
|
|
66
|
+
* recorded AS ITSELF: mode `api-key`, `apiBilled: false`, and a fault naming the variable to set. The
|
|
67
|
+
* cloud mode's refusals, and a word that is not a mode at all, are recorded as themselves too, by the
|
|
68
|
+
* refusal's own sentence.
|
|
64
69
|
*
|
|
65
70
|
* `apiBilled` is what the page should believe over `mode` — the two come apart in exactly this case,
|
|
66
71
|
* and only one of them describes who gets the invoice.
|
|
@@ -77,14 +82,38 @@ export function engineInventory(env = process.env) {
|
|
|
77
82
|
const billing = (() => {
|
|
78
83
|
try {
|
|
79
84
|
const a = resolveAuthMode({ engineName: id, env });
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
// `cloud` is the resolver's own answer, never re-derived here: the account a run bills is whatever
|
|
86
|
+
// the run door resolves, and a page that worked it out a second way could name another.
|
|
87
|
+
const cloud = a.cloud ?? null;
|
|
88
|
+
return { mode: a.mode, apiBilled: a.apiBilled === true, missing: [], cloud, cloudName: cloudName(cloud) };
|
|
89
|
+
} catch (e) {
|
|
90
|
+
// Recorded AS ITSELF, whichever refusal it was. An API-key mode with no key names the variable to
|
|
91
|
+
// set, reconstructed from the table so it cannot drift from it. Every other refusal (a cloud mode with
|
|
92
|
+
// no cloud switched on or with two, a cloud switch beside a mode it contradicts, a word that is not a
|
|
93
|
+
// mode) leaves `missing` empty, because the page reads `missing` as "set this key" and a key that is
|
|
94
|
+
// set is not missing, and carries a `reason` the page words itself (billingRefusalReason, below).
|
|
95
|
+
const mode = billingMode(env);
|
|
96
|
+
const keyAbsent = Boolean(spec?.apiKeyEnv) && String(env[spec.apiKeyEnv] ?? "") === "";
|
|
97
|
+
if (mode === "api-key" && keyAbsent) {
|
|
98
|
+
return { mode, apiBilled: false, missing: shown([spec.apiKeyEnv]), cloud: null, cloudName: null };
|
|
99
|
+
}
|
|
100
|
+
const reason = billingRefusalReason(id, env);
|
|
101
|
+
const notAMode = reason.kind === "not-a-mode";
|
|
84
102
|
return {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
103
|
+
// A WORD THAT IS NOT A MODE IS NOT RECORDED. It is whatever was typed into the setting that decides
|
|
104
|
+
// who pays, and a key pasted there by mistake is that word; this inventory is written to a file and
|
|
105
|
+
// served to a browser. So the mode reads `unknown`, and the refusal says the setting by name.
|
|
106
|
+
mode: notAMode ? "unknown" : mode,
|
|
107
|
+
apiBilled: false, missing: [], cloud: null, cloudName: null,
|
|
108
|
+
// THAT REFUSAL IS WRITTEN HERE, NOT CLEANED FROM THE RESOLVER'S. The resolver's sentence quotes the
|
|
109
|
+
// typed word, and removing it by pattern depends on how the word is spelled: a word that itself
|
|
110
|
+
// contains " is not a billing mode" left its tail behind. Built from names alone, nothing typed can
|
|
111
|
+
// reach it. Every other refusal quotes only setting names and the three mode words.
|
|
112
|
+
refusal: notAMode
|
|
113
|
+
? `${reason.setting} is set to a word that is not a billing mode — refusing to guess, because the guess `
|
|
114
|
+
+ `would bill the subscription. One of: ${reason.modes.join(", ")}.`
|
|
115
|
+
: billingRefusalWords(String(e?.message ?? e)),
|
|
116
|
+
reason,
|
|
88
117
|
};
|
|
89
118
|
}
|
|
90
119
|
})();
|
|
@@ -104,6 +133,80 @@ export function engineInventory(env = process.env) {
|
|
|
104
133
|
return { id, vendor: spec?.vendor ?? null, known: Boolean(spec), billing, binaryPresent };
|
|
105
134
|
}
|
|
106
135
|
|
|
136
|
+
/**
|
|
137
|
+
* What a reader calls the account a cloud mode bills: "Google Cloud", "Microsoft Azure", "Amazon Bedrock"
|
|
138
|
+
* or "Gateway". Null for no cloud.
|
|
139
|
+
*
|
|
140
|
+
* ONE TABLE OF CLOUD NAMES, NOT TWO. `CLOUD_CREDENTIAL_CHECK` in engine/auth.mjs already names each cloud
|
|
141
|
+
* the way a reader knows it, for the advice a refused sign-in prints, and this reads it rather than keeping
|
|
142
|
+
* a second list that could name a cloud differently on the page. It writes the gateway "the gateway", for
|
|
143
|
+
* use inside a sentence; a label on a page drops the article and starts with a capital, and that one
|
|
144
|
+
* adjustment is the whole of what this adds.
|
|
145
|
+
*/
|
|
146
|
+
export function cloudName(cloud) {
|
|
147
|
+
const who = CLOUD_CREDENTIAL_CHECK[cloud]?.who;
|
|
148
|
+
if (!who) return null;
|
|
149
|
+
const bare = who.replace(/^the /, "");
|
|
150
|
+
return bare.charAt(0).toUpperCase() + bare.slice(1);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* WHY A BILLING SETTING REFUSES EVERY SEARCH, as data: which refusal it is and the names involved, so the
|
|
155
|
+
* config page words it once, in plain English, without reading the resolver's sentence apart.
|
|
156
|
+
*
|
|
157
|
+
* `kind` is one of:
|
|
158
|
+
* switch-beside-mode subscription or api-key, and a cloud's switch on beside it (`clouds`)
|
|
159
|
+
* two-clouds cloud, and more than one cloud switched on (`clouds`)
|
|
160
|
+
* no-cloud cloud, and no cloud switched on and no gateway address (`clouds` lists every
|
|
161
|
+
* switch, and `gateway` the gateway's setting, as the choices to make)
|
|
162
|
+
* not-a-mode a word that is not a billing mode (`modes` are the ones this engine takes)
|
|
163
|
+
* cloud-on-codex cloud, on the Codex engine, which a cloud account cannot pay for (`engineSetting`
|
|
164
|
+
* and `engineChoice` name the Claude engine only where it would pay: one cloud
|
|
165
|
+
* switched on, or none and a gateway address; otherwise that move is one more refusal)
|
|
166
|
+
* unclassified a refusal this list does not name; the page says only that searches are refused.
|
|
167
|
+
* Not "other": that is an assistant's id in connect-clients.mjs, and a surface may
|
|
168
|
+
* not name one in code
|
|
169
|
+
*
|
|
170
|
+
* `defaulted` says the billing setting is blank, so `subscription` is the default and not a word anybody
|
|
171
|
+
* wrote: a page that said "payment is set to subscription" would send a reader looking for a line their
|
|
172
|
+
* settings file does not have. It is the state measured on Foundry, a switch on and the word unset.
|
|
173
|
+
*
|
|
174
|
+
* THE SAME PREDICATES AS THE RESOLVER, IN ITS ORDER. `resolveAuthMode` refuses by throwing a sentence and
|
|
175
|
+
* nothing else, so the kind is read back from the same environment through the same functions it uses
|
|
176
|
+
* (`billingMode`, `cloudsSwitchedOn`), in the order it checks them. Called only once it has thrown.
|
|
177
|
+
*
|
|
178
|
+
* NAMES, NEVER A VALUE. `mode` is sent only when it is one of the three modes; the word in a `not-a-mode`
|
|
179
|
+
* refusal is whatever was typed, and it is not sent at all.
|
|
180
|
+
*/
|
|
181
|
+
export function billingRefusalReason(id, env = process.env) {
|
|
182
|
+
const mode = billingMode(env);
|
|
183
|
+
const setting = "CLEAROTRON_AI_BILLING";
|
|
184
|
+
const clouds = (ids) => ids.map((c) => ({ name: cloudName(c), setting: CLOUD_SWITCH[c] }));
|
|
185
|
+
const defaulted = String(env[setting] ?? "").trim() === "";
|
|
186
|
+
const base = { setting, mode: null, defaulted, clouds: [], modes: [], gateway: null, engineSetting: null, engineChoice: null };
|
|
187
|
+
if (id === "openai-agent") {
|
|
188
|
+
if (mode === "cloud") {
|
|
189
|
+
// The resolver's own test for a cloud the Claude engine would pay through, in its words: one switch,
|
|
190
|
+
// or no switch and a gateway address.
|
|
191
|
+
const on = cloudsSwitchedOn(env);
|
|
192
|
+
const claudeWouldPay = on.length === 1 || (!on.length && Boolean(env.ANTHROPIC_BASE_URL));
|
|
193
|
+
return { ...base, kind: "cloud-on-codex", mode, modes: ["subscription", "api-key"],
|
|
194
|
+
...(claudeWouldPay ? { engineSetting: "CLEAROTRON_AI", engineChoice: "anthropic-agent" } : {}) };
|
|
195
|
+
}
|
|
196
|
+
if (mode !== "subscription" && mode !== "api-key") return { ...base, kind: "not-a-mode", modes: ["subscription", "api-key"] };
|
|
197
|
+
}
|
|
198
|
+
if (id === "anthropic-agent") {
|
|
199
|
+
const on = cloudsSwitchedOn(env);
|
|
200
|
+
if ((mode === "subscription" || mode === "api-key") && on.length) return { ...base, kind: "switch-beside-mode", mode, clouds: clouds(on) };
|
|
201
|
+
if (mode === "cloud" && on.length > 1) return { ...base, kind: "two-clouds", mode, clouds: clouds(on) };
|
|
202
|
+
if (mode === "cloud" && !on.length) {
|
|
203
|
+
return { ...base, kind: "no-cloud", mode, clouds: clouds(Object.keys(CLOUD_SWITCH)), gateway: "ANTHROPIC_BASE_URL" };
|
|
204
|
+
}
|
|
205
|
+
if (!BILLING_MODES.includes(mode)) return { ...base, kind: "not-a-mode", modes: [...BILLING_MODES] };
|
|
206
|
+
}
|
|
207
|
+
return { ...base, kind: "unclassified", mode: BILLING_MODES.includes(mode) ? mode : null };
|
|
208
|
+
}
|
|
209
|
+
|
|
107
210
|
/**
|
|
108
211
|
* The three states an install can be in, as far as running a search goes..
|
|
109
212
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"the baseline tracks named elements, and a rename is a new name. Regenerate rather than work around it.",
|
|
12
12
|
"Measured 139 of 287 declared elements."
|
|
13
13
|
],
|
|
14
|
-
"total":
|
|
14
|
+
"total": 105,
|
|
15
15
|
"byStage": {
|
|
16
16
|
"matter-frame": [
|
|
17
17
|
"### Intake asks line shape — rendered by the driver from intake_asks[]",
|
|
@@ -94,8 +94,6 @@
|
|
|
94
94
|
"register-digest": [
|
|
95
95
|
"## Summary counts — total queries executed (search + detail-fetch), enumerated records across N axes, crowd-descriptor count, candidates past the gate, surfaced count, open-verification-flag count",
|
|
96
96
|
"Audit trail — per-unit search/detail-fetch counts, per-jurisdiction `_query` attribution",
|
|
97
|
-
"INSTRUCTED CHECKS — the answer to each requester ask the register owns",
|
|
98
|
-
"adopt-or-override each placement by engaging its reason, and the `### Disagreement resolutions` rows (one per surfaced disagreement and per borderline:true, each ADOPTED/OVERRODE in writing)",
|
|
99
97
|
"return payload — the absolute output path plus a 2-3 line summary (counts + the path of the file written)",
|
|
100
98
|
"rolled-up coverage judgment — `sufficient: <true|false>`",
|
|
101
99
|
"source attribution — the register name tagged on each record, plus the EUIPO `environment` word",
|
|
@@ -283,7 +283,7 @@ export const E3_BACKLOG = [
|
|
|
283
283
|
{
|
|
284
284
|
stage: "register-unit",
|
|
285
285
|
kind: "exactly-these-keys",
|
|
286
|
-
where: "driver/stages.mjs:
|
|
286
|
+
where: "driver/stages.mjs:4195 (the frame-reopen / scoped-retry message builder). A second number stood here and had been stale for some time: it pointed at a contract-element description rather than a builder, at its old line and at every mechanical shift of it. Two candidate builders sit beside 4157 and picking one would be a guess, so the wrong pointer is removed rather than moved a third time — one accurate citation beats one accurate and one invented.",
|
|
287
287
|
surface: "stage-message",
|
|
288
288
|
evidence: "Every block you append MUST carry \"state\":\"enumerated\" (ONLY if paged to has_more:false) or \"state\":\"incomplete\" — EXACTLY those two strings … (re-dispatch builders, which REPLACE def.message)",
|
|
289
289
|
reparsedBy: "driver/named-band.mjs parseNamedBand. Scope warning: these builders replace def.message on every escalation / envelope-close / frame-reopen dispatch, so an E3 lint that walks STAGES[*].message only never sees them",
|
|
@@ -346,7 +346,7 @@ export const E3_BACKLOG = [
|
|
|
346
346
|
// (coverage-form.mjs coverageFormBrief) and the tool schema, with every row receiver-validated at
|
|
347
347
|
// call time. Same dictated vocabulary, same authored site, new route — this row's evidence follows
|
|
348
348
|
// the dictation so the row keeps describing something that exists.
|
|
349
|
-
where: "driver/stages.mjs:
|
|
349
|
+
where: "driver/stages.mjs:2622 (the digest message) + driver/coverage-form.mjs (coverageFormBrief — the dispatch block carrying the enum and the row shape)",
|
|
350
350
|
surface: "stage-message",
|
|
351
351
|
evidence: "Record a \"status\" and a \"reason\" on EVERY row ONLY by calling the … tool — the driver validates each row as it arrives, holds the record itself, and renders both the ## Coverage ledger table and the coverage JSON from it",
|
|
352
352
|
reparsedBy: "driver/coverage-call.mjs validateCoverageCall (receiver-validated at call time, the same predicates the gate judges with) + driver/coverage-form.mjs rowIsSettled via validators.registerFindings over the _driver/ accumulator",
|
|
@@ -429,7 +429,7 @@ export const E3_BACKLOG = [
|
|
|
429
429
|
{
|
|
430
430
|
stage: "frame-diff",
|
|
431
431
|
kind: "exactly-these-keys",
|
|
432
|
-
where: "driver/stages.mjs:
|
|
432
|
+
where: "driver/stages.mjs:2802",
|
|
433
433
|
surface: "stage-message",
|
|
434
434
|
evidence: "For each blind-model variant / field / source the run did NOT scope or search, emit one directive {layer, item, observation, severity} … severity = dominant-element (the omission is ON the spine) | material (a real omission worth a targeted sweep) | minor (already covered, or presentation only).",
|
|
435
435
|
reparsedBy: "driver/verify.mjs validators.frameDiff + driver/pipeline.mjs runSupplementalSweeps (the parser REFUSES a firing variant directive that dictates nothing dispatchable)",
|
|
@@ -453,7 +453,7 @@ export const E3_BACKLOG = [
|
|
|
453
453
|
{
|
|
454
454
|
stage: "synthesis",
|
|
455
455
|
kind: "literal-json-skeleton",
|
|
456
|
-
where: "driver/stages.mjs:
|
|
456
|
+
where: "driver/stages.mjs:3182",
|
|
457
457
|
surface: "stage-message",
|
|
458
458
|
evidence: "MACHINE FINDINGS (MANDATORY): … a JSON OBJECT {\"schema_version\":<FINDINGS_SCHEMA_VERSION>,\"rated_under_framework\":\"…\",\"findings\":[...],\"coverage\":[...],\"context_notes\":[...],\"actions\":[...],\"ask_answers\":[...]} … Each finding object has EXACTLY these keys: {\"ordinal\",\"mark\",\"owner\",\"band\",\"net\",\"bor",
|
|
459
459
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson via validators.narrative",
|
|
@@ -467,7 +467,7 @@ export const E3_BACKLOG = [
|
|
|
467
467
|
{
|
|
468
468
|
stage: "synthesis",
|
|
469
469
|
kind: "exactly-these-keys",
|
|
470
|
-
where: "driver/stages.mjs:
|
|
470
|
+
where: "driver/stages.mjs:3218",
|
|
471
471
|
surface: "stage-message",
|
|
472
472
|
evidence: "- off_field_ground (MANDATORY on every off-field finding, FORBIDDEN on every other disposition): EXACTLY one bare token of: ${OFF_FIELD_GROUNDS.join(\" / \")}",
|
|
473
473
|
reparsedBy: "driver/findings-model.mjs validateOffFieldGround — the enum is imported from findings-model.mjs and interpolated back into the prompt, so code already holds the list it asks the model to type",
|
|
@@ -476,7 +476,7 @@ export const E3_BACKLOG = [
|
|
|
476
476
|
{
|
|
477
477
|
stage: "synthesis",
|
|
478
478
|
kind: "literal-json-skeleton",
|
|
479
|
-
where: "driver/stages.mjs:
|
|
479
|
+
where: "driver/stages.mjs:3219",
|
|
480
480
|
surface: "stage-message",
|
|
481
481
|
evidence: "- manageable …: {\"category\":\"<EXACTLY one of large-competitor / commercial-partner / troll / well-known-enforcer>\",\"reason\":\"<one-two lines…>\"}",
|
|
482
482
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson",
|
|
@@ -485,7 +485,7 @@ export const E3_BACKLOG = [
|
|
|
485
485
|
{
|
|
486
486
|
stage: "synthesis",
|
|
487
487
|
kind: "literal-json-skeleton",
|
|
488
|
-
where: "driver/stages.mjs:
|
|
488
|
+
where: "driver/stages.mjs:3235",
|
|
489
489
|
surface: "stage-message",
|
|
490
490
|
evidence: "- meters: {\"mark_similarity\":{...},\"goods_proximity\":{...},\"use\":{...},\"enforcer\":{...}} — all four present, each {\"token\",\"basis\",\"source\"}. … mark_similarity = high | medium | low. goods_proximity = high | medium | low. enforcer = high | medium | low | unknown. use = confirmed | not-confirmed | un",
|
|
491
491
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson; driver/verify.mjs:1171 checkFindingsSibling gates meters.*.source; finding_basis_source_missing",
|
|
@@ -494,7 +494,7 @@ export const E3_BACKLOG = [
|
|
|
494
494
|
{
|
|
495
495
|
stage: "synthesis",
|
|
496
496
|
kind: "literal-json-skeleton",
|
|
497
|
-
where: "driver/stages.mjs:
|
|
497
|
+
where: "driver/stages.mjs:3236",
|
|
498
498
|
surface: "stage-message",
|
|
499
499
|
evidence: "- quadrant: {\"x\",\"y\"} numbers in [0,1]. x = goods/services proximity (0 = distant, 1 = identical). y = mark similarity (0 = distinct, 1 = identical).",
|
|
500
500
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson",
|
|
@@ -503,7 +503,7 @@ export const E3_BACKLOG = [
|
|
|
503
503
|
{
|
|
504
504
|
stage: "synthesis",
|
|
505
505
|
kind: "literal-json-skeleton",
|
|
506
|
-
where: "driver/stages.mjs:
|
|
506
|
+
where: "driver/stages.mjs:3237",
|
|
507
507
|
surface: "stage-message",
|
|
508
508
|
evidence: "- source: {\"source_type\",\"resolved_link\"}. source_type EXACTLY one of: register-vendor / register-euipo / common-law-marketplace / common-law-web / case-law",
|
|
509
509
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson",
|
|
@@ -512,7 +512,7 @@ export const E3_BACKLOG = [
|
|
|
512
512
|
{
|
|
513
513
|
stage: "synthesis",
|
|
514
514
|
kind: "exactly-these-keys",
|
|
515
|
-
where: "driver/stages.mjs:
|
|
515
|
+
where: "driver/stages.mjs:3238",
|
|
516
516
|
surface: "stage-message",
|
|
517
517
|
evidence: "coverage[]: ONE object per coverage AREA, EXACTLY {\"area\",\"state\",\"note\"}. … state EXACTLY one of: confirmed-clean / coverage-limited / open / not-searched / note.",
|
|
518
518
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson; the render owns the coverage panel from these typed states",
|
|
@@ -521,7 +521,7 @@ export const E3_BACKLOG = [
|
|
|
521
521
|
{
|
|
522
522
|
stage: "synthesis",
|
|
523
523
|
kind: "literal-json-skeleton",
|
|
524
|
-
where: "driver/stages.mjs:
|
|
524
|
+
where: "driver/stages.mjs:3247",
|
|
525
525
|
surface: "stage-message",
|
|
526
526
|
evidence: "use_check = {\"source\",\"quality\"}: … quality: OPTIONAL, EXACTLY one of owner-site / independent / register-mirror … own_rights = {\"source\"}",
|
|
527
527
|
reparsedBy: "driver/verify.mjs:988 checkFindingsSibling (finding_use_check_missing); driver/own-rights.mjs:19-22",
|
|
@@ -530,7 +530,7 @@ export const E3_BACKLOG = [
|
|
|
530
530
|
{
|
|
531
531
|
stage: "synthesis",
|
|
532
532
|
kind: "literal-json-skeleton",
|
|
533
|
-
where: "driver/stages.mjs:
|
|
533
|
+
where: "driver/stages.mjs:3304",
|
|
534
534
|
surface: "stage-message",
|
|
535
535
|
evidence: "MARK ASSESSMENT … STRUCTURED FORM …: either field may instead be an OBJECT {\"read\":\"…\",\"spectrum\":\"…\",\"per_class\":[{\"class\":\"5\",\"note\":\"…\"}],\"per_market\":[{\"market\":\"CN\",\"note\":\"…\"}],\"counter_registrations\":[{\"mark\":\"…\",\"uri\":\"/mark/…\",\"note\":\"…\"}],\"acquired\":\"<optional>\",\"note\":\"<optional residual>",
|
|
536
536
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson; the report collapses the rows behind toggles and the audit workbook renders them",
|
|
@@ -539,7 +539,7 @@ export const E3_BACKLOG = [
|
|
|
539
539
|
{
|
|
540
540
|
stage: "synthesis",
|
|
541
541
|
kind: "literal-json-skeleton",
|
|
542
|
-
where: "driver/stages.mjs:
|
|
542
|
+
where: "driver/stages.mjs:3310",
|
|
543
543
|
surface: "stage-message",
|
|
544
544
|
evidence: "FOUR ANSWERS …: \"four_answers\": {\"third_party_rights\":{...},\"objection_likelihood\":{...},\"registrability\":{...},\"client_enforceability\":{...}} … Each answer … is {\"read\":\"…\",\"token\":\"…\",\"basis\":\"…\",\"ordinals\":[…]}. Tokens (closed enums …): third_party_rights = strong|moderate|weak; objection_likelih",
|
|
545
545
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson",
|
|
@@ -548,7 +548,7 @@ export const E3_BACKLOG = [
|
|
|
548
548
|
{
|
|
549
549
|
stage: "synthesis",
|
|
550
550
|
kind: "literal-json-skeleton",
|
|
551
|
-
where: "driver/stages.mjs:
|
|
551
|
+
where: "driver/stages.mjs:3221",
|
|
552
552
|
surface: "stage-message",
|
|
553
553
|
evidence: "ACTIONS REGISTER …: emit \"actions\": [...] — ONE object per forward step …, each EXACTLY {\"id\",\"kind\",\"text\",\"ordinals\"} plus an OPTIONAL \"deadline\" and an OPTIONAL \"condition\". … kind: EXACTLY one of — consent / coexistence-agreement / territorial-delimitation / goods-amendment / mark-modification /",
|
|
554
554
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson; pipeline applyCoverageFloor legalActions arm derives the delivered disposition from the closed kind enum",
|
|
@@ -557,7 +557,7 @@ export const E3_BACKLOG = [
|
|
|
557
557
|
{
|
|
558
558
|
stage: "synthesis",
|
|
559
559
|
kind: "exactly-these-keys",
|
|
560
|
-
where: "driver/stages.mjs:
|
|
560
|
+
where: "driver/stages.mjs:3317",
|
|
561
561
|
surface: "stage-message",
|
|
562
562
|
evidence: "COVERAGE JUDGMENT …: emit \"coverage_judgment\": {\"sufficient\":<bool>, \"reason\":\"<one line…>\"} — EXACTLY those two keys. Do NOT emit \"rows\": the driver writes that register itself … anything you type there is replaced wholesale.",
|
|
563
563
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson. The \"Do NOT emit rows\" clause is the purest E3 case in the tree — the prompt names a field, dictates its shape and states in the same breath that code overwrites it",
|
|
@@ -566,7 +566,7 @@ export const E3_BACKLOG = [
|
|
|
566
566
|
{
|
|
567
567
|
stage: "synthesis",
|
|
568
568
|
kind: "literal-json-skeleton",
|
|
569
|
-
where: "driver/stages.mjs:
|
|
569
|
+
where: "driver/stages.mjs:3160",
|
|
570
570
|
surface: "stage-message",
|
|
571
571
|
// RE-QUOTED, NOT PARKED. The writer's conversion reworded this dictation — the
|
|
572
572
|
// ask answers ride the findings RECORD now and the driver renders the labelled line into both the
|
|
@@ -590,7 +590,7 @@ export const E3_BACKLOG = [
|
|
|
590
590
|
{
|
|
591
591
|
stage: "synthesis",
|
|
592
592
|
kind: "dictated-line-shape",
|
|
593
|
-
where: "driver/stages.mjs:
|
|
593
|
+
where: "driver/stages.mjs:3081 (restated at driver/skills/prelim-search/synthesis-rules.md:428)",
|
|
594
594
|
surface: "stage-message",
|
|
595
595
|
evidence: "END that finding's actual-use line with a literal \"- **Use-check source:** <result URL | \"perplexity_research — no result\">\" line",
|
|
596
596
|
reparsedBy: "driver/verify.mjs validators.narrative (spec-11 hard reject); the repair hint re-dictates the literal at driver/gateway.mjs:2153",
|
|
@@ -599,7 +599,7 @@ export const E3_BACKLOG = [
|
|
|
599
599
|
{
|
|
600
600
|
stage: "synthesis",
|
|
601
601
|
kind: "dictated-line-shape",
|
|
602
|
-
where: "driver/stages.mjs:
|
|
602
|
+
where: "driver/stages.mjs:3094 (restated at driver/skills/prelim-search/synthesis-rules.md:475)",
|
|
603
603
|
surface: "stage-message",
|
|
604
604
|
evidence: "END that finding's reasoning with a literal \"- **Own-rights source:** <record URI(s) | \"no applicant-owned registrations in the searched register material\">\" line",
|
|
605
605
|
reparsedBy: "driver/own-rights.mjs:19-22 — \"This module only requires the 'Own-rights source:' line to exist\"; repair hint at driver/gateway.mjs:2361 (the `own_rights_missing` branch; re-verified 2026-08-29 — the old :1736 predated this branch and pointed into the A4 repeat-signature block)",
|
|
@@ -608,7 +608,7 @@ export const E3_BACKLOG = [
|
|
|
608
608
|
{
|
|
609
609
|
stage: "synthesis",
|
|
610
610
|
kind: "exactly-these-keys",
|
|
611
|
-
where: "driver/stages.mjs:
|
|
611
|
+
where: "driver/stages.mjs:3296",
|
|
612
612
|
surface: "stage-message",
|
|
613
613
|
evidence: "add it to the top-level \"context_notes\" array — each object EXACTLY {\"type\":\"famous-neighbour-ungrounded\",\"mark\",\"owner\",\"context\"}",
|
|
614
614
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson",
|
|
@@ -617,7 +617,7 @@ export const E3_BACKLOG = [
|
|
|
617
617
|
{
|
|
618
618
|
stage: "synthesis",
|
|
619
619
|
kind: "literal-json-skeleton",
|
|
620
|
-
where: "driver/stages.mjs:
|
|
620
|
+
where: "driver/stages.mjs:3184",
|
|
621
621
|
surface: "stage-message",
|
|
622
622
|
evidence: "- owner: {\"name\",\"country\",\"registrations\":[...]}. … Each registration: {\"uri\", optionally \"classes\":[\"9\",\"41\"],\"status\",\"filed\",\"expiry\",\"jurisdiction\"}. The \"uri\" is the ONLY field that matters: the driver BINDS classes/status/filed/expiry/jurisdiction AND the owner name from the FETCHED record ke",
|
|
623
623
|
reparsedBy: "driver/findings-model.mjs:813 parseFindingsJson + the record-binding join. Six of the seven keys are stated in the prompt and overwritten by code in the same sentence",
|
|
@@ -626,7 +626,7 @@ export const E3_BACKLOG = [
|
|
|
626
626
|
{
|
|
627
627
|
stage: "case-law",
|
|
628
628
|
kind: "literal-json-skeleton",
|
|
629
|
-
where: "driver/stages.mjs:
|
|
629
|
+
where: "driver/stages.mjs:3466",
|
|
630
630
|
surface: "stage-message",
|
|
631
631
|
evidence: "ALSO write the RETRIEVAL RECORD to <path> — a JSON OBJECT with EXACTLY these keys: {\"schema_version\":1,\"queries\":[{\"query\":\"<the search you dispatched, verbatim>\",\"jurisdiction\":\"…\",\"results\":<how many hits it returned>}, …],\"citations\":[{\"proceeding\":\"…\",\"forum\":\"…\",\"jurisdiction\":\"…\",\"decided\":\"…\"",
|
|
632
632
|
reparsedBy: "driver/verify.mjs validators.caseLaw — the ledger arm, armed by the stage-contract marker `citations` (stages.mjs:1820)",
|
|
@@ -635,7 +635,7 @@ export const E3_BACKLOG = [
|
|
|
635
635
|
{
|
|
636
636
|
stage: "case-law",
|
|
637
637
|
kind: "dictated-line-shape",
|
|
638
|
-
where: "driver/stages.mjs:
|
|
638
|
+
where: "driver/stages.mjs:3474",
|
|
639
639
|
surface: "stage-message",
|
|
640
640
|
evidence: "EVERY \"Grounded profile\" section MUST start its body with the line \"- ord: <N>\" naming which finding it grounds (use the ordinal from this list; a profile that grounds no listed finding omits the line)",
|
|
641
641
|
reparsedBy: "driver/publish/parse.mjs:339 parseCaseLawProfiles (\"the optional '- ord: <N>' first body line … gives an EXACT join\"); driver/findings-model.mjs:273 /^-\\s*ord:\\s*(\\d+)\\s*$/m; driver/publish/index.mjs:778 runOrigins",
|
|
@@ -669,7 +669,7 @@ export const E3_BACKLOG = [
|
|
|
669
669
|
{
|
|
670
670
|
stage: "narrative-refutation",
|
|
671
671
|
kind: "dictated-line-shape",
|
|
672
|
-
where: "driver/stages.mjs:
|
|
672
|
+
where: "driver/stages.mjs:3606",
|
|
673
673
|
surface: "stage-message",
|
|
674
674
|
// RE-QUOTED BY CONVERSION 9. The LINE-TOKEN half is gone — no "anywhere on the line", no "[kind: …]
|
|
675
675
|
// token", no "a line with no token is treated as fact", because a kind is a typed field now and an
|
|
@@ -684,7 +684,7 @@ export const E3_BACKLOG = [
|
|
|
684
684
|
// because an un-anchorable row lands in the NOT-CHECKED slice, and that is coverage lost rather than
|
|
685
685
|
// a pass.
|
|
686
686
|
evidence: "is ONE of coverage-disposition | fact | rating | narrative — pick the one your own legal read says the correction IS: coverage-disposition (a coverage row / disposition placement is wrong or dishonest)",
|
|
687
|
-
reparsedBy: "driver/verify.mjs
|
|
687
|
+
reparsedBy: "driver/verify.mjs CORRECTION_KIND_RE = /\\[kind:\\s*([a-z][a-z-]*)\\s*\\]/i → parseCorrectionKinds (verify.mjs), consumed in pipelineInner() in pipeline.mjs for the run.jsonl `correction-kinds` histogram, which since #1558 also carries `kindChannelOk` — the counts are DERIVED from the parsed rows, and that key states whether the reviewer's kind channel produced anything at all rather than leaving a reader to infer it by comparing untyped against total. Telemetry only today",
|
|
688
688
|
removedByMove: "NOTHING ON THE #850 PLAN REMOVES THIS",
|
|
689
689
|
},
|
|
690
690
|
{
|
|
@@ -768,7 +768,7 @@ export const E3_BACKLOG = [
|
|
|
768
768
|
{
|
|
769
769
|
stage: "report-card",
|
|
770
770
|
kind: "literal-json-skeleton",
|
|
771
|
-
where: "driver/stages.mjs:
|
|
771
|
+
where: "driver/stages.mjs:3915",
|
|
772
772
|
surface: "stage-message",
|
|
773
773
|
evidence: "The finding's OWN record — the ONLY source for this card …:\\n```json\\n<JSON.stringify(finding, null, 2)>\\n```",
|
|
774
774
|
reparsedBy: "none — this is the INPUT side, and that is why it belongs in the survey: a full JSON object rendered into the prompt is exactly the mechanism #850 proves produced R-RECEIPT (the model pattern-matches a shown shape). E3's clause 1 as written (\"a code fence or inline example showing the exact object shape the model must emit\") does not reach an injected record, so the lint needs an explicit rule for shown-but-not-owed structure",
|
|
@@ -858,7 +858,7 @@ export const E3_EVIDENCE_UNRESOLVED = [
|
|
|
858
858
|
// absorbed. It was the narrative "## Answers to your instructions" row deleted above: its dictation is
|
|
859
859
|
// gone, so there is no un-anchorable quote left to be unresolved. The one that REMAINS is a live row
|
|
860
860
|
// whose quote spans a template line. Measured before deleting, not predicted — two rows shared
|
|
861
|
-
// `where: "driver/stages.mjs:
|
|
861
|
+
// `where: "driver/stages.mjs:3049"`, so which one occupied this slot could not be read off the strings.
|
|
862
862
|
"synthesis|driver/stages.mjs",
|
|
863
863
|
];
|
|
864
864
|
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
// D4 verify.mjs parseCoverageLedgerJson, same shape
|
|
22
22
|
// D5 verify.mjs:1504 fail(`${unaccounted[0].token}:…`) — token minted in a DATA ROW
|
|
23
23
|
// D6 verify.mjs:1567 fail(`${violations[0].token}…`) — validatePlanFeasibility in register-plan.mjs
|
|
24
|
-
// D7 verify.mjs:1558 fail(`${v2[0].token}${detail}…`) — register-plan.mjs:
|
|
25
|
-
// D8 verify.mjs:
|
|
24
|
+
// D7 verify.mjs:1558 fail(`${v2[0].token}${detail}…`) — register-plan.mjs:2183 disclosureTextByAxis
|
|
25
|
+
// D8 verify.mjs:2470 caseLawLedgerFail fail(caseLawLedgerFail(…)) — token built in case-law-ledger.mjs:195 caseLawLedgerFail
|
|
26
26
|
//
|
|
27
27
|
// A partition built on the 60 tokens a regex CAN see would run green while blind to the rest, which is
|
|
28
28
|
// worse than having no E2 at all: it certifies a partition it never checked. So the census is authored
|
|
@@ -70,7 +70,7 @@ export const VOCABULARY = [
|
|
|
70
70
|
// ── common-law / common-law-half ───────────────────────────────────────────────────────────────────
|
|
71
71
|
{ token: "declared_unavailable", stages: CL, site: "driver/verify.mjs" },
|
|
72
72
|
{ token: "grid_spec_unreadable", stages: CL, site: "driver/verify.mjs:257" },
|
|
73
|
-
{ token: "grid_ledger_missing", stages: CL, site: "driver/verify.mjs
|
|
73
|
+
{ token: "grid_ledger_missing", stages: CL, site: "driver/verify.mjs commonLawMeaningSeat" },
|
|
74
74
|
{ token: "grid_ledger_unparseable", stages: CL, site: "driver/verify.mjs:266" },
|
|
75
75
|
{ token: "connotation_query_unrecorded", stages: ["common-law-half"], site: "driver/verify.mjs" },
|
|
76
76
|
{ token: "profile_unparseable", stages: ["common-law"], site: "driver/verify.mjs" },
|
|
@@ -102,6 +102,36 @@ export const VOCABULARY = [
|
|
|
102
102
|
{ token: "finding", stages: ["synthesis"], site: "driver/verify.mjs", family: "driver/findings-model.mjs (token-first throws; `finding_*` and `findings_*`)", dynamic: "D2" },
|
|
103
103
|
|
|
104
104
|
// ── register-digest ────────────────────────────────────────────────────────────────────────────────
|
|
105
|
+
// The per-record accounting family, raised at the EXIT as well as at the call. The call-time refusal
|
|
106
|
+
// is scoped to the batch it judges, which is what lets a dense band be recorded at all; the exit gate
|
|
107
|
+
// is where that is paid for, because once any batch is accepted a document exists and half a band is
|
|
108
|
+
// the same SHAPE as a whole one. All three are armed by the era stamp, so an archived run raises none.
|
|
109
|
+
{ token: "registerdigest_unaccounted_records", stages: ["register-digest"], site: "driver/verify.mjs, and driver/register-digest-record.mjs at the call" },
|
|
110
|
+
{ token: "registerdigest_accounting_unreadable", stages: ["register-digest"], site: "driver/verify.mjs — driver-written, not a model defect" },
|
|
111
|
+
{ token: "registerdigest_model_missing", stages: ["register-digest"], site: "driver/verify.mjs — driver-written, not a model defect" },
|
|
112
|
+
// ── THE TYPED TRANSPORT'S OWN FAMILY (conversion 11) ──────────────────────────────────────────────
|
|
113
|
+
//
|
|
114
|
+
// These are raised by `register-digest-record.mjs` at the ACCEPTANCE BOUNDARY, not by verify.mjs, and
|
|
115
|
+
// they became visible to this census only when verify.mjs began reaching into that module for the
|
|
116
|
+
// digest's exit gate. They existed and were emitted for months before that; nothing was wrong with
|
|
117
|
+
// them, and nothing here changes behaviour. What changes is that the census can now see the family,
|
|
118
|
+
// which is the point of listing the module: a family the tripwire cannot read can grow a member no
|
|
119
|
+
// row covers, and nobody finds out.
|
|
120
|
+
{ token: "registerdigest_uri_missing", stages: ["register-digest"], site: "driver/register-digest-record.mjs — every row joins to a band record by its uri" },
|
|
121
|
+
{ token: "registerdigest_uri_unknown", stages: ["register-digest"], site: "driver/register-digest-record.mjs — a uri this run's band does not carry" },
|
|
122
|
+
{ token: "registerdigest_flag_reason_missing", stages: ["register-digest"], site: "driver/register-digest-record.mjs — the judgment the row exists to carry" },
|
|
123
|
+
{ token: "registerdigest_verify_invalid", stages: ["register-digest"], site: "driver/register-digest-record.mjs — one bare token of yes/no" },
|
|
124
|
+
{ token: "registerdigest_drop_reason_missing", stages: ["register-digest"], site: "driver/register-digest-record.mjs — a drop with no stated reason is a silent recall loss" },
|
|
125
|
+
{ token: "registerdigest_drop_ground_invalid", stages: ["register-digest"], site: "driver/register-digest-record.mjs — the closed ground token" },
|
|
126
|
+
{ token: "registerdigest_drop_ground_contradicted", stages: ["register-digest"], site: "driver/register-digest-record.mjs — the ground contradicts this run's own screen verdict" },
|
|
127
|
+
{ token: "registerdigest_instructed_incomplete", stages: ["register-digest"], site: "driver/register-digest-record.mjs — every instructed check carries ask AND answer" },
|
|
128
|
+
{ token: "registerdigest_adjudication_invalid", stages: ["register-digest"], site: "driver/register-digest-record.mjs — one bare token of ADOPTED/OVERRODE" },
|
|
129
|
+
{ token: "registerdigest_adjudication_incomplete", stages: ["register-digest"], site: "driver/register-digest-record.mjs — an override quotes the reason it contradicts" },
|
|
130
|
+
{ token: "registerdigest_nothing_judged", stages: ["register-digest"], site: "driver/register-digest-record.mjs — a digest that ends no record has not read the band" },
|
|
131
|
+
// The batching members, added with the batched accounting itself.
|
|
132
|
+
{ token: "registerdigest_batch_unknown", stages: ["register-digest"], site: "driver/register-digest-record.mjs — a batch number this run's split does not hold" },
|
|
133
|
+
{ token: "registerdigest_double_counted", stages: ["register-digest"], site: "driver/register-digest-record.mjs — a record ended under one batch cannot be ended under another" },
|
|
134
|
+
{ token: "registerdigest_model_write_failed", stages: ["register-digest"], site: "driver/register-digest-record.mjs — driver-written: the accumulator was lost mid-batch" },
|
|
105
135
|
{ token: "coverage_form_damaged", stages: ["register-digest"], site: "driver/verify.mjs" },
|
|
106
136
|
{ token: "coverage_form_engine_vocabulary", stages: ["register-digest"], site: "driver/verify.mjs" },
|
|
107
137
|
{ token: "coverage_form_axis_invalid", stages: ["register-digest"], site: "driver/verify.mjs" },
|
|
@@ -109,10 +139,10 @@ export const VOCABULARY = [
|
|
|
109
139
|
{ token: "coverage_form_missing", stages: ["register-digest"], site: "driver/verify.mjs" },
|
|
110
140
|
{ token: "coverage_form_empty", stages: ["register-digest"], site: "driver/verify.mjs" },
|
|
111
141
|
{ token: "coverage_status_offenum", stages: ["register-digest"], site: "driver/verify.mjs:2050" },
|
|
112
|
-
{ token: "coverage_deferred_unaccounted", stages: ["register-digest"], site: "driver/verify.mjs
|
|
113
|
-
{ token: "coverage_clean_unexecuted", stages: ["register-digest"], site: "driver/verify.mjs, the matterContext validator", family: "driver/register-plan.mjs:
|
|
114
|
-
{ token: "coverage_clean_skipped", stages: ["register-digest"], site: "driver/verify.mjs, the matterContext validator", family: "driver/register-plan.mjs:
|
|
115
|
-
{ token: "coverage_clean_unverified_incomplete", stages: ["register-digest"], site: "driver/verify.mjs, the matterContext validator", family: "driver/register-plan.mjs:
|
|
142
|
+
{ token: "coverage_deferred_unaccounted", stages: ["register-digest"], site: "driver/verify.mjs coverageFormFail", family: "driver/register-plan.mjs:1860 PROVIDER_HARD_ERROR_PREFIX — token on a data row", dynamic: "D5" },
|
|
143
|
+
{ token: "coverage_clean_unexecuted", stages: ["register-digest"], site: "driver/verify.mjs, the matterContext validator", family: "driver/register-plan.mjs:1594 validatePlanFeasibility", dynamic: "D6" },
|
|
144
|
+
{ token: "coverage_clean_skipped", stages: ["register-digest"], site: "driver/verify.mjs, the matterContext validator", family: "driver/register-plan.mjs:1955 searchedJurisdictionsFromPlan", dynamic: "D6" },
|
|
145
|
+
{ token: "coverage_clean_unverified_incomplete", stages: ["register-digest"], site: "driver/verify.mjs, the matterContext validator", family: "driver/register-plan.mjs:2183 disclosureTextByAxis", dynamic: "D7" },
|
|
116
146
|
{ token: "coverage_clean_tainted", stages: ["register-digest"], site: "driver/verify.mjs" },
|
|
117
147
|
{ token: "coverage_ledger_", stages: ["register-digest"], site: "driver/verify.mjs", family: "driver/coverage-ledger.mjs (parseCoverageLedgerJson token-first throws)", dynamic: "D4" },
|
|
118
148
|
{ token: "coverage_key_unknown", stages: ["register-digest"], site: "driver/verify.mjs", family: "driver/coverage-ledger.mjs", dynamic: "D4" },
|
|
@@ -430,7 +460,7 @@ export const INNER_CODES = Object.freeze([
|
|
|
430
460
|
{ code: "call_partial", mints: ["driver/connotation-search.mjs:2055"], rollsUpTo: ["connotation_call_partial"],
|
|
431
461
|
why: "As call_never_made — same table, same projection. This is the pair #1211 cites as its worked example: the composite is covered, the bare form reaches no stage." },
|
|
432
462
|
{ code: "quote_unbound", mints: ["driver/connotation-search.mjs:2186"], rollsUpTo: ["connotation_quote_unbound"],
|
|
433
|
-
why: "The ruled-but-unbound row. Projected at verify.mjs:
|
|
463
|
+
why: "The ruled-but-unbound row. Projected at verify.mjs:1450 unbound, and reported only once nothing is unruled." },
|
|
434
464
|
{ code: "token_absent", mints: ["driver/connotation-search.mjs:2213"], rollsUpTo: ["connotation_token_absent"],
|
|
435
465
|
why: "#592 split this out of no_ruling. Row-level only — repairs.mjs:352 says so in as many words: `never a top-level token`." },
|
|
436
466
|
{ code: "cite_absent", mints: ["driver/connotation-search.mjs:2222"], rollsUpTo: ["connotation_cite_absent"],
|
|
@@ -441,9 +471,9 @@ export const INNER_CODES = Object.freeze([
|
|
|
441
471
|
// data rather than deriving it. Every derivation anyone would write is `connotation_` + the code, and
|
|
442
472
|
// for this row that produces `connotation_no_recorded_queries`, which nothing mints and nothing covers.
|
|
443
473
|
// verify.mjs:912-913 states the ruling: a sweep that did not RUN is a canonical-only decision with its
|
|
444
|
-
// own token and its own remedy, so the projector
|
|
474
|
+
// own token and its own remedy, so the projector beside verify.mjs's CORRECTIONS_SECTION_RE deliberately does not handle it.
|
|
445
475
|
{ code: "no_recorded_queries", mints: ["driver/connotation-search.mjs:2070"], rollsUpTo: ["connotation_search_missing"],
|
|
446
|
-
why: "RENAMED, not namespaced: verify.mjs emits `connotation_search_missing`. It is excluded from CONNOTATION_FORM_REASONS at connotation-search.mjs
|
|
476
|
+
why: "RENAMED, not namespaced: verify.mjs emits `connotation_search_missing`. It is excluded from CONNOTATION_FORM_REASONS at connotation-search.mjs for exactly this reason." },
|
|
447
477
|
|
|
448
478
|
// ── case-law-ledger.mjs — ONE token, the codes as census payload ─────────────────────────────────
|
|
449
479
|
//
|
|
@@ -526,6 +556,10 @@ export const COVERED_SOURCES = [
|
|
|
526
556
|
"report-overview-record.mjs",
|
|
527
557
|
// Conversion 5 — the fan-out transport; it mints its own family including the bound-index refusals.
|
|
528
558
|
"report-card-record.mjs",
|
|
559
|
+
// Conversion 11 — verify.mjs now reaches `digestAccountingGap`, the digest's exit gate, so the
|
|
560
|
+
// tripwire must read this module's token literals too. Without it the accounting family could grow a
|
|
561
|
+
// member that no vocabulary row covers and nothing would notice, which is this list's whole subject.
|
|
562
|
+
"register-digest-record.mjs",
|
|
529
563
|
];
|
|
530
564
|
|
|
531
565
|
/**
|