clearotron 0.3.2-beta.10 → 0.3.2-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/.env.example +1 -1
  2. package/CONTRIBUTING.md +1 -0
  3. package/INSTALL.md +49 -46
  4. package/README.md +8 -7
  5. package/bin/clearotron.mjs +14 -0
  6. package/bin/connect.mjs +68 -3
  7. package/bin/key.mjs +6 -1
  8. package/bin/onboard.mjs +51 -14
  9. package/bin/passphrase.mjs +4 -2
  10. package/bin/start.mjs +43 -9
  11. package/build-info.json +2 -2
  12. package/docs/architecture/05-config-governance.md +1 -1
  13. package/driver/CHANGELOG.md +416 -388
  14. package/driver/contract-vocabulary.mjs +5 -5
  15. package/driver/engine/mcp/recording-server.mjs +21 -1
  16. package/driver/engine/mcp/supplemental.mjs +22 -5
  17. package/driver/knockout-next-step.mjs +72 -0
  18. package/driver/named-band.mjs +1 -1
  19. package/driver/package.json +1 -1
  20. package/driver/phase0.mjs +16 -7
  21. package/driver/pipeline-knockout.mjs +26 -0
  22. package/driver/pipeline.mjs +48 -1
  23. package/driver/portal-local-auth.mjs +14 -4
  24. package/driver/portal-report.mjs +21 -2
  25. package/driver/portal-service.mjs +20 -11
  26. package/driver/publish/attr.mjs +36 -0
  27. package/driver/publish/index.mjs +10 -10
  28. package/driver/publish/parse.mjs +1 -1
  29. package/driver/publish/render-knockout.mjs +14 -9
  30. package/driver/publish/render.mjs +9 -9
  31. package/driver/publish/xlsx.mjs +7 -1
  32. package/driver/queue-watch-verdict.mjs +1 -1
  33. package/driver/register-availability.mjs +1 -1
  34. package/driver/register-plan.mjs +81 -11
  35. package/driver/result-noun-fields.mjs +3 -1
  36. package/driver/stages-knockout.mjs +1 -1
  37. package/driver/suite-census.json +104 -38
  38. package/driver/unit-inventory.mjs +7 -7
  39. package/driver/verify-knockout.mjs +0 -27
  40. package/mcp-server/CHANGELOG.md +27 -19
  41. package/mcp-server/lib/audit-view.mjs +4 -4
  42. package/mcp-server/lib/trace.mjs +1 -1
  43. package/mcp-server/package.json +1 -1
  44. package/package.json +2 -2
  45. package/portal-ui/dist/assets/{index-CtvwLCti.css → index-7Lq-dXDV.css} +12 -9
  46. package/portal-ui/dist/assets/{index-DXSRxPV_.js → index-w8GFZftk.js} +110 -69
  47. package/portal-ui/dist/index.html +2 -2
  48. package/portal-ui/package.json +1 -1
  49. package/providers/jx/README.md +2 -2
  50. package/providers/jx-subclass/README.md +1 -1
  51. package/providers/oauth-mcp-bridge/CHANGELOG.md +8 -0
  52. package/providers/oauth-mcp-bridge/package.json +1 -1
  53. package/scripts/README.md +5 -10
  54. package/scripts/ask-ai-render-check.mjs +26 -1
  55. package/scripts/citation-line-check.mjs +2 -2
  56. package/scripts/dead-names.mjs +17 -16
  57. package/scripts/e2e.mjs +8 -8
  58. package/scripts/env-audit.mjs +6 -0
  59. package/scripts/generated-files-are-current.mjs +35 -4
  60. package/scripts/live-surface-check.mjs +17 -17
  61. package/scripts/release-code-scanning-check.mjs +114 -0
  62. package/scripts/release-visible-check.mjs +117 -0
  63. package/scripts/repo-writes.mjs +42 -0
  64. package/scripts/report-sections-render-check.mjs +245 -0
  65. package/scripts/report-theme-render-check.mjs +31 -3
  66. package/scripts/settings-render-check.mjs +10 -7
  67. package/scripts/test-run.mjs +63 -4
  68. package/shared/client-door.mjs +20 -0
  69. package/shared/invocation.mjs +2 -2
  70. package/shared/parent-watch.mjs +33 -0
  71. package/shared/register-selection.mjs +4 -1
  72. package/shared/root-doc-commands.mjs +10 -4
  73. package/shared/running-start.mjs +14 -3
  74. package/shared/scope.mjs +24 -5
@@ -279,6 +279,12 @@
279
279
  "skips": 0,
280
280
  "todos": 0
281
281
  },
282
+ "a-demo-stops-when-whatever-started-it-is-gone.test.mjs": {
283
+ "tests": 3,
284
+ "asserts": 11,
285
+ "skips": 0,
286
+ "todos": 0
287
+ },
282
288
  "a-depth-check-that-read-nothing-is-on-the-investigate-list.test.mjs": {
283
289
  "tests": 3,
284
290
  "asserts": 8,
@@ -394,8 +400,8 @@
394
400
  "todos": 0
395
401
  },
