pi-dev-team 0.2.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/LICENSE +21 -0
- package/PORTING.md +134 -0
- package/README.md +207 -0
- package/UPSTREAM.json +64 -0
- package/agents/Explore.md +15 -0
- package/agents/a11y-review.md +118 -0
- package/agents/adr-author.md +70 -0
- package/agents/ai-provenance-review.md +120 -0
- package/agents/angular-reactivity-review.md +95 -0
- package/agents/arch-review.md +135 -0
- package/agents/architect.md +78 -0
- package/agents/autoship-batch-proposer.md +69 -0
- package/agents/claude-setup-review.md +136 -0
- package/agents/codebase-recon.md +184 -0
- package/agents/component-architecture-review.md +119 -0
- package/agents/concurrency-review.md +109 -0
- package/agents/correctness-review.md +290 -0
- package/agents/data-flow-tracer.md +120 -0
- package/agents/doc-review.md +165 -0
- package/agents/domain-review.md +136 -0
- package/agents/general-purpose.md +10 -0
- package/agents/gherkin-quality-critic.md +113 -0
- package/agents/js-fp-review.md +114 -0
- package/agents/mutation-kill.md +684 -0
- package/agents/naming-review.md +142 -0
- package/agents/orchestrator.md +339 -0
- package/agents/performance-review.md +105 -0
- package/agents/plan-review-acceptance.md +115 -0
- package/agents/plan-review-design.md +90 -0
- package/agents/plan-review-parallelization.md +84 -0
- package/agents/plan-review-strategic.md +96 -0
- package/agents/plan-review-ux.md +110 -0
- package/agents/platform-engineer.md +64 -0
- package/agents/product-manager.md +68 -0
- package/agents/progress-guardian.md +79 -0
- package/agents/qa-engineer.md +289 -0
- package/agents/quality-reviewer.md +132 -0
- package/agents/react-reactivity-review.md +102 -0
- package/agents/refactor-opportunity-review.md +128 -0
- package/agents/security-engineer.md +60 -0
- package/agents/security-review.md +218 -0
- package/agents/session-analysis.md +95 -0
- package/agents/software-engineer.md +105 -0
- package/agents/spec-compliance-review.md +100 -0
- package/agents/spec-reviewer.md +114 -0
- package/agents/structure-review.md +146 -0
- package/agents/tech-writer.md +84 -0
- package/agents/test-review.md +246 -0
- package/agents/test-smell-review.md +188 -0
- package/agents/token-efficiency-review.md +139 -0
- package/agents/ui-ux-designer.md +54 -0
- package/agents/vue-reactivity-review.md +95 -0
- package/bin/__pycache__/claudecpython-314.pyc +0 -0
- package/bin/claude +258 -0
- package/docs/upstream/.pages +1 -0
- package/docs/upstream/CHANGELOG.md +2586 -0
- package/docs/upstream/README.md +155 -0
- package/docs/upstream/agent-architecture.md +214 -0
- package/docs/upstream/agent_info.md +187 -0
- package/docs/upstream/artifact-migration.md +124 -0
- package/docs/upstream/code-intelligence-nudge.md +149 -0
- package/docs/upstream/code-review-process.md +294 -0
- package/docs/upstream/concurrent-use.md +73 -0
- package/docs/upstream/context-management.md +111 -0
- package/docs/upstream/developer-notes.md +280 -0
- package/docs/upstream/diagrams/architecture-overview.svg +101 -0
- package/docs/upstream/diagrams/review-dispatch.svg +139 -0
- package/docs/upstream/diagrams/team-agents.svg +128 -0
- package/docs/upstream/diagrams/test-improve-flow.svg +166 -0
- package/docs/upstream/diagrams/workflow-linear.svg +66 -0
- package/docs/upstream/diagrams/workflow-three-phase.svg +200 -0
- package/docs/upstream/eval-maintenance.md +95 -0
- package/docs/upstream/eval-running-guide.md +147 -0
- package/docs/upstream/eval-system.md +291 -0
- package/docs/upstream/session-review-oss-complements.md +75 -0
- package/docs/upstream/session-review.md +212 -0
- package/docs/upstream/skills.md +188 -0
- package/docs/upstream/team-structure.md +21 -0
- package/docs/upstream/telemetry-ci-access.md +129 -0
- package/docs/upstream/telemetry-repo-security.md +120 -0
- package/docs/upstream/test-evaluation.md +277 -0
- package/docs/upstream/test-improve.md +154 -0
- package/docs/upstream/triage-workflow.md +282 -0
- package/docs/upstream/workflows.md +289 -0
- package/extensions/dev-team/index.ts +539 -0
- package/extensions/dev-team/lib/agents.ts +272 -0
- package/extensions/dev-team/lib/ai-credits.ts +92 -0
- package/extensions/dev-team/lib/autocompact.ts +81 -0
- package/extensions/dev-team/lib/child-run.ts +102 -0
- package/extensions/dev-team/lib/config.ts +236 -0
- package/extensions/dev-team/lib/gh-command.ts +103 -0
- package/extensions/dev-team/lib/github-style.ts +307 -0
- package/extensions/dev-team/lib/hooks.ts +350 -0
- package/extensions/dev-team/lib/metrics.ts +115 -0
- package/extensions/dev-team/lib/safe-read.ts +49 -0
- package/extensions/dev-team/lib/session-files.ts +57 -0
- package/extensions/dev-team/lib/session-spend.ts +123 -0
- package/extensions/dev-team/lib/shell-scan.ts +205 -0
- package/extensions/dev-team/lib/skills.ts +213 -0
- package/extensions/dev-team/lib/subagent-render.ts +245 -0
- package/extensions/dev-team/lib/subagent-types.ts +164 -0
- package/extensions/dev-team/lib/subagent.ts +596 -0
- package/extensions/dev-team/lib/terminal-text.ts +54 -0
- package/extensions/dev-team/lib/tools-misc.ts +152 -0
- package/extensions/dev-team/lib/transcript.ts +110 -0
- package/extensions/dev-team/lib/trust.ts +52 -0
- package/extensions/dev-team/lib/usage-breakdown.ts +176 -0
- package/extensions/dev-team/lib/usage-chart.ts +153 -0
- package/extensions/dev-team/lib/usage-command.ts +107 -0
- package/extensions/dev-team/lib/usage-history.ts +203 -0
- package/extensions/dev-team/lib/usage-render.ts +225 -0
- package/extensions/dev-team/lib/usage-split-bar.ts +127 -0
- package/extensions/dev-team/lib/usage-state.ts +116 -0
- package/extensions/dev-team/lib/usage-text.ts +159 -0
- package/extensions/dev-team/lib/usage-view.ts +109 -0
- package/hooks/__pycache__/refactor_test_freeze_guard.cpython-314.pyc +0 -0
- package/hooks/agent_dispatch_ledger.py +190 -0
- package/hooks/autocompact_setup_nudge.py +99 -0
- package/hooks/bash_retry_guard.py +228 -0
- package/hooks/boundary_events_write_guard.py +352 -0
- package/hooks/code_intelligence_nudge.py +293 -0
- package/hooks/code_intelligence_turn_mark.py +317 -0
- package/hooks/codegraph_bootstrap.py +139 -0
- package/hooks/contract_version_guard.py +362 -0
- package/hooks/cost_meter.py +106 -0
- package/hooks/destructive-commands.json +62 -0
- package/hooks/destructive_guard.py +477 -0
- package/hooks/eval_compliance_check.py +440 -0
- package/hooks/guards.json +17 -0
- package/hooks/hooks.json +323 -0
- package/hooks/internal_double_gate.py +296 -0
- package/hooks/js_fp_review.py +212 -0
- package/hooks/knowledge_index.py +119 -0
- package/hooks/lib/__pycache__/artifact_paths.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/atomic_state.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/autocompact_config.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/boundary_events.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/doc_classification.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/gh_pr_create_detect.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/git_safe_diff.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/instrument_log.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/metrics_query.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/plugin_version.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/pre_commit_doc_classifier.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/review_agent_registry.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/review_gate_corroboration.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/review_gate_hash.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/review_verdicts.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/stdin_json.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/stryker_invocation.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/telemetry_consent.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/test_file_classify.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/token_efficiency_limits.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/verify_guard_state.cpython-314.pyc +0 -0
- package/hooks/lib/__pycache__/xunit_v3_operator_gate.cpython-314.pyc +0 -0
- package/hooks/lib/agent_skill_hints.py +74 -0
- package/hooks/lib/artifact_paths.py +263 -0
- package/hooks/lib/atomic_state.py +557 -0
- package/hooks/lib/autocompact_config.py +103 -0
- package/hooks/lib/autoship_log.py +106 -0
- package/hooks/lib/banned_scripts_policy.py +51 -0
- package/hooks/lib/boundary_events.py +436 -0
- package/hooks/lib/build_knowledge_index.py +504 -0
- package/hooks/lib/build_skills_index.py +361 -0
- package/hooks/lib/build_state.py +116 -0
- package/hooks/lib/classify_ship_outcome.py +126 -0
- package/hooks/lib/config_changelog_schema.py +115 -0
- package/hooks/lib/cost_meter.py +955 -0
- package/hooks/lib/doc_classification.py +116 -0
- package/hooks/lib/gh_pr_create_detect.py +136 -0
- package/hooks/lib/git_safe_diff.py +123 -0
- package/hooks/lib/instrument_log.py +66 -0
- package/hooks/lib/iteration_journal_gate.py +197 -0
- package/hooks/lib/knowledge_index_paths.py +88 -0
- package/hooks/lib/mcp_json_repowise.py +177 -0
- package/hooks/lib/metrics_query.py +202 -0
- package/hooks/lib/minimal_yaml.py +434 -0
- package/hooks/lib/plugin_version.py +142 -0
- package/hooks/lib/pre_commit_detect.py +537 -0
- package/hooks/lib/pre_commit_doc_classifier.py +126 -0
- package/hooks/lib/pricing.py +118 -0
- package/hooks/lib/report_pdf.py +371 -0
- package/hooks/lib/review_agent_registry.py +142 -0
- package/hooks/lib/review_dispatch_ledger.py +101 -0
- package/hooks/lib/review_gate_corroboration.py +521 -0
- package/hooks/lib/review_gate_hash.py +252 -0
- package/hooks/lib/review_gate_normalized_hash.py +1115 -0
- package/hooks/lib/review_verdicts.py +301 -0
- package/hooks/lib/run_report.py +160 -0
- package/hooks/lib/skill_categories.yaml +125 -0
- package/hooks/lib/stdin_json.py +57 -0
- package/hooks/lib/stryker_invocation.py +102 -0
- package/hooks/lib/telemetry_consent.py +41 -0
- package/hooks/lib/telemetry_report.py +108 -0
- package/hooks/lib/test_file_classify.py +160 -0
- package/hooks/lib/token_efficiency_limits.py +51 -0
- package/hooks/lib/turn_identity.py +77 -0
- package/hooks/lib/verify_guard_state.py +110 -0
- package/hooks/lib/workflow_state.py +206 -0
- package/hooks/lib/xunit_v3_operator_gate.py +596 -0
- package/hooks/mcp_json_repowise_nudge.py +74 -0
- package/hooks/mutation_adapters/__init__.py +7 -0
- package/hooks/mutation_adapters/__pycache__/__init__.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/lib.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/mutmut.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/pitest.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/stryker.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/__pycache__/stryker_net.cpython-314.pyc +0 -0
- package/hooks/mutation_adapters/lib.py +478 -0
- package/hooks/mutation_adapters/mutmut.py +188 -0
- package/hooks/mutation_adapters/pitest.py +266 -0
- package/hooks/mutation_adapters/stryker.py +157 -0
- package/hooks/mutation_adapters/stryker_net.py +264 -0
- package/hooks/mutation_gate.py +193 -0
- package/hooks/mutation_testing_smoke_gate.py +371 -0
- package/hooks/pending_review_notify.py +121 -0
- package/hooks/phase_marker.py +138 -0
- package/hooks/post_compact_state_reinject.py +180 -0
- package/hooks/post_format.py +115 -0
- package/hooks/pre_commit_knowledge_index.py +128 -0
- package/hooks/pre_commit_review.py +66 -0
- package/hooks/pre_pr_review.py +694 -0
- package/hooks/pre_tool_guard.py +405 -0
- package/hooks/py.sh +73 -0
- package/hooks/refactor-bash-write-patterns.json +29 -0
- package/hooks/refactor_test_bash_guard.py +253 -0
- package/hooks/refactor_test_freeze_guard.py +139 -0
- package/hooks/refactor_test_revert_guard.py +186 -0
- package/hooks/repo_review_nudge.py +287 -0
- package/hooks/review_verdict_recorder.py +464 -0
- package/hooks/scan_bash_command_for_banned_scripts.py +428 -0
- package/hooks/scan_worktree_for_banned_scripts.py +238 -0
- package/hooks/session_learning_trigger.py +248 -0
- package/hooks/skills_index.py +126 -0
- package/hooks/stryker_xunit_shim_guard.py +571 -0
- package/hooks/subagent_completion_guard.py +309 -0
- package/hooks/subagent_skill_context.py +139 -0
- package/hooks/task_completion_metrics.py +216 -0
- package/hooks/tdd_guard.py +229 -0
- package/hooks/telemetry.py +341 -0
- package/hooks/token_efficiency_review.py +194 -0
- package/hooks/verify_guard.py +183 -0
- package/hooks/verify_guard_edit_marker.py +73 -0
- package/hooks/version_check.py +173 -0
- package/knowledge/accepted-risks-schema.md +98 -0
- package/knowledge/adr-decision-criteria.md +64 -0
- package/knowledge/adversarial-review-protocol.md +139 -0
- package/knowledge/agent-registry.md +228 -0
- package/knowledge/agent-review-methodology.md +80 -0
- package/knowledge/ai-friendly-repo-guidelines.md +67 -0
- package/knowledge/architecture-assessment.md +96 -0
- package/knowledge/artifact-lifecycle.md +57 -0
- package/knowledge/cd-maturity-model.md +82 -0
- package/knowledge/cd-test-architecture.md +190 -0
- package/knowledge/ci-cd-file-scope.md +24 -0
- package/knowledge/codegraph-vs-graphify.md +192 -0
- package/knowledge/component-test-patterns.md +139 -0
- package/knowledge/database-change-management.md +80 -0
- package/knowledge/database-test-patterns.md +79 -0
- package/knowledge/decision-defaults.md +88 -0
- package/knowledge/dependency-breaking-techniques.md +116 -0
- package/knowledge/deployment-pipeline.md +86 -0
- package/knowledge/design-smells.md +122 -0
- package/knowledge/directory-enumeration.md +38 -0
- package/knowledge/domain-modeling.md +123 -0
- package/knowledge/evidence-bundle.md +90 -0
- package/knowledge/exploratory-testing-field-guide.md +122 -0
- package/knowledge/failure-routing.md +28 -0
- package/knowledge/fixture-construction.md +56 -0
- package/knowledge/frontend-component-architecture.md +139 -0
- package/knowledge/gherkin-quality-review-dispatch.md +135 -0
- package/knowledge/index.json +6766 -0
- package/knowledge/internal-collaborator-doubling.md +101 -0
- package/knowledge/legacy-test-strategy.md +71 -0
- package/knowledge/long-run-waiting.md +66 -0
- package/knowledge/microservice-testing.md +71 -0
- package/knowledge/model-pricing.json +23 -0
- package/knowledge/mutation-score-formulas.md +60 -0
- package/knowledge/object-calisthenics.md +147 -0
- package/knowledge/oracle-provenance.md +94 -0
- package/knowledge/orchestrator-script-implementation.md +185 -0
- package/knowledge/owasp-detection.md +148 -0
- package/knowledge/plan-review-rubric.md +56 -0
- package/knowledge/proxy-connectivity.md +62 -0
- package/knowledge/reactive-effect-patterns.md +73 -0
- package/knowledge/recon-inventory-excludes.txt +32 -0
- package/knowledge/references/bdd-value-guide.md +61 -0
- package/knowledge/references/csharp-http-client-testing.md +264 -0
- package/knowledge/release-strategies.md +74 -0
- package/knowledge/report-output-location.md +117 -0
- package/knowledge/report-pdf-integration.md +63 -0
- package/knowledge/report-print.css +129 -0
- package/knowledge/report-template.md +114 -0
- package/knowledge/report-to-pdf.md +69 -0
- package/knowledge/request-processing-flow.md +63 -0
- package/knowledge/result-verification.md +52 -0
- package/knowledge/review-agent-output-contract.md +121 -0
- package/knowledge/review-lens-classification.md +113 -0
- package/knowledge/review-rubric.md +62 -0
- package/knowledge/review-template.md +104 -0
- package/knowledge/rule-fixtures/A02.insecure-random-js/negative.js +1 -0
- package/knowledge/rule-fixtures/A02.insecure-random-js/positive.js +1 -0
- package/knowledge/rule-fixtures/A02.weak-hashing-md5/negative.py +1 -0
- package/knowledge/rule-fixtures/A02.weak-hashing-md5/positive.py +1 -0
- package/knowledge/rule-fixtures/A03.command-injection/negative.js +1 -0
- package/knowledge/rule-fixtures/A03.command-injection/positive.js +1 -0
- package/knowledge/rule-fixtures/A03.sql-injection/negative.js +1 -0
- package/knowledge/rule-fixtures/A03.sql-injection/positive.js +1 -0
- package/knowledge/rule-fixtures/A03.xss-innerhtml/negative.js +1 -0
- package/knowledge/rule-fixtures/A03.xss-innerhtml/positive.js +1 -0
- package/knowledge/rule-fixtures/A05.cors-wildcard/negative.js +1 -0
- package/knowledge/rule-fixtures/A05.cors-wildcard/positive.js +1 -0
- package/knowledge/rule-fixtures/A05.default-credentials/negative.js +1 -0
- package/knowledge/rule-fixtures/A05.default-credentials/positive.js +1 -0
- package/knowledge/rule-fixtures/A07.jwt-alg-none/negative.js +1 -0
- package/knowledge/rule-fixtures/A07.jwt-alg-none/positive.js +1 -0
- package/knowledge/rule-fixtures/A08.binary-formatter/negative.cs +1 -0
- package/knowledge/rule-fixtures/A08.binary-formatter/positive.cs +1 -0
- package/knowledge/rule-fixtures/A08.js-eval/negative.js +1 -0
- package/knowledge/rule-fixtures/A08.js-eval/positive.js +1 -0
- package/knowledge/rule-fixtures/A08.object-input-stream/negative.java +1 -0
- package/knowledge/rule-fixtures/A08.object-input-stream/positive.java +1 -0
- package/knowledge/schemas/disposition-register-v1.json +65 -0
- package/knowledge/schemas/recon-envelope-v1.json +198 -0
- package/knowledge/schemas/unified-finding-v1.json +72 -0
- package/knowledge/security-primitives-contract.md +301 -0
- package/knowledge/security-review-rule-map.yaml +107 -0
- package/knowledge/skills-registry.md +72 -0
- package/knowledge/task-size-classifier.md +103 -0
- package/knowledge/telemetry-schema.md +881 -0
- package/knowledge/test-automation-maturity.md +56 -0
- package/knowledge/test-automation-principles.md +71 -0
- package/knowledge/test-cadence-tradeoffs.md +68 -0
- package/knowledge/test-doubles.md +105 -0
- package/knowledge/test-file-indicators.md +22 -0
- package/knowledge/test-layer-gates.md +35 -0
- package/knowledge/test-matrix-examples/django-batch.md +24 -0
- package/knowledge/test-matrix-examples/dotnet-grpc-fronting-api.md +90 -0
- package/knowledge/test-matrix-examples/dotnet-http-consumer.md +131 -0
- package/knowledge/test-matrix-examples/react-node-spa.md +24 -0
- package/knowledge/test-matrix-examples/spring-boot-service.md +25 -0
- package/knowledge/test-matrix-examples/ssr-htmx.md +24 -0
- package/knowledge/test-organization.md +70 -0
- package/knowledge/test-pyramid.md +84 -0
- package/knowledge/test-refactoring.md +67 -0
- package/knowledge/test-review-division-of-labor.md +85 -0
- package/knowledge/test-smells.md +80 -0
- package/knowledge/test-stack-profiles/bdd-frameworks.md +235 -0
- package/knowledge/test-stack-profiles/django.md +13 -0
- package/knowledge/test-stack-profiles/dotnet.md +18 -0
- package/knowledge/test-stack-profiles/go.md +16 -0
- package/knowledge/test-stack-profiles/node.md +16 -0
- package/knowledge/test-stack-profiles/react.md +12 -0
- package/knowledge/test-stack-profiles/spring-boot.md +16 -0
- package/knowledge/test-stack-profiles/ssr-htmx.md +14 -0
- package/knowledge/test-stack-profiles/vue.md +12 -0
- package/knowledge/test-strategy.md +70 -0
- package/knowledge/testability-patterns.md +240 -0
- package/knowledge/testing-quadrants.md +44 -0
- package/knowledge/testing-techniques/approval.md +15 -0
- package/knowledge/testing-techniques/chaos.md +17 -0
- package/knowledge/testing-techniques/fuzz.md +15 -0
- package/knowledge/testing-techniques/property-based.md +15 -0
- package/knowledge/testing-techniques/schema-validation.md +15 -0
- package/knowledge/testing-techniques/screenshot.md +15 -0
- package/knowledge/three-phase-workflow.md +198 -0
- package/knowledge/value-patterns.md +55 -0
- package/knowledge/verification-mode.md +116 -0
- package/knowledge/virtual-service-libraries.md +75 -0
- package/knowledge/wave-consolidation-guidance.md +21 -0
- package/overrides/agents/Explore.md +15 -0
- package/overrides/agents/general-purpose.md +10 -0
- package/overrides/notes/autoship.md +6 -0
- package/overrides/notes/issues-from-assessment.md +3 -0
- package/overrides/notes/issues-from-plan.md +3 -0
- package/overrides/notes/mutation-night-watch.md +3 -0
- package/overrides/notes/mutation-testing.md +3 -0
- package/overrides/notes/pr.md +7 -0
- package/overrides/notes/project-init.md +6 -0
- package/overrides/notes/setup.md +13 -0
- package/overrides/notes/specs.md +3 -0
- package/overrides/skills/headless-run/SKILL.md +45 -0
- package/overrides/skills/upgrade/SKILL.md +30 -0
- package/overrides/skills/version/SKILL.md +25 -0
- package/package.json +36 -0
- package/scripts/authoring_digest.py +93 -0
- package/scripts/autoship_discover.py +121 -0
- package/scripts/autoship_group.py +409 -0
- package/scripts/autoship_proposals.py +494 -0
- package/scripts/autoship_queue.py +291 -0
- package/scripts/autoship_reclaim.py +495 -0
- package/scripts/build_jobs.py +108 -0
- package/scripts/build_rollback_point.py +240 -0
- package/scripts/build_slice_scope.py +157 -0
- package/scripts/build_wave.py +109 -0
- package/scripts/build_wave_reconcile.py +252 -0
- package/scripts/build_worktree_baseref.py +113 -0
- package/scripts/check_agent_scope.py +117 -0
- package/scripts/check_agent_tool_mapping.py +213 -0
- package/scripts/check_review_agent_mcp_tools.py +317 -0
- package/scripts/check_security_assessment_mcp_tools.py +165 -0
- package/scripts/checkpoint_abort.py +502 -0
- package/scripts/claude_setup_review.py +438 -0
- package/scripts/codebase_recon.py +556 -0
- package/scripts/coverage_config.py +623 -0
- package/scripts/coverage_delta_steering.py +330 -0
- package/scripts/coverage_discovery_dotnet.py +315 -0
- package/scripts/coverage_discovery_java.py +742 -0
- package/scripts/coverage_discovery_js.py +546 -0
- package/scripts/coverage_gap_ranking.py +556 -0
- package/scripts/coverage_readiness.py +455 -0
- package/scripts/coverage_report_parse.py +521 -0
- package/scripts/detect_bdd_convention.py +252 -0
- package/scripts/eval_ablation.py +376 -0
- package/scripts/gherkin_analysis_coverage_gate.py +306 -0
- package/scripts/gherkin_cross_feature_duplicate_titles_gate.py +173 -0
- package/scripts/gherkin_effectiveness_rollup.py +238 -0
- package/scripts/gherkin_failure_path_gate.py +206 -0
- package/scripts/gherkin_feature_merge.py +720 -0
- package/scripts/gherkin_stub_gate.py +163 -0
- package/scripts/gherkin_stub_merge.py +479 -0
- package/scripts/git_origin_host.py +88 -0
- package/scripts/install-java-static-analysis.py +110 -0
- package/scripts/issue_deps.py +74 -0
- package/scripts/lib/_bdd_markers.py +28 -0
- package/scripts/lib/_gherkin_text.py +93 -0
- package/scripts/lib/_vendored_tree.py +70 -0
- package/scripts/lib/autoship_state.py +397 -0
- package/scripts/lib/claude_md_guard.py +226 -0
- package/scripts/lib/deterministic_recon.py +446 -0
- package/scripts/lib/mcp_tool_grants.py +211 -0
- package/scripts/lib/plan_parse.py +386 -0
- package/scripts/lib/review_result.py +84 -0
- package/scripts/lib/review_roster.py +86 -0
- package/scripts/lib/session_log/__init__.py +34 -0
- package/scripts/lib/session_log/__pycache__/__init__.cpython-314.pyc +0 -0
- package/scripts/lib/session_log/__pycache__/records.cpython-314.pyc +0 -0
- package/scripts/lib/session_log/classify.py +231 -0
- package/scripts/lib/session_log/corrections.py +194 -0
- package/scripts/lib/session_log/discovery.py +108 -0
- package/scripts/lib/session_log/records.py +218 -0
- package/scripts/lib/session_log/redact.py +76 -0
- package/scripts/lib/session_log/signals.py +373 -0
- package/scripts/lib/session_report_downstream.py +614 -0
- package/scripts/lib/session_report_maintainer.py +1273 -0
- package/scripts/lib/session_report_shared.py +262 -0
- package/scripts/lib/settings_hook_guard.py +157 -0
- package/scripts/lib/slug.py +33 -0
- package/scripts/lib/stub_extractors/__init__.py +82 -0
- package/scripts/lib/stub_extractors/_common.py +328 -0
- package/scripts/lib/stub_extractors/csharp.py +19 -0
- package/scripts/lib/stub_extractors/go.py +173 -0
- package/scripts/lib/stub_extractors/java.py +18 -0
- package/scripts/lib/stub_extractors/jsts.py +126 -0
- package/scripts/mutation_stack_sections.py +149 -0
- package/scripts/mutation_yield_steering.py +345 -0
- package/scripts/orchestrator.py +895 -0
- package/scripts/plan_gherkin_export.py +227 -0
- package/scripts/plan_waves.py +208 -0
- package/scripts/pr_close_keyword_lint.py +108 -0
- package/scripts/progress_guardian.py +888 -0
- package/scripts/recon_inventory.py +273 -0
- package/scripts/review_findings_log.py +93 -0
- package/scripts/run_invariants.py +124 -0
- package/scripts/select_lenses.py +640 -0
- package/scripts/session_report.py +486 -0
- package/scripts/set_autocompact_env.py +221 -0
- package/scripts/ship_resume_guard.py +135 -0
- package/scripts/ship_review_gate.py +63 -0
- package/scripts/specs_convention_marker.py +103 -0
- package/scripts/test_improve_resume.py +277 -0
- package/scripts/test_review_mechanics.py +958 -0
- package/scripts/token_efficiency_review.py +322 -0
- package/scripts/verdict_scope.py +285 -0
- package/scripts/verify_gherkin_quality_critic_isolation.py +296 -0
- package/scripts/verify_tier.py +157 -0
- package/skills/adr-tools/SKILL.md +118 -0
- package/skills/agent-readiness/SKILL.md +105 -0
- package/skills/agent-readiness/ai_friendly_analyzers.py +326 -0
- package/skills/agent-readiness/scanner.py +441 -0
- package/skills/agent-readiness/scorecard.yaml +88 -0
- package/skills/api-design/SKILL.md +115 -0
- package/skills/apply-fixes/SKILL.md +171 -0
- package/skills/apply-test-doubles/SKILL.md +321 -0
- package/skills/artifact-lifecycle/SKILL.md +127 -0
- package/skills/autoship/SKILL.md +1124 -0
- package/skills/benchmark/SKILL.md +105 -0
- package/skills/branch-workflow/SKILL.md +89 -0
- package/skills/browse/SKILL.md +184 -0
- package/skills/browser-testing/SKILL.md +62 -0
- package/skills/browser-testing/references/playwright-patterns.md +216 -0
- package/skills/build/SKILL.md +422 -0
- package/skills/build/references/static-self-heal.md +245 -0
- package/skills/careful/SKILL.md +72 -0
- package/skills/cd-test-architecture/SKILL.md +371 -0
- package/skills/ci-debugging/SKILL.md +105 -0
- package/skills/co-evolution-audit/SKILL.md +269 -0
- package/skills/code-review/SKILL.md +1015 -0
- package/skills/code-review/examples/aggregated-sample.json +56 -0
- package/skills/code-review/examples/sample-report.md +41 -0
- package/skills/code-review/output-format.md +478 -0
- package/skills/code-review/scripts/activation.py +86 -0
- package/skills/code-review/scripts/change_impact.py +357 -0
- package/skills/code-review/scripts/change_shape.py +372 -0
- package/skills/code-review/scripts/change_size.py +212 -0
- package/skills/code-review/scripts/changed_file_list.py +141 -0
- package/skills/code-review/scripts/closing_pass.py +187 -0
- package/skills/code-review/scripts/consolidate.py +277 -0
- package/skills/code-review/scripts/contract_failure_report.py +185 -0
- package/skills/code-review/scripts/dispatch_reconcile.py +66 -0
- package/skills/code-review/scripts/dispatch_waves.py +164 -0
- package/skills/code-review/scripts/finding_signature.py +446 -0
- package/skills/code-review/scripts/ledger.py +283 -0
- package/skills/code-review/scripts/partition.py +169 -0
- package/skills/code-review/scripts/render_tiered_findings.py +274 -0
- package/skills/code-review/scripts/repo_invariants.py +1066 -0
- package/skills/code-review/scripts/review_context_pack.py +306 -0
- package/skills/code-review/scripts/review_round_log.py +345 -0
- package/skills/code-review/scripts/review_value_coverage.py +297 -0
- package/skills/code-review/scripts/validate_review_output.py +467 -0
- package/skills/code-review/sliced-mode.md +205 -0
- package/skills/competitive-analysis/SKILL.md +191 -0
- package/skills/context-loading-protocol/SKILL.md +157 -0
- package/skills/continue/SKILL.md +90 -0
- package/skills/cost-report/SKILL.md +178 -0
- package/skills/coverage-baseline/SKILL.md +335 -0
- package/skills/coverage-baseline/references/multi-project-discovery.md +202 -0
- package/skills/coverage-delta/SKILL.md +181 -0
- package/skills/coverage-delta/references/mutation-gate.md +70 -0
- package/skills/design-doc/SKILL.md +95 -0
- package/skills/design-interrogation/SKILL.md +89 -0
- package/skills/design-it-twice/SKILL.md +91 -0
- package/skills/docker-image-audit/SKILL.md +108 -0
- package/skills/docker-image-audit/references/install-guide.md +64 -0
- package/skills/docker-image-audit/references/report-template.md +73 -0
- package/skills/docker-image-create/SKILL.md +185 -0
- package/skills/domain-analysis/SKILL.md +183 -0
- package/skills/domain-driven-design/SKILL.md +194 -0
- package/skills/exploratory-testing/SKILL.md +108 -0
- package/skills/explore/SKILL.md +51 -0
- package/skills/farley-score/SKILL.md +165 -0
- package/skills/feature-file-validation/SKILL.md +78 -0
- package/skills/feature-file-validation/references/validation-rules.md +115 -0
- package/skills/feedback-learning/SKILL.md +414 -0
- package/skills/fix/SKILL.md +450 -0
- package/skills/freeze/SKILL.md +68 -0
- package/skills/frontend-architecture/SKILL.md +113 -0
- package/skills/gherkin-derive/SKILL.md +630 -0
- package/skills/gherkin-public/SKILL.md +266 -0
- package/skills/governance-compliance/SKILL.md +150 -0
- package/skills/guard/SKILL.md +75 -0
- package/skills/handoff/SKILL.md +139 -0
- package/skills/handoff/references/summary-templates.md +242 -0
- package/skills/harness-audit/SKILL.md +751 -0
- package/skills/harness-audit/scripts/lesson_validate.py +386 -0
- package/skills/harness-audit/scripts/redundancy_criterion.py +188 -0
- package/skills/headless-run/SKILL.md +45 -0
- package/skills/headless-run/scripts/isolated_dispatch.py +381 -0
- package/skills/help/SKILL.md +72 -0
- package/skills/hexagonal-architecture/SKILL.md +85 -0
- package/skills/human-oversight-protocol/SKILL.md +224 -0
- package/skills/issues-from-assessment/SKILL.md +223 -0
- package/skills/issues-from-plan/SKILL.md +133 -0
- package/skills/legacy-code/SKILL.md +132 -0
- package/skills/mermaid-diagramming/SKILL.md +120 -0
- package/skills/mutation-night-watch/SKILL.md +154 -0
- package/skills/mutation-night-watch/references/scheduling.md +135 -0
- package/skills/mutation-testing/SKILL.md +396 -0
- package/skills/mutation-testing/references/languages/csharp-stryker-net.md +676 -0
- package/skills/mutation-testing/references/languages/go-go-mutesting.md +95 -0
- package/skills/mutation-testing/references/languages/java-pitest.md +77 -0
- package/skills/mutation-testing/references/languages/javascript-stryker.md +188 -0
- package/skills/mutation-testing/references/languages/python-mutmut.md +97 -0
- package/skills/mutation-testing/references/time-estimation.md +34 -0
- package/skills/mutation-testing/references/tool-detection.md +15 -0
- package/skills/mutation-testing/references/workflow-callers.md +23 -0
- package/skills/mutation-testing/scripts/__pycache__/xunit_v3_feature_detector.cpython-314.pyc +0 -0
- package/skills/mutation-testing/scripts/csharp_stryker_net_slice_runner.py +635 -0
- package/skills/mutation-testing/scripts/csharp_stryker_net_status_loop.py +525 -0
- package/skills/mutation-testing/scripts/csharp_stryker_net_wrapper.py +681 -0
- package/skills/mutation-testing/scripts/mutation_baseline_reuse.py +292 -0
- package/skills/mutation-testing/scripts/mutation_exclude_policy.py +268 -0
- package/skills/mutation-testing/scripts/mutation_feasibility_gate.py +463 -0
- package/skills/mutation-testing/scripts/mutation_kill_headless.py +331 -0
- package/skills/mutation-testing/scripts/mutation_kill_insert.py +199 -0
- package/skills/mutation-testing/scripts/mutation_kill_insert_python.py +150 -0
- package/skills/mutation-testing/scripts/mutation_kill_loop.py +869 -0
- package/skills/mutation-testing/scripts/mutation_kill_loop_python.py +949 -0
- package/skills/mutation-testing/scripts/mutation_kill_retry.py +592 -0
- package/skills/mutation-testing/scripts/mutation_kill_shared.py +620 -0
- package/skills/mutation-testing/scripts/mutation_nightwatch.py +462 -0
- package/skills/mutation-testing/scripts/mutation_nightwatch_stacks.py +425 -0
- package/skills/mutation-testing/scripts/mutation_report.py +743 -0
- package/skills/mutation-testing/scripts/mutation_report_cli.py +175 -0
- package/skills/mutation-testing/scripts/mutation_safety_gate.py +69 -0
- package/skills/mutation-testing/scripts/stryker_shard_pipeline.py +847 -0
- package/skills/mutation-testing/scripts/stryker_shard_setup.py +440 -0
- package/skills/mutation-testing/scripts/stryker_timeout_retry.py +142 -0
- package/skills/mutation-testing/scripts/xunit_v3_feature_detector.py +341 -0
- package/skills/performance-benchmark/SKILL.md +174 -0
- package/skills/performance-benchmark/examples/report-format.md +43 -0
- package/skills/performance-benchmark/references/benchmark-script.md +169 -0
- package/skills/performance-metrics/SKILL.md +265 -0
- package/skills/plan/SKILL.md +199 -0
- package/skills/plan/references/gherkin-persistence.md +43 -0
- package/skills/plan/references/plan-template.md +182 -0
- package/skills/pr/SKILL.md +289 -0
- package/skills/pr/scripts/gate_retry_state.py +368 -0
- package/skills/project-init/README.md +141 -0
- package/skills/project-init/SKILL.md +1197 -0
- package/skills/project-init/evals/evals.json +200 -0
- package/skills/project-init/references/capability-tools.md +55 -0
- package/skills/project-init/references/configs.md +221 -0
- package/skills/property-based-testing/SKILL.md +121 -0
- package/skills/property-based-testing/fixtures/invariant_fixture.py +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/README.md +42 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/LICENSE +21 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/README.md +263 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/fast-check.d.ts +5165 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/fast-check.js +12147 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/package.json +3 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/cjs/types57/fast-check.d.ts +5165 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/fast-check.d.ts +5165 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/fast-check.js +12011 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/rolldown-runtime-D7D4PA-g.js +13 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/lib/types57/fast-check.d.ts +5165 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/fast-check/package.json +94 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/LICENSE +21 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/README.md +168 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/RandomGenerator-DcXj09Ch.d.ts +14 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformBigInt.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformBigInt.js +38 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat32.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat32.js +18 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat64.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformFloat64.js +22 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformInt.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/distribution/uniformInt.js +134 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/RandomGenerator-DcXj09Ch.d.ts +14 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformBigInt.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformBigInt.js +37 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat32.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat32.js +17 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat64.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformFloat64.js +21 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformInt.d.ts +15 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/distribution/uniformInt.js +133 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/congruential32.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/congruential32.js +44 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/mersenne.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/mersenne.js +90 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xoroshiro128plus.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xoroshiro128plus.js +80 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xorshift128plus.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/generator/xorshift128plus.js +78 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/package.json +3 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/JumpableRandomGenerator.d.ts +16 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/JumpableRandomGenerator.js +0 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/RandomGenerator.d.ts +2 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/types/RandomGenerator.js +0 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/generateN.d.ts +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/generateN.js +8 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/purify.d.ts +12 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/purify.js +9 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/skipN.d.ts +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/esm/utils/skipN.js +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/congruential32.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/congruential32.js +46 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/mersenne.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/mersenne.js +92 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xoroshiro128plus.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xoroshiro128plus.js +82 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xorshift128plus.d.ts +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/generator/xorshift128plus.js +80 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/JumpableRandomGenerator.d.ts +16 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/JumpableRandomGenerator.js +0 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/RandomGenerator.d.ts +2 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/types/RandomGenerator.js +0 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/generateN.d.ts +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/generateN.js +9 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/purify.d.ts +12 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/purify.js +10 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/skipN.d.ts +6 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/lib/utils/skipN.js +7 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/node_modules/pure-rand/package.json +133 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/package-lock.json +1179 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/package.json +14 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/roundtrip.js +29 -0
- package/skills/property-based-testing/fixtures/js-roundtrip/roundtrip.properties.test.js +16 -0
- package/skills/property-based-testing/fixtures/no_property_fixture.py +10 -0
- package/skills/property-based-testing/fixtures/roundtrip_fixture.py +16 -0
- package/skills/property-based-testing/references/languages/javascript.md +54 -0
- package/skills/property-based-testing/scripts/detect_and_dispatch.py +80 -0
- package/skills/property-based-testing/scripts/hypothesis_scaffold.py +276 -0
- package/skills/proxy-resilience/SKILL.md +84 -0
- package/skills/quality-gate-pipeline/SKILL.md +184 -0
- package/skills/quality-targets-converge/SKILL.md +254 -0
- package/skills/repo-review/SKILL.md +159 -0
- package/skills/report-pdf/SKILL.md +66 -0
- package/skills/review/SKILL.md +47 -0
- package/skills/review-agent/SKILL.md +152 -0
- package/skills/review-summary/SKILL.md +73 -0
- package/skills/run-report/SKILL.md +70 -0
- package/skills/semantic-duplication-scan/SKILL.md +337 -0
- package/skills/semantic-scan/SKILL.md +53 -0
- package/skills/semgrep-analyze/SKILL.md +139 -0
- package/skills/setup/SKILL.md +1122 -0
- package/skills/ship/SKILL.md +240 -0
- package/skills/source-verification/SKILL.md +210 -0
- package/skills/source-verification/scripts/claim_extractor.py +155 -0
- package/skills/specs/.size-baseline.json +4 -0
- package/skills/specs/SKILL.md +243 -0
- package/skills/specs/references/completeness-checklist.md +83 -0
- package/skills/specs/references/extraction.md +58 -0
- package/skills/specs/references/glossary.md +59 -0
- package/skills/specs/references/persistence.md +115 -0
- package/skills/specs/references/predictability-check.md +77 -0
- package/skills/static-analysis-integration/SKILL.md +235 -0
- package/skills/static-analysis-integration/adapters/_envelope.py +26 -0
- package/skills/static-analysis-integration/adapters/jscpd-adapter.py +66 -0
- package/skills/static-analysis-integration/adapters/lizard-adapter.py +81 -0
- package/skills/static-analysis-integration/adapters/mypy-adapter.py +50 -0
- package/skills/static-analysis-integration/adapters/mypy-src-layout.py +93 -0
- package/skills/static-analysis-integration/adapters/security-review-adapter.py +212 -0
- package/skills/static-analysis-integration/maintenance.md +23 -0
- package/skills/static-analysis-integration/references/language-setup.md +228 -0
- package/skills/static-analysis-integration/references/sarif-parser.md +124 -0
- package/skills/static-analysis-integration/references/security-review-adapter.md +118 -0
- package/skills/static-analysis-integration/references/tool-configs.md +617 -0
- package/skills/static-analysis-integration/rulesets/pmd-quickstart.xml +24 -0
- package/skills/stryker-xunit-v2-shim/SKILL.md +274 -0
- package/skills/stryker-xunit-v2-shim/references/shim-howto.md +256 -0
- package/skills/stryker-xunit-v2-shim/scripts/generate_shim.py +143 -0
- package/skills/systematic-debugging/SKILL.md +130 -0
- package/skills/telemetry/SKILL.md +75 -0
- package/skills/test-audit-disable/SKILL.md +129 -0
- package/skills/test-design/SKILL.md +177 -0
- package/skills/test-design/scripts/__pycache__/internal_double_detector.cpython-314.pyc +0 -0
- package/skills/test-design/scripts/internal_double_detector.py +631 -0
- package/skills/test-design-advisor/SKILL.md +166 -0
- package/skills/test-driven-development/SKILL.md +169 -0
- package/skills/test-health/SKILL.md +262 -0
- package/skills/test-improve/SKILL.md +239 -0
- package/skills/test-improve/references/phase-0-approach-contract.md +228 -0
- package/skills/test-improve/references/phase-1-analyze.md +131 -0
- package/skills/test-improve/references/phase-2-baseline.md +121 -0
- package/skills/test-improve/references/phase-3-derive-gherkin.md +53 -0
- package/skills/test-improve/references/phase-4-plan-fixes.md +34 -0
- package/skills/test-improve/references/phase-5-improve.md +215 -0
- package/skills/test-improve/references/phase-6-refactor-decision.md +45 -0
- package/skills/test-improve/references/phase-7-refactor.md +44 -0
- package/skills/test-improve/references/phase-8-validate.md +66 -0
- package/skills/test-improve/references/phase-9-close-out-prompt.md +11 -0
- package/skills/test-improve/references/phase-9-report.md +62 -0
- package/skills/test-improve/references/review-loop.md +92 -0
- package/skills/test-improve/templates/executive-summary.md +123 -0
- package/skills/threat-modeling/SKILL.md +108 -0
- package/skills/triage/SKILL.md +211 -0
- package/skills/ubiquitous-language/SKILL.md +192 -0
- package/skills/ubiquitous-language/scripts/collect_domain_signals.py +300 -0
- package/skills/unfreeze/SKILL.md +37 -0
- package/skills/upgrade/SKILL.md +31 -0
- package/skills/upgrade/scripts/check_version_drift.py +113 -0
- package/skills/upgrade/scripts/enable_autoupdate.py +149 -0
- package/skills/version/SKILL.md +25 -0
- package/sync/__pycache__/sync_upstream.cpython-314.pyc +0 -0
- package/sync/sync_upstream.py +293 -0
- package/templates/ACCEPTED-RISKS.md.tmpl +46 -0
- package/templates/agents/agent-template.md +151 -0
- package/templates/agents/angular-testing.md +66 -0
- package/templates/agents/csharp-quality.md +63 -0
- package/templates/agents/esm-enforcer.md +52 -0
- package/templates/agents/front-end-testing.md +65 -0
- package/templates/agents/go-quality.md +65 -0
- package/templates/agents/python-quality.md +62 -0
- package/templates/agents/react-testing.md +61 -0
- package/templates/agents/ts-enforcer.md +60 -0
- package/templates/agents/twelve-factor-audit.md +49 -0
- package/tools/entropy-check.py +250 -0
- package/tools/model-hash-verify.py +213 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# C# HTTP client testing — fast, deterministic, pre-merge
|
|
2
|
+
|
|
3
|
+
Reference for testing a .NET service's **outbound** HTTP layer (`HttpClient`,
|
|
4
|
+
the **API Consumer** side of `knowledge/component-test-patterns.md` →
|
|
5
|
+
*API Consumer*). The canonical seam is `HttpMessageHandler`. The hand-rolled
|
|
6
|
+
stub implementation of that seam (below) makes the HTTP layer a pure
|
|
7
|
+
function of inputs: no sockets, no ports, no Kestrel, microsecond-fast,
|
|
8
|
+
bit-for-bit reproducible. WireMock.Net (see "WireMock.Net — the preferred
|
|
9
|
+
pre-merge double when installed" below) fills the same seam through a real
|
|
10
|
+
loopback HTTP server instead — same DI injection point, different traffic
|
|
11
|
+
shape; see that section for the honest trade-off.
|
|
12
|
+
|
|
13
|
+
This is the .NET realization of the **Adapter Rule** from
|
|
14
|
+
`knowledge/cd-test-architecture.md#the-adapter-rule-own-your-boundaries`:
|
|
15
|
+
wrap each third-party HTTP API in a thin team-owned adapter, then double the
|
|
16
|
+
adapter (or its `HttpMessageHandler`) in component and contract tests.
|
|
17
|
+
|
|
18
|
+
For testing the **inbound** HTTP surface (your own ASP.NET Core endpoints — the
|
|
19
|
+
API Provider side), use `WebApplicationFactory<TEntryPoint>` instead; see
|
|
20
|
+
`knowledge/test-stack-profiles/dotnet.md` → Component / Service row. This
|
|
21
|
+
reference is for the *outbound* direction.
|
|
22
|
+
|
|
23
|
+
## The core pattern: stub HttpMessageHandler
|
|
24
|
+
|
|
25
|
+
`HttpClient` delegates every request to its `HttpMessageHandler.SendAsync`.
|
|
26
|
+
Subclass `HttpMessageHandler` (or `DelegatingHandler`) and return canned
|
|
27
|
+
responses keyed off the incoming request. The whole transport stack
|
|
28
|
+
collapses to a function `HttpRequestMessage -> HttpResponseMessage`.
|
|
29
|
+
|
|
30
|
+
```csharp
|
|
31
|
+
public sealed class StubHttpMessageHandler : HttpMessageHandler
|
|
32
|
+
{
|
|
33
|
+
private readonly Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> _handler;
|
|
34
|
+
public List<HttpRequestMessage> Requests { get; } = new();
|
|
35
|
+
|
|
36
|
+
public StubHttpMessageHandler(
|
|
37
|
+
Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> handler)
|
|
38
|
+
=> _handler = handler;
|
|
39
|
+
|
|
40
|
+
protected override Task<HttpResponseMessage> SendAsync(
|
|
41
|
+
HttpRequestMessage request, CancellationToken ct)
|
|
42
|
+
{
|
|
43
|
+
Requests.Add(request);
|
|
44
|
+
return _handler(request, ct);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Inject via `new HttpClient(handler) { BaseAddress = ... }` into the
|
|
50
|
+
adapter under test. The captured `Requests` list is the spy surface for
|
|
51
|
+
request-shape assertions; the handler delegate is the stub surface for
|
|
52
|
+
response control.
|
|
53
|
+
|
|
54
|
+
## Wiring with IHttpClientFactory (production parity)
|
|
55
|
+
|
|
56
|
+
When the production code uses `IHttpClientFactory` / typed clients (the
|
|
57
|
+
recommended .NET pattern since 2.1), preserve the DI graph and swap only the
|
|
58
|
+
leaf handler:
|
|
59
|
+
|
|
60
|
+
```csharp
|
|
61
|
+
services.AddHttpClient<UserClient>(c => c.BaseAddress = new Uri("https://api.test/"))
|
|
62
|
+
.ConfigurePrimaryHttpMessageHandler(() => stubHandler);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Same `HttpClient` lifetime, same delegating-handler chain (auth, logging,
|
|
66
|
+
retry), only the bottom of the stack changes. This keeps tests honest about
|
|
67
|
+
the middleware that production runs.
|
|
68
|
+
|
|
69
|
+
## What to assert (drive from the contract, not the internals)
|
|
70
|
+
|
|
71
|
+
A consumer's contract is two-sided: the *request it builds* and the
|
|
72
|
+
*response shape it depends on*. Assert both, structurally:
|
|
73
|
+
|
|
74
|
+
- **Request shape** — method, path, query string, headers, body. Deserialize
|
|
75
|
+
JSON bodies and compare structurally; never string-match request bodies
|
|
76
|
+
(whitespace, member ordering, and culture-formatted numbers all flake).
|
|
77
|
+
- **Response handling** — success deserialization (including optional and
|
|
78
|
+
unknown fields per Postel's Law), non-2xx → typed exceptions, empty
|
|
79
|
+
bodies, malformed JSON, content-type mismatches.
|
|
80
|
+
- **Cross-cutting** — auth headers, correlation/idempotency keys,
|
|
81
|
+
trace-context propagation, cancellation propagation, deadline/timeout
|
|
82
|
+
enforcement.
|
|
83
|
+
- **Retry sequences** — queue a deterministic sequence
|
|
84
|
+
(e.g. `503, 503, 200`); assert the request count and the final outcome.
|
|
85
|
+
|
|
86
|
+
Map these onto the API Consumer success/failure list in
|
|
87
|
+
`knowledge/component-test-patterns.md#api-consumer` — the patterns there are
|
|
88
|
+
the source of truth for *what* to cover; this file is *how* to cover it on
|
|
89
|
+
.NET.
|
|
90
|
+
|
|
91
|
+
## Keep it deterministic
|
|
92
|
+
|
|
93
|
+
Two recurring sources of flake in HTTP-client tests:
|
|
94
|
+
|
|
95
|
+
- **Time.** Inject `TimeProvider` (built-in since .NET 8) — never call
|
|
96
|
+
`DateTime.UtcNow`, `DateTimeOffset.Now`, or `Task.Delay` directly in
|
|
97
|
+
application logic. In tests, drive `FakeTimeProvider` (from
|
|
98
|
+
`Microsoft.Extensions.TimeProvider.Testing`) forward explicitly. Mirrors
|
|
99
|
+
the determinism rule in
|
|
100
|
+
`knowledge/cd-test-architecture.md#determinism-techniques-minimal-tooling`.
|
|
101
|
+
- **Polly jitter / backoff.** When the adapter uses Polly (the .NET resilience
|
|
102
|
+
pipeline) for retry, circuit-breaker, or timeout, configure the pipeline
|
|
103
|
+
with the **same** `TimeProvider`. Polly v8 accepts `TimeProvider` directly
|
|
104
|
+
in its `ResiliencePipelineBuilder` — retries then advance *virtual* time,
|
|
105
|
+
not wall-clock, so a "wait 30s then retry" policy completes in
|
|
106
|
+
microseconds without `Thread.Sleep`.
|
|
107
|
+
|
|
108
|
+
Combined with the stub handler, the entire outbound HTTP layer — including
|
|
109
|
+
retries, timeouts, and circuit-breakers — is a pure function of inputs.
|
|
110
|
+
|
|
111
|
+
## Testing Polly resilience policies deterministically
|
|
112
|
+
|
|
113
|
+
This is the canonical setup for the consumer-resilience component tests
|
|
114
|
+
required by `knowledge/component-test-patterns.md` → API Consumer §
|
|
115
|
+
*Failure modes*:
|
|
116
|
+
|
|
117
|
+
```csharp
|
|
118
|
+
var time = new FakeTimeProvider();
|
|
119
|
+
var responses = new Queue<HttpResponseMessage>(new[]
|
|
120
|
+
{
|
|
121
|
+
new HttpResponseMessage(HttpStatusCode.ServiceUnavailable),
|
|
122
|
+
new HttpResponseMessage(HttpStatusCode.ServiceUnavailable),
|
|
123
|
+
new HttpResponseMessage(HttpStatusCode.OK) { Content = JsonContent.Create(payload) },
|
|
124
|
+
});
|
|
125
|
+
var handler = new StubHttpMessageHandler((_, _) => Task.FromResult(responses.Dequeue()));
|
|
126
|
+
|
|
127
|
+
var pipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
|
|
128
|
+
.AddRetry(new HttpRetryStrategyOptions { /* ... */ })
|
|
129
|
+
.ConfigureTelemetry(NullLoggerFactory.Instance)
|
|
130
|
+
.Build(); // bind TimeProvider via DI in production wiring
|
|
131
|
+
|
|
132
|
+
// drive: advance virtual time across each backoff window; assert request count == 3 and final result OK.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The same shape proves circuit-breaker open/half-open/closed transitions and
|
|
136
|
+
timeout enforcement without any real wall-clock waits.
|
|
137
|
+
|
|
138
|
+
## Where it sits on the pyramid
|
|
139
|
+
|
|
140
|
+
Map directly to `knowledge/cd-test-architecture.md` § *The Six Test Types*:
|
|
141
|
+
|
|
142
|
+
| Behavior under test | MinimumCD layer | Tool |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| Pure logic in the adapter (header building, query-string construction, response mapping) | **Unit** (solitary) | xUnit + the adapter constructed directly, no `HttpClient` needed |
|
|
145
|
+
| Adapter speaks the wire correctly to a doubled transport: builds the right request, parses the canned response, maps non-2xx to typed errors | **Contract** | xUnit + `StubHttpMessageHandler` |
|
|
146
|
+
| Resilience policy (retry/backoff/circuit-breaker/timeout) survives a doubled provider failure | **Component** (resilience) | xUnit + `StubHttpMessageHandler` + `FakeTimeProvider` + Polly bound to that `TimeProvider` |
|
|
147
|
+
| Adapter against the real provider API (in-house or third-party) in a non-prod test environment | **Scheduled provider verification** (out-of-band) | xUnit/console job vs the provider's real endpoint, **never pre-merge** |
|
|
148
|
+
| Multi-service journey across real deployed components | **E2E** (post-deploy smoke) | Playwright for .NET — only when the four-condition E2E justification gate from `knowledge/cd-test-architecture.md#the-e2e-justification-gate` is satisfied |
|
|
149
|
+
|
|
150
|
+
Contract and component tests with the stub handler are **deterministic and
|
|
151
|
+
pre-merge** per
|
|
152
|
+
`knowledge/cd-test-architecture.md#the-pre-merge-gate-rule`. The scheduled
|
|
153
|
+
provider-verification job is the **detection** half of
|
|
154
|
+
`knowledge/cd-test-architecture.md#double-validation-keeping-doubles-honest`;
|
|
155
|
+
the resilience component test is the **survival** half — both are required
|
|
156
|
+
regardless of ownership: assume the provider can break the contract without
|
|
157
|
+
warning even when it's the same team's, per the universal rule in
|
|
158
|
+
`knowledge/component-test-patterns.md#api-consumer`.
|
|
159
|
+
|
|
160
|
+
## Off-the-shelf alternatives to the hand-rolled stub
|
|
161
|
+
|
|
162
|
+
The hand-rolled `StubHttpMessageHandler` is usually enough and has zero
|
|
163
|
+
dependencies. Two libraries cover larger or noisier surfaces:
|
|
164
|
+
|
|
165
|
+
- **`RichardSzalay.MockHttp`** — fluent matcher API (`When(...).Respond(...)`).
|
|
166
|
+
Good when one test method exercises many endpoints and inline matching
|
|
167
|
+
beats a delegate's `switch`.
|
|
168
|
+
- **`Moq.Contrib.HttpClient`** — extensions for treating
|
|
169
|
+
`HttpMessageHandler` as a `Mock<>`. Good when the team already uses Moq
|
|
170
|
+
pervasively and prefers one mocking idiom across the suite.
|
|
171
|
+
|
|
172
|
+
Either library is a stylistic choice over the hand-rolled stub, **not** an
|
|
173
|
+
escalation up the pyramid; both still test the same `HttpMessageHandler`
|
|
174
|
+
seam in-process, deterministically.
|
|
175
|
+
|
|
176
|
+
## WireMock.Net — the preferred pre-merge double when installed
|
|
177
|
+
|
|
178
|
+
When installed, WireMock.Net is the **preferred** pre-merge double for this
|
|
179
|
+
seam — not the hand-rolled `StubHttpMessageHandler` above, which remains the
|
|
180
|
+
**backup** for when WireMock.Net is declined or unavailable. This is not an
|
|
181
|
+
in-process/no-socket claim: verified against WireMock's own docs, the
|
|
182
|
+
no-HTTP-layer `DirectCallHttpServer` mode ("Running Without the HTTP
|
|
183
|
+
Server") is a **WireMock-for-Java-only** feature — WireMock.Net's
|
|
184
|
+
`WireMockServer.Start()` always binds a real HTTP listener on localhost, on
|
|
185
|
+
an ephemeral port. What actually makes it pre-merge-safe despite that real
|
|
186
|
+
socket: it runs **same-process, localhost-only, on an ephemeral port, with
|
|
187
|
+
no separately-managed external server or container** — fast and
|
|
188
|
+
deterministic enough for the pre-merge gate, even though it is not a true
|
|
189
|
+
in-memory transport. See `knowledge/virtual-service-libraries.md` for the
|
|
190
|
+
full per-stack catalog and the preferred/backup interaction model this file
|
|
191
|
+
is one instance of.
|
|
192
|
+
|
|
193
|
+
**Reconciling this with the seam framing above and the anti-pattern below.**
|
|
194
|
+
The opening thesis's "no sockets, no ports, no Kestrel" description applies
|
|
195
|
+
to the hand-rolled `StubHttpMessageHandler`, not to this seam universally —
|
|
196
|
+
WireMock.Net fills the same `HttpMessageHandler` seam, through the same DI
|
|
197
|
+
injection point, but the actual network path is a real loopback HTTP
|
|
198
|
+
request, not an in-memory interception. That is a different claim from the
|
|
199
|
+
"Kestrel on a random port" anti-pattern the `What to avoid` section below
|
|
200
|
+
still flags: that anti-pattern hosts your own application's real inbound
|
|
201
|
+
pipeline (or an ad hoc hand-rolled HTTP host) as the downstream fake, with
|
|
202
|
+
no purpose-built stub tooling. WireMock.Net, by contrast, is purpose-built
|
|
203
|
+
stub tooling — request/response matching and expectation configuration are
|
|
204
|
+
its entire job — launched and torn down within the same test process
|
|
205
|
+
lifecycle, with no separately-managed external server or container to
|
|
206
|
+
configure. The honest trade-off: a real loopback socket is being traded for
|
|
207
|
+
that purpose-built tooling and faster iteration than hand-rolling a host —
|
|
208
|
+
not for the absence of sockets, DNS, or the network stack, which this file
|
|
209
|
+
does not claim WireMock.Net avoids.
|
|
210
|
+
|
|
211
|
+
## What to avoid for unit and component tests
|
|
212
|
+
|
|
213
|
+
These are integration/E2E tooling — fast feedback isn't what they're for,
|
|
214
|
+
so they don't belong on the pre-merge gate (see
|
|
215
|
+
`knowledge/cd-test-architecture.md#the-pre-merge-gate-rule`):
|
|
216
|
+
|
|
217
|
+
- **`WebApplicationFactory<T>` to test an outbound client.** It spins up
|
|
218
|
+
the *server* in-process. The seam you want is below the client, not above
|
|
219
|
+
the server. Use it for the API Provider side (inbound HTTP); use the
|
|
220
|
+
stub handler for the API Consumer side.
|
|
221
|
+
- **Kestrel on a random port + a real HTTP request.** You are now testing
|
|
222
|
+
the network stack and DNS, not your code. Slow, OS-dependent, flaky.
|
|
223
|
+
- **MockServer for unit tests.** Unlike WireMock.Net (see above), MockServer
|
|
224
|
+
is typically run as a separately-managed remote or containerized service.
|
|
225
|
+
Reserve it for the **adapter-integration** layer (out-of-band, on a
|
|
226
|
+
schedule) where the network behavior itself is under test — TLS, HTTP/2,
|
|
227
|
+
proxy, real timeouts.
|
|
228
|
+
|
|
229
|
+
## Common smells in C# HTTP-consumer tests
|
|
230
|
+
|
|
231
|
+
Catalogued so `test-smell-review` and `test-design-advisor` can map a
|
|
232
|
+
finding to the .NET-specific fix:
|
|
233
|
+
|
|
234
|
+
- **Mocking `HttpClient` directly** (e.g. with Moq). `HttpClient` is a
|
|
235
|
+
sealed/non-virtual surface in practice; mocking it requires reflection
|
|
236
|
+
hacks or `InternalsVisibleTo`, both of which are test workarounds for a
|
|
237
|
+
missing production seam. Wrap it in an adapter and double the
|
|
238
|
+
`HttpMessageHandler` instead. (`knowledge/test-doubles.md` rule:
|
|
239
|
+
never invent a test-only seam to dodge a missing production one.)
|
|
240
|
+
- **Mocking the third-party SDK directly** instead of an owned adapter.
|
|
241
|
+
Same pattern, same fix — Adapter Rule applies.
|
|
242
|
+
- **`DateTime.UtcNow` in retry/expiry logic** without `TimeProvider`. The
|
|
243
|
+
test must `Thread.Sleep` (or worse, give up determinism). Inject the
|
|
244
|
+
clock.
|
|
245
|
+
- **`Thread.Sleep`/`Task.Delay` in tests** to wait for retries. Always a
|
|
246
|
+
symptom of (a) above. Use `FakeTimeProvider` and Polly bound to it.
|
|
247
|
+
- **String-matching JSON request bodies.** Deserialize structurally; the
|
|
248
|
+
test breaks on whitespace and culture otherwise.
|
|
249
|
+
- **Asserting against the adapter's internal calls** (e.g. with a behaviour
|
|
250
|
+
verification mock) instead of the request that crossed the seam. The
|
|
251
|
+
contract is the request bytes the SUT *would emit*, not which method on
|
|
252
|
+
the SDK it called. Prefer state verification of `Requests` captured by
|
|
253
|
+
the stub handler.
|
|
254
|
+
|
|
255
|
+
## Boundaries
|
|
256
|
+
|
|
257
|
+
This file covers .NET-specific *mechanics* for the API Consumer pattern.
|
|
258
|
+
The pattern itself — coverage layers, success/failure scenarios, double
|
|
259
|
+
validation loop, pipeline placement — lives in
|
|
260
|
+
`knowledge/component-test-patterns.md#api-consumer` and is language-agnostic.
|
|
261
|
+
For the broader stack picture (which tool at which layer on .NET), see
|
|
262
|
+
`knowledge/test-stack-profiles/dotnet.md`. For a worked example using this
|
|
263
|
+
pattern end-to-end, see
|
|
264
|
+
`knowledge/test-matrix-examples/dotnet-http-consumer.md`.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Release Strategies
|
|
2
|
+
|
|
3
|
+
Reference for releasing changes with low risk and zero downtime. Source:
|
|
4
|
+
*Continuous Delivery* (Humble & Farley) Ch.10, plus the version-control
|
|
5
|
+
techniques from Ch.14 that keep mainline releasable. This file is advisory — the
|
|
6
|
+
plugin recommends and plans for these patterns; it does not execute deployments.
|
|
7
|
+
|
|
8
|
+
The governing distinction: **deploy ≠ release.** Deploying puts code on a server;
|
|
9
|
+
releasing exposes behavior to users. Keep them separate so you can deploy
|
|
10
|
+
continuously and release on a business decision.
|
|
11
|
+
|
|
12
|
+
## Decouple deployment from release
|
|
13
|
+
|
|
14
|
+
| Technique | What it does | Use when |
|
|
15
|
+
|-----------|--------------|----------|
|
|
16
|
+
| **Feature toggle / flag** | Ship code dark; turn behavior on at runtime without a deploy | Incremental delivery of an unfinished feature; instant kill-switch |
|
|
17
|
+
| **Branch by abstraction** | Introduce an abstraction over the thing being replaced, migrate callers behind it on mainline, then delete the old path | Large changes that would otherwise need a long-lived branch |
|
|
18
|
+
| **Dark launching** | Run new code paths in production against real traffic without showing results to users | Validate capacity/behavior before exposure |
|
|
19
|
+
| **Keep mainline releasable** | Every commit leaves trunk shippable; hide incomplete work behind toggles/abstractions rather than branching | Always — this is what makes continuous delivery possible |
|
|
20
|
+
|
|
21
|
+
Toggles are **inventory**: remove each one once the feature is permanent. Stale
|
|
22
|
+
flags are a liability (untested combinations, dead branches).
|
|
23
|
+
|
|
24
|
+
## Deployment patterns
|
|
25
|
+
|
|
26
|
+
| Pattern | How it works | Rollback | Trade-off |
|
|
27
|
+
|---------|--------------|----------|-----------|
|
|
28
|
+
| **Blue-green** | Two identical production environments; release by switching the router to the idle one | Switch the router back | Needs double the capacity (or shared data tier handled carefully) |
|
|
29
|
+
| **Canary** | Roll the new version to a small subset of servers/users first; widen as confidence grows | Stop and route back to the old version | Requires routing control + per-cohort metrics; A/B and capacity testing for free |
|
|
30
|
+
| **Rolling** | Replace instances in batches behind a load balancer | Roll the batches back | Both versions run at once — needs backward-compatible data + contracts |
|
|
31
|
+
| **Recreate** | Stop old, start new | Redeploy previous version | Incurs downtime; only where an outage window is acceptable |
|
|
32
|
+
|
|
33
|
+
Keep **as few versions in production as possible** — ideally two (old + new)
|
|
34
|
+
during a transition. Every concurrent version multiplies the compatibility matrix.
|
|
35
|
+
|
|
36
|
+
## Rollback is a practiced capability, not a hope
|
|
37
|
+
|
|
38
|
+
- **Always be able to roll back.** Back up production state before a release and
|
|
39
|
+
*rehearse* the rollback before every release — an untested rollback is not a
|
|
40
|
+
rollback.
|
|
41
|
+
- The simplest reliable rollback is **redeploying the last known-good version**
|
|
42
|
+
from scratch through the same pipeline.
|
|
43
|
+
- Data makes rollback hard: pair this with expand/contract migrations
|
|
44
|
+
(`database-change-management.md`) so the schema is compatible with the version
|
|
45
|
+
you roll back to.
|
|
46
|
+
- Prefer **rolling back over hot-fixing** a bad release. Emergency fixes still go
|
|
47
|
+
through the standard pipeline — never hand-patch production.
|
|
48
|
+
|
|
49
|
+
## Keeping mainline releasable (Ch.14)
|
|
50
|
+
|
|
51
|
+
- **Develop on trunk; commit at least daily.** Long-lived feature branches are
|
|
52
|
+
opposed to continuous integration — they cause merge hell and hide integration
|
|
53
|
+
risk until late.
|
|
54
|
+
- Make large changes as **small incremental steps on mainline** using feature
|
|
55
|
+
hiding, componentization, or branch by abstraction — not a branch.
|
|
56
|
+
- **Branch only for release, for a spike, or in extremis.** A release branch
|
|
57
|
+
takes only critical fixes, merged back to mainline immediately; it replaces the
|
|
58
|
+
anti-pattern of a code freeze.
|
|
59
|
+
|
|
60
|
+
## Planning hook
|
|
61
|
+
|
|
62
|
+
When `/plan` decomposes a feature, prefer slices that keep trunk releasable at
|
|
63
|
+
every step: land the change behind a toggle or behind an abstraction, sequence
|
|
64
|
+
data changes as expand-before-contract, and avoid a slice that is only shippable
|
|
65
|
+
once the whole feature is done.
|
|
66
|
+
|
|
67
|
+
## How this connects to the rest of the toolkit
|
|
68
|
+
|
|
69
|
+
- **`database-change-management.md`** — the data-tier half of every pattern here;
|
|
70
|
+
rolling, blue-green, and canary all require a schema compatible across versions.
|
|
71
|
+
- **`deployment-pipeline.md`** — these patterns ride on a pipeline that builds the
|
|
72
|
+
artifact once and promotes it; the deploy mechanism is identical per environment.
|
|
73
|
+
- **`cd-maturity-model.md`** — decoupling deploy from release and practiced
|
|
74
|
+
rollback are what move the "environments & deployment" practice area up the model.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Report Output Location
|
|
2
|
+
|
|
3
|
+
`.dev-team-reports/` is the shared location convention for dev-team's
|
|
4
|
+
human-invoked report-writing skills — `/review-agent`, `/code-review`
|
|
5
|
+
(interactive mode), `/triage`, and `/session-review`. It is a **literal,
|
|
6
|
+
hardcoded directory name** — it is not an environment variable, and it is
|
|
7
|
+
not currently overridable.
|
|
8
|
+
|
|
9
|
+
**Boundary: dated human-invoked reports vs. skill-internal scratch state.**
|
|
10
|
+
A skill lands here when a human directly invokes it to produce a durable,
|
|
11
|
+
readable deliverable (a review, a triage record, a session digest). Skills
|
|
12
|
+
that write bare `metrics/`/`memory/` scratch data for their *own* internal
|
|
13
|
+
bookkeeping — not a human-facing report — stay outside this convention even
|
|
14
|
+
when the word "report" appears in their name or output; see each such
|
|
15
|
+
skill's own path documentation for its rationale.
|
|
16
|
+
|
|
17
|
+
This file defines *where* reports go. `knowledge/report-template.md` defines
|
|
18
|
+
*what's inside* them (shared header/footer/empty-section contract) — the two
|
|
19
|
+
concerns compose independently.
|
|
20
|
+
|
|
21
|
+
## Write-scope rule
|
|
22
|
+
|
|
23
|
+
Only a **top-level human invocation** writes to `.dev-team-reports/`:
|
|
24
|
+
|
|
25
|
+
- `/review-agent <agent>` writes `.dev-team-reports/<agent>.md` — **unless**
|
|
26
|
+
`--internal` is passed (the orchestrator-internal dispatch signal; `/build`
|
|
27
|
+
is the only sanctioned caller today).
|
|
28
|
+
- `/code-review` (interactive, no `--json`) writes
|
|
29
|
+
`.dev-team-reports/code-review.md` — **unless** `--internal` is passed (the
|
|
30
|
+
sanctioned callers today are `/build`'s Step 6 backstop review and
|
|
31
|
+
`/test-improve`'s Phase 5/7 end-of-phase review loop — see below for
|
|
32
|
+
`/ship`'s Step 5, a deliberate, documented exception that keeps writing
|
|
33
|
+
the report) or `--json` is passed (CI/`/pr` callers — `--json` never
|
|
34
|
+
writes a file, full stop).
|
|
35
|
+
- `/triage` writes `.dev-team-reports/triage/<slug>.md` unconditionally — it
|
|
36
|
+
has no orchestrator-internal caller today.
|
|
37
|
+
- `/session-review` writes `.dev-team-reports/session-review-<date>.md` (or
|
|
38
|
+
`--out`) unconditionally — it has no orchestrator-internal caller today.
|
|
39
|
+
|
|
40
|
+
`--internal` and `--json` are orthogonal flags on `/code-review`: `--json`
|
|
41
|
+
governs output format and bypasses the review-fix loop; `--internal` only
|
|
42
|
+
suppresses the `.dev-team-reports/` write and has no effect on the fix loop
|
|
43
|
+
or output format.
|
|
44
|
+
|
|
45
|
+
## Report exception: /ship
|
|
46
|
+
|
|
47
|
+
`/ship`'s Step 5 ("Review") dispatches `/code-review` with neither
|
|
48
|
+
`--internal` nor `--json` — so it writes `.dev-team-reports/code-review.md`
|
|
49
|
+
by default, unlike `/build`'s Step 6 and `/test-improve`'s Phase 5/7 review
|
|
50
|
+
loop above. This is a **deliberate, stated exception** to the "only a
|
|
51
|
+
top-level human invocation writes" rule, not an unaudited gap (issue #982):
|
|
52
|
+
|
|
53
|
+
`/ship` is itself `user-invocable: true` and is only ever entered by a
|
|
54
|
+
human directly typing `/ship` — but so is `/build`, whose own internal
|
|
55
|
+
Step 6 dispatch is suppressed, so being human-typed at the top isn't by
|
|
56
|
+
itself what earns the exception. The stronger distinguishing factor is
|
|
57
|
+
**frequency and scope, not surfacing**: `/build`'s Step 7.5 evidence bundle
|
|
58
|
+
does surface the Step 6 `/code-review` *status* back to the human at
|
|
59
|
+
completion (a pass/fail line, not the artifact itself), and `/test-improve`
|
|
60
|
+
similarly surfaces its review outcome in each phase's evidence file — so
|
|
61
|
+
"no human-facing surfacing at all" is not the real dividing line. What
|
|
62
|
+
actually differs: `/build`'s Step 6 and `/test-improve`'s per-phase loop
|
|
63
|
+
each run **multiple times across a session** (once per build, once per
|
|
64
|
+
`/test-improve` phase) against a **diff-scoped** slice of the total change —
|
|
65
|
+
a `.dev-team-reports/code-review.md` write from either would represent only
|
|
66
|
+
one slice's worth of review, repeatedly overwritten, not "the latest state
|
|
67
|
+
for this repo." `/ship`'s Step 5 runs **once**, at the end of the whole
|
|
68
|
+
shipped feature, over the **full accumulated diff** — the one point in the
|
|
69
|
+
pipeline where a durable, complete review artifact is both meaningful and
|
|
70
|
+
non-redundant. Reinforcing this: `/code-review`'s own step-6 "exception (b)"
|
|
71
|
+
(which skips the interactive fix-or-report prompt for callers "running
|
|
72
|
+
inside `/build` or `/pr`") does not name `/ship` either — `/ship`'s dispatch
|
|
73
|
+
is genuinely interactive today, consistent with a human being present for
|
|
74
|
+
this one-time gate rather than an orchestrator-internal backstop.
|
|
75
|
+
|
|
76
|
+
## Fixed filenames: overwrite vs. never-overwrite
|
|
77
|
+
|
|
78
|
+
`/review-agent` and `/code-review` write a **fixed, per-workflow filename**
|
|
79
|
+
that is **overwritten on every run** (`.dev-team-reports/<agent>.md`,
|
|
80
|
+
`.dev-team-reports/code-review.md`) — safe to overwrite because each file
|
|
81
|
+
represents "the latest state for this repo," not a history. Both skills
|
|
82
|
+
print a confirmation line noting the overwrite (`Report written:
|
|
83
|
+
.dev-team-reports/<name>.md (replaced previous run)`) so this is visible at
|
|
84
|
+
the point of use, not only here.
|
|
85
|
+
|
|
86
|
+
`/triage` is the deliberate exception: `.dev-team-reports/triage/<slug>.md`
|
|
87
|
+
is **never overwritten** — a same-slug collision appends `-2`, `-3`, … up to
|
|
88
|
+
`-99`. This is safe and necessary because, unlike a single repo's "latest
|
|
89
|
+
review state," multiple distinct bugs can be triaged concurrently and each
|
|
90
|
+
deserves its own durable record.
|
|
91
|
+
|
|
92
|
+
## Write failures are always non-fatal
|
|
93
|
+
|
|
94
|
+
A `.dev-team-reports/` write failure (permission/read-only) is reported to
|
|
95
|
+
chat but never blocks or alters the skill's existing primary output — the
|
|
96
|
+
JSON result and chat summary for `/review-agent`, the prose summary for
|
|
97
|
+
`/code-review`, and the temp-file/chat fallback for `/triage`. The file
|
|
98
|
+
write is strictly additive.
|
|
99
|
+
|
|
100
|
+
## Gitignored by default, with a tracked exception for report data
|
|
101
|
+
|
|
102
|
+
`.dev-team-reports/` is gitignored by default — both in this repo's own
|
|
103
|
+
`.gitignore` and in `/project-init`'s JS-scaffold `.gitignore` template for
|
|
104
|
+
newly-provisioned target repos — matching the existing treatment of
|
|
105
|
+
`reports/` and the prior `.triage/` convention it replaces. Both use the
|
|
106
|
+
same anchored deny-all + re-included tracked-exception shape (`/.dev-team-reports/*`
|
|
107
|
+
followed by `!/.dev-team-reports/test-improve/`), not a blanket directory
|
|
108
|
+
ignore — `/test-improve`'s `<slug>/data/` sibling directory (issue #1412) is
|
|
109
|
+
git-tracked, and each artifact under it is written there directly, atomically,
|
|
110
|
+
at the point of capture (never copied there later from a separate working
|
|
111
|
+
location), so its report is a pure function of tracked data and regeneratable
|
|
112
|
+
from a fresh checkout.
|
|
113
|
+
|
|
114
|
+
## Related
|
|
115
|
+
|
|
116
|
+
- `knowledge/report-template.md` — the shared header/footer/empty-section
|
|
117
|
+
content contract for what goes *inside* a report written to this location.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# The `--pdf` flag on report-producing skills
|
|
2
|
+
|
|
3
|
+
The single contract for the `--pdf` pass-through, shared by every skill that
|
|
4
|
+
writes a Markdown report (`/code-review`, `/test-health`,
|
|
5
|
+
`/cd-test-architecture`, `/triage`, `/harness-audit`, `/repo-review`). Each
|
|
6
|
+
skill references this file rather than restating the behavior, so the
|
|
7
|
+
wording never drifts.
|
|
8
|
+
|
|
9
|
+
This file defines *how `--pdf` behaves*. `hooks/lib/report_pdf.py` is the render
|
|
10
|
+
engine it calls; [`report-to-pdf.md`](report-to-pdf.md) is the underlying
|
|
11
|
+
recipe; [`report-output-location.md`](report-output-location.md) details the
|
|
12
|
+
`.dev-team-reports/` write rules — the per-skill paths are in the table below.
|
|
13
|
+
|
|
14
|
+
## Contract
|
|
15
|
+
|
|
16
|
+
When a skill is invoked with `--pdf`:
|
|
17
|
+
|
|
18
|
+
1. **Render the report this run actually wrote — not a fixed path.** After the
|
|
19
|
+
skill has written its Markdown report, resolve the concrete path that run
|
|
20
|
+
produced (each skill knows its own — see the table below) and render it:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
sh "$CLAUDE_PLUGIN_ROOT/hooks/py.sh" "$CLAUDE_PLUGIN_ROOT/hooks/lib/report_pdf.py" <the-report-path-just-written>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The module prints a `Rendering PDF via <engine>…` progress line (the
|
|
27
|
+
render can take several seconds on a cold headless-Chrome start), then one
|
|
28
|
+
result line. Surface the output; on success it states the sibling PDF path
|
|
29
|
+
and the engine used.
|
|
30
|
+
|
|
31
|
+
2. **No report written → no-op with a message, never an error.** If the run
|
|
32
|
+
wrote no Markdown report (see the no-file modes below), do **not** invoke the
|
|
33
|
+
module. State plainly: `--pdf: no report file was written this run, nothing to render.` and continue. This is a no-op, not a failure.
|
|
34
|
+
|
|
35
|
+
3. **No engine available → skip, never fail.** If `report_pdf.py` finds no PDF
|
|
36
|
+
engine it exits 0 with an install hint and leaves the Markdown untouched.
|
|
37
|
+
`--pdf` never changes the skill's own exit status or primary output — PDF is
|
|
38
|
+
strictly additive.
|
|
39
|
+
|
|
40
|
+
4. **`--json` output stays pure.** When a skill also runs in a machine-readable
|
|
41
|
+
`--json` mode, all `--pdf` status text (progress, skip, no-op) goes to
|
|
42
|
+
**stderr** so stdout remains valid JSON for scripted callers.
|
|
43
|
+
|
|
44
|
+
**Distinct wording — keep these two cases lexically separate** so a reader can
|
|
45
|
+
self-diagnose which they hit:
|
|
46
|
+
|
|
47
|
+
- **skip** (no engine): `No PDF engine found. Install one, …` (from the module).
|
|
48
|
+
- **no-op** (no report file written): `--pdf: no report file was written this run, nothing to render.`
|
|
49
|
+
|
|
50
|
+
## Per-skill report path and no-file modes
|
|
51
|
+
|
|
52
|
+
| Skill | Report path this run wrote | `--pdf` no-op when |
|
|
53
|
+
|-------|----------------------------|--------------------|
|
|
54
|
+
| `/code-review` | `.dev-team-reports/code-review.md` | `--json` or `--internal` (no file written) |
|
|
55
|
+
| `/triage` | `.dev-team-reports/triage/<slug>.md` (the path just written) | never — it always writes a file |
|
|
56
|
+
| `/test-health` | `.dev-team-reports/test-health-<date>.md` | never — it always writes a file |
|
|
57
|
+
| `/cd-test-architecture` | `.dev-team-reports/cd-test-architecture-<app>.md` | single-component **chat-only** run (no file) |
|
|
58
|
+
| `/harness-audit` | `.dev-team-reports/harness-audit-<date>.md`, or the `--output <path>` override | never — it always writes a file |
|
|
59
|
+
| `/repo-review` | `.dev-team-reports/repo-review.md` | `--json` (no file written) |
|
|
60
|
+
|
|
61
|
+
A new report-producing skill inherits `--pdf` by adding a row here, documenting
|
|
62
|
+
`--pdf` in its `argument-hint`, and calling `report_pdf.py` on the path it wrote
|
|
63
|
+
— no new render logic.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/* report-print.css — bundled print stylesheet for dev-team report PDFs (#1114).
|
|
2
|
+
*
|
|
3
|
+
* Applied by hooks/lib/report_pdf.py when converting any .dev-team-reports/*.md
|
|
4
|
+
* (or reports/*.md) to a shareable PDF. Goals: accent-colored headings,
|
|
5
|
+
* zebra-striped bordered tables, monospace chips for `file:line`, sane @page
|
|
6
|
+
* margins, and no clipped wide cells or mid-row page breaks.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
@page {
|
|
10
|
+
size: A4;
|
|
11
|
+
margin: 18mm 16mm;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:root {
|
|
15
|
+
--accent: #2563eb;
|
|
16
|
+
--accent-dark: #1e3a8a;
|
|
17
|
+
--border: #d0d7de;
|
|
18
|
+
--zebra: #f6f8fa;
|
|
19
|
+
--chip-bg: #eef1f5;
|
|
20
|
+
--ink: #1f2328;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
html {
|
|
24
|
+
-webkit-print-color-adjust: exact;
|
|
25
|
+
print-color-adjust: exact;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
body {
|
|
29
|
+
font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
30
|
+
font-size: 10.5pt;
|
|
31
|
+
line-height: 1.5;
|
|
32
|
+
color: var(--ink);
|
|
33
|
+
margin: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
h1,
|
|
37
|
+
h2,
|
|
38
|
+
h3,
|
|
39
|
+
h4 {
|
|
40
|
+
color: var(--accent-dark);
|
|
41
|
+
line-height: 1.25;
|
|
42
|
+
page-break-after: avoid; /* never orphan a heading at the foot of a page */
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
h1 {
|
|
46
|
+
font-size: 20pt;
|
|
47
|
+
border-bottom: 3px solid var(--accent);
|
|
48
|
+
padding-bottom: 0.2em;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
h2 {
|
|
52
|
+
font-size: 15pt;
|
|
53
|
+
border-bottom: 1px solid var(--border);
|
|
54
|
+
padding-bottom: 0.15em;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
h3 {
|
|
58
|
+
font-size: 12.5pt;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
a {
|
|
62
|
+
color: var(--accent);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* Inline code / `file:line` chips — monospace, tinted, and allowed to wrap so a
|
|
66
|
+
* long path never clips out of a table cell. */
|
|
67
|
+
code {
|
|
68
|
+
font-family: "SF Mono", "Cascadia Code", Consolas, "Liberation Mono", monospace;
|
|
69
|
+
font-size: 0.9em;
|
|
70
|
+
background: var(--chip-bg);
|
|
71
|
+
padding: 0.08em 0.35em;
|
|
72
|
+
border-radius: 4px;
|
|
73
|
+
word-break: break-all;
|
|
74
|
+
overflow-wrap: anywhere;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
pre {
|
|
78
|
+
background: var(--zebra);
|
|
79
|
+
border: 1px solid var(--border);
|
|
80
|
+
border-radius: 6px;
|
|
81
|
+
padding: 0.75em 1em;
|
|
82
|
+
overflow-x: auto;
|
|
83
|
+
white-space: pre-wrap; /* wrap long lines instead of clipping */
|
|
84
|
+
word-break: break-word;
|
|
85
|
+
page-break-inside: avoid;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
pre code {
|
|
89
|
+
background: none;
|
|
90
|
+
padding: 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
table {
|
|
94
|
+
border-collapse: collapse;
|
|
95
|
+
width: 100%;
|
|
96
|
+
margin: 0.75em 0;
|
|
97
|
+
font-size: 9.5pt;
|
|
98
|
+
table-layout: fixed; /* honor width so wide cells wrap rather than overflow */
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
th,
|
|
102
|
+
td {
|
|
103
|
+
border: 1px solid var(--border);
|
|
104
|
+
padding: 0.4em 0.6em;
|
|
105
|
+
text-align: left;
|
|
106
|
+
vertical-align: top;
|
|
107
|
+
word-break: break-word;
|
|
108
|
+
overflow-wrap: anywhere; /* wide file:line cells wrap, never clip */
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
th {
|
|
112
|
+
background: var(--accent);
|
|
113
|
+
color: #ffffff;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
tbody tr:nth-child(even) {
|
|
117
|
+
background: var(--zebra); /* zebra striping */
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
tr {
|
|
121
|
+
page-break-inside: avoid; /* keep a row whole across a page boundary */
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
blockquote {
|
|
125
|
+
border-left: 4px solid var(--accent);
|
|
126
|
+
margin: 0.75em 0;
|
|
127
|
+
padding: 0.2em 1em;
|
|
128
|
+
color: #57606a;
|
|
129
|
+
}
|