clearotron 0.2.1 → 0.2.2

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 (622) hide show
  1. package/.env.example +54 -1
  2. package/CONTRIBUTING.md +3 -3
  3. package/INSTALL.md +53 -49
  4. package/bin/brandowner.mjs +1 -1
  5. package/bin/clearotron.mjs +4 -4
  6. package/bin/connect.mjs +2 -2
  7. package/bin/example.mjs +27 -11
  8. package/bin/grant.mjs +3 -3
  9. package/bin/key.mjs +1 -1
  10. package/bin/onboard.mjs +58 -118
  11. package/bin/start.mjs +22 -25
  12. package/bin/stop.mjs +65 -3
  13. package/bin/update.mjs +7 -7
  14. package/bin/uspto-sync.mjs +1 -1
  15. package/build-info.json +2 -2
  16. package/docs/DELIVERY.md +6 -2
  17. package/docs/architecture/01-product-overview.md +2 -2
  18. package/docs/architecture/02-architecture.md +2 -2
  19. package/docs/architecture/04-configuration-reference.md +6 -3
  20. package/docs/architecture/05-config-governance.md +38 -5
  21. package/docs/architecture/06-operations-runbook.md +13 -1
  22. package/docs/architecture/09-security-and-data.md +1 -1
  23. package/docs/decisions/0004-documentation-structure.md +1 -1
  24. package/driver/CHANGELOG.md +65 -1
  25. package/driver/README.md +2 -2
  26. package/driver/ask-ledger.mjs +3 -3
  27. package/driver/authority-trees.mjs +1 -1
  28. package/driver/call-capture.mjs +1 -1
  29. package/driver/card-frame.mjs +1 -1
  30. package/driver/case-law-ledger.mjs +1 -1
  31. package/driver/claim-liveness.mjs +1 -1
  32. package/driver/common-law-receipts.mjs +1 -1
  33. package/driver/commonlaw-carry.mjs +1 -1
  34. package/driver/config-inventory.mjs +1 -1
  35. package/driver/connotation-search.mjs +12 -12
  36. package/driver/contract-audit.mjs +5 -5
  37. package/driver/contract-dictation-registry.mjs +4 -4
  38. package/driver/contract-dictation.mjs +2 -2
  39. package/driver/contract-e3-backlog.mjs +6 -6
  40. package/driver/contract-vocabulary.mjs +3 -3
  41. package/driver/corrections-feedforward.mjs +1 -1
  42. package/driver/coverage-form-io.mjs +2 -2
  43. package/driver/coverage-form.mjs +4 -4
  44. package/driver/coverage-ledger.mjs +3 -3
  45. package/driver/coverage-union.mjs +1 -1
  46. package/driver/declination-call.mjs +35 -3
  47. package/driver/declination-duty.mjs +1 -1
  48. package/driver/deliver-trigger.sh +3 -3
  49. package/driver/deploy-live-run-guard.mjs +6 -2
  50. package/driver/dev-portal.mjs +1 -1
  51. package/driver/disposition-call.mjs +4 -4
  52. package/driver/disposition-tool.mjs +4 -4
  53. package/driver/disposition-union.mjs +2 -2
  54. package/driver/doc-constants.mjs +1 -1
  55. package/driver/door-gates.mjs +2 -2
  56. package/driver/doubt-selection.mjs +2 -2
  57. package/driver/drainer-identity.mjs +1 -1
  58. package/driver/driver.config.mjs +63 -11
  59. package/driver/e2e-rounds.mjs +2 -2
  60. package/driver/effort-model.mjs +2 -2
  61. package/driver/engine/anthropic-agent.mjs +24 -24
  62. package/driver/engine/auth.mjs +1 -1
  63. package/driver/engine/common.mjs +1 -1
  64. package/driver/engine/deny-authority-write.mjs +1 -1
  65. package/driver/engine/jx-turn.mjs +1 -1
  66. package/driver/engine/mcp/clarivate-server.mjs +1 -1
  67. package/driver/engine/mcp/corsearch-server.mjs +1 -1
  68. package/driver/engine/mcp/declination-server.mjs +1 -1
  69. package/driver/engine/mcp/dispositions-server.mjs +1 -1
  70. package/driver/engine/mcp/euipo-server.mjs +1 -1
  71. package/driver/engine/mcp/fetch-server.mjs +1 -1
  72. package/driver/engine/mcp/free-tier-server.mjs +2 -2
  73. package/driver/engine/mcp/gather-config.mjs +11 -11
  74. package/driver/engine/mcp/perplexity-server.mjs +1 -1
  75. package/driver/engine/mcp/recording-server.mjs +8 -4
  76. package/driver/engine/mcp/signa-server.mjs +1 -1
  77. package/driver/engine/mcp/uspto-local-server.mjs +1 -1
  78. package/driver/engine/openai-agent.mjs +2 -2
  79. package/driver/engine-build.mjs +2 -2
  80. package/driver/enqueue-schema.mjs +2 -2
  81. package/driver/enqueue.mjs +1 -1
  82. package/driver/envelope-settle.mjs +1 -1
  83. package/driver/evidence-claim-invariant.mjs +2 -2
  84. package/driver/findings-model.mjs +8 -8
  85. package/driver/floor-duty.mjs +1 -1
  86. package/driver/form-neighbourhood.mjs +1 -1
  87. package/driver/framework.mjs +1 -1
  88. package/driver/gateway.mjs +28 -23
  89. package/driver/grounds-grammar.mjs +1 -1
  90. package/driver/hit-list.mjs +1 -1
  91. package/driver/jurisdiction-systems.mjs +1 -1
  92. package/driver/jx-lanes.mjs +1 -1
  93. package/driver/jx-units.mjs +1 -1
  94. package/driver/jx.mjs +3 -3
  95. package/driver/knockout-assess-record.mjs +5 -1
  96. package/driver/narrative-refutation-record.mjs +3 -3
  97. package/driver/numeric-setting.mjs +1 -1
  98. package/driver/owner-use-check.mjs +184 -0
  99. package/driver/package.json +2 -2
  100. package/driver/phase0.mjs +1 -1
  101. package/driver/pipeline-knockout.mjs +52 -4
  102. package/driver/pipeline.mjs +175 -62
  103. package/driver/placement-diff.mjs +2 -2
  104. package/driver/placement-form.mjs +4 -4
  105. package/driver/placement-union.mjs +1 -1
  106. package/driver/portal-acks.mjs +1 -1
  107. package/driver/portal-config-view.mjs +2 -2
  108. package/driver/portal-local-auth.mjs +1 -1
  109. package/driver/portal-report.mjs +6 -6
  110. package/driver/portal-service.mjs +15 -15
  111. package/driver/predelivery-lint.mjs +28 -10
  112. package/driver/prelim-variants-record.mjs +2 -2
  113. package/driver/profile-page.html +1 -1
  114. package/driver/profile-selection.mjs +1 -1
  115. package/driver/profile-service.mjs +2 -2
  116. package/driver/profiles.mjs +1 -1
  117. package/driver/progress.mjs +6 -6
  118. package/driver/provider-usage.mjs +1 -1
  119. package/driver/publish/demo-marking.mjs +1 -1
  120. package/driver/publish/index.mjs +47 -6
  121. package/driver/publish/knockout.mjs +36 -14
  122. package/driver/publish/parse.mjs +4 -4
  123. package/driver/publish/publish-inputs.mjs +2 -2
  124. package/driver/publish/register-presence.mjs +1 -1
  125. package/driver/publish/render-knockout.mjs +198 -31
  126. package/driver/publish/report-data.mjs +13 -3
  127. package/driver/queue-watch-probe.mjs +1 -1
  128. package/driver/queue-watch-verdict.mjs +1 -1
  129. package/driver/recall-reconciliation.mjs +1 -1
  130. package/driver/recipe-service.mjs +1 -1
  131. package/driver/record-carry.mjs +5 -5
  132. package/driver/recording-agreement.mjs +3 -3
  133. package/driver/reference-score.mjs +7 -7
  134. package/driver/refusal-bound.mjs +3 -3
  135. package/driver/register-availability.mjs +2 -2
  136. package/driver/register-count.mjs +1 -1
  137. package/driver/register-grant-vocabulary.mjs +2 -2
  138. package/driver/register-plan.mjs +8 -8
  139. package/driver/register-records.mjs +2 -2
  140. package/driver/registry-fidelity.mjs +3 -3
  141. package/driver/remedy-accounting.mjs +1 -1
  142. package/driver/repair-composers.mjs +2 -2
  143. package/driver/repair-digest.mjs +3 -3
  144. package/driver/repairs.mjs +6 -6
  145. package/driver/replay-archive.mjs +2 -0
  146. package/driver/report-card-record.mjs +2 -2
  147. package/driver/result-noun-fields.mjs +10 -3
  148. package/driver/run-economics.mjs +2 -2
  149. package/driver/run-integrity.mjs +1 -1
  150. package/driver/runner.mjs +22 -22
  151. package/driver/scope-rules.mjs +1 -1
  152. package/driver/search-policy.mjs +3 -3
  153. package/driver/skeptic-search.mjs +1 -1
  154. package/driver/skills/blind-frame/SKILL.md +1 -1
  155. package/driver/skills/case-law-citation/SKILL.md +2 -2
  156. package/driver/skills/knockout-assess/SKILL.md +10 -4
  157. package/driver/skills/prelim-search/SKILL.md +2 -2
  158. package/driver/skills/prelim-search/template-formatting.md +1 -1
  159. package/driver/skills/prelim-search/templates/email/generic.md +1 -1
  160. package/driver/skills/prelim-search/worked-examples.md +1 -1
  161. package/driver/skills/prelim-variants/SKILL.md +2 -2
  162. package/driver/stage-context.mjs +1 -1
  163. package/driver/stages-knockout.mjs +55 -4
  164. package/driver/stages.mjs +97 -40
  165. package/driver/stray-artifacts.mjs +2 -2
  166. package/driver/suite-census.json +146 -32
  167. package/driver/synthesis-record.mjs +1 -1
  168. package/driver/systemd/clearotron-client-mcp.service +1 -1
  169. package/driver/systemd/clearotron-portal.service +1 -1
  170. package/driver/systemd/render-units.mjs +1 -1
  171. package/driver/tokens.mjs +1 -1
  172. package/driver/tool-calls.mjs +1 -1
  173. package/driver/turnaround-bands.mjs +1 -1
  174. package/driver/unit-file-drift.mjs +1 -1
  175. package/driver/unit-inventory.mjs +121 -61
  176. package/driver/unit-state-verdict.mjs +20 -12
  177. package/driver/verify-knockout.mjs +10 -2
  178. package/driver/verify.mjs +12 -12
  179. package/driver/whatif-memo-run.mjs +46 -5
  180. package/driver/whatif-queue.mjs +1 -1
  181. package/driver/whatif-worker.mjs +1 -1
  182. package/mcp-server/CHANGELOG.md +4 -0
  183. package/mcp-server/README.md +3 -3
  184. package/mcp-server/http-server.mjs +44 -1
  185. package/mcp-server/key-socket.mjs +184 -0
  186. package/mcp-server/lib/audit-view.mjs +69 -2
  187. package/mcp-server/lib/brief.mjs +15 -0
  188. package/mcp-server/lib/driver.mjs +7 -1
  189. package/mcp-server/lib/events.mjs +1 -1
  190. package/mcp-server/lib/http-handler.mjs +1 -1
  191. package/mcp-server/lib/knockout.mjs +435 -0
  192. package/mcp-server/lib/ops.mjs +4 -4
  193. package/mcp-server/lib/options.mjs +1 -1
  194. package/mcp-server/lib/plan.mjs +1 -1
  195. package/mcp-server/lib/runs.mjs +1 -1
  196. package/mcp-server/lib/scrub.mjs +1 -1
  197. package/mcp-server/lib/whatif.mjs +3 -3
  198. package/mcp-server/mint-token.mjs +1 -1
  199. package/mcp-server/package.json +2 -2
  200. package/mcp-server/server.mjs +76 -11
  201. package/package.json +3 -3
  202. package/portal-ui/package.json +1 -1
  203. package/providers/_shared/enumerate.mjs +1 -1
  204. package/providers/_shared/ledger-path.mjs +3 -3
  205. package/providers/_shared/ledger.mjs +1 -1
  206. package/providers/_shared/result-shape.mjs +3 -3
  207. package/providers/_shared/term-shape.mjs +1 -1
  208. package/providers/corsearch/src/core.js +1 -1
  209. package/providers/jx-subclass/BUILDING.md +1 -1
  210. package/providers/oauth-mcp-bridge/CHANGELOG.md +4 -0
  211. package/providers/oauth-mcp-bridge/package.json +1 -1
  212. package/providers/oauth-mcp-bridge/stdin-guard.mjs +2 -2
  213. package/scripts/README.md +1 -1
  214. package/scripts/added-reference-check.mjs +29 -1
  215. package/scripts/ai-page-render-check.mjs +1 -1
  216. package/scripts/authority-boundary-probe.mjs +1 -1
  217. package/scripts/backfill-started-at.mjs +1 -1
  218. package/scripts/citation-line-check.mjs +3 -3
  219. package/scripts/clearances-render-check.mjs +3 -3
  220. package/scripts/compare.mjs +2 -2
  221. package/scripts/composer-render-check.mjs +6 -6
  222. package/scripts/contract-dictation-scan.mjs +2 -2
  223. package/scripts/dead-names.mjs +1 -1
  224. package/scripts/drain-preflight.mjs +5 -5
  225. package/scripts/e2e-unread-terminals.mjs +1 -1
  226. package/scripts/e2e.mjs +8 -8
  227. package/scripts/env-audit.mjs +7 -7
  228. package/scripts/env-classify.mjs +139 -15
  229. package/scripts/freeze-example-run.mjs +3 -3
  230. package/scripts/head-arrived-gated.mjs +1 -1
  231. package/scripts/headless-page.mjs +51 -2
  232. package/scripts/home-render-check.mjs +2 -2
  233. package/scripts/live-surface-check.mjs +92 -19
  234. package/scripts/main-health.mjs +1 -1
  235. package/scripts/merge-presence-check.mjs +3 -3
  236. package/scripts/mint-suite-census.mjs +6 -6
  237. package/scripts/nightly-notice.mjs +1 -1
  238. package/scripts/portal-lifecycle-check.mjs +3 -3
  239. package/scripts/reconcile-runs.mjs +1 -1
  240. package/scripts/release-await-cut.mjs +6 -4
  241. package/scripts/release-version-pr-checks.mjs +1 -1
  242. package/scripts/release-version.mjs +2 -2
  243. package/scripts/render-check.mjs +66 -7
  244. package/scripts/report-frame-check.mjs +1 -1
  245. package/scripts/report-screenshot.mjs +1 -1
  246. package/scripts/revisit-render-check.mjs +1 -1
  247. package/scripts/score.mjs +4 -4
  248. package/scripts/strip-tracker-citations.mjs +116 -0
  249. package/scripts/test-run.mjs +3 -3
  250. package/scripts/third-party-notices.mjs +3 -3
  251. package/scripts/travelling-predicates.mjs +3 -3
  252. package/scripts/unexecuted-asserts.mjs +2 -2
  253. package/scripts/verify-publishable.mjs +2 -2
  254. package/scripts/write-up-form-census.mjs +1 -1
  255. package/shared/access-audience.mjs +1 -1
  256. package/shared/brand.mjs +13 -13
  257. package/shared/citation-scan.mjs +1 -1
  258. package/shared/client-door.mjs +7 -7
  259. package/shared/driver-dir.mjs +1 -1
  260. package/shared/env-aliases.mjs +0 -48
  261. package/shared/env-local.mjs +1 -1
  262. package/shared/identifier-scan.mjs +3 -3
  263. package/shared/invocation.mjs +1 -1
  264. package/shared/names-in-force.mjs +2 -0
  265. package/shared/product-owned-names.mjs +1 -1
  266. package/shared/register-selection.mjs +1 -1
  267. package/shared/scope.mjs +5 -5
  268. package/shared/server-units.mjs +4 -4
  269. package/shared/store-in-repo.mjs +2 -2
  270. package/shared/suite-census.mjs +4 -4
  271. package/shared/tty-style.mjs +1 -1
  272. package/shared/uspto-index-size.mjs +1 -1
  273. package/shared/vacuous-pass.mjs +1 -1
  274. package/skills/clearotron-account/SKILL.md +42 -13
  275. package/driver/systemd/prelim-driver.path +0 -69
  276. package/driver/systemd/prelim-driver.service +0 -86
  277. package/driver/systemd/prelim-driver.timer +0 -14
  278. package/driver/systemd/prelim-outbox.path +0 -27
  279. package/driver/systemd/prelim-outbox.service +0 -37
  280. package/driver/systemd/prelim-outbox.timer +0 -21
  281. package/node_modules/exceljs/README_zh.md +0 -2878
  282. package/node_modules/exceljs/dist/LICENSE +0 -22
  283. package/node_modules/exceljs/dist/es5/csv/csv.js +0 -182
  284. package/node_modules/exceljs/dist/es5/csv/csv.js.map +0 -1
  285. package/node_modules/exceljs/dist/es5/csv/line-buffer.js +0 -68
  286. package/node_modules/exceljs/dist/es5/csv/line-buffer.js.map +0 -1
  287. package/node_modules/exceljs/dist/es5/csv/stream-converter.js +0 -110
  288. package/node_modules/exceljs/dist/es5/csv/stream-converter.js.map +0 -1
  289. package/node_modules/exceljs/dist/es5/doc/anchor.js +0 -73
  290. package/node_modules/exceljs/dist/es5/doc/anchor.js.map +0 -1
  291. package/node_modules/exceljs/dist/es5/doc/cell.js +0 -961
  292. package/node_modules/exceljs/dist/es5/doc/cell.js.map +0 -1
  293. package/node_modules/exceljs/dist/es5/doc/column.js +0 -274
  294. package/node_modules/exceljs/dist/es5/doc/column.js.map +0 -1
  295. package/node_modules/exceljs/dist/es5/doc/data-validations.js +0 -18
  296. package/node_modules/exceljs/dist/es5/doc/data-validations.js.map +0 -1
  297. package/node_modules/exceljs/dist/es5/doc/defined-names.js +0 -173
  298. package/node_modules/exceljs/dist/es5/doc/defined-names.js.map +0 -1
  299. package/node_modules/exceljs/dist/es5/doc/enums.js +0 -49
  300. package/node_modules/exceljs/dist/es5/doc/enums.js.map +0 -1
  301. package/node_modules/exceljs/dist/es5/doc/image.js +0 -69
  302. package/node_modules/exceljs/dist/es5/doc/image.js.map +0 -1
  303. package/node_modules/exceljs/dist/es5/doc/modelcontainer.js +0 -16
  304. package/node_modules/exceljs/dist/es5/doc/modelcontainer.js.map +0 -1
  305. package/node_modules/exceljs/dist/es5/doc/note.js +0 -64
  306. package/node_modules/exceljs/dist/es5/doc/note.js.map +0 -1
  307. package/node_modules/exceljs/dist/es5/doc/range.js +0 -229
  308. package/node_modules/exceljs/dist/es5/doc/range.js.map +0 -1
  309. package/node_modules/exceljs/dist/es5/doc/row.js +0 -382
  310. package/node_modules/exceljs/dist/es5/doc/row.js.map +0 -1
  311. package/node_modules/exceljs/dist/es5/doc/table.js +0 -443
  312. package/node_modules/exceljs/dist/es5/doc/table.js.map +0 -1
  313. package/node_modules/exceljs/dist/es5/doc/workbook.js +0 -202
  314. package/node_modules/exceljs/dist/es5/doc/workbook.js.map +0 -1
  315. package/node_modules/exceljs/dist/es5/doc/worksheet.js +0 -900
  316. package/node_modules/exceljs/dist/es5/doc/worksheet.js.map +0 -1
  317. package/node_modules/exceljs/dist/es5/exceljs.bare.js +0 -14
  318. package/node_modules/exceljs/dist/es5/exceljs.bare.js.map +0 -1
  319. package/node_modules/exceljs/dist/es5/exceljs.browser.js +0 -36
  320. package/node_modules/exceljs/dist/es5/exceljs.browser.js.map +0 -1
  321. package/node_modules/exceljs/dist/es5/exceljs.nodejs.js +0 -15
  322. package/node_modules/exceljs/dist/es5/exceljs.nodejs.js.map +0 -1
  323. package/node_modules/exceljs/dist/es5/index.js +0 -15
  324. package/node_modules/exceljs/dist/es5/stream/xlsx/hyperlink-reader.js +0 -90
  325. package/node_modules/exceljs/dist/es5/stream/xlsx/hyperlink-reader.js.map +0 -1
  326. package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-comments-writer.js +0 -94
  327. package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-comments-writer.js.map +0 -1
  328. package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-rels-writer.js +0 -94
  329. package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-rels-writer.js.map +0 -1
  330. package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-reader.js +0 -362
  331. package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-reader.js.map +0 -1
  332. package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-writer.js +0 -347
  333. package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-writer.js.map +0 -1
  334. package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-reader.js +0 -392
  335. package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-reader.js.map +0 -1
  336. package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-writer.js +0 -652
  337. package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-writer.js.map +0 -1
  338. package/node_modules/exceljs/dist/es5/utils/auto-drain.js +0 -18
  339. package/node_modules/exceljs/dist/es5/utils/auto-drain.js.map +0 -1
  340. package/node_modules/exceljs/dist/es5/utils/browser-buffer-decode.js +0 -15
  341. package/node_modules/exceljs/dist/es5/utils/browser-buffer-decode.js.map +0 -1
  342. package/node_modules/exceljs/dist/es5/utils/browser-buffer-encode.js +0 -18
  343. package/node_modules/exceljs/dist/es5/utils/browser-buffer-encode.js.map +0 -1
  344. package/node_modules/exceljs/dist/es5/utils/cell-matrix.js +0 -149
  345. package/node_modules/exceljs/dist/es5/utils/cell-matrix.js.map +0 -1
  346. package/node_modules/exceljs/dist/es5/utils/col-cache.js +0 -258
  347. package/node_modules/exceljs/dist/es5/utils/col-cache.js.map +0 -1
  348. package/node_modules/exceljs/dist/es5/utils/copy-style.js +0 -43
  349. package/node_modules/exceljs/dist/es5/utils/copy-style.js.map +0 -1
  350. package/node_modules/exceljs/dist/es5/utils/encryptor.js +0 -58
  351. package/node_modules/exceljs/dist/es5/utils/encryptor.js.map +0 -1
  352. package/node_modules/exceljs/dist/es5/utils/iterate-stream.js +0 -46
  353. package/node_modules/exceljs/dist/es5/utils/iterate-stream.js.map +0 -1
  354. package/node_modules/exceljs/dist/es5/utils/parse-sax.js +0 -47
  355. package/node_modules/exceljs/dist/es5/utils/parse-sax.js.map +0 -1
  356. package/node_modules/exceljs/dist/es5/utils/shared-formula.js +0 -42
  357. package/node_modules/exceljs/dist/es5/utils/shared-formula.js.map +0 -1
  358. package/node_modules/exceljs/dist/es5/utils/shared-strings.js +0 -32
  359. package/node_modules/exceljs/dist/es5/utils/shared-strings.js.map +0 -1
  360. package/node_modules/exceljs/dist/es5/utils/stream-base64.js +0 -66
  361. package/node_modules/exceljs/dist/es5/utils/stream-base64.js.map +0 -1
  362. package/node_modules/exceljs/dist/es5/utils/stream-buf.js +0 -343
  363. package/node_modules/exceljs/dist/es5/utils/stream-buf.js.map +0 -1
  364. package/node_modules/exceljs/dist/es5/utils/string-buf.js +0 -73
  365. package/node_modules/exceljs/dist/es5/utils/string-buf.js.map +0 -1
  366. package/node_modules/exceljs/dist/es5/utils/string-builder.js +0 -32
  367. package/node_modules/exceljs/dist/es5/utils/string-builder.js.map +0 -1
  368. package/node_modules/exceljs/dist/es5/utils/stuttered-pipe.js +0 -61
  369. package/node_modules/exceljs/dist/es5/utils/stuttered-pipe.js.map +0 -1
  370. package/node_modules/exceljs/dist/es5/utils/typed-stack.js +0 -23
  371. package/node_modules/exceljs/dist/es5/utils/typed-stack.js.map +0 -1
  372. package/node_modules/exceljs/dist/es5/utils/under-dash.js +0 -168
  373. package/node_modules/exceljs/dist/es5/utils/under-dash.js.map +0 -1
  374. package/node_modules/exceljs/dist/es5/utils/utils.js +0 -171
  375. package/node_modules/exceljs/dist/es5/utils/utils.js.map +0 -1
  376. package/node_modules/exceljs/dist/es5/utils/xml-stream.js +0 -151
  377. package/node_modules/exceljs/dist/es5/utils/xml-stream.js.map +0 -1
  378. package/node_modules/exceljs/dist/es5/utils/zip-stream.js +0 -79
  379. package/node_modules/exceljs/dist/es5/utils/zip-stream.js.map +0 -1
  380. package/node_modules/exceljs/dist/es5/xlsx/defaultnumformats.js +0 -230
  381. package/node_modules/exceljs/dist/es5/xlsx/defaultnumformats.js.map +0 -1
  382. package/node_modules/exceljs/dist/es5/xlsx/rel-type.js +0 -18
  383. package/node_modules/exceljs/dist/es5/xlsx/rel-type.js.map +0 -1
  384. package/node_modules/exceljs/dist/es5/xlsx/xform/base-xform.js +0 -139
  385. package/node_modules/exceljs/dist/es5/xlsx/xform/base-xform.js.map +0 -1
  386. package/node_modules/exceljs/dist/es5/xlsx/xform/book/defined-name-xform.js +0 -85
  387. package/node_modules/exceljs/dist/es5/xlsx/xform/book/defined-name-xform.js.map +0 -1
  388. package/node_modules/exceljs/dist/es5/xlsx/xform/book/sheet-xform.js +0 -32
  389. package/node_modules/exceljs/dist/es5/xlsx/xform/book/sheet-xform.js.map +0 -1
  390. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js +0 -24
  391. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js.map +0 -1
  392. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-properties-xform.js +0 -27
  393. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-properties-xform.js.map +0 -1
  394. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-view-xform.js +0 -51
  395. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-view-xform.js.map +0 -1
  396. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-xform.js +0 -234
  397. package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-xform.js.map +0 -1
  398. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comment-xform.js +0 -103
  399. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comment-xform.js.map +0 -1
  400. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comments-xform.js +0 -76
  401. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comments-xform.js.map +0 -1
  402. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-position-xform.js +0 -35
  403. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-position-xform.js.map +0 -1
  404. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js +0 -32
  405. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js.map +0 -1
  406. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-anchor-xform.js +0 -53
  407. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-anchor-xform.js.map +0 -1
  408. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-client-data-xform.js +0 -97
  409. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-client-data-xform.js.map +0 -1
  410. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-notes-xform.js +0 -107
  411. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-notes-xform.js.map +0 -1
  412. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-shape-xform.js +0 -92
  413. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-shape-xform.js.map +0 -1
  414. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-textbox-xform.js +0 -61
  415. package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-textbox-xform.js.map +0 -1
  416. package/node_modules/exceljs/dist/es5/xlsx/xform/composite-xform.js +0 -51
  417. package/node_modules/exceljs/dist/es5/xlsx/xform/composite-xform.js.map +0 -1
  418. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js +0 -30
  419. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js.map +0 -1
  420. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js +0 -27
  421. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js.map +0 -1
  422. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-xform.js +0 -93
  423. package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-xform.js.map +0 -1
  424. package/node_modules/exceljs/dist/es5/xlsx/xform/core/content-types-xform.js +0 -112
  425. package/node_modules/exceljs/dist/es5/xlsx/xform/core/content-types-xform.js.map +0 -1
  426. package/node_modules/exceljs/dist/es5/xlsx/xform/core/core-xform.js +0 -158
  427. package/node_modules/exceljs/dist/es5/xlsx/xform/core/core-xform.js.map +0 -1
  428. package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationship-xform.js +0 -23
  429. package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationship-xform.js.map +0 -1
  430. package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationships-xform.js +0 -65
  431. package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationships-xform.js.map +0 -1
  432. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js +0 -47
  433. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js.map +0 -1
  434. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-fill-xform.js +0 -61
  435. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-fill-xform.js.map +0 -1
  436. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-xform.js +0 -40
  437. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-xform.js.map +0 -1
  438. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js +0 -35
  439. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js.map +0 -1
  440. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js +0 -62
  441. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js.map +0 -1
  442. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/cell-position-xform.js +0 -82
  443. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/cell-position-xform.js.map +0 -1
  444. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/drawing-xform.js +0 -98
  445. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/drawing-xform.js.map +0 -1
  446. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-lst-xform.js +0 -40
  447. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-lst-xform.js.map +0 -1
  448. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-xform.js +0 -38
  449. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-xform.js.map +0 -1
  450. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/hlink-click-xform.js +0 -38
  451. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/hlink-click-xform.js.map +0 -1
  452. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js +0 -59
  453. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js.map +0 -1
  454. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js +0 -63
  455. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js.map +0 -1
  456. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/pic-xform.js +0 -67
  457. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/pic-xform.js.map +0 -1
  458. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/sp-pr.js +0 -30
  459. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/sp-pr.js.map +0 -1
  460. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js +0 -62
  461. package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js.map +0 -1
  462. package/node_modules/exceljs/dist/es5/xlsx/xform/list-xform.js +0 -91
  463. package/node_modules/exceljs/dist/es5/xlsx/xform/list-xform.js.map +0 -1
  464. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/auto-filter-xform.js +0 -40
  465. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/auto-filter-xform.js.map +0 -1
  466. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cell-xform.js +0 -451
  467. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cell-xform.js.map +0 -1
  468. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js +0 -275
  469. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js.map +0 -1
  470. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js +0 -25
  471. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js.map +0 -1
  472. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js +0 -38
  473. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js.map +0 -1
  474. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js +0 -45
  475. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js.map +0 -1
  476. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js +0 -77
  477. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js.map +0 -1
  478. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/databar-xform.js +0 -42
  479. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/databar-xform.js.map +0 -1
  480. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +0 -71
  481. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js.map +0 -1
  482. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/formula-xform.js +0 -22
  483. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/formula-xform.js.map +0 -1
  484. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js +0 -43
  485. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js.map +0 -1
  486. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +0 -28
  487. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js.map +0 -1
  488. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +0 -88
  489. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js.map +0 -1
  490. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +0 -38
  491. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js.map +0 -1
  492. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +0 -52
  493. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js.map +0 -1
  494. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +0 -43
  495. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js.map +0 -1
  496. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +0 -75
  497. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js.map +0 -1
  498. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js +0 -22
  499. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js.map +0 -1
  500. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +0 -66
  501. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js.map +0 -1
  502. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +0 -22
  503. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js.map +0 -1
  504. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/col-xform.js +0 -78
  505. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/col-xform.js.map +0 -1
  506. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/data-validations-xform.js +0 -247
  507. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/data-validations-xform.js.map +0 -1
  508. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/dimension-xform.js +0 -28
  509. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/dimension-xform.js.map +0 -1
  510. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/drawing-xform.js +0 -32
  511. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/drawing-xform.js.map +0 -1
  512. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/ext-lst-xform.js +0 -69
  513. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/ext-lst-xform.js.map +0 -1
  514. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/header-footer-xform.js +0 -126
  515. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/header-footer-xform.js.map +0 -1
  516. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/hyperlink-xform.js +0 -50
  517. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/hyperlink-xform.js.map +0 -1
  518. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merge-cell-xform.js +0 -26
  519. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merge-cell-xform.js.map +0 -1
  520. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merges.js +0 -52
  521. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merges.js.map +0 -1
  522. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/outline-properties-xform.js +0 -35
  523. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/outline-properties-xform.js.map +0 -1
  524. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-breaks-xform.js +0 -24
  525. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-breaks-xform.js.map +0 -1
  526. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-margins-xform.js +0 -46
  527. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-margins-xform.js.map +0 -1
  528. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js +0 -32
  529. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js.map +0 -1
  530. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-xform.js +0 -99
  531. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-xform.js.map +0 -1
  532. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/picture-xform.js +0 -32
  533. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/picture-xform.js.map +0 -1
  534. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/print-options-xform.js +0 -45
  535. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/print-options-xform.js.map +0 -1
  536. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-breaks-xform.js +0 -37
  537. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-breaks-xform.js.map +0 -1
  538. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-xform.js +0 -128
  539. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-xform.js.map +0 -1
  540. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js +0 -51
  541. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js.map +0 -1
  542. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js +0 -83
  543. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js.map +0 -1
  544. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js +0 -84
  545. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js.map +0 -1
  546. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-view-xform.js +0 -190
  547. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-view-xform.js.map +0 -1
  548. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/table-part-xform.js +0 -32
  549. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/table-part-xform.js.map +0 -1
  550. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/worksheet-xform.js +0 -513
  551. package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/worksheet-xform.js.map +0 -1
  552. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/boolean-xform.js +0 -27
  553. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/boolean-xform.js.map +0 -1
  554. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/date-xform.js +0 -58
  555. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/date-xform.js.map +0 -1
  556. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/float-xform.js +0 -47
  557. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/float-xform.js.map +0 -1
  558. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/integer-xform.js +0 -53
  559. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/integer-xform.js.map +0 -1
  560. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/string-xform.js +0 -47
  561. package/node_modules/exceljs/dist/es5/xlsx/xform/simple/string-xform.js.map +0 -1
  562. package/node_modules/exceljs/dist/es5/xlsx/xform/static-xform.js +0 -61
  563. package/node_modules/exceljs/dist/es5/xlsx/xform/static-xform.js.map +0 -1
  564. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/phonetic-text-xform.js +0 -98
  565. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/phonetic-text-xform.js.map +0 -1
  566. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/rich-text-xform.js +0 -92
  567. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/rich-text-xform.js.map +0 -1
  568. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-string-xform.js +0 -99
  569. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-string-xform.js.map +0 -1
  570. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-strings-xform.js +0 -114
  571. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-strings-xform.js.map +0 -1
  572. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/text-xform.js +0 -39
  573. package/node_modules/exceljs/dist/es5/xlsx/xform/strings/text-xform.js.map +0 -1
  574. package/node_modules/exceljs/dist/es5/xlsx/xform/style/alignment-xform.js +0 -139
  575. package/node_modules/exceljs/dist/es5/xlsx/xform/style/alignment-xform.js.map +0 -1
  576. package/node_modules/exceljs/dist/es5/xlsx/xform/style/border-xform.js +0 -185
  577. package/node_modules/exceljs/dist/es5/xlsx/xform/style/border-xform.js.map +0 -1
  578. package/node_modules/exceljs/dist/es5/xlsx/xform/style/color-xform.js +0 -66
  579. package/node_modules/exceljs/dist/es5/xlsx/xform/style/color-xform.js.map +0 -1
  580. package/node_modules/exceljs/dist/es5/xlsx/xform/style/dxf-xform.js +0 -106
  581. package/node_modules/exceljs/dist/es5/xlsx/xform/style/dxf-xform.js.map +0 -1
  582. package/node_modules/exceljs/dist/es5/xlsx/xform/style/fill-xform.js +0 -308
  583. package/node_modules/exceljs/dist/es5/xlsx/xform/style/fill-xform.js.map +0 -1
  584. package/node_modules/exceljs/dist/es5/xlsx/xform/style/font-xform.js +0 -175
  585. package/node_modules/exceljs/dist/es5/xlsx/xform/style/font-xform.js.map +0 -1
  586. package/node_modules/exceljs/dist/es5/xlsx/xform/style/numfmt-xform.js +0 -59
  587. package/node_modules/exceljs/dist/es5/xlsx/xform/style/numfmt-xform.js.map +0 -1
  588. package/node_modules/exceljs/dist/es5/xlsx/xform/style/protection-xform.js +0 -53
  589. package/node_modules/exceljs/dist/es5/xlsx/xform/style/protection-xform.js.map +0 -1
  590. package/node_modules/exceljs/dist/es5/xlsx/xform/style/style-xform.js +0 -118
  591. package/node_modules/exceljs/dist/es5/xlsx/xform/style/style-xform.js.map +0 -1
  592. package/node_modules/exceljs/dist/es5/xlsx/xform/style/styles-xform.js +0 -612
  593. package/node_modules/exceljs/dist/es5/xlsx/xform/style/styles-xform.js.map +0 -1
  594. package/node_modules/exceljs/dist/es5/xlsx/xform/style/underline-xform.js +0 -46
  595. package/node_modules/exceljs/dist/es5/xlsx/xform/style/underline-xform.js.map +0 -1
  596. package/node_modules/exceljs/dist/es5/xlsx/xform/table/auto-filter-xform.js +0 -75
  597. package/node_modules/exceljs/dist/es5/xlsx/xform/table/auto-filter-xform.js.map +0 -1
  598. package/node_modules/exceljs/dist/es5/xlsx/xform/table/custom-filter-xform.js +0 -30
  599. package/node_modules/exceljs/dist/es5/xlsx/xform/table/custom-filter-xform.js.map +0 -1
  600. package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-column-xform.js +0 -89
  601. package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-column-xform.js.map +0 -1
  602. package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-xform.js +0 -28
  603. package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-xform.js.map +0 -1
  604. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-column-xform.js +0 -42
  605. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-column-xform.js.map +0 -1
  606. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-style-info-xform.js +0 -40
  607. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-style-info-xform.js.map +0 -1
  608. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-xform.js +0 -123
  609. package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-xform.js.map +0 -1
  610. package/node_modules/exceljs/dist/es5/xlsx/xlsx.js +0 -697
  611. package/node_modules/exceljs/dist/es5/xlsx/xlsx.js.map +0 -1
  612. package/node_modules/exceljs/dist/es5/xlsx/xml/theme1.js +0 -5
  613. package/node_modules/exceljs/dist/es5/xlsx/xml/theme1.js.map +0 -1
  614. package/node_modules/exceljs/dist/exceljs.bare.js +0 -55253
  615. package/node_modules/exceljs/dist/exceljs.bare.js.map +0 -761
  616. package/node_modules/exceljs/dist/exceljs.bare.min.js +0 -45
  617. package/node_modules/exceljs/dist/exceljs.bare.min.js.map +0 -1
  618. package/node_modules/exceljs/dist/exceljs.js +0 -59900
  619. package/node_modules/exceljs/dist/exceljs.js.map +0 -1083
  620. package/node_modules/exceljs/dist/exceljs.min.js +0 -45
  621. package/node_modules/exceljs/dist/exceljs.min.js.map +0 -1
  622. package/scripts/deploy-test.sh +0 -309
