@rubytech/create-maxy-code 0.1.488 → 0.1.490
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/package.json +1 -1
- package/payload/platform/docs/superpowers/plans/2026-07-22-task-1899-reconcile-report-only.md +748 -0
- package/payload/platform/docs/superpowers/plans/2026-07-22-task-1910-two-way-portal-exchange.md +1716 -0
- package/payload/platform/docs/superpowers/specs/2026-07-22-task-1899-reconcile-report-only-design.md +121 -0
- package/payload/platform/docs/superpowers/specs/2026-07-22-task-1910-two-way-portal-exchange-design.md +103 -0
- package/payload/platform/lib/graph-mcp/dist/__tests__/schema-cypher-parser.test.js +51 -0
- package/payload/platform/lib/graph-mcp/dist/__tests__/schema-cypher-parser.test.js.map +1 -1
- package/payload/platform/lib/graph-mcp/dist/schema-cypher-parser.d.ts +2 -2
- package/payload/platform/lib/graph-mcp/dist/schema-cypher-parser.d.ts.map +1 -1
- package/payload/platform/lib/graph-mcp/dist/schema-cypher-parser.js +20 -4
- package/payload/platform/lib/graph-mcp/dist/schema-cypher-parser.js.map +1 -1
- package/payload/platform/lib/graph-mcp/src/__tests__/schema-cypher-parser.test.ts +55 -0
- package/payload/platform/lib/graph-mcp/src/schema-cypher-parser.ts +19 -4
- package/payload/platform/lib/graph-style/dist/index.d.ts +24 -0
- package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-style/dist/index.js +25 -1
- package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-style/src/__tests__/additional-base-labels.test.ts +22 -0
- package/payload/platform/lib/graph-style/src/index.ts +27 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js +15 -0
- package/payload/platform/lib/storage-broker/dist/__tests__/audit.test.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/audit.d.ts +34 -1
- package/payload/platform/lib/storage-broker/dist/audit.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/audit.js +28 -4
- package/payload/platform/lib/storage-broker/dist/audit.js.map +1 -1
- package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts +13 -0
- package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
- package/payload/platform/lib/storage-broker/dist/cf-exec.js +22 -0
- package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
- package/payload/platform/lib/storage-broker/src/__tests__/audit.test.ts +21 -0
- package/payload/platform/lib/storage-broker/src/audit.ts +67 -3
- package/payload/platform/lib/storage-broker/src/cf-exec.ts +48 -0
- package/payload/platform/neo4j/schema.cypher +105 -0
- package/payload/platform/plugins/admin/skills/agent-builder/references/agent-pattern.md +34 -5
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +8 -2
- package/payload/platform/plugins/cloudflare/PLUGIN.md +22 -2
- package/payload/platform/plugins/cloudflare/bin/portal-index-push.mjs +161 -41
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-delete-withdraw.test.ts +95 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-directory-listing.test.ts +75 -13
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-index-push.test.ts +216 -16
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-indexed-download.test.ts +38 -2
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-moved-download.test.ts +83 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-schema-shape.test.ts +48 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-sign.test.ts +62 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-target.test.ts +103 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-upload-multipart.test.ts +211 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-upload-target.test.ts +168 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-uploads-listing.test.ts +138 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/template-config.test.ts +179 -0
- package/payload/platform/plugins/cloudflare/mcp/__tests__/upload-route.test.ts +14 -13
- package/payload/platform/plugins/cloudflare/skills/data-portal/SKILL.md +87 -13
- package/payload/platform/plugins/cloudflare/skills/data-portal/schema.sql +87 -9
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/portal-sign.mjs +74 -0
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/target.ts +91 -0
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/_lib/types.ts +23 -0
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/delete.ts +45 -0
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/download.ts +72 -5
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/files.ts +80 -13
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/functions/api/upload.ts +358 -16
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/index.html +12 -1
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/portal.css +45 -0
- package/payload/platform/plugins/cloudflare/skills/data-portal/template/portal.js +258 -21
- package/payload/platform/plugins/docs/references/calendar-booking.md +5 -1
- package/payload/platform/plugins/docs/references/internals.md +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-cypher-drift.test.js +61 -31
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-cypher-drift.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/PLUGIN.md +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/index.js +2 -2
- package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js +70 -5
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/getUserTimezone.test.js +31 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/getUserTimezone.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +31 -4
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +18 -7
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.d.ts +15 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js +24 -11
- package/payload/platform/plugins/scheduling/mcp/dist/lib/neo4j.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +5 -122
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +84 -5
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
- package/payload/platform/scripts/__tests__/quarantine-restore.test.sh +143 -0
- package/payload/platform/scripts/quarantine-restore.mjs +175 -0
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts +24 -7
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js +52 -74
- package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +11 -8
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +32 -0
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +32 -2
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/targets.d.ts +6 -1
- package/payload/platform/services/whatsapp-channel/dist/targets.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/targets.js +6 -0
- package/payload/platform/services/whatsapp-channel/dist/targets.js.map +1 -1
- package/payload/platform/templates/account-schema/SCHEMA.md +7 -4
- package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
- package/payload/platform/templates/agents/passive/IDENTITY.md +6 -0
- package/payload/platform/templates/agents/public/IDENTITY.md +6 -0
- package/payload/platform/templates/specialists/agents/citation-auditor.md +6 -0
- package/payload/platform/templates/specialists/agents/coding-assistant.md +6 -0
- package/payload/platform/templates/specialists/agents/compiled-truth-rewriter.md +6 -0
- package/payload/platform/templates/specialists/agents/content-producer.md +6 -0
- package/payload/platform/templates/specialists/agents/data-manager.md +6 -0
- package/payload/platform/templates/specialists/agents/database-operator.md +6 -0
- package/payload/platform/templates/specialists/agents/librarian.md +6 -0
- package/payload/platform/templates/specialists/agents/personal-assistant.md +6 -0
- package/payload/platform/templates/specialists/agents/project-manager.md +6 -0
- package/payload/platform/templates/specialists/agents/public-session-reviewer.md +6 -0
- package/payload/platform/templates/specialists/agents/research-assistant.md +7 -1
- package/payload/platform/templates/specialists/agents/typed-edge-classifier.md +6 -0
- package/payload/premium-plugins/writer-craft/agents/writer-craft--manuscript-reviewer.md +6 -0
- package/payload/server/{chunk-REWXLAPC.js → chunk-KZFE3MOY.js} +52 -4
- package/payload/server/public/activity.html +5 -6
- package/payload/server/public/assets/AdminLoginScreens-DgVFsHtd.js +1 -0
- package/payload/server/public/assets/AdminShell-BwNqwb4k.js +2 -0
- package/payload/server/public/assets/activity-2DL2DwLr.js +1 -0
- package/payload/server/public/assets/admin-COe0dT2U.js +1 -0
- package/payload/server/public/assets/{arc-D-QzyndF.js → arc-CFMJyMm-.js} +1 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-Cypt5qHL.js +1 -0
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-W7f0Us4S.js → architectureDiagram-Q4EWVU46-CiSSgdL8.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CfPS4FXg.js → blockDiagram-DXYQGD6D-_sXtIW5c.js} +1 -1
- package/payload/server/public/assets/{bot-DnuyRsLS.js → bot-CpBuDQlF.js} +1 -1
- package/payload/server/public/assets/{browser-q4EFqKvR.js → browser-CSApuZrv.js} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-Dq60cLVI.js → c4Diagram-AHTNJAMY-Bh7OAMXs.js} +1 -1
- package/payload/server/public/assets/{calendar-C-q9kWmA.js → calendar-DlvwZnS7.js} +1 -1
- package/payload/server/public/assets/channel-BMyXE4zc.js +1 -0
- package/payload/server/public/assets/chat-DWvYv9jq.js +1 -0
- package/payload/server/public/assets/chevron-down-Dnuuw6Q2.js +1 -0
- package/payload/server/public/assets/chevron-left-CC4zmWOr.js +1 -0
- package/payload/server/public/assets/chevron-right-CG_lHTx_.js +1 -0
- package/payload/server/public/assets/{chunk-2KRD3SAO-CXDjuDN0.js → chunk-2KRD3SAO-D4fktAwW.js} +1 -1
- package/payload/server/public/assets/{chunk-336JU56O-926ox0tj.js → chunk-336JU56O-CcQoKH2G.js} +2 -2
- package/payload/server/public/assets/chunk-426QAEUC-Xu6JKP4d.js +1 -0
- package/payload/server/public/assets/{chunk-4BX2VUAB-C2nrPCfN.js → chunk-4BX2VUAB-C13Wz3zS.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-CuW3FOR6.js → chunk-4TB4RGXK-BL48D7gN.js} +1 -1
- package/payload/server/public/assets/{chunk-55IACEB6-B4_-In90.js → chunk-55IACEB6-TmOKdy8a.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-DnYGr9CP.js → chunk-5FUZZQ4R-DZ_jSF6N.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-BYCOi9bf.js → chunk-5PVQY5BW-De4G1vfV.js} +1 -1
- package/payload/server/public/assets/{chunk-67CJDMHE-CBxsC4JP.js → chunk-67CJDMHE-Cif9Uu5C.js} +1 -1
- package/payload/server/public/assets/{chunk-7N4EOEYR-CAACaqFr.js → chunk-7N4EOEYR-WjTHCXnd.js} +1 -1
- package/payload/server/public/assets/{chunk-AA7GKIK3-BoamZdS6.js → chunk-AA7GKIK3-CwCfdQmb.js} +1 -1
- package/payload/server/public/assets/{chunk-BSJP7CBP-CHk82eFy.js → chunk-BSJP7CBP-9A67yXwT.js} +1 -1
- package/payload/server/public/assets/{chunk-CIAEETIT-DdeW9zxl.js → chunk-CIAEETIT-DPMiWSBi.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-DJqSRv2w.js → chunk-EDXVE4YY-C2f_Qvx-.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-BRi4BwM5.js → chunk-ENJZ2VHE-B-Q9EbSQ.js} +1 -1
- package/payload/server/public/assets/{chunk-FMBD7UC4-OJp2CtUE.js → chunk-FMBD7UC4-Bmt_ZRlV.js} +1 -1
- package/payload/server/public/assets/{chunk-FOC6F5B3-BUAQ6spG.js → chunk-FOC6F5B3-DfGJGxpX.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-DeRggD-Q.js → chunk-ICPOFSXX-Wyym1Q8K.js} +2 -2
- package/payload/server/public/assets/{chunk-K5T4RW27-EHiXZ8Py.js → chunk-K5T4RW27-DMpoaqw2.js} +1 -1
- package/payload/server/public/assets/{chunk-KGLVRYIC-tOajPcpn.js → chunk-KGLVRYIC-DYUFgri2.js} +1 -1
- package/payload/server/public/assets/{chunk-LIHQZDEY-uwO6oHIU.js → chunk-LIHQZDEY-x3LmeKmx.js} +1 -1
- package/payload/server/public/assets/{chunk-ORNJ4GCN-Dpa1_BCA.js → chunk-ORNJ4GCN-BeuNAWkW.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-ChdDqaQL.js → chunk-OYMX7WX6-BUWVAfQA.js} +1 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-7_kS3RBy.js +1 -0
- package/payload/server/public/assets/{chunk-U2HBQHQK-5JgWosPv.js → chunk-U2HBQHQK-DKS5adQo.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-BGJqysB2.js → chunk-X2U36JSP-CT_UM4IN.js} +1 -1
- package/payload/server/public/assets/{chunk-XPW4576I-GERE2ekx.js → chunk-XPW4576I-ByFnN4JO.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BskqX1V5.js → chunk-YZCP3GAM-DCetC20J.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-DG1iY-L9.js → chunk-ZZ45TVLE-Bh1QIv8N.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DJqbNcuC.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CGglqfQA.js +1 -0
- package/payload/server/public/assets/clone-BiTMTzp_.js +1 -0
- package/payload/server/public/assets/{cose-bilkent-S5V4N54A-C8Rl4ykh.js → cose-bilkent-S5V4N54A-DgLEaApT.js} +1 -1
- package/payload/server/public/assets/{dagre-KV5264BT-C0YrJPF3.js → dagre-KV5264BT-BfkUPrEV.js} +1 -1
- package/payload/server/public/assets/{dagre-DTlv-FFy.js → dagre-unhMIyVo.js} +1 -1
- package/payload/server/public/assets/data-CJbC_cVy.js +1 -0
- package/payload/server/public/assets/{diagram-5BDNPKRD-Dfk5oepI.js → diagram-5BDNPKRD-BjjwcTD9.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-QRj55DiB.js → diagram-G4DWMVQ6-BbgWtVSS.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-BAPKsohU.js → diagram-MMDJMWI5-DyAnkWGy.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-C3iZXPkC.js → diagram-TYMM5635-SAMMoLxq.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DIbI7g_5.js → erDiagram-SMLLAGMA-Cvo-5-fD.js} +1 -1
- package/payload/server/public/assets/{flatten-DlAJeN0L.js → flatten-BXzaHgtL.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-l3eJJr8R.js → flowDiagram-DWJPFMVM-y3o2Ycld.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-aaEzHxIq.js → ganttDiagram-T4ZO3ILL-BEm_CQaK.js} +1 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-C_-XjxLd.js +1 -0
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-Di-1eg_m.js → gitGraphDiagram-UUTBAWPF-CqmOxS7F.js} +1 -1
- package/payload/server/public/assets/{graph-CNgt7ygi.js → graph-kaxS9a_7.js} +2 -2
- package/payload/server/public/assets/graph-labels-GgejRtgV.js +1 -0
- package/payload/server/public/assets/{graphlib-D5awC2yp.js → graphlib-_HfbQcBf.js} +1 -1
- package/payload/server/public/assets/info-OMHHGYJF-BH8yDCfL.js +1 -0
- package/payload/server/public/assets/infoDiagram-42DDH7IO-DyDXyJ6U.js +2 -0
- package/payload/server/public/assets/{isEmpty-Dh1dF-tM.js → isEmpty-uB1dEu_Z.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-CLOd_cNf.js → ishikawaDiagram-UXIWVN3A-C_d0vcZC.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-cGyfW6Tg.js → journeyDiagram-VCZTEJTY-DsjRBqlW.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-CRTKWPlh.js → kanban-definition-6JOO6SKY-BwtK6LS-.js} +1 -1
- package/payload/server/public/assets/{line-B8Brm0TD.js → line-szBCFOLJ.js} +1 -1
- package/payload/server/public/assets/{linear-BHnSKXBe.js → linear-X3O7lwK3.js} +1 -1
- package/payload/server/public/assets/{maximize-2-k3Fu5hdP.js → maximize-2-CPq3nwZA.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-BtNpdQct.js → mermaid-parser.core-BavvMAhU.js} +2 -2
- package/payload/server/public/assets/{mermaid.core-BY87anQZ.js → mermaid.core-Br2F9Hdm.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-rUSv9qN1.js → mindmap-definition-QFDTVHPH-4qlwXoJ-.js} +1 -1
- package/payload/server/public/assets/operator-CldXXilj.js +1 -0
- package/payload/server/public/assets/{ordinal-Bnl5GL-x.js → ordinal-CZY9laxg.js} +1 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-Bajcns4r.js +1 -0
- package/payload/server/public/assets/{page-Bvx0A2jB.js → page-BE6DkJP9.js} +1 -1
- package/payload/server/public/assets/{page-DhwPG5Zf.js → page-BIwdWXnv.js} +3 -3
- package/payload/server/public/assets/{pdf-render-CrpAi4Ba.js → pdf-render-H884L3EI.js} +1 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-D7hjM5w1.js +1 -0
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-Cjn9IP-C.js → pieDiagram-DEJITSTG-BbXryIg0.js} +1 -1
- package/payload/server/public/assets/{public-BJ5Oo2Fw.js → public-BKQEQGPE.js} +1 -1
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-BkSHkSsn.js → quadrantDiagram-34T5L4WZ-BHLjcvh3.js} +1 -1
- package/payload/server/public/assets/radar-PYXPWWZC-B46d5x7a.js +1 -0
- package/payload/server/public/assets/{reduce-Bp5oNw1n.js → reduce-BGQzAenn.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-hLwgyB-F.js → requirementDiagram-MS252O5E-BXaVO0lk.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-D-ov5jM4.js → rotate-ccw-DieZzl10.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-D6Dl1RIa.js → sankeyDiagram-XADWPNL6-CmN1s17Q.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-j0QBqkbL.js → sequenceDiagram-FGHM5R23-DC08e5NY.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-TvEBNsuV.js → stateDiagram-FHFEXIEX-DnoQMuOW.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CrstH34p.js +1 -0
- package/payload/server/public/assets/{tasks-DHMxTZVD.js → tasks-DYyCGz8W.js} +1 -1
- package/payload/server/public/assets/{time-entry-format-EmV5lz6o.js → time-entry-format-CC_9jFuR.js} +1 -1
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-BfivOP-j.js → timeline-definition-GMOUNBTQ-eTn3uRaH.js} +1 -1
- package/payload/server/public/assets/treeView-SZITEDCU-3XQh5xQ1.js +1 -0
- package/payload/server/public/assets/treemap-W4RFUUIX-DwR-_l5z.js +1 -0
- package/payload/server/public/assets/{triangle-alert-CivyPfAL.js → triangle-alert-7mQfCQWP.js} +1 -1
- package/payload/server/public/assets/{useCopyFeedback-hbnPS-r9.js → useCopyFeedback-os7N0yCx.js} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-Bgfqig1V.css +1 -0
- package/payload/server/public/assets/{useVoiceRecorder-QN9_GqB_.js → useVoiceRecorder-ZFwt5i6d.js} +2 -2
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-Bvfw9aFJ.js → vennDiagram-DHZGUBPP-DNx6o_ZQ.js} +1 -1
- package/payload/server/public/assets/wardley-RL74JXVD-DZp9oCGv.js +1 -0
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-C9h04G6b.js → wardleyDiagram-NUSXRM2D-BZOchqF3.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BMvi2m2q.js → xychartDiagram-5P7HB3ND-ZBEGH6ZI.js} +1 -1
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +6 -6
- package/payload/server/public/chat.html +14 -14
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +10 -11
- package/payload/server/public/index.html +16 -17
- package/payload/server/public/operator.html +15 -16
- package/payload/server/public/public.html +14 -14
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +1836 -998
- package/payload/server/{src-JJ6PHO5I.js → src-UYDFMWF4.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-Dic_fPt6.js +0 -1
- package/payload/server/public/assets/AdminShell-JN7rZ8aG.js +0 -2
- package/payload/server/public/assets/Checkbox-CB74kINA.js +0 -1
- package/payload/server/public/assets/activity-DbfpHg3i.js +0 -1
- package/payload/server/public/assets/admin-CThbXaYH.js +0 -1
- package/payload/server/public/assets/architecture-YZFGNWBL-CGvD4r9F.js +0 -1
- package/payload/server/public/assets/channel-Bpg-ADC0.js +0 -1
- package/payload/server/public/assets/chat-DcefIV9q.js +0 -1
- package/payload/server/public/assets/chevron-down-Blma_CKl.js +0 -1
- package/payload/server/public/assets/chevron-left-xeYDxFiC.js +0 -1
- package/payload/server/public/assets/chevron-right-BonbtjqJ.js +0 -1
- package/payload/server/public/assets/chunk-426QAEUC-1poG7Nd3.js +0 -1
- package/payload/server/public/assets/chunk-QZHKN3VN-GN1tIO8J.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-DMGVq8Jv.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DfddT8UV.js +0 -1
- package/payload/server/public/assets/clone-Cc9vFIEk.js +0 -1
- package/payload/server/public/assets/data-D5dp6nj6.js +0 -1
- package/payload/server/public/assets/gitGraph-7Q5UKJZL-DtjXE0UI.js +0 -1
- package/payload/server/public/assets/graph-labels-DA48HrRR.js +0 -1
- package/payload/server/public/assets/info-OMHHGYJF-CmArhGYf.js +0 -1
- package/payload/server/public/assets/infoDiagram-42DDH7IO-utWz7oZy.js +0 -2
- package/payload/server/public/assets/operator-8NVpNLeD.js +0 -1
- package/payload/server/public/assets/packet-4T2RLAQJ-BTfK0Zw4.js +0 -1
- package/payload/server/public/assets/pie-ZZUOXDRM-BvtPeMQY.js +0 -1
- package/payload/server/public/assets/radar-PYXPWWZC-D2UXvQgn.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-Ur4eM6rb.js +0 -1
- package/payload/server/public/assets/treeView-SZITEDCU-0dE7FvM2.js +0 -1
- package/payload/server/public/assets/treemap-W4RFUUIX-BrwlXpr5.js +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-kwhG-aJj.css +0 -1
- package/payload/server/public/assets/wardley-RL74JXVD-CO9HdfJ-.js +0 -1
- /package/payload/server/public/assets/{_baseFor-BBkmqPEk.js → _baseFor-CMWvz0uA.js} +0 -0
- /package/payload/server/public/assets/{array-Bjtb2C_5.js → array-Cny_NT6T.js} +0 -0
- /package/payload/server/public/assets/{cytoscape.esm-B1dQ664k.js → cytoscape.esm-De0CCmB2.js} +0 -0
- /package/payload/server/public/assets/{defaultLocale-iwYA7ne8.js → defaultLocale-BahRht8U.js} +0 -0
- /package/payload/server/public/assets/{dist-CLmrZbY7.js → dist-C9D_xz81.js} +0 -0
- /package/payload/server/public/assets/{init-CxnBAgcf.js → init-DoIvjoJ_.js} +0 -0
- /package/payload/server/public/assets/{katex-DojHoLIr.js → katex-Bfn1OZEl.js} +0 -0
- /package/payload/server/public/assets/{path-JZiojYzQ.js → path-CTezU8L5.js} +0 -0
- /package/payload/server/public/assets/{preload-helper-CT1Z6Pdu.js → preload-helper-D_sPnjeL.js} +0 -0
- /package/payload/server/public/assets/{rough.esm-D5NinLFK.js → rough.esm-BJo4pvXu.js} +0 -0
- /package/payload/server/public/assets/{src-DQ0MSD6q.js → src-BTKk8KAG.js} +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-DotTrvX3.js → useSubAccountSwitcher-Q941cZYV.js} +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Tests the one-shot quarantine restore (Task 1899): a free target is moved back,
|
|
3
|
+
# an occupied target is skipped with both copies surviving, an already-restored
|
|
4
|
+
# entry reports absent, a malformed line reports unparsable, and --dry-run
|
|
5
|
+
# changes nothing on disk.
|
|
6
|
+
set -uo pipefail
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
RESTORE="$SCRIPT_DIR/../quarantine-restore.mjs"
|
|
9
|
+
PASS=0; FAIL=0; FAILED=()
|
|
10
|
+
assert_grep() { if printf '%s' "$2" | grep -qF "$1"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); FAILED+=("$3: expected to find [$1]"); fi; }
|
|
11
|
+
assert_nogrep() { if printf '%s' "$2" | grep -qF "$1"; then FAIL=$((FAIL+1)); FAILED+=("$3: expected NOT to find [$1]"); else PASS=$((PASS+1)); fi; }
|
|
12
|
+
assert_file() { if [ -e "$1" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); FAILED+=("$2: expected file [$1]"); fi; }
|
|
13
|
+
assert_nofile() { if [ -e "$1" ]; then FAIL=$((FAIL+1)); FAILED+=("$2: expected NO file [$1]"); else PASS=$((PASS+1)); fi; }
|
|
14
|
+
assert_eq() { if [ "$1" = "$2" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); FAILED+=("$3: expected [$2] got [$1]"); fi; }
|
|
15
|
+
|
|
16
|
+
# One accounts root with a single account whose manifest covers all four cases.
|
|
17
|
+
make_tree() {
|
|
18
|
+
local T; T="$(mktemp -d)"
|
|
19
|
+
local A="$T/acct-1"
|
|
20
|
+
mkdir -p "$A/.quarantine"
|
|
21
|
+
printf '{}' > "$A/account.json"
|
|
22
|
+
|
|
23
|
+
# (a) free target: quarantined copy exists, nothing at the root.
|
|
24
|
+
printf 'portal' > "$A/.quarantine/data-portal.json"
|
|
25
|
+
# (b) occupied target: quarantined copy AND a live copy the platform rewrote.
|
|
26
|
+
printf 'old' > "$A/.quarantine/wa-channel-bindings.json"
|
|
27
|
+
printf 'live' > "$A/wa-channel-bindings.json"
|
|
28
|
+
# (c) already restored by hand: manifest names a source that is gone.
|
|
29
|
+
printf 'restored' > "$A/session-titles.json"
|
|
30
|
+
|
|
31
|
+
cat > "$A/.quarantine/manifest.jsonl" <<'EOF'
|
|
32
|
+
{"name":"data-portal.json","originalPath":"data-portal.json","reason":"top-level","quarantinePath":".quarantine/data-portal.json","movedAt":"2026-07-21T19:16:05.216Z"}
|
|
33
|
+
{"name":"session-titles.json","originalPath":"session-titles.json","reason":"top-level","quarantinePath":".quarantine/session-titles.json","movedAt":"2026-07-21T19:20:00.000Z"}
|
|
34
|
+
not json at all
|
|
35
|
+
{"name":"wa-channel-bindings.json","originalPath":"wa-channel-bindings.json","reason":"top-level","quarantinePath":".quarantine/wa-channel-bindings.json","movedAt":"2026-07-21T20:45:00.000Z"}
|
|
36
|
+
EOF
|
|
37
|
+
printf '%s' "$T"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# --- dry run changes nothing -------------------------------------------------
|
|
41
|
+
T="$(make_tree)"; A="$T/acct-1"
|
|
42
|
+
OUT="$(node "$RESTORE" --accounts-root "$T" --dry-run 2>&1)"
|
|
43
|
+
assert_grep 'result=moved' "$OUT" "dry-run reports the move it would make"
|
|
44
|
+
assert_grep 'dry-run=1' "$OUT" "dry-run marks its lines"
|
|
45
|
+
assert_nofile "$A/data-portal.json" "dry-run leaves the root untouched"
|
|
46
|
+
assert_file "$A/.quarantine/data-portal.json" "dry-run leaves the quarantined copy"
|
|
47
|
+
assert_nofile "$A/.quarantine/restored.jsonl" "dry-run writes no restored.jsonl"
|
|
48
|
+
rm -rf "$T"
|
|
49
|
+
|
|
50
|
+
# --- real run ----------------------------------------------------------------
|
|
51
|
+
T="$(make_tree)"; A="$T/acct-1"
|
|
52
|
+
OUT="$(node "$RESTORE" --accounts-root "$T" 2>&1)"
|
|
53
|
+
|
|
54
|
+
assert_grep 'op=restore account=acct-1 name=data-portal.json result=moved' "$OUT" "free target moved"
|
|
55
|
+
assert_file "$A/data-portal.json" "free target is back at the root"
|
|
56
|
+
assert_nofile "$A/.quarantine/data-portal.json" "free target no longer in quarantine"
|
|
57
|
+
|
|
58
|
+
assert_grep 'name=wa-channel-bindings.json result=skipped-live-copy' "$OUT" "occupied target skipped"
|
|
59
|
+
assert_grep 'live' "$(cat "$A/wa-channel-bindings.json")" "live copy still wins"
|
|
60
|
+
assert_file "$A/.quarantine/wa-channel-bindings.json" "quarantined copy survives the skip"
|
|
61
|
+
|
|
62
|
+
assert_grep 'name=session-titles.json result=absent' "$OUT" "already-restored source reports absent"
|
|
63
|
+
assert_grep 'restored' "$(cat "$A/session-titles.json")" "hand-restored copy untouched"
|
|
64
|
+
|
|
65
|
+
assert_grep 'line=3 result=unparsable' "$OUT" "malformed manifest line is reported"
|
|
66
|
+
|
|
67
|
+
assert_file "$A/.quarantine/manifest.jsonl" "manifest is left intact"
|
|
68
|
+
RESTORED="$(cat "$A/.quarantine/restored.jsonl")"
|
|
69
|
+
assert_grep 'data-portal.json' "$RESTORED" "restored.jsonl records the move"
|
|
70
|
+
assert_nogrep 'wa-channel-bindings.json' "$RESTORED" "restored.jsonl records only moves"
|
|
71
|
+
assert_nogrep 'session-titles.json' "$RESTORED" "restored.jsonl records only moves"
|
|
72
|
+
rm -rf "$T"
|
|
73
|
+
|
|
74
|
+
# --- a name quarantined twice restores the NEWEST copy ------------------------
|
|
75
|
+
# The sweep took wa-channel-bindings.json up to four times on one live account,
|
|
76
|
+
# the platform rewriting it between each. The deleted quarantineDest() took the
|
|
77
|
+
# unsuffixed name first and appended .1 to the next collision, so .1 IS the newer
|
|
78
|
+
# copy. Walking the append-only manifest oldest-first would put the stalest copy
|
|
79
|
+
# back, and the newer record would then find the target occupied.
|
|
80
|
+
T="$(mktemp -d)"; A="$T/acct-2"
|
|
81
|
+
mkdir -p "$A/.quarantine"
|
|
82
|
+
printf '{}' > "$A/account.json"
|
|
83
|
+
printf 'OLDER' > "$A/.quarantine/data-portal.json"
|
|
84
|
+
printf 'NEWER' > "$A/.quarantine/data-portal.json.1"
|
|
85
|
+
cat > "$A/.quarantine/manifest.jsonl" <<'EOF'
|
|
86
|
+
{"name":"data-portal.json","originalPath":"data-portal.json","quarantinePath":".quarantine/data-portal.json","movedAt":"2026-07-21T19:16:05.216Z"}
|
|
87
|
+
{"name":"data-portal.json","originalPath":"data-portal.json","quarantinePath":".quarantine/data-portal.json.1","movedAt":"2026-07-21T20:45:00.000Z"}
|
|
88
|
+
EOF
|
|
89
|
+
OUT="$(node "$RESTORE" --accounts-root "$T" 2>&1)"
|
|
90
|
+
assert_grep 'NEWER' "$(cat "$A/data-portal.json")" "newest quarantined copy is the one restored"
|
|
91
|
+
# The target was created by THIS run, not by a live platform rewrite. Calling it
|
|
92
|
+
# skipped-live-copy would tell the operator the platform holds a current copy.
|
|
93
|
+
assert_grep 'result=skipped-superseded' "$OUT" "the older copy is superseded, not live"
|
|
94
|
+
assert_nogrep 'result=skipped-live-copy' "$OUT" "no live copy existed on this tree"
|
|
95
|
+
assert_file "$A/.quarantine/data-portal.json" "the older copy is left in quarantine, never deleted"
|
|
96
|
+
rm -rf "$T"
|
|
97
|
+
|
|
98
|
+
# --- a record pointing outside its account is refused -------------------------
|
|
99
|
+
# .quarantine is in the write guard's allowed-top-level set, so an account-scoped
|
|
100
|
+
# agent can append to its own manifest. This script runs as the platform user
|
|
101
|
+
# across every account, so an escaping path would move one account's live data
|
|
102
|
+
# into another.
|
|
103
|
+
T="$(mktemp -d)"
|
|
104
|
+
mkdir -p "$T/acct-a/.quarantine" "$T/acct-b"
|
|
105
|
+
printf '{}' > "$T/acct-a/account.json"
|
|
106
|
+
printf '{}' > "$T/acct-b/account.json"
|
|
107
|
+
printf 'LIVE' > "$T/acct-b/wa-channel-bindings.json"
|
|
108
|
+
printf 'x' > "$T/acct-a/.quarantine/evil.json"
|
|
109
|
+
cat > "$T/acct-a/.quarantine/manifest.jsonl" <<'EOF'
|
|
110
|
+
{"name":"evil.json","originalPath":"../acct-b/planted.json","quarantinePath":".quarantine/evil.json"}
|
|
111
|
+
{"name":"steal","originalPath":"stolen.json","quarantinePath":"../acct-b/wa-channel-bindings.json"}
|
|
112
|
+
EOF
|
|
113
|
+
OUT="$(node "$RESTORE" --accounts-root "$T" 2>&1)"; RC=$?
|
|
114
|
+
assert_grep 'result=refused-outside-account' "$OUT" "escaping record is refused"
|
|
115
|
+
assert_grep 'refused=2' "$OUT" "both escaping records are counted"
|
|
116
|
+
assert_nofile "$T/acct-b/planted.json" "nothing is planted in the other account"
|
|
117
|
+
assert_nofile "$T/acct-a/stolen.json" "nothing is stolen from the other account"
|
|
118
|
+
assert_file "$T/acct-b/wa-channel-bindings.json" "the other account's live file is untouched"
|
|
119
|
+
assert_eq "$RC" "1" "a refused record makes the run exit non-zero"
|
|
120
|
+
rm -rf "$T"
|
|
121
|
+
|
|
122
|
+
# --- a failed rename reaches the summary and the exit code --------------------
|
|
123
|
+
# A restore that cannot complete leaves data in quarantine. The operator runs
|
|
124
|
+
# this once and reads the tail line, so a clean summary with a silent stderr
|
|
125
|
+
# line would be the same silent-skip failure this task exists to end.
|
|
126
|
+
T="$(mktemp -d)"; A="$T/acct-3"
|
|
127
|
+
mkdir -p "$A/.quarantine"
|
|
128
|
+
printf '{}' > "$A/account.json"
|
|
129
|
+
printf 'x' > "$A/.quarantine/orphan.json"
|
|
130
|
+
# The target's parent bucket no longer exists, so the target itself is absent
|
|
131
|
+
# (not a live copy) and the rename fails with ENOENT.
|
|
132
|
+
cat > "$A/.quarantine/manifest.jsonl" <<'EOF'
|
|
133
|
+
{"name":"orphan.json","originalPath":"gone-bucket/orphan.json","quarantinePath":".quarantine/orphan.json","movedAt":"2026-07-21T19:16:05.216Z"}
|
|
134
|
+
EOF
|
|
135
|
+
OUT="$(node "$RESTORE" --accounts-root "$T" 2>&1)"; RC=$?
|
|
136
|
+
assert_grep 'result=failed' "$OUT" "the failed rename is reported"
|
|
137
|
+
assert_grep 'failed=1' "$OUT" "the failure reaches the summary line"
|
|
138
|
+
assert_eq "$RC" "1" "a failed restore makes the run exit non-zero"
|
|
139
|
+
rm -rf "$T"
|
|
140
|
+
|
|
141
|
+
# --- summary -----------------------------------------------------------------
|
|
142
|
+
echo "PASS=$PASS FAIL=$FAIL"
|
|
143
|
+
if [ "$FAIL" -gt 0 ]; then printf '%s\n' "${FAILED[@]}"; exit 1; fi
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Task 1899 — one-shot restore of everything the account-dir schema reconcile
|
|
3
|
+
// moved into <account>/.quarantine/ before it was made report-only. The sweep's
|
|
4
|
+
// allowed-list never matched what the platform and its agents write at an
|
|
5
|
+
// account root, so it took live features and live data dark with no error: the
|
|
6
|
+
// portal config, live signed agreements, the channel bindings.
|
|
7
|
+
//
|
|
8
|
+
// Per account it walks .quarantine/manifest.jsonl NEWEST-FIRST (the manifest is
|
|
9
|
+
// append-only, so that is reverse file order). Newest-first is what makes the
|
|
10
|
+
// occupied case correct for a name quarantined more than once: the most recent
|
|
11
|
+
// copy is considered first, and every older copy of that name then finds the
|
|
12
|
+
// target occupied. The live copy always wins, because the platform rewrote it
|
|
13
|
+
// after the move — four wa-channel-bindings.json records on one account prove
|
|
14
|
+
// that happened.
|
|
15
|
+
//
|
|
16
|
+
// Never deletes. The manifest is left intact so the history of what moved and
|
|
17
|
+
// what came back both survive.
|
|
18
|
+
//
|
|
19
|
+
// Usage: node quarantine-restore.mjs --accounts-root <dir> [--dry-run]
|
|
20
|
+
|
|
21
|
+
import { existsSync, readdirSync, readFileSync, renameSync, appendFileSync } from 'node:fs'
|
|
22
|
+
import { join, resolve, sep } from 'node:path'
|
|
23
|
+
|
|
24
|
+
const TAG = '[quarantine-restore]'
|
|
25
|
+
const QUARANTINE_DIR = '.quarantine'
|
|
26
|
+
|
|
27
|
+
/** True when `path` is `root` itself or lives underneath it. Both arguments must
|
|
28
|
+
* already be absolute. */
|
|
29
|
+
function isInside(root, path) {
|
|
30
|
+
return path === root || path.startsWith(root + sep)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parseArgs(argv) {
|
|
34
|
+
let accountsRoot = null
|
|
35
|
+
let dryRun = false
|
|
36
|
+
for (let i = 0; i < argv.length; i++) {
|
|
37
|
+
if (argv[i] === '--accounts-root') {
|
|
38
|
+
accountsRoot = argv[i + 1] ?? null
|
|
39
|
+
i++
|
|
40
|
+
} else if (argv[i] === '--dry-run') {
|
|
41
|
+
dryRun = true
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { accountsRoot, dryRun }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { accountsRoot, dryRun } = parseArgs(process.argv.slice(2))
|
|
48
|
+
if (!accountsRoot) {
|
|
49
|
+
console.error(`${TAG} usage: quarantine-restore.mjs --accounts-root <dir> [--dry-run]`)
|
|
50
|
+
process.exit(1)
|
|
51
|
+
}
|
|
52
|
+
if (!existsSync(accountsRoot)) {
|
|
53
|
+
console.error(`${TAG} accounts root not found: ${accountsRoot}`)
|
|
54
|
+
process.exit(1)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const suffix = dryRun ? ' dry-run=1' : ''
|
|
58
|
+
const totals = {
|
|
59
|
+
moved: 0,
|
|
60
|
+
'skipped-live-copy': 0,
|
|
61
|
+
'skipped-superseded': 0,
|
|
62
|
+
absent: 0,
|
|
63
|
+
unparsable: 0,
|
|
64
|
+
refused: 0,
|
|
65
|
+
failed: 0,
|
|
66
|
+
}
|
|
67
|
+
let accounts = 0
|
|
68
|
+
|
|
69
|
+
for (const entry of readdirSync(accountsRoot)) {
|
|
70
|
+
const accountDir = join(accountsRoot, entry)
|
|
71
|
+
const accountRoot = resolve(accountDir)
|
|
72
|
+
const quarantineRoot = resolve(accountDir, QUARANTINE_DIR)
|
|
73
|
+
const manifestPath = join(accountDir, QUARANTINE_DIR, 'manifest.jsonl')
|
|
74
|
+
if (!existsSync(manifestPath)) continue
|
|
75
|
+
accounts++
|
|
76
|
+
|
|
77
|
+
// Names this run put back at the account root. A later record naming one of
|
|
78
|
+
// them found the target occupied by THIS run, not by a live copy the platform
|
|
79
|
+
// rewrote — two different states that must not share one outcome label.
|
|
80
|
+
const restoredThisRun = new Set()
|
|
81
|
+
|
|
82
|
+
let lines
|
|
83
|
+
try {
|
|
84
|
+
lines = readFileSync(manifestPath, 'utf-8').split('\n')
|
|
85
|
+
} catch (err) {
|
|
86
|
+
totals.failed++
|
|
87
|
+
console.error(
|
|
88
|
+
`${TAG} op=restore account=${entry} result=manifest-unreadable error=${err.message}`,
|
|
89
|
+
)
|
|
90
|
+
continue
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Newest-first: the manifest is append-only, so walk it backwards. The 1-based
|
|
94
|
+
// file line number is carried so an unparsable line can be pointed at.
|
|
95
|
+
const numbered = lines.map((text, i) => ({ text, lineNo: i + 1 })).filter((l) => l.text.trim())
|
|
96
|
+
for (const { text, lineNo } of numbered.reverse()) {
|
|
97
|
+
let rec
|
|
98
|
+
try {
|
|
99
|
+
rec = JSON.parse(text)
|
|
100
|
+
} catch {
|
|
101
|
+
rec = null
|
|
102
|
+
}
|
|
103
|
+
if (!rec || typeof rec.originalPath !== 'string' || typeof rec.quarantinePath !== 'string') {
|
|
104
|
+
// Reported, never silently skipped: a line dropped without a word is the
|
|
105
|
+
// exact failure class this task exists to end.
|
|
106
|
+
totals.unparsable++
|
|
107
|
+
console.log(`${TAG} op=restore account=${entry} line=${lineNo} result=unparsable${suffix}`)
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const source = resolve(accountDir, rec.quarantinePath)
|
|
112
|
+
const target = resolve(accountDir, rec.originalPath)
|
|
113
|
+
const name = rec.originalPath
|
|
114
|
+
|
|
115
|
+
// The manifest is a file inside the account, and .quarantine is in the write
|
|
116
|
+
// guard's allowed-top-level set, so an account-scoped agent can append to it.
|
|
117
|
+
// This script runs as the platform user across every account, so a record
|
|
118
|
+
// whose paths escape the account would move one account's live data into
|
|
119
|
+
// another. Every record the reconcile ever wrote was a bare basename plus a
|
|
120
|
+
// path under .quarantine/, so this refuses nothing genuine.
|
|
121
|
+
if (!isInside(quarantineRoot, source) || !isInside(accountRoot, target)) {
|
|
122
|
+
totals.refused++
|
|
123
|
+
console.error(
|
|
124
|
+
`${TAG} op=restore account=${entry} line=${lineNo} result=refused-outside-account${suffix}`,
|
|
125
|
+
)
|
|
126
|
+
continue
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!existsSync(source)) {
|
|
130
|
+
totals.absent++
|
|
131
|
+
console.log(`${TAG} op=restore account=${entry} name=${name} result=absent${suffix}`)
|
|
132
|
+
continue
|
|
133
|
+
}
|
|
134
|
+
if (existsSync(target) || restoredThisRun.has(target)) {
|
|
135
|
+
// A target this run created is superseded, not live. Calling both
|
|
136
|
+
// skipped-live-copy would tell the operator the platform holds a current
|
|
137
|
+
// copy when what is really left is an older copy still in quarantine.
|
|
138
|
+
const outcome = restoredThisRun.has(target) ? 'skipped-superseded' : 'skipped-live-copy'
|
|
139
|
+
totals[outcome]++
|
|
140
|
+
console.log(`${TAG} op=restore account=${entry} name=${name} result=${outcome}${suffix}`)
|
|
141
|
+
continue
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (dryRun) {
|
|
145
|
+
totals.moved++
|
|
146
|
+
restoredThisRun.add(target)
|
|
147
|
+
console.log(`${TAG} op=restore account=${entry} name=${name} result=moved${suffix}`)
|
|
148
|
+
continue
|
|
149
|
+
}
|
|
150
|
+
try {
|
|
151
|
+
renameSync(source, target)
|
|
152
|
+
appendFileSync(
|
|
153
|
+
join(accountDir, QUARANTINE_DIR, 'restored.jsonl'),
|
|
154
|
+
JSON.stringify({ ...rec, restoredAt: new Date().toISOString() }) + '\n',
|
|
155
|
+
)
|
|
156
|
+
totals.moved++
|
|
157
|
+
restoredThisRun.add(target)
|
|
158
|
+
console.log(`${TAG} op=restore account=${entry} name=${name} result=moved`)
|
|
159
|
+
} catch (err) {
|
|
160
|
+
totals.failed++
|
|
161
|
+
console.error(
|
|
162
|
+
`${TAG} op=restore account=${entry} name=${name} result=failed error=${err.message}`,
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log(
|
|
169
|
+
`${TAG} accounts=${accounts} moved=${totals.moved} skipped-live-copy=${totals['skipped-live-copy']} skipped-superseded=${totals['skipped-superseded']} absent=${totals.absent} unparsable=${totals.unparsable} refused=${totals.refused} failed=${totals.failed}${suffix}`,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
// A rename that failed, a manifest that would not open, and a record refused for
|
|
173
|
+
// pointing outside its account all leave data in quarantine. The operator runs
|
|
174
|
+
// this once and reads the tail line, so the exit code has to say so too.
|
|
175
|
+
if (totals.failed > 0 || totals.refused > 0) process.exitCode = 1
|
package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
export interface ReconcileCounts {
|
|
2
2
|
strayTopLevel: number;
|
|
3
3
|
overDeep: number;
|
|
4
|
-
quarantined: number;
|
|
5
4
|
badName: number;
|
|
6
5
|
}
|
|
6
|
+
export interface ReconcileResult extends ReconcileCounts {
|
|
7
|
+
/** The account-root entries counted as strays, by name — the same set
|
|
8
|
+
* strayTopLevel counts, so PROTECTED_TOP_LEVEL entries and dot-prefixed
|
|
9
|
+
* entries are absent from it, and an account that failed the SCHEMA.md
|
|
10
|
+
* fail-open check returns it empty. A count alone cannot distinguish six
|
|
11
|
+
* pieces of debris from a live plugin config; this list is what makes the
|
|
12
|
+
* report-only posture actionable. */
|
|
13
|
+
strayNames: string[];
|
|
14
|
+
}
|
|
7
15
|
/** The single per-run summary line body. A non-zero count is the standing signal
|
|
8
16
|
* that an agent authored folders the hard guards could not prevent. Pure
|
|
9
17
|
* formatter so the emitter and its test share one wording. */
|
|
@@ -14,18 +22,27 @@ export declare function formatReconcileLine(c: ReconcileCounts): string;
|
|
|
14
22
|
export declare function parseAllowedTopLevel(schemaText: string): Set<string>;
|
|
15
23
|
/** Reconcile one account dir. Reads its SCHEMA.md allowed set; an absent/empty
|
|
16
24
|
* set skips the account (fail open, like the hook — an un-seeded legacy account
|
|
17
|
-
* must not have its whole root
|
|
18
|
-
*
|
|
19
|
-
export declare function reconcileAccount(accountDir: string
|
|
25
|
+
* must not have its whole root reported as stray). Counts and names stray
|
|
26
|
+
* top-level entries; counts over-deep files and bad names. Moves nothing. */
|
|
27
|
+
export declare function reconcileAccount(accountDir: string): ReconcileResult;
|
|
20
28
|
export interface ReconcileDeps {
|
|
21
29
|
accountsRoot: string;
|
|
22
30
|
logger: (line: string) => void;
|
|
23
|
-
now?: () => number;
|
|
24
31
|
}
|
|
25
|
-
/** One reconcile pass over every account under the accounts root
|
|
32
|
+
/** One reconcile pass over every account under the accounts root: one op=strays
|
|
33
|
+
* line naming the unaccounted-for entries of each account that has any, then the
|
|
26
34
|
* single summary line. An account is any child dir with an account.json (the
|
|
27
35
|
* account marker the census uses). Per-account errors are swallowed so one bad
|
|
28
|
-
* account never aborts the run.
|
|
36
|
+
* account never aborts the run.
|
|
37
|
+
*
|
|
38
|
+
* The op=strays line is the standing signal. When a feature that reads an
|
|
39
|
+
* account-root file goes dark, seeing that file named here says the schema does
|
|
40
|
+
* not account for it and it is still on disk, so declare it. The absence of its
|
|
41
|
+
* name reads as "gone" only for a file that could have been named at all: an
|
|
42
|
+
* entry in PROTECTED_TOP_LEVEL, a dot-prefixed entry, and every entry of an
|
|
43
|
+
* account whose SCHEMA.md is missing or has an empty allowed block are never
|
|
44
|
+
* named whether they are present or not. Check the account root itself before
|
|
45
|
+
* concluding a file is gone. */
|
|
29
46
|
export declare function runReconcile(deps: ReconcileDeps): void;
|
|
30
47
|
export interface AccountDirSchemaReconcile {
|
|
31
48
|
start(): void;
|
package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-dir-schema-reconcile.d.ts","sourceRoot":"","sources":["../src/account-dir-schema-reconcile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"account-dir-schema-reconcile.d.ts","sourceRoot":"","sources":["../src/account-dir-schema-reconcile.ts"],"names":[],"mappings":"AAqFA,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD;;;;;0CAKsC;IACtC,UAAU,EAAE,MAAM,EAAE,CAAA;CACrB;AAED;;+DAE+D;AAC/D,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAE9D;AAED;;8EAE8E;AAC9E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAcpE;AA+ED;;;8EAG8E;AAC9E,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAoCpE;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B;AAED;;;;;;;;;;;;;iCAaiC;AACjC,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAyBtD;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,IAAI,IAAI,CAAA;IACb,IAAI,IAAI,IAAI,CAAA;CACb;AAED;oDACoD;AACpD,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,aAAa,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,GAC3C,yBAAyB,CAiB3B"}
|
package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js
CHANGED
|
@@ -11,43 +11,45 @@
|
|
|
11
11
|
// the flat operator-data buckets, mirroring fs-schema-guard.sh's own depth rule
|
|
12
12
|
// exactly (projects/contacts/documents cap at 3 path segments; every other
|
|
13
13
|
// tool-owned bucket is unbounded and not walked), and (c) bad-named folders and
|
|
14
|
-
// files under those same buckets, mirroring the guard's name convention.
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
14
|
+
// files under those same buckets, mirroring the guard's name convention. All
|
|
15
|
+
// three are REPORTED, never moved: the pass used to quarantine stray top-level
|
|
16
|
+
// entries, and because its allowed-list lagged what the platform and its agents
|
|
17
|
+
// actually write at an account root, a mismatch on an entry something still read
|
|
18
|
+
// took that feature or that data dark with no error anywhere (Task 1899 — the
|
|
19
|
+
// portal config, live signed agreements and the channel bindings all went for
|
|
20
|
+
// exactly that reason). Nothing is moved, nothing is
|
|
21
|
+
// deleted, nothing is silently rewritten; re-filing a stray to its schema-correct
|
|
22
|
+
// home is the data-manager specialist's job on dispatch, not this pass.
|
|
21
23
|
//
|
|
22
24
|
// Shape mirrors the standing-audit family (rootless-client-audit.ts): a pure
|
|
23
25
|
// formatter (unit-tested) + an impure per-account collector + a start/stop
|
|
24
26
|
// factory whose setInterval is unref'd. Purely filesystem — no Neo4j, no graph
|
|
25
27
|
// writes, no deletes. Best-effort by construction: a per-account error is caught
|
|
26
28
|
// so one bad account never aborts the run.
|
|
27
|
-
import { existsSync,
|
|
29
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
28
30
|
import { join, relative, sep } from 'node:path';
|
|
29
31
|
const TAG = '[fs-reconcile]';
|
|
30
32
|
const QUARANTINE_DIR = '.quarantine';
|
|
31
|
-
/** Platform control-plane entries the reconcile NEVER
|
|
32
|
-
* what an account's SCHEMA.md allowed set says. provision-account-dir.sh makes
|
|
33
|
+
/** Platform control-plane entries the reconcile NEVER counts as strays, regardless
|
|
34
|
+
* of what an account's SCHEMA.md allowed set says. provision-account-dir.sh makes
|
|
33
35
|
* the account dir a git root (`.git`) and writes its hook-enforcement settings
|
|
34
|
-
* into `.claude/`, and the account's identity lives in account.json
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* block omits one of these must not have it moved. This is a fail-SAFE belt on
|
|
39
|
-
* the control plane, the mirror of the guard's fail-OPEN on a missing schema —
|
|
40
|
-
* operator strays are still quarantined; the account's own machinery is not.
|
|
36
|
+
* into `.claude/`, and the account's identity lives in account.json. SCHEMA.md is
|
|
37
|
+
* refreshed on every provision, but an account carrying a stale/older-template/
|
|
38
|
+
* hand-edited schema whose allowed block omits one of these must not be reported
|
|
39
|
+
* on every run for machinery it is required to have.
|
|
41
40
|
*
|
|
42
41
|
* The second group is platform-written control-plane FILES the platform reads
|
|
43
42
|
* and writes at the account root every run. Unlike the tool-owned buckets, no
|
|
44
|
-
* plugin declares them into the SCHEMA.md allowed-top-level block
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* -
|
|
49
|
-
*
|
|
50
|
-
*
|
|
43
|
+
* plugin declares them into the SCHEMA.md allowed-top-level block: calendar-
|
|
44
|
+
* availability.json is the booking page's availability config (quarantining it
|
|
45
|
+
* froze a live booking page, Task 1877 fix); wa/webchat/telegram-channel-
|
|
46
|
+
* bindings.json route each channel's inbound; canonical-webchat-session.json
|
|
47
|
+
* pins the webchat session; session-titles.json holds operator renames. Each is
|
|
48
|
+
* `join(accountDir, <name>)` in platform code, none is operator data.
|
|
49
|
+
*
|
|
50
|
+
* Since Task 1899 this belt no longer protects anything from being moved,
|
|
51
|
+
* because nothing moves. It keeps the account's own machinery out of the stray
|
|
52
|
+
* count so the standing op=strays line names only what an operator must act on. */
|
|
51
53
|
const PROTECTED_TOP_LEVEL = new Set([
|
|
52
54
|
'.git',
|
|
53
55
|
'.claude',
|
|
@@ -79,7 +81,7 @@ const FILE_NAME_RE = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/;
|
|
|
79
81
|
* that an agent authored folders the hard guards could not prevent. Pure
|
|
80
82
|
* formatter so the emitter and its test share one wording. */
|
|
81
83
|
export function formatReconcileLine(c) {
|
|
82
|
-
return `${TAG} stray-top-level=${c.strayTopLevel} over-deep=${c.overDeep}
|
|
84
|
+
return `${TAG} stray-top-level=${c.strayTopLevel} over-deep=${c.overDeep} bad-name=${c.badName}`;
|
|
83
85
|
}
|
|
84
86
|
/** Parse the fenced ```allowed-top-level block from an account's SCHEMA.md —
|
|
85
87
|
* the same structured set fs-schema-guard.sh parses with awk. Returns the
|
|
@@ -189,22 +191,12 @@ function countBadNameEntries(accountDir, bucket) {
|
|
|
189
191
|
walk(bucketRoot);
|
|
190
192
|
return count;
|
|
191
193
|
}
|
|
192
|
-
/** Pick a non-colliding destination name inside .quarantine for a stray. */
|
|
193
|
-
function quarantineDest(quarantineRoot, name) {
|
|
194
|
-
let candidate = join(quarantineRoot, name);
|
|
195
|
-
let n = 1;
|
|
196
|
-
while (existsSync(candidate)) {
|
|
197
|
-
candidate = join(quarantineRoot, `${name}.${n}`);
|
|
198
|
-
n++;
|
|
199
|
-
}
|
|
200
|
-
return candidate;
|
|
201
|
-
}
|
|
202
194
|
/** Reconcile one account dir. Reads its SCHEMA.md allowed set; an absent/empty
|
|
203
195
|
* set skips the account (fail open, like the hook — an un-seeded legacy account
|
|
204
|
-
* must not have its whole root
|
|
205
|
-
*
|
|
206
|
-
export function reconcileAccount(accountDir
|
|
207
|
-
const empty = { strayTopLevel: 0, overDeep: 0,
|
|
196
|
+
* must not have its whole root reported as stray). Counts and names stray
|
|
197
|
+
* top-level entries; counts over-deep files and bad names. Moves nothing. */
|
|
198
|
+
export function reconcileAccount(accountDir) {
|
|
199
|
+
const empty = { strayTopLevel: 0, overDeep: 0, badName: 0, strayNames: [] };
|
|
208
200
|
const schemaPath = join(accountDir, 'SCHEMA.md');
|
|
209
201
|
if (!existsSync(schemaPath))
|
|
210
202
|
return empty;
|
|
@@ -226,50 +218,34 @@ export function reconcileAccount(accountDir, now) {
|
|
|
226
218
|
}
|
|
227
219
|
// A dot-prefixed top-level entry is tool/system state, never operator data —
|
|
228
220
|
// the same judgement countBadNameEntries applies when it skips dotfiles. The
|
|
229
|
-
// stray check must agree, or it
|
|
230
|
-
//
|
|
231
|
-
//
|
|
221
|
+
// stray check must agree, or it reports .remember/.superpowers/.wrangler on
|
|
222
|
+
// every run (Task 1891). .git/.claude/.quarantine stay covered by
|
|
223
|
+
// PROTECTED_TOP_LEVEL regardless.
|
|
232
224
|
const strays = rootEntries.filter((name) => !name.startsWith('.') && !PROTECTED_TOP_LEVEL.has(name) && !allowed.has(name));
|
|
233
|
-
let quarantined = 0;
|
|
234
|
-
if (strays.length > 0) {
|
|
235
|
-
const quarantineRoot = join(accountDir, QUARANTINE_DIR);
|
|
236
|
-
const manifestPath = join(quarantineRoot, 'manifest.jsonl');
|
|
237
|
-
for (const name of strays) {
|
|
238
|
-
try {
|
|
239
|
-
mkdirSync(quarantineRoot, { recursive: true });
|
|
240
|
-
const dest = quarantineDest(quarantineRoot, name);
|
|
241
|
-
renameSync(join(accountDir, name), dest);
|
|
242
|
-
const record = {
|
|
243
|
-
name,
|
|
244
|
-
originalPath: name,
|
|
245
|
-
reason: 'top-level',
|
|
246
|
-
quarantinePath: relative(accountDir, dest),
|
|
247
|
-
movedAt: new Date(now()).toISOString(),
|
|
248
|
-
};
|
|
249
|
-
appendFileSync(manifestPath, JSON.stringify(record) + '\n');
|
|
250
|
-
quarantined++;
|
|
251
|
-
}
|
|
252
|
-
catch {
|
|
253
|
-
// Move failed (permissions, race). Counted as a detected stray below,
|
|
254
|
-
// not as quarantined — the summary line stays honest.
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
225
|
let overDeep = 0;
|
|
259
226
|
let badName = 0;
|
|
260
227
|
for (const bucket of DEPTH_CHECKED_BUCKETS) {
|
|
261
228
|
overDeep += countOverDeepFiles(accountDir, bucket);
|
|
262
229
|
badName += countBadNameEntries(accountDir, bucket);
|
|
263
230
|
}
|
|
264
|
-
return { strayTopLevel: strays.length, overDeep,
|
|
231
|
+
return { strayTopLevel: strays.length, overDeep, badName, strayNames: strays };
|
|
265
232
|
}
|
|
266
|
-
/** One reconcile pass over every account under the accounts root
|
|
233
|
+
/** One reconcile pass over every account under the accounts root: one op=strays
|
|
234
|
+
* line naming the unaccounted-for entries of each account that has any, then the
|
|
267
235
|
* single summary line. An account is any child dir with an account.json (the
|
|
268
236
|
* account marker the census uses). Per-account errors are swallowed so one bad
|
|
269
|
-
* account never aborts the run.
|
|
237
|
+
* account never aborts the run.
|
|
238
|
+
*
|
|
239
|
+
* The op=strays line is the standing signal. When a feature that reads an
|
|
240
|
+
* account-root file goes dark, seeing that file named here says the schema does
|
|
241
|
+
* not account for it and it is still on disk, so declare it. The absence of its
|
|
242
|
+
* name reads as "gone" only for a file that could have been named at all: an
|
|
243
|
+
* entry in PROTECTED_TOP_LEVEL, a dot-prefixed entry, and every entry of an
|
|
244
|
+
* account whose SCHEMA.md is missing or has an empty allowed block are never
|
|
245
|
+
* named whether they are present or not. Check the account root itself before
|
|
246
|
+
* concluding a file is gone. */
|
|
270
247
|
export function runReconcile(deps) {
|
|
271
|
-
const
|
|
272
|
-
const total = { strayTopLevel: 0, overDeep: 0, quarantined: 0, badName: 0 };
|
|
248
|
+
const total = { strayTopLevel: 0, overDeep: 0, badName: 0 };
|
|
273
249
|
let entries;
|
|
274
250
|
try {
|
|
275
251
|
entries = readdirSync(deps.accountsRoot);
|
|
@@ -283,10 +259,12 @@ export function runReconcile(deps) {
|
|
|
283
259
|
if (!existsSync(join(accountDir, 'account.json')))
|
|
284
260
|
continue;
|
|
285
261
|
try {
|
|
286
|
-
const c = reconcileAccount(accountDir
|
|
262
|
+
const c = reconcileAccount(accountDir);
|
|
263
|
+
if (c.strayNames.length > 0) {
|
|
264
|
+
deps.logger(`${TAG} op=strays account=${entry} names=${c.strayNames.join(',')}`);
|
|
265
|
+
}
|
|
287
266
|
total.strayTopLevel += c.strayTopLevel;
|
|
288
267
|
total.overDeep += c.overDeep;
|
|
289
|
-
total.quarantined += c.quarantined;
|
|
290
268
|
total.badName += c.badName;
|
|
291
269
|
}
|
|
292
270
|
catch {
|
package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-dir-schema-reconcile.js","sourceRoot":"","sources":["../src/account-dir-schema-reconcile.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,gFAAgF;AAChF,8EAA8E;AAC9E,iFAAiF;AACjF,iFAAiF;AACjF,kFAAkF;AAClF,kDAAkD;AAClD,EAAE;AACF,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,2EAA2E;AAC3E,gFAAgF;AAChF,+EAA+E;AAC/E,
|
|
1
|
+
{"version":3,"file":"account-dir-schema-reconcile.js","sourceRoot":"","sources":["../src/account-dir-schema-reconcile.ts"],"names":[],"mappings":"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"}
|
|
@@ -794,14 +794,17 @@ async function main() {
|
|
|
794
794
|
logger: log,
|
|
795
795
|
});
|
|
796
796
|
xacctCensus.start();
|
|
797
|
-
// Task 1877 — standing account-dir schema reconcile. The
|
|
798
|
-
// hook never sees Bash, and the immediate Bash hooks only
|
|
799
|
-
// command newly creates; neither retroactively catches the
|
|
800
|
-
// authored before the hooks existed. Folder creation through
|
|
801
|
-
// no-event failure, so this periodic filesystem pass is the only
|
|
802
|
-
//
|
|
803
|
-
//
|
|
804
|
-
// [fs-reconcile]
|
|
797
|
+
// Task 1877 / Task 1899 — standing account-dir schema reconcile. The
|
|
798
|
+
// fs-schema-guard path hook never sees Bash, and the immediate Bash hooks only
|
|
799
|
+
// catch strays a live command newly creates; neither retroactively catches the
|
|
800
|
+
// backlog an agent authored before the hooks existed. Folder creation through
|
|
801
|
+
// Bash is a no-event failure, so this periodic filesystem pass is the only
|
|
802
|
+
// signal. It REPORTS and never moves: each run emits one [fs-reconcile]
|
|
803
|
+
// op=strays line per account carrying entries the schema does not account for,
|
|
804
|
+
// naming them, then one [fs-reconcile] summary line counting those entries
|
|
805
|
+
// alongside over-deep files and bad names. It used to quarantine
|
|
806
|
+
// strays, and because a closed allowed-list always lags what the platform
|
|
807
|
+
// writes, that turned a metric into data loss. Purely filesystem — no Neo4j.
|
|
805
808
|
const schemaReconcile = createAccountDirSchemaReconcile({
|
|
806
809
|
accountsRoot: dirname(config.accountDir),
|
|
807
810
|
logger: log,
|