clearotron 0.3.2-beta.7 → 0.3.2-beta.9

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 (272) hide show
  1. package/.env.example +58 -26
  2. package/CONTRIBUTING.md +8 -8
  3. package/INSTALL.md +148 -81
  4. package/README.md +3 -3
  5. package/SECURITY.md +3 -3
  6. package/bin/brandowner.mjs +3 -3
  7. package/bin/framework-preflight.mjs +1 -1
  8. package/bin/onboard.mjs +637 -216
  9. package/bin/start.mjs +151 -27
  10. package/bin/update.mjs +58 -11
  11. package/build-info.json +2 -2
  12. package/docs/DELIVERY.md +2 -1
  13. package/docs/INTAKE.md +1 -1
  14. package/docs/ONBOARDING.md +1 -1
  15. package/docs/architecture/03-run-lifecycle.md +6 -6
  16. package/docs/architecture/04-configuration-reference.md +32 -14
  17. package/docs/architecture/05-config-governance.md +23 -8
  18. package/docs/architecture/05-customer-profiles.md +2 -2
  19. package/docs/architecture/06-operations-runbook.md +3 -3
  20. package/docs/architecture/08-development-guide.md +6 -6
  21. package/docs/configuration.md +5 -5
  22. package/docs/decisions/0003-credential-model.md +1 -1
  23. package/docs/writing-standard.md +4 -0
  24. package/driver/CHANGELOG.md +124 -0
  25. package/driver/README.md +3 -3
  26. package/driver/band-size.mjs +59 -0
  27. package/driver/binding-layers.mjs +1 -1
  28. package/driver/citation-census.json +3 -3
  29. package/driver/{prelim-variants-record.mjs → clearance-variants-record.mjs} +24 -24
  30. package/driver/common-law-receipts.mjs +2 -2
  31. package/driver/company-bundle.mjs +3 -3
  32. package/driver/compose-read.mjs +8 -14
  33. package/driver/config-inventory.mjs +112 -9
  34. package/driver/consumption-ledger.mjs +2 -2
  35. package/driver/contract-arm2-baseline.json +2 -5
  36. package/driver/contract-dictation-registry.mjs +19 -19
  37. package/driver/contract-e3-backlog.mjs +43 -43
  38. package/driver/contract-e3-baseline.json +14 -14
  39. package/driver/contract-vocabulary.mjs +68 -27
  40. package/driver/deliver-trigger.sh +16 -16
  41. package/driver/demo-container.mjs +3 -3
  42. package/driver/dev-portal.mjs +3 -3
  43. package/driver/disposition-call.mjs +1 -1
  44. package/driver/door-gates.mjs +41 -7
  45. package/driver/doubt-ledger.mjs +2 -2
  46. package/driver/drainer-identity.mjs +34 -8
  47. package/driver/driver.config.mjs +367 -104
  48. package/driver/engine/CONTRACT.md +10 -3
  49. package/driver/engine/README.md +2 -2
  50. package/driver/engine/anthropic-agent.mjs +77 -21
  51. package/driver/engine/auth.mjs +129 -10
  52. package/driver/engine/jx-turn.mjs +7 -6
  53. package/driver/engine/mcp/README.md +1 -1
  54. package/driver/engine/mcp/dispositions-server.mjs +3 -3
  55. package/driver/engine/mcp/gather-config.mjs +9 -9
  56. package/driver/engine/mcp/perplexity-server.mjs +2 -2
  57. package/driver/engine/mcp/recording-server.mjs +18 -5
  58. package/driver/engine/openai-agent.mjs +4 -2
  59. package/driver/engine/probe.mjs +110 -23
  60. package/driver/enqueue-schema.mjs +6 -2
  61. package/driver/findings-model.mjs +6 -3
  62. package/driver/flag-snapshot.mjs +34 -8
  63. package/driver/form-neighbourhood.mjs +54 -7
  64. package/driver/framework.mjs +4 -4
  65. package/driver/gateway.mjs +36 -24
  66. package/driver/jx-lanes.mjs +23 -4
  67. package/driver/jx-units.mjs +7 -4
  68. package/driver/jx.mjs +34 -4
  69. package/driver/knockout-review-record.mjs +56 -4
  70. package/driver/known-conflicts.mjs +1 -1
  71. package/driver/matter-frame-record.mjs +90 -1
  72. package/driver/named-band.mjs +1 -1
  73. package/driver/ordinary-words.mjs +51 -0
  74. package/driver/outbox-backoff.mjs +31 -16
  75. package/driver/package.json +1 -1
  76. package/driver/partial-payload-baseline.json +2 -2
  77. package/driver/phase0.mjs +3 -3
  78. package/driver/pipeline-knockout.mjs +5 -5
  79. package/driver/pipeline.mjs +396 -81
  80. package/driver/placement-form.mjs +77 -1
  81. package/driver/placement-model.mjs +1 -1
  82. package/driver/portal-config-view.mjs +30 -1
  83. package/driver/portal-report.mjs +107 -6
  84. package/driver/portal-service.mjs +80 -14
  85. package/driver/portal-upstream.mjs +1 -1
  86. package/driver/predelivery-lint.mjs +12 -2
  87. package/driver/preserve-merge.mjs +3 -3
  88. package/driver/product-rows.mjs +2 -2
  89. package/driver/products.mjs +1 -1
  90. package/driver/profiles/README.md +3 -3
  91. package/driver/profiles/demo-brand-owner.json +2 -2
  92. package/driver/profiles.mjs +55 -17
  93. package/driver/progress.mjs +18 -8
  94. package/driver/provider-usage.mjs +8 -8
  95. package/driver/publish/index.mjs +154 -8
  96. package/driver/publish/knockout.mjs +39 -5
  97. package/driver/publish/pool-admin.mjs +1 -1
  98. package/driver/publish/publish-inputs.mjs +18 -2
  99. package/driver/publish/render-knockout.mjs +184 -31
  100. package/driver/publish/render.mjs +323 -93
  101. package/driver/publish/report-data.mjs +4 -1
  102. package/driver/publish/report-topbar.mjs +58 -0
  103. package/driver/publish/search-depth.mjs +133 -4
  104. package/driver/publish/templates/report.css +78 -4
  105. package/driver/publish/xlsx.mjs +20 -1
  106. package/driver/queue-order.mjs +2 -2
  107. package/driver/recording-agreement.mjs +1 -1
  108. package/driver/reference-score.mjs +1 -1
  109. package/driver/register-availability.mjs +2 -2
  110. package/driver/register-count.mjs +50 -5
  111. package/driver/register-coverage.mjs +161 -1
  112. package/driver/register-digest-record.mjs +236 -11
  113. package/driver/register-grant-vocabulary.mjs +1 -1
  114. package/driver/register-plan.mjs +189 -2
  115. package/driver/registry-fidelity.mjs +3 -3
  116. package/driver/repair-composers.mjs +1 -1
  117. package/driver/repair-contract.mjs +1 -1
  118. package/driver/replay-archive.mjs +6 -6
  119. package/driver/report-overview-record.mjs +2 -2
  120. package/driver/result-noun-fields.mjs +2 -2
  121. package/driver/run-economics.mjs +41 -10
  122. package/driver/run-requirements.mjs +173 -9
  123. package/driver/runner.mjs +5 -5
  124. package/driver/scope-facts.mjs +20 -5
  125. package/driver/scope-ledger.mjs +5 -5
  126. package/driver/search-policy.mjs +22 -12
  127. package/driver/skills/README.md +15 -15
  128. package/driver/skills/blind-frame/SKILL.md +2 -2
  129. package/driver/skills/case-law-citation/SKILL.md +4 -4
  130. package/driver/skills/case-law-citation/sources/eurlex.md +1 -1
  131. package/driver/skills/{prelim-common-law → clearance-common-law}/SKILL.md +22 -22
  132. package/driver/skills/{prelim-common-law → clearance-common-law}/perplexity-prompts.md +1 -1
  133. package/driver/skills/{prelim-register → clearance-register}/SKILL.md +10 -10
  134. package/driver/skills/{prelim-register → clearance-register}/digest.md +2 -2
  135. package/driver/skills/{prelim-register → clearance-register}/providers/README.md +1 -1
  136. package/driver/skills/{prelim-register → clearance-register}/providers/clarivate.md +37 -35
  137. package/driver/skills/{prelim-register → clearance-register}/providers/corsearch.md +20 -11
  138. package/driver/skills/{prelim-register → clearance-register}/providers/signa.md +5 -5
  139. package/driver/skills/{prelim-register → clearance-register}/register-recipes.md +3 -3
  140. package/driver/skills/{prelim-register → clearance-register}/status-rules.md +2 -2
  141. package/driver/skills/{prelim-register → clearance-register}/stealth-filer-indicators.md +1 -1
  142. package/driver/skills/{prelim-register → clearance-register}/unit.md +2 -2
  143. package/driver/skills/{prelim-search → clearance-search}/SKILL.md +31 -31
  144. package/driver/skills/{prelim-search → clearance-search}/delivery-contract.md +1 -1
  145. package/driver/skills/{prelim-search → clearance-search}/phase2-execution.md +18 -18
  146. package/driver/skills/{prelim-search → clearance-search}/synthesis-rules.md +7 -7
  147. package/driver/skills/{prelim-variants → clearance-variants}/SKILL.md +18 -18
  148. package/driver/skills/{prelim-variants → clearance-variants}/transliteration-scripts.md +5 -5
  149. package/driver/skills/frame-diff/SKILL.md +1 -1
  150. package/driver/skills/knockout-assess/SKILL.md +10 -7
  151. package/driver/skills/matter-frame/SKILL.md +3 -3
  152. package/driver/skills/narrative-refutation/SKILL.md +9 -9
  153. package/driver/skills/placement-inquiry/SKILL.md +5 -5
  154. package/driver/stage-context.mjs +1 -1
  155. package/driver/stages-knockout.mjs +4 -4
  156. package/driver/stages.mjs +65 -61
  157. package/driver/status-snapshot.mjs +2 -2
  158. package/driver/suite-census.json +340 -136
  159. package/driver/surface-exit-verdict.mjs +58 -0
  160. package/driver/systemd/README.md +9 -6
  161. package/driver/systemd/clearotron-worker.service +1 -1
  162. package/driver/terminal-clamp.mjs +109 -1
  163. package/driver/tokens.mjs +169 -3
  164. package/driver/unit-environment.mjs +42 -15
  165. package/driver/unit-inventory.mjs +19 -2
  166. package/driver/usage-ledger.mjs +1 -1
  167. package/driver/variant-manifest-model.mjs +4 -4
  168. package/driver/verify-knockout.mjs +27 -0
  169. package/driver/verify.mjs +94 -6
  170. package/driver/whatif-queue.mjs +1 -1
  171. package/driver/wordlists/en.txt +63906 -0
  172. package/mcp-server/CHANGELOG.md +8 -0
  173. package/mcp-server/README.md +1 -1
  174. package/mcp-server/lib/README.md +1 -1
  175. package/mcp-server/lib/options.mjs +8 -7
  176. package/mcp-server/lib/plan.mjs +18 -2
  177. package/mcp-server/lib/runs.mjs +1 -1
  178. package/mcp-server/lib/usage.mjs +3 -3
  179. package/mcp-server/lib/whatif.mjs +1 -1
  180. package/mcp-server/package.json +1 -1
  181. package/mcp-server/server.mjs +18 -1
  182. package/package.json +12 -11
  183. package/portal-ui/dist/assets/{index-CVOIvdhc.css → index-CtvwLCti.css} +207 -3
  184. package/portal-ui/dist/assets/{index-5UyqAyNM.js → index-EVaSo5-g.js} +1580 -527
  185. package/portal-ui/dist/index.html +2 -2
  186. package/portal-ui/package.json +1 -1
  187. package/providers/README.md +1 -1
  188. package/providers/_shared/enumerate.mjs +6 -6
  189. package/providers/_shared/execute-plan.mjs +3 -3
  190. package/providers/_shared/ledger.mjs +119 -5
  191. package/providers/_shared/provider-text.mjs +2 -2
  192. package/providers/_shared/screen.mjs +2 -2
  193. package/providers/_shared/script-form.mjs +3 -3
  194. package/providers/_shared/territory-codes.mjs +23 -3
  195. package/providers/clarivate/README.md +1 -1
  196. package/providers/clarivate/src/capabilities.js +12 -12
  197. package/providers/clarivate/src/core.js +37 -43
  198. package/providers/corsearch/README.md +1 -1
  199. package/providers/corsearch/src/capabilities.js +5 -5
  200. package/providers/corsearch/src/core.js +3 -3
  201. package/providers/jx/README.md +2 -1
  202. package/providers/jx/src/turn-envelope.mjs +8 -3
  203. package/providers/oauth-mcp-bridge/CHANGELOG.md +8 -0
  204. package/providers/oauth-mcp-bridge/package.json +1 -1
  205. package/providers/perplexity/src/core.js +1 -1
  206. package/providers/signa/README.md +1 -1
  207. package/providers/signa/src/capabilities.js +42 -49
  208. package/providers/signa/src/core.js +106 -29
  209. package/providers/uspto-local/README.md +1 -1
  210. package/providers/uspto-local/src/sync.js +1 -1
  211. package/scripts/README.md +1 -0
  212. package/scripts/ask-ai-render-check.mjs +127 -1
  213. package/scripts/authority-boundary-probe.mjs +8 -6
  214. package/scripts/backfill-started-at.mjs +2 -2
  215. package/scripts/census-merge-driver.mjs +33 -2
  216. package/scripts/citation-anchor-report.mjs +181 -0
  217. package/scripts/dead-names.mjs +1 -1
  218. package/scripts/deprecate-below.mjs +66 -8
  219. package/scripts/drain-preflight.mjs +1 -1
  220. package/scripts/e2e.mjs +174 -0
  221. package/scripts/env-audit.mjs +39 -6
  222. package/scripts/env-classify.mjs +20 -2
  223. package/scripts/freeze-example-run.mjs +61 -18
  224. package/scripts/generated-files-are-current.mjs +69 -4
  225. package/scripts/live-surface-check.mjs +124 -41
  226. package/scripts/markdown-link-check.mjs +1 -1
  227. package/scripts/merge-shape-check.mjs +242 -0
  228. package/scripts/mint-names-in-force.mjs +5 -5
  229. package/scripts/mint-offered-territories.mjs +72 -0
  230. package/scripts/mint-public-residue.mjs +2 -2
  231. package/scripts/mint-reference-strip-backlog.mjs +2 -2
  232. package/scripts/mint-suite-census.mjs +75 -2
  233. package/scripts/mint-writing-standard-backlog.mjs +2 -2
  234. package/scripts/purge-runs.mjs +7 -7
  235. package/scripts/reconcile-runs.mjs +2 -2
  236. package/scripts/release-approve-parked.mjs +20 -2
  237. package/scripts/release-await-cut.mjs +120 -1
  238. package/scripts/release-note-required.mjs +76 -8
  239. package/scripts/report-header-render-check.mjs +164 -0
  240. package/scripts/settings-render-check.mjs +75 -2
  241. package/scripts/test-full.mjs +96 -3
  242. package/scripts/test-run.mjs +10 -0
  243. package/shared/brand.mjs +27 -0
  244. package/shared/connect-clients.mjs +39 -11
  245. package/shared/deployment-box.mjs +7 -2
  246. package/shared/driver-dir.mjs +1 -1
  247. package/shared/env-aliases.mjs +1 -1
  248. package/shared/identifier-scan.mjs +65 -9
  249. package/shared/identifier-sentinels.mjs +22 -0
  250. package/shared/names-in-force.mjs +4 -2
  251. package/shared/offered-territories.json +738 -0
  252. package/shared/pre-rename-spellings.mjs +53 -0
  253. package/shared/reference-guard-classes.mjs +40 -2
  254. package/shared/stdio-connect.mjs +39 -4
  255. package/shared/tree-commit.mjs +48 -0
  256. /package/driver/skills/{prelim-register → clearance-register}/providers/euipo.md +0 -0
  257. /package/driver/skills/{prelim-register → clearance-register}/providers/free-tier.md +0 -0
  258. /package/driver/skills/{prelim-register → clearance-register}/providers/uspto-local.md +0 -0
  259. /package/driver/skills/{prelim-search → clearance-search}/field-doctrine-pharma.md +0 -0
  260. /package/driver/skills/{prelim-search → clearance-search}/firm-wide-reasoning.md +0 -0
  261. /package/driver/skills/{prelim-search → clearance-search}/report-prose.md +0 -0
  262. /package/driver/skills/{prelim-search → clearance-search}/risk-framework-demo.manifest.json +0 -0
  263. /package/driver/skills/{prelim-search → clearance-search}/risk-framework-demo.md +0 -0
  264. /package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.manifest.json +0 -0
  265. /package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.md +0 -0
  266. /package/driver/skills/{prelim-search → clearance-search}/risk-framework.manifest.json +0 -0
  267. /package/driver/skills/{prelim-search → clearance-search}/risk-framework.md +0 -0
  268. /package/driver/skills/{prelim-search → clearance-search}/template-formatting.md +0 -0
  269. /package/driver/skills/{prelim-search → clearance-search}/templates/email/generic.md +0 -0
  270. /package/driver/skills/{prelim-search → clearance-search}/templates/search-request-form.html +0 -0
  271. /package/driver/skills/{prelim-search → clearance-search}/worked-examples-demo.md +0 -0
  272. /package/driver/skills/{prelim-search → clearance-search}/worked-examples.md +0 -0
