clearotron 0.2.1 → 0.2.3

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 (676) hide show
  1. package/.env.example +82 -1
  2. package/.nvmrc +1 -1
  3. package/CONTRIBUTING.md +3 -3
  4. package/INSTALL.md +64 -58
  5. package/README.md +11 -16
  6. package/THIRD-PARTY-NOTICES.md +1 -1
  7. package/bin/brandowner.mjs +1 -1
  8. package/bin/clearotron.mjs +26 -4
  9. package/bin/connect.mjs +2 -2
  10. package/bin/example.mjs +31 -11
  11. package/bin/grant.mjs +3 -3
  12. package/bin/key.mjs +1 -1
  13. package/bin/onboard.mjs +252 -136
  14. package/bin/start.mjs +176 -33
  15. package/bin/stop.mjs +65 -3
  16. package/bin/update.mjs +7 -7
  17. package/bin/uspto-sync.mjs +1 -1
  18. package/build-info.json +2 -2
  19. package/demo/full-country-search/run/_driver/framework.json +1 -1
  20. package/demo/global-preliminary-search/run/_driver/framework.json +1 -1
  21. package/demo/knockout-search/run/_driver/framework.json +1 -1
  22. package/demo/multi-country-focus-search/run/_driver/framework.json +1 -1
  23. package/docs/DELIVERY.md +6 -2
  24. package/docs/E2E.md +5 -5
  25. package/docs/PORTAL.md +2 -2
  26. package/docs/README.md +5 -4
  27. package/docs/SECURITY.md +17 -0
  28. package/docs/architecture/01-product-overview.md +2 -2
  29. package/docs/architecture/02-architecture.md +2 -2
  30. package/docs/architecture/04-configuration-reference.md +8 -3
  31. package/docs/architecture/05-config-governance.md +52 -5
  32. package/docs/architecture/05-customer-profiles.md +2 -2
  33. package/docs/architecture/06-operations-runbook.md +13 -1
  34. package/docs/architecture/09-security-and-data.md +1 -1
  35. package/docs/configuration.md +4 -3
  36. package/docs/decisions/0004-documentation-structure.md +1 -1
  37. package/driver/CHANGELOG.md +121 -1
  38. package/driver/README.md +2 -2
  39. package/driver/ask-ledger.mjs +3 -3
  40. package/driver/authority-trees.mjs +1 -1
  41. package/driver/call-capture.mjs +1 -1
  42. package/driver/card-frame.mjs +1 -1
  43. package/driver/case-law-ledger.mjs +1 -1
  44. package/driver/claim-liveness.mjs +1 -1
  45. package/driver/common-law-receipts.mjs +2 -2
  46. package/driver/commonlaw-carry.mjs +1 -1
  47. package/driver/config-inventory.mjs +1 -1
  48. package/driver/config-staleness.mjs +1 -1
  49. package/driver/connotation-search.mjs +12 -12
  50. package/driver/contract-audit.mjs +5 -5
  51. package/driver/contract-dictation-registry.mjs +4 -4
  52. package/driver/contract-dictation.mjs +2 -2
  53. package/driver/contract-e3-backlog.mjs +6 -6
  54. package/driver/contract-vocabulary.mjs +3 -3
  55. package/driver/corrections-feedforward.mjs +1 -1
  56. package/driver/coverage-form-io.mjs +2 -2
  57. package/driver/coverage-form.mjs +4 -4
  58. package/driver/coverage-ledger.mjs +3 -3
  59. package/driver/coverage-union.mjs +1 -1
  60. package/driver/declination-call.mjs +35 -3
  61. package/driver/declination-duty.mjs +1 -1
  62. package/driver/deliver-trigger.sh +3 -3
  63. package/driver/deploy-live-run-guard.mjs +6 -2
  64. package/driver/dev-portal.mjs +3 -3
  65. package/driver/disposition-call.mjs +4 -4
  66. package/driver/disposition-tool.mjs +4 -4
  67. package/driver/disposition-union.mjs +2 -2
  68. package/driver/doc-constants.mjs +1 -1
  69. package/driver/door-gates.mjs +2 -2
  70. package/driver/doubt-selection.mjs +2 -2
  71. package/driver/drainer-identity.mjs +1 -1
  72. package/driver/driver.config.mjs +64 -12
  73. package/driver/e2e-rounds.mjs +2 -2
  74. package/driver/effort-model.mjs +2 -2
  75. package/driver/engine/anthropic-agent.mjs +24 -24
  76. package/driver/engine/auth.mjs +1 -1
  77. package/driver/engine/cli-version.mjs +103 -0
  78. package/driver/engine/common.mjs +1 -1
  79. package/driver/engine/deny-authority-write.mjs +1 -1
  80. package/driver/engine/jx-turn.mjs +1 -1
  81. package/driver/engine/mcp/clarivate-server.mjs +1 -1
  82. package/driver/engine/mcp/corsearch-server.mjs +1 -1
  83. package/driver/engine/mcp/declination-server.mjs +1 -1
  84. package/driver/engine/mcp/dispositions-server.mjs +1 -1
  85. package/driver/engine/mcp/euipo-server.mjs +1 -1
  86. package/driver/engine/mcp/fetch-server.mjs +1 -1
  87. package/driver/engine/mcp/free-tier-server.mjs +2 -2
  88. package/driver/engine/mcp/gather-config.mjs +11 -11
  89. package/driver/engine/mcp/perplexity-server.mjs +1 -1
  90. package/driver/engine/mcp/recording-server.mjs +8 -4
  91. package/driver/engine/mcp/signa-server.mjs +1 -1
  92. package/driver/engine/mcp/uspto-local-server.mjs +1 -1
  93. package/driver/engine/openai-agent.mjs +2 -2
  94. package/driver/engine-build.mjs +2 -2
  95. package/driver/enqueue-schema.mjs +10 -10
  96. package/driver/enqueue.mjs +1 -1
  97. package/driver/envelope-settle.mjs +1 -1
  98. package/driver/evidence-claim-invariant.mjs +2 -2
  99. package/driver/feedback-store.mjs +1 -1
  100. package/driver/findings-model.mjs +60 -10
  101. package/driver/flag-snapshot.mjs +20 -0
  102. package/driver/floor-duty.mjs +1 -1
  103. package/driver/form-neighbourhood.mjs +1 -1
  104. package/driver/framework.mjs +2 -2
  105. package/driver/gateway.mjs +45 -23
  106. package/driver/grounds-grammar.mjs +1 -1
  107. package/driver/hit-list.mjs +1 -1
  108. package/driver/jurisdiction-systems.mjs +1 -1
  109. package/driver/jx-lanes.mjs +1 -1
  110. package/driver/jx-units.mjs +1 -1
  111. package/driver/jx.mjs +3 -3
  112. package/driver/knockout-assess-record.mjs +5 -1
  113. package/driver/narrative-refutation-record.mjs +3 -3
  114. package/driver/numeric-setting.mjs +1 -1
  115. package/driver/owner-use-check.mjs +184 -0
  116. package/driver/package.json +4 -4
  117. package/driver/party-facts.mjs +2 -2
  118. package/driver/phase0.mjs +2 -2
  119. package/driver/pipeline-knockout.mjs +52 -4
  120. package/driver/pipeline.mjs +180 -67
  121. package/driver/placement-diff.mjs +2 -2
  122. package/driver/placement-form.mjs +4 -4
  123. package/driver/placement-union.mjs +1 -1
  124. package/driver/plain-register.mjs +120 -0
  125. package/driver/portal-access.mjs +1 -1
  126. package/driver/portal-acks.mjs +1 -1
  127. package/driver/portal-config-view.mjs +42 -3
  128. package/driver/portal-families.mjs +1 -1
  129. package/driver/portal-local-auth.mjs +1 -1
  130. package/driver/portal-report.mjs +7 -7
  131. package/driver/portal-service.mjs +41 -22
  132. package/driver/portal-upstream.mjs +2 -2
  133. package/driver/predelivery-lint.mjs +149 -11
  134. package/driver/prelim-variants-record.mjs +2 -2
  135. package/driver/profile-page.html +11 -3
  136. package/driver/profile-selection.mjs +1 -1
  137. package/driver/profile-service.mjs +6 -6
  138. package/driver/profiles/README.md +3 -3
  139. package/driver/profiles.mjs +145 -13
  140. package/driver/progress.mjs +6 -6
  141. package/driver/provider-usage.mjs +1 -1
  142. package/driver/publish/demo-marking.mjs +1 -1
  143. package/driver/publish/index.mjs +49 -8
  144. package/driver/publish/knockout.mjs +42 -14
  145. package/driver/publish/parse.mjs +4 -4
  146. package/driver/publish/publish-inputs.mjs +2 -2
  147. package/driver/publish/register-presence.mjs +1 -1
  148. package/driver/publish/render-knockout.mjs +646 -144
  149. package/driver/publish/render.mjs +2 -2
  150. package/driver/publish/report-data.mjs +13 -3
  151. package/driver/queue-watch-probe.mjs +1 -1
  152. package/driver/queue-watch-verdict.mjs +1 -1
  153. package/driver/recall-reconciliation.mjs +1 -1
  154. package/driver/recipe-service.mjs +1 -1
  155. package/driver/record-carry.mjs +5 -5
  156. package/driver/recording-agreement.mjs +3 -3
  157. package/driver/reference-score.mjs +7 -7
  158. package/driver/reference-strip-signatures.mjs +20 -0
  159. package/driver/refusal-bound.mjs +3 -3
  160. package/driver/register-availability.mjs +2 -2
  161. package/driver/register-count.mjs +1 -1
  162. package/driver/register-grant-vocabulary.mjs +2 -2
  163. package/driver/register-plan.mjs +8 -8
  164. package/driver/register-records.mjs +2 -2
  165. package/driver/registry-fidelity.mjs +3 -3
  166. package/driver/remedy-accounting.mjs +1 -1
  167. package/driver/repair-composers.mjs +2 -2
  168. package/driver/repair-digest.mjs +3 -3
  169. package/driver/repairs.mjs +6 -6
  170. package/driver/replay-archive.mjs +2 -0
  171. package/driver/report-card-record.mjs +2 -2
  172. package/driver/result-noun-fields.mjs +10 -3
  173. package/driver/run-economics.mjs +2 -2
  174. package/driver/run-integrity.mjs +1 -1
  175. package/driver/runner.mjs +22 -22
  176. package/driver/scope-rules.mjs +1 -1
  177. package/driver/search-policy.mjs +5 -5
  178. package/driver/skeptic-search.mjs +1 -1
  179. package/driver/skills/blind-frame/SKILL.md +2 -2
  180. package/driver/skills/case-law-citation/SKILL.md +2 -2
  181. package/driver/skills/knockout-assess/SKILL.md +94 -4
  182. package/driver/skills/matter-frame/SKILL.md +6 -6
  183. package/driver/skills/matter-frame/watchlist-reference.md +2 -2
  184. package/driver/skills/prelim-common-law/SKILL.md +1 -1
  185. package/driver/skills/prelim-search/SKILL.md +3 -3
  186. package/driver/skills/prelim-search/report-prose.md +82 -0
  187. package/driver/skills/prelim-search/risk-framework-demo.manifest.json +1 -1
  188. package/driver/skills/prelim-search/risk-framework-triage.manifest.json +1 -1
  189. package/driver/skills/prelim-search/risk-framework.manifest.json +1 -1
  190. package/driver/skills/prelim-search/synthesis-rules.md +1 -1
  191. package/driver/skills/prelim-search/template-formatting.md +1 -1
  192. package/driver/skills/prelim-search/templates/email/generic.md +1 -1
  193. package/driver/skills/prelim-search/worked-examples.md +1 -1
  194. package/driver/skills/prelim-variants/SKILL.md +5 -5
  195. package/driver/stage-context.mjs +1 -1
  196. package/driver/stages-knockout.mjs +55 -4
  197. package/driver/stages.mjs +101 -44
  198. package/driver/stray-artifacts.mjs +2 -2
  199. package/driver/suite-census.json +275 -65
  200. package/driver/synthesis-record.mjs +1 -1
  201. package/driver/systemd/clearotron-client-mcp.service +1 -1
  202. package/driver/systemd/clearotron-portal.service +1 -1
  203. package/driver/systemd/render-units.mjs +1 -1
  204. package/driver/tokens.mjs +1 -1
  205. package/driver/tool-calls.mjs +1 -1
  206. package/driver/turnaround-bands.mjs +1 -1
  207. package/driver/unit-file-drift.mjs +1 -1
  208. package/driver/unit-inventory.mjs +297 -80
  209. package/driver/unit-state-verdict.mjs +20 -12
  210. package/driver/verify-knockout.mjs +10 -2
  211. package/driver/verify.mjs +13 -13
  212. package/driver/whatif-memo-run.mjs +72 -9
  213. package/driver/whatif-memo.mjs +19 -1
  214. package/driver/whatif-queue.mjs +1 -1
  215. package/driver/whatif-worker.mjs +1 -1
  216. package/examples/README.md +2 -2
  217. package/examples/grants.example.json +6 -7
  218. package/mcp-server/CHANGELOG.md +6 -0
  219. package/mcp-server/README.md +3 -3
  220. package/mcp-server/http-server.mjs +44 -1
  221. package/mcp-server/key-socket.mjs +184 -0
  222. package/mcp-server/lib/audit-view.mjs +69 -2
  223. package/mcp-server/lib/brief.mjs +15 -0
  224. package/mcp-server/lib/driver.mjs +7 -1
  225. package/mcp-server/lib/events.mjs +1 -1
  226. package/mcp-server/lib/http-handler.mjs +1 -1
  227. package/mcp-server/lib/knockout.mjs +435 -0
  228. package/mcp-server/lib/ops.mjs +4 -4
  229. package/mcp-server/lib/options.mjs +1 -1
  230. package/mcp-server/lib/plan.mjs +1 -1
  231. package/mcp-server/lib/runs.mjs +1 -1
  232. package/mcp-server/lib/scrub.mjs +2 -2
  233. package/mcp-server/lib/whatif.mjs +5 -5
  234. package/mcp-server/mint-token.mjs +1 -1
  235. package/mcp-server/package.json +2 -2
  236. package/mcp-server/packs/ops/EXAMPLES.md +2 -2
  237. package/mcp-server/server.mjs +77 -12
  238. package/package.json +30 -12
  239. package/portal-ui/dist/assets/{index-Ct3iQtZ2.css → index-1ziUJX1E.css} +43 -2
  240. package/portal-ui/dist/assets/{index-BUGgiYtF.js → index-CEYvXdqH.js} +226 -49
  241. package/portal-ui/dist/index.html +2 -2
  242. package/portal-ui/package.json +1 -1
  243. package/providers/_shared/enumerate.mjs +1 -1
  244. package/providers/_shared/ledger-path.mjs +3 -3
  245. package/providers/_shared/ledger.mjs +1 -1
  246. package/providers/_shared/result-shape.mjs +3 -3
  247. package/providers/_shared/term-shape.mjs +2 -2
  248. package/providers/corsearch/src/core.js +1 -1
  249. package/providers/jx-subclass/BUILDING.md +1 -1
  250. package/providers/oauth-mcp-bridge/CHANGELOG.md +6 -0
  251. package/providers/oauth-mcp-bridge/package.json +1 -1
  252. package/providers/oauth-mcp-bridge/stdin-guard.mjs +2 -2
  253. package/providers/uspto-local/src/index-store.js +2 -2
  254. package/scripts/README.md +1 -1
  255. package/scripts/added-reference-check.mjs +29 -1
  256. package/scripts/authority-boundary-probe.mjs +1 -1
  257. package/scripts/backfill-started-at.mjs +1 -1
  258. package/scripts/citation-line-check.mjs +124 -5
  259. package/scripts/compare.mjs +2 -2
  260. package/scripts/contract-dictation-scan.mjs +2 -2
  261. package/scripts/dead-names.mjs +1 -1
  262. package/scripts/drain-preflight.mjs +5 -5
  263. package/scripts/e2e-unread-terminals.mjs +1 -1
  264. package/scripts/e2e.mjs +8 -8
  265. package/scripts/env-audit.mjs +7 -7
  266. package/scripts/env-classify.mjs +206 -18
  267. package/scripts/freeze-example-run.mjs +3 -3
  268. package/scripts/head-arrived-gated.mjs +1 -1
  269. package/scripts/headless-page.mjs +51 -2
  270. package/scripts/live-surface-check.mjs +129 -19
  271. package/scripts/main-health.mjs +1 -1
  272. package/scripts/merge-presence-check.mjs +3 -3
  273. package/scripts/mint-suite-census.mjs +6 -6
  274. package/scripts/nightly-notice.mjs +1 -3
  275. package/scripts/preinstall-node-check.mjs +24 -0
  276. package/scripts/reconcile-runs.mjs +1 -1
  277. package/scripts/release-await-cut.mjs +6 -4
  278. package/scripts/release-version-pr-checks.mjs +1 -1
  279. package/scripts/release-version.mjs +2 -2
  280. package/scripts/render-check.mjs +66 -7
  281. package/scripts/report-frame-check.mjs +1 -1
  282. package/scripts/report-screenshot.mjs +1 -1
  283. package/scripts/revisit-render-check.mjs +1 -1
  284. package/scripts/score.mjs +4 -4
  285. package/scripts/strip-tracker-citations.mjs +139 -0
  286. package/scripts/test-run.mjs +19 -3
  287. package/scripts/third-party-notices.mjs +3 -3
  288. package/scripts/travelling-predicates.mjs +3 -3
  289. package/scripts/unexecuted-asserts.mjs +2 -2
  290. package/scripts/verify-publishable.mjs +2 -2
  291. package/scripts/write-up-form-census.mjs +1 -1
  292. package/shared/access-audience.mjs +1 -1
  293. package/shared/anon-overlay.mjs +3 -3
  294. package/shared/brand.mjs +13 -13
  295. package/shared/citation-scan.mjs +1 -1
  296. package/shared/client-door.mjs +7 -7
  297. package/shared/customer-store.mjs +1 -1
  298. package/shared/driver-dir.mjs +1 -1
  299. package/shared/env-aliases.mjs +0 -48
  300. package/shared/env-local.mjs +1 -1
  301. package/shared/identifier-scan.mjs +3 -3
  302. package/shared/invocation.mjs +29 -1
  303. package/shared/names-in-force.mjs +4 -0
  304. package/shared/node-floor.mjs +97 -0
  305. package/shared/product-owned-names.mjs +1 -1
  306. package/shared/register-selection.mjs +1 -1
  307. package/shared/scope.mjs +5 -5
  308. package/shared/server-units.mjs +4 -4
  309. package/shared/staff-domain.mjs +154 -0
  310. package/shared/store-in-repo.mjs +25 -4
  311. package/shared/suite-census.mjs +4 -4
  312. package/shared/tty-style.mjs +1 -1
  313. package/shared/uspto-index-size.mjs +1 -1
  314. package/shared/vacuous-pass.mjs +1 -1
  315. package/skills/clearotron-account/SKILL.md +42 -13
  316. package/skills/clearotron-ops/SKILL.md +1 -1
  317. package/driver/recipes/README.md +0 -49
  318. package/driver/skills/prelim-search/risk-framework-aurora.manifest.json +0 -19
  319. package/driver/skills/prelim-search/risk-framework-aurora.md +0 -77
  320. package/driver/skills/prelim-search/risk-framework-zephyr.manifest.json +0 -14
  321. package/driver/skills/prelim-search/risk-framework-zephyr.md +0 -33
  322. package/driver/skills/prelim-search/worked-examples-aurora.md +0 -10
  323. package/driver/skills/prelim-search/worked-examples-zephyr.md +0 -10
  324. package/driver/systemd/prelim-driver.path +0 -69
  325. package/driver/systemd/prelim-driver.service +0 -86
  326. package/driver/systemd/prelim-driver.timer +0 -14
  327. package/driver/systemd/prelim-outbox.path +0 -27
  328. package/driver/systemd/prelim-outbox.service +0 -37
  329. package/driver/systemd/prelim-outbox.timer +0 -21
  330. package/node_modules/exceljs/README_zh.md +0 -2878
  331. package/node_modules/exceljs/dist/LICENSE +0 -22
  332. package/node_modules/exceljs/dist/es5/csv/csv.js +0 -182
  333. package/node_modules/exceljs/dist/es5/csv/csv.js.map +0 -1
  334. package/node_modules/exceljs/dist/es5/csv/line-buffer.js +0 -68
  335. package/node_modules/exceljs/dist/es5/csv/line-buffer.js.map +0 -1
  336. package/node_modules/exceljs/dist/es5/csv/stream-converter.js +0 -110
  337. package/node_modules/exceljs/dist/es5/csv/stream-converter.js.map +0 -1
  338. package/node_modules/exceljs/dist/es5/doc/anchor.js +0 -73
  339. package/node_modules/exceljs/dist/es5/doc/anchor.js.map +0 -1
  340. package/node_modules/exceljs/dist/es5/doc/cell.js +0 -961
  341. package/node_modules/exceljs/dist/es5/doc/cell.js.map +0 -1
  342. package/node_modules/exceljs/dist/es5/doc/column.js +0 -274
  343. package/node_modules/exceljs/dist/es5/doc/column.js.map +0 -1
  344. package/node_modules/exceljs/dist/es5/doc/data-validations.js +0 -18
  345. package/node_modules/exceljs/dist/es5/doc/data-validations.js.map +0 -1
  346. package/node_modules/exceljs/dist/es5/doc/defined-names.js +0 -173
  347. package/node_modules/exceljs/dist/es5/doc/defined-names.js.map +0 -1
  348. package/node_modules/exceljs/dist/es5/doc/enums.js +0 -49
  349. package/node_modules/exceljs/dist/es5/doc/enums.js.map +0 -1
  350. package/node_modules/exceljs/dist/es5/doc/image.js +0 -69
  351. package/node_modules/exceljs/dist/es5/doc/image.js.map +0 -1
  352. package/node_modules/exceljs/dist/es5/doc/modelcontainer.js +0 -16
  353. package/node_modules/exceljs/dist/es5/doc/modelcontainer.js.map +0 -1
  354. package/node_modules/exceljs/dist/es5/doc/note.js +0 -64
  355. package/node_modules/exceljs/dist/es5/doc/note.js.map +0 -1
  356. package/node_modules/exceljs/dist/es5/doc/range.js +0 -229
  357. package/node_modules/exceljs/dist/es5/doc/range.js.map +0 -1
  358. package/node_modules/exceljs/dist/es5/doc/row.js +0 -382
  359. package/node_modules/exceljs/dist/es5/doc/row.js.map +0 -1
  360. package/node_modules/exceljs/dist/es5/doc/table.js +0 -443
  361. package/node_modules/exceljs/dist/es5/doc/table.js.map +0 -1
  362. package/node_modules/exceljs/dist/es5/doc/workbook.js +0 -202
  363. package/node_modules/exceljs/dist/es5/doc/workbook.js.map +0 -1
  364. package/node_modules/exceljs/dist/es5/doc/worksheet.js +0 -900
  365. package/node_modules/exceljs/dist/es5/doc/worksheet.js.map +0 -1
  366. package/node_modules/exceljs/dist/es5/exceljs.bare.js +0 -14
  367. package/node_modules/exceljs/dist/es5/exceljs.bare.js.map +0 -1
  368. package/node_modules/exceljs/dist/es5/exceljs.browser.js +0 -36
  369. package/node_modules/exceljs/dist/es5/exceljs.browser.js.map +0 -1
  370. package/node_modules/exceljs/dist/es5/exceljs.nodejs.js +0 -15
  371. package/node_modules/exceljs/dist/es5/exceljs.nodejs.js.map +0 -1
  372. package/node_modules/exceljs/dist/es5/index.js +0 -15
  373. package/node_modules/exceljs/dist/es5/stream/xlsx/hyperlink-reader.js +0 -90
  374. package/node_modules/exceljs/dist/es5/stream/xlsx/hyperlink-reader.js.map +0 -1
  375. package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-comments-writer.js +0 -94
  376. package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-comments-writer.js.map +0 -1
  377. package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-rels-writer.js +0 -94
  378. package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-rels-writer.js.map +0 -1
  379. package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-reader.js +0 -362
  380. package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-reader.js.map +0 -1
  381. package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-writer.js +0 -347
  382. package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-writer.js.map +0 -1
  383. package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-reader.js +0 -392
  384. package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-reader.js.map +0 -1
  385. package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-writer.js +0 -652
  386. package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-writer.js.map +0 -1
  387. package/node_modules/exceljs/dist/es5/utils/auto-drain.js +0 -18
  388. package/node_modules/exceljs/dist/es5/utils/auto-drain.js.map +0 -1
  389. package/node_modules/exceljs/dist/es5/utils/browser-buffer-decode.js +0 -15
  390. package/node_modules/exceljs/dist/es5/utils/browser-buffer-decode.js.map +0 -1
  391. package/node_modules/exceljs/dist/es5/utils/browser-buffer-encode.js +0 -18
  392. package/node_modules/exceljs/dist/es5/utils/browser-buffer-encode.js.map +0 -1
  393. package/node_modules/exceljs/dist/es5/utils/cell-matrix.js +0 -149
  394. package/node_modules/exceljs/dist/es5/utils/cell-matrix.js.map +0 -1
  395. package/node_modules/exceljs/dist/es5/utils/col-cache.js +0 -258
  396. package/node_modules/exceljs/dist/es5/utils/col-cache.js.map +0 -1
  397. package/node_modules/exceljs/dist/es5/utils/copy-style.js +0 -43
  398. package/node_modules/exceljs/dist/es5/utils/copy-style.js.map +0 -1
  399. package/node_modules/exceljs/dist/es5/utils/encryptor.js +0 -58
  400. package/node_modules/exceljs/dist/es5/utils/encryptor.js.map +0 -1
  401. package/node_modules/exceljs/dist/es5/utils/iterate-stream.js +0 -46
  402. package/node_modules/exceljs/dist/es5/utils/iterate-stream.js.map +0 -1
  403. package/node_modules/exceljs/dist/es5/utils/parse-sax.js +0 -47
  404. package/node_modules/exceljs/dist/es5/utils/parse-sax.js.map +0 -1
  405. package/node_modules/exceljs/dist/es5/utils/shared-formula.js +0 -42
  406. package/node_modules/exceljs/dist/es5/utils/shared-formula.js.map +0 -1
  407. package/node_modules/exceljs/dist/es5/utils/shared-strings.js +0 -32
  408. package/node_modules/exceljs/dist/es5/utils/shared-strings.js.map +0 -1
  409. package/node_modules/exceljs/dist/es5/utils/stream-base64.js +0 -66
  410. package/node_modules/exceljs/dist/es5/utils/stream-base64.js.map +0 -1
  411. package/node_modules/exceljs/dist/es5/utils/stream-buf.js +0 -343
  412. package/node_modules/exceljs/dist/es5/utils/stream-buf.js.map +0 -1
  413. package/node_modules/exceljs/dist/es5/utils/string-buf.js +0 -73
  414. package/node_modules/exceljs/dist/es5/utils/string-buf.js.map +0 -1
  415. package/node_modules/exceljs/dist/es5/utils/string-builder.js +0 -32
  416. package/node_modules/exceljs/dist/es5/utils/string-builder.js.map +0 -1
  417. package/node_modules/exceljs/dist/es5/utils/stuttered-pipe.js +0 -61
  418. package/node_modules/exceljs/dist/es5/utils/stuttered-pipe.js.map +0 -1
  419. package/node_modules/exceljs/dist/es5/utils/typed-stack.js +0 -23
  420. package/node_modules/exceljs/dist/es5/utils/typed-stack.js.map +0 -1
  421. package/node_modules/exceljs/dist/es5/utils/under-dash.js +0 -168
  422. package/node_modules/exceljs/dist/es5/utils/under-dash.js.map +0 -1
  423. package/node_modules/exceljs/dist/es5/utils/utils.js +0 -171
  424. package/node_modules/exceljs/dist/es5/utils/utils.js.map +0 -1
  425. package/node_modules/exceljs/dist/es5/utils/xml-stream.js +0 -151
  426. package/node_modules/exceljs/dist/es5/utils/xml-stream.js.map +0 -1
  427. package/node_modules/exceljs/dist/es5/utils/zip-stream.js +0 -79
  428. package/node_modules/exceljs/dist/es5/utils/zip-stream.js.map +0 -1
  429. package/node_modules/exceljs/dist/es5/xlsx/defaultnumformats.js +0 -230
  430. package/node_modules/exceljs/dist/es5/xlsx/defaultnumformats.js.map +0 -1
  431. package/node_modules/exceljs/dist/es5/xlsx/rel-type.js +0 -18
  432. package/node_modules/exceljs/dist/es5/xlsx/rel-type.js.map +0 -1
  433. package/node_modules/exceljs/dist/es5/xlsx/xform/base-xform.js +0 -139
  434. package/node_modules/exceljs/dist/es5/xlsx/xform/base-xform.js.map +0 -1
  435. package/node_modules/exceljs/dist/es5/xlsx/xform/book/defined-name-xform.js +0 -85
  436. package/node_modules/exceljs/dist/es5/xlsx/xform/book/defined-name-xform.js.map +0 -1
  437. package/node_modules/exceljs/dist/es5/xlsx/xform/book/sheet-xform.js +0 -32
  438. package/node_modules/exceljs/dist/es5/xlsx/xform/book/sheet-xform.js.map +0 -1
  439. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js +0 -24
  440. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js.map +0 -1
  441. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-properties-xform.js +0 -27
  442. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-properties-xform.js.map +0 -1
  443. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-view-xform.js +0 -51
  444. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-view-xform.js.map +0 -1
  445. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-xform.js +0 -234
  446. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-xform.js.map +0 -1
  447. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comment-xform.js +0 -103
  448. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comment-xform.js.map +0 -1
  449. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comments-xform.js +0 -76
  450. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comments-xform.js.map +0 -1
  451. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-position-xform.js +0 -35
  452. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-position-xform.js.map +0 -1
  453. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js +0 -32
  454. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js.map +0 -1
  455. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-anchor-xform.js +0 -53
  456. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-anchor-xform.js.map +0 -1
  457. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-client-data-xform.js +0 -97
  458. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-client-data-xform.js.map +0 -1
  459. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-notes-xform.js +0 -107
  460. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-notes-xform.js.map +0 -1
  461. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-shape-xform.js +0 -92
  462. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-shape-xform.js.map +0 -1
  463. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-textbox-xform.js +0 -61
  464. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-textbox-xform.js.map +0 -1
  465. package/node_modules/exceljs/dist/es5/xlsx/xform/composite-xform.js +0 -51
  466. package/node_modules/exceljs/dist/es5/xlsx/xform/composite-xform.js.map +0 -1
  467. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js +0 -30
  468. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js.map +0 -1
  469. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js +0 -27
  470. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js.map +0 -1
  471. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-xform.js +0 -93
  472. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-xform.js.map +0 -1
  473. package/node_modules/exceljs/dist/es5/xlsx/xform/core/content-types-xform.js +0 -112
  474. package/node_modules/exceljs/dist/es5/xlsx/xform/core/content-types-xform.js.map +0 -1
  475. package/node_modules/exceljs/dist/es5/xlsx/xform/core/core-xform.js +0 -158
  476. package/node_modules/exceljs/dist/es5/xlsx/xform/core/core-xform.js.map +0 -1
  477. package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationship-xform.js +0 -23
  478. package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationship-xform.js.map +0 -1
  479. package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationships-xform.js +0 -65
  480. package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationships-xform.js.map +0 -1
  481. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js +0 -47
  482. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js.map +0 -1
  483. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-fill-xform.js +0 -61
  484. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-fill-xform.js.map +0 -1
  485. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-xform.js +0 -40
  486. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-xform.js.map +0 -1
  487. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js +0 -35
  488. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js.map +0 -1
  489. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js +0 -62
  490. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js.map +0 -1
  491. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/cell-position-xform.js +0 -82
  492. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/cell-position-xform.js.map +0 -1
  493. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/drawing-xform.js +0 -98
  494. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/drawing-xform.js.map +0 -1
  495. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-lst-xform.js +0 -40
  496. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-lst-xform.js.map +0 -1
  497. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-xform.js +0 -38
  498. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-xform.js.map +0 -1
  499. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/hlink-click-xform.js +0 -38
  500. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/hlink-click-xform.js.map +0 -1
  501. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js +0 -59
  502. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js.map +0 -1
  503. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js +0 -63
  504. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js.map +0 -1
  505. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/pic-xform.js +0 -67
  506. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/pic-xform.js.map +0 -1
  507. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/sp-pr.js +0 -30
  508. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/sp-pr.js.map +0 -1
  509. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js +0 -62
  510. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js.map +0 -1
  511. package/node_modules/exceljs/dist/es5/xlsx/xform/list-xform.js +0 -91
  512. package/node_modules/exceljs/dist/es5/xlsx/xform/list-xform.js.map +0 -1
  513. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/auto-filter-xform.js +0 -40
  514. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/auto-filter-xform.js.map +0 -1
  515. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cell-xform.js +0 -451
  516. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cell-xform.js.map +0 -1
  517. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js +0 -275
  518. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js.map +0 -1
  519. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js +0 -25
  520. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js.map +0 -1
  521. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js +0 -38
  522. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js.map +0 -1
  523. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js +0 -45
  524. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js.map +0 -1
  525. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js +0 -77
  526. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js.map +0 -1
  527. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/databar-xform.js +0 -42
  528. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/databar-xform.js.map +0 -1
  529. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +0 -71
  530. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js.map +0 -1
  531. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/formula-xform.js +0 -22
  532. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/formula-xform.js.map +0 -1
  533. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js +0 -43
  534. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js.map +0 -1
  535. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +0 -28
  536. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js.map +0 -1
  537. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +0 -88
  538. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js.map +0 -1
  539. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +0 -38
  540. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js.map +0 -1
  541. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +0 -52
  542. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js.map +0 -1
  543. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +0 -43
  544. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js.map +0 -1
  545. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +0 -75
  546. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js.map +0 -1
  547. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js +0 -22
  548. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js.map +0 -1
  549. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +0 -66
  550. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js.map +0 -1
  551. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +0 -22
  552. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js.map +0 -1
  553. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/col-xform.js +0 -78
  554. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/col-xform.js.map +0 -1
  555. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/data-validations-xform.js +0 -247
  556. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/data-validations-xform.js.map +0 -1
  557. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/dimension-xform.js +0 -28
  558. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/dimension-xform.js.map +0 -1
  559. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/drawing-xform.js +0 -32
  560. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/drawing-xform.js.map +0 -1
  561. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/ext-lst-xform.js +0 -69
  562. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/ext-lst-xform.js.map +0 -1
  563. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/header-footer-xform.js +0 -126
  564. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/header-footer-xform.js.map +0 -1
  565. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/hyperlink-xform.js +0 -50
  566. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/hyperlink-xform.js.map +0 -1
  567. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merge-cell-xform.js +0 -26
  568. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merge-cell-xform.js.map +0 -1
  569. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merges.js +0 -52
  570. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merges.js.map +0 -1
  571. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/outline-properties-xform.js +0 -35
  572. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/outline-properties-xform.js.map +0 -1
  573. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-breaks-xform.js +0 -24
  574. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-breaks-xform.js.map +0 -1
  575. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-margins-xform.js +0 -46
  576. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-margins-xform.js.map +0 -1
  577. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js +0 -32
  578. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js.map +0 -1
  579. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-xform.js +0 -99
  580. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-xform.js.map +0 -1
  581. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/picture-xform.js +0 -32
  582. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/picture-xform.js.map +0 -1
  583. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/print-options-xform.js +0 -45
  584. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/print-options-xform.js.map +0 -1
  585. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-breaks-xform.js +0 -37
  586. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-breaks-xform.js.map +0 -1
  587. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-xform.js +0 -128
  588. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-xform.js.map +0 -1
  589. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js +0 -51
  590. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js.map +0 -1
  591. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js +0 -83
  592. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js.map +0 -1
  593. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js +0 -84
  594. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js.map +0 -1
  595. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-view-xform.js +0 -190
  596. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-view-xform.js.map +0 -1
  597. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/table-part-xform.js +0 -32
  598. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/table-part-xform.js.map +0 -1
  599. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/worksheet-xform.js +0 -513
  600. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/worksheet-xform.js.map +0 -1
  601. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/boolean-xform.js +0 -27
  602. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/boolean-xform.js.map +0 -1
  603. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/date-xform.js +0 -58
  604. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/date-xform.js.map +0 -1
  605. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/float-xform.js +0 -47
  606. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/float-xform.js.map +0 -1
  607. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/integer-xform.js +0 -53
  608. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/integer-xform.js.map +0 -1
  609. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/string-xform.js +0 -47
  610. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/string-xform.js.map +0 -1
  611. package/node_modules/exceljs/dist/es5/xlsx/xform/static-xform.js +0 -61
  612. package/node_modules/exceljs/dist/es5/xlsx/xform/static-xform.js.map +0 -1
  613. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/phonetic-text-xform.js +0 -98
  614. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/phonetic-text-xform.js.map +0 -1
  615. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/rich-text-xform.js +0 -92
  616. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/rich-text-xform.js.map +0 -1
  617. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-string-xform.js +0 -99
  618. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-string-xform.js.map +0 -1
  619. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-strings-xform.js +0 -114
  620. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-strings-xform.js.map +0 -1
  621. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/text-xform.js +0 -39
  622. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/text-xform.js.map +0 -1
  623. package/node_modules/exceljs/dist/es5/xlsx/xform/style/alignment-xform.js +0 -139
  624. package/node_modules/exceljs/dist/es5/xlsx/xform/style/alignment-xform.js.map +0 -1
  625. package/node_modules/exceljs/dist/es5/xlsx/xform/style/border-xform.js +0 -185
  626. package/node_modules/exceljs/dist/es5/xlsx/xform/style/border-xform.js.map +0 -1
  627. package/node_modules/exceljs/dist/es5/xlsx/xform/style/color-xform.js +0 -66
  628. package/node_modules/exceljs/dist/es5/xlsx/xform/style/color-xform.js.map +0 -1
  629. package/node_modules/exceljs/dist/es5/xlsx/xform/style/dxf-xform.js +0 -106
  630. package/node_modules/exceljs/dist/es5/xlsx/xform/style/dxf-xform.js.map +0 -1
  631. package/node_modules/exceljs/dist/es5/xlsx/xform/style/fill-xform.js +0 -308
  632. package/node_modules/exceljs/dist/es5/xlsx/xform/style/fill-xform.js.map +0 -1
  633. package/node_modules/exceljs/dist/es5/xlsx/xform/style/font-xform.js +0 -175
  634. package/node_modules/exceljs/dist/es5/xlsx/xform/style/font-xform.js.map +0 -1
  635. package/node_modules/exceljs/dist/es5/xlsx/xform/style/numfmt-xform.js +0 -59
  636. package/node_modules/exceljs/dist/es5/xlsx/xform/style/numfmt-xform.js.map +0 -1
  637. package/node_modules/exceljs/dist/es5/xlsx/xform/style/protection-xform.js +0 -53
  638. package/node_modules/exceljs/dist/es5/xlsx/xform/style/protection-xform.js.map +0 -1
  639. package/node_modules/exceljs/dist/es5/xlsx/xform/style/style-xform.js +0 -118
  640. package/node_modules/exceljs/dist/es5/xlsx/xform/style/style-xform.js.map +0 -1
  641. package/node_modules/exceljs/dist/es5/xlsx/xform/style/styles-xform.js +0 -612
  642. package/node_modules/exceljs/dist/es5/xlsx/xform/style/styles-xform.js.map +0 -1
  643. package/node_modules/exceljs/dist/es5/xlsx/xform/style/underline-xform.js +0 -46
  644. package/node_modules/exceljs/dist/es5/xlsx/xform/style/underline-xform.js.map +0 -1
  645. package/node_modules/exceljs/dist/es5/xlsx/xform/table/auto-filter-xform.js +0 -75
  646. package/node_modules/exceljs/dist/es5/xlsx/xform/table/auto-filter-xform.js.map +0 -1
  647. package/node_modules/exceljs/dist/es5/xlsx/xform/table/custom-filter-xform.js +0 -30
  648. package/node_modules/exceljs/dist/es5/xlsx/xform/table/custom-filter-xform.js.map +0 -1
  649. package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-column-xform.js +0 -89
  650. package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-column-xform.js.map +0 -1
  651. package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-xform.js +0 -28
  652. package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-xform.js.map +0 -1
  653. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-column-xform.js +0 -42
  654. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-column-xform.js.map +0 -1
  655. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-style-info-xform.js +0 -40
  656. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-style-info-xform.js.map +0 -1
  657. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-xform.js +0 -123
  658. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-xform.js.map +0 -1
  659. package/node_modules/exceljs/dist/es5/xlsx/xlsx.js +0 -697
  660. package/node_modules/exceljs/dist/es5/xlsx/xlsx.js.map +0 -1
  661. package/node_modules/exceljs/dist/es5/xlsx/xml/theme1.js +0 -5
  662. package/node_modules/exceljs/dist/es5/xlsx/xml/theme1.js.map +0 -1
  663. package/node_modules/exceljs/dist/exceljs.bare.js +0 -55253
  664. package/node_modules/exceljs/dist/exceljs.bare.js.map +0 -761
  665. package/node_modules/exceljs/dist/exceljs.bare.min.js +0 -45
  666. package/node_modules/exceljs/dist/exceljs.bare.min.js.map +0 -1
  667. package/node_modules/exceljs/dist/exceljs.js +0 -59900
  668. package/node_modules/exceljs/dist/exceljs.js.map +0 -1083
  669. package/node_modules/exceljs/dist/exceljs.min.js +0 -45
  670. package/node_modules/exceljs/dist/exceljs.min.js.map +0 -1
  671. package/scripts/ai-page-render-check.mjs +0 -532
  672. package/scripts/clearances-render-check.mjs +0 -480
  673. package/scripts/composer-render-check.mjs +0 -1027
  674. package/scripts/deploy-test.sh +0 -309
  675. package/scripts/home-render-check.mjs +0 -526
  676. package/scripts/portal-lifecycle-check.mjs +0 -639
