@yalehwang/cloudpit 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api-docs.html +3 -3
- package/dist/assets/{abnfDiagram-N423BO3Z-D5yLnMt9.js → abnfDiagram-N423BO3Z-D7Xt05gV.js} +1 -1
- package/dist/assets/{abnfDiagram-N423BO3Z-bTHtQIhR.js → abnfDiagram-N423BO3Z-dmPRRPEm.js} +1 -1
- package/dist/assets/{arc-1DmrBEyG.js → arc-B7W3R5qH.js} +1 -1
- package/dist/assets/{arc-BlGK--01.js → arc-BHMlIcaQ.js} +1 -1
- package/dist/assets/{architectureDiagram-T3A2C74G--lzbKBn9.js → architectureDiagram-T3A2C74G-CUUpAoN0.js} +1 -1
- package/dist/assets/{architectureDiagram-T3A2C74G-7lKNAbUU.js → architectureDiagram-T3A2C74G-DpXhbHxu.js} +1 -1
- package/dist/assets/{blockDiagram-VBNYF7ZC-17cdO9zs.js → blockDiagram-VBNYF7ZC-Bf0yfNxj.js} +1 -1
- package/dist/assets/{blockDiagram-VBNYF7ZC-BPavJfDj.js → blockDiagram-VBNYF7ZC-Cki9AOhc.js} +1 -1
- package/dist/assets/{c4Diagram-5PPSVZJV-Bm1-2w3b.js → c4Diagram-5PPSVZJV-DK2RqNDO.js} +1 -1
- package/dist/assets/{c4Diagram-5PPSVZJV-aHvFL3Wb.js → c4Diagram-5PPSVZJV-DyhTF0e5.js} +1 -1
- package/dist/assets/channel-DTLMNzbH.js +1 -0
- package/dist/assets/channel-DiqxUuPf.js +1 -0
- package/dist/assets/{chunk-2GRJ4B5K-D7WqZewM.js → chunk-2GRJ4B5K-BYtByJbf.js} +1 -1
- package/dist/assets/{chunk-2GRJ4B5K-DbwzBiPF.js → chunk-2GRJ4B5K-CksFgocc.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-DdCr89uy.js → chunk-2Q5K7J3B-D2kQa5TZ.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-TFd0ECKO.js → chunk-2Q5K7J3B-NSSX86FA.js} +1 -1
- package/dist/assets/{chunk-5RXB4S5H-BdhRBpEi.js → chunk-5RXB4S5H-DNNYC8_t.js} +1 -1
- package/dist/assets/{chunk-5RXB4S5H-D0SQ3nIe.js → chunk-5RXB4S5H-Rx0YaqNI.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-B9Lv3cWR.js → chunk-5VM5RSS4-B1k4I4CX.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DioqTIvB.js → chunk-5VM5RSS4-CsvQj3QC.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-09bwlcIv.js → chunk-6Q2QTUOP-48-dEgAs.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-JuhPJZZL.js → chunk-6Q2QTUOP-DCMSW5_0.js} +1 -1
- package/dist/assets/{chunk-GF5L2VYU-C6f2SgCw.js → chunk-GF5L2VYU-CGyvOsdN.js} +1 -1
- package/dist/assets/{chunk-GF5L2VYU-DzD9aOyp.js → chunk-GF5L2VYU-YXe113hp.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-BggnWNZv.js → chunk-JWPE2WC7-BT7vCW4x.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-Dte_Ax9K.js → chunk-JWPE2WC7-D2K1Oywq.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-9TCQV92m.js → chunk-KBJHAD2P-CQZWamtE.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-DDnJp7kJ.js → chunk-KBJHAD2P-gpEwZrNy.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-CE2Y4D_h.js → chunk-RYQCIY6F-BI0fMtjY.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-DsgFSTNw.js → chunk-RYQCIY6F-vguRdb4F.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-B1FIfsqq.js → chunk-XXDRQBXY-B99qH1_w.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-B4YfaqTO.js → chunk-XXDRQBXY-DZLJnbBB.js} +1 -1
- package/dist/assets/classDiagram-JCYQIIEL-BaV-s6x8.js +1 -0
- package/dist/assets/classDiagram-JCYQIIEL-D4M03B4L.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-BaV-s6x8.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-D4M03B4L.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-C1AG5Pib.js → cose-bilkent-JH36ORCC-EsVnz-E6.js} +1 -1
- package/dist/assets/{cose-bilkent-JH36ORCC-lMwWDibI.js → cose-bilkent-JH36ORCC-VI2OjCIx.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-BlabniRL.js → cynefin-VYW2F7L2-BVYg0ixs.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-W-c-z4IW.js → cynefin-VYW2F7L2-BnHmA5I2.js} +1 -1
- package/dist/assets/{cynefinDiagram-MW4NZA55-BtTep_pq.js → cynefinDiagram-MW4NZA55-B-OCRLIw.js} +1 -1
- package/dist/assets/{cynefinDiagram-MW4NZA55-Due6EIPh.js → cynefinDiagram-MW4NZA55-ItLlzjDR.js} +1 -1
- package/dist/assets/{dagre-VZM6K2ZE-CWLaFfdt.js → dagre-VZM6K2ZE-DkVDkAWJ.js} +1 -1
- package/dist/assets/{dagre-VZM6K2ZE-DZldvqiQ.js → dagre-VZM6K2ZE-bYR4z8-Z.js} +1 -1
- package/dist/assets/{diagram-7IWD3JNH-RnmUHYwN.js → diagram-7IWD3JNH-DjXMue67.js} +1 -1
- package/dist/assets/{diagram-7IWD3JNH-Di-7-nSA.js → diagram-7IWD3JNH-FNEXlm5k.js} +1 -1
- package/dist/assets/{diagram-B4RE2ZJO-Wybyn8fw.js → diagram-B4RE2ZJO-73NYiO_P.js} +1 -1
- package/dist/assets/{diagram-B4RE2ZJO-mrK79C2E.js → diagram-B4RE2ZJO-dB4QHq0D.js} +1 -1
- package/dist/assets/{diagram-LBJQPF4R-JY6FqSFu.js → diagram-LBJQPF4R-DyKT610O.js} +1 -1
- package/dist/assets/{diagram-LBJQPF4R-sWhu2VLy.js → diagram-LBJQPF4R-rMgmnjvd.js} +1 -1
- package/dist/assets/{diagram-Q27KOJAE-BJ4T0WGp.js → diagram-Q27KOJAE-BvsfmmQt.js} +1 -1
- package/dist/assets/{diagram-Q27KOJAE-DyGT9KhB.js → diagram-Q27KOJAE-c6DEjLQX.js} +1 -1
- package/dist/assets/{diagram-UB23O5K3-oXFJAndB.js → diagram-UB23O5K3-BMo2VXVb.js} +1 -1
- package/dist/assets/{diagram-UB23O5K3-tTd8qwEM.js → diagram-UB23O5K3-DRMKefnZ.js} +1 -1
- package/dist/assets/{ebnfDiagram-BXEA7PRR-DV67cBe6.js → ebnfDiagram-BXEA7PRR-BrOAekWh.js} +1 -1
- package/dist/assets/{ebnfDiagram-BXEA7PRR-OQGm8tPs.js → ebnfDiagram-BXEA7PRR-YmQkylwV.js} +1 -1
- package/dist/assets/{elk-BRx4gEGg.js → elk-Hz3WRESK.js} +1 -1
- package/dist/assets/{elk-CdAQJ-NA.js → elk-tPSZwRVB.js} +1 -1
- package/dist/assets/{erDiagram-JOGREHBK-BhD2xZ2I.js → erDiagram-JOGREHBK-BlaZnoQi.js} +1 -1
- package/dist/assets/{erDiagram-JOGREHBK-BqP8DqqW.js → erDiagram-JOGREHBK-CRCfRUXt.js} +1 -1
- package/dist/assets/{flowDiagram-UKHOOZJN-B4AjZxPJ.js → flowDiagram-UKHOOZJN-DQ1gbjxo.js} +1 -1
- package/dist/assets/{flowDiagram-UKHOOZJN-CP_1WsW4.js → flowDiagram-UKHOOZJN-Dinlbmds.js} +1 -1
- package/dist/assets/{ganttDiagram-PKOTCBZU-BMk6nngr.js → ganttDiagram-PKOTCBZU-CMGpcBZO.js} +1 -1
- package/dist/assets/{ganttDiagram-PKOTCBZU-B_ce39Ld.js → ganttDiagram-PKOTCBZU-Eh94zuPI.js} +1 -1
- package/dist/assets/{gitGraphDiagram-DS77QQ5N-CnZA42iA.js → gitGraphDiagram-DS77QQ5N-Bp8xIZbk.js} +1 -1
- package/dist/assets/{gitGraphDiagram-DS77QQ5N-DqEz_iTn.js → gitGraphDiagram-DS77QQ5N-Cu-b4YNw.js} +1 -1
- package/dist/assets/index-51e8fagd.css +32 -0
- package/dist/assets/{index-D5nLH7qP.js → index-CQE9C6k6.js} +356 -356
- package/dist/assets/{index-CqyOGerp.js → index-S8ow0XfK.js} +356 -356
- package/dist/assets/{infoDiagram-6WML65LV-BQf7m4X4.js → infoDiagram-6WML65LV-CClEEtTq.js} +1 -1
- package/dist/assets/{infoDiagram-6WML65LV-Dntf4YFM.js → infoDiagram-6WML65LV-QmHeojgl.js} +1 -1
- package/dist/assets/{ishikawaDiagram-WSZJBQD7-BDjsldAI.js → ishikawaDiagram-WSZJBQD7-BemSj9lN.js} +1 -1
- package/dist/assets/{ishikawaDiagram-WSZJBQD7-BqXpJeoL.js → ishikawaDiagram-WSZJBQD7-nw48g1vr.js} +1 -1
- package/dist/assets/{journeyDiagram-NVQOT4AX-CBcFzP2M.js → journeyDiagram-NVQOT4AX-DeNtO6OU.js} +1 -1
- package/dist/assets/{journeyDiagram-NVQOT4AX-DoWKjgKd.js → journeyDiagram-NVQOT4AX-q1lCfOYn.js} +1 -1
- package/dist/assets/{kanban-definition-27J2QSJJ-9bspl7j-.js → kanban-definition-27J2QSJJ-Bzhu6hql.js} +1 -1
- package/dist/assets/{kanban-definition-27J2QSJJ-Cjxa-Fbb.js → kanban-definition-27J2QSJJ-VfvD33YG.js} +1 -1
- package/dist/assets/{linear-YogAXmU_.js → linear-C0Kwu3Yp.js} +1 -1
- package/dist/assets/{linear-lIhI5Y8l.js → linear-CbM_4-fP.js} +1 -1
- package/dist/assets/{mermaid.core-2Spxcrg7.js → mermaid.core-G2huIsXn.js} +5 -5
- package/dist/assets/{mermaid.core-BxxInCBm.js → mermaid.core-fvTQFUX1.js} +5 -5
- package/dist/assets/{mindmap-definition-FAOFIHXS-DblO5EG4.js → mindmap-definition-FAOFIHXS-BONvuyvz.js} +1 -1
- package/dist/assets/{mindmap-definition-FAOFIHXS-_nlvJ9VK.js → mindmap-definition-FAOFIHXS-BzYawGKQ.js} +1 -1
- package/dist/assets/{pegDiagram-VL7TDLO6-BBJFPAZG.js → pegDiagram-VL7TDLO6-Df2HAKGH.js} +1 -1
- package/dist/assets/{pegDiagram-VL7TDLO6-DhRH7YRf.js → pegDiagram-VL7TDLO6-DnMwBHn_.js} +1 -1
- package/dist/assets/{pieDiagram-7S7Q4E2Y-4Qy7Nk4U.js → pieDiagram-7S7Q4E2Y-Cd3-a-dM.js} +1 -1
- package/dist/assets/{pieDiagram-7S7Q4E2Y-BUtdeYBT.js → pieDiagram-7S7Q4E2Y-LV6TOhOD.js} +1 -1
- package/dist/assets/{quadrantDiagram-CIZ2JOQS-BUoIDY1r.js → quadrantDiagram-CIZ2JOQS-8VOnA3FV.js} +1 -1
- package/dist/assets/{quadrantDiagram-CIZ2JOQS-D90kdHA1.js → quadrantDiagram-CIZ2JOQS-CnwxFPxh.js} +1 -1
- package/dist/assets/{railroadDiagram-AXF67PYL-CJf9--tj.js → railroadDiagram-AXF67PYL-CXBFj3Iu.js} +1 -1
- package/dist/assets/{railroadDiagram-AXF67PYL-D3S1oliC.js → railroadDiagram-AXF67PYL-DLoAPcsb.js} +1 -1
- package/dist/assets/{requirementDiagram-LRYGKXZP-C04jhjS6.js → requirementDiagram-LRYGKXZP-LrVlZXSz.js} +1 -1
- package/dist/assets/{requirementDiagram-LRYGKXZP-cQaGai5h.js → requirementDiagram-LRYGKXZP-pakITowN.js} +1 -1
- package/dist/assets/{sankeyDiagram-W5VNT64P-AT4cTVbY.js → sankeyDiagram-W5VNT64P-BIQQ8A1I.js} +1 -1
- package/dist/assets/{sankeyDiagram-W5VNT64P-DfFUdqYO.js → sankeyDiagram-W5VNT64P-C6QWOxNM.js} +1 -1
- package/dist/assets/{sequenceDiagram-SI44F4Z6-DbjhG030.js → sequenceDiagram-SI44F4Z6-CpHBe2CG.js} +1 -1
- package/dist/assets/{sequenceDiagram-SI44F4Z6-DKjdupix.js → sequenceDiagram-SI44F4Z6-cnLxaxcV.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-CCcKLP8m.js → sizeCapture-X5ZJPWSS-3g-1onHD.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-DGxRWxeo.js → sizeCapture-X5ZJPWSS-4U6b3PSL.js} +1 -1
- package/dist/assets/{stateDiagram-OKZ733FA-D7wGCNb7.js → stateDiagram-OKZ733FA-CFwVDdlY.js} +1 -1
- package/dist/assets/{stateDiagram-OKZ733FA-qdMAailp.js → stateDiagram-OKZ733FA-CKVGJcM2.js} +1 -1
- package/dist/assets/{stateDiagram-v2-UEYNNEHI-BbmmtA9w.js → stateDiagram-v2-UEYNNEHI-Dnbk8ftm.js} +1 -1
- package/dist/assets/{stateDiagram-v2-UEYNNEHI-Diz_hFvh.js → stateDiagram-v2-UEYNNEHI-rlA-woxH.js} +1 -1
- package/dist/assets/{swimlanes-SLNWSIFB-CZgIPz6I.js → swimlanes-SLNWSIFB-DCwz8-mf.js} +2 -2
- package/dist/assets/{swimlanes-SLNWSIFB-B16H-6OU.js → swimlanes-SLNWSIFB-M9Oumwnl.js} +2 -2
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CTtTyW6-.js +8 -0
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-Caohx6WZ.js +8 -0
- package/dist/assets/{timeline-definition-Z64GVDOM-7r7OVlrT.js → timeline-definition-Z64GVDOM-BVmfjoWH.js} +1 -1
- package/dist/assets/{timeline-definition-Z64GVDOM-nhnkS_wy.js → timeline-definition-Z64GVDOM-DyXvto1l.js} +1 -1
- package/dist/assets/{vennDiagram-T6HMQDX7-B1piFYrz.js → vennDiagram-T6HMQDX7-CNe6zorb.js} +1 -1
- package/dist/assets/{vennDiagram-T6HMQDX7-x8SJTFhK.js → vennDiagram-T6HMQDX7-DyzOWKx3.js} +1 -1
- package/dist/assets/{wardleyDiagram-T6FBY63Y-BdD4GExj.js → wardleyDiagram-T6FBY63Y-D5YvMVwa.js} +1 -1
- package/dist/assets/{wardleyDiagram-T6FBY63Y-C90xqNVS.js → wardleyDiagram-T6FBY63Y-DXo8BCrA.js} +1 -1
- package/dist/assets/{xychartDiagram-ELKLHX3M--Ndoz0Cq.js → xychartDiagram-ELKLHX3M-CIBffVxC.js} +1 -1
- package/dist/assets/{xychartDiagram-ELKLHX3M-BAKns-7o.js → xychartDiagram-ELKLHX3M-XlsWelDb.js} +1 -1
- package/dist/build-info.json +2 -2
- package/dist/convert-icons.md +10 -46
- package/dist/favicon.png +0 -0
- package/dist/favicon.svg +1 -9
- package/dist/generate-icons.js +67 -47
- package/dist/icons/icon-128x128.png +0 -0
- package/dist/icons/icon-144x144.png +0 -0
- package/dist/icons/icon-152x152.png +0 -0
- package/dist/icons/icon-192x192.png +0 -0
- package/dist/icons/icon-384x384.png +0 -0
- package/dist/icons/icon-512x512.png +0 -0
- package/dist/icons/icon-72x72.png +0 -0
- package/dist/icons/icon-96x96.png +0 -0
- package/dist/index.html +2 -2
- package/dist/logo-128.png +0 -0
- package/dist/logo-256.png +0 -0
- package/dist/logo-32.png +0 -0
- package/dist/logo-512.png +0 -0
- package/dist/logo-64.png +0 -0
- package/dist/logo-source.png +0 -0
- package/dist/logo.svg +1 -17
- package/dist/sw.js +7 -9
- package/dist-server/build-info.json +2 -2
- package/dist-server/server/load-env.js +12 -4
- package/dist-server/server/load-env.js.map +1 -1
- package/dist-server/server/modules/browser-use/browser-use.service.js +33 -11
- package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -1
- package/dist-server/server/modules/browser-use/index.js +4 -4
- package/dist-server/server/modules/browser-use/index.js.map +1 -1
- package/dist-server/server/modules/browser-use/mcp-server-names.js +6 -4
- package/dist-server/server/modules/browser-use/mcp-server-names.js.map +1 -1
- package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js +49 -1
- package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js.map +1 -1
- package/dist-server/server/modules/cli/asset-migration-files.js +74 -0
- package/dist-server/server/modules/cli/asset-migration-files.js.map +1 -0
- package/dist-server/server/modules/cli/asset-migration-report.js +80 -0
- package/dist-server/server/modules/cli/asset-migration-report.js.map +1 -0
- package/dist-server/server/modules/cli/asset-migration-store.js +153 -0
- package/dist-server/server/modules/cli/asset-migration-store.js.map +1 -0
- package/dist-server/server/modules/cli/asset-migration.service.js +161 -0
- package/dist-server/server/modules/cli/asset-migration.service.js.map +1 -0
- package/dist-server/server/modules/cli/browser-use-mcp.js +9 -4
- package/dist-server/server/modules/cli/browser-use-mcp.js.map +1 -1
- package/dist-server/server/modules/cli/cli.module.js +21 -1
- package/dist-server/server/modules/cli/cli.module.js.map +1 -1
- package/dist-server/server/modules/cli/cli.service.js +6 -1
- package/dist-server/server/modules/cli/cli.service.js.map +1 -1
- package/dist-server/server/modules/cli/tests/asset-migration.service.test.js +275 -0
- package/dist-server/server/modules/cli/tests/asset-migration.service.test.js.map +1 -0
- package/dist-server/server/modules/cli/tests/browser-use-mcp-entry.test.js +157 -0
- package/dist-server/server/modules/cli/tests/browser-use-mcp-entry.test.js.map +1 -1
- package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +1 -0
- package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js.map +1 -1
- package/dist-server/server/modules/cli/tests/cli.service.test.js +6 -1
- package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit-brief-prompt.js +1 -1
- package/dist-server/server/modules/cockpit/cockpit-card-actions.js +19 -3
- package/dist-server/server/modules/cockpit/cockpit-card-actions.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit-card-feedback-store.js +94 -9
- package/dist-server/server/modules/cockpit/cockpit-card-feedback-store.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit-card-registry.js +1 -1
- package/dist-server/server/modules/cockpit/cockpit-fleet-card-projection.js +3 -0
- package/dist-server/server/modules/cockpit/cockpit-fleet-card-projection.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit-knowledge-reading.js +16 -0
- package/dist-server/server/modules/cockpit/cockpit-knowledge-reading.js.map +1 -1
- package/dist-server/server/modules/cockpit/cockpit.module.js +1 -1
- package/dist-server/server/modules/cockpit/tests/cockpit-card-feedback.test.js +96 -1
- package/dist-server/server/modules/cockpit/tests/cockpit-card-feedback.test.js.map +1 -1
- package/dist-server/server/modules/cockpit/tests/cockpit-fleet-card-provider.test.js +2 -2
- package/dist-server/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.js +169 -3
- package/dist-server/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.js.map +1 -1
- package/dist-server/server/modules/context-events/context-event-writer.js +5 -5
- package/dist-server/server/modules/context-events/context-events.module.js +2 -2
- package/dist-server/server/modules/context-events/session-ask-stream-reader.js +1 -1
- package/dist-server/server/modules/context-events/session-blocked-events.js +3 -3
- package/dist-server/server/modules/context-events/tests/session-ask-event-writer.test.js +1 -1
- package/dist-server/server/modules/context-events/tests/session-blocked-events.test.js +3 -3
- package/dist-server/server/modules/context-events/tests/session-run-events.test.js +1 -1
- package/dist-server/server/modules/database/migrations.js +23 -1
- package/dist-server/server/modules/database/migrations.js.map +1 -1
- package/dist-server/server/modules/database/repositories/sessions.db.js +25 -4
- package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -1
- package/dist-server/server/modules/database/repositories/voice-user-identifiers.db.js +1 -1
- package/dist-server/server/modules/database/schema.js +16 -2
- package/dist-server/server/modules/database/schema.js.map +1 -1
- package/dist-server/server/modules/database/tests/migrations-ensure-columns.test.js +2 -0
- package/dist-server/server/modules/database/tests/migrations-ensure-columns.test.js.map +1 -1
- package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +2 -2
- package/dist-server/server/modules/debug-agent/tests/debug-agent-permission-popup.test.js +2 -2
- package/dist-server/server/modules/liaison/liaison-deliver.service.js +3 -3
- package/dist-server/server/modules/liaison/liaison.module.js +1 -1
- package/dist-server/server/modules/mcp-gateway/mcp-gateway.auth.js +3 -2
- package/dist-server/server/modules/mcp-gateway/mcp-gateway.auth.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/mcp-self-target.js +2 -2
- package/dist-server/server/modules/mcp-gateway/mcp-session-send.js +7 -0
- package/dist-server/server/modules/mcp-gateway/mcp-session-send.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/mcp-tool-annotations.js +4 -4
- package/dist-server/server/modules/mcp-gateway/oauth-metadata.gate.js +4 -2
- package/dist-server/server/modules/mcp-gateway/oauth-metadata.gate.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/knowledge-effective-config-proof.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/knowledge-peer-correlation-proof.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-approvals.test.js +3 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-approvals.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-audit-route.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-audit.test.js +4 -4
- package/dist-server/server/modules/mcp-gateway/tests/mcp-auth.test.js +3 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-auth.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.js +3 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.js +7 -3
- package/dist-server/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-correlation-id.test.js +8 -8
- package/dist-server/server/modules/mcp-gateway/tests/mcp-draft.test.js +3 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-draft.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-english-only.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-gateway-wiring.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-knowledge-facts.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.js +3 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-overview.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-pending-interaction.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-read-tools.test.js +3 -3
- package/dist-server/server/modules/mcp-gateway/tests/mcp-read-tools.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-run-get.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-self-target.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-self-target.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-background.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-background.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-host-control.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-host-control.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-search-pruning.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-search.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-send.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-session-send.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-ui-last-opened.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-usage-stats.test.js +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-usage-stats.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/mcp-write-notification.test.js +2 -2
- package/dist-server/server/modules/mcp-gateway/tests/mcp-write-notification.test.js.map +1 -1
- package/dist-server/server/modules/mcp-gateway/tests/oauth-flow.e2e.test.js +3 -3
- package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +1 -1
- package/dist-server/server/modules/oauth/access-tokens.service.js +8 -8
- package/dist-server/server/modules/oauth/oauth-consent.service.js +20 -15
- package/dist-server/server/modules/oauth/oauth-consent.service.js.map +1 -1
- package/dist-server/server/modules/oauth/tests/access-token-scopes.test.js +54 -34
- package/dist-server/server/modules/oauth/tests/access-token-scopes.test.js.map +1 -1
- package/dist-server/server/modules/oauth/tests/access-tokens.service.test.js +35 -14
- package/dist-server/server/modules/oauth/tests/access-tokens.service.test.js.map +1 -1
- package/dist-server/server/modules/oauth/tests/oauth-consent-page.test.js +27 -22
- package/dist-server/server/modules/oauth/tests/oauth-consent-page.test.js.map +1 -1
- package/dist-server/server/modules/oauth/tests/oauth-consent-ratelimit.test.js +2 -2
- package/dist-server/server/modules/oauth/tests/token-info.routes.test.js +2 -2
- package/dist-server/server/modules/oauth/tests/token-info.routes.test.js.map +1 -1
- package/dist-server/server/modules/observation/blind-spots.js +1 -1
- package/dist-server/server/modules/observation/observation-store.js +50 -17
- package/dist-server/server/modules/observation/observation-store.js.map +1 -1
- package/dist-server/server/modules/observation/observation-uri.js +31 -19
- package/dist-server/server/modules/observation/observation-uri.js.map +1 -1
- package/dist-server/server/modules/observation/observation.routes.js +1 -1
- package/dist-server/server/modules/observation/project-truth.js +1 -1
- package/dist-server/server/modules/observation/session-ask-decision-answer.js +2 -1
- package/dist-server/server/modules/observation/session-ask-decision-answer.js.map +1 -1
- package/dist-server/server/modules/observation/session-digest-llm.js +7 -1
- package/dist-server/server/modules/observation/session-digest-llm.js.map +1 -1
- package/dist-server/server/modules/observation/session-digest.js +39 -5
- package/dist-server/server/modules/observation/session-digest.js.map +1 -1
- package/dist-server/server/modules/observation/tests/architecture-delta.test.js +1 -1
- package/dist-server/server/modules/observation/tests/observation-routes.test.js +9 -0
- package/dist-server/server/modules/observation/tests/observation-routes.test.js.map +1 -1
- package/dist-server/server/modules/observation/tests/observation-store.test.js +38 -0
- package/dist-server/server/modules/observation/tests/observation-store.test.js.map +1 -1
- package/dist-server/server/modules/observation/tests/project-truth.test.js +2 -2
- package/dist-server/server/modules/observation/tests/session-ask-decision-digest.test.js +150 -0
- package/dist-server/server/modules/observation/tests/session-ask-decision-digest.test.js.map +1 -1
- package/dist-server/server/modules/observation/tests/session-digest.test.js +24 -1
- package/dist-server/server/modules/observation/tests/session-digest.test.js.map +1 -1
- package/dist-server/server/modules/providers/index.js +9 -0
- package/dist-server/server/modules/providers/index.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-host-driver.provider.js +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +22 -3
- package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-app-server.connection.js +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-host-driver.contract.js +11 -9
- package/dist-server/server/modules/providers/list/codex/codex-host-driver.contract.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-host-driver.provider.js +15 -1
- package/dist-server/server/modules/providers/list/codex/codex-host-driver.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +14 -3
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-provider-injection.js +248 -0
- package/dist-server/server/modules/providers/list/codex/codex-provider-injection.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-resident-provider-launch.js +37 -0
- package/dist-server/server/modules/providers/list/codex/codex-resident-provider-launch.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js +19 -1
- package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +23 -2
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-models.service.js +136 -106
- package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-runtime.service.js +3 -0
- package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/session-model-resolver.js +106 -0
- package/dist-server/server/modules/providers/services/session-model-resolver.js.map +1 -0
- package/dist-server/server/modules/providers/services/session-provider-binding.js +89 -0
- package/dist-server/server/modules/providers/services/session-provider-binding.js.map +1 -0
- package/dist-server/server/modules/providers/services/sessions.service.js +5 -1
- package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -1
- package/dist-server/server/modules/providers/tests/claude-resident-addressable.test.js +2 -2
- package/dist-server/server/modules/providers/tests/claude-session-name-authority.test.js +4 -4
- package/dist-server/server/modules/providers/tests/codex-app-server-protocol.test.js +1 -1
- package/dist-server/server/modules/providers/tests/codex-host-driver-persistent.test.js +2 -2
- package/dist-server/server/modules/providers/tests/codex-provider-model-binding.test.js +270 -0
- package/dist-server/server/modules/providers/tests/codex-provider-model-binding.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-resident-provider-injection.test.js +484 -0
- package/dist-server/server/modules/providers/tests/codex-resident-provider-injection.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-runtime-provider-injection.test.js +228 -0
- package/dist-server/server/modules/providers/tests/codex-runtime-provider-injection.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-session-provider-binding.test.js +306 -0
- package/dist-server/server/modules/providers/tests/codex-session-provider-binding.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/codex-sessions.test.js +1 -1
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +2 -2
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js +15 -0
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/provider.routes.test.js +1 -1
- package/dist-server/server/modules/quay/index.js +1 -1
- package/dist-server/server/modules/quay/quay-fleet-cli.js +1 -1
- package/dist-server/server/modules/quay/quay-fleet-locator.js +2 -2
- package/dist-server/server/modules/quay/quay-fleet-project-id.js +7 -7
- package/dist-server/server/modules/quay/quay-fleet-registry.js +3 -3
- package/dist-server/server/modules/quay/quay-suite-fanin-reader.js +1 -1
- package/dist-server/server/modules/quay/quay-uri-resolve.js +6 -6
- package/dist-server/server/modules/quay/quay.module.js +3 -3
- package/dist-server/server/modules/quay/quay.routes.js +1 -1
- package/dist-server/server/modules/quay/quay.service.js +4 -4
- package/dist-server/server/modules/quay/tests/contracts/fleet-cli-contracts.test.js +3 -3
- package/dist-server/server/modules/quay/tests/contracts/shapes.js +9 -9
- package/dist-server/server/modules/quay/tests/quay-fleet-locator.test.js +1 -1
- package/dist-server/server/modules/quay/tests/quay-fleet-project-id.test.js +4 -4
- package/dist-server/server/modules/quay/tests/quay-uri-resolve.test.js +10 -10
- package/dist-server/server/modules/session-hosts/tests/resident-server-restart.test.js +1 -1
- package/dist-server/server/modules/settings/codex-mcp-gateway.settings.js +1 -1
- package/dist-server/server/modules/settings/codex-model-providers.schema.js +349 -0
- package/dist-server/server/modules/settings/codex-model-providers.schema.js.map +1 -0
- package/dist-server/server/modules/settings/codex-model-providers.service.js +199 -0
- package/dist-server/server/modules/settings/codex-model-providers.service.js.map +1 -0
- package/dist-server/server/modules/settings/codex-model-providers.settings.js +547 -0
- package/dist-server/server/modules/settings/codex-model-providers.settings.js.map +1 -0
- package/dist-server/server/modules/settings/codex-model-providers.store.js +200 -0
- package/dist-server/server/modules/settings/codex-model-providers.store.js.map +1 -0
- package/dist-server/server/modules/settings/index.js +10 -0
- package/dist-server/server/modules/settings/index.js.map +1 -1
- package/dist-server/server/modules/settings/server-settings-file.js +28 -32
- package/dist-server/server/modules/settings/server-settings-file.js.map +1 -1
- package/dist-server/server/modules/settings/server-settings.js +2 -2
- package/dist-server/server/modules/settings/server-settings.js.map +1 -1
- package/dist-server/server/modules/settings/settings.module.js +35 -0
- package/dist-server/server/modules/settings/settings.module.js.map +1 -1
- package/dist-server/server/modules/settings/settings.routes.js +42 -0
- package/dist-server/server/modules/settings/settings.routes.js.map +1 -1
- package/dist-server/server/modules/settings/settings.service.js +8 -21
- package/dist-server/server/modules/settings/settings.service.js.map +1 -1
- package/dist-server/server/modules/settings/tests/cockpit-session-start-settings.routes.test.js +1 -0
- package/dist-server/server/modules/settings/tests/cockpit-session-start-settings.routes.test.js.map +1 -1
- package/dist-server/server/modules/settings/tests/codex-model-providers-settings.test.js +336 -0
- package/dist-server/server/modules/settings/tests/codex-model-providers-settings.test.js.map +1 -0
- package/dist-server/server/modules/settings/tests/codex-provider-advanced.test.js +466 -0
- package/dist-server/server/modules/settings/tests/codex-provider-advanced.test.js.map +1 -0
- package/dist-server/server/modules/settings/tests/codex-provider-import.test.js +475 -0
- package/dist-server/server/modules/settings/tests/codex-provider-import.test.js.map +1 -0
- package/dist-server/server/modules/voice/tests/voice-lexicon.test.js +9 -9
- package/dist-server/server/modules/voice/tests/voice-lexicon.test.js.map +1 -1
- package/dist-server/server/modules/voice/voice-lexicon.js +1 -1
- package/dist-server/server/modules/websocket/services/chat-control.service.js +21 -1
- package/dist-server/server/modules/websocket/services/chat-control.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js +25 -1
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/chat-background-task.test.js +18 -1
- package/dist-server/server/modules/websocket/tests/chat-background-task.test.js.map +1 -1
- package/dist-server/server/modules/websocket/tests/chat-stop-task.test.js +18 -1
- package/dist-server/server/modules/websocket/tests/chat-stop-task.test.js.map +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-list.service.js +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-open.service.js +1 -1
- package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +1 -1
- package/dist-server/server/shared/brand.js +18 -20
- package/dist-server/server/shared/brand.js.map +1 -1
- package/dist-server/server/shared/data-root-migration.js +3 -2
- package/dist-server/server/shared/data-root-migration.js.map +1 -1
- package/dist-server/server/shared/data-root.js +54 -59
- package/dist-server/server/shared/data-root.js.map +1 -1
- package/dist-server/server/shared/mcp-contract/types.js +20 -15
- package/dist-server/server/shared/mcp-contract/types.js.map +1 -1
- package/dist-server/server/shared/ports/codex-provider-registry.port.js +66 -0
- package/dist-server/server/shared/ports/codex-provider-registry.port.js.map +1 -0
- package/dist-server/server/shared/settings-file.js +120 -6
- package/dist-server/server/shared/settings-file.js.map +1 -1
- package/dist-server/server/shared/tests/cloudpit-brand-env.test.js +76 -34
- package/dist-server/server/shared/tests/cloudpit-brand-env.test.js.map +1 -1
- package/dist-server/server/shared/tests/cloudpit-data-root.test.js +35 -18
- package/dist-server/server/shared/tests/cloudpit-data-root.test.js.map +1 -1
- package/dist-server/server/shared/tests/cloudpit-goal-exit-gate.test.js +153 -17
- package/dist-server/server/shared/tests/cloudpit-goal-exit-gate.test.js.map +1 -1
- package/dist-server/server/shared/tests/cloudpit-runtime-flip.test.js +116 -114
- package/dist-server/server/shared/tests/cloudpit-runtime-flip.test.js.map +1 -1
- package/dist-server/server/shared/tests/frontend-import-cycle-budget.test.js +9 -1
- package/dist-server/server/shared/tests/frontend-import-cycle-budget.test.js.map +1 -1
- package/dist-server/server/shared/tests/quay-test-script.test.js +40 -6
- package/dist-server/server/shared/tests/quay-test-script.test.js.map +1 -1
- package/dist-server/server/shared/tests/settings-file.test.js +58 -2
- package/dist-server/server/shared/tests/settings-file.test.js.map +1 -1
- package/dist-server/server/shared/types.js.map +1 -1
- package/dist-server/server/shared/utils.js +1 -1
- package/electron/appIdMigration.js +467 -0
- package/electron/assets/logo-macos.icns +0 -0
- package/electron/assets/logo-macos.png +0 -0
- package/electron/assets/logo-windows.ico +0 -0
- package/electron/brandEnv.js +64 -0
- package/electron/cloud.js +3 -3
- package/electron/desktopNotifications.js +1 -1
- package/electron/launcher/index.html +1 -1
- package/electron/localServer.js +41 -7
- package/electron/main.js +33 -15
- package/electron/scripts/generate-macos-icon.js +34 -28
- package/electron/scripts/generate-windows-icon.js +66 -0
- package/electron/serverInstaller.js +20 -11
- package/electron/tests/cloudpit-appid-migration.test.mjs +514 -0
- package/electron/tests/cloudpit-brand-env-wiring.test.mjs +324 -0
- package/electron/tests/cloudpit-desktop-identity.test.mjs +42 -19
- package/electron/tests/cloudpit-runtime-identity-surfaces.test.mjs +10 -4
- package/electron/tests/cloudpit-userdata-migration.test.mjs +18 -5
- package/electron/userDataMigration.js +3 -0
- package/package.json +7 -6
- package/public/api-docs.html +3 -3
- package/scripts/brand-allowlist-check.mjs +233 -12
- package/scripts/brand-allowlist-check.test.mjs +270 -1
- package/scripts/cloudpit-distribution-check.mjs +57 -23
- package/scripts/cloudpit-distribution-check.test.mjs +42 -9
- package/scripts/codex-protocol-smoke.mjs +1 -1
- package/scripts/isolated-instance.sh +1 -1
- package/scripts/mcp-smoke.mjs +2 -2
- package/scripts/release/tests/fork-release-workflows.test.mjs +45 -0
- package/scripts/release/tests/server-installer-bundle-url.test.mjs +57 -9
- package/scripts/restart-when-idle.sh +1 -1
- package/scripts/shadow-prediction-report.mjs +1 -1
- package/scripts/suite-duration-baseline.tsv +45 -0
- package/scripts/ui-scenario.mjs +195 -0
- package/scripts/ui-scenarios/codex-provider-import.json +63 -0
- package/scripts/ui-scenarios/codex-provider-settings.json +77 -0
- package/scripts/voice-capture-process-check.false-forms.test.mjs +1 -1
- package/scripts/voice-phase0-report.test.mjs +1 -1
- package/server/load-env.ts +15 -4
- package/server/modules/browser-use/browser-use.service.ts +45 -14
- package/server/modules/browser-use/index.ts +3 -4
- package/server/modules/browser-use/mcp-server-names.ts +6 -5
- package/server/modules/browser-use/tests/browser-use.service.test.ts +63 -1
- package/server/modules/cli/asset-migration-files.ts +96 -0
- package/server/modules/cli/asset-migration-report.ts +123 -0
- package/server/modules/cli/asset-migration-store.ts +228 -0
- package/server/modules/cli/asset-migration.service.ts +236 -0
- package/server/modules/cli/browser-use-mcp.ts +9 -4
- package/server/modules/cli/cli.module.ts +21 -1
- package/server/modules/cli/cli.service.ts +14 -1
- package/server/modules/cli/tests/asset-migration.service.test.ts +349 -0
- package/server/modules/cli/tests/browser-use-mcp-entry.test.ts +202 -0
- package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +1 -0
- package/server/modules/cli/tests/cli.service.test.ts +6 -1
- package/server/modules/cockpit/cockpit-brief-prompt.ts +1 -1
- package/server/modules/cockpit/cockpit-card-actions.ts +20 -3
- package/server/modules/cockpit/cockpit-card-feedback-store.ts +104 -9
- package/server/modules/cockpit/cockpit-card-registry.ts +2 -2
- package/server/modules/cockpit/cockpit-fleet-card-projection.ts +3 -0
- package/server/modules/cockpit/cockpit-fleet-executor.ts +1 -1
- package/server/modules/cockpit/cockpit-knowledge-reading.ts +17 -0
- package/server/modules/cockpit/cockpit.module.ts +2 -2
- package/server/modules/cockpit/cockpit.reducer.ts +1 -1
- package/server/modules/cockpit/tests/cockpit-card-feedback.test.ts +116 -1
- package/server/modules/cockpit/tests/cockpit-fleet-card-provider.test.ts +2 -2
- package/server/modules/cockpit/tests/cockpit-knowledge-decision-handoff.test.ts +205 -3
- package/server/modules/context-events/context-event-writer.ts +6 -6
- package/server/modules/context-events/context-events.module.ts +2 -2
- package/server/modules/context-events/session-ask-stream-reader.ts +1 -1
- package/server/modules/context-events/session-blocked-events.ts +3 -3
- package/server/modules/context-events/tests/session-ask-event-writer.test.ts +1 -1
- package/server/modules/context-events/tests/session-blocked-events.test.ts +3 -3
- package/server/modules/context-events/tests/session-run-events.test.ts +1 -1
- package/server/modules/database/migrations.ts +24 -1
- package/server/modules/database/repositories/sessions.db.ts +41 -4
- package/server/modules/database/repositories/voice-user-identifiers.db.ts +1 -1
- package/server/modules/database/schema.ts +16 -2
- package/server/modules/database/tests/migrations-ensure-columns.test.ts +2 -0
- package/server/modules/database/tests/sessions-provider-mapping.test.ts +2 -2
- package/server/modules/debug-agent/tests/debug-agent-permission-popup.test.ts +2 -2
- package/server/modules/liaison/liaison-deliver.service.ts +4 -4
- package/server/modules/liaison/liaison.module.ts +1 -1
- package/server/modules/mcp-gateway/mcp-gateway.auth.ts +3 -2
- package/server/modules/mcp-gateway/mcp-self-target.ts +2 -2
- package/server/modules/mcp-gateway/mcp-session-send.ts +21 -2
- package/server/modules/mcp-gateway/mcp-tool-annotations.ts +4 -4
- package/server/modules/mcp-gateway/oauth-metadata.gate.ts +4 -5
- package/server/modules/mcp-gateway/tests/knowledge-effective-config-proof.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/knowledge-peer-correlation-proof.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-approvals.test.ts +3 -2
- package/server/modules/mcp-gateway/tests/mcp-audit-route.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-audit.test.ts +4 -4
- package/server/modules/mcp-gateway/tests/mcp-auth.test.ts +3 -1
- package/server/modules/mcp-gateway/tests/mcp-cancel-queued.test.ts +3 -2
- package/server/modules/mcp-gateway/tests/mcp-cockpit-tools.test.ts +7 -3
- package/server/modules/mcp-gateway/tests/mcp-correlation-id.test.ts +8 -8
- package/server/modules/mcp-gateway/tests/mcp-draft.test.ts +3 -2
- package/server/modules/mcp-gateway/tests/mcp-english-only.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-gateway-wiring.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-insufficient-scope.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-knowledge-facts.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-not-found-semantics.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-oauth-challenge.test.ts +3 -2
- package/server/modules/mcp-gateway/tests/mcp-overview.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-pending-interaction.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-read-tools.test.ts +3 -3
- package/server/modules/mcp-gateway/tests/mcp-run-get.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-self-target.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-background.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-session-host-control.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-lifecycle.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-reconfigure.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-session-search-pruning.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-search.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-session-send.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/mcp-ui-last-opened.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-usage-stats.test.ts +1 -1
- package/server/modules/mcp-gateway/tests/mcp-write-notification.test.ts +2 -2
- package/server/modules/mcp-gateway/tests/oauth-flow.e2e.test.ts +3 -3
- package/server/modules/notifications/services/notification-orchestrator.service.js +1 -1
- package/server/modules/oauth/access-tokens.service.ts +8 -8
- package/server/modules/oauth/oauth-consent.service.ts +20 -15
- package/server/modules/oauth/tests/access-token-scopes.test.ts +55 -34
- package/server/modules/oauth/tests/access-tokens.service.test.ts +50 -14
- package/server/modules/oauth/tests/oauth-consent-page.test.ts +29 -21
- package/server/modules/oauth/tests/oauth-consent-ratelimit.test.ts +2 -2
- package/server/modules/oauth/tests/token-info.routes.test.ts +2 -2
- package/server/modules/observation/architecture-delta.producer.ts +1 -1
- package/server/modules/observation/blind-spots.ts +1 -1
- package/server/modules/observation/observation-store.ts +54 -16
- package/server/modules/observation/observation-uri.ts +34 -21
- package/server/modules/observation/observation.routes.ts +1 -1
- package/server/modules/observation/project-truth.ts +3 -3
- package/server/modules/observation/session-ask-decision-answer.ts +2 -1
- package/server/modules/observation/session-digest-llm.ts +7 -1
- package/server/modules/observation/session-digest.ts +39 -5
- package/server/modules/observation/tests/architecture-delta.test.ts +1 -1
- package/server/modules/observation/tests/observation-routes.test.ts +13 -0
- package/server/modules/observation/tests/observation-store.test.ts +58 -0
- package/server/modules/observation/tests/project-truth.test.ts +2 -2
- package/server/modules/observation/tests/session-ask-decision-digest.test.ts +189 -0
- package/server/modules/observation/tests/session-digest.test.ts +43 -0
- package/server/modules/providers/index.ts +13 -0
- package/server/modules/providers/list/claude/claude-host-driver.provider.ts +1 -1
- package/server/modules/providers/list/codex/codex-app-server.client.ts +37 -5
- package/server/modules/providers/list/codex/codex-app-server.connection.ts +1 -1
- package/server/modules/providers/list/codex/codex-host-driver.contract.ts +18 -9
- package/server/modules/providers/list/codex/codex-host-driver.provider.ts +15 -1
- package/server/modules/providers/list/codex/codex-models.provider.ts +16 -3
- package/server/modules/providers/list/codex/codex-provider-injection.ts +323 -0
- package/server/modules/providers/list/codex/codex-resident-provider-launch.ts +71 -0
- package/server/modules/providers/list/codex/codex-runtime.provider.ts +20 -1
- package/server/modules/providers/list/cursor/cursor-models.provider.ts +1 -1
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +1 -1
- package/server/modules/providers/provider.routes.ts +23 -2
- package/server/modules/providers/services/provider-models.service.ts +187 -124
- package/server/modules/providers/services/provider-runtime.service.ts +3 -0
- package/server/modules/providers/services/session-model-resolver.ts +180 -0
- package/server/modules/providers/services/session-provider-binding.ts +176 -0
- package/server/modules/providers/services/sessions.service.ts +5 -1
- package/server/modules/providers/tests/claude-resident-addressable.test.ts +2 -2
- package/server/modules/providers/tests/claude-session-name-authority.test.ts +4 -4
- package/server/modules/providers/tests/codex-app-server-protocol.test.ts +1 -1
- package/server/modules/providers/tests/codex-host-driver-persistent.test.ts +2 -2
- package/server/modules/providers/tests/codex-provider-model-binding.test.ts +345 -0
- package/server/modules/providers/tests/codex-resident-provider-injection.test.ts +561 -0
- package/server/modules/providers/tests/codex-runtime-provider-injection.test.ts +269 -0
- package/server/modules/providers/tests/codex-session-provider-binding.test.ts +386 -0
- package/server/modules/providers/tests/codex-sessions.test.ts +1 -1
- package/server/modules/providers/tests/opencode-sessions.test.ts +2 -2
- package/server/modules/providers/tests/provider-models.service.test.ts +15 -0
- package/server/modules/providers/tests/provider.routes.test.ts +1 -1
- package/server/modules/quay/index.ts +1 -1
- package/server/modules/quay/quay-dispatch-carrier.ts +1 -1
- package/server/modules/quay/quay-fleet-cli.ts +1 -1
- package/server/modules/quay/quay-fleet-locator.ts +2 -2
- package/server/modules/quay/quay-fleet-project-id.ts +14 -14
- package/server/modules/quay/quay-fleet-registry.ts +8 -8
- package/server/modules/quay/quay-suite-fanin-reader.ts +1 -1
- package/server/modules/quay/quay-uri-resolve.ts +8 -8
- package/server/modules/quay/quay.module.ts +3 -3
- package/server/modules/quay/quay.routes.ts +1 -1
- package/server/modules/quay/quay.service.ts +6 -6
- package/server/modules/quay/session-task-chain.service.ts +1 -1
- package/server/modules/quay/tests/contracts/fleet-cli-contracts.test.ts +3 -3
- package/server/modules/quay/tests/contracts/shapes.ts +10 -10
- package/server/modules/quay/tests/quay-fleet-locator.test.ts +1 -1
- package/server/modules/quay/tests/quay-fleet-project-id.test.ts +6 -6
- package/server/modules/quay/tests/quay-uri-resolve.test.ts +10 -10
- package/server/modules/session-hosts/tests/resident-server-restart.test.ts +1 -1
- package/server/modules/settings/codex-mcp-gateway.settings.ts +1 -1
- package/server/modules/settings/codex-model-providers.schema.ts +460 -0
- package/server/modules/settings/codex-model-providers.service.ts +235 -0
- package/server/modules/settings/codex-model-providers.settings.ts +713 -0
- package/server/modules/settings/codex-model-providers.store.ts +244 -0
- package/server/modules/settings/index.ts +18 -0
- package/server/modules/settings/server-settings-file.ts +29 -41
- package/server/modules/settings/server-settings.ts +2 -3
- package/server/modules/settings/settings.module.ts +41 -0
- package/server/modules/settings/settings.routes.ts +37 -0
- package/server/modules/settings/settings.service.ts +21 -26
- package/server/modules/settings/tests/cockpit-session-start-settings.routes.test.ts +1 -0
- package/server/modules/settings/tests/codex-model-providers-settings.test.ts +413 -0
- package/server/modules/settings/tests/codex-provider-advanced.test.ts +540 -0
- package/server/modules/settings/tests/codex-provider-import.test.ts +621 -0
- package/server/modules/voice/tests/voice-lexicon.test.ts +10 -10
- package/server/modules/voice/voice-lexicon.ts +1 -1
- package/server/modules/websocket/services/chat-control.service.ts +35 -2
- package/server/modules/websocket/services/chat-websocket.service.ts +25 -1
- package/server/modules/websocket/tests/chat-background-task.test.ts +17 -1
- package/server/modules/websocket/tests/chat-stop-task.test.ts +17 -1
- package/server/modules/worktrees/services/worktree-list.service.ts +1 -1
- package/server/modules/worktrees/services/worktree-open.service.ts +1 -1
- package/server/modules/worktrees/services/worktree-remove.service.ts +1 -1
- package/server/shared/brand.ts +24 -38
- package/server/shared/data-root-migration.ts +3 -2
- package/server/shared/data-root.ts +73 -79
- package/server/shared/interfaces.ts +1 -1
- package/server/shared/mcp-contract/types.ts +20 -15
- package/server/shared/ports/codex-provider-registry.port.ts +133 -0
- package/server/shared/ports/session-blocked-events.port.ts +1 -1
- package/server/shared/ports/session-run-events.port.ts +2 -2
- package/server/shared/settings-file.ts +167 -6
- package/server/shared/tests/architecture-ratchet.baseline.json +15 -15
- package/server/shared/tests/cloudpit-brand-env.test.ts +106 -36
- package/server/shared/tests/cloudpit-data-root.test.ts +42 -18
- package/server/shared/tests/cloudpit-goal-exit-gate.baseline.json +6 -2
- package/server/shared/tests/cloudpit-goal-exit-gate.test.ts +179 -17
- package/server/shared/tests/cloudpit-runtime-flip.test.ts +162 -123
- package/server/shared/tests/frontend-import-cycle-budget.baseline.json +8 -6
- package/server/shared/tests/frontend-import-cycle-budget.test.ts +9 -1
- package/server/shared/tests/quay-test-script.test.ts +40 -6
- package/server/shared/tests/settings-file.test.ts +83 -1
- package/server/shared/types.ts +121 -8
- package/server/shared/utils.ts +1 -1
- package/dist/assets/channel-D7XqNTJC.js +0 -1
- package/dist/assets/channel-sbQyI1an.js +0 -1
- package/dist/assets/classDiagram-JCYQIIEL-DHudi-zH.js +0 -1
- package/dist/assets/classDiagram-JCYQIIEL-DV7ybJJG.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-DHudi-zH.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-DV7ybJJG.js +0 -1
- package/dist/assets/index-BsACp0s2.css +0 -32
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CNMNp6YA.js +0 -8
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-DOjtDEUW.js +0 -8
- package/dist/icons/icon-128x128.svg +0 -12
- package/dist/icons/icon-144x144.svg +0 -12
- package/dist/icons/icon-152x152.svg +0 -12
- package/dist/icons/icon-192x192.svg +0 -12
- package/dist/icons/icon-384x384.svg +0 -12
- package/dist/icons/icon-512x512.svg +0 -12
- package/dist/icons/icon-72x72.svg +0 -12
- package/dist/icons/icon-96x96.svg +0 -12
- package/dist/icons/icon-template.svg +0 -12
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"measuredAt": "2026-10-29",
|
|
3
|
-
"note": "RATCHET: every reading in this file may only FALL. Lower a value (or remove an entry) when a refactor genuinely shrinks it; never raise one to accommodate a red. A legitimate RAISE must be recorded here in AC-394's \"RECORDED CHANGE\" format: a dated paragraph naming the file, the old→new reading and why the increase is the honest shape of the change. The criterion prints `ratchet: <dimension> <file> <baseline>→<measured>,可下调基线` whenever a reading falls; lowering the baseline is encouraged but not required, so a parallel refactor that shrinks a reading never reds this criterion. A RECORDED CHANGE (2026-10-26, census re-sync by gap-codex-transcript-format-shared-helpers): `src/modules/architecture/semanticZoomLayout.ts` 1642→1688 and `src/modules/architecture/semanticZoomPlan.ts` 876→894 are raised to their measured values on develop. Both files are byte-identical to the develop tip in the re-recording tree — the growth landed in the architecture commits up to 3f1b1ea23 AFTER the census commit f7d20cdcb captured these readings, and no commit re-recorded it, so the criterion redded a tree neither this task nor its delta touches. This is a stale-census re-sync, not an accommodation of new growth: no entry is raised above its current reading, and the two files are not part of this task's delta. A RECORDED CHANGE (2026-10-27, cockpit-card-provider-contract-and-registry): `server/index.ts` 2754→2769, `server/shared/types.ts` 4629→4749 and `src/shared/types.ts` 4123→4243. This task introduces the cockpit card contract: the two types files each gain the 120-line card wire vocabulary (both ends are hand-copied and a TypeSync criterion compares them field-for-field, so the shape exists twice by design, not by duplication), and `server/index.ts` gains the three statements that build the card module and mount its authenticated router. The increase IS the deliverable — no new module carries the types instead, because the contract is the server/client seam. The other entries in this diff only FELL (encouraged by this file's own rule). A RECORDED CHANGE (2026-10-27, observation-session-ask-decision-digest): `server/shared/types.ts` 4749→4821. This task adds the 72-line ask/decision wire vocabulary (SessionAskDecisionOption, SessionAskDecision, SessionAskDecisionReading, SessionAskEventKind, SessionAskEvent) that the transcript reader, the answer normaliser, the digest producer and the injected ISessionAskEventWriter seam all share. The backend module standard puts a type used in two or more files in `server/shared/types.ts`, and no new module carries it instead: the event envelope is the seam quay-fleet's context-event stream will consume, so it is a shared contract rather than observation-internal state. The increase IS the deliverable, recorded on the same entry the preceding cockpit card contract raised for the same reason. A RECORDED CHANGE (2026-10-27, cockpit-card-ui-core): `src/shared/api.ts` 1749→1766 and `src/modules/cockpit/CockpitPage.tsx` 1881→1883. This is the UI half of the same cockpit card contract: `src/shared/api.ts` gains the two client entry points the card view calls (`cockpitCards` = GET /api/cockpit/cards and `cockpitConfirmCard` = POST /api/cockpit/cards/confirm, each with the revision/`optionId`/`replyText` shape the server enforces) — the API client surface IS where the client seam belongs, so no new module carries them instead; `CockpitPage.tsx` gains the one `cards` arm of the header's existing view-label ternary so `/cockpit?view=cards` names itself like every other view. The card UI itself lives in new files (`cockpitCardController.ts`, `CockpitCard*.tsx`, descriptors, hook), so it does not grow any baselined file. The other entries in this diff only FELL (encouraged by this file's own rule). A RECORDED CHANGE (2026-10-27, cockpit-card-session-executors): `server/index.ts` 2769→2777, `server/shared/types.ts` 4821→4839 and `src/shared/types.ts` 4243→4261. This task adds the two built-in cockpit content executors (`session.send`, `session.start`) and the subject-derived 「自己的回复」 default. The two types files each gain the same 18-line wire vocabulary (`CockpitFixtureSubject` plus the projection-owned `ownReplyUnavailable` field). They exist twice by design: the card wire contract is hand-copied on both ends and a TypeSync criterion compares the copies field-for-field, so no new module can carry the types instead. `server/index.ts` moves the card module's construction BELOW the one chat control service its executors send through, and gains the `createCockpitCardExecutors(...)` argument, the `fixtureSubject` argument and their one import; the increase IS the wiring statement the task requires at the composition root, and the binding itself lives in the new `server/cockpit-executors-wiring.ts` so this file grows by only the composition lines. A RECORDED CHANGE (2026-10-27, cockpit-card-brief-rendering): `server/shared/types.ts` 4839→5074 and `src/shared/types.ts` 4261→4496. This task adds the 235-line brief wire vocabulary (CockpitBriefResponse, the seven preset block shapes and their nested option/evidence/axis/series/row/token/failure types) at the same group boundary on both ends. The shape exists twice by design: the brief read is the server/client seam, the client copy is hand-mirrored, and `cockpitCardTypeSync.test.ts` reads both ends field-for-field, so no new module can carry the types instead. `src/shared/api.ts` 1766→1773 gains the one `cockpitCardBrief(cardId)` entry point (GET /api/cockpit/cards/:id/brief) the Details drawer calls; the endpoint belongs on the centralized client API surface rather than in the component. The increase IS the deliverable. A RECORDED CHANGE (2026-10-27, cockpit-mobile-header-and-page): `src/modules/cockpit/cockpitCardController.ts` is a NEW `oversizeFiles` entry at 871 (it was unbaselined at 766 on develop). This task adds the card page's route memory to the controller that already owns `selectedCardId` and `anchorCardId`: the `CockpitCardMemory` seam, the normalization that turns an unreadable store into \"start at the top\", the deferred restore of the remembered selection once the card list exists, and `setScrollPosition`'s persistence. The rule — \"the person returns to the card and the scroll offset they left\" — is a list rule, and putting a second owner beside it would be a second answer; no new module carries it instead, because the seam is the controller's own dependency contract and the binding only supplies the storage. The additions are the measured 105 lines; the file was already near the 800-line limit on develop, so this is the honest shape of the change, not a reorganization for line count. A RECORDED CHANGE (2026-10-27, observation-session-ask-event-writer-wiring): `server/index.ts` 2777→2788, and `server/shared/ports/session-ask-events.port.ts` is a NEW `moduleMutableState` entry at 1. The task wires the observation layer's `session.asking`/`session.answered` to the host-level context-event writer through a new install-style port (the same shape every sibling in `server/shared/ports/` already has, which is why each of them carries exactly this one reading): the port owns the installed-writer slot, and the composition root installs the adapter. `server/index.ts` grows by the port import, the adapter import/installation and the comment that states why a v0 fleet counts the two kinds instead of throwing; no existing statement was rewritten, so the increase IS the wiring the task requires at the composition root. The other entries in this diff only FELL (encouraged by this file's own rule). A RECORDED CHANGE (2026-10-27, cockpit-fleet-card-provider): `server/index.ts` 2788→2797, `server/shared/types.ts` 5074→5081 and `src/shared/types.ts` 4496→4503. This task registers the quay-fleet card provider at the composition root and adds the one card field that names why locally-filled content is not ready. `server/index.ts` gains the import and the `providers` entry that passes `cockpit.fleetCards.enabled` and `ttlMs` into `createCockpitCardsModule`; the fleet CLI and digest bindings live in the new `server/cockpit-fleet-wiring.ts`, so this file grows only by its composition statements. The two types files each gain the same 7-line `contentUnavailable?` field on `CockpitCard` with its doc comment: the card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry the field instead. The increase IS the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-27, gap-ac425-card-viz-and-zone-coverage): `server/shared/types.ts` 5081→5112 and `src/shared/types.ts` 4503→4534. This task adds the 31-line small-visualization wire vocabulary (`CockpitCardVizKind`, the `CockpitCardViz` reading envelope, and the `viz?` field on `CockpitCard`) at the same group boundary on both ends. The shape exists twice by design: the card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field (this task adds both rows to that comparison), so no new module can carry the types instead. The increase IS the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-27, gap-voice-keyboard-shortcut-toggle): `src/modules/chat/ChatInterface.tsx` 1395→1443 and `src/modules/chat/composer/ChatComposer.tsx` 1606→1628. This task wires a configurable keyboard chord to the two voice surfaces the pane owns: `ChatInterface` holds the registered dictation toggle, derives the Live Voice toggle from `composerMode`, and mounts the shortcut hook (48 lines), while `ChatComposer` registers its own `handleVoiceToggle` with the pane on each render (22 lines). Both increases ARE the wiring: the shortcut must reach the same handlers the on-screen controls use, and a second copy of that caret/draft logic in the pane is exactly the drift the shared `handleVoiceToggle` seam exists to prevent. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-27, gap-voice-shortcut-options): `src/modules/chat/ChatInterface.tsx` 1443→1477 and `src/modules/chat/composer/ChatComposer.tsx` 1628→1633. This task extends the same shortcut feature with three bindings — send-on-stop, cross-surface cancel and clear-input. `ChatInterface` gains the four pane-level readings the controller routes on (`stopAndSendDictation`, `isDictationRecording`, `isLiveVoiceActive`, and `isClearAvailable`, which mirrors the Escape guard's own condition so the clear chord cannot become a laxer second way to dismiss a running turn or an open menu), moves the shortcut block below `handleVoiceExit` so leaving Live Voice reuses the bar's own exit path (backlog back to the composer, run keeps going) instead of the bare mode teardown, and passes the larger command bag to `useVoiceShortcuts`; `ChatComposer` registers `stopAndSend` and the live `recording` reading with the pane. Both increases ARE the wiring: every new command is a pane-level fact (composer draft, processing state, dock/menu visibility) the React-free controller cannot read itself, and the chords must reach the same handlers the on-screen controls use. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-27, gap-cockpit-live-cards-session-link-confirmability-and-titles): `server/shared/types.ts` 5112→5120 and `src/shared/types.ts` 4534→4542. This task adds the option confirmability vocabulary (`confirmable?` and `confirmableReason?` on `CockpitCardOption`) at the same group boundary on both ends. The shape exists twice by design: the card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry the fields instead. The increase IS the deliverable; no other baselined entry rises. A RECORDED CHANGE (2026-10-27, cockpit-card-anatomy-matches-mockups): `server/shared/types.ts` 5120→5144, `src/shared/types.ts` 4542→4566 and `src/modules/cockpit/cockpitCardController.ts` 871→876. This task adds the card header's two provider-stated readings on the wire — `CockpitCard.load` (the 0–3 decision weight the header's three cells draw) and `CockpitCardSubject.title` (the subject's display name) — plus the `attempts` viz reading (`CockpitCardVizOutcome`, `CockpitCardVizAttempt`, and `cap`/`items` on `CockpitCardViz`), which turns the stuck/fix dot row into a per-attempt reading. The card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field (this task adds the two new rows), so no new module can carry the types instead; the increase IS the deliverable. The controller grows by the widened `isIrreversibleOption` predicate, which now also recognises the current `irreversible` tag name beside the pre-vocabulary `warn`; the predicate already lives there and a second copy would be the drift the single rule exists to prevent. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, cockpit-shell-filters-mobile-page-and-details-bar): `src/modules/cockpit/cockpitCardController.ts` 876→1047 and `src/modules/cockpit/CockpitPage.tsx` 1883→1902. This task adds the cards page's two filters to the controller that already owns the card list, selection and scroll memory: type chips with per-type counts constrained by the project selection, a multi-select project set with per-project counts constrained by the type, and the per-device persistence seam (`rememberFilters`) that restores both across a rebuild. The filtering rule — which cards are visible, and what each chip's count is under the other filter — is one rule, so a second owner beside the controller would be a second answer; the controller's dependency contract is where the storage binding belongs, and no new module carries it instead. `CockpitPage.tsx` grows by the mobile-width reading and the three `{!phoneCards && …}` wrappers that keep the deploy strip, project strip and Focus row off the phone's cards page while leaving them on wall/fleet/board. Both increases ARE the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-quay-tests-fanin-read-via-suite-verb-and-driver-log): `server/shared/types.ts` 5144→5168, `src/shared/types.ts` 4566→4590 and `src/modules/quay/QuayPanel.tsx` 1120→1176. This task moves the Tests/Fan-in readings off the local `.quay/` carrier files and onto quay's own read verbs (`quay suite`, `quay driver log`). The two types files each gain the same 24-line `QuayCarrierReading` vocabulary and the optional `carrierReadings` field on `QuaySnapshot`: the reading is the server/client seam (the adapter produces it, the panel states it), and both ends are hand-copied shared types, so the shape exists twice by design, not by duplication. `QuayPanel.tsx` grows by the one `CarrierReadingLine` helper and the two card arms that render a non-`ok` reading instead of the empty-state text — drawing \"no records\" for a failed or unavailable read would be a false claim about the project. The increases ARE the deliverable; no new module carries the carrier state instead, because it is wire vocabulary rather than panel-local state. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-ask-cards-judge-default-suggestion): `server/shared/types.ts` 5168→5172 and `src/modules/cockpit/cockpitCardController.ts` 1047→1049. This task lets the same summarising call's judge supply the session-ask default when the assistant recommends nothing: the shared type gains the optional `why` field carrying the judge's one-line reason, which the card renders and the projection forwards, so it is wire vocabulary shared by the observation layer and the card surface (no new module can carry it instead). The controller grows only by the doc statement of the rule it already implements — a suggested option of ANY source is the default. Both increases ARE the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-ask-cards-resolve-reliably-digest-json-and-details-polish): `server/index.ts` 2797→2805, `server/modules/websocket/services/chat-control.service.ts` 1105→1114, `server/shared/types.ts` 5172→5184 and `src/shared/types.ts` 4590→4596. The ask-card polish adds one optional verbatim `assistantQuote` field to `CockpitCard` (hand-copied on both ends like the rest of the card wire vocabulary, which a TypeSync criterion compares field-for-field), one optional `quote` field to `SessionAskDecision`, the observation→send port type and its one install in the composition root, and the send-path notification (a guarded port read so observation can never change a send result). No new module can carry the wire fields or the install: the contract is the server/client seam and the composition root is where every other port is installed. The increase IS the deliverable. A RECORDED CHANGE (2026-10-28, cockpit-inline-confirm-zero-focus-jump): `src/modules/cockpit/cockpitCardController.ts` 1049→1108. This task replaces the fixed bottom dialog with an in-place confirm state, and the state machine that decides it is the controller's own: the 6 s automatic retreat armed on `requestConfirm` and cleared on every commit that leaves no card pending (the injected clock's one timer), the three new transitions (`requestConfirm`, `cancelConfirm`, and `confirm` running only from a pending state), `selectCard` clearing the pending card when the selection moves elsewhere, and `handleKey('Enter')` becoming the same key twice — open in place, then send from the same bar. The additions also carry the doc paragraphs that state these rules, because the retreat window and the 「second Enter sends」 reading are behaviour a reader must find at the state owner rather than infer from the view. The controller already owns `pendingConfirm`, `confirming` and `lastOutcome`; a second owner beside it would be a second answer to what 「pending」 means, so no new module carries the machine instead. The increase IS the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-card-situation-full-text-with-inline-expand): `src/modules/cockpit/cockpitCardController.ts` 1108→1139. This task stops the card situation from being truncated to two lines: Cards draws it in full until it runs past six lines, then keeps it behind an in-place expand control, and that expansion is a per-card reading — mapped to the card id AND the revision it was opened at, so a re-read that moves the revision drops it. The rule belongs to the controller that already owns the card list, selection and pending confirm (a re-read reconciles card state in `normalize`), so the added snapshot field, its normalization in `normalize` and the toggle command live there rather than in a second owner (31 inserted lines, 0 deleted). `src/modules/cockpit/CockpitCard.tsx` did NOT need a baseline entry: the situation block moved to the new module-private `CockpitCardSituation.tsx`, so it measured 766 lines (below the 800 floor and below its 768 on develop). The increase IS the deliverable; no other baselined entry rises. A RECORDED CHANGE (2026-10-28, gap-cockpit-ask-answered-immediate-dedup-startup-sweep-and-repair): `server/index.ts` 2805→2817 and `server/modules/websocket/services/chat-control.service.ts` 1114→1116. This task states an answered ask the moment the person sends their next message — without waiting for the transcript to carry it — and adds the boot-time sweep that settles asks a restart left unfinished. `server/index.ts` gains the composition-root call that starts the sweep once the database is open: one import, the guarded `void … .catch(...)` and the comment stating why the pass is not awaited here, placed beside the other producer start-up statements because that is the file's existing job. `chat-control.service.ts` gains the two comment lines beside its user-turn notification stating that the send path knows no transcript message id, so the sweep — not this call — settles a pending ask whose answer has not landed yet. Both increases ARE the fix, not reorganization: no new module can carry the start-up call (every producer starts in this composition root) and the comment belongs on the call it explains. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-mcp-cockpit-card-tools): `server/index.ts` 2817→2827. This task exposes the cockpit card system over the MCP gateway: the composition root now hands the one `createCockpitCardsModule` instance's `registry` / `actions` / `briefForCard` to `createMcpGatewayModule` as `cockpitTools`, beside the other dependency bags it already builds there. The ten lines are the injection itself plus the comment stating that these are the SAME three members the HTTP face reads (the DoD's 'no second reading path' clause); no other module can carry the wiring because `server/index.ts` is the only place the card module is constructed, and the alternative — the gateway importing the cockpit barrel — is the edge AC-394 registers separately. Every other entry in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-confirm-delayed-send-with-cancel): `src/modules/cockpit/cockpitCardController.ts` 1139→1329. This task replaces the two-press confirmation of reversible options with a five-second send countdown, and the state machine that owns it is the controller's own: the countdown reading (card id, revision, started at, fires at) and its two injected-clock timers, the cancel path, the `confirmingCardId` field that keeps the bar in its pending state while the request is in flight after the countdown clears, the normalization that drops a countdown whose card or revision went away, the `stop()` rule that deliberately leaves the countdown armed so a page unload still sends, and the `requestConfirm`/`confirm`/`cancelConfirm`/`handleKey` transitions that split reversible (countdown) from irreversible (the unchanged 6 s two-press retreat). The added doc paragraphs state those rules at the state owner, because the countdown window, the cancel semantics and the unload-still-sends rule are behaviour a reader must find where the machine lives. The controller already owns `pendingConfirm`, `confirming` and `lastOutcome`; a second owner beside it would be a second answer to what a pending confirmation means, so no new module carries the countdown. The bar itself moved to the new module-private `CockpitCardConfirmBar.tsx`, which keeps `CockpitCard.tsx` at 628 lines, below its 800-line floor. The increase IS the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-session-start-background-resident-and-run-events): `server/index.ts` 2827→2845, `server/modules/providers/services/sessions.service.ts` 1314→1327, `server/modules/session-hosts/session-host-manager.service.ts` 1730→1745, `server/modules/websocket/services/chat-run-registry.service.ts` 1387→1401, and `src/modules/cockpit/cockpitCardController.ts` 1329→1364. The increase IS the deliverable in each case, and each file is the ONE owner of the fact it gained: `server/index.ts` installs the `session.run.ended` / `session.closed` adapter beside the existing session-ask one and hands `cockpit.sessionStart` to the card executors (the new writer lives in its own module because `context-event-writer.ts` is hard against this very ceiling); `sessions.service.ts` states `session.closed` at the delete/archive path it already owns; `session-host-manager.service.ts` states it when a RESIDENT host closes (the only host close that means the session is gone); `chat-run-registry.service.ts` states `session.run.ended` at the single terminal-frame branch where it already records the turn-end event; and `cockpitCardController.ts` now attaches a started session to its card, because the display no longer navigates into the background session and the card is the only place the new conversation can be reached from. Splitting any of these into a new helper module would be a module that exists only to keep a line count down, not a second owner. No entry is raised above its current reading, and the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-card-feedback-receipt-lifecycle): `server/index.ts` 2845→2849, `server/shared/types.ts` 5184→5257, `src/shared/types.ts` 4596→4669, `src/modules/cockpit/cockpitCardController.ts` 1364→1509 and `src/shared/api.ts` 1773→1780. This task adds the feedback receipt lifecycle. The five wire types (`CockpitCardReceiptDisposition`, `CockpitCardReceipt`, `CockpitCardFeedbackOutcome`, `CockpitCardFeedback`, `CockpitCardFeedbackNotice`) and the three optional overlay fields on `CockpitCard` are hand-mirrored on both types files: the card contract is the server/client seam and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry them instead. `server/index.ts` gains the `fixtureFeedback` and persisted `feedbackFilePath` arguments the composition root must pass (the overlay is CloudCLI's own state under `~/.cloudcli/`, not the provider's). `src/shared/api.ts` gains the one `cockpitResendFeedback(cardId)` entry point so a resend goes through the centralized client surface like every other read. `cockpitCardController.ts` gains the feedback WIRING the plan puts there — the phase/awaiting derivation, the one-second ticker armed only while some card waits, the resend command and the confirm-target lock — while the lifecycle rules themselves live in the new `src/modules/cockpit/cockpitCardFeedback.ts` and the overlay store in the new `server/modules/cockpit/cockpit-card-feedback-store.ts`; neither new file appears above, and the store keeps every piece of state in a factory closure, so it adds no `moduleMutableState` reading either. The increases ARE the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-29, gap-cockpit-asking-event-question-text): `server/shared/types.ts` 5257→5265. The `SessionAskEvent` doc comment gains the eight-line statement of what `session.asking.data.questionText` means — the asking message's verbatim UNTRUNCATED full text (2026-10-29: the earlier 4000-character tail cap was revoked by the user), omitted when the text is blank, and used ONLY by quay-fleet's 「session + normalised question text」 dedup key, never by a CloudCLI UI. The comment belongs beside the type because the fleet contract and the observation producer must read the same rule; no new module can carry it, and this is documentation growth rather than new code. A RECORDED CHANGE (2026-10-29, gap-cockpit-asking-event-question-text, writer): `server/modules/context-events/context-event-writer.ts` is a NEW `oversizeFiles` entry at 849 (it was unbaselined at 797 on develop, just under the 800 floor). The task makes a `session.asking` row's `questionText` exempt from the 16 KB line cut: quay-fleet hashes that text into the ask's dedup key, so a cut merges distinct questions, and the fleet reader imposes no line-size limit. The added code is the verbatim-field predicate, the probe that decides whether any cut could bring the row under the ceiling, the exemption in the final byte check, and the doc paragraphs that state why this one field must not be cut; no new module carries it, because the writer is the ONE place a line is assembled and cut. The increase IS the deliverable; no other baselined entry rises. A RECORDED CHANGE (2026-10-29, gap-cockpit-ask-content-anchored-by-askid): `server/shared/types.ts` 5265→5276. The `SessionAskDecisionReading` union gains the optional `originalAsk` field on all three arms, plus the doc paragraph stating what it is: the asking message's OWN verbatim words, read from the transcript as the fallback question for a card whose summary is missing or switched off, and never presented as the model's restatement. It must ride on the reading because the cockpit leaf may not import the observation layer — the reading IS the only channel from the digest reader to the card projection — so the field is wire vocabulary shared by both and no new module can carry it instead. The client mirror (`src/shared/types.ts`) is untouched: no card wire field changed, and the fallback reaches the card through its existing `ask` field. This is docs plus one optional field, not new behaviour in this file; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-29, gap-cockpit-card-sent-state-single-line): `server/shared/types.ts` 5276→5282 and `src/shared/types.ts` 4669→4675. This task adds the optional `lastError` field (with its doc comment) to `CockpitCardFeedback`: the reason the last feedback CALL failed, so the card can distinguish 「fleet unreachable」 from 「fleet slow」. The card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry the field instead. The increase IS the deliverable; no other baselined entry rises. A RECORDED CHANGE (2026-10-29, gap-cockpit-card-sent-state-single-line): `src/modules/cockpit/CockpitCard.tsx` 基线外→833. This task collapses the sent state into ONE status line — it removes the disabled confirm bar, the duplicated unconfirmed sentence and the whole-card dimming, and adds the dot+phase row, the amber failure reason and the resend row. Merging develop's `emptyAskContent` guard into the same confirm block leaves the file 33 lines above the 800-line oversize floor; the growth IS the deliverable at the one place the card lifecycle is drawn, and extracting it into a new module would add a file outside this task's declared Touches. Every other baselined entry is unchanged. A RECORDED CHANGE (2026-10-29, gap-cockpit-stable-option-identity): `server/shared/types.ts` 5282→5298, `src/shared/types.ts` 4675→4691, `src/modules/cockpit/CockpitCard.tsx` 833→856 and `src/modules/cockpit/cockpitCardController.ts` 1509→1557. This task makes an option's identity stable: the digest derives every option id from the normalised label instead of writing the model's free-text id, and the card carries the digest revision as `contentRevision`. The two types files each gain the same optional `contentRevision?` field (on `CockpitCard` and on `CockpitCardFeedback`) with its doc comment: the card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry the field instead. `CockpitCard.tsx` grows by the option-gone suffix on the sent line and the resend-refusal reason block — the two readings a person gets when the chosen option has left a recomputed card, and they belong beside the status line that draws the receipt. `cockpitCardController.ts` grows by `cockpitCardStateKey`, the content-keyed reset in `normalize` (shown option, open dropdown, inline expansion, brief) and the option-gone refusal message, because `normalize` is the ONE place per-card state is repaired and a second owner beside it would be a second answer to what 「the same content」 means. The increases ARE the deliverable, no entry is raised above its current reading, and the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-29, gap-cockpit-option-edit-into-own-reply): `server/shared/types.ts` 5298→5305 and `src/shared/types.ts` 4691→4698. This task adds the optional `CockpitCardOption.sendText` field to both hand-copied wire declarations (the Details drawer's 「✎ 编辑」 shortcut copies it into the person's own reply). The two files grow by the same seven-line field doc on each side, which IS the honest shape of a contract field stated twice by hand — there is no shared program between the server and bundle compilers, so the field cannot be stated once. No entry is raised above its current reading, and no other baseline entry changed. A RECORDED CHANGE (2026-10-29, gap-cockpit-duplicate-cards-collapsed): `src/modules/cockpit/CockpitCard.tsx` 856→917 and `src/modules/cockpit/cockpitCardController.ts` 1557→1628. This task folds cards that ask the same question in the same session. The controller grows by the grouping pass in `normalize` (the folded ids, the kept cards every count uses, the drawable order where an expansion re-inserts at the provider position, and the `toggleDuplicates` command); the card grows by the strip that states 「同一问题被问了 N 次」 and its expand control. Both additions are the honest shape of the change — the folding rules belong to the controller and the strip belongs to the card, so neither can live in a second file without inventing a surface. No entry is raised above its current reading, and no other baseline entry changed. A RECORDED CHANGE (2026-10-29, gap-cockpit-card-dismiss-disposition): `server/shared/types.ts` 5305→5307 and `src/shared/types.ts` 4698→4700 add `dismissed` to `CockpitCardReceiptDisposition` (the member plus one doc sentence); both ends are hand-mirrored and `cockpitCardTypeSync.test.ts` compares them field-for-field, so no new module carries the member instead. `src/shared/api.ts` 1780→1788 gains the one `cockpitDismissCard` entry (POST /api/cockpit/cards/dismiss) the card's third action calls; the endpoint belongs on the centralized client API surface. `src/modules/cockpit/cockpitCardController.ts` 1628→1797 gains the card-level dismiss target/notice vocabulary plus the three commands and their normalization: the dismiss choice is one card decision beside the shown option, owned by the controller that already owns the confirm target, and a second owner would be a second answer. `src/modules/cockpit/CockpitCard.tsx` 917→983 gains the third action's in-place button and confirmation in the card's control zone. Both increases ARE the deliverable; no entry is raised above its measured reading and no other entry rises. A RECORDED CHANGE (2026-10-30, gap-cockpit-ask-semantic-gate): `server/shared/types.ts` 5307→5318. The semantic ask gate needs one explicit verdict field on the ask-decision reading: `isAsking?: boolean` appears on all three arms (`evaluated`, `skipped`, `unevaluated`) because a definitive `false` suppresses the event/object while an absent value keeps the mechanical candidate visible, and the producer reads the field off whichever arm it has. The extra lines are the three optional declarations plus the doc paragraph that defines those three states for readers; the increase IS the deliverable and no entry rises above its measured reading. A RECORDED CHANGE (2026-10-30, gap-routine-architecture-analysis-dup-quay-json-field-readers): `server/shared/utils.ts` 1900→1930. The task hoists the byte-identical `readNullableString`/`readNullableNumber` readers out of `server/modules/quay/quay.service.ts` and `quay-suite-fanin-reader.ts` into the shared utility file that backend-module-standards designates for a helper used in two or more files, so the 30-line increase is the extraction itself; the two quay files shrink by 16 and 14 lines respectively (quay.service.ts 2993→2977 is a fall, noted not raised). A RECORDED CHANGE (2026-10-30, gap-cockpit-ask-retraction-and-ledger-backfill): `server/modules/context-events/context-event-writer.ts` 849→939 and `server/shared/types.ts` 5318→5327. This task states `session.asking.retracted`, the row that withdraws a mis-detected ask. The writer file gains the kind constant, its payload type, the exact-payload validator and the narrow `FLEET_TOLERATED_AHEAD_KINDS` allow-list (a 90-line addition); the wire types file gains the third member of `SessionAskEventKind` plus the doc paragraph stating why that row is written ahead of the installed fleet schema (a 9-line addition). The increase IS the deliverable: no new module can carry a kind the existing writer must validate and a union the wire type must name. The same task SPLITS `session-digest.producer.ts` back under the 800-line floor (1081→718) by moving the retraction walks and the startup sweep into `session-ask-retraction.ts` (534 lines, under the floor), so no baseline entry is created for it. A RECORDED CHANGE (2026-10-30, gap-codex-resident-develop-five-reds): `server/modules/providers/list/codex/codex-host-driver.provider.ts` 827→835 is recorded at its measured value. The file crossed the 800-line floor while the codex resident host driver landed (AC-435…AC-444: per-session hosts and connections, the busy-input queue, the approval broker, steer and live settings) and no census re-recorded it, so develop was already red on this dimension before this task; this task adds the last 8 lines — `liveHostFor` now also recognises the host a session was bound to through the driver's own session row, which is what keeps `run` on the host it started when the driver was handed one directly. The driver and its private helpers remain one cohesive unit; splitting them into a new leaf module to fit a wiring fix would add an import-graph node under AC-394 for no behavioural gain, which is not the honest shape of this change. No entry is raised above its current reading. A RECORDED CHANGE (2026-10-30, gap-mcp-session-steer-tool): `server/index.ts` 2849→2862. This task adds the `sessionSteer` bag to the MCP gateway's `writeTools` literal — the three process seams `session_steer` answers from (the session row's provider reader, the provider registry's host-driver resolver, and the session-hosts manager's live-host read) — so an external MCP client can steer a resident turn without a second send path. The increase IS the wiring: the tool itself is a new module, and the composition root is the only place the process singletons can be bound. No other entry is raised. | 2026-10-30: server/shared/ports/mcp-gateway-client.port.ts enters moduleMutableState at 1 — the installed-reader slot of the new provider-facing MCP-gateway port, the same shape as every existing port in that directory. No other reading rose. | 2026-10-30 (gap-cockpit-session-start-model-settings-ui): `src/shared/api.ts` 1788→1799 and `src/shared/types.ts` 4700→4719. This task gives the cockpit card new-conversation launch selection a settings surface: the two wire mirrors gain the flat six-field reading and its two api calls (`api.settings.cockpitSessionStart` / `saveCockpitSessionStart`). The increase IS the contract — the client must read the same server field the `session.start` executor uses, and both ends are hand-copied mirrors checked field-for-field by the wire-contract criterion, so the shape exists twice by design. No other reading rose. A RECORDED CHANGE (2026-10-31, claude-codex-new-session-default-resident): `server/modules/providers/provider.routes.ts` 1122→1152, `server/modules/providers/services/sessions.service.ts` 1327→1390, `server/shared/types.ts` 5327→5352, `src/shared/api.ts` 1799→1809 and `src/shared/types.ts` 4719→4743. This task moves the new-session lifecycle default into the provider capability matrix and writes the resolved mode in the session row's own INSERT. The capability service gains the provider-owned `defaultLifecycleMode` resolution (support and default are separate readings), and `sessions.service.ts` gains `resolveCreateLifecycleMode` — one place that gives an explicit mode precedence, falls back to that declared default, and refuses an unknown or unsupported mode before any row exists, so the HTTP, MCP and Live Voice entry points all create through it instead of each hard-coding a provider-id branch. The two shared types files each gain the same `defaultLifecycleMode` / `lifecycleMode` wire vocabulary: the contract is the server/client seam, both ends are hand-copied and `wireContractTypeSync.test.ts` compares them field-for-field, so no new module can carry the shape instead. `src/shared/api.ts` gains the client-side parse of the same capability field. The increases ARE the deliverable; no entry is raised above its current measured reading, and no baselined file grew for any other reason. A RECORDED CHANGE (2026-10-31, gap-session-binding-consistency): `server/modules/websocket/services/chat-run-registry.service.ts` 1401→1436. The increase IS the wiring for this task's single binding-write seam: the run record gains `bindingAtStart` (the binding a run was admitted under, frozen at startRun) and `recordProviderSessionId` now writes through `sessionBindingService`, whose outcome decides whether a late `session_created` is a write, a confirmation, or a rejection. The added lines are that field, its docblocks and the guarded write path; the repository half of the same change SHRANK `server/modules/database/repositories/sessions.db.ts` 1479→1422 (the binding writes moved to the new baseline-external sibling `server/modules/database/repositories/session-binding.db.ts`). No other entry is raised. A RECORDED CHANGE (2026-10-31, gap-quay-provider-transcript-prose): `server/modules/providers/list/codex/codex-sessions.provider.ts` 2348→2361, `server/shared/types.ts` 5352→5373 and `src/shared/types.ts` 4743→4749. The increase IS this task's deliverable at each site. Both provider sessions classes gain `readTranscriptMessage(row)` — the capability that lets Quay resolve prose through the provider registry instead of re-implementing each provider's transcript format — and the two lines of that method are the wiring itself; the recognition rules live in the pre-existing `claude-transcript-format.ts` / `codex-transcript-format.ts`, so no new module carries them. `server/shared/types.ts` gains the narrow `ProviderTranscriptMessage` contract (role/text/timestamp, deliberately smaller than `NormalizedMessage`) that both providers and the Quay consumer share, and `src/shared/types.ts` gains the `transcript: 'ok' | 'unreadable'` field on the wire reading `QuaySessionMentionsReading`, which is what lets the popover distinguish an unreadable transcript from a successful empty reading; both wire ends are hand-copied and a TypeSync criterion compares them field-for-field. A RECORDED CHANGE (2026-10-31, gap-ac178-new-session-switch-gate-drops-nonmatrix-provider): `src/modules/chat-session/hooks/useChatProviderState.ts` 913→923. The increase is the adoption guard this task's defect fix requires: the session-adoption effect must refuse a `__provider` that has no row in the capability matrix, otherwise a debug session's runtime id overwrites the validated preference and the new-session lifecycle gate (`canToggleNewSessionLifecycle`) goes false, hiding the composer's resident switch. Three lines are the guard and six are the comment stating why the matrix check is the boundary; the check belongs at the one place a session's provider is adopted, so no new module carries it instead. No other entry is raised. A RECORDED CHANGE (2026-10-31, gap-codex-resident-blocked-context-events): `server/index.ts` 2862→2871 and `server/modules/providers/list/codex/codex-host-driver.provider.ts` 835→841. This task states the Codex resident 「needs a person」 fact on the context-event stream. `server/index.ts` gains the install of the blocked-event adapter beside the existing session-run install — the composition root is the only place that writer is built — and `codex-host-driver.provider.ts` gains the one field, the one import and the four call sites that hand a settled turn to the new rule; the rule itself (which failed/interrupted turn left a card open) lives in the new `codex-resident-blocked-events.ts`, so the driver grows by the wiring rather than by a second copy. The approval arm lives in `codex-approval-broker.ts`, which stays under the 800-line floor, and the writer's new kinds were merged into existing constant lines so `context-event-writer.ts` does not grow at all. No entry is raised above its current reading. A RECORDED CHANGE (2026-10-31, census re-sync): `src/modules/chat-composer/composer/ChatComposer.tsx` 1633→1644 is raised to its measured value on develop. The file is byte-identical to the develop tip in this tree and is outside this task's delta; the growth landed with develop commit 61caec01a after the census captured 1633, and no commit re-recorded it, so AC1/AC4 redded a tree neither this task nor its delta touches. This is a stale-census re-sync, not an accommodation of new growth: the recorded value equals the measured one, and no other entry is raised for this file. A RECORDED CHANGE (2026-10-31, gap-codex-token-usage-snapshot-semantics): `src/shared/types.ts` 4749→4768 and `src/modules/chat-composer/composer/ChatComposer.tsx` 1633→1644 are raised to their measured values. The first is this task's wire vocabulary: the shared `TokenUsageCounts` shape and the `CostCommandData.tokenUsage`/`tokenBreakdown` fields describe the same cumulative/latest-request reading on both ends of the `/cost` response, so the contract belongs in `src/shared/types.ts` and no new module carries it instead. The second is a stale-census re-sync: `ChatComposer.tsx` is byte-identical to the develop tip and its growth landed in 61caec01a, after the 2d86ad361 census captured 1633; no commit re-recorded it, so the criterion redded a file this task does not touch. Neither entry is raised above its current reading, and no other entry is raised. A RECORDED CHANGE (2026-11-01, gap-cost-panel-cache-hit-ratio-and-cachewrite-bar): `src/shared/types.ts` 4768→4772. The increase is the wire vocabulary this task adds to the same `/cost` contract: `TokenUsageCounts` gains the `cacheWriteTokens?` quantity (mirrored field-for-field by the server's `ProviderTokenUsageCounts`, which the TypeSync criterion compares) and `CostCommandData.tokenBreakdown` gains `cacheWrite?`, each with its one-line doc comment. The shape is stated twice by hand by design, so the client half belongs in this shared types file and no new module carries it instead. No other entry is raised. A RECORDED CHANGE (2026-11-01, cockpit-knowledge-decision-handoff): `server/shared/types.ts` 5373→5482 and `src/shared/types.ts` 4772→4881 are raised to their measured values. The increase is the knowledge-suggestion wire vocabulary this task adds to the cockpit card contract: `CockpitKnowledgeCase`/`CockpitKnowledgePlan`/`CockpitKnowledgeVerification`/`CockpitKnowledgeDecision`/`CockpitKnowledgeCaseState` plus the `knowledge` block on `CockpitCard` and the `decision`/`confirmationRef` fields on `CockpitCardOption` and `CockpitCardFeedback`, each with the doc comments that state what the provider owns, what the cockpit only reads, and what a caller may never forge. Both wire ends are hand-copied and a TypeSync criterion compares them field-for-field, so the shape exists twice by design; no new module carries it instead. No other entry is raised above its current reading. A RECORDED CHANGE (2026-11-01, knowledge-application-fact-contract): `server/index.ts` 2871→2905. The increase is this task's composition-root wiring: the `knowledge_facts` read tool's fact source is constructed in `server/index.ts` and bound to the process's real session repository, session host manager, run registry and project lookup, so the gateway answers through the same injected services every other read tool uses rather than through a second private assembly. The adapter itself lives in the new `server/knowledge-facts-wiring.ts`; only the constructor call and its dep bag belong at the composition root. A RECORDED CHANGE (2026-11-01, gap-authoritative-token-reading-used-scope-elimination): `src/modules/chat-session/hooks/useChatSessionState.ts` hookStateHeavy 51→52. The task's deliverable is the split of the one dual-meaning `tokenBudget` state into two named channels — `liveFrame`, the realtime frame the composer counter renders, and `authoritativeReading`, the only reading `/cost` may send — and two independently-written states are the honest shape of that split: one object would hide which channel each of the ten call sites writes. The file's oversize reading is unchanged at 2127, so this is the only entry that moves. No other entry is raised. A RECORDED CHANGE (2026-11-02, pending-approval-dedup): `server/modules/providers/services/provider-runtime.service.ts` 1282→1288. The subscribe acknowledgement must read a shared approval registry once per provider: Claude and Codex expose the same ApprovalRequestsService, so the old fan-out listed the same pending question twice and the client drew two identical answer panels. The six added lines are the per-call reader set and the guard; no other entry moves. A RECORDED CHANGE (2026-11-02, gap-ratchet-baseline-knowledge-facts-wiring): `server/knowledge-facts-wiring.ts` is a NEW `oversizeFiles` entry at 842 — 基线外→842. The file was introduced by 9be415857 as the effective-config launchRequest slice's wiring composition root, and 842 is the real line count that landed with that delivery; this task only registers the existing delivery, it does not grow the file (zero diff on it), and splitting it would be an independent refactor outside this slice. Recording the reading is the honest shape of the change; no other entry is raised.",
|
|
3
|
+
"note": "RATCHET: every reading in this file may only FALL. Lower a value (or remove an entry) when a refactor genuinely shrinks it; never raise one to accommodate a red. A legitimate RAISE must be recorded here in AC-394's \"RECORDED CHANGE\" format: a dated paragraph naming the file, the old\u2192new reading and why the increase is the honest shape of the change. The criterion prints `ratchet: <dimension> <file> <baseline>\u2192<measured>\uff0c\u53ef\u4e0b\u8c03\u57fa\u7ebf` whenever a reading falls; lowering the baseline is encouraged but not required, so a parallel refactor that shrinks a reading never reds this criterion. A RECORDED CHANGE (2026-10-26, census re-sync by gap-codex-transcript-format-shared-helpers): `src/modules/architecture/semanticZoomLayout.ts` 1642\u21921688 and `src/modules/architecture/semanticZoomPlan.ts` 876\u2192894 are raised to their measured values on develop. Both files are byte-identical to the develop tip in the re-recording tree \u2014 the growth landed in the architecture commits up to 3f1b1ea23 AFTER the census commit f7d20cdcb captured these readings, and no commit re-recorded it, so the criterion redded a tree neither this task nor its delta touches. This is a stale-census re-sync, not an accommodation of new growth: no entry is raised above its current reading, and the two files are not part of this task's delta. A RECORDED CHANGE (2026-10-27, cockpit-card-provider-contract-and-registry): `server/index.ts` 2754\u21922769, `server/shared/types.ts` 4629\u21924749 and `src/shared/types.ts` 4123\u21924243. This task introduces the cockpit card contract: the two types files each gain the 120-line card wire vocabulary (both ends are hand-copied and a TypeSync criterion compares them field-for-field, so the shape exists twice by design, not by duplication), and `server/index.ts` gains the three statements that build the card module and mount its authenticated router. The increase IS the deliverable \u2014 no new module carries the types instead, because the contract is the server/client seam. The other entries in this diff only FELL (encouraged by this file's own rule). A RECORDED CHANGE (2026-10-27, observation-session-ask-decision-digest): `server/shared/types.ts` 4749\u21924821. This task adds the 72-line ask/decision wire vocabulary (SessionAskDecisionOption, SessionAskDecision, SessionAskDecisionReading, SessionAskEventKind, SessionAskEvent) that the transcript reader, the answer normaliser, the digest producer and the injected ISessionAskEventWriter seam all share. The backend module standard puts a type used in two or more files in `server/shared/types.ts`, and no new module carries it instead: the event envelope is the seam quay-fleet's context-event stream will consume, so it is a shared contract rather than observation-internal state. The increase IS the deliverable, recorded on the same entry the preceding cockpit card contract raised for the same reason. A RECORDED CHANGE (2026-10-27, cockpit-card-ui-core): `src/shared/api.ts` 1749\u21921766 and `src/modules/cockpit/CockpitPage.tsx` 1881\u21921883. This is the UI half of the same cockpit card contract: `src/shared/api.ts` gains the two client entry points the card view calls (`cockpitCards` = GET /api/cockpit/cards and `cockpitConfirmCard` = POST /api/cockpit/cards/confirm, each with the revision/`optionId`/`replyText` shape the server enforces) \u2014 the API client surface IS where the client seam belongs, so no new module carries them instead; `CockpitPage.tsx` gains the one `cards` arm of the header's existing view-label ternary so `/cockpit?view=cards` names itself like every other view. The card UI itself lives in new files (`cockpitCardController.ts`, `CockpitCard*.tsx`, descriptors, hook), so it does not grow any baselined file. The other entries in this diff only FELL (encouraged by this file's own rule). A RECORDED CHANGE (2026-10-27, cockpit-card-session-executors): `server/index.ts` 2769\u21922777, `server/shared/types.ts` 4821\u21924839 and `src/shared/types.ts` 4243\u21924261. This task adds the two built-in cockpit content executors (`session.send`, `session.start`) and the subject-derived \u300c\u81ea\u5df1\u7684\u56de\u590d\u300d default. The two types files each gain the same 18-line wire vocabulary (`CockpitFixtureSubject` plus the projection-owned `ownReplyUnavailable` field). They exist twice by design: the card wire contract is hand-copied on both ends and a TypeSync criterion compares the copies field-for-field, so no new module can carry the types instead. `server/index.ts` moves the card module's construction BELOW the one chat control service its executors send through, and gains the `createCockpitCardExecutors(...)` argument, the `fixtureSubject` argument and their one import; the increase IS the wiring statement the task requires at the composition root, and the binding itself lives in the new `server/cockpit-executors-wiring.ts` so this file grows by only the composition lines. A RECORDED CHANGE (2026-10-27, cockpit-card-brief-rendering): `server/shared/types.ts` 4839\u21925074 and `src/shared/types.ts` 4261\u21924496. This task adds the 235-line brief wire vocabulary (CockpitBriefResponse, the seven preset block shapes and their nested option/evidence/axis/series/row/token/failure types) at the same group boundary on both ends. The shape exists twice by design: the brief read is the server/client seam, the client copy is hand-mirrored, and `cockpitCardTypeSync.test.ts` reads both ends field-for-field, so no new module can carry the types instead. `src/shared/api.ts` 1766\u21921773 gains the one `cockpitCardBrief(cardId)` entry point (GET /api/cockpit/cards/:id/brief) the Details drawer calls; the endpoint belongs on the centralized client API surface rather than in the component. The increase IS the deliverable. A RECORDED CHANGE (2026-10-27, cockpit-mobile-header-and-page): `src/modules/cockpit/cockpitCardController.ts` is a NEW `oversizeFiles` entry at 871 (it was unbaselined at 766 on develop). This task adds the card page's route memory to the controller that already owns `selectedCardId` and `anchorCardId`: the `CockpitCardMemory` seam, the normalization that turns an unreadable store into \"start at the top\", the deferred restore of the remembered selection once the card list exists, and `setScrollPosition`'s persistence. The rule \u2014 \"the person returns to the card and the scroll offset they left\" \u2014 is a list rule, and putting a second owner beside it would be a second answer; no new module carries it instead, because the seam is the controller's own dependency contract and the binding only supplies the storage. The additions are the measured 105 lines; the file was already near the 800-line limit on develop, so this is the honest shape of the change, not a reorganization for line count. A RECORDED CHANGE (2026-10-27, observation-session-ask-event-writer-wiring): `server/index.ts` 2777\u21922788, and `server/shared/ports/session-ask-events.port.ts` is a NEW `moduleMutableState` entry at 1. The task wires the observation layer's `session.asking`/`session.answered` to the host-level context-event writer through a new install-style port (the same shape every sibling in `server/shared/ports/` already has, which is why each of them carries exactly this one reading): the port owns the installed-writer slot, and the composition root installs the adapter. `server/index.ts` grows by the port import, the adapter import/installation and the comment that states why a v0 fleet counts the two kinds instead of throwing; no existing statement was rewritten, so the increase IS the wiring the task requires at the composition root. The other entries in this diff only FELL (encouraged by this file's own rule). A RECORDED CHANGE (2026-10-27, cockpit-fleet-card-provider): `server/index.ts` 2788\u21922797, `server/shared/types.ts` 5074\u21925081 and `src/shared/types.ts` 4496\u21924503. This task registers the quay-fleet card provider at the composition root and adds the one card field that names why locally-filled content is not ready. `server/index.ts` gains the import and the `providers` entry that passes `cockpit.fleetCards.enabled` and `ttlMs` into `createCockpitCardsModule`; the fleet CLI and digest bindings live in the new `server/cockpit-fleet-wiring.ts`, so this file grows only by its composition statements. The two types files each gain the same 7-line `contentUnavailable?` field on `CockpitCard` with its doc comment: the card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry the field instead. The increase IS the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-27, gap-ac425-card-viz-and-zone-coverage): `server/shared/types.ts` 5081\u21925112 and `src/shared/types.ts` 4503\u21924534. This task adds the 31-line small-visualization wire vocabulary (`CockpitCardVizKind`, the `CockpitCardViz` reading envelope, and the `viz?` field on `CockpitCard`) at the same group boundary on both ends. The shape exists twice by design: the card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field (this task adds both rows to that comparison), so no new module can carry the types instead. The increase IS the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-27, gap-voice-keyboard-shortcut-toggle): `src/modules/chat/ChatInterface.tsx` 1395\u21921443 and `src/modules/chat/composer/ChatComposer.tsx` 1606\u21921628. This task wires a configurable keyboard chord to the two voice surfaces the pane owns: `ChatInterface` holds the registered dictation toggle, derives the Live Voice toggle from `composerMode`, and mounts the shortcut hook (48 lines), while `ChatComposer` registers its own `handleVoiceToggle` with the pane on each render (22 lines). Both increases ARE the wiring: the shortcut must reach the same handlers the on-screen controls use, and a second copy of that caret/draft logic in the pane is exactly the drift the shared `handleVoiceToggle` seam exists to prevent. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-27, gap-voice-shortcut-options): `src/modules/chat/ChatInterface.tsx` 1443\u21921477 and `src/modules/chat/composer/ChatComposer.tsx` 1628\u21921633. This task extends the same shortcut feature with three bindings \u2014 send-on-stop, cross-surface cancel and clear-input. `ChatInterface` gains the four pane-level readings the controller routes on (`stopAndSendDictation`, `isDictationRecording`, `isLiveVoiceActive`, and `isClearAvailable`, which mirrors the Escape guard's own condition so the clear chord cannot become a laxer second way to dismiss a running turn or an open menu), moves the shortcut block below `handleVoiceExit` so leaving Live Voice reuses the bar's own exit path (backlog back to the composer, run keeps going) instead of the bare mode teardown, and passes the larger command bag to `useVoiceShortcuts`; `ChatComposer` registers `stopAndSend` and the live `recording` reading with the pane. Both increases ARE the wiring: every new command is a pane-level fact (composer draft, processing state, dock/menu visibility) the React-free controller cannot read itself, and the chords must reach the same handlers the on-screen controls use. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-27, gap-cockpit-live-cards-session-link-confirmability-and-titles): `server/shared/types.ts` 5112\u21925120 and `src/shared/types.ts` 4534\u21924542. This task adds the option confirmability vocabulary (`confirmable?` and `confirmableReason?` on `CockpitCardOption`) at the same group boundary on both ends. The shape exists twice by design: the card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry the fields instead. The increase IS the deliverable; no other baselined entry rises. A RECORDED CHANGE (2026-10-27, cockpit-card-anatomy-matches-mockups): `server/shared/types.ts` 5120\u21925144, `src/shared/types.ts` 4542\u21924566 and `src/modules/cockpit/cockpitCardController.ts` 871\u2192876. This task adds the card header's two provider-stated readings on the wire \u2014 `CockpitCard.load` (the 0\u20133 decision weight the header's three cells draw) and `CockpitCardSubject.title` (the subject's display name) \u2014 plus the `attempts` viz reading (`CockpitCardVizOutcome`, `CockpitCardVizAttempt`, and `cap`/`items` on `CockpitCardViz`), which turns the stuck/fix dot row into a per-attempt reading. The card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field (this task adds the two new rows), so no new module can carry the types instead; the increase IS the deliverable. The controller grows by the widened `isIrreversibleOption` predicate, which now also recognises the current `irreversible` tag name beside the pre-vocabulary `warn`; the predicate already lives there and a second copy would be the drift the single rule exists to prevent. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, cockpit-shell-filters-mobile-page-and-details-bar): `src/modules/cockpit/cockpitCardController.ts` 876\u21921047 and `src/modules/cockpit/CockpitPage.tsx` 1883\u21921902. This task adds the cards page's two filters to the controller that already owns the card list, selection and scroll memory: type chips with per-type counts constrained by the project selection, a multi-select project set with per-project counts constrained by the type, and the per-device persistence seam (`rememberFilters`) that restores both across a rebuild. The filtering rule \u2014 which cards are visible, and what each chip's count is under the other filter \u2014 is one rule, so a second owner beside the controller would be a second answer; the controller's dependency contract is where the storage binding belongs, and no new module carries it instead. `CockpitPage.tsx` grows by the mobile-width reading and the three `{!phoneCards && \u2026}` wrappers that keep the deploy strip, project strip and Focus row off the phone's cards page while leaving them on wall/fleet/board. Both increases ARE the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-quay-tests-fanin-read-via-suite-verb-and-driver-log): `server/shared/types.ts` 5144\u21925168, `src/shared/types.ts` 4566\u21924590 and `src/modules/quay/QuayPanel.tsx` 1120\u21921176. This task moves the Tests/Fan-in readings off the local `.quay/` carrier files and onto quay's own read verbs (`quay suite`, `quay driver log`). The two types files each gain the same 24-line `QuayCarrierReading` vocabulary and the optional `carrierReadings` field on `QuaySnapshot`: the reading is the server/client seam (the adapter produces it, the panel states it), and both ends are hand-copied shared types, so the shape exists twice by design, not by duplication. `QuayPanel.tsx` grows by the one `CarrierReadingLine` helper and the two card arms that render a non-`ok` reading instead of the empty-state text \u2014 drawing \"no records\" for a failed or unavailable read would be a false claim about the project. The increases ARE the deliverable; no new module carries the carrier state instead, because it is wire vocabulary rather than panel-local state. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-ask-cards-judge-default-suggestion): `server/shared/types.ts` 5168\u21925172 and `src/modules/cockpit/cockpitCardController.ts` 1047\u21921049. This task lets the same summarising call's judge supply the session-ask default when the assistant recommends nothing: the shared type gains the optional `why` field carrying the judge's one-line reason, which the card renders and the projection forwards, so it is wire vocabulary shared by the observation layer and the card surface (no new module can carry it instead). The controller grows only by the doc statement of the rule it already implements \u2014 a suggested option of ANY source is the default. Both increases ARE the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-ask-cards-resolve-reliably-digest-json-and-details-polish): `server/index.ts` 2797\u21922805, `server/modules/websocket/services/chat-control.service.ts` 1105\u21921114, `server/shared/types.ts` 5172\u21925184 and `src/shared/types.ts` 4590\u21924596. The ask-card polish adds one optional verbatim `assistantQuote` field to `CockpitCard` (hand-copied on both ends like the rest of the card wire vocabulary, which a TypeSync criterion compares field-for-field), one optional `quote` field to `SessionAskDecision`, the observation\u2192send port type and its one install in the composition root, and the send-path notification (a guarded port read so observation can never change a send result). No new module can carry the wire fields or the install: the contract is the server/client seam and the composition root is where every other port is installed. The increase IS the deliverable. A RECORDED CHANGE (2026-10-28, cockpit-inline-confirm-zero-focus-jump): `src/modules/cockpit/cockpitCardController.ts` 1049\u21921108. This task replaces the fixed bottom dialog with an in-place confirm state, and the state machine that decides it is the controller's own: the 6 s automatic retreat armed on `requestConfirm` and cleared on every commit that leaves no card pending (the injected clock's one timer), the three new transitions (`requestConfirm`, `cancelConfirm`, and `confirm` running only from a pending state), `selectCard` clearing the pending card when the selection moves elsewhere, and `handleKey('Enter')` becoming the same key twice \u2014 open in place, then send from the same bar. The additions also carry the doc paragraphs that state these rules, because the retreat window and the \u300csecond Enter sends\u300d reading are behaviour a reader must find at the state owner rather than infer from the view. The controller already owns `pendingConfirm`, `confirming` and `lastOutcome`; a second owner beside it would be a second answer to what \u300cpending\u300d means, so no new module carries the machine instead. The increase IS the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-card-situation-full-text-with-inline-expand): `src/modules/cockpit/cockpitCardController.ts` 1108\u21921139. This task stops the card situation from being truncated to two lines: Cards draws it in full until it runs past six lines, then keeps it behind an in-place expand control, and that expansion is a per-card reading \u2014 mapped to the card id AND the revision it was opened at, so a re-read that moves the revision drops it. The rule belongs to the controller that already owns the card list, selection and pending confirm (a re-read reconciles card state in `normalize`), so the added snapshot field, its normalization in `normalize` and the toggle command live there rather than in a second owner (31 inserted lines, 0 deleted). `src/modules/cockpit/CockpitCard.tsx` did NOT need a baseline entry: the situation block moved to the new module-private `CockpitCardSituation.tsx`, so it measured 766 lines (below the 800 floor and below its 768 on develop). The increase IS the deliverable; no other baselined entry rises. A RECORDED CHANGE (2026-10-28, gap-cockpit-ask-answered-immediate-dedup-startup-sweep-and-repair): `server/index.ts` 2805\u21922817 and `server/modules/websocket/services/chat-control.service.ts` 1114\u21921116. This task states an answered ask the moment the person sends their next message \u2014 without waiting for the transcript to carry it \u2014 and adds the boot-time sweep that settles asks a restart left unfinished. `server/index.ts` gains the composition-root call that starts the sweep once the database is open: one import, the guarded `void \u2026 .catch(...)` and the comment stating why the pass is not awaited here, placed beside the other producer start-up statements because that is the file's existing job. `chat-control.service.ts` gains the two comment lines beside its user-turn notification stating that the send path knows no transcript message id, so the sweep \u2014 not this call \u2014 settles a pending ask whose answer has not landed yet. Both increases ARE the fix, not reorganization: no new module can carry the start-up call (every producer starts in this composition root) and the comment belongs on the call it explains. The other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-mcp-cockpit-card-tools): `server/index.ts` 2817\u21922827. This task exposes the cockpit card system over the MCP gateway: the composition root now hands the one `createCockpitCardsModule` instance's `registry` / `actions` / `briefForCard` to `createMcpGatewayModule` as `cockpitTools`, beside the other dependency bags it already builds there. The ten lines are the injection itself plus the comment stating that these are the SAME three members the HTTP face reads (the DoD's 'no second reading path' clause); no other module can carry the wiring because `server/index.ts` is the only place the card module is constructed, and the alternative \u2014 the gateway importing the cockpit barrel \u2014 is the edge AC-394 registers separately. Every other entry in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-confirm-delayed-send-with-cancel): `src/modules/cockpit/cockpitCardController.ts` 1139\u21921329. This task replaces the two-press confirmation of reversible options with a five-second send countdown, and the state machine that owns it is the controller's own: the countdown reading (card id, revision, started at, fires at) and its two injected-clock timers, the cancel path, the `confirmingCardId` field that keeps the bar in its pending state while the request is in flight after the countdown clears, the normalization that drops a countdown whose card or revision went away, the `stop()` rule that deliberately leaves the countdown armed so a page unload still sends, and the `requestConfirm`/`confirm`/`cancelConfirm`/`handleKey` transitions that split reversible (countdown) from irreversible (the unchanged 6 s two-press retreat). The added doc paragraphs state those rules at the state owner, because the countdown window, the cancel semantics and the unload-still-sends rule are behaviour a reader must find where the machine lives. The controller already owns `pendingConfirm`, `confirming` and `lastOutcome`; a second owner beside it would be a second answer to what a pending confirmation means, so no new module carries the countdown. The bar itself moved to the new module-private `CockpitCardConfirmBar.tsx`, which keeps `CockpitCard.tsx` at 628 lines, below its 800-line floor. The increase IS the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-session-start-background-resident-and-run-events): `server/index.ts` 2827\u21922845, `server/modules/providers/services/sessions.service.ts` 1314\u21921327, `server/modules/session-hosts/session-host-manager.service.ts` 1730\u21921745, `server/modules/websocket/services/chat-run-registry.service.ts` 1387\u21921401, and `src/modules/cockpit/cockpitCardController.ts` 1329\u21921364. The increase IS the deliverable in each case, and each file is the ONE owner of the fact it gained: `server/index.ts` installs the `session.run.ended` / `session.closed` adapter beside the existing session-ask one and hands `cockpit.sessionStart` to the card executors (the new writer lives in its own module because `context-event-writer.ts` is hard against this very ceiling); `sessions.service.ts` states `session.closed` at the delete/archive path it already owns; `session-host-manager.service.ts` states it when a RESIDENT host closes (the only host close that means the session is gone); `chat-run-registry.service.ts` states `session.run.ended` at the single terminal-frame branch where it already records the turn-end event; and `cockpitCardController.ts` now attaches a started session to its card, because the display no longer navigates into the background session and the card is the only place the new conversation can be reached from. Splitting any of these into a new helper module would be a module that exists only to keep a line count down, not a second owner. No entry is raised above its current reading, and the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-28, gap-cockpit-card-feedback-receipt-lifecycle): `server/index.ts` 2845\u21922849, `server/shared/types.ts` 5184\u21925257, `src/shared/types.ts` 4596\u21924669, `src/modules/cockpit/cockpitCardController.ts` 1364\u21921509 and `src/shared/api.ts` 1773\u21921780. This task adds the feedback receipt lifecycle. The five wire types (`CockpitCardReceiptDisposition`, `CockpitCardReceipt`, `CockpitCardFeedbackOutcome`, `CockpitCardFeedback`, `CockpitCardFeedbackNotice`) and the three optional overlay fields on `CockpitCard` are hand-mirrored on both types files: the card contract is the server/client seam and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry them instead. `server/index.ts` gains the `fixtureFeedback` and persisted `feedbackFilePath` arguments the composition root must pass (the overlay is CloudCLI's own state under `~/.cloudcli/`, not the provider's). `src/shared/api.ts` gains the one `cockpitResendFeedback(cardId)` entry point so a resend goes through the centralized client surface like every other read. `cockpitCardController.ts` gains the feedback WIRING the plan puts there \u2014 the phase/awaiting derivation, the one-second ticker armed only while some card waits, the resend command and the confirm-target lock \u2014 while the lifecycle rules themselves live in the new `src/modules/cockpit/cockpitCardFeedback.ts` and the overlay store in the new `server/modules/cockpit/cockpit-card-feedback-store.ts`; neither new file appears above, and the store keeps every piece of state in a factory closure, so it adds no `moduleMutableState` reading either. The increases ARE the deliverable; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-29, gap-cockpit-asking-event-question-text): `server/shared/types.ts` 5257\u21925265. The `SessionAskEvent` doc comment gains the eight-line statement of what `session.asking.data.questionText` means \u2014 the asking message's verbatim UNTRUNCATED full text (2026-10-29: the earlier 4000-character tail cap was revoked by the user), omitted when the text is blank, and used ONLY by quay-fleet's \u300csession + normalised question text\u300d dedup key, never by a CloudCLI UI. The comment belongs beside the type because the fleet contract and the observation producer must read the same rule; no new module can carry it, and this is documentation growth rather than new code. A RECORDED CHANGE (2026-10-29, gap-cockpit-asking-event-question-text, writer): `server/modules/context-events/context-event-writer.ts` is a NEW `oversizeFiles` entry at 849 (it was unbaselined at 797 on develop, just under the 800 floor). The task makes a `session.asking` row's `questionText` exempt from the 16 KB line cut: quay-fleet hashes that text into the ask's dedup key, so a cut merges distinct questions, and the fleet reader imposes no line-size limit. The added code is the verbatim-field predicate, the probe that decides whether any cut could bring the row under the ceiling, the exemption in the final byte check, and the doc paragraphs that state why this one field must not be cut; no new module carries it, because the writer is the ONE place a line is assembled and cut. The increase IS the deliverable; no other baselined entry rises. A RECORDED CHANGE (2026-10-29, gap-cockpit-ask-content-anchored-by-askid): `server/shared/types.ts` 5265\u21925276. The `SessionAskDecisionReading` union gains the optional `originalAsk` field on all three arms, plus the doc paragraph stating what it is: the asking message's OWN verbatim words, read from the transcript as the fallback question for a card whose summary is missing or switched off, and never presented as the model's restatement. It must ride on the reading because the cockpit leaf may not import the observation layer \u2014 the reading IS the only channel from the digest reader to the card projection \u2014 so the field is wire vocabulary shared by both and no new module can carry it instead. The client mirror (`src/shared/types.ts`) is untouched: no card wire field changed, and the fallback reaches the card through its existing `ask` field. This is docs plus one optional field, not new behaviour in this file; the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-29, gap-cockpit-card-sent-state-single-line): `server/shared/types.ts` 5276\u21925282 and `src/shared/types.ts` 4669\u21924675. This task adds the optional `lastError` field (with its doc comment) to `CockpitCardFeedback`: the reason the last feedback CALL failed, so the card can distinguish \u300cfleet unreachable\u300d from \u300cfleet slow\u300d. The card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry the field instead. The increase IS the deliverable; no other baselined entry rises. A RECORDED CHANGE (2026-10-29, gap-cockpit-card-sent-state-single-line): `src/modules/cockpit/CockpitCard.tsx` \u57fa\u7ebf\u5916\u2192833. This task collapses the sent state into ONE status line \u2014 it removes the disabled confirm bar, the duplicated unconfirmed sentence and the whole-card dimming, and adds the dot+phase row, the amber failure reason and the resend row. Merging develop's `emptyAskContent` guard into the same confirm block leaves the file 33 lines above the 800-line oversize floor; the growth IS the deliverable at the one place the card lifecycle is drawn, and extracting it into a new module would add a file outside this task's declared Touches. Every other baselined entry is unchanged. A RECORDED CHANGE (2026-10-29, gap-cockpit-stable-option-identity): `server/shared/types.ts` 5282\u21925298, `src/shared/types.ts` 4675\u21924691, `src/modules/cockpit/CockpitCard.tsx` 833\u2192856 and `src/modules/cockpit/cockpitCardController.ts` 1509\u21921557. This task makes an option's identity stable: the digest derives every option id from the normalised label instead of writing the model's free-text id, and the card carries the digest revision as `contentRevision`. The two types files each gain the same optional `contentRevision?` field (on `CockpitCard` and on `CockpitCardFeedback`) with its doc comment: the card wire contract is hand-mirrored on both ends and `cockpitCardTypeSync.test.ts` compares the copies field-for-field, so no new module can carry the field instead. `CockpitCard.tsx` grows by the option-gone suffix on the sent line and the resend-refusal reason block \u2014 the two readings a person gets when the chosen option has left a recomputed card, and they belong beside the status line that draws the receipt. `cockpitCardController.ts` grows by `cockpitCardStateKey`, the content-keyed reset in `normalize` (shown option, open dropdown, inline expansion, brief) and the option-gone refusal message, because `normalize` is the ONE place per-card state is repaired and a second owner beside it would be a second answer to what \u300cthe same content\u300d means. The increases ARE the deliverable, no entry is raised above its current reading, and the other entries in this diff only FELL. A RECORDED CHANGE (2026-10-29, gap-cockpit-option-edit-into-own-reply): `server/shared/types.ts` 5298\u21925305 and `src/shared/types.ts` 4691\u21924698. This task adds the optional `CockpitCardOption.sendText` field to both hand-copied wire declarations (the Details drawer's \u300c\u270e \u7f16\u8f91\u300d shortcut copies it into the person's own reply). The two files grow by the same seven-line field doc on each side, which IS the honest shape of a contract field stated twice by hand \u2014 there is no shared program between the server and bundle compilers, so the field cannot be stated once. No entry is raised above its current reading, and no other baseline entry changed. A RECORDED CHANGE (2026-10-29, gap-cockpit-duplicate-cards-collapsed): `src/modules/cockpit/CockpitCard.tsx` 856\u2192917 and `src/modules/cockpit/cockpitCardController.ts` 1557\u21921628. This task folds cards that ask the same question in the same session. The controller grows by the grouping pass in `normalize` (the folded ids, the kept cards every count uses, the drawable order where an expansion re-inserts at the provider position, and the `toggleDuplicates` command); the card grows by the strip that states \u300c\u540c\u4e00\u95ee\u9898\u88ab\u95ee\u4e86 N \u6b21\u300d and its expand control. Both additions are the honest shape of the change \u2014 the folding rules belong to the controller and the strip belongs to the card, so neither can live in a second file without inventing a surface. No entry is raised above its current reading, and no other baseline entry changed. A RECORDED CHANGE (2026-10-29, gap-cockpit-card-dismiss-disposition): `server/shared/types.ts` 5305\u21925307 and `src/shared/types.ts` 4698\u21924700 add `dismissed` to `CockpitCardReceiptDisposition` (the member plus one doc sentence); both ends are hand-mirrored and `cockpitCardTypeSync.test.ts` compares them field-for-field, so no new module carries the member instead. `src/shared/api.ts` 1780\u21921788 gains the one `cockpitDismissCard` entry (POST /api/cockpit/cards/dismiss) the card's third action calls; the endpoint belongs on the centralized client API surface. `src/modules/cockpit/cockpitCardController.ts` 1628\u21921797 gains the card-level dismiss target/notice vocabulary plus the three commands and their normalization: the dismiss choice is one card decision beside the shown option, owned by the controller that already owns the confirm target, and a second owner would be a second answer. `src/modules/cockpit/CockpitCard.tsx` 917\u2192983 gains the third action's in-place button and confirmation in the card's control zone. Both increases ARE the deliverable; no entry is raised above its measured reading and no other entry rises. A RECORDED CHANGE (2026-10-30, gap-cockpit-ask-semantic-gate): `server/shared/types.ts` 5307\u21925318. The semantic ask gate needs one explicit verdict field on the ask-decision reading: `isAsking?: boolean` appears on all three arms (`evaluated`, `skipped`, `unevaluated`) because a definitive `false` suppresses the event/object while an absent value keeps the mechanical candidate visible, and the producer reads the field off whichever arm it has. The extra lines are the three optional declarations plus the doc paragraph that defines those three states for readers; the increase IS the deliverable and no entry rises above its measured reading. A RECORDED CHANGE (2026-10-30, gap-routine-architecture-analysis-dup-quay-json-field-readers): `server/shared/utils.ts` 1900\u21921930. The task hoists the byte-identical `readNullableString`/`readNullableNumber` readers out of `server/modules/quay/quay.service.ts` and `quay-suite-fanin-reader.ts` into the shared utility file that backend-module-standards designates for a helper used in two or more files, so the 30-line increase is the extraction itself; the two quay files shrink by 16 and 14 lines respectively (quay.service.ts 2993\u21922977 is a fall, noted not raised). A RECORDED CHANGE (2026-10-30, gap-cockpit-ask-retraction-and-ledger-backfill): `server/modules/context-events/context-event-writer.ts` 849\u2192939 and `server/shared/types.ts` 5318\u21925327. This task states `session.asking.retracted`, the row that withdraws a mis-detected ask. The writer file gains the kind constant, its payload type, the exact-payload validator and the narrow `FLEET_TOLERATED_AHEAD_KINDS` allow-list (a 90-line addition); the wire types file gains the third member of `SessionAskEventKind` plus the doc paragraph stating why that row is written ahead of the installed fleet schema (a 9-line addition). The increase IS the deliverable: no new module can carry a kind the existing writer must validate and a union the wire type must name. The same task SPLITS `session-digest.producer.ts` back under the 800-line floor (1081\u2192718) by moving the retraction walks and the startup sweep into `session-ask-retraction.ts` (534 lines, under the floor), so no baseline entry is created for it. A RECORDED CHANGE (2026-10-30, gap-codex-resident-develop-five-reds): `server/modules/providers/list/codex/codex-host-driver.provider.ts` 827\u2192835 is recorded at its measured value. The file crossed the 800-line floor while the codex resident host driver landed (AC-435\u2026AC-444: per-session hosts and connections, the busy-input queue, the approval broker, steer and live settings) and no census re-recorded it, so develop was already red on this dimension before this task; this task adds the last 8 lines \u2014 `liveHostFor` now also recognises the host a session was bound to through the driver's own session row, which is what keeps `run` on the host it started when the driver was handed one directly. The driver and its private helpers remain one cohesive unit; splitting them into a new leaf module to fit a wiring fix would add an import-graph node under AC-394 for no behavioural gain, which is not the honest shape of this change. No entry is raised above its current reading. A RECORDED CHANGE (2026-10-30, gap-mcp-session-steer-tool): `server/index.ts` 2849\u21922862. This task adds the `sessionSteer` bag to the MCP gateway's `writeTools` literal \u2014 the three process seams `session_steer` answers from (the session row's provider reader, the provider registry's host-driver resolver, and the session-hosts manager's live-host read) \u2014 so an external MCP client can steer a resident turn without a second send path. The increase IS the wiring: the tool itself is a new module, and the composition root is the only place the process singletons can be bound. No other entry is raised. | 2026-10-30: server/shared/ports/mcp-gateway-client.port.ts enters moduleMutableState at 1 \u2014 the installed-reader slot of the new provider-facing MCP-gateway port, the same shape as every existing port in that directory. No other reading rose. | 2026-10-30 (gap-cockpit-session-start-model-settings-ui): `src/shared/api.ts` 1788\u21921799 and `src/shared/types.ts` 4700\u21924719. This task gives the cockpit card new-conversation launch selection a settings surface: the two wire mirrors gain the flat six-field reading and its two api calls (`api.settings.cockpitSessionStart` / `saveCockpitSessionStart`). The increase IS the contract \u2014 the client must read the same server field the `session.start` executor uses, and both ends are hand-copied mirrors checked field-for-field by the wire-contract criterion, so the shape exists twice by design. No other reading rose. A RECORDED CHANGE (2026-10-31, claude-codex-new-session-default-resident): `server/modules/providers/provider.routes.ts` 1122\u21921152, `server/modules/providers/services/sessions.service.ts` 1327\u21921390, `server/shared/types.ts` 5327\u21925352, `src/shared/api.ts` 1799\u21921809 and `src/shared/types.ts` 4719\u21924743. This task moves the new-session lifecycle default into the provider capability matrix and writes the resolved mode in the session row's own INSERT. The capability service gains the provider-owned `defaultLifecycleMode` resolution (support and default are separate readings), and `sessions.service.ts` gains `resolveCreateLifecycleMode` \u2014 one place that gives an explicit mode precedence, falls back to that declared default, and refuses an unknown or unsupported mode before any row exists, so the HTTP, MCP and Live Voice entry points all create through it instead of each hard-coding a provider-id branch. The two shared types files each gain the same `defaultLifecycleMode` / `lifecycleMode` wire vocabulary: the contract is the server/client seam, both ends are hand-copied and `wireContractTypeSync.test.ts` compares them field-for-field, so no new module can carry the shape instead. `src/shared/api.ts` gains the client-side parse of the same capability field. The increases ARE the deliverable; no entry is raised above its current measured reading, and no baselined file grew for any other reason. A RECORDED CHANGE (2026-10-31, gap-session-binding-consistency): `server/modules/websocket/services/chat-run-registry.service.ts` 1401\u21921436. The increase IS the wiring for this task's single binding-write seam: the run record gains `bindingAtStart` (the binding a run was admitted under, frozen at startRun) and `recordProviderSessionId` now writes through `sessionBindingService`, whose outcome decides whether a late `session_created` is a write, a confirmation, or a rejection. The added lines are that field, its docblocks and the guarded write path; the repository half of the same change SHRANK `server/modules/database/repositories/sessions.db.ts` 1479\u21921422 (the binding writes moved to the new baseline-external sibling `server/modules/database/repositories/session-binding.db.ts`). No other entry is raised. A RECORDED CHANGE (2026-10-31, gap-quay-provider-transcript-prose): `server/modules/providers/list/codex/codex-sessions.provider.ts` 2348\u21922361, `server/shared/types.ts` 5352\u21925373 and `src/shared/types.ts` 4743\u21924749. The increase IS this task's deliverable at each site. Both provider sessions classes gain `readTranscriptMessage(row)` \u2014 the capability that lets Quay resolve prose through the provider registry instead of re-implementing each provider's transcript format \u2014 and the two lines of that method are the wiring itself; the recognition rules live in the pre-existing `claude-transcript-format.ts` / `codex-transcript-format.ts`, so no new module carries them. `server/shared/types.ts` gains the narrow `ProviderTranscriptMessage` contract (role/text/timestamp, deliberately smaller than `NormalizedMessage`) that both providers and the Quay consumer share, and `src/shared/types.ts` gains the `transcript: 'ok' | 'unreadable'` field on the wire reading `QuaySessionMentionsReading`, which is what lets the popover distinguish an unreadable transcript from a successful empty reading; both wire ends are hand-copied and a TypeSync criterion compares them field-for-field. A RECORDED CHANGE (2026-10-31, gap-ac178-new-session-switch-gate-drops-nonmatrix-provider): `src/modules/chat-session/hooks/useChatProviderState.ts` 913\u2192923. The increase is the adoption guard this task's defect fix requires: the session-adoption effect must refuse a `__provider` that has no row in the capability matrix, otherwise a debug session's runtime id overwrites the validated preference and the new-session lifecycle gate (`canToggleNewSessionLifecycle`) goes false, hiding the composer's resident switch. Three lines are the guard and six are the comment stating why the matrix check is the boundary; the check belongs at the one place a session's provider is adopted, so no new module carries it instead. No other entry is raised. A RECORDED CHANGE (2026-10-31, gap-codex-resident-blocked-context-events): `server/index.ts` 2862\u21922871 and `server/modules/providers/list/codex/codex-host-driver.provider.ts` 835\u2192841. This task states the Codex resident \u300cneeds a person\u300d fact on the context-event stream. `server/index.ts` gains the install of the blocked-event adapter beside the existing session-run install \u2014 the composition root is the only place that writer is built \u2014 and `codex-host-driver.provider.ts` gains the one field, the one import and the four call sites that hand a settled turn to the new rule; the rule itself (which failed/interrupted turn left a card open) lives in the new `codex-resident-blocked-events.ts`, so the driver grows by the wiring rather than by a second copy. The approval arm lives in `codex-approval-broker.ts`, which stays under the 800-line floor, and the writer's new kinds were merged into existing constant lines so `context-event-writer.ts` does not grow at all. No entry is raised above its current reading. A RECORDED CHANGE (2026-10-31, census re-sync): `src/modules/chat-composer/composer/ChatComposer.tsx` 1633\u21921644 is raised to its measured value on develop. The file is byte-identical to the develop tip in this tree and is outside this task's delta; the growth landed with develop commit 61caec01a after the census captured 1633, and no commit re-recorded it, so AC1/AC4 redded a tree neither this task nor its delta touches. This is a stale-census re-sync, not an accommodation of new growth: the recorded value equals the measured one, and no other entry is raised for this file. A RECORDED CHANGE (2026-10-31, gap-codex-token-usage-snapshot-semantics): `src/shared/types.ts` 4749\u21924768 and `src/modules/chat-composer/composer/ChatComposer.tsx` 1633\u21921644 are raised to their measured values. The first is this task's wire vocabulary: the shared `TokenUsageCounts` shape and the `CostCommandData.tokenUsage`/`tokenBreakdown` fields describe the same cumulative/latest-request reading on both ends of the `/cost` response, so the contract belongs in `src/shared/types.ts` and no new module carries it instead. The second is a stale-census re-sync: `ChatComposer.tsx` is byte-identical to the develop tip and its growth landed in 61caec01a, after the 2d86ad361 census captured 1633; no commit re-recorded it, so the criterion redded a file this task does not touch. Neither entry is raised above its current reading, and no other entry is raised. A RECORDED CHANGE (2026-11-01, gap-cost-panel-cache-hit-ratio-and-cachewrite-bar): `src/shared/types.ts` 4768\u21924772. The increase is the wire vocabulary this task adds to the same `/cost` contract: `TokenUsageCounts` gains the `cacheWriteTokens?` quantity (mirrored field-for-field by the server's `ProviderTokenUsageCounts`, which the TypeSync criterion compares) and `CostCommandData.tokenBreakdown` gains `cacheWrite?`, each with its one-line doc comment. The shape is stated twice by hand by design, so the client half belongs in this shared types file and no new module carries it instead. No other entry is raised. A RECORDED CHANGE (2026-11-01, cockpit-knowledge-decision-handoff): `server/shared/types.ts` 5373\u21925482 and `src/shared/types.ts` 4772\u21924881 are raised to their measured values. The increase is the knowledge-suggestion wire vocabulary this task adds to the cockpit card contract: `CockpitKnowledgeCase`/`CockpitKnowledgePlan`/`CockpitKnowledgeVerification`/`CockpitKnowledgeDecision`/`CockpitKnowledgeCaseState` plus the `knowledge` block on `CockpitCard` and the `decision`/`confirmationRef` fields on `CockpitCardOption` and `CockpitCardFeedback`, each with the doc comments that state what the provider owns, what the cockpit only reads, and what a caller may never forge. Both wire ends are hand-copied and a TypeSync criterion compares them field-for-field, so the shape exists twice by design; no new module carries it instead. No other entry is raised above its current reading. A RECORDED CHANGE (2026-11-01, knowledge-application-fact-contract): `server/index.ts` 2871\u21922905. The increase is this task's composition-root wiring: the `knowledge_facts` read tool's fact source is constructed in `server/index.ts` and bound to the process's real session repository, session host manager, run registry and project lookup, so the gateway answers through the same injected services every other read tool uses rather than through a second private assembly. The adapter itself lives in the new `server/knowledge-facts-wiring.ts`; only the constructor call and its dep bag belong at the composition root. A RECORDED CHANGE (2026-11-01, gap-authoritative-token-reading-used-scope-elimination): `src/modules/chat-session/hooks/useChatSessionState.ts` hookStateHeavy 51\u219252. The task's deliverable is the split of the one dual-meaning `tokenBudget` state into two named channels \u2014 `liveFrame`, the realtime frame the composer counter renders, and `authoritativeReading`, the only reading `/cost` may send \u2014 and two independently-written states are the honest shape of that split: one object would hide which channel each of the ten call sites writes. The file's oversize reading is unchanged at 2127, so this is the only entry that moves. No other entry is raised. A RECORDED CHANGE (2026-11-02, pending-approval-dedup): `server/modules/providers/services/provider-runtime.service.ts` 1282\u21921288. The subscribe acknowledgement must read a shared approval registry once per provider: Claude and Codex expose the same ApprovalRequestsService, so the old fan-out listed the same pending question twice and the client drew two identical answer panels. The six added lines are the per-call reader set and the guard; no other entry moves. A RECORDED CHANGE (2026-11-02, gap-ratchet-baseline-knowledge-facts-wiring): `server/knowledge-facts-wiring.ts` is a NEW `oversizeFiles` entry at 842 \u2014 \u57fa\u7ebf\u5916\u2192842. The file was introduced by 9be415857 as the effective-config launchRequest slice's wiring composition root, and 842 is the real line count that landed with that delivery; this task only registers the existing delivery, it does not grow the file (zero diff on it), and splitting it would be an independent refactor outside this slice. Recording the reading is the honest shape of the change; no other entry is raised. A RECORDED CHANGE (2026-11-02, codex-provider-config-surface): `server/shared/types.ts` 5482\u21925526 and `src/shared/types.ts` 4881\u21924916. This task introduces the Codex upstream provider wire contract (`CodexModelProvider`, `CodexModelProvidersReading`); both ends carry the shape by design because the server tree is not part of the browser bundle and `src/shared/tests/wireContractTypeSync.test.ts` compares the two declarations field-for-field. The increase IS the deliverable \u2014 no new module carries the types instead, because the contract is the server/client seam \u2014 and no other entry is raised. A RECORDED CHANGE (2026-11-02, gap-cockpit-knowledge-title-statement-on-card): `server/shared/types.ts` 5526\u21925537 and `src/shared/types.ts` 4916\u21924927. The cockpit knowledge case type gains the two optional display fields `title` and `statement` \u2014 two field lines plus their doc comment on each side \u2014 so a card can draw what the knowledge entry says before a person decides; both ends carry the shape by design because the server tree is not part of the browser bundle and `src/shared/tests/cockpitCardTypeSync.test.ts` compares the declarations field-for-field. The increase IS the deliverable \u2014 no new module carries the fields instead, because the contract is the server/client seam \u2014 and no other entry is raised. A RECORDED CHANGE (2026-11-02, gap-cloudpit-brand-env-reader-wiring): `server/modules/browser-use/browser-use.service.ts` 920\u2192958. This task wires the brand env reader (`CLOUDPIT_*` first, `CLOUDCLI_*` fallback) into the browser-use service's limit reads and the MCP subprocess env write. The increase is that wiring: the three default constants, the exported `readBrowserUseEnvDefaults(env, warn)` seam (exported so the wiring criterion drives the exact production reads with an injected environment instead of mutating this process), the once-per-process resolved reader that replaces the two inline `process.env.CLOUDCLI_*` parses, and the new-spelling-plus-transitional-legacy-alias env bag that `registerAgentMcp` hands to every provider. No new module carries the reader instead: the reads and the subprocess env write are the same service's env surface, and moving the seam to a second file would put the production reads and their criterion in different modules. No other entry is raised. A RECORDED CHANGE (2026-11-03, codex-model-entry-provider-binding): `server/modules/providers/provider.routes.ts` 1152\u21921162, `server/shared/types.ts` 5537\u21925552 and `src/shared/types.ts` 4927\u21924935. This task gives a custom model entry an optional `codexProviderId` that binds it to a project Codex upstream provider. The three increases are that field and its route parse: the config shape gains one documented optional member on each side (the server tree is not part of the browser bundle, and `wireContractTypeSync` compares the two declarations field-for-field, so the mirror line IS the deliverable), and the route gains the string guard plus the pass-through line that carries it into the service. No new module carries the field instead: the contract is the server/client seam and the parse belongs to the route that already owns `config`. No other entry is raised. A RECORDED CHANGE (2026-11-03, codex-session-provider-id-binding): `server/modules/database/migrations.ts` 1167\u21921190, `server/modules/providers/provider.routes.ts` 1162\u21921173, `server/modules/providers/services/sessions.service.ts` 1390\u21921394, `server/modules/websocket/services/chat-control.service.ts` 1116\u21921149, `server/modules/websocket/services/chat-websocket.service.ts` 1970\u21921994 and `server/shared/types.ts` 5552\u21925572. This task records the session-level upstream-provider binding (AC-462): the migrations file gains the `model_provider_id` column migration, the sessions service copies the binding onto a fork, `server/shared/types.ts` states the two new members of `ProviderSessionModel` (`modelProviderId`, `modelProviderProblem`) that every display surface now reads, the providers route answers the fallback selection with them, and the two websocket files add the pre-admission switch refusal (dispatchRun checks before it reserves a run, because the recording write it guards runs after `startRun`) plus the control-service propagation of that refusal code. The binding RULES themselves did not grow any of these files: they live in the new leaves `session-provider-binding.ts` and `session-model-resolver.ts` (both under 200 lines), and the resolver extraction LOWERED `provider-models.service.ts` 765\u2192737, which is why that file is absent from this map. A RECORDED CHANGE (2026-11-03, codex-resident-provider-injection): `server/modules/providers/list/codex/codex-host-driver.provider.ts` 841\u2192855. This task gives the resident host driver a per-session app-server launch so a session bound to a project Codex upstream provider is spawned with `-c model_provider` (Codex 0.166 refuses the turn otherwise). The growth is the host-id launch map plus the two call sites that move the compiled launch from `startResidentSession` to `startHost` (which runs before `bind`) and pass it to `connectionFor`; the compilation itself and the option reader live in the new leaf `codex-resident-provider-launch.ts`, which kept the increase to these fourteen lines rather than the ~50 an inline implementation needed. `server/modules/providers/services/provider-runtime.service.ts` 1288\u21921291 is raised for the same task: `defaultResidentLaunchOptions` states the session row's `model_provider_id` in the launch bag the restore pass hands `startResidentSession` (one documented line plus the spread that writes it), so a restarted resident host re-injects the provider its thread was created under instead of dialling Codex's `openai` default. No other entry is raised. A RECORDED CHANGE (2026-11-03, codex-provider-advanced-capabilities): `server/shared/types.ts` 5572\u21925595 and `src/shared/types.ts` 4935\u21924958. This task adds nine optional advanced-connection fields to `CodexModelProvider` on both ends (the two declarations are hand-copied and `wireContractTypeSync` compares them field-for-field, so the shape exists twice by design, not by duplication), plus the two optional catalog window fields on `ProviderModelOption`. The increase is exactly those declarations and their doc comments; no other entry is raised.",
|
|
4
4
|
"oversizeFiles": {
|
|
5
5
|
"server/index.ts": 2905,
|
|
6
6
|
"server/knowledge-facts-wiring.ts": 842,
|
|
7
7
|
"server/modules/architecture/generator.ts": 1591,
|
|
8
8
|
"server/modules/architecture/service.ts": 1732,
|
|
9
|
-
"server/modules/browser-use/browser-use.service.ts":
|
|
9
|
+
"server/modules/browser-use/browser-use.service.ts": 958,
|
|
10
10
|
"server/modules/context-events/context-event-writer.ts": 939,
|
|
11
|
-
"server/modules/database/migrations.ts":
|
|
11
|
+
"server/modules/database/migrations.ts": 1190,
|
|
12
12
|
"server/modules/database/repositories/sessions.db.ts": 1479,
|
|
13
13
|
"server/modules/debug-agent/debug-agent.engine.ts": 1090,
|
|
14
14
|
"server/modules/debug-agent/debug-agent.host-driver.ts": 929,
|
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
"server/modules/providers/list/claude/claude-resident-lifecycle-outcome-handlers.ts": 1256,
|
|
23
23
|
"server/modules/providers/list/claude/claude-runtime.provider.ts": 2433,
|
|
24
24
|
"server/modules/providers/list/claude/claude-sessions.provider.ts": 1792,
|
|
25
|
-
"server/modules/providers/list/codex/codex-host-driver.provider.ts":
|
|
25
|
+
"server/modules/providers/list/codex/codex-host-driver.provider.ts": 855,
|
|
26
26
|
"server/modules/providers/list/codex/codex-sessions.provider.ts": 2361,
|
|
27
|
-
"server/modules/providers/provider.routes.ts":
|
|
27
|
+
"server/modules/providers/provider.routes.ts": 1173,
|
|
28
28
|
"server/modules/providers/services/claude-activity-task-reducer.service.ts": 958,
|
|
29
|
-
"server/modules/providers/services/provider-runtime.service.ts":
|
|
29
|
+
"server/modules/providers/services/provider-runtime.service.ts": 1291,
|
|
30
30
|
"server/modules/providers/services/session-conversations-search.service.ts": 1429,
|
|
31
31
|
"server/modules/providers/services/sessions-watcher.service.ts": 865,
|
|
32
|
-
"server/modules/providers/services/sessions.service.ts":
|
|
32
|
+
"server/modules/providers/services/sessions.service.ts": 1394,
|
|
33
33
|
"server/modules/quay/quay.service.ts": 2993,
|
|
34
34
|
"server/modules/resident-ledger/ledger.ts": 805,
|
|
35
35
|
"server/modules/session-hosts/session-host-manager.service.ts": 1745,
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"server/modules/voice-realtime/voice-realtime-ws-proxy.service.ts": 5569,
|
|
45
45
|
"server/modules/voice/voice-capture.ts": 1086,
|
|
46
46
|
"server/modules/voice/voice.service.ts": 1855,
|
|
47
|
-
"server/modules/websocket/services/chat-control.service.ts":
|
|
47
|
+
"server/modules/websocket/services/chat-control.service.ts": 1149,
|
|
48
48
|
"server/modules/websocket/services/chat-run-registry.service.ts": 1436,
|
|
49
|
-
"server/modules/websocket/services/chat-websocket.service.ts":
|
|
50
|
-
"server/shared/types.ts":
|
|
49
|
+
"server/modules/websocket/services/chat-websocket.service.ts": 1994,
|
|
50
|
+
"server/shared/types.ts": 5595,
|
|
51
51
|
"server/shared/utils.ts": 1930,
|
|
52
52
|
"shared/asr/asrInvariants.ts": 1760,
|
|
53
53
|
"shared/asr/asrRegistry.ts": 1043,
|
|
@@ -70,16 +70,16 @@
|
|
|
70
70
|
"src/modules/chat-tool-configs/configs/toolConfigs.ts": 822,
|
|
71
71
|
"src/modules/chat-voice/utils/voice/voiceContextPack.ts": 821,
|
|
72
72
|
"src/modules/chat-voice/voice-realtime/useVoiceRealtimeSession.ts": 2833,
|
|
73
|
-
"src/modules/cockpit/CockpitCard.tsx": 983,
|
|
74
|
-
"src/modules/cockpit/cockpitCardController.ts": 1797,
|
|
75
|
-
"src/modules/cockpit/CockpitPage.tsx": 1900,
|
|
73
|
+
"src/modules/cockpit/cards/CockpitCard.tsx": 983,
|
|
74
|
+
"src/modules/cockpit/cards/cockpitCardController.ts": 1797,
|
|
75
|
+
"src/modules/cockpit/workspace/CockpitPage.tsx": 1900,
|
|
76
76
|
"src/modules/git-panel/hooks/useGitPanelController.ts": 845,
|
|
77
77
|
"src/modules/project-workspace/hooks/useProjectsState.ts": 1457,
|
|
78
78
|
"src/modules/quay/QuayPanel.tsx": 1176,
|
|
79
79
|
"src/modules/shell/utils/mobileTerminalSelection.ts": 1061,
|
|
80
80
|
"src/modules/sidebar/hooks/useSidebarController.ts": 1343,
|
|
81
81
|
"src/shared/api.ts": 1809,
|
|
82
|
-
"src/shared/types.ts":
|
|
82
|
+
"src/shared/types.ts": 4958,
|
|
83
83
|
"src/shared/voiceClientAsrWorker.ts": 1533
|
|
84
84
|
},
|
|
85
85
|
"moduleMutableState": {
|
|
@@ -200,7 +200,7 @@
|
|
|
200
200
|
"hookStateHeavy": {
|
|
201
201
|
"src/modules/chat-session/hooks/useChatSessionState.ts": 52,
|
|
202
202
|
"src/modules/chat-voice/voice-realtime/useVoiceRealtimeSession.ts": 62,
|
|
203
|
-
"src/modules/cockpit/CockpitPage.tsx": 32,
|
|
203
|
+
"src/modules/cockpit/workspace/CockpitPage.tsx": 32,
|
|
204
204
|
"src/modules/git-panel/hooks/useGitPanelController.ts": 21,
|
|
205
205
|
"src/modules/project-workspace/hooks/useProjectsState.ts": 23,
|
|
206
206
|
"src/modules/sidebar/hooks/useSidebarController.ts": 35
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The Cloudpit brand criterion: the `BRAND` identity table and the
|
|
3
|
-
* `CLOUDPIT_
|
|
2
|
+
* The Cloudpit brand criterion: the `BRAND` identity table and the v3.0
|
|
3
|
+
* `CLOUDPIT_*`-only environment reader.
|
|
4
4
|
*
|
|
5
5
|
* Every leg drives the real reader with an in-memory environment; the `BRAND`
|
|
6
6
|
* reading comes from the TypeScript syntax tree so a comment or a string
|
|
7
7
|
* literal that merely spells a field cannot satisfy the assertion.
|
|
8
8
|
*
|
|
9
|
+
* v3.0 RETIREMENT: the reader no longer accepts the legacy `CLOUDCLI_*`
|
|
10
|
+
* spelling. A legacy-only environment reads absent (and the caller's shipped
|
|
11
|
+
* default applies); there is no fallback reading and no deprecation warning.
|
|
12
|
+
*
|
|
9
13
|
* Run directly:
|
|
10
14
|
* npx tsx --tsconfig server/tsconfig.json --test server/shared/tests/cloudpit-brand-env.test.ts
|
|
11
15
|
*/
|
|
@@ -68,11 +72,9 @@ function readBrandFields(): Record<string, string> {
|
|
|
68
72
|
return fields;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
/** Build a reader over `env
|
|
75
|
+
/** Build a reader over `env`. */
|
|
72
76
|
function readWith(env: Record<string, string | undefined>) {
|
|
73
|
-
|
|
74
|
-
const reader = createBrandEnvReader({ env, warn: (message) => warnings.push(message) });
|
|
75
|
-
return { reader, warnings };
|
|
77
|
+
return createBrandEnvReader({ env });
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
test('AC1: BRAND carries the Cloudpit identity read from the syntax tree', () => {
|
|
@@ -85,59 +87,127 @@ test('AC1: BRAND carries the Cloudpit identity read from the syntax tree', () =>
|
|
|
85
87
|
});
|
|
86
88
|
});
|
|
87
89
|
|
|
88
|
-
test('AC2 legacy-only: CLOUDCLI_X
|
|
89
|
-
const
|
|
90
|
+
test('AC2 legacy-only: CLOUDCLI_X is ignored and the read is absent', () => {
|
|
91
|
+
const reader = readWith({ CLOUDCLI_X: 'old' });
|
|
90
92
|
|
|
91
|
-
assert.deepEqual(reader.read('X'), { value:
|
|
92
|
-
assert.equal(warnings.length, 1, 'using the legacy spelling must warn exactly once');
|
|
93
|
+
assert.deepEqual(reader.read('X'), { value: undefined, source: 'absent', key: 'CLOUDPIT_X' });
|
|
93
94
|
});
|
|
94
95
|
|
|
95
|
-
test('AC2 new-only: CLOUDPIT_X supplies the value
|
|
96
|
-
const
|
|
96
|
+
test('AC2 new-only: CLOUDPIT_X supplies the value and is marked new', () => {
|
|
97
|
+
const reader = readWith({ CLOUDPIT_X: 'new' });
|
|
97
98
|
|
|
98
99
|
assert.deepEqual(reader.read('X'), { value: 'new', source: 'new', key: 'CLOUDPIT_X' });
|
|
99
|
-
assert.deepEqual(warnings, [], 'the new spelling is not deprecated');
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
test('AC2 both-set: the new spelling wins and
|
|
103
|
-
const
|
|
102
|
+
test('AC2 both-set: the new spelling wins and the legacy value is never consulted', () => {
|
|
103
|
+
const reader = readWith({ CLOUDPIT_X: 'new', CLOUDCLI_X: 'old' });
|
|
104
104
|
|
|
105
105
|
assert.deepEqual(reader.read('X'), { value: 'new', source: 'new', key: 'CLOUDPIT_X' });
|
|
106
|
-
assert.deepEqual(warnings, [], 'a legacy value shadowed by the new one must not warn');
|
|
107
106
|
});
|
|
108
107
|
|
|
109
108
|
test('AC3 absent: neither spelling set reads absent with no value', () => {
|
|
110
|
-
const
|
|
109
|
+
const reader = readWith({});
|
|
111
110
|
|
|
112
111
|
const reading = reader.read('X');
|
|
113
112
|
assert.equal(reading.value, undefined);
|
|
114
113
|
assert.equal(reading.source, 'absent');
|
|
115
114
|
assert.equal(reading.key, 'CLOUDPIT_X', 'absent reads name the canonical key to set');
|
|
116
|
-
assert.deepEqual(warnings, []);
|
|
117
115
|
});
|
|
118
116
|
|
|
119
|
-
test('AC3 empty new value: CLOUDPIT_X=""
|
|
120
|
-
const
|
|
117
|
+
test('AC3 empty new value: CLOUDPIT_X="" reads absent and does NOT fall back to the legacy value', () => {
|
|
118
|
+
const reader = readWith({ CLOUDPIT_X: '', CLOUDCLI_X: 'old' });
|
|
121
119
|
|
|
122
|
-
assert.deepEqual(reader.read('X'), { value:
|
|
123
|
-
assert.equal(warnings.length, 1);
|
|
120
|
+
assert.deepEqual(reader.read('X'), { value: undefined, source: 'absent', key: 'CLOUDPIT_X' });
|
|
124
121
|
});
|
|
125
122
|
|
|
126
|
-
test('
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
test('AC1: neither reader source carries the legacy env spelling in code', () => {
|
|
124
|
+
const sources: Array<[string, ts.ScriptKind]> = [
|
|
125
|
+
['server/shared/brand.ts', ts.ScriptKind.TS],
|
|
126
|
+
['electron/brandEnv.js', ts.ScriptKind.JS],
|
|
127
|
+
];
|
|
128
|
+
for (const [relativePath, kind] of sources) {
|
|
129
|
+
const filePath = path.join(REPO_ROOT, relativePath);
|
|
130
|
+
const sourceFile = ts.createSourceFile(
|
|
131
|
+
filePath,
|
|
132
|
+
readFileSync(filePath, 'utf8'),
|
|
133
|
+
ts.ScriptTarget.Latest,
|
|
134
|
+
true,
|
|
135
|
+
kind,
|
|
136
|
+
);
|
|
137
|
+
const literals: string[] = [];
|
|
138
|
+
const visit = (node: ts.Node): void => {
|
|
139
|
+
if (
|
|
140
|
+
ts.isStringLiteral(node)
|
|
141
|
+
|| ts.isNoSubstitutionTemplateLiteral(node)
|
|
142
|
+
|| ts.isTemplateHead(node)
|
|
143
|
+
|| ts.isTemplateMiddle(node)
|
|
144
|
+
|| ts.isTemplateTail(node)
|
|
145
|
+
) {
|
|
146
|
+
literals.push(node.text);
|
|
147
|
+
}
|
|
148
|
+
node.forEachChild(visit);
|
|
149
|
+
};
|
|
150
|
+
sourceFile.forEachChild(visit);
|
|
151
|
+
assert.deepEqual(
|
|
152
|
+
literals.filter((literal) => literal.includes('CLOUDCLI_')),
|
|
153
|
+
[],
|
|
154
|
+
`${relativePath} must not build a legacy env key (comments are not evaluated)`,
|
|
155
|
+
);
|
|
156
|
+
assert.ok(
|
|
157
|
+
literals.some((literal) => literal.includes('CLOUDPIT_')),
|
|
158
|
+
`${relativePath} must still build the canonical env key`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
132
161
|
});
|
|
133
162
|
|
|
134
|
-
test('AC3 reader isolation: two readers each warn once for the same legacy key', () => {
|
|
135
|
-
const first = readWith({ CLOUDCLI_X: 'old' });
|
|
136
|
-
const second = readWith({ CLOUDCLI_X: 'old' });
|
|
137
163
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Every brand name the production wiring points read (Electron main/localServer,
|
|
166
|
+
* serverInstaller, browser-use service and its MCP entry) resolved through the
|
|
167
|
+
* reader: the canonical spelling supplies the value, the legacy spelling is
|
|
168
|
+
* ignored, and an absent pair reads absent. This pins the *names* as well as the
|
|
169
|
+
* semantics, so a wiring point that invents a name the reader does not recognise
|
|
170
|
+
* turns red here instead of silently reading `undefined`.
|
|
171
|
+
*/
|
|
172
|
+
const WIRED_BRAND_ENV_NAMES = [
|
|
173
|
+
'CONTROL_PLANE_URL',
|
|
174
|
+
'DESKTOP_LOCAL_SERVER_URL',
|
|
175
|
+
'LOCAL_SERVER_URL',
|
|
176
|
+
'DESKTOP_LOCAL_SERVER_PORT',
|
|
177
|
+
'SERVER_PORT',
|
|
178
|
+
'USE_INSTALLED_SERVER',
|
|
179
|
+
'SERVER_BUNDLE_URL',
|
|
180
|
+
'SERVER_BUNDLE_RELEASE_TAG',
|
|
181
|
+
'SERVER_DIR',
|
|
182
|
+
'BROWSER_USE_MAX_SESSIONS_PER_OWNER',
|
|
183
|
+
'BROWSER_USE_SESSION_TTL_MS',
|
|
184
|
+
'BROWSER_USE_INSTALL_TIMEOUT_MS',
|
|
185
|
+
'BROWSER_USE_API_URL',
|
|
186
|
+
'BROWSER_USE_MCP_TOKEN',
|
|
187
|
+
'BROWSER_USE_API_TIMEOUT_MS',
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
test('AC3 wiring names: each brand name resolves new > absent, never legacy', () => {
|
|
191
|
+
for (const name of WIRED_BRAND_ENV_NAMES) {
|
|
192
|
+
const both = readWith({ [`CLOUDPIT_${name}`]: 'new', [`CLOUDCLI_${name}`]: 'old' });
|
|
193
|
+
assert.deepEqual(
|
|
194
|
+
both.read(name),
|
|
195
|
+
{ value: 'new', source: 'new', key: `CLOUDPIT_${name}` },
|
|
196
|
+
`${name}: the new spelling must win`,
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
const legacy = readWith({ [`CLOUDCLI_${name}`]: 'old' });
|
|
200
|
+
assert.deepEqual(
|
|
201
|
+
legacy.read(name),
|
|
202
|
+
{ value: undefined, source: 'absent', key: `CLOUDPIT_${name}` },
|
|
203
|
+
`${name}: the legacy spelling must no longer be read`,
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const absent = readWith({});
|
|
207
|
+
assert.deepEqual(
|
|
208
|
+
absent.read(name),
|
|
209
|
+
{ value: undefined, source: 'absent', key: `CLOUDPIT_${name}` },
|
|
210
|
+
`${name}: an unset pair reads absent`,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
143
213
|
});
|