clearotron 0.3.2-beta.8 → 0.3.2-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +34 -3
- package/CONTRIBUTING.md +8 -8
- package/INSTALL.md +6 -6
- package/SECURITY.md +3 -3
- package/bin/brandowner.mjs +3 -3
- package/bin/framework-preflight.mjs +1 -1
- package/bin/start.mjs +18 -4
- package/build-info.json +2 -2
- package/docs/DELIVERY.md +2 -1
- package/docs/INTAKE.md +1 -1
- package/docs/ONBOARDING.md +1 -1
- package/docs/architecture/03-run-lifecycle.md +6 -6
- package/docs/architecture/04-configuration-reference.md +6 -3
- package/docs/architecture/05-config-governance.md +6 -1
- package/docs/architecture/05-customer-profiles.md +2 -2
- package/docs/architecture/06-operations-runbook.md +3 -3
- package/docs/architecture/08-development-guide.md +6 -6
- package/docs/configuration.md +5 -5
- package/docs/decisions/0003-credential-model.md +1 -1
- package/docs/writing-standard.md +4 -0
- package/driver/CHANGELOG.md +48 -0
- package/driver/README.md +3 -3
- package/driver/binding-layers.mjs +1 -1
- package/driver/citation-census.json +3 -3
- package/driver/{prelim-variants-record.mjs → clearance-variants-record.mjs} +24 -24
- package/driver/common-law-receipts.mjs +2 -2
- package/driver/company-bundle.mjs +3 -3
- package/driver/compose-read.mjs +8 -14
- package/driver/consumption-ledger.mjs +2 -2
- package/driver/contract-arm2-baseline.json +2 -3
- package/driver/contract-dictation-registry.mjs +19 -19
- package/driver/contract-e3-backlog.mjs +19 -19
- package/driver/contract-e3-baseline.json +14 -14
- package/driver/contract-vocabulary.mjs +24 -17
- package/driver/deliver-trigger.sh +16 -16
- package/driver/demo-container.mjs +3 -3
- package/driver/dev-portal.mjs +3 -3
- package/driver/disposition-call.mjs +1 -1
- package/driver/doubt-ledger.mjs +2 -2
- package/driver/drainer-identity.mjs +34 -8
- package/driver/driver.config.mjs +95 -45
- package/driver/engine/mcp/README.md +1 -1
- package/driver/engine/mcp/dispositions-server.mjs +3 -3
- package/driver/engine/mcp/gather-config.mjs +9 -9
- package/driver/engine/mcp/perplexity-server.mjs +2 -2
- package/driver/engine/mcp/recording-server.mjs +5 -5
- package/driver/enqueue-schema.mjs +6 -2
- package/driver/findings-model.mjs +5 -2
- package/driver/flag-snapshot.mjs +6 -3
- package/driver/form-neighbourhood.mjs +54 -7
- package/driver/framework.mjs +4 -4
- package/driver/gateway.mjs +12 -6
- package/driver/jx-lanes.mjs +2 -2
- package/driver/jx-units.mjs +1 -1
- package/driver/jx.mjs +30 -2
- package/driver/knockout-review-record.mjs +56 -4
- package/driver/known-conflicts.mjs +1 -1
- package/driver/named-band.mjs +1 -33
- package/driver/ordinary-words.mjs +51 -0
- package/driver/outbox-backoff.mjs +31 -16
- package/driver/package.json +1 -1
- package/driver/partial-payload-baseline.json +2 -2
- package/driver/phase0.mjs +3 -3
- package/driver/pipeline-knockout.mjs +5 -5
- package/driver/pipeline.mjs +206 -68
- package/driver/placement-form.mjs +77 -1
- package/driver/placement-model.mjs +1 -1
- package/driver/portal-report.mjs +92 -5
- package/driver/portal-service.mjs +34 -8
- package/driver/portal-upstream.mjs +1 -1
- package/driver/preserve-merge.mjs +3 -3
- package/driver/product-rows.mjs +2 -2
- package/driver/products.mjs +1 -1
- package/driver/profiles/README.md +3 -3
- package/driver/profiles/demo-brand-owner.json +2 -2
- package/driver/profiles.mjs +55 -17
- package/driver/progress.mjs +18 -8
- package/driver/provider-usage.mjs +8 -8
- package/driver/publish/index.mjs +110 -5
- package/driver/publish/knockout.mjs +29 -4
- package/driver/publish/pool-admin.mjs +1 -1
- package/driver/publish/publish-inputs.mjs +18 -2
- package/driver/publish/render-knockout.mjs +115 -24
- package/driver/publish/render.mjs +153 -34
- package/driver/publish/search-depth.mjs +133 -4
- package/driver/publish/templates/report.css +60 -3
- package/driver/publish/xlsx.mjs +8 -1
- package/driver/queue-order.mjs +2 -2
- package/driver/recording-agreement.mjs +1 -1
- package/driver/reference-score.mjs +1 -1
- package/driver/register-count.mjs +50 -5
- package/driver/register-coverage.mjs +67 -0
- package/driver/register-grant-vocabulary.mjs +1 -1
- package/driver/register-plan.mjs +19 -2
- package/driver/registry-fidelity.mjs +3 -3
- package/driver/repair-composers.mjs +1 -1
- package/driver/repair-contract.mjs +1 -1
- package/driver/replay-archive.mjs +6 -6
- package/driver/report-overview-record.mjs +2 -2
- package/driver/run-requirements.mjs +3 -3
- package/driver/runner.mjs +2 -2
- package/driver/scope-facts.mjs +20 -5
- package/driver/scope-ledger.mjs +5 -5
- package/driver/search-policy.mjs +22 -12
- package/driver/skills/README.md +15 -15
- package/driver/skills/blind-frame/SKILL.md +2 -2
- package/driver/skills/case-law-citation/SKILL.md +4 -4
- package/driver/skills/case-law-citation/sources/eurlex.md +1 -1
- package/driver/skills/{prelim-common-law → clearance-common-law}/SKILL.md +22 -22
- package/driver/skills/{prelim-common-law → clearance-common-law}/perplexity-prompts.md +1 -1
- package/driver/skills/{prelim-register → clearance-register}/SKILL.md +10 -10
- package/driver/skills/{prelim-register → clearance-register}/digest.md +2 -2
- package/driver/skills/{prelim-register → clearance-register}/providers/README.md +1 -1
- package/driver/skills/{prelim-register → clearance-register}/providers/clarivate.md +37 -35
- package/driver/skills/{prelim-register → clearance-register}/providers/corsearch.md +20 -11
- package/driver/skills/{prelim-register → clearance-register}/providers/signa.md +5 -5
- package/driver/skills/{prelim-register → clearance-register}/register-recipes.md +3 -3
- package/driver/skills/{prelim-register → clearance-register}/status-rules.md +2 -2
- package/driver/skills/{prelim-register → clearance-register}/stealth-filer-indicators.md +1 -1
- package/driver/skills/{prelim-register → clearance-register}/unit.md +2 -2
- package/driver/skills/{prelim-search → clearance-search}/SKILL.md +31 -31
- package/driver/skills/{prelim-search → clearance-search}/delivery-contract.md +1 -1
- package/driver/skills/{prelim-search → clearance-search}/phase2-execution.md +18 -18
- package/driver/skills/{prelim-search → clearance-search}/synthesis-rules.md +7 -7
- package/driver/skills/{prelim-variants → clearance-variants}/SKILL.md +18 -18
- package/driver/skills/{prelim-variants → clearance-variants}/transliteration-scripts.md +5 -5
- package/driver/skills/frame-diff/SKILL.md +1 -1
- package/driver/skills/knockout-assess/SKILL.md +10 -7
- package/driver/skills/matter-frame/SKILL.md +3 -3
- package/driver/skills/narrative-refutation/SKILL.md +9 -9
- package/driver/skills/placement-inquiry/SKILL.md +5 -5
- package/driver/stage-context.mjs +1 -1
- package/driver/stages-knockout.mjs +4 -4
- package/driver/stages.mjs +53 -53
- package/driver/status-snapshot.mjs +2 -2
- package/driver/suite-census.json +218 -92
- package/driver/surface-exit-verdict.mjs +58 -0
- package/driver/systemd/README.md +2 -2
- package/driver/systemd/clearotron-worker.service +1 -1
- package/driver/terminal-clamp.mjs +2 -0
- package/driver/usage-ledger.mjs +1 -1
- package/driver/variant-manifest-model.mjs +4 -4
- package/driver/verify-knockout.mjs +27 -0
- package/driver/verify.mjs +67 -6
- package/driver/whatif-queue.mjs +1 -1
- package/driver/wordlists/en.txt +63906 -0
- package/mcp-server/CHANGELOG.md +4 -0
- package/mcp-server/README.md +1 -1
- package/mcp-server/lib/README.md +1 -1
- package/mcp-server/lib/options.mjs +8 -7
- package/mcp-server/lib/plan.mjs +18 -2
- package/mcp-server/lib/runs.mjs +1 -1
- package/mcp-server/lib/usage.mjs +3 -3
- package/mcp-server/lib/whatif.mjs +1 -1
- package/mcp-server/package.json +1 -1
- package/mcp-server/server.mjs +3 -0
- package/package.json +12 -11
- package/portal-ui/dist/assets/{index-CVOIvdhc.css → index-CtvwLCti.css} +207 -3
- package/portal-ui/dist/assets/{index-6jzO9HiX.js → index-EVaSo5-g.js} +1459 -482
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/README.md +1 -1
- package/providers/_shared/enumerate.mjs +6 -6
- package/providers/_shared/execute-plan.mjs +3 -3
- package/providers/_shared/ledger.mjs +119 -5
- package/providers/_shared/provider-text.mjs +2 -2
- package/providers/_shared/screen.mjs +2 -2
- package/providers/_shared/script-form.mjs +3 -3
- package/providers/_shared/territory-codes.mjs +23 -3
- package/providers/clarivate/README.md +1 -1
- package/providers/clarivate/src/capabilities.js +12 -12
- package/providers/clarivate/src/core.js +37 -43
- package/providers/corsearch/README.md +1 -1
- package/providers/corsearch/src/capabilities.js +5 -5
- package/providers/corsearch/src/core.js +3 -3
- package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/perplexity/src/core.js +1 -1
- package/providers/signa/README.md +1 -1
- package/providers/signa/src/capabilities.js +42 -49
- package/providers/signa/src/core.js +106 -29
- package/providers/uspto-local/src/sync.js +1 -1
- package/scripts/README.md +1 -0
- package/scripts/ask-ai-render-check.mjs +127 -1
- package/scripts/authority-boundary-probe.mjs +4 -4
- package/scripts/backfill-started-at.mjs +2 -2
- package/scripts/census-merge-driver.mjs +33 -2
- package/scripts/citation-anchor-report.mjs +181 -0
- package/scripts/dead-names.mjs +1 -1
- package/scripts/deprecate-below.mjs +66 -8
- package/scripts/drain-preflight.mjs +1 -1
- package/scripts/e2e.mjs +174 -0
- package/scripts/env-audit.mjs +27 -0
- package/scripts/env-classify.mjs +20 -2
- package/scripts/freeze-example-run.mjs +20 -10
- package/scripts/live-surface-check.mjs +124 -41
- package/scripts/markdown-link-check.mjs +1 -1
- package/scripts/merge-shape-check.mjs +242 -0
- package/scripts/mint-names-in-force.mjs +5 -5
- package/scripts/mint-offered-territories.mjs +72 -0
- package/scripts/mint-public-residue.mjs +2 -2
- package/scripts/mint-reference-strip-backlog.mjs +2 -2
- package/scripts/mint-suite-census.mjs +75 -2
- package/scripts/mint-writing-standard-backlog.mjs +2 -2
- package/scripts/purge-runs.mjs +7 -7
- package/scripts/reconcile-runs.mjs +2 -2
- package/scripts/release-approve-parked.mjs +20 -2
- package/scripts/release-await-cut.mjs +120 -1
- package/scripts/release-note-required.mjs +76 -8
- package/scripts/report-header-render-check.mjs +164 -0
- package/shared/brand.mjs +27 -0
- package/shared/connect-clients.mjs +39 -11
- package/shared/env-aliases.mjs +1 -1
- package/shared/identifier-scan.mjs +65 -9
- package/shared/identifier-sentinels.mjs +22 -0
- package/shared/names-in-force.mjs +3 -1
- package/shared/offered-territories.json +738 -0
- package/shared/pre-rename-spellings.mjs +53 -0
- package/shared/reference-guard-classes.mjs +40 -2
- package/shared/stdio-connect.mjs +39 -4
- package/shared/tree-commit.mjs +48 -0
- /package/driver/skills/{prelim-register → clearance-register}/providers/euipo.md +0 -0
- /package/driver/skills/{prelim-register → clearance-register}/providers/free-tier.md +0 -0
- /package/driver/skills/{prelim-register → clearance-register}/providers/uspto-local.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/field-doctrine-pharma.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/firm-wide-reasoning.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/report-prose.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework-demo.manifest.json +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework-demo.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.manifest.json +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework-triage.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework.manifest.json +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/risk-framework.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/template-formatting.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/templates/email/generic.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/templates/search-request-form.html +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/worked-examples-demo.md +0 -0
- /package/driver/skills/{prelim-search → clearance-search}/worked-examples.md +0 -0
package/.env.example
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# =============================================================================
|
|
2
2
|
# example.com-trademark — canonical environment contract (.env.example)
|
|
3
3
|
# =============================================================================
|
|
4
|
-
# The
|
|
4
|
+
# The clearance-search product reads all of its configuration + credentials from
|
|
5
5
|
# the environment. In production these live in the systemd EnvironmentFile
|
|
6
6
|
# (`~/.env`, loaded as whichever service account runs the engine); in dev they are
|
|
7
7
|
# exported before the run. This file is the DOCUMENTED CONTRACT — copy it to
|
|
@@ -86,6 +86,7 @@ CLEAROTRON_AI=anthropic-agent
|
|
|
86
86
|
# write the path of setup's copy here: it would become the forced copy, and one installed later would never
|
|
87
87
|
# be used. A path set here must be ABSOLUTE: stage subprocesses run with cwd set to the run directory.
|
|
88
88
|
# Only the live engine's value is read, so a machine that runs both engines can set both.
|
|
89
|
+
# effect: setup
|
|
89
90
|
CLEAROTRON_CLAUDE_PATH=claude
|
|
90
91
|
|
|
91
92
|
# ── openai-agent (codex) knobs — ONLY read when CLEAROTRON_AI=openai-agent ────────────────────────
|
|
@@ -93,7 +94,9 @@ CLEAROTRON_CLAUDE_PATH=claude
|
|
|
93
94
|
# overwriting the other — these were one variable until that collapse met a box needing two different
|
|
94
95
|
# paths, and this file shipped two live rows for the single name until then (a last-wins assignment in
|
|
95
96
|
# the copied `.env`, not a choice).
|
|
97
|
+
# effect: setup
|
|
96
98
|
CLEAROTRON_CODEX_PATH=codex
|
|
99
|
+
|
|
97
100
|
CLEAROTRON_WORK_DIR=
|
|
98
101
|
# Customer/project config store (loadProfiles). Unset ⇒ driver's built-in profiles dir.
|
|
99
102
|
CLEAROTRON_CUSTOMERS_DIR=
|
|
@@ -103,15 +106,28 @@ CLEAROTRON_INSTRUCTIONS_DIR=
|
|
|
103
106
|
# REQUIRED — the code default was removed. Unset, the engine refuses and names this variable instead
|
|
104
107
|
# of falling back to /srv/trademark-archive, which on a deployed box is real client matter.
|
|
105
108
|
CLEAROTRON_REPORTS_DIR=/srv/trademark-archive
|
|
106
|
-
# Run-slot lock dir. Default = $CLEAROTRON_WORK_DIR/
|
|
109
|
+
# Run-slot lock dir. Default = $CLEAROTRON_WORK_DIR/clearance-run-locks. Every run takes a slot here,
|
|
107
110
|
# whether the runner dispatched it or somebody launched it by hand, so this is what bounds concurrency
|
|
108
111
|
# across an install rather than within one process. The portal also reads it to find the worker
|
|
109
112
|
# heartbeat; two installs pointed at one lock dir would share a cap they do not expect to.
|
|
110
113
|
# effect: deployment
|
|
111
114
|
CLEAROTRON_RUN_LOCK_DIR=
|
|
112
|
-
# Delivery outbox dir (instant handoff-mode delivery wake). Default = $CLEAROTRON_WORK_DIR/
|
|
115
|
+
# Delivery outbox dir (instant handoff-mode delivery wake). Default = $CLEAROTRON_WORK_DIR/clearance-outbox.
|
|
116
|
+
# Was `prelim-outbox`. A box that never set this keeps its markers there and they are still read and drained;
|
|
117
|
+
# new markers are written under the new name. Nothing to move.
|
|
113
118
|
# effect: deployment
|
|
114
119
|
CLEAROTRON_OUTBOX_DIR=
|
|
120
|
+
# Where the shared register CALL ledger lives — the per-query record the register spend is counted from.
|
|
121
|
+
# Default = ~/trademark/telemetry/register-calls.jsonl. An install that moves or clears it changes what a
|
|
122
|
+
# later cost read can account for, and nothing else records where it went.
|
|
123
|
+
# effect: deployment
|
|
124
|
+
CLEAROTRON_REGISTER_CALL_LOG=
|
|
125
|
+
# Where the register RECORD log lives — the fetched-record store a "verified from the record" claim on a
|
|
126
|
+
# report joins against. Resolved by EXISTENCE over several directories and filenames, not by name alone,
|
|
127
|
+
# so that an install which inherited an older path keeps reading its own ledger; setting this overrides
|
|
128
|
+
# that ladder outright. An install pointed at an empty path reports no fetched records and no fault.
|
|
129
|
+
# effect: deployment
|
|
130
|
+
CLEAROTRON_REGISTER_RECORD_LOG=
|
|
115
131
|
# HEADLESS intake: one explicit queue dir (no agent workspaces needed) — the enqueue CLI + ops-MCP
|
|
116
132
|
# start_run write here and the runner drains it (additive to the workspace scan). See docs/INTAKE.md.
|
|
117
133
|
CLEAROTRON_QUEUE_DIR=
|
|
@@ -481,6 +497,21 @@ CLEAROTRON_CUT_REF=
|
|
|
481
497
|
# effect: tuning
|
|
482
498
|
CLEAROTRON_RELEASE_WAIT_MS=
|
|
483
499
|
|
|
500
|
+
# Whether this release run was dispatched to cut. The workflow sets `true` on a `workflow_dispatch` that
|
|
501
|
+
# is not a rehearsal, and `false` otherwise. Set, a wait that expires with no version published is a
|
|
502
|
+
# failure that names why, because the one thing the run was dispatched for did not happen; a push or the
|
|
503
|
+
# schedule asks nothing of the wait, so expiry there stays a quiet success. Read by
|
|
504
|
+
# scripts/release-await-cut.mjs.
|
|
505
|
+
# effect: tuning
|
|
506
|
+
CLEAROTRON_CUT_REQUESTED=
|
|
507
|
+
|
|
508
|
+
# The number of the version pull request the same run opened, so a failed wait reads why that pull
|
|
509
|
+
# request did not merge rather than guessing. The workflow sets it from the version job's output. Unset,
|
|
510
|
+
# or not a whole number, a dispatched wait says it found no pull request to wait on. Read by
|
|
511
|
+
# scripts/release-await-cut.mjs.
|
|
512
|
+
# effect: tuning
|
|
513
|
+
CLEAROTRON_CUT_PR=
|
|
514
|
+
|
|
484
515
|
# A GitHub token carrying Actions read and write. The release workflow supplies it from a repository
|
|
485
516
|
# secret so that a cut does not wait for a person to approve the version pull request's parked CI run:
|
|
486
517
|
# that run is authored by the repository's own Actions bot, and GitHub parks bot-authored runs as
|
package/CONTRIBUTING.md
CHANGED
|
@@ -54,7 +54,7 @@ Four more things run for free:
|
|
|
54
54
|
| Command | What it proves |
|
|
55
55
|
|---|---|
|
|
56
56
|
| `node mcp-server/smoke.mjs` | Drives the real MCP server over stdio against a built fixture. Prints `SMOKE OK`. |
|
|
57
|
-
| `node driver/dev-portal.mjs` | Serves a pool at `http://127.0.0.1:18899/` — archive index, reports,
|
|
57
|
+
| `node driver/dev-portal.mjs` | Serves a pool at `http://127.0.0.1:18899/` — archive index, reports, company pages. Loopback only; it refuses any other host. Needs a pool to point at (`CLEAROTRON_REPORTS_DIR`). |
|
|
58
58
|
| The $0 mock pipeline | A full run — intake, every stage, publish, delivery packet — on a mocked engine. Recipe in [docs/E2E.md § Tier 1](docs/E2E.md). Follow it as written; the absolute-path trap in it catches everybody. |
|
|
59
59
|
| `npx clearotron demo` | Replays `demo/` — a real run on a fictional mark — through the real publisher into `~/trademark-demo/pool` and serves it. No keys, no model, no engine. |
|
|
60
60
|
|
|
@@ -75,7 +75,7 @@ half did not run. `npx clearotron install` walks through both, and
|
|
|
75
75
|
[INSTALL.md § 1](INSTALL.md#1-prerequisites) is the full list.
|
|
76
76
|
|
|
77
77
|
**The scenario suite is private by design.** `scripts/e2e.mjs` scores runs against lawyer-written
|
|
78
|
-
reference answers on real matters; the references and the config store they load from are
|
|
78
|
+
reference answers on real matters; the references and the config store they load from are company work
|
|
79
79
|
product and will not be published. Its absence weakens nothing you can run — the in-repo suite covers
|
|
80
80
|
the machinery, and the scenario suite covers the answers. The validation ladder, from the $0 offline
|
|
81
81
|
suite to a paid live run, is [docs/E2E.md](docs/E2E.md).
|
|
@@ -130,13 +130,13 @@ The reviewer is the check. Say what you checked in the PR rather than citing a p
|
|
|
130
130
|
**3. Types are enforced, and `vite build` does not typecheck.** `npm run typecheck -w portal-ui`
|
|
131
131
|
runs as its own CI step. Run it before you push.
|
|
132
132
|
|
|
133
|
-
**4. Every sentence a
|
|
133
|
+
**4. Every sentence a company reads is written against the standard, and five classes of it are
|
|
134
134
|
checked.** The standard is [`docs/writing-standard.md`](docs/writing-standard.md); the prose rules
|
|
135
135
|
under it are [`docs/writing-rules.md`](docs/writing-rules.md), and they apply first. Together they
|
|
136
136
|
bind report HTML, portal screens, the README and the docs.
|
|
137
137
|
|
|
138
138
|
`node scripts/writing-standard-check.mjs` refuses what your change ADDS to one of those surfaces:
|
|
139
|
-
an engineering identifier in text a
|
|
139
|
+
an engineering identifier in text a company reads, a reviewer-only marker in rendered output, a known
|
|
140
140
|
caveat sentence, a screen that writes its own page heading instead of using `PageHeader`, and a lede
|
|
141
141
|
whose words are all already in its title. It names the class and prints the line. It never rewrites —
|
|
142
142
|
a rewritten sentence is a sentence nobody reviewed.
|
|
@@ -153,7 +153,7 @@ identifier, no caveat and no banned word and still be the thing the standard exi
|
|
|
153
153
|
heading that restates its section, a paragraph explaining what the reader can already see, a sentence
|
|
154
154
|
that only works if you know how the engine is built.
|
|
155
155
|
|
|
156
|
-
So: **a pull request that changes text a
|
|
156
|
+
So: **a pull request that changes text a company reads is reviewed against the rendered page or
|
|
157
157
|
report, not against the diff.** One reviewer reads it as someone who has never seen this product and
|
|
158
158
|
asks one question of every new sentence — *what would a reader with zero context think this means?*
|
|
159
159
|
If the answer needs the codebase, the sentence is cut or rewritten. One reviewer, one question,
|
|
@@ -288,9 +288,9 @@ narrower is usually the defect rather than the fix, and it will be read that way
|
|
|
288
288
|
|
|
289
289
|
### The three possible outcomes
|
|
290
290
|
|
|
291
|
-
**Into the base layer.** Your change becomes part of what every install gets, including ours and
|
|
292
|
-
|
|
293
|
-
for, not only for yours.
|
|
291
|
+
**Into the base layer.** Your change becomes part of what every install gets, including ours and the
|
|
292
|
+
installs we run for companies. That is the highest bar: it has to be an improvement for the matters
|
|
293
|
+
this doctrine is tuned for, not only for yours.
|
|
294
294
|
|
|
295
295
|
**Published as a pack.** Doctrine resolves file by file — an install can point at another directory and
|
|
296
296
|
have its files win, with everything it does not override falling through to ours. So a change that is
|
package/INSTALL.md
CHANGED
|
@@ -153,7 +153,7 @@ passed, and nothing has driven a live register through it.
|
|
|
153
153
|
|
|
154
154
|
**Upgrading an install made before 0.2.2: pin the agent id first.** The default agent id changed from
|
|
155
155
|
`clawdi` to `localagent`, and that id is part of a path — your runs live under
|
|
156
|
-
`<workspaceRoot>/workspace-<agent>/studio/
|
|
156
|
+
`<workspaceRoot>/workspace-<agent>/studio/clearance-search/`. If you never set an agent id, the upgraded
|
|
157
157
|
install reads a workspace that does not exist yet, and an empty workspace looks like an account with no
|
|
158
158
|
runs rather than like a misconfiguration. Set **both** names in your environment file before starting
|
|
159
159
|
it, because the register-search servers read their own:
|
|
@@ -624,12 +624,12 @@ a bespoke risk framework. A job resolves to a profile by the **forwarder's email
|
|
|
624
624
|
matches, the neutral Generic default applies.
|
|
625
625
|
|
|
626
626
|
- **Bundled with the package** (`driver/profiles/`): `generic.json` (the Generic default) and
|
|
627
|
-
`demo-brand-owner.json`, the
|
|
627
|
+
`demo-brand-owner.json`, the company the demo runs as, so you can run and read the machinery
|
|
628
628
|
immediately. `driver/profiles/README.md` documents every field. (A clone of the repository carries
|
|
629
629
|
three more, marked `testFixture` in their own files: the test suite reads them, no install offers
|
|
630
630
|
them, and they are excluded from the published package as well.)
|
|
631
631
|
- **Your real companies live outside the repo.** Point `CLEAROTRON_CUSTOMERS_DIR` at your own private
|
|
632
|
-
config store and the engine loads *those*
|
|
632
|
+
config store and the engine loads *those* companies instead. **Same engine, different config path** —
|
|
633
633
|
the code carries no company identities.
|
|
634
634
|
|
|
635
635
|
Two things go with it, and both are refusals rather than preferences:
|
|
@@ -661,7 +661,7 @@ self-contained.
|
|
|
661
661
|
A company is not only its `<key>.json`. Two more things sit beside it, both optional, both shipped as
|
|
662
662
|
working examples in `driver/profiles/`:
|
|
663
663
|
|
|
664
|
-
- **A context pack** — `<key>.context.md`, a sibling of the profile. Free prose about the
|
|
664
|
+
- **A context pack** — `<key>.context.md`, a sibling of the profile. Free prose about the company that
|
|
665
665
|
the engine attaches to the profile it loads. One ships beside a bundled demo company.
|
|
666
666
|
- **Project overlays** — `projects/<customer-key>/<slug>.json`. A project is one engagement under a
|
|
667
667
|
company: a launch screening, a flagship clearance, a regional push. Each may carry its own
|
|
@@ -689,7 +689,7 @@ overlay stating `defaultClasses` narrows to exactly what it states.
|
|
|
689
689
|
|
|
690
690
|
**Setting `CLEAROTRON_CUSTOMERS_DIR` replaces the whole tree, projects included.** The engine reads your
|
|
691
691
|
store's companies and your store's `projects/`, and none of ours. That is deliberate — a deployment's
|
|
692
|
-
roster holds its own
|
|
692
|
+
roster holds its own companies and nothing of ours — but it is silent, and it is the one thing here that
|
|
693
693
|
becomes an incident on a real deployment rather than a bundled one:
|
|
694
694
|
|
|
695
695
|
- A job naming a project your store does not carry is **not refused**. The `projectKey` is dropped and
|
|
@@ -1364,7 +1364,7 @@ A courier is a loop over one directory, and it needs no unit of its own if you a
|
|
|
1364
1364
|
|
|
1365
1365
|
1. **Watch the outbox** — `$CLEAROTRON_OUTBOX_DIR`. A `.pending` file appears there when a run
|
|
1366
1366
|
finishes. Read the variable rather than guessing the directory: the wizard writes `<data
|
|
1367
|
-
base>/outbox`, but an unset variable falls back to `
|
|
1367
|
+
base>/outbox`, but an unset variable falls back to `clearance-outbox` under the workspace root
|
|
1368
1368
|
(`driver/driver.config.mjs`), so the two are not the same path and only one of them is where your
|
|
1369
1369
|
markers are.
|
|
1370
1370
|
2. **Read what it points at.** A success marker is a few bytes naming the agent, *not* the payload —
|
package/SECURITY.md
CHANGED
|
@@ -26,7 +26,7 @@ affected versions, and a fix or a written decision not to fix. We will credit yo
|
|
|
26
26
|
ask us not to.
|
|
27
27
|
|
|
28
28
|
**Never attach a run artifact to a report.** Reports, audit workbooks, run directories and pool
|
|
29
|
-
contents can carry
|
|
29
|
+
contents can carry company names, marks and matters. Describe the shape of the data instead, or
|
|
30
30
|
reproduce it against the repo's synthetic fixtures.
|
|
31
31
|
|
|
32
32
|
## What is in scope
|
|
@@ -42,8 +42,8 @@ In particular, we want to hear about anything that breaks these:
|
|
|
42
42
|
- **Fail-closed construction.** The HTTP face refuses to start without an audience, an issuer, and an
|
|
43
43
|
identity gate. Any path that serves a request with authentication silently absent is in scope.
|
|
44
44
|
- **The dev portal's loopback bind.** `driver/dev-portal.mjs` must refuse every non-loopback host.
|
|
45
|
-
- **
|
|
46
|
-
rendered into a report or a
|
|
45
|
+
- **Company-facing surfaces leaking internals.** An env var name, a switch name, or an internal path
|
|
46
|
+
rendered into a report or a company-visible error.
|
|
47
47
|
- **Traversal and injection** into artifact reads, pool paths, or run directories.
|
|
48
48
|
|
|
49
49
|
[`docs/SECURITY.md`](docs/SECURITY.md) documents the whole envelope — what protects what, and where
|
package/bin/brandowner.mjs
CHANGED
|
@@ -113,7 +113,7 @@ const USAGE = `
|
|
|
113
113
|
--domains comma-separated email domains that resolve to this owner
|
|
114
114
|
--platforms comma-separated marketplaces their searches cover
|
|
115
115
|
omitted ⇒ the Generic default's platforms are applied and named in the output
|
|
116
|
-
--framework their risk framework, as skills/
|
|
116
|
+
--framework their risk framework, as skills/clearance-search/<file>.md
|
|
117
117
|
omitted ⇒ the Generic default is applied and named in the output
|
|
118
118
|
--industry free text, shown on their profile
|
|
119
119
|
--context a file whose contents become this owner's context pack
|
|
@@ -121,7 +121,7 @@ const USAGE = `
|
|
|
121
121
|
|
|
122
122
|
clearotron brandowner framework <key> <path>
|
|
123
123
|
|
|
124
|
-
Point an existing company at a risk framework, as skills/
|
|
124
|
+
Point an existing company at a risk framework, as skills/clearance-search/<file>.md.
|
|
125
125
|
The deck is checked before anything is written: a path that does not resolve, or a
|
|
126
126
|
manifest that will not load, is refused and the company is left exactly as it was.
|
|
127
127
|
|
|
@@ -298,7 +298,7 @@ export async function framework(argv, {
|
|
|
298
298
|
} = {}) {
|
|
299
299
|
const [key, path] = argv;
|
|
300
300
|
if (!key) throw new Refusal(`this command needs a company key.${USAGE}`);
|
|
301
|
-
if (!path) throw new Refusal(`this command needs a framework path, as skills/
|
|
301
|
+
if (!path) throw new Refusal(`this command needs a framework path, as skills/clearance-search/<file>.md.${USAGE}`);
|
|
302
302
|
try { assertProfileKey(key); }
|
|
303
303
|
catch (e) { throw new Refusal(e?.message ?? String(e)); }
|
|
304
304
|
|
|
@@ -20,7 +20,7 @@ import { invocationPrefix } from "../shared/invocation.mjs";
|
|
|
20
20
|
import { preflightFramework, formatPreflight } from "../driver/framework-preflight.mjs";
|
|
21
21
|
|
|
22
22
|
const USAGE = (cmd) => `
|
|
23
|
-
${cmd} framework <skills/
|
|
23
|
+
${cmd} framework <skills/clearance-search/your-framework.md>
|
|
24
24
|
|
|
25
25
|
Reads a risk framework deck and the manifest beside it, and reports what they declare —
|
|
26
26
|
the ladder, the company the deck names, the shape, and which file answered where.
|
package/bin/start.mjs
CHANGED
|
@@ -113,6 +113,7 @@ export async function runTables() {
|
|
|
113
113
|
import { spawn, spawnSync, execFileSync } from "node:child_process";
|
|
114
114
|
import { storeInRepo, storeOutsideRepoMessage, storeCommitRefusal } from "../shared/store-in-repo.mjs"; //
|
|
115
115
|
import { stdioConnectOffer } from "../shared/stdio-connect.mjs";
|
|
116
|
+
import { wslTarget } from "../shared/wsl.mjs"; // — and which distribution a row should start the server in
|
|
116
117
|
import { ensureDemoProgram } from "../shared/permanent-install.mjs"; // — a demo from npx keeps its own copy
|
|
117
118
|
import { mergeEnvFile } from "../shared/env-file-merge.mjs";
|
|
118
119
|
import { mcpOriginFor } from "../shared/lane-address.mjs"; // — one author for the origin
|
|
@@ -2522,11 +2523,24 @@ if (isMain) {
|
|
|
2522
2523
|
// THE WORKSPACE AND POOL THE SERVICES WERE HANDED, not this process's environment: a demo reads no env
|
|
2523
2524
|
// file, so its own line named no workspace and the connector fell back to the real install's.
|
|
2524
2525
|
// A demo run from npx names its own copy of the program, which a cache clean does not remove.
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2526
|
+
// AND WHICH SIDE OF A WSL INSTALL THE READER IS ON, because this is where he read the line from. An
|
|
2527
|
+
// install inside WSL can be reached from Windows and from inside the distribution, by two different
|
|
2528
|
+
// commands; printing one of them unheaded is how a reader pastes the wrong one. The target is read
|
|
2529
|
+
// here and passed, because this module is pure by design and reads no environment of its own.
|
|
2530
|
+
const connect = stdioConnectOffer({ workDir: paths.workspace, reportsDir: paths.pool, wsl: wslTarget(), ...(demoProgramRoot ? { installRoot: demoProgramRoot } : {}) });
|
|
2531
|
+
// "one line" IS DELETED RATHER THAN MADE CONDITIONAL. Under WSL two lines are printed, one per side,
|
|
2532
|
+
// and the count was never the point of the sentence — what it promises is no address and no sign-in,
|
|
2533
|
+
// which is true on both sides and on every other install.
|
|
2534
|
+
say(" Connect your assistant to this install — no address and no sign-in:");
|
|
2529
2535
|
say("");
|
|
2536
|
+
// THE HEADINGS COME WITH THE PAIR, from the composer. Nothing is written here: the page prints these
|
|
2537
|
+
// same two words above these same two commands, and a second author is how the two surfaces drift.
|
|
2538
|
+
if (connect.variants) {
|
|
2539
|
+
for (const v of connect.variants) { say(` ${v.heading}`); say(` ${v.text}`); say(""); }
|
|
2540
|
+
} else {
|
|
2541
|
+
say(` ${connect.command}`);
|
|
2542
|
+
say("");
|
|
2543
|
+
}
|
|
2530
2544
|
say(` Check it: ${connect.verify}`);
|
|
2531
2545
|
say("");
|
|
2532
2546
|
// ── WHERE TO TYPE THE THINGS JUST PRINTED ( — F31) ───────────────────────
|
package/build-info.json
CHANGED
package/docs/DELIVERY.md
CHANGED
|
@@ -18,7 +18,8 @@ ignores the value.
|
|
|
18
18
|
|
|
19
19
|
## The outbox
|
|
20
20
|
|
|
21
|
-
`config.outboxDir` = `CLEAROTRON_OUTBOX_DIR` (default `<CLEAROTRON_WORK_DIR>/
|
|
21
|
+
`config.outboxDir` = `CLEAROTRON_OUTBOX_DIR` (default `<CLEAROTRON_WORK_DIR>/clearance-outbox`; the
|
|
22
|
+
earlier `clearance-outbox` is still read, so markers written before the rename still drain).
|
|
22
23
|
All packets are written atomically (`.tmp` + rename) — a watcher never sees a half-written
|
|
23
24
|
file. Every packet carries a `ts` ISO timestamp. Watch the dir for `*.pending` (systemd
|
|
24
25
|
`.path`, inotify, or poll); a periodic scan of run `status.json` files is the recommended
|
package/docs/INTAKE.md
CHANGED
|
@@ -23,7 +23,7 @@ Resolution (the runner drains **all** of these; `config.queueDirs`):
|
|
|
23
23
|
| Source | Path | Use |
|
|
24
24
|
|---|---|---|
|
|
25
25
|
| `CLEAROTRON_QUEUE_DIR` env | one explicit dir | **headless deployments** (the product default; no agent workspaces needed). Jobs here run as `config.defaultAgent`. |
|
|
26
|
-
| workspace scan | `<CLEAROTRON_WORK_DIR>/workspace-<agent>/studio/
|
|
26
|
+
| workspace scan | `<CLEAROTRON_WORK_DIR>/workspace-<agent>/studio/clearance-search/queue` | legacy/agent-adjacent deployments; the agent identity is derived from the queue location |
|
|
27
27
|
|
|
28
28
|
The enqueue CLI resolves its target the same way: `--queue-dir` flag → `CLEAROTRON_QUEUE_DIR` →
|
|
29
29
|
the default agent's workspace queue.
|
package/docs/ONBOARDING.md
CHANGED
|
@@ -32,7 +32,7 @@ malformed one is refused before anything is written.
|
|
|
32
32
|
| `--name` | the legal name. Required. |
|
|
33
33
|
| `--domains` | comma-separated email domains that resolve to this company |
|
|
34
34
|
| `--platforms` | marketplaces their searches cover. Omitted, the default's platforms apply and are named in the output. |
|
|
35
|
-
| `--framework` | their risk framework, as `skills/
|
|
35
|
+
| `--framework` | their risk framework, as `skills/clearance-search/<file>.md`. Omitted, the default applies and is named in the output. |
|
|
36
36
|
| `--industry` | free text, shown on their profile |
|
|
37
37
|
| `--context` | a file whose contents become this company's context pack |
|
|
38
38
|
| `--dry-run` | say exactly what would be written, and write nothing |
|
|
@@ -27,7 +27,7 @@ Two doctrines govern everything below:
|
|
|
27
27
|
sequenceDiagram
|
|
28
28
|
autonumber
|
|
29
29
|
participant A as Forwarding agent<br/>(integrator platform)
|
|
30
|
-
participant Q as Per-agent queue dir<br/>(studio/
|
|
30
|
+
participant Q as Per-agent queue dir<br/>(studio/clearance-search/queue)
|
|
31
31
|
participant S as systemd<br/>(.path + 90s .timer)
|
|
32
32
|
participant R as runner.mjs
|
|
33
33
|
participant P as pipeline.mjs
|
|
@@ -89,7 +89,7 @@ an unknown company proceeds on the generic profile with a late-bind watch (§4).
|
|
|
89
89
|
|
|
90
90
|
**Matter-level dedup** (`runner.mjs`). Queue-file dedup is per *message*; a "please
|
|
91
91
|
proceed" reply in an already-handled thread arrives under a new message-id. The driver therefore
|
|
92
|
-
keeps a matter ledger (`studio/
|
|
92
|
+
keeps a matter ledger (`studio/clearance-search/.matter-ledger.jsonl`) and parks as `.duplicate` any
|
|
93
93
|
job within the window (a fixed 24 hours) that matches a prior entry by
|
|
94
94
|
exact signature (`forwarder|mark|classes|customer|ref`, plus a `|level:<product>` dimension on any
|
|
95
95
|
non-baseline product) or by same conversation-thread with agreeing mark *and* agreeing product. The
|
|
@@ -108,7 +108,7 @@ winner (`runner.mjs`). A `.pid` sidecar records `<pid>:<starttime>` (starttime t
|
|
|
108
108
|
**Run identity is minted before any spend.** The codename (`adjective-noun`) is minted at dispatch
|
|
109
109
|
and written atomically to `<id>.processing.meta` *before* the pipeline starts (`runner.mjs`).
|
|
110
110
|
A crash anywhere after that resumes the *same* run directory instead of re-spending a fresh run.
|
|
111
|
-
Run dirs are `<workspace>/studio/
|
|
111
|
+
Run dirs are `<workspace>/studio/clearance-search/<slug>/<date>-<codename>`, slug =
|
|
112
112
|
`tmp<n>-<kebab-mark>` (or `noref<6-hex>-<mark>` when no reference was given; `phase0.mjs`).
|
|
113
113
|
|
|
114
114
|
**Orphan reclaim** (`runner.mjs`) runs once per drain. A `.processing` whose claimer is
|
|
@@ -177,7 +177,7 @@ seeding. Frozen sidecars are never silently re-derived; a corrupt one crashes lo
|
|
|
177
177
|
```mermaid
|
|
178
178
|
flowchart TD
|
|
179
179
|
subgraph HEAD["Phase 1-2 head (fatal)"]
|
|
180
|
-
MF[matter-frame] --> PV[
|
|
180
|
+
MF[matter-frame] --> PV[clearance-variants]
|
|
181
181
|
PV --> DER["code derivations:<br/>scope ledger · form neighbourhood ·<br/>register plan freeze · recall probes"]
|
|
182
182
|
end
|
|
183
183
|
DER --> GRID["grid spec dictated by code<br/>(terms × platforms × connotation; A1 split)"]
|
|
@@ -217,7 +217,7 @@ flowchart TD
|
|
|
217
217
|
|
|
218
218
|
Reading order for the phases, with what code decides at each:
|
|
219
219
|
|
|
220
|
-
1. **Head stages** — `matter-frame` then `
|
|
220
|
+
1. **Head stages** — `matter-frame` then `clearance-variants`, both fatal. Code then derives the
|
|
221
221
|
scope ledger, the *form neighbourhood* (the model picks the distinctive token; the machine
|
|
222
222
|
generates the complete mechanical variant floor), freezes the register plan
|
|
223
223
|
(`_driver/register-plan.json`, frozen for the life of *this run* — a resume never re-plans, and a
|
|
@@ -445,7 +445,7 @@ node pipeline.mjs --resume <codename> --experiment <stage> [--label <t>]
|
|
|
445
445
|
- **`--from`** forces stages at or after the named ordinal even if their outputs validate; earlier
|
|
446
446
|
stages still skip. A `--from synthesis` fork deliberately does *not* lock the digest.
|
|
447
447
|
- **`--experiment`** runs one stage in a shadow dir (`_experiments/<ts>-<tag>/`) on copies of its
|
|
448
|
-
inputs, under a `
|
|
448
|
+
inputs, under a `clearance-exp-…` session key that is excluded from the run's provider-usage
|
|
449
449
|
attribution. The canonical run is untouched.
|
|
450
450
|
- **Orphan self-resume**: a manually resumed run that parks has no queue sidecars; the runner scans
|
|
451
451
|
run dirs for due, payload-complete `.postponed` sentinels not owned by any queue and resumes them
|
|
@@ -74,7 +74,7 @@ does after the stage's full retry ladder fails ([03 §5](03-run-lifecycle.md#5--
|
|
|
74
74
|
| # | Stage | Model · effort | Timeout / stall | Gated output (file truth) | Fatality |
|
|
75
75
|
|---|---|---|---|---|---|
|
|
76
76
|
| 1 | `matter-frame` | opus · high | 300 / 300 | `matter-context.md` | fatal |
|
|
77
|
-
| 2 | `
|
|
77
|
+
| 2 | `clearance-variants` | opus · high | 600 / 450 | `variant-manifest.md` (+ `.json` sibling, strict-parsed) | fatal |
|
|
78
78
|
| 3 | `blind-frame` | opus · high | 600 / 450 | `blind-frame-model.json` (strict-parsed; the prose twin was retired 2026-08-03 — nothing read it) | non-fatal (frame-diff skipped this run) |
|
|
79
79
|
| 4 | `common-law` | haiku · low | 2250 / 1100 | `common-law-findings.md` (+ grid ledger, plugin-written) | fatal at fan-in |
|
|
80
80
|
| 5 | `common-law-half` | per seat: `COMMON_LAW_SEAT_TIER` — halves `a`/`b` haiku · low; meaning seat `m` `CLEAROTRON_MEANING_SEAT_MODEL` \|\| haiku · low | 2250 / 1100 | `common-law-findings.half-{a,b,m}.md` (+ per-seat grid ledgers) | fatal at fan-in; one-half transient quarantine allowed |
|
|
@@ -201,8 +201,8 @@ deployment may override (verify live values per deployment).
|
|
|
201
201
|
| `CLEAROTRON_REPORTS_DIR` | **none — set it** | Publish pool (web-served). **No default since: unset refuses and names the variable.** It read`/srv/trademark-archive` — a deployed server's real archive — so a forgotten export published into somebody else's clearances, and two entry points already carried hand-written defences against exactly that (`bin/onboard.mjs`, `bin/example.mjs`). Same shape as `CLEAROTRON_DATABASE` and `scripts/purge-runs.mjs`: guessing wrong is expensive, so it does not guess. Read-only surfaces (flag snapshot, status page, MCP options) degrade to "no pool" instead of throwing; anything that writes refuses. `driver/production-pool-guard.mjs` still names `/srv/trademark-archive` on purpose — that constant is a fact about where the archive is, not a default. |
|
|
202
202
|
| `CLEAROTRON_REPORTS_URL` | **none — set it** | Pool base URL used in notification links. No placeholder default: unset ⇒ the link is omitted and the runner logs `deployment config MISSING` at activation. It does not gate the queue (a missing hostname costs a link, not the deliverable), so treat that log line as the alarm. |
|
|
203
203
|
| `CLEAROTRON_ACCESS_DOMAIN` | unset (note omitted) | Identity domain named in the delivery email's access note ("sign in with a `<domain>` account"). Unset ⇒ the note is omitted rather than naming the wrong domain. |
|
|
204
|
-
| `CLEAROTRON_RUN_LOCK_DIR` | `<workspaceRoot>/
|
|
205
|
-
| `CLEAROTRON_OUTBOX_DIR` | `<workspaceRoot>/
|
|
204
|
+
| `CLEAROTRON_RUN_LOCK_DIR` | `<workspaceRoot>/clearance-run-locks` | Run-slot lock dir (turn locks under `…/turns`). |
|
|
205
|
+
| `CLEAROTRON_OUTBOX_DIR` | `<workspaceRoot>/clearance-outbox` | Delivery outbox (`<runId>.pending` wake markers). Renamed from `clearance-outbox`; when this variable is unset the old directory is still READ, so a box that never pinned it does not orphan markers it has already written. Writers use the new name only. |
|
|
206
206
|
| `CLEAROTRON_OAUTH_BRIDGE` | module-relative `providers/oauth-mcp-bridge/bridge.mjs` | Case-law MCP bridge script. (Portable since the module-relative default; set explicitly only for a bridge outside the repo tree.) |
|
|
207
207
|
| `CLEAROTRON_REGISTER_CALL_LOG` | `~/trademark/telemetry/register-calls.jsonl`, or the existing file wherever it already is | Billing-grade provider-call ledger, shared by whichever ONE register provider is wired — not a vendor artifact. Every read site derives the default from`homedir()` at call time (2026-07-19: two sites had hardcoded a literal home directory, splitting the ledger under any other service account — guarded by `test/deployment-hostnames.test.mjs`). |
|
|
208
208
|
| `CLEAROTRON_REGISTER_RECORD_LOG` | **runtime-injected per run**: `<runDir>/_driver/register-record-bodies.jsonl` | Citation-fidelity log: the BODY of every fetched official record. ** moved it INTO the run** — created with the run, unioned into the run's`_records/`, archived and purged with it. There is no retention setting and no cleanup job, because it no longer grows on the box: held globally it reached 432 MB in 61 days on production and needed a rotation timer on every install. **Do not set this by hand** — a fixed value pins every run's bodies to one file and restores the problem. A box upgraded across still holds its old global file; nothing writes or reads it, the driver names it once per process on stderr, and archiving it is one`mv`. An empty log cannot read as verified: the run's successful `record_fetch` rows in the (still global) call ledger are compared against the assembled record set, and a gap is reported as a failure. |
|
|
@@ -303,6 +303,8 @@ because the rule is about what PRODUCT CODE reads, not about what a run reads.
|
|
|
303
303
|
| `CLEAROTRON_UPDATER_STAMP` | `_updater-identity.json` beside the update script, in the directory the updater runs from | The full path of the file in which the updater that deploys this box records which copy of itself ran. The updater writes it and deploy health reads it under this one name, so a box that moves the stamp sets it once for both. On a box with no updater unit, setting it says an updater exists elsewhere and is to be judged. Effect class `deployment`. |
|
|
304
304
|
| `CLEAROTRON_CUT_REF` | `HEAD` | Which ref the cut decision reads the version from. **Read only by the release workflow, never set on a deployment.** The jobs that ask about `main` set it to `origin/main` explicitly, because their checkout is pinned to the run's own ref and `HEAD` there is that ref rather than the branch they are deciding about. A job that asks the wrong subject gets a confident wrong answer. |
|
|
305
305
|
| `CLEAROTRON_RELEASE_WAIT_MS` | 25 minutes | How long a requested cut waits for the version pull request to merge itself before giving up. **Read only by the release workflow.** A rehearsal sets it to `0` so the wiring is exercised without holding a runner. Giving up is a quiet success by design — the scheduled run underneath catches a cut whose wait expired — so this budget failing shows up as a slow job rather than a red one. |
|
|
306
|
+
| `CLEAROTRON_CUT_REQUESTED` | unset (⇒ not dispatched) | Whether this release run was dispatched to cut. **Read only by the release workflow, never set on a deployment.** The workflow sets `true` on a dispatch that is not a rehearsal. Set, a wait that expires with no version published is a failure that names why; a push or the schedule leaves expiry a quiet success. Effect class `tuning`. |
|
|
307
|
+
| `CLEAROTRON_CUT_PR` | unset | The number of the version pull request the same run opened. **Read only by the release workflow, never set on a deployment.** A failed wait reads why that pull request did not merge from it. Unset or not a whole number, a dispatched wait says it found no pull request to wait on. Effect class `tuning`. |
|
|
306
308
|
| `ACTIONS_APPROVE_TOKEN` | unset | A GitHub token with Actions read and write, used to approve the version pull request's parked CI run so a cut does not wait for a person. **Read only by the release workflow, never set on a deployment.** The built-in token cannot approve a run — GitHub blocks self-approval — so this is a second, separate credential. Unset is the ordinary case and not an error: the script names the absent token and exits successfully, and the version run waits for a person as it did before. Actions write is broader than approval alone — it also dispatches workflows, cancels any run in the repository and deletes run logs. |
|
|
307
309
|
| `CLEAROTRON_AGENT_MCP_URL` | unset (⇒ `null`) | The API-key MCP door advertised to a signed-in person. Null until that door is deployed, and the UI keeps its honest empty state rather than inventing a URL. |
|
|
308
310
|
| `CLEAROTRON_AGENTS` | derived | Comma-separated agent ids for `scripts/purge-runs.mjs` to sweep. |
|
|
@@ -324,6 +326,7 @@ cannot be read as one list.
|
|
|
324
326
|
| Var | Consumer |
|
|
325
327
|
|---|---|
|
|
326
328
|
| `ANTHROPIC_API_KEY` | Engine child env in `api-key` mode only (deleted in subscription and cloud modes). |
|
|
329
|
+
| `CLAUDE_CODE_OAUTH_TOKEN` | The headless subscription sign-in's token, printed by `claude setup-token` on any machine that can sign in. Read by the Claude program itself: the engine's stage process inherits it untouched in every billing mode, which is how a browserless server authenticates the subscription lane. Setup names it as the token to paste. |
|
|
327
330
|
| `CLAUDE_CODE_USE_VERTEX` / `CLAUDE_CODE_USE_FOUNDRY` / `CLAUDE_CODE_USE_BEDROCK` | **Read by the Claude program**, which sends every turn to that cloud; `1`, `true`, `yes` or `on` switches one on. Clearotron reads them to name the cloud under `CLEAROTRON_AI_BILLING=cloud` and to refuse a switch left on under `subscription` or `api-key`. Under `CLEAROTRON_AI_BILLING=cloud`, `clearotron start --background` carries the switch that is on, and every setting in the five rows below that is set, the model pins included, into `~/.env` (a switch that is set and not on stays behind); under `subscription` or `api-key` it carries none. It adds only a line `~/.env` lacks, and names any of these on which that file and its own configuration differ. A missing switch is reported by `clearotron start` and `clearotron doctor`, and refuses a search when it is ordered. Doctor and setup's proof turn carry these and the five rows below from the settings file a search reads, which is the one at the old location while an install is still configured there (`CLOUD_SETTINGS` in `driver/engine/auth.mjs`). A value in the shell wins over the file's: setup's proof turn keeps a blank one, as a run does, where doctor passes over it and takes the file's. In setup, an answer given wins over both. A run takes the whole file. |
|
|
328
331
|
| `ANTHROPIC_VERTEX_PROJECT_ID` / `CLOUD_ML_REGION` / `GOOGLE_APPLICATION_CREDENTIALS` | Vertex AI's project, region and service-account key, read by the Claude program. Without the key file it uses gcloud's sign-in. |
|
|
329
332
|
| `ANTHROPIC_FOUNDRY_RESOURCE` / `ANTHROPIC_FOUNDRY_API_KEY` | The Foundry resource and its key, read by the Claude program. Without the key it uses the machine's Azure sign-in. |
|
|
@@ -91,7 +91,7 @@ product doc.
|
|
|
91
91
|
| **Job spec** (per matter): id, forwarder(+email/domain), markName/marks[], classes\|goods/use, ref, profileKey, projectKey, searchLevel/recipeKey, deliveryRoute, `customer`(+Unknown), deliverableSpec, commercialFlexibility, priorUse, dupOverride, deadline, brief | T1 | agent conversation → `start_run` MCP verb (ops token) → queue; validated by `enqueue-schema.mjs` | queue → run dir | LIVE (conversational; portal `run/plan`+`run` API exists) |
|
|
92
92
|
| **Company profile** (17 keys — identity/rating/provenance: name, matchDomains, selfExclusionOwners, frameworkPath, workedExamplesPath, allowedRecipes, jxPolicy, runCaps, demoData (`true` marks the record as demo data; a real clearance is refused at the runner's admission wall); overlayable: platforms, defaultClasses, defaultJurisdictions, marketplaceDensity, delivery, riskAppetite, industry, defaultProduct) | T2 (staff) + T1 (a company's people edit its own via portal §C) | profile-service UI (staff, `/profiles/*`); the portal (own profile) | config store, git auto-commit | LIVE. Merge law: project **replaces** every overlayable key except `platforms`, which **unions** (the company's floor is never subtractable) |
|
|
93
93
|
| **Project overlays** (8 overlayable keys) | T2 | profile-service UI | config store `profiles/projects/<cust>/` | LIVE. The project form deliberately withholds `defaultProduct` and both `delivery` sub-keys — for the first the sparse save path has no `""` ⇒ clear branch, so the control could only ever be turned on; for the second the engine replaces `delivery` wholesale, so a partial overlay would silently drop the company's other sub-keys. Both are company-level controls until the server side changes |
|
|
94
|
-
| **Frameworks / skills** (risk-framework-<key>.md + .manifest.json, worked examples, SKILL.md) | T2 (senior-lawyer content) | git edits in the config store (deliberate — the prose deck is the rating authority) | config store `skills/
|
|
94
|
+
| **Frameworks / skills** (risk-framework-<key>.md + .manifest.json, worked examples, SKILL.md) | T2 (senior-lawyer content) | git edits in the config store (deliberate — the prose deck is the rating authority) | config store `skills/clearance-search/` | LIVE via git; no UI by design |
|
|
95
95
|
| **Recipes / saved searches** (base level + component toggles + emailTable/defaultDeadlineDays/standingInstructions) | T2 | recipe-service UI | `<recipesDir>/<cust>/<slug>.json`, git | **DARK** — code complete, no unit deployed. A saved search is honoured wherever it resolves (the `CLEAROTRON_RECIPES_MODE` door was retired 2026-07-27) |
|
|
96
96
|
| **Run curation** (archive folds, republish, index regen) | T2 | `pool-admin.mjs` CLI only | pool `archive-tags.json` | LIVE, CLI-only |
|
|
97
97
|
| **Allowlist** (`{version, grants:[{email, customer}]}`) | T2 | git + PR on the `CLIENT_ACCESS_MAP` file | see §2 row 4 | LIVE, file-only; surfaced read-only at `admin.access` |
|
|
@@ -527,6 +527,11 @@ up is a quiet success by design and the scheduled run underneath catches what it
|
|
|
527
527
|
is wrong shows up as a slow job rather than a red one — which is why it is written down rather than left
|
|
528
528
|
to be inferred from a timeout.
|
|
529
529
|
|
|
530
|
+
`CLEAROTRON_CUT_REQUESTED` and `CLEAROTRON_CUT_PR` — whether this run was dispatched to cut, and the
|
|
531
|
+
version pull request it opened. The workflow sets both; nothing on a deployment reads either. Together they
|
|
532
|
+
separate a run that set nothing in motion, whose expired wait stays a quiet success, from a dispatched cut
|
|
533
|
+
that published nothing, which fails and names why the pull request did not merge.
|
|
534
|
+
|
|
530
535
|
## 6. Drift patterns — values that are mirrored by design
|
|
531
536
|
|
|
532
537
|
Wherever one value must exist in more than one place, name every copy and rotate them in one
|
|
@@ -16,7 +16,7 @@ rating is refused by pattern guards and by stage-level firewalls.
|
|
|
16
16
|
## The bundle
|
|
17
17
|
|
|
18
18
|
A company = one git-owned JSON file `profiles/<key>.json`, plus optionally: a prose context pack
|
|
19
|
-
(`<key>.context.md`), a per-company rating framework pair in `skills/
|
|
19
|
+
(`<key>.context.md`), a per-company rating framework pair in `skills/clearance-search/`
|
|
20
20
|
(`risk-framework-<key>.md` + its `.manifest.json`, plus worked examples), and per-engagement
|
|
21
21
|
project overlays under `profiles/projects/<key>/`.
|
|
22
22
|
|
|
@@ -182,7 +182,7 @@ this source tree.
|
|
|
182
182
|
`matchDomains` for forwarder-based fallback. A profile with empty `matchDomains` is reachable by
|
|
183
183
|
profileKey only.
|
|
184
184
|
- **Per-company framework** (optional; git-only, legal-team work — the UI cannot set it): add the
|
|
185
|
-
deck + manifest + worked examples under `skills/
|
|
185
|
+
deck + manifest + worked examples under `skills/clearance-search/`, set the two paths in the profile
|
|
186
186
|
JSON via git. Until then the company rates under the Generic default.
|
|
187
187
|
- **Per-engagement overlay** (optional): `profiles/projects/<key>/<slug>.json` with the 8
|
|
188
188
|
overlayable keys; intake stamps `job.projectKey` to select it.
|
|
@@ -112,7 +112,7 @@ and the environment file holding the secrets.
|
|
|
112
112
|
`XDG_RUNTIME_DIR` must be set for `systemctl --user` to work from cron.
|
|
113
113
|
- **Pin the agent id before upgrading an install made before 0.2.2.** The default agent id changed
|
|
114
114
|
from `clawdi` to `localagent`, and that id is a path segment: runs live under
|
|
115
|
-
`<workspaceRoot>/workspace-<agent>/studio/
|
|
115
|
+
`<workspaceRoot>/workspace-<agent>/studio/clearance-search/`. An install that never set one starts
|
|
116
116
|
reading an empty workspace, and empty reads as "no runs" rather than as an error. Set **both**
|
|
117
117
|
variables in the environment file — the gather servers read their own:
|
|
118
118
|
|
|
@@ -129,7 +129,7 @@ and the environment file holding the secrets.
|
|
|
129
129
|
|
|
130
130
|
| Surface | What it tells you |
|
|
131
131
|
|---|---|
|
|
132
|
-
| `systemctl --user status prelim-driver.{path,timer,service}
|
|
132
|
+
| `systemctl --user status prelim-driver.{path,timer,service} clearance-outbox.{path,timer,service} profile-service` | Trigger health; remember "activating = draining" |
|
|
133
133
|
| `journalctl --user -u prelim-driver.service -f` | Runner notes (stderr): claims, dedup parks, preflight failures, orphan reclaims |
|
|
134
134
|
| Run dir `status.json` / `run.jsonl` | Per-run state + the append-only decision trace; grep keys: `axes`, `profile`, `verdict`, `escalation`, `postponed`, `delivered`, `profile-mismatch` |
|
|
135
135
|
| `_driver/<stage>.jsonl` | Per-attempt telemetry: status, fail token, kill signals, wall, tokens |
|
|
@@ -173,7 +173,7 @@ survive until terminal state.
|
|
|
173
173
|
| Run parked with `*.tainted-N` artifacts | Timeout-taint convergence loop ([07 §3](07-quality-and-audit.md#3--completed-coverage-honesty-in-code)) | Let it converge; repeated signature goes terminal honestly |
|
|
174
174
|
| Chat failure ping never arrived for a failed run | By design: nothing here sends. The failure packet IS the notice, and an integrator consumes it | Check `_driver/failure.json` + the outbox lane (the guaranteed notice) |
|
|
175
175
|
| Deploy refused because a run is in flight | The in-flight guard above | Wait for the run. A force-restart of the gateway is not the answer — that is for a wedged gateway |
|
|
176
|
-
| Everything quiet after a deploy abort | Should not happen (EXIT trap restarts triggers) — if it does: `systemctl --user start prelim-driver.{path,timer}
|
|
176
|
+
| Everything quiet after a deploy abort | Should not happen (EXIT trap restarts triggers) — if it does: `systemctl --user start prelim-driver.{path,timer} clearance-outbox.{path,timer}` and file it |
|
|
177
177
|
|
|
178
178
|
## Selftest — retired
|
|
179
179
|
|
|
@@ -144,7 +144,7 @@ The reasoning layer dictates what it needs; a thin adapter supplies it. Concrete
|
|
|
144
144
|
preflighted at run start. Add the id to `KNOWN_REGISTER_PROVIDERS` too, or the error message that
|
|
145
145
|
tells an operator what to set will omit it. Selection is `CLEAROTRON_DATABASE` in every
|
|
146
146
|
environment, production included; there is no committed default to flip.
|
|
147
|
-
4. **Skill doc**: `skills/
|
|
147
|
+
4. **Skill doc**: `skills/clearance-register/providers/<provider>.md` — the provider-specific craft
|
|
148
148
|
the register stages read.
|
|
149
149
|
5. **The empirical verification checklist** — the real work is not code volume: operator
|
|
150
150
|
vocabulary and composition semantics, pagination behaviour to `has_more:false`, status-enum
|
|
@@ -157,8 +157,8 @@ The reasoning layer dictates what it needs; a thin adapter supplies it. Concrete
|
|
|
157
157
|
|
|
158
158
|
The methodology lives in the driver's `skills/` tree — 12 top-level directories, nearly all of it
|
|
159
159
|
Markdown carrying **prose only**, no executable code. The machine-parsed
|
|
160
|
-
exceptions are the four framework manifests (`skills/
|
|
161
|
-
further non-Markdown file rides along, `skills/
|
|
160
|
+
exceptions are the four framework manifests (`skills/clearance-search/risk-framework*.manifest.json`); one
|
|
161
|
+
further non-Markdown file rides along, `skills/clearance-search/templates/search-request-form.html`, named
|
|
162
162
|
only in `publish/index.mjs`.
|
|
163
163
|
The engine reads skills **in place from the git-deployed driver tree**: `absolutizeSkillRefs`
|
|
164
164
|
rewrites `skills/…` tokens to absolute paths and grants `--add-dir`. Code comments saying skills
|
|
@@ -168,8 +168,8 @@ What to know before editing:
|
|
|
168
168
|
|
|
169
169
|
- **Which stage reads what** is dictated solely by each stage message's `reads([...])` in
|
|
170
170
|
`stages.mjs` — read it there rather than trusting this summary. Broadly: matter-frame,
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
clearance-variants (+ `transliteration-scripts.md`), blind-frame, clearance-common-law (every grid seat),
|
|
172
|
+
clearance-register spine + `unit.md` *xor* `digest.md` (mode-routed — a unit must never read
|
|
173
173
|
digest doctrine and vice versa) + the active provider's `providers/<name>.md`,
|
|
174
174
|
placement-inquiry, `phase2-execution.md` §skeptic (that one section only), frame-diff,
|
|
175
175
|
synthesis (synthesis-rules + per-profile framework + worked examples + conditionally
|
|
@@ -186,7 +186,7 @@ What to know before editing:
|
|
|
186
186
|
- Several skill files are **legacy and not stage-read** (email/Excel templates, the formatting
|
|
187
187
|
reference). Verify a file appears in some stage's `reads([...])` before treating its claims as
|
|
188
188
|
live; where a legacy file and the code disagree, the code and `stages.mjs` win.
|
|
189
|
-
- The pharma module (`skills/
|
|
189
|
+
- The pharma module (`skills/clearance-search/field-doctrine-pharma.md`, loaded by a code predicate on
|
|
190
190
|
pharma-shaped matters) ships behind a named legal reviewer's sign-off — doctrine edits in
|
|
191
191
|
regulated verticals go through the practitioner, not just review.
|
|
192
192
|
|
package/docs/configuration.md
CHANGED
|
@@ -95,7 +95,7 @@ A framework is two files that travel together:
|
|
|
95
95
|
| `risk-framework.manifest.json` | A small sidecar carrying the framework's **vocabulary**: band labels, their severity order, the entity label, provenance. |
|
|
96
96
|
|
|
97
97
|
The Generic default ships at
|
|
98
|
-
[`driver/skills/
|
|
98
|
+
[`driver/skills/clearance-search/risk-framework.md`](../driver/skills/clearance-search/risk-framework.md)
|
|
99
99
|
with bands Very High · High · Moderate · Manageable.
|
|
100
100
|
|
|
101
101
|
**Replace it with your own.** Write your rubric as prose, add a manifest naming your bands,
|
|
@@ -174,14 +174,14 @@ prints what they declare, and where the deck and the manifest disagree it names
|
|
|
174
174
|
the deck did not do. It creates nothing, rates nothing and contacts nobody.
|
|
175
175
|
|
|
176
176
|
```
|
|
177
|
-
clearotron framework skills/
|
|
177
|
+
clearotron framework skills/clearance-search/your-framework.md
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
```
|
|
181
|
-
Framework: skills/
|
|
182
|
-
deck /srv/clearotron-config/skills/
|
|
181
|
+
Framework: skills/clearance-search/your-framework.md
|
|
182
|
+
deck /srv/clearotron-config/skills/clearance-search/your-framework.md
|
|
183
183
|
read from the configured store
|
|
184
|
-
manifest /srv/clearotron-config/skills/
|
|
184
|
+
manifest /srv/clearotron-config/skills/clearance-search/your-framework.manifest.json
|
|
185
185
|
read from the configured store
|
|
186
186
|
|
|
187
187
|
It declares itself "Your firm's clearance risk framework" (your-firm-2026), a bands-shaped
|
|
@@ -32,7 +32,7 @@ disclosure are both acceptable; degrading in silence is not. Which one applies i
|
|
|
32
32
|
| Register | refuses at preflight, by name | An unconfigured register that answered "no conflicts found" is the most dangerous output this system can produce |
|
|
33
33
|
| Case law (Full country search) | runs without the bridge, and the run's ledger records that the sweep did not dispatch | Access is free but auth breaks in practice. `driver/verify.mjs` plus `case-law-citations.json` stop any report claiming "no adverse case law" when nothing was read — the disclosure is the guard |
|
|
34
34
|
| Native-script lane | degrades and says so | Reached only on CJK territories |
|
|
35
|
-
| Research sweep (open web / marketplaces) | **on a Knockout search: degrades and says so.** On the three clearance searches: **refuses at preflight, by name** | acceptance 6, 2026-08-20. A knockout carries`registerProbe: true`, so its register half is a whole product without the sweep — refusing the screen threw away an answer the deployment could give. The three clearances carry `commonLawGrid: true` and their unregistered-use half is not severable, so nothing there degrades quietly into a clearance with a missing half. -6, 2026-08-20: that clearance failure MOVED to preflight — it used to happen at the common-law stage, after every register stage had been paid for. Same outcome, no spend.`preflightResearchCredential` gates on the component, never on the pipeline: `
|
|
35
|
+
| Research sweep (open web / marketplaces) | **on a Knockout search: degrades and says so.** On the three clearance searches: **refuses at preflight, by name** | acceptance 6, 2026-08-20. A knockout carries`registerProbe: true`, so its register half is a whole product without the sweep — refusing the screen threw away an answer the deployment could give. The three clearances carry `commonLawGrid: true` and their unregistered-use half is not severable, so nothing there degrades quietly into a clearance with a missing half. -6, 2026-08-20: that clearance failure MOVED to preflight — it used to happen at the common-law stage, after every register stage had been paid for. Same outcome, no spend.`preflightResearchCredential` gates on the component, never on the pipeline: `clearance-register-only` is a clearance carrying `commonLawGrid: false` and is not refused |
|
|
36
36
|
|
|
37
37
|
## Consequences
|
|
38
38
|
|
package/docs/writing-standard.md
CHANGED
|
@@ -83,3 +83,7 @@ their problem.
|
|
|
83
83
|
`enforcement.md` lists the classes a CI check refuses in a diff. Tone is not one of them, and no word
|
|
84
84
|
list will ever catch it: a reviewer reads the rendered page as someone who has never seen this product,
|
|
85
85
|
against `writing-rules.md`, and asks what they would think each sentence means.
|
|
86
|
+
|
|
87
|
+
A stylesheet that is inlined into a delivered document is delivered with it, comments included — the
|
|
88
|
+
reader receives the file, so a class name in a CSS comment is engineering vocabulary on a page they can
|
|
89
|
+
open, exactly as it would be in prose.
|