clearotron 0.4.0-beta.0 → 0.4.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/.env.example +9 -0
  2. package/bin/update.mjs +6 -1
  3. package/build-info.json +2 -2
  4. package/docs/architecture/04-configuration-reference.md +2 -6
  5. package/driver/CHANGELOG.md +10 -0
  6. package/driver/ask-ledger.mjs +2 -2
  7. package/driver/band-shape.mjs +8 -8
  8. package/driver/blind-frame-model.mjs +1 -1
  9. package/driver/common-law-receipts.mjs +2 -2
  10. package/driver/commonlaw-carry.mjs +2 -2
  11. package/driver/connotation-search.mjs +4 -4
  12. package/driver/contract-e3-backlog.mjs +3 -3
  13. package/driver/declination-call.mjs +1 -1
  14. package/driver/declination-tool.mjs +1 -1
  15. package/driver/dev-portal.mjs +1 -1
  16. package/driver/driver.config.mjs +16 -9
  17. package/driver/e2e/README.md +1 -1
  18. package/driver/engine/mcp/clarivate-server.mjs +2 -1
  19. package/driver/engine/mcp/corsearch-server.mjs +1 -0
  20. package/driver/engine/mcp/euipo-server.mjs +1 -0
  21. package/driver/engine/mcp/free-tier-server.mjs +1 -1
  22. package/driver/engine/mcp/gather-config.mjs +1 -1
  23. package/driver/engine/mcp/perplexity-server.mjs +1 -1
  24. package/driver/engine/mcp/recording-server.mjs +1 -1
  25. package/driver/engine/mcp/signa-server.mjs +1 -0
  26. package/driver/engine/mcp/supplemental.mjs +1 -1
  27. package/driver/engine/mcp/uspto-local-server.mjs +1 -0
  28. package/driver/enqueue-schema.mjs +2 -2
  29. package/driver/feedback-issues.mjs +1 -1
  30. package/driver/feedback-store.mjs +1 -1
  31. package/driver/findings-model.mjs +3 -3
  32. package/driver/flag-snapshot.mjs +1 -1
  33. package/driver/floor-duty.mjs +2 -2
  34. package/driver/form-neighbourhood.mjs +47 -15
  35. package/driver/frame-diff-model.mjs +3 -3
  36. package/driver/gateway.mjs +5 -5
  37. package/driver/jx-lanes.mjs +1 -1
  38. package/driver/known-conflicts.mjs +18 -0
  39. package/driver/log.mjs +2 -2
  40. package/driver/package.json +1 -1
  41. package/driver/pipeline-knockout.mjs +129 -95
  42. package/driver/pipeline.mjs +55 -27
  43. package/driver/placement-carry.mjs +2 -2
  44. package/driver/placement-form.mjs +1 -1
  45. package/driver/portal-service.mjs +2 -2
  46. package/driver/predelivery-lint.mjs +10 -10
  47. package/driver/progress.mjs +1 -1
  48. package/driver/provider-usage.mjs +24 -1
  49. package/driver/publish/index.mjs +4 -4
  50. package/driver/publish/knockout.mjs +3 -2
  51. package/driver/publish/render-knockout.mjs +1 -1
  52. package/driver/publish/render.mjs +1 -1
  53. package/driver/recall-reconciliation.mjs +1 -1
  54. package/driver/record-carry.mjs +6 -6
  55. package/driver/recording-agreement.mjs +2 -2
  56. package/driver/reference-score.mjs +27 -27
  57. package/driver/register-count.mjs +56 -1
  58. package/driver/register-digest-record.mjs +1 -1
  59. package/driver/register-plan.mjs +5 -5
  60. package/driver/register-records.mjs +10 -1
  61. package/driver/registry-fidelity.mjs +4 -4
  62. package/driver/repair-composers.mjs +6 -6
  63. package/driver/run-economics.mjs +1 -1
  64. package/driver/screen-gate.mjs +1 -1
  65. package/driver/skills/blind-frame/SKILL.md +2 -2
  66. package/driver/skills/clearance-common-law/SKILL.md +2 -2
  67. package/driver/skills/clearance-common-law/perplexity-prompts.md +4 -4
  68. package/driver/skills/clearance-register/digest.md +1 -1
  69. package/driver/skills/clearance-register/unit.md +1 -1
  70. package/driver/skills/clearance-search/report-prose.md +5 -5
  71. package/driver/skills/clearance-search/synthesis-rules.md +4 -4
  72. package/driver/skills/clearance-variants/SKILL.md +2 -2
  73. package/driver/skills/clearance-variants/transliteration-scripts.md +1 -1
  74. package/driver/skills/frame-diff/SKILL.md +2 -2
  75. package/driver/skills/knockout-assess/SKILL.md +9 -9
  76. package/driver/skills/matter-frame/watchlist-reference.md +1 -1
  77. package/driver/skills/narrative-refutation/SKILL.md +2 -2
  78. package/driver/skills/placement-inquiry/SKILL.md +1 -1
  79. package/driver/stage-context.mjs +4 -4
  80. package/driver/stages.mjs +23 -15
  81. package/driver/suite-census.json +84 -18
  82. package/driver/systemd/clearotron-client-mcp.service +24 -0
  83. package/driver/systemd/clearotron-mcp-face.service +24 -0
  84. package/driver/systemd/clearotron-portal.service +24 -0
  85. package/driver/systemd/clearotron-worker.service +24 -0
  86. package/driver/tokens.mjs +8 -7
  87. package/driver/turnaround-bands.mjs +1 -1
  88. package/driver/unit-inventory.mjs +3 -3
  89. package/driver/variant-manifest-model.mjs +1 -1
  90. package/driver/verify.mjs +2 -2
  91. package/driver/whatif-memo-run.mjs +1 -1
  92. package/mcp-server/CHANGELOG.md +4 -0
  93. package/mcp-server/package.json +1 -1
  94. package/mcp-server/server.mjs +1 -1
  95. package/package.json +1 -1
  96. package/portal-ui/dist/assets/{index-DVtz44vH.js → index-D_O_55vK.js} +2 -1
  97. package/portal-ui/dist/index.html +1 -1
  98. package/portal-ui/package.json +1 -1
  99. package/providers/_shared/README.md +1 -1
  100. package/providers/_shared/answer-memory.mjs +199 -0
  101. package/providers/_shared/ledger-path.mjs +1 -1
  102. package/providers/_shared/ledger.mjs +47 -5
  103. package/providers/_shared/script-form.mjs +24 -5
  104. package/providers/_shared/term-shape.mjs +5 -5
  105. package/providers/clarivate/src/capabilities.js +11 -0
  106. package/providers/clarivate/src/core.js +140 -13
  107. package/providers/jx-subclass/lookup.mjs +1 -1
  108. package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
  109. package/providers/oauth-mcp-bridge/package.json +1 -1
  110. package/providers/signa/src/capabilities.js +24 -0
  111. package/providers/signa/src/core.js +66 -0
  112. package/scripts/deprecate-below.mjs +114 -2
  113. package/scripts/release-entry-catch-up.mjs +77 -8
  114. package/scripts/release-note-required.mjs +102 -6
  115. package/scripts/release-rehearsal-version.mjs +60 -0
  116. package/scripts/release-sbom.mjs +104 -0
  117. package/scripts/release-visible-check.mjs +7 -5
  118. package/scripts/score.mjs +3 -3
  119. package/shared/brand.mjs +1 -1
  120. package/shared/driver-dir.mjs +20 -9
  121. package/shared/names-in-force.mjs +2 -0