@@ -194,7 +194,7 @@ const SCRIPT = `
194
194
  return false;
195
195
  };
196
196
  const txt = () => document.body.innerText;
197
- // tracker issue 1809 — A MISS THROWS, NAMING WHAT IT MISSED. This returned undefined, and the thirteen sites below
197
+ // A MISS THROWS, NAMING WHAT IT MISSED. This returned undefined, and the thirteen sites below
198
198
  // that dereference it immediately turned a missing button into "Cannot read properties of undefined
199
199
  // (reading 'click')" — a message naming no selector, no screen and no step. It was intermittent, so it
200
200
  // read as a flaky suite rather than as a driver that could not say what it had not found.
@@ -303,7 +303,7 @@ const SCRIPT = `
303
303
 
304
304
  // ...and the segmented toggle switches back, persistently.
305
305
  findByText('button', /Set it up myself/).click();
306
- // tracker issue 1809 — THIS WAIT WAS DEAD. It watched for the text "Start point", which the composer stopped
306
+ // THIS WAIT WAS DEAD. It watched for the text "Start point", which the composer stopped
307
307
  // rendering; the only "Start point" left in the tree is a COMMENT in NewClearance.tsx. Because settle
308
308
  // returned false silently, it degraded into a flat 6-second sleep and the check still reported
