clearotron 0.3.3 → 0.4.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +9 -0
- package/INSTALL.md +1 -14
- package/bin/brandowner.mjs +5 -5
- package/bin/connect.mjs +4 -4
- package/bin/onboard.mjs +5 -7
- package/bin/start.mjs +20 -5
- package/bin/update.mjs +6 -1
- package/build-info.json +2 -2
- package/docs/architecture/04-configuration-reference.md +2 -6
- package/driver/CHANGELOG.md +28 -0
- package/driver/ask-ledger.mjs +2 -2
- package/driver/band-shape.mjs +8 -8
- package/driver/blind-frame-model.mjs +1 -1
- package/driver/common-law-receipts.mjs +2 -2
- package/driver/commonlaw-carry.mjs +2 -2
- package/driver/company-bundle.mjs +11 -18
- package/driver/connotation-search.mjs +4 -4
- package/driver/contract-e3-backlog.mjs +3 -3
- package/driver/declination-call.mjs +1 -1
- package/driver/declination-tool.mjs +1 -1
- package/driver/dev-portal.mjs +1 -1
- package/driver/door-call-verdict.mjs +27 -0
- package/driver/driver.config.mjs +17 -11
- package/driver/e2e/README.md +1 -1
- package/driver/engine/mcp/clarivate-server.mjs +2 -1
- package/driver/engine/mcp/corsearch-server.mjs +1 -0
- package/driver/engine/mcp/euipo-server.mjs +1 -0
- package/driver/engine/mcp/free-tier-server.mjs +1 -1
- package/driver/engine/mcp/gather-config.mjs +1 -1
- package/driver/engine/mcp/perplexity-server.mjs +1 -1
- package/driver/engine/mcp/recording-server.mjs +1 -1
- package/driver/engine/mcp/signa-server.mjs +1 -0
- package/driver/engine/mcp/supplemental.mjs +1 -1
- package/driver/engine/mcp/uspto-local-server.mjs +1 -0
- package/driver/enqueue-schema.mjs +2 -2
- package/driver/feedback-issues.mjs +1 -1
- package/driver/feedback-store.mjs +1 -1
- package/driver/findings-model.mjs +3 -3
- package/driver/flag-snapshot.mjs +1 -1
- package/driver/floor-duty.mjs +2 -2
- package/driver/form-neighbourhood.mjs +47 -15
- package/driver/frame-diff-model.mjs +3 -3
- package/driver/gateway.mjs +5 -5
- package/driver/jx-lanes.mjs +1 -1
- package/driver/known-conflicts.mjs +18 -0
- package/driver/log.mjs +2 -2
- package/driver/package.json +1 -1
- package/driver/pipeline-knockout.mjs +129 -95
- package/driver/pipeline.mjs +69 -32
- package/driver/placement-carry.mjs +2 -2
- package/driver/placement-form.mjs +1 -1
- package/driver/portal-mcp-client.mjs +1 -1
- package/driver/portal-request-origin.mjs +79 -0
- package/driver/portal-service.mjs +45 -17
- package/driver/predelivery-lint.mjs +10 -10
- package/driver/profile-page.html +9 -13
- package/driver/profile-service.mjs +25 -13
- package/driver/profiles.mjs +17 -4
- package/driver/progress.mjs +1 -1
- package/driver/provider-usage.mjs +24 -1
- package/driver/publish/index.mjs +17 -5
- package/driver/publish/knockout.mjs +3 -2
- package/driver/publish/render-knockout.mjs +1 -1
- package/driver/publish/render.mjs +14 -3
- package/driver/publish/search-depth.mjs +4 -2
- package/driver/recall-reconciliation.mjs +1 -1
- package/driver/record-carry.mjs +6 -6
- package/driver/recording-agreement.mjs +2 -2
- package/driver/reference-score.mjs +27 -27
- package/driver/register-count.mjs +56 -1
- package/driver/register-digest-record.mjs +1 -1
- package/driver/register-plan.mjs +5 -5
- package/driver/register-records.mjs +10 -1
- package/driver/registry-fidelity.mjs +4 -4
- package/driver/repair-composers.mjs +6 -6
- package/driver/run-economics.mjs +8 -19
- package/driver/screen-gate.mjs +1 -1
- package/driver/skills/blind-frame/SKILL.md +2 -2
- package/driver/skills/clearance-common-law/SKILL.md +2 -2
- package/driver/skills/clearance-common-law/perplexity-prompts.md +4 -4
- package/driver/skills/clearance-register/digest.md +1 -1
- package/driver/skills/clearance-register/unit.md +1 -1
- package/driver/skills/clearance-search/report-prose.md +5 -5
- package/driver/skills/clearance-search/synthesis-rules.md +4 -4
- package/driver/skills/clearance-variants/SKILL.md +2 -2
- package/driver/skills/clearance-variants/transliteration-scripts.md +1 -1
- package/driver/skills/frame-diff/SKILL.md +2 -2
- package/driver/skills/knockout-assess/SKILL.md +9 -9
- package/driver/skills/matter-frame/watchlist-reference.md +1 -1
- package/driver/skills/narrative-refutation/SKILL.md +2 -2
- package/driver/skills/placement-inquiry/SKILL.md +1 -1
- package/driver/stage-context.mjs +4 -4
- package/driver/stages.mjs +23 -15
- package/driver/suite-census.json +138 -42
- package/driver/systemd/clearotron-client-mcp.service +24 -0
- package/driver/systemd/clearotron-mcp-face.service +24 -0
- package/driver/systemd/clearotron-portal.service +24 -0
- package/driver/systemd/clearotron-worker.service +24 -0
- package/driver/tokens.mjs +26 -17
- package/driver/turnaround-bands.mjs +1 -1
- package/driver/unit-inventory.mjs +3 -3
- package/driver/variant-manifest-model.mjs +1 -1
- package/driver/verify.mjs +2 -2
- package/driver/whatif-memo-run.mjs +1 -1
- package/mcp-server/CHANGELOG.md +8 -0
- package/mcp-server/lib/audit.mjs +9 -2
- package/mcp-server/lib/http-handler.mjs +7 -3
- package/mcp-server/mint-token.mjs +8 -6
- package/mcp-server/package.json +1 -1
- package/mcp-server/server.mjs +11 -1
- package/package.json +1 -1
- package/portal-ui/dist/assets/{index-GBbbyQxc.js → index-D_O_55vK.js} +59 -9
- package/portal-ui/dist/index.html +1 -1
- package/portal-ui/package.json +1 -1
- package/providers/_shared/README.md +1 -1
- package/providers/_shared/answer-memory.mjs +199 -0
- package/providers/_shared/ledger-path.mjs +1 -1
- package/providers/_shared/ledger.mjs +47 -5
- package/providers/_shared/script-form.mjs +24 -5
- package/providers/_shared/term-shape.mjs +5 -5
- package/providers/clarivate/src/capabilities.js +11 -0
- package/providers/clarivate/src/core.js +140 -13
- package/providers/jx-subclass/lookup.mjs +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +8 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/signa/src/capabilities.js +24 -0
- package/providers/signa/src/core.js +66 -0
- package/scripts/deprecate-below.mjs +114 -2
- package/scripts/freeze-example-run.mjs +1 -1
- package/scripts/live-surface-check.mjs +11 -2
- package/scripts/release-entry-catch-up.mjs +211 -0
- package/scripts/release-note-required.mjs +102 -6
- package/scripts/release-rehearsal-version.mjs +60 -0
- package/scripts/release-sbom.mjs +104 -0
- package/scripts/release-visible-check.mjs +7 -5
- package/scripts/score.mjs +3 -3
- package/shared/brand.mjs +1 -1
- package/shared/client-door.mjs +15 -8
- package/shared/driver-dir.mjs +20 -9
- package/shared/names-in-force.mjs +2 -0
- package/shared/scope.mjs +25 -10
- package/shared/store-in-repo.mjs +38 -17
package/driver/run-economics.mjs
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// ── WHAT A "DISPATCH" IS ──────────────────────────────────────────────────────────────────────────
|
|
17
17
|
// One model invocation: one row in `_driver/<stage>.jsonl` that tokens.mjs's `isAttemptRow` counts as
|
|
18
18
|
// a provider attempt (gateway.mjs writes one per ATTEMPT, so retries are separate dispatches and retry
|
|
19
|
-
// waste is counted, not averaged away). The
|
|
19
|
+
// waste is counted, not averaged away). The native-language jx lanes do not go through the gateway and write
|
|
20
20
|
// `_driver/jx-completions.jsonl` in the same {model, usage} shape; they are dispatches too, under stage
|
|
21
21
|
// `jx-completions`. `run.jsonl` is skipped (run events, not dispatches) — same file selection as
|
|
22
22
|
// tokens.mjs, deliberately, and the SAME ROW TEST as tokens.mjs, imported rather than copied: a jx row
|
|
@@ -106,7 +106,7 @@ import { runLog, note } from "./log.mjs";
|
|
|
106
106
|
import { writeRunStatus } from "./progress.mjs";
|
|
107
107
|
// tokens.mjs imports this module too (isCodeSide, stampRunEconomics). The cycle is safe because each side
|
|
108
108
|
// reads the other's bindings only inside functions, never while the module is loading.
|
|
109
|
-
import { isAttemptRow } from "./tokens.mjs";
|
|
109
|
+
import { isAttemptRow, modelKey } from "./tokens.mjs";
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
112
|
* The provider's separately-priced token kinds, in the driver's own `usage` vocabulary (gateway.mjs /
|
|
@@ -185,23 +185,12 @@ function billingKeyOf(rec) {
|
|
|
185
185
|
// is rather than dragged into "unknown" beside genuinely unstamped legacy rows.
|
|
186
186
|
const engine = isCodeSide(rec) ? "code" : String(rec.engine ?? "unknown");
|
|
187
187
|
const authMode = isCodeSide(rec) ? "not-provider-billed" : String(rec.authMode ?? "unknown");
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
// model
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
// is modelKey's own, a non-empty string `modelUsed`, and not `modelUsed == null`: under that looser test
|
|
195
|
-
// a row stamped `modelUsed: ""` keyed its bucket as the empty string while the rollup keyed the same
|
|
196
|
-
// turn `<engine>/no-model-reported`. Two copies of one rule drifting apart is how the census and the
|
|
197
|
-
// rollup came to disagree about what an attempt is, so the tests hold these two copies to each other on
|
|
198
|
-
// the rows the engine writes. They still part on a row no writer produces: no model and no engine, or
|
|
199
|
-
// engine `anthropic-agent`. This key names the missing model there, while modelKey resolves the absent
|
|
200
|
-
// model through the catalog before it asks whether one exists, and buckets the row as `undefined`.
|
|
201
|
-
const stamped = typeof rec.modelUsed === "string" && rec.modelUsed;
|
|
202
|
-
const model = !stamped && typeof rec.model !== "string"
|
|
203
|
-
? `${typeof rec.engine === "string" && rec.engine ? rec.engine : "unknown"}/no-model-reported`
|
|
204
|
-
: String(rec.modelUsed ?? rec.model ?? "unknown");
|
|
188
|
+
// THE MODEL IS NAMED BY THE TOKEN ROLLUP'S OWN RULE (modelKey in tokens.mjs), not a copy of it. A copy
|
|
189
|
+
// lived here while tokens.mjs did not export the rule, and the two drifted: a native-language turn that
|
|
190
|
+
// named its model was billed under the raw served id while the rollup keyed it `anthropic/unstamped:<id>`,
|
|
191
|
+
// so one turn had two names in the same run's figures. A code-side row comes back as its own name
|
|
192
|
+
// (`code:<step>`), which says no model ran.
|
|
193
|
+
const model = modelKey(rec);
|
|
205
194
|
return { engine, authMode, model, key: `${engine}|${authMode}|${model}` };
|
|
206
195
|
}
|
|
207
196
|
|
package/driver/screen-gate.mjs
CHANGED
|
@@ -65,7 +65,7 @@ const SURFACE_VERDICTS = new Set(["surface:in-scope-live", "surface:all-class"])
|
|
|
65
65
|
// "This cell references a SPECIFIC record" — wider than URI_RE on the jurisdiction segment (2-6 chars, so
|
|
66
66
|
// /mark/int/, /mark/uss/ and /mark/wipo/ all read as references) but still strict about the identifier:
|
|
67
67
|
// it must start alphanumeric. That excludes the glob forms digests write when they summarize a slice
|
|
68
|
-
// ("URI cluster /mark/es/*, /mark/eu/*", "URIs across /mark/*
|
|
68
|
+
// ("URI cluster /mark/es/*, /mark/eu/*", "URIs across /mark/* ZILEMA set") — those name no record and are
|
|
69
69
|
// exactly the unnamed dismissals this gate exists to refuse, so they must NOT be excused as parse gaps.
|
|
70
70
|
// Its only job is to tell an unnamed drop apart from a record URI_RE cannot read (see the header note).
|
|
71
71
|
// Non-global: `test()` against a /g regex advances lastIndex between calls and alternates true/false.
|
|
@@ -26,9 +26,9 @@ Work each layer from the actual product the instruction describes — not from c
|
|
|
26
26
|
Decompose the mark into its element(s) and name the **dominant element** (the spine the analysis will turn on). Then enumerate the neighbours that a searcher must not miss, in **both directions**:
|
|
27
27
|
|
|
28
28
|
- **Drop** characters: shorten the element (VELTRIN → VELTRI). A dropped letter is the commonest missed-cluster cause — the shorter root is its own crowded field.
|
|
29
|
-
- **Add** characters / **composite**: the element living inside a larger mark (
|
|
29
|
+
- **Add** characters / **composite**: the element living inside a larger mark (VELTRI Diagnostics, Halver Veltri, Veltric). A composite that shares your dominant element is on the board.
|
|
30
30
|
- **Phonetic / homophone**: sound-alikes (PHAROLIS / FAROLIS / PHAROLLIS). Carry the `ph`/`f` pair in particular: it sounds identical, files under a different letter, and survives no letter-distance measure — which is the whole reason this class is separate from the two above.
|
|
31
|
-
- **Neighbour**: a one-keystroke real-word or famous-mark neighbour (
|
|
31
|
+
- **Neighbour**: a one-keystroke real-word or famous-mark neighbour (KODAK on a CODAK clearance). A famous neighbour is carried for diligence even when off-field.
|
|
32
32
|
|
|
33
33
|
For each, give the value, the direction, and one line of rationale.
|
|
34
34
|
|
|
@@ -178,12 +178,12 @@ For game-title rows, the `developer_of_record` and `publisher_of_record` columns
|
|
|
178
178
|
### PR / reputational risk
|
|
179
179
|
|
|
180
180
|
Covers the core element(s) **and their plausible near-forms** (the connotation hazard often rides a
|
|
181
|
-
near-form — `
|
|
181
|
+
near-form — `mara` ("crowd") → `Mara` = a gang name — not the literal mark). `(None identified)` may be written
|
|
182
182
|
**only when the searched social/subcultural web came back empty** — never on a dictionary gloss. "It just
|
|
183
183
|
means *southern*" is context, not a clearance: a connotation reads clean only when Urban-Dictionary / Wikipedia
|
|
184
184
|
/ news / forums were searched (on the near-forms too) and surfaced nothing.
|
|
185
185
|
|
|
186
|
-
**Surface what the meaning search actually returned — a receipt is not a read.** Even when your call is clean, do **not** collapse the meaning sweep to a bare `(None identified)`: for the mark **and each near-form**, name the actual readings the search surfaced and label each benign or loaded (e.g. `
|
|
186
|
+
**Surface what the meaning search actually returned — a receipt is not a read.** Even when your call is clean, do **not** collapse the meaning sweep to a bare `(None identified)`: for the mark **and each near-form**, name the actual readings the search surfaced and label each benign or loaded (e.g. `mara → "crowd" (colloquial, benign); Mara → a Central American street gang (loaded)`). You are an extraction worker — lay out what the social/subcultural web actually returned per form; you do **not** make the final clearance call. The strong synthesis layer reads that material and decides whether a loaded secondary reading needs pulling. A row that only says "searched, nothing found" hands synthesis a verdict instead of the evidence it needs to look past the obvious gloss.
|
|
187
187
|
|
|
188
188
|
| Finding | Source | Notes |
|
|
189
189
|
|---|---|---|
|
|
@@ -69,13 +69,13 @@ competitor_intel / crowded_field extras are RETIRED: nothing ever read them):
|
|
|
69
69
|
- pr_risk: search offensive / subcultural / controversial associations on BOTH (a) each core element AND
|
|
70
70
|
(b) its plausible NEAR-FORMS — the edit-1 / transliteration / homophone forms from `form-neighbourhood.json`
|
|
71
71
|
(`elements[].band.exactQueries` + `.transliterations`) that read as a real word, name, or plausible term in
|
|
72
|
-
any in-scope market language (e.g. `
|
|
72
|
+
any in-scope market language (e.g. `VELANO` → `veleno`). A near-form that is a real word/term in a market is
|
|
73
73
|
a connotation candidate — search it; never pre-drop one as "unlikely" (connotation is not mechanically
|
|
74
74
|
enumerable, so you search the candidates, you do not filter them). Per term run TWO queries: "[TERM]
|
|
75
75
|
controversy offensive association" AND "[TERM] meaning slang". **Weight subcultural / social / community web
|
|
76
|
-
— Urban Dictionary, Wikipedia, news, forums — NOT just dictionaries:** the hazard (e.g. "
|
|
77
|
-
|
|
78
|
-
means
|
|
76
|
+
— Urban Dictionary, Wikipedia, news, forums — NOT just dictionaries:** the hazard (e.g. "Mara" = a
|
|
77
|
+
Central American street gang) lives on the social web, never in a lexical entry. **A dictionary gloss ("it just
|
|
78
|
+
means crowd") is context, NEVER a clearance** — a connotation reads CLEAN only when the searched social/web
|
|
79
79
|
sources came back empty, never because a dictionary looked benign.
|
|
80
80
|
The program prints EXACTLY one JSON object to stdout:
|
|
81
81
|
{"cells": [{"term", "platform", "status", "results": [{"name", "url"}]}],
|
|
@@ -142,7 +142,7 @@ descriptive-compound risk theory retains DAWN-only hits only in gaming, and this
|
|
|
142
142
|
|
|
143
143
|
The driver joins, after EVERY digest pass (including flush rewrites), the set of **live, in-scope,
|
|
144
144
|
screen-surfaced records whose mark carries the dominant element** — as a standalone token, an edit-1
|
|
145
|
-
token, or concatenated inside a longer word (`
|
|
145
|
+
token, or concatenated inside a longer word (`WAVOTONK`-class) — against your endings. **The unit is
|
|
146
146
|
the POSITION, the same collapse Sheet-1 rows follow**: the driver groups those records by
|
|
147
147
|
`_driver/register-positions.json` and an ending on ANY ONE constituent URI ends the whole position.
|
|
148
148
|
A position with NO ending is a hard discrepancy: one warm follow-up, then the run **blocks
|
|
@@ -40,7 +40,7 @@ You were spawned to run exactly ONE axis named in your task. Read the manifest +
|
|
|
40
40
|
|
|
41
41
|
**The FORM band is MACHINE-DEFINED — search `form-neighbourhood.json`, not a model guess.** The driver writes the *complete* mechanical form neighbourhood of the distinctive element(s) — every edit-1 spelling/sound/transposition, the phonetic-family skeleton, visual / homoglyph look-alikes, and cross-script transliterations — to `form-neighbourhood.json` (`elements[].band`). **For the form axis your query set IS that file**, searched exhaustively, never a subset:
|
|
42
42
|
- **`band.exactQueries`** — OR-STACK them as `names: [...]` (implicit OR within the name field), ≤80 names per call (the executor's chunk bound — the plan compiler splits at the same width). **Count-first is CODE now, not your protocol**: whenever a multi-name stack crowds over the ceiling, the tool itself counts every term (`limit:1`, `fields:["uri"]`), individually enumerates each populated tractable term, and returns `term_counts` (verified-zero | enumerated | crowd | unenumerated | error) with the carried records — **a populated near-form can never read as 0 inside a saturated pile** (the FROSTBERRY drop). Your job is to READ `term_counts` honestly: a `crowd`/`unenumerated`/`error` disposition is an open question for judgment, never a clean. In plan mode the form band is a dictated plan entry — the executor runs it; you never hand-stack it.
|
|
43
|
-
- **`band.wildcardPatterns`** — run the consonant-skeleton wildcard (e.g. `
|
|
43
|
+
- **`band.wildcardPatterns`** — run the consonant-skeleton wildcard (e.g. `z?l?m?`) to retrieve the vowel family (ZYLOMA/ZILIMA-class) the exact OR-stack can't.
|
|
44
44
|
- Class-scope and per-jurisdiction rules apply unchanged (every call carries `nice_classes`/`in_scope_classes`). The manifest's model-authored `phonetic`/`visual`/`numeric` rows are **supplementary salience hints**, never the form definition; the `translit-*`/`meaning` rows (the non-mechanical axis) are still searched. If `form-neighbourhood.json` is absent (legacy run), fall back to the manifest variants — never worse than before.
|
|
45
45
|
3. **ENUMERATE the dangerous NAMED band with `register_enumerate` — class-scoped, never manual paginate-then-sample.** For each named query (the exact mark + each specific variant × in-scope class × material/major jurisdiction), call **`register_enumerate`** with the query (`name`/`names`/`match_mode`/`nice_classes`/`regions`/`owner_country`/`in_scope_classes` + the usual `register_search` fields). **MANDATORY: every `register_enumerate` call MUST carry `nice_classes`=<the matter's in-scope Nice set> AND `in_scope_classes`=<the same set>.** An enumerate with `nice_classes` OMITTED runs an all-45-class crowd (the `default` / `starts_with` / `ends_with` / `phonetic` / `fuzzy` modes are unbounded unscoped) — it floods the band and TIMES OUT the stage, and it is **FORBIDDEN**: scope-by-class is breadth the matter instructed, not a "good enough" call. The **only** all-class exception is the exact-IDENTICAL cross-class merch check (`match_mode:exact`, `nice_classes:[25]`). `fuzzy` is **never** an enumerate mode. **The tool owns the page loop and CANNOT return a partial list** — you cannot get a partial result and call it done, and there is no top-N mode. It returns exactly **one of two states**:
|
|
46
46
|
- **`{state:"enumerated", total_hits, count, records:[…]}`** — it paged to `has_more:false`; every named record is carried forward, already batch-screened (each record carries `record_id`, `mark_text`, `classes`, `status`, `owner_name`, `owner_country`, `application_date`, `registration_date`, `expiry_date`, `jurisdictions`, `screen_verdict`). Write this verbatim as an `enumerated` band block.
|
|
@@ -55,7 +55,7 @@ the rest of a lawyer's sentence standing around it.
|
|
|
55
55
|
| subsisting | live |
|
|
56
56
|
| senior | earlier, or came first |
|
|
57
57
|
| specification | goods list |
|
|
58
|
-
|
|
|
58
|
+
| VELTR-formative | names built on VELTR- |
|
|
59
59
|
| prevail | win |
|
|
60
60
|
| citable prior rights | earlier marks the office can raise against you |
|
|
61
61
|
| vulnerable to a non-use attack | could be cancelled for not being used |
|
|
@@ -69,19 +69,19 @@ the rest of a lawyer's sentence standing around it.
|
|
|
69
69
|
|
|
70
70
|
### The standard, in full sentences
|
|
71
71
|
|
|
72
|
-
A basis line, rewritten: *"
|
|
73
|
-
stores, and of an established
|
|
72
|
+
A basis line, rewritten: *"WAYPOINT is already the name of two navigation apps on the same app
|
|
73
|
+
stores, and of an established mapping company. Any of them would likely win a dispute
|
|
74
74
|
over this name for this software. The word is a weak mark for these goods, which is why this is High and
|
|
75
75
|
not Very High."*
|
|
76
76
|
|
|
77
77
|
An answer, rewritten: *"Blocked. An identical earlier mark for the same goods stops registration in
|
|
78
|
-
Switzerland, the EU and the US. Below that, earlier
|
|
78
|
+
Switzerland, the EU and the US. Below that, earlier VELTR- marks in EU class 5 and US class 42 can be
|
|
79
79
|
raised against the application."*
|
|
80
80
|
|
|
81
81
|
A card's detail — allowed the fold's vocabulary, still written plainly: *"Same name, same goods, and
|
|
82
82
|
their Swiss filing came first in every territory we searched. We see no argument against it."*
|
|
83
83
|
|
|
84
|
-
A note, rewritten: *"Ask the client whether it already uses
|
|
84
|
+
A note, rewritten: *"Ask the client whether it already uses WAYPOINT. Its own earlier use would change the
|
|
85
85
|
picture and is not reflected here."*
|
|
86
86
|
|
|
87
87
|
**Shortening by dropping the reason is not the fix.** The "why" stays, in plain words. A visible line
|
|
@@ -74,7 +74,7 @@ rendered as clean is a delivery failure the `narrative-refutation` skeptic block
|
|
|
74
74
|
**Say which negative you hold — and say it once (P6).** The two readings are different facts and must never
|
|
75
75
|
both attach to the same source in one report: *"searched — none found"* for a source this run actually
|
|
76
76
|
queried, *"not searched this run"* / *"could not be searched — <reason>"* for one it did not reach. (The
|
|
77
|
-
delivered
|
|
77
|
+
delivered WAVO report said both about TTAB decisions, which **are** searchable — the reader could not tell
|
|
78
78
|
which had happened.) Coverage prose is also the **longest-running prose in the report** — two of its four
|
|
79
79
|
longest sentences were coverage/gap prose — so it is held to the house budgets like everything else:
|
|
80
80
|
~20–25 words a sentence, each coverage fact stated **once**, in one place (an area's state in its
|
|
@@ -282,7 +282,7 @@ rules govern it:
|
|
|
282
282
|
|
|
283
283
|
**Crowding is per-market only.** Every crowd / dilution statement — narrative, per-finding reasoning,
|
|
284
284
|
`legal_position`, coverage prose — names the jurisdiction × goods lane it was counted in ("the US
|
|
285
|
-
class-32 register carries ~N live
|
|
285
|
+
class-32 register carries ~N live WAVO-formative marks"). That lane is the only one where the dilution
|
|
286
286
|
is earned (see *Volume is not a risk multiplier* and the use-meets-use rule); a global crowd sentence
|
|
287
287
|
("the field is crowded", "diluted worldwide") is forbidden on every surface.
|
|
288
288
|
|
|
@@ -417,9 +417,9 @@ Non-exact-match cancelled hits are excluded from the Findings sheet entirely.
|
|
|
417
417
|
|
|
418
418
|
## Connotation / meaning-search — every recorded receipt is disposed of, and a clean claim also cites its source
|
|
419
419
|
|
|
420
|
-
The common-law layer runs a CONNOTATION / meaning search — the mark **and its near-forms** on the social/subcultural web (Urban Dictionary, Wikipedia, news, forums) for gang / slang / offensive / cultural meaning, **distinct from the marketplace grid** (the grid asks "who *sells* this name?"; this asks "what does this name *mean*, and to whom?"). In deterministic-grid mode the driver DICTATES these queries into the grid (`grid-spec.connotation`) and the `perplexity_research` plugin records each into the ledger's `extras.pr_risk[]`. **Every recorded query with results MUST be ruled on in the driver-written disposition form — a ruling and a note per row — whatever the section concludes.** That obligation comes from the receipts existing, not from what the section says: reporting a loaded reading discharges that reading, not the rest of the sweep, and a section carrying no clean claim is policed exactly the same. The validator rejects any unruled row (`connotation_no_ruling`) and any row naming a receipt that is not one of its own candidates (`connotation_form_damaged`). A section that ADDITIONALLY asserts a CLEAN result (`None identified` / "no gang/offensive association" / "affirmative sweep") must carry a `- **Connotation-search source:** <URL | "perplexity_research — no result">` line — the driver's `commonLaw` validator rejects the findings file otherwise (`connotation_search_missing`). A clean connotation is sayable **only** when the meaning search ran; a benign dictionary gloss is NEVER a clearance (a mark can read as a benign old given name yet sit one letter off `
|
|
420
|
+
The common-law layer runs a CONNOTATION / meaning search — the mark **and its near-forms** on the social/subcultural web (Urban Dictionary, Wikipedia, news, forums) for gang / slang / offensive / cultural meaning, **distinct from the marketplace grid** (the grid asks "who *sells* this name?"; this asks "what does this name *mean*, and to whom?"). In deterministic-grid mode the driver DICTATES these queries into the grid (`grid-spec.connotation`) and the `perplexity_research` plugin records each into the ledger's `extras.pr_risk[]`. **Every recorded query with results MUST be ruled on in the driver-written disposition form — a ruling and a note per row — whatever the section concludes.** That obligation comes from the receipts existing, not from what the section says: reporting a loaded reading discharges that reading, not the rest of the sweep, and a section carrying no clean claim is policed exactly the same. The validator rejects any unruled row (`connotation_no_ruling`) and any row naming a receipt that is not one of its own candidates (`connotation_form_damaged`). A section that ADDITIONALLY asserts a CLEAN result (`None identified` / "no gang/offensive association" / "affirmative sweep") must carry a `- **Connotation-search source:** <URL | "perplexity_research — no result">` line — the driver's `commonLaw` validator rejects the findings file otherwise (`connotation_search_missing`). A clean connotation is sayable **only** when the meaning search ran; a benign dictionary gloss is NEVER a clearance (a mark can read as a benign old given name yet sit one letter off `Mara`, a street-gang label — a benign primary meaning does not clear an offensive secondary one). An empty-results search is a clean receipt; a missing search is not.
|
|
421
421
|
|
|
422
|
-
**Read it, don't just receipt it — the search running is not the work being done.** The receipt proves the meaning search *ran*; it does not mean anyone *read* it. Do not accept the common-law layer's bottom-line `clean` / `None identified` at face value — read the actual readings it surfaced for the mark **and each near-form** like a skeptical lawyer: **is the obvious meaning the whole story, or is there an odd, loaded, or unresolved secondary reading the tidy gloss skipped past?** (`
|
|
422
|
+
**Read it, don't just receipt it — the search running is not the work being done.** The receipt proves the meaning search *ran*; it does not mean anyone *read* it. Do not accept the common-law layer's bottom-line `clean` / `None identified` at face value — read the actual readings it surfaced for the mark **and each near-form** like a skeptical lawyer: **is the obvious meaning the whole story, or is there an odd, loaded, or unresolved secondary reading the tidy gloss skipped past?** (`mara` = "crowd" is the tidy gloss; `Mara` is the street gang the same word carries — the colloquial reading does not clear it.) This is a **general habit, not a meaning-only checklist**: wherever a result resolves to a tidy answer, the question is whether one cheap thread is worth pulling before you accept it — meaning is simply where it bites first.
|
|
423
423
|
|
|
424
424
|
**Pull the thread in-run; don't defer what one search would settle.** When a secondary reading looks loaded or unresolved and a single check would settle it, run **one scoped `perplexity_research` query** now (the same tool you already use for the actual-use check) and record it inline as `- **Meaning-pull:** <query> → <result | "no result">`. This is judgment-gated, **not** a new per-run requirement — pull only the one thread that is both *worth it* and *checkable*. If it resolves, say so; if it surfaces something real, carry it. This settle-don't-defer rule is **general**: a live question a single cheap search would close is closed in this run, not written down as homework. The honest *"a human should look"* outcome (a staff-lawyer purple bullet / `coverage_judgment.sufficient:false`) is reserved for a question **genuinely unanswerable now** — never for one a single search would have closed.
|
|
425
425
|
|
|
@@ -291,7 +291,7 @@ The variant categories are shaped by the archetype. Don't generate every categor
|
|
|
291
291
|
|
|
292
292
|
**The generation boundary (read first — it governs every axis and every bound below).** This step's only question about any candidate form is: ***could a real conflict plausibly take this shape?*** Generate every form a real collision could take; the ONLY valid reason to drop a form is that a real conflict could **not** take it (ungrammatical, semantically broken, not market-realistic — a collision-plausibility call, which is yours to make). **Never drop a plausible form because the search would be crowded, saturated, or noisy, or because the term is common / descriptive / generic.** Noise is no longer yours to manage: the register funnel enumerates the dangerous band **class-scoped** and hands any residual crowd to judgment ([clearance-register register-recipes.md](../clearance-register/register-recipes.md)) — generating a noisy-but-plausible form is safe by construction. A *"would drown in noise" / "too saturated to be worth it" / "descriptive, so skip it"* reason on a **dropped** row is the boundary violation this step must never commit. Saturation is a signal to the downstream search to **narrow** (class-scope the token and enumerate); it is never a reason to drop a variant here.
|
|
293
293
|
|
|
294
|
-
**The FORM axis is now mechanically COMPLETE — you do not own form coverage.** The driver generates the *complete* form neighbourhood of the distinctive element(s) **deterministically, with no model in the loop** — every edit-1 spelling/sound/transposition, the phonetic-key vowel family (the
|
|
294
|
+
**The FORM axis is now mechanically COMPLETE — you do not own form coverage.** The driver generates the *complete* form neighbourhood of the distinctive element(s) **deterministically, with no model in the loop** — every edit-1 spelling/sound/transposition, the phonetic-key vowel family (the ZYLOMA/ZILIMA class), visual / homoglyph look-alikes, and cross-script transliterations — into `form-neighbourhood.json`, which the register funnel searches as the authoritative **form floor**. This exists because a *guessed* form set is never complete: for an anchor like `VELTRIS` a model thinks of `ZELTRIS` but not `MELTRIS` (the same single edit), and the vendor's own phonetic/fuzzy modes cannot reach a first-consonant swap either (live-verified on a production matter — the missed first-consonant-swap neighbour existed as 69 live records yet Corsearch's complete in-class phonetic band for the anchor excluded it). The machine closes that lottery. **So your FORM-axis job is JUDGMENT, not enumeration:**
|
|
295
295
|
1. **Name the distinctive element + formative root precisely** (Step 3) — this is the *one* input the mechanical band seeds from; get the token right and the complete neighbourhood follows.
|
|
296
296
|
2. **Flag the high-salience look-alikes** — a real word or a known/famous mark the anchor sits an edit or homophone away from (SONICA→SONIC) — for **risk RANKING**. The machine generates the *string*; it cannot know SONIC is Sega's. This is salience, not coverage.
|
|
297
297
|
3. **Own the meaning / translit axis** (below) — connotation and translation are *not* mechanically enumerable; they remain yours.
|
|
@@ -361,7 +361,7 @@ A distinctive root is rarely owned in isolation — it anchors a **family of mar
|
|
|
361
361
|
|
|
362
362
|
The phonetic axis catches *sound-alikes*. This axis catches *look-alikes* — and the highest-value look-alike is a **real word or a known/famous mark** the anchor sits one or two edits (or a homophone) away from, because a consumer or a court confuses them and a famous holder may own one.
|
|
363
363
|
|
|
364
|
-
**Ask the question first (this is the primary step, not a string generator):** *"What real words, names, or well-known/famous marks is this anchor about **one or two keystrokes (a diacritic counts as an edit), or a homophone,** away from?"* List them; then run each through the famous-mark lens below. (Worked: for anchor `SONICA`, the obvious neighbour is `SONIC` — Sega's famous mark, one letter off — plus `SONIKA` / `SONYKA`. A generator that only emits typo-strings misses SONIC; the question surfaces it. This is the whole point — reason like the lawyer who reaches for SONIC on sight, don't enumerate edits.) **Reach the second edit when it lands on a real word or a known mark** — an accented or vowel-swapped form a market actually uses (e.g. for an anchor like `
|
|
364
|
+
**Ask the question first (this is the primary step, not a string generator):** *"What real words, names, or well-known/famous marks is this anchor about **one or two keystrokes (a diacritic counts as an edit), or a homophone,** away from?"* List them; then run each through the famous-mark lens below. (Worked: for anchor `SONICA`, the obvious neighbour is `SONIC` — Sega's famous mark, one letter off — plus `SONIKA` / `SONYKA`. A generator that only emits typo-strings misses SONIC; the question surfaces it. This is the whole point — reason like the lawyer who reaches for SONIC on sight, don't enumerate edits.) **Reach the second edit when it lands on a real word or a known mark** — an accented or vowel-swapped form a market actually uses (e.g. for an anchor like `LUMIERA`, the real word `LUMIÈRE`/`LUMIERE` — "light", two edits off). A plausible real-word or known-mark neighbour is worth generating even at two edits; the bound drops only *implausible* strings, never a real word the eye or ear reads as the same name because it sits one keystroke further out.
|
|
365
365
|
|
|
366
366
|
**Then fill in the mechanical typographic neighbours** the eye reads as the same token (secondary to the question; schematic anchor `FENRIQ`):
|
|
367
367
|
|
|
@@ -91,7 +91,7 @@ For specific country lists, the orchestrator passes the jurisdiction list throug
|
|
|
91
91
|
2b. **Meaning translation = the everyday-word-first equivalence SET (it reverses the older "specific concept, drop the everyday word" rule).** Emit the small deterministic set common-usage first, then technical, then adjacent — one manifest row per member, each tagged with its register (everyday | technical | adjacent). **Never drop the everyday word for looking saturated:** saturation is handled downstream by class-scoped enumeration in the register layer ([register-recipes.md](../clearance-register/register-recipes.md)) — the token narrowed to the filed in-scope Nice classes, not by ANDing goods words into the query and not by abandoning the word. A common everyday word is never grounds to skip a meaning rendering or to drop a live in-class hit behind it.
|
|
92
92
|
3. **Tag the variant row** in the Variants table with the category `translit-<script>` (e.g. `translit-cjk-japanese`, `translit-arabic`) and a rationale explaining whether it's phonetic or meaning-based. **For Chinese the category token MUST carry the sense** — `translit-zh-meaning` for a meaning translation, `translit-zh-phonetic` for a phonetic one — because the downstream saturation / class-scoped-enumeration gates key on the `translit-*-meaning` tag; a meaning row tagged only `translit-zh` would silently skip the field-narrowing and revert to the old drop-on-saturation behaviour.
|
|
93
93
|
4. **Flag for verification** by putting `✅` in the Variants table's `Verify?` column for every transliteration row. The downstream skill marks any HIT against these variants as needing reviewer sign-off before inclusion in the deliverable.
|
|
94
|
-
5. **Every non-Latin row carries its ROMANISATION, on its own row** — `"romanization"` in the manifest's structured sibling, and the Latin form in parentheses in the prose row's rationale. This is not decoration: **half the registers we search hold a non-Latin filing ONLY under its transliteration and cannot answer the characters at all.** A row without one is a term that can be searched on some providers and on no others — and the one that refuses it is right to, because searching the characters there returns 0 with no error and reads as a clean. (A clearance run on 2026-07-29 compiled thirteen native-script terms with no romanisation; every one was refused and the transliteration axis produced no coverage.) Rules: plain ASCII letters and digits, syllable-separated by single spaces, no tone marks and no diacritics (华威豹 → `HUA WEI BAO`,
|
|
94
|
+
5. **Every non-Latin row carries its ROMANISATION, on its own row** — `"romanization"` in the manifest's structured sibling, and the Latin form in parentheses in the prose row's rationale. This is not decoration: **half the registers we search hold a non-Latin filing ONLY under its transliteration and cannot answer the characters at all.** A row without one is a term that can be searched on some providers and on no others — and the one that refuses it is right to, because searching the characters there returns 0 with no error and reads as a clean. (A clearance run on 2026-07-29 compiled thirteen native-script terms with no romanisation; every one was refused and the transliteration axis produced no coverage.) Rules: plain ASCII letters and digits, syllable-separated by single spaces, no tone marks and no diacritics (华威豹 → `HUA WEI BAO`, ワボスラッシュ → `WABO SURASSHU`, 와보 슬러시 → `WABO SEULLEOSI`, Ваво Слаш → `VAVO SLASH`); the romanisation goes on the row whose own value it romanises, never on a neighbour and never as a row of its own; and a value that is already Latin never gets one. The driver puts BOTH forms on the search entry and each provider expresses the one its index holds — you state the pair, you never choose which gets searched.
|
|
95
95
|
|
|
96
96
|
## When transliteration is overkill
|
|
97
97
|
|
|
@@ -44,7 +44,7 @@ Be honest and conservative: a clean diff (the run scoped what the blind model de
|
|
|
44
44
|
A directive may carry a structured `remedy`:
|
|
45
45
|
|
|
46
46
|
```json
|
|
47
|
-
"remedy": { "terms": ["TROPICAL
|
|
47
|
+
"remedy": { "terms": ["TROPICAL WAVO", "ISLAND WAVO"], "nice_classes": ["5", "32"], "regions": [] }
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
- `terms` — the exact MARK-SHAPED search term(s) the re-search should dispatch. Each term is something a register would hold as a mark: a word, a short composite. Never a description of a family.
|
|
@@ -57,7 +57,7 @@ A directive may carry a structured `remedy`:
|
|
|
57
57
|
1. its `item` is *itself* a single mark-shaped search term (`TAKIS`, `AXIOS`, `CORAL MAGIC`), **or**
|
|
58
58
|
2. it carries `remedy.terms` naming the mark-shaped term(s) to search.
|
|
59
59
|
|
|
60
|
-
A label-shaped `item` — more than 4 words, a parenthetical, an enumeration ("TAKIS (famous CPG snack, one-keystroke neighbour)", "Reverse-order
|
|
60
|
+
A label-shaped `item` — more than 4 words, a parenthetical, an enumeration ("TAKIS (famous CPG snack, one-keystroke neighbour)", "Reverse-order WAVO composites (TROPICAL WAVO, ISLAND WAVO)") — is **never dispatched as a search term**: dispatched verbatim it is a nil search that comes back 0 and reads as a clean, which is worse than no search. So a firing `variant` directive whose item is a label **and which carries no remedy is a PARSE DEFECT** — the driver refuses the file and asks you to restate it, in this same turn, while restating is still free. Every term you put in `remedy.terms` is linted the same way: a remedy that is itself a label is refused exactly like the item was.
|
|
61
61
|
|
|
62
62
|
The refusal names **every** offending directive at once, and it arrives as the tool's answer to your call — in this turn, while restating is still free. Fix them **all** in one further call: the repair ladder counts attempts, not directives, so repairing only the first one loses the rest. A call replaces the stored diff, so send the whole thing again, not only the corrected directives.
|
|
63
63
|
|
|
@@ -171,7 +171,7 @@ are worked examples of the one failure, not its boundary:
|
|
|
171
171
|
| subsisting | live |
|
|
172
172
|
| senior | earlier, or came first |
|
|
173
173
|
| specification | goods list |
|
|
174
|
-
|
|
|
174
|
+
| VELTR-formative | names built on VELTR- |
|
|
175
175
|
| prevail | win |
|
|
176
176
|
| citable prior rights | earlier marks the office can raise against you |
|
|
177
177
|
| vulnerable to a non-use attack | could be cancelled for not being used |
|
|
@@ -185,15 +185,15 @@ are worked examples of the one failure, not its boundary:
|
|
|
185
185
|
|
|
186
186
|
The target is the level of these, each the standard for its line:
|
|
187
187
|
|
|
188
|
-
> **Basis.** "
|
|
189
|
-
> established
|
|
188
|
+
> **Basis.** "WAYPOINT is already the name of two navigation apps on the same app stores, and of an
|
|
189
|
+
> established mapping company. Any of them would likely win a dispute over this name
|
|
190
190
|
> for this software. The word is a weak mark for these goods, which is why this is High and not Very
|
|
191
191
|
> High."
|
|
192
192
|
|
|
193
193
|
> **A finding's `net`.** "Same name, same goods, and their filing came first in every territory we
|
|
194
194
|
> searched. We see no argument against it."
|
|
195
195
|
|
|
196
|
-
> **The batch opener.** "One name screened:
|
|
196
|
+
> **The batch opener.** "One name screened: WAYPOINT, rated High."
|
|
197
197
|
|
|
198
198
|
**Shortening by dropping the reason is not the fix.** The "why" stays, in plain words. A visible
|
|
199
199
|
line that is short because it no longer says why is worse than the long one it replaced, and it
|
|
@@ -214,19 +214,19 @@ A note about the request NAMES the request in the note — "the request", or "wh
|
|
|
214
214
|
not a formality: the report sorts the two kinds by what the note talks about, so a request note that
|
|
215
215
|
never mentions the request is filed under the name and prints in the wrong place.
|
|
216
216
|
|
|
217
|
-
> "Check the request. The client is described as a
|
|
218
|
-
> to screen
|
|
217
|
+
> "Check the request. The client is described as a bakery business, but we were asked
|
|
218
|
+
> to screen navigation software in Class 9. We screened the software. If baking is the real
|
|
219
219
|
> business, this screen looked at the wrong market."
|
|
220
220
|
|
|
221
|
-
> "Ask the client whether it already uses
|
|
221
|
+
> "Ask the client whether it already uses WAYPOINT. The request does not say, and the client's own earlier
|
|
222
222
|
> use would change the picture."
|
|
223
223
|
|
|
224
224
|
A note about the name opens on what the lawyer should do about the name:
|
|
225
225
|
|
|
226
|
-
> "Pull
|
|
226
|
+
> "Pull Acme Mapping's full goods list at clearance. It is the record most likely to change the picture in
|
|
227
227
|
> either direction."
|
|
228
228
|
|
|
229
|
-
> "Search Classes 42 and
|
|
229
|
+
> "Search Classes 42 and 39 in their own right. Both carry live WAYPOINT filings, not spillover from
|
|
230
230
|
> Class 9."
|
|
231
231
|
|
|
232
232
|
A note that restates a finding already on the page is not a note. Cut it.
|
|
@@ -42,7 +42,7 @@ watchlists come from in any case, and is why this file was never authority.
|
|
|
42
42
|
- **Nordwave** — `aggressive_enforcers`. NOVAPULSE (lighting / peripheral ecosystem);
|
|
43
43
|
a dynamic-lighting ecosystem partner, so name with the partnership context when
|
|
44
44
|
the client is in the PC-gaming hardware lane. Surface NOVAPULSE and the
|
|
45
|
-
near-exact / phonetic fringe (NORDWAVE NOVAPULSE,
|
|
45
|
+
near-exact / phonetic fringe (NORDWAVE NOVAPULSE, NOVAPULZE) on lighting / peripheral
|
|
46
46
|
marks.
|
|
47
47
|
|
|
48
48
|
## Cross-sector
|
|
@@ -79,7 +79,7 @@ in the file:
|
|
|
79
79
|
that means "no finding"; the absence is the statement.
|
|
80
80
|
|
|
81
81
|
Use the finding's **ordinal**, the number the narrative and `findings.json` already agree on — not the
|
|
82
|
-
mark, not the owner. You are writing them anyway ("Finding 9 —
|
|
82
|
+
mark, not the owner. You are writing them anyway ("Finding 9 — VELTRIC…"); the token is the same fact
|
|
83
83
|
where a machine can read it.
|
|
84
84
|
|
|
85
85
|
**What it buys, and it is not bookkeeping.** When every flag carries one, the author is told to change
|
|
@@ -295,7 +295,7 @@ For each obvious neighbour missing from the manifest, **FLAG (missing-variant)**
|
|
|
295
295
|
|
|
296
296
|
### Meaning / connotation read — did it look past the obvious gloss?
|
|
297
297
|
|
|
298
|
-
The PR / reputational section carries a search *receipt*, but a receipt is not a read. With fresh eyes, take the proposed mark **and its near-forms** and ask the question the run was meant to ask: **is the obvious meaning the whole story, or does the same word carry an odd / loaded / subcultural secondary reading the section glossed past?** (`
|
|
298
|
+
The PR / reputational section carries a search *receipt*, but a receipt is not a read. With fresh eyes, take the proposed mark **and its near-forms** and ask the question the run was meant to ask: **is the obvious meaning the whole story, or does the same word carry an odd / loaded / subcultural secondary reading the section glossed past?** (`mara` reads as "crowd" — and `Mara` is a street gang; the benign gloss does not clear the loaded reading.) A clean PR claim that stopped at the tidy gloss while a loaded secondary reading is plausible is exactly the kind of specific suspicion your one Fresh probe exists to confirm — spend it here (below) if this is the more worth-pulling thread. If the probe surfaces a real loaded meaning the run never addressed, **FLAG (meaning-read-shallow)** and treat it like an unsupported clean negative (material); if the probe comes back clean, the meaning read holds — note it and move on.
|
|
299
299
|
|
|
300
300
|
**Confirm before you flag — bring in one input the run did not already consume.** Re-reading the same files the author read can only show they agree with themselves; it can never show you what the run missed. So when you suspect an obvious neighbour, a closer conflict on the applicant's *own* goods that the run did not carry, **or a loaded secondary meaning the PR section glossed past**, run **one scoped `perplexity_research` query** to confirm it *before* flagging — and **record that query and its result verbatim in this review** as a one-line `Fresh probe: <query> → <result or URL>`. This is the single place the review is required to introduce evidence the upstream units did not produce; cite it. One probe per review is enough — you are confirming a specific suspicion, not re-running the search.
|
|
301
301
|
|
|
@@ -183,7 +183,7 @@ The inquiry above is primary. The patterns below describe how the inquiry's answ
|
|
|
183
183
|
- **Don't down-place an on-field in-class identical mark on filer-size or apparent-dormancy grounds.** A small / individual / tail-market filer of an in-class identical mark is a real paper conflict — place it at headline-candidate or sheet-2 (never out-of-scope), the promotion question deciding which, and leave the filer-size / revocation-vulnerability read for the digest/synthesis Stage-2. Those are mitigants to weigh, not reasons to keep a real conflict out of the report.
|
|
184
184
|
- **Famous-mark neighbours cross fields — don't off-field-filter them.** A famous mark that is a visual / phonetic neighbour of the proposed mark (one keystroke or a homophone away) and that covers the target goods or an adjacent field is placed **headline-candidate or sheet-2** (the promotion question deciding which), never watchlist-annex or out-of-scope — *regardless of field-divergence*, and even if matter-context flags the owner's core business as off-field. The famous owner's cross-sector reach and enforcement posture make it a real candidate; field-divergence (e.g. "their main product is a browser, ours is a dev-kit") is a Stage-2 mitigant the digest/synthesis weighs, not a reason to demote it here. What matters at placement is that the famous neighbour *covers the target goods*.
|
|
185
185
|
- **Active same-field brand in the core classes — don't down-place on mark-shape alone.** An owner running an *active* brand (current marketplace presence — a live product / app / site under the mark) that is a near-identical neighbour in the applicant's *core* classes is a real same-field conflict: place it **headline-candidate or sheet-2 — the promotion question deciding which — and carry an explicit `active same-field` flag**, never demoted out of the headline tier on a mark-shape distinction (an onset-letter difference, a one-keystroke swap) *alone*. Onset / phonetic distance is a Stage-2 confusion-read input the digest/synthesis weighs — it is **not** a placement-demotion ground for an active in-class competitor whose own use meets the client's. What matters at placement is *active + same-field + core class*; whether the word-shape ultimately distinguishes is the rating step's call, made with the conflict in front of it, not foreclosed by a quiet demotion to sheet-2. (Symmetric to the famous-neighbour rule above: a demotion needs a real, surfaced reason, never a silent drop on shape.)
|
|
186
|
-
- **Don't dump a look-alike or shared-meaning family when one member is in our field.** When a cluster of related forms (a look-alike or shared-meaning family — e.g. `
|
|
186
|
+
- **Don't dump a look-alike or shared-meaning family when one member is in our field.** When a cluster of related forms (a look-alike or shared-meaning family — e.g. `FALCON` / `FALCONE` / `FALCÓN` / the *falcon* sense) is being off-fielded as "unrelated," check **each member against the target goods before dropping the cluster**: if *any single member* is in our field (e.g. a niche or academic registration for the applicant's own goods — say social-networking software), carry that member at **headline-candidate or sheet-2** — the promotion question deciding which — and keep the family as context. Never drop the whole family wholesale because its dominant association sits off-field — a family is dropped member-by-member with a reason, never as a cluster on its headline meaning. (Same discipline as the famous-neighbour and active-same-field rules above: a drop needs a real, surfaced, per-member reason.)
|
|
187
187
|
- **Don't re-derive matter-context.** matter-frame did the strategic framing; you apply it. Disagreements with matter-context are surfaced explicitly ("matter-context flagged X as off-field; this candidate may warrant re-evaluation because Y"), not smoothed or reframed.
|
|
188
188
|
|
|
189
189
|
## What NOT to do
|
package/driver/stage-context.mjs
CHANGED
|
@@ -317,10 +317,10 @@ export const DISPATCH_EXTRAS = [
|
|
|
317
317
|
// ride record_coverage), so an arm dispatched without it is not measuring its variable — it is
|
|
318
318
|
// measuring the absence of the rows the stage's whole coverage contract now runs through. The
|
|
319
319
|
// same file is on VALIDATOR_SIDECARS, because it is also the copy the gate judges.
|
|
320
|
-
{ path: driverDir(P.runDir, "register-coverage-form.form.json"), why: "the accumulator coverageFormBrief enumerates into the dispatch (
|
|
321
|
-
{ path: P.coverageEnum, why: "the era stamp that says a coverage form is required on this run
|
|
322
|
-
{ path: P.planExecution, why: "the coverage form's skeleton + per-qid deferral reasons (
|
|
323
|
-
{ path: P.registerPlan, why: "the coverage form's unit labels and open-block join come from the frozen plan
|
|
320
|
+
{ path: driverDir(P.runDir, "register-coverage-form.form.json"), why: "the accumulator coverageFormBrief enumerates into the dispatch (typed transport)" },
|
|
321
|
+
{ path: P.coverageEnum, why: "the era stamp that says a coverage form is required on this run" },
|
|
322
|
+
{ path: P.planExecution, why: "the coverage form's skeleton + per-qid deferral reasons (was the A8 deferred-axis hint)" },
|
|
323
|
+
{ path: P.registerPlan, why: "the coverage form's unit labels and open-block join come from the frozen plan" },
|
|
324
324
|
{ path: P.placementModel, why: "the borderline-declaration count row" },
|
|
325
325
|
{ path: P.placement, why: "the placement RULINGS TAIL, carried as data on a corrective pass (P5)" },
|
|
326
326
|
{ path: P.ownerScreen, why: "the owner×element screen receipt (P2-B)" },
|