clearotron 0.4.0 → 0.4.1-beta.0

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 (96) hide show
  1. package/THIRD-PARTY-NOTICES.md +2 -2
  2. package/build-info.json +2 -2
  3. package/docs/SECURITY-OWASP.md +21 -13
  4. package/docs/SECURITY.md +20 -14
  5. package/docs/architecture/04-configuration-reference.md +3 -2
  6. package/docs/architecture/05-config-governance.md +1 -1
  7. package/docs/architecture/06-operations-runbook.md +1 -1
  8. package/docs/architecture/09-security-and-data.md +16 -11
  9. package/driver/CHANGELOG.md +18 -0
  10. package/driver/binding-layers.mjs +28 -6
  11. package/driver/citation-census.json +3 -3
  12. package/driver/common-law-coverage-status.mjs +52 -0
  13. package/driver/common-law-receipts.mjs +1 -1
  14. package/driver/connotation-search.mjs +5 -5
  15. package/driver/contract-dictation-registry.mjs +1 -1
  16. package/driver/contract-e3-backlog.mjs +1 -1
  17. package/driver/contract-vocabulary.mjs +18 -18
  18. package/driver/degraded-parts.mjs +10 -3
  19. package/driver/dispatch-record.mjs +19 -0
  20. package/driver/doubt-closure-tool.mjs +2 -2
  21. package/driver/driver.config.mjs +39 -6
  22. package/driver/engagement-receipt.mjs +1 -1
  23. package/driver/engine/CONTRACT.md +41 -1
  24. package/driver/engine/anthropic-agent.mjs +56 -4
  25. package/driver/engine/mcp/codex-config.mjs +1 -1
  26. package/driver/engine/mcp/coverage-server.mjs +1 -1
  27. package/driver/engine/mcp/gather-config.mjs +1 -1
  28. package/driver/engine/mcp/recording-server.mjs +31 -4
  29. package/driver/engine/mcp/stdio-server.mjs +45 -7
  30. package/driver/engine/openai-agent.mjs +100 -17
  31. package/driver/engine/session-record.mjs +223 -0
  32. package/driver/enqueue-schema.mjs +2 -2
  33. package/driver/findings-model.mjs +3 -3
  34. package/driver/form-neighbourhood.mjs +7 -7
  35. package/driver/frame-diff-model.mjs +3 -3
  36. package/driver/framework.mjs +22 -0
  37. package/driver/gateway.mjs +94 -12
  38. package/driver/named-band.mjs +2 -0
  39. package/driver/package.json +1 -1
  40. package/driver/phase0.mjs +13 -2
  41. package/driver/pipeline-knockout.mjs +1 -1
  42. package/driver/pipeline.mjs +46 -33
  43. package/driver/portal-families.mjs +3 -3
  44. package/driver/portal-service.mjs +1 -1
  45. package/driver/predelivery-lint.mjs +19 -19
  46. package/driver/publish/index.mjs +1 -1
  47. package/driver/publish/knockout.mjs +5 -4
  48. package/driver/publish/office-record-links.mjs +17 -2
  49. package/driver/publish/publish-inputs.mjs +1 -1
  50. package/driver/publish/render-knockout.mjs +17 -5
  51. package/driver/publish/render.mjs +4 -2
  52. package/driver/record-fold.mjs +177 -0
  53. package/driver/register-count.mjs +18 -1
  54. package/driver/register-plan.mjs +71 -17
  55. package/driver/register-records.mjs +7 -0
  56. package/driver/registry-fidelity.mjs +2 -2
  57. package/driver/repairs.mjs +1 -1
  58. package/driver/report-card-record.mjs +4 -4
  59. package/driver/scope-facts.mjs +11 -3
  60. package/driver/search-policy.mjs +20 -1
  61. package/driver/skills/clearance-common-law/SKILL.md +22 -22
  62. package/driver/skills/clearance-register/digest.md +3 -3
  63. package/driver/skills/clearance-register/register-recipes.md +11 -11
  64. package/driver/skills/clearance-register/status-rules.md +1 -1
  65. package/driver/skills/clearance-register/unit.md +1 -1
  66. package/driver/skills/clearance-search/firm-wide-reasoning.md +3 -2
  67. package/driver/skills/clearance-search/phase2-execution.md +6 -5
  68. package/driver/skills/clearance-search/synthesis-rules.md +4 -4
  69. package/driver/skills/clearance-search/worked-examples.md +39 -39
  70. package/driver/skills/clearance-variants/SKILL.md +16 -16
  71. package/driver/skills/frame-diff/SKILL.md +2 -2
  72. package/driver/stage-context.mjs +27 -1
  73. package/driver/stages.mjs +12 -12
  74. package/driver/suite-census.json +175 -31
  75. package/driver/synthesis-record.mjs +5 -0
  76. package/driver/unit-inventory.mjs +17 -28
  77. package/driver/verify.mjs +6 -6
  78. package/mcp-server/CHANGELOG.md +4 -0
  79. package/mcp-server/lib/evidence.mjs +8 -8
  80. package/mcp-server/lib/knockout.mjs +1 -1
  81. package/mcp-server/package.json +2 -2
  82. package/package.json +2 -2
  83. package/portal-ui/package.json +1 -1
  84. package/providers/_shared/count.mjs +4 -1
  85. package/providers/_shared/enumerate.mjs +61 -22
  86. package/providers/_shared/execute-plan.mjs +2 -0
  87. package/providers/corsearch/src/capabilities.js +1 -1
  88. package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
  89. package/providers/oauth-mcp-bridge/package.json +2 -2
  90. package/providers/signa/src/capabilities.js +17 -2
  91. package/providers/signa/src/core.js +234 -37
  92. package/scripts/band-shape-probe.mjs +2 -2
  93. package/scripts/deprecate-below.mjs +28 -4
  94. package/scripts/e2e-first-time.mjs +16 -1
  95. package/scripts/freeze-example-run.mjs +2 -2
  96. package/shared/scope.mjs +18 -2