309
309
  // "render check passed" — making the wait loud is what surfaced it. Waits on the picker the manual
@@ -388,7 +388,7 @@ const SCRIPT = `
388
388
  out.knockoutTier = /Knockout search/.test(tierText() || '');
389
389
  out.knockoutSweep = /1 broad sweep per name/.test(txt());
390
390
  out.nativeHiddenOnKnockout = !maybeByText('button', /Native-language investigation/);
391
- // tracker issue 706 — the copy changed and the assertion follows it. The OLD string ("not searched; filing counts
391
+ // the copy changed and the assertion follows it. The OLD string ("not searched; filing counts
392
392
  // only") led with the absence and then contradicted it in the same clause; what a Knockout buys at the
393
393
  // register is three counts per name in the classes named, and what it does not buy is a reading of the
394
394
  // filings behind them. This measures the same thing the ok() below claims: that the card states the
@@ -527,7 +527,7 @@ const SCRIPT = `
527
527
  // The blocker text only proves the label. What matters is that NOTHING is posted: a screen that shows
528
528
  // a blocker and posts anyway is a screen whose refusal is decoration.
529
529
  //
530
- // tracker issue 2119 — WAIT FOR THE BUTTON, NOT FOR ITS NEIGHBOUR. The settle above waits for the
530
+ // WAIT FOR THE BUTTON, NOT FOR ITS NEIGHBOUR. The settle above waits for the
531
531
  // failure notice to CLEAR, and the notice can clear before the dialog re-renders its controls. This
