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.
- package/.claude-plugin/archetypes.json +166 -0
- package/.claude-plugin/components.json +75 -0
- package/.claude-plugin/marketplace.json +15 -0
- package/.claude-plugin/plugin.json +174 -0
- package/.claude-plugin/specialist.json +48 -0
- package/.claude-plugin/stack-registry.json +96 -0
- package/AGENTS.md +13 -0
- package/CHANGELOG.md +712 -0
- package/CONTRIBUTING.md +99 -0
- package/ETHOS.md +83 -0
- package/LICENSE +21 -0
- package/README.md +115 -0
- package/WICKED_GARDEN_BUS_EVENTS.md +149 -0
- package/agents/agentic/architect.md +449 -0
- package/agents/agentic/performance-analyst.md +702 -0
- package/agents/agentic/safety-reviewer.md +662 -0
- package/agents/crew/implementer.md +163 -0
- package/agents/crew/researcher.md +94 -0
- package/agents/crew/reviewer.md +184 -0
- package/agents/data/data-engineer.md +227 -0
- package/agents/engineering/api-documentarian.md +440 -0
- package/agents/engineering/migration-engineer.md +301 -0
- package/agents/engineering/solution-architect.md +208 -0
- package/agents/jam/brainstorm-facilitator.md +297 -0
- package/agents/jam/council.md +322 -0
- package/agents/jam/quick-facilitator.md +85 -0
- package/agents/persona/persona-agent.md +121 -0
- package/agents/platform/compliance-officer.md +266 -0
- package/agents/platform/privacy-expert.md +496 -0
- package/agents/platform/security-engineer.md +287 -0
- package/agents/product/a11y-expert.md +323 -0
- package/agents/product/requirements-analyst.md +238 -0
- package/agents/product/ui-reviewer.md +180 -0
- package/agents/product/ux-designer.md +199 -0
- package/agents/product/value-strategist.md +269 -0
- package/agents/qe/semantic-reviewer.md +78 -0
- package/commands/agentic/audit.md +24 -0
- package/commands/agentic/design.md +24 -0
- package/commands/agentic/frameworks.md +25 -0
- package/commands/agentic/review.md +27 -0
- package/commands/archetype/build.md +12 -0
- package/commands/archetype/decide.md +12 -0
- package/commands/archetype/explore.md +12 -0
- package/commands/archetype/incident.md +12 -0
- package/commands/archetype/migrate.md +12 -0
- package/commands/archetype/modernize.md +12 -0
- package/commands/archetype/review.md +14 -0
- package/commands/archetype/ship.md +12 -0
- package/commands/archetype/specify.md +12 -0
- package/commands/archetype/triage.md +12 -0
- package/commands/compile.md +37 -0
- package/commands/data/analyze.md +18 -0
- package/commands/data/data.md +21 -0
- package/commands/data/ml.md +18 -0
- package/commands/data/ontology.md +22 -0
- package/commands/data/pipeline.md +17 -0
- package/commands/deliberate.md +181 -0
- package/commands/engineering/add-field.md +77 -0
- package/commands/engineering/apply.md +58 -0
- package/commands/engineering/arch.md +26 -0
- package/commands/engineering/debug.md +27 -0
- package/commands/engineering/docs.md +27 -0
- package/commands/engineering/new-generator.md +257 -0
- package/commands/engineering/patch-plan.md +59 -0
- package/commands/engineering/plan.md +29 -0
- package/commands/engineering/remove.md +48 -0
- package/commands/engineering/rename.md +44 -0
- package/commands/engineering/review.md +32 -0
- package/commands/help.md +128 -0
- package/commands/install.md +118 -0
- package/commands/intent.md +54 -0
- package/commands/jam/brainstorm.md +37 -0
- package/commands/jam/council.md +49 -0
- package/commands/jam/quick.md +21 -0
- package/commands/jam/revisit.md +79 -0
- package/commands/persona/as.md +136 -0
- package/commands/persona/define.md +24 -0
- package/commands/persona/list.md +118 -0
- package/commands/platform/actions.md +20 -0
- package/commands/platform/assert.md +18 -0
- package/commands/platform/audit.md +23 -0
- package/commands/platform/compliance.md +20 -0
- package/commands/platform/gh.md +22 -0
- package/commands/platform/health.md +22 -0
- package/commands/platform/incident.md +23 -0
- package/commands/platform/infra.md +24 -0
- package/commands/platform/peer-health.md +103 -0
- package/commands/platform/plugin-health.md +58 -0
- package/commands/platform/security.md +38 -0
- package/commands/platform/toolchain.md +96 -0
- package/commands/platform/traces.md +20 -0
- package/commands/product/a11y.md +19 -0
- package/commands/product/acceptance.md +19 -0
- package/commands/product/align.md +20 -0
- package/commands/product/analyze.md +23 -0
- package/commands/product/elicit.md +19 -0
- package/commands/product/listen.md +24 -0
- package/commands/product/mockup.md +20 -0
- package/commands/product/screenshot.md +19 -0
- package/commands/product/strategy.md +40 -0
- package/commands/product/synthesize.md +23 -0
- package/commands/product/ux-review.md +42 -0
- package/commands/product/ux.md +20 -0
- package/commands/product/visual-direction.md +34 -0
- package/commands/prove.md +47 -0
- package/commands/report-issue.md +243 -0
- package/commands/reset.md +144 -0
- package/commands/search/blast-radius.md +58 -0
- package/commands/search/hotspots.md +55 -0
- package/commands/search/index.md +38 -0
- package/commands/search/lineage.md +47 -0
- package/commands/search/service-map.md +79 -0
- package/commands/setup.md +363 -0
- package/commands/smaht/briefing.md +200 -0
- package/commands/smaht/events-import.md +95 -0
- package/commands/smaht/state.md +19 -0
- package/commands/where-am-i.md +58 -0
- package/docs/README.md +32 -0
- package/docs/adr/0001-code-relationship-graph-engine.md +116 -0
- package/docs/adr/0002-major-cleanup-keep-cut.md +91 -0
- package/docs/adr/0003-peers-gate-required-layers-optin.md +41 -0
- package/docs/adr/0004-code-graph-moves-to-wicked-brain.md +47 -0
- package/docs/brain-chunk-format.md +135 -0
- package/docs/compiler.md +95 -0
- package/docs/daemon-api.md +70 -0
- package/docs/domains.md +197 -0
- package/docs/getting-started.md +208 -0
- package/docs/plans/2026-06-08-wicked-loom-conduct.md +1337 -0
- package/docs/plans/2026-06-08-wicked-loom-contract.md +638 -0
- package/docs/plans/2026-06-08-wicked-loom-cutover.md +1300 -0
- package/docs/plans/2026-06-08-wicked-loom-expand-compose.md +843 -0
- package/docs/plans/2026-06-08-wicked-loom-flow-cutover.md +403 -0
- package/docs/plans/2026-06-10-codegraph-to-brain-phase1a-graph-core.md +838 -0
- package/docs/plans/2026-06-10-codegraph-to-brain-phase1b-injected-edges.md +44 -0
- package/docs/required-peers.md +60 -0
- package/docs/specs/2026-06-08-wicked-loom-extraction.md +225 -0
- package/docs/specs/2026-06-10-codegraph-to-brain-migration.md +168 -0
- package/docs/v11/archetypes.md +231 -0
- package/hooks/hooks.json +275 -0
- package/hooks/scripts/bootstrap.py +1797 -0
- package/hooks/scripts/invoke.py +62 -0
- package/hooks/scripts/notification.py +166 -0
- package/hooks/scripts/permission_request.py +223 -0
- package/hooks/scripts/post_tool.py +1374 -0
- package/hooks/scripts/pre_compact.py +272 -0
- package/hooks/scripts/pre_tool.py +1278 -0
- package/hooks/scripts/prompt_submit.py +1109 -0
- package/hooks/scripts/session_end.py +95 -0
- package/hooks/scripts/stop.py +624 -0
- package/hooks/scripts/subagent_lifecycle.py +464 -0
- package/hooks/scripts/subscribers/on_gate_decided.py +84 -0
- package/hooks/scripts/task_completed.py +322 -0
- package/hooks/scripts/worktree_guard.py +148 -0
- package/hooks/subscriptions/on_gate_decided.json +9 -0
- package/install.mjs +128 -0
- package/package.json +41 -0
- package/pyproject.toml +59 -0
- package/schemas/README.md +32 -0
- package/schemas/assert_contracts.json +37 -0
- package/schemas/health_probe.json +46 -0
- package/schemas/plugin_status.json +37 -0
- package/scripts/_adapters/__init__.py +166 -0
- package/scripts/_adapters/jira_adapter.py +18 -0
- package/scripts/_adapters/linear_adapter.py +18 -0
- package/scripts/_adapters/miro_adapter.py +18 -0
- package/scripts/_adapters/notion_adapter.py +18 -0
- package/scripts/_agents.py +357 -0
- package/scripts/_brain_ingest/__init__.py +2 -0
- package/scripts/_brain_ingest/session_fact_extractor.py +341 -0
- package/scripts/_brain_port.py +163 -0
- package/scripts/_bus.py +1081 -0
- package/scripts/_bus_catalog_gen.py +93 -0
- package/scripts/_bus_consumers.json +46 -0
- package/scripts/_bus_emit.py +43 -0
- package/scripts/_capability_registry.py +334 -0
- package/scripts/_capability_resolver.py +322 -0
- package/scripts/_domain_store.py +559 -0
- package/scripts/_event_log_reader.py +154 -0
- package/scripts/_event_schema.py +305 -0
- package/scripts/_event_store.py +397 -0
- package/scripts/_heavy_cadence.py +324 -0
- package/scripts/_integration_resolver.py +321 -0
- package/scripts/_logger.py +151 -0
- package/scripts/_loom.py +482 -0
- package/scripts/_paths.py +133 -0
- package/scripts/_python.sh +22 -0
- package/scripts/_run.py +137 -0
- package/scripts/_session.py +502 -0
- package/scripts/_validate_registry.py +1042 -0
- package/scripts/_wicked_testing_probe.py +277 -0
- package/scripts/agentic/analyze_agents.py +391 -0
- package/scripts/agentic/detect_framework.py +420 -0
- package/scripts/agentic/issue_taxonomy.py +357 -0
- package/scripts/agentic/pattern_scorer.py +434 -0
- package/scripts/classify/persist.py +169 -0
- package/scripts/compiler/compile.py +552 -0
- package/scripts/compiler/phase0/VERDICT.md +60 -0
- package/scripts/compiler/phase0/detect.py +292 -0
- package/scripts/compiler/phase0/emit.py +228 -0
- package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.bindings.json +30 -0
- package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.lint-output.txt +17 -0
- package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/.wg/evidence/failing-tests.txt +4 -0
- package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/.wg/evidence/honest-tests.txt +2 -0
- package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/fab-fail.build.md +8 -0
- package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/fab-missing.build.md +8 -0
- package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/honest.build.md +8 -0
- package/scripts/compiler/phase0/evidence/Enterprise-AISDLC.stage/wg_check_claims.py +174 -0
- package/scripts/compiler/phase0/evidence/command_iq.bindings.json +45 -0
- package/scripts/compiler/phase0/evidence/command_iq.lint-output.txt +17 -0
- package/scripts/compiler/phase0/evidence/command_iq.stage/.projects/evidence-domain/phase-1-clarify/evidence/failing-tests.txt +4 -0
- package/scripts/compiler/phase0/evidence/command_iq.stage/.projects/evidence-domain/phase-1-clarify/evidence/honest-tests.txt +3 -0
- package/scripts/compiler/phase0/evidence/command_iq.stage/fab-fail.build.md +8 -0
- package/scripts/compiler/phase0/evidence/command_iq.stage/fab-missing.build.md +8 -0
- package/scripts/compiler/phase0/evidence/command_iq.stage/honest.build.md +8 -0
- package/scripts/compiler/phase0/evidence/command_iq.stage/wg_check_claims.py +174 -0
- package/scripts/compiler/phase0/evidence/memos.bindings.json +28 -0
- package/scripts/compiler/phase0/evidence/memos.lint-output.txt +17 -0
- package/scripts/compiler/phase0/evidence/memos.stage/.wg/evidence/failing-tests.txt +4 -0
- package/scripts/compiler/phase0/evidence/memos.stage/.wg/evidence/honest-tests.txt +2 -0
- package/scripts/compiler/phase0/evidence/memos.stage/fab-fail.build.md +8 -0
- package/scripts/compiler/phase0/evidence/memos.stage/fab-missing.build.md +8 -0
- package/scripts/compiler/phase0/evidence/memos.stage/honest.build.md +8 -0
- package/scripts/compiler/phase0/evidence/memos.stage/wg_check_claims.py +174 -0
- package/scripts/compiler/phase0/evidence/verdict.json +104 -0
- package/scripts/compiler/phase0/evidence/wicked-bus.bindings.json +29 -0
- package/scripts/compiler/phase0/evidence/wicked-bus.lint-output.txt +17 -0
- package/scripts/compiler/phase0/evidence/wicked-bus.stage/coverage/failing-tests.txt +4 -0
- package/scripts/compiler/phase0/evidence/wicked-bus.stage/coverage/honest-tests.txt +3 -0
- package/scripts/compiler/phase0/evidence/wicked-bus.stage/fab-fail.build.md +8 -0
- package/scripts/compiler/phase0/evidence/wicked-bus.stage/fab-missing.build.md +8 -0
- package/scripts/compiler/phase0/evidence/wicked-bus.stage/honest.build.md +8 -0
- package/scripts/compiler/phase0/evidence/wicked-bus.stage/wg_check_claims.py +174 -0
- package/scripts/compiler/phase0/evidence/wire-vault-transcript.txt +60 -0
- package/scripts/compiler/phase0/run_probe.py +234 -0
- package/scripts/compiler/phase0/wire_vault.py +310 -0
- package/scripts/crew/__init__.py +0 -0
- package/scripts/crew/_task_audit_writer.py +243 -0
- package/scripts/crew/_task_reader.py +389 -0
- package/scripts/crew/archetypes_v11.py +348 -0
- package/scripts/crew/detectors/__init__.py +12 -0
- package/scripts/crew/flow_compiler.py +121 -0
- package/scripts/crew/phase_manager.py +703 -0
- package/scripts/crew/scope_delta.py +264 -0
- package/scripts/crew/specialist_resolver.py +218 -0
- package/scripts/crew/stack_registry.py +189 -0
- package/scripts/data/data_profiler.py +271 -0
- package/scripts/data/ontology_recommender.py +231 -0
- package/scripts/data/schema_validator.py +267 -0
- package/scripts/delivery/drift.py +739 -0
- package/scripts/delivery/telemetry.py +614 -0
- package/scripts/engineering/patch/codegraph_db.py +125 -0
- package/scripts/engineering/patch/generators/__init__.py +56 -0
- package/scripts/engineering/patch/generators/base.py +373 -0
- package/scripts/engineering/patch/generators/csharp_generator.py +494 -0
- package/scripts/engineering/patch/generators/go_generator.py +430 -0
- package/scripts/engineering/patch/generators/java_generator.py +928 -0
- package/scripts/engineering/patch/generators/jsp_generator.py +454 -0
- package/scripts/engineering/patch/generators/kotlin_generator.py +561 -0
- package/scripts/engineering/patch/generators/perl_generator.py +510 -0
- package/scripts/engineering/patch/generators/php_generator.py +644 -0
- package/scripts/engineering/patch/generators/propagation_engine.py +929 -0
- package/scripts/engineering/patch/generators/python_generator.py +487 -0
- package/scripts/engineering/patch/generators/ruby_generator.py +463 -0
- package/scripts/engineering/patch/generators/rust_generator.py +400 -0
- package/scripts/engineering/patch/generators/sql_generator.py +594 -0
- package/scripts/engineering/patch/generators/typescript_generator.py +439 -0
- package/scripts/engineering/patch/patch.py +800 -0
- package/scripts/engineering/patch/safety.py +429 -0
- package/scripts/jam/__init__.py +0 -0
- package/scripts/jam/_bus_consumers.py +271 -0
- package/scripts/jam/agentic_cli_registry.py +703 -0
- package/scripts/jam/consensus.py +737 -0
- package/scripts/jam/detect_clis.py +409 -0
- package/scripts/jam/jam.py +283 -0
- package/scripts/jam/save_transcript.py +171 -0
- package/scripts/loom/__init__.py +22 -0
- package/scripts/loom/cli.py +170 -0
- package/scripts/loom/compose.py +180 -0
- package/scripts/loom/gate.py +120 -0
- package/scripts/loom/manifest.py +140 -0
- package/scripts/loom/resolve.py +59 -0
- package/scripts/persona/__init__.py +0 -0
- package/scripts/persona/registry.py +688 -0
- package/scripts/platform/guard_pipeline.py +1214 -0
- package/scripts/platform/guard_profiles.py +216 -0
- package/scripts/platform/observability/assert_contracts.py +434 -0
- package/scripts/platform/observability/health_probe.py +915 -0
- package/scripts/platform/observability/ops_log_viewer.py +209 -0
- package/scripts/platform/prereq_doctor.py +567 -0
- package/scripts/qe/conditions_manifest.py +260 -0
- package/scripts/qe/content_sanitizer.py +160 -0
- package/scripts/qe/coverage_tracker.py +535 -0
- package/scripts/qe/discover_scenarios.py +243 -0
- package/scripts/qe/evidence_tracker.py +232 -0
- package/scripts/qe/prove.py +196 -0
- package/scripts/qe/registry_lookup.py +80 -0
- package/scripts/qe/registry_store.py +176 -0
- package/scripts/qe/semantic_review.py +1005 -0
- package/scripts/qe/vault_gate.py +382 -0
- package/scripts/qe/verdict_audit.py +175 -0
- package/scripts/qe/verdict_schema.py +335 -0
- package/scripts/reset.py +220 -0
- package/scripts/resolve_path.py +22 -0
- package/scripts/sentinel/invariants.py +402 -0
- package/scripts/sentinel/pre_push.py +73 -0
- package/scripts/setup/__init__.py +1 -0
- package/scripts/setup/detect_state.py +114 -0
- package/scripts/setup/migrate_legacy.py +67 -0
- package/scripts/setup/migrate_v6_projects.py +232 -0
- package/scripts/setup/onboarding.py +114 -0
- package/scripts/smaht/_bus_consumers.py +98 -0
- package/scripts/smaht/adapters/__init__.py +83 -0
- package/scripts/smaht/adapters/brain_adapter.py +254 -0
- package/scripts/smaht/adapters/context7_adapter.py +438 -0
- package/scripts/smaht/adapters/delegation_adapter.py +104 -0
- package/scripts/smaht/adapters/domain_adapter.py +206 -0
- package/scripts/smaht/adapters/events_adapter.py +231 -0
- package/scripts/smaht/adapters/tools_adapter.py +49 -0
- package/scripts/smaht/cheatsheet_store.py +236 -0
- package/scripts/smaht/context_package.py +386 -0
- package/scripts/smaht/knowledge_graph.py +395 -0
- package/scripts/smaht/propose_skills.py +856 -0
- package/scripts/smaht/test_cheatsheet_store.py +428 -0
- package/scripts/statusline.py +151 -0
- package/scripts/where_am_i.py +236 -0
- package/skills/agentic/agentic-patterns/SKILL.md +91 -0
- package/skills/agentic/agentic-patterns/refs/anti-patterns-design.md +283 -0
- package/skills/agentic/agentic-patterns/refs/anti-patterns-operational.md +216 -0
- package/skills/agentic/agentic-patterns/refs/pattern-catalog.md +329 -0
- package/skills/agentic/context-engineering/SKILL.md +142 -0
- package/skills/agentic/context-engineering/refs/caching-and-optimization.md +251 -0
- package/skills/agentic/context-engineering/refs/compression-techniques.md +171 -0
- package/skills/agentic/context-engineering/refs/cost-calculation-budget.md +250 -0
- package/skills/agentic/context-engineering/refs/cost-optimization-reporting.md +300 -0
- package/skills/agentic/context-engineering/refs/selective-loading.md +179 -0
- package/skills/agentic/frameworks/SKILL.md +191 -0
- package/skills/agentic/frameworks/refs/framework-profiles-1.md +209 -0
- package/skills/agentic/frameworks/refs/framework-profiles-2.md +214 -0
- package/skills/agentic/frameworks/refs/migration-patterns-paths.md +267 -0
- package/skills/agentic/frameworks/refs/migration-patterns-testing.md +208 -0
- package/skills/agentic/refs/audit.md +134 -0
- package/skills/agentic/refs/design.md +137 -0
- package/skills/agentic/refs/frameworks.md +102 -0
- package/skills/agentic/refs/review.md +160 -0
- package/skills/agentic/review-methodology/SKILL.md +186 -0
- package/skills/agentic/review-methodology/refs/deliverable-templates.md +246 -0
- package/skills/agentic/review-methodology/refs/issue-taxonomy-quality-testing.md +277 -0
- package/skills/agentic/review-methodology/refs/issue-taxonomy-reliability-safety.md +253 -0
- package/skills/agentic/trust-and-safety/SKILL.md +177 -0
- package/skills/agentic/trust-and-safety/refs/guardrails-actions.md +246 -0
- package/skills/agentic/trust-and-safety/refs/guardrails-input-output.md +238 -0
- package/skills/agentic/trust-and-safety/refs/guardrails-resources.md +209 -0
- package/skills/agentic/trust-and-safety/refs/safety-checklist-advanced.md +209 -0
- package/skills/agentic/trust-and-safety/refs/safety-checklist-core.md +215 -0
- package/skills/archetype/SKILL.md +104 -0
- package/skills/archetype/refs/build.md +142 -0
- package/skills/archetype/refs/decide.md +117 -0
- package/skills/archetype/refs/explore.md +66 -0
- package/skills/archetype/refs/incident.md +149 -0
- package/skills/archetype/refs/migrate.md +170 -0
- package/skills/archetype/refs/modernize.md +187 -0
- package/skills/archetype/refs/review.md +145 -0
- package/skills/archetype/refs/ship.md +117 -0
- package/skills/archetype/refs/specify.md +108 -0
- package/skills/archetype/refs/triage.md +62 -0
- package/skills/classify/SKILL.md +157 -0
- package/skills/data/analysis/SKILL.md +125 -0
- package/skills/data/analysis/refs/templates.md +170 -0
- package/skills/data/data/SKILL.md +118 -0
- package/skills/data/data/refs/examples.md +235 -0
- package/skills/data/ml/SKILL.md +125 -0
- package/skills/data/ml/refs/templates.md +172 -0
- package/skills/data/pipeline/SKILL.md +136 -0
- package/skills/data/pipeline/refs/templates.md +175 -0
- package/skills/data/refs/analyze.md +123 -0
- package/skills/data/refs/data.md +95 -0
- package/skills/data/refs/ml.md +118 -0
- package/skills/data/refs/pipeline.md +92 -0
- package/skills/deliberate/SKILL.md +125 -0
- package/skills/deliberate/refs/architecture-lens.md +37 -0
- package/skills/deliberate/refs/assumptions-lens.md +43 -0
- package/skills/deliberate/refs/code-lens.md +38 -0
- package/skills/deliberate/refs/content-lens.md +37 -0
- package/skills/deliberate/refs/data-lens.md +43 -0
- package/skills/deliberate/refs/design-lens.md +37 -0
- package/skills/deliberate/refs/opportunity-patterns.md +107 -0
- package/skills/deliberate/refs/ops-lens.md +43 -0
- package/skills/deliberate/refs/product-lens.md +46 -0
- package/skills/deliberate/refs/rethink-framework.md +77 -0
- package/skills/deliberate/refs/security-lens.md +47 -0
- package/skills/deliberate/refs/testing-lens.md +45 -0
- package/skills/deliberate/refs/timing-lens.md +42 -0
- package/skills/engineering/architecture/SKILL.md +177 -0
- package/skills/engineering/architecture/refs/adr-template.md +268 -0
- package/skills/engineering/architecture/refs/architecture-template-deployment.md +176 -0
- package/skills/engineering/architecture/refs/architecture-template-design.md +300 -0
- package/skills/engineering/architecture/refs/examples-ecommerce-analytics.md +299 -0
- package/skills/engineering/architecture/refs/examples-saas-trading.md +291 -0
- package/skills/engineering/architecture/refs/patterns-advanced.md +238 -0
- package/skills/engineering/architecture/refs/patterns-structural.md +303 -0
- package/skills/engineering/backend/SKILL.md +102 -0
- package/skills/engineering/backend/refs/checklists.md +146 -0
- package/skills/engineering/backend/refs/patterns.md +181 -0
- package/skills/engineering/debugging/SKILL.md +99 -0
- package/skills/engineering/debugging/refs/patterns.md +248 -0
- package/skills/engineering/debugging/refs/process.md +203 -0
- package/skills/engineering/docs/SKILL.md +97 -0
- package/skills/engineering/engineering/SKILL.md +88 -0
- package/skills/engineering/engineering/refs/checklists.md +91 -0
- package/skills/engineering/engineering/refs/templates.md +71 -0
- package/skills/engineering/frontend/SKILL.md +92 -0
- package/skills/engineering/frontend/refs/checklists.md +96 -0
- package/skills/engineering/frontend/refs/patterns.md +167 -0
- package/skills/engineering/integration/SKILL.md +183 -0
- package/skills/engineering/integration/refs/error-handling-best-practices.md +139 -0
- package/skills/engineering/integration/refs/error-handling-error-classes-typescript.md +212 -0
- package/skills/engineering/integration/refs/error-handling-error-response-format.md +301 -0
- package/skills/engineering/integration/refs/error-handling-retry-strategies.md +190 -0
- package/skills/engineering/integration/refs/event-schemas-best-practices.md +225 -0
- package/skills/engineering/integration/refs/event-schemas-event-naming-conventions.md +303 -0
- package/skills/engineering/integration/refs/event-schemas-event-structure.md +288 -0
- package/skills/engineering/integration/refs/graphql-best-practices.md +138 -0
- package/skills/engineering/integration/refs/graphql-error-handling.md +198 -0
- package/skills/engineering/integration/refs/graphql-graphql-basics.md +197 -0
- package/skills/engineering/integration/refs/graphql-query-examples.md +226 -0
- package/skills/engineering/integration/refs/graphql-schema-design-patterns.md +280 -0
- package/skills/engineering/integration/refs/grpc-grpc-overview.md +246 -0
- package/skills/engineering/integration/refs/grpc-implementation-examples.md +269 -0
- package/skills/engineering/integration/refs/grpc-metadata-headers.md +304 -0
- package/skills/engineering/integration/refs/grpc-testing.md +49 -0
- package/skills/engineering/integration/refs/openapi-template.yaml +682 -0
- package/skills/engineering/integration/refs/resilience-best-practices.md +109 -0
- package/skills/engineering/integration/refs/resilience-circuit-breaker-pattern.md +302 -0
- package/skills/engineering/integration/refs/resilience-rate-limiting.md +245 -0
- package/skills/engineering/integration/refs/resilience-timeout-pattern.md +212 -0
- package/skills/engineering/integration/refs/rest-api-fundamentals.md +299 -0
- package/skills/engineering/integration/refs/rest-api-responses-security.md +302 -0
- package/skills/engineering/integration/refs/versioning-breaking-changes.md +237 -0
- package/skills/engineering/integration/refs/versioning-migration-strategies.md +257 -0
- package/skills/engineering/integration/refs/versioning-versioning-strategies.md +296 -0
- package/skills/engineering/large-scale-migration/SKILL.md +65 -0
- package/skills/engineering/patch/SKILL.md +184 -0
- package/skills/engineering/refs/arch.md +126 -0
- package/skills/engineering/refs/debug.md +142 -0
- package/skills/engineering/refs/docs.md +190 -0
- package/skills/engineering/refs/plan.md +109 -0
- package/skills/engineering/refs/review.md +138 -0
- package/skills/engineering/system-design/SKILL.md +154 -0
- package/skills/engineering/system-design/refs/anti-patterns-big-ball-of-mud.md +254 -0
- package/skills/engineering/system-design/refs/anti-patterns-circular-dependencies.md +241 -0
- package/skills/engineering/system-design/refs/anti-patterns-feature-envy.md +168 -0
- package/skills/engineering/system-design/refs/anti-patterns-god-object.md +247 -0
- package/skills/engineering/system-design/refs/component-template-lifecycle.md +210 -0
- package/skills/engineering/system-design/refs/component-template-maintenance.md +219 -0
- package/skills/engineering/system-design/refs/component-template-structure.md +276 -0
- package/skills/engineering/system-design/refs/dependencies-best-practices.md +260 -0
- package/skills/engineering/system-design/refs/dependencies-dependency-principles.md +295 -0
- package/skills/engineering/system-design/refs/dependencies-dependency-tracking.md +261 -0
- package/skills/engineering/system-design/refs/interface-template-lifecycle.md +211 -0
- package/skills/engineering/system-design/refs/interface-template-maintenance.md +212 -0
- package/skills/engineering/system-design/refs/interface-template-structure.md +269 -0
- package/skills/engineering/system-design/refs/patterns-dependency-injection.md +151 -0
- package/skills/engineering/system-design/refs/patterns-facade-pattern.md +257 -0
- package/skills/engineering/system-design/refs/patterns-layered-pattern.md +204 -0
- package/skills/engineering/system-design/refs/patterns-plugin-architecture.md +229 -0
- package/skills/engineering/unit-test-quality/SKILL.md +194 -0
- package/skills/ground/SKILL.md +130 -0
- package/skills/integration-discovery/SKILL.md +168 -0
- package/skills/integration-discovery/refs/capabilities.md +282 -0
- package/skills/integration-discovery/refs/cli-detection.md +295 -0
- package/skills/integration-discovery/refs/discovery-sources.md +233 -0
- package/skills/integration-discovery/refs/task-patterns.md +206 -0
- package/skills/jam/SKILL.md +45 -0
- package/skills/jam/refs/facilitation-patterns.md +125 -0
- package/skills/jam/refs/quick.md +64 -0
- package/skills/jam/refs/synthesis-patterns.md +114 -0
- package/skills/multi-model/SKILL.md +168 -0
- package/skills/multi-model/refs/aichat.md +119 -0
- package/skills/multi-model/refs/aider.md +100 -0
- package/skills/multi-model/refs/auditability.md +238 -0
- package/skills/multi-model/refs/codex.md +169 -0
- package/skills/multi-model/refs/context.md +306 -0
- package/skills/multi-model/refs/copilot.md +161 -0
- package/skills/multi-model/refs/examples.md +224 -0
- package/skills/multi-model/refs/gemini.md +185 -0
- package/skills/multi-model/refs/goose.md +112 -0
- package/skills/multi-model/refs/llm.md +124 -0
- package/skills/multi-model/refs/opencode.md +196 -0
- package/skills/multi-model/refs/orchestration.md +188 -0
- package/skills/multi-model/refs/pi.md +208 -0
- package/skills/persona/SKILL.md +144 -0
- package/skills/persona/refs/define.md +133 -0
- package/skills/platform/actions/refs/actions.md +114 -0
- package/skills/platform/audit/SKILL.md +174 -0
- package/skills/platform/audit/refs/audit.md +145 -0
- package/skills/platform/audit/refs/checklists-evidence-operations.md +144 -0
- package/skills/platform/audit/refs/checklists-gdpr-pci-evidence.md +213 -0
- package/skills/platform/audit/refs/checklists-soc2-hipaa.md +120 -0
- package/skills/platform/audit/refs/frameworks-gdpr-pci.md +225 -0
- package/skills/platform/audit/refs/frameworks-soc2-hipaa.md +228 -0
- package/skills/platform/compliance/SKILL.md +169 -0
- package/skills/platform/compliance/refs/checklists.md +303 -0
- package/skills/platform/compliance/refs/compliance.md +117 -0
- package/skills/platform/compliance/refs/frameworks.md +282 -0
- package/skills/platform/errors/SKILL.md +183 -0
- package/skills/platform/errors/refs/patterns.md +271 -0
- package/skills/platform/errors/refs/severity.md +264 -0
- package/skills/platform/gate-benchmark-rebaseline/SKILL.md +108 -0
- package/skills/platform/gh/refs/gh.md +105 -0
- package/skills/platform/gh-cli/SKILL.md +120 -0
- package/skills/platform/gh-cli/refs/automation.md +63 -0
- package/skills/platform/gh-cli/refs/gh-ops.md +103 -0
- package/skills/platform/gh-cli/refs/patterns.md +132 -0
- package/skills/platform/gh-cli/scripts/gh_ops.py +454 -0
- package/skills/platform/github-actions/SKILL.md +159 -0
- package/skills/platform/github-actions/refs/security.md +150 -0
- package/skills/platform/github-actions/refs/templates.md +230 -0
- package/skills/platform/github-actions/refs/troubleshooting.md +174 -0
- package/skills/platform/github-actions/scripts/workflow_gen.py +215 -0
- package/skills/platform/gitlab-ci/SKILL.md +140 -0
- package/skills/platform/gitlab-ci/refs/templates.md +223 -0
- package/skills/platform/gitlab-ci/refs/troubleshooting.md +213 -0
- package/skills/platform/glab-cli/SKILL.md +133 -0
- package/skills/platform/glab-cli/refs/ci-debugging.md +95 -0
- package/skills/platform/glab-cli/refs/glab-ops.md +78 -0
- package/skills/platform/glab-cli/refs/patterns.md +131 -0
- package/skills/platform/glab-cli/scripts/glab_ops.py +313 -0
- package/skills/platform/health/SKILL.md +177 -0
- package/skills/platform/health/refs/health.md +72 -0
- package/skills/platform/health/refs/sources.md +302 -0
- package/skills/platform/incident/refs/incident.md +136 -0
- package/skills/platform/infra/refs/infra.md +104 -0
- package/skills/platform/observability/SKILL.md +128 -0
- package/skills/platform/observability/refs/toolchain-discovery.md +243 -0
- package/skills/platform/prereq-doctor/SKILL.md +57 -0
- package/skills/platform/prereq-doctor/refs/tool-registry.md +58 -0
- package/skills/platform/traces/refs/traces.md +101 -0
- package/skills/product/acceptance-criteria/SKILL.md +193 -0
- package/skills/product/acceptance-criteria/refs/ac-anti-patterns.md +291 -0
- package/skills/product/acceptance-criteria/refs/ac-examples.md +277 -0
- package/skills/product/accessibility/SKILL.md +197 -0
- package/skills/product/accessibility/refs/aria-patterns-basics.md +250 -0
- package/skills/product/accessibility/refs/aria-patterns-dynamic.md +187 -0
- package/skills/product/accessibility/refs/aria-patterns-interactive.md +246 -0
- package/skills/product/accessibility/refs/audit-report-findings.md +248 -0
- package/skills/product/accessibility/refs/audit-report-results.md +276 -0
- package/skills/product/accessibility/refs/common-violations-html-css.md +270 -0
- package/skills/product/accessibility/refs/common-violations-interactive.md +303 -0
- package/skills/product/accessibility/refs/keyboard-testing-basics.md +222 -0
- package/skills/product/accessibility/refs/keyboard-testing-patterns.md +173 -0
- package/skills/product/accessibility/refs/screen-reader-testing-advanced.md +294 -0
- package/skills/product/accessibility/refs/screen-reader-testing-commands.md +255 -0
- package/skills/product/accessibility/refs/wcag-checklist.md +262 -0
- package/skills/product/analyze/SKILL.md +164 -0
- package/skills/product/analyze/refs/algorithms.md +238 -0
- package/skills/product/analyze/refs/sentiment-patterns.md +180 -0
- package/skills/product/imagery/SKILL.md +97 -0
- package/skills/product/imagery/alter/SKILL.md +105 -0
- package/skills/product/imagery/alter/refs/editing-reference.md +146 -0
- package/skills/product/imagery/create/SKILL.md +109 -0
- package/skills/product/imagery/create/refs/prompt-engineering.md +112 -0
- package/skills/product/imagery/create/refs/provider-reference.md +219 -0
- package/skills/product/imagery/review/SKILL.md +101 -0
- package/skills/product/imagery/review/refs/analysis-lenses.md +136 -0
- package/skills/product/imagery/review/refs/quality-gates.md +153 -0
- package/skills/product/imagery/scripts/analyze.sh +23 -0
- package/skills/product/imagery/scripts/edit.sh +14 -0
- package/skills/product/imagery/scripts/generate.sh +13 -0
- package/skills/product/imagery/scripts/provider.py +787 -0
- package/skills/product/listen/SKILL.md +175 -0
- package/skills/product/listen/refs/channels.md +220 -0
- package/skills/product/mockup/SKILL.md +106 -0
- package/skills/product/mockup/refs/templates.md +95 -0
- package/skills/product/refs/a11y.md +109 -0
- package/skills/product/refs/acceptance.md +79 -0
- package/skills/product/refs/align.md +67 -0
- package/skills/product/refs/analyze.md +77 -0
- package/skills/product/refs/elicit.md +67 -0
- package/skills/product/refs/listen.md +58 -0
- package/skills/product/refs/mockup.md +77 -0
- package/skills/product/refs/screenshot.md +59 -0
- package/skills/product/refs/strategy.md +77 -0
- package/skills/product/refs/synthesize.md +54 -0
- package/skills/product/refs/ux-review.md +68 -0
- package/skills/product/refs/ux.md +101 -0
- package/skills/product/requirements-analysis/SKILL.md +136 -0
- package/skills/product/requirements-analysis/refs/requirements-example-auth.md +264 -0
- package/skills/product/requirements-analysis/refs/requirements-example-export-integration.md +88 -0
- package/skills/product/requirements-analysis/refs/requirements-output-format-template.md +247 -0
- package/skills/product/requirements-analysis/refs/user-story-guide.md +296 -0
- package/skills/product/requirements-graph/SKILL.md +155 -0
- package/skills/product/requirements-graph/refs/examples.md +223 -0
- package/skills/product/requirements-graph/refs/schema.md +162 -0
- package/skills/product/requirements-migrate/SKILL.md +90 -0
- package/skills/product/requirements-navigate/SKILL.md +141 -0
- package/skills/product/requirements-navigate/refs/meta-templates.md +141 -0
- package/skills/product/screenshot/SKILL.md +147 -0
- package/skills/product/strategy/SKILL.md +198 -0
- package/skills/product/strategy/refs/frameworks.md +295 -0
- package/skills/product/strategy/refs/templates-competitive-market.md +299 -0
- package/skills/product/strategy/refs/templates-roi-value.md +207 -0
- package/skills/product/synthesize/SKILL.md +116 -0
- package/skills/product/synthesize/refs/journey-mapping.md +212 -0
- package/skills/product/synthesize/refs/prioritization.md +193 -0
- package/skills/product/ux-review/SKILL.md +164 -0
- package/skills/product/visual-direction/SKILL.md +137 -0
- package/skills/product/visual-review/SKILL.md +131 -0
- package/skills/runtime-exec/SKILL.md +138 -0
- package/skills/search/codebase-narrator/SKILL.md +131 -0
- package/skills/search/codebase-narrator/refs/output-template.md +100 -0
- package/skills/smaht/SKILL.md +72 -0
- package/skills/smaht/discovery/SKILL.md +65 -0
- package/skills/smaht/intent/SKILL.md +89 -0
- package/skills/smaht/propose-skills/SKILL.md +142 -0
- package/skills/smaht/refs/state.md +76 -0
- package/skills/swarm/SKILL.md +132 -0
- package/skills/swarm/refs/fan-out.md +104 -0
- package/skills/swarm/refs/independent-verification.md +86 -0
- package/skills/swarm/refs/receipts-and-evidence.md +69 -0
- package/skills/swarm/refs/recon-synthesis.md +87 -0
- package/skills/swarm/refs/ship-discipline.md +90 -0
- package/skills/wickedizer/SKILL.md +147 -0
- package/skills/wickedizer/refs/artifact-types.md +238 -0
- package/skills/wickedizer/refs/complexity.md +278 -0
- package/skills/wickedizer/refs/de-ai-pass.md +140 -0
- package/skills/wickedizer/refs/failure-modes.md +249 -0
- package/skills/wickedizer/refs/patterns.md +282 -0
- package/skills/wickedizer/refs/review.md +221 -0
- package/skills/wickedizer/refs/structure.md +282 -0
- package/skills/wickedizer/refs/voice-profile.md +125 -0
- package/skills/workflow/SKILL.md +132 -0
- package/skills/workflow/refs/archetype-adjustments.md +205 -0
- package/skills/workflow/refs/evidence.md +58 -0
- package/skills/workflow/refs/integration.md +130 -0
- package/skills/workflow/refs/risk-dimension-signals.md +260 -0
- package/skills/workflow/refs/scoring-rubric.md +49 -0
- package/skills/workflow/refs/signal-keywords.md +176 -0
- package/skills/workflow/refs/specialist-routing-rules.md +159 -0
- package/skills/worktrees/SKILL.md +87 -0
- package/skills/worktrees/refs/recipes.md +96 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""compile.py — the wicked-garden compiler emit stage.
|
|
3
|
+
|
|
4
|
+
Phase 0 proved a single repo-agnostic detector can infer a repo's bindings
|
|
5
|
+
(``detect.py``) and that detect→declare-contract→record→cross-check works
|
|
6
|
+
end-to-end (``wire_vault.py``). But ``wire_vault`` is a *probe*: it cleans up
|
|
7
|
+
after itself, leaving the target repo untouched. This is the *emitter*: it
|
|
8
|
+
writes a **persistent, self-contained harness** into the target repo.
|
|
9
|
+
|
|
10
|
+
The thesis, made concrete:
|
|
11
|
+
|
|
12
|
+
wicked-garden = a compiler that emits a small repo-native harness
|
|
13
|
+
= compiled bindings + compiled enforcement + a trigger
|
|
14
|
+
over a *utility* (wicked-vault) it never compiles.
|
|
15
|
+
|
|
16
|
+
What gets emitted into ``<repo>/.wicked/``:
|
|
17
|
+
|
|
18
|
+
- ``bindings.json`` — the detected bindings (provenance; what we saw).
|
|
19
|
+
- ``contract.json`` — the vault contract: the repo's real test command,
|
|
20
|
+
pinned, as a ``tests-pass`` claim → ``exit_code_eq:0``.
|
|
21
|
+
This is the **compiled binding**.
|
|
22
|
+
- ``gate.py`` — a stdlib-only, dependency-free harness that resolves
|
|
23
|
+
the vault via ``npx`` (or ``WICKED_VAULT_BIN``), then
|
|
24
|
+
init → declare-contract → record --run → cross-check.
|
|
25
|
+
Exit 0 == the build's claims re-derive. This is the
|
|
26
|
+
**compiled enforcement** + the **trigger** a CI step or
|
|
27
|
+
pre-commit hook invokes. It imports NOTHING from
|
|
28
|
+
wicked-garden — the garden compiled it and left.
|
|
29
|
+
- ``README.md`` — what this is and how to wire it into CI / pre-commit.
|
|
30
|
+
|
|
31
|
+
The on-switch rule holds: the vault (the *tool*) is resolved at runtime via
|
|
32
|
+
npx and is fully skippable by the operator; its *trigger* (gate.py in CI) is
|
|
33
|
+
what the compiler bakes in and what is not skippable once wired.
|
|
34
|
+
|
|
35
|
+
Stdlib-only. The emitted gate is stdlib-only too, so it runs in any repo's
|
|
36
|
+
CI with zero deps beyond node+npx (which the vault needs anyway).
|
|
37
|
+
"""
|
|
38
|
+
from __future__ import annotations
|
|
39
|
+
|
|
40
|
+
import json
|
|
41
|
+
import sys
|
|
42
|
+
from pathlib import Path
|
|
43
|
+
|
|
44
|
+
_HERE = Path(__file__).resolve().parent
|
|
45
|
+
sys.path.insert(0, str(_HERE / "phase0"))
|
|
46
|
+
import detect as _detect # noqa: E402 (phase0/detect.py — the proven binding detector)
|
|
47
|
+
import emit as _emit # noqa: E402 (phase0/emit.py — the claims-vs-evidence lint renderer)
|
|
48
|
+
|
|
49
|
+
# A detected test command below this confidence is emitted but flagged: the
|
|
50
|
+
# harness still works, but a human should confirm the command is right.
|
|
51
|
+
_LOW_CONFIDENCE = 0.6
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ---------------------------------------------------------------------------
|
|
55
|
+
# Binding → contract
|
|
56
|
+
# ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
# Each detected command becomes one required claim. `tests-pass` is the core
|
|
59
|
+
# claim and is always present (flagged unconfigured if no test command was
|
|
60
|
+
# found); lint/build claims are added only when actually detected — pinning a
|
|
61
|
+
# command the repo doesn't have would make the gate fail forever.
|
|
62
|
+
_CLAIM_MAP = [
|
|
63
|
+
("tests-pass", "test-run", "test_command", True),
|
|
64
|
+
("lint-clean", "lint-run", "lint_command", False),
|
|
65
|
+
("build-clean", "build-run", "build_command", False),
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def claim_specs(bindings: dict) -> list[dict]:
|
|
70
|
+
"""Detected commands → claim specs {claim_id, kind, command, source, confidence}."""
|
|
71
|
+
specs = []
|
|
72
|
+
for claim_id, kind, key, always in _CLAIM_MAP:
|
|
73
|
+
b = bindings.get(key) or {}
|
|
74
|
+
cmd = b.get("value")
|
|
75
|
+
if always or cmd:
|
|
76
|
+
specs.append({
|
|
77
|
+
"claim_id": claim_id, "kind": kind, "command": cmd,
|
|
78
|
+
"source": b.get("source"), "confidence": b.get("confidence"),
|
|
79
|
+
})
|
|
80
|
+
# claims_surface: when the repo carries structured `claims:` docs (the
|
|
81
|
+
# command_iq shape), emit a claims-lint and gate on it too — every
|
|
82
|
+
# success-claim in the docs must point to backing evidence. The lint is
|
|
83
|
+
# just another verifiable command; the vault re-derives it like the rest.
|
|
84
|
+
cs = bindings.get("claims_surface") or {}
|
|
85
|
+
if cs.get("value") == "frontmatter":
|
|
86
|
+
specs.append({
|
|
87
|
+
"claim_id": "claims-backed", "kind": "claims-lint",
|
|
88
|
+
"command": "python3 .wicked/claims_lint.py",
|
|
89
|
+
"source": cs.get("source"), "confidence": cs.get("confidence"),
|
|
90
|
+
})
|
|
91
|
+
return specs
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def derive_contract(bindings: dict) -> dict:
|
|
95
|
+
"""Turn detected bindings into a multi-claim wicked-vault contract spec.
|
|
96
|
+
|
|
97
|
+
Each detected command (test / lint / build) becomes a required claim
|
|
98
|
+
pinned (G8) to an ``exit_code_eq:0`` verifier. The gate then means "this
|
|
99
|
+
build is actually clean" — re-derived at gate time — not merely "tests ran".
|
|
100
|
+
"""
|
|
101
|
+
specs = claim_specs(bindings)
|
|
102
|
+
required = [
|
|
103
|
+
{
|
|
104
|
+
"claim_id": s["claim_id"],
|
|
105
|
+
"kind": s["kind"],
|
|
106
|
+
"source_pin": s["command"],
|
|
107
|
+
"verifier": {"kind": "exit_code_eq", "params": {"code": 0}},
|
|
108
|
+
"required": True,
|
|
109
|
+
}
|
|
110
|
+
for s in specs
|
|
111
|
+
]
|
|
112
|
+
return {
|
|
113
|
+
"required_evidence": required,
|
|
114
|
+
"origin": "wicked-garden:compiler:emit",
|
|
115
|
+
"_provenance": {
|
|
116
|
+
"ecosystem": bindings["test_command"].get("ecosystem"),
|
|
117
|
+
"claims": {s["claim_id"]: {"command": s["command"],
|
|
118
|
+
"source": s["source"],
|
|
119
|
+
"confidence": s["confidence"]} for s in specs},
|
|
120
|
+
"test_command_ambiguity": bindings["test_command"].get("ambiguity"),
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# ---------------------------------------------------------------------------
|
|
126
|
+
# The emitted harness (self-contained; imports nothing from wicked-garden)
|
|
127
|
+
# ---------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
_GATE_TEMPLATE = '''#!/usr/bin/env python3
|
|
130
|
+
"""gate.py — EMITTED by the wicked-garden compiler. DO NOT hand-edit bindings.
|
|
131
|
+
|
|
132
|
+
A repo-native build gate. It re-derives this build's claims against frozen
|
|
133
|
+
acceptance criteria using wicked-vault — it never trusts a cached or
|
|
134
|
+
self-asserted "done". This script depends on NOTHING but the Python stdlib
|
|
135
|
+
and a resolvable wicked-vault CLI (via npx, or the WICKED_VAULT_BIN env).
|
|
136
|
+
wicked-garden is not required to run it.
|
|
137
|
+
|
|
138
|
+
Flow: init (idempotent) -> declare-contract (.wicked/contract.json)
|
|
139
|
+
-> record --run each claim's command (capture fresh exit codes NOW)
|
|
140
|
+
-> cross-check (re-run the pure verifiers; exit 0 == all PASS).
|
|
141
|
+
|
|
142
|
+
Usage:
|
|
143
|
+
python3 .wicked/gate.py # record a fresh run, then gate
|
|
144
|
+
python3 .wicked/gate.py --check # gate on existing evidence (no new run)
|
|
145
|
+
python3 .wicked/gate.py --dry-run # print compiled bindings, do nothing
|
|
146
|
+
"""
|
|
147
|
+
from __future__ import annotations
|
|
148
|
+
|
|
149
|
+
import json
|
|
150
|
+
import os
|
|
151
|
+
import shutil
|
|
152
|
+
import subprocess # noqa: S404 — argv lists, shell=False
|
|
153
|
+
import sys
|
|
154
|
+
from pathlib import Path
|
|
155
|
+
|
|
156
|
+
# ---- COMPILED BINDINGS (repo-specific; emitted, not hand-written) ----
|
|
157
|
+
REPO = {repo!r}
|
|
158
|
+
SCOPE = {scope!r}
|
|
159
|
+
PHASE = "build"
|
|
160
|
+
# Each claim: re-derived by running `command` and checking it exits 0.
|
|
161
|
+
CLAIMS = {claims!r}
|
|
162
|
+
# ----------------------------------------------------------------------
|
|
163
|
+
|
|
164
|
+
_ROOT = Path(__file__).resolve().parent.parent # repo root (.wicked/ is one down)
|
|
165
|
+
_CONTRACT = Path(__file__).resolve().parent / "contract.json"
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _vault_prefix():
|
|
169
|
+
"""Resolve the wicked-vault CLI argv prefix. npx is the portable fallback,
|
|
170
|
+
so this harness works on a fresh checkout. WICKED_VAULT_BIN set-but-empty
|
|
171
|
+
is a kill-switch: disables resolution (the gate then fails closed)."""
|
|
172
|
+
if "WICKED_VAULT_BIN" in os.environ:
|
|
173
|
+
env = os.environ["WICKED_VAULT_BIN"].strip()
|
|
174
|
+
if not env:
|
|
175
|
+
return None # kill-switch
|
|
176
|
+
return ["node", env] if env.endswith((".mjs", ".js")) else [env]
|
|
177
|
+
found = shutil.which("wicked-vault")
|
|
178
|
+
if found:
|
|
179
|
+
return [found]
|
|
180
|
+
if shutil.which("npx"):
|
|
181
|
+
return ["npx", "--yes", "wicked-vault"]
|
|
182
|
+
return None
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _vault(prefix, args, timeout=600):
|
|
186
|
+
try:
|
|
187
|
+
proc = subprocess.run( # noqa: S603 — argv list, shell=False
|
|
188
|
+
prefix + args, cwd=str(_ROOT), capture_output=True, text=True, timeout=timeout,
|
|
189
|
+
)
|
|
190
|
+
except FileNotFoundError:
|
|
191
|
+
# node/npx/wicked-vault not on PATH — fail closed, don't crash.
|
|
192
|
+
return 127, {{"error": "wicked-vault executable not found"}}
|
|
193
|
+
out = proc.stdout.strip()
|
|
194
|
+
try:
|
|
195
|
+
parsed = json.loads(out) if out else {{}}
|
|
196
|
+
except json.JSONDecodeError:
|
|
197
|
+
parsed = {{"_raw": out, "_stderr": proc.stderr.strip()[:400]}}
|
|
198
|
+
return proc.returncode, parsed
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def main(argv) -> int:
|
|
202
|
+
dry = "--dry-run" in argv
|
|
203
|
+
check_only = "--check" in argv
|
|
204
|
+
|
|
205
|
+
if dry:
|
|
206
|
+
print(json.dumps({{
|
|
207
|
+
"repo": REPO, "scope": SCOPE, "phase": PHASE, "claims": CLAIMS,
|
|
208
|
+
"contract": json.loads(_CONTRACT.read_text()) if _CONTRACT.exists() else None,
|
|
209
|
+
}}, indent=2))
|
|
210
|
+
return 0
|
|
211
|
+
|
|
212
|
+
prefix = _vault_prefix()
|
|
213
|
+
if prefix is None:
|
|
214
|
+
print(json.dumps({{"gate": "unavailable",
|
|
215
|
+
"error": "wicked-vault not resolvable (need npx or WICKED_VAULT_BIN); "
|
|
216
|
+
"install: npm i -g wicked-vault"}}))
|
|
217
|
+
return 1 # fail closed — never self-assert a PASS
|
|
218
|
+
|
|
219
|
+
_vault(prefix, ["init"]) # idempotent
|
|
220
|
+
if _CONTRACT.exists():
|
|
221
|
+
_vault(prefix, ["declare-contract", "--scope", SCOPE, "--phase", PHASE,
|
|
222
|
+
"--spec", str(_CONTRACT)])
|
|
223
|
+
|
|
224
|
+
if not check_only:
|
|
225
|
+
runnable = [c for c in CLAIMS if c.get("command")]
|
|
226
|
+
if not runnable:
|
|
227
|
+
print(json.dumps({{"gate": "unconfigured",
|
|
228
|
+
"error": "no runnable command was detected for any claim; "
|
|
229
|
+
"edit .wicked/gate.py + contract.json"}}))
|
|
230
|
+
return 1
|
|
231
|
+
for c in runnable:
|
|
232
|
+
_vault(prefix, ["record", "--scope", SCOPE, "--phase", PHASE,
|
|
233
|
+
"--claim", c["claim"], "--kind", c["kind"],
|
|
234
|
+
"--source", c["command"],
|
|
235
|
+
"--criteria", c["claim"] + ": `" + c["command"] + "` exits 0",
|
|
236
|
+
"--verifier", "exit_code_eq:0", "--run"])
|
|
237
|
+
|
|
238
|
+
rc, cc = _vault(prefix, ["cross-check", "--scope", SCOPE, "--phase", PHASE])
|
|
239
|
+
overall = cc.get("overall") if isinstance(cc, dict) else None
|
|
240
|
+
print(json.dumps({{"gate": "vault-cross-check", "overall": overall,
|
|
241
|
+
"scope": SCOPE, "phase": PHASE,
|
|
242
|
+
"claims": cc.get("claims") if isinstance(cc, dict) else None}},
|
|
243
|
+
indent=2))
|
|
244
|
+
return 0 if overall == "PASS" else 1
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
if __name__ == "__main__":
|
|
248
|
+
raise SystemExit(main(sys.argv[1:]))
|
|
249
|
+
'''
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
_README_TEMPLATE = '''# .wicked/ — emitted build gate (wicked-garden compiler)
|
|
253
|
+
|
|
254
|
+
This directory was **emitted** by the wicked-garden compiler from this repo's
|
|
255
|
+
detected bindings. It is self-contained: the gate depends only on the Python
|
|
256
|
+
stdlib and a resolvable [wicked-vault](https://www.npmjs.com/package/wicked-vault)
|
|
257
|
+
CLI (`npx wicked-vault`). wicked-garden itself is **not** required to run it.
|
|
258
|
+
|
|
259
|
+
## What it does
|
|
260
|
+
|
|
261
|
+
`gate.py` re-derives this build's claims instead of trusting a self-asserted
|
|
262
|
+
"done": it runs each detected command (test / lint / build), captures the real
|
|
263
|
+
exit code, and re-runs a pure verifier through the vault. Exit 0 means every
|
|
264
|
+
claim re-derives.
|
|
265
|
+
|
|
266
|
+
- **Repo:** `{repo}`
|
|
267
|
+
- **Vault scope:** `{scope}` · phase `build`
|
|
268
|
+
|
|
269
|
+
### Claims this gate re-derives
|
|
270
|
+
|
|
271
|
+
{claims_md}
|
|
272
|
+
{flag_block}{risk_block}
|
|
273
|
+
## Run it
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
python3 .wicked/gate.py # record a fresh run, then gate (exit 0 = PASS)
|
|
277
|
+
python3 .wicked/gate.py --check # gate on existing evidence, no new run
|
|
278
|
+
python3 .wicked/gate.py --dry-run # show the compiled bindings
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Wire it into CI
|
|
282
|
+
|
|
283
|
+
```yaml
|
|
284
|
+
# .github/workflows — minimal
|
|
285
|
+
- run: python3 .wicked/gate.py
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Or as a pre-push hook (`.git/hooks/pre-push`): `python3 .wicked/gate.py`.
|
|
289
|
+
|
|
290
|
+
## Files
|
|
291
|
+
|
|
292
|
+
- `bindings.json` — what the detector saw (provenance).
|
|
293
|
+
- `contract.json` — the vault contract: one required claim per detected
|
|
294
|
+
command (test / lint / build), each pinned to its command + `exit_code_eq:0`.
|
|
295
|
+
Edit this to add claims/verifiers.
|
|
296
|
+
- `gate.py` — the harness (compiled enforcement + trigger). Re-emit rather
|
|
297
|
+
than hand-editing the bindings block.
|
|
298
|
+
|
|
299
|
+
Regenerate after the repo changes shape:
|
|
300
|
+
`python3 <wicked-garden>/scripts/compiler/compile.py <repo-root>`.
|
|
301
|
+
'''
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def _claims_md(specs: list[dict]) -> str:
|
|
305
|
+
rows = []
|
|
306
|
+
for s in specs:
|
|
307
|
+
cmd = f"`{s['command']}`" if s.get("command") else "_(none detected)_"
|
|
308
|
+
rows.append(f"- `{s['claim_id']}` → {cmd} "
|
|
309
|
+
f"_({s.get('source')}, confidence {s.get('confidence')})_")
|
|
310
|
+
return "\n".join(rows)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def _risk_block(bindings: dict) -> str:
|
|
314
|
+
"""Advisory: list detected risk surfaces. Fuzzy binding — informational,
|
|
315
|
+
not enforced. Changes touching these surfaces warrant a claim."""
|
|
316
|
+
rs = bindings.get("risk_surfaces") or {}
|
|
317
|
+
surfaces = rs.get("value") or []
|
|
318
|
+
if not surfaces:
|
|
319
|
+
return ""
|
|
320
|
+
src = rs.get("from", "module structure")
|
|
321
|
+
listed = ", ".join(f"`{s}`" for s in surfaces[:12])
|
|
322
|
+
return (f"\n### Risk surfaces (advisory)\n\n"
|
|
323
|
+
f"Detected from {src}: {listed}. Changes here warrant their own "
|
|
324
|
+
f"claim + evidence — not yet enforced by this gate.\n")
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def _flag_block(bindings: dict, specs: list[dict]) -> str:
|
|
328
|
+
notes = []
|
|
329
|
+
for s in specs:
|
|
330
|
+
if s.get("command") and (s.get("confidence") or 0) < _LOW_CONFIDENCE:
|
|
331
|
+
notes.append(
|
|
332
|
+
f"- ⚠️ **Low confidence** for `{s['claim_id']}` "
|
|
333
|
+
f"(`{s['command']}`, {s.get('confidence')}). Inferred, not declared "
|
|
334
|
+
"— confirm before relying on the gate; fix in `contract.json` + `gate.py`."
|
|
335
|
+
)
|
|
336
|
+
if not s.get("command") and s["claim_id"] == "tests-pass":
|
|
337
|
+
notes.append(
|
|
338
|
+
"- ⚠️ **No test command detected** — `tests-pass` will fail closed "
|
|
339
|
+
"(MISSING) until you set a command in `contract.json` + `gate.py`."
|
|
340
|
+
)
|
|
341
|
+
tc = bindings["test_command"]
|
|
342
|
+
if tc.get("ambiguity"):
|
|
343
|
+
notes.append(f"- ⚠️ **Ambiguity:** {tc['ambiguity']} (alt: `{tc.get('alt')}`).")
|
|
344
|
+
return ("\n".join(notes) + "\n") if notes else ""
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
# ---------------------------------------------------------------------------
|
|
348
|
+
# Emit
|
|
349
|
+
# ---------------------------------------------------------------------------
|
|
350
|
+
|
|
351
|
+
def compile_repo(repo_root: str, out_subdir: str = ".wicked") -> dict:
|
|
352
|
+
"""Detect bindings and emit the harness into ``<repo>/<out_subdir>/``.
|
|
353
|
+
|
|
354
|
+
Returns a manifest: the emitted files, the derived scope, and
|
|
355
|
+
``needs_review`` (True when a binding was inferred at low confidence).
|
|
356
|
+
"""
|
|
357
|
+
root = Path(repo_root).resolve()
|
|
358
|
+
if not root.is_dir():
|
|
359
|
+
raise NotADirectoryError(f"not a directory: {root}")
|
|
360
|
+
|
|
361
|
+
bindings = _detect.detect(str(root))
|
|
362
|
+
contract = derive_contract(bindings)
|
|
363
|
+
specs = claim_specs(bindings)
|
|
364
|
+
scope = root.name
|
|
365
|
+
|
|
366
|
+
out = root / out_subdir
|
|
367
|
+
out.mkdir(parents=True, exist_ok=True)
|
|
368
|
+
|
|
369
|
+
(out / "bindings.json").write_text(json.dumps(bindings, indent=2))
|
|
370
|
+
(out / "contract.json").write_text(json.dumps(contract, indent=2))
|
|
371
|
+
|
|
372
|
+
emitted = ["bindings.json", "contract.json", "gate.py", "README.md"]
|
|
373
|
+
|
|
374
|
+
gate_claims = [{"claim": s["claim_id"], "kind": s["kind"], "command": s["command"]}
|
|
375
|
+
for s in specs]
|
|
376
|
+
(out / "gate.py").write_text(_GATE_TEMPLATE.format(
|
|
377
|
+
repo=bindings["repo"], scope=scope, claims=gate_claims,
|
|
378
|
+
))
|
|
379
|
+
|
|
380
|
+
# claims_surface consumer: emit the claims-vs-evidence lint when the repo
|
|
381
|
+
# has structured claims docs (its `claims-backed` claim runs it).
|
|
382
|
+
if (bindings.get("claims_surface") or {}).get("value") == "frontmatter":
|
|
383
|
+
(out / "claims_lint.py").write_text(_emit.render_lint(bindings))
|
|
384
|
+
emitted.append("claims_lint.py")
|
|
385
|
+
|
|
386
|
+
(out / "README.md").write_text(_README_TEMPLATE.format(
|
|
387
|
+
repo=bindings["repo"], scope=scope,
|
|
388
|
+
claims_md=_claims_md(specs), flag_block=_flag_block(bindings, specs),
|
|
389
|
+
risk_block=_risk_block(bindings),
|
|
390
|
+
))
|
|
391
|
+
|
|
392
|
+
tc = bindings["test_command"]
|
|
393
|
+
needs_review = (
|
|
394
|
+
not tc.get("value") # no test command at all
|
|
395
|
+
or any(s.get("command") and (s.get("confidence") or 0) < _LOW_CONFIDENCE
|
|
396
|
+
for s in specs)
|
|
397
|
+
or bool(tc.get("ambiguity"))
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
return {
|
|
401
|
+
"repo": bindings["repo"],
|
|
402
|
+
"root": str(root),
|
|
403
|
+
"scope": scope,
|
|
404
|
+
"out_dir": str(out),
|
|
405
|
+
"emitted": emitted,
|
|
406
|
+
"claims": {s["claim_id"]: s["command"] for s in specs},
|
|
407
|
+
"needs_review": needs_review,
|
|
408
|
+
"bindings": bindings,
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
# ---------------------------------------------------------------------------
|
|
413
|
+
# Triggers — what FIRES the gate. The gate is the compiled enforcement; a
|
|
414
|
+
# trigger is what makes it non-skippable once wired. We compile the trigger;
|
|
415
|
+
# we never compile the tool (the vault is resolved at runtime via npx).
|
|
416
|
+
# ---------------------------------------------------------------------------
|
|
417
|
+
|
|
418
|
+
_HOOK_START = "# >>> wicked-gate (managed by wicked-garden) >>>"
|
|
419
|
+
_HOOK_END = "# <<< wicked-gate <<<"
|
|
420
|
+
_HOOK_BLOCK = f'''{_HOOK_START}
|
|
421
|
+
# Re-derives this build's claims via .wicked/gate.py before allowing a push.
|
|
422
|
+
# Delete this block (or the file) to disable; edit .wicked/gate.py to retune.
|
|
423
|
+
_root="$(git rev-parse --show-toplevel 2>/dev/null)"
|
|
424
|
+
if [ -n "$_root" ] && [ -f "$_root/.wicked/gate.py" ]; then
|
|
425
|
+
python3 "$_root/.wicked/gate.py" || {{
|
|
426
|
+
echo "wicked-gate: build claims do not re-derive — push blocked." >&2
|
|
427
|
+
exit 1
|
|
428
|
+
}}
|
|
429
|
+
fi
|
|
430
|
+
{_HOOK_END}'''
|
|
431
|
+
|
|
432
|
+
_CI_MARKER = "generated-by: wicked-garden:compiler:emit"
|
|
433
|
+
|
|
434
|
+
# The vault needs node/npx everywhere; the repo's own toolchain is added per
|
|
435
|
+
# detected ecosystem so `gate.py` can actually run the test command in CI.
|
|
436
|
+
_CI_SETUP = {
|
|
437
|
+
"node": " - uses: actions/setup-node@v4\n with:\n node-version: '20'\n",
|
|
438
|
+
"go": (" - uses: actions/setup-node@v4\n with:\n node-version: '20'\n"
|
|
439
|
+
" - uses: actions/setup-go@v5\n with:\n go-version: 'stable'\n"),
|
|
440
|
+
"python": (" - uses: actions/setup-node@v4\n with:\n node-version: '20'\n"
|
|
441
|
+
" - uses: actions/setup-python@v5\n with:\n python-version: '3.x'\n"),
|
|
442
|
+
"rust": (" - uses: actions/setup-node@v4\n with:\n node-version: '20'\n"
|
|
443
|
+
" - uses: dtolnay/rust-toolchain@stable\n"),
|
|
444
|
+
}
|
|
445
|
+
_CI_SETUP_DEFAULT = (" - uses: actions/setup-node@v4\n with:\n node-version: '20'\n"
|
|
446
|
+
" # TODO: add your toolchain setup so .wicked/gate.py can run the tests\n")
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
def _ci_workflow(ecosystem: str | None) -> str:
|
|
450
|
+
setup = _CI_SETUP.get(ecosystem or "", _CI_SETUP_DEFAULT)
|
|
451
|
+
return (
|
|
452
|
+
f"# {_CI_MARKER} (safe to re-emit; edit .wicked/gate.py or contract.json instead)\n"
|
|
453
|
+
"name: wicked-gate\n"
|
|
454
|
+
"on: [push, pull_request]\n"
|
|
455
|
+
"jobs:\n"
|
|
456
|
+
" gate:\n"
|
|
457
|
+
" runs-on: ubuntu-latest\n"
|
|
458
|
+
" steps:\n"
|
|
459
|
+
" - uses: actions/checkout@v4\n"
|
|
460
|
+
f"{setup}"
|
|
461
|
+
" - name: re-derive build claims (wicked-vault)\n"
|
|
462
|
+
" run: python3 .wicked/gate.py\n"
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def _install_pre_push_hook(root: Path) -> dict:
|
|
467
|
+
git_dir = root / ".git"
|
|
468
|
+
if not git_dir.exists():
|
|
469
|
+
return {"trigger": "pre-push-hook", "status": "skipped", "reason": "not a git repo"}
|
|
470
|
+
# In submodules / worktrees, `.git` is a FILE holding a `gitdir:` pointer
|
|
471
|
+
# to the real git directory — not a directory we can mkdir hooks/ under.
|
|
472
|
+
if git_dir.is_file():
|
|
473
|
+
try:
|
|
474
|
+
content = git_dir.read_text(encoding="utf-8").strip()
|
|
475
|
+
except OSError:
|
|
476
|
+
return {"trigger": "pre-push-hook", "status": "skipped",
|
|
477
|
+
"reason": "could not read .git file"}
|
|
478
|
+
if content.startswith("gitdir:"):
|
|
479
|
+
git_dir = (root / content.split(":", 1)[1].strip()).resolve()
|
|
480
|
+
if not git_dir.is_dir():
|
|
481
|
+
return {"trigger": "pre-push-hook", "status": "skipped",
|
|
482
|
+
"reason": "resolved gitdir is not a directory"}
|
|
483
|
+
hooks = git_dir / "hooks"
|
|
484
|
+
hooks.mkdir(parents=True, exist_ok=True)
|
|
485
|
+
hook = hooks / "pre-push"
|
|
486
|
+
existing = hook.read_text(encoding="utf-8") if hook.exists() else ""
|
|
487
|
+
|
|
488
|
+
if _HOOK_START in existing:
|
|
489
|
+
# Replace our managed region in place (idempotent re-emit).
|
|
490
|
+
pre = existing.split(_HOOK_START)[0]
|
|
491
|
+
post = existing.split(_HOOK_END, 1)[1] if _HOOK_END in existing else ""
|
|
492
|
+
text, status = pre + _HOOK_BLOCK + post, "updated"
|
|
493
|
+
elif existing.strip():
|
|
494
|
+
# Foreign hook present — preserve it, append our block. Never clobber.
|
|
495
|
+
text, status = existing.rstrip() + "\n\n" + _HOOK_BLOCK + "\n", "appended"
|
|
496
|
+
else:
|
|
497
|
+
text, status = "#!/bin/sh\n" + _HOOK_BLOCK + "\n", "created"
|
|
498
|
+
|
|
499
|
+
hook.write_text(text, encoding="utf-8")
|
|
500
|
+
hook.chmod(0o755)
|
|
501
|
+
return {"trigger": "pre-push-hook", "status": status, "path": str(hook)}
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
def _install_ci_workflow(root: Path, ecosystem: str | None) -> dict:
|
|
505
|
+
wf_dir = root / ".github" / "workflows"
|
|
506
|
+
wf = wf_dir / "wicked-gate.yml"
|
|
507
|
+
if wf.exists() and _CI_MARKER not in wf.read_text(encoding="utf-8"):
|
|
508
|
+
# A foreign file owns this name — do not overwrite hand-authored CI.
|
|
509
|
+
return {"trigger": "ci-workflow", "status": "skipped",
|
|
510
|
+
"reason": "wicked-gate.yml exists but is not wicked-generated", "path": str(wf)}
|
|
511
|
+
status = "updated" if wf.exists() else "created"
|
|
512
|
+
wf_dir.mkdir(parents=True, exist_ok=True)
|
|
513
|
+
wf.write_text(_ci_workflow(ecosystem), encoding="utf-8")
|
|
514
|
+
return {"trigger": "ci-workflow", "status": status, "path": str(wf)}
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def install_triggers(repo_root: str, kinds: list[str], ecosystem: str | None = None) -> list[dict]:
|
|
518
|
+
"""Install the requested trigger surfaces. ``kinds`` ⊆ {"hook", "ci"}.
|
|
519
|
+
|
|
520
|
+
Idempotent and non-destructive: the pre-push hook appends to (never
|
|
521
|
+
clobbers) a foreign hook and replaces only its own managed block; the CI
|
|
522
|
+
workflow refuses to overwrite a same-named file it did not generate.
|
|
523
|
+
"""
|
|
524
|
+
root = Path(repo_root).resolve()
|
|
525
|
+
results = []
|
|
526
|
+
if "hook" in kinds:
|
|
527
|
+
results.append(_install_pre_push_hook(root))
|
|
528
|
+
if "ci" in kinds:
|
|
529
|
+
results.append(_install_ci_workflow(root, ecosystem))
|
|
530
|
+
return results
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
if __name__ == "__main__":
|
|
534
|
+
import argparse
|
|
535
|
+
|
|
536
|
+
p = argparse.ArgumentParser(description="wicked-garden compiler — emit a repo-native gate.")
|
|
537
|
+
p.add_argument("repo_root")
|
|
538
|
+
p.add_argument("--out", default=".wicked", help="harness subdir (default .wicked)")
|
|
539
|
+
p.add_argument("--trigger", default="",
|
|
540
|
+
help="comma list of triggers to install: hook,ci (or 'all'). "
|
|
541
|
+
"Default: emit harness only (no triggers).")
|
|
542
|
+
a = p.parse_args()
|
|
543
|
+
|
|
544
|
+
manifest = compile_repo(a.repo_root, a.out)
|
|
545
|
+
|
|
546
|
+
kinds_raw = [k.strip() for k in a.trigger.split(",") if k.strip()]
|
|
547
|
+
kinds = ["hook", "ci"] if "all" in kinds_raw else kinds_raw
|
|
548
|
+
if kinds:
|
|
549
|
+
manifest["triggers"] = install_triggers(
|
|
550
|
+
a.repo_root, kinds, ecosystem=manifest["bindings"]["test_command"].get("ecosystem"))
|
|
551
|
+
|
|
552
|
+
print(json.dumps({k: v for k, v in manifest.items() if k != "bindings"}, indent=2))
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Phase-0 Verdict — compiler falsification probe
|
|
2
|
+
|
|
3
|
+
**Result: PASS (4/4).** The compiler thesis cleared its Phase-0 bar.
|
|
4
|
+
Prototype under `scripts/compiler/phase0/` — committed as provenance, not
|
|
5
|
+
production code. The production emit stage is `scripts/compiler/compile.py`,
|
|
6
|
+
which reuses this prototype's `detect.py` and `emit.py`.
|
|
7
|
+
|
|
8
|
+
## What was tested
|
|
9
|
+
|
|
10
|
+
Can ONE repo-agnostic detector infer a repo's `test_command` + evidence
|
|
11
|
+
conventions, and can ONE emitter produce a working repo-native
|
|
12
|
+
claim→evidence lint, **without per-repo hand-correction**, across
|
|
13
|
+
structurally different repos? Falsifier: if it needs hand-correction per
|
|
14
|
+
repo, the "compiler" is really templating-with-manual-wiring.
|
|
15
|
+
|
|
16
|
+
## Targets (real repos)
|
|
17
|
+
|
|
18
|
+
| Repo | Ecosystem | Detected `test_command` | Conf | Notes |
|
|
19
|
+
|---|---|---|---|---|
|
|
20
|
+
| command_iq | node pnpm **monorepo** | `pnpm test` (→ turbo wrapper) | 0.9 | real `claims:` frontmatter + real evidence dir both detected |
|
|
21
|
+
| wicked-bus | node single-package | `npm test` (→ `vitest run`) | 0.9 | `coverage/` evidence dir detected |
|
|
22
|
+
| Enterprise-AISDLC | python | `python3 -m pytest` | 0.55 | **ambiguity flagged**: Makefile `test:` AND pytest both present |
|
|
23
|
+
| memos | **go** (foreign, no package.json) | `go test ./...` | 0.9 | clean foreign-ecosystem detection |
|
|
24
|
+
|
|
25
|
+
## Findings
|
|
26
|
+
|
|
27
|
+
1. **Detection generalized, unaided** — all 4 ecosystems, including the
|
|
28
|
+
foreign no-`package.json` Go path. The ambiguous python case was
|
|
29
|
+
*flagged* (conf 0.55), not silently guessed. This was the risky core.
|
|
30
|
+
2. **The emitter is genuinely generic** — the first emit had a UNIFORM
|
|
31
|
+
bug (mixed `N passed | M failed` evidence slipped through a
|
|
32
|
+
"tests pass" claim — the §7 "5848 pass / 4 fail → build green"
|
|
33
|
+
failure mode). ONE central fix in `emit.py` flipped all 4 repos.
|
|
34
|
+
A per-repo-rigged emitter could not be fixed by a single central edit.
|
|
35
|
+
3. **The emitted lint runs with zero wicked-garden runtime** — plain
|
|
36
|
+
stdlib python; catches missing-evidence AND contradictory-evidence
|
|
37
|
+
claims; embeds the repo's own re-verification command.
|
|
38
|
+
|
|
39
|
+
## Honest caveats (what Phase-0 did NOT prove)
|
|
40
|
+
|
|
41
|
+
- **Claims surface is the real next problem.** Only command_iq had a
|
|
42
|
+
structured `claims:` convention to detect. The other 3 fell back to
|
|
43
|
+
`commit-msg` (a stub). The lint LOGIC was proven via staged fixtures,
|
|
44
|
+
but in practice 3/4 repos have no claims doc to check. → Phase-2 emit
|
|
45
|
+
must *install* the claim+evidence convention where absent, not just
|
|
46
|
+
detect it. The compiler establishes conventions in greenfield repos.
|
|
47
|
+
- **Honest-control real-runs were mostly synthetic** (vitest invocation
|
|
48
|
+
issues; go toolchain timed out). Only python got a REAL run. The
|
|
49
|
+
fabrication-catch gate held regardless, but "detected command actually
|
|
50
|
+
executes & passes" is only truly proven for 1/4.
|
|
51
|
+
- **risk_surfaces detection was not exercised** by the lint (that's the
|
|
52
|
+
validator-pair trigger — Phase 3).
|
|
53
|
+
- n=4, narrow sample.
|
|
54
|
+
|
|
55
|
+
## Decision
|
|
56
|
+
|
|
57
|
+
Plan gate (`>=2/3 → compiler is real → proceed`) is met decisively.
|
|
58
|
+
**Proceed to Phase 2 (compiler emit stage) + Phase 1 (verb re-index +
|
|
59
|
+
re-runner) in parallel.** The sharpened Phase-2 scope: the emit stage
|
|
60
|
+
must scaffold the claims+evidence convention, since most repos lack one.
|