396
402
  "a-gone-session-meets-a-door-not-a-json-body.test.mjs": {
397
- "tests": 4,
398
- "asserts": 16,
403
+ "tests": 6,
404
+ "asserts": 22,
399
405
  "skips": 0,
400
406
  "todos": 0
401
407
  },
@@ -411,6 +417,18 @@
411
417
  "skips": 0,
412
418
  "todos": 0
413
419
  },
420
+ "a-hostile-line-is-read-in-linear-time.test.mjs": {
421
+ "tests": 3,
422
+ "asserts": 7,
423
+ "skips": 0,
424
+ "todos": 0
425
+ },
426
+ "a-hostile-value-stays-inside-its-attribute.test.mjs": {
427
+ "tests": 6,
428
+ "asserts": 16,
429
+ "skips": 0,
430
+ "todos": 0
431
+ },
414
432
  "a-jq-program-in-a-js-string-keeps-its-backslash.test.mjs": {
415
433
  "tests": 2,
416
434
  "asserts": 6,
@@ -453,6 +471,12 @@
453
471
  "skips": 0,
454
472
  "todos": 0
455
473
  },
474
+ "a-link-in-the-workbook-is-not-banned-vocabulary.test.mjs": {
475
+ "tests": 2,
476
+ "asserts": 5,
477
+ "skips": 0,
478
+ "todos": 0
479
+ },
456
480
  "a-local-install-hands-its-stores-to-every-reader.test.mjs": {
457
481
  "tests": 1,
458
482
  "asserts": 10,
@@ -532,11 +556,17 @@
532
556
  "todos": 0
533
557
  },
534
558
  "a-new-install-signs-in-with-its-own-passphrase.test.mjs": {
535
- "tests": 9,
536
- "asserts": 47,
559
+ "tests": 10,
560
+ "asserts": 57,
537
561
  "skips": 1,
538
562
  "todos": 0
539
563
  },
564
+ "a-next-step-the-model-writes-comes-off-at-publish.test.mjs": {
565
+ "tests": 12,
566
+ "asserts": 28,
567
+ "skips": 0,
568
+ "todos": 0
569
+ },
540
570
  "a-note-the-release-refuses-is-refused-on-its-own-pull-request.test.mjs": {
541
571
  "tests": 2,
542
572
  "asserts": 3,
@@ -759,6 +789,12 @@
759
789
  "skips": 0,
760
790
  "todos": 0
761
791
  },
792
+ "a-release-is-announced-only-once-a-stranger-can-install-it.test.mjs": {
793
+ "tests": 8,
794
+ "asserts": 19,
795
+ "skips": 0,
796
+ "todos": 0
797
+ },
762
798
  "a-release-note-cannot-be-counted-twice.test.mjs": {
763
799
  "tests": 12,
764
800
  "asserts": 33,
@@ -813,6 +849,12 @@
813
849
  "skips": 0,
814
850
  "todos": 0
815
851
  },
852
+ "a-running-demo-connects-by-its-folder.test.mjs": {
853
+ "tests": 4,
854
+ "asserts": 18,
855
+ "skips": 0,
856
+ "todos": 0
857
+ },
816
858
  "a-save-that-cannot-commit-says-so.test.mjs": {
817
859
  "tests": 4,
818
860
  "asserts": 19,
@@ -885,6 +927,12 @@
885
927
  "skips": 0,
886
928
  "todos": 0
887
929
  },
930
+ "a-stable-is-published-only-over-a-clean-code-scan.test.mjs": {
931
+ "tests": 9,
932
+ "asserts": 19,
933
+ "skips": 0,
934
+ "todos": 0
935
+ },
888
936
  "a-stale-classification-names-the-rows-that-moved.test.mjs": {
889
937
  "tests": 6,
890
938
  "asserts": 24,
@@ -1510,8 +1558,8 @@
1510
1558
  "todos": 0
1511
1559
  },
1512
1560
  "codename-freshness.test.mjs": {
1513
- "tests": 5,
1514
- "asserts": 7,
1561
+ "tests": 6,
1562
+ "asserts": 9,
1515
1563
  "skips": 0,
1516
1564
  "todos": 0
1517
1565
  },
@@ -1714,8 +1762,8 @@
1714
1762
  "todos": 0
1715
1763
  },
1716
1764
  "coverage-disclosure-carries-no-engine-output.test.mjs": {
1717
- "tests": 8,
1718
- "asserts": 18,
1765
+ "tests": 9,
1766
+ "asserts": 25,
1719
1767
  "skips": 0,
1720
1768
  "todos": 0
1721
1769
  },
@@ -1797,6 +1845,12 @@
1797
1845
  "skips": 0,
1798
1846
  "todos": 0
1799
1847
  },