532
532
  // click then landed on a screen that had not finished and threw "no button matching /Back to edit/ is
533
533
  // on screen" — which reads as a missing control and was a missing wait. Measured on CI run
@@ -653,7 +653,7 @@ const SCRIPT = `
653
653
  // full product names the table ran ~2x its wrapper and barely two of the columns were visible — a
654
654
  // boolean could not tell that from the 40px the 760px min-width has always cost.
655
655
  out.matrixOverflowPx = wrap && table ? table.scrollWidth - wrap.clientWidth : null;
656
- // ── Refs tracker issue 2144 — THE ESCAPE MUST BE A CHILD OF THE THING THAT CAPS IT ─────────────
656
+ // ── THE ESCAPE MUST BE A CHILD OF THE THING THAT CAPS IT ─────────────
657
657
  // The cap is a direct-child selector. The opt-out spent two rounds of fixing applied to a
658
658
  // GRANDCHILD, where lifting the max-width asks a box to be wider than the box it lives in — which
659
659
  // is why the table stayed at 718px while reading, in the source, as though it had opted out. No
@@ -732,7 +732,7 @@ const SCRIPT = `
732
732
  // assertion to touch a missing key blew up with a TypeError instead. out.steps says how far it got.
733
733
  out.fatal = String(e && e.message ? e.message : e);
