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,703 @@
1
+ #!/usr/bin/env python3
2
+ """phase_manager.py — v11 slim project-state manager.
3
+
4
+ The v6-v10 universal-pipeline implementation (gate-result.json schema
5
+ validators, addendum freshness, conditions-manifest enforcement, BLEND-
6
+ RULE dispatch, banned-reviewer enforcement, dispatch-log HMAC,
7
+ convergence-verify, semantic-alignment, propose-process facilitator
8
+ rubric, rigor tiers, gate-policy.json) lived in this module across many
9
+ thousands of lines. v11 collapsed all of that into per-archetype playbooks
10
+ under skills/archetype/refs/{archetype}.md, with the catalog at
11
+ .claude-plugin/archetypes.json driving phase shape, produces, HITL
12
+ discipline, and cost band per archetype.
13
+
14
+ What's left here:
15
+ - ProjectState dataclass: name, current_phase, phase_plan, phases dict,
16
+ extras, created_at.
17
+ - create_project / load_project_state / save_project_state.
18
+ - start_phase / complete_phase / approve_phase / skip_phase — slim state
19
+ transitions, no gate machinery.
20
+ - CLI: status, create, start, complete, approve, skip, advance.
21
+
22
+ Archetype mode is the v11 default for new projects; legacy projects
23
+ (no phase_plan_mode) still load and read but don't get the legacy gate
24
+ checks back — they were the bug, not the value.
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ import argparse
30
+ import json
31
+ import re
32
+ import sys
33
+ from pathlib import Path
34
+ from datetime import datetime, timezone
35
+ from typing import Any, Dict, List, Optional, Tuple
36
+ from dataclasses import dataclass, field, asdict
37
+
38
+ # Make scripts/ importable for _domain_store
39
+ sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
40
+ from _domain_store import DomainStore, get_local_path # noqa: E402
41
+
42
+ _sm = DomainStore("projects")
43
+ logger = __import__("logging").getLogger("wicked-garden.phase-manager")
44
+
45
+
46
+ def _bus_emit_safe(event_type: str, payload: dict, *,
47
+ chain_id: Optional[str] = None) -> None:
48
+ """Fire-and-forget bus emit. Fail-open on every error.
49
+
50
+ The phase_manager is the v11 source-of-truth surface for project
51
+ state transitions. Each transition emits an event for downstream
52
+ consumers (audit, dashboards, future replay). Bus unavailable
53
+ must never block the disk write — bus failure is recorded only
54
+ in emit_stats.
55
+ """
56
+ try:
57
+ from _bus import emit_event # type: ignore
58
+ emit_event(event_type, payload, chain_id=chain_id)
59
+ except Exception:
60
+ pass # Bus is optional infrastructure.
61
+
62
+
63
+ # Strangler shim toward wicked-loom (cutover phase). Read-only parity mirror:
64
+ # the in-process hard-gate enforcement below STAYS authoritative; loom is
65
+ # consulted only to cross-check the park-at-hard-gate decision during cutover.
66
+ try:
67
+ import _loom # scripts/ is on sys.path
68
+ except ImportError: # pragma: no cover
69
+ _loom = None # type: ignore
70
+
71
+
72
+ def _loom_confirms_hard_gate(archetype: str, phase: str) -> "Optional[bool]":
73
+ """Ask loom (via the compiled flow def) whether (archetype, phase) is a
74
+ hard gate. Returns True/False, or None when loom is unavailable/uncertain
75
+ (in which case the in-process _HARD_GATE_PHASES map remains authoritative).
76
+ Best-effort, fail-soft — never raises, never blocks the state write."""
77
+ if _loom is None or not _loom.use_loom():
78
+ return None
79
+ try:
80
+ from flow_compiler import compile_flow
81
+ flow_def = compile_flow(archetype, flow_id=f"{archetype}-parity")
82
+ for p in flow_def.get("phases", []):
83
+ if p.get("name") == phase:
84
+ hitl = p.get("hitl")
85
+ return isinstance(hitl, str) and hitl.startswith("hard:")
86
+ return False
87
+ except Exception:
88
+ return None # fail-soft: in-process map stays authoritative
89
+
90
+
91
+ # ---------------------------------------------------------------------------
92
+ # Naming & resolution
93
+ # ---------------------------------------------------------------------------
94
+
95
+ _PROJECT_NAME_RE = re.compile(r"^[A-Za-z0-9_-]{1,64}$")
96
+
97
+
98
+ def is_safe_project_name(name: str) -> bool:
99
+ """Names are kebab/snake/alphanumeric, max 64 chars."""
100
+ return bool(_PROJECT_NAME_RE.match(name or ""))
101
+
102
+
103
+ # Phase aliases used historically — keep the resolver so old project files
104
+ # still load correctly.
105
+ _PHASE_ALIASES: Dict[str, str] = {
106
+ "implement": "implement",
107
+ "implementation": "implement",
108
+ "plan": "plan",
109
+ "test": "test",
110
+ "review": "review",
111
+ "build": "build",
112
+ "clarify": "clarify",
113
+ "design": "design",
114
+ "operate": "operate",
115
+ }
116
+
117
+
118
+ def resolve_phase(phase: str) -> str:
119
+ """Normalize a phase name. Returns the input unchanged when no alias matches."""
120
+ if not phase:
121
+ return phase
122
+ return _PHASE_ALIASES.get(phase.lower(), phase)
123
+
124
+
125
+ def get_utc_timestamp() -> str:
126
+ return datetime.now(timezone.utc).isoformat()
127
+
128
+
129
+ # ---------------------------------------------------------------------------
130
+ # Project state
131
+ # ---------------------------------------------------------------------------
132
+
133
+ @dataclass
134
+ class PhaseState:
135
+ """Per-phase status. Status is one of: pending | in_progress | completed | approved | skipped."""
136
+ status: str = "pending"
137
+ started_at: Optional[str] = None
138
+ completed_at: Optional[str] = None
139
+ approved_at: Optional[str] = None
140
+
141
+
142
+ @dataclass
143
+ class ProjectState:
144
+ name: str
145
+ current_phase: str
146
+ created_at: str
147
+ version: str = "v11"
148
+ phase_plan: List[str] = field(default_factory=list)
149
+ phases: Dict[str, PhaseState] = field(default_factory=dict)
150
+ extras: Dict[str, Any] = field(default_factory=dict)
151
+
152
+
153
+ def get_project_dir(project_name: str) -> Path:
154
+ """Resolve and create the on-disk project directory."""
155
+ if not is_safe_project_name(project_name):
156
+ raise ValueError(f"Invalid project name: {project_name!r}")
157
+ base = get_local_path("wicked-crew", "projects")
158
+ project_dir = (base / project_name).resolve()
159
+ try:
160
+ project_dir.relative_to(base.resolve())
161
+ except ValueError:
162
+ raise ValueError("Path traversal detected")
163
+ project_dir.mkdir(parents=True, exist_ok=True)
164
+ return project_dir
165
+
166
+
167
+ def save_project_state(state: ProjectState) -> None:
168
+ """Persist state to the DomainStore.
169
+
170
+ Uses ``id = state.name`` as the canonical key. Update is idempotent
171
+ via ``DomainStore.update`` when the record exists; otherwise we
172
+ create.
173
+ """
174
+ payload = {
175
+ "id": state.name,
176
+ "name": state.name,
177
+ "current_phase": state.current_phase,
178
+ "created_at": state.created_at,
179
+ "version": state.version,
180
+ "phase_plan": list(state.phase_plan),
181
+ "phases": {k: asdict(v) for k, v in state.phases.items()},
182
+ "extras": dict(state.extras),
183
+ }
184
+ existing = _sm.get("projects", state.name)
185
+ if existing:
186
+ _sm.update("projects", state.name, payload)
187
+ else:
188
+ _sm.create("projects", payload)
189
+
190
+
191
+ def load_project_state(project_name: str) -> Optional[ProjectState]:
192
+ """Load state from DomainStore, hydrating phases dict from raw."""
193
+ if not is_safe_project_name(project_name):
194
+ return None
195
+ data = _sm.get("projects", project_name)
196
+ if not data:
197
+ return None
198
+ phases: Dict[str, PhaseState] = {}
199
+ for k, v in (data.get("phases") or {}).items():
200
+ if isinstance(v, dict):
201
+ phases[resolve_phase(k)] = PhaseState(
202
+ status=v.get("status", "pending"),
203
+ started_at=v.get("started_at"),
204
+ completed_at=v.get("completed_at"),
205
+ approved_at=v.get("approved_at"),
206
+ )
207
+ return ProjectState(
208
+ name=data.get("name", project_name),
209
+ current_phase=resolve_phase(data.get("current_phase", "")),
210
+ created_at=data.get("created_at", get_utc_timestamp()),
211
+ version=data.get("version", "v11"),
212
+ phase_plan=[resolve_phase(p) for p in (data.get("phase_plan") or [])],
213
+ phases=phases,
214
+ extras=dict(data.get("extras") or {}),
215
+ )
216
+
217
+
218
+ # ---------------------------------------------------------------------------
219
+ # Project creation
220
+ # ---------------------------------------------------------------------------
221
+
222
+ def create_project(
223
+ name: str,
224
+ description: str = "",
225
+ archetype_mode: Optional[str] = None,
226
+ ) -> Tuple[ProjectState, Path]:
227
+ """Create a new project. When ``archetype_mode`` is set, hydrate the
228
+ phase_plan from .claude-plugin/archetypes.json and stamp the project
229
+ as v11 archetype-driven."""
230
+ if not is_safe_project_name(name):
231
+ raise ValueError(f"Invalid project name: {name!r}")
232
+
233
+ state = ProjectState(
234
+ name=name,
235
+ current_phase="",
236
+ created_at=get_utc_timestamp(),
237
+ version="v11",
238
+ )
239
+ if description:
240
+ state.extras["description"] = description
241
+
242
+ if archetype_mode:
243
+ try:
244
+ from archetypes_v11 import load_catalog
245
+ catalog = load_catalog()
246
+ arch_def = catalog.get("archetypes", {}).get(archetype_mode)
247
+ if not arch_def:
248
+ raise ValueError(
249
+ f"Unknown archetype '{archetype_mode}'. "
250
+ f"Known: {list(catalog.get('archetypes', {}).keys())}"
251
+ )
252
+ state.phase_plan = list(arch_def.get("phases", []))
253
+ state.current_phase = state.phase_plan[0] if state.phase_plan else ""
254
+ state.extras["phase_plan_mode"] = "archetype"
255
+ state.extras["v11_archetype"] = archetype_mode
256
+ state.extras["archetype_produces"] = list(arch_def.get("produces", []))
257
+ state.extras["archetype_hitl"] = arch_def.get("hitl")
258
+ except ImportError:
259
+ raise RuntimeError("archetypes_v11 unavailable — cannot init archetype-mode project")
260
+
261
+ project_dir = get_project_dir(name)
262
+ save_project_state(state)
263
+
264
+ # v11.1.1: bus emit for archetype-mode creation. Legacy (no archetype)
265
+ # projects also emit project.created via the v6 path; archetype-mode
266
+ # gets its own event so dashboards can distinguish.
267
+ if archetype_mode:
268
+ _bus_emit_safe(
269
+ "wicked.archetype.created",
270
+ {
271
+ "project_id": name,
272
+ "archetype": archetype_mode,
273
+ "phase_plan": state.phase_plan,
274
+ "produces": list(state.extras.get("archetype_produces") or []),
275
+ "hitl": state.extras.get("archetype_hitl"),
276
+ },
277
+ chain_id=f"{name}.{archetype_mode}.root",
278
+ )
279
+ else:
280
+ _bus_emit_safe(
281
+ "wicked.project.created",
282
+ {"project_id": name},
283
+ chain_id=f"{name}.root",
284
+ )
285
+ return state, project_dir
286
+
287
+
288
+ # ---------------------------------------------------------------------------
289
+ # State transitions
290
+ # ---------------------------------------------------------------------------
291
+
292
+ def start_phase(state: ProjectState, phase: str) -> ProjectState:
293
+ """Mark a phase as in_progress."""
294
+ phase = resolve_phase(phase)
295
+ ps = state.phases.get(phase) or PhaseState()
296
+ ps.status = "in_progress"
297
+ ps.started_at = ps.started_at or get_utc_timestamp()
298
+ state.phases[phase] = ps
299
+ state.current_phase = phase
300
+ save_project_state(state)
301
+ return state
302
+
303
+
304
+ def complete_phase(state: ProjectState, phase: str) -> ProjectState:
305
+ """Mark a phase as completed (work done; awaiting approval)."""
306
+ phase = resolve_phase(phase)
307
+ ps = state.phases.get(phase) or PhaseState(started_at=get_utc_timestamp())
308
+ ps.status = "completed"
309
+ ps.completed_at = get_utc_timestamp()
310
+ state.phases[phase] = ps
311
+ save_project_state(state)
312
+ return state
313
+
314
+
315
+ _HARD_GATE_PHASES: Dict[str, Tuple[str, ...]] = {
316
+ # The (archetype, phase) pairs that genuinely need the user in the loop
317
+ # AT RUNTIME — not just in playbook prose. These MUST mirror the archetypes
318
+ # declared ``hard:<gate>`` in .claude-plugin/archetypes.json (the source of
319
+ # truth). migrate/modernize/incident/review are hard; specify
320
+ # (discrete:validate) and decide (discrete:select) are discrete gates that
321
+ # auto-pass when the produces contract re-derives — promoting them here
322
+ # over-reached the catalog and contradicted the "steering, not blocking"
323
+ # doctrine, so they were removed. modernize's cutover is the legacy→new-stack
324
+ # parity-proved switch — the same hard-gate discipline as migrate.cutover.
325
+ # test_hard_gate_map_matches_catalog locks this alignment.
326
+ "migrate": ("cutover",),
327
+ "modernize": ("cutover",),
328
+ "incident": ("mitigate",),
329
+ "review": ("remediate-or-accept",),
330
+ }
331
+
332
+
333
+ def _is_hard_gate(state: ProjectState, phase: str) -> bool:
334
+ """True iff (archetype, phase) is a hard gate per _HARD_GATE_PHASES."""
335
+ archetype = (state.extras or {}).get("v11_archetype")
336
+ if not archetype:
337
+ return False
338
+ return resolve_phase(phase) in _HARD_GATE_PHASES.get(archetype, ())
339
+
340
+
341
+ def resolve_hard_gate(state: ProjectState, phase: str) -> bool:
342
+ """Authoritative hard-gate decision for ``(archetype, phase)`` (flow cutover).
343
+
344
+ The flow surface is now loom-AUTHORITATIVE for *where the human stops*:
345
+ loom's verdict (derived from the compiled flow-def, which reproduces loom's
346
+ own ``hitl.startswith("hard:")`` park rule) decides whether this phase is a
347
+ hard gate — WHEN loom is available. The in-process ``_HARD_GATE_PHASES`` map
348
+ is two things at once:
349
+
350
+ - the FALLBACK: when loom is unavailable/uncertain
351
+ (``_loom_confirms_hard_gate`` returns None — off, auto-unresolvable, or
352
+ a compile error), the map answers (fail-soft, rollback-safe).
353
+ - the FLOOR: even when loom answers, the resolved decision is
354
+ ``loom or in_process`` — loom may ADD a park the map omits, but can
355
+ NEVER remove a park the map asserts. This is the fail-closed posture of
356
+ the flow surface: we never silently skip a human-in-the-loop stop that
357
+ the in-process doctrine demands. A loom that (wrongly) says "not hard"
358
+ for migrate.cutover cannot disarm the cutover gate.
359
+
360
+ A divergence (loom != in_process, with loom present) is surfaced as a
361
+ ``wicked.loom.parity_mismatch`` signal — retained from the parity mirror —
362
+ so operators see drift even though the resolved decision is the safe OR.
363
+ """
364
+ in_process = _is_hard_gate(state, phase)
365
+ archetype = (state.extras or {}).get("v11_archetype")
366
+ if not archetype:
367
+ return in_process
368
+
369
+ loom_says = _loom_confirms_hard_gate(archetype, phase)
370
+ if loom_says is None:
371
+ return in_process # fail-soft: in-process map is authoritative
372
+
373
+ if loom_says != in_process:
374
+ print(f"[wicked-garden] loom/in-process hard-gate parity mismatch: "
375
+ f"archetype={archetype} phase={phase} "
376
+ f"loom={loom_says} in_process={in_process}", file=sys.stderr)
377
+ _bus_emit_safe(
378
+ "wicked.loom.parity_mismatch",
379
+ {"project_id": state.name, "archetype": archetype,
380
+ "phase": phase, "loom": loom_says, "in_process": in_process,
381
+ "resolved": loom_says or in_process},
382
+ chain_id=f"{state.name}.{archetype}.{phase}.parity",
383
+ )
384
+ # loom authoritative, but fail-closed floor: a park is required if EITHER
385
+ # source says hard. loom can add a park; it can never remove the map's.
386
+ return loom_says or in_process
387
+
388
+
389
+ def approve_phase(
390
+ state: ProjectState,
391
+ phase: str,
392
+ approver: str = "user",
393
+ *,
394
+ confirmed_by: Optional[str] = None,
395
+ confirmation_evidence: Optional[str] = None,
396
+ ) -> Tuple[ProjectState, Optional[str]]:
397
+ """Approve a phase. Returns (state, next_phase_name_or_None).
398
+
399
+ Hard-gate enforcement (v11): when (archetype, phase) is in
400
+ ``_HARD_GATE_PHASES`` (e.g. migrate.cutover, incident.mitigate),
401
+ advancing past the phase REQUIRES non-empty ``confirmed_by`` AND
402
+ ``confirmation_evidence``. The audit log records both. ``approver``
403
+ alone is not enough — the doctrine of "user in the loop" becomes
404
+ runtime: the caller must explicitly attest that confirmation
405
+ happened, and name the artifact (commit / dashboard URL / ticket /
406
+ Slack thread) that proves it.
407
+
408
+ Non-hard phases retain the v11 default: lightweight state transition,
409
+ no gate machinery, archetype's playbook owns discipline.
410
+ """
411
+ phase = resolve_phase(phase)
412
+
413
+ # --- loom cutover (flow surface): loom-AUTHORITATIVE park decision -------
414
+ # The hard-gate verdict now routes through resolve_hard_gate: loom wins when
415
+ # present, the in-process _HARD_GATE_PHASES map is the fallback (loom
416
+ # unavailable) AND the floor (loom can ADD a park, never remove one the map
417
+ # asserts). The parity-mismatch signal lives inside resolve_hard_gate.
418
+ # -------------------------------------------------------------------------
419
+
420
+ # Hard-gate guard: enforce explicit confirmation at runtime.
421
+ if resolve_hard_gate(state, phase):
422
+ if not confirmed_by or not confirmed_by.strip():
423
+ archetype = (state.extras or {}).get("v11_archetype")
424
+ raise ValueError(
425
+ f"Hard gate at archetype={archetype!r} phase={phase!r} "
426
+ f"requires --confirmed-by (user / oncall / approver name). "
427
+ f"This is a v11 enforced HITL gate, not a doctrinal "
428
+ f"hint — the playbook documents this as hard:* and the "
429
+ f"runtime mirrors that. Pass --confirmed-by AND "
430
+ f"--confirmation-evidence (path / URL / ticket id)."
431
+ )
432
+ if not confirmation_evidence or not confirmation_evidence.strip():
433
+ archetype = (state.extras or {}).get("v11_archetype")
434
+ raise ValueError(
435
+ f"Hard gate at archetype={archetype!r} phase={phase!r} "
436
+ f"requires --confirmation-evidence (path to artifact "
437
+ f"proving the gate-specific check passed: rollback "
438
+ f"drill log, dashboard screenshot, mitigation commit, "
439
+ f"approval ticket, etc.)."
440
+ )
441
+
442
+ ps = state.phases.get(phase) or PhaseState()
443
+ ps.status = "approved"
444
+ ps.approved_at = get_utc_timestamp()
445
+ state.phases[phase] = ps
446
+
447
+ approval_record = {
448
+ "phase": phase, "approver": approver, "at": ps.approved_at,
449
+ }
450
+ if confirmed_by:
451
+ approval_record["confirmed_by"] = confirmed_by
452
+ approval_record["confirmation_evidence"] = confirmation_evidence
453
+ approval_record["hard_gate"] = True
454
+
455
+ state.extras.setdefault("approvals", []).append(approval_record)
456
+
457
+ # Resolve next phase from phase_plan
458
+ next_phase: Optional[str] = None
459
+ if state.phase_plan:
460
+ try:
461
+ idx = state.phase_plan.index(phase)
462
+ if idx + 1 < len(state.phase_plan):
463
+ next_phase = state.phase_plan[idx + 1]
464
+ except ValueError:
465
+ pass
466
+
467
+ if next_phase:
468
+ state.current_phase = next_phase
469
+ save_project_state(state)
470
+
471
+ # v11.1.1: emit hard_gate_passed when a hard gate advanced
472
+ archetype = (state.extras or {}).get("v11_archetype")
473
+ if archetype and confirmed_by:
474
+ _bus_emit_safe(
475
+ "wicked.archetype.hard_gate_passed",
476
+ {
477
+ "project_id": state.name,
478
+ "archetype": archetype,
479
+ "phase": phase,
480
+ "confirmed_by": confirmed_by,
481
+ "confirmation_evidence": confirmation_evidence,
482
+ },
483
+ chain_id=f"{state.name}.{archetype}.{phase}.hard-gate",
484
+ )
485
+
486
+ # v11.1.1: emit advance event for any archetype-mode approval
487
+ if archetype:
488
+ _bus_emit_safe(
489
+ "wicked.archetype.advanced",
490
+ {
491
+ "project_id": state.name,
492
+ "archetype": archetype,
493
+ "phase": phase,
494
+ "next_phase": next_phase,
495
+ },
496
+ chain_id=f"{state.name}.{archetype}.{phase}",
497
+ )
498
+
499
+ # v11.1.1: emit completed event when project is_complete after this approval
500
+ if archetype and is_complete(state):
501
+ _bus_emit_safe(
502
+ "wicked.archetype.completed",
503
+ {
504
+ "project_id": state.name,
505
+ "archetype": archetype,
506
+ "final_phase": phase,
507
+ },
508
+ chain_id=f"{state.name}.{archetype}.completed",
509
+ )
510
+
511
+ return state, next_phase
512
+
513
+
514
+ def skip_phase(state: ProjectState, phase: str, reason: str = "") -> ProjectState:
515
+ phase = resolve_phase(phase)
516
+ ps = state.phases.get(phase) or PhaseState()
517
+ ps.status = "skipped"
518
+ ps.completed_at = get_utc_timestamp()
519
+ state.phases[phase] = ps
520
+ state.extras.setdefault("skips", []).append({
521
+ "phase": phase, "reason": reason, "at": ps.completed_at,
522
+ })
523
+ save_project_state(state)
524
+ return state
525
+
526
+
527
+ def is_complete(state: ProjectState) -> bool:
528
+ """All phases in the plan are approved or skipped."""
529
+ if not state.phase_plan:
530
+ return False
531
+ for p in state.phase_plan:
532
+ ps = state.phases.get(p)
533
+ if not ps or ps.status not in ("approved", "skipped"):
534
+ return False
535
+ return True
536
+
537
+
538
+ # ---------------------------------------------------------------------------
539
+ # CLI
540
+ # ---------------------------------------------------------------------------
541
+
542
+ def _emit(payload: Dict[str, Any], as_json: bool, fallback: str = "") -> None:
543
+ if as_json:
544
+ print(json.dumps(payload, indent=2, default=str))
545
+ elif fallback:
546
+ print(fallback)
547
+
548
+
549
+ def main() -> None:
550
+ parser = argparse.ArgumentParser(description="v11 slim project state manager")
551
+ parser.add_argument("project")
552
+ parser.add_argument(
553
+ "action",
554
+ choices=["status", "create", "start", "complete", "approve", "skip",
555
+ "advance", "delete"],
556
+ )
557
+ parser.add_argument("--phase", default=None)
558
+ parser.add_argument("--description", default="")
559
+ parser.add_argument("--reason", default="")
560
+ parser.add_argument("--approver", default="user")
561
+ parser.add_argument(
562
+ "--confirmed-by", default=None,
563
+ help="v11 hard-gate confirmation: name of the user/oncall/approver "
564
+ "who confirmed the gate-specific check (required for "
565
+ "migrate:cutover, modernize:cutover, incident:mitigate, "
566
+ "review:remediate-or-accept).",
567
+ )
568
+ parser.add_argument(
569
+ "--confirmation-evidence", default=None,
570
+ help="v11 hard-gate confirmation evidence: path / URL / ticket id "
571
+ "proving the check passed (e.g. rollback drill log, "
572
+ "dashboard screenshot, mitigation commit).",
573
+ )
574
+ parser.add_argument(
575
+ "--archetype-mode",
576
+ default=None,
577
+ choices=["triage", "explore", "specify", "decide", "ship",
578
+ "review", "incident", "build", "migrate", "modernize"],
579
+ help="Hydrate phase_plan from .claude-plugin/archetypes.json on create.",
580
+ )
581
+ parser.add_argument("--json", action="store_true")
582
+ args = parser.parse_args()
583
+
584
+ if args.action == "create":
585
+ try:
586
+ state, _project_dir = create_project(
587
+ args.project,
588
+ description=args.description,
589
+ archetype_mode=args.archetype_mode,
590
+ )
591
+ except (ValueError, RuntimeError) as exc:
592
+ _emit({"ok": False, "error": str(exc)}, args.json,
593
+ f"Error: {exc}")
594
+ sys.exit(1)
595
+ _emit(
596
+ {"ok": True, "name": state.name, "phase_plan": state.phase_plan,
597
+ "current_phase": state.current_phase,
598
+ "v11_archetype": state.extras.get("v11_archetype")},
599
+ args.json,
600
+ f"Created project '{state.name}' "
601
+ f"(phases: {' -> '.join(state.phase_plan) or 'none'})",
602
+ )
603
+ return
604
+
605
+ state = load_project_state(args.project)
606
+ if state is None:
607
+ _emit({"ok": False, "error": f"Project not found: {args.project}"},
608
+ args.json, f"Error: project not found: {args.project}")
609
+ sys.exit(1)
610
+
611
+ phase = args.phase or state.current_phase
612
+
613
+ if args.action == "status":
614
+ complete = is_complete(state)
615
+ _emit(
616
+ {
617
+ "name": state.name,
618
+ "current_phase": state.current_phase,
619
+ "phase_plan": state.phase_plan,
620
+ "phases": {k: asdict(v) for k, v in state.phases.items()},
621
+ "extras": state.extras,
622
+ "is_complete": complete,
623
+ "v11_archetype": state.extras.get("v11_archetype"),
624
+ },
625
+ args.json,
626
+ f"Project: {state.name}\n"
627
+ f"Phase: {state.current_phase}\n"
628
+ f"Plan: {' -> '.join(state.phase_plan) or 'none'}\n"
629
+ f"Complete: {complete}",
630
+ )
631
+ return
632
+
633
+ if args.action == "start":
634
+ state = start_phase(state, phase)
635
+ _emit({"ok": True, "phase": phase, "status": "in_progress"},
636
+ args.json, f"Started phase '{phase}'.")
637
+ return
638
+
639
+ if args.action == "complete":
640
+ state = complete_phase(state, phase)
641
+ _emit({"ok": True, "phase": phase, "status": "completed"},
642
+ args.json, f"Completed phase '{phase}'.")
643
+ return
644
+
645
+ if args.action == "approve":
646
+ try:
647
+ state, next_phase = approve_phase(
648
+ state, phase, approver=args.approver,
649
+ confirmed_by=args.confirmed_by,
650
+ confirmation_evidence=args.confirmation_evidence,
651
+ )
652
+ except ValueError as exc:
653
+ _emit({"ok": False, "error": str(exc)}, args.json,
654
+ f"Error: {exc}")
655
+ sys.exit(1)
656
+ _emit(
657
+ {"ok": True, "phase": phase, "status": "approved",
658
+ "next_phase": next_phase, "is_complete": is_complete(state),
659
+ "hard_gate_confirmed": bool(args.confirmed_by)},
660
+ args.json,
661
+ f"Approved phase '{phase}'. "
662
+ f"{'Next: ' + next_phase if next_phase else 'Project complete.'}",
663
+ )
664
+ return
665
+
666
+ if args.action == "skip":
667
+ state = skip_phase(state, phase, reason=args.reason)
668
+ _emit({"ok": True, "phase": phase, "status": "skipped",
669
+ "reason": args.reason},
670
+ args.json, f"Skipped phase '{phase}'.")
671
+ return
672
+
673
+ if args.action == "advance":
674
+ try:
675
+ state, next_phase = approve_phase(
676
+ state, phase, approver=args.approver,
677
+ confirmed_by=args.confirmed_by,
678
+ confirmation_evidence=args.confirmation_evidence,
679
+ )
680
+ except ValueError as exc:
681
+ _emit({"ok": False, "error": str(exc)}, args.json,
682
+ f"Error: {exc}")
683
+ sys.exit(1)
684
+ if next_phase:
685
+ state = start_phase(state, next_phase)
686
+ _emit(
687
+ {"ok": True, "approved": phase, "started": next_phase,
688
+ "is_complete": is_complete(state)},
689
+ args.json,
690
+ f"Approved '{phase}', started '{next_phase}'." if next_phase
691
+ else f"Approved '{phase}'. Project complete.",
692
+ )
693
+ return
694
+
695
+ if args.action == "delete":
696
+ _sm.delete("projects", args.project)
697
+ _emit({"ok": True, "deleted": args.project},
698
+ args.json, f"Deleted project '{args.project}'.")
699
+ return
700
+
701
+
702
+ if __name__ == "__main__":
703
+ main()