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
@@ -1,10 +1,10 @@
1
1
  // SPDX-License-Identifier: AGPL-3.0-only
2
2
  // Copyright 2026 Cordillera Sàrl. Additional terms under section 7 of the AGPL-3.0 apply — see ADDITIONAL-TERMS.md
3
- // placement-diff.mjs —: compare two runs' placement tiers, so 's repeat runs can be scored.
3
+ // placement-diff.mjs —: compare two runs' placement tiers, so the repeat runs can be scored.
4
4
  //
5
5
  // ── why this exists ──────────────────────────────────────────────────────────────────────────────────
6
6
  //
7
- // 's offline half is answered: the band-shape seam moves its input, so the branch is taken and the
7
+ // That offline half is answered: the band-shape seam moves its input, so the branch is taken and the
8
8
  // noise floor needs repeat PAID arms on one matter. Those runs are the E2E agent's. When they land there
9
9
  // is nothing to compare them with — `placement-carry.mjs` joins placements to the digest surfaces WITHIN
10
10
  // one run, and nothing in the tree diffs two `placements.json`.
@@ -13,12 +13,12 @@
13
13
  // fails `placementmodel_missing` while the structured sibling `placements.json` is absent — and the seat
14
14
  // wrote the prose first (on disk that run: md at 09:08:58, json at 09:15:50, by attempt 2). The kill
15
15
  // landed in the gap between the two files, so 31 minutes of finished work were discarded and re-derived
16
- // from scratch. Raising the wall (, `638f885`) made that less likely; it did not make finished work
16
+ // from scratch. Raising the wall (`638f885`) made that less likely; it did not make finished work
17
17
  // survivable, and this does.
18
18
  //
19
19
  // THE CURE IS AUTHORSHIP, NOT A GUARD. The seat stops writing `placements.json`. The driver renders it
20
20
  // from a FORM the seat fills, and an accumulator holds every answer across attempts, parks and process
21
- // restarts — exactly as 's disposition union and 's coverage union already do for their seats.
21
+ // restarts — exactly as the disposition union and the coverage union already do for their seats.
22
22
  // A killed attempt then keeps every tier it had already placed.
23
23
  //
24
24
  // THE ROW SOURCE IS SELECTION-BY-REFERENCE, and it was settled by measurement, not by design taste. The