1848
+ "dead-names.test.mjs": {
1849
+ "tests": 5,
1850
+ "asserts": 8,
1851
+ "skips": 2,
1852
+ "todos": 0
1853
+ },
1800
1854
  "declared-park-excuses-proof-not-judgment.test.mjs": {
1801
1855
  "tests": 9,
1802
1856
  "asserts": 34,
@@ -2032,8 +2086,8 @@
2032
2086
  "todos": 0
2033
2087
  },
2034
2088
  "doctor-refuses-what-cannot-run.test.mjs": {
2035
- "tests": 8,
2036
- "asserts": 20,
2089
+ "tests": 9,
2090
+ "asserts": 22,
2037
2091
  "skips": 0,
2038
2092
  "todos": 0
2039
2093
  },
@@ -2573,7 +2627,7 @@
2573
2627
  },
2574
2628
  "free-tier-credential-sites.test.mjs": {
2575
2629
  "tests": 5,
2576
- "asserts": 13,
2630
+ "asserts": 14,
2577
2631
  "skips": 0,
2578
2632
  "todos": 0
2579
2633
  },
@@ -2782,8 +2836,8 @@
2782
2836
  "todos": 0
2783
2837
  },
2784
2838
  "knockout-structured-read.test.mjs": {
2785
- "tests": 14,
2786
- "asserts": 63,
2839
+ "tests": 12,
2840
+ "asserts": 57,
2787
2841
  "skips": 0,
2788
2842
  "todos": 0
2789
2843
  },
@@ -2872,8 +2926,8 @@
2872
2926
  "todos": 0
2873
2927
  },
2874
2928
  "matter-frame-record.test.mjs": {
2875
- "tests": 24,
2876
- "asserts": 81,
2929
+ "tests": 25,
2930
+ "asserts": 88,
2877
2931
  "skips": 0,
2878
2932
  "todos": 0
2879
2933
  },
@@ -2974,8 +3028,8 @@
2974
3028
  "todos": 0
2975
3029
  },
2976
3030
  "no-test-writes-inside-the-checkout.test.mjs": {
2977
- "tests": 16,
2978
- "asserts": 35,
3031
+ "tests": 20,
3032
+ "asserts": 52,
2979
3033
  "skips": 0,
2980
3034
  "todos": 0
2981
3035
  },
@@ -3005,7 +3059,7 @@
3005
3059
  },
3006
3060
  "onboard-wizard.test.mjs": {
3007
3061
  "tests": 77,
3008
- "asserts": 293,
3062
+ "asserts": 294,
3009
3063
  "skips": 2,
3010
3064
  "todos": 0
3011
3065
  },
@@ -3173,7 +3227,7 @@
3173
3227
  },
3174
3228
  "pipeline.mock.test.mjs": {
3175
3229
  "tests": 98,
3176
- "asserts": 815,
3230
+ "asserts": 820,
3177
3231
  "skips": 0,
3178
3232
  "todos": 0
3179
3233
  },
@@ -3275,7 +3329,7 @@
3275
3329
  },
3276
3330
  "portal-local-login.test.mjs": {
3277
3331
  "tests": 28,
3278
- "asserts": 111,
3332
+ "asserts": 113,
3279
3333
  "skips": 0,
3280
3334
  "todos": 0
3281
3335
  },
@@ -3455,7 +3509,7 @@
3455
3509
  },
3456
3510
  "provider-neutral-prose.test.mjs": {
3457
3511
  "tests": 4,
3458
- "asserts": 7,
3512
+ "asserts": 8,
3459
3513
  "skips": 0,
3460
3514
  "todos": 0
3461
3515
  },
@@ -3731,7 +3785,7 @@
3731
3785
  },
3732
3786
  "register-ledger-rename.test.mjs": {
3733
3787
  "tests": 12,
3734
- "asserts": 32,
3788
+ "asserts": 33,
3735
3789
  "skips": 0,
3736
3790
  "todos": 0
3737
3791
  },
@@ -3749,7 +3803,7 @@
3749
3803
  },
3750
3804
  "register-provider-required.test.mjs": {
3751
3805
  "tests": 10,
3752
- "asserts": 27,
3806
+ "asserts": 28,
3753
3807
  "skips": 0,
3754
3808
  "todos": 0
3755
3809
  },
@@ -3808,8 +3862,8 @@
3808
3862
  "todos": 0
3809
3863
  },
3810
3864
  "release-pipeline.test.mjs": {
3811
- "tests": 117,
3812
- "asserts": 445,
3865
+ "tests": 120,
3866
+ "asserts": 452,
3813
3867
  "skips": 0,
3814
3868
  "todos": 0
3815
3869
  },
@@ -3832,8 +3886,8 @@
3832
3886
  "todos": 0
3833
3887
  },
3834
3888
  "render.test.mjs": {
3835
- "tests": 161,
3836
- "asserts": 670,
3889
+ "tests": 162,
3890
+ "asserts": 675,
3837
3891
  "skips": 0,
3838
3892
  "todos": 0
3839
3893
  },
@@ -4277,7 +4331,7 @@
4277
4331
  },
