clearotron 0.4.0-beta.1 → 0.4.0-beta.2

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 (250) hide show
  1. package/INSTALL.md +4 -31
  2. package/README.md +5 -5
  3. package/bin/brandowner.mjs +1 -1
  4. package/bin/onboard.mjs +18 -74
  5. package/bin/start.mjs +58 -14
  6. package/bin/update.mjs +4 -1
  7. package/build-info.json +2 -2
  8. package/demo/full-country-search/run/_driver/search-policy.json +1 -1
  9. package/demo/full-country-search/run/status.json +1 -1
  10. package/demo/global-preliminary-search/run/_driver/search-policy.json +1 -1
  11. package/demo/global-preliminary-search/run/status.json +1 -1
  12. package/demo/knockout-search/run/_driver/search-policy.json +1 -1
  13. package/demo/knockout-search/run/status.json +1 -1
  14. package/demo/multi-country-focus-search/run/_driver/search-policy.json +1 -1
  15. package/demo/multi-country-focus-search/run/status.json +1 -1
  16. package/docs/README.md +1 -0
  17. package/docs/SECURITY-OWASP.md +298 -0
  18. package/docs/SECURITY.md +18 -13
  19. package/docs/architecture/02-architecture.md +5 -5
  20. package/docs/architecture/03-run-lifecycle.md +28 -29
  21. package/docs/architecture/04-configuration-reference.md +3 -4
  22. package/docs/architecture/05-config-governance.md +5 -7
  23. package/docs/architecture/06-operations-runbook.md +0 -12
  24. package/docs/architecture/07-quality-and-audit.md +12 -13
  25. package/docs/architecture/09-security-and-data.md +9 -4
  26. package/driver/CHANGELOG.md +60 -0
  27. package/driver/ask-ledger.mjs +2 -0
  28. package/driver/authority-trees.mjs +90 -8
  29. package/driver/band-shape.mjs +5 -5
  30. package/driver/case-law-ledger.mjs +19 -3
  31. package/driver/claim-liveness.mjs +30 -1
  32. package/driver/clearance-variants-record.mjs +10 -3
  33. package/driver/common-law-receipts.mjs +62 -12
  34. package/driver/commonlaw-carry.mjs +1 -1
  35. package/driver/compare.mjs +2 -2
  36. package/driver/connotation-search.mjs +30 -101
  37. package/driver/contract-arm2-baseline.json +6 -5
  38. package/driver/contract-e3-backlog.mjs +60 -60
  39. package/driver/contract-vocabulary.mjs +38 -31
  40. package/driver/coverage-form-io.mjs +13 -1
  41. package/driver/coverage-form.mjs +42 -4
  42. package/driver/coverage-ledger.mjs +3 -5
  43. package/driver/cross-check-wait.mjs +43 -0
  44. package/driver/declination-call.mjs +33 -9
  45. package/driver/declination-tool.mjs +27 -15
  46. package/driver/deferral-row.mjs +139 -0
  47. package/driver/degraded-parts.mjs +377 -0
  48. package/driver/deliver-trigger.sh +1 -1
  49. package/driver/demo-container.mjs +4 -1
  50. package/driver/dev-portal.mjs +4 -4
  51. package/driver/dispatch-record.mjs +2 -2
  52. package/driver/driver.config.mjs +177 -87
  53. package/driver/effective-scope.mjs +58 -2
  54. package/driver/engine/anthropic-agent.mjs +103 -27
  55. package/driver/engine/auth.mjs +2 -2
  56. package/driver/engine/child-record.mjs +11 -0
  57. package/driver/engine/cli-version.mjs +4 -3
  58. package/driver/engine/common.mjs +17 -2
  59. package/driver/engine/deny-authority-write.mjs +3 -1
  60. package/driver/engine/engine-env.mjs +174 -0
  61. package/driver/engine/engine-spawn.mjs +179 -0
  62. package/driver/engine/mcp/band-server.mjs +1 -1
  63. package/driver/engine/mcp/codex-config.mjs +112 -3
  64. package/driver/engine/mcp/declination-server.mjs +9 -8
  65. package/driver/engine/mcp/dispositions-server.mjs +2 -1
  66. package/driver/engine/mcp/fetch-server.mjs +14 -11
  67. package/driver/engine/mcp/gather-config.mjs +22 -10
  68. package/driver/engine/mcp/perplexity-server.mjs +96 -16
  69. package/driver/engine/mcp/probe-server.mjs +43 -21
  70. package/driver/engine/mcp/public-fetch.mjs +195 -0
  71. package/driver/engine/mcp/recording-server.mjs +78 -13
  72. package/driver/engine/mcp/supplemental.mjs +13 -13
  73. package/driver/engine/mcp/unit-note-server.mjs +50 -1
  74. package/driver/engine/openai-agent.mjs +109 -28
  75. package/driver/engine/probe.mjs +152 -19
  76. package/driver/enqueue-schema.mjs +3 -3
  77. package/driver/findings-model.mjs +64 -13
  78. package/driver/floor-duty.mjs +21 -5
  79. package/driver/form-neighbourhood.mjs +5 -2
  80. package/driver/framework-method.mjs +304 -0
  81. package/driver/gateway.mjs +44 -16
  82. package/driver/hand-off-exits.mjs +129 -0
  83. package/driver/jx.mjs +8 -5
  84. package/driver/knockout-assess-record.mjs +7 -1
  85. package/driver/knockout-frame-record.mjs +96 -34
  86. package/driver/knockout-review-record.mjs +7 -2
  87. package/driver/matter-frame-record.mjs +31 -2
  88. package/driver/methodology-witness.mjs +6 -3
  89. package/driver/named-band.mjs +1 -1
  90. package/driver/owner-use-check.mjs +45 -10
  91. package/driver/package.json +1 -1
  92. package/driver/partial-payload-baseline.json +4 -0
  93. package/driver/phase0.mjs +2 -2
  94. package/driver/pipeline-knockout.mjs +128 -35
  95. package/driver/pipeline.mjs +373 -598
  96. package/driver/placement-carry.mjs +20 -1
  97. package/driver/placement-form-io.mjs +18 -4
  98. package/driver/placement-form.mjs +52 -3
  99. package/driver/placement-union.mjs +32 -5
  100. package/driver/portal-report.mjs +3 -3
  101. package/driver/portal-service.mjs +4 -3
  102. package/driver/portal-static.mjs +11 -18
  103. package/driver/profile-page.html +5 -5
  104. package/driver/profiles.mjs +5 -5
  105. package/driver/progress.mjs +5 -3
  106. package/driver/provider-usage.mjs +1 -1
  107. package/driver/publish/index.mjs +94 -22
  108. package/driver/publish/knockout.mjs +133 -12
  109. package/driver/publish/profiles-page.mjs +2 -0
  110. package/driver/publish/publish-inputs.mjs +10 -4
  111. package/driver/publish/render-knockout.mjs +47 -20
  112. package/driver/publish/render.mjs +12 -7
  113. package/driver/publish/report-data.mjs +2 -0
  114. package/driver/publish/search-depth.mjs +77 -4
  115. package/driver/publish/templates/report.css +1 -1
  116. package/driver/publish/xlsx.mjs +34 -15
  117. package/driver/reasoning-tripwires.mjs +2 -160
  118. package/driver/recall-receipt.mjs +27 -0
  119. package/driver/record-carry.mjs +8 -8
  120. package/driver/reference-score.mjs +142 -20
  121. package/driver/register-count.mjs +5 -3
  122. package/driver/register-digest-record.mjs +13 -0
  123. package/driver/register-plan.mjs +156 -75
  124. package/driver/register-records.mjs +27 -3
  125. package/driver/registration-scripts.mjs +22 -0
  126. package/driver/repair-composers.mjs +19 -3
  127. package/driver/repair-contract.mjs +1 -1
  128. package/driver/repairs.mjs +5 -2
  129. package/driver/reviewer-open-points.mjs +33 -0
  130. package/driver/rule-shape.mjs +8 -8
  131. package/driver/run-economics.mjs +2 -2
  132. package/driver/run-integrity.mjs +2 -2
  133. package/driver/runner.mjs +17 -5
  134. package/driver/scope-facts.mjs +89 -12
  135. package/driver/score-redaction.mjs +247 -0
  136. package/driver/search-policy.mjs +17 -0
  137. package/driver/skills/README.md +2 -2
  138. package/driver/skills/clearance-common-law/SKILL.md +29 -36
  139. package/driver/skills/clearance-common-law/perplexity-prompts.md +5 -27
  140. package/driver/skills/clearance-register/SKILL.md +15 -16
  141. package/driver/skills/clearance-register/digest.md +14 -30
  142. package/driver/skills/clearance-register/register-recipes.md +14 -56
  143. package/driver/skills/clearance-register/unit.md +36 -47
  144. package/driver/skills/clearance-search/SKILL.md +6 -8
  145. package/driver/skills/clearance-search/delivery-contract.md +0 -7
  146. package/driver/skills/clearance-search/firm-wide-reasoning.md +5 -4
  147. package/driver/skills/clearance-search/phase2-execution.md +5 -6
  148. package/driver/skills/clearance-search/risk-framework-triage.md +2 -2
  149. package/driver/skills/clearance-search/synthesis-rules.md +5 -5
  150. package/driver/skills/clearance-search/template-formatting.md +2 -2
  151. package/driver/skills/clearance-variants/SKILL.md +6 -6
  152. package/driver/skills/clearance-variants/transliteration-scripts.md +1 -1
  153. package/driver/skills/knockout-assess/SKILL.md +31 -1
  154. package/driver/skills/knockout-frame/SKILL.md +42 -10
  155. package/driver/skills/matter-frame/SKILL.md +12 -5
  156. package/driver/skills/narrative-refutation/SKILL.md +3 -1
  157. package/driver/skills/placement-inquiry/SKILL.md +4 -0
  158. package/driver/stage-context.mjs +23 -2
  159. package/driver/stages-knockout.mjs +92 -79
  160. package/driver/stages.mjs +88 -53
  161. package/driver/stray-artifacts.mjs +9 -5
  162. package/driver/suite-census.json +620 -140
  163. package/driver/synthesis-record.mjs +26 -4
  164. package/driver/systemd/README.md +5 -6
  165. package/driver/systemd/clearotron-worker.service +6 -1
  166. package/driver/tokens.mjs +2 -2
  167. package/driver/unit-inventory.mjs +21 -40
  168. package/driver/variant-manifest-model.mjs +21 -2
  169. package/driver/verify-knockout.mjs +163 -4
  170. package/driver/verify.mjs +40 -14
  171. package/driver/web-grid.mjs +150 -0
  172. package/driver/withheld-families.mjs +113 -4
  173. package/driver/worker-heartbeat.mjs +13 -2
  174. package/mcp-server/CHANGELOG.md +4 -0
  175. package/mcp-server/README.md +1 -1
  176. package/mcp-server/lib/knockout.mjs +1 -1
  177. package/mcp-server/lib/ops.mjs +10 -10
  178. package/mcp-server/lib/scrub.mjs +1 -1
  179. package/mcp-server/lib/trace.mjs +3 -2
  180. package/mcp-server/package.json +1 -1
  181. package/mcp-server/server.mjs +2 -2
  182. package/package.json +1 -1
  183. package/portal-ui/dist/assets/{index-D_O_55vK.js → index-BPAUjcI0.js} +1 -1
  184. package/portal-ui/dist/assets/{index-5CCwiJG7.css → index-D2wrw9cH.css} +18 -2
  185. package/portal-ui/dist/assets/plus-jakarta-sans-BUCHxqJ-.woff2 +0 -0
  186. package/portal-ui/dist/index.html +2 -15
  187. package/portal-ui/package.json +1 -1
  188. package/providers/_shared/enumerate.mjs +155 -50
  189. package/providers/_shared/execute-plan.mjs +62 -16
  190. package/providers/_shared/ledger.mjs +1 -1
  191. package/providers/_shared/plan-guards.mjs +7 -0
  192. package/providers/clarivate/src/core.js +54 -6
  193. package/providers/corsearch/README.md +1 -2
  194. package/providers/corsearch/src/core.js +2 -2
  195. package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
  196. package/providers/oauth-mcp-bridge/README.md +8 -7
  197. package/providers/oauth-mcp-bridge/bridge.mjs +21 -5
  198. package/providers/oauth-mcp-bridge/package.json +1 -1
  199. package/providers/oauth-mcp-bridge/systemd/courtlistener-mcp.service +1 -1
  200. package/providers/oauth-mcp-bridge/warm-server.mjs +16 -5
  201. package/providers/perplexity/src/core.js +246 -21
  202. package/providers/signa/src/core.js +27 -25
  203. package/scripts/README.md +2 -1
  204. package/scripts/added-reference-check.mjs +2 -1
  205. package/scripts/backup-recall-stores.mjs +5 -5
  206. package/scripts/demo-evidence.mjs +2 -1
  207. package/scripts/drive-env-check.mjs +2 -1
  208. package/scripts/e2e-first-time.mjs +469 -0
  209. package/scripts/e2e-scenario-ops.mjs +441 -0
  210. package/scripts/e2e.mjs +104 -16
  211. package/scripts/env-audit.mjs +8 -0
  212. package/scripts/freeze-example-run.mjs +7 -7
  213. package/scripts/generated-files-are-current.mjs +2 -1
  214. package/scripts/hand-off-exits-probe.mjs +75 -0
  215. package/scripts/import-cycle-check.mjs +2 -1
  216. package/scripts/merge-shape-check.mjs +2 -1
  217. package/scripts/package-size-budget.mjs +2 -1
  218. package/scripts/record-carry-probe.mjs +1 -1
  219. package/scripts/release-install-check.mjs +4 -1
  220. package/scripts/release-note-required.mjs +44 -10
  221. package/scripts/render-check.mjs +5 -2
  222. package/scripts/report-offline-render-check.mjs +169 -0
  223. package/scripts/score.mjs +76 -5
  224. package/scripts/strip-titles-and-attributions.mjs +2 -1
  225. package/scripts/strip-tracker-citations.mjs +2 -1
  226. package/scripts/test-full.mjs +2 -1
  227. package/scripts/test-run.mjs +10 -3
  228. package/scripts/third-party-notices.mjs +3 -1
  229. package/scripts/travelling-predicates.mjs +1 -1
  230. package/scripts/writing-standard-check.mjs +2 -1
  231. package/shared/brand-fonts.mjs +59 -0
  232. package/shared/brand.mjs +5 -5
  233. package/shared/browser-temp-root.mjs +3 -2
  234. package/shared/doctrine-overlay.mjs +1 -1
  235. package/shared/driver-dir.mjs +27 -2
  236. package/shared/fonts/OFL-fira-code.txt +93 -0
  237. package/shared/fonts/OFL-plus-jakarta-sans.txt +93 -0
  238. package/shared/fonts/README.md +37 -0
  239. package/shared/fonts/fira-code.woff2 +0 -0
  240. package/shared/fonts/plus-jakarta-sans.woff2 +0 -0
  241. package/shared/npm-cli.mjs +23 -0
  242. package/shared/os-advice.mjs +14 -2
  243. package/shared/path-seps.mjs +42 -0
  244. package/shared/process-table.mjs +71 -3
  245. package/shared/reference-guard-classes.mjs +30 -6
  246. package/shared/root-doc-commands.mjs +6 -2
  247. package/shared/running-start.mjs +24 -7
  248. package/shared/scope.mjs +2 -2
  249. package/shared/wsl.mjs +1 -1
  250. package/driver/known-conflicts.mjs +0 -345