@@ -17,7 +17,7 @@
17
17
  - [Variant execution strategy (register layer)](#variant-execution-strategy-register-layer)
18
18
  - [Step 2.6 — Skeptic review](#step-26--skeptic-review-a-fresh-eyes-self-audit-before-you-trust-the-findings)
19
19
  - [Step 3 — Cross-pollination (Option D — deterministic cross-checks, cap N=10)](#step-3--cross-pollination-option-d--deterministic-cross-checks-cap-n10)
20
- - [Step 3.5 — Actual-use check (mandatory for Medium/High/Very High register hits)](#step-35--actual-use-check-mandatory-for-mediumhighvery-high-register-hits)
20
+ - [Step 3.5 — Actual-use and enforcement check (mandatory for register hits rated medium risk or higher)](#step-35--actual-use-and-enforcement-check-mandatory-for-register-hits-rated-medium-risk-or-higher)
21
21
  - [Step 3.6 — Owner workup (mandatory for high-risk findings)](#step-36--owner-workup-mandatory-for-high-risk-findings)
22
22
  - [Step 4 — Joint synthesis](#step-4--joint-synthesis)
23
23
  - [Step 4.5 — Case-law grounding](#step-45--case-law-grounding)
@@ -78,7 +78,7 @@ skipped step must be logged with its reason in the unit's digest audit.
78
78
  1. **Macro probes** — one search per element of the compound + one for the full compound phrase (limit=10 each), to establish saturation levels. Minimum 3 searches. SKIP only if all elements are non-common-words (rare).
79
79
  2. **Compound-phrase sweeps** — the compound phrase across **three match-modes (exact, phrase, default)**, limit=100 per search. Minimum 3 searches. SKIP only if the phrase is a single word (then it's a single-word funnel, not compound).
80
80
  3. **Single-word coverage hunts** — for each element marked "demote to filter" in the manifest, one search with product/industry filters applied (limit=50). Minimum 1 per such element.
81
- 4. **Wildcard reorders** — if the manifest lists word-order variants, at least one wildcard sweep per distinct ordering (e.g. `Elevate * game`, `game * Elevate`).
81
+ 4. **Wildcard reorders** — if the manifest lists word-order variants, at least one wildcard sweep per distinct ordering (e.g. `Raise * play`, `play * Raise`).
82
82
  5. **Numeric-substitution and transliteration sweeps** — execute every sweep marked ✅ (requires verification) in the variant manifest, UNLESS the manifest classifies the mark as English-only (single-language Recipe 1 pattern). Skipping any ✅ requires a stated reason in the unit's digest audit.
83
83
  6. **Material-jurisdiction sub-queries** — a **protected, non-yielding** line item, NOT folded into the sweep budget. Run one scoped sub-query per jurisdiction `matter-context` declares materially-matters (no top-N cap). These outrank within-axis breadth: if budget is tight, an extra script group (step 5) yields and is logged `coverage-limited` — a material jurisdiction is never dropped to fund breadth, and a jurisdiction that genuinely can't run is logged `deferred`, never silent.
84
84
 
@@ -230,9 +230,9 @@ Cap-overflow MUST be flagged in the deliverable audit trail with a specific reas
230
230
 
231
231
  Every cross-check (including "checked, found nothing") logged in the unified audit trail as proof-of-work. The collaborator value-add (vs assistant) is in this section: synthesis can be decisive ("HP uses, does not register → Level 2 B") rather than tentative ("recommend the staff lawyer check HP register").
232
232
 
233
- ## Step 3.5 — Actual-use check (mandatory for register hits above the framework's lowest band)
233
+ ## Step 3.5 — Actual-use and enforcement check (mandatory for register hits rated medium risk or higher)
234
234
 
235
- Before synthesis, for **every register finding** advisory-rated **above the framework's lowest band**, run a marketplace check via `perplexity_research` to determine whether the registered mark is **actually being used in the marketplace within the scope of the current search** (i.e. for the goods/services and field this clearance targets).
235
+ Before synthesis, for **every register finding** advisory-rated on a rung **the framework rates medium risk or higher** (the stage message names those rungs; a rung below that is not checked, on any client's ladder), run a marketplace check via `perplexity_research` to determine whether the registered mark is **actually being used in the marketplace within the scope of the current search** (i.e. for the goods/services and field this clearance targets). **The same query also asks for the owner's enforcement record:** whether the owner has opposed, disputed or sued over this mark or a similar one.
236
236
 
237
237
  Example: a JELLY register hit owned by Jellycat (a toy company) for Class 9 video game software — check whether Jellycat actually sells or markets video games under JELLY. If they don't (their commercial use is toys), note the filed-vs-used distinction in Key Factors and weigh it as a Stage-2 factor together with revocation-vulnerability — no automatic downgrade (see `synthesis-rules.md` → *Actual-use assessment results*).
238
238
 
@@ -244,6 +244,7 @@ Example: a JELLY register hit owned by Jellycat (a toy company) for Class 9 vide
244
244
  - If actual use in the relevant field is **not found** (despite the filing), do **NOT** automatically downgrade — weigh the lack of field use as a Stage-2 factor together with revocation-vulnerability (`synthesis-rules.md` → *Actual-use assessment results* / *Rule on downgrade quantum*), and note in Key Factors: "Register filing claims [field] but no marketplace use identified — filed-vs-used noted; weighed with revocability."
245
245
  - This check measures *use in the field*, not registry status: a renewal / re-registration / "Registered" status is administrative upkeep, not marketplace use, and does not satisfy the actual-use check or defeat a non-use mitigant (see `synthesis-rules.md` → "Administrative liveness is not market use").
246
246
  - Owner-portfolio-bound common-law checks already counted in this step count toward the Option D cap (Step 3).
247
+ - **Enforcement the query finds is a lead, not a verified authority** (the ENFORCEMENT AUTHORITY rule in the stage message): it informs the enforcer meter with basis `inferred-from-signal`, and its URL is cited inline in the finding's prose. If the query finds no enforcement record, the enforcer is `low` with basis `inferred-from-signal`, and the finding says the search found none. The enforcer stays `unknown`, and nothing is claimed, only when the query could not run.
247
248
 
248
249
  **Output contract — ENFORCED by the driver (spec 11), not optional.** For every Composite 3+ finding whose
249
250
  mitigant or verdict turns on the **absence** of use (it says the mark is "not in actual use" / "unused" / has
@@ -360,7 +361,7 @@ the verdict** (the driver decides this in code):
360
361
  Runs **ONCE**, after all marks have completed Steps 2–4.5. Review findings across all marks and identify:
361
362
 
362
363
  1. **Shared findings:** a single entity/finding relevant to more than one proposed mark (e.g., "Prize Crate Retail" is relevant to both "PRIZE CRATE" and "CAVERN CRATES")
363
- 2. **Pattern findings:** recurring themes across marks (e.g., "the 'loot' prefix is crowded across all gaming platforms")
364
+ 2. **Pattern findings:** recurring themes across marks (e.g., "the 'prize' prefix is crowded across all gaming platforms")
364
365
  3. **Compound risk:** where the combination of marks might amplify risk (e.g., using both "PRIZE CRATE" and "CAVERN CRATES" increases the chance of a dispute with Prize Crate Retail)
365
366
 
366
367
  For each cross-reference: note which marks are affected, describe the connection, flag any compounding risk. Cross-references appear in the narrative summary and as a note in the Findings sheet.
@@ -28,7 +28,7 @@ Across the synthesis, two postures are load-bearing:
28
28
  - [Per-finding synthesis structure](#per-finding-synthesis-structure)
29
29
  - [Cancelled / invalid marks — include if exact, no commentary](#cancelled--invalid-marks--include-if-exact-no-commentary)
30
30
  - [The mark itself — standing assessment (every run)](#the-mark-itself--standing-assessment-every-run)
31
- - [Filed-vs-used check — mandatory for findings above the lowest band](#filed-vs-used-check--mandatory-for-findings-above-the-lowest-band)
31
+ - [Filed-vs-used check — mandatory for findings rated medium risk or higher](#filed-vs-used-check--mandatory-for-findings-rated-medium-risk-or-higher)
32
32
  - [Prosecution history — mandatory for identical-mark hits in relevant classes](#prosecution-history--mandatory-for-identical-mark-hits-in-relevant-classes)
33
33
  - [Revocability — mandatory assessment for register findings above the lowest band](#revocability--mandatory-assessment-for-register-findings-above-the-lowest-band)
34
34
  - [Verify-or-defer — procedure, deadlines, registry statistics](#verify-or-defer--procedure-deadlines-registry-statistics)
@@ -449,15 +449,15 @@ reviewing lawyer to assess), frames the report, and **never moves any band**.
449
449
  into a longer paragraph. Real PR / reputational **hits** still live in the PR / reputational section (see
450
450
  above); this block is the standing read, not the incident report.
451
451
 
452
- ## Filed-vs-used check — mandatory for findings above the lowest band
452
+ ## Filed-vs-used check — mandatory for findings rated medium risk or higher
453
453
 
454
- For every register finding advisory-rated ABOVE the framework's lowest band, synthesis runs an actual-use marketplace check via `perplexity_research` (see `phase2-execution.md` Step 3.5), scoped to owner + mark + the goods/field, and **records the result inline**. Any finding whose mitigant turns on the *absence* of use (non-use revocation/cancellation, "not in actual use", "no marketplace use found", "owner's use unknown") MUST carry a `- **Use-check source:** <URL | "perplexity_research — no result">` line — the driver's `narrative` validator rejects the narrative otherwise (spec 11). A use-negative is sayable **only** when a search produced it; an inference from the owner's profile ("a music act → probably no game use") is **not** a searched result and must be either run or labelled an inference, never dressed as a clean negative.
454
+ For every register finding advisory-rated on a rung the framework rates medium risk or higher, synthesis runs an actual-use marketplace check via `perplexity_research` (see `phase2-execution.md` Step 3.5, which also asks for the owner's enforcement record), scoped to owner + mark + the goods/field, and **records the result inline**. Any finding whose mitigant turns on the *absence* of use (non-use revocation/cancellation, "not in actual use", "no marketplace use found", "owner's use unknown") MUST carry a `- **Use-check source:** <URL | "perplexity_research — no result">` line — the driver's `narrative` validator rejects the narrative otherwise (spec 11). A use-negative is sayable **only** when a search produced it; an inference from the owner's profile ("a music act → probably no game use") is **not** a searched result and must be either run or labelled an inference, never dressed as a clean negative.
455
455
 
456
456
  ## Own-rights evidence — mandatory when reasoning relies on the client's house mark (spec-v3 A4)
457
457
 
458
458
  The same enforced contract applies to the client's OWN rights: if a finding's clearance reasoning relies on the client's house mark or franchise root ("the prefix is the client's own registered mark"), synthesis runs ONE own-portfolio check over the run's FROZEN register material — `band_lookup` with `owner:<the applicant/house-mark owner>` (plus `band_record` for any registration cited) — and the finding MUST end with a `- **Own-rights source:** <record URI(s) | "no applicant-owned registrations in the searched register material">` line — the driver's `narrative` validator rejects the narrative otherwise. **Know what the negative means:** the frozen material covers only this matter's dispatched slices (its classes, its mark texts), so an empty owner lookup is NEVER evidence the client's registrations do not exist — a house mark's registrations usually live in the client's home classes under mark text no slice covers. Never write "no registrations found" or any portfolio-wide register-negative: state the honest scoped negative, let the reasoning stand or fall without the crutch, and record the un-run owner query (owner + house root + its home classes/key jurisdictions) as an open Coverage/open-item row so the escalation lane can propose it through the supplemental mint — the same treatment as any instructed check the frozen material cannot answer. The affiliate-exclusion mandate governs *conflicts* (never flag the client against itself); it does **not** suppress this *supporting-evidence* check — those are different things.
459
459
 
460
- **The staff lawyer's rule:** Any use of a registered trademark that poses medium risk or higher (any band above the framework's lowest) is relevant. The actual-use check applies **after** the preliminary legal read is made — not before. The correct sequence is:
460
+ **The staff lawyer's rule:** Any use of a registered trademark that poses medium risk or higher (any band the framework rates medium risk or higher, whatever its position on the ladder) is relevant. The actual-use check applies **after** the preliminary legal read is made — not before. The correct sequence is:
461
461
 
462
462
  1. **Stage 1 — Legal claim strength, net of merits defences:** Make the legal read as the probability the claim prevails, stated in plain likelihood words — the whole-mark confusion read, **net of the credible merits defences** named in the per-finding structure (descriptiveness / weak senior mark, the opponent's own undermining conduct, the client's fair-use defence, priority). Whether **our actual use meets theirs in the market** (real commercial / manner-of-use / channel overlap) IS part of this Stage-1 read — it is the goods-half of likelihood-of-confusion and it sets the read: our use being a descriptive / in-product label vs their standalone source-brand, or the two sitting in a genuinely different commercial field, is a merits reason the claim may not prevail → the **client-favoured read**. **The basis for "theirs" splits by right type:** a **registered** senior meets us on the mark and G&S **as registered** (read the specification; quote it when it decides the point) — never on the owner's current presentation; a **common-law** senior meets us on its **actual trade**. OUR side of the meeting stays our own actual/intended manner of use (per the request form) — that lever is untouched. What stays in Stage 2 is the *senior's enforcement reality* — is the mark actually used, revocable for non-use, will the owner bother, how the owner currently dresses or positions it in the market — **NOT** whether the uses meet. (Merits defences are claim-strength, not practical mitigation; they belong in the legal read.)
463
463
  2. **Stage 2 — Practical risk mitigation:** For every hit whose legal read reaches "more likely than not they'd win" or worse, apply the practical mitigants — actual use, revocation-vulnerability, owner enforcement appetite, coexistence. These are the **business read**. **Response availability is Stage 2 at most:** that a route exists — coexistence, consent, rebrand, a cancellation lever — never enters the Stage-1 Legal position; mitigation-availability speaks only through the framework's own **Practical position** words for the band it belongs to.
@@ -33,7 +33,7 @@ Notice across all three:
33
33
  - **The proposed mark's own distinctiveness is assessed *per field*** — and it drives how narrowly any
34
34
  third-party right can block (descriptive term → narrow rights → weak block).
35
35
  - **Family-of-marks / branded-context is a real mitigant** ("consumers will perceive EMBERSTRIKE as
36
- an extension of the Breaker range"; "strong Blockvale branding").
36
+ an extension of the Strike range"; "strong Blockvale branding").
37
37
  - **Use / revocability / enforcement appetite carry the analysis** — a registration with no use, in
38
38
  insolvency, or outside the owner's core market is a different risk from an active enforcer.
39
39
  - **Executive summary is synthesised prose:** name the primary risk(s), the overall rating, and the
@@ -236,30 +236,30 @@ cannot be excluded.
236
236
  sufficient differences to avoid confusion.
237
237
 
238
238
  *Common-law use*
239
- - **Manageable** — "Solstrikers" is a game "coming soon" on Steam from indie developer Crobatspr.
239
+ - **Manageable** — "Solstrikers" is a game "coming soon" on Steam from an indie developer.
240
240
 
241
241
  **Emberstrike — Manageable Risk**
242
242
 
243
- - 3,060 live FLAME/FLAME-formative filings internationally in the searched classes (640 claim gaming
244
- software/hardware/online gaming); analysis focuses on FLAME and FLAME BR___ marks covering gaming.
245
- - 8,575 live BR(E)AKER(S)/BR(E)AK(E)-formative filings (2,317 claim gaming); analysis focuses on
246
- BR(E)AKER(S) and F__ BR(E)AKER(S) marks covering gaming.
243
+ - 3,060 live EMBER/EMBER-formative filings internationally in the searched classes (640 claim gaming
244
+ software/hardware/online gaming); analysis focuses on EMBER and EMBER ST___ marks covering gaming.
245
+ - 8,575 live STRIKE(S)/STRIK(E)-formative filings (2,317 claim gaming); analysis focuses on
246
+ STRIKE(S) and E__ STRIKE(S) marks covering gaming.
247
247
 
248
248
  *Filings*
249
- - **Manageable** — Numerous FLAME/FLAMES marks claim gaming goods/services; most significant is
250
- an international FLAMES portfolio owned by gambling company Euro Games Technology (no apparent current
249
+ - **Manageable** — Numerous EMBER/EMBERS marks claim gaming goods/services; most significant is
250
+ an international EMBERS portfolio owned by a gambling company (no apparent current
251
251
  use).
252
- - **Manageable** — Numerous BREAKER marks claim gaming goods/services; none appears to have
253
- objected to the client's ongoing use of ___ BREAKER for controllers.
252
+ - **Manageable** — Numerous STRIKE marks claim gaming goods/services; none appears to have
253
+ objected to the client's ongoing use of ___ STRIKE for controllers.
254
254
 
255
255
  *Common-law use*
256
256
  - **Manageable** — EmberstrikeGaming: streamer/YouTube channel (205 videos, 405 subscribers)
257
257
  with a merch store that does not sell hardware/accessories.
258
- - **Manageable** — Flamebreak: a 2016 Steam game (444 "very positive" reviews) by Nimbly Games;
258
+ - **Manageable** — Emberstruck: a 2016 Steam game (444 "very positive" reviews) by an indie studio;
259
259
  no game published in ~10 years.
260
- - **Not a rated conflict (clear win)** — A "Emberstrike Set" appears in several Zelda games; not monetised or
260
+ - **Not a rated conflict (clear win)** — A "Emberstrike Set" appears in several games of a long-running adventure series; not monetised or
261
261
  prominent.
262
- - **Not a rated conflict (clear win)** — Remedy's co-op shooter "Firebreak" (1,914 "mixed" reviews on Steam).
262
+ - **Not a rated conflict (clear win)** — A studio's co-op shooter "Firestrike" (1,914 "mixed" reviews on Steam).
263
263
 
264
264
  ---
265
265
 
@@ -292,7 +292,7 @@ manageable.
292
292
  - **Moderate (register risk; no obvious market overlap)** — a Canadian provincial lottery corporation owns an official Canadian
293
293
  registration for CHART YOUR COURSE (all goods/services) used descriptively for self-service lotteries.
294
294
  Legal risk, but low practical objection risk — no enforcement history, no commercial overlap with a
295
- console tagline. A Canadian application would undoubtedly be blocked; consent from OLC the only route.
295
+ console tagline. A Canadian application would undoubtedly be blocked; consent from that corporation the only route.
296
296
  - **Moderate (register risk; no obvious market overlap)** — A sports broadcaster owns a US registration covering publication of
297
297
  physical-fitness games and instruction-sharing websites, for an inactive youth-fitness program. No
298
298
  obvious current use. Statement-of-use deadline 27 July 2026 — if not filed (which seems possible),
@@ -301,7 +301,7 @@ manageable.
301
301
  via games consoles (among much else), used for a tennis participation campaign and descriptively.
302
302
  Revocable for unused goods/services; low confusion with a console tagline; scope likely reducible
303
303
  away from gaming services if challenged.
304
- - **Manageable** — Polish telecom P4 ("Play") owns a Polish registration covering computer game
304
+ - **Manageable** — A Polish telecom owns a Polish registration covering computer game
305
305
  software and console game programs; no specific gaming interest; minor use on its careers site;
306
306
  low confusion; scope likely reducible away from gaming goods if challenged.
307
307
  - **Manageable** — A games-accessory maker holds invalid/lapsed CHART YOUR COURSE filings
@@ -313,11 +313,11 @@ manageable.
313
313
  - **Manageable** — "Chart Your Course" platform for sharing love of video games; limited social
314
314
  presence.
315
315
  - **Manageable** — "Chart Your Course" 2025 mental-health-in-gaming fundraiser (£7,000 raised).
316
- - **Manageable** — "Chart Your Course" announced as a major update for the game Peak (~127k
316
+ - **Manageable** — "Chart Your Course" announced as a major update for a popular co-op game (~127k
317
317
  "overwhelmingly positive" Steam reviews).
318
318
  - **Manageable** — "Charting Your Course" arcade-game subscription service.
319
319
  - **Not a rated conflict (clear win)** — A third-party Nebula console-streaming app uses "Chart Your Course" descriptively.
320
- - **Not a rated conflict (clear win)** — PC gaming companion app Wand has minor descriptive use.
320
+ - **Not a rated conflict (clear win)** — A PC gaming companion app has minor descriptive use.
321
321
  - **Not a rated conflict (clear win)** — A "Chart Your Course" card-game app and a "Chart My Course" fitness app.
322
322
 
323
323
  ---
@@ -336,18 +336,18 @@ side-glance at **Classes 35 and 39** (retail pizza store / pizza delivery) and *
336
336
 
337
337
  ### Executive summary (per mark)
338
338
 
339
- - **PRIZE CRATE — manageable.** Closest entries: UK registrations for PRIZE CRATE (food, not pizza) and LOOT
340
- CHEST (cardboard pizza boxes); confusion unlikely in a Blockvale pizza context, practical objection
339
+ - **PRIZE CRATE — manageable.** Closest entries: UK registrations for PRIZE CRATE (food, not pizza) and PRIZE
340
+ TRUNK (cardboard pizza boxes); confusion unlikely in a Blockvale pizza context, practical objection
341
341
  unlikely. Heavy gaming use/registration of PRIZE CRATE but none an immediate obstacle. Note the term's
342
342
  specific (often negative) gaming meaning — a PR consideration before use.
343
343
  - **CAVERN CRATES — manageable.** Closest is a US application CAVERN CRATE (Class 30, candy); confusion
344
344
  unlikely in the Blockvale pizza context, and no obvious use of CAVERN CRATE for candy. Some "Cavern
345
345
  Crate" use in a prize-crate context — minor negative-association risk.
346
- - **COUCH CO-OP MEAL — manageable.** "Couch co-op" = multiple players sharing one screen/console.
346
+ - **LOCAL CO-OP MEAL — manageable.** "Local co-op" = multiple players sharing one screen/console.
347
347
  Numerous supermarket CO(-)OP registrations cover pizza and gaming goods, but given the descriptive
348
- gaming meaning of "couch co-op" and strong Blockvale branding, confusion is unlikely.
349
- - **THE HERO'S CHEST: ADVENTURE ESSENTIALS — manageable.**
350
- - **THE SLICE AND DICE COMBO — moderate (low end).** An international "pizza and board game" venue trend uses
348
+ gaming meaning of "local co-op" and strong Blockvale branding, confusion is unlikely.
349
+ - **THE RANGER'S SATCHEL: QUEST ESSENTIALS — manageable.**
350
+ - **THE SLICE AND DICE PLATTER — moderate (low end).** An international "pizza and board game" venue trend uses
351
351
  "Slice and Dice"-type names (mostly unregistered, low reputation). The moderate rating attaches to an
352
352
  Irish registration SLICE N DICE (individual owner) claiming *both* pizza and electronic gaming goods;
353
353
  no use found but within the non-use grace period — plausibly a pizza/board-game venture. Given the
@@ -364,38 +364,38 @@ side-glance at **Classes 35 and 39** (retail pizza store / pizza delivery) and *
364
364
  - *Potential negative association / PR:* prize crates are tied to "compulsion loop" game design,
365
365
  criticised as gambling-style "dark patterns" and increasingly regulated; using "Prize Crate" for a
366
366
  gaming-pizza promo could be read as normalising a criticised practice. (Blockvale's natural-chest
367
- loot is non-monetised, not a gambling-style system.)
368
- - *Filings* — **Manageable**: Pence Technology (UK) owns PRIZE CRATE (Stylised) over broad food/beverage
367
+ prizes are non-monetised, not a gambling-style system.)
368
+ - *Filings* — **Manageable**: A UK technology company owns PRIZE CRATE (Stylised) over broad food/beverage
369
369
  (not pizza); no obvious use; not revocable yet, but low practical objection risk (company inactive).
370
- Prize Crate Retail (UK) owns LOOT CHEST & device over "cardboard pizza boxes" + broad goods; in
371
- voluntary insolvency, no recent operations, low practical risk. Loot Crate (geek subscription boxes)
372
- owns an international LOOT CRATE portfolio (apparel/paper/toys/retail), not food — no overlap. Numerous
373
- third-party LOOT( )BOX gaming filings — none can block given the term's non-distinctiveness in gaming.
374
- Pepsi owns LOOT / DORITO'S LOOT / EAT. DRINK. GET LOOT. over Class 30 foods (not pizza) — noted only
370
+ Prize Crate Retail (UK) owns PRIZE TRUNK & device over "cardboard pizza boxes" + broad goods; in
371
+ voluntary insolvency, no recent operations, low practical risk. Prize Case (geek subscription boxes)
372
+ owns an international PRIZE CASE portfolio (apparel/paper/toys/retail), not food — no overlap. Numerous
373
+ third-party PRIZE( )CRATE gaming filings — none can block given the term's non-distinctiveness in gaming.
374
+ Crunchmore Foods owns PRIZE / CRUNCHMORE'S PRIZE / EAT. DRINK. GET PRIZE. over Class 30 foods (not pizza) — noted only
375
375
  as a large food player; no confusion.
376
376
  - *Common-law* — **Manageable**: a virtual unboxing platform "Prize Crate"; "PRIZECRATE Game Store" (card/
377
- tabletop games); "Loot Drink" gamer energy-drink powder.
377
+ tabletop games); "Prize Drink" gamer energy-drink powder.
378
378
 
379
- **THE SLICE AND DICE COMBO — Moderate (low end)**
379
+ **THE SLICE AND DICE PLATTER — Moderate (low end)**
380
380
  - *Distinctiveness/context:* "slice"/"dice" are not very distinctive for pizza (knife actions; "slice"
381
381
  = pizza), reflected in 370 live SLICE/DICE filings claiming pizza in Class 30 — so analysis focuses on
382
382
  marks with both words or another element bringing them closer; "slice and dice" *is* distinctive for
383
383
  non-dice computer games; "dice" is not distinctive for board games.
384
- - *Filings* — **Moderate (low end; settleable overlap, or paper-only if unused)**: Conor Jordan (individual) owns an
384
+ - *Filings* — **Moderate (low end; settleable overlap, or paper-only if unused)**: An individual owns an
385
385
  Irish SLICE N DICE registration with a detailed gaming list (Class 28) *and* detailed pizza list
386
386
  (Class 30) — notable for that specificity. No use found; an international "board game + pizza" café
387
387
  trend uses identical "Slice and Dice" branding, plausibly the intent here. Despite the Blockvale
388
388
  context, given the identical mark and highly specific pizza+gaming intersection, **Irish counsel
389
- advice is recommended** (ideally with an example of the proposed use). Also **Manageable**: Wymac
390
- (Australian gaming-machine maker) SLICE N DICE (AU/US) — vulnerable to cancellation for unused goods,
391
- and in-venue machines don't overlap; Seneca (US casino) SLICE-N-DICE for a casino restaurant;
392
- Ravensburger DICE AND SLICE for a physical pizza-themed strategy game.
389
+ advice is recommended** (ideally with an example of the proposed use). Also **Manageable**: an
390
+ Australian gaming-machine maker's SLICE N DICE (AU/US) — vulnerable to cancellation for unused goods,
391
+ and in-venue machines don't overlap; a US casino's SLICE-N-DICE for a casino restaurant;
392
+ a board-game publisher's DICE AND SLICE for a physical pizza-themed strategy game.
393
393
  - *Common-law* — **Manageable**: "Slice & Dice" tactical dice roguelike (App Store / Google Play /
394
394
  Steam, 1m+ downloads, 2020) — no pizza theme, "dice" refers to the mechanic; confusion unlikely in
395
395
  the Blockvale pizza context. Numerous "Slice and Dice"-type pizzerias/bars, some offering tabletop
396
396
  gaming — none with reputation enough to confuse. "Slice and Dice" is also the name of a third-party Blockvale mod.
397
397
 
398
- *(Full CAVERN CRATES, COUCH CO-OP MEAL and THE HERO'S CHEST analyses follow the same chain — owner →
398
+ *(Full CAVERN CRATES, LOCAL CO-OP MEAL and THE RANGER'S SATCHEL analyses follow the same chain — owner →
399
399
  coverage + distinctiveness → use/revocability → overlap → enforcement → net, in a Blockvale-branded
400
400
  promotional context.)*
401
401
 
@@ -443,7 +443,7 @@ The crowded-field framing drives the whole mark: a register sweep returned rough
443
443
 
444
444
  **Aqua Dawn — Manageable Risk**
445
445
 
446
- A register sweep returned roughly 1,900 live DAWN / DAWN-formative filings internationally, but only a small fraction touch beverages or supplements, and the single dominant DAWN right sits in an unrelated cleaning-products field. Analysis focuses on DAWN and DAYBR___ marks with any Class 5/30/32 claim, and on the coffee-hybrid space the product actually occupies.
446
+ A register sweep returned roughly 1,900 live DAWN / DAWN-formative filings internationally, but only a small fraction touch beverages or supplements, and the single dominant DAWN right sits in an unrelated cleaning-products field. Analysis focuses on DAWN and SOLSTR___ marks with any Class 5/30/32 claim, and on the coffee-hybrid space the product actually occupies.
447
447
 
448
448
  *Filings*
449
449
  - **Manageable** — Procter & Gamble owns the well-known DAWN house mark, but its registrations sit in Class 3 (dishwashing/cleaning) with no beverage or supplement claim located. Famous mark, but a different field entirely; the dilution-style theory a famous-mark owner might raise is remote against a AQUA-led beverage extension, and there is no goods overlap. Noted because the name is prominent, not because it obstructs.
@@ -74,11 +74,11 @@ A single file inside the active run-dir: `studio/clearance-search/<slug>/<date>/
74
74
  ### Format
75
75
 
76
76
  ```markdown
77
- # Variant manifest — Dawn: Legends of Lumengarde (2026-05-11)
77
+ # Variant manifest — Dusk: Tales of Lumengarde (2026-05-11)
78
78
 
79
79
  ## Request
80
80
 
81
- - **Marks:** Dawn: Legends of Lumengarde
81
+ - **Marks:** Dusk: Tales of Lumengarde
82
82
  - **Classes:** 9, 28, 41, 42
83
83
  - **Jurisdiction:** worldwide
84
84
  - **Industry:** gaming
@@ -89,34 +89,34 @@ A single file inside the active run-dir: `studio/clearance-search/<slug>/<date>/
89
89
 
90
90
  ## Scope statement
91
91
 
92
- Preliminary clearance for "Dawn: Legends of Lumengarde" as a game title, Classes 9/28/41/42, worldwide. Industry-incumbent parallel sweeps apply for LUMENGARDE (lighting electronics).
92
+ Preliminary clearance for "Dusk: Tales of Lumengarde" as a game title, Classes 9/28/41/42, worldwide. Industry-incumbent parallel sweeps apply for LUMENGARDE (lighting electronics).
93
93
 
94
94
  ---
95
95
 
96
- ## Mark: Dawn: Legends of Lumengarde
96
+ ## Mark: Dusk: Tales of Lumengarde
97
97
 
98
98
  ### Archetype
99
99
 
100
- - **Primary:** Descriptive compound (3-word title; LUMENGARDE distinctive, DAWN + LEGENDS common saturated commons in gaming)
100
+ - **Primary:** Descriptive compound (3-word title; LUMENGARDE distinctive, DUSK + TALES common saturated commons in gaming)
101
101
  - **Modifiers:** None
102
102
  - **Boundary note:** LUMENGARDE alone would be a coined-word; the compound title shape places it under descriptive-compound. Coined-word axes (phonetic, transliteration, leet) still apply to LUMENGARDE element-solo.
103
103
 
104
104
  ### Distinctiveness & registrability (advisory — the staff lawyer to assess)
105
105
 
106
- - **Dominant element:** LUMENGARDE (DAWN + LEGENDS are common/descriptive — stripped). Search + conflict-ranking centre here.
106
+ - **Dominant element:** LUMENGARDE (DUSK + TALES are common/descriptive — stripped). Search + conflict-ranking centre here.
107
107
  - **Spectrum:** distinctive (LUMENGARDE coined; the compound is arbitrary for gaming). No obvious absolute-grounds problem.
108
108
  - **Flags:** none — not descriptive/generic/laudatory/geographic for the goods; not deceptive or offensive.
109
109
 
110
110
  ### Risk theory
111
111
 
112
- LUMENGARDE is the distinctive anchor — risk concentrates on coined-word axes around that element (phonetic variants, leet, foreign transliteration) plus the Lumengarde Electronics lighting incumbent. DAWN and LEGENDS are saturated commons; risk there is the single-distinctive-word DAWN-alone or LEGENDS-alone filing in gaming, not crowded-field volume. Compound-phrase exact hit is low-probability but high-impact if it surfaces.
112
+ LUMENGARDE is the distinctive anchor — risk concentrates on coined-word axes around that element (phonetic variants, leet, foreign transliteration) plus the Lumengarde Electronics lighting incumbent. DUSK and TALES are saturated commons; risk there is the single-distinctive-word DUSK-alone or TALES-alone filing in gaming, not crowded-field volume. Compound-phrase exact hit is low-probability but high-impact if it surfaces.
113
113
 
114
114
  ### Elements
115
115
 
116
116
  | Element | Role | Saturation | Famous-mark | Notes |
117
117
  |---|---|---|---|---|
118
- | DAWN | common-word | high | no | Morning / new beginning; fantasy / adventure |
119
- | LEGENDS | common-word | very-high | no | Myth / tale; epic / fantasy |
118
+ | DUSK | common-word | high | no | Evening / sunset; fantasy / adventure |
119
+ | TALES | common-word | very-high | no | Story / myth; epic / fantasy |
120
120
  | LUMENGARDE | distinctive | low | no | Industry incumbent: **Lumengarde Electronics Co.** (lighting / LED / semiconductors, classes 9 + 11) — triggers parallel sweep |
121
121
 
122
122
  ### Variants
@@ -140,10 +140,10 @@ silently narrows what was searched, and the deferred row is the honest outcome.
140
140
 
141
141
  | Category | Value | Rationale | Verify? |
142
142
  |---|---|---|---|
143
- | exact-phrase | Dawn: Legends of Lumengarde | full mark | |
143
+ | exact-phrase | Dusk: Tales of Lumengarde | full mark | |
144
144
  | exact-element | LUMENGARDE | distinctive anchor — primary register vector | |
145
- | exact-element | DAWN | common element — single-word coverage hunt | |
146
- | exact-element | LEGENDS | common element — single-word coverage hunt | |
145
+ | exact-element | DUSK | common element — single-word coverage hunt | |
146
+ | exact-element | TALES | common element — single-word coverage hunt | |
147
147
  | plural-root | LEGEND | tokeniser superset | |
148
148
  | phonetic | EVERLITE | homophone, distinctive element | |
149
149
  | phonetic | EVRLIGHT | vowel drop | |
@@ -179,7 +179,7 @@ silently narrows what was searched, and the deferred row is the honest outcome.
179
179
  ### Watchlists
180
180
 
181
181
  - **Aggressive enforcers:** Nordwave, Foxglade Interactive
182
- - **Major brand owners:** Sony, Aureon, Nintendo, HP, Activision, Take-Two, EA
182
+ - **Major brand owners:** Veltrona, Aureon, Pinecrest, Brightwick, Halloway, Duomark, Skyvault
183
183
  - **Competitors:** Epic Games, Valve, Unity, Riot Games
184
184
 
185
185
  ### Famous-mark Perplexity calls needed
@@ -188,7 +188,7 @@ None for this mark.
188
188
 
189
189
  ### Diligence notes
190
190
 
191
- LUMENGARDE carries coined-word axes (phonetic + transliteration) despite the descriptive-compound primary archetype. Industry-incumbent alert triggers a parallel-class 11 sweep. DAWN and LEGENDS are saturated commons — still generated as single-word vectors; their saturation tells the downstream register search to **narrow** (class-scope the token and enumerate), it is never a reason to skip the vector here or to pre-judge the crowd clean.
191
+ LUMENGARDE carries coined-word axes (phonetic + transliteration) despite the descriptive-compound primary archetype. Industry-incumbent alert triggers a parallel-class 11 sweep. DUSK and TALES are saturated commons — still generated as single-word vectors; their saturation tells the downstream register search to **narrow** (class-scope the token and enumerate), it is never a reason to skip the vector here or to pre-judge the crowd clean.
192
192
 
193
193
  ---
194
194
 
@@ -227,7 +227,7 @@ Pick one **primary** archetype. Pick zero or more **modifiers**. Write a one-lin
227
227
  **Worked examples:**
228
228
 
229
229
  - "LUMENGARDE" (single mark) → Coined word. No modifier. Risk: phonetic, transliteration, leet, coined-word collisions.
230
- - "Dawn: Legends of Lumengarde" → Descriptive compound (DAWN + LEGENDS commons, LUMENGARDE distinctive anchor). No modifier. Risk concentrates on LUMENGARDE element + compound-phrase hit.
230
+ - "Dusk: Tales of Lumengarde" → Descriptive compound (DUSK + TALES commons, LUMENGARDE distinctive anchor). No modifier. Risk concentrates on LUMENGARDE element + compound-phrase hit.
231
231
  - "CHART YOUR COURSE" → Slogan. No modifier. Risk: family patterns (CHART * COURSE, * YOUR COURSE, CHART YOUR *), verb swaps, slang.
232
232
  - "Bloodguard Sabatons" → Descriptive compound + famous-element-masked (Sabatons = Swedish metal band). Risk: per-element famous-mark search on Sabatons; descriptive-compound axes on the rest.
233
233
  - "RAIZ8" → Acronym/initialism (leet form of RAISE). Risk: letter-collision; expansion-form search on RAISE.
@@ -330,7 +330,7 @@ The `phonetic` / `visual-substitution` / `numeric-substitution` / typographic ro
330
330
 
331
331
  For multi-word marks where the structure carries meaning (slogans, descriptive compounds), substitute each stem-formative back into the phrase template:
332
332
 
333
- - "RAISE YOUR PLAY" → "ELEVATING YOUR GAME", "RAISE THE PLAY", "RAISING YOUR PLAY", etc.
333
+ - "RAISE YOUR PLAY" → "LIFTING YOUR PLAY", "RAISE THE PLAY", "RAISING YOUR PLAY", etc.
334
334
  - "CHART YOUR COURSE" → "CHARTING YOUR COURSE", "CHART MY COURSE", "CHART THE COURSE", "PLOT YOUR COURSE" (verb swap)
335
335
 
336
336
  Drop ungrammatical or semantically broken strings. Default: generate liberally; macro-count probes filter.
@@ -54,10 +54,10 @@ A directive may carry a structured `remedy`:
54
54
 
55
55
  **A firing `variant` directive — severity `dominant-element` or `material` — MUST be dispatchable.** That means one of exactly two things:
56
56
 
57
- 1. its `item` is *itself* a single mark-shaped search term (`TAKIS`, `AXIOS`, `CORAL MAGIC`), **or**
57
+ 1. its `item` is *itself* a single mark-shaped search term (`WAVA`, `ORBEXA`, `CORAL MAGIC`), **or**
58
58
  2. it carries `remedy.terms` naming the mark-shaped term(s) to search.
59
59
 
60
- A label-shaped `item` — more than 4 words, a parenthetical, an enumeration ("TAKIS (famous CPG snack, one-keystroke neighbour)", "Reverse-order WAVO composites (TROPICAL WAVO, ISLAND WAVO)") — is **never dispatched as a search term**: dispatched verbatim it is a nil search that comes back 0 and reads as a clean, which is worse than no search. So a firing `variant` directive whose item is a label **and which carries no remedy is a PARSE DEFECT** — the driver refuses the file and asks you to restate it, in this same turn, while restating is still free. Every term you put in `remedy.terms` is linted the same way: a remedy that is itself a label is refused exactly like the item was.
60
+ A label-shaped `item` — more than 4 words, a parenthetical, an enumeration ("WAVA (famous CPG snack, one-keystroke neighbour)", "Reverse-order WAVO composites (TROPICAL WAVO, ISLAND WAVO)") — is **never dispatched as a search term**: dispatched verbatim it is a nil search that comes back 0 and reads as a clean, which is worse than no search. So a firing `variant` directive whose item is a label **and which carries no remedy is a PARSE DEFECT** — the driver refuses the file and asks you to restate it, in this same turn, while restating is still free. Every term you put in `remedy.terms` is linted the same way: a remedy that is itself a label is refused exactly like the item was.
61
61
 
62
62
  The refusal names **every** offending directive at once, and it arrives as the tool's answer to your call — in this turn, while restating is still free. Fix them **all** in one further call: the repair ladder counts attempts, not directives, so repairing only the first one loses the rest. A call replaces the stored diff, so send the whole thing again, not only the corrected directives.
63
63
 
@@ -123,6 +123,19 @@ export const TOOL_GROUP_EDGES = {
123
123
  { path: P.bandShapeMd, why: "band_shape serves band-shape.md (the readable shape, part-paged)" },
124
124
  { path: P.registerPositions, why: "the exact-identity projection the shape and the recall join read as one unit" },
125
125
  { path: join(P.runDir, "_records"), dir: true, why: "band_record serves the official registry records fetched into this run" },
126
+ // SEVENTH OCCURRENCE OF THIS TABLE'S OWN SUBJECT, and the arm written to prevent it could not see this
127
+ // one. `band_record` serves a body from `_records/` OR from this log, and at step 2 the real run served
128
+ // placement's reads from the log rather than from files. Undeclared, the sandbox copy held no bodies and
129
+ // every one of those reads failed — measured on five saved runs, where placement opened 31, 32, 2, 2 and
130
+ // 0 records: in the sandbox as shipped, all of them fail.
131
+ //
132
+ // WHY THE GENERIC ARM MISSED IT. That arm walked the servers for `driverDir(runDir, X)` and kept X only
133
+ // when it ended in `.json`; this file ends in `.jsonl`, so it was never in the population the arm
134
+ // checked. The filter stood in for telling a read from a write, since every file the servers write is
135
+ // `.jsonl` too. The walk now makes that distinction itself, at any extension (experiment-context.test.mjs,
136
+ // `driverFileUses`), so this file is held by the same rule as every other read.
137
+ { path: driverDir(P.runDir, "register-record-bodies.jsonl"),
138
+ why: "band_record serves a record body from this log when the run fetched it through the ledger rather than into _records/ (band-server.mjs recordLedgerPath); without it the sandbox's record reads all fail and the re-run sees less than the stage saw" },
126
139
  ],
127
140
  // ── conversion 11 — THE RECORD TOOL READS A DRIVER-WRITTEN SIDECAR, AND NOTHING DECLARED IT ───────
128
141
  //
@@ -200,7 +213,20 @@ const UNDECLARED = {
200
213
  // inline and names the `record_coverage` tool), the seat opens no coverage file, and the accumulator
201
214
  // the gate judges is declared on VALIDATOR_SIDECARS below. The brief's own read of that accumulator
202
215
  // is declared on DISPATCH_EXTRAS.
203
- "register-digest": () => [],
216
+ // THE PROMPT NAMES A FILE THE SANDBOX DID NOT COPY, so a re-run of the digest differed from the real
217
+ // stage in one input the prompt names, invisibly: the stage passed. The digest's message ("MARK THE LIST")
218
+ // names the hit list and asks the model to mark lines on it, and `hit-list.mjs` reads those marks back.
219
+ // Absent from the copy, a marking the model sends lands nowhere and nothing refuses — measured on a bench
220
+ // plumbing run where the digest completed with owed 7 accounted 7 and the hit list was simply not there.
221
+ //
222
+ // DECLARED UNCONDITIONALLY, for the reason the digest's accounting stamp above is: `sandboxGaps` reports a
223
+ // gap only for something the CANONICAL run holds, so a run that never built a hit list contributes no gap,
224
+ // and one that built it and lost it in the copy refuses by name. Listing it costs nothing on the first and
225
+ // is the whole point on the second.
226
+ "register-digest": (P) => [
227
+ { path: P.registerHitList,
228
+ why: "the digest's own message names this file and asks the model to mark lines on it (hit-list.mjs reads the marks back); without it in the copy a marking lands nowhere and the stage passes having been given a different input than the real one" },
229
+ ],
204
230
  // The provider enforcement telemetry: the prompt names the path only when ctx.enforcerSignals is a
205
231
  // non-zero count (stages.mjs synthesis message). Undeclared on purpose — it is aim-attention only and
206
232
  // must never move a freshness stamp — but a sandbox without it hands a different prompt.
package/driver/stages.mjs CHANGED
@@ -35,7 +35,7 @@ import { LINE_GROUNDS } from "./hit-list.mjs"; // — the dictation reads the
35
35
  import { marketplaceScopeDirective } from "./jurisdiction-systems.mjs";
36
36
  import { MEANING_SEAT } from "./common-law-receipts.mjs"; // — the seat whose whole dispatch is the meaning sweep
37
37
  import { meaningSweepReceiptsInstruction } from "./connotation-search.mjs"; // M1 — ONE composer; this sentence was authored four times
38
- import { frameworkFor, workedExamplesFor } from "./framework.mjs"; import { methodDictation, inputsShape } from "./framework-method.mjs";
38
+ import { frameworkFor, workedExamplesFor, materialBandPhrase } from "./framework.mjs"; import { methodDictation, inputsShape } from "./framework-method.mjs";
39
39
  import { requiredScriptsFor } from "./registration-scripts.mjs"; // item 21 — which scripts a territory registers marks in
40
40
  import { resolveTerritories, defaultJurisdictionsLine, narrowingOrderLine } from "./effective-scope.mjs"; // the ONE territory ladder (the geography stamp included) + the defaults-never-widen rule (2160)
41
41
  import { editRepairTail } from "./repair-contract.mjs";
@@ -1436,7 +1436,7 @@ export const STAGES = {
1436
1436
  },
1437
1437
  "mark — \"<the mark verbatim>\"": {
1438
1438
  class: "mechanical:pre-bound", tokens: ["variantmodel_mark_missing"],
1439
- why: "_driver/instructed-scope.json.marks holds it and stage-context.mjs:175 binds that file to this stage. variant-manifest-model.mjs:225-231 already concedes the field is not the model's: it is excluded from the term-shape gate because \"the stage is told to emit it VERBATIM, and it arrives from the job… a value this stage CANNOT restate\" [citation unverified]",
1439
+ why: "_driver/instructed-scope.json.marks holds it and stage-context.mjs:175 TOOL_GROUP_EDGES binds that file to this stage. variant-manifest-model.mjs:225-231 parseVariantManifestModel already concedes the field is not the model's: it is excluded from the term-shape gate because \"the stage is told to emit it VERBATIM, and it arrives from the job… a value this stage CANNOT restate\" [citation unverified]",
1440
1440
  },
1441
1441
  "dominant_element — the distinctive anchor the sweep enumerates": {
1442
1442
  class: "judgment", tokens: ["variantmodel_dominant_element_missing"],
@@ -1516,7 +1516,7 @@ export const STAGES = {
1516
1516
  },
1517
1517
  "### Scope ledger rows — {Layer, Item, Status: applied|dropped, Reason, Reopen trigger} across variant / field / source / jurisdiction": {
1518
1518
  class: "judgment", tokens: [],
1519
- why: "defending an omission with the concrete observation that should reopen it is the whole judgment, and frame-diff diffs it against the blind re-derivation. The ROW SHAPE is mechanical — scope-ledger.mjs:123-126 parses the table into scope-ledger.json — and the jurisdiction rows are largely a re-carry of the matter frame's own Scope-jurisdictions line [citation unverified]",
1519
+ why: "defending an omission with the concrete observation that should reopen it is the whole judgment, and frame-diff diffs it against the blind re-derivation. The ROW SHAPE is mechanical — scope-ledger.mjs:123-126 renderScopeLedgerJson parses the table into scope-ledger.json — and the jurisdiction rows are largely a re-carry of the matter frame's own Scope-jurisdictions line [citation unverified]",
1520
1520
  },
1521
1521
  "Prose variant-table category token — translit-<script>, and for Chinese translit-zh-meaning vs translit-zh-phonetic": {
1522
1522
  class: "judgment", tokens: [],
@@ -2372,7 +2372,7 @@ export const STAGES = {
2372
2372
  },
2373
2373
  "select — one record URI of the register candidate being placed": {
2374
2374
  class: "mechanical:code-extracted", tokens: [],
2375
- why: "buildSelectionIndex() in placement-form.mjs already holds every selectable record, built from _driver/register-positions.json plus the band shape's floors, and resolves any URI of a family to the canonical row. #850 M1: the model should return the 1-based index into that driver-written list; code resolves index→id. WHICH candidate to place stays judgment — the row existing at all is the judgment; only the pointing token is mechanical. NO VALIDATOR TOKEN speaks about it: an unresolved select is recorded on the form as `unresolved[]` (placement-union.mjs:134) and handed back in the next dispatch, never a fail. [citation unverified]",
2375
+ why: "buildSelectionIndex() in placement-form.mjs already holds every selectable record, built from _driver/register-positions.json plus the band shape's floors, and resolves any URI of a family to the canonical row. #850 M1: the model should return the 1-based index into that driver-written list; code resolves index→id. WHICH candidate to place stays judgment — the row existing at all is the judgment; only the pointing token is mechanical. NO VALIDATOR TOKEN speaks about it: an unresolved select is recorded on the form as `unresolved[]` (placement-union.mjs:134 pushSelection) and handed back in the next dispatch, never a fail. [citation unverified]",
2376
2376
  },
2377
2377
  "seat rows for candidates the register does not hold — mark / owner / jurisdiction / records: [] written in full": {
2378
2378
  class: "judgment", tokens: ["placement_mark_missing", "placement_owner_missing", "placement_jurisdiction_invalid", "placement_records_invalid"],
@@ -2384,7 +2384,7 @@ export const STAGES = {
2384
2384
  },
2385
2385
  "the identifier half of each `cleared:` / `material-gap:` line — the axis, the named slice and its count": {
2386
2386
  class: "mechanical:code-extracted", tokens: [],
2387
- why: "The band's `incomplete` crowd descriptor carries query, total_hits, fetched and reason, and the driver already writes one coverage-form row per unaccounted crowd block with the qid, hit count and unaccounted classes/terms computed (coverage-form.mjs; digest.md:196-201). The MATERIALITY CALL is judgment and stays in the element above; the descriptor's identity and count are transcription of the driver's own numbers.",
2387
+ why: "The band's `incomplete` crowd descriptor carries query, total_hits, fetched and reason, and the driver already writes one coverage-form row per unaccounted crowd block with the qid, hit count and unaccounted classes/terms computed (coverage-form.mjs; digest.md, 'Coverage ledger'). The MATERIALITY CALL is judgment and stays in the element above; the descriptor's identity and count are transcription of the driver's own numbers.",
2388
2388
  },
2389
2389
  "the md's four tier sections — one per-candidate entry restating that candidate's tier and reasoning": {
2390
2390
  class: "mechanical:code-rendered", tokens: ["missing", "too_short"],
@@ -2404,7 +2404,7 @@ export const STAGES = {
2404
2404
  },
2405
2405
  "retract: <row_id> — withdrawing a seat row already on the form": {
2406
2406
  class: "judgment", tokens: [],
2407
- why: "Whether a placed candidate should come off is a call only the model makes. The row_id it names is driver-assigned (shortId 'PS'/'PR', placement-form.mjs:205/273), so the HANDLE is code-assigned even though the act is judgment. [citation unverified]",
2407
+ why: "Whether a placed candidate should come off is a call only the model makes. The row_id it names is driver-assigned (shortId 'PS'/'PR', placement-form.mjs:205 renderEntry/273), so the HANDLE is code-assigned even though the act is judgment. [citation unverified]",
2408
2408
  },
2409
2409
  "return payload — the absolute output path plus a 2-3 line summary": {
2410
2410
  class: "mechanical:pre-bound", tokens: [],
@@ -2490,7 +2490,7 @@ export const STAGES = {
2490
2490
  },
2491
2491
  "seat-added coverage rows — the decision to add one, and the axis it is filed under (expressed in the `unit` label)": {
2492
2492
  class: "judgment", tokens: ["coverage_form_axis_invalid"],
2493
- why: "The shipped code rules it judgment in its own words: 'THE AXIS IS PART OF THE JUDGMENT, and on a SEAT row it is the one identifier the seat still supplies' and normalizeAxis 'repair[s] formatting, never invent[s] an axis' (coverage-form.mjs:519-524). The driver cannot know which axis a coverage unit it never planned belongs under. [citation unverified]",
2493
+ why: "The shipped code rules it judgment in its own words: 'THE AXIS IS PART OF THE JUDGMENT, and on a SEAT row it is the one identifier the seat still supplies' and normalizeAxis 'repair[s] formatting, never invent[s] an axis' (coverage-form.mjs:519-524 coverageFormRows). The driver cannot know which axis a coverage unit it never planned belongs under. [citation unverified]",
2494
2494
  },
2495
2495
  "the seat row's duplicate `axis` cell (the same token already typed as the leading segment of `unit`)": {
2496
2496
  class: "mechanical:code-extracted", tokens: ["coverage_form_axis_invalid"],
@@ -2502,7 +2502,7 @@ export const STAGES = {
2502
2502
  },
2503
2503
  "the compulsory dominant-element crowd row's `unit` cell — the dictated grammar `<axis> / dominant-element crowd (<N> members): <label>` and the bare integer N": {
2504
2504
  class: "mechanical:code-rendered", tokens: [],
2505
- why: "The driver computes the denominator: it groups screened-live dominant-element records by _driver/register-positions.json, counts the positions the digest did not individually end, verifies N and re-verifies after every rewrite (digest.md:132-164). The model is asked to retype a number the driver already checks it against — the frame_scope_missing loop restated. The RULING (why crowd membership ends this residual class) is judgment and lives in `reason`. No verify.mjs token: the reconciliation gate is a delivery block in pipeline.mjs, not this stage's validator.",
2505
+ why: "The driver computes the denominator: it groups screened-live dominant-element records by _driver/register-positions.json, counts the positions the digest did not individually end, verifies N and re-verifies after every rewrite (digest.md, 'Dominant-element reconciliation'). The model is asked to retype a number the driver already checks it against — the frame_scope_missing loop restated. The RULING (why crowd membership ends this residual class) is judgment and lives in `reason`. No verify.mjs token: the reconciliation gate is a delivery block in pipeline.mjs, not this stage's validator.",
2506
2506
  },
2507
2507
  "rolled-up coverage judgment — `sufficient: <true|false>`": {
2508
2508
  class: "mechanical:code-extracted", tokens: [],
@@ -2542,7 +2542,7 @@ export const STAGES = {
2542
2542
  },
2543
2543
  "Audit trail — per-unit search/detail-fetch counts, per-jurisdiction `_query` attribution": {
2544
2544
  class: "mechanical:tool-written", tokens: [],
2545
- why: "CONVERTED (conversion 11): the driver renders the Audit trail table from the same artifacts as the Summary counts, plus `_query` which digest.md:388 says 'the driver stamps at merge' — carrying that forward was transcription of a driver stamp. The judgment half — flagging a unit that shortcut its axis — stays in the findings-prose element.",
2545
+ why: "CONVERTED (conversion 11): the driver renders the Audit trail table from the same artifacts as the Summary counts, plus `_query` which digest.md says 'the driver stamps at merge' — carrying that forward was transcription of a driver stamp. The judgment half — flagging a unit that shortcut its axis — stays in the findings-prose element.",
2546
2546
  },
2547
2547
  "INSTRUCTED CHECKS — the answer to each requester ask the register owns": {
2548
2548
  class: "judgment", tokens: ["registerdigest_instructed_incomplete"],
@@ -2839,7 +2839,7 @@ export const STAGES = {
2839
2839
  // demands. Stating it only in skills/frame-diff/SKILL.md would leave this line inviting the exact
2840
2840
  // shape the parse throws on — enforcement without a matching invitation, which is how the
2841
2841
  // 2026-07-29 run raised four omissions nothing could search.
2842
- `A FIRING variant directive (severity dominant-element or material) MUST be dispatchable: either its "item" is ITSELF a single mark-shaped search term (TAKIS, AXIOS, CORAL MAGIC), or it carries remedy: {terms:["<mark-shaped term>", …], nice_classes:["<class>", …]} saying WHAT to search. A label — a parenthetical, an enumeration, more than about four words ("TAKIS (famous CPG snack, one-keystroke neighbour)") — dispatches as a nil search that reads CLEAN, so the driver REFUSES the file and asks you to restate it in-turn. Every offending directive is named at once: fix them ALL in one re-save. Never delete a directive or downgrade it to "minor" to get past this — a real omission must still be raised, it just has to say what the search IS.`,
2842
+ `A FIRING variant directive (severity dominant-element or material) MUST be dispatchable: either its "item" is ITSELF a single mark-shaped search term (WAVA, ORBEXA, CORAL MAGIC), or it carries remedy: {terms:["<mark-shaped term>", …], nice_classes:["<class>", …]} saying WHAT to search. A label — a parenthetical, an enumeration, more than about four words ("WAVA (famous CPG snack, one-keystroke neighbour)") — dispatches as a nil search that reads CLEAN, so the driver REFUSES the file and asks you to restate it in-turn. Every offending directive is named at once: fix them ALL in one re-save. Never delete a directive or downgrade it to "minor" to get past this — a real omission must still be raised, it just has to say what the search IS.`,
2843
2843
  `field and source directives are NOT under that rule: an un-classed field directive and a source channel are disclosed rather than swept blind, which is a principled ending for those layers. A remedy is welcome on them whenever you know the exact re-search, and any remedy you supply is linted the same way wherever it rides.`,
2844
2844
  `Set dominant_element_gap true when the dominant element is not fully enumerated (the crowd not yet counted worldwide, a spine neighbour unsearched). The driver holds the dominant element and re-checks this against it — do not rely on it to hide a spine omission.`,
2845
2845
  //, third conversion — THE WRITE DICTATION AND BOTH PATHS ARE GONE. This dispatch used to end
@@ -3112,7 +3112,7 @@ export const STAGES = {
3112
3112
  // WS2 (spec 11) — ENFORCED, not advisory: validators.narrative HARD-REJECTS this file if a
3113
3113
  // use-dependent finding above the framework's lowest band asserts a use-negative without a searched
3114
3114
  // source line. So actually run the query.
3115
- `USE-CHECK (enforced): for EVERY finding whose mitigant/verdict turns on the ABSENCE of use (regardless of its band) ("not in actual use", "unused", "no marketplace use found", non-use revocation/cancellation as the mitigant, "owner's use unknown"), run ONE scoped \`perplexity_research\` query (owner + mark + the goods/field) and END that finding's actual-use line with a literal "- **Use-check source:** <result URL | "perplexity_research — no result">" line. Mirror the result into the matching # Actions item (the deferred "confirm the owner's use" becomes a stated result). NEVER assert a use-negative you did not search — an inference from the owner's profile is not a searched result. On a perplexity outage write "- **Use-check source:** perplexity_research — no result" and proceed (the run still delivers). ALSO populate that finding's use_check field in findings.json: {"source": "<the result URL | perplexity_research — no result>"} — the structured field is the authoritative cite the report renders from (the prose line is for narrative readability).`,
3115
+ `USE-CHECK (enforced): run the scoped use check (phase2-execution.md Step 3.5) on EVERY finding banded ${(framework && materialBandPhrase(framework)) || "medium risk or higher"} — the rungs this framework rates medium risk or higher; a lower rung is not checked — and ask in the SAME query for the owner's enforcement record (oppositions, disputes or court actions over this mark or a similar one). After the search, use is "confirmed" or "not-confirmed", never "unknown". What the query finds about enforcement is a LEAD under ENFORCEMENT AUTHORITY below: enforcer basis "inferred-from-signal", its URL cited inline in that finding's prose; where it finds none, the enforcer is "low" with basis "inferred-from-signal" and the finding says the search found no enforcement record. ALSO, for EVERY finding whose mitigant/verdict turns on the ABSENCE of use (regardless of its band) ("not in actual use", "unused", "no marketplace use found", non-use revocation/cancellation as the mitigant, "owner's use unknown"), run ONE scoped \`perplexity_research\` query (owner + mark + the goods/field) and END that finding's actual-use line with a literal "- **Use-check source:** <result URL | "perplexity_research — no result">" line. Mirror the result into the matching # Actions item (the deferred "confirm the owner's use" becomes a stated result). NEVER assert a use-negative you did not search — an inference from the owner's profile is not a searched result. On a perplexity outage write "- **Use-check source:** perplexity_research — no result" and proceed (the run still delivers). ALSO populate that finding's use_check field in findings.json: {"source": "<the result URL | perplexity_research — no result>"} — the structured field is the authoritative cite the report renders from (the prose line is for narrative readability).`,
3116
3116
  // Spec-v3 A4 — ENFORCED the same way (validators.narrative): own-rights reliance needs its evidence.
3117
3117
  // PR-8 review fix: synthesis holds the FROZEN band, not the live register — and the band is class-
3118
3118
  // and mark-text-scoped to this matter's dispatched slices, so the client's OWN house-mark
@@ -3280,7 +3280,7 @@ export const STAGES = {
3280
3280
  // beside it is caught only if the prose form itself trips SCOPE_NUMBER_RE — which the narrative's
3281
3281
  // own phrasings routinely dodge. Prompt-only per §7; the fix is to stop authoring the duplicate.
3282
3282
  `COVERAGE PROSE (the lane that runs longest — hold it to the house budgets): the register coverage line a reader sees is COMPUTED from this run's own record and STAMPED BY CODE as front-matter (the proportion, the class states, the searched registers). Do NOT re-type its numbers anywhere in prose — not in a coverage[] note, not in the coverage_judgment reason, not in the narrative. Nothing catches the duplicate for you (the code-stamped line sits outside the prose checks precisely because ITS numbers are the authoritative ones), so a re-typed count does not disagree with the record — it silently drifts from it a redelivery later. Carry the SUBSTANCE and drop the number: "the remaining forms are non-Latin script" says the useful half; the code says how many. State each coverage fact ONCE, in ONE place — an area's state belongs in its coverage[] row, the sufficiency read belongs in coverage_judgment.reason, and neither is re-narrated in the other or in the findings. And say WHICH KIND of negative you hold every time: a source this run actually queried and got nothing from reads "searched — none found"; a source it did not reach reads "not searched this run" or "could not be searched — <the reason>". The same source must never wear both readings in one report.`,
3283
- `- use_check / own_rights: OPTIONAL per-finding objects; populate per the USE-CHECK / OWN-RIGHTS rules above. use_check = {"source","quality"}: source is the cite of record the report renders — MANDATORY (spec-48 A4, symmetric) for ANY ASSERTED use status (token "confirmed" OR "not-confirmed") on a finding banded ABOVE the framework's lowest band, not only use-negatives (the validator rejects an asserted use with no receipt: finding_use_check_missing); "unknown" needs none. quality: OPTIONAL, EXACTLY one of owner-site / independent / register-mirror — your read of what KIND of page the source is (the code re-derives its own classification and wins; a register mirror is never evidence of use). own_rights = {"source"} — MANDATORY for any own-rights-reliant finding.`,
3283
+ `- use_check / own_rights: OPTIONAL per-finding objects; populate per the USE-CHECK / OWN-RIGHTS rules above. use_check = {"source","quality"}: source is the cite of record the report renders — MANDATORY (spec-48 A4, symmetric) for ANY ASSERTED use status (token "confirmed" OR "not-confirmed") on a finding banded ${(framework && materialBandPhrase(framework)) || "medium risk or higher"}, not only use-negatives (the validator rejects an asserted use with no receipt: finding_use_check_missing); "unknown" needs none. quality: OPTIONAL, EXACTLY one of owner-site / independent / register-mirror — your read of what KIND of page the source is (the code re-derives its own classification and wins; a register mirror is never evidence of use). own_rights = {"source"} — MANDATORY for any own-rights-reliant finding.`,
3284
3284
  // U3 (probative grading) — a risk-RAISING signal must say what it proves about THIS conflict.
3285
3285
  `- bears_on: a string, MANDATORY whenever this finding's enforcer meter is "high" (and good practice for any other risk-RAISING adjustment): one line on what the fact proves about THIS mark against THIS owner's rights on the disputed element — e.g. "owner has asserted <element> against comparable <goods>", NOT a bare "aggressive enforcer". A default win on a different element, or against an obvious copycat, does not count: if you cannot say why it bears on this confusion, the fact is annotation and the enforcer meter is not "high".`,
3286
3286
  // doc-35 T1 (authority grounding — fetch-before-cite, like use_check/own_rights): an enforcement AUTHORITY