734
734
  out.raw = 'driver threw after: ' + out.steps.join(' -> ');
735
- // tracker issue 1809 — the named throw says WHAT was missing; this says what was on screen instead. Without it a
735
+ // the named throw says WHAT was missing; this says what was on screen instead. Without it a
736
736
  // diagnostic fix still loses the diagnosis, which is the whole complaint this change answers.
737
737
  out.body = txt().slice(0, 900);
738
738
  return out;
@@ -7,7 +7,7 @@
7
7
  // that touches disk, and it exists so the planted-divergence test can hand the checker an invented
8
8
  // file instead of writing one into the tree.
9
9
  //
10
- // THE CORPUS IS DISCOVERED, NEVER ENUMERATED, and that is 's hardest requirement rather than a
10
+ // THE CORPUS IS DISCOVERED, NEVER ENUMERATED, and that is the hardest requirement rather than a
11
11
  // preference: "plant a divergence in a NEW authoring layer — the check must find it structurally, not
12
12
  // because the layer was enumerated." So the corpus is every tracked `.mjs` and `.md` under `driver/`,
13
13
  // full stop. A new dispatch module, a new skill file, a seventh authoring surface nobody has thought
@@ -15,7 +15,7 @@
15
15
  //
16
16
  // `git ls-files`, via shared/tracked-files.mjs, because a directory walk lists a different set (build
17
17
  // output, an editor backup, a contributor's scratch file) and because a guard that cannot see its
18
- // corpus must SAY SO rather than report a clean zero. 's lesson, and CLAUDE.md's hard rule: an
18
+ // corpus must SAY SO rather than report a clean zero. That lesson, and CLAUDE.md's hard rule: an
19
19
  // absence is a finding.
20
20
  //
21
21
  // node scripts/contract-dictation-scan.mjs report; exit 1 on any divergence
@@ -45,7 +45,7 @@ export const GUARD = "dead-names (#853)";
45
45
  // `clawdi-lisa` and `clawdi-lidia` are 's, not 's, and they are here rather than in a second
46
46
  // scanner because the mechanism is identical: a name that must never reappear. They were per-person
47
47
  // agent identities for individuals at this firm, shipped in an operator script's default roster, in a
48
- // systemd unit watching their queues, and in two test fixtures. 's out-of-scope note ruled `alex`
48
+ // systemd unit watching their queues, and in two test fixtures. That out-of-scope note ruled `alex`
49
49
  // and `sam` INVENTED, which is why those stay; these two were never covered by that ruling.
50
50
  export const DEAD_NAME_RE = /lorestar|lore_(pool|url|flags)|prelim_lore|lorectl|loreurl|lorecontrols|trademark-lore|\blore\b|\baughra|clawdi-(lisa|lidia)/i;
51
51
 
@@ -5,7 +5,7 @@
5
5
  //
6
6
  // The question came from the codex round (18 Aug): an engine override is carried by the DRIVER
7
7
  // ACTIVATION's environment, and an activation that never happens carries no environment. On the box this
8
- // was first asked about, no runner process was running for any user and no prelim unit existed at system
8
+ // was first asked about, no runner process was running for any user and no clearotron unit existed at system
9
9
  // level — so every job enqueued would have sat there, and the round would have been fiction.
10
10
  //
11
11
  // Nothing here builds a drainer. ONE ALREADY SHIPS: `driver/systemd/prelim-driver.path` (inotify),
@@ -29,7 +29,7 @@
29
29
 
30
30
  import { spawnSync } from "node:child_process";
31
31
  import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
32
- import { fileURLToPath } from "node:url";
32
+ import { fileURLToPath, pathToFileURL } from "node:url";
33
33
  import { join, dirname } from "node:path";
34
34
  import { homedir, userInfo } from "node:os";
35
35
  import { isEntrypoint } from "../shared/is-entrypoint.mjs"; // — one entry-point test, all spellings