@@ -127,7 +127,7 @@ export function formRowKey(row) {
127
127
  *
128
128
  * DRIVER FACTS COME FROM `canonical`, never from the submitted row. A seat that rewrote `records` or
129
129
  * `owner` on its copy cannot widen what binds; only its three judgment fields are read from `row`.
130
- * That is 's discipline and it is the reason the union cannot be talked into anything.
130
+ * That is the discipline and it is the reason the union cannot be talked into anything.
131
131
  * PURE; never throws.
132
132
  */
133
133
  export function rowIsSettled(row, canonical) {
@@ -235,7 +235,7 @@ export function buildSelectionIndex({ floors = null, positions = null } = {}) {
235
235
  floor_records: floorList.length,
236
236
  positions: posList.length,
237
237
  selectable_records: byUri.size,
238
- // An ABSENCE is recorded in the artifact rather than swallowed — 's rule. "no floors" and "the
238
+ // An ABSENCE is recorded in the artifact rather than swallowed — the rule. "no floors" and "the
239
239
  // band shape would not parse" are different facts and must not read alike.
240
240
  floors_unreadable: floors === null,
241
241
  positions_unreadable: positions === null,
@@ -102,7 +102,7 @@ export function unionPlacementForm(prior, submitted, input) {
102
102
  const consumed = new WeakSet();
103
103
  // RETRACTION IS EXPLICIT, and it is the only way a row leaves this form.
104
104
  //
105
- // 's seat rows were retracted by SILENCE — a submission that spoke owned them — and that was right
105
+ // That seat rows were retracted by SILENCE — a submission that spoke owned them — and that was right
106
106
  // there, because that seat rewrote its whole form every pass. This one does not: it writes DELTAS, so a
107
107
  // corrective attempt that re-tiers two register rows says nothing about the run's common-law
108
108
  // candidates, and silence-retraction would delete every one of them without a word. The 2026-08-09
@@ -0,0 +1,120 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright 2026 Cordillera Sàrl. Additional terms under section 7 of the AGPL-3.0 apply — see ADDITIONAL-TERMS.md
3
+ //
4
+ // THE TWO-REGISTER RULE, AS THE REVIEWER READS IT — tracker issue 333.
5
+ //
6
+ // The report goes to a lawyer who layers advice on top, and that lawyer's client reads the same page.
7
+ // The band, the summary, the basis line and the one-liners are the whole product for the second reader,
8
+ // and they were the hardest lines on it: single sentences of seventy-odd words in the lawyer's
9
+ // vocabulary. The owner's ruling is that default-visible text carries no legal or engine vocabulary at
10
+ // all, and that inside a fold the lawyer's words are allowed where a plain one would lose precision.
11
+ //
12
+ // THIS IS ADVISORY AND MUST STAY ADVISORY. A hit is a rewrite of that line — never a disclosure to the
13
+ // client, never a run failure. The rule is presentation: it changes no band, no evidence and nothing
14
+ // that is searched.
15
+ //
16
+ // — AND IT MUST NOT FIRE ON THE MARK IT IS CLEARING.
17
+ //
18
+ // This is the defect `coverage-form.mjs` records one level in: a refusal that cannot tell a mark from
19
+ // engine vocabulary blocked a clearance on the mark SLICE, and a render-time substitution turned "AXIS
20
+ // Bank filed in class 36" into "group Bank filed in class 36" on a report clearing AXIS. Half the words
21
+ // here are ordinary English and several are plausible marks — PREVAIL, SENIOR, SPECIFICATION. A check
22
+ // that flagged the mark under clearance would put noise on exactly the report that matters most, so
23
+ // every term the run is about is excluded before the text is read.
24
+
25
+ /**
26
+ * The lawyer's vocabulary, as WORKED EXAMPLES with the plain form beside each. Not a ban list: the
27
+ * issue rejects "a list of forbidden words as the mechanism" in terms, and this is what the reviewer
28
+ * offers a seat as the rewrite, which is a different thing from a gate that refuses.
29
+ *
30
+ * Each entry is [what a lawyer writes, what the reader needs]. The second half is the load-bearing one —
31
+ * a flag naming a word teaches nothing, and the seat has to produce a sentence.
32
+ */
33
+ export const PLAIN_FORMS = Object.freeze([
34
+ ["proprietor", "owner"],
35
+ ["subsisting", "live"],
36
+ ["specification", "goods list"],
37
+ ["citable", "earlier marks the office can raise against you"],
38
+ ["prevail", "win"],
39
+ ["formative", "names built on"],
40
+ ["belt-and-braces", "extra"],
41
+ ["non-use attack", "could be cancelled for not being used"],
42
+ ["on the record as it stands", "on what we found"],
43
+ ["marks-and-goods comparison", "same name, same goods"],
44
+ ["dispatch", "the request"],
45
+ ["instructed", "what was asked"],
46
+ ["chunk", ""],
47
+ ]);
48
+
49
+ /** The longest visible sentence a reader should meet. The issue's number, not a derived one. */
50
+ export const SENTENCE_WORD_LIMIT = 25;
51
+
52
+ /** Everything the run is ABOUT — the mark, its variants, the owners named. Never flagged. */
53
+ const ownTerms = (about = {}) => {
54
+ const out = [];
55
+ for (const v of [about.mark, ...(about.marks ?? []), ...(about.owners ?? []), ...(about.terms ?? [])]) {
56
+ const s = String(v ?? "").trim();
57
+ if (s) out.push(s.toLowerCase());
58
+ }
59
+ return out;
60
+ };
61
+
62
+ /** Sentences, split on terminators that end one. Crude on purpose — this counts words, not grammar. */
63
+ export const sentencesOf = (text) =>
64
+ String(text ?? "").split(/(?<=[.!?])\s+/).map((s) => s.trim()).filter(Boolean);
65
+
66
+ export const wordsIn = (sentence) => String(sentence ?? "").trim().split(/\s+/).filter(Boolean).length;
67
+
68
+ /**
69
+ * What is wrong with one default-visible line, as rewrite advice. `[]` means nothing to say.
70
+ *
71
+ * `about` carries the run's own marks and owners so they are never reported — see the header. A term
72
+ * that IS the thing being cleared is not the lawyer's vocabulary, it is the subject.
73
+ */
74
+ export function plainRegisterFlags(text, about = {}) {
75
+ const raw = String(text ?? "");
76
+ if (!raw.trim()) return [];
77
+ const mine = ownTerms(about);
78
+ // Blank the run's own terms before reading, rather than filtering hits afterwards: a mark can contain
79
+ // one of these words ("PREVAIL"), and a hit inside it is not a hit at all.
80
+ let scan = raw;
81
+ for (const t of mine) {
82
+ if (!t) continue;
83
+ scan = scan.replace(new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi"), " ");
84
+ }
85
+
86
+ const flags = [];
87
+ for (const [term, plain] of PLAIN_FORMS) {
88
+ const re = new RegExp(`\\b${term.replace(/[-]/g, "[- ]").replace(/\s+/g, "\\s+")}\\b`, "i");
89
+ if (!re.test(scan)) continue;
90
+ flags.push({
91
+ kind: "vocabulary",
92
+ term,
93
+ say: plain
94
+ ? `"${term}" is the lawyer's word — the reader needs "${plain}". Rewrite the sentence, do not swap the word.`
95
+ : `"${term}" is an engine word and has no place on a page a client reads. Rewrite the sentence.`,
96
+ });
97
+ }
98
+
99
+ for (const s of sentencesOf(raw)) {
100
+ const n = wordsIn(s);
101
+ if (n > SENTENCE_WORD_LIMIT) {
102
+ flags.push({
103
+ kind: "length",
104
+ words: n,
105
+ say: `${n} words in one sentence, and a visible line takes ${SENTENCE_WORD_LIMIT}. Split it — one idea per sentence, `
106
+ + "the conclusion first. Do not shorten it by dropping the reason.",
107
+ });
108
+ }
109
+ }
110
+ return flags;
111
+ }
112
+
113
+ /**
114
+ * The fields a reader meets before opening anything. Named here rather than at each call site so the
115
+ * two products answer to one list — the knockout and the clearance drifted apart once already.
116
+ */
117
+ export const DEFAULT_VISIBLE_FIELDS = Object.freeze({
118
+ knockout: ["summary", "batchOpener", "basis", "net", "factors", "counterFactors", "mitigation", "standardCaveats", "reviewerNotes"],
119
+ clearance: ["summary", "oneLiner", "registrability", "thirdPartyRights", "ownRights", "freedomToOperate", "reviewerNotes", "coverage"],
120
+ });
@@ -17,7 +17,7 @@ const domainOf = (email) => { const e = String(email ?? "").toLowerCase(); const
17
17
  /**
18
18
  * makePrincipal({ email, grants, staffDomains }) →
19
19
  * { role: "staff", email, accounts: "*" } — firm identity: everything, acting-for allowed
20
- * | { role: "client", email, accounts: ["aurora", …] } — enrolled client: exactly the granted accounts
20
+ * | { role: "client", email, accounts: ["foxglade", …] } — enrolled client: exactly the granted accounts
21
21
  * | null — unknown identity: no portal (the door 403s)
22
22
  * Staff wins over an (accidental) grants row; a client row with a tenant-wide "*" grant is honored
23
23
  * but the role stays client (no staff surfaces).
@@ -6,7 +6,7 @@
6
6
  // On the test instance they are the dominant content — a wall of dead runs crowding out the work
7
7
  // actually running, which is the one thing that section exists to show.
8
8
  //
9
- // WHAT THIS IS NOT. It is not a state change on the run, not a delete, and NOT 's retire. Retiring
9
+ // WHAT THIS IS NOT. It is not a state change on the run, not a delete, and NOT the retire. Retiring
10
10
  // writes `archive-tags.json`, which is pool-wide: it hides a run from everyone, including the brand
11
11
  // owner. Dashboard clutter is one person's annoyance, so it gets one person's store. Giving both to one
12
12
  // control would mean a staff member tidying their own dashboard silently hiding a client's run.
@@ -162,7 +162,7 @@ const FRONTED_MODES = new Set(["auth-proxy"]);
162
162
  /**
163
163
  * The auth row — the one row on this page that is NOT snapshot-derived, and deliberately so.
164
164
  *
165
- * WHY THIS BREAKS THE PAGE'S OWN RULE ON PURPOSE (, ruled 2026-08-21). Every other row here comes
165
+ * WHY THIS BREAKS THE PAGE'S OWN RULE ON PURPOSE (ruled 2026-08-21). Every other row here comes
166
166
  * from a snapshot because the portal cannot see the engine's environment. `PORTAL_AUTH_MODE` is the
167
167
  * opposite case: the PORTAL reads it (portal-service.mjs) and acts on it, so the portal is the
168
168
  * authoritative source for its own door. Routing it through flag-snapshot.mjs would publish another
@@ -239,6 +239,41 @@ export function authView({ mode = "", oidcIssuer = "", team = "", jwksUrl = "",
239
239
  };
240
240
  }
241
241
 
242
+ /**
243
+ * Where the staff-domain rule was written, so a reader can go and undo it.
244
+ *
245
+ * ── WHY A PAGE THAT NAMES A RULE MUST ALSO NAME ITS ADDRESS ─────────────────────────────────────────
246
+ *
247
+ * The People & access screen renders the rule — "Anyone at <domain> — a rule, not a person" — and said
248
+ * nothing about where it came from. A reader who does not recognise the domain therefore learns that
249
+ * strangers may hold an administrator's view of their instance and has no next step at all: the value
250
+ * is in an environment variable, in one of two files depending on how the instance is run, and neither
251
+ * is named anywhere on the screen. The one outside reader who met this reported it as a back door,
252
+ * twice, which is the correct thing to do with an access rule you cannot trace.
253
+ *
254
+ * PURE, and it answers "could not tell" as itself. `envLoad` is `shared/env-local.mjs`'s own report of
255
+ * what this process read, so the answer describes the process actually serving the page rather than
256
+ * being composed from a path that some other process would have read — the distinction that module
257
+ * exists for. A service started by systemd took its configuration from an EnvironmentFile; a child of
258
+ * `clearotron start` was handed an explicit environment and read no file at all; a hand-run CLI read
259
+ * the CLI's file. Each gets its own sentence, because the remedy is a different file in each.
260
+ */
261
+ export function staffRuleSource({ name = "PORTAL_STAFF_DOMAINS", value = "", envLoad = null,
262
+ unitEnvFile = null, cliEnvFile = null } = {}) {
263
+ if (!String(value ?? "").trim()) return null;
264
+ const reason = envLoad?.reason ?? null;
265
+ const applied = Array.isArray(envLoad?.applied) ? envLoad.applied : [];
266
+ if (reason === "read" && applied.includes(name))
267
+ return { name, where: `read from ${envLoad.path}` };
268
+ if (reason === "service-managed")
269
+ return { name, where: unitEnvFile ? `set in this service's environment file, ${unitEnvFile}` : "set in this service's environment" };
270
+ if (reason === "opted-out")
271
+ return { name, where: cliEnvFile
272
+ ? `handed to this service by the command that started it, which takes it from ${cliEnvFile} or derives it from the sign-in address`
273
+ : "handed to this service by the command that started it" };
274
+ return { name, where: cliEnvFile ? `set in this service's environment (the file it would otherwise read is ${cliEnvFile})` : "set in this service's environment" };
275
+ }
276
+
242
277
  /**
243
278
  * The enrolment view: who is granted what, and where an enrolment is half done.
244
279
  *
@@ -246,7 +281,7 @@ export function authView({ mode = "", oidcIssuer = "", team = "", jwksUrl = "",
246
281
  * they are reported separately — a staff member absent from the grants file is normal, not a fault,
247
282
  * and listing them as "unenrolled" would bury the real problems.
248
283
  */
249
- export function accessView({ grants, staffDomains = [], knownAccounts = [], grantsFile = null }) {
284
+ export function accessView({ grants, staffDomains = [], knownAccounts = [], grantsFile = null, staffRule = null }) {
250
285
  const tenants = grants?.tenants ?? {};
251
286
  const known = new Set(knownAccounts);
252
287
  const people = [];
@@ -277,6 +312,10 @@ export function accessView({ grants, staffDomains = [], knownAccounts = [], gran
277
312
  return {
278
313
  people: people.sort((a, b) => a.email.localeCompare(b.email)),
279
314
  staffDomains: [...staffDomains],
315
+ // An ADDITIONAL field rather than a reshape of `staffDomains`: that array is parsed by the browser
316
+ // contract and read by three screens' worth of arms, and a rule nobody can trace is a copy problem,
317
+ // not a data-shape problem. Null when there is no rule, or when the source could not be told.
318
+ staffRule,
280
319
  // Accounts named in grants that no profile matches — the other typo direction.
281
320
  unknownAccounts: [...unknownAccounts].sort(),
282
321
  // Where to go to change any of this — a filename and a date, so "I want to add someone" has a
@@ -336,7 +375,7 @@ export function accessView({ grants, staffDomains = [], knownAccounts = [], gran
336
375
  * because a log is unbounded by nature and this runs inside a web request.
337
376
  */
338
377
  /**
339
- * 's outcome rows — the events that record a request being TURNED AWAY rather than done. Kept
378
+ * That outcome rows — the events that record a request being TURNED AWAY rather than done. Kept
340
379
  * beside the reader rather than in portal-service.mjs so this file has no import cycle with the
341
380
  * service that writes them; the names are the contract between the two and are asserted in the test.
342
381
  */
@@ -18,7 +18,7 @@
18
18
  // ── the shape ────────────────────────────────────────────────────────────────────────────────────────
19
19
  //
20
20
  // { "schema": 1,
21
- // "families": { "hydra-range": { "name": "Hydra range", "account": "aurora" } },
21
+ // "families": { "hydra-range": { "name": "Hydra range", "account": "foxglade" } },
22
22
  // "of": { "<runId>": "hydra-range" } }
23
23
  //
24
24
  // Keyed by RUN rather than by mark. A mark is not a thing the pool stores — it is a grouping the browser
@@ -137,7 +137,7 @@ export function readLocalCredential(path) {
137
137
  */
138
138
  export function credentialPathFor(env = process.env, home = null) {
139
139
  // `homedir()` is resolved ON THE RETURN LINE, not as a signature default, and that is deliberate:
140
- // 's arm finds the single line naming the credential's env override and asserts the fallback
140
+ // That arm finds the single line naming the credential's env override and asserts the fallback
141
141
  // derives from homedir() rather than a literal path. A one-line decision gets a one-line check, and
142
142
  // a signature default would put the fact where that check cannot see it. `home` stays injectable.
143
143
  //
@@ -21,7 +21,7 @@ import { SUMMARY_BLOCK_LINE } from "../shared/summary-blocks.mjs";
21
21
  // a brand lockup, links to the pool index, status, profiles, and a "Clients" dropdown listing
22
22
  // EVERY customer by key:
23
23
  //
24
- // <a href="../customer/zephyr/">… <a href="../customer/aurora/">…
24
+ // <a href="../customer/coastline/">… <a href="../customer/foxglade/">…
25
25
  //
26
26
  // That is correct for a file a lawyer opens from the archive, and it is a disclosure of the client list
27
27
  // to anybody else. It has to come out before the document is embedded, and not because the nav is ugly:
@@ -388,7 +388,7 @@ function dropConnectorToken(html) {
388
388
  //
389
389
  // That is not a subtle degradation. chrome.css is 35KB of shared typography and layout, and among the
390
390
  // rules that went missing was `.lk-flag{width:10px;height:10px}` — sizing a lockup element that has
391
- // since been retired ( applied 's ruling to this lockup too), an SVG with no intrinsic size
391
+ // since been retired ( applied the ruling to this lockup too), an SVG with no intrinsic size
392
392
  // falling back to the browser default for a replaced element and painting at 300x150. The reported
393
393
  // symptoms — "a huge flag at the bottom", "font sizings inconsistent, multiple font types" — were one
394
394
  // cause: this file did not load. The example is historical; the failure mode is not, and any sizing
@@ -463,7 +463,7 @@ html{scrollbar-gutter:stable}
463
463
  // three functions the document already exposes to its own buttons. `openAll`/`pickAll` take a boolean and
464
464
  // nothing else; `exportPDF` takes no argument at all.
465
465
  const FEEDBACK_CSS = `
466
- /* tracker issue 260 — the per-finding flag. Injected here rather than in render.mjs, which is frozen and produces
466
+ /* the per-finding flag. Injected here rather than in render.mjs, which is frozen and produces
467
467
  every report ever delivered: putting the control at SERVE time means it reaches reports baked long
468
468
  before feedback existed, and the document on disk stays exactly what was delivered. */
469
469
  .pf-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:10px;padding-top:9px;border-top:1px solid var(--line,#e5ded4)}
@@ -590,7 +590,7 @@ const EMBED_JS = `
590
590
  // <body>), so by the time it runs for an '#c<ordinal>' link the ancestors are already open and the
591
591
  // measured offset is the revealed position. preventDefault stops the frame's dead-end fragment
592
592
  // navigation for the links the document's handler does not claim (#common-law, #only-you).
593
- // tracker issue 735 — AND WHEN THERE IS NO PARENT, DO NOT CANCEL THE CLICK.
593
+ // AND WHEN THERE IS NO PARENT, DO NOT CANCEL THE CLICK.
594
594
  //
595
595
  // Everything above is right INSIDE the portal's Result screen. Un-framed it is a dead link: parent is
596
596
  // window, the message is posted to this same document, and the only 'message' listener here requires
@@ -638,7 +638,7 @@ const FEEDBACK_JS = `
638
638
  (function(){
639
639
  var TAG='cordillera-report';
640
640
  function schedule(){ try{ parent.postMessage({source:TAG,type:'height',height:document.body.scrollHeight+16},'*'); }catch(e){} }
641
- // tracker issue 260 — PER-FINDING FEEDBACK, and why it posts outward instead of fetching.
641
+ // PER-FINDING FEEDBACK, and why it posts outward instead of fetching.
642
642
  //
643
643
  // This frame has NO allow-same-origin (Result.tsx), so its origin is "null": it holds no portal
644
644
  // session, a credentials:'include' fetch sends nothing, and a request from here arrives unauthenticated.
@@ -650,11 +650,11 @@ const FEEDBACK_JS = `
650
650
  // service reads those from the run's own artifacts, so nothing typed inside this frame can decide
651
651
  // which finding a flag lands on or whose matter it is labelled with.
652
652
  //
653
- // tracker issue 487 — THE POSITION IS TWO NUMBERS ON THE KNOCKOUT LANE, and it used to be none.
653
+ // THE POSITION IS TWO NUMBERS ON THE KNOCKOUT LANE, and it used to be none.
654
654
  //
655
655
  // The clearance report numbers its findings once across the document and hangs each on a
656
656
  // div.card with id "c<ordinal>". The knockout report has neither: its conflicts render as div.ko-find,
657
- // and tracker issue 471 restarts ordinals at 1 FOR EACH MARK. So this selector matched nothing on a knockout report
657
+ // and the knockout report restarts ordinals at 1 FOR EACH MARK. So this selector matched nothing on a knockout report
658
658
  // and the control was never drawn — the channel was not merely resolving wrong, it was absent. A
659
659
  // reader could not flag a knockout finding at all.
660
660
  //
@@ -38,7 +38,7 @@ import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
38
38
  import { storeInRepo, storeOutsideRepoMessage, makeCommittableAudit, resolveStoreRepoRoot, makeStoreCommit } from "../shared/store-in-repo.mjs"; //,
39
39
  import { customerStoreDir, customerStoreLine } from "../shared/customer-store.mjs"; // — one store for the surface and the runs
40
40
  import { clientFailureNote } from "../shared/client-failure-note.mjs"; // — one sentence, three surfaces
41
- import { bareInvocation, invocationPrefix } from "../shared/invocation.mjs"; // — and why this one surface is by NAME
41
+ import { bareInvocation, invocationPrefix, installRoute } from "../shared/invocation.mjs"; // — and why this one surface is by NAME
42
42
  import { stdioConnectOffer, stdioConnectFor, STDIO_SHAPES } from "../shared/stdio-connect.mjs"; // — ONE author for the connect route
43
43
  import { connectOffers, offersForWire } from "../shared/connect-clients.mjs"; // — ONE table, resolved server-side
44
44
  // — the portal became an ISSUANCE PATH here, deliberately and by owner ruling.
@@ -92,7 +92,7 @@ import { readFlagSnapshot, builtFor, registerCanCountFor, registerTerritoriesFor
92
92
  import { isDemo, demoPostureLine } from "./demo-posture.mjs";
93
93
  import { triggerCapGap, triggerCapWarning } from "./trigger-cap.mjs"; // F51 — one answer, three surfaces
94
94
  import { makeUpstream } from "./portal-upstream.mjs";
95
- import { flagView, accessView, observedView, authView } from "./portal-config-view.mjs";
95
+ import { flagView, accessView, observedView, authView, staffRuleSource } from "./portal-config-view.mjs";
96
96
  import { livePosture } from "./flag-snapshot.mjs"; // — for the capture-vs-box comparison only, never for a value
97
97
  import { familiesView, groupRuns, ungroupRuns } from "./portal-families.mjs";
98
98
  import { validateJob } from "./enqueue-schema.mjs";
@@ -102,7 +102,7 @@ import { batchMarkName } from "./mark-name.mjs";
102
102
  import { DEFAULT_CLIENT_DAILY_RUNS, accountUsage } from "./usage-ledger.mjs";
103
103
  import { productIdentity } from "../shared/product-identity.mjs"; // AGPL §13 — one answer, three surfaces
104
104
  import { engineCommit } from "./engine-build.mjs"; // — the SAME stamp pool meta records
105
- // — siblings, on their own line: 's guard pins the line above and its subject is the JOIN
105
+ // — siblings, on their own line: the guard pins the line above and its subject is the JOIN
106
106
  // (this endpoint and pool meta stamp the same function), not the import list. Kept separate so that
107
107
  // pin keeps reading the shape it was written against.
108
108
  import { engineCommitDate, engineProvenance } from "./engine-build.mjs";
@@ -948,7 +948,7 @@ const DENIAL_REASON = Object.freeze({
948
948
  *
949
949
  * The capture path it gates is intact: `feedback-store.mjs`, `feedback-issues.mjs`, `feedback-mint.mjs`,
950
950
  * `scripts/feedback-mint.mjs` and their suites are untouched and still green. Re-enabling is this
951
- * constant, the `feedback: true` argument at the serve call site, and reverting 's portal-ui half.
951
+ * constant, the `feedback: true` argument at the serve call site, and reverting the portal-ui half.
952
952
  */
953
953
  const FEEDBACK_CAPTURE = false;
954
954
 
@@ -968,7 +968,7 @@ const NON_MUTATING_POSTS = Object.freeze(["/portal/api/compose/read", "/portal/a
968
968
  /**
969
969
  * Does a refusal on this route owe the audit log a line?
970
970
  *
971
- * ── WIDENS 's ANSWER, and the reason is on that issue ─────────────────
971
+ * ── WIDENS the ANSWER, and the reason is on that issue ─────────────────
972
972
  *
973
973
  * scoped this to `/portal/admin/*` plus the one named client write, on the reasoning that the
974
974
  * other write routes "already file a richer row" of their own. Measured, that is true of their
@@ -980,9 +980,9 @@ const NON_MUTATING_POSTS = Object.freeze(["/portal/api/compose/read", "/portal/a
980
980
  *
981
981
  * So the rule is now the PREFIX, not a list: a POST under `/portal/api` or `/portal/admin` is a write
982
982
  * unless it is named above. A route added later is covered without anybody remembering to add it,
983
- * which is the half of 's shape that kept failing.
983
+ * which is the half of the shape that kept failing.
984
984
  *
985
- * STILL REFUSALS ONLY, and 's cost argument is why that half is unchanged: `/portal/admin/observed`
985
+ * STILL REFUSALS ONLY, and the cost argument is why that half is unchanged: `/portal/admin/observed`
986
986
  * reads this log back through a fixed 256 KiB tail, so every row a success files is span that panel can
987
987
  * no longer see. The routes that file a rich success row keep filing it and nothing duplicates it.
988
988
  *
@@ -1029,6 +1029,11 @@ function outcomeRow({ event = "request-refused", method, path, email = null, sta
1029
1029
  export function makePortalService({
1030
1030
  poolRoot, workspaceRoot, recipesDir = undefined, secret,
1031
1031
  staffDomains = [], grants = null,
1032
+ // Where the staff-domain rule is written, for the People & access page to name. INJECTED, because
1033
+ // the answer is a fact about the PROCESS — which file, if any, it took its configuration from — and
1034
+ // this constructor is deliberately pure over its inputs. Null means "no rule, or could not tell",
1035
+ // and the page then says nothing rather than guessing at a path.
1036
+ staffRule = null,
1032
1037
  // The queue directories the RUNNER drains — the same list it hands checkRunCaps. The allowance counter
1033
1038
  // and the quota pre-check read their ledger beside these, so they count what the wall counts (:
1034
1039
  // they used to reconstruct a workspace-relative path that resolved to nothing once the queue moved out
@@ -1077,7 +1082,7 @@ export function makePortalService({
1077
1082
  // — IS THE PER-FINDING FLAG CAPTURE ON? It is not, and `FEEDBACK_CAPTURE` is why (see above).
1078
1083
  //
1079
1084
  // A SEAM SO THE RETAINED PATH STAYS TESTED, which is the whole difference between disabled and
1080
- // rotting. The resolver below carries 's two-lane shape and 's disposition read; the owner
1085
+ // rotting. The resolver below carries the two-lane shape and the disposition read; the owner
1081
1086
  // ruled disable rather than delete, and code nothing can execute is code nobody can prove still works.
1082
1087
  // The eleven route tests in portal-service.test.mjs pass `feedbackCapture: true` and keep exercising it.
1083
1088
  //
@@ -1158,7 +1163,7 @@ export function makePortalService({
1158
1163
  // ── — COVERAGE RIDES BESIDE AVAILABILITY, NOT INSIDE IT ───────────
1159
1164
  //
1160
1165
  // The owner, on his own install with a partial register: "i cannot press the button for Global
1161
- // prelim search. Why. it doesnt appear disabled, no message etc — but i cant select it." The
1166
+ // clearotron search. Why. it doesnt appear disabled, no message etc — but i cant select it." The
1162
1167
  // product is orderable now (owner ruling on that issue), and what the register does not reach
1163
1168
  // is a SENTENCE on a live row rather than the reason a dead one cannot be pressed.
1164
1169
  //
@@ -1338,7 +1343,7 @@ export function makePortalService({
1338
1343
  assertPrincipal(principal, { door: true }); // door check only — a multi-account client enters and gets the picker list
1339
1344
  // `accountNames` — the DISPLAY name of each account this identity holds, and nothing else.
1340
1345
  //
1341
- // Every profile carries a name ("Vantor Labs", "Aurora Interactive"); the account KEY is a
1346
+ // Every profile carries a name ("Vantor Labs", "Foxglade Interactive"); the account KEY is a
1342
1347
  // slug ("vantor"). Staff read names because the account picker fetches the staff-only
1343
1348
  // roster; a client had no name source at all, so the identical screen printed the slug at them.
1344
1349
  // The same brand owner therefore read two different ways depending on who signed in, which is
@@ -1386,12 +1391,18 @@ export function makePortalService({
1386
1391
  // must leave the button alone rather than infer demo from an absent file.
1387
1392
  return { status: 200, json: { role: principal.role, email: principal.email, accounts: principal.accounts, accountNames,
1388
1393
  concurrentRuns: concurrentRunsCap(), brand: BRAND.name, engineMode: flagView(poolRoot).engineMode,
1394
+ // HOW THIS INSTALL ARRIVED, so a screen can name the setup command the reader can actually
1395
+ // type. `npm run setup` and `npx clearotron install` are the same wizard and each one is
1396
+ // unrunnable on the other route; the no-engine notice named one of them and was wrong for
1397
+ // half its readers. A WORD, never a command line and never a prefix: `invocationForm` can
1398
+ // answer with this machine's absolute path, and this value is rendered in a browser.
1399
+ setupRoute: installRoute(),
1389
1400
  // — a button that always fails must not render as available. The reason is
1390
1401
  // operator-shaped and staff-only; a client reads the generic sentence the button carries.
1391
1402
  controls: { stop: { available: stopControl.available !== false,
1392
1403
  reason: principal.role === "staff" ? (stopControl.reason ?? null) : null } } } };
1393
1404
  }
1394
- // /portal/api/about — the AGPL §13 source offer (,)
1405
+ // /portal/api/about — the AGPL §13 source offer ()
1395
1406
  //
1396
1407
  // UNAUTHENTICATED, DELIBERATELY, and it is the only route here that is. §13 obliges an operator
1397
1408
  // running a modified version to offer the source to the users interacting with it — the offer is
@@ -2500,7 +2511,7 @@ export function makePortalService({
2500
2511
  // row, and a retired-endpoint row is a different fact from a not-yours row. If an old open tab is
2501
2512
  // still clicking Flag, that is a thing worth being able to count.
2502
2513
  //
2503
- // WHAT IS DELIBERATELY STILL BELOW THIS LINE: the whole resolver — 's two-lane shape, 's
2514
+ // WHAT IS DELIBERATELY STILL BELOW THIS LINE: the whole resolver — the two-lane shape, 's
2504
2515
  // disposition read, the server-side-locator rule. The owner ruled "disable services and any code",
2505
2516
  // and the acceptance criterion says re-enabling must be a switch and not a rebuild. Deleting 130
2506
2517
  // lines of hard-won doctrine would have made it a rebuild.
@@ -2568,7 +2579,7 @@ export function makePortalService({
2568
2579
  //
2569
2580
  // JOINED ON ORDINAL **AND** MARK, and it resolves NOTHING on a mismatch. report-data projects the
2570
2581
  // same parsed findings array publish read from that same findings.json, so the ordinals are one
2571
- // set — but a wrong disposition on a lawyer's flag is worse than no disposition ('s ruling on
2582
+ // set — but a wrong disposition on a lawyer's flag is worse than no disposition (the ruling on
2572
2583
  // the batch lane, applied here), so the mark is checked rather than assumed.
2573
2584
  //
2574
2585
  // CLEARANCE ONLY, on purpose. publish/knockout.mjs emits no disposition, so `found?.disposition`
@@ -2655,7 +2666,7 @@ export function makePortalService({
2655
2666
  // report every switch as off on a box where they are on — and this page, of all pages, would be
2656
2667
  // believed.
2657
2668
  if (parts[2] === "config" && method === "GET") {
2658
- // THE AUTH ROW IS READ LIVE, HERE, and not from the snapshot (, ruled 2026-08-21).
2669
+ // THE AUTH ROW IS READ LIVE, HERE, and not from the snapshot (ruled 2026-08-21).
2659
2670
  // Everything else on this page is RENDERED from the snapshot. The reason recorded here used
2660
2671
  // to be "because this process has no engine environment", and that has not been true since
2661
2672
  // the owner's 2026-08-26 one-configuration-per-server-box ruling gave every unit the same
@@ -2822,7 +2833,7 @@ export function makePortalService({
2822
2833
  const p = envFrom(process.env, "CLEAROTRON_ACCESS_FILE");
2823
2834
  if (p) grantsFile = { name: basename(p), modifiedAt: new Date(statSync(p).mtimeMs).toISOString() };
2824
2835
  } catch { /* reported as unknown; a failed stat must not take down the page that explains access */ }
2825
- return { status: 200, json: accessView({ grants: grantsNow(), staffDomains, knownAccounts, grantsFile }) };
2836
+ return { status: 200, json: accessView({ grants: grantsNow(), staffDomains, knownAccounts, grantsFile, staffRule }) };
2826
2837
  }
2827
2838
  // /portal/admin/observed — who has actually USED this instance lately, from the audit log.
2828
2839
  //
@@ -3212,7 +3223,7 @@ const escHtml = (t) => String(t).replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<"
3212
3223
  // mentioned. A colour literal reappearing in this function is what
3213
3224
  // `driver/test/door-pages-take-their-colours-from-brand.test.mjs` fails on.
3214
3225
  //
3215
- // The dark ground moved with that change: the block this page used to carry had guessed tracker issue 17150f/#ece5d8,
3226
+ // The dark ground moved with that change: the block this page used to carry had guessed #17150f/#ece5d8,
3216
3227
  // and brand pack §01 fixes dark at #0f0e0c near-black + #f0e8d8 parchment. The pack wins.
3217
3228
  export function loginPage({ email, error = null, signedIn = false }) {
3218
3229
  const title = signedIn ? "Signed in" : "Sign in";
@@ -3408,7 +3419,7 @@ export function makeHttpHandler({ verify, limiter, service, log = () => {}, devI
3408
3419
  // PATHNAME ONLY. `req.url` carries the query string and this row must not; parsed defensively
3409
3420
  // because the outer catch can run before `url` was successfully built.
3410
3421
  const pathOnly = (u) => { try { return new URL(String(u ?? ""), "http://localhost").pathname; } catch { return ""; } };
3411
- // SAME SCOPE AS THE ROUTER'S ('s Out of scope). Without this the door files a row for every
3422
+ // SAME SCOPE AS THE ROUTER'S (the Out of scope). Without this the door files a row for every
3412
3423
  // 302 to the login page and every rate-limited poll of /portal/api/runs — which is per-request
3413
3424
  // access logging arriving through the other entrance, and the first cut of this change did exactly
3414
3425
  // that. Computed once so a redirect and a 500 on the same request cannot disagree about it.
@@ -3506,7 +3517,7 @@ export function makeHttpHandler({ verify, limiter, service, log = () => {}, devI
3506
3517
  // local-auth block, so calling it from here threw ReferenceError and this route answered 500 —
3507
3518
  // worse than the dead link it replaced, because a dead link looks like a dead link and a 500
3508
3519
  // looks like the server broke. Found by `npm run lint:driver`, which says it in one line
3509
- // (`'redirect' is not defined`), and by role-dev/Grogu driving the route rather than reading it.
3520
+ // (`'redirect' is not defined`), and by driving the route rather than reading it (review, 2026-08).
3510
3521
  // Hoisting that helper would move it away from the comment explaining its own no-`?next=` rule,
3511
3522
  // so the four lines live here instead.
3512
3523
  if (!localAuth && url.pathname === "/portal/sign-out") {
@@ -3669,7 +3680,7 @@ export function makeHttpHandler({ verify, limiter, service, log = () => {}, devI
3669
3680
  // THE ROW THE ISSUE WAS FILED ABOUT. Both doors throw this shape — the Cloudflare edge's verify
3670
3681
  // and the local sign-in's LocalAuthError — so one line here covers a refused write on either
3671
3682
  // deployment. Before the Accept split below, because a refusal is one event however it renders.
3672
- // A FIXED VOCABULARY, NEVER `e.message` ('s third criterion: "a refusal must not become a
3683
+ // A FIXED VOCABULARY, NEVER `e.message` (the third criterion: "a refusal must not become a
3673
3684
  // new disclosure surface"). This message comes out of `verify()` — the Cloudflare edge's JWT
3674
3685
  // check, a third-party library on some deployments — and nothing constrains what it puts in
3675
3686
  // there: a claim value, a subject, a fragment of the token it just rejected. The row is read
@@ -3915,6 +3926,14 @@ const PORT = PORT_CHOICE.port;
3915
3926
  const grants = () => loadGrants({});
3916
3927
  const staffDomains = (process.env.PORTAL_STAFF_DOMAINS || "").split(",").map((s) => s.trim()).filter(Boolean);
3917
3928
  if (!staffDomains.length && !grants()) { log(`FATAL: neither PORTAL_STAFF_DOMAINS nor CLEAROTRON_ACCESS_FILE configured — nobody could ever sign in (fail-closed).`); process.exit(1); }
3929
+ // WHERE THAT RULE IS WRITTEN, resolved once at boot and handed to the service. `loaded` is this
3930
+ // process's own report of which file configured it — never a path composed here, which would answer
3931
+ // for a process that read nothing (see `envFileRead`'s note in shared/env-local.mjs).
3932
+ const { loaded, unitEnvPath, envLocalPath } = await import("../shared/env-local.mjs");
3933
+ const staffRule = staffRuleSource({
3934
+ value: process.env.PORTAL_STAFF_DOMAINS, envLoad: loaded,
3935
+ unitEnvFile: unitEnvPath(), cliEnvFile: envLocalPath(),
3936
+ });
3918
3937
 
3919
3938
  const { config } = await import("./driver.config.mjs");
3920
3939
  const { appendFileSync: append } = await import("node:fs");
@@ -3929,7 +3948,7 @@ const PORT = PORT_CHOICE.port;
3929
3948
  // is what an operator reads, never mentioned the file existed.
3930
3949
  //
3931
3950
  // So triage of "I clicked Retire and it errored" looked at 17 lines of startup banner and concluded
3932
- // the request never arrived. 's own triage recorded that same absence as its central lead and
3951
+ // the request never arrived. its own triage recorded that same absence as its central lead and
3933
3952
  // called it "the first thing to explain" — there was nothing to explain, and a second investigation
3934
3953
  // spent itself on the same non-signal.
3935
3954
  //
@@ -4188,7 +4207,7 @@ const PORT = PORT_CHOICE.port;
4188
4207
  // The result was not a failure. It was worse. With the overlay unset, resolveSkillPath falls back
4189
4208
  // to the PRODUCT REPO's own driver/skills — where the customer frameworks either do not exist
4190
4209
  // (a config-store-only customer → the page's fail-loud "could not be read" card) or exist as the SYNTHETIC
4191
- // DEMO fixtures the sellable codebase ships (Aurora, Zephyr "Aurora Interactive risk framework
4210
+ // DEMO fixtures the repository carries for the suite (a framework titled " risk framework
4192
4211
  // (synthetic demo)", source_deck "content invented"). The second case renders with a title, a band
4193
4212
  // ladder and band meanings, and is indistinguishable on screen from the client's real framework.
4194
4213
  // A lawyer read invented risk definitions as their client's own for as long as this was live.
@@ -4356,7 +4375,7 @@ const PORT = PORT_CHOICE.port;
4356
4375
  const service = makePortalService({ poolRoot: config.poolRoot, workspaceRoot: config.workspaceRoot,
4357
4376
  // Re-read per request (a getter that rescans), so a workspace created after boot is counted.
4358
4377
  queueDirs: () => config.queueDirs,
4359
- secret, staffDomains, grants, trigger, stopRun, audit, auditPath, upstream, composeRead, stopControl,
4378
+ secret, staffDomains, staffRule, grants, trigger, stopRun, audit, auditPath, upstream, composeRead, stopControl,
4360
4379
  // — the ONLY place the environment is read for this. `bin/start.mjs` is the
4361
4380
  // only thing that sets it, and it sets it explicitly rather than passing the operator's inherited
4362
4381
  // environment through, so a stray `.env` can neither put a live install into demo mode nor take a
@@ -96,7 +96,7 @@ export const PATH_FIELDS = ["frameworkPath", "workedExamplesPath"];
96
96
  /**
97
97
  * The code-owned values, READ-ONLY, for display. The page shows them badged; it cannot send them.
98
98
  *
99
- * Two of them are PATHS INSIDE THE ENGINE — `skills/prelim-search/risk-framework-zephyr.md` — and they
99
+ * Two of them are PATHS INSIDE THE ENGINE — `skills/prelim-search/risk-framework-<customer>.md` — and they
100
100
  * are withheld from a client here, on the server, where the role is already in hand. The React page has
101
101
  * filtered them out of its own render since the rebuild, but a filter in the browser is a display
102
102
  * convenience and not a wall: the value still crossed the wire and was one devtools tab away.
@@ -129,7 +129,7 @@ export function readOnlyFields(profile, { staff = false } = {}) {
129
129
  *
130
130
  * house "…IP Risk Assessment Framework.pptx (Privileged & Confidential), transcribed 2026-07-05
131
131
  * (doc 50); supersedes the client-transposed neutral default"
132
- * aurora "Synthetic demo transposition of a customer risk deck (structure faithful, content
132
+ * demo "Synthetic demo transposition of a customer risk deck (structure faithful, content
133
133
  * invented), doc 50 shape"
134
134
  * triage "Ported from the interactive knockout-searches skill's 5-tier rating system (SKILL.md
135
135
  * rating table + calibration rules), doc 50 shape"