clearotron 0.2.2 → 0.2.4

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 (161) hide show
  1. package/.env.example +64 -37
  2. package/.nvmrc +1 -1
  3. package/CONTRIBUTING.md +8 -4
  4. package/INSTALL.md +36 -14
  5. package/README.md +18 -22
  6. package/THIRD-PARTY-NOTICES.md +1 -1
  7. package/bin/clearotron.mjs +22 -0
  8. package/bin/example.mjs +10 -5
  9. package/bin/onboard.mjs +370 -28
  10. package/bin/start.mjs +220 -12
  11. package/build-info.json +2 -2
  12. package/demo/README.md +1 -1
  13. package/demo/full-country-search/run/_driver/framework.json +1 -1
  14. package/demo/global-preliminary-search/run/_driver/framework.json +1 -1
  15. package/demo/knockout-search/run/_driver/framework.json +1 -1
  16. package/demo/multi-country-focus-search/run/_driver/framework.json +1 -1
  17. package/docs/E2E.md +5 -5
  18. package/docs/GLOSSARY.md +85 -0
  19. package/docs/PORTAL.md +2 -2
  20. package/docs/README.md +6 -4
  21. package/docs/SECURITY.md +17 -0
  22. package/docs/architecture/01-product-overview.md +21 -9
  23. package/docs/architecture/04-configuration-reference.md +2 -0
  24. package/docs/architecture/05-config-governance.md +19 -0
  25. package/docs/architecture/05-customer-profiles.md +2 -2
  26. package/docs/configuration.md +4 -3
  27. package/docs/decisions/0006-what-the-public-repository-carries.md +30 -5
  28. package/driver/CHANGELOG.md +90 -0
  29. package/driver/README.md +25 -6
  30. package/driver/common-law-receipts.mjs +1 -1
  31. package/driver/config-staleness.mjs +1 -1
  32. package/driver/connotation-search.mjs +1 -1
  33. package/driver/contract-audit.mjs +5 -1
  34. package/driver/contract-e3-baseline.json +11 -11
  35. package/driver/dev-portal.mjs +2 -2
  36. package/driver/doubt-selection.mjs +1 -1
  37. package/driver/drainer-identity.mjs +1 -1
  38. package/driver/driver.config.mjs +1 -1
  39. package/driver/effort-model.mjs +2 -2
  40. package/driver/engine/cli-version.mjs +103 -0
  41. package/driver/engine/probe.mjs +45 -5
  42. package/driver/enqueue-schema.mjs +8 -8
  43. package/driver/feedback-store.mjs +1 -1
  44. package/driver/findings-model.mjs +52 -2
  45. package/driver/flag-snapshot.mjs +20 -0
  46. package/driver/framework.mjs +1 -1
  47. package/driver/gateway.mjs +20 -3
  48. package/driver/outbox-backoff.mjs +1 -1
  49. package/driver/package.json +3 -3
  50. package/driver/party-facts.mjs +2 -2
  51. package/driver/phase0.mjs +1 -1
  52. package/driver/pipeline.mjs +211 -106
  53. package/driver/plain-register.mjs +134 -0
  54. package/driver/portal-access.mjs +1 -1
  55. package/driver/portal-config-view.mjs +70 -2
  56. package/driver/portal-families.mjs +1 -1
  57. package/driver/portal-local-auth.mjs +5 -1
  58. package/driver/portal-report.mjs +1 -1
  59. package/driver/portal-service.mjs +79 -9
  60. package/driver/portal-upstream.mjs +2 -2
  61. package/driver/predelivery-lint.mjs +151 -2
  62. package/driver/profile-page.html +10 -2
  63. package/driver/profile-service.mjs +4 -4
  64. package/driver/profiles/README.md +3 -3
  65. package/driver/profiles.mjs +144 -12
  66. package/driver/publish/index.mjs +2 -2
  67. package/driver/publish/knockout.mjs +7 -1
  68. package/driver/publish/render-knockout.mjs +453 -118
  69. package/driver/publish/render.mjs +111 -16
  70. package/driver/reference-strip-signatures.mjs +20 -0
  71. package/driver/search-policy.mjs +3 -3
  72. package/driver/skills/blind-frame/SKILL.md +1 -1
  73. package/driver/skills/knockout-assess/SKILL.md +84 -0
  74. package/driver/skills/matter-frame/SKILL.md +6 -6
  75. package/driver/skills/matter-frame/watchlist-reference.md +2 -2
  76. package/driver/skills/prelim-common-law/SKILL.md +1 -1
  77. package/driver/skills/prelim-search/SKILL.md +1 -1
  78. package/driver/skills/prelim-search/report-prose.md +82 -0
  79. package/driver/skills/prelim-search/risk-framework-demo.manifest.json +1 -1
  80. package/driver/skills/prelim-search/risk-framework-triage.manifest.json +1 -1
  81. package/driver/skills/prelim-search/risk-framework.manifest.json +1 -1
  82. package/driver/skills/prelim-search/synthesis-rules.md +1 -1
  83. package/driver/skills/prelim-variants/SKILL.md +3 -3
  84. package/driver/stage-context.mjs +13 -0
  85. package/driver/stages.mjs +54 -7
  86. package/driver/suite-census.json +220 -58
  87. package/driver/systemd/clearotron-worker.service +3 -3
  88. package/driver/tokens.mjs +1 -1
  89. package/driver/unit-inventory.mjs +214 -27
  90. package/driver/verify.mjs +1 -1
  91. package/driver/whatif-memo-run.mjs +26 -4
  92. package/driver/whatif-memo.mjs +19 -1
  93. package/examples/README.md +2 -2
  94. package/examples/grants.example.json +6 -7
  95. package/mcp-server/CHANGELOG.md +4 -0
  96. package/mcp-server/lib/scrub.mjs +1 -1
  97. package/mcp-server/lib/whatif.mjs +2 -2
  98. package/mcp-server/package.json +1 -1
  99. package/mcp-server/packs/ops/EXAMPLES.md +2 -2
  100. package/mcp-server/server.mjs +1 -1
  101. package/package.json +31 -19
  102. package/portal-ui/dist/assets/{index-Ct3iQtZ2.css → index-1ziUJX1E.css} +43 -2
  103. package/portal-ui/dist/assets/{index-BUGgiYtF.js → index-KFAHMgdT.js} +289 -73
  104. package/portal-ui/dist/index.html +2 -2
  105. package/portal-ui/package.json +1 -1
  106. package/providers/_shared/term-shape.mjs +1 -1
  107. package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
  108. package/providers/oauth-mcp-bridge/package.json +1 -1
  109. package/providers/uspto-local/src/index-store.js +2 -2
  110. package/scripts/added-reference-check.mjs +45 -89
  111. package/scripts/citation-line-check.mjs +121 -2
  112. package/scripts/e2e.mjs +2 -2
  113. package/scripts/env-classify.mjs +67 -3
  114. package/scripts/generated-files-are-current.mjs +125 -0
  115. package/scripts/live-surface-check.mjs +38 -1
  116. package/scripts/mint-names-in-force.mjs +4 -2
  117. package/scripts/mint-public-residue.mjs +74 -0
  118. package/scripts/mint-reference-strip-backlog.mjs +12 -1
  119. package/scripts/mint-suite-census.mjs +5 -2
  120. package/scripts/nightly-notice.mjs +0 -2
  121. package/scripts/preinstall-node-check.mjs +24 -0
  122. package/scripts/render-check.mjs +13 -2
  123. package/scripts/report-frame-check.mjs +8 -1
  124. package/scripts/report-screenshot.mjs +6 -3
  125. package/scripts/revisit-render-check.mjs +6 -3
  126. package/scripts/score.mjs +1 -1
  127. package/scripts/strip-tracker-citations.mjs +38 -7
  128. package/scripts/test-full.mjs +226 -0
  129. package/scripts/test-run.mjs +16 -0
  130. package/shared/README.md +2 -1
  131. package/shared/anon-overlay.mjs +3 -3
  132. package/shared/browser-temp-root.mjs +142 -0
  133. package/shared/checkout-move.mjs +1 -1
  134. package/shared/client-door.mjs +4 -3
  135. package/shared/customer-store.mjs +1 -1
  136. package/shared/identifier-scan.mjs +1 -1
  137. package/shared/install-auth.mjs +35 -0
  138. package/shared/invocation.mjs +33 -1
  139. package/shared/listen.mjs +55 -3
  140. package/shared/names-in-force.mjs +6 -1
  141. package/shared/node-floor.mjs +97 -0
  142. package/shared/os-advice.mjs +91 -0
  143. package/shared/reap-on-exit.mjs +42 -0
  144. package/shared/reference-guard-classes.mjs +351 -0
  145. package/shared/staff-domain.mjs +154 -0
  146. package/shared/store-in-repo.mjs +23 -2
  147. package/shared/suite-census.mjs +31 -3
  148. package/shared/withheld-paths-access.mjs +36 -18
  149. package/skills/clearotron-ops/SKILL.md +1 -1
  150. package/driver/recipes/README.md +0 -49
  151. package/driver/skills/prelim-search/risk-framework-aurora.manifest.json +0 -19
  152. package/driver/skills/prelim-search/risk-framework-aurora.md +0 -77
  153. package/driver/skills/prelim-search/risk-framework-zephyr.manifest.json +0 -14
  154. package/driver/skills/prelim-search/risk-framework-zephyr.md +0 -33
  155. package/driver/skills/prelim-search/worked-examples-aurora.md +0 -10
  156. package/driver/skills/prelim-search/worked-examples-zephyr.md +0 -10
  157. package/scripts/ai-page-render-check.mjs +0 -532
  158. package/scripts/clearances-render-check.mjs +0 -480
  159. package/scripts/composer-render-check.mjs +0 -1027
  160. package/scripts/home-render-check.mjs +0 -526
  161. package/scripts/portal-lifecycle-check.mjs +0 -639
