wicked-garden 12.27.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.
Files changed (640) hide show
  1. package/.claude-plugin/archetypes.json +166 -0
  2. package/.claude-plugin/components.json +75 -0
  3. package/.claude-plugin/marketplace.json +15 -0
  4. package/.claude-plugin/plugin.json +174 -0
  5. package/.claude-plugin/specialist.json +48 -0
  6. package/.claude-plugin/stack-registry.json +96 -0
  7. package/AGENTS.md +13 -0
  8. package/CHANGELOG.md +712 -0
  9. package/CONTRIBUTING.md +99 -0
  10. package/ETHOS.md +83 -0
  11. package/LICENSE +21 -0
  12. package/README.md +115 -0
  13. package/WICKED_GARDEN_BUS_EVENTS.md +149 -0
  14. package/agents/agentic/architect.md +449 -0
  15. package/agents/agentic/performance-analyst.md +702 -0
  16. package/agents/agentic/safety-reviewer.md +662 -0
  17. package/agents/crew/implementer.md +163 -0
  18. package/agents/crew/researcher.md +94 -0
  19. package/agents/crew/reviewer.md +184 -0
  20. package/agents/data/data-engineer.md +227 -0
  21. package/agents/engineering/api-documentarian.md +440 -0
  22. package/agents/engineering/migration-engineer.md +301 -0
  23. package/agents/engineering/solution-architect.md +208 -0
  24. package/agents/jam/brainstorm-facilitator.md +297 -0
  25. package/agents/jam/council.md +322 -0
  26. package/agents/jam/quick-facilitator.md +85 -0
  27. package/agents/persona/persona-agent.md +121 -0
  28. package/agents/platform/compliance-officer.md +266 -0
  29. package/agents/platform/privacy-expert.md +496 -0
  30. package/agents/platform/security-engineer.md +287 -0
  31. package/agents/product/a11y-expert.md +323 -0
  32. package/agents/product/requirements-analyst.md +238 -0
  33. package/agents/product/ui-reviewer.md +180 -0
  34. package/agents/product/ux-designer.md +199 -0
  35. package/agents/product/value-strategist.md +269 -0
  36. package/agents/qe/semantic-reviewer.md +78 -0
  37. package/commands/agentic/audit.md +24 -0
  38. package/commands/agentic/design.md +24 -0
  39. package/commands/agentic/frameworks.md +25 -0
  40. package/commands/agentic/review.md +27 -0
  41. package/commands/archetype/build.md +12 -0
  42. package/commands/archetype/decide.md +12 -0
  43. package/commands/archetype/explore.md +12 -0
  44. package/commands/archetype/incident.md +12 -0
  45. package/commands/archetype/migrate.md +12 -0
  46. package/commands/archetype/modernize.md +12 -0
  47. package/commands/archetype/review.md +14 -0
  48. package/commands/archetype/ship.md +12 -0
  49. package/commands/archetype/specify.md +12 -0
  50. package/commands/archetype/triage.md +12 -0
  51. package/commands/compile.md +37 -0
  52. package/commands/data/analyze.md +18 -0
  53. package/commands/data/data.md +21 -0
  54. package/commands/data/ml.md +18 -0
  55. package/commands/data/ontology.md +22 -0
  56. package/commands/data/pipeline.md +17 -0
  57. package/commands/deliberate.md +181 -0
  58. package/commands/engineering/add-field.md +77 -0
  59. package/commands/engineering/apply.md +58 -0
  60. package/commands/engineering/arch.md +26 -0
  61. package/commands/engineering/debug.md +27 -0
  62. package/commands/engineering/docs.md +27 -0
  63. package/commands/engineering/new-generator.md +257 -0
  64. package/commands/engineering/patch-plan.md +59 -0
  65. package/commands/engineering/plan.md +29 -0
  66. package/commands/engineering/remove.md +48 -0
  67. package/commands/engineering/rename.md +44 -0
  68. package/commands/engineering/review.md +32 -0
  69. package/commands/help.md +128 -0
  70. package/commands/install.md +118 -0
  71. package/commands/intent.md +54 -0
  72. package/commands/jam/brainstorm.md +37 -0
  73. package/commands/jam/council.md +49 -0
  74. package/commands/jam/quick.md +21 -0
  75. package/commands/jam/revisit.md +79 -0
  76. package/commands/persona/as.md +136 -0
  77. package/commands/persona/define.md +24 -0
  78. package/commands/persona/list.md +118 -0
  79. package/commands/platform/actions.md +20 -0
  80. package/commands/platform/assert.md +18 -0
  81. package/commands/platform/audit.md +23 -0
  82. package/commands/platform/compliance.md +20 -0
  83. package/commands/platform/gh.md +22 -0
  84. package/commands/platform/health.md +22 -0
  85. package/commands/platform/incident.md +23 -0
  86. package/commands/platform/infra.md +24 -0
  87. package/commands/platform/peer-health.md +103 -0
  88. package/commands/platform/plugin-health.md +58 -0
  89. package/commands/platform/security.md +38 -0
  90. package/commands/platform/toolchain.md +96 -0
  91. package/commands/platform/traces.md +20 -0
  92. package/commands/product/a11y.md +19 -0
  93. package/commands/product/acceptance.md +19 -0
  94. package/commands/product/align.md +20 -0
  95. package/commands/product/analyze.md +23 -0
  96. package/commands/product/elicit.md +19 -0
  97. package/commands/product/listen.md +24 -0
  98. package/commands/product/mockup.md +20 -0
  99. package/commands/product/screenshot.md +19 -0
  100. package/commands/product/strategy.md +40 -0
  101. package/commands/product/synthesize.md +23 -0
  102. package/commands/product/ux-review.md +42 -0
  103. package/commands/product/ux.md +20 -0
  104. package/commands/product/visual-direction.md +34 -0
  105. package/commands/prove.md +47 -0
  106. package/commands/report-issue.md +243 -0
  107. package/commands/reset.md +144 -0
  108. package/commands/search/blast-radius.md +58 -0
  109. package/commands/search/hotspots.md +55 -0
  110. package/commands/search/index.md +38 -0
  111. package/commands/search/lineage.md +47 -0
  112. package/commands/search/service-map.md +79 -0
  113. package/commands/setup.md +363 -0
  114. package/commands/smaht/briefing.md +200 -0
  115. package/commands/smaht/events-import.md +95 -0
  116. package/commands/smaht/state.md +19 -0
  117. package/commands/where-am-i.md +58 -0
  118. package/docs/README.md +32 -0
  119. package/docs/adr/0001-code-relationship-graph-engine.md +116 -0
  120. package/docs/adr/0002-major-cleanup-keep-cut.md +91 -0
  121. package/docs/adr/0003-peers-gate-required-layers-optin.md +41 -0
  122. package/docs/adr/0004-code-graph-moves-to-wicked-brain.md +47 -0
  123. package/docs/brain-chunk-format.md +135 -0
  124. package/docs/compiler.md +95 -0
  125. package/docs/daemon-api.md +70 -0
  126. package/docs/domains.md +197 -0
  127. package/docs/getting-started.md +208 -0
  128. package/docs/plans/2026-06-08-wicked-loom-conduct.md +1337 -0
  129. package/docs/plans/2026-06-08-wicked-loom-contract.md +638 -0
  130. package/docs/plans/2026-06-08-wicked-loom-cutover.md +1300 -0
  131. package/docs/plans/2026-06-08-wicked-loom-expand-compose.md +843 -0
  132. package/docs/plans/2026-06-08-wicked-loom-flow-cutover.md +403 -0
  133. package/docs/plans/2026-06-10-codegraph-to-brain-phase1a-graph-core.md +838 -0
  134. package/docs/plans/2026-06-10-codegraph-to-brain-phase1b-injected-edges.md +44 -0
  135. package/docs/required-peers.md +60 -0
  136. package/docs/specs/2026-06-08-wicked-loom-extraction.md +225 -0
  137. package/docs/specs/2026-06-10-codegraph-to-brain-migration.md +168 -0
  138. package/docs/v11/archetypes.md +231 -0
  139. package/hooks/hooks.json +275 -0
  140. package/hooks/scripts/bootstrap.py +1797 -0
  141. package/hooks/scripts/invoke.py +62 -0
  142. package/hooks/scripts/notification.py +166 -0
  143. package/hooks/scripts/permission_request.py +223 -0
  144. package/hooks/scripts/post_tool.py +1374 -0
  145. package/hooks/scripts/pre_compact.py +272 -0
  146. package/hooks/scripts/pre_tool.py +1278 -0
  147. package/hooks/scripts/prompt_submit.py +1109 -0
  148. package/hooks/scripts/session_end.py +95 -0
  149. package/hooks/scripts/stop.py +624 -0
  150. package/hooks/scripts/subagent_lifecycle.py +464 -0
  151. package/hooks/scripts/subscribers/on_gate_decided.py +84 -0
  152. package/hooks/scripts/task_completed.py +322 -0
  153. package/hooks/scripts/worktree_guard.py +148 -0
  154. package/hooks/subscriptions/on_gate_decided.json +9 -0
  155. package/install.mjs +128 -0
  156. package/package.json +41 -0
  157. package/pyproject.toml +59 -0
  158. package/schemas/README.md +32 -0
  159. package/schemas/assert_contracts.json +37 -0
  160. package/schemas/health_probe.json +46 -0
  161. package/schemas/plugin_status.json +37 -0
  162. package/scripts/_adapters/__init__.py +166 -0
  163. package/scripts/_adapters/jira_adapter.py +18 -0
  164. package/scripts/_adapters/linear_adapter.py +18 -0
  165. package/scripts/_adapters/miro_adapter.py +18 -0
  166. package/scripts/_adapters/notion_adapter.py +18 -0
  167. package/scripts/_agents.py +357 -0
  168. package/scripts/_brain_ingest/__init__.py +2 -0
  169. package/scripts/_brain_ingest/session_fact_extractor.py +341 -0
  170. package/scripts/_brain_port.py +163 -0
  171. package/scripts/_bus.py +1081 -0
  172. package/scripts/_bus_catalog_gen.py +93 -0
  173. package/scripts/_bus_consumers.json +46 -0
  174. package/scripts/_bus_emit.py +43 -0
  175. package/scripts/_capability_registry.py +334 -0
  176. package/scripts/_capability_resolver.py +322 -0
  177. package/scripts/_domain_store.py +559 -0
  178. package/scripts/_event_log_reader.py +154 -0
  179. package/scripts/_event_schema.py +305 -0
  180. package/scripts/_event_store.py +397 -0
  181. package/scripts/_heavy_cadence.py +324 -0
  182. package/scripts/_integration_resolver.py +321 -0
  183. package/scripts/_logger.py +151 -0
  184. package/scripts/_loom.py +482 -0
  185. package/scripts/_paths.py +133 -0
  186. package/scripts/_python.sh +22 -0
  187. package/scripts/_run.py +137 -0
  188. package/scripts/_session.py +502 -0
  189. package/scripts/_validate_registry.py +1042 -0
  190. package/scripts/_wicked_testing_probe.py +277 -0
  191. package/scripts/agentic/analyze_agents.py +391 -0
  192. package/scripts/agentic/detect_framework.py +420 -0
  193. package/scripts/agentic/issue_taxonomy.py +357 -0
  194. package/scripts/agentic/pattern_scorer.py +434 -0
  195. package/scripts/classify/persist.py +169 -0
  196. package/scripts/compiler/compile.py +552 -0
  197. package/scripts/compiler/phase0/VERDICT.md +60 -0
  198. package/scripts/compiler/phase0/detect.py +292 -0
  199. package/scripts/compiler/phase0/emit.py +228 -0
  200. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.bindings.json +30 -0
  201. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.lint-output.txt +17 -0
  202. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/.wg/evidence/failing-tests.txt +4 -0
  203. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/.wg/evidence/honest-tests.txt +2 -0
  204. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/fab-fail.build.md +8 -0
  205. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/fab-missing.build.md +8 -0
  206. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/honest.build.md +8 -0
  207. package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/wg_check_claims.py +174 -0
  208. package/scripts/compiler/phase0/evidence/command_iq.bindings.json +45 -0
  209. package/scripts/compiler/phase0/evidence/command_iq.lint-output.txt +17 -0
  210. package/scripts/compiler/phase0/evidence/command_iq.stage/.projects/evidence-domain/phase-1-clarify/evidence/failing-tests.txt +4 -0
  211. package/scripts/compiler/phase0/evidence/command_iq.stage/.projects/evidence-domain/phase-1-clarify/evidence/honest-tests.txt +3 -0
  212. package/scripts/compiler/phase0/evidence/command_iq.stage/fab-fail.build.md +8 -0
  213. package/scripts/compiler/phase0/evidence/command_iq.stage/fab-missing.build.md +8 -0
  214. package/scripts/compiler/phase0/evidence/command_iq.stage/honest.build.md +8 -0
  215. package/scripts/compiler/phase0/evidence/command_iq.stage/wg_check_claims.py +174 -0
  216. package/scripts/compiler/phase0/evidence/memos.bindings.json +28 -0
  217. package/scripts/compiler/phase0/evidence/memos.lint-output.txt +17 -0
  218. package/scripts/compiler/phase0/evidence/memos.stage/.wg/evidence/failing-tests.txt +4 -0
  219. package/scripts/compiler/phase0/evidence/memos.stage/.wg/evidence/honest-tests.txt +2 -0
  220. package/scripts/compiler/phase0/evidence/memos.stage/fab-fail.build.md +8 -0
  221. package/scripts/compiler/phase0/evidence/memos.stage/fab-missing.build.md +8 -0
  222. package/scripts/compiler/phase0/evidence/memos.stage/honest.build.md +8 -0
  223. package/scripts/compiler/phase0/evidence/memos.stage/wg_check_claims.py +174 -0
  224. package/scripts/compiler/phase0/evidence/verdict.json +104 -0
  225. package/scripts/compiler/phase0/evidence/wicked-bus.bindings.json +29 -0
  226. package/scripts/compiler/phase0/evidence/wicked-bus.lint-output.txt +17 -0
  227. package/scripts/compiler/phase0/evidence/wicked-bus.stage/coverage/failing-tests.txt +4 -0
  228. package/scripts/compiler/phase0/evidence/wicked-bus.stage/coverage/honest-tests.txt +3 -0
  229. package/scripts/compiler/phase0/evidence/wicked-bus.stage/fab-fail.build.md +8 -0
  230. package/scripts/compiler/phase0/evidence/wicked-bus.stage/fab-missing.build.md +8 -0
  231. package/scripts/compiler/phase0/evidence/wicked-bus.stage/honest.build.md +8 -0
  232. package/scripts/compiler/phase0/evidence/wicked-bus.stage/wg_check_claims.py +174 -0
  233. package/scripts/compiler/phase0/evidence/wire-vault-transcript.txt +60 -0
  234. package/scripts/compiler/phase0/run_probe.py +234 -0
  235. package/scripts/compiler/phase0/wire_vault.py +310 -0
  236. package/scripts/crew/__init__.py +0 -0
  237. package/scripts/crew/_task_audit_writer.py +243 -0
  238. package/scripts/crew/_task_reader.py +389 -0
  239. package/scripts/crew/archetypes_v11.py +348 -0
  240. package/scripts/crew/detectors/__init__.py +12 -0
  241. package/scripts/crew/flow_compiler.py +121 -0
  242. package/scripts/crew/phase_manager.py +703 -0
  243. package/scripts/crew/scope_delta.py +264 -0
  244. package/scripts/crew/specialist_resolver.py +218 -0
  245. package/scripts/crew/stack_registry.py +189 -0
  246. package/scripts/data/data_profiler.py +271 -0
  247. package/scripts/data/ontology_recommender.py +231 -0
  248. package/scripts/data/schema_validator.py +267 -0
  249. package/scripts/delivery/drift.py +739 -0
  250. package/scripts/delivery/telemetry.py +614 -0
  251. package/scripts/engineering/patch/codegraph_db.py +125 -0
  252. package/scripts/engineering/patch/generators/__init__.py +56 -0
  253. package/scripts/engineering/patch/generators/base.py +373 -0
  254. package/scripts/engineering/patch/generators/csharp_generator.py +494 -0
  255. package/scripts/engineering/patch/generators/go_generator.py +430 -0
  256. package/scripts/engineering/patch/generators/java_generator.py +928 -0
  257. package/scripts/engineering/patch/generators/jsp_generator.py +454 -0
  258. package/scripts/engineering/patch/generators/kotlin_generator.py +561 -0
  259. package/scripts/engineering/patch/generators/perl_generator.py +510 -0
  260. package/scripts/engineering/patch/generators/php_generator.py +644 -0
  261. package/scripts/engineering/patch/generators/propagation_engine.py +929 -0
  262. package/scripts/engineering/patch/generators/python_generator.py +487 -0
  263. package/scripts/engineering/patch/generators/ruby_generator.py +463 -0
  264. package/scripts/engineering/patch/generators/rust_generator.py +400 -0
  265. package/scripts/engineering/patch/generators/sql_generator.py +594 -0
  266. package/scripts/engineering/patch/generators/typescript_generator.py +439 -0
  267. package/scripts/engineering/patch/patch.py +800 -0
  268. package/scripts/engineering/patch/safety.py +429 -0
  269. package/scripts/jam/__init__.py +0 -0
  270. package/scripts/jam/_bus_consumers.py +271 -0
  271. package/scripts/jam/agentic_cli_registry.py +703 -0
  272. package/scripts/jam/consensus.py +737 -0
  273. package/scripts/jam/detect_clis.py +409 -0
  274. package/scripts/jam/jam.py +283 -0
  275. package/scripts/jam/save_transcript.py +171 -0
  276. package/scripts/loom/__init__.py +22 -0
  277. package/scripts/loom/cli.py +170 -0
  278. package/scripts/loom/compose.py +180 -0
  279. package/scripts/loom/gate.py +120 -0
  280. package/scripts/loom/manifest.py +140 -0
  281. package/scripts/loom/resolve.py +59 -0
  282. package/scripts/persona/__init__.py +0 -0
  283. package/scripts/persona/registry.py +688 -0
  284. package/scripts/platform/guard_pipeline.py +1214 -0
  285. package/scripts/platform/guard_profiles.py +216 -0
  286. package/scripts/platform/observability/assert_contracts.py +434 -0
  287. package/scripts/platform/observability/health_probe.py +915 -0
  288. package/scripts/platform/observability/ops_log_viewer.py +209 -0
  289. package/scripts/platform/prereq_doctor.py +567 -0
  290. package/scripts/qe/conditions_manifest.py +260 -0
  291. package/scripts/qe/content_sanitizer.py +160 -0
  292. package/scripts/qe/coverage_tracker.py +535 -0
  293. package/scripts/qe/discover_scenarios.py +243 -0
  294. package/scripts/qe/evidence_tracker.py +232 -0
  295. package/scripts/qe/prove.py +196 -0
  296. package/scripts/qe/registry_lookup.py +80 -0
  297. package/scripts/qe/registry_store.py +176 -0
  298. package/scripts/qe/semantic_review.py +1005 -0
  299. package/scripts/qe/vault_gate.py +382 -0
  300. package/scripts/qe/verdict_audit.py +175 -0
  301. package/scripts/qe/verdict_schema.py +335 -0
  302. package/scripts/reset.py +220 -0
  303. package/scripts/resolve_path.py +22 -0
  304. package/scripts/sentinel/invariants.py +402 -0
  305. package/scripts/sentinel/pre_push.py +73 -0
  306. package/scripts/setup/__init__.py +1 -0
  307. package/scripts/setup/detect_state.py +114 -0
  308. package/scripts/setup/migrate_legacy.py +67 -0
  309. package/scripts/setup/migrate_v6_projects.py +232 -0
  310. package/scripts/setup/onboarding.py +114 -0
  311. package/scripts/smaht/_bus_consumers.py +98 -0
  312. package/scripts/smaht/adapters/__init__.py +83 -0
  313. package/scripts/smaht/adapters/brain_adapter.py +254 -0
  314. package/scripts/smaht/adapters/context7_adapter.py +438 -0
  315. package/scripts/smaht/adapters/delegation_adapter.py +104 -0
  316. package/scripts/smaht/adapters/domain_adapter.py +206 -0
  317. package/scripts/smaht/adapters/events_adapter.py +231 -0
  318. package/scripts/smaht/adapters/tools_adapter.py +49 -0
  319. package/scripts/smaht/cheatsheet_store.py +236 -0
  320. package/scripts/smaht/context_package.py +386 -0
  321. package/scripts/smaht/knowledge_graph.py +395 -0
  322. package/scripts/smaht/propose_skills.py +856 -0
  323. package/scripts/smaht/test_cheatsheet_store.py +428 -0
  324. package/scripts/statusline.py +151 -0
  325. package/scripts/where_am_i.py +236 -0
  326. package/skills/agentic/agentic-patterns/SKILL.md +91 -0
  327. package/skills/agentic/agentic-patterns/refs/anti-patterns-design.md +283 -0
  328. package/skills/agentic/agentic-patterns/refs/anti-patterns-operational.md +216 -0
  329. package/skills/agentic/agentic-patterns/refs/pattern-catalog.md +329 -0
  330. package/skills/agentic/context-engineering/SKILL.md +142 -0
  331. package/skills/agentic/context-engineering/refs/caching-and-optimization.md +251 -0
  332. package/skills/agentic/context-engineering/refs/compression-techniques.md +171 -0
  333. package/skills/agentic/context-engineering/refs/cost-calculation-budget.md +250 -0
  334. package/skills/agentic/context-engineering/refs/cost-optimization-reporting.md +300 -0
  335. package/skills/agentic/context-engineering/refs/selective-loading.md +179 -0
  336. package/skills/agentic/frameworks/SKILL.md +191 -0
  337. package/skills/agentic/frameworks/refs/framework-profiles-1.md +209 -0
  338. package/skills/agentic/frameworks/refs/framework-profiles-2.md +214 -0
  339. package/skills/agentic/frameworks/refs/migration-patterns-paths.md +267 -0
  340. package/skills/agentic/frameworks/refs/migration-patterns-testing.md +208 -0
  341. package/skills/agentic/refs/audit.md +134 -0
  342. package/skills/agentic/refs/design.md +137 -0
  343. package/skills/agentic/refs/frameworks.md +102 -0
  344. package/skills/agentic/refs/review.md +160 -0
  345. package/skills/agentic/review-methodology/SKILL.md +186 -0
  346. package/skills/agentic/review-methodology/refs/deliverable-templates.md +246 -0
  347. package/skills/agentic/review-methodology/refs/issue-taxonomy-quality-testing.md +277 -0
  348. package/skills/agentic/review-methodology/refs/issue-taxonomy-reliability-safety.md +253 -0
  349. package/skills/agentic/trust-and-safety/SKILL.md +177 -0
  350. package/skills/agentic/trust-and-safety/refs/guardrails-actions.md +246 -0
  351. package/skills/agentic/trust-and-safety/refs/guardrails-input-output.md +238 -0
  352. package/skills/agentic/trust-and-safety/refs/guardrails-resources.md +209 -0
  353. package/skills/agentic/trust-and-safety/refs/safety-checklist-advanced.md +209 -0
  354. package/skills/agentic/trust-and-safety/refs/safety-checklist-core.md +215 -0
  355. package/skills/archetype/SKILL.md +104 -0
  356. package/skills/archetype/refs/build.md +142 -0
  357. package/skills/archetype/refs/decide.md +117 -0
  358. package/skills/archetype/refs/explore.md +66 -0
  359. package/skills/archetype/refs/incident.md +149 -0
  360. package/skills/archetype/refs/migrate.md +170 -0
  361. package/skills/archetype/refs/modernize.md +187 -0
  362. package/skills/archetype/refs/review.md +145 -0
  363. package/skills/archetype/refs/ship.md +117 -0
  364. package/skills/archetype/refs/specify.md +108 -0
  365. package/skills/archetype/refs/triage.md +62 -0
  366. package/skills/classify/SKILL.md +157 -0
  367. package/skills/data/analysis/SKILL.md +125 -0
  368. package/skills/data/analysis/refs/templates.md +170 -0
  369. package/skills/data/data/SKILL.md +118 -0
  370. package/skills/data/data/refs/examples.md +235 -0
  371. package/skills/data/ml/SKILL.md +125 -0
  372. package/skills/data/ml/refs/templates.md +172 -0
  373. package/skills/data/pipeline/SKILL.md +136 -0
  374. package/skills/data/pipeline/refs/templates.md +175 -0
  375. package/skills/data/refs/analyze.md +123 -0
  376. package/skills/data/refs/data.md +95 -0
  377. package/skills/data/refs/ml.md +118 -0
  378. package/skills/data/refs/pipeline.md +92 -0
  379. package/skills/deliberate/SKILL.md +125 -0
  380. package/skills/deliberate/refs/architecture-lens.md +37 -0
  381. package/skills/deliberate/refs/assumptions-lens.md +43 -0
  382. package/skills/deliberate/refs/code-lens.md +38 -0
  383. package/skills/deliberate/refs/content-lens.md +37 -0
  384. package/skills/deliberate/refs/data-lens.md +43 -0
  385. package/skills/deliberate/refs/design-lens.md +37 -0
  386. package/skills/deliberate/refs/opportunity-patterns.md +107 -0
  387. package/skills/deliberate/refs/ops-lens.md +43 -0
  388. package/skills/deliberate/refs/product-lens.md +46 -0
  389. package/skills/deliberate/refs/rethink-framework.md +77 -0
  390. package/skills/deliberate/refs/security-lens.md +47 -0
  391. package/skills/deliberate/refs/testing-lens.md +45 -0
  392. package/skills/deliberate/refs/timing-lens.md +42 -0
  393. package/skills/engineering/architecture/SKILL.md +177 -0
  394. package/skills/engineering/architecture/refs/adr-template.md +268 -0
  395. package/skills/engineering/architecture/refs/architecture-template-deployment.md +176 -0
  396. package/skills/engineering/architecture/refs/architecture-template-design.md +300 -0
  397. package/skills/engineering/architecture/refs/examples-ecommerce-analytics.md +299 -0
  398. package/skills/engineering/architecture/refs/examples-saas-trading.md +291 -0
  399. package/skills/engineering/architecture/refs/patterns-advanced.md +238 -0
  400. package/skills/engineering/architecture/refs/patterns-structural.md +303 -0
  401. package/skills/engineering/backend/SKILL.md +102 -0
  402. package/skills/engineering/backend/refs/checklists.md +146 -0
  403. package/skills/engineering/backend/refs/patterns.md +181 -0
  404. package/skills/engineering/debugging/SKILL.md +99 -0
  405. package/skills/engineering/debugging/refs/patterns.md +248 -0
  406. package/skills/engineering/debugging/refs/process.md +203 -0
  407. package/skills/engineering/docs/SKILL.md +97 -0
  408. package/skills/engineering/engineering/SKILL.md +88 -0
  409. package/skills/engineering/engineering/refs/checklists.md +91 -0
  410. package/skills/engineering/engineering/refs/templates.md +71 -0
  411. package/skills/engineering/frontend/SKILL.md +92 -0
  412. package/skills/engineering/frontend/refs/checklists.md +96 -0
  413. package/skills/engineering/frontend/refs/patterns.md +167 -0
  414. package/skills/engineering/integration/SKILL.md +183 -0
  415. package/skills/engineering/integration/refs/error-handling-best-practices.md +139 -0
  416. package/skills/engineering/integration/refs/error-handling-error-classes-typescript.md +212 -0
  417. package/skills/engineering/integration/refs/error-handling-error-response-format.md +301 -0
  418. package/skills/engineering/integration/refs/error-handling-retry-strategies.md +190 -0
  419. package/skills/engineering/integration/refs/event-schemas-best-practices.md +225 -0
  420. package/skills/engineering/integration/refs/event-schemas-event-naming-conventions.md +303 -0
  421. package/skills/engineering/integration/refs/event-schemas-event-structure.md +288 -0
  422. package/skills/engineering/integration/refs/graphql-best-practices.md +138 -0
  423. package/skills/engineering/integration/refs/graphql-error-handling.md +198 -0
  424. package/skills/engineering/integration/refs/graphql-graphql-basics.md +197 -0
  425. package/skills/engineering/integration/refs/graphql-query-examples.md +226 -0
  426. package/skills/engineering/integration/refs/graphql-schema-design-patterns.md +280 -0
  427. package/skills/engineering/integration/refs/grpc-grpc-overview.md +246 -0
  428. package/skills/engineering/integration/refs/grpc-implementation-examples.md +269 -0
  429. package/skills/engineering/integration/refs/grpc-metadata-headers.md +304 -0
  430. package/skills/engineering/integration/refs/grpc-testing.md +49 -0
  431. package/skills/engineering/integration/refs/openapi-template.yaml +682 -0
  432. package/skills/engineering/integration/refs/resilience-best-practices.md +109 -0
  433. package/skills/engineering/integration/refs/resilience-circuit-breaker-pattern.md +302 -0
  434. package/skills/engineering/integration/refs/resilience-rate-limiting.md +245 -0
  435. package/skills/engineering/integration/refs/resilience-timeout-pattern.md +212 -0
  436. package/skills/engineering/integration/refs/rest-api-fundamentals.md +299 -0
  437. package/skills/engineering/integration/refs/rest-api-responses-security.md +302 -0
  438. package/skills/engineering/integration/refs/versioning-breaking-changes.md +237 -0
  439. package/skills/engineering/integration/refs/versioning-migration-strategies.md +257 -0
  440. package/skills/engineering/integration/refs/versioning-versioning-strategies.md +296 -0
  441. package/skills/engineering/large-scale-migration/SKILL.md +65 -0
  442. package/skills/engineering/patch/SKILL.md +184 -0
  443. package/skills/engineering/refs/arch.md +126 -0
  444. package/skills/engineering/refs/debug.md +142 -0
  445. package/skills/engineering/refs/docs.md +190 -0
  446. package/skills/engineering/refs/plan.md +109 -0
  447. package/skills/engineering/refs/review.md +138 -0
  448. package/skills/engineering/system-design/SKILL.md +154 -0
  449. package/skills/engineering/system-design/refs/anti-patterns-big-ball-of-mud.md +254 -0
  450. package/skills/engineering/system-design/refs/anti-patterns-circular-dependencies.md +241 -0
  451. package/skills/engineering/system-design/refs/anti-patterns-feature-envy.md +168 -0
  452. package/skills/engineering/system-design/refs/anti-patterns-god-object.md +247 -0
  453. package/skills/engineering/system-design/refs/component-template-lifecycle.md +210 -0
  454. package/skills/engineering/system-design/refs/component-template-maintenance.md +219 -0
  455. package/skills/engineering/system-design/refs/component-template-structure.md +276 -0
  456. package/skills/engineering/system-design/refs/dependencies-best-practices.md +260 -0
  457. package/skills/engineering/system-design/refs/dependencies-dependency-principles.md +295 -0
  458. package/skills/engineering/system-design/refs/dependencies-dependency-tracking.md +261 -0
  459. package/skills/engineering/system-design/refs/interface-template-lifecycle.md +211 -0
  460. package/skills/engineering/system-design/refs/interface-template-maintenance.md +212 -0
  461. package/skills/engineering/system-design/refs/interface-template-structure.md +269 -0
  462. package/skills/engineering/system-design/refs/patterns-dependency-injection.md +151 -0
  463. package/skills/engineering/system-design/refs/patterns-facade-pattern.md +257 -0
  464. package/skills/engineering/system-design/refs/patterns-layered-pattern.md +204 -0
  465. package/skills/engineering/system-design/refs/patterns-plugin-architecture.md +229 -0
  466. package/skills/engineering/unit-test-quality/SKILL.md +194 -0
  467. package/skills/ground/SKILL.md +130 -0
  468. package/skills/integration-discovery/SKILL.md +168 -0
  469. package/skills/integration-discovery/refs/capabilities.md +282 -0
  470. package/skills/integration-discovery/refs/cli-detection.md +295 -0
  471. package/skills/integration-discovery/refs/discovery-sources.md +233 -0
  472. package/skills/integration-discovery/refs/task-patterns.md +206 -0
  473. package/skills/jam/SKILL.md +45 -0
  474. package/skills/jam/refs/facilitation-patterns.md +125 -0
  475. package/skills/jam/refs/quick.md +64 -0
  476. package/skills/jam/refs/synthesis-patterns.md +114 -0
  477. package/skills/multi-model/SKILL.md +168 -0
  478. package/skills/multi-model/refs/aichat.md +119 -0
  479. package/skills/multi-model/refs/aider.md +100 -0
  480. package/skills/multi-model/refs/auditability.md +238 -0
  481. package/skills/multi-model/refs/codex.md +169 -0
  482. package/skills/multi-model/refs/context.md +306 -0
  483. package/skills/multi-model/refs/copilot.md +161 -0
  484. package/skills/multi-model/refs/examples.md +224 -0
  485. package/skills/multi-model/refs/gemini.md +185 -0
  486. package/skills/multi-model/refs/goose.md +112 -0
  487. package/skills/multi-model/refs/llm.md +124 -0
  488. package/skills/multi-model/refs/opencode.md +196 -0
  489. package/skills/multi-model/refs/orchestration.md +188 -0
  490. package/skills/multi-model/refs/pi.md +208 -0
  491. package/skills/persona/SKILL.md +144 -0
  492. package/skills/persona/refs/define.md +133 -0
  493. package/skills/platform/actions/refs/actions.md +114 -0
  494. package/skills/platform/audit/SKILL.md +174 -0
  495. package/skills/platform/audit/refs/audit.md +145 -0
  496. package/skills/platform/audit/refs/checklists-evidence-operations.md +144 -0
  497. package/skills/platform/audit/refs/checklists-gdpr-pci-evidence.md +213 -0
  498. package/skills/platform/audit/refs/checklists-soc2-hipaa.md +120 -0
  499. package/skills/platform/audit/refs/frameworks-gdpr-pci.md +225 -0
  500. package/skills/platform/audit/refs/frameworks-soc2-hipaa.md +228 -0
  501. package/skills/platform/compliance/SKILL.md +169 -0
  502. package/skills/platform/compliance/refs/checklists.md +303 -0
  503. package/skills/platform/compliance/refs/compliance.md +117 -0
  504. package/skills/platform/compliance/refs/frameworks.md +282 -0
  505. package/skills/platform/errors/SKILL.md +183 -0
  506. package/skills/platform/errors/refs/patterns.md +271 -0
  507. package/skills/platform/errors/refs/severity.md +264 -0
  508. package/skills/platform/gate-benchmark-rebaseline/SKILL.md +108 -0
  509. package/skills/platform/gh/refs/gh.md +105 -0
  510. package/skills/platform/gh-cli/SKILL.md +120 -0
  511. package/skills/platform/gh-cli/refs/automation.md +63 -0
  512. package/skills/platform/gh-cli/refs/gh-ops.md +103 -0
  513. package/skills/platform/gh-cli/refs/patterns.md +132 -0
  514. package/skills/platform/gh-cli/scripts/gh_ops.py +454 -0
  515. package/skills/platform/github-actions/SKILL.md +159 -0
  516. package/skills/platform/github-actions/refs/security.md +150 -0
  517. package/skills/platform/github-actions/refs/templates.md +230 -0
  518. package/skills/platform/github-actions/refs/troubleshooting.md +174 -0
  519. package/skills/platform/github-actions/scripts/workflow_gen.py +215 -0
  520. package/skills/platform/gitlab-ci/SKILL.md +140 -0
  521. package/skills/platform/gitlab-ci/refs/templates.md +223 -0
  522. package/skills/platform/gitlab-ci/refs/troubleshooting.md +213 -0
  523. package/skills/platform/glab-cli/SKILL.md +133 -0
  524. package/skills/platform/glab-cli/refs/ci-debugging.md +95 -0
  525. package/skills/platform/glab-cli/refs/glab-ops.md +78 -0
  526. package/skills/platform/glab-cli/refs/patterns.md +131 -0
  527. package/skills/platform/glab-cli/scripts/glab_ops.py +313 -0
  528. package/skills/platform/health/SKILL.md +177 -0
  529. package/skills/platform/health/refs/health.md +72 -0
  530. package/skills/platform/health/refs/sources.md +302 -0
  531. package/skills/platform/incident/refs/incident.md +136 -0
  532. package/skills/platform/infra/refs/infra.md +104 -0
  533. package/skills/platform/observability/SKILL.md +128 -0
  534. package/skills/platform/observability/refs/toolchain-discovery.md +243 -0
  535. package/skills/platform/prereq-doctor/SKILL.md +57 -0
  536. package/skills/platform/prereq-doctor/refs/tool-registry.md +58 -0
  537. package/skills/platform/traces/refs/traces.md +101 -0
  538. package/skills/product/acceptance-criteria/SKILL.md +193 -0
  539. package/skills/product/acceptance-criteria/refs/ac-anti-patterns.md +291 -0
  540. package/skills/product/acceptance-criteria/refs/ac-examples.md +277 -0
  541. package/skills/product/accessibility/SKILL.md +197 -0
  542. package/skills/product/accessibility/refs/aria-patterns-basics.md +250 -0
  543. package/skills/product/accessibility/refs/aria-patterns-dynamic.md +187 -0
  544. package/skills/product/accessibility/refs/aria-patterns-interactive.md +246 -0
  545. package/skills/product/accessibility/refs/audit-report-findings.md +248 -0
  546. package/skills/product/accessibility/refs/audit-report-results.md +276 -0
  547. package/skills/product/accessibility/refs/common-violations-html-css.md +270 -0
  548. package/skills/product/accessibility/refs/common-violations-interactive.md +303 -0
  549. package/skills/product/accessibility/refs/keyboard-testing-basics.md +222 -0
  550. package/skills/product/accessibility/refs/keyboard-testing-patterns.md +173 -0
  551. package/skills/product/accessibility/refs/screen-reader-testing-advanced.md +294 -0
  552. package/skills/product/accessibility/refs/screen-reader-testing-commands.md +255 -0
  553. package/skills/product/accessibility/refs/wcag-checklist.md +262 -0
  554. package/skills/product/analyze/SKILL.md +164 -0
  555. package/skills/product/analyze/refs/algorithms.md +238 -0
  556. package/skills/product/analyze/refs/sentiment-patterns.md +180 -0
  557. package/skills/product/imagery/SKILL.md +97 -0
  558. package/skills/product/imagery/alter/SKILL.md +105 -0
  559. package/skills/product/imagery/alter/refs/editing-reference.md +146 -0
  560. package/skills/product/imagery/create/SKILL.md +109 -0
  561. package/skills/product/imagery/create/refs/prompt-engineering.md +112 -0
  562. package/skills/product/imagery/create/refs/provider-reference.md +219 -0
  563. package/skills/product/imagery/review/SKILL.md +101 -0
  564. package/skills/product/imagery/review/refs/analysis-lenses.md +136 -0
  565. package/skills/product/imagery/review/refs/quality-gates.md +153 -0
  566. package/skills/product/imagery/scripts/analyze.sh +23 -0
  567. package/skills/product/imagery/scripts/edit.sh +14 -0
  568. package/skills/product/imagery/scripts/generate.sh +13 -0
  569. package/skills/product/imagery/scripts/provider.py +787 -0
  570. package/skills/product/listen/SKILL.md +175 -0
  571. package/skills/product/listen/refs/channels.md +220 -0
  572. package/skills/product/mockup/SKILL.md +106 -0
  573. package/skills/product/mockup/refs/templates.md +95 -0
  574. package/skills/product/refs/a11y.md +109 -0
  575. package/skills/product/refs/acceptance.md +79 -0
  576. package/skills/product/refs/align.md +67 -0
  577. package/skills/product/refs/analyze.md +77 -0
  578. package/skills/product/refs/elicit.md +67 -0
  579. package/skills/product/refs/listen.md +58 -0
  580. package/skills/product/refs/mockup.md +77 -0
  581. package/skills/product/refs/screenshot.md +59 -0
  582. package/skills/product/refs/strategy.md +77 -0
  583. package/skills/product/refs/synthesize.md +54 -0
  584. package/skills/product/refs/ux-review.md +68 -0
  585. package/skills/product/refs/ux.md +101 -0
  586. package/skills/product/requirements-analysis/SKILL.md +136 -0
  587. package/skills/product/requirements-analysis/refs/requirements-example-auth.md +264 -0
  588. package/skills/product/requirements-analysis/refs/requirements-example-export-integration.md +88 -0
  589. package/skills/product/requirements-analysis/refs/requirements-output-format-template.md +247 -0
  590. package/skills/product/requirements-analysis/refs/user-story-guide.md +296 -0
  591. package/skills/product/requirements-graph/SKILL.md +155 -0
  592. package/skills/product/requirements-graph/refs/examples.md +223 -0
  593. package/skills/product/requirements-graph/refs/schema.md +162 -0
  594. package/skills/product/requirements-migrate/SKILL.md +90 -0
  595. package/skills/product/requirements-navigate/SKILL.md +141 -0
  596. package/skills/product/requirements-navigate/refs/meta-templates.md +141 -0
  597. package/skills/product/screenshot/SKILL.md +147 -0
  598. package/skills/product/strategy/SKILL.md +198 -0
  599. package/skills/product/strategy/refs/frameworks.md +295 -0
  600. package/skills/product/strategy/refs/templates-competitive-market.md +299 -0
  601. package/skills/product/strategy/refs/templates-roi-value.md +207 -0
  602. package/skills/product/synthesize/SKILL.md +116 -0
  603. package/skills/product/synthesize/refs/journey-mapping.md +212 -0
  604. package/skills/product/synthesize/refs/prioritization.md +193 -0
  605. package/skills/product/ux-review/SKILL.md +164 -0
  606. package/skills/product/visual-direction/SKILL.md +137 -0
  607. package/skills/product/visual-review/SKILL.md +131 -0
  608. package/skills/runtime-exec/SKILL.md +138 -0
  609. package/skills/search/codebase-narrator/SKILL.md +131 -0
  610. package/skills/search/codebase-narrator/refs/output-template.md +100 -0
  611. package/skills/smaht/SKILL.md +72 -0
  612. package/skills/smaht/discovery/SKILL.md +65 -0
  613. package/skills/smaht/intent/SKILL.md +89 -0
  614. package/skills/smaht/propose-skills/SKILL.md +142 -0
  615. package/skills/smaht/refs/state.md +76 -0
  616. package/skills/swarm/SKILL.md +132 -0
  617. package/skills/swarm/refs/fan-out.md +104 -0
  618. package/skills/swarm/refs/independent-verification.md +86 -0
  619. package/skills/swarm/refs/receipts-and-evidence.md +69 -0
  620. package/skills/swarm/refs/recon-synthesis.md +87 -0
  621. package/skills/swarm/refs/ship-discipline.md +90 -0
  622. package/skills/wickedizer/SKILL.md +147 -0
  623. package/skills/wickedizer/refs/artifact-types.md +238 -0
  624. package/skills/wickedizer/refs/complexity.md +278 -0
  625. package/skills/wickedizer/refs/de-ai-pass.md +140 -0
  626. package/skills/wickedizer/refs/failure-modes.md +249 -0
  627. package/skills/wickedizer/refs/patterns.md +282 -0
  628. package/skills/wickedizer/refs/review.md +221 -0
  629. package/skills/wickedizer/refs/structure.md +282 -0
  630. package/skills/wickedizer/refs/voice-profile.md +125 -0
  631. package/skills/workflow/SKILL.md +132 -0
  632. package/skills/workflow/refs/archetype-adjustments.md +205 -0
  633. package/skills/workflow/refs/evidence.md +58 -0
  634. package/skills/workflow/refs/integration.md +130 -0
  635. package/skills/workflow/refs/risk-dimension-signals.md +260 -0
  636. package/skills/workflow/refs/scoring-rubric.md +49 -0
  637. package/skills/workflow/refs/signal-keywords.md +176 -0
  638. package/skills/workflow/refs/specialist-routing-rules.md +159 -0
  639. package/skills/worktrees/SKILL.md +87 -0
  640. package/skills/worktrees/refs/recipes.md +96 -0