package/.env.example CHANGED
@@ -265,6 +265,15 @@ CLARIVATE_API_KEY=changeme
265
265
  # Signa.
266
266
  SIGNA_API_KEY=changeme
267
267
  #
268
+ # The run memory: within one run, reuse an answer the register already gave instead of asking again.
269
+ # Signa's starts off: `watch` still sends every request and records whether a held answer would have
270
+ # matched, and `on` reuses held answers. Clarivate's starts on, and `off` asks every time. Read when a run
271
+ # starts, by providers/_shared/answer-memory.mjs.
272
+ # effect: tuning
273
+ CLEAROTRON_SIGNA_ANSWER_MEMORY=off
274
+ # effect: tuning
275
+ CLEAROTRON_CLARIVATE_ANSWER_MEMORY=on
276
+ #
268
277
  # USPTO, local — the free US source, and the only one here that is not a paid vendor. TWO
269
278
  # variables, and they are needed at different moments, which is why neither substitutes for the other.
270
279
  #
package/bin/update.mjs CHANGED
@@ -383,7 +383,12 @@ export async function update(argv = process.argv.slice(2)) {
383
383
  return pulled;
384
384
  }
385
385
 
386
- const installed = runInCheckout("npm", ["ci"]);
386
+ // NO INSTALL SCRIPTS. A dependency's install script runs with everything this account can reach, and an
387
+ // update fetches whatever the registry serves that day. None is needed here: the only dependency that
388
+ // carries one is optional and macOS-only, and this package's own two are the Node floor, which the CLI
389
+ // checks at every start, and a contributor's git hooks. Dev dependencies stay, because the portal
390
+ // bundle below is rebuilt from them.
391
+ const installed = runInCheckout("npm", ["ci", "--ignore-scripts"]);
387
392
  if (installed !== 0) {
388
393
  console.error("\n npm ci failed. The code is updated; its dependencies are not, so this install is");
389
394
  console.error(" in a half-updated state and should not be run until that command succeeds.\n");
package/build-info.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "commit": "1b114acfd84b91de944063c0f16a99d16652adce",
3
- "version": "0.4.0-beta.0"
2
+ "commit": "e60329390d653439053b900cf97b65e082e06622",
3
+ "version": "0.4.0-beta.1"
4
4
  }
@@ -138,12 +138,6 @@ id is what a dispatch row and a token-rollup row carry as the model *asked for*;
138
138
  the turn is recorded beside it, and the report names that. A version here would be a claim about a
139
139
  request nobody made, and wrong the day a newer model of the tier shipped.
140
140
 
141
- One consequence, accepted when this was decided: per-model totals are keyed on what was asked for,
142
- and the native-language lanes call the API directly, where a model id is required and a tier word is
143
- not accepted. So one model reached by a stage and by those lanes appears under two keys —
144
- `anthropic/claude-haiku` and `anthropic/claude-haiku-4-5`. They are different requests, and the split
145
- says so.
146
-
147
141
  The bottom four are **legacy names that no stage declares and no engine can run** — they resolve at
148
142
  level 1 and then throw at level 2 (below). They are catalogue entries, not available tiers.
149
143
 
@@ -248,6 +242,8 @@ deployment may override (verify live values per deployment).
248
242
  | `CLEAROTRON_MAX_CLAIM_AGE_MS` | 172800000 (48 h; 0 disables) | Hard ceiling on a claim's age (from the `.pid` sidecar mtime) — beyond it, re-claim regardless of liveness. |