@@ -8,33 +8,50 @@
8
8
  // private." `shared/withheld-paths.mjs` STAYS BEHIND. The reading where it ships with a rewritten
9
9
  // header is dead and must not be revived.
10
10
  //
11
- // Five files read that record and are wanted on the public tree: `scripts/citation-line-check.mjs`,
12
- // `scripts/mint-suite-census.mjs`, and the arms `no-caveat-repair`,
13
- // `signa-mock-lane-is-unreachable-from-a-run` and `the-providers-suite-is-censused`. A static import of
14
- // a module that is not there throws before anything runs for a test that means its cases VANISH FROM
15
- // THE COUNT rather than failing, which is the 354-to-279 shape already records. This
16
- // module is how they degrade on purpose instead.
11
+ // THREE files read that record, and all three are in this repository:
12
+ // `scripts/citation-line-check.mjs`, `scripts/mint-suite-census.mjs` and
13
+ // `shared/reference-guard-classes.mjs`. A static import of a module that is not there throws before
14
+ // anything runs, and for a test that means its cases VANISH FROM THE COUNT rather than failing. This
15
+ // module is how those three degrade on purpose instead.
16
+ //
17
+ // The list above was wrong in both directions and is corrected here (measured 2026-09-09): it said
18
+ // five, naming three tests that exist in this repository under no path, and it omitted
19
+ // `shared/reference-guard-classes.mjs`, which had already recorded itself as a reader in its own file.
17
20
  //