package/bin/onboard.mjs CHANGED
@@ -64,11 +64,16 @@ import { stdin as input, stdout as output } from "node:process";
64
64
  import { accessSync, constants, copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, chmodSync } from "node:fs"; // read the process table here; moved that to shared/process-table.mjs
65
65
  import { homedir, userInfo } from "node:os";
66
66
  import { invocationPrefix } from "../shared/invocation.mjs"; // — one rule for how the reader invokes us
67
+ import { nodeFloorVerdict } from "../shared/node-floor.mjs"; // — the floor is package.json engines, not a constant here
67
68
  import { invocationForm } from "../shared/invocation.mjs"; // — and WHY that form
68
69
  import { standFrom } from "../shared/invocation.mjs"; // is this tree one npm replaces?
69
70
  import { installShim } from "../shared/verb-shim.mjs"; // — the verb goes on PATH
70
71
  import { styleFor, banner } from "../shared/tty-style.mjs"; // — weight where the meaning is
71
- import { bracketAsciiCells } from "../shared/brand.mjs"; // F18 — the mark, from the geometry the SVG already uses
72
+ import { bracketAsciiCells, BRAND } from "../shared/brand.mjs"; // F18 — the mark, from the geometry the SVG already uses
73
+ // ONE CLASSIFIER, shared with `bin/start.mjs`. The wizard asks the question; the launcher enforces the
74
+ // answer. Two copies of "what does this domain admit" is a wizard that consents to one rule and a
75
+ // launcher that builds another.
76
+ import { classifyStaffDomain, domainOfEmail, staffDomainRefusal, staffGrantSentence } from "../shared/staff-domain.mjs";
72
77
  import { join, dirname, isAbsolute, resolve } from "node:path";