@@ -11,7 +11,7 @@
11
11
 
12
12
  import { readFileSync, existsSync, readdirSync } from "node:fs";
13
13
  import { join, basename, isAbsolute } from "node:path";
14
- import { driverDir } from "../shared/driver-dir.mjs"; //
14
+ import { driverDir, driverFileName } from "../shared/driver-dir.mjs"; //
15
15
  import { fileURLToPath } from "node:url";
16
16
  import { STAGES, paths } from "./stages.mjs";
17
17
  import { isEntrypoint } from "../shared/is-entrypoint.mjs"; // — one entry-point test, all spellings
@@ -141,7 +141,7 @@ function outPath(dir, stage, axis) {
141
141
  // last JSONL line of a stage's telemetry, tried at <dir>/<label>.jsonl (snapshot) and <dir>/_driver/<label>.jsonl.
142
142
  function readTel(dir, stage, axis) {
143
143
  const label = labelFor(stage, axis);
144
- for (const p of [join(dir, `${label}.jsonl`), driverDir(dir, `${label}.jsonl`)]) {
144
+ for (const p of [join(dir, driverFileName(`${label}.jsonl`)), driverDir(dir, `${label}.jsonl`)]) {
145
145
  try {
146
146
  const lines = readFileSync(p, "utf8").trim().split("\n").filter(Boolean);
147
147
  if (lines.length) return JSON.parse(lines[lines.length - 1]);
@@ -11,9 +11,9 @@
11
11
  // for the meaning search, the model fabricated "(None identified — affirmative sweep) … no gang associations".
12
12
  //
13
13
  // Two halves, both PURE (no node imports → tests offline):
14
- // 1. buildConnotationQueries — the driver dictates the meaning queries (mark + near-forms × shapes) VERBATIM
15
- // into grid-spec.json; the perplexity plugin runs them on the general web and records each into the grid
16
- // ledger's extras.pr_risk[] (a recorded query — even with empty results — is the receipt the search ran).
14
+ // 1. meaningAnglesFromMatterContext — the driver dictates the meaning queries, the matter frame's own list,
15
+ // VERBATIM into grid-spec.json; the perplexity plugin runs them on the general web and records each into the
16
+ // grid ledger's extras.pr_risk[] (a recorded query — even with empty results — is the receipt the search ran).
17
17
  // 2. findConnotationViolations — the validator: recorded meaning receipts must be disposed of, per query,
18
18
  // citing the receipt. A PR/reputational section that ASSERTS a clean result must additionally cite a
19
19
  // Connotation-search source line. A searched-clean (recorded queries, empty results) passes.
@@ -28,98 +28,21 @@
28
28
  // section at all matched no block, so DELETING the section passed the gate. Receipts present now means
29
29
  // receipts validated, whatever the document says.
30
30
 
31
- // The meaning query shapes. NOT a banned-word list — these are SEARCH directions ("what does this name mean,
32
- // and to whom?"). Perplexity surfaces foreign-language / gang / slang meanings from English query shapes
33
- // (a benign given name one letter off "Mara" → the gang label surfaces from "<mark> gang" / "<mark> urban dictionary").
34
-
31
+ // THE SHAPES THE FIXED MEANING SWEEP ASKED, until 2026-09-25: every run searched the first 6 spellings on
32
+ // the five core shapes and the first 8 translated forms on the three below, about 54 web questions whatever
33
+ // the matter. The matter frame decides the sweep now, as it decides the stores, and no query is built from
34
+ // these. They stay so connotationReasonKey still reads the queries of the runs archived before.
35
35
  export const CONNOTATION_SHAPES = ["meaning slang", "gang", "offensive", "urban dictionary", "wikipedia"];
36
-
37
- /**
38
- * Build the dictated connotation queries from the mark + its near-forms (the grid variants). De-dups
39
- * case-insensitively and caps the term count (the meaning search is the mark + a handful of near-forms, not
40
- * the full variant explosion). Returns ["<term> <shape>", …] — run VERBATIM by the plugin's grid program. PURE.
41
- */
42
- export function pickConnotationTerms(terms, maxTerms = 6) {
43
- const seen = new Set();
44
- const picked = [];
45
- for (const t of (terms ?? [])) {
46
- const v = String(t ?? "").trim();
47
- if (!v) continue;
48
- // KEYED THE SAME WAY THE GATES COMPARE. A producer that folds less than its consumer dictates two
49
- // terms the gate can only see as one, and a seat recording either satisfies it for both — the gate
50
- // then passes a query that never ran, which is the fault it exists to catch, inverted.
51
- const k = queryKey(v);
52
- if (seen.has(k)) continue;
53
- seen.add(k);
54
- picked.push(v);
55
- if (picked.length >= maxTerms) break;
56
- }
57
- return picked;
58
- }
59
-
60
- export function buildConnotationQueries(terms, { shapes = CONNOTATION_SHAPES, maxTerms = 6 } = {}) {
61
- const picked = pickConnotationTerms(terms, maxTerms);
62
- const queries = [];
63
- for (const t of picked) for (const s of shapes) queries.push(`${t} ${s}`);
64
- return queries;
65
- }
66
-
67
- // WP-56 B1 — the NON-ENGLISH half of the meaning sweep. The core bucket runs the mark + its first
68
- // near-forms; the manifest's translated/transliterated forms (non-Latin script rows, "丝绸与铁 / 席尔克"
69
- // packed alternates) sat beyond its cap, so a mark could ship with no meaning read in the very scripts the
70
- // manifest committed to search. These forms get their OWN capped bucket with meaning-appropriate shapes —
71
- // the slang / urban-dictionary shapes are Latin-web search directions; a non-Latin or translated form
72
- // wants its meaning and English reading. Which forms exist stays the variants stage's judgment (the
73
- // structured manifest); this stays mechanical.
74
36
  export const CONNOTATION_SHAPES_TRANSLIT = ["meaning", "meaning in english", "offensive meaning"];
75
37
 
76
- // A letter outside the Latin script (property escape, not a codepoint range — punctuation/dashes in a
77
- // Latin term must not read as "non-Latin").
78
- const NON_LATIN_LETTER_RE = /(?![\p{Script=Latin}])\p{L}/u;
79
-
80
- /**
81
- * Build the translit/translation connotation queries from the STRUCTURED variant-manifest model's
82
- * variants[] ({value, category, rationale}): rows typed category "transliteration" (a Latin-script
83
- * translation typed there rides along) plus any variant value carrying a non-Latin letter, whatever its
84
- * category. " / "-packed alternates split into individual forms; forms the core bucket already queries
85
- * (coreTerms, case-insensitive) are dropped; own cap (default 8, beside the core bucket's 6).
86
- * Returns ["<form> <shape>", …] like buildConnotationQueries. PURE.
87
- */
88
- export function buildTranslitConnotationQueries(modelVariants, { shapes = CONNOTATION_SHAPES_TRANSLIT, maxTerms = 8, coreTerms = [] } = {}) {
89
- const seen = new Set((coreTerms ?? []).map((t) => queryKey(t)).filter(Boolean));
90
- const picked = [];
91
- for (const v of (modelVariants ?? [])) {
92
- const value = String(v?.value ?? "").trim();
93
- if (!value) continue;
94
- const isTranslit = String(v?.category ?? "").trim().toLowerCase() === "transliteration" || NON_LATIN_LETTER_RE.test(value);
95
- if (!isTranslit) continue;
96
- for (const form of value.split(" / ")) {
97
- const f = form.trim();
98
- if (!f) continue;
99
- const k = queryKey(f);
100
- if (seen.has(k)) continue;
101
- seen.add(k);
102
- picked.push(f);
103
- if (picked.length >= maxTerms) break;
104
- }
105
- if (picked.length >= maxTerms) break;
106
- }
107
- const queries = [];
108
- for (const t of picked) for (const s of shapes) queries.push(`${t} ${s}`);
109
- return queries;
110
- }
111
-
112
- // ── P2-C (Round-2 §8b) — the DERIVED half of the sweep's scope ─────────────────────────────────────────
113
- // The fixed CONNOTATION_SHAPES floor asks generic search DIRECTIONS ("<mark> offensive") and stays — it is
114
- // not a sensitivities checklist, and on the evidence run it did retrieve the cultural-criticism material.
115
- // What no fixed list can ask is the PER-MATTER angle: the cultural origin a word evokes, the charged history
116
- // of its imagery, the controversy specific to these goods in this market. Deriving those is judgment, so the
117
- // MATTER FRAME authors them — its dictated `Meaning angles:` line (semantic field × market/industry; the
118
- // stage message dictates it and the matterContext validator requires it on fresh runs, `none` allowed as an
119
- // explicit reasoned emptiness). This parser is the mechanical half: extract, sanitize, cap. The queries are
120
- // appended VERBATIM to grid-spec connotation.queries BESIDE the floor, so the per-query identity join
121
- // (findDroppedConnotationQueries) polices their execution exactly like the floor's. NEVER a hardcoded
122
- // sensitivities checklist — the angles are authored per matter; code only carries them.
38
+ // ── THE MATTER FRAME'S LIST IS THE WHOLE MEANING SWEEP (ruled 2026-09-25) ─────────────────────────────────
39
+ // Deriving what a name could mean, and to whom, is judgment, so the MATTER FRAME authors the questions: its
40
+ // `Meaning angles:` line — the mark's semantic field × this matter's market and goods, the languages whose
41
+ // buyers matter, and any slang, gang or offensive reading (the stage message dictates it and the
42
+ // matterContext validator requires it on fresh runs, `none` allowed as an asserted zero). A fixed floor rode
43
+ // beside it and is gone. This parser is the mechanical half: extract and sanitize; the frame decides how
44
+ // many. The queries go VERBATIM into grid-spec connotation.queries, and the per-query identity join
45
+ // (findDroppedConnotationQueries) polices their execution. NEVER a hardcoded sensitivities checklist.
123
46
 
124
47
  // The frame's machine line (mirrors channelsFromMatterContext's "Search channels:" shape), ANCHORED to a
125
48
  // line start: prose that merely MENTIONS `"Meaning angles:" line …` must never read as the line (the
@@ -167,15 +90,15 @@ function sanitizeMeaningAngle(raw) {
167
90
  }
168
91
 
169
92
  /**
170
- * Parse the matter frame's `Meaning angles: <q>; <q>; …` line into sanitized derived queries.
171
- * Semicolon-separated (an angle phrase may contain commas); `none` (the explicit reasoned-emptiness form)
172
- * and a missing line both yield [] — the floor always rides regardless. Sanitization is mechanical only:
173
- * strip WRAPPING quotes/backticks (see sanitizeMeaningAngle — a phrase quote inside the angle survives),
174
- * collapse whitespace, drop empties and over-length entries, dedupe
175
- * case-insensitively (against itself and `alreadyQueried`, so a derived angle never double-dictates a floor
176
- * query), cap the count. Content judgment stays the frame's. PURE.
93
+ * Parse the matter frame's `Meaning angles: <q>; <q>; …` line into the sanitized meaning queries.
94
+ * Semicolon-separated (an angle phrase may contain commas); `none` (the asserted-zero form) and a missing
95
+ * line both yield [], and meaningAnglesAssertedNone tells the two apart: only the first is the frame's
96
+ * decision. Sanitization is mechanical only: strip WRAPPING quotes/backticks (see sanitizeMeaningAngle — a
97
+ * phrase quote inside the angle survives), collapse whitespace, drop empties, dedupe case-insensitively
98
+ * (against itself and `alreadyQueried`). No cap on length or count: the frame's tool refuses an over-long
99
+ * question at the source, every question is run as written, and how many is the frame's call. PURE.
177
100
  */
178
- export function meaningAnglesFromMatterContext(md, { alreadyQueried = [], maxAngles = 8, maxLen = 90 } = {}) {
101
+ export function meaningAnglesFromMatterContext(md, { alreadyQueried = [], maxAngles = Infinity } = {}) {
179
102
  const m = String(md || "").match(MEANING_ANGLES_RE);
180
103
  if (!m) return [];
181
104
  const value = m[1].trim();
@@ -188,7 +111,7 @@ export function meaningAnglesFromMatterContext(md, { alreadyQueried = [], maxAng
188
111
  // quote runs at both ends unconditionally, so `"` sanitized to "" and fell out here; the wrapper rule
189
112
  // keeps it, and a lone `"` dictated as a query is a search nobody asked for that no receipt can ever
190
113
  // match — the failure this change exists to stop. Dropped explicitly rather than as a side effect.
191
- if (!q || !/[\p{L}\p{N}]/u.test(q) || q.length > maxLen) continue;
114
+ if (!q || !/[\p{L}\p{N}]/u.test(q)) continue;
192
115
  const k = queryKey(q);
193
116
  if (seen.has(k)) continue;
194
117
  seen.add(k);
@@ -198,6 +121,12 @@ export function meaningAnglesFromMatterContext(md, { alreadyQueried = [], maxAng
198
121
  return picked;
199
122
  }
200
123
 
124
+ /** Whether the matter frame asserted that no meaning question applies: its `Meaning angles:` line reads `none`. PURE. */
125
+ export function meaningAnglesAssertedNone(md) {
126
+ const m = String(md || "").match(MEANING_ANGLES_RE);
127
+ return Boolean(m) && /^none\b/i.test(m[1].trim());
128
+ }
129
+
201
130
  // The PR / reputational / connotation section heading (the only place the gate polices — it must not flag a
202
131
  // clean note that appears in some other section's prose, mirroring use-check's section-scoping).
203
132
  const SECTION_RE = /reputational|connotation/i;
@@ -11,7 +11,7 @@
11
11
  "the baseline tracks named elements, and a rename is a new name. Regenerate rather than work around it.",
12
12
  "Measured 139 of 287 declared elements."
13
13
  ],
14
- "total": 104,
14
+ "total": 105,
15
15
  "byStage": {
16
16
  "matter-frame": [
17
17
  "### Intake asks line shape — rendered by the driver from intake_asks[]",
@@ -22,14 +22,15 @@
22
22
  "Class scope & adjacency — classes scoped IN with a one-line reason each, classes deliberately scoped OUT",
23
23
  "Return shape — hand the frame back through record_matter_frame, write NO file, return ONLY a 2-3 line summary",
24
24
  "Scope reasoning — search-wide/cite-narrow, the in-scope-by-reach routes, and the reopen trigger behind each exclusion",
25
- "search_channels — the domains where real use of THIS matter's goods would show"
25
+ "confusable_forms — the forms a buyer could confuse, searched on the stores",
26
+ "search_channels — the domains where real use of THIS matter's goods would show",
27
+ "set_aside — the profile stores and forms the frame does not search, each with its reason"
26
28
  ],
27
29
  "clearance-variants": [
28
30
  "### Scope ledger rows — {Layer, Item, Status: applied|dropped, Reason, Reopen trigger} across variant / field / source / jurisdiction",
29
31
  "Archetype — primary (one of six) + modifiers + one-line reasoning",
30
32
  "Cross-mark themes — shared elements, shared conceptual themes, shared industry-incumbent alerts (multi-mark requests)",
31
33
  "Distinctiveness & registrability read — spectrum placement per market language, descriptive/generic/laudatory/geographic/deceptive/offensive flags, acquired-distinctiveness note",
32
- "Famous-mark flags per element + famous_mark_calls_needed[]",
33
34
  "Formative root: <root> — the shortest distinctive stem a family of marks would share, on its own line",
34
35
  "Output paths + return shape — write the prose manifest and the structured model to the named absolute paths, return ONLY the path + a 2-3 line summary",
35
36
  "Per-jurisdiction sub-queries",
@@ -41,6 +42,7 @@
41
42
  "Verify? ✅ column on every transliteration row of the prose Variants table",
42
43
  "Watchlist union / client-exclusion / 24-owner cap applied by the model before emitting watchlist_owners[]",
43
44
  "elements[] — {value, kind: distinctive|common|saturated-common}",
45
+ "elements[].famous_mark_flag — the elements Step 2's famous-mark check flags",
44
46
  "incumbent_classes[] — the industry-incumbent alert's Nice classes",
45
47
  "variants[].category — one of core|phonetic|visual|transliteration|numeric|composite|other",
46
48
  "variants[].rationale — one line per variant",
@@ -73,13 +75,12 @@
73
75
  "register-unit": [
74
76
  "`CROSS-CHECK REQUIRED: <what> — <why>` — the check that is needed and why",
75
77
  "`CROSS-CHECK REQUIRED:` exact line shape — prefix, em-dash, mark in CAPS, own line",
76
- "escalation judgement — the CROWD BOUND: attempt each dangerous-category slice once class-scoped, gate on the RESULT, stop terminal on a crowd, and write a block only for the distinctive anchor",
78
+ "escalation judgement — the CROWD BOUND: attempt each dangerous-category slice once class-scoped, gate on the RESULT, decide on a crowd, and write a block only for the distinctive anchor",
77
79
  "final return — the absolute output path plus queries-enumerated count, incomplete-block count, records carried forward",
78
80
  "proposal `romanization` beside a single non-Latin term — plain-ASCII Latin form, space-separated syllables",
79
81
  "proposal class scoping — pass nice_classes:[...] AND in_scope_classes:[...] on every proposal/call",
80
82
  "proposal envelope — predicate enum {exact, default, wildcard, phonetic, owner}, term vs terms, rationale",
81
83
  "reading the band back and judging it — keep proposing until the axis's dangerous named band is covered",
82
- "recall carry-or-justify — for each prior-confirmed conflict, a reasoned drop row written over the fetched record (primary-sweep only)",
83
84
  "supplemental proposals — WHICH queries the manifest/frame warrant beyond the dictated set",
84
85
  "the dictated entry list — qid, predicate, terms, owner, nice_classes, regions, when-guard, expected_kind, covered_by"
85
86
  ],