18
21
  // ── WHY DEGRADING IS SAFE HERE, WHICH IS THE WHOLE ARGUMENT ──────────────────────────────────────
19
22
  //
20
- // Every one of the five asks the record ONE question: is this file absent because it was deliberately
23
+ // Every one of the three asks the record ONE question: is this file absent because it was deliberately
21
24
  // withheld, or absent because something broke? On the public tree nothing was withheld FROM that tree,
22
25
  // so the honest answer is "nothing is withheld" — and each caller then becomes STRICTER, never weaker:
23
26
  //
24
27
  // citation-line-check every file crosses the cut, so every citation must resolve
25
28
  // mint-suite-census no exemption, so a removed test file is a LOSS
26
- // the three arms an absence is damage, never a stated consequence
29
+ // reference-guard-classes nothing is skipped, so the whole tree is counted
30
+ //
31
+ // MEASURED, not argued (2026-09-09): `censusOf` was run twice over one file list. With no record it
32
+ // counted four files and skipped none; with a record naming two of them it counted two and skipped
33
+ // two. Absent, the record cannot hide a defect.
27
34
  //
28
35
  // A fallback that can only tighten is one that cannot hide a defect. That is the property that makes
29
36
  // this safe to do without a flag, and it is the property to re-check before adding a sixth caller: if a
30
37
  // new caller would be LOOSER without the record, it does not belong here.
31
38
  //