249
243
  | `CLEAROTRON_KNOCKOUT_VARIANT_CAP` | unset (⇒ the lane's own cap) | Ceiling on variants a knockout screens per name. Set only to bound an unusually wide batch; absent means the lane decides. |
250
244
  | `CLEAROTRON_KNOCKOUT_RECORD_CAP` | unset (⇒ the lane's own cap) | Ceiling on records a knockout fetches per hit. Same shape as the variant cap: absent is the normal state. |
245
+ | `CLEAROTRON_SIGNA_ANSWER_MEMORY` | `off` | On the Signa register, whether a run reuses an answer it already holds instead of asking again. `off` asks every time. `watch` also asks every time, and records whether a held answer would have matched. `on` reuses held answers. |
246
+ | `CLEAROTRON_CLARIVATE_ANSWER_MEMORY` | `on` | On the Clarivate register, whether a run reuses a count, a search, an owner lookup or a record it already holds instead of asking again. `off` asks every time. |
251
247
 
252
248
  ### Retries, timeouts, watchdogs
253
249
 
@@ -1,5 +1,15 @@
1
1
  # clearotron-driver
2
2
 
3
+ ## 0.4.0-beta.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed: Clarivate clearances no longer count look-alike spellings that mix Latin with Greek or Cyrillic letters as searches that could not be completed.
8
+ - For operators: Clarivate clearances no longer fetch a record, or repeat a count, search or owner lookup, that the same run already made.
9
+ - For operators: Knockouts on Signa and Clarivate take their name and close-variation counts from the listing, so each is asked of the register once.
10
+ - Fixed: Knockouts on the Signa register now say how many register hits the listed filings were drawn from.
11
+ - Fixed: Clearances on the Signa register no longer search look-alike spellings that mix Latin with Greek or Cyrillic letters; those searches found only unrelated marks.
12
+
3
13
  ## 0.4.0-beta.0
4
14
 
5
15
  ### Minor Changes
@@ -179,7 +179,7 @@ function recallEnding(name, qid, join, ts) {
179
179
  if (discharges) return { ending, handoff: null };
180
180
  return {
181
181
  ending: null,
182
- handoff: `the probe ran and ${why} — a recall probe discharges on what came back, not on having run (#1349). `
182
+ handoff: `the probe ran and ${why} — a recall probe discharges on what came back, not on having run. `
183
183
  + `Ships OPEN in the audit's ask ledger for the reviewing lawyer.`,
184
184
  };
185
185
  }
@@ -601,7 +601,7 @@ const normMark = (s) => String(s ?? "").toLowerCase().replace(/[^a-z0-9]/g, "");
601
601
  * as immaterial only when the mark it went looking for is in the client's findings. Otherwise the mark
602
602
  * is owed a finding and the ask stays open.
603
603
  *
604
- * The defect this answers: a recall probe found OSLER DELPHI, the closure stage pointed at
604
+ * The defect this answers: a recall probe found HALVER KORPHI, the closure stage pointed at
605
605
  * `register-findings.md` — the run's own working sheet, where the mark genuinely IS reasoned — and the
606
606
  * ask closed. The sheet is a citable file and the citation was true. It is simply not the document the
607
607
  * client reads, and nothing checked that.
@@ -65,7 +65,7 @@ const tokensOf = (s) => String(s ?? "").split(/[^\p{L}\p{N}]+/u).map((t) => norm
65
65
 
66
66
  /**
67
67
  * The ALTERNATIVE NAMES a label carries — `VENZAL / VENZALMONO / VENZALKOMB` is one relabelled entry,
68
- * `CHROMA & Device` is one mark plus a device note.
68
+ * `LUMIVANE & Device` is one mark plus a device note.
69
69
  *
70
70
  * The separator class is reference-score's `labelAliases`, character for character, and the two are
71
71
  * meant to stay that way: the scorer and the engine must agree about what a relabelling is, or a record
@@ -175,7 +175,7 @@ export function classifyRecord(markText, targets) {
175
175
 
176
176
  // ── member 2 — A RELABELLED RECORD IS THE SAME MARK, AND IT WAS TIERING BELOW THE FLOOR ────────
177
177
  //
178
- // Measured against the scorer on `origin/main`: `VENZAL / VENZALMONO / VENZALKOMB` and `CHROMA &
178
+ // Measured against the scorer on `origin/main`: `VENZAL / VENZALMONO / VENZALKOMB` and `LUMIVANE &
179
179
  // Device` are `alias` to reference-score and `same-family / token-identical` here. Not dropped —
180
180
  // tiered BELOW the line. The floors take `identical` and `near-identical` only, so a register record
181
181
  // that IS the mark under a relabelling never became a row a lawyer had to answer. Same consequence as
@@ -184,7 +184,7 @@ export function classifyRecord(markText, targets) {
184
184
  // ALIAS SEPARATORS ONLY, and the distinction is reference-score's, kept deliberately identical
185
185
  // because the two must agree about what a relabelling IS: `/ , · & |` separate ALTERNATIVE NAMES for
186
186
  // one record; whitespace and hyphens separate WORDS WITHIN one name. Conflating them makes every
187
- // multi-word mark match its own first word — `TIKI TWIST` would become `TIKI`, which is a different
187
+ // multi-word mark match its own first word — `WAVO TWIST` would become `WAVO`, which is a different
188
188
  // proprietor's different mark and the collision the scorer's own doc block warns about. Whitespace is
189
189
  // NOT in the class here for exactly that reason.
190
190
  //
@@ -213,7 +213,7 @@ export function classifyRecord(markText, targets) {
213
213
  // The candidate set of the retrieved→judgment reconciliation: every LIVE, in-scope, SCREEN-SURFACED
214
214
  // record whose mark carries the manifest's dominant element — as a standalone token
215
215
  // (`token-identical`), a token one edit away (`token-edit-1`), or CONCATENATED inside a longer
216
- // squashed word (`concatenation` — the TIKITONK class: same-family in substance, "other" to the
216
+ // squashed word (`concatenation` — the WAVOTONK class: same-family in substance, "other" to the
217
217
  // token classifier, and the proven silent-death seam). Screen-surfaced only (screen_verdict
218
218
  // surface:*): the obligation this feeds is "everything the screen surfaced ends somewhere a reader
219
219
  // can see"; drop:* records were already ended by the screen with a policed drop row.
@@ -227,7 +227,7 @@ export function classifyRecord(markText, targets) {
227
227
  // itself never spells. They rank last so they never reached the top slice, but they inflate the
228
228
  // residual a declared crowd count must cover — a count written one short blocks the run (the
229
229
  // reviewer reproduced 378 declared vs 379 residual → blocked). A concatenation is a SQUASHED WORD
230
- // (TIKITONK), which is a property of one token.
230
+ // (WAVOTONK), which is a property of one token.
231
231
  export const MIN_CONCAT_LEN = 4;
232
232
 
233
233
  /**
@@ -323,8 +323,8 @@ export function dominantElementComposites(band, { dominantElement, inScopeClasse
323
323
  // identity, and the arithmetic becomes a cross-reference instead.
324
324
  // (2) owner identity is compared on a CORE + LEGAL-FORM pair, not on the suffix-stripped core
325
325
  // alone. Stripping entity words is what makes "Fairmile Snack Foods Corp." = "Fairmile Snack Foods
326
- // Corporation" work, but on the same band it also collapsed "Tiki Group Limited", "Tiki AG"
327
- // and "Tiki Corporation" to the bare core "tiki" and merged three distinct registrants on the
326
+ // Corporation" work, but on the same band it also collapsed "Wavo Group Limited", "Wavo AG"
327
+ // and "Wavo Corporation" to the bare core "wavo" and merged three distinct registrants on the
328
328
  // mark-owner edge alone. So: same core AND compatible legal forms (one side's form set a
329
329
  // SUBSET of the other's — a register that simply omits the form still matches, two different
330
330
  // stated forms never do).
@@ -359,7 +359,7 @@ export function ownerIdentical(a, b) {
359
359
  }
360
360
 
361
361
  /** The union-find bucket key for the mark+owner edge — core + the SORTED form set, so
362
- * "Tiki AG" and "Tiki Corporation" land in different buckets while "X Corp."/"X Corporation" share
362
+ * "Wavo AG" and "Wavo Corporation" land in different buckets while "X Corp."/"X Corporation" share
363
363
  * one. The subset relaxation (a register omitting the form) is applied by the second pass below. */
364
364
  const ownerKey = (s) => { const { core, forms } = ownerIdentity(s); return core ? `${core}|${[...forms].sort().join("+")}` : ""; };
365
365
  const normOwner = (s) => ownerIdentity(s).core;
@@ -13,7 +13,7 @@
13
13
  // PURE (no node imports) → tests offline. Mirrors coverage-ledger.mjs / findings-model.mjs.
14
14
 
15
15
  // add/drop = the both-directions element neighbours (VELTRIN→VELTRI is "drop"); phonetic/homophone =
16
- // sound-alikes; neighbour = a one-keystroke real-word / famous-mark neighbour (CHROME on NOVAPULSE);
16
+ // sound-alikes; neighbour = a one-keystroke real-word / famous-mark neighbour (NOVAPULSO on NOVAPULSE);
17
17
  // composite = the element inside a larger mark (VELTRI-composite cluster).
18
18
  export const VARIANT_DIRECTIONS = ["add", "drop", "phonetic", "homophone", "neighbour", "composite"];
19
19
  // the spine is ranked by goods-overlap with the actual product, not by class number + registration status.
@@ -861,9 +861,9 @@ export function mergeCommonLawFindings(parts) {
861
861
  // a present row chose.
862
862
  //
863
863
  // The join bug is fixed independently, because a census nobody can trust is worse than none:
864
- // • TERM match is EXACT after stripping a trailing annotation ("提基冰沙 (ZH: …)"). It used to be
864
+ // • TERM match is EXACT after stripping a trailing annotation ("瓦波冰沙 (ZH: …)"). It used to be
865
865
  // `rowTerm.includes(cellTerm)`, so the row for "CORAL FREEZE" was credited to the cells for "SLUSH"
866
- // and even "TIK", and the row for "提基冰沙" to the cell for "冰沙" — 71 of the 221.
866
+ // and even "WAV", and the row for "瓦波冰沙" to the cell for "冰沙" — 71 of the 221.
867
867
  // • a platform ROLL-UP row ("Multiple platforms") counts only when the term has no platform-specific
868
868
  // row of its own; combined with the substring bug it used to match every platform at once.
869
869
  // `undisposed` (title containment over raw web-search titles) is GONE: it returned 1,986 rows on the
@@ -9,7 +9,7 @@
9
9
  //
10
10
  // ── the loss this exists to catch ────────────────────────────────────────────────────────────────────
11
11
  //
12
- // TIKI TWIST and TIKI TROPICS. Both sat in R3's own common-law records and reached no findings list, and
12
+ // WAVO TWIST and WAVO TROPICS. Both sat in R3's own common-law records and reached no findings list, and
13
13
  // nothing anywhere said why. `common-law-receipts.mjs`'s `findGridCandidateOmissions` already reports one
14
14
  // class of this — a hit cell denied by the Negative-results matrix — but it is CELL-granular, and a cell
15
15
  // carries up to eight candidates. This is the per-candidate half.
@@ -39,7 +39,7 @@
39
39
  // ── THE NON-LATIN TRAP IS ANSWERED, NOT AVOIDED ──────────────────────────────────────────────────────
40
40
  //
41
41
  // `normalizeJoinText` folds every non-[A-Za-z0-9] run to a space, so it returns the EMPTY STRING for
42
- // 色度, 冰沙, 提基冰沙, ティキスラッシュ and 티키 슬러시. A mark-keyed trace is structurally blind to
42
+ // 色度, 冰沙, 瓦波冰沙, ワボスラッシュ and 와보 슬러시. A mark-keyed trace is structurally blind to
43
43
  // every one of them.
44
44
  //
45
45
  // NOTHING HERE TOUCHES IT. A Han-script candidate joins on its ASCII/percent-encoded URL. A Han-script
@@ -4,7 +4,7 @@
4
4
  // searched-not-asserted enforcement (validator side). Sister of use-check.mjs (spec 11): a "clean" claim
5
5
  // is sayable ONLY when a search produced it.
6
6
  //
7
- // The bug this closes (live incident: a mark reading as a benign given name one letter off the Sureño
7
+ // The bug this closes (live incident: a mark reading as a benign given name one letter off the Mara
8
8
  // street-gang label): the deterministic grid runs term×platform marketplace cells only — it asks
9
9
  // "who SELLS this name?", never "what does this name MEAN?". A marketplace grid that finds no listing for
10
10
  // the mark is SILENT on the street-gang association; only a MEANING search surfaces it. With no machine slot
@@ -30,7 +30,7 @@
30
30
 
31
31
  // The meaning query shapes. NOT a banned-word list — these are SEARCH directions ("what does this name mean,
32
32
  // and to whom?"). Perplexity surfaces foreign-language / gang / slang meanings from English query shapes
33
- // (a benign given name one letter off "Sureño" → the gang label surfaces from "<mark> gang" / "<mark> urban dictionary").
33
+ // (a benign given name one letter off "Mara" → the gang label surfaces from "<mark> gang" / "<mark> urban dictionary").
34
34
 
35
35
  export const CONNOTATION_SHAPES = ["meaning slang", "gang", "offensive", "urban dictionary", "wikipedia"];
36
36
 
@@ -1125,7 +1125,7 @@ const RECURRENT_MIN = 4;
1125
1125
  // ── — THE REASON SCALE IS MEASURED HERE AND DELIBERATELY DOES NOT DECIDE ────────────────────────
1126
1126
  // was ruled "recurrence counts independent reasons, not query strings": a dictated query is
1127
1127
  // "<term> <shape>", the sweep asks every shape of every mark variant, so the seven queries reading
1128
- // BIODELFIN/BIODELFINO/BIODOLPHIN/ΒΙΟΔΕΛΦΙΣ/ΔΕΛΦΙΣ/ΜΠΙΟΔΕΛΦΙΣ/Дельфис + "offensive meaning" that all
1128
+ // BIOVELTRYN/BIOVELTRINO/BIOVELTRINE/ΒΙΟΒΕΛΤΡΙΝ/ΒΕΛΤΡΙΝ/ΜΠΙΟΒΕΛΤΡΙΝ/Вельтрин + "offensive meaning" that all
1129
1129
  // return the dictionary definition of the word "offensive" are one reason asked seven ways. That
1130
1130
  // reasoning is sound and the shape is the right way to express it. It is implemented below as
1131
1131
  // connotationReasonKey, and it is RECORDED on every run — but it is NOT what clears the floor.
@@ -1133,7 +1133,7 @@ const RECURRENT_MIN = 4;
1133
1133
  // IT WAS BUILT, MEASURED AGAINST THE THREE PRESERVED RUNS, AND REFUTED BY THEM. Making the floor read
1134
1134
  // the reason scale inverts the signal it exists to read:
1135
1135
  // - The 2026-07 evidence run (test/fixtures/coral-freeze-pr-risk.json, 54 recorded queries): the floor's
1136
- // obligation set goes 7 → 0. `punchdrink.com/articles/problem-with-tiki-bars-cultural-appropriation`
1136
+ // obligation set goes 7 → 0. `punchdrink.com/articles/problem-with-wavo-bars-cultural-appropriation`
1137
1137
  // — THE receipt this floor was invented to force onto the page — is surfaced by four queries that are
1138
1138
  // all shape "offensive", so it scores ONE reason and drops out. The gate stops firing on the run it
1139
1139
  // was designed for.
@@ -151,7 +151,7 @@ export const E3_BACKLOG = [
151
151
  kind: "literal-json-skeleton",
152
152
  where: "driver/skills/blind-frame/SKILL.md:62-83",
153
153
  surface: "skill-file",
154
- evidence: "A JSON OBJECT with EXACTLY these keys:\\n```json\\n{\\n \"schema_version\": 1,\\n \"dominant_element\": \"the spine, verbatim\",\\n \"variants\": [{\"value\": \"DELPHI\", \"direction\": \"drop\", \"rationale\": \"…\"}],\\n \"fields\": […],\\n \"sources\": […],\\n \"ranking_basis\": \"goods-overlap\"\\n}\\n``` … `direction` is EXACTLY on",
154
+ evidence: "A JSON OBJECT with EXACTLY these keys:\\n```json\\n{\\n \"schema_version\": 1,\\n \"dominant_element\": \"the spine, verbatim\",\\n \"variants\": [{\"value\": \"KORPHI\", \"direction\": \"drop\", \"rationale\": \"…\"}],\\n \"fields\": […],\\n \"sources\": […],\\n \"ranking_basis\": \"goods-overlap\"\\n}\\n``` … `direction` is EXACTLY on",
155
155
  reparsedBy: "driver/verify.mjs validators.blindFrame — emits invalid_file:…:blindframe_* on an off-enum or missing key (stages.mjs:952-957 doc block)",
156
156
  removedByMove: "NOTHING ON THE #850 PLAN REMOVES THIS",
157
157
  },
@@ -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:4202 (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.",
286
+ where: "driver/stages.mjs:4210 (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",
@@ -446,7 +446,7 @@ export const E3_BACKLOG = [
446
446
  kind: "literal-json-skeleton",
447
447
  where: "driver/skills/frame-diff/SKILL.md:44-48",
448
448
  surface: "skill-file",
449
- evidence: "A directive may carry a structured `remedy`:\\n```json\\n\"remedy\": { \"terms\": [\"TROPICAL TIKI\", \"ISLAND TIKI\"], \"nice_classes\": [\"5\", \"32\"], \"regions\": [] }\\n```",
449
+ evidence: "A directive may carry a structured `remedy`:\\n```json\\n\"remedy\": { \"terms\": [\"TROPICAL WAVO\", \"ISLAND WAVO\"], \"nice_classes\": [\"5\", \"32\"], \"regions\": [] }\\n```",
450
450
  reparsedBy: "driver/pipeline.mjs runSupplementalSweeps — the remedy lint refuses a label-shaped term; stages.mjs:2809 restates the same shape in the message (\"THE ASK CONTRACT, stated at BOTH levels\")",
451
451
  removedByMove: "NOTHING ON THE #850 PLAN REMOVES THIS",
452
452
  },
@@ -6,7 +6,7 @@
6
6
  //
7
7
  // `record-carry.json` on a full clearance test run read `unreasoned: 0` and was telling the truth in the weak
8
8
  // sense only: every drop had a LABEL, and on 102 of them the label was inferred from where the record
9
- // stopped rather than stated by the step that stopped it. One of those 102 was DELPHIC — a lawyer-named
9
+ // stopped rather than stated by the step that stopped it. One of those 102 was KORPHIC — a lawyer-named
10
10
  // gold mark, REGISTERED, placed on sheet-2, stamped `carry: "carried"`, carried onto the findings
11
11
  // surface, and then absent from the delivered report with nothing anywhere saying why.
12
12
  //
@@ -116,7 +116,7 @@ export function appendDeclinations(runDir, accepted, { now = () => new Date().to
116
116
  }
117
117
  ensureDriverDir(runDir);
118
118
  writeFileSync(ledger, JSON.stringify({
119
- _provenance: "synthesis's own stated decision not to deliver a record that reached the findings surface (#1117). "
119
+ _provenance: "synthesis's own stated decision not to deliver a record that reached the findings surface. "
120
120
  + "Written by the driver from typed calls — never hand-authored, never parsed out of prose.",
121
121
  ts: now(), count: byUri.size, declinations: [...byUri.values()],
122
122
  }, null, 2) + "\n");
@@ -78,7 +78,7 @@ export const DEV_COCKPIT_JOB_FIELDS = Object.freeze({
78
78
  + "is a form for composing REAL dev runs; a fixture run is declared by the job file that wants one, so "
79
79
  + "the fact travels with the run rather than with whoever filled in a form.",
80
80
  promptParts: "the requester's declaration that the prose rides as SIDECAR files. The cockpit composes a job "
81
- + "from its own form and writes no sidecars, so it may not claim that shape (#1085).",
81
+ + "from its own form and writes no sidecars, so it may not claim that shape.",
82
82
  forwarderDomain: "the cockpit's assembler defaults it; a dev form has no forwarding domain to state.",
83
83
  provider: "which register vendor answers is the dev instance's own configuration, not a form field.",
84
84
  name: "the pre-markName spelling of the search subject. The form posts `mark`.",
@@ -668,13 +668,12 @@ export const config = {
668
668
  // Owner's ruling, 2026-09-23: record the tier. What a run asked for is a tier, what it was served is
669
669
  // recorded separately and already is, and the report names the model that ran — none of that moves.
670
670
  //
671
- // WHAT IT COSTS, RULED ON AND ACCEPTED RATHER THAN DISCOVERED LATER. Per-model totals are keyed on what
672
- // was ASKED for, and the direct-API lanes must name a version because they call the API rather than the
673
- // program — the API takes model ids, not tier words. So one model reached by both routes now lands in
674
- // two buckets: `anthropic/claude-haiku` from a stage, `anthropic/claude-haiku-4-5` from those lanes.
675
- // That is a real split in a per-model total and it was accepted with the ruling: the two are genuinely
676
- // different requests, and keying the totals on what actually SERVED each turn is the change that would
677
- // fix it properly, which is larger than this and not what was ruled.
671
+ // WHAT IT COSTS, RULED ON AND ACCEPTED RATHER THAN DISCOVERED LATER. A stage's rows are keyed on the
672
+ // tier it asked for, and a native-language lane's rows on the model that served them (`modelKey` in
673
+ // tokens.mjs). So one model reached both ways lands in two buckets: `anthropic/claude-haiku` from a
674
+ // stage, `anthropic/claude-haiku-4-5` from a native-language lane. That is a real split in a per-model
675
+ // total and it was accepted with the ruling; keying every row on what served it is the change that
676
+ // would close it, which is larger than this and not what was ruled.
678
677
  export const MODELS = {
679
678
  haiku: "anthropic/claude-haiku",
680
679
  sonnet: "anthropic/claude-sonnet",
@@ -1319,7 +1318,15 @@ export const PROVIDERS = {
1319
1318
  // The office's own numbers come off the full record Signa returns on search, through the
1320
1319
  // provider's own normaliser, so publish can address the office's page for each filing
1321
1320
  // (publish/office-record-links.mjs) instead of showing the handle.
1322
- return { ok: true, records: (Array.isArray(p.results) ? p.results : []).map((row) => {
1321
+ //
1322
+ // THE TOTAL RIDES THE SAME ANSWER and is carried, not dropped: `include_total` puts the register's
1323
+ // own count for this exact question on every search, so the listing of a term already holds the
1324
+ // figure the count lane would ask for separately. An approximation stays one: no number in
1325
+ // `total`, the floor beside it — the count lane's rule, unchanged.
1326
+ return { ok: true,
1327
+ total: Number.isFinite(p.total_hits) ? p.total_hits : null,
1328
+ ...(p.total_approximate === true ? { approximate: true, floor: Number.isFinite(p.total_floor) ? p.total_floor : null } : {}),
1329
+ records: (Array.isArray(p.results) ? p.results : []).map((row) => {
1323
1330
  const rec = row?.raw && typeof row.raw === "object" ? core.normalizeRecord(row.raw, row.office || null) : null;
1324
1331
  return {
1325
1332
  record_id: row?.record_id ?? null,
@@ -2361,7 +2368,7 @@ export function preflightEngineBinary(env = process.env, { platform = process.pl
2361
2368
 
2362
2369
  if (r.relative) {
2363
2370
  throw new Error(`[preflight] ${where} is the RELATIVE path "${bin}", which cannot work: the engine is `
2364
- + "spawned with the RUN DIRECTORY as its cwd (#524), not the repo, so a relative command is looked "
2371
+ + "spawned with the RUN DIRECTORY as its cwd, not the repo, so a relative command is looked "
2365
2372
  + `for inside the run. Give an absolute path — e.g. ${join(REPO_ROOT, bin)} — or a bare name on PATH.`);
2366
2373
  }
2367
2374
 
@@ -37,7 +37,7 @@ other, which is the only proof available where no gold set exists.
37
37
 
38
38
  A knockout scenario graded against a similar-marks sheet scores a **structural zero**. Knockout answers
39
39
  one narrow question — how many register filings exist for the exact mark and its close variations in the
40
- named classes — and never retrieves similar marks, so a lawyer's list of TIKI PUNCH and TIKI TROPICS is
40
+ named classes — and never retrieves similar marks, so a lawyer's list of WAVO PUNCH and WAVO TROPICS is
41
41
  unreachable by construction. R3 and R4 scored 0/8 and 0/9 on both free-tier and clarivate on the same
42
42
  day with the same engine, which measured the pairing rather than the engine.
43
43
 
@@ -121,6 +121,7 @@ serve({
121
121
  plan_path: { type: "string", description: "Absolute path to the frozen _driver/register-plan.json" },
122
122
  axis: { type: "string", description: "The register axis to execute (e.g. primary-sweep)" },
123
123
  output_path: { type: "string", description: "Absolute path of the named band to write (register-units/<axis>-band.json)" },
124
+ qids: { type: "array", items: { type: "string" }, description: "Optional: the qids of the plan entries to run. Only those run, and every other block in the band stays as it is. Leave it out only on the axis's first run: without it every entry on the axis runs again." },
124
125
  } },
125
126
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
126
127
  handler: guard((a) => doExecutePlan(API_KEY, BASE, a, tctx("execute_plan"))),
@@ -134,7 +135,7 @@ serve({
134
135
  proposals: { type: "array", minItems: 1, items: { type: "object", properties: {
135
136
  predicate: { type: "string", enum: ["exact", "default", "wildcard", "phonetic", "owner"] },
136
137
  term: { type: "string" }, terms: { type: "array", items: { type: "string" } },
137
- romanization: { type: "string", description: "The Latin-script form of a NON-LATIN term — plain ASCII letters/digits, syllable-separated by single spaces, no tone marks or diacritics (华威豹 → \"HUA WEI BAO\", ティキスラッシュ → \"TIKI SURASSHU\"). MANDATORY beside a non-Latin term: without it this register cannot answer the characters and the slice defers. Single-term proposals only (never an OR-stack, never predicate:owner), and never on a term that is already Latin." },
138
+ romanization: { type: "string", description: "The Latin-script form of a NON-LATIN term — plain ASCII letters/digits, syllable-separated by single spaces, no tone marks or diacritics (华威豹 → \"HUA WEI BAO\", ワボスラッシュ → \"WABO SURASSHU\"). MANDATORY beside a non-Latin term: without it this register cannot answer the characters and the slice defers. Single-term proposals only (never an OR-stack, never predicate:owner), and never on a term that is already Latin." },
138
139
  owner: { type: "string", description: "OPTIONAL owner scope field on a MARK-TEXT proposal: the query is the owner×term intersection (the owner's filings within the term band). Not allowed on predicate:owner (there the owner name IS the term)." },
139
140
  nice_classes: { type: "array", items: {} },
140
141
  // The narrowing fields every register serves (proposal-fields.mjs); this register's two facts ride in.
@@ -104,6 +104,7 @@ serve({
104
104
  plan_path: { type: "string", description: "Absolute path to the frozen _driver/register-plan.json" },
105
105
  axis: { type: "string", description: "The register axis to execute (e.g. primary-sweep)" },
106
106
  output_path: { type: "string", description: "Absolute path of the named band to write (register-units/<axis>-band.json)" },
107
+ qids: { type: "array", items: { type: "string" }, description: "Optional: the qids of the plan entries to run. Only those run, and every other block in the band stays as it is. Leave it out only on the axis's first run: without it every entry on the axis runs again." },
107
108
  } },
108
109
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
109
110
  handler: guard((a) => doExecutePlan(COOKIE, a, tctx("execute_plan"))),
@@ -139,6 +139,7 @@ serve({
139
139
  plan_path: { type: "string", description: "Absolute path to the frozen _driver/register-plan.json" },
140
140
  axis: { type: "string", description: "The register axis to execute (e.g. primary-sweep)" },
141
141
  output_path: { type: "string", description: "Absolute path of the named band to write (register-units/<axis>-band.json)" },
142
+ qids: { type: "array", items: { type: "string" }, description: "Optional: the qids of the plan entries to run. Only those run, and every other block in the band stays as it is. Leave it out only on the axis's first run: without it every entry on the axis runs again." },
142
143
  } },
143
144
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
144
145
  handler: guard((a) => doExecutePlan(AUTH, a, tctx("execute_plan"))),
@@ -151,7 +151,7 @@ serve({
151
151
  description: `Execute the frozen register plan for ONE axis across ${CAPABILITY_OFFICES} and write the named band. One qid per plan entry, spanning both offices — the execution-receipt shape is identical to a single-source provider's.`,
152
152
  inputSchema: { type: "object", required: ["plan_path", "axis", "output_path"], properties: {
153
153
  plan_path: { type: "string" }, axis: { type: "string" }, output_path: { type: "string" },
154
- qids: { type: "array", items: { type: "string" } },
154
+ qids: { type: "array", items: { type: "string" }, description: "Optional: the qids of the plan entries to run. Only those run, and every other block in the band stays as it is. Leave it out only on the axis's first run: without it every entry on the axis runs again." },
155
155
  } },
156
156
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
157
157
  handler: guard((a) => doExecutePlan(AUTH, a, tctx("execute_plan"))),
@@ -903,7 +903,7 @@ export function buildGatherMcpConfig(groups = [], { sessionKey, agent, runDir, r
903
903
  localEntry("register");
904
904
  if (!runDir) {
905
905
  throw new Error("gather-config: a register server needs the run it is fetching for — record bodies "
906
- + "belong to their run since #743, and the box-global ledger is retired (#1390). Pass runDir.");
906
+ + "belong to their run, and the box-global ledger is retired. Pass runDir.");
907
907
  }
908
908
  }
909
909
  const env = serverEnv({ sessionKey, agent, runDir, recordAxis });
@@ -122,7 +122,7 @@ function tellObligations(spec, ledgerJson) {
122
122
  writeFileSync(
123
123
  obligationsSidecarPath(spec.output_path),
124
124
  JSON.stringify({
125
- _provenance: `what the seat was TOLD it owed, computed by connotationObligations() from ${basename(spec.output_path)} at the moment the grid tool returned — the same calculation the validator judges with (#426)`,
125
+ _provenance: `what the seat was TOLD it owed, computed by connotationObligations() from ${basename(spec.output_path)} at the moment the grid tool returned — the same calculation the validator judges with`,
126
126
  floor: ob.floor,
127
127
  queriesOwed: ob.queries.map((e) => e.query),
128
128
  rowsTold,
@@ -700,7 +700,7 @@ serve({
700
700
  type: "object", required: ["text"],
701
701
  properties: {
702
702
  text: { type: "string", description: "The result, in one line — what was checked and how it came back." },
703
- source_link: { type: "string", description: "An http(s) URL for the page it came from. OMIT it when the source is a SEARCH rather than a page — a citation label in a link destination ships a link to nowhere (#875)." },
703
+ source_link: { type: "string", description: "An http(s) URL for the page it came from. OMIT it when the source is a SEARCH rather than a page — a citation label in a link destination ships a link to nowhere." },
704
704
  internal: { type: "boolean", description: "true marks this an INTERNAL reviewer note; the driver renders the ::p:: marker and the client export strips it." },
705
705
  },
706
706
  },
@@ -86,6 +86,7 @@ serve({
86
86
  plan_path: { type: "string", description: "Absolute path to the frozen _driver/register-plan.json" },
87
87
  axis: { type: "string", description: "The register axis to execute (e.g. primary-sweep)" },
88
88
  output_path: { type: "string", description: "Absolute path of the named band to write (register-units/<axis>-band.json)" },
89
+ qids: { type: "array", items: { type: "string" }, description: "Optional: the qids of the plan entries to run. Only those run, and every other block in the band stays as it is. Leave it out only on the axis's first run: without it every entry on the axis runs again." },
89
90
  } },
90
91
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
91
92
  handler: guard((a) => doExecutePlan({ apiKey: API_KEY, base: BASE }, a, tctx("execute_plan"))),
@@ -112,7 +112,7 @@ export function mintSupplementalEntries(axis, proposals, { existingQids = new Se
112
112
  // rather than guessed about.
113
113
  const owner = typeof p.owner === "string" ? p.owner.trim() : "";
114
114
  if (p.owner != null && !owner) { issue("owner, when present, must be a non-empty string"); continue; }
115
- if (owner && predicate === "owner") { issue(`predicate "owner" carries the owner name as its term — the owner scope field rides a MARK-TEXT predicate ({predicate:"default", term:"TIKI", owner:"…"})`); continue; }
115
+ if (owner && predicate === "owner") { issue(`predicate "owner" carries the owner name as its term — the owner scope field rides a MARK-TEXT predicate ({predicate:"default", term:"WAVO", owner:"…"})`); continue; }
116
116
  // ── romanization (2026-07-30 review round — the enforcement-without-invitation fix) ────────────
117
117
  // Half the live incident's non-Latin deferrals were supp: entries, because the guard's remediation
118
118
  // ("supply the romanisation on the entry's romanizedTerms") pointed at a field this proposing
@@ -124,6 +124,7 @@ serve({
124
124
  plan_path: { type: "string", description: "Absolute path to the frozen _driver/register-plan.json" },
125
125
  axis: { type: "string", description: "The register axis to execute (e.g. primary-sweep)" },
126
126
  output_path: { type: "string", description: "Absolute path of the named band to write (register-units/<axis>-band.json)" },
127
+ qids: { type: "array", items: { type: "string" }, description: "Optional: the qids of the plan entries to run. Only those run, and every other block in the band stays as it is. Leave it out only on the axis's first run: without it every entry on the axis runs again." },
127
128
  } },
128
129
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true },
129
130
  handler: guard((a) => doExecutePlan(AUTH, a, tctx("execute_plan"))),
@@ -242,14 +242,14 @@ function niceClassErrors(list, label) {
242
242
  // A zero-width joiner makes "IRON\u200DWHISK" render as IRONWHISK and compare unequal to it, so
243
243
  // `selfExclusionOwners` and dedup both miss a mark a human reads as the account's own.
244
244
  //
245
- // NFD "SIRÈNE" !== NFC "SIRÈNE", so one mark submitted two ways is two matters, two searches, two bills.
245
+ // NFD "FALCÓN" !== NFC "FALCÓN", so one mark submitted two ways is two matters, two searches, two bills.
246
246
  //
247
247
  // REFUSED, NOT STRIPPED, for the display-control classes. Silently altering the mark a client asked
248
248
  // about is its own defect and a worse one: the deliverable would then name a mark nobody ordered. NFC is
249
249
  // the exception because it changes no character a reader can see — it is the same string, spelled once.
250
250
  //
251
251
  // WHAT THIS DELIBERATELY DOES NOT TOUCH, because an over-broad filter here is worse than the defect:
252
- // • ACCENTED AND NON-LATIN LETTERS. SIRÈNE, СOLA and an Arabic or Hebrew mark are all legitimate things
252
+ // • ACCENTED AND NON-LATIN LETTERS. FALCÓN, СOLA and an Arabic or Hebrew mark are all legitimate things
253
253
  // to clear. The refusal is for explicit direction-OVERRIDE controls, never for letters that happen to
254
254
  // be right-to-left — an Arabic mark contains no U+202x at all.
255
255
  // • HOMOGLYPHS. A Cyrillic ES in СOLA is measured in and explicitly NOT claimed as a defect;
@@ -26,7 +26,7 @@ export const BASE_LABELS = ["source:report-feedback", "area:report"];
26
26
  * describe, which is triage — the thing this issue forbids. A human adds the real area during triage.
27
27
  */
28
28
  export const REQUIRED_LABELS = [
29
- { name: "source:report-feedback", color: "c5def5", description: "Raised by a reviewing lawyer on a delivered report (#260)." },
29
+ { name: "source:report-feedback", color: "c5def5", description: "Raised by a reviewing lawyer on a delivered report." },
30
30
  { name: "feedback:good", color: "0e8a16", description: "A lawyer marked this finding RIGHT. Not a defect — a confirmation worth keeping." },
31
31
  { name: "feedback:bad", color: "b60205", description: "A lawyer marked this finding WRONG. Input for triage, not yet buildable work." },
32
32
  { name: "area:report", color: "d4c5f9", description: "The delivered report and what it says." },
@@ -18,7 +18,7 @@
18
18
  // disposition — read SERVER-SIDE from the run's own artifacts, never taken from the request. Mark and band
19
19
  // come from report-data.json; the disposition comes from findings.json beside it in the same run dir,
20
20
  // because report-data.json is the CLIENT cut and stopped serving the engine's placement key. A
21
- // reader who finds the ordinal now points at `KURENA / Manageable / rebuttable` when the flag says
21
+ // reader who finds the ordinal now points at `KOLEMA / Manageable / rebuttable` when the flag says
22
22
  // `BURROWELL / Medium / conceded` knows the run was republished, which is exactly the thing a bare id
23
23
  // would have hidden.
24
24
 
@@ -139,7 +139,7 @@ export const POSITION_REQUIRED_DISPOSITIONS = ["adversarial", "coexistence-partn
139
139
  export const OFF_FIELD_GROUNDS = ["different-field", "no-material-risk"];
140
140
  // Context notes (A1) — the valid HOME for a knowledge-cited reference that is NOT a fetched-record finding:
141
141
  // a famous one-keystroke neighbour kept for diligence per digest.md's "never dropped" rule but with NO
142
- // register record to ground a finding (e.g. CHROME on a NOVAPULSE clearance). A context note is NEVER a finding
142
+ // register record to ground a finding (e.g. NOVAPULSO on a NOVAPULSE clearance). A context note is NEVER a finding
143
143
  // (no composite/level/meters/registration), never drives the rating, and carries no uri — so it cannot
144
144
  // launder an ungrounded mark into the findings contract: the F-14 URI guard (validateOwner) stays whole, and
145
145
  // "the famous neighbour is never dropped" is honoured HERE rather than via a broken empty-uri finding.
@@ -246,7 +246,7 @@ export function deriveDisplayVerdict({ verdict, reasons, kinds, findings, manife
246
246
  }
247
247
 
248
248
  // ── wp50 — THE deterministic client-summary-block → finding join ────────────────────────────────────────
249
- // The old first-match substring-containment join mis-bound "DEMVENZY — Novartis" to the VENZY finding
249
+ // The old first-match substring-containment join mis-bound "DEMVENZY — Norvanta" to the VENZY finding
250
250
  // (the head CONTAINS "venzy"), so the validator and the lint auto-correct VALIDATED — and would have
251
251
  // ENFORCED — the wrong finding's tier, rating two Composite-3 conflicts at the top band. One join,
252
252
  // used by the validator, the auto-correct and the email
@@ -728,7 +728,7 @@ const CORRECTION_ENTRY_KEYS = ["entity", "disposition", "note"];
728
728
  // blob. The frozen renderer receives a deterministic STRING PROJECTION (projectAssessmentField); the
729
729
  // structured rows render in the audit workbook + report-data, both unfrozen.
730
730
  // spec 2026-07-30 §3: `read` — the one-to-two-sentence consequence the reader sees ("A weak name to
731
- // own. SLUSH is simply what the product is, so the whole mark rests on TIKI."). The renderer shows it
731
+ // own. SLUSH is simply what the product is, so the whole mark rests on WAVO."). The renderer shows it
732
732
  // as the visible prose and collapses the typed rows behind toggles; absent (archived structured runs)
733
733
  // the renderer falls back to spectrum/acquired/note.
734
734
  const ASSESSMENT_FIELD_KEYS = ["spectrum", "read", "per_class", "per_market", "counter_registrations", "acquired", "note"];
@@ -238,7 +238,7 @@ export function buildFlagSnapshot(env, { capturedAt, registerProvider = null, re
238
238
  * reports a delta that does not exist, which is the same class of lie as reporting none.
239
239
  */
240
240
  export const PRODUCTION_POSTURE = {
241
- source: "production unit environment, read 2026-08-04 with owner authorisation (#372); the flag half "
241
+ source: "production unit environment, read 2026-08-04 with owner authorisation; the flag half "
242
242
  + "retired 2026-08-20 when #1149 item 8 deleted every switch it named",
243
243
  // The three it named are gone — deleted BECAUSE production ran them on while the source shipped them
244
244
  // off, which is the delta this block existed to expose. There is nothing left to differ about, and
@@ -64,8 +64,8 @@ export function armFloorDuty(runDir, { now = () => new Date().toISOString() } =
64
64
  try {
65
65
  ensureDriverDir(String(runDir ?? ""));
66
66
  writeFileSync(driverDir(String(runDir ?? ""), FLOOR_DUTY_STAMP), JSON.stringify({
67
- _provenance: "the placement pass on this run ran under code that orders the floors by record id "
68
- + "(#1117), so its floor account may be held to that order",
67
+ _provenance: "the placement pass on this run ran under code that orders the floors by record id"
68
+ + ", so its floor account may be held to that order",
69
69
  ts: now(),
70
70
  }, null, 2) + "\n");
71
71
  return true;