@deepseek-insight/dsi 0.6.12 → 0.6.14
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/.agents/skills/dsi-thin/SKILL.md +140 -0
- package/.agents/skills/dsi-thin/references/ADR-0019-snapshot.md +363 -0
- package/.agents/skills/dsi-thin/references/authority-adr.md +28 -0
- package/.agents/skills/dsi-thin/references/input-contract.md +42 -0
- package/.agents/skills/dsi-thin/references/proven-gates.md +61 -0
- package/.agents/skills/dsi-thin/references/two-lane-contract.md +53 -0
- package/build/client/_app/immutable/assets/0.B-dIufDc.css +2 -0
- package/build/client/_app/immutable/assets/2.B70dfiy3.css +1 -0
- package/build/client/_app/immutable/chunks/{B9fOkvHb.js → 0HT0ILkA.js} +1 -1
- package/build/client/_app/immutable/chunks/{Dwt_JXeR.js → 2KTqoQH-.js} +1 -1
- package/build/client/_app/immutable/chunks/{BIvFR1xA.js → 2M1KS72j.js} +1 -1
- package/build/client/_app/immutable/chunks/{a1Hqq5w-.js → 2XtVrxH4.js} +1 -1
- package/build/client/_app/immutable/chunks/38H6DLwz.js +1 -0
- package/build/client/_app/immutable/chunks/{Cdn_bzx2.js → 3E8jbhSl.js} +1 -1
- package/build/client/_app/immutable/chunks/{CmNEu9LM.js → A5Iiq81h.js} +1 -1
- package/build/client/_app/immutable/chunks/{C48u-2qp.js → ANnPTMPF.js} +1 -1
- package/build/client/_app/immutable/chunks/{BfChGCnE.js → B5S0Wke9.js} +1 -1
- package/build/client/_app/immutable/chunks/BBDOLPkB.js +1 -0
- package/build/client/_app/immutable/chunks/{DJ36HFmi.js → BImoJlJo.js} +1 -1
- package/build/client/_app/immutable/chunks/{DqRXQwgi.js → BJsp4NMH.js} +1 -1
- package/build/client/_app/immutable/chunks/{C7a8i7sD.js → BKU5-8Td.js} +1 -1
- package/build/client/_app/immutable/chunks/BMgyB-Sy.js +1 -0
- package/build/client/_app/immutable/chunks/BYHxHjHc.js +1 -0
- package/build/client/_app/immutable/chunks/{BC5nqwvj.js → BZ6uvzU8.js} +1 -1
- package/build/client/_app/immutable/chunks/{CvjdFV1E.js → B_Gknb5_.js} +1 -1
- package/build/client/_app/immutable/chunks/{CDTTZjYW.js → Bf1I5ROF.js} +1 -1
- package/build/client/_app/immutable/chunks/{CaAId7nh.js → Bh_Z0-Fh.js} +1 -1
- package/build/client/_app/immutable/chunks/{CLvIgAhR.js → BjafRUyA.js} +1 -1
- package/build/client/_app/immutable/chunks/{CG77uzLI.js → Bq4mG8qS.js} +1 -1
- package/build/client/_app/immutable/chunks/{CI1tkkzb.js → BqX9BB0G.js} +1 -1
- package/build/client/_app/immutable/chunks/BwNsQhd8.js +1 -0
- package/build/client/_app/immutable/chunks/{CvWnUnS1.js → Bx68-tOf.js} +1 -1
- package/build/client/_app/immutable/chunks/{RIIj2qfU.js → C1dC47iq.js} +1 -1
- package/build/client/_app/immutable/chunks/{BNx4_m7U.js → C6zqVyWx.js} +1 -1
- package/build/client/_app/immutable/chunks/{GLtnCmfd.js → C8seIiU_.js} +1 -1
- package/build/client/_app/immutable/chunks/{B_6pr4k2.js → CCWXLdgd.js} +1 -1
- package/build/client/_app/immutable/chunks/{D5ecapQY.js → CHYEvS-6.js} +1 -1
- package/build/client/_app/immutable/chunks/{OVDjSnH6.js → CIH5Juz4.js} +1 -1
- package/build/client/_app/immutable/chunks/CMByLjfJ.js +1 -0
- package/build/client/_app/immutable/chunks/{CnAA0dO8.js → CNJYmM8n.js} +1 -1
- package/build/client/_app/immutable/chunks/CP4wchdA.js +2 -0
- package/build/client/_app/immutable/chunks/{B2hm1w7K.js → CQTGR8fW.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bp4vT1Ke.js → CW2uYEvb.js} +1 -1
- package/build/client/_app/immutable/chunks/{BPFR73BS.js → C_Gd0Wor.js} +1 -1
- package/build/client/_app/immutable/chunks/{Dn4fSUjR.js → C_MwBDNt.js} +1 -1
- package/build/client/_app/immutable/chunks/{Dea0pTfN.js → Ch7rc-L7.js} +4 -4
- package/build/client/_app/immutable/chunks/{J3KpJGd_.js → ChC4viXw.js} +1 -1
- package/build/client/_app/immutable/chunks/{4pCoNSa4.js → CiLhSVIj.js} +1 -1
- package/build/client/_app/immutable/chunks/{C7iYNw8X.js → Cx8YXmgi.js} +1 -1
- package/build/client/_app/immutable/chunks/{BRNBFqQ_.js → D4I0Dqwh.js} +1 -1
- package/build/client/_app/immutable/chunks/D6mTYwDH.js +6 -0
- package/build/client/_app/immutable/chunks/{l5GiMY16.js → D7-uGicP.js} +1 -1
- package/build/client/_app/immutable/chunks/{C8wGq5T2.js → D7XrPGMK.js} +1 -1
- package/build/client/_app/immutable/chunks/{xRO38jd8.js → D7eKc9ur.js} +1 -1
- package/build/client/_app/immutable/chunks/{CEj_BGCY.js → DCmONIPx.js} +1 -1
- package/build/client/_app/immutable/chunks/DJWLLhNJ.js +1 -0
- package/build/client/_app/immutable/chunks/{qkxAgKjo.js → DNf96C-O.js} +1 -1
- package/build/client/_app/immutable/chunks/{D4Ogpdhb.js → DSqRqQNp.js} +1 -1
- package/build/client/_app/immutable/chunks/{D4xFb7_b.js → DT1b6JaK.js} +1 -1
- package/build/client/_app/immutable/chunks/{D3bC95qg.js → DWYSL4om.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bi5NvDds.js → DYfx-RRD.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bi25XSWW.js → DfIqw6WM.js} +1 -1
- package/build/client/_app/immutable/chunks/{CGux-rdo.js → Dj4_qcIH.js} +4 -4
- package/build/client/_app/immutable/chunks/{Cx__ttXF.js → Dk9aRp2m.js} +1 -1
- package/build/client/_app/immutable/chunks/{C-58cZAk.js → DmLHHlla.js} +3 -3
- package/build/client/_app/immutable/chunks/{GNZHLVjs.js → Do0VAo0_.js} +1 -1
- package/build/client/_app/immutable/chunks/{BFsDYOFz.js → DrVddB75.js} +1 -1
- package/build/client/_app/immutable/chunks/{CdFbOrCf.js → Dso_gKeU.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bl78Sc72.js → DykTZ90H.js} +1 -1
- package/build/client/_app/immutable/chunks/{DNlR6G0m.js → GdM4UPkS.js} +1 -1
- package/build/client/_app/immutable/chunks/{B52Khb6E.js → IBXFCASw.js} +1 -1
- package/build/client/_app/immutable/chunks/{BIUi504d.js → IoX9lmZK.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bn64J6A-.js → bpkmZ_Dv.js} +1 -1
- package/build/client/_app/immutable/chunks/{iK_uzrhN.js → crRp5OG4.js} +1 -1
- package/build/client/_app/immutable/chunks/da2fibLv.js +8 -0
- package/build/client/_app/immutable/chunks/{BOKyldQm.js → dcghWWmq.js} +1 -1
- package/build/client/_app/immutable/chunks/{CItDRTlN.js → fJBuRi-A.js} +1 -1
- package/build/client/_app/immutable/chunks/{CRe9IZg0.js → gXyYVhfn.js} +1 -1
- package/build/client/_app/immutable/chunks/{C2vkjTiv.js → j2lJ25s0.js} +1 -1
- package/build/client/_app/immutable/chunks/{DypDva7F.js → l3etNtOh.js} +1 -1
- package/build/client/_app/immutable/chunks/{BGQXNvll.js → olUfRNXS.js} +1 -1
- package/build/client/_app/immutable/chunks/{D3W5wGWM.js → uEyn1Z7p.js} +1 -1
- package/build/client/_app/immutable/entry/app.CCuVGpQc.js +2 -0
- package/build/client/_app/immutable/entry/start.BtgtnpyB.js +1 -0
- package/build/client/_app/immutable/nodes/0.GHtnahSb.js +1 -0
- package/build/client/_app/immutable/nodes/1.CaQ_jAq8.js +1 -0
- package/build/client/_app/immutable/nodes/2.DxOLlTKc.js +337 -0
- package/build/client/_app/version.json +1 -1
- package/build/handler.js +7 -6
- package/build/index.js +7 -6
- package/build/server/chunks/chunks/{app-config.svelte.js-BW7TwbBy.js → app-config.svelte.js-D7wkLUkK.js} +2 -2
- package/build/server/chunks/chunks/{db.js-BylhmazO.js → db.js-DRhjT6xK.js} +2 -2
- package/build/server/chunks/chunks/{db2.js-Cm8FBINY.js → db2.js-DUta2B-n.js} +207 -222
- package/build/server/chunks/chunks/{dsh-connection.js-Lnv7PlHw.js → dsh-connection.js-DRtqPR_j.js} +959 -752
- package/build/server/chunks/chunks/{dsh-events.js-D9tSYE7f.js → dsh-events.js-B_E1BU9F.js} +141 -350
- package/build/server/chunks/chunks/{git-probe.js-D_H3YQbR.js → git-probe.js-Daf6r7Z9.js} +3 -3
- package/build/server/chunks/chunks/index-server.js-CV2lq-ha.js +147 -0
- package/build/server/chunks/chunks/{insight-config.js-XUD5BN0g.js → insight-config.js-CA-iT3lB.js} +5 -3
- package/build/server/chunks/chunks/{internal2.js-BcS47nI-.js → internal.js-BcS47nI-.js} +1 -1
- package/build/server/chunks/chunks/{internal.js-D_QJoxN-.js → internal2.js-DAPn3Vk8.js} +11 -153
- package/build/server/chunks/chunks/merge.js-yMwW440S.js +228 -0
- package/build/server/chunks/chunks/{server.js-11-pxAWV.js → server.js-DqHGsQU2.js} +2 -2
- package/build/server/chunks/chunks/{state.js-DbUk4Hrz.js → state.js-CsIZcr7q.js} +5 -4
- package/build/server/chunks/chunks/theme-prefs.svelte.js-8CaWz46g.js +109 -0
- package/build/server/chunks/chunks/{watcher.js-DU-MZGLU.js → watcher.js-CoR53lwR.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/_id_/{_server.ts.js-DQenu1Rx.js → _server.ts.js-CpeC2QLb.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/a2a/{_server.ts.js-BvEDeAhP.js → _server.ts.js-BKlF4XGH.js} +7 -6
- package/build/server/chunks/entries/endpoints/api/a2a/register/{_server.ts.js-DLJ4sQBq.js → _server.ts.js-BpEhlidV.js} +7 -6
- package/build/server/chunks/entries/endpoints/api/config/{_server.ts.js-zogZnK_B.js → _server.ts.js-BG78X__J.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/directory/{_server.ts.js-BAfRDeE_.js → _server.ts.js-Dmh7f-hU.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/pick-directory/{_server.ts.js-N21TnqYh.js → _server.ts.js-BEci0ZAx.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/presets/{_server.ts.js-C5ckDTov.js → _server.ts.js-OXFzXBSp.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/{_server.ts.js-CEPz4kVZ.js → _server.ts.js-x44GKy4R.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/cancel/{_server.ts.js-CUB5TKnW.js → _server.ts.js-Da5ZqeJ7.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/catalog/{_server.ts.js-BfDAa0Vb.js → _server.ts.js-BACv9hW-.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/changes/{_server.ts.js-QiLS5yAj.js → _server.ts.js-BtiUS3iD.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/command/{_server.ts.js-C5kJrRx-.js → _server.ts.js-BOOyd1LI.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/events/{_server.ts.js-vydjdEkJ.js → _server.ts.js-D0GwQbdF.js} +5 -4
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/fork/{_server.ts.js-y5sqH_UC.js → _server.ts.js-Bd0JYMlf.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/goal/{_server.ts.js-BoYIpj-f.js → _server.ts.js-DqAV7OOv.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/history/{_server.ts.js-SchAEll8.js → _server.ts.js-Cz4P-68E.js} +5 -4
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/models/{_server.ts.js-B8bmQCwT.js → _server.ts.js-C4fXXBIM.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/path/{_server.ts.js-DxiKkvE-.js → _server.ts.js-_SIiC8sn.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/permission/{_server.ts.js-BBexDstc.js → _server.ts.js-BiqNZiiN.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/prompt/{_server.ts.js-fd9StFXw.js → _server.ts.js-Bdx9V4oY.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/rename/{_server.ts.js-98HaDusY.js → _server.ts.js-CuBqoV3c.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/respond/{_server.ts.js-DN9APffn.js → _server.ts.js-CXPFI_Pn.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/select-model/{_server.ts.js-CeROEmUY.js → _server.ts.js-CRcaw4Yo.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/sessions/{_server.ts.js-DKHmiqIs.js → _server.ts.js-dYrtVHDP.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/{_server.ts.js-S6XZDJmC.js → _server.ts.js-BtlfuMjf.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-tree/{_server.ts.js-CA4PUERZ.js → _server.ts.js-D12kAP9B.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/{_server.ts.js-BObM3Axz.js → _server.ts.js-C9JHp1WU.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/delete/{_server.ts.js-CA34p4GV.js → _server.ts.js-bLF4Fbgn.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/rename/{_server.ts.js-DPoRM_7u.js → _server.ts.js-BSw_zD-0.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/prompts/_id_/{_server.ts.js-u-regI3R.js → _server.ts.js-bRLZ5TWI.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/prompts/{_server.ts.js-YtkQGu7O.js → _server.ts.js-ChzWZoFk.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/prompts/use/{_server.ts.js-tv0ivn2x.js → _server.ts.js-DdH5QmPS.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/settings/{_server.ts.js-DmU2MBc5.js → _server.ts.js-DwGQj520.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/terminal/{_server.ts.js-DHhod6dT.js → _server.ts.js-CwXC6Stk.js} +3 -2
- package/build/server/chunks/entries/endpoints/api/workspace/file-write/{_server.ts.js-BmEUPTSa.js → _server.ts.js-CqyKA9g2.js} +6 -5
- package/build/server/chunks/entries/endpoints/api/workspace/git-events/{_server.ts.js-_1uYvYEA.js → _server.ts.js-yu695YoE.js} +6 -5
- package/build/server/chunks/entries/endpoints/api/workspace/git-file-head/{_server.ts.js-DaXO3et9.js → _server.ts.js-BhDAvM6y.js} +6 -5
- package/build/server/chunks/entries/endpoints/api/workspace/git-map/{_server.ts.js-hp85iKSu.js → _server.ts.js-BRUgPrJ2.js} +6 -5
- package/build/server/chunks/entries/endpoints/api/workspace/git-status/{_server.ts.js-CPB-9252.js → _server.ts.js-C7VJ2G4_.js} +6 -5
- package/build/server/chunks/entries/endpoints/api/workspace/write-gate/{_server.ts.js-DKqzSQBE.js → _server.ts.js-BH5BRA_d.js} +6 -5
- package/build/server/chunks/entries/pages/{_error.svelte.js-AsgAVyDR.js → _error.svelte.js-B5TEtccE.js} +10 -9
- package/build/server/chunks/entries/pages/_layout.svelte.js-DRfiLzlz.js +20 -0
- package/build/server/chunks/entries/pages/{_page.server.ts.js-DTjoTdYK.js → _page.server.ts.js-CityLNBO.js} +3 -3
- package/build/server/chunks/entries/pages/{_page.svelte.js-CFdCjELr.js → _page.svelte.js-i6KsWK9O.js} +4654 -2413
- package/build/server/chunks/{handler-Bx2fbkEJ.js → handler-XuK3Ihhf.js} +3 -3
- package/build/server/chunks/{index.js-BldXQ38P.js → index.js-D2FEiD0I.js} +5 -4
- package/build/server/chunks/{manifest.js-Du-9DaEd.js → manifest.js-B_kahcFI.js} +45 -45
- package/build/server/chunks/nodes/0.js-C0B2o0le.js +12 -0
- package/build/server/chunks/nodes/1.js-C2e7NFqd.js +9 -0
- package/build/server/chunks/nodes/{2.js-DGLcInR6.js → 2.js-Bh3kLeYq.js} +9 -8
- package/package.json +2 -2
- package/skills/dsi-sloc/SKILL.md +117 -0
- package/skills/dsi-sloc/references/measurement.md +79 -0
- package/skills/dsi-sloc/references/report-skeleton.md +79 -0
- package/skills/dsi-thin/SKILL.md +214 -0
- package/skills/dsi-thin/references/ADR-0019-snapshot.md +363 -0
- package/skills/dsi-thin/references/authority-adr.md +28 -0
- package/skills/dsi-thin/references/input-contract.md +42 -0
- package/skills/dsi-thin/references/proven-gates.md +61 -0
- package/skills/dsi-thin/references/two-lane-contract.md +53 -0
- package/template/.dsi/prompts.sqlite +0 -0
- package/template/.dsi/prompts.sqlite-shm +0 -0
- package/template/.dsi/prompts.sqlite-wal +0 -0
- package/template/.dsi/resources/skills-reff.md +5 -4
- package/build/client/_app/immutable/assets/0.CRU0GiZX.css +0 -2
- package/build/client/_app/immutable/assets/2.Bzy6Q5kl.css +0 -1
- package/build/client/_app/immutable/chunks/-BV4MEqr.js +0 -1
- package/build/client/_app/immutable/chunks/66qbK5h1.js +0 -2
- package/build/client/_app/immutable/chunks/BLxS3bAX.js +0 -6
- package/build/client/_app/immutable/chunks/CPhcxli7.js +0 -1
- package/build/client/_app/immutable/chunks/CT1m72HM.js +0 -1
- package/build/client/_app/immutable/chunks/CxnI-Htc.js +0 -8
- package/build/client/_app/immutable/chunks/D0uZseUH.js +0 -1
- package/build/client/_app/immutable/chunks/D73RufXg.js +0 -1
- package/build/client/_app/immutable/chunks/HwuqC1sa.js +0 -1
- package/build/client/_app/immutable/chunks/NtHUheoE.js +0 -1
- package/build/client/_app/immutable/entry/app.D8WfdLSe.js +0 -2
- package/build/client/_app/immutable/entry/start.CVl0g0cv.js +0 -1
- package/build/client/_app/immutable/nodes/0.k1Ikzbp6.js +0 -1
- package/build/client/_app/immutable/nodes/1.X0If5xAN.js +0 -1
- package/build/client/_app/immutable/nodes/2.CELzu2i6.js +0 -337
- package/build/server/chunks/entries/pages/_layout.svelte.js-EFiihTdF.js +0 -18
- package/build/server/chunks/nodes/0.js-B0560RI0.js +0 -12
- package/build/server/chunks/nodes/1.js-D55AmdZs.js +0 -9
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "dsi-thin"
|
|
3
|
+
description: "Meta skill: take the dsi-sloc over-threshold report as input and batch-refactor multiple files to the ADR-0019 thin-shell standard — one branch, one batch ADR, a rolling pool of TWO parallel sub-agents (next file starts the moment one finishes), dsi-spec + dsi-task per file, gates and registry amendments enforced. Reserved keyword: /dsi-thin."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DSI Thin — Batch Refactor from the SLOC Report
|
|
7
|
+
|
|
8
|
+
One trigger → batch thin-shell refactor. The `dsi-sloc` report is the input contract; the ADR-0019 standard is the authority; each file runs through dsi-spec → dsi-task as a sequential-commit wave unit, executed by a **rolling pool of two sub-agents**.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- User runs `/dsi-thin` or says "thin out the fat files" / "refactor the sloc report list"
|
|
13
|
+
- A freshly-landed thin-shell standard (e.g. ADR-0019) needs applying to the remaining over-threshold files
|
|
14
|
+
|
|
15
|
+
### Prerequisites ⛔
|
|
16
|
+
|
|
17
|
+
- An **authority ADR** must exist that defines the thin-shell standard. If absent, STOP — draft it first via `dsi-adr`; this skill applies a standard, it does not invent one.
|
|
18
|
+
- **Resolving the authority ADR — see `references/authority-adr.md`** for the full rules. Summary:
|
|
19
|
+
1. **Live first**: discover the newest thin-shell ADR in `dev/architectural-decission/` (grep for the standard's name, e.g. "Floor Registry" / "thin shell"). Pick the ADR that **DEFINES the standard**, not merely applies it: if a candidate's TL;DR says it applies/extends another ADR's method (e.g. ADR-0020 applies ADR-0019's move-whole method at component scale), climb to the one it cites. The defining ADR's path goes into the batch ADR citation; applying ADRs (e.g. ADR-0020) are cited as WORKED EXAMPLES, not authority.
|
|
20
|
+
2. **Snapshot fallback**: `references/ADR-0019-snapshot.md` is a dated copy of the standard at skill-freeze time — use it when the repo has no match (fresh clone, wrong repo, mirror-only context), and LABEL the run as snapshot-based.
|
|
21
|
+
3. **Drift check**: when both exist and the live ADR is newer than the snapshot, note "live ADR differs from snapshot" and follow the LIVE one; refresh the snapshot as part of batch close.
|
|
22
|
+
- A fresh `dsi-sloc` report under `dev/sloc/` (run it if the latest is stale — files refactored since the report dropped below threshold and must not be re-picked).
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Step 0.5: Date Resolution ⛔ MANDATORY
|
|
27
|
+
|
|
28
|
+
Resolve today's date via `date +%Y-%m-%d`. Store as `TODAY`. Never infer from context.
|
|
29
|
+
|
|
30
|
+
## Step 1: Curate the Input List
|
|
31
|
+
|
|
32
|
+
1. Read the latest `dev/sloc/{date} - SLOC Report - *.md` over-threshold table.
|
|
33
|
+
2. **Re-verify each candidate live** — re-run the per-file SLOC count (`references/input-contract.md`); the report may be stale.
|
|
34
|
+
3. Present the ranked list to the user with, per file: raw code, its touchpoints (which shared registries/servers it hits), and a suggested **lane assignment** (see Step 3).
|
|
35
|
+
4. User picks, skips, and reorders. The confirmed list is the batch contract. Do NOT proceed without it.
|
|
36
|
+
|
|
37
|
+
## Step 2: Branch + Batch ADR
|
|
38
|
+
|
|
39
|
+
1. ⛔ **One branch per batch**: `refactor/thin-batch-{TODAY}`, created and activated BEFORE any artifact and BEFORE the first commit — no wave commit, spec commit, or ADR commit may land on any other branch. If the branch already exists (earlier run today), RESUME it: inspect its log and worktrees first, never create a same-day duplicate or commit to main while it exists.
|
|
40
|
+
2. **One batch ADR** via `dsi-adr` — but the depth rule applies to what is actually DECIDED here:
|
|
41
|
+
- Cite the authority ADR (ADR-0019) as the standard being applied; do NOT re-argue it.
|
|
42
|
+
- Decide only batch-specific questions: the confirmed file list, per-file exclusions and why, which frozen registries amend, the two-lane concurrency contract, and accepted give-ups.
|
|
43
|
+
- Numbered decisions (D1…Dn), each naming its rejected alternative; diagram showing the two-lane pool and the merge gate.
|
|
44
|
+
|
|
45
|
+
## Step 3: The Two-Lane Rolling Pool ⛔ THE CORE MECHANIC
|
|
46
|
+
|
|
47
|
+
Run the batch through **two lanes, each a sub-agent, always two in flight**. The moment one lane's file fully completes (waves committed, gates green), immediately dispatch the next queued file into that lane. Never zero in-flight, never three.
|
|
48
|
+
|
|
49
|
+
⛔ **All DEVELOPMENT is sub-agent work** (operator rule, batch R3 2026-10-10): every wave, extraction, and code commit is executed by a lane sub-agent — the orchestrator NEVER writes `src/` code. The orchestrator's job is verification and gates only: doc-gate checks, independent disk re-runs of reported gate outputs (commit hash, suite count, SLOC — a worker claim is never accepted as evidence), one-lane-at-a-time merge-backs, and adjudications. Serial milestones keep a lane sub-agent too (pool contracts to one in-flight, not zero-with-orchestrator-coding). If a sub-agent stalls (no commit across two orchestrator polls), re-dispatch a FRESH sub-agent with incremental commit phases (commit after each doc/wave so progress is observable) before ever considering takeover.
|
|
50
|
+
|
|
51
|
+
### Concurrency safety — see `references/two-lane-contract.md` for the full contract
|
|
52
|
+
|
|
53
|
+
- **Lane isolation by git worktree**: each lane gets its own worktree (`.worktrees/lane-a`, `.worktrees/lane-b`) branched from the batch branch, so two agents never share one working tree, one dev-server port, or one suite baseline. `.worktrees/` MUST be in `.gitignore` before the first worktree is created (untracked lane dirs would pollute every main-tree `git status`/`add`).
|
|
54
|
+
- **Touchpoint disjointness**: when building the queue, pair files so the two in-flight files never mutate the same shared module (e.g. never floor-registry AND panel-registry together). If every pairing collides, fall back to strictly sequential for the colliding files — say so in the batch ADR.
|
|
55
|
+
- **Merge gate**: lane worktree commits merge back to the batch branch ONE LANE AT A TIME; the other lane keeps working undisturbed. After each merge, the merging lane re-bases its next file on the updated batch branch.
|
|
56
|
+
- **Suite baseline per lane**: each lane records the suite count from ITS starting commit; its gates compare against that. The merge gate re-runs the full suite on the batch branch after every merge.
|
|
57
|
+
|
|
58
|
+
### Per-file unit (what each lane sub-agent does — the Composer session's proven chain)
|
|
59
|
+
|
|
60
|
+
0. **Read the worked example first**: ADR-0020 + its spec folder + the wave completion notes (`dev/specs/2026-10/2026-10-10 - Composer Thin Shell/`) are the reference execution — and **check `references/proven-gates.md`** before writing any controller: paid-for lessons (`$effect.root` + `destroy()`, census assertion, live-getter props, focus fidelity) that fail quietly when skipped.
|
|
61
|
+
1. `dsi-spec` for the file — visible checklist in progress; PRD + Tasks + Karpathy context + Tasks.json under `dev/specs/{YYYY-MM}/{TODAY} - {File} Thin Shell/`
|
|
62
|
+
2. `dsi-task` for that file's waves — visible checklist in progress; behavior-neutral gates per wave: suites pass UNCHANGED (count + names), `svelte-autofixer` zero issues, `scripts/dep-graph.mjs --check` frozen crossings, **census assertion** (grep the shell for the moved declarations: zero hits)
|
|
63
|
+
3. Commit per wave: `refactor(ADR-00XX Wn): {what moved whole} — suites pass unchanged (N), +M unit tests`
|
|
64
|
+
4. If the file's floor registry must amend (the 500-line registry): stage the amendment in the lane, applied at merge time
|
|
65
|
+
|
|
66
|
+
### Stop-the-line rule
|
|
67
|
+
|
|
68
|
+
A file whose suites cannot stay green unchanged, or that reveals the standard doesn't fit it, falls OUT of the batch: record it in the batch ADR as a named rejected/excluded item with the reason, and continue the pool with the next file. One bad file never blocks the batch.
|
|
69
|
+
|
|
70
|
+
## Step 4: Goal + Todo Discipline (every batch)
|
|
71
|
+
|
|
72
|
+
- ONE batch goal at dispatch: objective = "Thin-shell refactor batch: {file list} per {authority ADR} on {branch}".
|
|
73
|
+
- Todos per file-wave: `file → W1`, `file → W2`, ..., plus one per merge-back and one for the final registry sweep.
|
|
74
|
+
- Update the todo the moment each unit completes; ALWAYS show the full todo list at every phase transition and after every lane completion. Never let the todo go stale between lane events.
|
|
75
|
+
- ⛔ **Visible-checklist pattern** (see `docs/visible-checklist-pattern.md` — declare → execute → announce, same-turn): the pipeline checklist is output at the START, then **checked in progress** — at every phase transition, doc gate, and lane merge, re-output it with `[✅]/[🔄]/[❌]` and announce EACH item's result immediately after verifying it, with the disk evidence inline (commit hash, suite count, SLOC number, dep-graph line). Two layers per the pattern: the visible checklist (social) + objective disk verification (`git log`, vitest counts, verify-sloc2, dep-graph) — a worker's report is NEVER the evidence; the orchestrator re-runs the check and announces the result. A claim without a matching disk check stays `[🔄]`.
|
|
76
|
+
|
|
77
|
+
## Step 5: Close the Batch
|
|
78
|
+
|
|
79
|
+
1. All files merged, pool drained.
|
|
80
|
+
2. Registry sweep: every refactored file that dropped below threshold is removed from the floor registry; `dep-graph --check` green.
|
|
81
|
+
3. Re-run `dsi-sloc` — the "after" report. The delta (before → after raw SLOC per file) is appended to the batch ADR as its evidence section.
|
|
82
|
+
4. Batch ADR → Implemented ONLY when every picked file is done or explicitly excluded with reason.
|
|
83
|
+
5. Show the final visible checklist: ALL `[✅]` / `[❌]` with reasons. Commit and push on user command (or per batch contract).
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Pipeline Checklist — MANDATORY
|
|
88
|
+
|
|
89
|
+
This is the ONLY checklist output to the user. Declared at the start. Verified at the end.
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
📋 dsi-thin: batch on {branch} — {n} files, two-lane pool
|
|
93
|
+
|
|
94
|
+
[ ] 0.5 ⛔ Resolve today's date via `date +%Y-%m-%d` (store as TODAY)
|
|
95
|
+
|
|
96
|
+
Step 1: Curate Input
|
|
97
|
+
[ ] 1.1 Latest dsi-sloc report read; candidates re-verified live
|
|
98
|
+
[ ] 1.2 Touchpoints identified per file; lane pairing plan built
|
|
99
|
+
[ ] 1.3 User confirmed the batch list
|
|
100
|
+
|
|
101
|
+
Step 2: Branch + Batch ADR
|
|
102
|
+
[ ] 2.1 Branch refactor/thin-batch-{TODAY} created AND activated
|
|
103
|
+
[ ] 2.2 Batch ADR drafted via dsi-adr (cites authority ADR, decides batch specifics only)
|
|
104
|
+
[ ] 2.3 Two-lane worktrees created from the batch branch
|
|
105
|
+
|
|
106
|
+
Step 3: Rolling Pool (per file, until queue empty)
|
|
107
|
+
[ ] 3.1 dsi-spec per file (visible checklist shown)
|
|
108
|
+
[ ] 3.2 dsi-task per file (visible checklist shown, behavior-neutral gates per wave)
|
|
109
|
+
[ ] 3.3 Lane merge-back one at a time, full suite green on batch branch after each
|
|
110
|
+
[ ] 3.4 Next file dispatched into the freed lane immediately (never 0 in-flight)
|
|
111
|
+
[ ] 3.5 Todos updated and SHOWN after every lane event
|
|
112
|
+
|
|
113
|
+
Step 4: Close
|
|
114
|
+
[ ] 4.1 Registry amendments applied; dep-graph --check green
|
|
115
|
+
[ ] 4.2 dsi-sloc re-run; before→after delta recorded in batch ADR
|
|
116
|
+
[ ] 4.3 Batch ADR marked Implemented (or exclusions recorded with reasons)
|
|
117
|
+
[ ] 4.4 Final checklist shown, all ✅/❌
|
|
118
|
+
|
|
119
|
+
⛔ Behavioral Commitments:
|
|
120
|
+
[ ] I will NOT make any commit before the batch branch exists and is activated
|
|
121
|
+
[ ] I will NOT run three sub-agents or let the pool drop to zero while queue remains
|
|
122
|
+
[ ] I will NOT let two in-flight files share a working tree or a shared-module mutation
|
|
123
|
+
[ ] I will NOT merge both lanes simultaneously — one lane at a time, suite-gated
|
|
124
|
+
[ ] I will NOT re-argue the authority ADR in the batch ADR
|
|
125
|
+
[ ] I will NOT let one failing file block the batch — it gets excluded with a reason
|
|
126
|
+
[ ] I will NOT go silent between lane events — todo + checklist always visible
|
|
127
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Check-Off Rules
|
|
131
|
+
|
|
132
|
+
- Re-output the checklist at each phase transition and after every lane merge with `[✅]` / `[🔄]` / `[ ]`
|
|
133
|
+
- At completion, output the final checklist: ALL `[✅]`, any `[❌]` for failures
|
|
134
|
+
- Do NOT deliver without showing the final checklist
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Attention-Degradation Protection
|
|
139
|
+
|
|
140
|
+
This skill stays SHORT. The input-contract mechanics live in `references/input-contract.md`; the full two-lane concurrency contract (worktrees, pairing, merge gate, failure recovery) lives in `references/two-lane-contract.md`; paid-for extraction lessons live in `references/proven-gates.md`. This file only orchestrates.
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
# ADR-0019 — The Floor Registry: The Machine Moves Whole, the Shell Stays Thin
|
|
2
|
+
|
|
3
|
+
| | |
|
|
4
|
+
|---|---|
|
|
5
|
+
| **ADR ID** | 0019 |
|
|
6
|
+
| **Title** | The `+page.svelte` floor state machine (65 functions over one `panels` array) moves wholesale into an additive floor-registry service — one mutator delegation at a time behind a green e2e net — so the route collapses to wiring + markup and ADR-0018 D4's missed floor is met as a consequence, not by line-counting |
|
|
7
|
+
| **Status** | Implemented (2026-10-09 — see the amendment below; D5's line number carries an honest miss, recorded) |
|
|
8
|
+
| **Date** | 2026-10-09 |
|
|
9
|
+
| **Project** | deepseek-insight |
|
|
10
|
+
| **Companions** | [KB — Why the 500-Line Floor Missed](../../kb/component-graph/2026-10-09%20-%20Why%20the%20500-Line%20Floor%20Missed%20—%20Post-Implementation%20Measurement.md) (the facts section this ADR cites), [ADR-0018 — The Component Standard](2026-10-09%20-%20ADR-0018%20—%20The%20Component%20Standard%20—%20Thin%20Shells%2C%20Service%20State%2C%20Nine%20Crossings.md) (D2 state homes; D4 the failed promise this ADR re-plans), [ADR-0006 — The Panel Floor](../2026-08/2026-08-24%20—%20The%20Panel%20Floor%20—%20Many%20Conversations%2C%20One%20Page.md) (the leaf→root registry this generalizes to service scale) |
|
|
11
|
+
| **Supersedes** | Nothing — it executes what ADR-0018's D4 amendment deferred; it re-opens ADR-0006's ownership question at service scale, with ADR-0006's control grammar preserved |
|
|
12
|
+
| **Question this answers** | *The KB left open: schedule the floor-registry rewrite as its own ADR now, or leave it as documented debt until the e2e net is green?* |
|
|
13
|
+
|
|
14
|
+
## TL;DR — for the reader in a hurry
|
|
15
|
+
|
|
16
|
+
ADR-0018 promised the three god-files under 500 lines. Waves 1–3 drained the
|
|
17
|
+
fuel (prefs, feeds, timers — now tested services) and the files barely moved
|
|
18
|
+
(2,109 → 2,020), because what remains in `+page.svelte` is not a pile of
|
|
19
|
+
independent logic but **one connected machine**: 65 functions that all read and
|
|
20
|
+
write the same reactive `panels` array. This ADR decides that machine moves —
|
|
21
|
+
**whole, additively, behind a green e2e net** — into a floor-registry service.
|
|
22
|
+
This session's function census (§2) shows why the move is safe to stage: the
|
|
23
|
+
machine's 65 functions already egress through exactly **two contracts** —
|
|
24
|
+
markup prop-handlers and the two service registries — so delegating the
|
|
25
|
+
mutators one-by-one to the service touches no third surface. The 500-line
|
|
26
|
+
floor falls out at the end. Debt is not cheaper with age: every feature adds
|
|
27
|
+
a 66th function to the machine.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 1. The problem, in plain words
|
|
32
|
+
|
|
33
|
+
An operator closes a skill-shelf panel and a half-dozen things happen: the
|
|
34
|
+
shelf's tab memory dies, the selection falls to a neighbor, the loupe closes
|
|
35
|
+
if it was louvered on that panel, the desk re-persists to localStorage. All
|
|
36
|
+
of that logic lives in one 2,020-line file, in functions that share one
|
|
37
|
+
mutable array. Nobody can unit-test "closing a shelf keeps the desk honest"
|
|
38
|
+
without rendering the whole page — so nobody does, and the e2e suite (24
|
|
39
|
+
specs failing before any of this work started) is the only net, and it has
|
|
40
|
+
holes.
|
|
41
|
+
|
|
42
|
+
The newcomer's question, and the operator's, is the same: *where does the
|
|
43
|
+
floor live?* The written answer today is "in the route" — which is a
|
|
44
|
+
location, not a design. ADR-0018's D2 said state like this belongs in a
|
|
45
|
+
service. D4 promised the file would shrink and it did not, because the
|
|
46
|
+
extractable-without-moving-the-machine part was already gone. What is left
|
|
47
|
+
moves only as a machine. This ADR moves the machine.
|
|
48
|
+
|
|
49
|
+
## 2. What the codebase gives us (the facts)
|
|
50
|
+
|
|
51
|
+
Numbered; each inspected this session (2026-10-09, branch
|
|
52
|
+
`component-standard-adr`, commit `dc51a8e`):
|
|
53
|
+
|
|
54
|
+
1. **The census.** `src/routes/+page.svelte` declares **65 functions**
|
|
55
|
+
(script spans L44–L1,629; template L1,630–L2,020). Classified by where
|
|
56
|
+
their name appears:
|
|
57
|
+
- **29 markup-bound handlers** — no script caller, referenced only in the
|
|
58
|
+
template as prop/handler values into child components (e.g.
|
|
59
|
+
`setShelfTab` L226 → template L1733; `toggleExplorerPath` L336 →
|
|
60
|
+
L1771; `removePanel` L709 → seven template sites).
|
|
61
|
+
- **~27 script-internal machinery** — never appear in the template
|
|
62
|
+
(`make*Panel` factories, `insertPanel` L932, `insertionSlot` L955,
|
|
63
|
+
`pinnedSlotIndex` L967, the `doAdd`/`doReplace*` family,
|
|
64
|
+
`seedSessionId` L137, `fetchCold` L1462).
|
|
65
|
+
- **6 both-script-and-template functions** shared by both surfaces
|
|
66
|
+
(`openWorkspaceExplorer` L313, `openWorkspaceFile` L476,
|
|
67
|
+
`panelTitleFor` L828, `panelWorkspaceFor` L842, `selectPanel` L705,
|
|
68
|
+
`clearLoupeIfGone` L699).
|
|
69
|
+
- **2 dead functions** — `makeWorkspaceFilePanel` (L444) and
|
|
70
|
+
`parentOfSession` (L1197) have **zero references** in `src/` or
|
|
71
|
+
`tests/` (their caller moved to the `auto-open-slots` service in W3).
|
|
72
|
+
2. **Two egress contracts, no third.** The machine's functions reach the rest
|
|
73
|
+
of the app only via: (a) template props/handlers into child components
|
|
74
|
+
(census group 1), and (b) the two registries wired in `onMount`
|
|
75
|
+
(L1592–L1611): `registerAddPanel(doAdd)`, `registerReplaceSelected`,
|
|
76
|
+
`registerReplacePanel`, `registerReplacePanelBySession`,
|
|
77
|
+
`registerSelectPanel(selectPanel)`,
|
|
78
|
+
`registerStartPanelResize(doStartPanelResize)`,
|
|
79
|
+
`registerMovePanel(doMovePanel)` — plus `setWorkspaceState({ select:
|
|
80
|
+
selectPanel, remove: removePanel, ... })` (R6 context). No function is
|
|
81
|
+
exported; no module outside the route can touch `panels`.
|
|
82
|
+
3. **The service pattern is proven at small scale.** `page-feeds.svelte.ts`
|
|
83
|
+
already runs a module-scope reactive store with install/teardown
|
|
84
|
+
lifecycle, consumed reactively from the route (L818, L885); the KB calls
|
|
85
|
+
it "a miniature of" the registry move.
|
|
86
|
+
4. **The wall and the floor are measured.** Template + styles = L1,630–L2,020
|
|
87
|
+
≈ **391 lines** of identity-bound markup D2 forbids moving; wiring
|
|
88
|
+
(imports, two thin effects, registry mount) ≈ **100 lines**. 391 + 100 ≈
|
|
89
|
+
**490** — the <500 floor is physically reachable **only after** the
|
|
90
|
+
~1,100-line script core moves.
|
|
91
|
+
5. **The net is red.** 24 e2e specs fail pre-rewrite (KB §3; W2/W3
|
|
92
|
+
completion notes adjudicated them as pre-existing failures). Current
|
|
93
|
+
god-file sizes measured today: 2,020 / 1,269 / 1,126.
|
|
94
|
+
6. **ADR-0018's gates are live.** The boundary rule (D1) and autofixer gate
|
|
95
|
+
(D3) run in the commit path — any extraction this ADR lands is already
|
|
96
|
+
lint-guarded, so this ADR adds no new gate.
|
|
97
|
+
|
|
98
|
+
## 3. The principle, unfolded
|
|
99
|
+
|
|
100
|
+
**Ownership is where the writes live, not where the markup renders.** The
|
|
101
|
+
floor's state (`panels`, selection, loupe, resize gesture) has one legitimate
|
|
102
|
+
writer — the floor itself — and every consumer is either a leaf rendering a
|
|
103
|
+
piece of it or a leaf requesting a change. When the writer lives in a route
|
|
104
|
+
component, every consumer must be able to *see the route*; when the writer
|
|
105
|
+
lives in a service, leaves reach it through the two channels they already use
|
|
106
|
+
(props down, registry up), and the route becomes one consumer among many —
|
|
107
|
+
the thinnest one, holding only markup and identity-bound constructs (D2).
|
|
108
|
+
|
|
109
|
+
And: **a machine moves whole, but it can be *carried* one bolt at a time** —
|
|
110
|
+
provided that during the carry, exactly one component holds the write
|
|
111
|
+
authority at any moment, and each bolt-transfer is behavior-neutral and
|
|
112
|
+
verified.
|
|
113
|
+
|
|
114
|
+
## 4. Decisions
|
|
115
|
+
|
|
116
|
+
### D1 — Schedule the rewrite NOW, as this ADR's own plan — not as parked debt
|
|
117
|
+
|
|
118
|
+
The KB's open question is answered: the floor-registry rewrite starts with
|
|
119
|
+
this ADR's task run, before new features land on the floor.
|
|
120
|
+
|
|
121
|
+
**REJECTED — leave as documented debt until "the net is green":** the net and
|
|
122
|
+
the machine are coupled the other way round than the debt framing implies —
|
|
123
|
+
several of the 24 failing specs are floor-behavior specs that a rewrite would
|
|
124
|
+
exercise hardest; waiting means the next N features each add functions to the
|
|
125
|
+
machine (making the eventual move bigger) while the net stays red for the
|
|
126
|
+
same rewrite-sized reason. Debt here does not amortize; it compounds.
|
|
127
|
+
|
|
128
|
+
**REJECTED — close D4 as "met in spirit" and move on:** ADR-0018's own
|
|
129
|
+
amendment (the admission, commit `dc51a8e`) records that the plan misjudged.
|
|
130
|
+
Re-deriving the target from measurement and executing it is the only
|
|
131
|
+
correction that makes the record true; abandoning the number while keeping
|
|
132
|
+
the standard's other gates would teach every future ADR that numbers in
|
|
133
|
+
decisions are decorative.
|
|
134
|
+
|
|
135
|
+
### D2 — Additive strangle: the service owns `panels` + mutators; the route delegates one function at a time; authority never splits
|
|
136
|
+
|
|
137
|
+
A new `services/panels/floor-registry.svelte.ts` begins as a mirror: it owns
|
|
138
|
+
`panels`, `selectedPanelId`, and the mutator family, but the route's
|
|
139
|
+
functions delegate one-by-one (`function insertPanel(...) { return
|
|
140
|
+
floorRegistry.insertPanel(...) }`). Each delegation is a separate,
|
|
141
|
+
behavior-neutral commit, unit-testable as a plain module. The migration ends
|
|
142
|
+
when the last mutator moves and the route's originals delete.
|
|
143
|
+
|
|
144
|
+
**REJECTED — big-bang rewrite in one commit:** 65 functions and every
|
|
145
|
+
template closure at once against any net converts a partial failure into a
|
|
146
|
+
full-file bisect; the exact failure mode ADR-0018's amendment confessed to
|
|
147
|
+
(promising wholesale outcomes without staged verification).
|
|
148
|
+
|
|
149
|
+
**REJECTED — keep state in the route, export only the mutators:** that is the
|
|
150
|
+
split-authority trap D2 of ADR-0018 warns against, at full scale — two homes
|
|
151
|
+
for writes to `panels`, forever. The state and its writers move together;
|
|
152
|
+
that is the entire point of "the machine moves whole."
|
|
153
|
+
|
|
154
|
+
### D3 — The two egress contracts are preserved, not redesigned
|
|
155
|
+
|
|
156
|
+
The census (fact 2) is the design: template prop-handlers stay
|
|
157
|
+
prop-handlers — they become one-line closures delegating to the service —
|
|
158
|
+
and the seven registry registrations (plus `setWorkspaceState`) re-point at
|
|
159
|
+
service mutators directly. No leaf component changes its interface.
|
|
160
|
+
|
|
161
|
+
**REJECTED — convert the 29 markup handlers into registry actions ("props
|
|
162
|
+
are crossings too"):** it would churn ~24 template sites and every child
|
|
163
|
+
component's contract for zero behavioral gain, and it deepens coupling: the
|
|
164
|
+
registry's leaf→root channel exists for leaves that *cannot* see the owner,
|
|
165
|
+
not for direct children the template already binds. The props are how a
|
|
166
|
+
parent talks to its children; that is the tree working, not a violation.
|
|
167
|
+
|
|
168
|
+
**REJECTED — rewrite the template's snippet ladders during the move:** the
|
|
169
|
+
markup wall (fact 4) is identity-bound and out of scope (D2, ADR-0018);
|
|
170
|
+
touching it during the migration makes every visual diff ambiguous — was it
|
|
171
|
+
the move or the template?
|
|
172
|
+
|
|
173
|
+
### D4 — The e2e net is greened as wave zero, and the net's own verdicts are recorded
|
|
174
|
+
|
|
175
|
+
The 24 pre-existing failures are adjudicated first (fix, or
|
|
176
|
+
stash-baseline-prove-and-record with owner sign-off), so every later
|
|
177
|
+
delegation commit has a binary read: green means behavior preserved.
|
|
178
|
+
|
|
179
|
+
**REJECTED — run net repair in parallel with mutator migration:** the point
|
|
180
|
+
of the net is attribution; a red spec landing mid-migration is exactly the
|
|
181
|
+
"maybe the rewrite did it" ambiguity the KB priced (§3). Waves serialize.
|
|
182
|
+
|
|
183
|
+
### D5 — The dead weight drops first, and the target is re-derived from measurement
|
|
184
|
+
|
|
185
|
+
`makeWorkspaceFilePanel` (L444) and `parentOfSession` (L1197) — zero
|
|
186
|
+
references anywhere (fact 1) — delete before any move, so the census the
|
|
187
|
+
migration stages against is honest. The completion target is the measured
|
|
188
|
+
floor of fact 4: route = wiring (~100) + markup wall (~391) ≈ **490 lines**,
|
|
189
|
+
met as a consequence of the last delegation, verified by `wc -l`, with
|
|
190
|
+
every extracted mutator unit-tested as a plain module (ADR-0018 D4's
|
|
191
|
+
original testability intent).
|
|
192
|
+
|
|
193
|
+
**REJECTED — a new four-digit promise ("under 400!"):** the failure being
|
|
194
|
+
corrected was a target set from optimism; the replacement is the measured
|
|
195
|
+
sum of the parts that physically cannot move. The number is derived, not
|
|
196
|
+
aspirated.
|
|
197
|
+
|
|
198
|
+
## 5. Lifecycle — one mutator's migration
|
|
199
|
+
|
|
200
|
+
```mermaid
|
|
201
|
+
sequenceDiagram
|
|
202
|
+
participant R as +page.svelte (route shell)
|
|
203
|
+
participant S as floor-registry service
|
|
204
|
+
participant T as Unit tests
|
|
205
|
+
participant E as e2e net (green)
|
|
206
|
+
|
|
207
|
+
Note over S: wave 0 — net greened, dead functions deleted
|
|
208
|
+
R->>S: introduce service owning panels + mutators (mirror, unused)
|
|
209
|
+
loop per mutator (65 route originals down to 0)
|
|
210
|
+
R->>S: delegate — route fn becomes a one-line call
|
|
211
|
+
T->>S: unit-test the service mutator as a plain module
|
|
212
|
+
E->>R: full suite stays green (behavior-neutral proof)
|
|
213
|
+
R->>R: last consumer gone — delete the route original
|
|
214
|
+
end
|
|
215
|
+
Note over R: script collapses to wiring (~100) + markup (~391)
|
|
216
|
+
R->>R: wc -l near 490 — the floor, met as a consequence
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## 6. State homes and control matrix
|
|
220
|
+
|
|
221
|
+
```mermaid
|
|
222
|
+
flowchart TD
|
|
223
|
+
subgraph Before["Today - authority in the route"]
|
|
224
|
+
P1["panels + selection + loupe<br/>STATE inside +page.svelte"] --> F1["65 functions<br/>write locally"]
|
|
225
|
+
F1 -->|template props| L1["Leaf components"]
|
|
226
|
+
F1 -->|registry onMount| G1["panel-registry + workspace-context"]
|
|
227
|
+
end
|
|
228
|
+
subgraph After["Target - authority in the service"]
|
|
229
|
+
S1["floor-registry service<br/>owns panels + mutators"] -->|registered mutators| G2["panel-registry + workspace-context"]
|
|
230
|
+
R2["+page.svelte shell<br/>wiring + markup only"] -->|one-line delegations| S1
|
|
231
|
+
L2["Leaf components<br/>same props as today"] --> R2
|
|
232
|
+
end
|
|
233
|
+
Before -->|per-mutator delegation waves| After
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
| Fact | Home today | Home after | Authority during migration |
|
|
237
|
+
|---|---|---|---|
|
|
238
|
+
| `panels` array | route `$state` | service `$state` | **single** — flips once per mutator transfer, never both |
|
|
239
|
+
| Selection / loupe / resize gesture | route `$state` | service | single, as above |
|
|
240
|
+
| Mutator implementations (65) | route functions | service functions | original deleted at its wave's end |
|
|
241
|
+
| Leaf prop contracts | template bindings | **unchanged** | leaves never know the move happened |
|
|
242
|
+
| Registry registrations | route `onMount` | route `onMount` re-pointed | one commit per registration |
|
|
243
|
+
| Persistence (panel-prefs effect) | route effect | route effect reading service | flips with `panels` |
|
|
244
|
+
|
|
245
|
+
## 7. Consequences
|
|
246
|
+
|
|
247
|
+
**Gains**
|
|
248
|
+
- The floor becomes unit-testable: "closing a shelf keeps the desk honest"
|
|
249
|
+
is a plain-module test, not a rendered page.
|
|
250
|
+
- ADR-0018's D4 record becomes true on measurement, not amended again.
|
|
251
|
+
- The route stops being the single point every floor feature edits; features
|
|
252
|
+
touch the service, and the shell stays thin.
|
|
253
|
+
- The dead code (fact 1) leaves before it confuses the migration.
|
|
254
|
+
|
|
255
|
+
**Accepted give-ups**
|
|
256
|
+
- During the waves, `+page.svelte` is churn-heavy — merge contention on the
|
|
257
|
+
file every feature touches (ADR-0018 priced this; the waves concentrate it).
|
|
258
|
+
- One more service with a mount lifecycle (`page-feeds`' pattern repeated).
|
|
259
|
+
- The wave discipline serializes net repair before migration — slower start
|
|
260
|
+
than a parallel dash, chosen deliberately (D4).
|
|
261
|
+
|
|
262
|
+
**What does NOT change**
|
|
263
|
+
- Any leaf component's props, events, or markup — the census's two egress
|
|
264
|
+
contracts are preserved verbatim (D3).
|
|
265
|
+
- ADR-0006's control grammar (leaf→root requests, state down through
|
|
266
|
+
context); the registry channel just gains a service on the root side.
|
|
267
|
+
- The ADR-0018 gates (boundary rule, autofixer) — they keep guarding every
|
|
268
|
+
touched file during the waves.
|
|
269
|
+
- The template's snippet ladders and styles — untouched (D3).
|
|
270
|
+
|
|
271
|
+
## 8. File map (implementation footprint)
|
|
272
|
+
|
|
273
|
+
| Artifact | Path | Pinned by |
|
|
274
|
+
|---|---|---|
|
|
275
|
+
| Dead-function deletion | `src/routes/+page.svelte` L444, L1197 | unit suite green; grep proves zero references |
|
|
276
|
+
| The floor registry service | `src/lib/services/panels/floor-registry.svelte.ts` (name at PR) | new unit tests beside it, one per mutator family (add/replace/select/move/remove/explorer/shelf intent) |
|
|
277
|
+
| e2e net repair | `tests/`, `playwright.config.ts` as needed | the 24 adjudicated specs — verdicts recorded per spec |
|
|
278
|
+
| Route shell collapse | `src/routes/+page.svelte` (2,020 → ≈490) | existing floor e2e (greened in wave 0); `wc -l` check in the final wave's task |
|
|
279
|
+
| Registry re-pointing | route `onMount` L1592–L1611 | A2A/panel registry live tests (`playwright.a2a.config.ts`) |
|
|
280
|
+
| Facts source | KB — Why the 500-Line Floor Missed (2026-10-09) | — |
|
|
281
|
+
|
|
282
|
+
## Glossary (for the layman)
|
|
283
|
+
|
|
284
|
+
- **Floor** — the workspace page's row of panels; the thing that owns which
|
|
285
|
+
conversations are open, where they sit, and which is selected.
|
|
286
|
+
- **The machine** — shorthand for the 65 functions in `+page.svelte` that all
|
|
287
|
+
read and write the same `panels` array; you cannot move half of it without
|
|
288
|
+
splitting who is allowed to change the array.
|
|
289
|
+
- **Strangle / additive migration** — putting the new owner in place beside
|
|
290
|
+
the old one and moving responsibility one function at a time, so every
|
|
291
|
+
step can be verified and reversed.
|
|
292
|
+
- **Split authority** — two places both allowed to write the same state; the
|
|
293
|
+
worst outcome of a half-finished extraction because it silently diverges.
|
|
294
|
+
- **Egress contract** — the way the outside world reaches a function: here,
|
|
295
|
+
template props (parent→child) and the two registries (child→root).
|
|
296
|
+
- **Net** — the automated test suite that would catch a behavior change; a
|
|
297
|
+
"red net" is one with pre-existing failures that drown any new signal.
|
|
298
|
+
|
|
299
|
+
## Post-implementation amendments
|
|
300
|
+
|
|
301
|
+
### 2026-10-09 — Implemented: the machine moved whole; the line floor needs one more honest correction
|
|
302
|
+
|
|
303
|
+
**What landed** (branch `component-standard-adr`, commit `ec6c692` + the W3 commit):
|
|
304
|
+
|
|
305
|
+
- **D1/D2/D3 as decided.** `src/lib/services/panels/floor-registry.svelte.ts` (1,081 lines) owns the WHOLE
|
|
306
|
+
machine — panels, selection, loupe, file-intent mailbox, gutter-drag + afterglow, every mutator family —
|
|
307
|
+
as module-scope `$state` + plain exported functions over ONE dep seam (`configureFloorRegistry`).
|
|
308
|
+
The route never writes floor state (grep-proven at every wave boundary); the registry and the template
|
|
309
|
+
bind service mutators directly. A second service, `floor-reads.svelte.ts` (181 lines), owns the READ side
|
|
310
|
+
(spine joins, lineage/row derivations, per-session lookups) behind plain getters the route's `$derived`
|
|
311
|
+
wrappers cache — module-scope `$derived` cannot be exported (Svelte compile gate `derived_invalid_export`,
|
|
312
|
+
probed this session), which is a fact the plan did not anticipate.
|
|
313
|
+
- **D4 as decided, with the operator's attribution amendment honored:** wave 0 greened/adjudicated the net;
|
|
314
|
+
every delegation wave ran against the recorded failure set (net-verdicts.md) under the failure-set
|
|
315
|
+
attribution rule. Final sweep (W3, 2026-10-09): 175 passed / 35 failed — every failure attributed to the
|
|
316
|
+
recorded baseline, proven pre-existing, or a load flake that passes in isolation (prompt-tags 02: the one
|
|
317
|
+
new name this sweep, green in isolation at 1.9s). ZERO migration-attributable failures.
|
|
318
|
+
- **Tests:** 60-test mutator suite (`tests/unit/floor-registry.test.ts`); unit suite 4,881 green; leaf
|
|
319
|
+
components byte-identical.
|
|
320
|
+
|
|
321
|
+
**D5 — the line number, measured and MISSED, with the miss owned:** the target was wiring (~100) +
|
|
322
|
+
markup (~391) ≈ **490**. Measured: `+page.svelte` = **603 lines** (script ≈212, markup 391) — down from
|
|
323
|
+
1,993 (−70%), but 113 over the estimate. The ≈100-wiring estimate repeated the original D4 mistake at
|
|
324
|
+
smaller scale: it did not measure the irreducible shell — ~57 lines of leaf/service imports (16 Svelte
|
|
325
|
+
components), the dep-seam configure + seed/restore init, the persistence effect, the seed strip, the mount
|
|
326
|
+
registrations, and 15 one-line derived wrappers the route must keep because template names bind them. The
|
|
327
|
+
compile gate above also forbids the route from importing module deriveds directly. Cutting the remaining
|
|
328
|
+
113 would require template restructuring (D3 forbids) or logic-free line tricks (the exact vanity this ADR
|
|
329
|
+
was written to end). The measured, honest floor for this route under D1/D3 constraints is ~540–600;
|
|
330
|
+
**490 is recorded as un-meetable without breaking a harder decision**, and D5's method — re-derive from
|
|
331
|
+
measurement, never from optimism — is applied to its own number.
|
|
332
|
+
|
|
333
|
+
**Rejected — flip D5 to "met" because 603 ≈ "roughly 500":** the D4 admission exists precisely because a
|
|
334
|
+
four-digit promise was answered with rounding. 603 is reported as 603, the estimate as missed, and the
|
|
335
|
+
constraint analysis as the closure evidence.
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
(none yet — dated entries only, never edit the body in place)
|
|
339
|
+
|
|
340
|
+
## Self-audit (dsi-adr §5)
|
|
341
|
+
|
|
342
|
+
1. Alternatives enumerated per decision, not fused — **yes** (each D carries
|
|
343
|
+
its own REJECTED blocks).
|
|
344
|
+
2. Every decision names what it rejected and why the rejection lost — **yes**
|
|
345
|
+
(D1×2, D2×2, D3×2, D4×1, D5×1).
|
|
346
|
+
3. TL;DR + glossary stand alone — **yes** (the machine/net/egress story is
|
|
347
|
+
told without requiring the codebase).
|
|
348
|
+
4. Every §2 fact inspected this session — **yes** (the 65-function census,
|
|
349
|
+
the registry block L1592–L1611, template span L1,630–L2,020, dead-function
|
|
350
|
+
grep across `src/` and `tests/`, `wc -l` 2020/1269/1126, commit
|
|
351
|
+
`dc51a8e`).
|
|
352
|
+
5. Diagrams where state changes hands — **yes**: §5 sequence (a mutator's
|
|
353
|
+
migration), §6 flowchart + state-homes table; mermaid blocks contain no
|
|
354
|
+
`;` in message text.
|
|
355
|
+
6. Shape copied from a recent ADR instead of matched to the trade — **no**;
|
|
356
|
+
depth follows the KB's measured alternative space, exemplars consulted
|
|
357
|
+
per the skill.
|
|
358
|
+
7. Consequences include what does NOT change — **yes**.
|
|
359
|
+
8. File map names the pinning tests — **yes**.
|
|
360
|
+
|
|
361
|
+
## Post-implementation amendments
|
|
362
|
+
|
|
363
|
+
**2026-10-09 — D4's green-net clause amended before W1 (operator-approved).** The 26 remaining e2e failures are conversation/attachments/prompt-streaming fixture specs: pre-existing on the stash baseline, unrelated to the floor surface, and each a dedicated repair effort. Attribution switches from "zero failures" to the **failure-set rule**: every delegation commit's failure set must equal the recorded baseline set in the W0 ledger; any new failure is the migration's. D4's intent (attribution) holds; strict green moves to post-migration.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Authority ADR — resolution rules
|
|
2
|
+
|
|
3
|
+
The thin-shell standard lives in a repo ADR (currently ADR-0019, "The Floor Registry — The Machine Moves Whole, the Shell Stays Thin"). This skill must never INVENT the standard — only apply it. But a hard-coded path breaks: ADRs get amended, superseded, renumbered, and this skill also runs from the `~/.agents/skills` mirror where no repo may be present. So the authority is dual-sourced:
|
|
4
|
+
|
|
5
|
+
## Source 1 — the live ADR (preferred)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# discover candidates
|
|
9
|
+
grep -rln "thin shell\|Floor Registry\|Thin Shells" dev/architectural-decission/ | sort
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Pick the newest ADR that defines the standard and is not marked superseded: highest ADR number, latest date, and its status line says Draft/Accepted/Implemented (NOT superseded/rejected). Its path is what the batch ADR must cite, and the per-wave commits reference its number (`refactor(ADR-00XX Wn): ...`).
|
|
13
|
+
|
|
14
|
+
## Source 2 — the frozen snapshot (fallback)
|
|
15
|
+
|
|
16
|
+
`references/ADR-0019-snapshot.md` is a verbatim copy of ADR-0019 at skill-freeze time (2026-10-10, commit 392054d^). Use it only when no live ADR is discoverable (fresh clone of the mirror, skill used outside the DSI repo). When used, the batch ADR must say: "authority = ADR-0019 via skill snapshot; live repo copy not found".
|
|
17
|
+
|
|
18
|
+
## Drift check (both exist)
|
|
19
|
+
|
|
20
|
+
If the live ADR and the snapshot differ (diff the two, or compare the live file's git log against the freeze date):
|
|
21
|
+
|
|
22
|
+
- Follow the LIVE one — it is the standard of record.
|
|
23
|
+
- Say so once: "live ADR differs from the skill snapshot; following live".
|
|
24
|
+
- At batch close, refresh the snapshot: copy the live ADR over `references/ADR-0019-snapshot.md`, update this file's freeze stamp, and include the refresh in the batch commit.
|
|
25
|
+
|
|
26
|
+
## Supersession
|
|
27
|
+
|
|
28
|
+
If discovery finds a NEWER standard ADR that supersedes the thin-shell one (e.g. ADR-0030 replaces the floor model), STOP and ask the user: this skill's mechanics (per-file waves, registry amendments, unchanged-suite gates) assume the ADR-0019 shape. Adapting to a new standard is a skill revision, not a runtime decision.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Input Contract — from dsi-sloc report to batch queue
|
|
2
|
+
|
|
3
|
+
The `dsi-sloc` report is the input, but it is a SNAPSHOT. This reference defines how to turn it into a verified, lane-paired queue.
|
|
4
|
+
|
|
5
|
+
## 1. Re-verify live
|
|
6
|
+
|
|
7
|
+
The report was measured at its date; commits since then change the numbers. For every candidate in the report table, re-run the per-file raw-code count (method: `skills/dsi-sloc/references/measurement.md` — the `sloc` analyzer, not `wc -l`).
|
|
8
|
+
|
|
9
|
+
- File now under threshold → drop silently (mention in one line: "already thin — fixed by commit X" if findable)
|
|
10
|
+
- File gone/renamed → drop with a note
|
|
11
|
+
- File grew → keep, use the new figure
|
|
12
|
+
|
|
13
|
+
## 2. Identify touchpoints per file
|
|
14
|
+
|
|
15
|
+
For each candidate, list the SHARED modules it will mutate or whose registry it will amend. Quick probes:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# who imports this file (its consumers)
|
|
19
|
+
grep -rn "from.*{file-basename}" src --include='*.ts' --include='*.svelte' -l
|
|
20
|
+
|
|
21
|
+
# which shared registries it touches
|
|
22
|
+
grep -n "floor-registry|panel-registry|dsh-connection|prompt" {file} | head
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Record per file: consumers, shared-module mutations, registry amendments, test files that pin it.
|
|
26
|
+
|
|
27
|
+
## 3. Build the queue with lane pairing
|
|
28
|
+
|
|
29
|
+
The pool runs TWO lanes. Queue order must satisfy: **the two in-flight files never mutate the same shared module**.
|
|
30
|
+
|
|
31
|
+
- Sort by raw-code descending, then greedily pair A+B such that their touchpoint sets are disjoint; the pair ships to lanes a/b together, next pair waits.
|
|
32
|
+
- If a file collides with EVERYTHING (e.g. a change to `floor-registry.svelte.ts` itself, which every panel file touches), it becomes a **serial milestone**: pause lane b, run it alone on the batch branch, resume the pool after. Record the pause in the ADR.
|
|
33
|
+
- Present the pairing plan to the user with the curated list — the user may reorder by risk appetite instead.
|
|
34
|
+
|
|
35
|
+
## 4. The delta ledger
|
|
36
|
+
|
|
37
|
+
Every batch appends to the report file (or the batch ADR) a ledger:
|
|
38
|
+
|
|
39
|
+
| File | Raw before | Raw after | Waves | Excluded? |
|
|
40
|
+
|---|---|---|---|---|
|
|
41
|
+
|
|
42
|
+
Convergence rule: a file that drops below threshold leaves all future queues. The batch is done when the ledger's "after" column has no entry over threshold (or every remaining one carries a recorded exclusion).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Proven Gates — lessons from executed thin-shell runs
|
|
2
|
+
|
|
3
|
+
Each entry was paid for in a real run. Check every one during per-file
|
|
4
|
+
dsi-task waves; skip only with a stated reason.
|
|
5
|
+
|
|
6
|
+
## 1. `$effect` in `.svelte.ts` needs a root AND a teardown (Composer W1/W3)
|
|
7
|
+
|
|
8
|
+
A class constructor in a `.svelte.ts` module cannot call `$effect` bare —
|
|
9
|
+
outside component init it throws `effect_orphan`. Wrap the machine's
|
|
10
|
+
effects in `$effect.root(() => { ... })`, keep the returned stop function,
|
|
11
|
+
and expose `destroy()`; the shell calls it via `onDestroy`. Skip this and
|
|
12
|
+
unmount-time reads warn `derived_inert` — the machine's effects outlive
|
|
13
|
+
their component.
|
|
14
|
+
|
|
15
|
+
## 2. Census assertion per wave (Composer W1–W4)
|
|
16
|
+
|
|
17
|
+
Behavior-neutral extraction is proven by absence: after each wave, grep the
|
|
18
|
+
shell for the moved declarations (`$state` names, machine functions) and
|
|
19
|
+
assert **zero hits**. A grep hit on a prop KEY name (e.g. a gate key called
|
|
20
|
+
`helpVisible:`) is a false positive — verify the line, don't blind-count.
|
|
21
|
+
Record the count in the wave's completion notes.
|
|
22
|
+
|
|
23
|
+
## 3. Tests pass UNCHANGED — and failure attribution
|
|
24
|
+
|
|
25
|
+
If a pinned suite fails after an extraction, the FIRST suspect is the
|
|
26
|
+
extraction, but audit before reverting: test-side assumptions (fake DOM
|
|
27
|
+
elements missing methods, wrong type shapes vs the wire type, misread
|
|
28
|
+
grammar) get corrected with a written reason; production code does not move
|
|
29
|
+
to make a test green. This is dsi-task Step 3.5 applied.
|
|
30
|
+
|
|
31
|
+
## 4. Props/callbacks: live getters, never initial capture
|
|
32
|
+
|
|
33
|
+
When the shell passes a prop callback into a controller, pass a **getter**
|
|
34
|
+
(`get onpickcommand() { return onpickcommand; }`) — a direct reference
|
|
35
|
+
captures the initial value (svelte-check: `state_referenced_locally`) and
|
|
36
|
+
freezes the controller to mount-time wiring. This also keeps the
|
|
37
|
+
undefined-check semantics honest (BC-A3's no-callback early return).
|
|
38
|
+
|
|
39
|
+
## 5. Focus/caret fidelity is behavior
|
|
40
|
+
|
|
41
|
+
Re-focus paths are behavior, not plumbing: if the pre-move code queued a
|
|
42
|
+
microtask to set caret-to-end, the controller callback must replicate that
|
|
43
|
+
exactly (including the `== null` guard for a nulled `bind:this`); if it
|
|
44
|
+
focused directly, direct focus. Two different re-focus semantics need two
|
|
45
|
+
injected callbacks — do not unify them "while you're in there".
|
|
46
|
+
|
|
47
|
+
## 6. Neutral router exception (D2 amendment, 2026-10-10)
|
|
48
|
+
|
|
49
|
+
A keyboard/event ladder that arbitrates BETWEEN sibling machines may move
|
|
50
|
+
into its own `.svelte.ts` router only if it owns no surface and no draft —
|
|
51
|
+
constructed by the shell with the machines as deps. Never into a leaf
|
|
52
|
+
component or one of the arbitrated machines. Worked example:
|
|
53
|
+
`controller/keyboard-router.svelte.ts`.
|
|
54
|
+
|
|
55
|
+
## Worked example — the reference execution
|
|
56
|
+
|
|
57
|
+
ADR-0020 (dev/architectural-decission/2026-10/) + its spec folder
|
|
58
|
+
(dev/specs/2026-10/2026-10-10 - Composer Thin Shell/) + commits 65a1027 →
|
|
59
|
+
f4c1585 on `composer-thin-shell`: one file, four waves, suites unchanged at
|
|
60
|
+
every commit, census 1,269 → 822 lines. Lane sub-agents should read the ADR
|
|
61
|
+
and the wave completion notes before starting any file.
|