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,624 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Stop hook — wicked-garden unified session teardown (async, 30s timeout).
4
+
5
+ Consolidates: crew stop, mem stop, session-end fact emission.
6
+
7
+ Flow:
8
+ 1. Session outcome check (mismatch report from auto_issue_reporter state)
9
+ 2. Automatic memory promotion from native tasks (session_fact_extractor)
10
+ 3. Working-tier consolidation via brain compile + lint
11
+ 4. Memory decay maintenance
12
+ 5. Persist final SessionState
13
+ 6. Event store retention purge
14
+ 7. Emit memory flush reminder directive
15
+
16
+ Always fails open — any unhandled exception returns {"systemMessage": ...}.
17
+ Runs async so it does NOT block the user on exit.
18
+ """
19
+
20
+ import json
21
+ import os
22
+ import sys
23
+ import time
24
+ from pathlib import Path
25
+ from typing import Optional
26
+
27
+ # Add shared scripts directory to path
28
+ _PLUGIN_ROOT = Path(os.environ.get("CLAUDE_PLUGIN_ROOT", Path(__file__).resolve().parents[2]))
29
+ sys.path.insert(0, str(_PLUGIN_ROOT / "scripts"))
30
+
31
+ def _resolve_brain_port():
32
+ try:
33
+ from _brain_port import resolve_port
34
+ return resolve_port()
35
+ except Exception:
36
+ return int(os.environ.get("WICKED_BRAIN_PORT", "4242"))
37
+
38
+ # ---------------------------------------------------------------------------
39
+ # Ops logger wrapper — fail-silent, never crashes the hook
40
+ # ---------------------------------------------------------------------------
41
+
42
+ def _log(domain, level, event, ok=True, ms=None, detail=None):
43
+ """Ops logger — fail-silent, never crashes the hook."""
44
+ try:
45
+ from _logger import log
46
+ log(domain, level, event, ok=ok, ms=ms, detail=detail)
47
+ except Exception:
48
+ pass
49
+
50
+
51
+ # ---------------------------------------------------------------------------
52
+ # Helpers
53
+ # ---------------------------------------------------------------------------
54
+
55
+ def _get_session_id() -> str:
56
+ raw = os.environ.get("CLAUDE_SESSION_ID", "default")
57
+ return raw.replace("/", "_").replace("\\", "_").replace("..", "_")
58
+
59
+
60
+ def _session_dir(subdir: str) -> Path:
61
+ tmpdir = (os.environ.get("TMPDIR") or __import__("tempfile").gettempdir()).rstrip("/")
62
+ return Path(tmpdir) / subdir / _get_session_id()
63
+
64
+
65
+ # ---------------------------------------------------------------------------
66
+ # Claim sentinel (answer tier) — claim-gated at the Stop boundary.
67
+ # Replaces the old PostToolUse ref-watch that fired on every Bash call. Reads
68
+ # the turn's final assistant message from the transcript; only a real
69
+ # done/passing/shipped claim with no verdict for HEAD produces a nudge.
70
+ # ---------------------------------------------------------------------------
71
+
72
+ def _extract_text(content) -> Optional[str]:
73
+ """Pull concatenated text from a transcript message's `content` — either a
74
+ raw string or a list of {type:'text', text:...} blocks."""
75
+ if isinstance(content, str):
76
+ return content or None
77
+ if isinstance(content, list):
78
+ parts = [b["text"] for b in content
79
+ if isinstance(b, dict) and b.get("type") == "text" and b.get("text")]
80
+ return "\n".join(parts) if parts else None
81
+ return None
82
+
83
+
84
+ def _read_final_assistant_text(transcript_path: str) -> Optional[str]:
85
+ """Return the text of the LAST assistant message in the transcript JSONL,
86
+ or None. Fail-open — any read/parse error yields None (no claim => no fire)."""
87
+ try:
88
+ p = Path(transcript_path)
89
+ if not p.is_file():
90
+ return None
91
+ last = None
92
+ for line in p.read_text(encoding="utf-8", errors="ignore").splitlines():
93
+ line = line.strip()
94
+ if not line:
95
+ continue
96
+ try:
97
+ rec = json.loads(line)
98
+ except (json.JSONDecodeError, ValueError):
99
+ continue
100
+ if not isinstance(rec, dict):
101
+ continue
102
+ msg = rec.get("message") if isinstance(rec.get("message"), dict) else None
103
+ role = (msg or {}).get("role") or rec.get("role") or rec.get("type")
104
+ if role != "assistant":
105
+ continue
106
+ text = _extract_text((msg or {}).get("content", rec.get("content")))
107
+ if text:
108
+ last = text
109
+ return last
110
+ except Exception:
111
+ return None
112
+
113
+
114
+ def _check_claim_sentinel(input_data: dict) -> list:
115
+ """If the turn's final assistant message asserts done/passing/shipped and
116
+ HEAD has no re-derived verdict, return a one-line nudge (debounced per sha
117
+ per session via SessionState). Fail-open — never breaks Stop."""
118
+ try:
119
+ transcript = input_data.get("transcript_path")
120
+ final_text = _read_final_assistant_text(transcript) if transcript else None
121
+ if not final_text:
122
+ return []
123
+ sys.path.insert(0, str(_PLUGIN_ROOT / "scripts" / "sentinel"))
124
+ from invariants import claim_tick, render # type: ignore
125
+ from _session import SessionState
126
+ state = SessionState.load()
127
+ cwd = input_data.get("cwd")
128
+ violation = claim_tick(
129
+ lambda k: getattr(state, k, None),
130
+ lambda k, v: state.update(**{k: v}),
131
+ final_message=final_text,
132
+ cwd=Path(cwd) if cwd else None,
133
+ )
134
+ return [render(violation)] if violation else []
135
+ except Exception:
136
+ return []
137
+
138
+
139
+ # ---------------------------------------------------------------------------
140
+ # Step 1: Session outcome check
141
+ # ---------------------------------------------------------------------------
142
+
143
+ def _check_session_outcome() -> list:
144
+ """Return a list of outcome messages from the issue reporter state.
145
+
146
+ v9.2.12: Pre-fix, this function emitted the [Issue Reporter] banner on
147
+ EVERY Stop hook (i.e. every model response) as long as pending_issues.jsonl
148
+ or mismatches.jsonl had any content. Users saw the same banner re-fire
149
+ every turn until the issues were filed — chronic noise. The change-gated
150
+ latches (last_outcome_pending_count / last_outcome_mismatch_count on
151
+ SessionState) suppress re-emission unless the count has actually grown
152
+ since the previous emission. The first emission per session ALWAYS fires
153
+ (compares against default 0). Subsequent emissions only fire when new
154
+ issues / mismatches accumulate.
155
+ """
156
+ messages = []
157
+ try:
158
+ # Latch state — fail-open if SessionState is unreachable.
159
+ try:
160
+ from _session import SessionState
161
+ session_state = SessionState.load()
162
+ except Exception:
163
+ session_state = None
164
+
165
+ sdir = _session_dir("wicked-issue-reporter")
166
+ pending_file = sdir / "pending_issues.jsonl"
167
+ mismatches_file = sdir / "mismatches.jsonl"
168
+
169
+ # Count pending issues
170
+ if pending_file.exists():
171
+ lines = [l.strip() for l in pending_file.read_text().splitlines() if l.strip()]
172
+ count = len(lines)
173
+ last_count = (
174
+ int(getattr(session_state, "last_outcome_pending_count", 0) or 0)
175
+ if session_state else 0
176
+ )
177
+ if count and count > last_count:
178
+ messages.append(
179
+ f"[Issue Reporter] {count} issue(s) queued this session. "
180
+ "Review with /wicked-garden:report-issue --list-unfiled."
181
+ )
182
+ if session_state is not None:
183
+ session_state.update(last_outcome_pending_count=count)
184
+
185
+ # Count task mismatches
186
+ if mismatches_file.exists():
187
+ lines = [l.strip() for l in mismatches_file.read_text().splitlines() if l.strip()]
188
+ count = len(lines)
189
+ last_count = (
190
+ int(getattr(session_state, "last_outcome_mismatch_count", 0) or 0)
191
+ if session_state else 0
192
+ )
193
+ if count and count > last_count:
194
+ signals = []
195
+ for line in lines[:3]:
196
+ try:
197
+ record = json.loads(line)
198
+ # Sanitize subject — strip control chars, truncate
199
+ subj = record.get("subject", "?")[:60]
200
+ subj = "".join(c for c in subj if c.isprintable())
201
+ signals.append(subj)
202
+ except (json.JSONDecodeError, ValueError):
203
+ pass
204
+ messages.append(
205
+ f"[Issue Reporter] {count} task completion mismatch(es) detected: "
206
+ + "; ".join(signals)
207
+ )
208
+ if session_state is not None:
209
+ session_state.update(last_outcome_mismatch_count=count)
210
+ except Exception:
211
+ pass
212
+ return messages
213
+
214
+
215
+
216
+
217
+ # ---------------------------------------------------------------------------
218
+ # Step 2b: Session-end fact emission → wicked-brain auto-memorize
219
+ # ---------------------------------------------------------------------------
220
+ #
221
+ # v6: Session facts are extracted from native Claude tasks
222
+ # (${CLAUDE_CONFIG_DIR:-~/.claude}/tasks/{session_id}/*.json) by
223
+ # scripts/mem/session_fact_extractor.py. This replaces the v5 smaht
224
+ # FactExtractor/HistoryCondenser pipeline deleted in Gate 4 Phase 2 (#428).
225
+ # Emission shape is unchanged: wicked.fact.extracted events on wicked-bus,
226
+ # picked up by wicked-brain's auto-memorize subscriber, which re-applies its
227
+ # own type/length/dedup policy.
228
+
229
+ # Fact types eligible for emission — mirrors brain's auto-memorize policy.
230
+ # Brain will re-check these; this pre-filter keeps bus traffic sensible.
231
+ _EMITTABLE_FACT_TYPES = frozenset({"decision", "discovery"})
232
+ _MIN_FACT_CONTENT_LENGTH = 15
233
+
234
+
235
+ def _run_memory_promotion(session_id: str) -> list:
236
+ """Emit high-value session facts as wicked.fact.extracted events on wicked-bus.
237
+
238
+ Reads native task records (TaskCreate/TaskUpdate output) via
239
+ scripts/mem/session_fact_extractor.py, filters to decisions + discoveries
240
+ over the length threshold, and emits one event per fact. Brain's
241
+ auto-memorize subscriber handles persistence asynchronously.
242
+
243
+ Returns a list of message strings (empty when nothing was emitted or the
244
+ bus is unavailable). Always fails open — exceptions are caught and logged
245
+ to stderr.
246
+ """
247
+ try:
248
+ # scripts/ is on sys.path via the hook bootstrap; _brain_ingest is a
249
+ # package under scripts/ so the qualified import resolves without any
250
+ # additional sys.path manipulation.
251
+ from _brain_ingest.session_fact_extractor import extract_session_facts
252
+ from _bus import emit_event
253
+
254
+ facts = extract_session_facts(session_id, limit=20)
255
+ if not facts:
256
+ if os.environ.get("WICKED_DEBUG"):
257
+ print(
258
+ f"[wicked-garden] fact emit: no promotable facts in session {session_id}",
259
+ file=sys.stderr,
260
+ )
261
+ return []
262
+
263
+ emitted = 0
264
+ for fact in facts:
265
+ if fact.type not in _EMITTABLE_FACT_TYPES:
266
+ continue
267
+ if len(fact.content) < _MIN_FACT_CONTENT_LENGTH:
268
+ continue
269
+ emit_event(
270
+ "wicked.fact.extracted",
271
+ {
272
+ "type": fact.type,
273
+ "content": fact.content,
274
+ "entities": list(fact.entities)[:5] if fact.entities else [],
275
+ "source": fact.source or "task",
276
+ "session_id": session_id,
277
+ },
278
+ )
279
+ emitted += 1
280
+
281
+ if emitted == 0:
282
+ return []
283
+ return [f"[Memory] Emitted {emitted} fact event(s); wicked-brain will auto-memorize eligible ones."]
284
+
285
+ except Exception as e:
286
+ print(f"[wicked-garden] fact emit error: {e}", file=sys.stderr)
287
+ return []
288
+
289
+
290
+ # ---------------------------------------------------------------------------
291
+ # Step 2 & 3: Memory flush reminder + decay
292
+ # ---------------------------------------------------------------------------
293
+
294
+ def _brain_api(action, params=None, timeout=3):
295
+ """Call brain API. Returns parsed JSON or None."""
296
+ try:
297
+ import urllib.request
298
+ port = _resolve_brain_port()
299
+ payload = json.dumps({"action": action, "params": params or {}}).encode("utf-8")
300
+ req = urllib.request.Request(
301
+ f"http://localhost:{port}/api",
302
+ data=payload,
303
+ headers={"Content-Type": "application/json"},
304
+ method="POST",
305
+ )
306
+ with urllib.request.urlopen(req, timeout=timeout) as resp:
307
+ return json.loads(resp.read().decode("utf-8"))
308
+ except Exception:
309
+ return None
310
+
311
+
312
+ def _run_memory_decay() -> list:
313
+ """Run decay maintenance via brain lint API. Return list of result message strings."""
314
+ messages = []
315
+ try:
316
+ # Session-end maintenance writes — auto-start the server so a stopped
317
+ # server doesn't silently skip decay (fail-open, lock-safe, one
318
+ # spawn attempt per process).
319
+ try:
320
+ from _brain_port import ensure_server
321
+ ensure_server(wait_secs=2.0)
322
+ except Exception:
323
+ pass
324
+ result = _brain_api("lint", {}, timeout=5)
325
+ if result and (result.get("archived", 0) > 0 or result.get("deleted", 0) > 0):
326
+ messages.append(
327
+ f"[Memory] Decay: {result.get('archived', 0)} archived, {result.get('deleted', 0)} cleaned"
328
+ )
329
+ except Exception as e:
330
+ print(f"[wicked-garden] decay error: {e}", file=sys.stderr)
331
+ return messages
332
+
333
+
334
+ def _run_working_consolidation() -> list:
335
+ """Consolidate working-tier memories via brain compile + lint.
336
+
337
+ Returns a list of message strings. Fails open — never blocks session end.
338
+ """
339
+ messages = []
340
+ try:
341
+ try:
342
+ from _brain_port import ensure_server
343
+ ensure_server(wait_secs=2.0)
344
+ except Exception:
345
+ pass
346
+ compile_result = _brain_api("compile", {}, timeout=10)
347
+ lint_result = _brain_api("lint", {}, timeout=5)
348
+ compiled = compile_result.get("compiled", 0) if compile_result else 0
349
+ cleaned = lint_result.get("deleted", 0) if lint_result else 0
350
+ if compiled > 0 or cleaned > 0:
351
+ messages.append(
352
+ f"[Memory] Consolidation: {compiled} compiled, {cleaned} cleaned"
353
+ )
354
+ except Exception as e:
355
+ print(f"[wicked-garden] consolidation error: {e}", file=sys.stderr)
356
+ return messages
357
+
358
+
359
+ def _get_turn_count() -> int:
360
+ try:
361
+ from _session import SessionState
362
+ state = SessionState.load()
363
+ return state.turn_count or 0
364
+ except Exception:
365
+ return 0
366
+
367
+
368
+ # ---------------------------------------------------------------------------
369
+ # Step 6: Persist final session state
370
+ # ---------------------------------------------------------------------------
371
+
372
+ def _persist_session_state() -> None:
373
+ """Mark session as ended in session state file."""
374
+ try:
375
+ from _session import SessionState
376
+ state = SessionState.load()
377
+ state.update(session_ended=True)
378
+ state.save()
379
+ except Exception:
380
+ pass
381
+
382
+
383
+ # ---------------------------------------------------------------------------
384
+ # Step 7: Event store retention purge
385
+ # ---------------------------------------------------------------------------
386
+
387
+ def _purge_old_events() -> None:
388
+ """Purge events older than retention period (default 90 days)."""
389
+ try:
390
+ from _event_store import EventStore
391
+ EventStore.ensure_schema()
392
+ deleted = EventStore.purge_before(days=90)
393
+ if deleted > 0:
394
+ _log("stop", "debug", f"event_store.purged {deleted} events")
395
+ except Exception:
396
+ pass # fire-and-forget
397
+
398
+
399
+ # ---------------------------------------------------------------------------
400
+ # Cross-session quality telemetry (Issue #443)
401
+ #
402
+ # Captures a JSONL record of session-level quality metrics and runs drift
403
+ # classification against the 4-session baseline. Always fail-open — must
404
+ # never break Stop. Target budget: <100ms typical, <500ms worst.
405
+ # ---------------------------------------------------------------------------
406
+
407
+ def _run_quality_telemetry(session_id: str) -> list:
408
+ """Append a timeline record + detect drift. Returns any messages."""
409
+ messages = []
410
+ try:
411
+ sys.path.insert(0, str(_PLUGIN_ROOT / "scripts" / "delivery"))
412
+ import telemetry as _telemetry
413
+ import drift as _drift
414
+
415
+ t_cap = time.monotonic()
416
+ record = _telemetry.capture_session(session_id)
417
+ cap_ms = int((time.monotonic() - t_cap) * 1000)
418
+ _log("telemetry", "debug", "telemetry.capture", ok=record is not None, ms=cap_ms)
419
+ if record is None:
420
+ return messages
421
+
422
+ project = record.get("project") or "_global"
423
+ records = _telemetry.read_timeline(project)
424
+ cls = _drift.classify(records)
425
+ # Emit bus event when drift actionable; fail-open when bus is absent.
426
+ emitted = _drift.emit_drift_event(project, cls)
427
+ if cls.get("drift"):
428
+ messages.append(
429
+ f"[Telemetry] Drift detected for {project}: " + _drift.summarize(cls)
430
+ + (" (emitted to wicked-bus)" if emitted else "")
431
+ )
432
+ elif cls.get("zone") == "warn":
433
+ messages.append(
434
+ f"[Telemetry] Watch signal for {project}: " + _drift.summarize(cls)
435
+ )
436
+ except Exception as e:
437
+ print(f"[wicked-garden] telemetry error: {e}", file=sys.stderr)
438
+ return messages
439
+
440
+
441
+ # ---------------------------------------------------------------------------
442
+ # Step 6: Autonomous guard pipeline (Issue #448)
443
+ # ---------------------------------------------------------------------------
444
+ #
445
+ # Runs a tiered profile of surface-level verification at session close:
446
+ # * scalpel (<1s) — always runs when the pipeline is reachable
447
+ # * standard (~5s) — build-phase just closed, or substantial changes
448
+ # * deep (~30s) — release-branch sessions or explicit WG_GUARD_PROFILE=deep
449
+ #
450
+ # Always fails open — never hard-blocks session close. Findings are written
451
+ # to a session-scoped file that bootstrap.py can surface in the next briefing,
452
+ # and emitted as a `wicked.guard.findings` event on wicked-bus.
453
+ #
454
+ # Ordering: runs AFTER telemetry (#443) so both can share the end-of-session
455
+ # snapshot without blocking each other.
456
+
457
+ def _run_guard_pipeline() -> list:
458
+ """Run the autonomous session-close guard pipeline.
459
+
460
+ Returns a list of human-readable message strings to prepend to the session
461
+ message. Always fails open — any error returns an empty list.
462
+ """
463
+ try:
464
+ sys.path.insert(0, str(_PLUGIN_ROOT / "scripts" / "platform"))
465
+ from guard_pipeline import (
466
+ run_pipeline,
467
+ write_briefing_file,
468
+ emit_findings_event,
469
+ render_summary,
470
+ )
471
+ except Exception as exc:
472
+ print(f"[wicked-garden] guard pipeline unavailable: {exc}", file=sys.stderr)
473
+ return []
474
+
475
+ try:
476
+ # Detect whether build phase just closed — best-effort via session state
477
+ build_just_closed = False
478
+ try:
479
+ from _session import SessionState
480
+ state = SessionState.load()
481
+ build_just_closed = bool(
482
+ getattr(state, "last_phase_approved", None) == "build"
483
+ )
484
+ except Exception:
485
+ pass # fail open — treat unknown phase as "not just closed"
486
+
487
+ report = run_pipeline(build_phase_just_closed=build_just_closed)
488
+
489
+ # Write briefing file (next session pickup)
490
+ write_briefing_file(report)
491
+
492
+ # Emit bus event (fire-and-forget)
493
+ emit_findings_event(report)
494
+
495
+ # Only return a summary line when we actually have findings or budget blew.
496
+ if report.total_findings > 0 or report.status != "ok":
497
+ return [render_summary(report)]
498
+ return []
499
+ except Exception as exc:
500
+ print(f"[wicked-garden] guard pipeline error: {exc}", file=sys.stderr)
501
+ return []
502
+
503
+
504
+ # ---------------------------------------------------------------------------
505
+ # Main
506
+ # ---------------------------------------------------------------------------
507
+
508
+ def main():
509
+ _t0 = time.monotonic()
510
+ _log("session", "debug", "hook.start")
511
+
512
+ try:
513
+ raw = sys.stdin.read()
514
+ input_data = json.loads(raw) if raw.strip() else {}
515
+ except Exception:
516
+ input_data = {}
517
+
518
+ try:
519
+ session_id = input_data.get("session_id", os.environ.get("CLAUDE_SESSION_ID", "default"))
520
+ turn_count = _get_turn_count()
521
+
522
+ # 1. Session outcome check
523
+ outcome_messages = _check_session_outcome()
524
+
525
+ # 2b. Automatic memory promotion (fail open — never blocks session end)
526
+ # KEPT in stop.py per-turn — lightweight (single bus emit per fact),
527
+ # self-reports cleanly, and the next session's bootstrap relies on
528
+ # memories being current. Heavy cadence work (decay/consolidation/
529
+ # telemetry/guard) was extracted in v9.2.15 — see _heavy_cadence.py.
530
+ promotion_messages = _run_memory_promotion(session_id)
531
+
532
+ # 4. Persist session state
533
+ _persist_session_state()
534
+
535
+ # 5. Event store retention purge
536
+ _purge_old_events()
537
+
538
+ # 6. Heavy cadence (v9.2.15) — formerly per-turn, now per-session-end
539
+ # primary via the SessionEnd hook (hooks/scripts/session_end.py).
540
+ # Stop only runs the heavy work as a 60-min FALLBACK for the partial-
541
+ # session failure mode (CLI killed, network drop, user walked away —
542
+ # SessionEnd never fires). Sidecar at <local store>/wicked-garden/
543
+ # heavy-cadence/last_run.json gates the fallback deterministically.
544
+ consolidation_messages: list = []
545
+ decay_messages: list = []
546
+ telemetry_messages: list = []
547
+ guard_messages: list = []
548
+ try:
549
+ sys.path.insert(0, str(_PLUGIN_ROOT / "scripts"))
550
+ from _heavy_cadence import ( # type: ignore
551
+ run_heavy_cadence, should_run_fallback, TRIGGER_STOP_FALLBACK,
552
+ )
553
+ if should_run_fallback():
554
+ fallback_messages = run_heavy_cadence(
555
+ TRIGGER_STOP_FALLBACK, session_id=session_id, plugin_root=_PLUGIN_ROOT,
556
+ )
557
+ # Single combined list — semantics preserved for downstream
558
+ # joining; per-category split was only used by the deleted
559
+ # [Memory] reflection block.
560
+ consolidation_messages = fallback_messages
561
+ except Exception as e:
562
+ print(f"[wicked-garden] heavy cadence fallback error: {e}", file=sys.stderr)
563
+
564
+ # Read session state for task completion count (fail open)
565
+ tasks_completed_this_session = 0
566
+ try:
567
+ sys.path.insert(0, str(_PLUGIN_ROOT / "scripts"))
568
+ from _session import SessionState
569
+ session_state = SessionState.load()
570
+ tasks_completed_this_session = session_state.memory_compliance_tasks_completed or 0
571
+ except Exception:
572
+ pass
573
+
574
+ # NOTE (v9.2.15): the [Memory] reflection block was deleted.
575
+ # - It had a parser bug: looked for substring "Auto-extracted " but
576
+ # _run_memory_promotion emits "Emitted N fact event(s)" — so
577
+ # `promoted_count` was ALWAYS 0 and only the fallback prompt-mode
578
+ # branch ever fired. The "smart" branching had never executed in
579
+ # production.
580
+ # - _run_memory_promotion already self-reports when facts are
581
+ # auto-extracted ("[Memory] Emitted N fact event(s); wicked-brain
582
+ # will auto-memorize..."), so the reflection's "use wicked-brain:
583
+ # memory" guidance was duplicate noise.
584
+ # - The brainstorm in v9.2.15 chose Option A (delete) over Option B
585
+ # (fix the parser + re-gate) because the smart branch is dead
586
+ # code defending behavior no user has seen. CLAUDE.md's "Memory
587
+ # Management" section already tells Claude to use wicked-brain:
588
+ # memory for decisions; an end-of-turn reminder adds no signal.
589
+ # `tasks_completed_this_session` is no longer read; the variable
590
+ # remains in scope above for any future use without breaking the
591
+ # `session_state` load.
592
+ reflection = ""
593
+ # for this session (post-first-Stop) — only join with separator if both
594
+ # halves have content.
595
+ # Answer-tier claim sentinel — claim-gated, computed here (after
596
+ # _persist_session_state) so its debounce write is the last state write
597
+ # of the turn (avoids clobbering session_ended).
598
+ sentinel_messages = _check_claim_sentinel(input_data)
599
+ prepend_messages = sentinel_messages + outcome_messages + promotion_messages + consolidation_messages + telemetry_messages + guard_messages
600
+ if prepend_messages and reflection:
601
+ final_message = "\n".join(prepend_messages) + "\n\n" + reflection
602
+ elif prepend_messages:
603
+ final_message = "\n".join(prepend_messages)
604
+ else:
605
+ final_message = reflection
606
+
607
+ # Compute log file path for session summary
608
+ _ops_log_path = str(
609
+ Path(os.environ.get("TMPDIR") or __import__("tempfile").gettempdir()) / f"wicked-ops-{_get_session_id()}.jsonl"
610
+ )
611
+ _log("session", "verbose", "session.end",
612
+ detail={"turns": turn_count,
613
+ "tasks_completed": tasks_completed_this_session,
614
+ "log_file": _ops_log_path})
615
+ _log("session", "debug", "hook.end", ms=int((time.monotonic() - _t0) * 1000))
616
+ print(json.dumps({"systemMessage": final_message}))
617
+
618
+ except Exception as e:
619
+ print(f"[wicked-garden] stop hook error: {e}", file=sys.stderr)
620
+ print(json.dumps({"systemMessage": ""}))
621
+
622
+
623
+ if __name__ == "__main__":
624
+ main()