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,372 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Classify a changeset's shape to gate low-yield review lenses (#1254).
|
|
3
|
+
|
|
4
|
+
Running the full review panel unconditionally wastes tokens on diffs with no
|
|
5
|
+
runtime/logic surface. The 2026-07-20 audit found `performance-review` fired
|
|
6
|
+
0/10 and `correctness-review` 1/10 — on doc/config-dominated commits most lenses
|
|
7
|
+
no-op. `/code-review` (invoked directly) applies no complexity gate the way
|
|
8
|
+
`/build` and `/plan` do, so every lens runs on every changed file regardless of
|
|
9
|
+
change shape.
|
|
10
|
+
|
|
11
|
+
This module is the deterministic gate. Given the changed-file list it decides
|
|
12
|
+
whether the changeset has any **runtime surface** — a file that could hold
|
|
13
|
+
executable logic. When it does not (every file is documentation or config),
|
|
14
|
+
the two low-yield code lenses (`performance-review`, `correctness-review`) are
|
|
15
|
+
skipped; the rest of the panel still runs.
|
|
16
|
+
|
|
17
|
+
**Fail-safe by construction.** A file is "no runtime surface" only when it is
|
|
18
|
+
*provably* documentation or config (matches an explicit allowlist). Anything
|
|
19
|
+
else — an unknown extension, a source file, functional Claude-config markdown —
|
|
20
|
+
counts as runtime surface, so the lenses run. A misclassification can only ever
|
|
21
|
+
*add* a lens, never silently drop one on real code.
|
|
22
|
+
|
|
23
|
+
Pure policy — no filesystem, no globals. Mirrors the documentation-only
|
|
24
|
+
short-circuit's classification in `code-review/SKILL.md` (this gate is the
|
|
25
|
+
weaker sibling: the short-circuit skips *everything* when every file is
|
|
26
|
+
documentation; this skips only the two low-yield lenses when every file is
|
|
27
|
+
documentation *or* config, which the doc-only short-circuit does not cover).
|
|
28
|
+
|
|
29
|
+
Test-only classification (#1964)
|
|
30
|
+
--------------------------------
|
|
31
|
+
This module answers a second, independent question: is *every* changed file
|
|
32
|
+
provably a test file (per `knowledge/test-file-indicators.md`)? A diff of that
|
|
33
|
+
shape is structurally incapable of exhibiting what several expensive lenses
|
|
34
|
+
look for — and under `/test-improve`'s default `refactor-mode: no-refactor`,
|
|
35
|
+
Phase 5's diff is *guaranteed* to have it, because `/build` rejects
|
|
36
|
+
production-code changes in that mode.
|
|
37
|
+
|
|
38
|
+
`testOnly` is reported but currently skips **nothing**: `TEST_ONLY_SKIP_LENSES`
|
|
39
|
+
ships empty on purpose. Which lens is safe to drop on a test-only diff is an
|
|
40
|
+
empirical question, and the evidence (per-lens outcomes split by `diff_shape`
|
|
41
|
+
in `review-value.jsonl`) is still being collected. This mirrors the
|
|
42
|
+
architectural-impact gate's own rule — "widen `GATED_LENSES` from #1624's
|
|
43
|
+
measured per-agent data, not from intuition about which lens probably no-ops."
|
|
44
|
+
Two lenses in particular must NOT be added without data: `security-review`
|
|
45
|
+
(tests embed credentials and injection payloads) and `correctness-review`
|
|
46
|
+
(an inverted assertion is precisely its subject).
|
|
47
|
+
|
|
48
|
+
Test-only classification is **include-biased in the same direction** as the
|
|
49
|
+
runtime-surface check: a changeset is test-only only when every file is
|
|
50
|
+
*provably* a test. Anything unproven — a fixture, a `conftest.py`, a helper, a
|
|
51
|
+
`.cs` file whose test-ness needs its contents — makes the answer `False`, so
|
|
52
|
+
the full panel runs. Because this module is filesystem-free by contract, the
|
|
53
|
+
content-probing branches of the shared classifier are deliberately starved
|
|
54
|
+
(`content=""`), which can only ever move the answer toward "not test-only".
|
|
55
|
+
|
|
56
|
+
Scope note: this is a filename-shape gate. Annotation-only edits *inside* a
|
|
57
|
+
source file (e.g. adding a C# attribute) still count as runtime surface — that
|
|
58
|
+
would require diff parsing and is deliberately out of scope for v1.
|
|
59
|
+
|
|
60
|
+
Shared literal tables (#1477): the documentation-extension, doc-root-word,
|
|
61
|
+
and functional-config-name/segment literals below are byte-identical to
|
|
62
|
+
`hooks/pre_commit_review.py`'s own doc-only classifier and were previously
|
|
63
|
+
hand-duplicated between the two, kept in sync only by comment convention.
|
|
64
|
+
They now live in `hooks/lib/doc_classification.py`, imported here via the
|
|
65
|
+
same `sys.path.insert` cross-boundary pattern `pre_commit_review.py` already
|
|
66
|
+
uses for its own `hooks/lib/` imports — see that module's docstring for why
|
|
67
|
+
this location was chosen and why the *matching logic* (prefix vs. exact
|
|
68
|
+
match) intentionally stays local to each caller rather than being unified
|
|
69
|
+
too.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
from __future__ import annotations
|
|
73
|
+
|
|
74
|
+
import argparse
|
|
75
|
+
import json
|
|
76
|
+
import sys
|
|
77
|
+
from collections.abc import Iterable
|
|
78
|
+
from pathlib import Path, PurePosixPath
|
|
79
|
+
|
|
80
|
+
# skills/code-review/scripts -> skills/code-review -> skills -> plugin root
|
|
81
|
+
# -> hooks/lib
|
|
82
|
+
_HOOKS_LIB_DIR = Path(__file__).resolve().parents[3] / "hooks" / "lib"
|
|
83
|
+
if str(_HOOKS_LIB_DIR) not in sys.path:
|
|
84
|
+
sys.path.insert(0, str(_HOOKS_LIB_DIR))
|
|
85
|
+
|
|
86
|
+
# Both shared modules are imported, never re-implemented. There is deliberately
|
|
87
|
+
# no `except ImportError` fallback (#1968): a hand-written stand-in for a shared
|
|
88
|
+
# classifier is a second copy of the logic that can drift from its source
|
|
89
|
+
# silently, and one already did — the `is_test_file` fallback added in #1964
|
|
90
|
+
# shipped folding all four indicator families into one `re.IGNORECASE` pattern
|
|
91
|
+
# while `test_file_classify` compiles its step-definition regex
|
|
92
|
+
# case-sensitively, so `backsteps.py` read as a step definition and an ordinary
|
|
93
|
+
# source file could pass as a test. The whole suite stayed green, because every
|
|
94
|
+
# other test exercised the import path that succeeds.
|
|
95
|
+
#
|
|
96
|
+
# `hooks/lib/` ships inside this same plugin, so an unreachable one is a broken
|
|
97
|
+
# install or a moved file, not a supported degraded mode. Failing here — loudly,
|
|
98
|
+
# naming the path that was searched — surfaces that immediately instead of
|
|
99
|
+
# silently answering classification questions from a divergent copy.
|
|
100
|
+
def _require_shared(module: str) -> ImportError:
|
|
101
|
+
"""Build the diagnostic for a shared-module import that could not resolve.
|
|
102
|
+
|
|
103
|
+
The parent-count in `_HOOKS_LIB_DIR` is the fragile part (a moved file
|
|
104
|
+
changes it), so the message names the resolved path rather than leaving a
|
|
105
|
+
bare `No module named ...` to be reverse-engineered.
|
|
106
|
+
"""
|
|
107
|
+
return ImportError(
|
|
108
|
+
f"{__name__} requires the shared classifier {module!r} from the "
|
|
109
|
+
f"dev-team plugin's hooks/lib, which could not be imported.\n"
|
|
110
|
+
f" searched: {_HOOKS_LIB_DIR}\n"
|
|
111
|
+
f" exists: {_HOOKS_LIB_DIR.is_dir()}\n"
|
|
112
|
+
"This module deliberately has no fallback copy of the classifier "
|
|
113
|
+
"(#1968) — a divergent stand-in silently mis-classifies files. Fix the "
|
|
114
|
+
"install or the path rather than re-adding a local implementation."
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
from doc_classification import ( # type: ignore[import-not-found]
|
|
120
|
+
DOC_EXTENSIONS,
|
|
121
|
+
DOC_ROOT_WORDS,
|
|
122
|
+
is_functional_config,
|
|
123
|
+
)
|
|
124
|
+
except ImportError as exc: # pragma: no cover - broken install, not a supported mode
|
|
125
|
+
raise _require_shared("doc_classification") from exc
|
|
126
|
+
|
|
127
|
+
# `knowledge/test-file-indicators.md`'s single encoding, shared with the
|
|
128
|
+
# refactor test-freeze guards (#1964).
|
|
129
|
+
try:
|
|
130
|
+
from test_file_classify import is_test_file # type: ignore[import-not-found]
|
|
131
|
+
except ImportError as exc: # pragma: no cover - broken install, not a supported mode
|
|
132
|
+
raise _require_shared("test_file_classify") from exc
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
LOW_YIELD_LENSES = ["performance-review", "correctness-review"]
|
|
136
|
+
|
|
137
|
+
# Lenses to skip when EVERY changed file is provably prose (`.md`/`.mdx`),
|
|
138
|
+
# including functional Claude-config markdown (#2104). `has_runtime_surface`
|
|
139
|
+
# correctly treats agents/skills/knowledge/.claude markdown as runtime
|
|
140
|
+
# surface — it drives agent behavior, so `performance-review` and
|
|
141
|
+
# `correctness-review` still run against it above. But a handful of lenses
|
|
142
|
+
# review a *code-level* property no markdown file, functional or not, can
|
|
143
|
+
# exhibit: an injection/auth/data-exposure vulnerability, a domain-boundary
|
|
144
|
+
# leak, a test-coverage gap, or a resource leak/N+1 query. Dispatching a
|
|
145
|
+
# 9-agent panel (including these four) against a single-file skill-markdown
|
|
146
|
+
# diff produced elaborate findings framed as security/domain/test/performance
|
|
147
|
+
# issues that were really prose/spec-consistency nitpicks belonging to
|
|
148
|
+
# doc-review/spec-compliance-review/correctness-review instead. Each of these
|
|
149
|
+
# four agents' own `## Skip` clause already self-reports skip on a
|
|
150
|
+
# documentation-only target (security-review: "static assets, images, or
|
|
151
|
+
# documentation"; domain-review: "no business logic or domain entities
|
|
152
|
+
# present"; test-review: "no test files in target"; performance-review:
|
|
153
|
+
# "configuration, documentation, or type definitions") — dispatching them
|
|
154
|
+
# anyway just pays for a self-reported skip, or worse, an ungrounded finding
|
|
155
|
+
# stretched to fit the lens.
|
|
156
|
+
#
|
|
157
|
+
# Deliberately NARROWER than `select_lenses.py`'s own
|
|
158
|
+
# `NON_EXECUTABLE_SKIP_ELIGIBLE` allowlist, which considered and REJECTED
|
|
159
|
+
# adding security-review/domain-review/arch-review for its broader
|
|
160
|
+
# "non-executable" category (docs **and** config/lockfiles/assets): that
|
|
161
|
+
# module's own comment documents why — security-review's Skip clause does not
|
|
162
|
+
# cover config/lockfiles (its Scope mandates scanning them for hardcoded
|
|
163
|
+
# credentials) and domain-review's is a content judgment a config file's type
|
|
164
|
+
# alone can't answer. This module's prose-only signal is strictly `.md`/
|
|
165
|
+
# `.mdx` — it never widens to config, so neither rejection applies here.
|
|
166
|
+
# `arch-review` and `correctness-review` are deliberately absent from this
|
|
167
|
+
# list for the same reason `select_lenses.py` keeps `arch-review` unfiltered:
|
|
168
|
+
# a pure-markdown ADR update, or a functional-config skill/agent file, is
|
|
169
|
+
# exactly the content their own `## Detect` sections exist to review.
|
|
170
|
+
PROSE_ONLY_SKIP_LENSES = [
|
|
171
|
+
"security-review", "domain-review", "test-review", "performance-review",
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
# Extensions provably incapable of holding anything but prose (lower-cased).
|
|
175
|
+
_PROSE_EXTENSIONS = {".md", ".mdx"}
|
|
176
|
+
|
|
177
|
+
# Lenses to skip when EVERY changed file is provably a test file (#1964).
|
|
178
|
+
# Deliberately EMPTY until per-lens `diff_shape` outcome data justifies each
|
|
179
|
+
# entry — see this module's docstring. Adding a name here without citing that
|
|
180
|
+
# measurement is the mistake the docstring names; `security-review` and
|
|
181
|
+
# `correctness-review` are explicitly not candidates on intuition.
|
|
182
|
+
TEST_ONLY_SKIP_LENSES: list[str] = []
|
|
183
|
+
|
|
184
|
+
# Documentation extensions (lower-cased). Mirrors SKILL.md's doc-only rule.
|
|
185
|
+
_DOC_EXTENSIONS = DOC_EXTENSIONS
|
|
186
|
+
|
|
187
|
+
# Documentation root-file stems (matched case-insensitively on the stem
|
|
188
|
+
# prefix) — same word list `pre_commit_review.py`'s doc-only classifier uses
|
|
189
|
+
# for its own (exact-match) root-doc check.
|
|
190
|
+
_DOC_ROOT_PREFIXES = DOC_ROOT_WORDS
|
|
191
|
+
|
|
192
|
+
# Config / data extensions with no executable logic surface (lower-cased).
|
|
193
|
+
# Unique to this gate — `pre_commit_review.py` has no equivalent "config"
|
|
194
|
+
# concept, so this stays local (nothing to extract against).
|
|
195
|
+
_CONFIG_EXTENSIONS = {
|
|
196
|
+
".json", ".yaml", ".yml", ".toml", ".ini", ".cfg", ".conf",
|
|
197
|
+
".properties", ".lock", ".csv", ".tsv",
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
# Config dotfiles carry no suffix (``PurePosixPath(".gitignore").suffix == ""``),
|
|
201
|
+
# so they are matched by full name instead (lower-cased).
|
|
202
|
+
_CONFIG_NAMES = {
|
|
203
|
+
".gitignore", ".gitattributes", ".editorconfig", ".env", ".dockerignore",
|
|
204
|
+
".npmignore", ".prettierignore",
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
# Functional-config classification (markdown/paths that drive agent/skill/
|
|
208
|
+
# command behavior and always count as runtime surface, same exclusion as
|
|
209
|
+
# SKILL.md) now lives in `is_functional_config` above — shared with
|
|
210
|
+
# `select_lenses.py` (#1923), including the "templates" addition this gate
|
|
211
|
+
# has always applied on top of the shared core set (`pre_commit_review.py`'s
|
|
212
|
+
# doc-only classifier deliberately does not include it; see that module's
|
|
213
|
+
# docstring on staying a strict subset — unaffected by this extraction).
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _is_documentation(path: PurePosixPath) -> bool:
|
|
217
|
+
if path.suffix.lower() in _DOC_EXTENSIONS:
|
|
218
|
+
return True
|
|
219
|
+
if "docs" in path.parts:
|
|
220
|
+
return True
|
|
221
|
+
stem = path.name.lower()
|
|
222
|
+
return any(stem.startswith(prefix) for prefix in _DOC_ROOT_PREFIXES)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def _is_config(path: PurePosixPath) -> bool:
|
|
226
|
+
return (
|
|
227
|
+
path.suffix.lower() in _CONFIG_EXTENSIONS
|
|
228
|
+
or path.name.lower() in _CONFIG_NAMES
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _has_runtime_surface_file(file: str) -> bool:
|
|
233
|
+
"""True when a single file could hold executable logic (fail-safe default)."""
|
|
234
|
+
path = PurePosixPath(str(file).strip())
|
|
235
|
+
if not path.name:
|
|
236
|
+
return False # empty entry contributes nothing
|
|
237
|
+
if is_functional_config(path):
|
|
238
|
+
return True
|
|
239
|
+
# Provably non-runtime only when documentation or config; anything else
|
|
240
|
+
# (source, unknown extension) is treated as runtime surface.
|
|
241
|
+
return not (_is_documentation(path) or _is_config(path))
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def has_runtime_surface(files: Iterable[str]) -> bool:
|
|
245
|
+
"""True when *any* changed file could hold executable logic.
|
|
246
|
+
|
|
247
|
+
An empty changeset has no runtime surface (returns False).
|
|
248
|
+
"""
|
|
249
|
+
return any(_has_runtime_surface_file(f) for f in files if str(f).strip())
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _is_provably_test_file(file: str) -> bool:
|
|
253
|
+
"""True when a single file is provably a test (fail-safe default: False).
|
|
254
|
+
|
|
255
|
+
`content=""` starves the shared classifier's content-probing branches (C#
|
|
256
|
+
attributes, Java annotations) rather than touching the filesystem, keeping
|
|
257
|
+
this module's no-I/O contract. That can only ever answer "not a test",
|
|
258
|
+
which biases the changeset toward "not test-only" — i.e. toward running
|
|
259
|
+
every lens. Java's class-name convention (`FooTest.java`) still resolves
|
|
260
|
+
by name and is unaffected.
|
|
261
|
+
"""
|
|
262
|
+
name = str(file).strip()
|
|
263
|
+
if not name:
|
|
264
|
+
return False
|
|
265
|
+
return bool(is_test_file(name, content=""))
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def is_test_only(files: Iterable[str]) -> bool:
|
|
269
|
+
"""True when *every* changed file is provably a test file.
|
|
270
|
+
|
|
271
|
+
An empty changeset is not test-only (there is nothing to prove), matching
|
|
272
|
+
`has_runtime_surface`'s treatment of the empty case.
|
|
273
|
+
"""
|
|
274
|
+
file_list = [f for f in files if str(f).strip()]
|
|
275
|
+
if not file_list:
|
|
276
|
+
return False
|
|
277
|
+
return all(_is_provably_test_file(f) for f in file_list)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _is_prose_file(file: str) -> bool:
|
|
281
|
+
return PurePosixPath(str(file).strip()).suffix.lower() in _PROSE_EXTENSIONS
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def is_prose_only(files: Iterable[str]) -> bool:
|
|
285
|
+
"""True when *every* changed file is `.md`/`.mdx` prose (#2104).
|
|
286
|
+
|
|
287
|
+
Unlike `has_runtime_surface`, this makes no exception for functional
|
|
288
|
+
Claude-config markdown: a `.md` file cannot exhibit an injection
|
|
289
|
+
vulnerability, a domain-boundary leak, a test-coverage gap, or an N+1
|
|
290
|
+
query regardless of whether it also drives agent behavior. An empty
|
|
291
|
+
changeset is not prose-only, matching the other predicates' empty-case
|
|
292
|
+
convention.
|
|
293
|
+
"""
|
|
294
|
+
file_list = [f for f in files if str(f).strip()]
|
|
295
|
+
if not file_list:
|
|
296
|
+
return False
|
|
297
|
+
return all(_is_prose_file(f) for f in file_list)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def lenses_to_skip(files: Iterable[str]) -> list[str]:
|
|
301
|
+
"""Return the low-yield lenses to skip for this changeset.
|
|
302
|
+
|
|
303
|
+
Empty when the changeset has any runtime surface and is not prose-only.
|
|
304
|
+
A doc/config-only changeset (no runtime surface) skips `performance-review`
|
|
305
|
+
and `correctness-review`; a prose-only changeset (every file `.md`/`.mdx`,
|
|
306
|
+
including functional Claude-config markdown) additionally skips
|
|
307
|
+
`security-review`, `domain-review`, and `test-review` (#2104) — the two
|
|
308
|
+
sets are independent and union together, since a prose-only diff is
|
|
309
|
+
always also a no-runtime-surface diff unless it is functional config.
|
|
310
|
+
"""
|
|
311
|
+
file_list = [f for f in files if str(f).strip()]
|
|
312
|
+
if not file_list:
|
|
313
|
+
return [] # nothing to review — the caller handles empty scope
|
|
314
|
+
|
|
315
|
+
# Ordered, deduplicated union — preserves each source list's own order and
|
|
316
|
+
# never lists a lens twice (e.g. `performance-review` is in both
|
|
317
|
+
# LOW_YIELD_LENSES and PROSE_ONLY_SKIP_LENSES for a plain-docs-only diff).
|
|
318
|
+
skip: list[str] = []
|
|
319
|
+
seen: set[str] = set()
|
|
320
|
+
|
|
321
|
+
def _extend(names: Iterable[str]) -> None:
|
|
322
|
+
for name in names:
|
|
323
|
+
if name not in seen:
|
|
324
|
+
seen.add(name)
|
|
325
|
+
skip.append(name)
|
|
326
|
+
|
|
327
|
+
if not has_runtime_surface(file_list):
|
|
328
|
+
_extend(LOW_YIELD_LENSES)
|
|
329
|
+
# Runtime surface present. A test-only changeset may still narrow the
|
|
330
|
+
# roster once TEST_ONLY_SKIP_LENSES is populated from measured data; it is
|
|
331
|
+
# empty today, so this contributes nothing (#1964).
|
|
332
|
+
elif is_test_only(file_list):
|
|
333
|
+
_extend(TEST_ONLY_SKIP_LENSES)
|
|
334
|
+
if is_prose_only(file_list):
|
|
335
|
+
_extend(PROSE_ONLY_SKIP_LENSES)
|
|
336
|
+
return skip
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def main(argv=None) -> int:
|
|
340
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
341
|
+
parser.add_argument(
|
|
342
|
+
"--files", nargs="*", default=[],
|
|
343
|
+
help="changed file paths (space-separated)",
|
|
344
|
+
)
|
|
345
|
+
parser.add_argument(
|
|
346
|
+
"--files-from", default=None,
|
|
347
|
+
help="read newline-separated file paths from this file ('-' for stdin)",
|
|
348
|
+
)
|
|
349
|
+
args = parser.parse_args(argv)
|
|
350
|
+
|
|
351
|
+
files = list(args.files)
|
|
352
|
+
if args.files_from:
|
|
353
|
+
if args.files_from == "-":
|
|
354
|
+
text = sys.stdin.read()
|
|
355
|
+
else:
|
|
356
|
+
with open(args.files_from) as f:
|
|
357
|
+
text = f.read()
|
|
358
|
+
files.extend(line for line in text.splitlines() if line.strip())
|
|
359
|
+
|
|
360
|
+
skip = lenses_to_skip(files)
|
|
361
|
+
result = {
|
|
362
|
+
"hasRuntimeSurface": has_runtime_surface(files),
|
|
363
|
+
"isTestOnly": is_test_only(files),
|
|
364
|
+
"isProseOnly": is_prose_only(files),
|
|
365
|
+
"skipLenses": skip,
|
|
366
|
+
}
|
|
367
|
+
print(json.dumps(result, sort_keys=True))
|
|
368
|
+
return 0
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
if __name__ == "__main__":
|
|
372
|
+
raise SystemExit(main(sys.argv[1:]))
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Classify a changeset's size to gate the /code-review agent panel (#1339).
|
|
3
|
+
|
|
4
|
+
`/code-review` Step 3 dispatches the full ~17-agent `Scope: always` panel on
|
|
5
|
+
every review regardless of diff size — a 2-line registry-table-row removal
|
|
6
|
+
(issue #1331's fix: 2 files, ~1 added line) pays the same review cost as a
|
|
7
|
+
25-file structural migration (issue #1334's fix: 537 added lines). The
|
|
8
|
+
pre-PR hook (`hooks/pre_pr_review.py`, #1886) has no coupling to which or how
|
|
9
|
+
many agents ran — it only checks that `/code-review` produced a matching
|
|
10
|
+
`.pr-review-passed` hash — so the panel-size decision is entirely Step 3's to
|
|
11
|
+
make, and today it makes no such distinction.
|
|
12
|
+
|
|
13
|
+
This module is the deterministic gate, sibling to `change_shape.py` (#1254,
|
|
14
|
+
which gates by file *type*). This gate gates by file *size*: given the target
|
|
15
|
+
files' `git diff --numstat` lines, it decides whether the changeset qualifies
|
|
16
|
+
for a narrowed agent panel.
|
|
17
|
+
|
|
18
|
+
**Added lines only, not deleted.** Added lines are unverified, newly
|
|
19
|
+
introduced content a reviewer must actually check; deleted lines are
|
|
20
|
+
comparatively low-risk (a dangling reference from a large deletion breaks the
|
|
21
|
+
build/tests, not silently). This is what lets issue #1331's fix (97 deleted
|
|
22
|
+
lines, ~1 added) qualify while issue #1334's fix (537 added lines) does not —
|
|
23
|
+
weighting total added+deleted would keep #1331's fix on the slow path,
|
|
24
|
+
defeating this gate's own motivating example.
|
|
25
|
+
|
|
26
|
+
**Gate-machinery carve-out.** Any file under `hooks/` or `skills/code-review/`
|
|
27
|
+
— the enforcement mechanism and this gate's own review orchestration —
|
|
28
|
+
always disqualifies, at any size. A change to the gate's own logic is exactly
|
|
29
|
+
the case where a cheap, self-certifying review would be a problem, so it is
|
|
30
|
+
excluded from ever qualifying for the shortcut it defines.
|
|
31
|
+
|
|
32
|
+
**Fail-safe by construction**, mirroring `change_shape.py`'s own philosophy:
|
|
33
|
+
a `git diff --numstat` failure, a binary-file marker (`-\t-\tpath`), or any
|
|
34
|
+
line this module cannot parse disqualifies the gate for that run (full
|
|
35
|
+
panel) — never counts as "small enough" by omission.
|
|
36
|
+
|
|
37
|
+
**Applicability is Step 3's job, not this module's.** This gate only makes
|
|
38
|
+
sense when there is an actual diff to measure (auto-scoped uncommitted
|
|
39
|
+
changes, or `--since <ref>`) — `--path`, `--all`, and the full-repository
|
|
40
|
+
fallback review complete files, not a diff, so `SKILL.md` never invokes this
|
|
41
|
+
module for those scopes. That decision is documented in `SKILL.md` Step 3's
|
|
42
|
+
"Change-size gate" subsection, not enforced here.
|
|
43
|
+
|
|
44
|
+
Pure policy — no filesystem, no globals. Stdlib-only.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
from __future__ import annotations
|
|
48
|
+
|
|
49
|
+
import argparse
|
|
50
|
+
import json
|
|
51
|
+
import sys
|
|
52
|
+
from collections.abc import Iterable
|
|
53
|
+
from typing import NamedTuple
|
|
54
|
+
|
|
55
|
+
# Thresholds calibrated against two real commits cited in spec #1345:
|
|
56
|
+
# issue #1331's fix (2 files, ~1 added line — should qualify) and issue
|
|
57
|
+
# #1334's fix (25 files, 537 added lines — should not). Hardcoded, not a new
|
|
58
|
+
# review-config.json surface — smallest change that solves the stated
|
|
59
|
+
# problem; revisit if real usage shows these miscalibrated.
|
|
60
|
+
MAX_FILES = 3
|
|
61
|
+
MAX_ADDED_LINES = 20
|
|
62
|
+
|
|
63
|
+
# The agents that stay meaningful at any diff size and survive the fast path:
|
|
64
|
+
# a single line can introduce a vulnerability (security-review), a logic
|
|
65
|
+
# defect (correctness-review), a spec mismatch (spec-compliance-review), or
|
|
66
|
+
# doc drift (doc-review). Every other `Scope: always` agent is primarily a
|
|
67
|
+
# code-quality-at-scale concern a diff this small essentially cannot exhibit
|
|
68
|
+
# meaningfully.
|
|
69
|
+
#
|
|
70
|
+
# KEEP THIS IN SYNC with the identically-named list restated in English in
|
|
71
|
+
# `code-review/SKILL.md`'s "Change-size gate" subsection (Step 3) — same
|
|
72
|
+
# single-source-of-truth risk `change_shape.py`'s `LOW_YIELD_LENSES` already
|
|
73
|
+
# carries against its own `SKILL.md` restatement.
|
|
74
|
+
FAST_PATH_AGENTS = [
|
|
75
|
+
"security-review",
|
|
76
|
+
"correctness-review",
|
|
77
|
+
"spec-compliance-review",
|
|
78
|
+
"doc-review",
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
# Path segments marking the review/gate machinery itself. A change here is
|
|
82
|
+
# exactly the case where a cheap, self-certifying review is a safety problem,
|
|
83
|
+
# so it always disqualifies, regardless of size. Narrower than
|
|
84
|
+
# `change_shape.py`'s "functional Claude-config" carve-out (agents/,
|
|
85
|
+
# knowledge/, .claude/, templates/) — those stay eligible for the fast path
|
|
86
|
+
# when small enough, since issue #1331's own motivating example touches
|
|
87
|
+
# `knowledge/agent-registry.md` and an `agents/` file and is exactly the case
|
|
88
|
+
# this gate must unblock.
|
|
89
|
+
_GATE_MACHINERY_PREFIXES = ("hooks/", "skills/code-review/")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class NumstatResult(NamedTuple):
|
|
93
|
+
file_count: int
|
|
94
|
+
added_lines: int
|
|
95
|
+
ok: bool
|
|
96
|
+
files: tuple[str, ...]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def parse_numstat(lines: Iterable[str]) -> NumstatResult:
|
|
100
|
+
"""Parse `git diff --numstat` lines into a size signal.
|
|
101
|
+
|
|
102
|
+
Each line is `<added>\\t<deleted>\\t<path>`. A binary file reports `-` for
|
|
103
|
+
both counts; any line that isn't exactly that shape, or whose added/
|
|
104
|
+
deleted fields aren't parseable as non-negative integers (or `-`), marks
|
|
105
|
+
the whole result not-ok (fail-safe — a partial read is not "small").
|
|
106
|
+
"""
|
|
107
|
+
files: list[str] = []
|
|
108
|
+
added_total = 0
|
|
109
|
+
ok = True
|
|
110
|
+
for raw in lines:
|
|
111
|
+
line = raw.rstrip("\n")
|
|
112
|
+
if not line.strip():
|
|
113
|
+
continue
|
|
114
|
+
parts = line.split("\t")
|
|
115
|
+
if len(parts) != 3:
|
|
116
|
+
ok = False
|
|
117
|
+
continue
|
|
118
|
+
added_field, deleted_field, path = parts
|
|
119
|
+
if not path.strip():
|
|
120
|
+
ok = False
|
|
121
|
+
continue
|
|
122
|
+
if added_field == "-" and deleted_field == "-":
|
|
123
|
+
# Binary file — numstat can't report line counts. Fail-safe: we
|
|
124
|
+
# cannot prove this file is small, so disqualify the whole run.
|
|
125
|
+
ok = False
|
|
126
|
+
files.append(path)
|
|
127
|
+
continue
|
|
128
|
+
if not added_field.isdigit() or not deleted_field.isdigit():
|
|
129
|
+
ok = False
|
|
130
|
+
continue
|
|
131
|
+
added_total += int(added_field)
|
|
132
|
+
files.append(path)
|
|
133
|
+
return NumstatResult(
|
|
134
|
+
file_count=len(files), added_lines=added_total, ok=ok, files=tuple(files)
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def is_gate_machinery(path: str) -> bool:
|
|
139
|
+
"""True when `path` is under the review/gate enforcement machinery."""
|
|
140
|
+
normalized = str(path).strip().replace("\\", "/")
|
|
141
|
+
return any(normalized.startswith(prefix) for prefix in _GATE_MACHINERY_PREFIXES)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def qualifies_for_fast_path(result: NumstatResult) -> bool:
|
|
145
|
+
"""True when this changeset qualifies for the narrowed fast-path panel.
|
|
146
|
+
|
|
147
|
+
Requires: numstat parsed cleanly, file count and added-line count both
|
|
148
|
+
within threshold, and no file is gate machinery. Any single failing
|
|
149
|
+
condition disqualifies (fail-safe by construction).
|
|
150
|
+
"""
|
|
151
|
+
if not result.ok:
|
|
152
|
+
return False
|
|
153
|
+
if result.file_count == 0:
|
|
154
|
+
return False
|
|
155
|
+
if result.file_count > MAX_FILES:
|
|
156
|
+
return False
|
|
157
|
+
if result.added_lines > MAX_ADDED_LINES:
|
|
158
|
+
return False
|
|
159
|
+
return not any(is_gate_machinery(f) for f in result.files)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def evaluate(lines: Iterable[str]) -> dict:
|
|
163
|
+
"""Evaluate numstat lines and return the full decision as a dict."""
|
|
164
|
+
result = parse_numstat(lines)
|
|
165
|
+
qualifies = qualifies_for_fast_path(result)
|
|
166
|
+
return {
|
|
167
|
+
"filesChanged": result.file_count,
|
|
168
|
+
"addedLines": result.added_lines,
|
|
169
|
+
"qualifiesForFastPath": qualifies,
|
|
170
|
+
"keepAgents": list(FAST_PATH_AGENTS) if qualifies else [],
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def main(argv=None) -> int:
|
|
175
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
176
|
+
parser.add_argument(
|
|
177
|
+
"--numstat", nargs="*", default=[],
|
|
178
|
+
help="git diff --numstat lines, one per arg (space-separated)",
|
|
179
|
+
)
|
|
180
|
+
parser.add_argument(
|
|
181
|
+
"--numstat-from", default=None,
|
|
182
|
+
help="read newline-separated numstat lines from this file ('-' for stdin)",
|
|
183
|
+
)
|
|
184
|
+
args = parser.parse_args(argv)
|
|
185
|
+
|
|
186
|
+
lines = list(args.numstat)
|
|
187
|
+
if args.numstat_from:
|
|
188
|
+
if args.numstat_from == "-":
|
|
189
|
+
text = sys.stdin.read()
|
|
190
|
+
else:
|
|
191
|
+
with open(args.numstat_from) as handle:
|
|
192
|
+
text = handle.read()
|
|
193
|
+
lines.extend(line for line in text.splitlines() if line.strip())
|
|
194
|
+
|
|
195
|
+
print(json.dumps(evaluate(lines), sort_keys=True))
|
|
196
|
+
return 0
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
if __name__ == "__main__":
|
|
200
|
+
raise SystemExit(main(sys.argv[1:]))
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
__all__ = (
|
|
204
|
+
"FAST_PATH_AGENTS",
|
|
205
|
+
"MAX_ADDED_LINES",
|
|
206
|
+
"MAX_FILES",
|
|
207
|
+
"NumstatResult",
|
|
208
|
+
"evaluate",
|
|
209
|
+
"is_gate_machinery",
|
|
210
|
+
"parse_numstat",
|
|
211
|
+
"qualifies_for_fast_path",
|
|
212
|
+
)
|