73
78
  import { fileURLToPath, pathToFileURL } from "node:url";
74
79
  import { delimiter } from "node:path";
@@ -121,7 +126,6 @@ const ENV_PATH = envLocalPath({ repoRoot: REPO }); // resolved, never composed
121
126
  // command is applying. Writes stay on ENV_PATH: a writer that followed the file backwards would keep an
122
127
  // install in the directory npm replaces forever.
123
128
  const READ_ENV_PATH = () => activeEnvPath({ repoRoot: REPO });
124
- const NODE_FLOOR = 22;
125
129
 
126
130
  const argv = process.argv.slice(2);
127
131
  const has = (n) => argv.includes(n);
@@ -133,7 +137,7 @@ const PROBE_ENGINE = has("--probe-engine");
133
137
  // issue 1871 — the same opt-in shape, for the credentials that had no proof at all. Never implied by
134
138
  // a plain --check: this SPENDS, and on two of the register adapters the count IS a billable search.
135
139
  const PROBE_PROVIDERS = has("--probe-providers");
136
- // tracker issue 149 — the same opt-in shape again, and this one WRITES: every registration it gets
140
+ // the same opt-in shape again, and this one WRITES: every registration it gets
137
141
  // accepted CREATES an OAuth client on the operator's account. `doctor` promises in INSTALL.md that it