@@ -0,0 +1,402 @@
1
+ #!/usr/bin/env python3
2
+ """invariants.py — the claim sentinel: state-transition gates without command lists.
3
+
4
+ The design problem (session-tested): steering that fires at *prompt time* ("this
5
+ is a build!") or as ambient tips gets ignored — the agent overrides even MUST
6
+ wording when local context says "irrelevant", and nothing records the skip. What
7
+ changes behavior is a check that fires **at the claim moment**, carries **observed
8
+ evidence**, names **one action**, and makes skipping a **recorded decision**.
9
+
10
+ And you can't catch claim moments by pattern-matching commands (`gh pr merge`,
11
+ raw `git push`, `glab`, an API curl, next year's tool…). You catch the state all
12
+ of them converge on:
13
+
14
+ - a **git ref moving** is the universal "ship it" (ref-watch, below);
15
+ - a **task completing** is the universal in-session "done" (TaskCompleted hook);
16
+ - the **session ending** is the last exit (info tier).
17
+
18
+ Each toolkit component already has one observable state-store, so every gate here
19
+ is an *invariant between two observable states* — never a command match:
20
+
21
+ invariant observable A observable B
22
+ ------------------------ ---------------------- -------------------------
23
+ done-claim has a verdict sentinel verdict ledger ref advance / task done
24
+ evidence is fresh .wicked-testing ledger mtime of modified files
25
+ learnings captured brain memory dir session activity
26
+ playbooks current repo-* skill dirs commits since their mtime
27
+
28
+ Tiers: info (one line, ignorable) → **answer** (the agent must act or the skip
29
+ is logged to the bus as `wicked.sentinel.*` — the skip becomes evidence) →
30
+ block (git pre-push / CI, outside this module). Everything here fails OPEN on
31
+ error (a broken sentinel must never break a session) but never invents an OK.
32
+
33
+ Stdlib-only. All git access via argv subprocess, short timeouts, throttled.
34
+ """
35
+
36
+ from __future__ import annotations
37
+
38
+ import hashlib
39
+ import json
40
+ import os
41
+ import re
42
+ import subprocess # noqa: S404 — argv lists only, shell=False
43
+ import time
44
+ from pathlib import Path
45
+ from typing import Any, Dict, List, Optional
46
+
47
+ _GIT_TIMEOUT = 5
48
+ _LEDGER_MAX_STAMPS = 200 # ledger read window (recent stamps only)
49
+ _RECENT_HISTORY = 80 # a verdict covers a sha within this many ancestors
50
+ _PLAYBOOK_STALE_COMMITS = 30 # repo-playbooks "drifted" threshold
51
+
52
+
53
+ # ---------------------------------------------------------------------------
54
+ # git plumbing (fail-open: None / {} on any error)
55
+ # ---------------------------------------------------------------------------
56
+
57
+ def _git(repo: Path, *args: str) -> Optional[str]:
58
+ try:
59
+ proc = subprocess.run( # noqa: S603 — argv list, shell=False
60
+ ["git", "-C", str(repo), *args],
61
+ capture_output=True, text=True, timeout=_GIT_TIMEOUT,
62
+ )
63
+ if proc.returncode != 0:
64
+ return None
65
+ return proc.stdout.strip()
66
+ except (OSError, subprocess.TimeoutExpired):
67
+ return None
68
+
69
+
70
+ def repo_toplevel(cwd: Optional[Path] = None) -> Optional[Path]:
71
+ top = _git(Path(cwd) if cwd else Path.cwd(), "rev-parse", "--show-toplevel")
72
+ return Path(top) if top else None
73
+
74
+
75
+ # ---------------------------------------------------------------------------
76
+ # The verdict ledger — stamped by the gate, read by every claim check.
77
+ # Keyed by repo toplevel (NOT cwd) so gate runs and hook checks agree even when
78
+ # they run from different directories of the same repo.
79
+ # ---------------------------------------------------------------------------
80
+
81
+ def _ledger_path(repo: Path) -> Path:
82
+ slug = hashlib.sha256(str(repo.resolve()).encode("utf-8")).hexdigest()[:12]
83
+ base = Path.home() / ".something-wicked" / "wicked-garden" / "sentinel"
84
+ base.mkdir(parents=True, exist_ok=True)
85
+ return base / f"{slug}.jsonl"
86
+
87
+
88
+ def stamp_verdict(repo: Path, *, overall: str, satisfied: bool,
89
+ re_derived: bool, scope: str = "", phase: str = "") -> None:
90
+ """Record a gate verdict for the repo's current HEAD. Called by the
91
+ produces-gate (vault_gate.gate_satisfied) — the single front door — so any
92
+ prove/gate run anywhere stamps the ledger. Fail-open."""
93
+ try:
94
+ sha = _git(repo, "rev-parse", "HEAD")
95
+ if not sha:
96
+ return
97
+ rec = {"sha": sha, "overall": overall, "satisfied": bool(satisfied),
98
+ "re_derived": bool(re_derived), "scope": scope, "phase": phase,
99
+ "ts": time.time()}
100
+ with _ledger_path(repo).open("a", encoding="utf-8") as fh:
101
+ fh.write(json.dumps(rec) + "\n")
102
+ except Exception: # noqa: BLE001 — sentinel must never break the gate
103
+ return
104
+
105
+
106
+ def _recent_stamps(repo: Path) -> List[Dict[str, Any]]:
107
+ try:
108
+ p = _ledger_path(repo)
109
+ if not p.exists():
110
+ return []
111
+ lines = p.read_text(encoding="utf-8").splitlines()[-_LEDGER_MAX_STAMPS:]
112
+ return [json.loads(ln) for ln in lines if ln.strip()]
113
+ except Exception: # noqa: BLE001
114
+ return []
115
+
116
+
117
+ def verdict_for(repo: Path, sha: Optional[str] = None) -> Optional[Dict[str, Any]]:
118
+ """The most recent satisfied+re-derived stamp covering `sha` (default HEAD):
119
+ the stamped commit must be the sha itself or one of its recent ancestors."""
120
+ target = sha or _git(repo, "rev-parse", "HEAD")
121
+ if not target:
122
+ return None
123
+ history = _git(repo, "rev-list", f"-{_RECENT_HISTORY}", target)
124
+ if history is None:
125
+ return None
126
+ recent = set(history.splitlines())
127
+ for rec in reversed(_recent_stamps(repo)):
128
+ if rec.get("sha") in recent and rec.get("satisfied") and rec.get("re_derived"):
129
+ return rec
130
+ return None
131
+
132
+
133
+ # ---------------------------------------------------------------------------
134
+ # Override / detection events → the bus (fire-and-forget; the skip is evidence)
135
+ # ---------------------------------------------------------------------------
136
+
137
+ def log_sentinel_event(repo: Path, event: str, detail: Dict[str, Any]) -> None:
138
+ """Emit wicked.sentinel.<event> to the bus if available; always append to a
139
+ local trail so the record exists even without the bus layer."""
140
+ payload = {"repo": str(repo), "ts": time.time(), **detail}
141
+ try:
142
+ trail = _ledger_path(repo).with_suffix(".events.jsonl")
143
+ with trail.open("a", encoding="utf-8") as fh:
144
+ fh.write(json.dumps({"event": event, **payload}) + "\n")
145
+ except Exception: # noqa: BLE001
146
+ pass
147
+ try:
148
+ import sys
149
+ plugin_scripts = Path(__file__).resolve().parents[1]
150
+ if str(plugin_scripts) not in sys.path:
151
+ sys.path.insert(0, str(plugin_scripts))
152
+ from _bus import emit_event # type: ignore
153
+ emit_event(f"wicked.sentinel.{event}", payload)
154
+ except Exception: # noqa: BLE001 — bus is an opt-in layer; fail open
155
+ pass
156
+
157
+
158
+ # ---------------------------------------------------------------------------
159
+ # Invariant 1 — claim-gate (answer tier): a done/passing CLAIM must have a
160
+ # verdict. Fires at the Stop boundary, and only when the turn's final message
161
+ # actually asserts done/passing/shipped — never as a side effect of a tool
162
+ # call. Ship/publish protection (an actual push to main or a tag) is the BLOCK
163
+ # tier (pre_push.py + CI); this is the harness backstop nudge.
164
+ #
165
+ # History: this replaced a PostToolUse ref-watch that keyed off git-ref state
166
+ # (origin default branch + newest tag advancing) with no claim check, wired to
167
+ # a blanket Bash matcher — so any Bash call (git log, cat, find) during pure
168
+ # planning tripped "the claim sentinel that never checked for a claim".
169
+ # ---------------------------------------------------------------------------
170
+
171
+ # Verification-completion phrases. Deliberately conservative — the failure mode
172
+ # being fixed is OVER-firing, so we match explicit verification/publish
173
+ # assertions, not bare "done" (too common in progress chatter).
174
+ _CLAIM_PATTERNS = (
175
+ r"\btests?\s+(?:all\s+)?(?:pass|passing|passes|passed)\b",
176
+ r"\ball\s+tests?\s+(?:are\s+)?(?:pass|passing|green)",
177
+ r"\ball\s+green\b",
178
+ r"\ball\s+checks?\s+(?:pass|passing|green)",
179
+ r"\bbuild\s+(?:is\s+)?clean\b",
180
+ r"\bready\s+to\s+(?:merge|ship)\b",
181
+ r"\bshipped\b",
182
+ r"\bship(?:ping)?\s+it\b",
183
+ r"\bit\s+works\b",
184
+ r"\bverified\b",
185
+ )
186
+ _CLAIM_RE = re.compile("|".join(_CLAIM_PATTERNS), re.IGNORECASE)
187
+
188
+
189
+ def is_done_claim(text: Optional[str]) -> bool:
190
+ """True iff `text` asserts verified completion / shipping — a 'done' claim.
191
+ Conservative by design (matches explicit verification/publish phrases, not
192
+ bare 'done') so planning and progress chatter never trip the sentinel."""
193
+ if not text:
194
+ return False
195
+ return bool(_CLAIM_RE.search(text))
196
+
197
+
198
+ def claim_tick(state_get, state_set, *, final_message: Optional[str],
199
+ cwd: Optional[Path] = None) -> Optional[Dict[str, Any]]:
200
+ """Stop-hook entry point. Fires ONLY when the turn's final assistant message
201
+ asserts done/passing/shipped (is_done_claim) AND the repo HEAD has no
202
+ re-derived verdict. Debounced once per unproven sha per session. Fail-open.
203
+
204
+ `state_get(key)`/`state_set(key, value)` wrap SessionState so this module
205
+ stays import-light."""
206
+ try:
207
+ if not is_done_claim(final_message):
208
+ return None
209
+ repo = repo_toplevel(cwd)
210
+ if repo is None:
211
+ return None
212
+ head = _git(repo, "rev-parse", "HEAD")
213
+ if not head:
214
+ return None
215
+ if verdict_for(repo, head): # a re-derived verdict covers HEAD — suppress
216
+ return None
217
+ if state_get("sentinel_claim_sha") == head: # debounce: once per sha/session
218
+ return None
219
+ state_set("sentinel_claim_sha", head)
220
+ violation = {
221
+ "tier": "answer",
222
+ "invariant": "done-claim-verdict",
223
+ "evidence": (f"a done/passing claim was made but HEAD {head[:9]} has no "
224
+ "re-derived verdict on record"),
225
+ "action": ("Run `/wicked-garden:prove` to re-derive the claim now, or state "
226
+ "the override reason — the claim is logged either way."),
227
+ }
228
+ log_sentinel_event(repo, "unverified_claim",
229
+ {"sha": head, "invariant": "done-claim-verdict"})
230
+ return violation
231
+ except Exception: # noqa: BLE001 — sentinel never breaks a hook
232
+ return None
233
+
234
+
235
+ # ---------------------------------------------------------------------------
236
+ # Invariant 2 — evidence freshness: a claim is stale when source moved after
237
+ # the newest recorded evidence. Applies only when the testing layer is present.
238
+ # ---------------------------------------------------------------------------
239
+
240
+ def _newest_evidence_ts(repo: Path) -> Optional[float]:
241
+ root = repo / ".wicked-testing"
242
+ if not root.is_dir():
243
+ return None
244
+ newest = 0.0
245
+ try:
246
+ for p in root.rglob("*"):
247
+ if p.is_file():
248
+ ts = p.stat().st_mtime
249
+ if ts > newest:
250
+ newest = ts
251
+ except OSError:
252
+ return None
253
+ return newest or None
254
+
255
+
256
+ def check_evidence_freshness(repo: Path) -> Optional[Dict[str, Any]]:
257
+ """Answer-tier (only when .wicked-testing exists). Modified-but-uncommitted /
258
+ just-committed files newer than the newest evidence record = stale claim."""
259
+ newest_evidence = _newest_evidence_ts(repo)
260
+ if newest_evidence is None:
261
+ return None # testing layer absent or no runs — not applicable
262
+ changed = _git(repo, "diff", "--name-only", "HEAD")
263
+ if changed is None:
264
+ return None
265
+ paths = [repo / ln for ln in changed.splitlines() if ln.strip()]
266
+ newest_src = 0.0
267
+ for p in paths:
268
+ try:
269
+ ts = p.stat().st_mtime
270
+ if ts > newest_src:
271
+ newest_src = ts
272
+ except OSError:
273
+ continue
274
+ if newest_src <= newest_evidence:
275
+ return None
276
+ age_min = (newest_src - newest_evidence) / 60
277
+ return {
278
+ "tier": "answer",
279
+ "invariant": "evidence-freshness",
280
+ "evidence": (f"source files changed {age_min:.0f}m after the newest "
281
+ f".wicked-testing evidence — the recorded runs predate this work"),
282
+ "action": "Re-run the relevant scenario (/wicked-testing:execution) or state why the evidence still holds.",
283
+ }
284
+
285
+
286
+ # ---------------------------------------------------------------------------
287
+ # Invariant 3+4+5 — session-end info tier (one line each, never blocking)
288
+ # ---------------------------------------------------------------------------
289
+
290
+ def _brain_memory_dir(repo: Path) -> Optional[Path]:
291
+ projects = Path.home() / ".wicked-brain" / "projects"
292
+ if not projects.is_dir():
293
+ return None
294
+ try:
295
+ for proj in projects.iterdir():
296
+ cfg = proj / "_meta" / "config.json"
297
+ if cfg.is_file():
298
+ try:
299
+ src = json.loads(cfg.read_text(encoding="utf-8")).get("source_path", "")
300
+ if src and Path(src).resolve() == repo.resolve():
301
+ mem = proj / "memory"
302
+ return mem if mem.is_dir() else None
303
+ except (json.JSONDecodeError, OSError):
304
+ continue
305
+ except OSError:
306
+ return None
307
+ return None
308
+
309
+
310
+ def check_session_capture(repo: Path, session_start_ts: float,
311
+ activity_count: int) -> Optional[Dict[str, Any]]:
312
+ """Info-tier: a significant session (>= 10 tracked activities) that captured
313
+ zero brain memories. Only applies when the brain layer is present."""
314
+ if activity_count < 10:
315
+ return None
316
+ mem = _brain_memory_dir(repo)
317
+ if mem is None:
318
+ return None # brain layer absent for this repo — not applicable
319
+ try:
320
+ wrote = any(p.stat().st_mtime >= session_start_ts
321
+ for p in mem.glob("*.md"))
322
+ except OSError:
323
+ return None
324
+ if wrote:
325
+ return None
326
+ return {
327
+ "tier": "info",
328
+ "invariant": "session-capture",
329
+ "evidence": f"{activity_count} tracked activities this session, 0 memories captured",
330
+ "action": "Worth one `wicked-brain:memory` store (decision/gotcha) before you go?",
331
+ }
332
+
333
+
334
+ def check_playbook_freshness(repo: Path) -> Optional[Dict[str, Any]]:
335
+ """Info-tier: wicked-understanding playbooks exist but the repo has moved
336
+ well past them (commits since their newest mtime > threshold)."""
337
+ roots = [Path.home() / ".claude" / "skills"]
338
+ cfg = os.environ.get("CLAUDE_CONFIG_DIR")
339
+ if cfg:
340
+ roots.append(Path(cfg) / "skills")
341
+ newest = 0.0
342
+ for root in roots:
343
+ try:
344
+ if root.is_dir():
345
+ for entry in root.iterdir():
346
+ if entry.is_dir() and entry.name.startswith(("repo-", "fix-bug", "add-feature")):
347
+ ts = entry.stat().st_mtime
348
+ if ts > newest:
349
+ newest = ts
350
+ except OSError:
351
+ continue
352
+ if not newest:
353
+ return None # understanding layer absent — not applicable
354
+ iso = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime(newest))
355
+ count = _git(repo, "rev-list", "--count", f"--since={iso}", "HEAD")
356
+ try:
357
+ behind = int(count) if count else 0
358
+ except ValueError:
359
+ return None
360
+ if behind < _PLAYBOOK_STALE_COMMITS:
361
+ return None
362
+ return {
363
+ "tier": "info",
364
+ "invariant": "playbook-freshness",
365
+ "evidence": f"repo playbooks were generated ~{behind} commits ago",
366
+ "action": "Re-run `repo-analyst` so the how-to playbooks track HEAD.",
367
+ }
368
+
369
+
370
+ def session_end_lines(cwd: Optional[Path], session_start_ts: float,
371
+ activity_count: int) -> List[str]:
372
+ """The Stop/SessionEnd bundle — info-tier lines only, each fail-open."""
373
+ repo = repo_toplevel(cwd)
374
+ if repo is None:
375
+ return []
376
+ lines: List[str] = []
377
+ for check in (lambda: check_session_capture(repo, session_start_ts, activity_count),
378
+ lambda: check_playbook_freshness(repo)):
379
+ try:
380
+ v = check()
381
+ except Exception: # noqa: BLE001
382
+ v = None
383
+ if v:
384
+ lines.append(f"[Sentinel:{v['invariant']}] {v['evidence']} → {v['action']}")
385
+ return lines
386
+
387
+
388
+ # ---------------------------------------------------------------------------
389
+ # Rendering — one consistent voice for the answer tier
390
+ # ---------------------------------------------------------------------------
391
+
392
+ def render(violation: Dict[str, Any]) -> str:
393
+ return (f"[Sentinel:{violation['invariant']}] {violation['evidence']}.\n"
394
+ f"→ {violation['action']}")
395
+
396
+
397
+ __all__ = [
398
+ "repo_toplevel", "stamp_verdict", "verdict_for", "log_sentinel_event",
399
+ "is_done_claim", "claim_tick",
400
+ "check_evidence_freshness", "check_session_capture",
401
+ "check_playbook_freshness", "session_end_lines", "render",
402
+ ]
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env python3
2
+ """pre_push.py — the claim sentinel's local pre-push gate (layer 1 of 3).
3
+
4
+ Reads git's pre-push stdin ("<local_ref> <local_sha> <remote_ref> <remote_sha>"
5
+ per line) and BLOCKS (exit 1) when a *publish-shaped* ref — the remote default
6
+ branch or any tag — is being pushed with no re-derived verdict covering the
7
+ pushed sha on the sentinel ledger. Feature-branch pushes always pass: the claim
8
+ moment is publishing "done", not sharing work-in-progress.
9
+
10
+ Layers (see scripts/sentinel/invariants.py):
11
+ 1. this hook — local, fires for ANY tool that pushes through git
12
+ 2. required CI check — server-side, catches gh-pr-merge/web/API paths
13
+ 3. harness ref-watch — detects + records what slipped past both
14
+
15
+ Override: `git push --no-verify` (git's own explicit skip — visible, and the
16
+ server layer still gates). Fail-open on machinery errors: a broken sentinel
17
+ must never brick pushes; only a *present ledger with no verdict* blocks.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import sys
23
+ from pathlib import Path
24
+
25
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
26
+ from invariants import log_sentinel_event, repo_toplevel, verdict_for # noqa: E402
27
+
28
+ _ZERO_SHA = "0" * 40
29
+ _DEFAULT_BRANCH_REFS = ("refs/heads/main", "refs/heads/master")
30
+
31
+
32
+ def _publish_shaped(remote_ref: str) -> bool:
33
+ return remote_ref in _DEFAULT_BRANCH_REFS or remote_ref.startswith("refs/tags/")
34
+
35
+
36
+ def main() -> int:
37
+ try:
38
+ repo = repo_toplevel()
39
+ if repo is None:
40
+ return 0 # not a repo — nothing to gate
41
+ blocked = []
42
+ for line in sys.stdin.read().splitlines():
43
+ parts = line.split()
44
+ if len(parts) != 4:
45
+ continue
46
+ _local_ref, local_sha, remote_ref, _remote_sha = parts
47
+ if local_sha == _ZERO_SHA: # deletion — not a done-claim
48
+ continue
49
+ if not _publish_shaped(remote_ref):
50
+ continue
51
+ if verdict_for(repo, local_sha) is None:
52
+ blocked.append((remote_ref, local_sha))
53
+ if not blocked:
54
+ return 0
55
+ for remote_ref, sha in blocked:
56
+ print(
57
+ f"[Sentinel:done-claim-verdict] pushing {remote_ref} @ {sha[:9]} "
58
+ "with no re-derived verdict on record.\n"
59
+ "→ Run `/wicked-garden:prove` (stamps the ledger via the gate), "
60
+ "or override deliberately with `git push --no-verify` — the server "
61
+ "gate still applies.",
62
+ file=sys.stderr,
63
+ )
64
+ log_sentinel_event(repo, "prepush_blocked",
65
+ {"ref": remote_ref, "sha": sha,
66
+ "invariant": "done-claim-verdict"})
67
+ return 1
68
+ except Exception: # noqa: BLE001 — machinery failure must not brick pushes
69
+ return 0
70
+
71
+
72
+ if __name__ == "__main__":
73
+ sys.exit(main())
@@ -0,0 +1 @@
1
+ """Setup helpers for /wicked-garden:setup. Stdlib-only."""
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env python3
2
+ """detect_state.py — environment + config detection for /wicked-garden:setup.
3
+
4
+ Pure-function probes that the slash command would otherwise inline as
5
+ ad-hoc Python. Each subcommand prints a single JSON object so the
6
+ markdown body can `jq` or read raw.
7
+
8
+ Stdlib-only.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import argparse
14
+ import json
15
+ import os
16
+ import sys
17
+ from pathlib import Path
18
+
19
+ _SCRIPTS_ROOT = Path(__file__).resolve().parents[1]
20
+ sys.path.insert(0, str(_SCRIPTS_ROOT))
21
+
22
+
23
+ def detect_question_mode() -> str:
24
+ """Return ``'PLAIN_TEXT'`` if dangerous mode is active, else ``'INTERACTIVE'``.
25
+
26
+ The slash command branches between AskUserQuestion and numbered-list
27
+ prompts on this value.
28
+ """
29
+ try:
30
+ from _session import SessionState # type: ignore
31
+ except Exception:
32
+ return "INTERACTIVE"
33
+ try:
34
+ state = SessionState.load()
35
+ except Exception:
36
+ return "INTERACTIVE"
37
+ return "PLAIN_TEXT" if getattr(state, "dangerous_mode", False) else "INTERACTIVE"
38
+
39
+
40
+ def read_config() -> dict:
41
+ """Read ``~/.something-wicked/wicked-garden/config.json`` if present."""
42
+ path = Path.home() / ".something-wicked" / "wicked-garden" / "config.json"
43
+ if not path.exists():
44
+ return {"present": False, "path": str(path)}
45
+ try:
46
+ data = json.loads(path.read_text(encoding="utf-8"))
47
+ except (OSError, json.JSONDecodeError) as exc:
48
+ return {"present": True, "path": str(path), "error": str(exc)}
49
+ return {"present": True, "path": str(path), "config": data}
50
+
51
+
52
+ # Marker files used to fingerprint the working directory.
53
+ _LANGUAGE_MARKERS: dict[str, list[str]] = {
54
+ "Python": ["pyproject.toml", "setup.py", "requirements.txt", "Pipfile"],
55
+ "Node/TypeScript": ["package.json", "tsconfig.json"],
56
+ "Go": ["go.mod"],
57
+ "Rust": ["Cargo.toml"],
58
+ "Java/Kotlin": ["pom.xml", "build.gradle", "build.gradle.kts"],
59
+ "Ruby": ["Gemfile"],
60
+ "PHP": ["composer.json"],
61
+ "Swift": ["Package.swift"],
62
+ "C/C++": ["CMakeLists.txt", "Makefile"],
63
+ }
64
+
65
+ _FRAMEWORK_MARKERS: dict[str, list[str]] = {
66
+ "FastAPI": ["app/main.py", "main.py"],
67
+ "Django": ["manage.py"],
68
+ "Flask": ["app.py"],
69
+ "Next.js": ["next.config.js", "next.config.ts"],
70
+ "React": ["src/App.tsx", "src/App.jsx"],
71
+ "Vue": ["vue.config.js"],
72
+ "Rails": ["config/routes.rb"],
73
+ "Claude Plugin": [".claude-plugin/plugin.json"],
74
+ }
75
+
76
+
77
+ def detect_project_env(cwd: Path | None = None) -> dict:
78
+ """Detect languages and frameworks in ``cwd`` (defaults to CWD)."""
79
+ root = (cwd or Path.cwd()).resolve()
80
+ languages = [
81
+ name
82
+ for name, files in _LANGUAGE_MARKERS.items()
83
+ if any((root / f).exists() for f in files)
84
+ ]
85
+ frameworks = [
86
+ name
87
+ for name, files in _FRAMEWORK_MARKERS.items()
88
+ if any((root / f).exists() for f in files)
89
+ ]
90
+ return {"cwd": str(root), "languages": languages, "frameworks": frameworks}
91
+
92
+
93
+ def _cli() -> int:
94
+ parser = argparse.ArgumentParser(description=__doc__)
95
+ sub = parser.add_subparsers(dest="cmd", required=True)
96
+ sub.add_parser("question-mode", help="INTERACTIVE | PLAIN_TEXT")
97
+ sub.add_parser("config", help="Show wicked-garden config.json contents")
98
+ env = sub.add_parser("project-env", help="Detect languages + frameworks in CWD")
99
+ env.add_argument("--cwd", default=None)
100
+ args = parser.parse_args()
101
+ if args.cmd == "question-mode":
102
+ sys.stdout.write(detect_question_mode() + "\n")
103
+ elif args.cmd == "config":
104
+ json.dump(read_config(), sys.stdout, indent=2)
105
+ sys.stdout.write("\n")
106
+ elif args.cmd == "project-env":
107
+ cwd = Path(args.cwd) if args.cwd else None
108
+ json.dump(detect_project_env(cwd), sys.stdout, indent=2)
109
+ sys.stdout.write("\n")
110
+ return 0
111
+
112
+
113
+ if __name__ == "__main__":
114
+ sys.exit(_cli())
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env python3
2
+ """migrate_legacy.py — legacy reference scans for /wicked-garden:setup.
3
+
4
+ Section 2.6 of the setup command needs to scan crew project directories
5
+ for legacy ``qe-evaluator`` strings in reeval and amendment logs. The
6
+ scan was inlined in markdown; this module exposes it as a callable +
7
+ CLI so the command body can stay slim.
8
+
9
+ Stdlib-only.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import argparse
15
+ import json
16
+ import sys
17
+ from pathlib import Path
18
+
19
+ _LEGACY_PATTERNS = (
20
+ '"reviewer": "qe-evaluator"',
21
+ '"trigger": "qe-evaluator:',
22
+ )
23
+ _TARGET_GLOBS = (
24
+ "phases/*/reeval-log.jsonl",
25
+ "phases/*/amendments.jsonl",
26
+ )
27
+
28
+
29
+ def scan_qe_evaluator_refs(projects_root: Path | None = None) -> list[str]:
30
+ """Return the list of files that still contain legacy qe-evaluator refs."""
31
+ root = projects_root or (
32
+ Path.home() / ".something-wicked" / "wicked-garden" / "projects"
33
+ )
34
+ found: list[str] = []
35
+ if not root.exists():
36
+ return found
37
+ for pattern in _TARGET_GLOBS:
38
+ for f in root.glob("*/" + pattern):
39
+ try:
40
+ text = f.read_text(encoding="utf-8")
41
+ except OSError:
42
+ continue
43
+ if any(p in text for p in _LEGACY_PATTERNS):
44
+ found.append(str(f))
45
+ return found
46
+
47
+
48
+ def _cli() -> int:
49
+ parser = argparse.ArgumentParser(description=__doc__)
50
+ parser.add_argument("--projects-root", default=None)
51
+ parser.add_argument("--json", action="store_true", help="Emit JSON instead of human text")
52
+ args = parser.parse_args()
53
+ root = Path(args.projects_root) if args.projects_root else None
54
+ found = scan_qe_evaluator_refs(root)
55
+ if args.json:
56
+ json.dump({"status": "LEGACY_FOUND" if found else "CLEAN", "files": found},
57
+ sys.stdout, indent=2)
58
+ sys.stdout.write("\n")
59
+ else:
60
+ sys.stdout.write("LEGACY_FOUND\n" if found else "CLEAN\n")
61
+ for path in found:
62
+ sys.stdout.write(path + "\n")
63
+ return 0
64
+
65
+
66
+ if __name__ == "__main__":
67
+ sys.exit(_cli())