4278
4332
  "seat-outputs-outside-driver-tree.test.mjs": {
4279
4333
  "tests": 5,
4280
- "asserts": 11,
4334
+ "asserts": 12,
4281
4335
  "skips": 0,
4282
4336
  "todos": 0
4283
4337
  },
@@ -4335,6 +4389,12 @@
4335
4389
  "skips": 0,
4336
4390
  "todos": 0
4337
4391
  },
4392
+ "setup-promises-a-login-shell-only-when-one-adds-the-directory.test.mjs": {
4393
+ "tests": 3,
4394
+ "asserts": 8,
4395
+ "skips": 0,
4396
+ "todos": 0
4397
+ },
4338
4398
  "shipped-brand-is-the-product.test.mjs": {
4339
4399
  "tests": 7,
4340
4400
  "asserts": 24,
@@ -4450,8 +4510,8 @@
4450
4510
  "todos": 0
4451
4511
  },
4452
4512
  "status-and-stop-see-a-foreground-start.test.mjs": {
4453
- "tests": 6,
4454
- "asserts": 25,
4513
+ "tests": 7,
4514
+ "asserts": 30,
4455
4515
  "skips": 0,
4456
4516
  "todos": 0
4457
4517
  },
@@ -4606,8 +4666,8 @@
4606
4666
  "todos": 0
4607
4667
  },
4608
4668
  "test-full-runs-every-corpus-or-names-the-one-it-did-not.test.mjs": {
4609
- "tests": 17,
4610
- "asserts": 54,
4669
+ "tests": 18,
4670
+ "asserts": 61,
4611
4671
  "skips": 0,
4612
4672
  "todos": 0
4613
4673
  },
@@ -4923,6 +4983,12 @@
4923
4983
  "skips": 0,
4924
4984
  "todos": 0
4925
4985
  },
4986
+ "the-house-element-stays-out-of-what-folds-in-later.test.mjs": {
4987
+ "tests": 6,
4988
+ "asserts": 22,
4989
+ "skips": 0,
4990
+ "todos": 0
4991
+ },
4926
4992
  "the-identifier-sweep-fires-on-its-sentinels.test.mjs": {
4927
4993
  "tests": 10,
4928
4994
  "asserts": 36,
@@ -5291,7 +5357,7 @@
5291
5357
  },
5292
5358
  "the-sign-in-door-folds-its-administrator-help.test.mjs": {
5293
5359
  "tests": 5,
5294
- "asserts": 21,
5360
+ "asserts": 23,
5295
5361
  "skips": 0,
5296
5362
  "todos": 0
5297
5363
  },
@@ -5308,8 +5374,8 @@
5308
5374
  "todos": 0
5309
5375
  },
5310
5376
  "the-summary-carries-structure.test.mjs": {
5311
- "tests": 13,
5312
- "asserts": 35,
5377
+ "tests": 14,
5378
+ "asserts": 37,
5313
5379
  "skips": 0,
5314
5380
  "todos": 0
5315
5381
  },
@@ -5998,7 +6064,7 @@
5998
6064
  },
5999
6065
  "root-mcp-json-connects.test.mjs": {
6000
6066
  "tests": 3,
6001
- "asserts": 13,
6067
+ "asserts": 14,
6002
6068
  "skips": 0,
6003
6069
  "todos": 0
6004
6070
  },
@@ -6410,8 +6476,8 @@
6410
6476
  "todos": 0
6411
6477
  },
6412
6478
  "reportSections.test.ts": {
6413
- "tests": 9,
6414
- "asserts": 27,
6479
+ "tests": 13,
6480
+ "asserts": 41,
6415
6481
  "skips": 0,
6416
6482
  "todos": 0
6417
6483
  },