138
142
  // writes nothing, and that promise is why a reader runs it on a production box without thinking. So
139
143
  // this is never implied, it says what it is about to create before it creates it, and it reports what
@@ -141,7 +145,7 @@ const PROBE_PROVIDERS = has("--probe-providers");
141
145
  const PROBE_CONNECTOR = has("--probe-connector");
142
146
 
143
147
  // ── output ───────────────────────────────────────────────────────────────────────────────────────────
144
- // WEIGHT WHERE THE MEANING IS (, owner ruling 2026-08-31). Every line here used to
148
+ // WEIGHT WHERE THE MEANING IS (owner ruling 2026-08-31). Every line here used to
145
149
  // be the same weight, which is why the passphrase and the coverage reason both disappeared into their
146
150
  // surroundings — two defects on that issue that are formatting defects wearing other clothes.
147
151
  //
@@ -587,6 +591,80 @@ export const AMBIENT_KEYS = [
587
591
  // ── helpers ──────────────────────────────────────────────────────────────────────────────────────────
588
592
  const present = (v) => typeof v === "string" && v.trim() !== "";
589
593
 
594
+ /**
595
+ * Ask who signs in, and take a real yes for the access rule that address implies.
596
+ *
597
+ * ── WHY THIS QUESTION EXISTS AT ALL ─────────────────────────────────────────────────────────────────
598
+ *
599
+ * Setup never asked for an address. `clearotron start` therefore took one from `--user`, from
600
+ * `PORTAL_LOCAL_USER`, or from the local account as `<account>@localhost` — and derived a STAFF RULE
601
+ * from everything after its `@`. On the local-account default that rule is `localhost`: one machine,
602
+ * one identity, nothing granted to anyone. Given a real address it is that address's whole domain, and
603
+ * the settings page then reports it back as "Anyone at <domain> — a rule, not a person".
604
+ *
605
+ * An outside install reached exactly that state. Nobody typed the address into this wizard, because
606
+ * this wizard had no prompt for it; an assistant filled one into the environment file on the operator's
607
+ * behalf, and the install granted a documentation domain. They read their own settings page and
608
+ * reported it as a back door. They were right to: a grant to a group had been made, by nobody.
609
+ *
610
+ * So the address is asked for here, where a person is definitionally present, and the grant it implies
611
+ * is shown in the words the settings page uses BEFORE it is written. `start` no longer guesses: it
612
+ * refuses a rule wider than one machine unless `PORTAL_STAFF_DOMAINS` says so in writing, which is what
613
+ * a yes here writes.
614
+ *
615
+ * THE DEFAULT IS THE LOCAL ACCOUNT AND NOTHING ELSE — not the git author, not the hostname, not a shell
616
+ * variable. An identity that becomes an access rule comes from the person, or from the one source that
617
+ * cannot name a second person.
618
+ *
619
+ * `io` IS INJECTED for the reason `offerUsptoSync`'s is: the branch that matters is the one where a
620
+ * reader pressed Enter at the grant question and NOTHING must be granted, and closed over a terminal
621
+ * that branch is asserted nowhere. Returns the `.env` keys to write and nothing else.
622
+ */
623
+ export async function askSignIn(io, { localAccount = "user", staffLabel = "Staff", envPath = "" } = {}) {
624
+ const { askValue, confirm, say = () => {}, ok = () => {}, info = () => {},
625
+ warn = () => {}, problem = () => {} } = io;
626
+ const localDefault = `${localAccount}@localhost`;
627
+ prose("The portal admits one address on this install, and that address is also what decides who is an",
628
+ "administrator. Enter accepts the local-account form, which is this machine and nobody else.");
629
+ for (;;) {
630
+ const typed = String(await askValue("Sign-in address:", { def: localDefault })).trim().toLowerCase();
631
+ if (!typed.includes("@") || typed.indexOf("@") !== typed.lastIndexOf("@")) {
632
+ problem(`"${typed}" is not a single email address. The portal refuses a multi-@ identity outright, `
633
+ + "so this would sign in and then be denied at the door.");
634
+ continue;
635
+ }
636
+ const domain = domainOfEmail(typed);
637
+ const verdict = classifyStaffDomain(domain);
638
+ if (verdict === "public" || verdict === "reserved") {
639
+ // The classifier's own sentence, never a second copy: `clearotron start` prints these same words
640
+ // when it meets the same domain, and two wordings of one refusal is how a reader comes to believe
641
+ // they have met two different problems.
642
+ problem(staffDomainRefusal(domain));
643
+ continue;
644
+ }
645
+ if (verdict === "narrow") {
646
+ ok(`${typed} — this machine only. No domain rule is written, and nobody else is granted anything.`);
647
+ return { PORTAL_LOCAL_USER: typed };
648
+ }
649
+ // `wide`: a real domain, so the grant is a grant. Stated first, in the settings page's own words,
650
+ // and Enter is NOT a yes — the default is no, because this is the one answer in the wizard that
651
+ // admits people the reader has never met.
652
+ say("");
653
+ warn(`${typed} makes this a rule about ${domain}, not about you.`);
654
+ say(` ${staffGrantSentence(domain, { staffLabel })}`);
655
+ say("");
656
+ say(` Everyone at ${domain} who gets past this install's sign-in door would see every brand owner`);
657
+ say(" on it — every clearance, every report, every configuration. On a laptop that is only you,");
658
+ say(" because only one address can sign in. Behind a company login it is the whole domain.");
659
+ say("");
660
+ if (await confirm(`Grant ${domain} that, and write it down as PORTAL_STAFF_DOMAINS?`, false))
661
+ return { PORTAL_LOCAL_USER: typed, PORTAL_STAFF_DOMAINS: domain };
662
+ info(`nothing granted${envPath ? `, and nothing written to ${envPath}` : ""}. ${typed} would sign in `
663
+ + "and every page would refuse it, because signing in is not being enrolled — so choose the "
664
+ + "local-account form, or answer yes above.");
665
+ }
666
+ }
667
+
590
668
  /**
591
669
  * An engine binary, resolved the way the engine resolves it — and the trap that resolution carries.
592
670
  *
@@ -693,8 +771,8 @@ export async function preflightCandidate(candidate) {
693
771
  /** Ask EUIPO for a token. This is the check that makes "refuses to persist a bad secret" true. */
694
772
  export async function validateEuipo({ clientId, clientSecret, environment }) {
695
773
  try {
696
- const { resolveConfig } = await import(join(REPO, "providers", "euipo", "src", "core.js"));
697
- const { getAccessToken } = await import(join(REPO, "providers", "euipo", "src", "euipo-client.js"));
774
+ const { resolveConfig } = await import(pathToFileURL(join(REPO, "providers", "euipo", "src", "core.js")).href);
775
+ const { getAccessToken } = await import(pathToFileURL(join(REPO, "providers", "euipo", "src", "euipo-client.js")).href);
698
776
  await getAccessToken(resolveConfig({ clientId, clientSecret, environment }), { force: true });
699
777
  return { ok: true };
700
778
  } catch (e) {
@@ -705,7 +783,7 @@ export async function validateEuipo({ clientId, clientSecret, environment }) {
705
783
  /** One minimal Perplexity call. Costs a request, so it is never made without being asked for. */
706
784
  export async function validatePerplexity(apiKey) {
707
785
  try {
708
- const { buildRequestBody, callAgentAPI } = await import(join(REPO, "providers", "perplexity", "src", "core.js"));
786
+ const { buildRequestBody, callAgentAPI } = await import(pathToFileURL(join(REPO, "providers", "perplexity", "src", "core.js")).href);
709
787
  await callAgentAPI(apiKey, buildRequestBody({ task: "Reply with the single word: ok.", preset: "fast-search" }), { retries: 0 });
710
788
  return { ok: true };
711
789
  } catch (e) {
@@ -998,9 +1076,9 @@ export async function runCheck() {
998
1076
  }
999
1077
 
1000
1078
  say("\n Node");
1001
- const major = Number(process.versions.node.split(".")[0]);
1002
- if (major >= NODE_FLOOR) ok(`node ${process.versions.node}`);
1003
- else problem(`node ${process.versions.node} — this engine needs >= ${NODE_FLOOR} (node:sqlite and TS type-stripping are load-bearing)`);
1079
+ const nodeV = nodeFloorVerdict();
1080
+ if (nodeV.ok) ok(`node ${nodeV.current}`);
1081
+ else problem(`node ${nodeV.current} — this engine needs ${nodeV.required} or newer; node:sqlite is not a built-in module before then`);
1004
1082
 
1005
1083
  // Read the file up here rather than at the `.env` heading below: the engine section is the first that
1006
1084
  // needs `effective()`, and which ENGINE is configured decides which binary variable to check. Reading
@@ -1053,7 +1131,7 @@ export async function runCheck() {
1053
1131
  // deliberate — a second reader would drift from this one exactly as the composer and the checker did
1054
1132
  // in F41, and the drift is invisible because both sides keep passing their own arms.
1055
1133
  const unitDir = join(homedir(), ".config", "systemd", "user");
1056
- const { BACKGROUND_UNITS } = await import(join(REPO, "bin", "start.mjs"));
1134
+ const { BACKGROUND_UNITS } = await import(pathToFileURL(join(REPO, "bin", "start.mjs")).href);
1057
1135
  const hosted = BACKGROUND_UNITS.some((u) => existsSync(join(unitDir, u)));
1058
1136
  const unitEnv = hosted
1059
1137
  ? unitEnvironment({
@@ -1166,8 +1244,48 @@ export async function runCheck() {
1166
1244
  + "and the MCP connection are live right now; `npm run example` needs no engine.");
1167
1245
  info(`To leave demo: install ${engSpec.vendor}'s CLI (\`${engSpec.fallback}\`), then ${engSpec.signIn}.`);
1168
1246
  } else {
1169
- info("MODE: engine attached, sign-in UNPROVEN a binary resolves, and whether it can complete a turn "
1170
- + "is not knowable from the filesystem. --probe-engine is what settles it.");
1247
+ info("The engine program is installed. Whether it is signed in cannot be read from disk: run "
1248
+ + "clearotron doctor --probe-engine to find out.");
1249
+ }
1250
+
1251
+ // AND WHETHER THE ENGINE AGREES, which is a different question from the one above and the reason an
1252
+ // outside user gave up on this product. This command reads its OWN environment; the portal's New
1253
+ // clearance screen reads what the engine recorded when it last started. Both were right and they
1254
+ // said opposite things, so a reader who checked the confident-looking one first was told the engine
1255
+ // was fine while no search would start. Reported here in the same words the configuration page uses,
1256
+ // because a doctor that cannot see a contradiction the product ships with is the wrong doctor.
1257
+ try {
1258
+ const { readFlagSnapshot, postureDisagreement } = await import("../driver/flag-snapshot.mjs");
1259
+ // THE READ-SIDE ACCESSOR, because this is a read: `config.poolRoot` throws on a box with no pool
1260
+ // configured, and `readFlagSnapshot(null)` already answers "no capture" for exactly that case.
1261
+ const snap = readFlagSnapshot(config.poolRootOrNull);
1262
+ const rows = snap
1263
+ ? postureDisagreement(snap, { flags: {}, engine: engineInventory(invEnv) })
1264
+ : null;
1265
+ // NULL IS NOT AGREEMENT and neither is an empty pool — a box with no capture has nothing to
1266
+ // disagree with, and saying so beats printing a clean bill nobody measured.
1267
+ const clash = (rows ?? []).find((r) => r.what === "engine program");
1268
+ if (clash) {
1269
+ problem(`The engine that last ran and this machine disagree about the engine program: the last run `
1270
+ + `recorded it as ${clash.capture}, this machine reads it as ${clash.live}. A NEW search will `
1271
+ + `refuse while that is true. Restart the engine service so it re-reads its PATH, or install the `
1272
+ + `CLI where the service can see it.`);
1273
+ }
1274
+ } catch (e) {
1275
+ // WHAT ACTUALLY REACHES THIS CATCH, established by driving it rather than by reading it.
1276
+ //
1277
+ // Not a box with no pool: `poolRootOrNull` answers null and `readFlagSnapshot(null)` answers null,
1278
+ // neither throwing. And NOT an unreadable capture either — `readFlagSnapshot` has its own try and
1279
+ // returns null for a corrupt file, so a damaged capture is already indistinguishable from an absent
1280
+ // one by the time this code sees it. That is worth knowing and is not this change's to fix.
1281
+ //
1282
+ // So this catch covers an import that has broken or an unexpected throw out of the comparison —
1283
+ // the check having stopped running. A doctor silent about its own failure is the defect the rest of
1284
+ // this change is about, an absence rendered as a clean bill, so it says so. A caution rather than a
1285
+ // problem: the engine may be perfectly fine and it is this check that is broken.
1286
+ info(`Could not compare this machine against what the engine last recorded (${e?.message ?? e}). `
1287
+ + `That comparison is what catches a settings page reading healthy while a search will not start, `
1288
+ + `so this run has not checked it either way.`);
1171
1289
  }
1172
1290
 
1173
1291
  // item 5 — WHICH BILLING LANE, reported rather than left to be inferred from a variable's
@@ -1188,8 +1306,8 @@ export async function runCheck() {
1188
1306
  if (e) envForResolve[k] = e.v;
1189
1307
  }
1190
1308
  const auth = resolveAuthMode({ engineName: engineId, env: envForResolve });
1191
- if (auth.mode === "unknown") info(`billing lane: not policied for ${engineId} — this engine declares no auth modes`);
1192
- else ok(`billing lane: ${auth.mode}${auth.apiBilled ? ` — metered per token against ${engSpec.apiKeyEnv}` : " — drawn against the signed-in subscription, not metered per token"}`);
1309
+ if (auth.mode === "unknown") info(`billing: no policy for ${engineId} — this engine declares no sign-in modes`);
1310
+ else ok(`billing: ${auth.mode}${auth.apiBilled ? ` — charged per token against ${engSpec.apiKeyEnv}` : " — charged to the signed-in subscription, not per token"}`);
1193
1311
  } catch (e) {
1194
1312
  problem(String(e?.message ?? e));
1195
1313
  }
@@ -1366,7 +1484,7 @@ export async function runCheck() {
1366
1484
  // Both lines were honest about their own source and neither said what it was. The first reads this
1367
1485
  // command's env file; the second reads THIS PROCESS's resolution, and a CLI is started by a login
1368
1486
  // shell that carries none of the units' `EnvironmentFile`. The deployment was correct and served
1369
- // celsius, microsoft and generic throughout.
1487
+ // the configured roster throughout.
1370
1488
  //
1371
1489
  // THE UNITS' ENV IS NOT PASSED INTO `profileStoreResolution`, deliberately. `PROFILES_OVERLAY_DIR`
1372
1490
  // is captured when profiles.mjs LOADS, so handing it the units' value would set `live` with no
@@ -1418,17 +1536,38 @@ export async function runCheck() {
1418
1536
  const demo = keys.filter((k) => roster.get(k)?.demoData === true);
1419
1537
  // `generic` is the universal fallback the module requires by name, not a brand owner somebody
1420
1538
  // onboarded — counting it would tell an operator with an empty store that they have one.
1421
- const owners = keys.filter((k) => k !== "generic");
1539
+ //
1540
+ // A DEMO ACCOUNT IS NOT AN ONBOARDED OWNER EITHER, and until this line it was counted as one. A
1541
+ // fresh install used to ship the demo account into every roster, so `doctor` reported "1 brand
1542
+ // owner(s) resolve here: demo-brand-owner (DEMO DATA)" on a machine where nobody had onboarded
1543
+ // anything — and never named `generic`, which is the account that actually rates a run there.
1544
+ // The reader is told they have a customer and not told what they are running on. Both halves
1545
+ // wrong from one list.
1546
+ //
1547
+ // SINCE 2026-09-08 A FRESH INSTALL RESOLVES `generic` ALONE (owner ruling): nobody should have to
1548
+ // clean demo material out of an environment they just created. So the demo branch below no longer
1549
+ // fires on a plain install — it fires inside the demo, which asks for its own account. It is kept
1550
+ // rather than deleted because it is still reachable, and a reader who meets the demo account
1551
+ // there is owed the same two facts: it is fiction, and a real clearance under it is refused at
1552
+ // the admission wall.
1553
+ //
1554
+ // Three states, told apart, because they mean three different things to whoever is reading:
1555
+ // an onboarded roster, the house default alone, and the house default beside what the demo
1556
+ // brought with it.
1557
+ const owners = keys.filter((k) => k !== "generic" && !demo.includes(k));
1422
1558
  if (!owners.length) {
1423
- info(`no brand owners resolve here only the \`generic\` fallback. An empty store is a working `
1424
- + `install on Generic defaults; it is also what a store pointed at the wrong directory looks like`);
1559
+ const base = "`generic` is the account this install rates under the house default, and the "
1560
+ + "only one a clean install has";
1561
+ if (demo.length) {
1562
+ info(`${base}. The demo brought one with it, marked DEMO DATA: ${demo.join(", ")} — fiction `
1563
+ + "rather than an account anybody onboarded, and a real clearance under one is refused");
1564
+ } else {
1565
+ info(`${base}. An empty store is a working install on Generic defaults; it is also what a `
1566
+ + "store pointed at the wrong directory looks like");
1567
+ }
1425
1568
  } else {
1426
- const marked = owners.map((k) => (demo.includes(k) ? `${k} (DEMO DATA)` : k)).join(", ");
1427
- const line = `${owners.length} brand owner(s) resolve here: ${marked}`;
1428
- // The demo marker is the member-level half: naming the store is not the
1429
- // same as saying the accounts in it are fiction, and a real clearance under one is refused at
1430
- // the admission wall — which an operator should learn here rather than from that refusal.
1431
- if (demo.length) info(`${line} — accounts marked DEMO DATA cannot start a real clearance`);
1569
+ const line = `${owners.length} brand owner(s) resolve here: ${owners.join(", ")}`;
1570
+ if (demo.length) info(`${line}. The demo brought one with it, marked DEMO DATA: ${demo.join(", ")} — not counted above, and a real clearance under one is refused`);
1432
1571
  else ok(line);
1433
1572
  }
1434
1573
  try {
@@ -1513,7 +1652,7 @@ export async function runCheck() {
1513
1652
  //
1514
1653
  // REPORTS, NEVER JUDGES: nothing here sets `problem()`. Drift is information for the reader, not a
1515
1654
  // fault in their install, and a doctor that called their own overrides broken would be wrong.
1516
- say("\n Doctrine overlay");
1655
+ say("\n Custom instructions");
1517
1656
  try {
1518
1657
  const report = overlayReport({ baseRoot: config.skillsBaseDir, overlayRoot: config.skillsOverlayDir });
1519
1658
  for (const line of renderOverlayReport(report, { indent: "" })) say(` ${line}`);
@@ -1528,7 +1667,7 @@ export async function runCheck() {
1528
1667
  // answer for somebody running the engine by hand. This line is what the services see.
1529
1668
  const svcDoctrine = effectiveForService("CLEAROTRON_INSTRUCTIONS_DIR");
1530
1669
  if (hosted && serviceKnown && svcDoctrine?.v && svcDoctrine.v !== config.skillsOverlayDir) {
1531
- info(`the services read a doctrine overlay this process does not: ${svcDoctrine.v} `
1670
+ info(`the services read custom instructions this process does not: ${svcDoctrine.v} `
1532
1671
  + `(${svcDoctrine.from}). The lines above are this command's own environment — a CLI is not `
1533
1672
  + "started by the units' EnvironmentFile, so \"none configured\" here is not a statement about "
1534
1673
  + "the deployment");
@@ -1541,7 +1680,7 @@ export async function runCheck() {
1541
1680
  // An unreadable overlay THROWS by design (config.resolveSkillPath refuses rather than falling back
1542
1681
  // to the product's copy). Surfaced here rather than allowed to abort the whole check: the doctor's
1543
1682
  // job is to report every section, and a section that kills the run tells the reader least.
1544
- problem(`the doctrine overlay could not be read — ${e.message}`);
1683
+ problem(`the custom instructions could not be read — ${e.message}`);
1545
1684
  }
1546
1685
 
1547
1686
  say("\n Register provider");
@@ -1585,7 +1724,7 @@ export async function runCheck() {
1585
1724
  say("\n Research provider");
1586
1725
  const px = effective("PERPLEXITY_API_KEY");
1587
1726
  if (px) ok(`PERPLEXITY_API_KEY present (${px.from}) — presence only; add --probe-providers to prove it answers`);
1588
- else info("PERPLEXITY_API_KEY is not set — the three clearance searches carry the common-law grid and cannot switch it off, so a clearance refuses at preflight; a Knockout search still runs and discloses the half it skipped");
1727
+ else info("PERPLEXITY_API_KEY is not set — the three clearance searches carry the common-law grid and cannot switch it off, so a clearance stops before it starts, and names the missing key; a Knockout search still runs and discloses the half it skipped");
1589
1728
 
1590
1729
  // ── — THE LANES A PRODUCT DECLARES IT NEEDS, BEFORE A REPORT NAMES THEM ──
1591
1730
  //
@@ -1663,7 +1802,7 @@ export async function runCheck() {
1663
1802
  // could print, and the portal's own config view does — is deliberately not printed here: `doctor` goes
1664
1803
  // to a terminal, into a paste, into an issue.
1665
1804
  // THE ONE CONDITION THAT STOPS THE PORTAL RENDERING, and `doctor` said nothing about it at all
1666
- // (bb8, F2). `portal-ui/dist` is committed, so an absent bundle means a bad checkout on
1805
+ // (found in review). `portal-ui/dist` is committed, so an absent bundle means a bad checkout on
1667
1806
  // a deployment and an unbuilt tree on a source clone; the service already answers 503 and says so in
1668
1807
  // its boot log, but a reader who runs `doctor` BEFORE `start` — which is the order every document
1669
1808
  // gives — had no way to learn it. The product's OWN predicate decides rather than a second existence
@@ -1770,7 +1909,7 @@ export async function runCheck() {
1770
1909
  }
1771
1910
  }
1772
1911
 
1773
- say("\n Portal door");
1912
+ say("\n Portal sign-in");
1774
1913
  {
1775
1914
  const { authView } = await import("../driver/portal-config-view.mjs");
1776
1915
  const door = authView({
@@ -1785,10 +1924,11 @@ export async function runCheck() {
1785
1924
  // NOT A TICK, AND THAT IS THE POINT. This reads the environment THIS command is
1786
1925
  // typed in. `bin/start.mjs` INJECTS `PORTAL_AUTH_MODE: "local"` into the portal's own environment,
1787
1926
  // and a systemd unit's EnvironmentFile can name a third thing — so a green tick here was a
1788
- // confident claim about a door the running service may not be serving. Measured on the test box:
1789
- // doctor said `auth-proxy door (PORTAL_AUTH_MODE is unset)` with a tick while the box served
1790
- // cf-access, and said `local passphrase door` with a tick while it still served cf-access. Both
1791
- // green, neither the door a caller meets.
1927
+ // confident claim about a door the running service may not be serving. Measured on the test
1928
+ // machine, in the wording doctor used at the time: it said `auth-proxy door (PORTAL_AUTH_MODE is
1929
+ // unset)` with a tick while the machine served cf-access, and said `local passphrase door` with a
1930
+ // tick while it still served cf-access. Both green, neither the door a caller meets. Those two
1931
+ // lines read differently now; what they claimed is the point, not how they were worded.
1792
1932
  //
1793
1933
  // The reading is still worth printing — it is what a hand-run process here would use, and it is
1794
1934
  // what `clearotron start` would launch from. It is stated as that, and the sentence below says
@@ -1808,7 +1948,7 @@ export async function runCheck() {
1808
1948
  say(` · local passphrase door (${typed}) — one operator, one passphrase, no identity provider`);
1809
1949
  info(`a lost passphrase is recoverable: ${invocationPrefix()}clearotron passphrase --reset`);
1810
1950
  } else if (door.shape === "fronted") {
1811
- say(` · auth-proxy door (${typed}) — identity is proved by whatever sits in front, and this process trusts it`);
1951
+ say(` · Sign-in: handled by a proxy in front (${typed}) — identity is proved by whatever sits in front, and this process trusts it`);
1812
1952
  for (const v of door.proxyValues) {
1813
1953
  if (v.present) ok(` ${v.name} present`);
1814
1954
  else info(` ${v.name} not set`);
@@ -1908,8 +2048,8 @@ export async function runCheck() {
1908
2048
  say("\n Register lane — proven, not inferred");
1909
2049
  try {
1910
2050
  const [{ activeProvider }, { makeLaneProbe, probeSpend, DEFAULT_CONTROLS, loadProviderCapabilities }] = await Promise.all([
1911
- import(join(REPO, "driver", "driver.config.mjs")),
1912
- import(join(REPO, "providers", "_shared", "lane-probe.mjs")),
2051
+ import(pathToFileURL(join(REPO, "driver", "driver.config.mjs")).href),
2052
+ import(pathToFileURL(join(REPO, "providers", "_shared", "lane-probe.mjs")).href),
1913
2053
  ]);
1914
2054
  const adapter = activeProvider();
1915
2055
  // NOT `adapter.capabilities` — that is null on every adapter, and reading it announced a LOCAL
@@ -1952,7 +2092,7 @@ export async function runCheck() {
1952
2092
  }
1953
2093
  }
1954
2094
 
1955
- say("\n Data-plane paths");
2095
+ say("\n Where files are stored");
1956
2096
  // Each entry is a FUNCTION, called only on the branch that prints it, so a getter is read at access
1957
2097
  // time and never captured as a constant here. The reader of this command is deciding what to
1958
2098
  // provision; a default quoted from memory is the one thing that can send them to the wrong path and
@@ -1963,7 +2103,7 @@ export async function runCheck() {
1963
2103
  // whole rather than summarised: a summary is a second copy, and a second copy is what drifted.
1964
2104
  ["CLEAROTRON_REPORTS_DIR", (name) => {
1965
2105
  const d = defaultWith(name, () => config.poolRoot);
1966
- return d.refusal ?? `${name} is not set — the published-report pool falls back to ${d.value}`;
2106
+ return d.refusal ?? `${name} is not set — the published-reports folder falls back to ${d.value}`;
1967
2107
  }],
1968
2108
  ["CLEAROTRON_WORK_DIR", (name) => {
1969
2109
  const d = defaultWith(name, () => config.workspaceRoot);
@@ -1985,67 +2125,6 @@ export async function runCheck() {
1985
2125
  // The status surface the ruling names: "status should say whether a key is still valid". Stopping
1986
2126
  // the door revokes nothing — a key outlives every teardown until it expires or its id is denylisted —
1987
2127
  // so a doctor that reported the unit and stayed silent about the keys would bless exactly the state
1988
- // the issue was filed about. Judged by the verifier's own pieces (`connectKeyReport` takes the real
1989
- // `isRevoked`), never by a second opinion written here.
1990
- // ── THE PROFILE STORE RESOLVES, OR THE PORTAL 500s ────────────────────────
1991
- //
1992
- // Asked by RUNNING the engine's own resolution, not by re-deriving it: loadProfiles() layers the
1993
- // configured store over the bundled base with generic falling through by name, and its refusal text
1994
- // is the exact line the portal prints on every screen when this is broken. A doctor that stayed
1995
- // green over that state would bless the owner's fresh-install 500.
1996
- say("\n Profile store");
1997
- try {
1998
- const { loadProfiles } = await import(join(REPO, "driver", "profiles.mjs"));
1999
- const resolved = loadProfiles({ force: true });
2000
- const named = [...resolved.keys()];
2001
- ok(`resolves: ${named.length} profile(s) (${named.slice(0, 6).join(", ")}${named.length > 6 ? ", …" : ""}) — the universal fallback is present`);
2002
- } catch (e) {
2003
- problem(`the profile store does NOT resolve — every portal profile screen and every run refuses on this: ${e.message}`);
2004
- }
2005
-
2006
- // ── THE SUBMIT LANE, WALKED (the owner's 502, 2026-09-02) ────────────────────────────────────────
2007
- //
2008
- // Every surface on that box was green while the portal's Start button had no engine to call. This is
2009
- // the only check that asks the question the client's own path asks, so it goes before the connector
2010
- // section: a dead submit lane matters more than a connector nobody has configured yet.
2011
- // ── SETTINGS THIS BUILD DOES NOT READ ( tracker issue 168) ────────────────────────────────────────
2012
- //
2013
- // THE SURFACE AN OPERATOR CHECKS AFTER AN UPGRADE, and until now the surface that told them
2014
- // everything was fine. Upgrading the production install across the `PRELIM_*` rename left thirteen
2015
- // configured settings with no reader in the new build; doctor exited 0 and mentioned none of them.
2016
- //
2017
- // EVERY ENVIRONMENT THE DEPLOYMENT ACTUALLY READS, not this shell's alone — the F34 lesson one step
2018
- // on. A hosted box's values live in the file the units load, so checking `process.env` here would
2019
- // pass a box whose units carry thirteen dead lines. Each source is named in its own row: "it is in
2020
- // your env file" and "it is in the units' environment" are different fixes.
2021
- //
2022
- // A source that could not be read is NOT reported as clean. `unitEnvironment` already distinguishes
2023
- // that, and an unreadable unit environment is said out loud rather than counted as zero dead names —
2024
- // an absence of evidence is not evidence of absence, and this whole check exists because something
2025
- // invisible was being read as fine.
2026
- {
2027
- const { retiredSpellingsIn, retiredSpellingLine } = await import(join(REPO, "shared", "env-aliases.mjs"));
2028
- const sources = [
2029
- { label: "your environment file", env: fileEnv, known: true },
2030
- { label: "this shell's environment", env: process.env, known: true },
2031
- ];
2032
- if (hosted) sources.push({ label: "the units' environment", env: unitEnv?.env, known: unitEnv?.known === true });
2033
-
2034
- const seen = new Set();
2035
- let anyUnknown = false;
2036
- for (const src of sources) {
2037
- if (!src.known || !src.env) { if (src.label === "the units' environment") anyUnknown = true; continue; }
2038
- for (const row of retiredSpellingsIn(src.env)) {
2039
- // One row per NAME, not per source: a name set in both the file and the units is one thing to
2040
- // fix, and two rows would read as two faults.
2041
- if (seen.has(row.name)) continue;
2042
- seen.add(row.name);
2043
- inertSetting(`${retiredSpellingLine(row)} (found in ${src.label})`);
2044
- }
2045
- }
2046
- if (anyUnknown) warn(couldNotDetermine("retired setting names", unitEnv));
2047
- if (!seen.size && !anyUnknown) ok("no retired setting names — every configured name is one this build reads");
2048
- }
2049
2128
 
2050
2129
  // LINGERING, WHICH NOTHING ELSE CHECKS ( — F9). `--background` installs USER units,
2051
2130
  // and a user manager without lingering is torn down at logout: the units stop with the session and
@@ -2075,9 +2154,9 @@ export async function runCheck() {
2075
2154
  + "failing to look, not a report that it is off.");
2076
2155
  }
2077
2156
 
2078
- say("\n Submit lane");
2157
+ say("\n Start-button path");
2079
2158
  try {
2080
- const { triggerLaneVerdict, HOSTED, SUPERVISED } = await import(join(REPO, "shared", "trigger-lane.mjs"));
2159
+ const { triggerLaneVerdict, HOSTED, SUPERVISED } = await import(pathToFileURL(join(REPO, "shared", "trigger-lane.mjs")).href);
2081
2160
  // POSTURE FROM THE BOX, NOT FROM A FLAG. Units installed means the units serve, and the units read
2082
2161
  // %h/.env — so an absent value there is the incident. No units means `start` supervises and derives
2083
2162
  // the value at runtime, where reading this process's environment says nothing either way.
@@ -2117,7 +2196,7 @@ export async function runCheck() {
2117
2196
  // Stop control's availability on — one reader, two surfaces.
2118
2197
  let verbs = null;
2119
2198
  try {
2120
- const { opsTokenPosture } = await import(join(REPO, "driver", "portal-service.mjs"));
2199
+ const { opsTokenPosture } = await import(pathToFileURL(join(REPO, "driver", "portal-service.mjs")).href);
2121
2200
  verbs = opsTokenPosture(opsToken).verbs;
2122
2201
  } catch { /* unreadable posture leaves verbs null, which reads as full ops — see the verdict */ }
2123
2202
  let probe = null;
@@ -2153,12 +2232,12 @@ export async function runCheck() {
2153
2232
  } catch (e) { warn(`the submit lane could not be read: ${e.message}`); }
2154
2233
 
2155
2234
  say("\n Client connector");
2156
- // THE REVOCATION LIST, REPORTED ( bb8's F14). `isRevoked` treats an unreadable
2235
+ // THE REVOCATION LIST, REPORTED (found in review). `isRevoked` treats an unreadable
2157
2236
  // denylist as "not revoked", so a named-but-absent file makes every revocation silently ineffective:
2158
2237
  // measured on a default install, a revoked key completed a full handshake with nothing logged. Nothing
2159
2238
  // surfaced that state anywhere, which is why it survived to be found by hand.
2160
2239
  {
2161
- const { defaultDenylistPath } = await import(join(REPO, "shared", "client-door.mjs"));
2240
+ const { defaultDenylistPath } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
2162
2241
  const dl = effective("TRADEMARK_MCP_TOKEN_DENYLIST")?.v || defaultDenylistPath(homedir());
2163
2242
  try {
2164
2243
  const n = readFileSync(dl, "utf8").split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#")).length;
@@ -2172,8 +2251,8 @@ export async function runCheck() {
2172
2251
  }
2173
2252
  }
2174
2253
  try {
2175
- const { clientDoorState: doorState, describeDoorState, connectKeyReport, CLIENT_DOOR_UNIT: doorUnit } = await import(join(REPO, "shared", "client-door.mjs"));
2176
- const { loadGrants: readGrantsFile, isRevoked: revokedCheck } = await import(join(REPO, "shared", "scope.mjs"));
2254
+ const { clientDoorState: doorState, describeDoorState, connectKeyReport, CLIENT_DOOR_UNIT: doorUnit } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
2255
+ const { loadGrants: readGrantsFile, isRevoked: revokedCheck } = await import(pathToFileURL(join(REPO, "shared", "scope.mjs")).href);
2177
2256
  // ── CONFIGURED IS NOT RUNNING, AND THIS IS THE SURFACE IT WAS MEASURED ON ──
2178
2257
  //
2179
2258
  // `describeDoorState` was written for exactly this block and then never called from it: the split
@@ -2242,14 +2321,14 @@ export async function runCheck() {
2242
2321
  const doorEnvKnown = !hosted || unitEnv?.known === true;
2243
2322
  const doorEnv = hosted && unitEnv?.known === true ? unitEnv.env : process.env;
2244
2323
  if (!doorEnvKnown) warn(couldNotDetermine("CLIENT_MCP_ACCOUNT_ACCESS", unitEnv));
2245
- // THE PORT AND ITS ALLOW-LIST ARE ONE SETTING, AND NOTHING SAID SO (, Hera's
2246
- // operator pass). `start` derives CLIENT_MCP_ALLOWED_HOSTS from the port it resolved, so moving the
2324
+ // THE PORT AND ITS ALLOW-LIST ARE ONE SETTING, AND NOTHING SAID SO (found in an operator pass).
2325
+ // `start` derives CLIENT_MCP_ALLOWED_HOSTS from the port it resolved, so moving the
2247
2326
  // port THROUGH start works. Moving it in the env file the units load does not: the door binds the
2248
2327
  // new port and then answers "403 Invalid Host header" on every request, because the allow-list still
2249
2328
  // names the old one. A door that is up, listening, and refuses everything is the worst of the three
2250
2329
  // states to debug, and nothing surfaced the mismatch.
2251
2330
  {
2252
- const { clientDoorPort: portOf, allowedHosts: hostsFor } = await import(join(REPO, "shared", "client-door.mjs"));
2331
+ const { clientDoorPort: portOf, allowedHosts: hostsFor } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
2253
2332
  const declared = String(effective("CLIENT_MCP_ALLOWED_HOSTS")?.v ?? "").trim();
2254
2333
  if (declared) {
2255
2334
  const port = portOf(doorEnv);
@@ -2265,14 +2344,14 @@ export async function runCheck() {
2265
2344
  }
2266
2345
  }
2267
2346
 
2268
- // IS ANYTHING ANSWERING? ( bb8's F11.) The unit file is evidence about the
2347
+ // IS ANYTHING ANSWERING? (found in review) The unit file is evidence about the
2269
2348
  // background shape only. A foreground `clearotron start` runs the door as its own child with no unit
2270
2349
  // at all, and this section then told a reader whose door was listening that it "is not set up here",
2271
2350
  // pointing them at the command they had just run. One loopback connect settles it, and null stays
2272
2351
  // null — a probe that could not be made is not a door that is absent.
2273
2352
  let doorListening = null;
2274
2353
  try {
2275
- const { clientDoorPort: portOf } = await import(join(REPO, "shared", "client-door.mjs"));
2354
+ const { clientDoorPort: portOf } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
2276
2355
  const { createConnection } = await import("node:net");
2277
2356
  doorListening = await new Promise((resolve) => {
2278
2357
  const sock = createConnection({ host: "127.0.0.1", port: portOf(doorEnv), timeout: 700 });
@@ -2307,10 +2386,10 @@ export async function runCheck() {
2307
2386
  problem("a valid key is on record but NO revocation list is configured (TRADEMARK_MCP_TOKEN_DENYLIST unset) "
2308
2387
  + `— \`${invoke("disconnect")}\` could not actually revoke it. \`${invoke("connect")}\` arms one; set the variable or reconnect.`);
2309
2388
  }
2310
- // THE PUBLISHED ADDRESS, AND WHETHER IT ANSWERS (, acceptance 2). Reported here
2389
+ // THE PUBLISHED ADDRESS, AND WHETHER IT ANSWERS (acceptance 2). Reported here
2311
2390
  // rather than beside the unit, because the unit running and the address being reachable are
2312
2391
  // different facts and the second is the one a client depends on.
2313
- const { clientDoorReachability } = await import(join(REPO, "shared", "client-door.mjs"));
2392
+ const { clientDoorReachability } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
2314
2393
  // FROM THE FILE THE UNITS LOAD, NOT THE SHELL THIS COMMAND WAS TYPED IN (the tracker issue 226
2315
2394
  // family, met again here). On a hosted box the published address lives in the units' environment,
2316
2395
  // and reading `process.env` reported "no client connector address is published — that is correct
@@ -2357,7 +2436,7 @@ export async function runCheck() {
2357
2436
  // No new credential and no provider API: the audience is in the redirect handed to a caller with
2358
2437
  // no session at all, which is the request just made.
2359
2438
  {
2360
- const { readAudience, audienceVerdict } = await import(join(REPO, "shared", "access-audience.mjs"));
2439
+ const { readAudience, audienceVerdict } = await import(pathToFileURL(join(REPO, "shared", "access-audience.mjs")).href);
2361
2440
  const configuredAud = effectiveForService("CLEAROTRON_OIDC_AUDIENCE")?.v ?? "";
2362
2441
  const read = readAudience(probe ?? { error: "the published address was never asked" });
2363
2442
  // NOTHING IS CLAIMED ABOUT A BOX THAT USES NO EDGE. With no audience configured AND no Access
@@ -2370,6 +2449,27 @@ export async function runCheck() {
2370
2449
  // unreachable; repeating it as a second failure teaches the reader that this section
2371
2450
  // double-counts. It still states what was NOT established, which is the whole job.
2372
2451
  else if (v.kind === "could-not-look") info(v.message);
2452
+ // NO ACCESS IN FRONT OF THE CLIENT DOOR IS A POSTURE, NOT A FAULT (owner ruling 2026-09-08).
2453
+ //
2454
+ // This is the CLIENT connector's address, and how a client reaches it is the client's decision:
2455
+ // "client access sitting behind OAuth is totally up to a client — plenty might just run it token
2456
+ // based on their own laptop." A door answering with its own Bearer challenge and no Access front
2457
+ // is a supported shape, not a misconfiguration, so raising it made `doctor` exit 1 on a healthy
2458
+ // deployment and taught its reader to skim the one command that must never be skimmed.
2459
+ //
2460
+ // It is still SAID rather than dropped, and it still states what was not established: an
2461
+ // audience that was never compared is not an audience that agreed. What changed is that the
2462
+ // sentence no longer calls a client's own arrangement a finding about this install.
2463
+ //
2464
+ // Scoped deliberately to `not-fronted` on THIS address. A configured audience that DISAGREES
2465
+ // with the one the edge issues is still a fault, and the portal and ops surfaces are untouched —
2466
+ // they are checked elsewhere and Access in front of them is not optional.
2467
+ else if (v.kind === "not-fronted") {
2468
+ info(`nothing is fronting this hostname with Access — ${read.why}. That is this client door's `
2469
+ + "posture rather than a fault: a client may reach it with its own token and no Access in "
2470
+ + "front, which is a supported shape. The configured audience was not compared against this "
2471
+ + "address, so nothing here says the two agree.");
2472
+ }
2373
2473
  else problem(v.message);
2374
2474
  }
2375
2475
  }
@@ -2383,7 +2483,7 @@ export async function runCheck() {
2383
2483
  // announces the side effect first, and its control runs before any vendor.
2384
2484
  if (PROBE_CONNECTOR && String(published ?? "").trim()) {
2385
2485
  const { registrationEndpointFrom, probeRegistration, describeRegistration } =
2386
- await import(join(REPO, "shared", "connector-signin-probe.mjs"));
2486
+ await import(pathToFileURL(join(REPO, "shared", "connector-signin-probe.mjs")).href);
2387
2487
  say("");
2388
2488
  say(" --probe-connector: asking this door's sign-in whether each assistant vendor could register.");
2389
2489
  say(" Each attempt that SUCCEEDS creates a throwaway OAuth client on your account, which you may");
@@ -2571,7 +2671,7 @@ try {
2571
2671
  // is DERIVED: the engines from ENGINE_BINARIES, the search vendors from the same adapter tables the
2572
2672
  // prompts loop over, each wearing its own table row's where-to-get line. A hand-kept copy here would
2573
2673
  // be the SERPAPI defect again, one screen earlier. Everything is skippable; the list says so.
2574
- // THE BANNER — once, on entry, named (, owner ruling 2026-08-31). Not on every
2674
+ // THE BANNER — once, on entry, named (owner ruling 2026-08-31). Not on every
2575
2675
  // command: a banner every verb prints is how a product becomes tiresome to use twice. It sits here
2576
2676
  // rather than at the top of main() so that `--check`, which writes nothing and is run repeatedly,
2577
2677
  // does not wear it either.
@@ -2581,7 +2681,7 @@ try {
2581
2681
  say("");
2582
2682
  say(` ${style.bold("Before you start")} — what this setup can take, so nothing here surprises you:`);
2583
2683
  // `vendor`, not `label`: the labels are engineer sentences carrying flag names, and a question a
2584
- // lawyer reads may not ('s first rule).
2684
+ // lawyer reads may not (the first rule).
2585
2685
  say(` · Which AI runs the searches (${Object.values(ENGINE_BINARIES).map((e) => e.vendor).join(" or ")}),`);
2586
2686
  say(" and how it bills — the subscription you already sign in with, or an API key.");
2587
2687
  say(" · Your trademark register vendor's credential, if you have one (a register can be chosen later).");
@@ -2594,13 +2694,13 @@ try {
2594
2694
 
2595
2695
  // 1 ── Node
2596
2696
  say(" Node");
2597
- const major = Number(process.versions.node.split(".")[0]);
2598
- if (major < NODE_FLOOR) {
2599
- problem(`node ${process.versions.node} — this engine needs >= ${NODE_FLOOR}. Upgrade Node and run setup again.`);
2697
+ const nodeV = nodeFloorVerdict();
2698
+ if (!nodeV.ok) {
2699
+ problem(`node ${nodeV.current} — this engine needs ${nodeV.required} or newer. Upgrade Node and run setup again.`);
2600
2700
  aborted = "node";
2601
2701
  throw new Error("node floor");
2602
2702
  }
2603
- ok(`node ${process.versions.node}`);
2703
+ ok(`node ${nodeV.current}`);
2604
2704
 
2605
2705
  // 2 ── the engine: which one, which binary, and PROOF that it can run a turn
2606
2706
  //
@@ -2855,7 +2955,7 @@ try {
2855
2955
  }
2856
2956
  }
2857
2957
  }
2858
- // — bb8's F9, and the same trap closed one prompt over. The default
2958
+ // — found in review, and the same trap closed one prompt over. The default
2859
2959
  // was YES, so Enter re-ran a probe that CANNOT succeed until the reader has signed in somewhere
2860
2960
  // else — and the wizard's own header tells them Enter is the safe key. Driven with Enter it went
2861
2961
  // 19 attempts, no cap and no escape, in a wizard whose header says everything here is skippable.
@@ -3049,7 +3149,7 @@ try {
3049
3149
  const baseDefault = join(homedir(), "trademark");
3050
3150
  prose("Reports, run workspaces, queues and locks all live under one directory.");
3051
3151
  if (poolDefault.refusal) {
3052
- prose(`Enter accepts ${baseDefault}. There is no built-in default for the pool — left unset a run`,
3152
+ prose(`Enter accepts ${baseDefault}. There is no built-in default for the reports folder — left unset a run`,
3053
3153
  "refuses and names it rather than guessing — so setup gives it a real path under your home,",
3054
3154
  "and this install publishes only where you own the disk.");
3055
3155
  } else {
@@ -3095,7 +3195,7 @@ try {
3095
3195
  // The escape goes in the BRACKETS and the consequence in `skipped`, matching the two prompts that
3096
3196
  // already take this mode — the question no longer carries "(empty for none)" because the bracket now
3097
3197
  // says it, and a prompt that says it twice in two different wordings is how the two drift apart.
3098
- const reportsUrl = await askValue("Public base URL for the pool:", {
3198
+ const reportsUrl = await askValue("Public base URL for the reports folder:", {
3099
3199
  skippable: true,
3100
3200
  skipped: "CLEAROTRON_REPORTS_URL left unset — runs will deliver, and their notifications will carry no link",
3101
3201
  });
@@ -3134,7 +3234,7 @@ try {
3134
3234
  prose("No default — it is your hostname. Skip it and this stays a local install: everything works",
3135
3235
  "here, and the Use-your-AI page says so rather than handing out an address that fails.");
3136
3236
  prose("The usual shape, and why: mcp-server/CONNECT.md.");
3137
- const { clientDoorReachability } = await import(join(REPO, "shared", "client-door.mjs"));
3237
+ const { clientDoorReachability } = await import(pathToFileURL(join(REPO, "shared", "client-door.mjs")).href);
3138
3238
  for (;;) {
3139
3239
  const clientUrl = await askValue("Public connector address:", {
3140
3240
  skippable: true,
@@ -3177,7 +3277,7 @@ try {
3177
3277
  // making a decision about where their customer data lives without being told they had made it.
3178
3278
  const cfgDefault = join(base, "config");
3179
3279
  say("\n Where this install keeps its own configuration");
3180
- prose("Your customers and any doctrine you override live here, outside the checkout — which is what",
3280
+ prose("Your customers and any instructions you override live here, outside the checkout — which is what",
3181
3281
  "lets you take updates with `git pull` instead of merging into files you never meant to own.");
3182
3282
  prose(`Enter accepts ${cfgDefault}, and your customers are written there.`);
3183
3283
  const cfg = await askValue("Configuration directory:", { def: cfgDefault });
@@ -3202,7 +3302,7 @@ try {
3202
3302
  candidate.PROFILE_REPO_ROOT = cfg; // no alias row — this name is current
3203
3303
  for (const k of ["CLEAROTRON_CUSTOMERS_DIR", "PROFILE_REPO_ROOT"]) ok(`${k}=${candidate[k]}`);
3204
3304
 
3205
- // CLEAROTRON_INSTRUCTIONS_DIR IS DELIBERATELY NOT WRITTEN ( bb8's F25).
3305
+ // CLEAROTRON_INSTRUCTIONS_DIR IS DELIBERATELY NOT WRITTEN (found in review).
3206
3306
  //
3207
3307
  // Setup used to point it at `<cfg>/skills` and create that directory empty. `clearotron start` then
3208
3308
  // makes `<cfg>` a git repository for saved searches — so the doctrine store ends up INSIDE a checkout
@@ -3218,7 +3318,7 @@ try {
3218
3318
  // Note for whoever adds an overlay later: it needs this name set, which is why the line below says so
3219
3319
  // rather than leaving a reader to discover that files they dropped in are being ignored.
3220
3320
  info(`doctrine: this install overrides nothing, so CLEAROTRON_INSTRUCTIONS_DIR stays unset and the `
3221
- + `product's own files are used. To override a doctrine file later, put it in ${join(cfg, "skills")}, `
3321
+ + `product's own files are used. To override an instruction file later, put it in ${join(cfg, "skills")}, `
3222
3322
  + `COMMIT it in ${cfg}, and set CLEAROTRON_INSTRUCTIONS_DIR to that directory — an uncommitted store `
3223
3323
  + "cannot be identified, and a run says so rather than guessing.");
3224
3324
 
@@ -3231,10 +3331,26 @@ try {
3231
3331
  // PRECISELY what shows through, because the last wording said "bundled customers" and the loader
3232
3332
  // says otherwise: the demo roster never layers into a deployment (a typo'd key must not resolve to
3233
3333
  // our fixtures), generic.json falls through BY NAME, and doctrine resolves file-by-file.
3234
- say(" Left empty. The house doctrine shows through file-by-file, and generic.json — the universal");
3334
+ say(" Left empty. The bundled instructions show through file-by-file, and generic.json — the universal");
3235
3335
  say(" fallback — falls through by name, so an empty store is a working install. Your own customers");
3236
3336
  say(" are added here by name; the bundled demo customers never show through into your roster.");
3237
3337
 
3338
+ // 7c ── WHO SIGNS IN, AND WHAT THAT ADDRESS GRANTS
3339
+ //
3340
+ // Setup never asked for an address, so `clearotron start` derived one — and derived a staff-domain
3341
+ // rule from everything after its `@`. The whole reasoning, and the install that granted a
3342
+ // documentation domain to a reader who had never been asked, is on `askSignIn` above.
3343
+ section("Who signs in");
3344
+ const localAccount = (() => {
3345
+ try { return userInfo().username || "user"; } catch { return "user"; }
3346
+ })();
3347
+ // ONE CALL SITE. The loop itself lives in `askSignIn` so that the branch that matters — a reader who
3348
+ // pressed Enter at the grant question, and a staff rule that must therefore NOT be written — is
3349
+ // reachable without a terminal. The same seam and the same reason as `offerUsptoSync`.
3350
+ Object.assign(candidate, await askSignIn(
3351
+ { askValue, confirm, say, ok, info, warn, problem },
3352
+ { localAccount, staffLabel: `${BRAND.name} staff`, envPath: ENV_PATH }));
3353
+
3238
3354
  // 8 ── the engine's own preflight over the whole candidate
3239
3355
  //
3240
3356
  // — THIS STEP CHECKS THE REGISTER PROVIDER AND NOTHING ELSE. `preflightCandidate` pins
@@ -3289,7 +3405,7 @@ try {
3289
3405
  // rather than fall back, so a permissions fault can never silently swap a customer's framework for the
3290
3406
  // Generic default). Nothing is written INTO them — see the note at step 7b.
3291
3407
  for (const k of ["CLEAROTRON_CUSTOMERS_DIR"]) mkdirSync(candidate[k], { recursive: true });
3292
- ok(`configuration directories created under ${cfg} (empty — doctrine and the generic fallback show through; customers are yours to add)`);
3408
+ ok(`configuration directories created under ${cfg} (empty — the bundled instructions and the generic fallback show through; customers are yours to add)`);
3293
3409
 
3294
3410
  // 9a ── PUT THE VERB ON THIS OPERATOR'S PATH
3295
3411
  //
@@ -3329,17 +3445,17 @@ try {
3329
3445
  // They are `clearotron` verbs now for a second reason as well: from an INSTALLED package there is
3330
3446
  // no `npm run example` to type — no package.json, no scripts block — so the old advice was not
3331
3447
  // merely misordered there, it was unrunnable.
3332
- // ONE COMMAND, AND WHAT TO EXPECT FROM IT (, the owner's point 10). This screen
3448
+ // ONE COMMAND, AND WHAT TO EXPECT FROM IT (the owner's point 10). This screen
3333
3449
  // offered three, each with a sentence, and a reader who has just answered a page of questions is
3334
3450
  // being asked to make one more choice at the moment they most want to be told what to do. Three
3335
3451
  // equally-weighted options is not generosity; it is the decision handed back.
3336
3452
  //
3337
3453
  // `start` is the one, because it is the product — the other two were already ordered behind it for
3338
- // that reason (, when this screen offered `npm run example` and a raw pipeline invocation and
3454
+ // that reason (when this screen offered `npm run example` and a raw pipeline invocation and
3339
3455
  // named the product nowhere). They keep their place as an afterthought line rather than an option.
3340
3456
  // THE COMMAND LINE STAYS A PLAIN LITERAL, DELIBERATELY. onboard-wizard.test.mjs reads this screen
3341
3457
  // STATICALLY — it extracts every say() literal and asserts which command leads — and that guard is
3342
- // the only thing standing between this screen and 's defect coming back. Wrapping the command in
3458
+ // the only thing standing between this screen and the defect coming back. Wrapping the command in
3343
3459
  // style.bold() puts a nested template literal inside the say(), the extractor stops matching, and the
3344
3460
  // corpus goes empty. Its own comment records the previous generation of exactly this: the arms went
3345
3461
  // vacuous the moment these lines became template literals.
@@ -3360,7 +3476,7 @@ try {
3360
3476
  say(" What this box has now:");
3361
3477
  for (const line of [
3362
3478
  stateLine("register", candidate.CLEAROTRON_DATABASE, "no register, so every search refuses until one is chosen"),
3363
- stateLine("web research", present(candidate.PERPLEXITY_API_KEY) ? "a key" : "", "a clearance refuses at preflight; a knockout search runs and discloses the half it skipped"),
3479
+ stateLine("web research", present(candidate.PERPLEXITY_API_KEY) ? "a key" : "", "a clearance stops before it starts, and names the missing key; a knockout search runs and discloses the half it skipped"),
3364
3480
  stateLine("data directory", candidate.CLEAROTRON_REPORTS_DIR, "unset"),
3365
3481
  stateLine("configuration store", candidate.CLEAROTRON_CUSTOMERS_DIR, "the bundled demo roster"),
3366
3482
  stateLine("notification links", candidate.CLEAROTRON_REPORTS_URL, "notifications carry no link into the report"),