@@ -132,7 +132,7 @@ export function watchedQueueDirs(unitText, home) {
132
132
  //
133
133
  // Reading the list without the reset is wrong in BOTH directions — it keeps globs the deployment
134
134
  // has disowned, and (because the caller then compares against a superset) it can report a directory
135
- // as watched that nothing watches. The second is 's original harm, produced by the guard built
135
+ // as watched that nothing watches. The second is the original harm, produced by the guard built
136
136
  // to prevent it.
137
137
  if (!m[1].trim()) { out.length = 0; continue; }
138
138
  // EXTENSION-AGNOSTIC. The queue watcher globs `*.json` and the outbox watcher globs `*.pending`;
@@ -223,7 +223,7 @@ export function runnerRunning() {
223
223
  return { known: true, procs };
224
224
  }
225
225
 
226
- // ── THE OUTBOX IS THE SAME HAZARD, ONE LANE OVER ('s tail) ───────────────────────────────────────
226
+ // ── THE OUTBOX IS THE SAME HAZARD, ONE LANE OVER (the tail) ───────────────────────────────────────
227
227
  //
228
228
  // `prelim-outbox.path` carries the identical literal glob and says so in its own header: "this literal
229
229
  // and the driver's `config.outboxDir` are two spellings of one fact with nothing checking them against
@@ -244,7 +244,7 @@ export async function preflight({ home = homedir(), root = ROOT } = {}) {
244
244
  const unitPath = join(root, "driver", "systemd", "prelim-driver.path");
245
245
  const unitText = existsSync(unitPath) ? readFileSync(unitPath, "utf8") : null;
246
246
 
247
- const { config } = await import(join(root, "driver", "driver.config.mjs"));
247
+ const { config } = await import(pathToFileURL(join(root, "driver", "driver.config.mjs")).href);
248
248
  const queueDirs = config.queueDirs ?? [];
249
249
  const watched = unitText == null ? null : watchedQueueDirs(unitText, home);
250
250
 
@@ -39,7 +39,7 @@ import { readFileSync, readdirSync, statSync } from "node:fs";
39
39
  import { join } from "node:path";
40
40
  import { driverDir } from "../shared/driver-dir.mjs"; //
41
41
  // The seat-record reader, imported rather than re-derived: "does this run have work in it" must be the
42
- // SAME question the retry instrument asks, or two tools disagree about one fact (,).
42
+ // SAME question the retry instrument asks, or two tools disagree about one fact ().
43
43
  import { dispatchRows } from "../driver/seat-attempts.mjs";
44
44
  import { isEntrypoint } from "../shared/is-entrypoint.mjs"; // — realpath both sides, or a symlinked invocation exits 0 silently
45
45
 
package/scripts/e2e.mjs CHANGED
@@ -44,7 +44,7 @@ import { mcpToolCall } from "../driver/portal-mcp-client.mjs";
44
44
  // resolve the depth the same way every other door does — never from a word the scenario file typed.
45
45
  import { reportIdentityFor, ORDERABLE_PRODUCTS, RETIRED_PRODUCTS } from "../driver/search-policy.mjs";
46
46
  // The queue's filename vocabulary, from the module that owns it. created that module because the
47
- // vocabulary "has now been written down three times and the copies disagreed"; 's first draft wrote it
47
+ // vocabulary "has now been written down three times and the copies disagreed"; the first draft wrote it
48
48
  // down twice more here, from memory, and false-alarmed on every prose sidecar of every live job. Sourced,
49
49
  // so the next suffix the engine adds reaches this harness the day it lands. queue-markers.mjs is PURE —
50
50
  // importing it pulls in nothing, which is why this file can have it and cannot have runner.mjs (that chain
@@ -57,10 +57,10 @@ import { isLiveQueueMarker, isQueueSidecar, liveQueueState, LIVE_QUEUE_STATES, T
57
57
  // leave the real one to park tomorrow's re-run as a duplicate. usage-ledger.mjs is a pure leaf too
58
58
  // (node:fs + node:path + queue-markers.mjs), so it drags no driver machinery in either.
59
59
  import { matterLedgerPath } from "../driver/usage-ledger.mjs";
60
- import { probeWorker } from "../driver/queue-watch-probe.mjs"; // tracker issue 181 — the drain this deployment actually has
60
+ import { probeWorker } from "../driver/queue-watch-probe.mjs"; // the drain this deployment actually has
61
61
  // Teardown asks whether a process is actually producing a run before it rewrites the record that says so.
62
62
  import { claimLivenessForCodename, claimForbidsDestruction } from "../driver/claim-liveness.mjs";
63
- // The store admission sweep (, moved here from a bundled-store CI test when the bundled scenarios
63
+ // The store admission sweep (moved here from a bundled-store CI test when the bundled scenarios
64
64
  // were deleted): every job block in the configured store must be treated by the doors exactly the way
65
65
  // its scenario declares, and the check has to run where the store exists — CI cannot read it.
66
66
  import { validateJob } from "../driver/enqueue-schema.mjs";
@@ -82,7 +82,7 @@ import { readReceipt, appendRound, stampRound, tokenFromRef, roundsFromRuns, mer
82
82
  roundLetters, receiptPath, scenarioRefs as scenarioRefsOf, findRunsByRef as findRunsIn,
83
83
  SCENARIO_FILE, byScenarioNumber, tierOf, SCENARIO_TIERS, DEFAULT_TIER }
84
84
  from "../driver/e2e-rounds.mjs";
85
- // 's refusal — "is this data plane production" — sourced, because this file used to restate it and
85
+ // That refusal — "is this data plane production" — sourced, because this file used to restate it and
86
86
  // the two copies had ALREADY drifted, in both directions:
87
87
  // CLEAROTRON_REPORTS_DIR=/srv/trademark-archive-dev the guard passes (it matches the archive as a path
88
88
  // PREFIX, and its own test requires that a name merely resembling production's passes). The copy
@@ -403,7 +403,7 @@ export function lintScenarios(scenarios) {
403
403
  //
404
404
  // Deliberately here rather than at a selection site, because that is what gets the SCOPE right for
405
405
  // nothing: `sweepStoreOrDie()` bare (cmdList) refuses on any scenario's finding, and
406
- // `sweepStoreOrDie(id)` (cmdRun) refuses only on the named scenario's — 's split, already
406
+ // `sweepStoreOrDie(id)` (cmdRun) refuses only on the named scenario's — the split, already
407
407
  // implemented at the two call sites. A round that selects BY tier has to read every tier to choose,
408
408
  // so a typo anywhere corrupts the selection rather than one entry; a run that named its scenario is
409
409
  // answerable only for that one. Both fall out of where this line sits.
@@ -886,7 +886,7 @@ function enqueueViaCli(job) {
886
886
  } finally { rmSync(dir, { recursive: true, force: true }); }
887
887
  }
888
888
 
889
- // EXPORTED for 's arm: the not-configured branch is the whole subject, and the only honest way to
889
+ // EXPORTED for the arm: the not-configured branch is the whole subject, and the only honest way to
890
890
  // drive it is to call this function in a process with no MCP port in scope — the state a rebuilt box
891
891
  // is actually in. Asserting on the source text instead would pass on a file that no longer runs it.
892
892
  export async function enqueueViaMcp(job, { clientPrincipal = false, forwarder = null } = {}) {
@@ -894,7 +894,7 @@ export async function enqueueViaMcp(job, { clientPrincipal = false, forwarder =
894
894
  // refusing one. A door that is not configured on this deployment never saw the job, so it holds no
895
895
  // opinion about it: recording it as a refusal manufactures agreement on the refusal cases (a
896
896
  // correctly-refusing door and an absent one produce the same line) and, on the admit cases, fires
897
- // #98's "the one that ACCEPTED is the defect" at the door that behaved. This is 's rule reaching
897
+ // the "the one that ACCEPTED is the defect" rule at the door that behaved. This is that rule reaching
898
898
  // the one transport failure that happens BEFORE any request: not-configured is could-not-ask.
899
899
  if (!MCP_URL) return { ok: false, transport: true, status: null,
900
900
  out: "no TRADEMARK_MCP_HTTP_PORT in scope — this door is not configured on this deployment, so it was never asked" };
@@ -1601,7 +1601,7 @@ function queueDrainState({
1601
1601
  // THREE STATES, NOT TWO, and the third is the reason this is a function rather than a field read.
1602
1602
  // A scenario that states nothing must read as CANNOT TELL — never as synthetic, and never as silence.
1603
1603
  // Defaulting an absent label to "synthetic" would be a guess presented as a fact, and letting it print
1604
- // nothing is 's defect exactly: a benchmark that printed only when the key was present rendered as
1604
+ // nothing is the defect exactly: a benchmark that printed only when the key was present rendered as
1605
1605
  // silence, which reads exactly like a benchmark that was met. An unstated label is reported, every time.
1606
1606
  export const MARK_PROVENANCE = { LIVE: "live", SYNTHETIC: "synthetic", UNSTATED: "unstated" };
1607
1607
 
@@ -10,7 +10,7 @@
10
10
  // ── why this exists ──────────────────────────────────────────────────────────────────────────────
11
11
  //
12
12
  // `docs/architecture/05-config-governance.md` states its own maintenance rule: "adding a var anywhere
13
- // in the repo means adding its row here". 's review found that rule has NO enforcement — the
13
+ // in the repo means adding its row here". That review found that rule has NO enforcement — the
14
14
  // placeholder-default guard checks fallbacks, not existence — so it has been prose since it was
15
15
  // written, and the surface has grown the whole time.
16
16
  //
@@ -36,7 +36,7 @@
36
36
  //
37
37
  // ── what it deliberately does not do ─────────────────────────────────────────────────────────────
38
38
  //
39
- // It deletes nothing. 's tier 2 (delete the dead) is explicitly not this, and the issue's own
39
+ // It deletes nothing. That tier 2 (delete the dead) is explicitly not this, and the issue's own
40
40
  // queue note says deleting toggles mid-verification moves the range again. This reports; a person
41
41
  // decides.
42
42
 
@@ -108,7 +108,7 @@ const CODE_RE = /\.(mjs|js|cjs|ts)$/;
108
108
  // above describes happening again. Converting the eight numeric getters from
109
109
  // `Number(this.envValue("NAME") || d)` to `numericSetting("NAME")` moved the name out of a shape this
110
110
  // scanner knew and into one it did not: the audit stopped seeing CLEAROTRON_MAX_CLAIM_AGE_MS and
111
- // CLEAROTRON_CARD_CONCURRENCY, whose ONLY reads are accessor reads, and 's product-read arm went red.
111
+ // CLEAROTRON_CARD_CONCURRENCY, whose ONLY reads are accessor reads, and the product-read arm went red.
112
112
  // It went red because that arm names those two variables — which is the whole reason it names them. A
113
113
  // conversion narrows this guard silently, so both spellings land in the same commit as the conversion.
114
114
  const ACCESSOR_RE = /\b(?:envValue|envOn|envGateOn|numericSetting|resolveNumericSetting)\s*\(\s*["']([A-Z][A-Z0-9_]*)["']|\benvFrom\s*\(\s*[^,()]+,\s*["']([A-Z][A-Z0-9_]*)["']/g;
@@ -154,7 +154,7 @@ const stripCommentLines = (text) => text.split("\n").filter((l) => !COMMENT_LINE
154
154
  // — no `env`-prefixed regex can match a read where the name never appears beside an `env` token.
155
155
  //
156
156
  // THE BINDING IS SCREAMING_CASE AND THE LITERAL IS ENV-SHAPED, both required. `const label = "x"` is
157
- // not an env binding, and neither is `const PREFIX = "prelim-"`. The pair is what makes this a
157
+ // not an env binding, and neither is `const PREFIX = "clearotron-"`. The pair is what makes this a
158
158
  // declaration of an environment name rather than a string that happens to be uppercase.
159
159
  const BINDING_RE = /(?<![.\w$])const\s+([A-Z][A-Z0-9_]*)\s*=\s*["']([A-Z][A-Z0-9_]{2,})["']/g;
160
160
 
@@ -230,7 +230,7 @@ export const SYSTEM_OWNED = new Set([
230
230
  // — both arrived with the injected-`env` widening above, and both are set by the service
231
231
  // manager rather than by any deployment of this product: systemd sets INVOCATION_ID (which is
232
232
  // exactly what shared/env-local.mjs reads it to detect), and the session bus sets
233
- // DBUS_SESSION_BUS_ADDRESS. 's body asserts the audit already excluded these two. It did not —
233
+ // DBUS_SESSION_BUS_ADDRESS. That body asserts the audit already excluded these two. It did not —
234
234
  // they were absent from this list, and they only stayed out of the register because the scanner
235
235
  // could not see the reads at all.
236
236
  "INVOCATION_ID", "DBUS_SESSION_BUS_ADDRESS",
@@ -520,7 +520,7 @@ export function auditEnv(root = ROOT) {
520
520
  // 1 CLEAROTRON_SEND_TOOL_PREFIX — genuinely dead, and this direction does not
521
521
  // catch it either: its one surviving mention is a governance-doc line, and
522
522
  // a mention is enough to spare a row. Under-firing is the cost of the
523
- // trade, taken deliberately. It is 's prose-sweep class.
523
+ // trade, taken deliberately. It is the prose-sweep class.
524
524
  //
525
525
  // So SIX of ten deletions would have been wrong, two of them credential rows.
526
526
  // Evidence used instead: the bare NAME, on a name boundary, anywhere in the
@@ -639,7 +639,7 @@ export function orphanRows(rows, mentioned) {
639
639
  }
640
640
 
641
641
  // The catalogues describe the contract; they are not readers of it. Include them and every row is its
642
- // own evidence, which is the circularity 's "a check cannot use its own source as evidence" names.
642
+ // own evidence, which is the circularity the "a check cannot use its own source as evidence" names.
643
643
  // — `docs/architecture/env-set-in-production.txt` joins them, and the reason is the rule this set
644
644
  // exists for. It is a LIST OF NAMES, committed as step 1's production evidence because a reviewer cannot
645
645
  // make that read. Left in the corpus it becomes an alibi for every catalogue row at once: each row
@@ -38,7 +38,7 @@ import "../shared/env-local.mjs"; // — FIRST, and it became REQUIRED here:
38
38
  // the capture evaluates before the CLEAROTRON_* translation lands. A
39
39
  // call in this file's BODY would run too late. The guard named the
40
40
  // file, the module it reaches, and the fix.
41
- import { readFileSync, writeFileSync, existsSync } from "node:fs";
41
+ import { readFileSync, readdirSync, writeFileSync, existsSync } from "node:fs";
42
42
  // — the product-owned-names rule, shared rather than a regex in this file.
43
43
  import { makeIsProductOwned, partitionByOwnership, droppedShape, FILTER_DECLARATION }
44
44
  from "../shared/product-owned-names.mjs";
@@ -60,7 +60,7 @@ export function namesInEnvFile(text) {
60
60
  }
61
61
  /** Every house or vendor variable MENTIONED in a script — the shape the config repo's bin/ writes. */
62
62
  export function namesMentioned(text) {
63
- return [...text.matchAll(/\b(?:PRELIM|CLEAROTRON|PORTAL|TRADEMARK_MCP|CLIENT_MCP|CLIENT_ACCESS|PROFILE|RECIPE|MOCK)_[A-Z0-9_]+/g)].map((m) => m[0]);
63
+ return [...text.matchAll(/\b(?:CLEAROTRON|CLEAROTRON|PORTAL|TRADEMARK_MCP|CLIENT_MCP|CLIENT_ACCESS|PROFILE|RECIPE|MOCK)_[A-Z0-9_]+/g)].map((m) => m[0]);
64
64
  }
65
65
 
66
66
  /**
@@ -73,7 +73,7 @@ export function namesMentioned(text) {
73
73
  // — NO EXECUTABLE LINE NAMES A SPECIFIC ACCOUNT'S HOME. These paths are per-box facts and this
74
74
  // script ships. They arrive as COMMAND-LINE FLAGS, not environment variables.
75
75
  //
76
- // The first fix used four new house-prefixed variables instead, and 's ratchet refused them —
76
+ // The first fix used four new house-prefixed variables instead, and the ratchet refused them —
77
77
  // correctly: adding four names to the configuration surface is precisely wrong in the tool built to
78
78
  // shrink it, and a maintainer's per-invocation path is an argument. The names are deliberately not
79
79
  // written out even here: `namesRead` scans comments too, and a variable that exists only in prose is
@@ -83,7 +83,74 @@ const flag = (name) => {
83
83
  return i > 0 && process.argv[i + 1] && !process.argv[i + 1].startsWith("--") ? process.argv[i + 1] : "";
84
84
  };
85
85
 
86
- export function gather({ root = ROOT, prodList = read(PROD) } = {}) {
86
+ /**
87
+ * A SHIPPED FILE THIS SCRIPT CANNOT WORK WITHOUT — read it, or say so and stop.
88
+ *
89
+ * `read()` answers "" on ENOENT, which is right where a file is legitimately absent and wrong where its
90
+ * absence means the tree is broken. Every caller here is the second kind: they are files the product
91
+ * always ships, and an empty read of one silently empties a source that feeds `everSet` — and a name
92
+ * nothing is recorded as setting is a name a configuration cleanup removes.
93
+ *
94
+ * One helper rather than a check at each site, so a source added later cannot get this wrong by being
95
+ * written the obvious way: reading through it is how you read.
96
+ */
97
+ function mustRead(root, rel, why) {
98
+ const p = join(root, rel);
99
+ // READ FIRST AND KEEP THE REASON. Going through `read()` and then asking `existsSync` would separate
100
+ // absent from present only by accident of which case that second call can see: `read()` swallows
101
+ // EVERY error, so a file that EXISTS and cannot be read — a permission, a directory standing where a
102
+ // file belongs, a truncated mount — comes back "" and passes straight through as though it held
103
+ // nothing. Same consequence as absence and the same silence, one test narrower.
104
+ try {
105
+ return readFileSync(p, "utf8");
106
+ } catch (e) {
107
+ const tail = `${why} Reading it as empty would put every name it holds on the deletion population.`;
108
+ if (e.code !== "ENOENT")
109
+ throw new Error(`env-classify: ${p} exists and could not be read (${e.code}). ${tail}`);
110
+ throw new Error(`env-classify: ${p} is absent. ${tail} Its absence is this script failing to look, `
111
+ + "not a finding about the tree.");
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Every variable name a WORKFLOW sets, across all of them.
117
+ *
118
+ * This source used to read `.github/workflows/ci.yml` and nothing else, which made the release workflow
119
+ * invisible to it. `CLEAROTRON_CUT_REF` and `CLEAROTRON_RELEASE_WAIT_MS` are set there and nowhere else,
120
+ * so both reported `everSet: []` and both landed on the deletion population — two names a reviewer would
121
+ * have been asked to remove because the one file that sets them was not being read. A name being set by
122
+ * the release surface rather than the test surface says nothing about whether it is a knob.
123
+ *
124
+ * AN ABSENT DIRECTORY THROWS instead of returning nothing. `read()` answers "" on ENOENT, so the old
125
+ * single-file read degraded silently: a renamed or moved ci.yml would have emptied this source, reported
126
+ * every workflow-set name as never set, and nothing in the output would have said the look had failed.
127
+ */
128
+ function workflowNames(root) {
129
+ const dir = join(root, ".github/workflows");
130
+ let files;
131
+ try {
132
+ files = readdirSync(dir).filter((f) => /\.ya?ml$/.test(f)).sort();
133
+ } catch (e) {
134
+ throw new Error(`env-classify: cannot read ${dir} (${e.code}). That is this script failing to look, `
135
+ + "not a tree with no workflows, and an empty CI source silently widens the deletion population.");
136
+ }
137
+ if (!files.length)
138
+ throw new Error(`env-classify: ${dir} holds no .yml files. Every workflow-set name would read as `
139
+ + "never set, which is the shape this source exists to prevent.");
140
+ return files.flatMap((f) => [...read(join(dir, f)).matchAll(/^\s*([A-Z][A-Z0-9_]*):/gm)].map((m) => m[1]));
141
+ }
142
+
143
+ export function gather({ root = ROOT, prodList = null } = {}) {
144
+ // THE PRODUCTION HALF CAN BE ABSENT, AND ABSENT MUST NOT READ AS "PRODUCTION SETS NOTHING". `read()`
145
+ // answers "" on ENOENT, so a missing list made all 72 production-set names report `everSet: []` — and
146
+ // `tuning` with an empty `everSet` IS the deletion population. That is the same failure the CI source
147
+ // carried, one source over: the file is withheld from the public tree, so on a public checkout this
148
+ // silently classified production's own configuration as unused. `prodRead` records whether the look
149
+ // happened, so a caller can tell a real answer from no answer. A list passed in is its caller's claim
150
+ // to make, and counts as read.
151
+ const prodGiven = prodList !== null;
152
+ const prodText = prodGiven ? prodList : read(PROD);
153
+ const prodRead = prodGiven || existsSync(PROD);
87
154
  const set = (xs) => new Set(xs.filter(Boolean));
88
155
  const tracked = (glob) => git("ls-files", "--", glob).split("\n").filter(Boolean);
89
156
  const sudoRead = (p) => { try { return execFileSync("sudo", ["-n", "cat", p], { encoding: "utf8" }); } catch { return ""; } };
@@ -91,14 +158,16 @@ export function gather({ root = ROOT, prodList = read(PROD) } = {}) {
91
158
  const config = flag("config-repo") ? [flag("config-repo")] : [];
92
159
  return {
93
160
  // COMMITTED, not gathered: the production read needs privilege a reviewer does not have.
94
- prod: set(prodList.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"))),
161
+ prod: set(prodText.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#"))),
162
+ prodRead,
95
163
  test: set(flag("test-env") ? namesInEnvFile(sudoRead(flag("test-env"))) : []),
96
164
  config: set(config.flatMap((r) => {
97
165
  let files = []; try { files = execFileSync("sudo", ["-n", "find", r, "-type", "f", "-not", "-path", "*/.git/*"], { encoding: "utf8" }).split("\n").filter(Boolean); } catch { return []; }
98
166
  return files.flatMap((f) => { const t = sudoRead(f); return [...namesInEnvFile(t), ...namesMentioned(t)]; });
99
167
  })),
100
- ci: set([...read(join(root, ".github/workflows/ci.yml")).matchAll(/^\s*([A-Z][A-Z0-9_]*):/gm)].map((m) => m[1])),
101
- e2e: set(["scripts/e2e.mjs", "scripts/test-run.mjs"].flatMap((f) => namesMentioned(read(join(root, f))))),
168
+ ci: set(workflowNames(root)),
169
+ e2e: set(["scripts/e2e.mjs", "scripts/test-run.mjs"]
170
+ .flatMap((f) => namesMentioned(mustRead(root, f, "It is the end-to-end surface, and the names it sets are set nowhere else.")))),
102
171
  // A DESCRIPTION, never a setting. Kept apart so `everSet` cannot be satisfied by documentation.
103
172
  docs: set([".env.example", ".env.dev.example", ".env.prod.example"]
104
173
  .flatMap((f) => [...read(join(root, f)).matchAll(/^#?\s*([A-Z][A-Z0-9_]*)=/gm)].map((m) => m[1]))),
@@ -108,8 +177,15 @@ export function gather({ root = ROOT, prodList = read(PROD) } = {}) {
108
177
 
109
178
  /** The setup population: what the wizard WRITES, expanded through the alias table. */
110
179
  export function setupNames(root = ROOT) {
111
- const onboard = read(join(root, "bin/onboard.mjs"));
112
- const cfg = read(join(root, "driver/driver.config.mjs"));
180
+ // THE WORST ONE TO LOSE, and the reason it is read through `mustRead`. This is the population that
181
+ // separates "the wizard writes this at install" from "nobody sets this anywhere". Empty, every setup
182
+ // name falls through the shape tests to `tuning` — the residual bucket — and `tuning` with no recorded
183
+ // set-site IS the deletion population. So a missing wizard would not merely lose a source; it would
184
+ // propose the whole install surface for removal, with nothing in the output saying the file was gone.
185
+ const onboard = mustRead(root, "bin/onboard.mjs",
186
+ "It is the install wizard, and what it writes is the whole setup population.");
187
+ const cfg = mustRead(root, "driver/driver.config.mjs",
188
+ "It carries the table whose credential fields name the rest of that population.");
113
189
  const seed = new Set();
114
190
  for (const m of onboard.matchAll(/candidate\.([A-Z][A-Z0-9_]*)\s*=/g)) seed.add(m[1]);
115
191
  for (const m of onboard.matchAll(/candidate\["([A-Z][A-Z0-9_]*)"\]\s*=/g)) seed.add(m[1]);
@@ -246,11 +322,44 @@ export function defaultAtReadSite(name, root = ROOT) {
246
322
  /** The whole classification, pure over its inputs so a test drives it without a box. */
247
323
  export function classify({ catalogue, sources, setup = setupNames(), readSites = defaultAtReadSite,
248
324
  deploymentNames = DEPLOYMENT_NAMES } = {}) {
249
- // ONE NAMED OVERRIDE, and it is listed rather than folded into a pattern so that it can be argued
250
- // with. `CLEAROTRON_AGENT_WHATSAPP` matches no deployment shape and is not a knob: production sets it to
251
- // a contact map, so it is a notification DESTINATION. Established from the SHAPE of the value, never
252
- // its content. A pattern wide enough to catch it would have swept in real knobs.
253
- const OVERRIDES = { CLEAROTRON_AGENT_WHATSAPP: "deployment" };
325
+ // NAMED OVERRIDES, listed rather than folded into a pattern so that each can be argued with.
326
+ //
327
+ // `CLEAROTRON_AGENT_WHATSAPP` matches no deployment shape and is not a knob: production sets it to a
328
+ // contact map, so it is a notification DESTINATION. Established from the SHAPE of the value, never its
329
+ // content. A pattern wide enough to catch it would have swept in real knobs.
330
+ //
331
+ // The other two are the same fact about the same thing, and they are here because the register already
332
+ // declares them `deployment` while this classifier — which keys on the NAME — filed them as `tuning`.
333
+ // That disagreement is not cosmetic: tuning names with no recorded set-site are the population this
334
+ // script walks for deletion candidates, and both are destinations a deployment may legitimately leave
335
+ // unset. A one-word mismatch would have put a notification address on a list of names to remove.
336
+ //
337
+ // · CLEAROTRON_REQUESTER_WHATSAPP — the map of requester → number. A destination, like the agent
338
+ // map above, and the reason that one is here applies verbatim.
339
+ // · CLEAROTRON_WHATSAPP_OPERATOR_COPY — whether the operator keeps a copy. It reads as a knob and is
340
+ // not one: it decides WHETHER a second destination is used, so
341
+ // changing it changes who is told, never what a run concludes.
342
+ //
343
+ // `CLEAROTRON_JX_SUBCLASS_DB` is the fourth, and it is the plainest reading of `deployment` on this
344
+ // list: the catalogue row says it names WHERE THE SUBCLASS TABLE LIVES, and that what the table says
345
+ // belongs to the build. Where input lives, with the conclusion a run reaches unchanged — the
346
+ // definition, almost word for word. The classifier filed it `tuning` because no shape in this file
347
+ // matches the spelling, and `tuning` is the residual bucket, so the row was not an opinion about the
348
+ // name so much as the absence of one.
349
+ //
350
+ // It is here rather than in a widened pattern because the name has no default and the lane REFUSES
351
+ // when it is unset. That makes it the worst possible member of a deletion population: removing it
352
+ // does not retire an unused knob, it takes out the only way the lane can be pointed at a table at all.
353
+ //
354
+ // The first three were found in review, not by the classifier, because nothing reconciled the
355
+ // catalogue's declared effect against this table and the two could disagree indefinitely. That
356
+ // comparison now runs as an arm, and this entry is the first thing it produced.
357
+ const OVERRIDES = {
358
+ CLEAROTRON_AGENT_WHATSAPP: "deployment",
359
+ CLEAROTRON_REQUESTER_WHATSAPP: "deployment",
360
+ CLEAROTRON_WHATSAPP_OPERATOR_COPY: "deployment",
361
+ CLEAROTRON_JX_SUBCLASS_DB: "deployment",
362
+ };
254
363
 
255
364
  const cls = (name) => OVERRIDES[name] ?? (setup.has(name) ? "setup"
256
365
  : VENDOR_RE.test(name) ? "vendor-credential"
@@ -306,6 +415,7 @@ function build() {
306
415
  const catalogue = audit.catalogue.rows.map((r) => r.name);
307
416
  const sources = gather();
308
417
  const { rows, buckets } = classify({ catalogue, sources });
418
+ const prodRead = sources.prodRead;
309
419
  const by = (k) => rows.filter((r) => r.class === k).length;
310
420
  return {
311
421
  _what: "#1838 step 1 — every catalogued variable classified, and for every TUNING name the environments that have ever set it.",
@@ -323,6 +433,7 @@ function build() {
323
433
  "non-numeric-default": buckets["non-numeric-default"], "no-default-found": buckets["no-default-found"],
324
434
  },
325
435
  rows,
436
+ _productionListRead: prodRead,
326
437
  };
327
438
  }
328
439
 
@@ -375,6 +486,18 @@ function main() {
375
486
  return;
376
487
  }
377
488
  const next = build();
489
+ // A COULD-NOT-LOOK IS NOT AN ANSWER, and this is the one place it would have become one. Without the
490
+ // production list every name production sets reports `everSet: []`, and `tuning` with an empty
491
+ // `everSet` is the deletion population — so stamping here would record production's own configuration
492
+ // as a list of names to remove, in the artifact a reviewer reads to authorise removing them. Exit 2,
493
+ // not 1: this is the look failing, not the tree being stale, and `--check` already has 1.
494
+ if (!next._productionListRead && (arg === "--apply" || arg === "--check")) {
495
+ console.error(`env-classify: ${PROD} is absent, so nothing is known about what production sets.\n`
496
+ + " Every production-set name would report `everSet: []` and land on the deletion population.\n"
497
+ + " That is this script failing to look, not a finding. Refresh it with `--gather-prod` on the\n"
498
+ + " production box, or run this where the list is present.");
499
+ process.exitCode = 2; return;
500
+ }
378
501
  if (arg === "--apply") { writeFileSync(ART, JSON.stringify(next, null, 2) + "\n"); console.log(`wrote ${ART}`); return; }
379
502
  if (arg === "--check") {
380
503
  const prev = existsSync(ART) ? readFileSync(ART, "utf8") : "";
@@ -384,7 +507,8 @@ function main() {
384
507
  return;
385
508
  }
386
509
  console.log(JSON.stringify(next._counts));
387
- console.log(`step-3 population: ${next._stepThreePopulation.count}`);
510
+ console.log(`step-3 population: ${next._stepThreePopulation.count}`
511
+ + (next._productionListRead ? "" : " — WITHOUT the production list, so every name production sets is counted as never set"));
388
512
  for (const [k, v] of Object.entries(next._excludedFromDeletion)) console.log(` excluded ${k.padEnd(24)} ${v.length}`);
389
513
  }
390
514
 
@@ -47,7 +47,7 @@ import { join, dirname, relative, basename } from "node:path";
47
47
  import { createHash } from "node:crypto";
48
48
  import { driverDir } from "../shared/driver-dir.mjs"; //
49
49
  import { tmpdir } from "node:os";
50
- import { fileURLToPath } from "node:url";
50
+ import { fileURLToPath, pathToFileURL } from "node:url";
51
51
 
52
52
  const REPO = join(dirname(fileURLToPath(import.meta.url)), "..");
53
53
 
@@ -123,7 +123,7 @@ const FROZEN_DIRS = [
123
123
  //
124
124
  // research/ IS REQUIRED AND THE PROOF IS WHAT FOUND IT. publish/knockout.mjs
125
125
  // traces every finding citation back to the run's own research payload — `research/<mark>.md`, read from
126
- // the workspace (knockout.mjs:317) — and REFUSES the publish when a citation cannot be traced. The first
126
+ // the workspace (publish/knockout.mjs:317) — and REFUSES the publish when a citation cannot be traced. The first
127
127
  // knockout freeze copied nine files, left research/ behind, and the republish proof threw:
128
128
  //
129
129
  // knockout publish REFUSED: 2 finding citation(s) could not be traced to this run's own research
@@ -506,7 +506,7 @@ const poolFull = join(scratch, "full");
506
506
  const poolFrozen = join(scratch, "frozen");
507
507
  const meta = { runId, codename, customerKey, template };
508
508
 
509
- const { republishRun } = await import(join(REPO, "driver", "publish", "report-registry.mjs"));
509
+ const { republishRun } = await import(pathToFileURL(join(REPO, "driver", "publish", "report-registry.mjs")).href);
510
510
  const publishInto = async (pool, dir) => {
511
511
  mkdirSync(pool, { recursive: true });
512
512
  return republishRun({ runId, meta, pool, poolUrl: "", runDir: dir, skipRegen: true });
@@ -113,7 +113,7 @@ export function fetchPulls(sha, repo, run = ghJson) {
113
113
  /**
114
114
  * `owner/repo` for the checkout this runs in, from its own origin remote.
115
115
  *
116
- * DERIVED, NOT CONFIGURED, and deliberately not an environment variable: 's ratchet is right that
116
+ * DERIVED, NOT CONFIGURED, and deliberately not an environment variable: the ratchet is right that
117
117
  * a new knob owes a documented row, and this one would document a fact the checkout already knows.
118
118
  * It also keeps the script honest in a fork — a published clone asks about ITS repository
119
119
  * rather than about ours.
@@ -36,6 +36,12 @@ import { execFileSync } from "node:child_process";
36
36
 
37
37
  /** Chrome's own error pages live under this scheme. Nothing a real document is served from does. */
38
38
  export const CHROME_ERROR_SCHEME = "chrome-error:";
39
+ /** What Chrome shows before it has navigated. Not a document, and not a wrong one. */
40
+ export const START_PAGE = "about:blank";
41
+ /** How long `assertPageLoaded` will wait for the browser to leave its start page. */
42
+ export const NAVIGATION_GRACE_MS = 5000;
43
+ /** How often it asks, inside that grace. */
44
+ export const NAVIGATION_POLL_MS = 100;
39
45
 
40
46
  /**
41
47
  * PURE. Given what the page says about itself, is it the document we asked for?
@@ -74,6 +80,25 @@ export function pageVerdict({ href = "", expected = "", marker = null, markerNam
74
80
  + "captured is Chrome's interstitial, not the artefact — and that page carries an `<h1>`, a "
75
81
  + "`<title>` and a body, so a content check alone reads it as a success." };
76
82
  }
83
+ // ── THE BROWSER'S START PAGE IS NOT A WRONG DOCUMENT (tracker issue 273) ────────────────────────
84
+ //
85
+ // `about:blank` is what Chrome shows before it has navigated anywhere. Reaching the check below, it
86
+ // compares unequal to the expected URL and was reported as `wrong-document` — "a redirect, a stale tab
87
+ // or a second page target" — which is a finding about a page. It is not one. Nothing was ever loaded,
88
+ // so nothing about the target document has been measured either way.
89
+ //
90
+ // This mattered because it is what a LOADED BOX produces: three of these scripts launch Chrome with the
91
+ // URL as a command-line argument and cannot wait for a navigation event, so under load the address is
92
+ // read before the browser has moved. A real defect and a slow browser then arrived as the same message,
93
+ // and the arms that exist to catch a wrong page were the ones that fired.
94
+ if (said === START_PAGE || said.startsWith(`${START_PAGE}?`) || said.startsWith(`${START_PAGE}#`)) {
95
+ return { ok: false, kind: "not-navigated",
96
+ why: `chrome is on its start page (${said}) and never reached ${expected}. Nothing about that `
97
+ + "document has been measured, so this is not a finding about the page. TWO THINGS LOOK LIKE "
98
+ + "THIS and the address cannot tell them apart: a navigation that failed without saying so, and "
99
+ + "one that had not happened yet. That is why the caller waits before asking — a verdict of this "
100
+ + "kind means it waited and the browser never left the start page." };
101
+ }
77
102
  // NORMALISED ON BOTH SIDES. Chrome resolves and percent-encodes a `file://` argument, so a raw string
78
103
  // comparison fails on a path with a space and reports "the wrong document" about the right one.
79
104
  const norm = (u) => { try { return new URL(u).href; } catch { return String(u); } };
@@ -103,8 +128,32 @@ export function pageVerdict({ href = "", expected = "", marker = null, markerNam
103
128
  * handshake before this file existed and rewriting seven of them to share one is a bigger change than the
104
129
  * defect warrants. What they must share is the QUESTION.
105
130
  */
106
- export async function assertPageLoaded(evaluate, { expected, marker = null, markerName = "the page's own content", what = "this page", errorText = null } = {}) {
107
- const href = await evaluate("location.href");
131
+ export async function assertPageLoaded(evaluate, { expected, marker = null, markerName = "the page's own content", what = "this page", errorText = null,
132
+ graceMs = NAVIGATION_GRACE_MS, pollMs = NAVIGATION_POLL_MS,
133
+ sleep = (ms) => new Promise((r) => setTimeout(r, ms)), now = () => Date.now() } = {}) {
134
+ // ── WAIT FOR THE BROWSER TO LEAVE ITS START PAGE, THEN JUDGE (tracker issue 273) ─────────────────
135
+ //
136
+ // Three of these scripts launch Chrome with the URL as an argument and get no response to wait on, so
137
+ // the first read of `location.href` can land before the browser has moved. On an idle box it never
138
+ // does; under a full parallel suite it did, repeatedly, and the arms reported the start page as a
139
+ // wrong document.
140
+ //
141
+ // BOUNDED, AND THE BOUND IS THE POINT. This waits for the browser to become ready — it does not wait
142
+ // for the page to become correct. If the address is anything other than the start page it is judged
143
+ // immediately, so a genuinely wrong document still fails on the first read and fails as fast as it did
144
+ // before. Only the "nothing has happened yet" case costs time, and only up to the grace.
145
+ //
146
+ // When the grace runs out the verdict is `not-navigated`, which is a could-not-look and says so.
147
+ // Deadline arithmetic is the caller's to drive: `sleep` and `now` are injected so the exhausted path
148
+ // can be exercised without a browser and without waiting.
149
+ let href = await evaluate("location.href");
150
+ if (String(href ?? "") === START_PAGE) {
151
+ const until = now() + graceMs;
152
+ while (String(href ?? "") === START_PAGE && now() < until) {
153
+ await sleep(pollMs);
154
+ href = await evaluate("location.href");
155
+ }
156
+ }
108
157
  const found = marker == null ? null : Boolean(await evaluate(`Boolean(${marker})`));
109
158
  const verdict = pageVerdict({ href, expected, marker: found, markerName, errorText });
110
159
  if (!verdict.ok) {