@@ -228,7 +228,7 @@ export const UNIT_INVENTORY = Object.freeze([
228
228
  // checkout path an ordinary systemd expansion and leaves no placeholder to render.
229
229
  note: "NOT RUNNING ANYWHERE, measured 2026-09-08. This row said LIVE ON PRODUCTION for as long as it "
230
230
  + "existed and no enumeration ever supported it. Was a TEMPLATE unit carrying identity-provider "
231
- + "values inline; generic since tracker issue 1925.",
231
+ + "values inline; generic since the product installed its own units.",
232
232
  orphanReason: "CLAIMED A DEPLOYMENT IT WAS NEVER MEASURED ON, which is a FOURTH kind of orphan and "
233
233
  + "the only one that was ever a wrong claim rather than a waiting decision: the other three run "
234
234
  + "under another name, were deliberately switched off, or have simply never been installed. This "
@@ -246,7 +246,7 @@ export const UNIT_INVENTORY = Object.freeze([
246
246
  // it, against a fresh enumeration, which is the ratchet working rather than being edited around.
247
247
  unit: "clearotron-portal", runsOn: ["test"], tracked: ["clearotron-portal.service"],
248
248
  measured: "2026-09-07, test box, `systemctl --user show` with a working user bus: ActiveState=active, UnitFileState=enabled, fragment under ~/.config/systemd/user/.",
249
- note: "NEW, tracker issue 1925, SHIPPED BUT NOT YET DEPLOYED. The portal had NO unit at all — it "
249
+ note: "NEW, SHIPPED BUT NOT YET DEPLOYED. The portal had NO unit at all — it "
250
250
  + "and the MCP face are the two children bin/start.mjs supervises, and neither ran under systemd, "
251
251
  + "so a hosted deployment kept them alive with a hand launcher and `clearotron start` had nothing "
252
252
  + "to refuse in favour of.",
@@ -263,7 +263,7 @@ export const UNIT_INVENTORY = Object.freeze([
263
263
  // asserting a production state no enumeration has ever shown.
264
264
  unit: "clearotron-mcp-face", runsOn: ["test"], tracked: ["clearotron-mcp-face.service"],
265
265
  measured: "2026-09-07, test box, `systemctl --user show` with a working user bus: ActiveState=active, UnitFileState=enabled, fragment under ~/.config/systemd/user/.",
266
- note: "NEW, tracker issue 1925, SHIPPED BUT NOT YET DEPLOYED. The engine door the portal calls over "
266
+ note: "NEW, SHIPPED BUT NOT YET DEPLOYED. The engine door the portal calls over "
267
267
  + "MCP; the other of the two processes that had no unit.",
268
268
  orphanReason: "THE ENGINE DOOR THE PORTAL CALLS, shipped with no box carrying it yet. Same kind as "
269
269
  + "clearotron-portal beside it and as clearotron-deploy — never installed — and distinct from "
@@ -292,11 +292,11 @@ export const UNIT_INVENTORY = Object.freeze([
292
292
  // enumeration of a box shows it running.
293
293
  unit: "clearotron-client-mcp", runsOn: ["test"], tracked: ["clearotron-client-mcp.service"],
294
294
  measured: "2026-09-07, test box, `systemctl --user show` with a working user bus: ActiveState=active, UnitFileState=enabled, fragment under ~/.config/systemd/user/.",
295
- note: "tracker issue 1976, and INSTALLED WITH THE PRODUCT since tracker issue 2148. The client door "
295
+ note: "INSTALLED WITH THE PRODUCT since 2026-09-03. The client door "
296
296
  + "— the one surface that accepts an account-scoped key, and a separate process from the engine "
297
297
  + "door, which refuses one outright.",
298
- orphanReason: "Awaiting a box. It joined the install set on 2026-09-03 (tracker issue 2148 settled "
299
- + "point 2, superseding the on-demand posture it shipped under), so `render-units.mjs --apply` "
298
+ orphanReason: "Awaiting a box. It joined the install set on 2026-09-03, superseding the "
299
+ + "on-demand posture it shipped under, so `render-units.mjs --apply` "
300
300
  + "and `clearotron start --background` both place and enable it. It REFUSES TO START without "
301
301
  + "CLIENT_MCP_TOKEN_ONLY=1, CLIENT_MCP_ACCOUNT_ACCESS=1, the allow-list, the signing secret and "
302
302
  + "CLEAROTRON_ACCESS_FILE in the box's `%h/.env` (it otherwise demands an OIDC audience and an "
@@ -310,7 +310,7 @@ export const UNIT_INVENTORY = Object.freeze([
310
310
  // it leaves a hosted box healthy-looking and draining nothing.
311
311
  unit: "clearotron-worker", runsOn: ["test"], tracked: ["clearotron-worker.service"],
312
312
  measured: "2026-09-07, test box, `systemctl --user show` with a working user bus: ActiveState=active, UnitFileState=enabled, fragment under ~/.config/systemd/user/.",
313
- note: "NEW, tracker issue 1863. The drain, as one plain service unit invoking the entrypoint "
313
+ note: "NEW. The drain, as one plain service unit invoking the entrypoint "
314
314
  + "directly (owner ruling 2026-08-31). Ships tracked, runs nowhere yet — production takes it at "
315
315
  + "its rebuild, which is the same event that lets the retired units' files leave the tree.",
316
316
  orphanReason: "AWAITING A BOX, not an orphan by design. It is the hosted posture's drainer, and the "
@@ -29,25 +29,6 @@ const nameKey = (s) => norm(s).toLowerCase().replace(/\s+/g, " ");
29
29
 
30
30
  // ── Tone guards (the skill's rules, mechanical subset) ───────────────────────────────────────────────
31
31
  export const BANNED_TONE_RE = /\b(extremely difficult|most dangerous|massive|enormous)\b/i;
32
-
33
- /**
34
- * A RECOMMENDATION IS A SHAPE, AND THIS SCREEN MAY NOT WRITE ONE (owner, 2026-09-18).
35
- *
36
- * The screen states findings and a rating; what to do with the name is the reading lawyer's. Two
37
- * instructions that asked for a conclusion were cut first, and a re-run then wrote one anyway, under a
38
- * heading of its own: "Practical next step — <NAME> is not knocked out at this screening depth. Advance
39
- * it to clearance…". Cutting an instruction stops the engine asking; only a refusal stops the offer.
40
- *
41
- * TWO SHAPES, because both reached a reader: a block the writer heads itself, and a closing line that
42
- * moves the name on. WHAT THIS CANNOT SEE: the same conclusion as ordinary prose — "the remaining work
43
- * here is a full search" — and no pattern can. It is a floor under the doctrine, never a substitute.
44
- *
45
- * The false positives were measured rather than assumed: the degraded note this lane REQUIRES reads
46
- * "Manual verification recommended" and matches neither, and a register record "proceeding to
47
- * registration" matches neither — only proceeding *to clearance* does.
48
- */
49
- export const RECOMMENDATION_RE = /^[ \t]*(?:[*_]{0,2}|#{1,6}\s*)(?:practical\s+|immediate\s+|suggested\s+)?(?:next steps?|what to do\b|what happens next|recommendations?|our recommendation)/im;
50
- export const ADVANCE_RE = /\b(?:advance|move|take|send)\s+(?:it|this|the name|[A-Z][A-Z0-9'’-]{2,})\s+(?:on\s+)?(?:to|into|through)\s+(?:a\s+)?(?:full\s+)?clearance\b|\bproceeds?\s+to\s+(?:a\s+)?(?:full\s+)?clearance\b|\bshould\s+(?:proceed|advance|be advanced|move)\b|\bwe\s+recommend\b/i;
51
32
  export const QUANT_CLAIM_RE = /(\b\d[\d,.]*\s*(?:M|million|billion|k|thousand)?\s*(?:streams|downloads|copies sold|units sold)\b)|(\$\s?\d[\d,.]*\s*(?:M|million|billion|k)?\s*(?:in\s+)?(?:annual\s+)?(?:revenue|sales))/i;
52
33
 
53
34
  // ── URL normalization for the receipts gate ──────────────────────────────────────────────────────────
@@ -505,14 +486,6 @@ export const validators = {
505
486
  const claim = [prose, c.chunkSummary].filter(Boolean).join("\n").match(REGISTER_CLAIM_RE);
506
487
  if (claim)
507
488
  return { ok: false, reason: `knockout_register_claim:${m.name}: "${claim[0].trim()}" — this turn cannot see the register lane and must not describe it. The report states register coverage in code, from the run's own count sidecar; a summary that says the registers were not run, above a table of counts that were, is the contradiction this rule closes. Delete the clause` };
508
- // THE PER-NAME READ IS SWEPT TOO, and until now it was not: the checks below read the finding
509
- // fields, while `assessment` was validated for length and structure alone — which is exactly the
510
- // field the conclusion arrived in. Refused HERE so the stage re-asks with the line quoted, rather
511
- // than a reader meeting it.
512
- const read = [m.assessment, prose].filter(Boolean).join("\n");
513
- const recommended = read.match(RECOMMENDATION_RE) ?? read.match(ADVANCE_RE);
514
- if (recommended)
515
- return { ok: false, reason: `mark "${m.name}": "${recommended[0].trim()}" — this screen states findings and a rating; what to do with the name, and whether it advances, is the reading lawyer's. Delete the sentence: the report's own closing caveat already says what the screen is` };
516
489
  const banned = prose.match(BANNED_TONE_RE);
517
490
  if (banned) return { ok: false, reason: `mark "${m.name}": banned tone "${banned[0]}" — measured tone only (the band colour carries urgency)` };
518
491
  const quant = prose.match(QUANT_CLAIM_RE);
@@ -1,10 +1,18 @@
1
1
  # trademark-artifacts-mcp
2
2
 
3
+ ## 0.3.2-beta.12
4
+
5
+ No changes in this release.
6
+
7
+ ## 0.3.2-beta.11
8
+
9
+ No changes in this release.
10
+
3
11
  ## 0.3.2-beta.10
4
12
 
5
13
  ### Patch Changes
6
14
 
7
- - 98a57dd: Fixed: An assistant connected with nothing configured is now told which settings are missing, instead of being shown an empty list of searches.
15
+ - Fixed: An assistant connected with nothing configured is now told which settings are missing, instead of being shown an empty list of searches.
8
16
 
9
17
  ## 0.3.2-beta.9
10
18
 
@@ -50,16 +58,16 @@ No changes in this release.
50
58
 
51
59
  ### Patch Changes
52
60
 
53
- - f96c089: Fixed: A clearance for a new client can be ordered through an assistant connector without setting up a company first.
54
- - 56a760f: Fixed: Removing somebody's access now ends their assistant's connection on its next request. Until now an assistant that had already connected kept the access it started with for up to half an hour.
55
- - c05e0a7: Fixed: Ask your assistant for a client's recent searches by the client's name and it finds them. Every search in the list now says which client it was for, and which project. A search whose own record cannot be read says so, instead of appearing to belong to nobody.
56
- - d9798db: Fixed: A clearance that stops now always records that its notice is still owed, so a failure cannot be passed over as already handled.
57
- - 240673c: Fixed: Sending an access key to the engine's network address now gets a refusal that says so. It reports that the address takes an identity from the sign-in proxy and never a key.
61
+ - Fixed: A clearance for a new client can be ordered through an assistant connector without setting up a company first.
62
+ - Fixed: Removing somebody's access now ends their assistant's connection on its next request. Until now an assistant that had already connected kept the access it started with for up to half an hour.
63
+ - Fixed: Ask your assistant for a client's recent searches by the client's name and it finds them. Every search in the list now says which client it was for, and which project. A search whose own record cannot be read says so, instead of appearing to belong to nobody.
64
+ - Fixed: A clearance that stops now always records that its notice is still owed, so a failure cannot be passed over as already handled.
65
+ - Fixed: Sending an access key to the engine's network address now gets a refusal that says so. It reports that the address takes an identity from the sign-in proxy and never a key.
58
66
 
59
67
  Fixed: That refusal also names the local door where a key is accepted. Before, it reported only a missing sign-in assertion, which sent operators to the wrong configuration.
60
68
 
61
69
  For operators: A program on the same machine can now reach the engine's local key door without setting a host name for it. The local door no longer applies a browser protection that only a network address needs.
62
- - f96c089: New: The free preview of a search lists, for each territory ordered, which registers legally bind it.
70
+ - New: The free preview of a search lists, for each territory ordered, which registers legally bind it.
63
71
 
64
72
  ## 0.3.1-beta.4
65
73
 
@@ -69,20 +77,20 @@ No changes in this release.
69
77
 
70
78
  ### Patch Changes
71
79
 
72
- - 56a760f: Fixed: Removing somebody's access now ends their assistant's connection on its next request. Until now an assistant that had already connected kept the access it started with for up to half an hour.
73
- - c05e0a7: Fixed: Ask your assistant for a client's recent searches by the client's name and it finds them. Every search in the list now says which client it was for, and which project. A search whose own record cannot be read says so, instead of appearing to belong to nobody.
80
+ - Fixed: Removing somebody's access now ends their assistant's connection on its next request. Until now an assistant that had already connected kept the access it started with for up to half an hour.
81
+ - Fixed: Ask your assistant for a client's recent searches by the client's name and it finds them. Every search in the list now says which client it was for, and which project. A search whose own record cannot be read says so, instead of appearing to belong to nobody.
74
82
 
75
83
  ## 0.3.1-beta.2
76
84
 
77
85
  ### Patch Changes
78
86
 
79
- - f96c089: Fixed: A clearance for a new client can be ordered through an assistant connector without setting up a company first.
80
- - 240673c: Fixed: Sending an access key to the engine's network address now gets a refusal that says so. It reports that the address takes an identity from the sign-in proxy and never a key.
87
+ - Fixed: A clearance for a new client can be ordered through an assistant connector without setting up a company first.
88
+ - Fixed: Sending an access key to the engine's network address now gets a refusal that says so. It reports that the address takes an identity from the sign-in proxy and never a key.
81
89
 
82
90
  Fixed: That refusal also names the local door where a key is accepted. Before, it reported only a missing sign-in assertion, which sent operators to the wrong configuration.
83
91
 
84
92
  For operators: A program on the same machine can now reach the engine's local key door without setting a host name for it. The local door no longer applies a browser protection that only a network address needs.
85
- - f96c089: New: The free preview of a search lists, for each territory ordered, which registers legally bind it.
93
+ - New: The free preview of a search lists, for each territory ordered, which registers legally bind it.
86
94
 
87
95
  ## 0.3.1-beta.1
88
96
 
@@ -92,7 +100,7 @@ No changes in this release.
92
100
 
93
101
  ### Patch Changes
94
102
 
95
- - d9798db: Fixed: A clearance that stops now always records that its notice is still owed, so a failure cannot be passed over as already handled.
103
+ - Fixed: A clearance that stops now always records that its notice is still owed, so a failure cannot be passed over as already handled.
96
104
 
97
105
  ## 0.3.0
98
106
 
@@ -122,7 +130,7 @@ No changes in this release.
122
130
 
123
131
  ### Patch Changes
124
132
 
125
- - e7cd9e1: Fixed: On an install run with `clearotron start`, a connected assistant now lists the same saved searches as the portal, including Generic's. `clearotron doctor` no longer says working saved searches are off, and it names one place profiles come from.
133
+ - Fixed: On an install run with `clearotron start`, a connected assistant now lists the same saved searches as the portal, including Generic's. `clearotron doctor` no longer says working saved searches are off, and it names one place profiles come from.
126
134
 
127
135
  ## 0.3.0-beta.4
128
136
 
@@ -136,13 +144,13 @@ No changes in this release.
136
144
 
137
145
  ### Patch Changes
138
146
 
139
- - eacfce4: Fixed: An assistant reading a knockout's filings through the connector now gets each filing's page at the trade mark office, as the report does. Where that register publishes no page for a single record, it gets the office and the number instead. Before, it got a reference that opens nowhere.
147
+ - Fixed: An assistant reading a knockout's filings through the connector now gets each filing's page at the trade mark office, as the report does. Where that register publishes no page for a single record, it gets the office and the number instead. Before, it got a reference that opens nowhere.
140
148
 
141
149
  ## 0.3.0-beta.1
142
150
 
143
151
  ### Patch Changes
144
152
 
145
- - b8ec213: Fixed: A company you create in the browser now appears in your assistant's list of companies straight away.
153
+ - Fixed: A company you create in the browser now appears in your assistant's list of companies straight away.
146
154
 
147
155
  It used to appear only after the service restarted, although a search could already be started for it. Its projects were missing from the list in the same way, and so was its account in the search options.
148
156
 
@@ -186,7 +194,7 @@ No changes in this release.
186
194
 
187
195
  ### Patch Changes
188
196
 
189
- - 19a1869: New: Ask a what-if about a delivered report and get a supplementary memo over its archived evidence, without touching the report.
197
+ - New: Ask a what-if about a delivered report and get a supplementary memo over its archived evidence, without touching the report.
190
198
 
191
199
  ## 0.1.3
192
200
 
@@ -196,12 +204,12 @@ No changes in this release.
196
204
 
197
205
  ### Patch Changes
198
206
 
199
- - 6d05f62: Fixed: An assistant connected to Clearotron no longer asks permission before reading; it still asks before starting or stopping a search.
207
+ - Fixed: An assistant connected to Clearotron no longer asks permission before reading; it still asks before starting or stopping a search.
200
208
 
201
209
  ## 0.1.1-beta.1
202
210
 
203
211
  ### Patch Changes
204
212
 
205
- - 6d05f62: An assistant connected to Clearotron no longer asks permission before reading; it still asks before starting or stopping a search.
213
+ - An assistant connected to Clearotron no longer asks permission before reading; it still asks before starting or stopping a search.
206
214
 
207
215
  ## 0.1.1-beta.0
@@ -261,10 +261,10 @@ export function accountTrace(result) {
261
261
  out.auditTrailNote = result.auditTrailNote ?? null;
262
262
  }
263
263
  // `note` is NOT forwarded, and this is the one place a raw string looked harmless and was not. trace's
264
- // verdict branch returns a hard-coded sentence ending "unresolved concerns are surfaced to Alex (never
265
- // withheld)" — an internal identity, in a literal, so no prose filter would ever have caught it: the
266
- // scrub transforms MODEL output, and this is ours. The fact it carries is worth keeping, so it is
267
- // restated here in client words rather than dropped: what the verdict is FOR.
264
+ // verdict branch returns a hard-coded sentence written for whoever operates the engine, not for a
265
+ // client — a literal, so no prose filter would ever catch what it says: the scrub transforms MODEL
266
+ // output, and this is ours. The fact it carries is worth keeping, so it is restated here in client
267
+ // words rather than dropped: what the verdict is FOR.
268
268
  if (result.note) out.note = result.resolvedAs?.kind === "verdict"
269
269
  ? "The verdict gates delivery: a reviewer reads the narrative against the source records and rules CLEAR, CONDITIONAL or BLOCKING. Anything short of CLEAR sends the work back for a corrective pass, and an unresolved concern is raised rather than withheld."
270
270
  : clean(result.note);
@@ -242,7 +242,7 @@ export function trace(run, target, { depth = 2, shallow = false } = {}) {
242
242
  out.auditTrail = relatedAuditRows(findings.audit, f);
243
243
  out.auditTrailNote = "Best-effort match of audit-trail rows to this finding; the full audit trail is available via list_findings(kind:'audit').";
244
244
  } else if (resolved.kind === "verdict") {
245
- out.note = "The verdict gates delivery: the refutation reviewer reads narrative + the source files and writes CLEAR / CONDITIONAL / BLOCKING. A non-CLEAR verdict triggers a corrective re-synthesis; unresolved concerns are surfaced to Alex (never withheld).";
245
+ out.note = "The verdict gates delivery: the refutation reviewer reads narrative + the source files and writes CLEAR / CONDITIONAL / BLOCKING. A non-CLEAR verdict triggers a corrective re-synthesis; unresolved concerns are surfaced to the reader (never withheld).";
246
246
  }
247
247
  return out;
248
248
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trademark-artifacts-mcp",
3
- "version": "0.3.2-beta.10",
3
+ "version": "0.3.2-beta.12",
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.3.2-beta.10",
4
+ "version": "0.3.2-beta.12",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
7
7
  "type": "git",
@@ -11,7 +11,7 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/CordilleraSarl/clearotron/issues"
13
13
  },
14
- "description": "Clearotron — trademark-clearance engine: deterministic orchestration driver + MCP interrogation server. Provider-agnostic, model-agnostic, runs headless (no gateway).",
14
+ "description": "Trademark clearance engine. Searches the registers and the open web, rates the conflicts, and delivers a written report with the record behind every finding.",
15
15
  "keywords": [
16
16
  "trademark",
17
17
  "trademark-clearance",