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.
- package/.env.example +64 -37
- package/.nvmrc +1 -1
- package/CONTRIBUTING.md +8 -4
- package/INSTALL.md +36 -14
- package/README.md +18 -22
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/bin/clearotron.mjs +22 -0
- package/bin/example.mjs +10 -5
- package/bin/onboard.mjs +370 -28
- package/bin/start.mjs +220 -12
- package/build-info.json +2 -2
- package/demo/README.md +1 -1
- package/demo/full-country-search/run/_driver/framework.json +1 -1
- package/demo/global-preliminary-search/run/_driver/framework.json +1 -1
- package/demo/knockout-search/run/_driver/framework.json +1 -1
- package/demo/multi-country-focus-search/run/_driver/framework.json +1 -1
- package/docs/E2E.md +5 -5
- package/docs/GLOSSARY.md +85 -0
- package/docs/PORTAL.md +2 -2
- package/docs/README.md +6 -4
- package/docs/SECURITY.md +17 -0
- package/docs/architecture/01-product-overview.md +21 -9
- package/docs/architecture/04-configuration-reference.md +2 -0
- package/docs/architecture/05-config-governance.md +19 -0
- package/docs/architecture/05-customer-profiles.md +2 -2
- package/docs/configuration.md +4 -3
- package/docs/decisions/0006-what-the-public-repository-carries.md +30 -5
- package/driver/CHANGELOG.md +90 -0
- package/driver/README.md +25 -6
- package/driver/common-law-receipts.mjs +1 -1
- package/driver/config-staleness.mjs +1 -1
- package/driver/connotation-search.mjs +1 -1
- package/driver/contract-audit.mjs +5 -1
- package/driver/contract-e3-baseline.json +11 -11
- package/driver/dev-portal.mjs +2 -2
- package/driver/doubt-selection.mjs +1 -1
- package/driver/drainer-identity.mjs +1 -1
- package/driver/driver.config.mjs +1 -1
- package/driver/effort-model.mjs +2 -2
- package/driver/engine/cli-version.mjs +103 -0
- package/driver/engine/probe.mjs +45 -5
- package/driver/enqueue-schema.mjs +8 -8
- package/driver/feedback-store.mjs +1 -1
- package/driver/findings-model.mjs +52 -2
- package/driver/flag-snapshot.mjs +20 -0
- package/driver/framework.mjs +1 -1
- package/driver/gateway.mjs +20 -3
- package/driver/outbox-backoff.mjs +1 -1
- package/driver/package.json +3 -3
- package/driver/party-facts.mjs +2 -2
- package/driver/phase0.mjs +1 -1
- package/driver/pipeline.mjs +211 -106
- package/driver/plain-register.mjs +134 -0
- package/driver/portal-access.mjs +1 -1
- package/driver/portal-config-view.mjs +70 -2
- package/driver/portal-families.mjs +1 -1
- package/driver/portal-local-auth.mjs +5 -1
- package/driver/portal-report.mjs +1 -1
- package/driver/portal-service.mjs +79 -9
- package/driver/portal-upstream.mjs +2 -2
- package/driver/predelivery-lint.mjs +151 -2
- package/driver/profile-page.html +10 -2
- package/driver/profile-service.mjs +4 -4
- package/driver/profiles/README.md +3 -3
- package/driver/profiles.mjs +144 -12
- package/driver/publish/index.mjs +2 -2
- package/driver/publish/knockout.mjs +7 -1
- package/driver/publish/render-knockout.mjs +453 -118
- package/driver/publish/render.mjs +111 -16
- package/driver/reference-strip-signatures.mjs +20 -0
- package/driver/search-policy.mjs +3 -3
- package/driver/skills/blind-frame/SKILL.md +1 -1
- package/driver/skills/knockout-assess/SKILL.md +84 -0
- package/driver/skills/matter-frame/SKILL.md +6 -6
- package/driver/skills/matter-frame/watchlist-reference.md +2 -2
- package/driver/skills/prelim-common-law/SKILL.md +1 -1
- package/driver/skills/prelim-search/SKILL.md +1 -1
- package/driver/skills/prelim-search/report-prose.md +82 -0
- package/driver/skills/prelim-search/risk-framework-demo.manifest.json +1 -1
- package/driver/skills/prelim-search/risk-framework-triage.manifest.json +1 -1
- package/driver/skills/prelim-search/risk-framework.manifest.json +1 -1
- package/driver/skills/prelim-search/synthesis-rules.md +1 -1
- package/driver/skills/prelim-variants/SKILL.md +3 -3
- package/driver/stage-context.mjs +13 -0
- package/driver/stages.mjs +54 -7
- package/driver/suite-census.json +220 -58
- package/driver/systemd/clearotron-worker.service +3 -3
- package/driver/tokens.mjs +1 -1
- package/driver/unit-inventory.mjs +214 -27
- package/driver/verify.mjs +1 -1
- package/driver/whatif-memo-run.mjs +26 -4
- package/driver/whatif-memo.mjs +19 -1
- package/examples/README.md +2 -2
- package/examples/grants.example.json +6 -7
- package/mcp-server/CHANGELOG.md +4 -0
- package/mcp-server/lib/scrub.mjs +1 -1
- package/mcp-server/lib/whatif.mjs +2 -2
- package/mcp-server/package.json +1 -1
- package/mcp-server/packs/ops/EXAMPLES.md +2 -2
- package/mcp-server/server.mjs +1 -1
- package/package.json +31 -19
- package/portal-ui/dist/assets/{index-Ct3iQtZ2.css → index-1ziUJX1E.css} +43 -2
- package/portal-ui/dist/assets/{index-BUGgiYtF.js → index-KFAHMgdT.js} +289 -73
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/_shared/term-shape.mjs +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/uspto-local/src/index-store.js +2 -2
- package/scripts/added-reference-check.mjs +45 -89
- package/scripts/citation-line-check.mjs +121 -2
- package/scripts/e2e.mjs +2 -2
- package/scripts/env-classify.mjs +67 -3
- package/scripts/generated-files-are-current.mjs +125 -0
- package/scripts/live-surface-check.mjs +38 -1
- package/scripts/mint-names-in-force.mjs +4 -2
- package/scripts/mint-public-residue.mjs +74 -0
- package/scripts/mint-reference-strip-backlog.mjs +12 -1
- package/scripts/mint-suite-census.mjs +5 -2
- package/scripts/nightly-notice.mjs +0 -2
- package/scripts/preinstall-node-check.mjs +24 -0
- package/scripts/render-check.mjs +13 -2
- package/scripts/report-frame-check.mjs +8 -1
- package/scripts/report-screenshot.mjs +6 -3
- package/scripts/revisit-render-check.mjs +6 -3
- package/scripts/score.mjs +1 -1
- package/scripts/strip-tracker-citations.mjs +38 -7
- package/scripts/test-full.mjs +226 -0
- package/scripts/test-run.mjs +16 -0
- package/shared/README.md +2 -1
- package/shared/anon-overlay.mjs +3 -3
- package/shared/browser-temp-root.mjs +142 -0
- package/shared/checkout-move.mjs +1 -1
- package/shared/client-door.mjs +4 -3
- package/shared/customer-store.mjs +1 -1
- package/shared/identifier-scan.mjs +1 -1
- package/shared/install-auth.mjs +35 -0
- package/shared/invocation.mjs +33 -1
- package/shared/listen.mjs +55 -3
- package/shared/names-in-force.mjs +6 -1
- package/shared/node-floor.mjs +97 -0
- package/shared/os-advice.mjs +91 -0
- package/shared/reap-on-exit.mjs +42 -0
- package/shared/reference-guard-classes.mjs +351 -0
- package/shared/staff-domain.mjs +154 -0
- package/shared/store-in-repo.mjs +23 -2
- package/shared/suite-census.mjs +31 -3
- package/shared/withheld-paths-access.mjs +36 -18
- package/skills/clearotron-ops/SKILL.md +1 -1
- package/driver/recipes/README.md +0 -49
- package/driver/skills/prelim-search/risk-framework-aurora.manifest.json +0 -19
- package/driver/skills/prelim-search/risk-framework-aurora.md +0 -77
- package/driver/skills/prelim-search/risk-framework-zephyr.manifest.json +0 -14
- package/driver/skills/prelim-search/risk-framework-zephyr.md +0 -33
- package/driver/skills/prelim-search/worked-examples-aurora.md +0 -10
- package/driver/skills/prelim-search/worked-examples-zephyr.md +0 -10
- package/scripts/ai-page-render-check.mjs +0 -532
- package/scripts/clearances-render-check.mjs +0 -480
- package/scripts/composer-render-check.mjs +0 -1027
- package/scripts/home-render-check.mjs +0 -526
- package/scripts/portal-lifecycle-check.mjs +0 -639
|
@@ -125,8 +125,8 @@ LUMENGARDE is the distinctive anchor — risk concentrates on coined-word axes a
|
|
|
125
125
|
|
|
126
126
|
**A variant VALUE is a mark term, never a note about one.** A parenthetical, sentence punctuation
|
|
127
127
|
(`—`, `;`) or a space-flanked slash makes it a label, and a label dispatched verbatim returns a
|
|
128
|
-
confident zero over marks that exist — a nil search that reads as a clean. Write `
|
|
129
|
-
`
|
|
128
|
+
confident zero over marks that exist — a nil search that reads as a clean. Write `COASTLINE`, not
|
|
129
|
+
`COASTLINE (root)`; the rationale column is where the note belongs. The compiler refuses annotated values
|
|
130
130
|
whatever their length, so a two-word one is caught the same way a long one is.
|
|
131
131
|
|
|
132
132
|
**If a value genuinely IS a mark carrying that punctuation** — a device mark recorded with its Vienna
|
|
@@ -178,7 +178,7 @@ silently narrows what was searched, and the deferred row is the honest outcome.
|
|
|
178
178
|
|
|
179
179
|
### Watchlists
|
|
180
180
|
|
|
181
|
-
- **Aggressive enforcers:** Nordwave,
|
|
181
|
+
- **Aggressive enforcers:** Nordwave, Foxglade Interactive
|
|
182
182
|
- **Major brand owners:** Sony, Aureon, Nintendo, HP, Activision, Take-Two, EA
|
|
183
183
|
- **Competitors:** Epic Games, Valve, Unity, Riot Games
|
|
184
184
|
|
package/driver/stage-context.mjs
CHANGED
|
@@ -369,6 +369,19 @@ export const DISPATCH_EXTRAS = [
|
|
|
369
369
|
{ path: join(P.runDir, "_records"), dir: true, why: "assembleRunRecords — the fetched official records each claimed field is checked against; without them the check finds zero mismatches and the block silently vanishes" },
|
|
370
370
|
],
|
|
371
371
|
},
|
|
372
|
+
{
|
|
373
|
+
// Rule 1 of the two-register rule, measured over the record's default-visible lines and handed to
|
|
374
|
+
// the pass that already rewrites. Advisory by construction: it reaches the writer, never the reader.
|
|
375
|
+
//
|
|
376
|
+
// It reads the RECORD rather than the narrative, and that is the point — the lines a client meets
|
|
377
|
+
// first are typed fields (each conflict's one sentence, the coverage notes, the actions, the mark
|
|
378
|
+
// assessment's two reads), not prose to be re-parsed out of a document. A sandbox without this file
|
|
379
|
+
// composes no block, which is correct and visible: the composer stamps what it built.
|
|
380
|
+
id: "refute-plain-register", stage: "narrative-refutation",
|
|
381
|
+
reads: (P) => [
|
|
382
|
+
{ path: P.findings, why: "plainRegisterExtra reads the typed default-visible fields — net, coverage notes, actions, mark assessment — and the owners it must blank before reading" },
|
|
383
|
+
],
|
|
384
|
+
},
|
|
372
385
|
// ── — synthesis's two, and the asymmetry they close ─────────────────────────────────────────
|
|
373
386
|
//
|
|
374
387
|
// The reviewer received the plan-execution receipt as a code-derived table; the stage it reviews
|
package/driver/stages.mjs
CHANGED
|
@@ -66,9 +66,9 @@ export { REGISTER_AXES, decideAxes };
|
|
|
66
66
|
//
|
|
67
67
|
// (stages.mjs cannot import pipeline.mjs — pipeline imports stages — and stage-context.mjs, where the
|
|
68
68
|
// extras are declared, imports stages.mjs too. stages.mjs is the one home both sides can reach.)
|
|
69
|
-
export function stampDispatchBlocks(ctx, stage, { built = [], failed = [] } = {}) {
|
|
69
|
+
export function stampDispatchBlocks(ctx, stage, { built = [], failed = [], empty = [] } = {}) {
|
|
70
70
|
if (!ctx || typeof ctx !== "object") return;
|
|
71
|
-
ctx.dispatchBlocks = { ...(ctx.dispatchBlocks ?? {}), [stage]: { built: [...built], failed: [...failed] } };
|
|
71
|
+
ctx.dispatchBlocks = { ...(ctx.dispatchBlocks ?? {}), [stage]: { built: [...built], failed: [...failed], empty: empty.map((e) => ({ ...e })) } };
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
// Three states, and the third is the point: ABSENT IS NOT CORRUPT. A run with no register plan is a
|
|
@@ -85,7 +85,7 @@ export function dispatchBlockState(ctx, stage, id) {
|
|
|
85
85
|
if (!rec) return "absent";
|
|
86
86
|
if (rec.built?.includes(id)) return "present";
|
|
87
87
|
if (rec.failed?.some((f) => f.id === id)) return "failed";
|
|
88
|
-
return "absent";
|
|
88
|
+
return rec.empty?.find((x) => x.id === id)?.kind ?? "absent"; // ran and produced no text; WHICH nothing is the builder's own word — see `nothingFound` at the foot of this file
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// ── The two synthesis lines that make a claim about the blocks, branched in ONE place ──────────────
|
|
@@ -1301,7 +1301,7 @@ export const STAGES = {
|
|
|
1301
1301
|
job.jurisdictions ? `Instructed territories (AUTHORITATIVE scope — do NOT widen to "major markets"): ${Array.isArray(job.jurisdictions) ? job.jurisdictions.join(", ") : job.jurisdictions}` : "",
|
|
1302
1302
|
job.customer ? `Customer/applicant (from the intake brief — drives the self-exclusion set): ${job.customer}` : "",
|
|
1303
1303
|
// WS-B profile defaults — falsy-omitted, so an empty profile renders this message byte-identical
|
|
1304
|
-
// to the pre-profile shape (the
|
|
1304
|
+
// to the pre-profile shape (the regression anchor).
|
|
1305
1305
|
// Industry is CONTEXT not a rule (Design Law #1): it sharpens which sectors/adjacencies matter for
|
|
1306
1306
|
// the vertical (e.g. food/ingestible adjacency for a beverage brand), it never dictates a conclusion.
|
|
1307
1307
|
profile?.industry ? `Customer industry (context for sector framing — let it sharpen the relevant sectors and adjacencies for this vertical; it is context, never a rule that decides a finding): ${profile.industry}.` : "",
|
|
@@ -1813,7 +1813,7 @@ export const STAGES = {
|
|
|
1813
1813
|
// DETERMINISTIC GRID (robust fix, 2026-06-14): when the driver wrote a grid-spec, the model is OUT
|
|
1814
1814
|
// of the grid data path entirely — it passes grid_spec_path, the plugin runs the dictated cells and
|
|
1815
1815
|
// WRITES common-law-grid.json from the API response (no truncation, no dropped/mis-keyed cells), and
|
|
1816
|
-
// the model only judges the returned candidates. This is the structural cure for both the
|
|
1816
|
+
// the model only judges the returned candidates. This is the structural cure for both the dense-marketplace
|
|
1817
1817
|
// truncation and the NOVA PULSE dropped-cell failures (no tier bump would fix the output ceiling).
|
|
1818
1818
|
if (gridSpecPath) {
|
|
1819
1819
|
return lines(
|
|
@@ -2353,7 +2353,7 @@ export const STAGES = {
|
|
|
2353
2353
|
},
|
|
2354
2354
|
"placements.json — the structured mirror, keys EXACTLY {mark, owner, jurisdiction, records, tier, reason} + optional borderline": {
|
|
2355
2355
|
class: "mechanical:code-rendered", tokens: ["placementmodel_missing", "placements_unparseable", "placements_key_unknown", "placement_invalid", "placement_key_unknown"],
|
|
2356
|
-
why: "The driver renders it: renderPlacementsJson() in placement-form.mjs over the union, landed by gateway.mjs
|
|
2356
|
+
why: "The driver renders it: renderPlacementsJson() in placement-form.mjs over the union, landed by `syncPlacementForm` in gateway.mjs (the union-then-render block). Cited by SYMBOL because the number has now moved twice: an earlier :507 pointed at an engine-resolution comment, and :706 went blank when an unrelated block was inserted above it. The skill file was not updated with #562, so the stage's two sources contradict each other — the contract that escapes if E1 is authored against stages.mjs alone.",
|
|
2357
2357
|
},
|
|
2358
2358
|
"mark / owner / records / territories / classes on a SELECTED row": {
|
|
2359
2359
|
class: "mechanical:code-extracted", tokens: [],
|
|
@@ -3222,7 +3222,7 @@ export const STAGES = {
|
|
|
3222
3222
|
// lane's own prose contract. Two of the four longest sentences in the delivered report were
|
|
3223
3223
|
// coverage/gap prose, and NOTHING governed it: the code-stamped `coverage_line:` front-matter
|
|
3224
3224
|
// (scope-facts.mjs,) is EXCLUDED from predelivery-lint's prose scan by design
|
|
3225
|
-
// (stripFrontMatterBlock, predelivery-lint.mjs:
|
|
3225
|
+
// (stripFrontMatterBlock, predelivery-lint.mjs:376), so a coverage number re-typed into prose
|
|
3226
3226
|
// beside it is caught only if the prose form itself trips SCOPE_NUMBER_RE — which the narrative's
|
|
3227
3227
|
// own phrasings routinely dodge. Prompt-only per §7; the fix is to stop authoring the duplicate.
|
|
3228
3228
|
`COVERAGE PROSE (the lane that runs longest — hold it to the house budgets): the register coverage line a reader sees is COMPUTED from this run's own record and STAMPED BY CODE as front-matter (the proportion, the class states, the searched registers). Do NOT re-type its numbers anywhere in prose — not in a coverage[] note, not in the coverage_judgment reason, not in the narrative. Nothing catches the duplicate for you (the code-stamped line sits outside the prose checks precisely because ITS numbers are the authoritative ones), so a re-typed count does not disagree with the record — it silently drifts from it a redelivery later. Carry the SUBSTANCE and drop the number: "the remaining forms are non-Latin script" says the useful half; the code says how many. State each coverage fact ONCE, in ONE place — an area's state belongs in its coverage[] row, the sufficiency read belongs in coverage_judgment.reason, and neither is re-narrated in the other or in the findings. And say WHICH KIND of negative you hold every time: a source this run actually queried and got nothing from reads "searched — none found"; a source it did not reach reads "not searched this run" or "could not be searched — <the reason>". The same source must never wear both readings in one report.`,
|
|
@@ -4617,3 +4617,50 @@ export function whatsappRouting(job, agentId) {
|
|
|
4617
4617
|
whatsappCcOperator: OPERATOR_WHATSAPP_COPY ? (AGENT_WHATSAPP[agentId] ?? null) : null,
|
|
4618
4618
|
};
|
|
4619
4619
|
}
|
|
4620
|
+
|
|
4621
|
+
// ── A BUILDER THAT RAN AND SAID NOTHING SAYS SO, AND SAYS WHICH NOTHING ────────────────────────────
|
|
4622
|
+
//
|
|
4623
|
+
// AT THE FOOT OF THE FILE ON PURPOSE, and not because it belongs here. It belongs beside
|
|
4624
|
+
// `dispatchBlockState`, which is where a reader will look for it. Sixty-one line citations elsewhere in
|
|
4625
|
+
// the tree point INTO this file by number, and inserting twenty-three lines near the top moved every one
|
|
4626
|
+
// of them — three onto blank lines, where a guard caught them, and the rest onto real code, where one
|
|
4627
|
+
// guard could not see them and a second one could. Repointing them then rewrote their lines, which put
|
|
4628
|
+
// fifty-four pre-existing bare citations on the ADDED side of the diff and failed the check that refuses
|
|
4629
|
+
// newly-added ones. Appending costs a reader one jump; shifting costs the tree ninety-four citations and
|
|
4630
|
+
// two guards' worth of churn. The same reasoning is written up on the export tagging in bin/onboard.mjs.
|
|
4631
|
+
//
|
|
4632
|
+
// The receipt used to record a builder only when it produced text. An empty return landed in neither
|
|
4633
|
+
// list, so "this run had nothing to flag" and "this builder never ran" were the same reading — and the
|
|
4634
|
+
// second is a defect while the first is an ordinary run. Found in review on the narrative refutation
|
|
4635
|
+
// block: it reached its stage with flags and the stage rewrote none, and the receipt could not be used
|
|
4636
|
+
// to tell that apart from a block that never built.
|
|
4637
|
+
//
|
|
4638
|
+
// TWO EMPTIES, NOT ONE, because collapsing them repeats the fault one size down. A builder that read the
|
|
4639
|
+
// record and found nothing to flag has made a NEGATIVE FINDING; a builder whose source file was not
|
|
4640
|
+
// there has not looked at all. A single `empty` class would make "no flags over forty visible lines"
|
|
4641
|
+
// indistinguishable from "there was no record to open". So a builder returns one of these rather than a
|
|
4642
|
+
// bare "", and a bare "" from a builder nobody has taught to discriminate is recorded as exactly that —
|
|
4643
|
+
// unstated — rather than being counted as either.
|
|
4644
|
+
export const nothingFound = (why) => ({ dispatchEmpty: "nothing-found", why: String(why) });
|
|
4645
|
+
export const nothingToRead = (why) => ({ dispatchEmpty: "nothing-to-read", why: String(why) });
|
|
4646
|
+
|
|
4647
|
+
/** The sentinel a builder returned, or null when it returned something else. PURE. */
|
|
4648
|
+
export const emptyReturn = (v) =>
|
|
4649
|
+
(v && typeof v === "object" && typeof v.dispatchEmpty === "string" && typeof v.why === "string" ? v : null);
|
|
4650
|
+
|
|
4651
|
+
/**
|
|
4652
|
+
* Sort one builder's return into the three lists the receipt carries. Mutates the arrays it is given,
|
|
4653
|
+
* which is what keeps its caller two lines long — and its caller is inside a file whose line numbers
|
|
4654
|
+
* thirty-three citations depend on.
|
|
4655
|
+
*/
|
|
4656
|
+
export function recordEmptyReturn(built, id, { parts, ids, empty }) {
|
|
4657
|
+
const said = emptyReturn(built);
|
|
4658
|
+
if (said) empty.push({ id, kind: said.dispatchEmpty, why: said.why });
|
|
4659
|
+
else if (typeof built === "string" && built) { parts.push(built); ids.push({ id, chars: built.length }); }
|
|
4660
|
+
else empty.push({ id, kind: "empty-unstated", why: "the builder returned nothing and named no reason" });
|
|
4661
|
+
}
|
|
4662
|
+
|
|
4663
|
+
/** Why a builder that ran produced nothing — its own sentence, or null when it is not in that state. PURE. */
|
|
4664
|
+
export function dispatchBlockWhy(ctx, stage, id) {
|
|
4665
|
+
return ctx?.dispatchBlocks?.[stage]?.empty?.find((x) => x.id === id)?.why ?? null;
|
|
4666
|
+
}
|