32
- // ── AND IT ANNOUNCES, SO IT CANNOT FIRE UNNOTICED WHERE IT MUST NOT ──────────────────────────────
39
+ // ── NO TREE CARRIES THE RECORD TODAY, AND THE MODE LINE SAYS WHICH WAY THAT LEANS ───────────────
40
+ //
41
+ // This block used to say the record exists here and that losing it "would quietly relax five checks".
42
+ // Both halves were false, and the second contradicted the paragraph above it. Measured 2026-09-09:
43
+ // `CUT_RECORD_PRESENT` is false here and false in the larger tree the suite is also run against — the
44
+ // record exists in neither, so every reader has always run in fallback, and fallback is the strict side.
45
+ //
46
+ // The mode is still announced once to stderr, the way `announceBlocklistMode` does for the identifier
47
+ // roster. What the line may NOT do is call itself an alarm: this module can see whether the record is
48
+ // present, and cannot see whether it ought to be. So it states the mode and what that means for the
49
+ // three readers, and leaves the judgement to a reader who knows which tree they are looking at.
33
50
  //
34
- // On our tree the record exists and behaviour is unchanged. If it ever went missing here, the fallback
35
- // would quietly relax five checks the exact silent-pass this repository keeps paying for. So the mode
36
- // is announced once to stderr, the way `announceBlocklistMode` does for the identifier roster, and an
37
- // arm pins that the announcement happens.
51
+ // NOTHING PINS THIS ANNOUNCEMENT, and this block used to claim something did. Measured 2026-09-09: no
52
+ // test in either repository imports `announceWithheldMode` or asserts its line, so the wording above is
53
+ // held by nothing and a silent removal of it would pass. That gap is filed rather than fixed here,
54
+ // because closing it adds a test file and this change is comment text only.
38
55
 
39
56
  let record = null;
