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,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
phase_relevance: ["design", "build"]
|
|
3
|
+
archetype_relevance: ["*"]
|
|
4
|
+
---
|
|
5
|
+
# API Versioning Guide: Migration Strategies
|
|
6
|
+
|
|
7
|
+
## Migration Strategies
|
|
8
|
+
|
|
9
|
+
### Dual-Write Pattern
|
|
10
|
+
|
|
11
|
+
Support multiple versions simultaneously.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
class UserService {
|
|
15
|
+
async createUser(data: any, version: string): Promise<User> {
|
|
16
|
+
const user = await db.users.create(data);
|
|
17
|
+
|
|
18
|
+
// Write to both old and new formats
|
|
19
|
+
if (version === '1') {
|
|
20
|
+
return this.formatV1(user);
|
|
21
|
+
} else if (version === '2') {
|
|
22
|
+
return this.formatV2(user);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private formatV1(user: User) {
|
|
27
|
+
return {
|
|
28
|
+
id: user.id,
|
|
29
|
+
name: user.name
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private formatV2(user: User) {
|
|
34
|
+
return {
|
|
35
|
+
id: user.id,
|
|
36
|
+
name: user.name,
|
|
37
|
+
email: user.email,
|
|
38
|
+
created_at: user.createdAt
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Adapter Pattern
|
|
45
|
+
|
|
46
|
+
Transform between versions.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
class V1toV2Adapter {
|
|
50
|
+
transform(v1Response: any): any {
|
|
51
|
+
return {
|
|
52
|
+
...v1Response,
|
|
53
|
+
email: v1Response.user_email, // Renamed field
|
|
54
|
+
createdAt: v1Response.created_date, // Renamed field
|
|
55
|
+
metadata: {
|
|
56
|
+
// Restructured
|
|
57
|
+
version: '2.0',
|
|
58
|
+
legacy: true
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Usage
|
|
65
|
+
app.get('/api/v2/users/:id', async (req, res) => {
|
|
66
|
+
const user = await userServiceV1.getUser(req.params.id);
|
|
67
|
+
const adapted = new V1toV2Adapter().transform(user);
|
|
68
|
+
res.json(adapted);
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Proxy Pattern
|
|
73
|
+
|
|
74
|
+
V2 proxies to V1 with transformations.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// V2 endpoint delegates to V1
|
|
78
|
+
app.get('/api/v2/users/:id', async (req, res) => {
|
|
79
|
+
// Call V1 handler
|
|
80
|
+
const v1Response = await handleV1Request(req);
|
|
81
|
+
|
|
82
|
+
// Transform to V2 format
|
|
83
|
+
const v2Response = transformV1toV2(v1Response);
|
|
84
|
+
|
|
85
|
+
res.json(v2Response);
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Deprecation Timeline
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
Month 1-3: Announce deprecation, V2 available
|
|
93
|
+
Month 4-9: V1 marked deprecated, warnings in responses
|
|
94
|
+
Month 10-12: V1 read-only, writes redirect to V2
|
|
95
|
+
Month 13+: V1 removed
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Version Management
|
|
99
|
+
|
|
100
|
+
### Default Version
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
app.use('/api/users', (req, res, next) => {
|
|
104
|
+
// Default to latest version if not specified
|
|
105
|
+
const version = req.headers['api-version'] || '2';
|
|
106
|
+
req.apiVersion = version;
|
|
107
|
+
next();
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Version Support Matrix
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
const SUPPORTED_VERSIONS = {
|
|
115
|
+
'1': {
|
|
116
|
+
status: 'deprecated',
|
|
117
|
+
sunset: '2026-01-01',
|
|
118
|
+
docs: 'https://docs.example.com/api/v1'
|
|
119
|
+
},
|
|
120
|
+
'2': {
|
|
121
|
+
status: 'current',
|
|
122
|
+
sunset: null,
|
|
123
|
+
docs: 'https://docs.example.com/api/v2'
|
|
124
|
+
},
|
|
125
|
+
'3': {
|
|
126
|
+
status: 'beta',
|
|
127
|
+
sunset: null,
|
|
128
|
+
docs: 'https://docs.example.com/api/v3'
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
app.use((req, res, next) => {
|
|
133
|
+
const version = req.apiVersion;
|
|
134
|
+
const versionInfo = SUPPORTED_VERSIONS[version];
|
|
135
|
+
|
|
136
|
+
if (!versionInfo) {
|
|
137
|
+
return res.status(400).json({
|
|
138
|
+
error: 'Unsupported API version',
|
|
139
|
+
supported_versions: Object.keys(SUPPORTED_VERSIONS)
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Add deprecation warning
|
|
144
|
+
if (versionInfo.status === 'deprecated') {
|
|
145
|
+
res.set('Warning', `299 - "API version ${version} is deprecated. Sunset: ${versionInfo.sunset}"`);
|
|
146
|
+
res.set('Sunset', versionInfo.sunset);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
next();
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Sunset Header
|
|
154
|
+
|
|
155
|
+
Communicate deprecation:
|
|
156
|
+
|
|
157
|
+
```http
|
|
158
|
+
HTTP/1.1 200 OK
|
|
159
|
+
Warning: 299 - "API v1 is deprecated. Please migrate to v2"
|
|
160
|
+
Sunset: Mon, 01 Jan 2026 00:00:00 GMT
|
|
161
|
+
Deprecation: true
|
|
162
|
+
Link: <https://docs.example.com/migration>; rel="deprecation"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## GraphQL Versioning
|
|
166
|
+
|
|
167
|
+
GraphQL uses schema evolution instead of versioning.
|
|
168
|
+
|
|
169
|
+
### Field Deprecation
|
|
170
|
+
|
|
171
|
+
```graphql
|
|
172
|
+
type User {
|
|
173
|
+
id: ID!
|
|
174
|
+
name: String!
|
|
175
|
+
fullName: String! # New field
|
|
176
|
+
|
|
177
|
+
# Deprecated field
|
|
178
|
+
user_name: String! @deprecated(reason: "Use 'name' instead")
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Schema Directives
|
|
183
|
+
|
|
184
|
+
```graphql
|
|
185
|
+
directive @apiVersion(
|
|
186
|
+
added: String!
|
|
187
|
+
deprecated: String
|
|
188
|
+
removed: String
|
|
189
|
+
) on FIELD_DEFINITION
|
|
190
|
+
|
|
191
|
+
type User {
|
|
192
|
+
id: ID!
|
|
193
|
+
name: String! @apiVersion(added: "1.0")
|
|
194
|
+
email: String! @apiVersion(added: "2.0")
|
|
195
|
+
age: Int @apiVersion(added: "1.0", deprecated: "2.0", removed: "3.0")
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## gRPC Versioning
|
|
200
|
+
|
|
201
|
+
### Package Versioning
|
|
202
|
+
|
|
203
|
+
```protobuf
|
|
204
|
+
// v1/user.proto
|
|
205
|
+
syntax = "proto3";
|
|
206
|
+
package user.v1;
|
|
207
|
+
|
|
208
|
+
service UserService {
|
|
209
|
+
rpc GetUser(GetUserRequest) returns (GetUserResponse);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// v2/user.proto
|
|
213
|
+
syntax = "proto3";
|
|
214
|
+
package user.v2;
|
|
215
|
+
|
|
216
|
+
service UserService {
|
|
217
|
+
rpc GetUser(GetUserRequest) returns (GetUserResponse);
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Field Evolution
|
|
222
|
+
|
|
223
|
+
```protobuf
|
|
224
|
+
message User {
|
|
225
|
+
string id = 1;
|
|
226
|
+
string name = 2;
|
|
227
|
+
|
|
228
|
+
// V2: Added email
|
|
229
|
+
string email = 3;
|
|
230
|
+
|
|
231
|
+
// V3: Deprecated age (use birthdate instead)
|
|
232
|
+
int32 age = 4 [deprecated = true];
|
|
233
|
+
string birthdate = 5;
|
|
234
|
+
|
|
235
|
+
// Never reuse field numbers!
|
|
236
|
+
reserved 6, 7; // Old fields
|
|
237
|
+
reserved "old_field";
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Best Practices
|
|
242
|
+
|
|
243
|
+
### 1. Version from Day One
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// Don't start with
|
|
247
|
+
/api/users
|
|
248
|
+
|
|
249
|
+
// Start with versioned endpoint
|
|
250
|
+
/api/v1/users
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### 2. Document Breaking Changes
|
|
254
|
+
|
|
255
|
+
```markdown
|
|
256
|
+
# V2 Migration Guide
|
|
257
|
+
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
---
|
|
2
|
+
phase_relevance: ["design", "build"]
|
|
3
|
+
archetype_relevance: ["*"]
|
|
4
|
+
---
|
|
5
|
+
# API Versioning Guide: Versioning Strategies
|
|
6
|
+
|
|
7
|
+
## Versioning Strategies
|
|
8
|
+
|
|
9
|
+
### URL Versioning
|
|
10
|
+
|
|
11
|
+
Most common and explicit approach.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
/api/v1/users
|
|
15
|
+
/api/v2/users
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Pros**:
|
|
19
|
+
- Explicit and visible
|
|
20
|
+
- Easy to route
|
|
21
|
+
- Browser-friendly
|
|
22
|
+
- Easy to test different versions
|
|
23
|
+
|
|
24
|
+
**Cons**:
|
|
25
|
+
- URLs change between versions
|
|
26
|
+
- Can't version individual resources differently
|
|
27
|
+
|
|
28
|
+
**Implementation**:
|
|
29
|
+
```typescript
|
|
30
|
+
// Express.js
|
|
31
|
+
app.use('/api/v1', v1Router);
|
|
32
|
+
app.use('/api/v2', v2Router);
|
|
33
|
+
|
|
34
|
+
// v1Router
|
|
35
|
+
v1Router.get('/users/:id', (req, res) => {
|
|
36
|
+
// V1 implementation
|
|
37
|
+
res.json({
|
|
38
|
+
id: user.id,
|
|
39
|
+
name: user.name
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// v2Router
|
|
44
|
+
v2Router.get('/users/:id', (req, res) => {
|
|
45
|
+
// V2 implementation (added email)
|
|
46
|
+
res.json({
|
|
47
|
+
id: user.id,
|
|
48
|
+
name: user.name,
|
|
49
|
+
email: user.email
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Header Versioning
|
|
55
|
+
|
|
56
|
+
Version specified in request headers.
|
|
57
|
+
|
|
58
|
+
```http
|
|
59
|
+
GET /api/users/123
|
|
60
|
+
Accept: application/vnd.myapi.v2+json
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
or
|
|
64
|
+
|
|
65
|
+
```http
|
|
66
|
+
GET /api/users/123
|
|
67
|
+
API-Version: 2
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Pros**:
|
|
71
|
+
- Clean URLs (don't change)
|
|
72
|
+
- Can version per-resource
|
|
73
|
+
- RESTful purist preference
|
|
74
|
+
|
|
75
|
+
**Cons**:
|
|
76
|
+
- Less visible
|
|
77
|
+
- Harder to test (can't just paste URL)
|
|
78
|
+
- More complex routing
|
|
79
|
+
|
|
80
|
+
**Implementation**:
|
|
81
|
+
```typescript
|
|
82
|
+
app.get('/api/users/:id', (req, res) => {
|
|
83
|
+
const version = req.headers['api-version'] || '1';
|
|
84
|
+
|
|
85
|
+
if (version === '1') {
|
|
86
|
+
return handleV1(req, res);
|
|
87
|
+
} else if (version === '2') {
|
|
88
|
+
return handleV2(req, res);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
res.status(400).json({ error: 'Unsupported API version' });
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Query Parameter Versioning
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
/api/users?version=2
|
|
99
|
+
/api/users?api-version=2
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Pros**:
|
|
103
|
+
- Simple to implement
|
|
104
|
+
- Visible in URL
|
|
105
|
+
- Optional parameter
|
|
106
|
+
|
|
107
|
+
**Cons**:
|
|
108
|
+
- Clutters query string
|
|
109
|
+
- Not as clean as URL versioning
|
|
110
|
+
|
|
111
|
+
### Content Negotiation
|
|
112
|
+
|
|
113
|
+
Using Accept header with custom media type.
|
|
114
|
+
|
|
115
|
+
```http
|
|
116
|
+
GET /api/users/123
|
|
117
|
+
Accept: application/vnd.myapi.user.v2+json
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Pros**:
|
|
121
|
+
- RESTful approach
|
|
122
|
+
- Fine-grained control
|
|
123
|
+
- Can version per resource type
|
|
124
|
+
|
|
125
|
+
**Cons**:
|
|
126
|
+
- Complex
|
|
127
|
+
- Difficult to debug
|
|
128
|
+
- Harder for clients to use
|
|
129
|
+
|
|
130
|
+
## Semantic Versioning
|
|
131
|
+
|
|
132
|
+
Use semantic versioning for API versions:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
MAJOR.MINOR.PATCH
|
|
136
|
+
|
|
137
|
+
2.1.3
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- **MAJOR**: Breaking changes
|
|
141
|
+
- **MINOR**: New features, backward compatible
|
|
142
|
+
- **PATCH**: Bug fixes
|
|
143
|
+
|
|
144
|
+
### Examples
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
v1.0.0 → v1.1.0 # Added new optional field
|
|
148
|
+
v1.1.0 → v1.1.1 # Fixed bug in response
|
|
149
|
+
v1.1.1 → v2.0.0 # Removed field (breaking)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### In Practice
|
|
153
|
+
|
|
154
|
+
Most APIs simplify to major version only:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
/api/v1/users
|
|
158
|
+
/api/v2/users
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Full semantic version in response headers:
|
|
162
|
+
```http
|
|
163
|
+
HTTP/1.1 200 OK
|
|
164
|
+
API-Version: 2.1.3
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Backward Compatibility
|
|
168
|
+
|
|
169
|
+
### Adding Fields (Safe)
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// V1 Response
|
|
173
|
+
{
|
|
174
|
+
"id": "123",
|
|
175
|
+
"name": "Alice"
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// V2 Response (added email - backward compatible)
|
|
179
|
+
{
|
|
180
|
+
"id": "123",
|
|
181
|
+
"name": "Alice",
|
|
182
|
+
"email": "alice@example.com" // New field
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Clients ignoring unknown fields will continue to work.
|
|
187
|
+
|
|
188
|
+
### Making Fields Optional (Safe)
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// V1 Request
|
|
192
|
+
{
|
|
193
|
+
"name": "Alice",
|
|
194
|
+
"email": "alice@example.com" // Required
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// V2 Request (email optional)
|
|
198
|
+
{
|
|
199
|
+
"name": "Alice"
|
|
200
|
+
// email is now optional
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Adding Optional Parameters (Safe)
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// V1
|
|
208
|
+
GET /api/users?limit=10
|
|
209
|
+
|
|
210
|
+
// V2 (added sort parameter)
|
|
211
|
+
GET /api/users?limit=10&sort=name
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Deprecation (Safe)
|
|
215
|
+
|
|
216
|
+
Mark fields as deprecated but keep them:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// V2 Response
|
|
220
|
+
{
|
|
221
|
+
"id": "123",
|
|
222
|
+
"name": "Alice",
|
|
223
|
+
"full_name": "Alice Smith", // New field
|
|
224
|
+
"deprecated_name": "Alice" // Deprecated, but still present
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Breaking Changes
|
|
229
|
+
|
|
230
|
+
### Removing Fields
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
// V1 Response
|
|
234
|
+
{
|
|
235
|
+
"id": "123",
|
|
236
|
+
"name": "Alice",
|
|
237
|
+
"age": 30
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// V2 Response (removed age - BREAKING)
|
|
241
|
+
{
|
|
242
|
+
"id": "123",
|
|
243
|
+
"name": "Alice"
|
|
244
|
+
// age removed
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Solution**: Keep field but deprecate it first.
|
|
249
|
+
|
|
250
|
+
### Renaming Fields
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// V1 Response
|
|
254
|
+
{
|
|
255
|
+
"user_name": "Alice"
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// V2 Response (renamed - BREAKING)
|
|
259
|
+
{
|
|
260
|
+
"username": "Alice"
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Solution**: Include both fields temporarily.
|
|
265
|
+
|
|
266
|
+
### Changing Field Types
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
// V1 Response
|
|
270
|
+
{
|
|
271
|
+
"id": 123 // number
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// V2 Response (changed to string - BREAKING)
|
|
275
|
+
{
|
|
276
|
+
"id": "123" // string
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Solution**: Create new major version.
|
|
281
|
+
|
|
282
|
+
### Changing Behavior
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// V1: Returns 404 if user not found
|
|
286
|
+
GET /api/users/999
|
|
287
|
+
Response: 404 Not Found
|
|
288
|
+
|
|
289
|
+
// V2: Returns 200 with null (BREAKING)
|
|
290
|
+
GET /api/users/999
|
|
291
|
+
Response: 200 OK
|
|
292
|
+
{ "user": null }
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Solution**: Document clearly and version.
|
|
296
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: large-scale-migration
|
|
3
|
+
description: How to execute a LARGE MECHANICAL change across any codebase with LEVERAGE instead of an agent-grind or hand-edits — a cross-cutting migration, refactor, rename, dialect/framework/DB port, library adoption, or bulk transform. The map→transform→gate pattern: a deterministic transform driven by a source-of-truth map, proven by a differential-equivalence gate. Use when the work is "migrate all X to Y", "rename Z everywhere", "port to a new DB/dialect/framework", "adopt a library across N files", "refactor this pattern in M places", or any change touching dozens-to-thousands of sites. Language/DB/framework-agnostic — the thinking, not a specific tool.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Large-scale mechanical change — leverage, not grind
|
|
7
|
+
|
|
8
|
+
A change touching dozens-to-thousands of sites is NOT N problems. It is a small number of repeated PATTERNS. Reaching for "fan out 1000 agents to edit each site", "hand-edit every file", or "sed the repo" is the paper bag. Reduce the work to **MAP → TRANSFORM → GATE** instead.
|
|
9
|
+
|
|
10
|
+
## The core pattern
|
|
11
|
+
|
|
12
|
+
1. **MAP** — the source of truth that already exists or can be **deterministically extracted**: an inventory of the affected sites, an ownership/registry table, a call graph, a schema. Build it with an **AST tool** (ts-morph, libcst, jscodeshift, tree-sitter, Roslyn…) or **semgrep** — never a regex string-grep (quote/escaping/comment blind spots), and never "an agent grepped and *thinks* it found them all." An exhaustive, reproducible map is the foundation; an approximate one ships a partial migration.
|
|
13
|
+
2. **TRANSFORM** — a **deterministic** operation over the map: a **codemod** (AST rewrite), **codegen** (emit from the map), or **regenerate** (edit a single source-of-truth + re-run a generator that produces the derived artifacts). NOT per-site LLM editing. The transform should **preserve semantics by construction** — rewrite the call *shape* while keeping the literal; move a block intact; change the *binding* not the *logic* — so correctness is structural, not hoped-for.
|
|
14
|
+
3. **GATE** — a **verifiable equivalence/green check**: **differential execution** (run old vs new on identical seeded inputs, assert identical outputs), the full test suite, or a lint count driven to 0. The change is trusted because it is **proven equivalent**, not because someone reviewed N diffs.
|
|
15
|
+
|
|
16
|
+
The bulk goes through the transform. The transform **self-flags** what it can't handle (the exceptions). Humans/agents touch **only the residue** — never the bulk.
|
|
17
|
+
|
|
18
|
+
## The TRANSFORM techniques menu (ranked: deterministic → AI)
|
|
19
|
+
|
|
20
|
+
The TRANSFORM step is not one tool — it is a ranked ladder. **Prefer the lowest-numbered technique that fully covers the task.** Determinism is cheaper to trust than generation: a recipe or codemod preserves semantics by construction and is re-runnable; an AI wave must be eval-gated every time. Mixing rungs 80/20 across one migration is fine (most go through rung 1–2, the awkward residue through 4–5). **Never reach for rung 4/5 for what a rung-1 recipe already does** — that trades a proven transform for a hoped-for one. **Record which rung you chose** per wave, so "should I use AI here?" is a defensible, auditable decision, not an implicit one.
|
|
21
|
+
|
|
22
|
+
| # | Technique | Use when |
|
|
23
|
+
|---|-----------|----------|
|
|
24
|
+
| 1 | **Recipe** (e.g. OpenRewrite, ts-morph preset, framework upgrade-assistant) | A well-known, parameterized transform already exists for this exact change (version bump, API rename, framework migration). Highest leverage, lowest risk — adopt it. |
|
|
25
|
+
| 2 | **AST codemod** (jscodeshift, libcst, tree-sitter, Roslyn, ts-morph) | No off-the-shelf recipe, but the change is a structural rewrite expressible as a tree operation (rewrite the call *shape*, move a block intact, change a binding). Deterministic, semantics-preserving by construction. |
|
|
26
|
+
| 3 | **Pattern-replace / codegen / regenerate** | The change is driven by a source-of-truth map — emit the derived artifacts from the map, or edit the single source + re-run a generator. (Structured replace only; **never** raw `sed`/regex on code — string blind spots break semantics silently.) |
|
|
27
|
+
| 4 | **AI-assisted wave (eval-gated)** | The transform needs judgment a tree op can't encode (idiomatic re-expression, semantic translation across a paradigm gap) but is still bulk-shaped. Run it in waves, each **gated by the differential-equivalence check** — never ship an AI wave on a build-green alone. |
|
|
28
|
+
| 5 | **Manual + AI pair** | Genuinely non-portable / one-off residue the transform self-flagged (cross-cutting joins, sync/async boundaries, non-portable platform features). Judgment-only, case-by-case — the *smallest* slice, never the bulk. |
|
|
29
|
+
|
|
30
|
+
The GATE is the same regardless of rung: differential equivalence (or suite-green / lint-to-0) is what makes the change trustworthy. A higher rung does not lower the bar — it raises it (rungs 4–5 need *more* fixture coverage, not less).
|
|
31
|
+
|
|
32
|
+
## Before you transform: make the INSTRUMENT trustworthy
|
|
33
|
+
You cannot drive a count to 0 if the count is a fiction. Fix the *measurement* FIRST:
|
|
34
|
+
- Does the lint/audit/inventory actually see **all** the cases? Prove it: inject a known violation and confirm it's caught. (Real failure mode: a "complete" audit that masked single-quoted strings and silently under-counted by hundreds.)
|
|
35
|
+
- Is the **baseline** the right one? Diffing the after-state against a baseline that *already contains part of the change* catches nothing — pin the true before-state.
|
|
36
|
+
|
|
37
|
+
## Buy / rewrite / build — not "write more code"
|
|
38
|
+
Solve for the OUTCOME with maximum leverage, per sub-problem:
|
|
39
|
+
- An **OSS component** that meets the requirement beats building it — a query builder, an **in-process embedded engine** for tests (so the test→fix loop needs no infra), a parser/translator. Adopt it; build only the thin seam it doesn't cover.
|
|
40
|
+
- A clean **rewrite** of a section (you have the working code as the spec) beats editing it in place across dozens of touch-points.
|
|
41
|
+
|
|
42
|
+
## The rules (non-negotiable)
|
|
43
|
+
- **No grandfathering.** "Done" = the count is 0 **AND** zero exemptions (suppressions / allow-markers / "left raw with a TODO / DEFERRAL"). Fix the code; never exempt it. An exemption is a landmine that *defeats the migration's purpose* — it preserves the exact case the migration exists to remove, and it stays invisible until it breaks.
|
|
44
|
+
- **Differential equivalence is the trust — not review.** `old(input) === new(input)` on real seeded data. Strength tracks fixture coverage → seed broadly; an empty fixture passes trivially and lies.
|
|
45
|
+
- **Residue is small, self-flagged, judgment-only.** The transform reports what it couldn't do; that list is the only place to reason case-by-case (cross-cutting joins, genuinely non-portable constructs, sync/async boundaries).
|
|
46
|
+
- **Prove the runtime — don't trust build-green.** Build/test green ≠ feature works, *especially* for LLM/agent features (the assembled context can drift while stored rows stay byte-identical → degraded reasoning / hallucination that no unit test catches). Prove the running process serves the right build; **grade** functional outputs (content correctness + faithfulness), don't just check a 200-OK.
|
|
47
|
+
- **No implicit completeness, and never narrow the DoD to skip work.** Name what is NOT done. If a phase can't reach its green gate, STOP there and name the blocker — do not declare a convenient subset "done."
|
|
48
|
+
|
|
49
|
+
## Worked example (transferable): a data-access migration → second engine
|
|
50
|
+
Goal: move ~1,900 raw `db.prepare(sql)`-style call sites behind one typed port, then run the app on a second DB engine/dialect — without hand-editing 1,900 sites or standing up infra.
|
|
51
|
+
- **MAP:** an AST extractor walks the *call expressions* (matching the call node, not string contents → no quote blind spot) → an exhaustive inventory of every query, its tables, and static-vs-dynamic shape.
|
|
52
|
+
- **TRANSFORM:** a codemod rewrites the call *shape* (e.g. positional `?` → named params; SQL literal preserved) and injects the port; the sync→async cascade propagates up the call graph; sync-boundaries self-flag for manual handling.
|
|
53
|
+
- **GATE:** a differential test runs the OLD query and the NEW port call against the **same seeded in-memory DB** and asserts byte-identical results (rows + affected-rows + resulting state). Per-module then full-suite green is the bar.
|
|
54
|
+
- **Second engine:** adopt an **in-process embedded build of the target engine** for tests (no server), translate **only** the non-portable patterns the inventory *proves* exist (dialect translation at the adapter boundary), and route truly-non-portable features (full-text, vector) behind **thin adapter interfaces**. The **cross-engine differential** (same query, both engines, equivalent) is the gate.
|
|
55
|
+
- **Same pattern, different map, per phase:** correcting an *ownership/registry map* = edit the single source-of-truth + **regenerate** the derived artifacts (never hand-edit the derivatives). Relocating code by an ownership map = a codemod keyed on that map. Isolating onto separate connections/processes = a **config flip** on a registry the port already abstracts (no code rewrite — that's the payoff of routing everything through the port first).
|
|
56
|
+
|
|
57
|
+
## Anti-patterns this kills
|
|
58
|
+
- "Fan out 1,000 agents to hand-edit each site" — context blow-up, non-deterministic, no equivalence proof.
|
|
59
|
+
- "sed / regex replace across the repo" — string blind spots, false positives, breaks semantics silently.
|
|
60
|
+
- "Exempt the hard ones / leave a TODO / suppress the lint" — grandfathering, the landmine.
|
|
61
|
+
- "Build green + suite green, ship it" — never proved the feature, never proved the runtime.
|
|
62
|
+
- "This subset counts as done" — narrowing the DoD to skip work.
|
|
63
|
+
|
|
64
|
+
## Pair with (if your project has them)
|
|
65
|
+
A "prove the feature works, not just build-green" discipline; a "no silent failures" discipline; and a recorded "definition of done" you refuse to narrow.
|