scip-query 0.19.4 → 0.19.6
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 +75 -1
- package/README.md +242 -49
- package/dist/augment-vue-worker.js +1 -1
- package/dist/{chunk-2YU7I3QO.js → chunk-24QNP7MN.js} +2 -2
- package/dist/{chunk-CNKAGUPL.js → chunk-26X7KCJR.js} +2 -2
- package/dist/{chunk-GPBBJ5Y4.js → chunk-273W2U4Y.js} +3 -3
- package/dist/{chunk-7GXM52MI.js → chunk-2CVXCGL4.js} +2 -2
- package/dist/{chunk-ABMYA4TN.js → chunk-2EZSOTSY.js} +2 -2
- package/dist/{chunk-HKEHS2AS.js → chunk-2GSQR6YA.js} +2 -2
- package/dist/{chunk-FECYOO5O.js → chunk-2OXVAGGT.js} +2 -2
- package/dist/chunk-2ZOCHAL2.js +8 -0
- package/dist/{chunk-QGXBRIM5.js → chunk-336DC5NJ.js} +2 -2
- package/dist/chunk-35SQLYCQ.js +2 -0
- package/dist/{chunk-VXQNNXJE.js → chunk-3OIKRYU5.js} +2 -2
- package/dist/{chunk-52ZYCAEO.js → chunk-47X75ZKH.js} +2 -2
- package/dist/{chunk-NPKYOIFM.js → chunk-4CGVLUDP.js} +2 -2
- package/dist/chunk-4RI4BJGT.js +8 -0
- package/dist/{chunk-P2PC2WGR.js → chunk-52HQTTPB.js} +2 -2
- package/dist/{chunk-YNRNA5LK.js → chunk-5OC3HWP5.js} +2 -2
- package/dist/{chunk-STOL2BTL.js → chunk-6XFC7PQ5.js} +2 -2
- package/dist/{chunk-J77UIT3I.js → chunk-6XHTISLI.js} +2 -2
- package/dist/chunk-6YTSKJJ3.js +2 -0
- package/dist/{chunk-BTEE5NZQ.js → chunk-7E3TH5ZN.js} +2 -2
- package/dist/{chunk-X6D5IC6I.js → chunk-7LABSJSR.js} +2 -2
- package/dist/chunk-7Q6VYYCH.js +2 -0
- package/dist/{chunk-FWUUZTIO.js → chunk-A43URCQ3.js} +2 -2
- package/dist/chunk-A63U2W3P.js +3 -0
- package/dist/{chunk-3MJ5YA4Y.js → chunk-ADFSIJP2.js} +2 -2
- package/dist/chunk-AOLE4DYM.js +6 -0
- package/dist/chunk-APMMR5Y2.js +2 -0
- package/dist/chunk-B5MHCHP3.js +107 -0
- package/dist/{chunk-4RSI5EMG.js → chunk-CSTYYXKC.js} +2 -2
- package/dist/{chunk-25LPM4DG.js → chunk-CYJM7CYF.js} +2 -2
- package/dist/{chunk-S44IULR6.js → chunk-DD5BOU5I.js} +2 -2
- package/dist/{chunk-YGAGTIDK.js → chunk-DGMCFMPG.js} +7 -7
- package/dist/{chunk-UOAV44HR.js → chunk-E2ZXPB7J.js} +2 -2
- package/dist/{chunk-IZKFSVBV.js → chunk-EVOC5I5I.js} +2 -2
- package/dist/{chunk-XTX6QHOF.js → chunk-F42A3AKG.js} +2 -2
- package/dist/{chunk-Q4IIEGXJ.js → chunk-FHCTEANE.js} +2 -2
- package/dist/{chunk-3SVWW4PN.js → chunk-FKGN4A4E.js} +2 -2
- package/dist/{chunk-IG7N5ZIK.js → chunk-FQTPPXNA.js} +2 -2
- package/dist/{chunk-F6O7AAC3.js → chunk-G4UQL4CP.js} +2 -2
- package/dist/chunk-GA64UPMI.js +6 -0
- package/dist/{chunk-ZXJYMGD3.js → chunk-GK3GRUJX.js} +2 -2
- package/dist/chunk-HEBAY673.js +2 -0
- package/dist/chunk-HELS7KFF.js +2 -0
- package/dist/{chunk-B5NLK2B3.js → chunk-IPDCSB6N.js} +2 -2
- package/dist/{chunk-M7MTH5NR.js → chunk-IYAOX36F.js} +2 -2
- package/dist/{chunk-YVVCVR2L.js → chunk-J7VT2CRB.js} +2 -2
- package/dist/{chunk-4333ETTV.js → chunk-JELJLXEE.js} +2 -2
- package/dist/{chunk-LBMJEAEW.js → chunk-JERWGHQT.js} +2 -2
- package/dist/chunk-JJJCO4QC.js +945 -0
- package/dist/{chunk-6E7UTQY7.js → chunk-JZNLMHWY.js} +2 -2
- package/dist/{chunk-R4FQGQ4X.js → chunk-K42M2KWT.js} +2 -2
- package/dist/{chunk-H7UKLTWJ.js → chunk-KLVJABXA.js} +2 -2
- package/dist/chunk-KP4KBDVF.js +3 -0
- package/dist/{chunk-RV2FQIX3.js → chunk-LMFVTUW2.js} +2 -2
- package/dist/chunk-LRTP3DKL.js +3 -0
- package/dist/{chunk-U6WNH5GC.js → chunk-MGBJHRFB.js} +2 -2
- package/dist/{chunk-QDV6RDCP.js → chunk-MLGTCX56.js} +2 -2
- package/dist/{chunk-54HA4ZXH.js → chunk-N3SE646F.js} +2 -2
- package/dist/{chunk-KP6XRY5Z.js → chunk-NBRUH7OE.js} +2 -2
- package/dist/{chunk-M7AIS73L.js → chunk-NN4ZIRPK.js} +2 -2
- package/dist/{chunk-I5RJM53C.js → chunk-NQLSSVOB.js} +2 -2
- package/dist/{chunk-4SALD7RU.js → chunk-OBKDTVZ3.js} +2 -2
- package/dist/{chunk-GBQ5NYPR.js → chunk-OHWZKLVA.js} +6 -6
- package/dist/{chunk-6NSFJYRC.js → chunk-OP3MTFJR.js} +2 -2
- package/dist/{chunk-EOOJGLDU.js → chunk-OQ2A4G2G.js} +2 -2
- package/dist/{chunk-DLWR3NUU.js → chunk-P6HBYNBE.js} +2 -2
- package/dist/{chunk-QVWS2VWZ.js → chunk-PC44K7RF.js} +2 -2
- package/dist/{chunk-A2EZV2UM.js → chunk-QBYYWGAT.js} +2 -2
- package/dist/{chunk-QRGV2F7L.js → chunk-QHKUY4FW.js} +2 -2
- package/dist/chunk-QHRL4LKM.js +2 -0
- package/dist/{chunk-I5AWSI2G.js → chunk-QQWOFXNW.js} +2 -2
- package/dist/{chunk-WQTAC523.js → chunk-RBFFD4V2.js} +2 -2
- package/dist/{chunk-SOAT6NLA.js → chunk-RJHCPSZ7.js} +2 -2
- package/dist/{chunk-VGRICIQI.js → chunk-RWRLUZ6U.js} +2 -2
- package/dist/{chunk-4T3LTWUS.js → chunk-S2GP3CU3.js} +2 -2
- package/dist/{chunk-HEXVUYFQ.js → chunk-SHKZ7OVJ.js} +2 -2
- package/dist/{chunk-NSS46APD.js → chunk-TFUU5MQQ.js} +2 -2
- package/dist/{chunk-IUFDSKGG.js → chunk-TYQ76QHQ.js} +2 -2
- package/dist/{chunk-NRCXJDHL.js → chunk-U5CNPPTZ.js} +2 -2
- package/dist/{chunk-MITTUCEH.js → chunk-UQK5CRUK.js} +2 -2
- package/dist/{chunk-XLTP42QA.js → chunk-UUJBLG6J.js} +2 -2
- package/dist/chunk-UXP636P5.js +144 -0
- package/dist/{chunk-64RFXJT5.js → chunk-VEVBIAOJ.js} +6 -6
- package/dist/chunk-VKRQDBW5.js +9 -0
- package/dist/{chunk-C7NIYIQ4.js → chunk-VOQFGC2W.js} +4 -4
- package/dist/{chunk-DZ74OMG6.js → chunk-VP542C25.js} +2 -2
- package/dist/{chunk-Q3AFUTGB.js → chunk-WMXRRBII.js} +2 -2
- package/dist/{chunk-ZGZUZ7XE.js → chunk-WXAAURU7.js} +2 -2
- package/dist/chunk-X3NLZHPA.js +20 -0
- package/dist/{chunk-WER3B7MI.js → chunk-XF3KLXN3.js} +2 -2
- package/dist/{chunk-NH5ALKPW.js → chunk-XVJ3V7LM.js} +2 -2
- package/dist/{chunk-4XTA5OMB.js → chunk-YGQN3XGZ.js} +2 -2
- package/dist/{chunk-CFMXJPHH.js → chunk-YHXBD52M.js} +2 -2
- package/dist/{chunk-7B3UPBVA.js → chunk-YLVE3SXZ.js} +2 -2
- package/dist/{chunk-YIJ7ZAA4.js → chunk-YTUD45PU.js} +2 -2
- package/dist/{chunk-VTKGCT3V.js → chunk-YWB2EBNB.js} +2 -2
- package/dist/{chunk-UKZBVX4U.js → chunk-Z2LHPIOM.js} +2 -2
- package/dist/chunk-Z5QQPJ3U.js +30 -0
- package/dist/{chunk-NZL2DBT7.js → chunk-ZLJLE6LK.js} +2 -2
- package/dist/{chunk-XYADIZHU.js → chunk-ZTTISZ7J.js} +2 -2
- package/dist/cli.js +3 -3
- package/dist/command-descriptors-SJDZ7QGR.js +617 -0
- package/dist/{config-types-D20KuvvZ.d.ts → config-types-BWQ5xPGI.d.ts} +4 -0
- package/dist/{db-G_II8yXU.d.ts → db-B0r1o7Vt.d.ts} +18 -1
- package/dist/direct-navigation-HTKOZEOM.js +3 -0
- package/dist/{health-oblXYgkF.d.ts → health-CFnlCiTz.d.ts} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/postinstall.js +1 -1
- package/dist/queries/affected.d.ts +2 -2
- package/dist/queries/affected.js +1 -1
- package/dist/queries/architecture.d.ts +2 -2
- package/dist/queries/architecture.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 +2 -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 +2 -2
- package/dist/queries/complexity-hotspots.js +1 -1
- package/dist/queries/complexity.d.ts +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/queries/dead.js +1 -1
- package/dist/queries/decorative-checkers.d.ts +3 -3
- package/dist/queries/decorative-checkers.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 +30 -2
- package/dist/queries/diff-gate.js +1 -1
- package/dist/queries/diff-impact.d.ts +2 -2
- package/dist/queries/diff-impact.js +1 -1
- package/dist/queries/doc-drift.d.ts +2 -2
- package/dist/queries/doc-drift.js +1 -1
- package/dist/queries/drift.d.ts +2 -2
- package/dist/queries/drift.js +1 -1
- package/dist/queries/duplicate-bodies.d.ts +2 -2
- package/dist/queries/duplicate-bodies.js +1 -1
- 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 +2 -2
- 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 +2 -2
- package/dist/queries/incomplete-migration.js +1 -1
- package/dist/queries/index.d.ts +17 -3
- 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/not-implemented.d.ts +3 -3
- package/dist/queries/not-implemented.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 +2 -2
- package/dist/queries/passthrough-candidates.js +1 -1
- package/dist/queries/plan-context.d.ts +2 -2
- package/dist/queries/plan-context.js +1 -1
- package/dist/queries/react-component-duplicates.d.ts +2 -2
- package/dist/queries/react-component-duplicates.js +1 -1
- package/dist/queries/react-hook-candidates.d.ts +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dist/queries/similar-signatures.js +1 -1
- package/dist/queries/similar.d.ts +2 -2
- 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/stats.js +1 -1
- 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/test-quality.d.ts +2 -2
- package/dist/queries/test-quality.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 +3 -3
- package/dist/queries/twin-ab.js +1 -1
- package/dist/queries/twin-drift.d.ts +2 -2
- package/dist/queries/twin-drift.js +1 -1
- 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 +2 -2
- package/dist/queries/vue-component-duplicates.js +1 -1
- package/dist/queries/vue-composable-candidates.d.ts +2 -2
- package/dist/queries/vue-composable-candidates.js +1 -1
- package/dist/queries/vue-large-view-pressure.d.ts +2 -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 +23 -24
- package/dist/reindex.d.ts +10 -4
- package/dist/reindex.js +33 -38
- package/dist/runtime.d.ts +167 -11
- package/dist/runtime.js +3 -2
- package/dist/rust-semantic-session-server.js +1 -1
- package/dist/rust-semantic-session-worker.js +1 -1
- package/dist/rust-semantic-worker.js +1 -1
- package/dist/{scip-cli-kRpaexVJ.d.ts → scip-cli-DCvnlZCu.d.ts} +5 -1
- package/dist/watch-server.js +5 -5
- package/docs/AGENT_GUIDE.md +1 -1
- package/docs/AI_FAILURE_MODES.md +18 -18
- package/docs/API_EVOLUTION.md +71 -0
- package/docs/CLI_JSON_OUTPUT.md +83 -0
- package/docs/COMMAND_REFERENCE.md +10 -8
- package/docs/COMMITTED_RECORD_COMPATIBILITY.md +117 -0
- package/docs/CONFIGURATION_WRITE_SAFETY.md +130 -0
- package/docs/DETECTOR_GUIDE.md +47 -47
- package/docs/DURABILITY.md +103 -0
- package/docs/INDEX_GENERATIONS.md +121 -0
- package/docs/LOCK_PROTOCOL.md +133 -0
- package/docs/MAILBOX_LIFECYCLE.md +197 -0
- package/docs/REINDEX_METADATA_COMPATIBILITY.md +84 -0
- package/docs/RUST_DURABLE_SESSION_PROTOCOL.md +126 -0
- package/docs/TELEMETRY_RETENTION.md +72 -0
- package/docs/TIME_SEMANTICS.md +77 -0
- package/docs/WATCH_REFRESH_REQUESTS.md +110 -0
- package/docs/WINDOWS_SIDECAR_RELEASE.md +298 -0
- package/docs/analyzer-validation-ledger.md +24 -23
- package/docs/schemas/cli-json-envelope.schema.json +53 -0
- package/docs/schemas/npm-release-state.schema.json +146 -0
- package/docs/schemas/outcome-event-record.schema.json +39 -0
- package/docs/schemas/project-config.schema.json +247 -0
- package/docs/schemas/suppression-record.schema.json +31 -0
- package/docs/schemas/windows-sidecar-provenance.schema.json +137 -0
- package/package.json +15 -5
- package/scripts/build-scip-windows.mjs +180 -61
- package/scripts/scip-windows-provenance.mjs +364 -0
- package/scripts/verify-scip-windows.mjs +29 -0
- package/skills/_shared/SKILL.md +91 -242
- package/skills/_shared/agents/openai.yaml +1 -1
- package/skills/_shared/references/agent-contract-catalog.md +105 -0
- package/skills/_shared/references/command-catalog.md +118 -0
- package/skills/_shared/references/detector-precision-and-diffgate.md +59 -0
- package/skills/_shared/references/evidence-and-dead-code.md +25 -0
- package/skills/scip-audit/SKILL.md +76 -0
- package/skills/scip-audit/agents/openai.yaml +4 -0
- package/skills/scip-audit/references/claims.md +98 -0
- package/skills/scip-audit/references/cleanup.md +101 -0
- package/skills/scip-audit/references/directory.md +222 -0
- package/skills/scip-audit/references/frontend.md +130 -0
- package/skills/scip-audit/references/integrity.md +154 -0
- package/skills/scip-audit/references/maintainability.md +162 -0
- package/skills/scip-audit/references/twin-drift.md +104 -0
- package/skills/scip-diagnose/SKILL.md +52 -0
- package/skills/scip-diagnose/agents/openai.yaml +4 -0
- package/skills/scip-diagnose/references/debug.md +117 -0
- package/skills/{scip-probe-reachability/SKILL.md → scip-diagnose/references/probe-reachability.md} +12 -27
- package/skills/scip-diagnose/references/root-cause.md +145 -0
- package/skills/scip-diagnose/references/triage.md +119 -0
- package/skills/scip-explore/SKILL.md +53 -84
- package/skills/scip-explore/agents/openai.yaml +2 -2
- package/skills/scip-explore/references/diagrams.md +40 -0
- package/skills/scip-explore/references/language-playbook.md +49 -0
- package/skills/scip-improve/SKILL.md +56 -0
- package/skills/scip-improve/agents/openai.yaml +4 -0
- package/skills/scip-improve/references/cleanup-batches.md +53 -0
- package/skills/scip-improve/references/directory-moves.md +53 -0
- package/skills/scip-improve/references/doc-reconcile.md +30 -0
- package/skills/scip-improve/references/frontend-extraction.md +39 -0
- package/skills/scip-improve/references/maintainability-mechanism.md +43 -0
- package/skills/scip-improve/references/twin-drift.md +35 -0
- package/skills/scip-plan/SKILL.md +68 -0
- package/skills/scip-plan/agents/openai.yaml +4 -0
- package/skills/scip-plan/references/api-impact.md +19 -0
- package/skills/scip-plan/references/conductor.md +41 -0
- package/skills/scip-plan/references/high-assurance.md +43 -0
- package/skills/scip-plan/references/hyper-optimization.md +50 -0
- package/skills/scip-plan/references/tla-model.md +88 -0
- package/skills/scip-query/SKILL.md +52 -97
- package/skills/scip-query/agents/openai.yaml +2 -2
- package/skills/scip-setup/SKILL.md +65 -176
- package/skills/scip-setup/agents/openai.yaml +3 -3
- package/skills/scip-setup/references/bootstrap-workflow.md +120 -0
- package/skills/scip-setup/references/language-verification.md +61 -0
- package/skills/scip-setup/references/lifecycle-commands.md +119 -0
- package/skills/scip-setup/references/per-repo-triage.md +24 -0
- package/skills/scip-verify/SKILL.md +123 -70
- package/skills/scip-verify/agents/openai.yaml +2 -2
- package/skills/scip-verify/references/calibrate-detectors.md +170 -0
- package/dist/chunk-2CTX5CMX.js +0 -4
- package/dist/chunk-2Y373BDD.js +0 -2
- package/dist/chunk-C2QSK7E7.js +0 -2
- package/dist/chunk-D4U5Q3FT.js +0 -7
- package/dist/chunk-K2ERX4UT.js +0 -3
- package/dist/chunk-KHE7J5ZN.js +0 -3
- package/dist/chunk-L7SPDE73.js +0 -84
- package/dist/chunk-LHMNRHGV.js +0 -3
- package/dist/chunk-LM72NQ7T.js +0 -3
- package/dist/chunk-MSWVMDAH.js +0 -122
- package/dist/chunk-NH7WNNQC.js +0 -20
- package/dist/chunk-OMPZHGHO.js +0 -2
- package/dist/chunk-SVLTAG5O.js +0 -927
- package/dist/chunk-U7DSEKOM.js +0 -30
- package/dist/chunk-V27BEQJN.js +0 -7
- package/dist/chunk-VMNZB6WI.js +0 -4
- package/dist/chunk-XBN5VO53.js +0 -2
- package/dist/chunk-ZAIILQNP.js +0 -5
- package/dist/command-descriptors-MFU4BCJ7.js +0 -612
- package/dist/direct-navigation-MRMQFIRB.js +0 -3
- package/skills/scip-api-impact/SKILL.md +0 -139
- package/skills/scip-api-impact/agents/openai.yaml +0 -4
- package/skills/scip-calibrate/SKILL.md +0 -131
- package/skills/scip-calibrate/agents/openai.yaml +0 -4
- package/skills/scip-claim-audit/SKILL.md +0 -106
- package/skills/scip-claim-audit/agents/openai.yaml +0 -4
- package/skills/scip-cleanup-audit/SKILL.md +0 -126
- package/skills/scip-cleanup-audit/agents/openai.yaml +0 -4
- package/skills/scip-cleanup-improve/SKILL.md +0 -84
- package/skills/scip-cleanup-improve/agents/openai.yaml +0 -4
- package/skills/scip-concrete-plan/SKILL.md +0 -262
- package/skills/scip-concrete-plan/agents/openai.yaml +0 -4
- package/skills/scip-conductor/SKILL.md +0 -133
- package/skills/scip-conductor/agents/openai.yaml +0 -4
- package/skills/scip-debug/SKILL.md +0 -130
- package/skills/scip-debug/agents/openai.yaml +0 -4
- package/skills/scip-diagram/SKILL.md +0 -110
- package/skills/scip-diagram/agents/openai.yaml +0 -4
- package/skills/scip-directory-architecture/SKILL.md +0 -254
- package/skills/scip-directory-architecture/agents/openai.yaml +0 -4
- package/skills/scip-doc-reconcile/SKILL.md +0 -89
- package/skills/scip-doc-reconcile/agents/openai.yaml +0 -4
- package/skills/scip-hyper-optimization/SKILL.md +0 -156
- package/skills/scip-hyper-optimization/agents/openai.yaml +0 -4
- package/skills/scip-integrity-audit/SKILL.md +0 -152
- package/skills/scip-integrity-audit/agents/openai.yaml +0 -4
- package/skills/scip-language-playbook/SKILL.md +0 -106
- package/skills/scip-language-playbook/agents/openai.yaml +0 -4
- package/skills/scip-maintainability/SKILL.md +0 -158
- package/skills/scip-maintainability/agents/openai.yaml +0 -4
- package/skills/scip-probe-reachability/agents/openai.yaml +0 -4
- package/skills/scip-react-maintainability/SKILL.md +0 -101
- package/skills/scip-react-maintainability/agents/openai.yaml +0 -4
- package/skills/scip-root-cause/SKILL.md +0 -150
- package/skills/scip-root-cause/agents/openai.yaml +0 -4
- package/skills/scip-tla-model-system/SKILL.md +0 -148
- package/skills/scip-tla-model-system/agents/openai.yaml +0 -4
- package/skills/scip-triage-issue/SKILL.md +0 -126
- package/skills/scip-triage-issue/agents/openai.yaml +0 -4
- package/skills/scip-twin-drift/SKILL.md +0 -107
- package/skills/scip-twin-drift/agents/openai.yaml +0 -4
- package/skills/scip-vue-maintainability/SKILL.md +0 -107
- package/skills/scip-vue-maintainability/agents/openai.yaml +0 -4
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Twin drift
|
|
2
|
+
|
|
3
|
+
Use when the same concept exists in more than one place under the same or a near-name and the bodies have silently diverged — 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
|
+
|
|
5
|
+
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's `duplicate-bodies`' job) nor unrelated (a homonym like `render` or `parse`), but partially overlapping — a concept copied once and edited independently in only some copies. "Near-name" means case-insensitive match, or edit-distance ≤ 2 for names of 8+ characters.
|
|
6
|
+
|
|
7
|
+
## Detect
|
|
8
|
+
|
|
9
|
+
Run `scip-query twin-drift --json --full` to surface every DIVERGENT and near-name group in scope; scope it with `-s/--scope <path>` when the review should be bounded. Cross-check against `scip-query duplicate-bodies --json --full` — IDENTICAL groups belong there, not here; don't re-report them. Homonyms (similarity below `--min-similarity`, default 0.3) are noise — skip them unless `--include-homonyms` was explicitly requested. Record group count, member count, and `maxDivergence` per group. Done only when every group in scope is enumerated with its relationship (divergent vs. suppressed homonym).
|
|
10
|
+
|
|
11
|
+
## Classify
|
|
12
|
+
|
|
13
|
+
For every DIVERGENT group, read each member's body with `scip-query code <symbol>`, starting from the group's `firstDivergentTokens` field to locate where the bodies diverge. Assign exactly one label with a one-line reason:
|
|
14
|
+
|
|
15
|
+
- **Intentional variation** — the domains genuinely differ (e.g., a React-specific vs. Vue-specific structural comparator branching on framework-specific checks). Essential variation stays; record the reason.
|
|
16
|
+
- **Drifted policy** — one policy (a threshold, a normalization rule, an edge-case guard) 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.
|
|
17
|
+
- **One-sided fix** — one copy was bugfixed or hardened and its twin(s) weren't. This is a bug: apply the same fix to every member, or consolidate.
|
|
18
|
+
|
|
19
|
+
Done only when every DIVERGENT group has one of the three labels with its reason.
|
|
20
|
+
|
|
21
|
+
## Consolidate
|
|
22
|
+
|
|
23
|
+
Pick the canonical member by comparing consumer counts via `scip-query refs <symbol-in-file-A>` and `scip-query refs <symbol-in-file-B>` — prefer the member with more consumers, or the one in the more general/shared location on a tie. Extract or move the canonical body to one exported helper and update the other members to call it, or delete them outright if they were pure duplication under a different name for caller convenience. Preserve classified-essential variation as a parameter or a thin caller-side branch, not a second copy of the whole body. For intentional-variation groups, don't 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.
|
|
24
|
+
|
|
25
|
+
Done only when every DIVERGENT group is either consolidated (old copies gone or forwarding) or has a recorded reason it stays separate.
|
|
26
|
+
|
|
27
|
+
## Verify
|
|
28
|
+
|
|
29
|
+
Rerun `scip-query twin-drift --json --full` to confirm consolidated groups no longer appear as DIVERGENT, then run the routed postchecks from `scip-verify`. The twin-partner check inside `diff-gate` is advisory and never blocks the gate by itself — but a finding there on your own diff means you've reproduced the exact defect class this skill exists to catch; treat it as a signal to run this workflow, not just to suppress the finding. Fix it or explicitly accept it before finishing.
|
|
30
|
+
|
|
31
|
+
Done only when `twin-drift` shows no unclassified DIVERGENT groups in scope and any `diff-gate` findings are resolved or explained.
|
|
32
|
+
|
|
33
|
+
## Report
|
|
34
|
+
|
|
35
|
+
Scope, groups found (total / divergent / suppressed homonyms), each divergent group with its classification and action taken, and the verification results of `twin-drift --json --full` and `diff-gate --json`.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scip-plan
|
|
3
|
+
description: Use before, during, AND after non-trivial work: plan a change, migration, or refactor; assess what breaks when changing a public export, module boundary, schema, route, CLI command, config field, generated artifact, signature, or documented behaviour; conduct a multi-phase program and review a delegated agent's work mid-flight; plan a performance campaign; scaffold a TLA+ model before implementing, and trace-check it against the real system afterward. Distinct from the `review` skill, which reviews a finished branch or PR against coding standards and the originating spec — this one oversees a program you are conducting.
|
|
4
|
+
commands:
|
|
5
|
+
- template: "scip-query plan-context <target>"
|
|
6
|
+
when: "Anchor the current flow, consumers, reuse options, and change risks."
|
|
7
|
+
- template: "scip-query refs <symbol>"
|
|
8
|
+
when: "Complete or narrow the direct consumer set for a planned symbol change."
|
|
9
|
+
- template: "scip-query affected <symbol> --json"
|
|
10
|
+
when: "Measure transitive impact when the change is not consumer-local."
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# scip-plan
|
|
14
|
+
|
|
15
|
+
<!-- BEGIN GENERATED SKILL COMMANDS -->
|
|
16
|
+
## Commands for this skill
|
|
17
|
+
|
|
18
|
+
| Command | Purpose | Returns | Coverage | When |
|
|
19
|
+
| --- | --- | --- | --- | --- |
|
|
20
|
+
| `scip-query plan-context <target>` | Pre-edit planning context for a symbol, file, or module | definitions and references; callers and callees; dataflow producers and consumers; backward and forward slices; affected symbols; change-surface risk; dependencies and reverse dependencies; module files and exports; external surface use; complexity; churn; co-change partners; active suppressions | `bounded` | Anchor the current flow, consumers, reuse options, and change risks. |
|
|
21
|
+
| `scip-query refs <symbol>` | Find all files referencing a symbol | referencing file paths; reference line numbers grouped by file | `bounded` | Complete or narrow the direct consumer set for a planned symbol change. |
|
|
22
|
+
| `scip-query affected <symbol> --json` | Transitive closure of symbols that could break if this symbol changes | affected symbol identities, files, and traversal depths | `bounded` | Measure transitive impact when the change is not consumer-local. |
|
|
23
|
+
|
|
24
|
+
Use this shortlist first. Open [`../_shared/SKILL.md`](../_shared/SKILL.md) only when it is insufficient.
|
|
25
|
+
<!-- END GENERATED SKILL COMMANDS -->
|
|
26
|
+
|
|
27
|
+
## Purpose
|
|
28
|
+
|
|
29
|
+
Plan and conduct work: a single non-trivial change, public-surface impact, a multi-phase program carried end to end with verification at each handoff (including reviewing a delegated agent's work in flight), a benchmark-driven optimization campaign, and TLA+ modelling both before implementation and as post-implementation trace-conformance.
|
|
30
|
+
|
|
31
|
+
Shared mechanics (lookup tips, command families, postchecks, subagent-briefing text, general command catalogue) live in `../_shared/SKILL.md` — load it only when this skill's own shortlist is insufficient.
|
|
32
|
+
|
|
33
|
+
## Pick the mode first
|
|
34
|
+
|
|
35
|
+
| Situation | Do this |
|
|
36
|
+
|---|---|
|
|
37
|
+
| One non-trivial change, refactor, migration, or bug fix | Ordinary-mode scenario below |
|
|
38
|
+
| The change touches a security boundary, money, a destructive/irreversible op, a persistent-data migration, shared-state concurrency, a broad public API, or an unrollback-able rollout — or the user asks for the rigorous version | `references/high-assurance.md` |
|
|
39
|
+
| You're about to edit a public export, route, schema, CLI command, config field, generated artifact, or documented behavior, and need to know what breaks | `references/api-impact.md` |
|
|
40
|
+
| You're running a multi-phase program: writing an executable plan, delegating steps, reviewing a subagent's work mid-flight, or carrying a change end to end | `references/conductor.md` |
|
|
41
|
+
| You need something faster and must prove the speedup with measurements | `references/hyper-optimization.md` |
|
|
42
|
+
| You need a TLA+ model of a risky protocol, before or after implementation | `references/tla-model.md` |
|
|
43
|
+
|
|
44
|
+
Picking the mode matters: running the high-assurance certificate on routine work is how planning becomes a tax people route around. When genuinely unsure whether a change needs a heavier mode, ask rather than defaulting up.
|
|
45
|
+
|
|
46
|
+
## Scenario: plan a single non-trivial change (ordinary mode, the default)
|
|
47
|
+
|
|
48
|
+
Start with `scip-query status --capabilities` to confirm the index is fresh before citing graph facts — reindex only if the index is stale, missing, or unknown. Then run `scip-query plan-context <target>` — the single anchoring call for planning. Its composite return already includes definitions, references, callers, callees, dataflow producers/consumers, forward and backward slices, affected symbols, change-surface risk, dependencies and reverse dependencies, module exports, external surface use, complexity, churn, co-change partners, and active suppressions, so the job is to interpret this composite rather than rebuild a proof system on top of it.
|
|
49
|
+
|
|
50
|
+
Reach for a second command only when a section `plan-context` returned came back bounded (not complete) or the target wasn't indexed: `scip-query refs <symbol>` to enumerate consumers in full, `scip-query affected <symbol>` for the transitive blast radius when the change isn't consumer-local, `scip-query code <symbol>` to read the source behind a behavior claim before writing it into the plan.
|
|
51
|
+
|
|
52
|
+
Write the plan to `docs/plans/YYYY-MM-DD-<short-name>.md` with these sections:
|
|
53
|
+
|
|
54
|
+
- **Goal** — what the user is trying to accomplish, and what done looks like for them.
|
|
55
|
+
- **Current Flow** — the affected path from entry point to observable effect, in prose, with evidence behind each claim; if current behavior can't be described end to end, the change isn't ready to make.
|
|
56
|
+
- **Affected Consumers** — who calls/imports/reads the changed code and what breaks if the contract shifts; state explicitly whether the list is complete or bounded — a capped list presented as complete is worse than one flagged as bounded.
|
|
57
|
+
- **Reuse Decision** — for every new helper/wrapper/type/parameter/flag/component/hook/module, name what it could have extended instead and why extension loses. New parallel code with no reuse decision is the single most common defect this skill exists to prevent.
|
|
58
|
+
- **Slices** — ordered implementation steps, each naming its files/symbols, the behavior change, and the validation (a test, command, or specific manual check) that proves it. A slice with no validation is a wish.
|
|
59
|
+
- **Risks and Unknowns** — what could go wrong, what couldn't be established, and any rollout constraint; keep unknowns explicit rather than rounding them to assumptions.
|
|
60
|
+
|
|
61
|
+
The plan is done only when: the entry-to-effect path is described and evidenced, every affected consumer is assigned to a slice or explicitly out of scope, every new unit has a reuse decision, every slice has validation, and unknowns are written down rather than resolved by guessing. Then implement in the smallest coherent slice and run `scip-verify` when the change lands.
|
|
62
|
+
|
|
63
|
+
## Owned command quick-reference
|
|
64
|
+
|
|
65
|
+
`bench`, `work-audit` → performance campaigns, see `references/hyper-optimization.md`.
|
|
66
|
+
`tla`, `tla scaffold`, `tla verify`, `tla instrument`, `tla trace-check`, `tla fetch-tools` → model scaffolding and conformance, see `references/tla-model.md`.
|
|
67
|
+
|
|
68
|
+
Everything else used above (`plan-context`, `refs`, `affected`, `code`, `surface`, `co-change`, `doc-drift`, `diff-gate`, `health`, `call-graph`, `complexity`, `change-surface`, ...) is general catalogue — see `../_shared/SKILL.md` for the full vocabulary.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Public-surface impact
|
|
2
|
+
|
|
3
|
+
Use before changing anything another process or person depends on: a callable, export, route, schema, config field, CLI command, generated artifact, or documented behavior. Its defining trait: a local edit can force coordinated consumer, docs, tests, or migration changes outside the implementation file.
|
|
4
|
+
|
|
5
|
+
## Scenario: assess what breaks before editing a public surface
|
|
6
|
+
|
|
7
|
+
**Step 1 — identify the actual surface.** Run `scip-query surface <module-or-package>`, `scip-query outline <file>`, `scip-query trace <symbol-or-command>`, `scip-query code <symbol-or-command>`, and `scip-query hierarchy <symbol> --json`. Done only when the real surface is named as one of: member, class, module, package, route, schema, command, or config field.
|
|
8
|
+
|
|
9
|
+
**Step 2 — find consumers.** Run `scip-query refs <symbol>`, `scip-query fan-in <symbol>`, `scip-query rdeps <file>`, `scip-query affected <symbol> --json`, and `scip-query change-surface <file> --json --full`. Record direct consumers separately from transitive consumers. Done only when direct breakage and regression blast radius are both known.
|
|
10
|
+
|
|
11
|
+
**Step 3 — find hidden partners.** Run `scip-query co-change <file> --json --full` (files historically coupled without a dependency edge), `scip-query doc-drift --json --full` (docs describing the surface), `scip-query similar <symbol> --json --full`, and `scip-query similar-files <file> --json --full`. Docs, generated files, tests, and config count as part of the API when they describe or enforce the surface. Done only when docs, generated files, fixtures, sibling APIs, and hand-synchronized partners are accounted for or ruled out.
|
|
12
|
+
|
|
13
|
+
**Step 4 — choose the migration shape.** Pick one of: compatible extension, two-step migration, breaking coordinated change, or an adapter shim for external consumers/compatibility windows. Prefer backward-compatible migrations when consumers are broad or external. Reject speculative new parameters or empty wrappers using `scip-query unused-params --json --full`, `scip-query wrapper-candidates --json --full`, and `scip-query passthrough-candidates --json --full`. Done only when the migration shape explains deploy order, rollback, and compatibility risk.
|
|
14
|
+
|
|
15
|
+
**Step 5 — write the plan and verify.** Plan template: Surface; a Consumer dispositions table (Consumer | Kind: direct/transitive/doc/config/test | Disposition: unchanged-safe/update/shim/defer); Required co-changes; Migration; Verification (targeted tests, `scip-query diff-impact --json`, `scip-verify`, `scip-query doc-drift --json --full` if docs changed, `scip-query config-validate` if config changed). Every consumer returned by refs/affected must appear as a row — a blank disposition means the analysis is unfinished. Non-indexed consumers (SQL, fixtures, dynamic strings, external callers) must be checked with `rg` and rowed the same way as indexed consumers.
|
|
16
|
+
|
|
17
|
+
After editing, run the routed checks from `_shared` and invoke `scip-verify`. The workflow is complete only when direct consumers, docs/config partners, and scip-verify have all been checked.
|
|
18
|
+
|
|
19
|
+
Final report shape: API impact (low/medium/high); Surface changed; Consumers; Migration plan; Co-changes; Verification; Remaining risk.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Conducting a multi-phase program
|
|
2
|
+
|
|
3
|
+
This governs running a program of work — planning, delegation, review, closure — across multiple steps, not how to write a single change plan (use the main SKILL.md's ordinary-mode scenario, or `references/high-assurance.md`, for that). Act like a skeptical principal engineer.
|
|
4
|
+
|
|
5
|
+
Key commands: `scip-query plan-context <target>` anchors each phase's step before delegating it; `scip-query diff-gate --json` verifies a handoff before accepting it and before closing the program; `scip-query health --json` pre-registers or checks a program-level health benchmark.
|
|
6
|
+
|
|
7
|
+
## The three laws
|
|
8
|
+
|
|
9
|
+
1. **A green result you have never seen fail is unverified.** This applies to tests, gates, reports from other agents, and your own checks (the integrity scenario in `scip-audit` applies the same law to code, where available).
|
|
10
|
+
2. **A plan is a contract for a less-capable executor, not a note to self.** If a competent-but-uninspired agent could not execute a step without guessing, the step is not finished being written.
|
|
11
|
+
3. **Nothing is silent.** Every finding, deviation, and shortcut must be either fixed or written down with a reason someone else would accept. 0% silent is the invariant — "fixed everything" is not.
|
|
12
|
+
|
|
13
|
+
## Scenario: write the program plan
|
|
14
|
+
|
|
15
|
+
State DONE MEANS falsifiably in the Goal — a command someone can run and a result they can check, not an aspiration. Pre-register acceptance benchmarks before any work: measure the current number (test count, timing, finding count, proof line), write it in the plan, and state the target number; work that cannot move a pre-registered number is scope to question.
|
|
16
|
+
|
|
17
|
+
Every plan step carries five fields: a file anchor with verified current behavior (cite how you know), the exact change, the validation command with expected output, a testability design (pure core, injected effects), and why this step is safe in this order. "Update X" with no current/target behavior is a wish, not a step.
|
|
18
|
+
|
|
19
|
+
Order phases by information gain and risk: blockers and evidence-integrity first, cheap discriminating probes before expensive builds, measurement before optimization, and anything not yet decided by the human becomes a GATED phase the executor must not start. Infrastructure that later steps inherit (a labeling choke point, a shared helper layer) must land before the features that need it. Flag one-way doors with their migration path, and keep an explicit DEFER list so cut scope is visible instead of forgotten.
|
|
20
|
+
|
|
21
|
+
Working agreement to include in the plan: ONE COMMIT PER STEP — bisectability is non-negotiable, and phase-level commits hide which step broke. Gate commands must be the FULL gate set the repo defines per phase — tests, typecheck, lint/format, and build — not just focused tests, because focused tests hide cross-phase regressions and omitting the linter is how red mains ship. Include regeneration duties and a deviation protocol: if source contradicts an anchor, BLOCKED-note it and continue; never improvise silently.
|
|
22
|
+
|
|
23
|
+
## Scenario: delegate and review a handoff
|
|
24
|
+
|
|
25
|
+
Delegate breadth, keep judgment: fan out mechanical/scoped work to subagents, but personally own anything requiring taste, cross-cutting context, or the final word on "is this real." Concurrent agents must get disjoint write scopes, named in their briefs; if a collision happens anyway, stop racing, apply-verify-commit atomically in one action, and re-sequence to a single writer.
|
|
26
|
+
|
|
27
|
+
Never accept a report at face value — reproduce its evidence. On every handoff, choose the minimal discriminating probe (the one command most likely to expose the report being wrong: a mutation input, a hand count, the benchmark number) and run it yourself; a report verified only by reading it is not verified. Loop until `scip-query diff-gate --json` is quiet: fix, re-run the discriminating probe, re-run the gate, and only then move on.
|
|
28
|
+
|
|
29
|
+
Verify your verifier: a gate check that cannot fail is no gate (e.g. a lint grep that only matches one linter's output, a diff-gate run on a clean tree, a test suite that skips the new path) — prove the check catches a planted failure once before trusting its green. After any "all green," ask what that check does NOT cover (eslint vs prettier; unit vs integration; clean-tree vacuity).
|
|
30
|
+
|
|
31
|
+
## Git and commit discipline
|
|
32
|
+
|
|
33
|
+
Never run `git checkout`/`restore`/`stash` on a tree with uncommitted work, yours or anyone's; revert probe edits by targeted deletion instead, and if source is lost, check `dist/*.map` sourcesContent before panicking. Commit working states early and surgically using explicit paths, never `add -A` on a shared tree; an unbisectable pile of work is a liability. Make commit cadence mechanical: at every step boundary run the arithmetic check "steps completed == commits made"; if they differ, stop and commit before touching anything new. "I'll commit when it's all done" is the signature decay pattern of a long or low-effort run — in two real executions this rationalized delay led to finishing an entire plan with zero or one commit, with the deviation rationalized mid-run rather than decided; a self-check that is a count (not a feeling) prevents this rationalization.
|
|
34
|
+
|
|
35
|
+
## Closing the program
|
|
36
|
+
|
|
37
|
+
After the program, fold what was learned back into the durable layer (docs, skills, followups) — insight that lives only in the conversation is lost. Escalate only genuine decision points — one-way doors, scope changes, taste, spending; for everything else, decide, act, and disclose.
|
|
38
|
+
|
|
39
|
+
Every conducted program and every plan written under this skill must end with a self-report checklist mapping each section above to concrete evidence: pre-registered benchmarks and their before/after values, each handoff's discriminating probe and its OBSERVED result (a probe listed but not run counts as not run), the deviation ledger, the DEFER list, and which learnings were folded back and where — so a reviewer can audit the conduct, not just the artifact.
|
|
40
|
+
|
|
41
|
+
The program is complete only when: every pre-registered benchmark is met or its miss explained; every handoff probe is run and recorded; the gate is quiet on the final state; nothing is silent (every finding fixed or ledgered); and the self-report is written.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# High-assurance planning (the certificate)
|
|
2
|
+
|
|
3
|
+
Load this only when the change meets a documented trigger: a security boundary or authorization decision, money/billing/external financial effect, a destructive or irreversible operation, a persistent-data migration, shared-state concurrency, a broad public API change, a rollout that cannot be rolled back, or the user explicitly requests the rigorous version. For ordinary work this protocol costs more than it protects — its cost lands on every future change routed through it. When genuinely unsure, ask rather than defaulting up.
|
|
4
|
+
|
|
5
|
+
A high-assurance plan is a **certificate**: a dated Markdown document whose "ready to implement" conclusion is derived from numbered, source-cited premises, defended against constructed counterexamples, and shaped so intended behavior is easy to test before it is easy to ship.
|
|
6
|
+
|
|
7
|
+
## Definitions (state these with referents, not by assertion)
|
|
8
|
+
|
|
9
|
+
- **Premise** — a numbered, source-cited statement of fact about the current code (P1, P2, ...); steps and defenses cite it by ID so a false premise is traceable to everything built on it. Literal source facts cite a native file read; compiler-resolved identity and complete writer/reader/caller/dependency/consumer/impact sets cite scip-query.
|
|
10
|
+
- **State-authority premise** — a premise enumerating the complete writer and reader sets of one shared state surface, made falsifiable by `refs` and `dataflow`, turning a forgotten write path from unknowable into a checkable omission.
|
|
11
|
+
- **Invariant** — a property of the changed system that must hold at every observable moment, stated in "iff" or "must always" form; the final verdict is derived from whether it survives every attack.
|
|
12
|
+
- **Contract** — the stable promise one code unit exposes to another: accepted inputs, returned outputs, errors, timing expectations, and side effects callers may rely on.
|
|
13
|
+
- **Reuse audit** — the part of a plan that proves a proposed new symbol/file/option/wrapper/contract is needed, by tying the new shape to existing definitions, consumers, and rejected extension points. Do not propose a new helper, wrapper, type, parameter, config flag, component, hook, or module until this proves reuse or extension is not the better move.
|
|
14
|
+
- **Test seam** — the entry point a test can call to prove a behavior without replaying the whole product path; must name the exact unit or boundary where correctness will be observed.
|
|
15
|
+
- **Side-effect boundary** — the edge where deterministic program decisions meet files, processes, clocks, networks, databases, or other external capabilities, so failures and fakes can be isolated there while core decisions stay easy to test.
|
|
16
|
+
- **Counterexample attack** — a concrete actor, starting state, and action sequence constructed to violate an invariant, whose defense cites premises and steps so "we considered failure" becomes "this specific failure is blocked here."
|
|
17
|
+
- **Enforcement window** — the interval between the step that installs an invariant enforcer and the step that brings the last existing writer into compliance; during it, every unupdated writer fails the new check in production, so the plan that adds safety can itself be the outage.
|
|
18
|
+
|
|
19
|
+
Every load-bearing concept gets a `Source:` line with referents — a definition without referents is a guess. Place each concept in its wider class, then name the one trait that causally explains its other traits in this codebase, written as prose (not labeled genus/differentia). Circular and synonym definitions are banned (e.g. "the refresh coordinator coordinates refreshes" defines nothing). Good definitions condense: they imply the concept's other traits instead of listing them, so derived requirements fall out automatically — e.g. if "restore" is defined as the inverse of "cancel," the privilege to restore must not be weaker than the privilege to cancel, and a plan gating them asymmetrically must defend that asymmetry. A claim with no supporting premise is either new evidence to gather or must be marked an explicit ASSUMPTION — never left silent.
|
|
20
|
+
|
|
21
|
+
## The six-step procedure
|
|
22
|
+
|
|
23
|
+
**Step 1 — Discover.** Run `scip-query status --capabilities` then `scip-query plan-context <target>` before filling in Goal, Definitions & Invariants, Current State, and Reuse Audit. Done only when concepts are defined with referents, invariants are stated formally, and every proposed new unit has a reuse decision with citations.
|
|
24
|
+
|
|
25
|
+
**Step 2 — Establish Premises.** For every state surface the plan touches (database column, store field, event topic, endpoint, cache entry), write one state-authority premise enumerating its complete writer and reader sets, established via `refs` and `dataflow` rather than memory. Case study: a sprint-restore plan hardened `restore()` and the cancellation path but never enumerated the writers of sprint status; review later found `PATCH /sprints/:id` could set `status:'active'` around every restore invariant, and transition automations wrote `sprintId` straight past the new membership guard — two of that review's five ship-blockers, both sitting in the writer list a single `refs` call would have produced. Done only when every state surface named in any phase has a state-authority premise and every remaining unknown is an explicit ASSUMPTION.
|
|
26
|
+
|
|
27
|
+
**Step 3 — Shape for Tests.** Shape plans so tests can call the pure core directly and exercise the side-effect shell with injected replacements. Preferred code shape: (1) parse and validate at the boundary, (2) pass domain data and injected dependencies into a small orchestrator, (3) put calculations/filtering/selection/formatting/state-transition decisions in pure functions, (4) keep database/network/filesystem/clock/randomness/logging/email/payment calls in thin side-effect shells, (5) depend on small contracts at boundaries and avoid broad option objects, booleans that hide behavior, and forwarding-only wrappers. Done only when every changed behavior has a named test seam and the plan makes clear which logic can be tested without real external services.
|
|
28
|
+
|
|
29
|
+
**Step 4 — Design the Checklist.** Write phases in execution order; keep each phase deployable or explicitly mark why it is not. Each checklist step needs: file anchor with line range; cited premises; a Deployable yes/no declaration (with reason or single-deploy group name); current behavior verified from source (What); the exact edit (Change); a full testability breakdown (test seam, injected dependencies, pure core, side-effect shell, contract); and a Validation entry (test, smoke command, or manual check). If a step installs an enforcer, check its enforcement window: every existing writer in the relevant state-authority premise is brought into compliance in the same or an earlier step, or the window is carried into the attack record as a hole to accept or repair. Done only when no checklist item says "update this file" without exact current behavior, target behavior, cited premises, a deployability declaration, and validation.
|
|
30
|
+
|
|
31
|
+
**Step 5 — Attack the Plan.** This pass is falsification, not defense — it should find holes against a draft. Prefer delegating it to a fresh subagent: give the adversary only the Definitions & Invariants, Premises, state-authority maps, and checklist (not the design rationale), and brief it that it wins by producing holes; fold findings back as HOLE entries and repair steps. Solo fallback: enumerate the full attack list from the coverage-matrix rows before writing any Outcome line, so attacks are not shaped around defenses already in hand. Use these lenses as attack prompts: purpose, blast radius, valid intermediate state, reversibility, failure, concurrency, boundaries, data integrity, observability, human experience, efficiency, reuse, testability.
|
|
32
|
+
|
|
33
|
+
Each attack record states an invariant and lens, an Attack (actor + starting state + action sequence), and an Outcome: HELD (defended by step N.M citing premises), HOLE — repaired by new step N.M, or HOLE — accepted with reason. A HELD outcome that cannot name its defending step and premises is not HELD — it is "a hole wearing confidence." An assertion of absence (e.g. "no new shared mutable state is introduced") is never a valid defense, because it cannot fail and therefore cannot catch anything. Invalid example that preceded three post-review remediation rounds on a real plan: "Concurrency: Validation happens before database writes; no new shared mutable state or retry behavior is introduced." — no actor, no interleaving, cites nothing. Valid contrast: "A3. Every stored value is a member of its field's option set via concurrency — Attack: admin removes option O in transaction A while a user writes value O in transaction B; interleaving B-validates → A-commits → B-commits persists an orphaned value. Outcome: HOLE — repaired by new step 2.2: validation reads the option definition outside B's lock (P4), so serialize definition changes with every value writer via FOR UPDATE on the definition row; regression proves both interleavings against PostgreSQL."
|
|
34
|
+
|
|
35
|
+
A repaired hole keeps its "HOLE — repaired by step N.M" label permanently and must never be rewritten to HELD, because the repair history is the evidence the pass falsified; the verdict's repaired count must equal the number of HOLE — repaired entries. Close the record with a coverage matrix — one row per writer in every state-authority premise and per applicable lens (valid intermediate state is always applicable when any step installs an enforcer or migration); a blank row is an unattacked writer, and the record is incomplete until every row names an attack or carries an accepted reason. Spread attacks across coverage-matrix rows before deepening any single one — depth on an axis already anticipated does not protect axes that were not; leaks come from blank rows, not from the tenth variation of an already-modeled race. An attack record where nothing ever broke is a red flag — rerun the pass as falsification, preferably in a fresh subagent context. Done only when the coverage matrix has no blank rows and every attack entry ends in a cited HELD or a recorded HOLE.
|
|
36
|
+
|
|
37
|
+
**Step 6 — Verify and Derive the Verdict.** Phase-by-phase reference verification (run or delegated) confirms: every path exists, every line range is still within about five lines, every premise reproduces when its Source command is rerun (a premise that no longer reproduces is false and everything citing it is suspect until fixed), every behavior claim matches source, every new unit has reuse evidence, and every behavior-changing step has cited premises, a validation command, and a testability design. After reference verification, rerun `scip-query plan-context <target>` for the cited targets to reconfirm the source-producing context.
|
|
38
|
+
|
|
39
|
+
Verdict template: "A plan is PLANNED-COMPLETE iff the coverage matrix has no blank rows, every attack ends in HELD with cited steps and premises or an accepted hole with a written reason, and no premise failed reverification," followed by a Result line stating PLANNED-COMPLETE or INCOMPLETE plus attack/hole counts and unresolved items. The attack/hole counts are part of the verdict itself — e.g. "16 attacks, 0 holes repaired" against a fresh draft signals an attack pass that defended instead of falsified, and should be rerun before shipping. Done only when stale references are fixed, every premise is reverified, and the verdict line is derived from the attack record.
|
|
40
|
+
|
|
41
|
+
## Document section order
|
|
42
|
+
|
|
43
|
+
Title and date; Goal; Definitions & Invariants; Premises (incl. state-authority premises and explicit assumptions); Current State (narrative citing premise IDs); Reuse Audit; Testability Design; Design Phases (steps citing premises, each with deployability declaration); Attack Record (attacks with outcomes, holes repaired or accepted, coverage matrix); Execution Order and deployable phase notes; Ship Order with one-way doors flagged; Verdict with attack and hole counts; Summary of files to create, edit, delete, and verify.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Performance optimization campaigns
|
|
2
|
+
|
|
3
|
+
For making a command, workflow, service, page, or tool faster without changing its observable result. Hyper optimization is a bounded campaign that improves runtime, memory, or computational cost against repeatable measurements. Campaign-level conduct (delegation, handoff verification, benchmark pre-registration across multiple phases) belongs to `references/conductor.md`; this file is the performance-domain method that runs inside it or standalone for a single target.
|
|
4
|
+
|
|
5
|
+
If the repo is not a reliable scip-query workspace, invoke the `scip-setup` skill first, before starting an optimization target.
|
|
6
|
+
|
|
7
|
+
## Choose QUICK or CAMPAIGN
|
|
8
|
+
|
|
9
|
+
- **QUICK** — a single command/function target with an obvious hot path: capture one `docs/benchmarks/runs/YYYY-MM-DD-<target>.jsonl` baseline, skip the ledger and the rest of the campaign artifact set, fix the hypothesis, measure after, done.
|
|
10
|
+
- **CAMPAIGN** — multiple targets, an unclear bottleneck, or a decision between competing designs: requires the full machinery — baseline doc, ledger, profiling, and an alternative-design track.
|
|
11
|
+
|
|
12
|
+
Decide with one test: if you can already name the one function you expect to fix and a single before/after number will settle it, use QUICK; if naming that function requires investigation or the fix might be architectural, use CAMPAIGN.
|
|
13
|
+
|
|
14
|
+
## Definitions
|
|
15
|
+
|
|
16
|
+
- **Measurement harness** — the repeatable set of commands, fixtures, corpora, environment notes, and result documents used to decide whether performance changed.
|
|
17
|
+
- **Run history** — the durable time series of measurements, one record per run, command, subprocess, or profiled stage.
|
|
18
|
+
- **Profile span** — one named timed piece of work inside the target process (input loading, cache reads, database queries, graph traversal, rendering, a child process, ...).
|
|
19
|
+
- **Hierarchical profiling** — measuring coarse spans first, then recursively splitting only the dominant span until the expensive operation is concrete enough to fix.
|
|
20
|
+
- **Command ledger** — the living document for one optimization target: output contract, current pipeline, timings, tried ideas, and decisions.
|
|
21
|
+
|
|
22
|
+
## Scenario: target-and-harness (both modes)
|
|
23
|
+
|
|
24
|
+
For a scip-query command target, start with `scip-query bench --json` (baseline timings, command outcomes, environment, optional sampled profiles), then `scip-query bench --json --cold-index --include-heavy --timeout-ms 600000` for cold-path and heavy-detector timings. Do not optimize until a measurement harness exists or is created. Capture representative inputs, the output contract, and correctness checks before editing anything for performance. Record every benchmark in machine-readable run history; measure cold and warm paths separately when they can diverge. Choose the target from user pain, telemetry, benchmark ranking, regression data, cost, frequency, or risk.
|
|
25
|
+
|
|
26
|
+
Artifacts: CAMPAIGN mode creates/updates `docs/benchmarks/YYYY-MM-DD-<target>-baseline.md` (QUICK mode skips this file); both modes create/update `docs/benchmarks/runs/YYYY-MM-DD-<target>.jsonl` — the one required run-history artifact in every mode.
|
|
27
|
+
|
|
28
|
+
Done only when baseline timings, output identity evidence, corpus, environment, and run-history location all exist.
|
|
29
|
+
|
|
30
|
+
## Scenario: the ledger (CAMPAIGN only)
|
|
31
|
+
|
|
32
|
+
QUICK mode skips this and goes straight to tracing behavior, using the single run-history file as its record. Write `docs/benchmarks/YYYY-MM-DD-<target>-ledger.md` with sections: Output Contract, Target Selection, Current Pipeline, Run History Location, Profile Spans, Bottleneck Candidates, Measurements, Current-Pipeline Optimizations, Alternative Designs, Decisions. Done only when the ledger can explain what must not change.
|
|
33
|
+
|
|
34
|
+
## Scenario: trace behavior
|
|
35
|
+
|
|
36
|
+
Run `scip-query plan-context`, `trace`, `call-graph`, `code`, `dataflow`, and `complexity` on the entry/hot symbol — `call-graph <entry-symbol>` returns callers/callees, `complexity <hot-symbol>` returns LOC, branch, complexity, callee, fan-in/out counts — then `scip-query change-surface <touched-file> --json --full` to verify blast radius. Record input parsing, option resolution, subprocesses, lookups, database queries, graph traversal, source scans, semantic calls, cache reads/writes, rendering, serialization, and verification. Done only when each major pipeline step can be timed as a profile span.
|
|
37
|
+
|
|
38
|
+
Before adding profiling spans, check whether the target app already has an instrumentation layer — a bespoke profiling harness competes with the one the codebase already trusts. When the optimization target is scip-query itself, its instrumentation is `src/instrumentation/profile.ts` (`profileSpan`/`profileAsyncSpan`), env-gated by `SCIP_QUERY_PROFILE` and `SCIP_QUERY_PROFILE_OUT`, with `SCIP_QUERY_PROFILE_CACHE_STATE` for cache-state labels and inherited workload/subsystem identities — use it instead of adding a parallel harness.
|
|
39
|
+
|
|
40
|
+
## Scenario: profile the chain
|
|
41
|
+
|
|
42
|
+
Measure the target unprofiled, then measure profiled once and compare overhead. Measure distinct states: cold index, cold evidence/cache fill, warm cache hit, repeated focused run, production-like mixed state. Add coarse spans covering the whole chain, then split the largest workload-weighted span, repeating until the slow operation is a repeated lookup, initialization, scan, traversal, subprocess, serialization step, or wait. Attach cardinality to spans: files, rows, symbols, candidates, cache hits/misses, bytes, edges, nodes, retries, or output rows — write span records with cardinality to run history. When spans carry work identities, run `scip-query work-audit <profile> --json` on the profiling JSONL to separate exact repeats from same-name work on different inputs, ranking repeated-work groups by measured avoidable time (bounded coverage). Done only when the dominant cost is concrete enough to form a falsifiable hypothesis.
|
|
43
|
+
|
|
44
|
+
## Scenario: diagnose and fix
|
|
45
|
+
|
|
46
|
+
Classify the dominant performance shape as one of: cold-only setup, warm slow path, repeated setup, N+1 work, broad scan, database time, subprocess startup, serialization, or cache invalidation. Prefer fixes in this order: remove accidental repetition; batch scalar work; move stable derived work to an index/cache with invalidation; replace broad scans with indexed lookups; replace wrapper APIs only after output identity proves equivalence; add pruning only when mathematically equivalent or corpus-proven. Make the smallest reversible change that tests one hypothesis at a time. Work both tracks in parallel — tune the current pipeline and evaluate alternative algorithms or data models — and keep only changes that improve real workloads without reducing accuracy, diagnostics, safety, or supported inputs. Reject faster changes that alter the output contract unless the user explicitly approved a behavior change. Done only when before/after timings, profile deltas, and output identity are recorded.
|
|
47
|
+
|
|
48
|
+
## Scenario: verify, report, and close
|
|
49
|
+
|
|
50
|
+
Run the narrow correctness check, benchmark cases, and routed postchecks, then invoke `scip-verify`. End the campaign with a scoreboard from run history containing: starting value, current value, delta, scenario, corpus, commit/version, output identity, accepted changes, rejected ideas, remaining bottlenecks, and next target.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# TLA+ modeling with code evidence
|
|
2
|
+
|
|
3
|
+
Use when a TypeScript system needs a TLA+ model tied to code evidence — before implementing a risky protocol, or as post-implementation trace-conformance against the real system. A **modeled slice** is the bounded part of the real system represented by the model: state, transitions, inputs, outputs, and failure modes.
|
|
4
|
+
|
|
5
|
+
Model the part of the system 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.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
- `scip-query tla scaffold <file>` — starts a new model: derives a draft spec, config, and mapping from indexed code.
|
|
10
|
+
- `scip-query tla verify <spec>` — mechanical conformance: checks referents, reads/writes, calls, and runs the model checker.
|
|
11
|
+
- `scip-query tla instrument <spec>` — generates a trace recorder plus wiring sites for each mapped action.
|
|
12
|
+
- `scip-query tla trace-check <spec> --trace <file>` — semantic conformance: checks a recorded execution against the model's Next relation.
|
|
13
|
+
- `scip-query tla fetch-tools` — downloads the pinned tla2tools.jar into the cache when the model checker is unavailable.
|
|
14
|
+
|
|
15
|
+
## Scenario: scaffold a model from code
|
|
16
|
+
|
|
17
|
+
`scip-query tla scaffold <file>` 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. `--out` must stay inside the project root.
|
|
18
|
+
|
|
19
|
+
Scaffold calls `getDefinitionsForFile(db, file, { includeClassMemberFallbacks: true })`, which surfaces class-member fallback rows (`ClassName#field.` symbols with a real definition mention) alongside primary rows even when the file has other primary-indexed definitions — verified live with the `Watcher` class in `src/runtime/watch.ts`, so concurrency classes like locks, connection pools, or watchers now scaffold correctly. What remains genuinely invisible to scaffold is narrower: a file where the indexer emitted no member row for a class at all (neither a primary `defn_enclosing_ranges` row nor a `role=1` definition mention) — scaffold reports "no mutable state discovered" because there is nothing in the index to find. When that happens, model by hand from `plan-context`/`trace` evidence instead of via scaffold.
|
|
20
|
+
|
|
21
|
+
TRIAGE the scaffold output first: if 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.
|
|
22
|
+
|
|
23
|
+
## Scenario: the modeling loop
|
|
24
|
+
|
|
25
|
+
1. **Explore.** `scip-query plan-context <target>`, `system`, `trace`, `call-graph`, `dataflow` until state and transitions are concrete.
|
|
26
|
+
2. **Scaffold.** `scip-query tla scaffold <file>` to generate the draft spec, config, and mapping.
|
|
27
|
+
3. **Resolve every TODO the scaffold emits** — guards, domains, initial values. The scaffold derives what changes; you must supply when it may change. `tla verify` does not detect unfilled TODOs and will report PASS on a placeholder model — grep the spec for TODO before trusting a green run.
|
|
28
|
+
4. **Verify.** `scip-query tla verify <spec> --map <map> --config <cfg>` and read the Proof line; every waiver must carry a reason you would defend in review. `--map` is usually unnecessary: if no `Spec.scip-tla.json` sits next to `Spec.tla`, `tla verify` scans sibling `*.scip-tla.json` files for one whose `module` field names this spec (project-relative `.tla` path, bare filename, or TLA MODULE identifier all accepted) and uses it automatically, printing "(matched by module field)". Two or more mappings naming the same module is a hard error listing every candidate; pass `--map` explicitly to disambiguate. Use `--checker none` only when intentionally checking the mapping without SANY, TLC, or Apalache. If the model checker fails, fix the TLA+ model before relying on conformance output.
|
|
29
|
+
5. **Instrument and trace-check.** Wire the recorder from `scip-query tla instrument`, run the existing tests with `SCIP_TLA_TRACE=<path>` set, 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. When 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.
|
|
30
|
+
6. **Classify every finding** as code bug, model bug, mapping bug, insufficient trace/alias evidence, or accepted non-modeled behavior.
|
|
31
|
+
7. **Patch code, model, or mapping and rerun** until only explicitly waived uncertainty remains.
|
|
32
|
+
|
|
33
|
+
Done 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.
|
|
34
|
+
|
|
35
|
+
## Model quality rules
|
|
36
|
+
|
|
37
|
+
- **TypeOK first** — write the type invariant before any property; it catches most modeling mistakes at the lowest checking cost.
|
|
38
|
+
- **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 and should be deleted or replaced.
|
|
39
|
+
- **Falsify every invariant individually** — 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 and should be deleted or redesigned.
|
|
40
|
+
- **Break the model on purpose** — after the first green run, remove one guard or widen one domain and confirm TLC catches it, then restore it; a spec that cannot fail proves nothing.
|
|
41
|
+
- **Safety before liveness** — add fairness only when a liveness property demands it; check deadlock unless termination is intended.
|
|
42
|
+
- **Bound the space deliberately** — use small symbolic constant sets, symmetry where sound, and short sequences; nondeterministic `\in` transitions from the scaffold are permissive placeholders that should be tightened to concrete transitions as you learn the code.
|
|
43
|
+
|
|
44
|
+
## Trace divergence and regression models
|
|
45
|
+
|
|
46
|
+
Divergence taxonomy: 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 and requires writing the regression model before fixing it.
|
|
47
|
+
|
|
48
|
+
A **regression model** is a small TLA+ module or checker config derived from a counterexample, production bug, or suspected transition. Fast workflow: preserve the full model as source of truth, create a companion regression spec/config named for the failure and seeded from the exact counterexample trace (a diverging trace-check output is already that trace), prefer bounded constants and narrowed action sets over weakening the main model, run the regression first after each patch then run the full model after it passes, and keep the regression if it protects future behavior.
|
|
49
|
+
|
|
50
|
+
If code changed but the model did not, inspect whether the mapped transition changed meaning; `diff-gate` flags the changed referents.
|
|
51
|
+
|
|
52
|
+
## The mapping contract
|
|
53
|
+
|
|
54
|
+
Top-level fields: `module`, `config`, `scope`, `variables`, `actions`, `invariants`, `traces` (see the example mapping for `specs/Queue.tla`). Mapping 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).
|
|
55
|
+
|
|
56
|
+
**Four state backings:** program variables use normal aliases, filesystem-backed state uses resource bindings, SQL-backed state uses statements bindings, and ORM-backed state with no literal SQL uses ormCalls bindings — only genuinely dynamic SQL or an unmatched ORM shape still needs a waiver naming the residual class; never fake attribution.
|
|
57
|
+
|
|
58
|
+
- **Resource mapping** binds a variable to filesystem state — a lock file, a published artifact — anything the model treats as owned state but 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 resource path as writes, and `readFileSync`/`existsSync`/`statSync` calls the same way as reads. Matching 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.
|
|
59
|
+
- **Statements mapping** (feature Q2) binds a variable to SQL-backed state — prepared statements, table rows behind `db.prepare(...)`/`.exec(...)`/tagged templates — via entries shaped `{ "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 with `${...}` interpolations excluded) matches the pattern is classified by its leading SQL verb: INSERT/UPDATE/DELETE/REPLACE is a write, SELECT is a read. Dynamic SQL built by string concatenation has no static text to match and still falls through to needing a waiver. Two variables sharing a statements pattern is a mapping-load error, the same as a shared resource path.
|
|
60
|
+
- **ormCalls mapping** (feature C1) binds a variable to ORM-backed state when there is no literal SQL text to match — Drizzle-style query builders such as `db.update(t).set(...)`, `db.insert(t).values(...)`, `db.select().from(t)`, `db.delete(t)` — via entries shaped `{ "table": "<identifier>", "methods"?: [...] }`. A match requires a call chain whose own method name is in the write set (update/insert/delete by default) or read set (select/query/findFirst/findMany by default) AND whose own table argument (or, for select, the `.from(t)` chain segment) names the mapped table — matching never looks at the receiver (`db`, `tx`, ...), only the method + table-arg shape. `methods` narrows the effective set to a subset of the seven-name vocabulary; an unrecognized method name fails to load. Two variables binding the same (table, method) pair is a mapping-load error — but a write-only binding and a read-only binding on the same table do not collide.
|
|
61
|
+
|
|
62
|
+
**Waivers are per-fact and require a reason** — the blanket `allowUnknown` waiver is legacy and should not be used. Write/read waiver symmetry: `actions.<name>.waive.writes` exempts model-code-write, undeclared-write, and missing-write-evidence findings, the same way `waive.reads` exempts the read-side equivalents. A variable-level waive on `actions.<name>.writes` also exempts the corresponding model-mapping-write mismatch against the SANY-derived model text. A waived write still shows up in the Proof line's waiver ledger with its reason — it never silently vanishes.
|
|
63
|
+
|
|
64
|
+
**Line windows** (feature C3): an action code entry can narrow itself to `file#function@L<start>-L<end>` — when several guard/branch actions share one function, a whole-function code reference forces every sibling to claim every write in it, whereas a window scopes fact collection to a sub-range so each branch action attributes only its own write. A mapping line window must fall entirely inside the referent's actual resolved span or `tla verify` reports a hard invalid-line-window error naming the file, function, and actual span — it never silently clamps back to the whole function. (Line windows are line-number-brittle by design: a later refactor that shifts lines is caught loudly by the containment check plus referent resolution, not silently mis-scanned.)
|
|
65
|
+
|
|
66
|
+
**Variable-level controls.** `variables.<v>.selfAlias: false` opts out of the automatic self-name alias (default true); normally a variable's own TLA+ name is always added to its alias list, which can make an object-literal key or identifier that merely echoes the variable's name — but means something unrelated elsewhere in scope — become an unavoidable false write/read attribution. A `selfAlias: false` variable with no other alias, no resource, no statements, and no waive is a mapping load error, since it would otherwise be silently unattributable. `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`) — but a variable-level waive does not exempt read/write facts; those stay on the action's own waive.
|
|
67
|
+
|
|
68
|
+
**Scope enforcement.** Top-level `unmappedWriteScope: 'actions' | 'scope-files'` (default `scope-files`) controls strictness: 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 it to `'actions'` to opt out of the 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.
|
|
69
|
+
|
|
70
|
+
**Init binding** (feature Q3): top-level `init: { codeRefs: ["file#function", ...], waive?: {reason} }` binds the model's Init to the code referent(s) that materialize initial state — most often a lazy-init factory. `init.codeRefs` resolves and kind-checks like an action's code field (function-like, missing-referent/invalid-referent-kind findings apply, and waive exempts both). Writes statically found inside an Init referent's own range are Init-attributed and excluded from unmapped-write findings without needing `unmappedWriteScope: 'actions'`. `init.codeRefs` must not overlap any action's code referents — overlap is a mapping-load error, the same category as a variable-alias collision. Lazy initialization is Init, not an action: a factory that lazily builds state corresponds to the model's Init and must be mapped to `init`, never to an action.
|
|
71
|
+
|
|
72
|
+
## Alias discipline
|
|
73
|
+
|
|
74
|
+
Alias selection is the sharpest knife: never alias a variable to a ubiquitous local identifier (`connection`, `result`, `data`), because 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. Turn off the forced self-alias when the variable's own name is a common word (`status`, `phase`, `state`) since object literals elsewhere in scope will otherwise match it and cause misattribution; set `selfAlias: false` and give a precise alias naming the actual stored field. Prefer an honest variable waive over citing an unrelated real symbol just to satisfy the value-like-kind check — name a referent that plainly does not resolve (or resolves to the wrong kind) and waive it, so a reader never has to guess that a `code[]` entry is a decoy.
|
|
75
|
+
|
|
76
|
+
## Traces and coverage
|
|
77
|
+
|
|
78
|
+
Design for traces early: the trace encoder pins scalar (and scalar-array) variables only, so a model whose state is all functions and tuple-sets cannot be trace-validated; add scalar projection variables (counts, last outcomes, a phase) alongside the structured state if trace-check matters for the slice.
|
|
79
|
+
|
|
80
|
+
Trace until covered: one accepted trace proves one path, not the whole 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.
|
|
81
|
+
|
|
82
|
+
`tla trace-check ... --coverage` (feature C2) mechanizes coverage checking: it reports steps-exercised-per-action counted from accepted steps only (a step that never proved a legal transition — checker unavailable, or past the divergence point of a rejected trace — does not count), and names every action still unexercised. `--trace` is repeatable and merged/deduped with the mapping's own `traces` list, so recording another trace to cover a gap is additive, not a rewrite. Coverage is informational and does not change trace-check's exit code, so it never substitutes for actually closing the gap.
|
|
83
|
+
|
|
84
|
+
## Accuracy and evidence tiers
|
|
85
|
+
|
|
86
|
+
`tla verify` is the mechanical checker and `tla trace-check` is the semantic one — only the pair together justifies the word "conforms." A PASS with waivers is a conditional claim — the Proof line says exactly what was and was not proven, and must never be summarized as unconditional. A PASS on a scaffold with unresolved TODOs is meaningless, not conditional, since the checker has no TODO detector and will pass a placeholder model — never report a PASS without confirming the scaffold's TODOs were actually resolved.
|
|
87
|
+
|
|
88
|
+
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 and is marked "(via `<callee>`, one call hop...)" in findings. The one-call-hop scanner 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 via the one-call-hop scanner, update the waiver reason to name the real call chain instead of deleting the explanation — the evidence is still approximate since which specific runtime call path executes is not proven, only that the code family does.
|