40
57
  try {
@@ -59,15 +76,16 @@ export const isWithheld = (relPath) => (record ? record.isWithheld(relPath) : fa
59
76
 
60
77
  let announced = false;
61
78
  /**
62
- * Say which mode this process is in, once, to stderr. A green run in fallback mode on a tree that
63
- * SHOULD carry the record is five checks quietly relaxed, and the only thing standing between that and
64
- * silence is this line.
79
+ * Say which mode this process is in, once, to stderr. Fallback is the strict side, so this line is a
80
+ * statement of fact rather than a warning: it reports what the three readers will do, and whether that
81
+ * is right depends on the tree, which this module cannot see.
65
82
  */
66
83
  export function announceWithheldMode() {
67
84
  const line = CUT_RECORD_PRESENT
68
85
  ? `[repo-guard] cut record present — ${WITHHELD.length} withheld entry/entries; absences they cover are stated consequences`
69
- : "[repo-guard] NO cut record in this tree — nothing counts as withheld, so every absence is damage "
70
- + "and every citation must resolve. This is correct on the published tree and an ALARM anywhere else.";
86
+ : "[repo-guard] no cut record in this tree — nothing counts as withheld, so every absence is damage "
87
+ + "and every citation must resolve. This is the STRICTER of the two modes: it cannot hide a defect, "
88
+ + "and it is the expected mode wherever nothing was withheld from the tree in hand.";
71
89
  if (!announced) { announced = true; console.error(line); }
72
90
  return line;
73
91
  }
@@ -41,7 +41,7 @@ Extract from the request, faithfully (verbatim beats paraphrase):
41
41
  - **`forwarder`** (+ `forwarderEmail`) — the requester/reply route. REQUIRED, no default: this is
42
42
  where the report goes; a wrong route misdelivers a confidential document.
43
43
  - **`profileKey`** — call **`list_profiles`** and resolve by JUDGMENT: an explicit name, a
44
- misspelling ("Zefyr" zephyr), or an implicit reference ("our functional-beverage client") all
44
+ misspelling (a name typed as it sounds), or an implicit reference ("our functional-beverage client") all
45
45
  map to a key. OMIT it for a new/unknown customer (the neutral generic profile applies — this is
46
46
  non-blocking by design). Ask the requester only when you genuinely cannot tell. **Never pick a
47
47
  profile from the sender's email domain.**
@@ -1,49 +0,0 @@
1
- # Saved searches ("recipes")
2
-
3
- One subdirectory per customer — `aurora/` and `zephyr/` — each holding one JSON file per saved search at
4
- `<customer>/<slug>.json`; the loader walks directories only, so nothing else here is a store. A recipe is a
5
- small named bundle: a base product, optional component toggles, an optional `scope` block (where the
6
- machinery points: `jurisdictions`, `platforms`, `classes`), and instruction-shaped `extras`.
7
- The display field is `label`, deliberately not `name` — `name` is a profile key, and the two key sets are
8
- disjoint by design, so a saved search can never carry rating config.
9
-
10
- ## What reads it
11
-
12
- `loadRecipes()` in `../search-policy.mjs` walks `<dir>/<customer>/<slug>.json` into a
13
- `Map("customer/slug" → recipe)`, validating each file with `validateRecipe` — the same validator the write
14
- door uses, so the UI cannot persist a recipe the driver would later reject. `resolveSearchPolicy` then
15
- turns a job's `recipeKey` into the product, components, extras and scope the run uses; a recipe only runs
16
- for its own customer, and an `archived` one refuses with a clarify.
17
-
18
- The write side is `../recipe-service.mjs` (loopback, CF Access JWT, git auto-commit as the verified
19
- identity). The portal mounts those routes through `../portal-upstream.mjs`, which rebuilds the customer
20
- path segment from the resolved account; `../dev-portal.mjs` proxies `/recipes/*` for dev.
21
-
22
- **The store is named, never guessed.** `CLEAROTRON_RECIPES_DIR` unset means the deployment has no saved
23
- searches — not that it falls back to this directory. That fallback existed and was removed: production is
24
- exactly where the variable is unset, so it would have surfaced invented customers inside the product.
25
-
26
- ## These are synthetic demos
27
-
28
- `aurora` and `zephyr` are fictional customers (`../profiles/aurora.json`, `../profiles/zephyr.json`) that
29
- exist so the dev cockpit and the test suite have something to render. A real deployment's recipes live
30
- outside the repo, in the customer-config store beside the profiles — no client data in git.
31
-
32
- | File | Base product, and any extras it carries |
33
- |---|---|
34
- | `aurora/quarterly-screen.json` | `knockout-search`, `extras.emailTable` |
35
- | `aurora/screen-with-register-counts.json` | `knockout-search` |
36
- | `zephyr/standard-clearance.json` | `multi-country-focus-search`, `extras.standingInstructions` + `extras.defaultDeadlineDays` |
37
-
38
- Two of them carry settings the product no longer offers, which is not an oversight: `emailTable` is inert
39
- but still validated so recipes written while it worked keep loading, and `defaultDeadlineDays` is a retired
40
- extra that `loadRecipes` drops on read and `validateRecipe` refuses on save. A stored recipe must not brick
41
- on a change it never asked for.
42
-
43
- ## Where to start
44
-
45
- `zephyr/standard-clearance.json` — twelve lines, and the one whose `extras` show both what an
46
- instruction-shaped setting looks like (`standingInstructions`) and what a retired one looks like still
47
- sitting in a stored file. Then the recipe block in `../search-policy.mjs` (`RECIPE_KEYS`,
48
- `RECIPE_SCOPE_KEYS`, `RECIPE_EXTRA_KEYS`, `validateRecipe`), which is where every rule above is enforced
49
- and commented.
@@ -1,19 +0,0 @@
1
- {
2
- "schema_version": 1,
3
- "framework_key": "aurora",
4
- "title": "Aurora Interactive risk framework (synthetic demo)",
5
- "source_deck": "Synthetic demo transposition of a customer risk deck (structure faithful, content invented), doc 50 shape",
6
- "entity_label": "Aurora Interactive",
7
- "bands": [
8
- { "label": "Very High", "tone": "severe" },
9
- { "label": "High", "tone": "high" },
10
- { "label": "Medium", "tone": "medium" },
11
- { "label": "Manageable", "tone": "low" },
12
- { "label": "Low", "tone": "minimal" }
13
- ],
14
- "structure": {
15
- "kind": "matrix",
16
- "axes": ["Legal Risk Level (A–E)", "Dispute Type"],
17
- "display_note": "The band is read off this framework's Level × Dispute Type matrix; the matrix ceilings are stated in the deck and honoured as written."
18
- }
19
- }
@@ -1,77 +0,0 @@
1
- # Risk framework — Aurora Interactive (SYNTHETIC demo customer)
2
-
3
- - **Applies to:** Aurora Interactive matters (`profileKey: aurora`).
4
- - **Source:** house-authored demonstration framework. Matrix-shaped, to exercise the two-input path.
5
- - **Bands, highest to lowest:** Very High · High · **Medium** · Manageable · **Low** (this framework, unlike the house default, has a Low band — its Level A output).
6
- - **Entity in prose:** **Aurora Interactive** (name the company; acquired studios are self-exclusions, not the entity).
7
- - **Customer emphasis:** defensibility-first and conservative — lead with a clear go / no-go and the practical "would they actually enforce" read; surface an alternative-name track early on a headline conflict.
8
-
9
- *A rubric to be reasoned with — not paraphrased away and not reduced to a lookup.* This framework RATES Aurora Interactive matters (doc 50). It is **matrix-shaped**: reason the two inputs below in order — the Legal Risk Level, then the Dispute Type — and read the band off the matrix. **State the rating as the band word** (Very High / High / Medium / Manageable / Low); the numerals beside the bands are internal indices, never the output. The engine applies this framework on an advisory basis; the senior lawyer makes the final determination. The firm-wide reasoning discipline — the consumer-confusion gate, the dominant-element rule, crowded-field handling, G&S discipline — lives in [`synthesis-rules.md`](synthesis-rules.md) and applies under every framework; Aurora calibration examples live in [`worked-examples-aurora.md`](worked-examples-aurora.md).
10
-
11
- ## Legal Risk Levels (probability adverse party prevails)
12
-
13
- | Level | Probability | Description |
14
- |-------|------------|-------------|
15
- | **A** | 0–24% | Weak claim, negligible risk, strong defences available |
16
- | **B** | 25–49% | Some credible claims but more likely to prevail; manageable |
17
- | **C** | 51–60% | Better than even chance of adverse outcome; material risk, may need settlement |
18
- | **D** | 61–74% | Likely adverse outcome; some credible defences but unsuccessful result expected |
19
- | **E** | 75%+ | Strong claim / slam dunk against us; no or only weak defences |
20
-
21
- > **The letter follows the words (consistency rule — apply to every rated finding).** State the likelihood of confusion in plain words *first* — "more likely than not they'd win", "better-than-even is not reached", "confusion is unlikely", "distinguishable as wholes" — **then pick the letter those words require**: better-than-even reached → **C–E**; not reached → **A or B** (B = 25–49%, "credible claim but we have the better of it"). The prose read and the A–E letter are **one judgment and may not disagree.**
22
-
23
- ## Dispute Types
24
-
25
- | Type | Characteristics |
26
- |------|----------------|
27
- | **Classic** | Actual confusion anticipated, well-known/famous mark, aggressive brand owner, direct industry competitor |
28
- | **Horse Trade** | Market overlap, settlement likely with payment or use restrictions |
29
- | **Paper Conflict** | Material register risk but no obvious market overlap in practice |
30
- | **Descriptive Terms** | Descriptiveness defence available, or extensive unregistered use weakens distinctiveness |
31
- | **Nuisance Claim** | Weak claim but party may still complain (trolls, squatters, speculative filings) |
32
-
33
- ## The band matrix — reason the two inputs, then read the band off the matrix
34
-
35
- The band is **derived from two reasoned inputs, in this order — it is not chosen freely, and no practical /
36
- optics factor moves the band directly:**
37
-
38
- 1. **Legal Risk Level (A–E) — first.** Answers one question: *"if this third party sued Aurora Interactive,
39
- would they win?"* Set it from the likelihood-of-confusion comparison (marks-as-wholes × goods/services; see
40
- `synthesis-rules.md` → *The consumer confusion test*), net of merits defences. (50% is not allowed — take a
41
- view.) Applies to registered AND common-law rights.
42
- 2. **Dispute Type — second.** Classic / Horse Trade / Paper Conflict / Descriptive (or extensive-use) / Nuisance.
43
-
44
- Then read the **band off the matrix** — this is the *output*; you do not adjust it afterwards:
45
-
46
- | Band | Requires |
47
- |---|---|
48
- | **Very High** *(5)* | Level **D or E** AND **Classic** |
49
- | **High** *(4)* | Level **D or E** AND (**Horse Trade** or **Nuisance**) |
50
- | **Medium** *(3)* | Level **C / D / E** AND (**Paper** or **Descriptive**) — OR — Level **C** AND (**Horse Trade** / **Classic** / **Nuisance**) |
51
- | **Manageable** *(2)* | Level **B** (routinely accepted; still alert on a troll/squatter, a known competitor / major brand owner, or heavy clean-up cost) |
52
- | **Low** *(1)* | Level **A** |
53
-
54
- **The ceilings are hard — and they ARE this framework's anti-escalation mechanism:**
55
- - **High and Very High REQUIRE Legal Level D or E.** A **Level-C finding tops out at Medium**, whatever the
56
- dispute type or the practical factors. **Level A → Low and Level B → Manageable are fixed.**
57
- - **Elevate / mitigate considerations move the INPUTS — the Legal Level or the Dispute Type — never the output
58
- band** (the factor lists live in `synthesis-rules.md`). A "confirmed aggressive enforcer", owner size, PR
59
- sensitivity, or an Aurora Interactive partnership cannot lift a finding past its level's ceiling: they only
60
- change *whether they'd win* (the Level) or the *character* of the dispute (the Type), and the matrix then
61
- produces the band. This is exactly the optics-escalation error the ceilings prevent — a Level-C read does NOT
62
- become High because the owner enforces aggressively; a house-mark-distinguished Level-B mark does NOT become
63
- Very High because the owner is large or a partner.
64
-
65
- **Calibration anchors (structure-faithful; the mark names are invented, the anchor companies are real and named only as public examples of scale):** VELARIS / POLARIS-class famous-mark conflicts = Level
66
- **E** + **Classic** = **Very High**; TerraForge / TerraFlex = Level **E** + **Horse Trade** = **High**;
67
- Northgate / NorthData = Level **D** + **Horse Trade** = **High**.
68
-
69
- ## Band meanings
70
-
71
- | Band | Meaning | Typical Response |
72
- |-------|---------|-----------------|
73
- | **Very High** | Generally not accepted | Run alternative name in parallel |
74
- | **High** | May accept with strong mitigation | Requires active risk management plan |
75
- | **Medium** | May accept with settlement/clean-up plan | Proceed with awareness and contingency |
76
- | **Manageable** | Routinely accepted | Note and monitor |
77
- | **Low** | Target outcome | Proceed with confidence |
@@ -1,14 +0,0 @@
1
- {
2
- "schema_version": 1,
3
- "framework_key": "zephyr",
4
- "title": "Zephyr Beverages risk framework (synthetic demo)",
5
- "source_deck": "Synthetic demo transposition of a customer risk deck (structure faithful, content invented), doc 50 shape",
6
- "entity_label": "Zephyr/Volt/Kaskade",
7
- "bands": [
8
- { "label": "Very High", "tone": "severe" },
9
- { "label": "High", "tone": "high" },
10
- { "label": "Medium", "tone": "medium" },
11
- { "label": "Manageable", "tone": "low" }
12
- ],
13
- "structure": { "kind": "bands" }
14
- }
@@ -1,33 +0,0 @@
1
- # Risk framework — Zephyr Beverages (SYNTHETIC demo customer)
2
-
3
- - **Applies to:** Zephyr matters (`profileKey: zephyr`).
4
- - **Source:** house-authored demonstration framework. The house default with a different entity family and one band relabelled.
5
- - **Bands, highest to lowest:** Very High · High · **Medium** · Manageable. There is no "Low"; Manageable is the lowest band.
6
- - **Entity in prose:** **Zephyr/Volt/Kaskade** — name the brand family, not "the company".
7
- - **Customer emphasis:** pragmatic and launch-oriented — a clear go / no-go and the facts that condition each real blocker, rather than exhaustive caveats. (Express this emphasis in the product voice: facts that condition, never a recommended "path" — retired voice, 2026-07-28.)
8
-
9
- *This is the house default with exactly two differences: the entity family, and band 3 is labelled **Medium** (not "Moderate"). A rubric to be reasoned with, not paraphrased.* This framework RATES the matter (doc 50): reason each conflict through the band definitions below — Legal position first, then Practical position, then Potential outcomes — and the band follows the words. A conflict Zephyr/Volt/Kaskade clearly wins with no material risk is **not a rated conflict** (there is no "Low" band; see `synthesis-rules.md`). The engine applies this framework on an advisory basis; the senior lawyer makes the final determination. The firm-wide reasoning discipline lives in [`synthesis-rules.md`](synthesis-rules.md) and applies under every framework; Zephyr calibration examples live in [`worked-examples-zephyr.md`](worked-examples-zephyr.md).
10
-
11
- ## VERY HIGH RISK
12
-
13
- - **Legal position.** Prior rights owner is **very likely to win** and there are **no** credible defences or risk-mitigation strategies available to **Zephyr/Volt/Kaskade**.
14
- - **Practical position (one or more).** There is an obvious market overlap or risk of actual confusion — coexistence does not appear possible, even with payment of money, use restrictions or other exchange; **or** the prior mark is famous, owned by a known aggressor, or an industry competitor.
15
- - **Potential outcomes.** Name change likely required, possibly on an urgent basis · monetary exposure **more than $10 million** · severe PR consequences · highly unlikely to mitigate risk irrespective of time and money.
16
-
17
- ## HIGH RISK
18
-
19
- - **Legal position.** Prior rights owner is **likely to win**, although some credible defences are available to **Zephyr/Volt/Kaskade**.
20
- - **Practical position.** There is possible market overlap, but co-existence appears possible with settlement involving payment of money, use restrictions, and/or other exchange.
21
- - **Potential outcomes.** Name change may be required, possibly on an urgent basis · high business disruption possible · monetary exposure **up to $10 million** · PR consequences · cleanup or mitigation may be possible depending on time and budget.
22
-
23
- ## MEDIUM RISK
24
-
25
- - **Legal position.** Prior rights owner is **more likely than not to win**, although reasonable defences or risk-mitigation steps are available to **Zephyr/Volt/Kaskade**.
26
- - **Practical position (one or more).** There is no obvious market overlap; **or** risk-mitigation strategies are available to Zephyr/Volt/Kaskade (e.g. the prior mark is arguably weak or vulnerable to attack); **or** there are practical factors which suggest the prior rights owner may not object (e.g. settlement discussions are underway).
27
- - **Potential outcomes.** Name change may be required, possibly on an urgent basis · business disruption possible · monetary exposure **$5 to 7 figures** · PR consequences possible · cleanup or mitigation may be possible depending on time and budget.
28
-
29
- ## MANAGEABLE RISK *(lowest band)*
30
-
31
- - **Legal position.** **Zephyr/Volt/Kaskade** is **more likely than not to win**, although there is still material risk and uncertainty.
32
- - **Practical position.** This level of risk includes nuisance claims, strategic (but weak) complaints by a competitor, and registration obstacles.
33
- - **Potential outcomes.** Budget potentially required for prosecution hurdles and nuisance claims.
@@ -1,10 +0,0 @@
1
- # Example per-customer worked examples — aurora (synthetic)
2
-
3
- Synthetic placeholder demonstrating a profile's `workedExamplesPath` hook. Real per-customer worked
4
- examples are a customer-config-store artifact, not repo code.
5
-
6
- **Convention (P6):** a per-customer file ADDS CALIBRATION and never replaces the voice. The before/after
7
- voice pairs live in [`worked-examples.md`](worked-examples.md) → *Voice — worked before / after pairs*, and
8
- a customer artifact that omits them leaves this customer's runs without the examples the house voice is
9
- learned from. The house prose contract itself is carried unconditionally by the stage message, so the RULES
10
- reach every run regardless of profile — it is the worked pairs that a replacement file can silently drop.
@@ -1,10 +0,0 @@
1
- # Example per-customer worked examples — zephyr (synthetic)
2
-
3
- Synthetic placeholder demonstrating a profile's `workedExamplesPath` hook. Real per-customer worked
4
- examples are a customer-config-store artifact, not repo code.
5
-
6
- **Convention (P6):** a per-customer file ADDS CALIBRATION and never replaces the voice. The before/after
7
- voice pairs live in [`worked-examples.md`](worked-examples.md) → *Voice — worked before / after pairs*, and
8
- a customer artifact that omits them leaves this customer's runs without the examples the house voice is
9
- learned from. The house prose contract itself is carried unconditionally by the stage message, so the RULES
10
- reach every run regardless of profile — it is the worked pairs that a replacement file can silently drop.