@@ -1,17 +1,17 @@
1
1
  ---
2
- name: prelim-common-law
3
- description: Common-law / marketplace execution for the v3 preliminary trademark search workflow. **Invoked exclusively by the `prelim-search` orchestrator** — do not call directly. Reads the variant manifest produced by `prelim-variants` and runs structured Perplexity research across the DICTATED platform list (the task message's PLATFORMS block names the exact store domains for this customer; the gaming default is 6 stores) plus general web, social, e-commerce, and industry press. Produces a common-law findings file consumed by the orchestrator for synthesis and Excel assembly. Runs alongside `prelim-register`.
2
+ name: clearance-common-law
3
+ description: Common-law / marketplace execution for the v3 preliminary trademark search workflow. **Invoked exclusively by the `clearance-search` orchestrator** — do not call directly. Reads the variant manifest produced by `clearance-variants` and runs structured Perplexity research across the DICTATED platform list (the task message's PLATFORMS block names the exact store domains for this customer; the gaming default is 6 stores) plus general web, social, e-commerce, and industry press. Produces a common-law findings file consumed by the orchestrator for synthesis and Excel assembly. Runs alongside `clearance-register`.
4
4
  ---
5
5
 
6
6
  ## Spawned session
7
7
 
8
- Invoked from `prelim-search` (orchestrator) alongside `prelim-register`. Reads:
9
- - The variant manifest at `studio/prelim-search/<slug>/<date>/variant-manifest.md` (produced by `prelim-variants`)
8
+ Invoked from `clearance-search` (orchestrator) alongside `clearance-register`. Reads:
9
+ - The variant manifest at `studio/clearance-search/<slug>/<date>/variant-manifest.md` (produced by `clearance-variants`)
10
10
  - The request context (classes, jurisdiction scope, industry, manner of use)
11
11
 
12
12
  Writes:
13
- - A common-law findings file at `studio/prelim-search/<slug>/<date>/common-law-findings.md`
14
- - **The machine grid ledger** at `studio/prelim-search/<slug>/<date>/common-law-grid.json` — the grid
13
+ - A common-law findings file at `studio/clearance-search/<slug>/<date>/common-law-findings.md`
14
+ - **The machine grid ledger** at `studio/clearance-search/<slug>/<date>/common-law-grid.json` — the grid
15
15
  call's stdout JSON saved **verbatim** (a single stdout object, or a JSON array of the per-batch
16
16
  stdout objects in batch order when the grid is batched). Copy it exactly as the tool returned it —
17
17
  no reformatting, no re-typing, no judging. **The driver validates grid completeness from this file**
@@ -29,7 +29,7 @@ Companion files:
29
29
 
30
30
  ## Trigger
31
31
 
32
- Called by `prelim-search` after `prelim-variants` has produced the manifest. Runs alongside `prelim-register` against the same manifest. Not invoked directly by operators.
32
+ Called by `clearance-search` after `clearance-variants` has produced the manifest. Runs alongside `clearance-register` against the same manifest. Not invoked directly by operators.
33
33
 
34
34
  ## Model
35
35
 
@@ -37,8 +37,8 @@ The model tier is set **by the deterministic driver** — `driver/stages.mjs` is
37
37
  source of truth (currently Haiku, low thinking). This worker is extraction, not open analysis: it
38
38
  fills templated Perplexity prompts from the manifest and transcribes what Perplexity returns into
39
39
  the fixed finding taxonomy. The creative variant/strategy work is already done upstream by
40
- `prelim-variants` (Opus), and the cross-cutting risk synthesis is the orchestrator's (Opus). If the
41
- orchestrator's skeptic review (prelim-search Step 2.6) finds this worker shortcut the manifest's
40
+ `clearance-variants` (Opus), and the cross-cutting risk synthesis is the orchestrator's (Opus). If the
41
+ orchestrator's skeptic review (clearance-search Step 2.6) finds this worker shortcut the manifest's
42
42
  coverage, it is re-spawned escalated to Opus.
43
43
 
44
44
  ## Tool call budget
@@ -61,7 +61,7 @@ the artifacts this stage writes, so there is nothing here to call and nothing to
61
61
 
62
62
  ## Search approval (HITL exception)
63
63
 
64
- The full HITL exception covering this workflow is declared **once** in the orchestrator at [prelim-search/SKILL.md](../prelim-search/SKILL.md#hitl-exception-shared-across-sub-skills). It is pre-approved at workflow trigger time when the requesting lawyer or a staff lawyer forwards the request email.
64
+ The full HITL exception covering this workflow is declared **once** in the orchestrator at [clearance-search/SKILL.md](../clearance-search/SKILL.md#hitl-exception-shared-across-sub-skills). It is pre-approved at workflow trigger time when the requesting lawyer or a staff lawyer forwards the request email.
65
65
 
66
66
  Operative rules for this sub-skill (Perplexity-side):
67
67
  - **Include in queries:** mark name, product type, relevant industry context
@@ -105,14 +105,14 @@ so there is **no partial-delivery fallback**:
105
105
 
106
106
  ### Out of scope (register-layer concerns)
107
107
 
108
- - USPTO / WIPO / national trademark office database searches — handled by `prelim-register`
108
+ - USPTO / WIPO / national trademark office database searches — handled by `clearance-register`
109
109
  - Class-specific register queries
110
110
  - Register statistics and filing volumes
111
111
  - Stealth-filing pattern analysis
112
112
  - Formal enforcement history analysis (organic mentions OK; targeted register-based enforcement search NOT)
113
113
  - Prior-art register-based analysis
114
114
 
115
- **Bleed rule:** if register information surfaces organically during a common-law search (e.g., a news article mentions a filing), note it briefly and flag it in the findings file's `Cross-checks suggested` section. Do not pursue it — the orchestrator hands such flags to `prelim-register` for cross-pollination.
115
+ **Bleed rule:** if register information surfaces organically during a common-law search (e.g., a news article mentions a filing), note it briefly and flag it in the findings file's `Cross-checks suggested` section. Do not pursue it — the orchestrator hands such flags to `clearance-register` for cross-pollination.
116
116
 
117
117
  ## Output — common-law findings file
118
118
 
@@ -165,14 +165,14 @@ For game-title rows, the `developer_of_record` and `publisher_of_record` columns
165
165
 
166
166
  | Finding | Source / Platform | URL | Notes |
167
167
  |---|---|---|---|
168
- | "Raising Your Play" | HP marketing | https://... | HP uses tagline for gaming hardware; no register protection found (flagged for prelim-register cross-check) |
168
+ | "Raising Your Play" | HP marketing | https://... | HP uses tagline for gaming hardware; no register protection found (flagged for clearance-register cross-check) |
169
169
  | 1,600+ "Dawn" titles on Steam | Steam | https://... | Crowded field — supportive evidence |
170
170
 
171
171
  ### Competitor intelligence
172
172
 
173
173
  | Finding | Source / Platform | URL | Notes |
174
174
  |---|---|---|---|
175
- | Sony "Pulse Elevate" portfolio | Sony products | https://... | Sony uses "Elevate" in audio products; flagged for prelim-register cross-check |
175
+ | Sony "Pulse Elevate" portfolio | Sony products | https://... | Sony uses "Elevate" in audio products; flagged for clearance-register cross-check |
176
176
  | Foxglade "Borealis" console "Raise Your Play" tagline (prior usage) | Foxglade Interactive marketing | https://... | Client's own prior use — note as supportive |
177
177
 
178
178
  ### PR / reputational risk
@@ -356,7 +356,7 @@ forms (and the gap form) — this is what the driver's receipt gate counts:
356
356
  ### Coverage ledger (feeds synthesis coverage-honesty + skeptic audit)
357
357
  <!-- clearotron:section=coverage-ledger -->
358
358
 
359
- One row per planned coverage unit (each mandatory platform; the field-scoped general search; non-Latin / transliteration platform reach), with status + one-line reason. Same three statuses as the register side (see `prelim-register/SKILL.md` → *Coverage ledger*): `confirmed-clean` (ran to completion), `coverage-limited` (the search **ran and reached the platform** but could not be exhausted — thin data, non-Latin reach), `deferred` (planned but **not run, or the platform/tool could not be reached**). Per the keystone doctrine: a could-not-reach gap (a platform/tool that was unavailable) is `deferred`, never `coverage-limited` — the latter is a searched-but-unexhausted DATA limit. This is the structured form of the Open-verification-flags prose — a `coverage-limited` row is **not** a clean negative downstream.
359
+ One row per planned coverage unit (each mandatory platform; the field-scoped general search; non-Latin / transliteration platform reach), with status + one-line reason. Same three statuses as the register side (see `clearance-register/SKILL.md` → *Coverage ledger*): `confirmed-clean` (ran to completion), `coverage-limited` (the search **ran and reached the platform** but could not be exhausted — thin data, non-Latin reach), `deferred` (planned but **not run, or the platform/tool could not be reached**). Per the keystone doctrine: a could-not-reach gap (a platform/tool that was unavailable) is `deferred`, never `coverage-limited` — the latter is a searched-but-unexhausted DATA limit. This is the structured form of the Open-verification-flags prose — a `coverage-limited` row is **not** a clean negative downstream.
360
360
 
361
361
  | Coverage unit | Status | Reason |
362
362
  |---|---|---|
@@ -364,7 +364,7 @@ One row per planned coverage unit (each mandatory platform; the field-scoped gen
364
364
  | field-scoped general search (collab / non-gaming goods) | confirmed-clean | run per matter scope |
365
365
  | non-Latin platform reach (translit variants) | coverage-limited | marketplace data thin for non-Latin scripts; absence not confirmed clean |
366
366
 
367
- ### Cross-checks suggested (handed to orchestrator for prelim-register dispatch)
367
+ ### Cross-checks suggested (handed to orchestrator for clearance-register dispatch)
368
368
 
369
369
  | Trigger | Suggested cross-check |
370
370
  |---|---|
@@ -400,7 +400,7 @@ Four steps per mark.
400
400
 
401
401
  ### Step 1 — Read variant manifest
402
402
 
403
- Open `studio/prelim-search/<slug>/<date>/variant-manifest.md`. Parse:
403
+ Open `studio/clearance-search/<slug>/<date>/variant-manifest.md`. Parse:
404
404
  - Request context: marks, classes, jurisdiction, industry, manner of use
405
405
  - Per-mark variant tables — these become the search terms in the Perplexity prompt
406
406
  - Watchlists — used for competitor intelligence framing
@@ -446,10 +446,10 @@ filling in:
446
446
 
447
447
  The tool returns the program's stdout JSON (`cells` + `extras` + `gaps`) and the program code as an
448
448
  audit receipt. **Trademark-register lookups stay out of scope** — the grid only searches
449
- marketplaces/web (the register layer is `prelim-register`'s).
449
+ marketplaces/web (the register layer is `clearance-register`'s).
450
450
 
451
451
  **LEGACY path only (no `grid_spec_path` given) — immediately after the grid call(s): save the stdout
452
- JSON verbatim** to `studio/prelim-search/<slug>/<date>/common-law-grid.json` — one call → the stdout
452
+ JSON verbatim** to `studio/clearance-search/<slug>/<date>/common-law-grid.json` — one call → the stdout
453
453
  object as-is; batched calls → a JSON array of the per-batch stdout objects, in batch order. This is a
454
454
  copy operation, not a writing task: the bytes the tool returned, unmodified. The deterministic driver
455
455
  validates the grid by exact join on this file (machine receipts) — the markdown Negative results
@@ -486,7 +486,7 @@ common word) does not. Then categorise each finding into one of:
486
486
  - **Competitor intelligence** — watchlist matches; existing partnerships major brands have in the space
487
487
  - **PR / reputational risk** — the meaning read of the mark AND its near-forms, scoped by the run's OWN dictated sweep: the fixed meaning / slang / gang / offensive / lookup shapes plus the matter frame's derived `Meaning angles:` queries (cultural origin/appropriation, charged history of the term or its imagery, category-specific controversy — as THIS matter's frame reasoned them). Never a generic sensitivities checklist — the scope IS the dictated sweep. NOT scored on legal-risk framework — separate category. **Every recorded query with results carries a ruling recorded through `record_dispositions`, whatever this section concludes** — reporting a loaded reading does not discharge the rest of the sweep (see the PR / reputational risk contract above). `None identified` is additionally a clean *receipt* ONLY when the meaning sweep ran — cite a `Connotation-search source:` line; the driver rejects an unsearched clean claim (`connotation_search_missing`) and refuses the turn while any ruling is unrecorded (the `connotation_call_*` family). A dictionary gloss is never a clearance.
488
488
  - **Negative results** — **one row for EVERY variant × platform grid cell** (the full grid accounting the driver's receipt gate counts), **plus rows for the field-scoped cells** (collab / non-gaming goods) when run. **Each row carries its receipt:** `No results` (the search returned nothing), `No similar listings (N candidates reviewed)` (returned N candidates, none prima facie similar), `Similar listing(s) found — see Findings (N candidates)` (the cell produced findings), or `not executed — coverage-limited (see ledger)` (the cell is in the grid's `gaps` — never a clean negative).
489
- - **Cross-checks suggested** — register-side checks the orchestrator should dispatch to `prelim-register` (every common-law owner found → ONE register check)
489
+ - **Cross-checks suggested** — register-side checks the orchestrator should dispatch to `clearance-register` (every common-law owner found → ONE register check)
490
490
 
491
491
  **100% URL coverage is mandatory.** Every finding row must have a clickable URL. If a finding cannot be verified with a URL, mark it as an Open verification flag and note the source.
492
492
 
@@ -514,7 +514,7 @@ This requirement applies even when the model running this skill is at the Haiku
514
514
 
515
515
  ### Step 6 — Compile common-law findings file
516
516
 
517
- Assemble `studio/prelim-search/<slug>/<date>/common-law-findings.md` per the format above. Sections (in order):
517
+ Assemble `studio/clearance-search/<slug>/<date>/common-law-findings.md` per the format above. Sections (in order):
518
518
 
519
519
  1. **Summary** — call counts, platform coverage, finding counts
520
520
  2. **Consumer-confusion risks** — gaming-industry overlap
@@ -545,6 +545,6 @@ Assemble `studio/prelim-search/<slug>/<date>/common-law-findings.md` per the for
545
545
  - [ ] Coverage ledger emitted — one row per planned coverage unit; non-Latin / thin-data reach logged `coverage-limited`, not silently clean
546
546
  - [ ] Cross-checks suggested section populated
547
547
  - [ ] Open verification flags listed (URL-404s, thin coverage, transliteration confirmations)
548
- - [ ] Common-law findings file written to `studio/prelim-search/<slug>/<date>/common-law-findings.md`
548
+ - [ ] Common-law findings file written to `studio/clearance-search/<slug>/<date>/common-law-findings.md`
549
549
  - [ ] Perplexity budget under workflow cap (15 calls)
550
550
  - [ ] No client identity, reference numbers, or contact names in any submitted Perplexity prompt
@@ -1,6 +1,6 @@
1
1
  # Perplexity prompts
2
2
 
3
- Templates for the `perplexity_research` calls in `prelim-common-law`. Prompts are **prescriptive, not exploratory** — they tell Perplexity exactly what to search for, where, and how to report.
3
+ Templates for the `perplexity_research` calls in `clearance-common-law`. Prompts are **prescriptive, not exploratory** — they tell Perplexity exactly what to search for, where, and how to report.
4
4
 
5
5
  ## Depth routing (mandatory)
6
6
 
@@ -1,11 +1,11 @@
1
1
  ---
2
- name: prelim-register
3
- description: Register-side execution for the v3 preliminary trademark search workflow. **Invoked exclusively by the `prelim-search` orchestrator** — do not call directly. Runs in one of two modes the orchestrator selects via the spawn task. **Unit mode (the FUNNEL — Layer A):** execute ONE register search axis (saturation / primary-sweep / transliteration-numeric / incumbent-class) against the variant manifest — ENUMERATE each named query to completion via `register_enumerate` (the completeness primitive that owns the page loop), describe saturation crowds as count-only incomplete descriptors, and write the COMPLETE NAMED BAND (`register-units/<axis>-band.json`) carrying every record with its status; the funnel decides NOTHING about relevance / sufficiency / prioritisation and never samples or self-accepts; only the raw character-noise pile dies in this session. **Digest mode (judgment — Layer B):** read the complete merged band through the band tools (`band_shape` / `band_lookup` / `band_record` — every call on the run's reading audit; never by slicing band files), run the cross-cutting judgment (relevance, identical-match + cross-class merchandising, owner aggregation, watchlists, stealth-filer + Option-D cross-checks, opposition), decide sufficiency, and hand the register-side findings back as typed rows — the driver renders the document the orchestrator synthesises from; the seat writes no file.
2
+ name: clearance-register
3
+ description: Register-side execution for the v3 preliminary trademark search workflow. **Invoked exclusively by the `clearance-search` orchestrator** — do not call directly. Runs in one of two modes the orchestrator selects via the spawn task. **Unit mode (the FUNNEL — Layer A):** execute ONE register search axis (saturation / primary-sweep / transliteration-numeric / incumbent-class) against the variant manifest — ENUMERATE each named query to completion via `register_enumerate` (the completeness primitive that owns the page loop), describe saturation crowds as count-only incomplete descriptors, and write the COMPLETE NAMED BAND (`register-units/<axis>-band.json`) carrying every record with its status; the funnel decides NOTHING about relevance / sufficiency / prioritisation and never samples or self-accepts; only the raw character-noise pile dies in this session. **Digest mode (judgment — Layer B):** read the complete merged band through the band tools (`band_shape` / `band_lookup` / `band_record` — every call on the run's reading audit; never by slicing band files), run the cross-cutting judgment (relevance, identical-match + cross-class merchandising, owner aggregation, watchlists, stealth-filer + Option-D cross-checks, opposition), decide sufficiency, and hand the register-side findings back as typed rows — the driver renders the document the orchestrator synthesises from; the seat writes no file.
4
4
  ---
5
5
 
6
6
  ## Spawned session
7
7
 
8
- Invoked from `prelim-search` (the orchestrator) as an **isolated depth-2 worker**, in one of two
8
+ Invoked from `clearance-search` (the orchestrator) as an **isolated depth-2 worker**, in one of two
9
9
  modes. **This skill never spawns sub-agents** — the orchestrator owns all dispatch. (This is
10
10
  deliberate: the announce/completion chain supports one nesting level — `main → orchestrator →
11
11
  workers` — so every register worker is a flat depth-2 sibling of the common-law worker, not a nested
@@ -26,16 +26,16 @@ Two modes, chosen by the orchestrator and stated in the spawn `task`:
26
26
  band. The worker reads that COMPLETE band **through the band tools** (`band_shape` first, then
27
27
  `band_lookup` / `band_record` — every call lands in the reading audit; never by opening or slicing band
28
28
  files), performs all cross-cutting judgment (relevance, owner aggregation, opposition, Option-D),
29
- DECIDES SUFFICIENCY, and writes `studio/prelim-search/<slug>/<date>/register-findings.md`.
29
+ DECIDES SUFFICIENCY, and writes `studio/clearance-search/<slug>/<date>/register-findings.md`.
30
30
 
31
- Reads (both modes): the variant manifest at `studio/prelim-search/<slug>/<date>/variant-manifest.md` (archetype + risk
32
- theory), the `matter-context.md` at `studio/prelim-search/<slug>/<date>/matter-context.md` (Phase 0 strategic anchor — names materially-matters jurisdictions, watchlist-owner seeds, off-field sectors), the request context, the active **provider**. The **watchlist-owner seeds are enrichment / additive-surfacing context, not a search or priority filter** — an in-class identical/near-identical incumbent surfaces on field-relevance alone whether or not its owner is named (see `digest.md` Step 5).
31
+ Reads (both modes): the variant manifest at `studio/clearance-search/<slug>/<date>/variant-manifest.md` (archetype + risk
32
+ theory), the `matter-context.md` at `studio/clearance-search/<slug>/<date>/matter-context.md` (Phase 0 strategic anchor — names materially-matters jurisdictions, watchlist-owner seeds, off-field sectors), the request context, the active **provider**. The **watchlist-owner seeds are enrichment / additive-surfacing context, not a search or priority filter** — an in-class identical/near-identical incumbent surfaces on field-relevance alone whether or not its owner is named (see `digest.md` Step 5).
33
33
 
34
- **Digest mode also reads**: `placement-recommendations.md` at `studio/prelim-search/<slug>/<date>/placement-recommendations.md` (Touchpoint 2 per-candidate placements — informs digest tiering), and its structured mirror `placements.json` beside it (one `{mark, owner, jurisdiction, records, tier, reason}` entry per candidate; when present, the authoritative per-candidate tier record — the md carries the rulings tail as prose).
34
+ **Digest mode also reads**: `placement-recommendations.md` at `studio/clearance-search/<slug>/<date>/placement-recommendations.md` (Touchpoint 2 per-candidate placements — informs digest tiering), and its structured mirror `placements.json` beside it (one `{mark, owner, jurisdiction, records, tier, reason}` entry per candidate; when present, the authoritative per-candidate tier record — the md carries the rulings tail as prose).
35
35
 
36
36
  Writes:
37
- - Unit mode — TWO artifacts, both gate-checked, neither optional. `studio/prelim-search/<slug>/<date>/register-units/<axis>.md` is the stage's DECLARED OUTPUT: the driver fails the pass outright when it is absent, and the digest worker reads it as an input. `studio/prelim-search/<slug>/<date>/register-units/<axis>-band.json` is the COMPLETE named band — a JSON array of `enumerated` / `incomplete` blocks (see `unit.md` → *Named-band artifact*) — carrying every record and no clearance verdict. The md narrates and proves nothing on its own: an md narrating a completed sweep while the band its plan entries call for is missing is refused as `named_band_missing`. In plan mode `register_execute_plan` writes the band itself and you never hand-write its blocks.
38
- - Digest mode: `studio/prelim-search/<slug>/<date>/register-findings.md`. Coverage statuses are NOT a file you write: they ride the `record_coverage` tool into a driver-held record, and the driver renders the `## Coverage ledger` table and its JSON mirror from it (see *Coverage ledger* below and `digest.md` → *Coverage ledger*). Optional: `register-details/` snapshots inside the run-dir.
37
+ - Unit mode — TWO artifacts, both gate-checked, neither optional. `studio/clearance-search/<slug>/<date>/register-units/<axis>.md` is the stage's DECLARED OUTPUT: the driver fails the pass outright when it is absent, and the digest worker reads it as an input. `studio/clearance-search/<slug>/<date>/register-units/<axis>-band.json` is the COMPLETE named band — a JSON array of `enumerated` / `incomplete` blocks (see `unit.md` → *Named-band artifact*) — carrying every record and no clearance verdict. The md narrates and proves nothing on its own: an md narrating a completed sweep while the band its plan entries call for is missing is refused as `named_band_missing`. In plan mode `register_execute_plan` writes the band itself and you never hand-write its blocks.
38
+ - Digest mode: `studio/clearance-search/<slug>/<date>/register-findings.md`. Coverage statuses are NOT a file you write: they ride the `record_coverage` tool into a driver-held record, and the driver renders the `## Coverage ledger` table and its JSON mirror from it (see *Coverage ledger* below and `digest.md` → *Coverage ledger*). Optional: `register-details/` snapshots inside the run-dir.
39
39
 
40
40
  Returns to the orchestrator: your **final session message** — a 2–3 line summary (counts + the
41
41
  absolute path of the file you wrote). Keep raw character-noise records out of the message and out of any
@@ -50,7 +50,7 @@ Companion files:
50
50
 
51
51
  ## Trigger
52
52
 
53
- Called by `prelim-search` after `prelim-variants` has produced the manifest. The orchestrator spawns
53
+ Called by `clearance-search` after `clearance-variants` has produced the manifest. The orchestrator spawns
54
54
  the unit-mode workers and the common-law worker together, then spawns the digest-mode worker once the
55
55
  unit digests exist. Not invoked directly by operators.
56
56
 
@@ -1,4 +1,4 @@
1
- # prelim-register — MODE B (DIGEST)
1
+ # clearance-register — MODE B (DIGEST)
2
2
 
3
3
  > Read `SKILL.md` first (the shared spine). This file is the DIGEST-mode procedure + the register-findings output format. **Do NOT read `unit.md`.**
4
4
 
@@ -470,7 +470,7 @@ for the same URI across fields or sources, OR an EUIPO cross-check disagrees wit
470
470
  owner identity, OR a portfolio-size signal (many filings clustering under a normalised owner) would
471
471
  materially change the enforcement-appetite read, do NOT silently pick one. Surface both readings in the
472
472
  findings row and set `Verify? ✅` with reason "owner-identity conflict — confirm before enforcement
473
- read." Owner identity drives enforcer-profiling (see `prelim-search/firm-wide-reasoning.md`, *Enforcer profiling*
473
+ read." Owner identity drives enforcer-profiling (see `clearance-search/firm-wide-reasoning.md`, *Enforcer profiling*
474
474
  rule) — a wrong owner is a wrong risk read.
475
475
 
476
476
  ### Step 4 — Proactive competitor + aggressive-enforcer sweep
@@ -10,7 +10,7 @@ This boundary is enforced by `test/provider-neutral-prose.test.mjs` — it fails
10
10
 
11
11
  ```bash
12
12
  # manual equivalent
13
- grep -rnE "corsearch_|clarivate_|signa_" ../../prelim-{register,variants,search}/*.md
13
+ grep -rnE "corsearch_|clarivate_|signa_" ../../clearance-{register,variants,search}/*.md
14
14
  # should return zero hits OUTSIDE this providers/ directory
15
15
  ```
16
16
 
@@ -44,35 +44,37 @@ claimed. Booleans, parentheses and wildcards are parsed **inside `searchFields[]
44
44
 
45
45
  | `match_mode` | Field + value shape | Semantics | Probe |
46
46
  |---|---|---|---|
47
- | `default` | `WORD_MARK_SPECIFICATION` = `*TERM*` | **A TRUE CONTAINS** — the substring band | `*NIK*` = 806 |
48
- | `exact` | `EXACT_WORD_MARK_SPECIFICATION` = `TERM` | Full-string, case-insensitive, **punctuation-sensitive** (punctuation is stripped client-side for you) | `NIKE` = 34 on CH |
49
- | `wildcard` | `WORD_MARK_SPECIFICATION` = your pattern, untouched | `*` and `?` are native | `NIK*` = 128, `*NIKE` = 36, `NIK?` = 48 |
50
- | `starts_with` | `WORD_MARK_SPECIFICATION` = `TERM*` | prefix | `NIK*` = 128 |
51
- | `ends_with` | `WORD_MARK_SPECIFICATION` = `*TERM` | suffix | `*NIKE` = 36 |
47
+ | `default` | `WORD_MARK_SPECIFICATION` = `*TERM*` | **A TRUE CONTAINS** — the substring band | `*TERM*` |
48
+ | `exact` | `EXACT_WORD_MARK_SPECIFICATION` = `TERM` | Full-string, case-insensitive, **punctuation-sensitive** (punctuation is stripped client-side for you) | `TERM` |
49
+ | `wildcard` | `WORD_MARK_SPECIFICATION` = your pattern, untouched | `*` and `?` are native | `TERM*`, `*TERM`, `TER?` |
50
+ | `starts_with` | `WORD_MARK_SPECIFICATION` = `TERM*` | prefix | `TERM*` |
51
+ | `ends_with` | `WORD_MARK_SPECIFICATION` = `*TERM` | suffix | `*TERM` |
52
52
  | `phonetic` | `PHONETIC_WORD_MARK_SPECIFICATION` = `TERM` | Native server-side sound-alike. Opaque — no variant list. | — |
53
53
 
54
54
  `contains` is accepted as an alias of `default` and produces the identical query. There is no separate
55
55
  "contains mode" to reach for any more.
56
56
 
57
- **Booleans are explicit and native.** `"NIKE OR ADIDAS"` = 38 = 34 + 4 exactly. `AND` works. `NOT` works
58
- (`"NIK* NOT NIKE"` = 94 = 128 − 34). Parentheses group. Regex is not supported (`/NIK./` = 0) despite
59
- what the field description hints.
57
+ **Booleans are explicit and native**, and they are evaluated as real set operations rather than as text.
58
+ An `OR` stack answers the union of its legs — on two names that share no marks that is the two totals
59
+ added, and on names that overlap it is less, because nothing is counted twice. `AND` and `NOT` compose the
60
+ same way. Parentheses group. Regex is not supported despite what the field description hints: a regex
61
+ value matches nothing rather than erroring.
60
62
 
61
- **Multi-word terms work — pass them normally.** A bare space is an implicit *AND*
62
- (`*KESTREL BEVERAGE*` = `*KESTREL* AND *BEVERAGE*` = 75, and it is order-blind: `*CORAL PUP*` =
63
- `*PUP CORAL*` = 11), so the tool compiles your phrase to the **ADJ** adjacency operator instead —
64
- `*CORAL ADJ PUP*`, an ordered phrase match (11 hits; reversed = 0). You write the term the way a
63
+ **Multi-word terms work — pass them normally.** A bare space is an implicit *AND*, and it is order-blind,
64
+ so the tool compiles your phrase to the **ADJ** adjacency operator instead — an ordered phrase match,
65
+ which matches only the order you write it in. You write the term the way a
65
66
  lawyer would say it; the tool does the translation. This applies to `default`/`contains`/`wildcard`/
66
67
  `starts_with`/`ends_with`/`phonetic` alike.
67
68
 
68
69
  Two things to know when you read the results:
69
70
 
70
71
  - **A multi-word `starts_with`/`ends_with` is not anchored.** No string anchor exists on this provider
71
- (`BEGINS_WITH "ALPINE SPRING"` = 9 vs the phrase's 7), so it runs as a phrase-*contains* — a superset
72
- of what you asked. Extra hits, never fewer. Screen them as usual.
72
+ (`BEGINS_WITH` on a multi-word value degrades to a per-token AND, which is a superset of the ordered
73
+ phrase), so it runs as a phrase-*contains* — a superset of what you asked. Extra hits, never fewer.
74
+ Screen them as usual.
73
75
  - **`exact` is still the tightest read** — `EXACT_WORD_MARK_SPECIFICATION` is an ordered whole-string
74
- match ("KESTREL BEVERAGE" = 4, "BEVERAGE KESTREL" = 0). Use it when you want the mark itself, not the
75
- neighbourhood.
76
+ match — the whole string as written, so the same words in another order are a different string. Use it
77
+ when you want the mark itself, not the neighbourhood.
76
78
 
77
79
  **A term you pass is never silently re-parsed.** Parentheses, or (outside `wildcard`) a stray `*`/`?`,
78
80
  are **REJECTED** with a plain-English error and the slice defers — there is no escape syntax for those.
@@ -80,9 +82,9 @@ An operator word *inside* a phrase is handled for you: "BLACK AND DECKER" goes o
80
82
  `*BLACK ADJ A?D ADJ DECKER*` (the `?` stops the parser reading AND as an operator). The one term that
81
83
  still defers is a bare two-letter operator word — `OR` alone has no interior character to wildcard.
82
84
 
83
- `names[]` (an OR-stack) becomes ONE value joined with explicit ` OR `. The safe width is **500 terms**
84
- (80/200/500 all fine; 1000 → HTTP 500 *"Document nesting depth (1001) exceeds the maximum allowed"*).
85
- `register_enumerate` chunks wider stacks for you at that bound.
85
+ `names[]` (an OR-stack) becomes ONE value joined with explicit ` OR `. The safe width is **500 terms** —
86
+ the bound is the JSON parser's document-nesting cap, which the register names in the refusal it answers a
87
+ wider stack with. `register_enumerate` chunks wider stacks for you at that bound.
86
88
 
87
89
  ## Filters
88
90
 
@@ -99,8 +101,8 @@ still defers is a bare two-letter operator word — `OR` alone has no interior c
99
101
 
100
102
  ### Multi-class is ONE call — the fan-out is gone
101
103
 
102
- `INT_CLASS_NUMBER` value `"9 OR 28 OR 41 OR 42"` returns **18** — identical to the deduplicated union of
103
- four per-class calls (`"9,28,41,42"` also = 18). The old per-class fan-out and its `warnings[]` cost
104
+ `INT_CLASS_NUMBER` value `"9 OR 28 OR 41 OR 42"` returns the deduplicated union of what four per-class
105
+ calls returned — the comma form `"9,28,41,42"` is the same. The old per-class fan-out and its `warnings[]` cost
104
106
  breakdown have been **deleted from the core**. N classes cost one call; budget accordingly, and ignore
105
107
  any older guidance that told you to size a class fan-out.
106
108
 
@@ -113,8 +115,8 @@ becomes a `deferred` coverage row — it is never quietly dropped from the filte
113
115
 
114
116
  ### Owner search — resolve first, and never emit CONTAINS
115
117
 
116
- `APPLICANT_NAME` supports `EQUALS` (156 hits), `BEGINS_WITH` (159), wildcards (`"NIKE*"` with EQUALS =
117
- 159, i.e. equivalent to BEGINS_WITH), and `OR`. **`CONTAINS` is a hard HTTP 400** —
118
+ `APPLICANT_NAME` supports `EQUALS`, `BEGINS_WITH`, wildcards (a trailing `*` with EQUALS is equivalent to
119
+ `BEGINS_WITH`), and `OR`. **`CONTAINS` is a hard HTTP 400** —
118
120
  *"Operator CONTAINS is not supported for search field APPLICANT_NAME"* — and is never emitted anywhere.
119
121
 
120
122
  This provider has something Corsearch does not: **`POST /resolution/company`** returns confidence-scored
@@ -125,13 +127,12 @@ a narrower one. The result carries an `owner_resolution` note; cite it when the
125
127
 
126
128
  ## Completeness, crowds and the ceiling
127
129
 
128
- `/search` has **no pagination** and needs none: it returns the whole guid set (128 guids for a count of
129
- 128; 806 for 806). Past 30 000 it **fails loud**: HTTP 400 *"tooManyResults — The search returned 209012
130
- results. Maximum number of results is 30000."*
130
+ `/search` has **no pagination** and needs none: it returns one guid for every hit the count reports, at
131
+ any size below the ceiling. **The ceiling is 30 000**, and past it the search **fails loud** with a
132
+ `tooManyResults` HTTP 400 naming that maximum and how many results the search reached.
131
133
 
132
134
  `register_enumerate` therefore probes `POST /count` first. `/count` is cheap, takes the same body, works
133
- at **any** magnitude, and returns per-office counts in one call
134
- (`{"counts":{"CH":34,"EM":60,"WO":7,"CN":14345,"GB":91,"US":138}}`).
135
+ at **any** magnitude, and returns a `counts` object keyed by office code in one call.
135
136
 
136
137
  **A `tooManyResults` / over-ceiling band is `state:"incomplete"` — a CROWD DESCRIPTOR, never an error and
137
138
  never a clean negative.** It is dilution the lawyer reads. On this provider the crowd block also carries
@@ -156,7 +157,7 @@ identical-match is class-agnostic.
156
157
 
157
158
  ## Records — `register_record_fetch` / `register_batch_screen`
158
159
 
159
- `/text` takes **exactly 100 ids** per call (101+ → HTTP 400); the adapter chunks at 100. Response splits
160
+ `/text` takes **exactly 100 ids** per call and refuses a longer list; the adapter chunks at 100. Response splits
160
161
  into `trademarks[]` and `nonTrademarks[]` (design-only / bookkeeping artefacts — generally skip, but
161
162
  sanity-check it if results look sparse).
162
163
 
@@ -205,16 +206,17 @@ silently omit the dimension.
205
206
  - **No regex** — wildcards and booleans cover the plan vocabulary.
206
207
  - **No cross-language single query** — run the variant manifest per script.
207
208
  - **No native-script search — send the ROMANISATION instead.** This index holds non-Latin marks by
208
- their transliteration and does not hold the characters at all. `华威豹` answers **0**; its own
209
- transliteration `HUA WEI BAO` answers **32**, and those 32 include 华威豹. Same for `小米` (0) vs
210
- `XIAOMI` (57632). Universal — every non-Latin record sampled across CN/TW/JP/KR/TH/GR/UA/EG/SA/IL
209
+ their transliteration and does not hold the characters at all. A native-script term answers nothing;
210
+ its own transliteration answers records that carry those very characters. Universal — every non-Latin
211
+ record sampled across CN/TW/JP/KR/TH/GR/UA/EG/SA/IL
211
212
  carried a populated `markTransliteration`. A native term you send is REFUSED client-side (a 0 here
212
213
  would read as clean), so send the romanised form and say in the report that the register was
213
214
  searched by transliteration. Two rules that come with it:
214
215
  - use **contains, not `exact`** — the office writes its own spacing and trailing tokens, so
215
- `exact` on a transliteration is a silent zero (GR 0/10, EG 0/7);
216
- - the romanisation is **broader than the characters, not narrower** — it catches homophone
217
- variants (`HUA WEI BAO` → 华威豹, 华味宝, 华为爆破), which is the shape most Chinese squatting takes.
216
+ `exact` on a transliteration can be a silent zero where the same term under contains answers;
217
+ - the romanisation is **broader than the characters, not narrower** — the search key is the
218
+ romanisation, so it returns every character set filed under that pronunciation and not only the one
219
+ you meant, which is the shape most Chinese squatting takes.
218
220
 
219
221
  Each of these, when it blocks a dictated slice, is a **`deferred` coverage row** — escalate and disclose.
220
222
  Never substitute a weaker query under the same heading.
@@ -22,17 +22,26 @@ Auth: `CORSEARCH_SESSION_KEY` environment variable, supplied from the deployment
22
22
 
23
23
  Corsearch's supremesearch API uses single-character prefixes on field names. All field values must be **backtick-quoted** (the plugin handles this).
24
24
 
25
- | Match mode | API prefix | Semantics | Hit volume (NIKE benchmark) |
25
+ | Match mode | API prefix | Semantics | Budget as |
26
26
  |---|---|---|---|
27
- | `default` | (none) | Exact-token, case-insensitive — catches tokenisation splits and case variations | ~15,083 |
28
- | `exact` | `=` | Strictest — full-string match | ~3,014 |
29
- | `phrase` | `"` | Ordered phrase match | ~10,075 |
30
- | `starts_with` | `^` | Prefix | ~7,681 |
31
- | `ends_with` | `$` | Suffix | ~8,248 |
32
- | `phonetic` | `*` (or `P`) | Server-side phoneme match; extend with `phonetic_variants[]` | ~5,854 bare / ~6,022 with variants |
33
- | `fuzzy` | `~` | Approximate (diacritics, transliterations) | ~143,184 |
27
+ | `default` | (none) | Exact-token, case-insensitive — catches tokenisation splits and case variations | a read |
28
+ | `exact` | `=` | Strictest — full-string match | a read |
29
+ | `phrase` | `"` | Ordered phrase match | a read |
30
+ | `starts_with` | `^` | Prefix | a read |
31
+ | `ends_with` | `$` | Suffix | a read |
32
+ | `phonetic` | `*` (or `P`) | Server-side phoneme match; extend with `phonetic_variants[]` | a read |
33
+ | `fuzzy` | `~` | Approximate (diacritics, transliterations) | **a crowd** |
34
34
  | `not` | `!` (or `-`) | Complement; useful in compound queries | — |
35
- | `must` | `&` | Force AND within same-field stacking | ~433 (NIKE + ADIDAS) |
35
+ | `must` | `&` | Force AND within same-field stacking | a read |
36
+
37
+ Two facts about size, and no more than two, because a mode's breadth is a fact about the mark you send and
38
+ not about the mode: **`fuzzy` answers an order of magnitude wider than anything else here** — budget it as
39
+ a crowd unless you have narrowed it another way — and **`must` and `exact` are the two narrowest**, which
40
+ is what to reach for when a band has to be read rather than screened.
41
+
42
+ No mode's results contain another's. A prefix and a suffix each hold marks the other does not, a
43
+ sound-alike need not begin with your letters, and an intersection is not a subset of either half — so
44
+ running the wider one does not cover the narrower one, and a leg you drop is a leg nobody searched.
36
45
 
37
46
  **Critical:** No explicit `AND` / `OR` keywords — those return HTTP 400. Composition is space-separated. Repeated fields = implicit OR. Use `must` prefix for AND within same field. Repeated `nice-class:` fields are therefore an implicit-OR union — `nice_classes:[9,28,41,42]` correctly scopes to *any of* those classes.
38
47
 
@@ -150,7 +159,7 @@ Capture VERBATIM in the register findings file's "Opposition history" section. D
150
159
 
151
160
  Corsearch supports phoneme expansion via `register_expand_phoneme`. Returns `{ base, aiVariants[] }`. Use the variants as `phonetic_variants[]` in `register_search` with `match_mode: "phonetic"`.
152
161
 
153
- Declared languages: `en_US` (~29 variants per word), `de_DE` (~29), `fr_FR` (~49). Other languages (`it_IT`, `es_ES`) are supported by the API but UNDECLARED here — treat them as a stated unknown, not as unavailable.
162
+ Declared languages: `en_US`, `de_DE`, `fr_FR` — each returns a few dozen variants for a typical word. Other languages (`it_IT`, `es_ES`) are supported by the API but UNDECLARED here — treat them as a stated unknown, not as unavailable.
154
163
 
155
164
  **Usage pattern:** for multi-language jurisdictions, call expand-phoneme once per relevant language, concatenate `aiVariants[]`, pass to a single search call. Don't run multiple separate phonetic searches — costs more, returns largely overlapping results.
156
165
 
@@ -165,7 +174,7 @@ Only invoke for marks where `markFeature: "Figurative"` or `markFeature: "Stylis
165
174
  Be aware these capabilities are missing, so the skill doesn't promise them:
166
175
 
167
176
  - **POCA scoring** — not available through this adapter. Skill returns `null`
168
- - **Cross-language search within one query** — Corsearch doesn't support "search this mark in Japanese AND English in one query." Skill handles this by generating transliteration variants in `prelim-variants` and querying each separately.
177
+ - **Cross-language search within one query** — Corsearch doesn't support "search this mark in Japanese AND English in one query." Skill handles this by generating transliteration variants in `clearance-variants` and querying each separately.
169
178
  - **Server-side stem-folding** — present but not configurable (the default match-mode tokenizer catches LEGEND ↔ LEGENDS). The variant manifest's `plural-root` category encodes this — search the root form to catch inflected forms.
170
179
 
171
180
  ## Provider-specific behaviour
@@ -125,8 +125,8 @@ difference is not a margin. On the same term:
125
125
 
126
126
  | request | national | regional | madrid |
127
127
  |---|---|---|---|
128
- | `filters.offices: ["inpi-fr"]` | 6898 | 0 | 0 |
129
- | `filters.jurisdictions: ["FR"]`, protection | 6898 | 10000+ | 2708 |
128
+ | `filters.offices: ["inpi-fr"]` | yes | **none** | **none** |
129
+ | `filters.jurisdictions: ["FR"]`, protection | yes | yes | yes |
130
130
 
131
131
  **So an EU trade mark that blocks use in France is now found**, and it never appears in the French
132
132
  register. Every covered territory reaches its Madrid layer this way and the EU members additionally reach
@@ -154,10 +154,10 @@ French national marks. On the same term:
154
154
 
155
155
  | what the executor sends | national | regional | Madrid |
156
156
  |---|---|---|---|
157
- | `filters.offices: ["inpi-fr"]` (the shape this doc used to describe) | 6898 | 0 | 0 |
158
- | `filters.jurisdictions: ["FR"]`, `territory_match: "protection"` | 6898 | 10000+ | 2708 |
157
+ | `filters.offices: ["inpi-fr"]` (the shape this doc used to describe) | yes | **none** | **none** |
158
+ | `filters.jurisdictions: ["FR"]`, `territory_match: "protection"` | yes | yes | yes |
159
159
 
160
- It is ONE call, not three. A territory under no regional register — Switzerland — returns regional 0 either
160
+ It is ONE call, not three. A territory under no regional register — Switzerland — gains no regional rows either
161
161
  way and still reaches its Madrid layer, which is what shows `protection` adds a LAYER rather than just more
162
162
  rows.
163
163
 
@@ -26,7 +26,7 @@ sufficiency, and prioritisation. See [unit.md](unit.md).
26
26
  > match-mode, never "all classes". The ONLY all-class enumerate is the exact-IDENTICAL cross-class merch check
27
27
  > (`match_mode:exact`, `nice_classes:[25]`). `fuzzy` is never an enumerate mode.
28
28
 
29
- **Execution note:** `prelim-register` now runs as a worker that decomposes these axes into isolated
29
+ **Execution note:** `clearance-register` now runs as a worker that decomposes these axes into isolated
30
30
  search **units** (saturation-probe / primary-sweep / transliteration-numeric / incumbent-class /
31
31
  merch-sweep), each executing one axis and writing its named-band array (`register-units/<axis>-band.json`).
32
32
  If you are a unit, run only your assigned axis from the recipe below; the judgment worker (Layer B) performs
@@ -190,7 +190,7 @@ For each transliteration variant in the manifest:
190
190
  → transliteration plausibility is a verification flag for the lawyer (Verify? ✅)
191
191
  ```
192
192
 
193
- **Important:** transliteration hits are NOT confirmed without senior-lawyer sign-off. Claude generates plausible transliterations but Korean/Arabic/etc native speakers must confirm. The `Verify? ✅` flag from `prelim-variants` carries through to the band so judgment surfaces it. The funnel does not decide a transliteration is wrong — it enumerates and passes the record with its flag.
193
+ **Important:** transliteration hits are NOT confirmed without senior-lawyer sign-off. Claude generates plausible transliterations but Korean/Arabic/etc native speakers must confirm. The `Verify? ✅` flag from `clearance-variants` carries through to the band so judgment surfaces it. The funnel does not decide a transliteration is wrong — it enumerates and passes the record with its flag.
194
194
 
195
195
  **Breadth note (this recipe shares a unit with the per-jurisdiction named queries).** Both the script-group enumerations here and the material-jurisdiction named queries are owned by the `transliteration-numeric` unit, and **both are enumerated** — there is no "yield one to fund the other" sufficiency trade any more. `register_enumerate` owns each query's page loop; the unit runs every variant query the manifest declares. If a query genuinely cannot run (provider error), that surfaces as an `incomplete` block, not a silently-dropped sweep.
196
196
 
@@ -331,7 +331,7 @@ by goods **words**. The everyday-word saturation is the trigger to **scope the n
331
331
  class)** — never to drop the token, re-narrow it to a more specific concept, or swap it for the phonetic form. The
332
332
  saturated meaning token is enumerated like any other named slice; the lawyer reads it. (This is the register half
333
333
  of the variant-stage everyday-word-first rule — see
334
- [transliteration-scripts.md](../prelim-variants/transliteration-scripts.md): the everyday word is kept upstream,
334
+ [transliteration-scripts.md](../clearance-variants/transliteration-scripts.md): the everyday word is kept upstream,
335
335
  class-scoped and enumerated here.) Reuse steps 1–2 above with the class-scoped meaning token as the `register_enumerate` predicate.
336
336
 
337
337
  **Expected output:** on a saturated field, the complete enumerated near-exact in-class band (live + dead with status) the ranker's top-N paging would have buried, plus the phonetic-fringe band — each as an `enumerated` block, or an `incomplete` descriptor where a slice was a genuine crowd. On a non-saturated field this recipe does not fire.
@@ -1,6 +1,6 @@
1
1
  # Status rules — status classification, Madrid handling, non-Latin status strings
2
2
 
3
- Cross-referenced from [prelim-register/SKILL.md](SKILL.md) — the canonical entry point. The provider files and stealth-filer indicators link here for the status-classification rules; the orchestrator never reads this file directly.
3
+ Cross-referenced from [clearance-register/SKILL.md](SKILL.md) — the canonical entry point. The provider files and stealth-filer indicators link here for the status-classification rules; the orchestrator never reads this file directly.
4
4
 
5
5
  > **Funnel vs judgment (read this first).** Under the two-layer split, the **funnel (Layer A) does NOT drop
6
6
  > records on status** — `register_enumerate` carries **every** record forward (live AND dead) **with its
@@ -226,7 +226,7 @@ For owner country:
226
226
 
227
227
  If after the full fallback chain the owner is still empty, set owner column to `(unknown — confirm)` and add to Open verification flags.
228
228
 
229
- **Owner-identity conflict.** If two fields in the chain (or an EUIPO cross-check vs the vendor record) yield *materially different* owner names for the same URI, do NOT silently pick the first — record both candidate names in the owner field and set `Verify? ✅` with reason "owner-identity conflict — confirm before enforcement read." Likewise, when a portfolio-size signal (many filings clustering under one normalised owner) would change the enforcement-appetite read, surface it. Owner identity drives enforcer-profiling (`prelim-search/firm-wide-reasoning.md`, *Enforcer profiling*) — a wrong owner is a wrong risk read.
229
+ **Owner-identity conflict.** If two fields in the chain (or an EUIPO cross-check vs the vendor record) yield *materially different* owner names for the same URI, do NOT silently pick the first — record both candidate names in the owner field and set `Verify? ✅` with reason "owner-identity conflict — confirm before enforcement read." Likewise, when a portfolio-size signal (many filings clustering under one normalised owner) would change the enforcement-appetite read, surface it. Owner identity drives enforcer-profiling (`clearance-search/firm-wide-reasoning.md`, *Enforcer profiling*) — a wrong owner is a wrong risk read.
230
230
 
231
231
  ### USPTO extended country codes
232
232
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Detect "law firm as owner" (i.e., the registered owner is a legal-services entity rather than the underlying client) via the following regex / substring patterns. Any match flags the row as a candidate stealth filing — surface this in the Findings sheet and feed it into Option D Trigger 2 (one common-law query for the underlying client's marketplace use).
4
4
 
5
- Canonical entry point: [prelim-register/SKILL.md](SKILL.md) lists this file and `status-rules.md` as siblings; this file references back to `status-rules.md` only for the owner-extraction fallback chain it depends on.
5
+ Canonical entry point: [clearance-register/SKILL.md](SKILL.md) lists this file and `status-rules.md` as siblings; this file references back to `status-rules.md` only for the owner-extraction fallback chain it depends on.
6
6
 
7
7
  ## Indicator patterns
8
8
 
@@ -1,4 +1,4 @@
1
- # prelim-register — MODE A (UNIT)
1
+ # clearance-register — MODE A (UNIT)
2
2
 
3
3
  > Read `SKILL.md` first (the shared spine: Spawned session, Model, Provider, Tool call budget, the band-block coverage model, Failure fallback). This file is the UNIT-mode procedure only. **Do NOT read `digest.md`** — that is digest-mode judgment a unit must never run.
4
4
 
@@ -52,7 +52,7 @@ You were spawned to run exactly ONE axis named in your task. Read the manifest +
52
52
  - **off-field-drop on goods** — brand-json has no goods/services text; an in-scope-class live record is carried forward and the lawyer decides on its actual goods/services. (`screen_verdict` is enrichment for judgment, not a funnel drop authority.)
53
53
  - **sample or self-accept** — no top-N, no "narrow to tractable and stop", no per-jurisdiction 3-fetch ceiling, no switch-to-exact-standalone-as-enumeration. Those were funnel sufficiency calls; they are **deleted**. The tool enumerates or reports incomplete — there is no in-between for you to author.
54
54
  6. **Surface dead records WITH their status — no funnel date-cutoff.** Carry every record `register_enumerate` returns **with its `status`** (live / lapsed / expired / lapse-date in the record's dates). You do **NOT** apply a recency/date threshold and you do **NOT** drop dead-except-identical. **`recently-dead` is a STATUS for judgment**, not a funnel filter: whether a recently-lapsed near-identical matters (revival window, field history, non-use vulnerability) is the lawyer's call (Layer B), made on the status + lapse date you passed through. Volume is handled by the completeness contract (step 3): if the dead-inclusive named band is bounded, `register_enumerate` returns it `enumerated`; if it is a crowd, it returns `incomplete` → descriptor. You pass the fact; judgment weighs it. (The old D4 ≤5y date-cutoff drop is **removed** — it was a funnel-side judgment.)
55
- 7. **Write the band artifact, then return.** Write `register-units/<axis>-band.json` (the named-band array, schema below) to `studio/prelim-search/<slug>/<date>/register-units/<axis>-band.json`, **before you return — returning without it is a failure** (the deterministic driver gates on this file: if it is missing after your turn it fails the stage and retries it under a fresh session key; a band that never lands as a file is lost work). Then **file your audit note by calling `record_unit_note`** — you do not write it, and the dispatch hands you no path for it: the driver renders it from your call. **The counts are not yours to type.** Queries enumerated, incomplete blocks and records carried forward are taken from the band you just wrote, so the note and the band cannot disagree; a note filed before the band exists is refused by name, because an account of a sweep that has not happened is not a short note but a wrong one. What you send is the half the band cannot say: `null_result` if this axis genuinely found nothing (refused against a band that carries records), and `note` — one short observation an auditor would want, in a lawyer's words. **The raw character-noise pile stays in this session** — what crosses the firewall is the **complete named band + crowd descriptors** (the `<axis>-band.json` array), NOT the raw rows. Do **not** apply a relevance gate, do **not** aggregate owners, do **not** decide sufficiency — those are judgment's job (Layer B).
55
+ 7. **Write the band artifact, then return.** Write `register-units/<axis>-band.json` (the named-band array, schema below) to `studio/clearance-search/<slug>/<date>/register-units/<axis>-band.json`, **before you return — returning without it is a failure** (the deterministic driver gates on this file: if it is missing after your turn it fails the stage and retries it under a fresh session key; a band that never lands as a file is lost work). Then **file your audit note by calling `record_unit_note`** — you do not write it, and the dispatch hands you no path for it: the driver renders it from your call. **The counts are not yours to type.** Queries enumerated, incomplete blocks and records carried forward are taken from the band you just wrote, so the note and the band cannot disagree; a note filed before the band exists is refused by name, because an account of a sweep that has not happened is not a short note but a wrong one. What you send is the half the band cannot say: `null_result` if this axis genuinely found nothing (refused against a band that carries records), and `note` — one short observation an auditor would want, in a lawyer's words. **The raw character-noise pile stays in this session** — what crosses the firewall is the **complete named band + crowd descriptors** (the `<axis>-band.json` array), NOT the raw rows. Do **not** apply a relevance gate, do **not** aggregate owners, do **not** decide sufficiency — those are judgment's job (Layer B).
56
56
 
57
57
  ## What else your grant carries, and why you do not call it
58
58