scip-query 0.10.11 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/{vendor/scip/LICENSE.scip → LICENSE} +1 -0
- package/README.md +168 -55
- package/dist/augment-vue-worker.js +1 -1
- package/dist/chunk-2VSDXOG5.js +2 -0
- package/dist/chunk-343O6EVV.js +2 -0
- package/dist/chunk-3KDUITBE.js +7 -0
- package/dist/chunk-3T2FNHIU.js +2 -0
- package/dist/chunk-3V6JQQM5.js +2 -0
- package/dist/chunk-5AAAEZ2Z.js +2 -0
- package/dist/chunk-6Q6OFLFQ.js +8 -0
- package/dist/chunk-6XA4LDHY.js +2 -0
- package/dist/chunk-75X52JTA.js +2 -0
- package/dist/{chunk-54KGX7EX.js → chunk-7HB3CZFD.js} +2 -2
- package/dist/chunk-7JZRFDCU.js +2 -0
- package/dist/chunk-7XL7J7PT.js +3 -0
- package/dist/chunk-ALHNAPS2.js +2 -0
- package/dist/{chunk-JATUZIEH.js → chunk-BDRBPG7Y.js} +2 -2
- package/dist/chunk-BN5SXXQS.js +40 -0
- package/dist/chunk-C4ICAIJ4.js +3 -0
- package/dist/{chunk-LSET2TXH.js → chunk-CMHYBXJB.js} +2 -2
- package/dist/{chunk-YWYFU2V3.js → chunk-DRPAQAFM.js} +6 -6
- package/dist/chunk-FERAXG6Y.js +72 -0
- package/dist/chunk-FLJJLSGB.js +2 -0
- package/dist/chunk-FXG3PHVW.js +9 -0
- package/dist/chunk-GCN2P4EJ.js +2 -0
- package/dist/chunk-GHXRVCIY.js +21 -0
- package/dist/chunk-GNG622H3.js +3 -0
- package/dist/chunk-H4LUPLEJ.js +2 -0
- package/dist/{chunk-BASVXNY3.js → chunk-H56MGERE.js} +4 -4
- package/dist/chunk-H7NSJ7L2.js +5 -0
- package/dist/chunk-HINMXZ6J.js +2 -0
- package/dist/chunk-HXXMPYEF.js +2 -0
- package/dist/{chunk-Z3YYR4OS.js → chunk-HZKMEXA3.js} +2 -2
- package/dist/chunk-IFSX6YVU.js +4 -0
- package/dist/chunk-ISLWJ4PY.js +10 -0
- package/dist/chunk-J5WVNZ6O.js +2 -0
- package/dist/chunk-K2HYR5A7.js +3 -0
- package/dist/chunk-K6UI6EBZ.js +2 -0
- package/dist/chunk-KJCDEDQW.js +2 -0
- package/dist/{chunk-Z4HICZGY.js → chunk-KKMOB3OJ.js} +2 -2
- package/dist/{chunk-YWOOQ4FF.js → chunk-KMVGRIO2.js} +2 -2
- package/dist/chunk-LWOOTRHC.js +2 -0
- package/dist/{chunk-EY43NV4M.js → chunk-LZNLRE4X.js} +17 -8
- package/dist/chunk-M2YXL62V.js +23 -0
- package/dist/chunk-MNEJYEHW.js +3 -0
- package/dist/chunk-MTDBHTSF.js +2 -0
- package/dist/{chunk-ZQDIXAF5.js → chunk-N2Z3CU7X.js} +2 -2
- package/dist/chunk-N7PNFLGY.js +2 -0
- package/dist/chunk-NAH5EAZS.js +6 -0
- package/dist/chunk-NBXK32I6.js +2 -0
- package/dist/chunk-NJJ7AS4F.js +2 -0
- package/dist/{chunk-FDEQIPPK.js → chunk-NLMRJ7SI.js} +2 -2
- package/dist/chunk-ODVITBYU.js +26 -0
- package/dist/chunk-ORBRX2QJ.js +2 -0
- package/dist/chunk-P36UR5II.js +2 -0
- package/dist/chunk-PYZZBIEU.js +3 -0
- package/dist/chunk-PZS6J5YG.js +16 -0
- package/dist/{chunk-LM5SHAN4.js → chunk-QARYU7R3.js} +2 -2
- package/dist/chunk-QJ3FK4TB.js +38 -0
- package/dist/chunk-QXGTGE2C.js +35 -0
- package/dist/chunk-QZ4JVECJ.js +2 -0
- package/dist/chunk-R3JY4EZ4.js +102 -0
- package/dist/{chunk-VOYOYC5T.js → chunk-R5336VHZ.js} +2 -2
- package/dist/chunk-RJMXSHKM.js +2 -0
- package/dist/chunk-STBXCPKY.js +5 -0
- package/dist/chunk-T2FQ4GHD.js +9 -0
- package/dist/chunk-TFWDJDGO.js +2 -0
- package/dist/chunk-TG7QSYCJ.js +2 -0
- package/dist/{chunk-FKCGBZAC.js → chunk-TTS75UF2.js} +5 -5
- package/dist/{chunk-BVRS7RKQ.js → chunk-U7I373V4.js} +2 -2
- package/dist/chunk-UIKLA3F5.js +2 -0
- package/dist/{chunk-P753MDDE.js → chunk-UMPNL7T6.js} +2 -2
- package/dist/chunk-URSSPS5H.js +2 -0
- package/dist/chunk-VGMUFW3J.js +2 -0
- package/dist/chunk-VXTNADIW.js +18 -0
- package/dist/chunk-VYF5HA76.js +2 -0
- package/dist/chunk-WFGOH2UI.js +43 -0
- package/dist/chunk-WGA5BBTA.js +4 -0
- package/dist/chunk-WIBFXSYB.js +6 -0
- package/dist/chunk-WPSS37EW.js +2 -0
- package/dist/chunk-WQHWIVA7.js +3 -0
- package/dist/chunk-WS3Z6W3M.js +65 -0
- package/dist/chunk-WXVGNFAO.js +2 -0
- package/dist/{chunk-6LJHXREW.js → chunk-WZLPXFZU.js} +2 -2
- package/dist/chunk-X4O6K47U.js +2 -0
- package/dist/chunk-X6OGDTQH.js +2 -0
- package/dist/chunk-XEMQUN3Z.js +20 -0
- package/dist/{chunk-7B6LP46R.js → chunk-XHWLNQVZ.js} +2 -2
- package/dist/chunk-XMR747CP.js +2 -0
- package/dist/chunk-Y6L4LXPG.js +2 -0
- package/dist/chunk-YCPASUCX.js +2 -0
- package/dist/chunk-YZXV3CU3.js +60 -0
- package/dist/chunk-ZEKBR4OK.js +10 -0
- package/dist/chunk-ZMGBWSFZ.js +2 -0
- package/dist/cli.js +462 -274
- package/dist/{config-types-BDIWAYzr.d.ts → config-types-BrHl3Bge.d.ts} +61 -1
- package/dist/{db-Djj3Nqrb.d.ts → db-_Bdx0E1W.d.ts} +1 -1
- package/dist/diff-gate-types-CG2YQ_ei.d.ts +4 -0
- package/dist/{frontend-behavior-evidence-BxKpKWUu.d.ts → frontend-behavior-evidence-EfM4_9bc.d.ts} +1 -1
- package/dist/{health-D5J42g4D.d.ts → health-BEZ1Rt0S.d.ts} +54 -2
- package/dist/index.d.ts +10 -70
- package/dist/index.js +2 -2
- package/dist/postinstall.js +1 -4
- package/dist/queries/affected.d.ts +2 -2
- package/dist/queries/affected.js +1 -1
- package/dist/queries/bottlenecks.d.ts +2 -2
- package/dist/queries/bottlenecks.js +1 -1
- package/dist/queries/by-kind.d.ts +2 -2
- package/dist/queries/by-kind.js +1 -1
- package/dist/queries/call-graph.d.ts +2 -2
- package/dist/queries/call-graph.js +1 -1
- package/dist/queries/change-surface.d.ts +2 -2
- package/dist/queries/change-surface.js +1 -1
- package/dist/queries/cleanup-plan.d.ts +2 -2
- package/dist/queries/cleanup-plan.js +1 -1
- package/dist/queries/co-change.d.ts +12 -2
- package/dist/queries/co-change.js +1 -1
- package/dist/queries/code.d.ts +2 -2
- package/dist/queries/code.js +1 -1
- package/dist/queries/complexity-hotspots.d.ts +7 -3
- package/dist/queries/complexity-hotspots.js +1 -1
- package/dist/queries/complexity.d.ts +42 -4
- package/dist/queries/complexity.js +1 -1
- package/dist/queries/convergence.d.ts +2 -2
- package/dist/queries/convergence.js +1 -1
- package/dist/queries/coupling.d.ts +2 -2
- package/dist/queries/coupling.js +1 -1
- package/dist/queries/cycles.d.ts +12 -3
- package/dist/queries/cycles.js +1 -1
- package/dist/queries/dataflow.d.ts +2 -2
- package/dist/queries/dataflow.js +1 -1
- package/dist/queries/dead.d.ts +3 -3
- package/dist/queries/dead.js +1 -1
- package/dist/queries/deep-chains.d.ts +2 -2
- package/dist/queries/deep-chains.js +1 -1
- package/dist/queries/deps.d.ts +2 -2
- package/dist/queries/deps.js +1 -1
- package/dist/queries/diff-gate.d.ts +65 -8
- package/dist/queries/diff-gate.js +1 -1
- package/dist/queries/diff-impact.d.ts +21 -3
- package/dist/queries/diff-impact.js +1 -1
- package/dist/queries/doc-drift.d.ts +29 -2
- package/dist/queries/doc-drift.js +1 -1
- package/dist/queries/drift.d.ts +15 -3
- package/dist/queries/drift.js +1 -1
- package/dist/queries/duplicate-bodies.d.ts +55 -0
- package/dist/queries/duplicate-bodies.js +2 -0
- package/dist/queries/extract-candidates.d.ts +2 -2
- package/dist/queries/extract-candidates.js +1 -1
- package/dist/queries/fan.d.ts +2 -2
- package/dist/queries/fan.js +1 -1
- package/dist/queries/files.d.ts +4 -3
- package/dist/queries/files.js +1 -1
- package/dist/queries/health.d.ts +3 -3
- package/dist/queries/health.js +1 -1
- package/dist/queries/hierarchy.d.ts +2 -2
- package/dist/queries/hierarchy.js +1 -1
- package/dist/queries/hotspots.d.ts +2 -2
- package/dist/queries/hotspots.js +1 -1
- package/dist/queries/imports.d.ts +2 -2
- package/dist/queries/imports.js +1 -1
- package/dist/queries/incomplete-migration.d.ts +3 -2
- package/dist/queries/incomplete-migration.js +1 -1
- package/dist/queries/index.d.ts +12 -7
- package/dist/queries/index.js +1 -1
- package/dist/queries/isolated.d.ts +2 -2
- package/dist/queries/isolated.js +1 -1
- package/dist/queries/locality-candidates.d.ts +2 -2
- package/dist/queries/locality-candidates.js +1 -1
- package/dist/queries/members.d.ts +2 -2
- package/dist/queries/members.js +1 -1
- package/dist/queries/methods.d.ts +2 -2
- package/dist/queries/methods.js +1 -1
- package/dist/queries/outline.d.ts +2 -2
- package/dist/queries/outline.js +1 -1
- package/dist/queries/passthrough-candidates.d.ts +11 -3
- package/dist/queries/passthrough-candidates.js +1 -1
- package/dist/queries/plan-context.d.ts +3 -2
- package/dist/queries/plan-context.js +1 -1
- package/dist/queries/react-component-duplicates.d.ts +7 -2
- package/dist/queries/react-component-duplicates.js +1 -1
- package/dist/queries/react-hook-candidates.d.ts +3 -3
- package/dist/queries/react-hook-candidates.js +1 -1
- package/dist/queries/react-large-component-pressure.d.ts +2 -2
- package/dist/queries/react-large-component-pressure.js +1 -1
- package/dist/queries/recent-duplicates.d.ts +2 -2
- package/dist/queries/recent-duplicates.js +1 -1
- package/dist/queries/redundant-reexports.d.ts +2 -2
- package/dist/queries/redundant-reexports.js +1 -1
- package/dist/queries/refs.d.ts +2 -2
- package/dist/queries/refs.js +1 -1
- package/dist/queries/self-audit.d.ts +9 -4
- package/dist/queries/self-audit.js +1 -1
- package/dist/queries/similar-chains.d.ts +2 -2
- package/dist/queries/similar-chains.js +1 -1
- package/dist/queries/similar-files.d.ts +2 -2
- package/dist/queries/similar-files.js +1 -1
- package/dist/queries/similar-signatures.d.ts +17 -10
- package/dist/queries/similar-signatures.js +1 -1
- package/dist/queries/similar.d.ts +85 -17
- package/dist/queries/similar.js +1 -1
- package/dist/queries/slice.d.ts +2 -2
- package/dist/queries/slice.js +1 -1
- package/dist/queries/stale-abstractions.d.ts +2 -2
- package/dist/queries/stale-abstractions.js +1 -1
- package/dist/queries/stats.d.ts +2 -2
- package/dist/queries/surface.d.ts +2 -2
- package/dist/queries/surface.js +1 -1
- package/dist/queries/symbols.d.ts +2 -2
- package/dist/queries/symbols.js +1 -1
- package/dist/queries/system.d.ts +2 -2
- package/dist/queries/system.js +1 -1
- package/dist/queries/trace.d.ts +2 -2
- package/dist/queries/trace.js +1 -1
- package/dist/queries/twin-ab.d.ts +55 -0
- package/dist/queries/twin-ab.js +2 -0
- package/dist/queries/twin-drift.d.ts +97 -0
- package/dist/queries/twin-drift.js +2 -0
- package/dist/queries/unused-imports.d.ts +2 -2
- package/dist/queries/unused-imports.js +1 -1
- package/dist/queries/unused-params.d.ts +2 -2
- package/dist/queries/unused-params.js +1 -1
- package/dist/queries/vue-component-duplicates.d.ts +7 -2
- package/dist/queries/vue-component-duplicates.js +1 -1
- package/dist/queries/vue-composable-candidates.d.ts +3 -3
- package/dist/queries/vue-composable-candidates.js +1 -1
- package/dist/queries/vue-large-view-pressure.d.ts +6 -2
- package/dist/queries/vue-large-view-pressure.js +1 -1
- package/dist/queries/wrapper-candidates.d.ts +2 -2
- package/dist/queries/wrapper-candidates.js +1 -1
- package/dist/reindex-worker.js +9 -9
- package/dist/reindex.d.ts +30 -4
- package/dist/reindex.js +19 -19
- package/dist/runtime.d.ts +12 -6
- package/dist/runtime.js +2 -2
- package/dist/{scip-cli-CnK9Va4O.d.ts → scip-cli-C7cg4ZHR.d.ts} +1 -1
- package/dist/symbol-types-DaoeXKUt.d.ts +66 -0
- package/docs/AGENT_GUIDE.md +20 -18
- package/docs/AI_FAILURE_MODES.md +36 -13
- package/docs/API.md +1 -1
- package/docs/COMMAND_REFERENCE.md +57 -14
- package/docs/DETECTOR_GUIDE.md +20 -3
- package/docs/REGEX_POLICY.md +34 -0
- package/docs/analyzer-inventory.md +48 -3
- package/docs/analyzer-validation-ledger.md +41 -6
- package/package.json +23 -7
- package/scripts/build-scip-windows.mjs +10 -7
- package/scripts/evidence-product-contract.mjs +197 -0
- package/skills/_shared/SKILL.md +243 -0
- package/skills/_shared/agents/openai.yaml +4 -0
- package/skills/scip-api-impact/SKILL.md +55 -71
- package/skills/scip-claim-audit/SKILL.md +105 -0
- package/skills/scip-claim-audit/agents/openai.yaml +4 -0
- package/skills/scip-cleanup-audit/SKILL.md +122 -0
- package/skills/scip-cleanup-audit/agents/openai.yaml +4 -0
- package/skills/scip-cleanup-improve/SKILL.md +84 -0
- package/skills/scip-cleanup-improve/agents/openai.yaml +4 -0
- package/skills/scip-concrete-plan/SKILL.md +181 -0
- package/skills/scip-concrete-plan/agents/openai.yaml +4 -0
- package/skills/scip-conductor/SKILL.md +133 -0
- package/skills/scip-conductor/agents/openai.yaml +4 -0
- package/skills/scip-debug/SKILL.md +60 -58
- package/skills/scip-diagram/SKILL.md +64 -94
- package/skills/scip-directory-architecture/SKILL.md +65 -107
- package/skills/scip-doc-reconcile/SKILL.md +56 -67
- package/skills/scip-explore/SKILL.md +78 -210
- package/skills/scip-hyper-optimization/SKILL.md +124 -198
- package/skills/scip-integrity-audit/SKILL.md +103 -0
- package/skills/scip-integrity-audit/agents/openai.yaml +4 -0
- package/skills/scip-language-playbook/SKILL.md +56 -326
- package/skills/scip-maintainability/SKILL.md +80 -219
- package/skills/scip-probe-reachability/SKILL.md +92 -0
- package/skills/scip-probe-reachability/agents/openai.yaml +4 -0
- package/skills/scip-query/SKILL.md +108 -124
- package/skills/scip-react-maintainability/SKILL.md +64 -82
- package/skills/scip-setup/SKILL.md +121 -0
- package/skills/scip-setup/agents/openai.yaml +4 -0
- package/skills/scip-tla-model-system/SKILL.md +138 -0
- package/skills/scip-tla-model-system/agents/openai.yaml +4 -0
- package/skills/scip-triage-issue/SKILL.md +53 -41
- package/skills/scip-twin-drift/SKILL.md +107 -0
- package/skills/scip-twin-drift/agents/openai.yaml +4 -0
- package/skills/scip-verify/SKILL.md +70 -88
- package/skills/scip-vue-maintainability/SKILL.md +67 -94
- package/dist/chunk-2KHTSEIL.js +0 -102
- package/dist/chunk-3VD3JMK2.js +0 -2
- package/dist/chunk-4UZO3XCV.js +0 -35
- package/dist/chunk-5GOLFJEO.js +0 -8
- package/dist/chunk-5OST6GYB.js +0 -2
- package/dist/chunk-65AU3HFZ.js +0 -2
- package/dist/chunk-6GN7FXCH.js +0 -2
- package/dist/chunk-6IR2AOBM.js +0 -7
- package/dist/chunk-6JRV4MY2.js +0 -23
- package/dist/chunk-6QSOCTZT.js +0 -18
- package/dist/chunk-72KY2ZFO.js +0 -2
- package/dist/chunk-7GO4EQF5.js +0 -2
- package/dist/chunk-7IVSJJZU.js +0 -7
- package/dist/chunk-7TWLSZK5.js +0 -2
- package/dist/chunk-A536TEU4.js +0 -3
- package/dist/chunk-AVWPHM2Q.js +0 -4
- package/dist/chunk-B32FX5KB.js +0 -2
- package/dist/chunk-B6MJ5VQV.js +0 -2
- package/dist/chunk-BFXPG2VN.js +0 -2
- package/dist/chunk-BSN22NRK.js +0 -9
- package/dist/chunk-BZ53S4ZN.js +0 -2
- package/dist/chunk-C5CTSJ6X.js +0 -6
- package/dist/chunk-CO5GJRP7.js +0 -2
- package/dist/chunk-CW5YFOCP.js +0 -5
- package/dist/chunk-DS6QEB3G.js +0 -5
- package/dist/chunk-E35O7UCB.js +0 -2
- package/dist/chunk-EXDQ35NN.js +0 -2
- package/dist/chunk-FAYI6KZ5.js +0 -2
- package/dist/chunk-FFVIFETB.js +0 -2
- package/dist/chunk-FG4NT6VY.js +0 -2
- package/dist/chunk-FXNWFMKW.js +0 -25
- package/dist/chunk-G5UPYQGL.js +0 -4
- package/dist/chunk-GQBMH2TQ.js +0 -2
- package/dist/chunk-GRJY65YT.js +0 -2
- package/dist/chunk-HF25DFSC.js +0 -3
- package/dist/chunk-HHN2B5KA.js +0 -2
- package/dist/chunk-IHUETYFW.js +0 -2
- package/dist/chunk-JCLDUKT6.js +0 -38
- package/dist/chunk-JGN2ZFJR.js +0 -2
- package/dist/chunk-JM72FNGA.js +0 -2
- package/dist/chunk-JME7OWD3.js +0 -2
- package/dist/chunk-KDFONWTW.js +0 -40
- package/dist/chunk-LPL4MA6R.js +0 -2
- package/dist/chunk-LZHUWKGD.js +0 -2
- package/dist/chunk-M4COR2H6.js +0 -2
- package/dist/chunk-NOJAM5ZV.js +0 -21
- package/dist/chunk-O6ZH6C6Y.js +0 -2
- package/dist/chunk-OBGRLXWF.js +0 -3
- package/dist/chunk-OLTESY4K.js +0 -3
- package/dist/chunk-ONPCQ2PM.js +0 -6
- package/dist/chunk-P4KYUPBD.js +0 -4
- package/dist/chunk-P5RYBRIO.js +0 -4
- package/dist/chunk-P7AL7Y37.js +0 -2
- package/dist/chunk-PFOCOG57.js +0 -2
- package/dist/chunk-QLAUCRDJ.js +0 -2
- package/dist/chunk-QPU7EXAW.js +0 -2
- package/dist/chunk-QYB5P7GL.js +0 -2
- package/dist/chunk-RNM6LMCF.js +0 -2
- package/dist/chunk-RVWSAMTT.js +0 -2
- package/dist/chunk-TK7O5ER5.js +0 -3
- package/dist/chunk-TQ5W2H3S.js +0 -4
- package/dist/chunk-USPV3T5K.js +0 -2
- package/dist/chunk-UUBMFL3F.js +0 -59
- package/dist/chunk-VCQYSG2M.js +0 -10
- package/dist/chunk-VUKC6F77.js +0 -20
- package/dist/chunk-W2CBNBEL.js +0 -71
- package/dist/chunk-W6BVEKYC.js +0 -3
- package/dist/chunk-WUCEKFQC.js +0 -3
- package/dist/chunk-XUGQU7PM.js +0 -41
- package/dist/chunk-Y5NBHMQX.js +0 -2
- package/dist/chunk-YCOFCT4B.js +0 -2
- package/dist/chunk-YZA6PPZL.js +0 -3
- package/skills/concrete-plan/SKILL.md +0 -372
- package/skills/concrete-plan/agents/openai.yaml +0 -4
- package/skills/scip-adoption/SKILL.md +0 -122
- package/skills/scip-adoption/agents/openai.yaml +0 -4
- package/skills/scip-ai-cleanup/SKILL.md +0 -153
- package/skills/scip-ai-cleanup/agents/openai.yaml +0 -4
- package/skills/scip-debloat/SKILL.md +0 -439
- package/skills/scip-debloat/agents/openai.yaml +0 -4
- package/skills/scip-health-audit/SKILL.md +0 -162
- package/skills/scip-health-audit/agents/openai.yaml +0 -4
- package/skills/scip-health-improve/SKILL.md +0 -155
- package/skills/scip-health-improve/agents/openai.yaml +0 -4
- package/skills/scip-query-setup/SKILL.md +0 -170
- package/skills/scip-query-setup/agents/openai.yaml +0 -3
- package/vendor/scip/README.md +0 -6
- package/vendor/scip/win32-arm64/scip.exe +0 -0
- package/vendor/scip/win32-x64/scip.exe +0 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scip-tla-model-system
|
|
3
|
+
description: Model TypeScript systems with TLA+ and scip-query evidence. Use to scaffold, verify, instrument, or trace-check TLA+ specs, mapping files, configs, regression models, counterexample loops, or code/model conformance for an existing system.
|
|
4
|
+
commands:
|
|
5
|
+
- template: 'scip-query tla scaffold <file>'
|
|
6
|
+
when: 'Start here for a new model: derive a draft spec, config, and mapping from indexed code.'
|
|
7
|
+
- template: 'scip-query tla verify <spec>'
|
|
8
|
+
when: 'Mechanical conformance: referents, reads/writes, calls, and the model checker.'
|
|
9
|
+
- template: 'scip-query tla instrument <spec>'
|
|
10
|
+
when: 'Generate a trace recorder plus wiring sites for each mapped action.'
|
|
11
|
+
- template: 'scip-query tla trace-check <spec> --trace <file>'
|
|
12
|
+
when: "Semantic conformance: check a recorded execution against the model's Next relation."
|
|
13
|
+
- template: 'scip-query tla fetch-tools'
|
|
14
|
+
when: 'Download the pinned tla2tools.jar into the cache when the checker is unavailable.'
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# scip-tla-model-system
|
|
18
|
+
|
|
19
|
+
Use this skill when a TypeScript system needs a TLA+ model tied to code evidence. A modeled slice is the bounded part of the real system represented by the model: state, transitions, inputs, outputs, and failure modes.
|
|
20
|
+
|
|
21
|
+
Load shared mechanics from [`../_shared/SKILL.md`](../_shared/SKILL.md).
|
|
22
|
+
|
|
23
|
+
<!-- BEGIN GENERATED SKILL COMMANDS -->
|
|
24
|
+
|
|
25
|
+
## Commands for this skill
|
|
26
|
+
|
|
27
|
+
| Command | Purpose | When |
|
|
28
|
+
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
29
|
+
| `scip-query tla scaffold <file>` | TLA+ model workflow: verify a model and mapping contract, scaffold a draft model from indexed code, generate a trace recorder, or check a recorded trace against the next-state relation | Start here for a new model: derive a draft spec, config, and mapping from indexed code. |
|
|
30
|
+
| `scip-query tla verify <spec>` | TLA+ model workflow: verify a model and mapping contract, scaffold a draft model from indexed code, generate a trace recorder, or check a recorded trace against the next-state relation | Mechanical conformance: referents, reads/writes, calls, and the model checker. |
|
|
31
|
+
| `scip-query tla instrument <spec>` | TLA+ model workflow: verify a model and mapping contract, scaffold a draft model from indexed code, generate a trace recorder, or check a recorded trace against the next-state relation | Generate a trace recorder plus wiring sites for each mapped action. |
|
|
32
|
+
| `scip-query tla trace-check <spec> --trace <file>` | TLA+ model workflow: verify a model and mapping contract, scaffold a draft model from indexed code, generate a trace recorder, or check a recorded trace against the next-state relation | Semantic conformance: check a recorded execution against the model's Next relation. |
|
|
33
|
+
| `scip-query tla fetch-tools` | TLA+ model workflow: verify a model and mapping contract, scaffold a draft model from indexed code, generate a trace recorder, or check a recorded trace against the next-state relation | Download the pinned tla2tools.jar into the cache when the checker is unavailable. |
|
|
34
|
+
|
|
35
|
+
Use this shortlist first. Open [`../_shared/SKILL.md`](../_shared/SKILL.md) only when it is insufficient.
|
|
36
|
+
|
|
37
|
+
<!-- END GENERATED SKILL COMMANDS -->
|
|
38
|
+
|
|
39
|
+
## Choose the Slice
|
|
40
|
+
|
|
41
|
+
Model the part with the most dangerous interleavings — retries, concurrency, partial failure, money, state machines with guards. Never model a linear happy path: a model that cannot meaningfully fail verifies nothing. If the state space would exceed roughly a million states, the model is too concrete; collapse data you never branch on and replace unbounded values with small symbolic sets. `scaffold` requires the target file to own mutable module-level state (a `let`/const plus a writer function) or, failing that, a class whose instance fields a method of that same class writes; a file of pure functions or constants is rejected — pick the file that holds the state, not the file that only computes over it.
|
|
42
|
+
|
|
43
|
+
**Known boundary: class fields on files with any indexed method are usually invisible to `scaffold`.** The write scanner can find `this.field = ...` writes fine, but the class-field fallback only ever sees candidates that `getDefinitionsForFile` actually returns — and that catalog (`definition-catalog.ts`/`symbol-row-policy.ts`) deliberately drops class-member fallback rows whenever the file has any other primary-indexed (enclosing-range) definition, which any class with a constructor or a named method always has. So a concurrency class like a lock or connection pool — exactly the shape this skill most wants to model — will almost always report "no mutable state discovered", not because the state isn't there but because the shared definition catalog hides it one layer below scaffold. When you hit this: model by hand from `plan-context`/`trace` evidence instead of via `scaffold`, or narrow the target file so the class in question is the only indexed definition in it. Widening the catalog itself is out of scope for this skill's tooling — it's a shared primitive nearly every other command depends on.
|
|
44
|
+
|
|
45
|
+
## Loop
|
|
46
|
+
|
|
47
|
+
1. Explore the target with `scip-query plan-context <target>`, `system`, `trace`, `call-graph`, and `dataflow` until state and transitions are concrete.
|
|
48
|
+
2. Run `scip-query tla scaffold <file>` to generate the draft spec, config, and mapping (`--out` must stay inside the project root). Resolve every `TODO` it emits: guards, domains, initial values. The scaffold derives _what_ changes; you supply _when_ it may. TRIAGE the output first: if the discovered variables are mostly constants and the system's real state lives in files or a database (locks, caches, published artifacts), keep the mapping referents but discard the scaffolded variable set — hand-model the protocol's conceptual state and bind it with `resource` aliases instead. `tla verify` does not detect unfilled `TODO`s and will report PASS on a placeholder model — grep the spec for `TODO` before trusting a green run.
|
|
49
|
+
3. Strengthen the model per the quality rules below.
|
|
50
|
+
4. Run `scip-query tla verify <spec> --map <map> --config <cfg>`. Read the Proof line: every waiver must carry a reason you would defend in review.
|
|
51
|
+
5. Wire the recorder from `scip-query tla instrument`, run the existing tests with `SCIP_TLA_TRACE=<path>`, then run `scip-query tla trace-check <spec> --trace <path>`. Acceptance means the code's observed behavior is a behavior of the model; divergence names the step to investigate. Modeling a fix-vs-regression pair as two named `Next` relations in one spec (e.g. `NextCurrent`/`NextVulnerable`)? Pass `--next <operator>` to pick which one the trace must satisfy — the harness defaults to a bare `Next`, which such specs deliberately don't define.
|
|
52
|
+
6. Classify every finding as code bug, model bug, mapping bug, insufficient trace/alias evidence, or accepted non-modeled behavior.
|
|
53
|
+
7. Patch code, model, or mapping and rerun until only explicitly waived uncertainty remains.
|
|
54
|
+
|
|
55
|
+
The loop is complete only when `tla verify` passes with reasoned waivers, at least one recorded trace passes `tla trace-check`, and unexercised actions are listed as accepted gaps.
|
|
56
|
+
|
|
57
|
+
## Model Quality Rules
|
|
58
|
+
|
|
59
|
+
- **TypeOK first.** Write the type invariant before any property; it catches most modeling mistakes at the lowest checking cost.
|
|
60
|
+
- **Every invariant needs a failure story.** Before running TLC, write down the concrete scenario that would violate it. If no scenario exists, the invariant is decorative — delete or replace it.
|
|
61
|
+
- **Falsify every invariant individually.** One break-test is not enough: for EACH invariant there must be a documented variant or mutation under which TLC refutes it (the CurrentSpec/VulnerableSpec pattern makes this permanent instead of a throwaway edit). An invariant no variant can violate is decorative — delete or redesign it.
|
|
62
|
+
- **Break the model on purpose.** After the first green run, remove one guard or widen one domain and confirm TLC catches it. A spec that cannot fail proves nothing. Restore it afterward.
|
|
63
|
+
- **Safety before liveness.** Add fairness only when a liveness property demands it; check deadlock unless termination is intended.
|
|
64
|
+
- **Bound the space deliberately.** Small symbolic constant sets, symmetry where sound, sequences kept short. Nondeterministic `\in` transitions from the scaffold are permissive placeholders — tighten them to concrete transitions as you learn the code.
|
|
65
|
+
- **Trace divergence taxonomy.** When `trace-check` diverges: a missing model transition means the model is too strict; an impossible recorded state means instrumentation projects the wrong slice; a genuinely illegal code transition is a bug — write the regression model before fixing it.
|
|
66
|
+
|
|
67
|
+
## Fast Regression Models
|
|
68
|
+
|
|
69
|
+
A regression model is a small TLA+ module or checker config derived from a counterexample, production bug, or suspected transition.
|
|
70
|
+
|
|
71
|
+
1. Preserve the full model as source of truth.
|
|
72
|
+
2. Create a companion regression spec/config named for the failure, seeded from the exact counterexample trace (a diverging `trace-check` output is already that trace).
|
|
73
|
+
3. Prefer bounded constants and narrowed action sets over weakening the main model.
|
|
74
|
+
4. Run the regression first after each patch; run the full model after it passes.
|
|
75
|
+
5. Keep the regression if it protects future behavior.
|
|
76
|
+
|
|
77
|
+
## Mapping Contract
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"module": "specs/Queue.tla",
|
|
82
|
+
"config": "specs/Queue.cfg",
|
|
83
|
+
"scope": ["src/queue"],
|
|
84
|
+
"variables": {
|
|
85
|
+
"queue": { "code": ["src/queue/store.ts/queue"], "aliases": ["queue"] },
|
|
86
|
+
"lockOwner": {
|
|
87
|
+
"code": ["src/queue/lock.ts/LockMetadata#pid"],
|
|
88
|
+
"aliases": ["pid"],
|
|
89
|
+
"resource": { "path": "lockPath" }
|
|
90
|
+
},
|
|
91
|
+
"phase": {
|
|
92
|
+
"code": ["src/queue/lock.ts/__phase_no_stored_field__"],
|
|
93
|
+
"aliases": ["__phase_unmatchable__"],
|
|
94
|
+
"waive": { "reason": "phase is a pure control-flow position; no code field stores it" }
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"actions": {
|
|
98
|
+
"Enqueue": {
|
|
99
|
+
"code": ["src/queue/commands.ts/enqueue"],
|
|
100
|
+
"reads": ["queue"],
|
|
101
|
+
"writes": ["queue"],
|
|
102
|
+
"waive": { "reason": "required only when a declared fact cannot be statically proven" }
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"invariants": ["TypeOK"],
|
|
106
|
+
"traces": ["specs/queue-run.trace.json"]
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`code` entries must resolve through `scip-query trace`; variables must map to value-like symbols (a const, let, field, or property holding runtime state — never a type). Waivers are per-fact and require a reason; blanket `allowUnknown` is legacy.
|
|
111
|
+
|
|
112
|
+
`resource` binds a variable to filesystem state — a lock file, a published artifact — anything the model treats as owned state but that code only touches through path-taking calls, never a plain assignment. The conformance scanner classifies `writeFileSync`/`rmSync`/`renameSync`/`mkdirSync`/`unlinkSync` calls whose first argument's text contains the declared `path` as writes of the variable, and `readFileSync`/`existsSync`/`statSync` calls the same way as reads. The match is textual containment, not a resolved value — evidence tier stays `static-action`, and a resource-bound variable still needs a value-like `code` referent for the kind check.
|
|
113
|
+
|
|
114
|
+
`statements` (Q2) binds a variable to SQL-backed state — prepared statements, table rows behind `db.prepare(...)`/`.exec(...)`/tagged templates. Each entry is `{ "pattern": "<substring or regex>" }`, compiled as a RegExp. Any call expression argument whose static string text (a string literal, or the static fragments of a template literal — `${...}` interpolations excluded) matches `pattern` is classified by its leading SQL verb: `INSERT`/`UPDATE`/`DELETE`/`REPLACE` is a write, `SELECT` is a read. Matching is not restricted to a callee allowlist (SQL APIs vary too much) — classification comes entirely from the matched text's leading verb. Two variables sharing a `statements` pattern is a mapping-load error, same as a shared `resource` path. Evidence tier stays `static-action`. Dynamic SQL built by string concatenation has no static text to match and still falls through to a waiver.
|
|
115
|
+
|
|
116
|
+
`variables.<v>.waive: {reason}` exempts that one variable's `missing-referent`/`invalid-referent-kind` findings — for state that genuinely has no code twin (a pure control-flow position, a derived decision, a value observable only through `process.exitCode`). It does not exempt read/write facts; those stay on the action's own `waive`. Prefer this over the old workaround of citing an unrelated real symbol just to satisfy the value-like-kind check — name a referent that plainly does not resolve (or does resolve but to the wrong kind) and waive it honestly; a reader should never have to guess that a `code[]` entry is a decoy.
|
|
117
|
+
|
|
118
|
+
Top-level `"unmappedWriteScope": "actions" | "scope-files"` (default `"scope-files"`) controls how strictly `scope` is enforced: the default requires every function anywhere in `scope` that touches a modeled variable to be mapped as an action, or its write is a hard `unmapped-write` error. Set `"actions"` to opt out of that whole-file sweep when `scope` legitimately contains code the mapping was never meant to cover in full — only the per-action write/read checks still run.
|
|
119
|
+
|
|
120
|
+
Top-level `"init": { "codeRefs": ["file#function", ...], "waive"?: {"reason": ...} }` (Q3) binds the model's `Init` to the code referent(s) that materialize initial state — most often a lazy-init factory. `codeRefs` resolves and kind-checks like an action's `code` (function-like, `missing-referent`/`invalid-referent-kind` findings apply, `waive` exempts both). Writes statically found inside an Init referent's own range are Init-attributed: they are excluded from `unmapped-write` findings without needing `unmappedWriteScope: "actions"`. `init.codeRefs` must not overlap any action's `code` referents — that is a mapping-load error, same category as a variable-alias collision.
|
|
121
|
+
|
|
122
|
+
## Mapping Discipline
|
|
123
|
+
|
|
124
|
+
- **Alias selection is the sharpest knife.** Never alias a variable to a ubiquitous local identifier (`connection`, `result`, `data`) — every function touching that local gets misattributed across actions. For state with no code twin, use a deliberately unmatchable alias (e.g. `evidenceRowsModelOnly`) so the static layer neither proves nor pollutes, and let the reasoned waiver carry the fact.
|
|
125
|
+
- **Know the three state backings.** Program variables: normal aliases. Filesystem-backed state (locks, published artifacts): `resource: { "path": ... }` bindings make fs calls provable. Database/SQL-backed state (prepared statements, table rows): `statements: [{ "pattern": ... }]` bindings make it provable too (Q2) — a call argument's static SQL text matching `pattern` is classified as a write or read by its leading verb. Only genuinely dynamic SQL (built by string concatenation, no static text to match) still needs a waiver naming the residual class; never fake attribution.
|
|
126
|
+
- **Lazy initialization is Init, not an action.** A factory that lazily builds state corresponds to the model's `Init`. Top-level `"init": { "codeRefs": ["file#function", ...] }` (Q3) binds it: writes statically found inside an Init referent are Init-attributed and excluded from `unmapped-write` findings without needing `unmappedWriteScope: "actions"` as a whole-file workaround. `init.codeRefs` must not overlap any action's `code` referents — map the factory to `init`, never to an action.
|
|
127
|
+
- **Design for traces early.** The trace encoder pins scalar (and scalar-array) variables only; a model whose state is all functions and tuple-sets cannot be trace-validated. If trace-check matters for the slice, add scalar projection variables (counts, last outcomes, a phase) alongside the structured state.
|
|
128
|
+
- **Trace until covered.** One accepted trace proves one path, not the mapping. Record traces until every Current action with a code twin is exercised by at least one accepted trace, or is explicitly classified with why it cannot be (unreachable without fault injection, environment-gated, model-only). An action no trace ever exercises is a conformance claim resting on static mapping alone.
|
|
129
|
+
|
|
130
|
+
## Accuracy Rules
|
|
131
|
+
|
|
132
|
+
- `tla verify` is the mechanical checker; `tla trace-check` is the semantic one. Only the pair justifies the word "conforms".
|
|
133
|
+
- A PASS with waivers is a conditional claim — the Proof line says exactly what was and was not proven. Never summarize it as unconditional.
|
|
134
|
+
- A PASS on a scaffold with unresolved `TODO`s is meaningless, not conditional: the checker has no TODO detector and will pass a placeholder model. Never report a PASS without confirming step 2 of the Loop is actually done.
|
|
135
|
+
- If code changed but the model did not, inspect whether the mapped transition changed meaning; `diff-gate` flags the changed referents.
|
|
136
|
+
- If the model checker fails, fix the TLA+ model before relying on conformance output.
|
|
137
|
+
- Use `--checker none` only when intentionally checking the mapping without SANY, TLC, or Apalache.
|
|
138
|
+
- The write/read scanner follows one call hop from a mapped action's referent (no recursion) — a callee's effect on a _declared_ fact counts as evidence, marked `(via <callee>, one call hop...)` in findings. It never asserts a new, undeclared fact: a callee shared by several actions cannot make one action silently inherit another's write. If a variable's waiver becomes provable this way, update the waiver reason to name the real call chain instead of deleting the explanation — the evidence is still approximate (which specific runtime call path executes is not proven, only that the code family does).
|
|
@@ -1,49 +1,71 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scip-triage-issue
|
|
3
|
-
description: Triage
|
|
3
|
+
description: Triage issues with scip-query evidence. Use for bug reports, GitHub issues, failing tests, support reports, TODOs, vague defects, root-cause packets, issue bodies, or test-first fix plans.
|
|
4
|
+
commands:
|
|
5
|
+
- template: "scip-query files <issue-term>"
|
|
6
|
+
when: "Map ownership: locate files for the reported term."
|
|
7
|
+
- template: "scip-query trace <entry-or-error-symbol>"
|
|
8
|
+
when: "Trace the failing path: definition plus every reference."
|
|
9
|
+
- template: "scip-query code <entry-or-error-symbol>"
|
|
10
|
+
when: "Trace the failing path: read the exact source."
|
|
11
|
+
- template: "scip-query call-graph <entry-symbol>"
|
|
12
|
+
when: "Trace the failing path: callers and callees."
|
|
13
|
+
- template: "scip-query similar <suspect-symbol> --json --full"
|
|
14
|
+
when: "Compare and bound: nearby implementations for missing handling."
|
|
15
|
+
- template: "scip-query affected <symbol> --json"
|
|
16
|
+
when: "Compare and bound: transitive impact bound for the fix plan."
|
|
4
17
|
---
|
|
5
18
|
|
|
6
|
-
#
|
|
19
|
+
# scip-triage-issue
|
|
7
20
|
|
|
8
|
-
Use this skill to turn a report into a grounded fix
|
|
21
|
+
Use this skill to turn a report into a grounded fix packet. Triage is the evidence pass that determines whether the issue is reproducible, where it enters the codebase, what root cause is likely, and what test should fail before the fix.
|
|
22
|
+
|
|
23
|
+
Load shared mechanics from [`../_shared/SKILL.md`](../_shared/SKILL.md).
|
|
24
|
+
|
|
25
|
+
<!-- BEGIN GENERATED SKILL COMMANDS -->
|
|
26
|
+
## Commands for this skill
|
|
27
|
+
|
|
28
|
+
| Command | Purpose | When |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| `scip-query files <issue-term>` | Find files matching a pattern | Map ownership: locate files for the reported term. |
|
|
31
|
+
| `scip-query trace <entry-or-error-symbol>` | Trace a symbol: definition + all references | Trace the failing path: definition plus every reference. |
|
|
32
|
+
| `scip-query code <entry-or-error-symbol>` | Read the source code for a symbol (bounded to its definition range) | Trace the failing path: read the exact source. |
|
|
33
|
+
| `scip-query call-graph <entry-symbol>` | Show incoming callers and outgoing callees for a symbol | Trace the failing path: callers and callees. |
|
|
34
|
+
| `scip-query similar <suspect-symbol> --json --full` | Find heuristic function similarity candidates from callee fingerprints | Compare and bound: nearby implementations for missing handling. |
|
|
35
|
+
| `scip-query affected <symbol> --json` | Transitive closure of symbols that could break if this symbol changes | Compare and bound: transitive impact bound for the fix plan. |
|
|
36
|
+
|
|
37
|
+
Use this shortlist first. Open [`../_shared/SKILL.md`](../_shared/SKILL.md) only when it is insufficient.
|
|
38
|
+
<!-- END GENERATED SKILL COMMANDS -->
|
|
9
39
|
|
|
10
40
|
## Rules
|
|
11
41
|
|
|
12
|
-
1. Do not file or implement from the title alone.
|
|
42
|
+
1. Do not file or implement from the title alone.
|
|
13
43
|
2. Use scip-query for code evidence: entry points, references, call flow, data flow, blast radius, and similar implementations.
|
|
14
|
-
3. Prefer a failing test plan before a code plan.
|
|
15
|
-
4. If the user asks only for triage, stop at the
|
|
44
|
+
3. Prefer a failing test plan before a code plan.
|
|
45
|
+
4. If the user asks only for triage, stop at the packet. If they asked to fix it too, implement after the packet is clear.
|
|
16
46
|
|
|
17
47
|
## Workflow
|
|
18
48
|
|
|
19
49
|
### 1. Normalize the report
|
|
20
50
|
|
|
21
|
-
Record
|
|
51
|
+
Record summary, observed behavior, expected behavior, reproduction, affected surface, severity, user impact, and logs/screenshots/tests/links.
|
|
22
52
|
|
|
23
|
-
|
|
24
|
-
- observed behavior;
|
|
25
|
-
- expected behavior;
|
|
26
|
-
- reproduction steps or missing reproduction data;
|
|
27
|
-
- affected surface: CLI command, API route, UI view, job, library export, docs, or config;
|
|
28
|
-
- severity and user impact;
|
|
29
|
-
- known logs, stack traces, screenshots, failing tests, or issue links.
|
|
53
|
+
Ask the user only for product intent, credentials, private data, or external system state the repo cannot answer.
|
|
30
54
|
|
|
31
|
-
|
|
55
|
+
This step is complete only when missing facts are either recovered or named.
|
|
32
56
|
|
|
33
|
-
### 2. Map
|
|
57
|
+
### 2. Map ownership
|
|
34
58
|
|
|
35
59
|
```bash
|
|
36
|
-
scip-query status --capabilities
|
|
37
|
-
scip-query status --capabilities
|
|
38
|
-
# If freshness is stale, missing, or unknown:
|
|
39
|
-
# scip-query reindex
|
|
40
60
|
scip-query files <issue-term>
|
|
41
61
|
scip-query outline <candidate-file>
|
|
42
62
|
scip-query system <module-or-scope>
|
|
43
63
|
scip-query surface <module-or-scope>
|
|
44
64
|
```
|
|
45
65
|
|
|
46
|
-
Use `
|
|
66
|
+
Use `kind-counts` and `by-kind` for broad subsystems.
|
|
67
|
+
|
|
68
|
+
This step is complete only when likely owner files and surfaces are named.
|
|
47
69
|
|
|
48
70
|
### 3. Trace the failing path
|
|
49
71
|
|
|
@@ -55,32 +77,24 @@ scip-query dataflow <state-or-input-symbol>
|
|
|
55
77
|
scip-query slice <state-or-input-symbol>
|
|
56
78
|
```
|
|
57
79
|
|
|
58
|
-
|
|
80
|
+
For stack traces, read the exact range with `scip-query code 'file:start-end'`.
|
|
81
|
+
|
|
82
|
+
This step is complete only when a suspected root cause is tied to source evidence or labeled unproven.
|
|
59
83
|
|
|
60
|
-
### 4.
|
|
84
|
+
### 4. Compare and bound
|
|
61
85
|
|
|
62
86
|
```bash
|
|
63
87
|
scip-query similar <suspect-symbol> --json --full
|
|
64
|
-
scip-query
|
|
88
|
+
scip-query similar <suspect-symbol> <comparison-symbol> --plan
|
|
65
89
|
scip-query similar-files <suspect-file> --json --full
|
|
66
90
|
scip-query co-change <suspect-file> --json --full
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Use comparisons to identify a missing guard, validation step, conversion, docs partner, generated artifact, or test fixture.
|
|
70
|
-
|
|
71
|
-
### 5. Bound impact and test shape
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
91
|
scip-query change-surface <suspect-file> --json --full
|
|
75
92
|
scip-query affected <suspect-symbol> --json
|
|
76
|
-
scip-query diff-impact --json
|
|
77
93
|
```
|
|
78
94
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
## Triage Packet
|
|
95
|
+
This step is complete only when the packet has a narrow test shape and impact bound.
|
|
82
96
|
|
|
83
|
-
|
|
97
|
+
## Packet
|
|
84
98
|
|
|
85
99
|
```markdown
|
|
86
100
|
## Issue
|
|
@@ -97,18 +111,16 @@ Write the packet before filing or fixing:
|
|
|
97
111
|
|
|
98
112
|
## Impact
|
|
99
113
|
- users/surfaces affected
|
|
100
|
-
- blast radius
|
|
114
|
+
- blast radius
|
|
101
115
|
|
|
102
116
|
## Fix Plan
|
|
103
117
|
1. Add or update failing test/smoke check.
|
|
104
118
|
2. Make the smallest code change.
|
|
105
119
|
3. Run targeted test.
|
|
106
|
-
4.
|
|
107
|
-
5. Run `scip-query diff-gate --json`.
|
|
108
|
-
6. Invoke `scip-verify`.
|
|
120
|
+
4. Invoke `scip-verify`.
|
|
109
121
|
|
|
110
122
|
## Open Questions
|
|
111
123
|
- <product intent or external state only>
|
|
112
124
|
```
|
|
113
125
|
|
|
114
|
-
If
|
|
126
|
+
If no root cause is proven, label the issue `needs reproduction` or `needs product decision`.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scip-twin-drift
|
|
3
|
+
description: Find and resolve twin drift with scip-query. Use for same-name or near-name functions across files with diverged bodies, drifted policy thresholds, one-sided fixes, or consolidating a duplicated concept into one canonical helper.
|
|
4
|
+
commands:
|
|
5
|
+
- template: "scip-query twin-drift --json --full"
|
|
6
|
+
when: "Run the detector: every DIVERGENT and near-name group in scope."
|
|
7
|
+
- template: "scip-query duplicate-bodies --json --full"
|
|
8
|
+
when: "Cross-check: IDENTICAL groups are duplicate-bodies' job, not this skill's."
|
|
9
|
+
- template: "scip-query code <symbol>"
|
|
10
|
+
when: "Classify a divergent group: read every member's body."
|
|
11
|
+
- template: "scip-query refs <symbol>"
|
|
12
|
+
when: "Pick the canonical twin: consumer count per member."
|
|
13
|
+
- template: "scip-query diff-gate --json"
|
|
14
|
+
when: "Verify: the twin-partner check must not flag a one-sided fix."
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# scip-twin-drift
|
|
18
|
+
|
|
19
|
+
Use this skill when the same concept exists in more than one place under the same or a near-name (case-insensitive, or edit-distance ≤ 2 for names ≥ 8 characters) and the bodies have silently diverged. A twin drift group is a same-leaf-name family of callables spanning at least two files whose normalized-token bodies are neither identical (that is `duplicate-bodies`' job) nor unrelated (a homonym like `render` or `parse`) but partially overlapping — the signature of a concept that was copied once and then edited independently in only some of its copies.
|
|
20
|
+
|
|
21
|
+
Load shared mechanics from [`../_shared/SKILL.md`](../_shared/SKILL.md).
|
|
22
|
+
|
|
23
|
+
<!-- BEGIN GENERATED SKILL COMMANDS -->
|
|
24
|
+
## Commands for this skill
|
|
25
|
+
|
|
26
|
+
| Command | Purpose | When |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| `scip-query twin-drift --json --full` | Twin drift candidates: same-name (or near-name) functions across files with diverged bodies | Run the detector: every DIVERGENT and near-name group in scope. |
|
|
29
|
+
| `scip-query duplicate-bodies --json --full` | Find exact duplicate small-body candidates across files | Cross-check: IDENTICAL groups are duplicate-bodies' job, not this skill's. |
|
|
30
|
+
| `scip-query code <symbol>` | Read the source code for a symbol (bounded to its definition range) | Classify a divergent group: read every member's body. |
|
|
31
|
+
| `scip-query refs <symbol>` | Find all files referencing a symbol | Pick the canonical twin: consumer count per member. |
|
|
32
|
+
| `scip-query diff-gate --json` | Gate the current diff: echo candidates, incomplete migrations, missing co-change partners, unedited twin partners (advisory), uncited doc updates, unused params, new dead symbols; exit 1 on blocking findings | Verify: the twin-partner check must not flag a one-sided fix. |
|
|
33
|
+
|
|
34
|
+
Use this shortlist first. Open [`../_shared/SKILL.md`](../_shared/SKILL.md) only when it is insufficient.
|
|
35
|
+
<!-- END GENERATED SKILL COMMANDS -->
|
|
36
|
+
|
|
37
|
+
## Rules
|
|
38
|
+
|
|
39
|
+
1. `IDENTICAL` groups defer to `duplicate-bodies`; do not re-report them here.
|
|
40
|
+
2. Homonyms (similarity below `--min-similarity`, default 0.3) are noise unless `--include-homonyms` was requested; do not chase them.
|
|
41
|
+
3. Every `DIVERGENT` group in scope gets a classification before this skill reports done.
|
|
42
|
+
4. Prefer consolidation to one exported helper over leaving parallel copies; when consolidation is unsafe or premature, record the intent gap explicitly (comment or waiver) rather than silently accepting drift.
|
|
43
|
+
5. A twin-partner `diff-gate` finding on a change you are making is the live version of this same defect class — treat it as a signal to run this skill, not just to suppress.
|
|
44
|
+
|
|
45
|
+
## Workflow
|
|
46
|
+
|
|
47
|
+
### 1. Run the detector
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
scip-query twin-drift --json --full
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Scope with `-s/--scope <path>` when the review is bounded to a module. Record group count, member count, and `maxDivergence` per group.
|
|
54
|
+
|
|
55
|
+
This step is complete only when every group in scope is enumerated with its relationship (`divergent` vs suppressed homonym).
|
|
56
|
+
|
|
57
|
+
### 2. Classify each DIVERGENT group
|
|
58
|
+
|
|
59
|
+
For each group, read every member with `scip-query code <symbol-or-file:range>` and use the group's `firstDivergentTokens` as a starting point for where the bodies diverge. Classify the group as one of:
|
|
60
|
+
|
|
61
|
+
- **Intentional variation**: the copies differ because the domains genuinely differ (for example a React-specific vs Vue-specific structural comparator that must branch on framework-specific overlap checks). Essential variation stays; record why.
|
|
62
|
+
- **Drifted policy**: the copies encode what should be one policy (a threshold, a normalization rule, an edge-case guard) that only some copies received when it last changed. This is a bug: pick the correct value and propagate it, or extract the policy into one named function/constant.
|
|
63
|
+
- **One-sided fix**: one copy was bugfixed or hardened and its twin(s) were not. This is also a bug: apply the same fix to every member, or consolidate.
|
|
64
|
+
|
|
65
|
+
This step is complete only when every DIVERGENT group in scope has one of these three labels with a one-line reason.
|
|
66
|
+
|
|
67
|
+
### 3. Pick the canonical twin and act
|
|
68
|
+
|
|
69
|
+
For groups getting consolidated, pick the canonical member by consumer count:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
scip-query refs <symbol-in-file-A>
|
|
73
|
+
scip-query refs <symbol-in-file-B>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Prefer the member with the most consumers, or the one in the more general/shared location when counts tie. Extract or move the canonical body to one exported helper; update the other member(s) to call it, or delete them if they were pure duplication with different names for the caller's convenience. Preserve any classified-essential variation as a parameter or a thin caller-side branch, not as a second copy of the whole body.
|
|
77
|
+
|
|
78
|
+
For groups marked intentional variation, do not force consolidation; record the reason in a comment near one of the members so the next `twin-drift` run and the next reader both see it was considered.
|
|
79
|
+
|
|
80
|
+
This step is complete only when every DIVERGENT group is either consolidated (with the old copies gone or forwarding) or has a recorded reason it stays separate.
|
|
81
|
+
|
|
82
|
+
### 4. Verify
|
|
83
|
+
|
|
84
|
+
Rerun the detector to confirm consolidated groups no longer appear as DIVERGENT, then run the routed postchecks from the shared reference and:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
scip-query diff-gate --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The `twin-partner` check is advisory (it never blocks the gate by itself) but a finding here on your own diff means you just reproduced the exact defect class this skill exists to catch — fix or explicitly accept it before finishing.
|
|
91
|
+
|
|
92
|
+
This step is complete only when `twin-drift` shows no unclassified `DIVERGENT` groups in scope and `diff-gate` findings are resolved or explained.
|
|
93
|
+
|
|
94
|
+
## Report
|
|
95
|
+
|
|
96
|
+
```markdown
|
|
97
|
+
Scope:
|
|
98
|
+
Groups found: N (M divergent, K suppressed homonyms)
|
|
99
|
+
|
|
100
|
+
Divergent groups:
|
|
101
|
+
- <leaf name> (<files>) — classification: intentional variation / drifted policy / one-sided fix
|
|
102
|
+
- action: consolidated into <canonical file:symbol> / reason kept separate
|
|
103
|
+
|
|
104
|
+
Verification:
|
|
105
|
+
- `scip-query twin-drift --json --full`: <result>
|
|
106
|
+
- `scip-query diff-gate --json`: <result>
|
|
107
|
+
```
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "SCIP Twin Drift"
|
|
3
|
+
short_description: "Find and resolve same-name twins that have silently diverged"
|
|
4
|
+
default_prompt: "Use scip-query twin-drift to find same-name or near-name functions that have diverged across files, classify each divergence, and consolidate or record the intent gap."
|