clearotron 0.2.3 → 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 +36 -37
- package/CONTRIBUTING.md +8 -4
- package/INSTALL.md +24 -4
- package/README.md +7 -6
- package/bin/example.mjs +6 -5
- package/bin/onboard.mjs +175 -9
- package/bin/start.mjs +66 -4
- package/build-info.json +2 -2
- package/demo/README.md +1 -1
- package/docs/GLOSSARY.md +85 -0
- package/docs/README.md +1 -0
- package/docs/architecture/01-product-overview.md +21 -9
- package/docs/architecture/05-config-governance.md +5 -0
- package/docs/decisions/0006-what-the-public-repository-carries.md +30 -5
- package/driver/CHANGELOG.md +34 -0
- package/driver/README.md +25 -6
- package/driver/connotation-search.mjs +1 -1
- package/driver/contract-audit.mjs +5 -1
- package/driver/contract-e3-baseline.json +11 -11
- package/driver/doubt-selection.mjs +1 -1
- package/driver/drainer-identity.mjs +1 -1
- package/driver/effort-model.mjs +2 -2
- package/driver/engine/probe.mjs +45 -5
- package/driver/gateway.mjs +2 -2
- package/driver/outbox-backoff.mjs +1 -1
- package/driver/package.json +1 -1
- package/driver/pipeline.mjs +206 -101
- package/driver/plain-register.mjs +16 -2
- package/driver/portal-config-view.mjs +30 -1
- package/driver/portal-local-auth.mjs +5 -1
- package/driver/portal-service.mjs +53 -2
- package/driver/predelivery-lint.mjs +54 -25
- package/driver/publish/render.mjs +109 -14
- package/driver/search-policy.mjs +1 -1
- package/driver/stage-context.mjs +13 -0
- package/driver/stages.mjs +51 -4
- package/driver/suite-census.json +97 -31
- package/driver/systemd/clearotron-worker.service +3 -3
- package/driver/tokens.mjs +1 -1
- package/driver/unit-inventory.mjs +34 -4
- package/mcp-server/CHANGELOG.md +2 -0
- package/mcp-server/package.json +1 -1
- package/package.json +4 -10
- package/portal-ui/dist/assets/{index-CEYvXdqH.js → index-KFAHMgdT.js} +73 -34
- package/portal-ui/dist/index.html +1 -1
- package/portal-ui/package.json +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +2 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/scripts/added-reference-check.mjs +45 -89
- package/scripts/e2e.mjs +2 -2
- package/scripts/generated-files-are-current.mjs +125 -0
- 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/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 +9 -1
- package/scripts/test-full.mjs +226 -0
- package/shared/README.md +2 -1
- package/shared/browser-temp-root.mjs +142 -0
- package/shared/checkout-move.mjs +1 -1
- package/shared/client-door.mjs +4 -3
- package/shared/identifier-scan.mjs +1 -1
- package/shared/install-auth.mjs +35 -0
- package/shared/invocation.mjs +5 -1
- package/shared/listen.mjs +55 -3
- package/shared/names-in-force.mjs +4 -1
- 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/suite-census.mjs +31 -3
- package/shared/withheld-paths-access.mjs +36 -18
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 ──────────────
|
|
@@ -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
|
+
}
|
package/driver/suite-census.json
CHANGED
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"todos": 0
|
|
41
41
|
},
|
|
42
42
|
"a-bare-reference-added-in-a-diff-is-refused.test.mjs": {
|
|
43
|
-
"tests":
|
|
44
|
-
"asserts":
|
|
43
|
+
"tests": 21,
|
|
44
|
+
"asserts": 69,
|
|
45
45
|
"skips": 0,
|
|
46
46
|
"todos": 0
|
|
47
47
|
},
|
|
@@ -51,12 +51,24 @@
|
|
|
51
51
|
"skips": 0,
|
|
52
52
|
"todos": 0
|
|
53
53
|
},
|
|
54
|
+
"a-block-that-ran-and-said-nothing-is-not-a-block-that-never-ran.test.mjs": {
|
|
55
|
+
"tests": 6,
|
|
56
|
+
"asserts": 16,
|
|
57
|
+
"skips": 0,
|
|
58
|
+
"todos": 0
|
|
59
|
+
},
|
|
54
60
|
"a-borrowed-node-modules-is-not-a-licence-defect.test.mjs": {
|
|
55
61
|
"tests": 8,
|
|
56
62
|
"asserts": 28,
|
|
57
63
|
"skips": 0,
|
|
58
64
|
"todos": 0
|
|
59
65
|
},
|
|
66
|
+
"a-browser-run-gets-its-own-temp-root.test.mjs": {
|
|
67
|
+
"tests": 13,
|
|
68
|
+
"asserts": 33,
|
|
69
|
+
"skips": 0,
|
|
70
|
+
"todos": 0
|
|
71
|
+
},
|
|
60
72
|
"a-cancel-marker-names-its-actor.test.mjs": {
|
|
61
73
|
"tests": 14,
|
|
62
74
|
"asserts": 34,
|
|
@@ -207,6 +219,12 @@
|
|
|
207
219
|
"skips": 1,
|
|
208
220
|
"todos": 0
|
|
209
221
|
},
|
|
222
|
+
"a-door-is-moved-only-when-nothing-outside-resolves-to-it.test.mjs": {
|
|
223
|
+
"tests": 7,
|
|
224
|
+
"asserts": 12,
|
|
225
|
+
"skips": 0,
|
|
226
|
+
"todos": 0
|
|
227
|
+
},
|
|
210
228
|
"a-door-that-is-not-there-is-not-a-door-that-agrees.test.mjs": {
|
|
211
229
|
"tests": 20,
|
|
212
230
|
"asserts": 75,
|
|
@@ -413,7 +431,7 @@
|
|
|
413
431
|
},
|
|
414
432
|
"a-public-clone-is-told-why-a-command-cannot-run.test.mjs": {
|
|
415
433
|
"tests": 3,
|
|
416
|
-
"asserts":
|
|
434
|
+
"asserts": 12,
|
|
417
435
|
"skips": 0,
|
|
418
436
|
"todos": 0
|
|
419
437
|
},
|
|
@@ -977,7 +995,7 @@
|
|
|
977
995
|
},
|
|
978
996
|
"both-doors-start-on-both-paths.test.mjs": {
|
|
979
997
|
"tests": 26,
|
|
980
|
-
"asserts":
|
|
998
|
+
"asserts": 61,
|
|
981
999
|
"skips": 0,
|
|
982
1000
|
"todos": 0
|
|
983
1001
|
},
|
|
@@ -1000,9 +1018,9 @@
|
|
|
1000
1018
|
"todos": 0
|
|
1001
1019
|
},
|
|
1002
1020
|
"browser-check-membership.test.mjs": {
|
|
1003
|
-
"tests":
|
|
1004
|
-
"asserts":
|
|
1005
|
-
"skips":
|
|
1021
|
+
"tests": 8,
|
|
1022
|
+
"asserts": 17,
|
|
1023
|
+
"skips": 8,
|
|
1006
1024
|
"todos": 0
|
|
1007
1025
|
},
|
|
1008
1026
|
"bundle-rebuild-and-ports.test.mjs": {
|
|
@@ -1288,8 +1306,8 @@
|
|
|
1288
1306
|
"todos": 0
|
|
1289
1307
|
},
|
|
1290
1308
|
"contract-audit.test.mjs": {
|
|
1291
|
-
"tests":
|
|
1292
|
-
"asserts":
|
|
1309
|
+
"tests": 54,
|
|
1310
|
+
"asserts": 167,
|
|
1293
1311
|
"skips": 0,
|
|
1294
1312
|
"todos": 0
|
|
1295
1313
|
},
|
|
@@ -1409,7 +1427,7 @@
|
|
|
1409
1427
|
},
|
|
1410
1428
|
"coverage-judgment-rows.test.mjs": {
|
|
1411
1429
|
"tests": 9,
|
|
1412
|
-
"asserts":
|
|
1430
|
+
"asserts": 40,
|
|
1413
1431
|
"skips": 0,
|
|
1414
1432
|
"todos": 0
|
|
1415
1433
|
},
|
|
@@ -2015,7 +2033,7 @@
|
|
|
2015
2033
|
},
|
|
2016
2034
|
"example-replay.test.mjs": {
|
|
2017
2035
|
"tests": 8,
|
|
2018
|
-
"asserts":
|
|
2036
|
+
"asserts": 32,
|
|
2019
2037
|
"skips": 0,
|
|
2020
2038
|
"todos": 0
|
|
2021
2039
|
},
|
|
@@ -2800,8 +2818,8 @@
|
|
|
2800
2818
|
"todos": 0
|
|
2801
2819
|
},
|
|
2802
2820
|
"plain-words-on-what-the-reader-sees-first.test.mjs": {
|
|
2803
|
-
"tests":
|
|
2804
|
-
"asserts":
|
|
2821
|
+
"tests": 19,
|
|
2822
|
+
"asserts": 45,
|
|
2805
2823
|
"skips": 0,
|
|
2806
2824
|
"todos": 0
|
|
2807
2825
|
},
|
|
@@ -2848,8 +2866,8 @@
|
|
|
2848
2866
|
"todos": 0
|
|
2849
2867
|
},
|
|
2850
2868
|
"portal-config-view.test.mjs": {
|
|
2851
|
-
"tests":
|
|
2852
|
-
"asserts":
|
|
2869
|
+
"tests": 35,
|
|
2870
|
+
"asserts": 94,
|
|
2853
2871
|
"skips": 0,
|
|
2854
2872
|
"todos": 0
|
|
2855
2873
|
},
|
|
@@ -2902,8 +2920,8 @@
|
|
|
2902
2920
|
"todos": 0
|
|
2903
2921
|
},
|
|
2904
2922
|
"portal-service.test.mjs": {
|
|
2905
|
-
"tests":
|
|
2906
|
-
"asserts":
|
|
2923
|
+
"tests": 119,
|
|
2924
|
+
"asserts": 634,
|
|
2907
2925
|
"skips": 0,
|
|
2908
2926
|
"todos": 0
|
|
2909
2927
|
},
|
|
@@ -3293,7 +3311,7 @@
|
|
|
3293
3311
|
},
|
|
3294
3312
|
"register-count.test.mjs": {
|
|
3295
3313
|
"tests": 20,
|
|
3296
|
-
"asserts":
|
|
3314
|
+
"asserts": 154,
|
|
3297
3315
|
"skips": 0,
|
|
3298
3316
|
"todos": 0
|
|
3299
3317
|
},
|
|
@@ -3418,8 +3436,8 @@
|
|
|
3418
3436
|
"todos": 0
|
|
3419
3437
|
},
|
|
3420
3438
|
"render.test.mjs": {
|
|
3421
|
-
"tests":
|
|
3422
|
-
"asserts":
|
|
3439
|
+
"tests": 154,
|
|
3440
|
+
"asserts": 630,
|
|
3423
3441
|
"skips": 0,
|
|
3424
3442
|
"todos": 0
|
|
3425
3443
|
},
|
|
@@ -4167,6 +4185,12 @@
|
|
|
4167
4185
|
"skips": 0,
|
|
4168
4186
|
"todos": 0
|
|
4169
4187
|
},
|
|
4188
|
+
"test-full-runs-every-corpus-or-names-the-one-it-did-not.test.mjs": {
|
|
4189
|
+
"tests": 16,
|
|
4190
|
+
"asserts": 51,
|
|
4191
|
+
"skips": 0,
|
|
4192
|
+
"todos": 0
|
|
4193
|
+
},
|
|
4170
4194
|
"test-run-deps.test.mjs": {
|
|
4171
4195
|
"tests": 5,
|
|
4172
4196
|
"asserts": 21,
|
|
@@ -4174,8 +4198,14 @@
|
|
|
4174
4198
|
"todos": 0
|
|
4175
4199
|
},
|
|
4176
4200
|
"test-run-tmpdir.test.mjs": {
|
|
4177
|
-
"tests":
|
|
4178
|
-
"asserts":
|
|
4201
|
+
"tests": 11,
|
|
4202
|
+
"asserts": 25,
|
|
4203
|
+
"skips": 0,
|
|
4204
|
+
"todos": 0
|
|
4205
|
+
},
|
|
4206
|
+
"the-advice-fits-the-machine-it-is-printed-on.test.mjs": {
|
|
4207
|
+
"tests": 14,
|
|
4208
|
+
"asserts": 43,
|
|
4179
4209
|
"skips": 0,
|
|
4180
4210
|
"todos": 0
|
|
4181
4211
|
},
|
|
@@ -4402,14 +4432,14 @@
|
|
|
4402
4432
|
"todos": 0
|
|
4403
4433
|
},
|
|
4404
4434
|
"the-inventory-names-the-units-this-box-runs.test.mjs": {
|
|
4405
|
-
"tests":
|
|
4406
|
-
"asserts":
|
|
4435
|
+
"tests": 12,
|
|
4436
|
+
"asserts": 33,
|
|
4407
4437
|
"skips": 0,
|
|
4408
4438
|
"todos": 0
|
|
4409
4439
|
},
|
|
4410
4440
|
"the-knockout-page-leads-with-the-read.test.mjs": {
|
|
4411
|
-
"tests":
|
|
4412
|
-
"asserts":
|
|
4441
|
+
"tests": 28,
|
|
4442
|
+
"asserts": 68,
|
|
4413
4443
|
"skips": 0,
|
|
4414
4444
|
"todos": 0
|
|
4415
4445
|
},
|
|
@@ -4431,6 +4461,12 @@
|
|
|
4431
4461
|
"skips": 0,
|
|
4432
4462
|
"todos": 0
|
|
4433
4463
|
},
|
|
4464
|
+
"the-minters-read-the-published-tree.test.mjs": {
|
|
4465
|
+
"tests": 2,
|
|
4466
|
+
"asserts": 5,
|
|
4467
|
+
"skips": 0,
|
|
4468
|
+
"todos": 0
|
|
4469
|
+
},
|
|
4434
4470
|
"the-narrative-is-checked-against-its-depth-rules.test.mjs": {
|
|
4435
4471
|
"tests": 19,
|
|
4436
4472
|
"asserts": 70,
|
|
@@ -4485,6 +4521,12 @@
|
|
|
4485
4521
|
"skips": 0,
|
|
4486
4522
|
"todos": 0
|
|
4487
4523
|
},
|
|
4524
|
+
"the-probe-spawns-the-environment-it-validated.test.mjs": {
|
|
4525
|
+
"tests": 4,
|
|
4526
|
+
"asserts": 12,
|
|
4527
|
+
"skips": 0,
|
|
4528
|
+
"todos": 0
|
|
4529
|
+
},
|
|
4488
4530
|
"the-process-table-reads-a-box-with-no-proc.test.mjs": {
|
|
4489
4531
|
"tests": 7,
|
|
4490
4532
|
"asserts": 25,
|
|
@@ -4497,6 +4539,12 @@
|
|
|
4497
4539
|
"skips": 0,
|
|
4498
4540
|
"todos": 0
|
|
4499
4541
|
},
|
|
4542
|
+
"the-public-residue-is-a-floor.test.mjs": {
|
|
4543
|
+
"tests": 13,
|
|
4544
|
+
"asserts": 51,
|
|
4545
|
+
"skips": 5,
|
|
4546
|
+
"todos": 0
|
|
4547
|
+
},
|
|
4500
4548
|
"the-published-door-must-answer-not-merely-exist.test.mjs": {
|
|
4501
4549
|
"tests": 5,
|
|
4502
4550
|
"asserts": 14,
|
|
@@ -4557,6 +4605,12 @@
|
|
|
4557
4605
|
"skips": 0,
|
|
4558
4606
|
"todos": 0
|
|
4559
4607
|
},
|
|
4608
|
+
"the-reviewing-pass-reads-the-lines-a-client-sees-first.test.mjs": {
|
|
4609
|
+
"tests": 10,
|
|
4610
|
+
"asserts": 27,
|
|
4611
|
+
"skips": 0,
|
|
4612
|
+
"todos": 0
|
|
4613
|
+
},
|
|
4560
4614
|
"the-root-strip-rule-survives-and-can-only-widen.test.mjs": {
|
|
4561
4615
|
"tests": 5,
|
|
4562
4616
|
"asserts": 21,
|
|
@@ -4761,6 +4815,12 @@
|
|
|
4761
4815
|
"skips": 0,
|
|
4762
4816
|
"todos": 0
|
|
4763
4817
|
},
|
|
4818
|
+
"under-wsl-the-windows-binary-on-path-is-not-the-engine.test.mjs": {
|
|
4819
|
+
"tests": 8,
|
|
4820
|
+
"asserts": 26,
|
|
4821
|
+
"skips": 0,
|
|
4822
|
+
"todos": 0
|
|
4823
|
+
},
|
|
4764
4824
|
"unexecuted-asserts.test.mjs": {
|
|
4765
4825
|
"tests": 5,
|
|
4766
4826
|
"asserts": 28,
|
|
@@ -5288,8 +5348,8 @@
|
|
|
5288
5348
|
"ext": "ts",
|
|
5289
5349
|
"perFile": {
|
|
5290
5350
|
"api.test.ts": {
|
|
5291
|
-
"tests":
|
|
5292
|
-
"asserts":
|
|
5351
|
+
"tests": 37,
|
|
5352
|
+
"asserts": 138,
|
|
5293
5353
|
"skips": 0,
|
|
5294
5354
|
"todos": 0
|
|
5295
5355
|
},
|
|
@@ -5312,8 +5372,8 @@
|
|
|
5312
5372
|
"todos": 0
|
|
5313
5373
|
},
|
|
5314
5374
|
"composerProduct.test.ts": {
|
|
5315
|
-
"tests":
|
|
5316
|
-
"asserts":
|
|
5375
|
+
"tests": 30,
|
|
5376
|
+
"asserts": 113,
|
|
5317
5377
|
"skips": 0,
|
|
5318
5378
|
"todos": 0
|
|
5319
5379
|
},
|
|
@@ -5335,6 +5395,12 @@
|
|
|
5335
5395
|
"skips": 0,
|
|
5336
5396
|
"todos": 0
|
|
5337
5397
|
},
|
|
5398
|
+
"engineState.test.ts": {
|
|
5399
|
+
"tests": 7,
|
|
5400
|
+
"asserts": 27,
|
|
5401
|
+
"skips": 0,
|
|
5402
|
+
"todos": 0
|
|
5403
|
+
},
|
|
5338
5404
|
"exportControls.test.ts": {
|
|
5339
5405
|
"tests": 10,
|
|
5340
5406
|
"asserts": 25,
|
|
@@ -5409,7 +5475,7 @@
|
|
|
5409
5475
|
},
|
|
5410
5476
|
"nav.test.ts": {
|
|
5411
5477
|
"tests": 12,
|
|
5412
|
-
"asserts":
|
|
5478
|
+
"asserts": 46,
|
|
5413
5479
|
"skips": 0,
|
|
5414
5480
|
"todos": 0
|
|
5415
5481
|
},
|
|
@@ -61,9 +61,9 @@ ExecStart=/usr/bin/node ${CLEAROTRON_CHECKOUT_DIR}/driver/runner.mjs --watch
|
|
|
61
61
|
# `-` prefix: a snapshot is a diagnostic surface, and failing to write one must never fail the service.
|
|
62
62
|
ExecStartPost=-/usr/bin/node ${CLEAROTRON_CHECKOUT_DIR}/driver/flag-snapshot.mjs
|
|
63
63
|
#
|
|
64
|
-
# THIS LINE DOES NOT REACH A RUNNING BOX BY DEPLOYING (
|
|
65
|
-
#
|
|
66
|
-
# neither does the hourly timer.
|
|
64
|
+
# THIS LINE DOES NOT REACH A RUNNING BOX BY DEPLOYING (measured on
|
|
65
|
+
# the test deployment, 2026-09-05). `clearotron update` pulls and rebuilds; it does not refresh unit files, and
|
|
66
|
+
# neither does the hourly timer. The deployment's installed copy of this unit had NO ExecStartPost while the
|
|
67
67
|
# tracked one had it, so the capture sat four hours stale on a box whose checkout was current.
|
|
68
68
|
#
|
|
69
69
|
# AND THE VERB ALREADY EXISTS, which is what makes it a one-line defect rather than a missing feature.
|
package/driver/tokens.mjs
CHANGED
|
@@ -144,7 +144,7 @@ export function rollupTokens(runDir) {
|
|
|
144
144
|
// `model: "code"` / `modelUsed: "code:execute-plan"` and carries NO engine and NO authMode fields,
|
|
145
145
|
// because no engine served it and nobody was billed. Read with `?? "unknown"` it landed in the
|
|
146
146
|
// bucket that means "we could not attribute this dispatch" — beside genuinely unstamped rows — and
|
|
147
|
-
// destroyed that bucket's whole diagnostic value, which
|
|
147
|
+
// destroyed that bucket's whole diagnostic value, which the testing doctrine actively reads. It also
|
|
148
148
|
// made this rollup contradict `run-economics.byBilling`, which had the branch and got it right, on
|
|
149
149
|
// the same dispatch in the same run. `isCodeSide` is IMPORTED from that module, not copied: one
|
|
150
150
|
// definition, because two copies drifting apart is how the disagreement started.
|
|
@@ -123,7 +123,7 @@ export const UNIT_INVENTORY = Object.freeze([
|
|
|
123
123
|
// exists to make impossible — and a mechanism that installs itself is the easiest kind to ship
|
|
124
124
|
// undeclared.
|
|
125
125
|
unit: "clearotron-deploy", runsOn: ["test"],
|
|
126
|
-
measured: "2026-09-08, the test deployment: the timer and its service are installed for that deployment's own user, the timer is enabled and ACTIVE, and it last fired within the hour — `systemctl --user list-timers`. The service's own state says nothing about this: it is `inactive` between runs and `inactive` when the timer has been stopped. The timer's ActiveState is
|
|
126
|
+
measured: "2026-09-08, the test deployment: the timer and its service are installed for that deployment's own user, the timer is enabled and ACTIVE, and it last fired within the hour — `systemctl --user list-timers`. The service's own state says nothing about this: it is `inactive` between runs and `inactive` when the timer has been stopped. The timer's ActiveState says the timer itself is still up. It is NOT a next elapse and does not promise one: `active` means UP, never SCHEDULED. Proving something will still fire takes a real next elapse, which `systemctl list-timers --all` supplies and `show -p ActiveState` cannot. Measured in testing 2026-09-09: a timer reading `ActiveState=active` whose `OnCalendar` names a date already past, so `list-timers` reports its next fire as null and it will never run again.",
|
|
127
127
|
tracked: ["clearotron-deploy.service", "clearotron-deploy.timer"],
|
|
128
128
|
note: "the install's own updater. Placed on the test deployment, where it pulls hourly; production takes it when the owner asks.",
|
|
129
129
|
// IT WAS AN ORPHAN, AND THE CONDITION IT NAMED HAS BEEN MET. This entry carried an `orphanReason`
|
|
@@ -323,10 +323,40 @@ export const UNIT_INVENTORY = Object.freeze([
|
|
|
323
323
|
{
|
|
324
324
|
unit: "client-mcp-apikey", runsOn: ["test"],
|
|
325
325
|
measured: "2026-09-08, read by account: enabled and present on the TEST deployment, beside the "
|
|
326
|
-
+ "renamed `clearotron-client-mcp
|
|
327
|
-
+ "production
|
|
328
|
-
+ "
|
|
326
|
+
+ "renamed `clearotron-client-mcp`, and INACTIVE — enabled with no running process. Absent from "
|
|
327
|
+
+ "production under any account. The entry declared production and the reading puts it on the "
|
|
328
|
+
+ "other deployment — the claim was not stale, it named the wrong machine.",
|
|
329
329
|
tracked: ["client-mcp-apikey.service"],
|
|
330
|
+
// THE SEPARATE QUESTION, ANSWERED. The line above used to end by saying that why it runs beside the
|
|
331
|
+
// renamed door was a question for somebody else. It is a survivor of the rename, not a posture
|
|
332
|
+
// anyone still wants: the key-based access it is named for moved to the other scheme, and this unit
|
|
333
|
+
// serves the same surface as the renamed door from a second name.
|
|
334
|
+
//
|
|
335
|
+
// ENABLED IS THE PART THAT MATTERS, and it is why this is a retirement rather than a note. An
|
|
336
|
+
// inactive unit does nothing today; an ENABLED one comes back on the next reboot, and it would come
|
|
337
|
+
// back onto a second endpoint that no entry declares, nothing checks and nothing routes to. That is
|
|
338
|
+
// the difference between a leftover and a decision, and it is the shape that produced the
|
|
339
|
+
// two-clone straddle: one surface served from two places with nothing asserting they agree.
|
|
340
|
+
retired: {
|
|
341
|
+
ruled: "2026-09-08",
|
|
342
|
+
filesStayUntil: "test",
|
|
343
|
+
why: "a survivor of the client-door rename, not a wanted posture: the key-based access this unit "
|
|
344
|
+
+ "is named for moved to the other scheme, and it serves the same surface as the renamed door "
|
|
345
|
+
+ "under a second name. ENABLED AND INACTIVE on the test deployment as this is written, which "
|
|
346
|
+
+ "is the whole reason it is a retirement: an inactive unit does nothing, an enabled one "
|
|
347
|
+
+ "returns on the next reboot onto an endpoint nothing declares. Nothing wants it but "
|
|
348
|
+
+ "default.target, so disabling takes nothing with it. THE DISABLE FOLLOWS THIS ENTRY ONTO THE "
|
|
349
|
+
+ "BOX RATHER THAN PRECEDING IT, and the order is measured rather than chosen: with this entry "
|
|
350
|
+
+ "not yet deployed, a disabled unit whose file is still present FAILS `every live unit is "
|
|
351
|
+
+ "declared` and un-stamps the deploy, because the arm reads a unit declared for this box and "
|
|
352
|
+
+ "not among the live ones as absent, and only a retired entry moves it to the branch that is "
|
|
353
|
+
+ "reported without being a fault. So no box state may be green ahead of the repo. Once this "
|
|
354
|
+
+ "deploys the disable is one command, and it belongs to the lane that owns that box. It will "
|
|
355
|
+
+ "not be masked: mask exits 1 while the unit file occupies the path it wants, and that file "
|
|
356
|
+
+ "stays deliberately. The tracked TEMPLATE stays until that box no longer carries the unit, "
|
|
357
|
+
+ "because deleting the only tracked description of a unit a box still holds is the mistake "
|
|
358
|
+
+ "this file already recorded twice.",
|
|
359
|
+
},
|
|
330
360
|
note: "TRACKED, in mcp-server/remote/. Same correction as client-mcp: the old reason claimed the live "
|
|
331
361
|
+ "key made a tracked file impossible, and the tracked TEMPLATE — which holds no key — already existed.",
|
|
332
362
|
},
|
package/mcp-server/CHANGELOG.md
CHANGED
package/mcp-server/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trademark-artifacts-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"private": true,
|
|
6
6
|
"description": "MCP server to interrogate clearotron trademark-clearance runs — list/read artifacts, trace the full decision flow, telemetry/cost, coverage, single-run search, and a gated single-step what-if. Imports the clearotron-driver read-only; touches no driver/template/deploy files.",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clearotron",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.4",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"prepack": "node scripts/write-build-info.mjs",
|
|
28
28
|
"prepublishOnly": "node scripts/release-completeness-check.mjs",
|
|
29
29
|
"test": "npm test --workspaces --if-present",
|
|
30
|
-
"test:full": "
|
|
30
|
+
"test:full": "node scripts/test-full.mjs",
|
|
31
31
|
"test:driver": "npm run test:full -w driver",
|
|
32
|
-
"test:providers": "node scripts/test-
|
|
32
|
+
"test:providers": "node scripts/test-full.mjs --only providers",
|
|
33
33
|
"test:mcp": "npm test -w mcp-server",
|
|
34
34
|
"start": "node bin/start.mjs",
|
|
35
35
|
"build:ui": "npm run build -w portal-ui",
|
|
@@ -49,17 +49,11 @@
|
|
|
49
49
|
"bench:uspto": "node providers/uspto-local/bench/bench.mjs",
|
|
50
50
|
"verify:uspto": "node providers/uspto-local/bin/verify-index.mjs",
|
|
51
51
|
"lint:driver": "eslint --no-error-on-unmatched-pattern --max-warnings 0 --config eslint.driver.config.mjs \"driver/**/*.mjs\" \"bin/**/*.mjs\" \"shared/**/*.mjs\" \"mcp-server/**/*.mjs\" \"scripts/**/*.mjs\" \"cut/**/*.mjs\"",
|
|
52
|
-
"deploy:drift": "node -e \"const{existsSync}=require('node:fs');const{execFileSync}=require('node:child_process');const p='scripts/deploy-drift-check.mjs';if(!existsSync(p)){console.error('npm run deploy:drift requires '+p+', internal tooling that is not included in this distribution.');process.exit(1)}try{execFileSync(process.execPath,[p],{stdio:'inherit'})}catch(e){process.exit(typeof e.status==='number'?e.status:1)}\"",
|
|
53
52
|
"doctrine-report": "node scripts/doctrine-report.mjs",
|
|
54
53
|
"notices": "node scripts/third-party-notices.mjs",
|
|
55
54
|
"notices:check": "node scripts/third-party-notices.mjs --check",
|
|
56
55
|
"grant": "node bin/grant.mjs",
|
|
57
|
-
"
|
|
58
|
-
"assert-census": "node scripts/unexecuted-asserts.mjs",
|
|
59
|
-
"guard:messages": "node -e \"const{existsSync}=require('node:fs');const{execFileSync}=require('node:child_process');const p='scripts/commit-message-guard.mjs';if(!existsSync(p)){console.error('npm run guard:messages requires '+p+', internal tooling that is not included in this distribution.');process.exit(1)}try{execFileSync(process.execPath,[p],{stdio:'inherit'})}catch(e){process.exit(typeof e.status==='number'?e.status:1)}\"",
|
|
60
|
-
"guard:messages:self-test": "node -e \"const{existsSync}=require('node:fs');const{execFileSync}=require('node:child_process');const p='scripts/commit-message-guard.mjs';if(!existsSync(p)){console.error('npm run guard:messages:self-test requires '+p+', internal tooling that is not included in this distribution.');process.exit(1)}try{execFileSync(process.execPath,[p,'--self-test'],{stdio:'inherit'})}catch(e){process.exit(typeof e.status==='number'?e.status:1)}\"",
|
|
61
|
-
"hooks:install": "node -e \"const{existsSync}=require('node:fs');const{execFileSync}=require('node:child_process');const p='scripts/install-hooks.mjs';if(!existsSync(p)){console.error('npm run hooks:install requires '+p+', internal tooling that is not included in this distribution.');process.exit(1)}try{execFileSync(process.execPath,[p],{stdio:'inherit'})}catch(e){process.exit(typeof e.status==='number'?e.status:1)}\"",
|
|
62
|
-
"hooks:check": "node -e \"const{existsSync}=require('node:fs');const{execFileSync}=require('node:child_process');const p='scripts/install-hooks.mjs';if(!existsSync(p)){console.error('npm run hooks:check requires '+p+', internal tooling that is not included in this distribution.');process.exit(1)}try{execFileSync(process.execPath,[p,'--check'],{stdio:'inherit'})}catch(e){process.exit(typeof e.status==='number'?e.status:1)}\""
|
|
56
|
+
"assert-census": "node scripts/unexecuted-asserts.mjs"
|
|
63
57
|
},
|
|
64
58
|
"devDependencies": {
|
|
65
59
|
"@changesets/cli": "3.0.1",
|