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,463 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Pre-loop feasibility gate for the mutant-kill loop (#1158, part of #1156).
|
|
3
|
+
|
|
4
|
+
The mutant-kill loop re-runs mutation after every generation round, so it is
|
|
5
|
+
only viable when a scoped run gets **per-test** coverage (covering-subset per
|
|
6
|
+
mutant). On an xunit.v3 suite that requires the v2 shim; if the shim path is
|
|
7
|
+
declined, or per-test coverage capture fails (#1157) so Stryker degrades to
|
|
8
|
+
whole-suite-per-mutant, or a single round would blow a wall-clock budget, then
|
|
9
|
+
looping is infeasible — pay the cost once as a single advisory pass, never loop.
|
|
10
|
+
|
|
11
|
+
This module is the pure, testable **arbiter**: given the shim-first one-file
|
|
12
|
+
probe's results it returns ``enter-loop``, ``degrade``, or ``ask-operator``
|
|
13
|
+
with a reason. A shim decline or a capture failure returns ``degrade``
|
|
14
|
+
unconditionally; an estimated round over budget with no other blocker returns
|
|
15
|
+
``ask-operator`` instead — a pure time estimate is not a hard blocker, so the
|
|
16
|
+
gate defers to the operator rather than degrading on its own. The agent runs
|
|
17
|
+
the probe (reusing the wrapper + #1157's capture detection) and feeds the
|
|
18
|
+
measurements here; applying the shim exclusions is #1159's job.
|
|
19
|
+
|
|
20
|
+
``ask-operator`` is also the arbiter's answer when the detector found
|
|
21
|
+
shim-breaking xunit.v3 constructs (#1791). That used to be a pure time-budget
|
|
22
|
+
question, which meant the operator's real decision — port, exclude, skip, or
|
|
23
|
+
degrade — was never presented anywhere; the shim was silently built, declined,
|
|
24
|
+
or degraded and they found out from a report, if at all. Feeding the detector's
|
|
25
|
+
findings in through ``ProbeResult.v3_blockers`` makes the same decision point
|
|
26
|
+
carry the per-construct breakdown plus those four options (built and rendered
|
|
27
|
+
by ``hooks/lib/xunit_v3_operator_gate.py``, so the guard hook and this gate
|
|
28
|
+
present one story).
|
|
29
|
+
|
|
30
|
+
Fail-closed on an omitted ``--v3-findings-json`` (#1870): every caller of this
|
|
31
|
+
CLI is, by the calling convention, already on an xunit.v3 project — "plain
|
|
32
|
+
xunit.v2 / other stacks skip this gate" per ``agents/mutation-kill.md``. Before
|
|
33
|
+
this fix, omitting the flag silently meant "no blockers" (``_load_v3_findings``
|
|
34
|
+
returned an empty tuple indistinguishable from "the detector ran and found
|
|
35
|
+
none"), so a caller that forgot to run the detector — or wired it up wrong —
|
|
36
|
+
got ``enter-loop`` with no operator question ever asked, the exact silent
|
|
37
|
+
decision #1791 exists to stop. ``ProbeResult.v3_findings_known`` (default
|
|
38
|
+
``True``, so direct ``decide()`` callers that already know their own
|
|
39
|
+
"no blockers" state are unaffected) is ``False`` only when the CLI itself
|
|
40
|
+
observed the flag was never supplied; :func:`decide` then forces
|
|
41
|
+
``ask-operator`` with a reason naming the missing detector run, combined with
|
|
42
|
+
the budget signal exactly like a real blocker set would be.
|
|
43
|
+
|
|
44
|
+
Version scope (#2184): this gate exists for Stryker.NET < 5.0.0. On a known
|
|
45
|
+
>= 5.0.0 install, ``stryker_xunit_shim_guard.py`` silent-passes before the
|
|
46
|
+
shim-first probe this arbiter consumes would ever run — ``-t mtp`` +
|
|
47
|
+
``coverage-analysis: perTest`` already gets per-test coverage directly on
|
|
48
|
+
xunit.v3 (stryker-net#3752), so there is no shim to probe, decline, or
|
|
49
|
+
degrade from. Running this gate's probe against a >= 5.0.0 install is
|
|
50
|
+
unnecessary work, not incorrect — the arbiter itself is unchanged; the
|
|
51
|
+
version gate simply means callers on a known >= 5.0.0 install should skip
|
|
52
|
+
invoking it in the first place.
|
|
53
|
+
|
|
54
|
+
Stdlib-only.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
from __future__ import annotations
|
|
58
|
+
|
|
59
|
+
import argparse
|
|
60
|
+
import enum
|
|
61
|
+
import json
|
|
62
|
+
import os
|
|
63
|
+
import sys
|
|
64
|
+
from collections.abc import Sequence
|
|
65
|
+
from dataclasses import asdict, dataclass, field
|
|
66
|
+
from pathlib import Path
|
|
67
|
+
|
|
68
|
+
# skills/mutation-testing/scripts -> skills/mutation-testing -> skills
|
|
69
|
+
# -> plugin root -> hooks/lib
|
|
70
|
+
_HOOKS_LIB_DIR = Path(__file__).resolve().parents[3] / "hooks" / "lib"
|
|
71
|
+
if str(_HOOKS_LIB_DIR) not in sys.path:
|
|
72
|
+
sys.path.insert(0, str(_HOOKS_LIB_DIR))
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
import xunit_v3_operator_gate as _operator_gate # type: ignore[import-not-found]
|
|
76
|
+
except ImportError: # pragma: no cover - degraded fallback, hooks/lib unreachable
|
|
77
|
+
_operator_gate = None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class Outcome(enum.Enum):
|
|
81
|
+
"""The three valid ``Decision.outcome`` values the arbiter can return."""
|
|
82
|
+
|
|
83
|
+
ENTER_LOOP = "enter-loop"
|
|
84
|
+
DEGRADE = "degrade"
|
|
85
|
+
ASK_OPERATOR = "ask-operator"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
# Wall-clock ceiling for a single estimated loop round. Not a magic constant on
|
|
89
|
+
# the probe side — the round estimate is *derived from the measured probe*
|
|
90
|
+
# (probe_seconds × scope files); this ceiling is the operator-tolerable maximum,
|
|
91
|
+
# overridable so slow-but-working environments degrade rather than grind.
|
|
92
|
+
DEFAULT_ROUND_BUDGET_SECONDS = 1800.0
|
|
93
|
+
_BUDGET_ENV = "DEV_TEAM_MUTATION_ROUND_BUDGET_SECONDS"
|
|
94
|
+
|
|
95
|
+
WAIVER_MESSAGE = (
|
|
96
|
+
"mutant-kill loop not feasible on this suite (xunit.v3); ran single-pass "
|
|
97
|
+
"advisory instead"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# #1870: the reason surfaced when `ProbeResult.v3_findings_known` is False —
|
|
101
|
+
# the CLI never consulted the shim-breaking-construct detector for this
|
|
102
|
+
# xunit.v3 project, so entering the loop would be a guess, not a decision.
|
|
103
|
+
_V3_FINDINGS_UNKNOWN_REASON = (
|
|
104
|
+
"the xunit.v3 shim-breaking-construct detector output (--v3-findings-json) "
|
|
105
|
+
"was not supplied for this xunit.v3 project (#1870) — cannot rule out "
|
|
106
|
+
"shim-breaking constructs without it; run xunit_v3_feature_detector.py or "
|
|
107
|
+
"confirm none apply"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _clamp_budget_seconds(budget_seconds: float) -> float:
|
|
112
|
+
"""Clamp a non-positive budget back to ``DEFAULT_ROUND_BUDGET_SECONDS``.
|
|
113
|
+
|
|
114
|
+
Shared by :func:`resolve_budget_seconds` (env-sourced) and
|
|
115
|
+
:func:`decide` (an explicit ``budget_seconds``/``--budget-seconds``
|
|
116
|
+
override) so a non-positive value is treated identically regardless of
|
|
117
|
+
which path it arrived by (#1549) — an explicit ``0``/negative override
|
|
118
|
+
no longer silently bypasses the clamp and forces ``ASK_OPERATOR`` on
|
|
119
|
+
every invocation."""
|
|
120
|
+
return budget_seconds if budget_seconds > 0 else DEFAULT_ROUND_BUDGET_SECONDS
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def resolve_budget_seconds(env: dict | None = None) -> float:
|
|
124
|
+
"""The per-round wall-clock ceiling — ``DEFAULT_ROUND_BUDGET_SECONDS``
|
|
125
|
+
unless ``DEV_TEAM_MUTATION_ROUND_BUDGET_SECONDS`` overrides it. A
|
|
126
|
+
non-positive or unparseable override falls back to the default."""
|
|
127
|
+
src = os.environ if env is None else env
|
|
128
|
+
raw = src.get(_BUDGET_ENV)
|
|
129
|
+
if raw is None:
|
|
130
|
+
return DEFAULT_ROUND_BUDGET_SECONDS
|
|
131
|
+
try:
|
|
132
|
+
val = float(raw)
|
|
133
|
+
except (TypeError, ValueError):
|
|
134
|
+
return DEFAULT_ROUND_BUDGET_SECONDS
|
|
135
|
+
return _clamp_budget_seconds(val)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def estimate_round_seconds(probe_seconds: float, scope_file_count: int) -> float:
|
|
139
|
+
"""Estimate one full loop round from the one-file probe. Under working
|
|
140
|
+
per-test coverage each file costs ~the probe's wall-clock, so a round over
|
|
141
|
+
N files is ~probe × N. Derived from the probe, never hardcoded."""
|
|
142
|
+
if probe_seconds < 0:
|
|
143
|
+
probe_seconds = 0.0
|
|
144
|
+
return probe_seconds * max(1, scope_file_count)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass(frozen=True)
|
|
148
|
+
class ProbeResult:
|
|
149
|
+
"""The shim-first one-file probe's measurements — the four values that
|
|
150
|
+
always travel together as one probe's result set, plus the detector's
|
|
151
|
+
shim-breaking findings (#1791) when there are any.
|
|
152
|
+
|
|
153
|
+
``v3_blockers`` holds ``xunit_v3_feature_detector`` findings (its dataclass
|
|
154
|
+
or its ``--json`` dict form). ``v3_unclassified_files`` holds files the
|
|
155
|
+
guard hook's broader token scan flagged but the detector cannot classify —
|
|
156
|
+
they must still reach the operator rather than being dropped for lacking a
|
|
157
|
+
classification.
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
shim_declined: bool
|
|
161
|
+
capture_failed: bool
|
|
162
|
+
probe_seconds: float
|
|
163
|
+
scope_file_count: int
|
|
164
|
+
project: str = ""
|
|
165
|
+
v3_blockers: tuple = field(default_factory=tuple)
|
|
166
|
+
v3_unclassified_files: tuple = field(default_factory=tuple)
|
|
167
|
+
#: False only when the caller has NOT actually consulted the detector for
|
|
168
|
+
#: this xunit.v3 project (#1870) — e.g. the CLI's `--v3-findings-json` was
|
|
169
|
+
#: omitted. Defaults True so a direct `decide(ProbeResult(...))` caller
|
|
170
|
+
#: that already knows its own "detector ran, found nothing" state
|
|
171
|
+
#: (`v3_blockers=()`) is unaffected; only the CLI sets this False.
|
|
172
|
+
v3_findings_known: bool = True
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@dataclass(frozen=True)
|
|
176
|
+
class Decision:
|
|
177
|
+
outcome: Outcome
|
|
178
|
+
reason: str
|
|
179
|
+
estimated_round_seconds: float | None = None
|
|
180
|
+
budget_seconds: float | None = None
|
|
181
|
+
#: The operator question payload (breakdown + the four remediation
|
|
182
|
+
#: options) when v3 blockers drove an ``ask-operator``; None otherwise.
|
|
183
|
+
question: dict | None = None
|
|
184
|
+
|
|
185
|
+
@property
|
|
186
|
+
def waiver(self) -> str | None:
|
|
187
|
+
"""The precise waiver line to record when degrading; None when the
|
|
188
|
+
loop is entered (no waiver needed) or when the operator still has to
|
|
189
|
+
be asked (no waiver yet — pending operator input)."""
|
|
190
|
+
if self.outcome is Outcome.ENTER_LOOP:
|
|
191
|
+
return None
|
|
192
|
+
if self.outcome is Outcome.ASK_OPERATOR:
|
|
193
|
+
return None
|
|
194
|
+
if self.outcome is Outcome.DEGRADE:
|
|
195
|
+
return WAIVER_MESSAGE
|
|
196
|
+
raise ValueError(f"unknown outcome: {self.outcome!r}")
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _construct_of(finding) -> str:
|
|
200
|
+
if isinstance(finding, dict):
|
|
201
|
+
return str(finding.get("construct") or "")
|
|
202
|
+
return str(getattr(finding, "construct", "") or "")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _blocking_constructs(probe: ProbeResult) -> str:
|
|
206
|
+
"""The distinct construct names, for the ``ask-operator`` reason line."""
|
|
207
|
+
names: list[str] = []
|
|
208
|
+
for finding in probe.v3_blockers:
|
|
209
|
+
name = _construct_of(finding)
|
|
210
|
+
if name and name not in names:
|
|
211
|
+
names.append(name)
|
|
212
|
+
if probe.v3_unclassified_files:
|
|
213
|
+
names.append("unclassified")
|
|
214
|
+
return ", ".join(names) or "unclassified"
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def build_operator_question(probe: ProbeResult) -> dict | None:
|
|
218
|
+
"""The operator question payload for ``probe``, or None when nothing blocks.
|
|
219
|
+
|
|
220
|
+
Delegates to ``hooks/lib/xunit_v3_operator_gate.py`` so this gate and the
|
|
221
|
+
``stryker_xunit_shim_guard`` PreToolUse hook cannot drift into telling the
|
|
222
|
+
operator two different stories. If that library is unreachable the gate
|
|
223
|
+
still ASKS — with a degraded payload naming the files — rather than
|
|
224
|
+
proceeding as if nothing blocked.
|
|
225
|
+
"""
|
|
226
|
+
if not (probe.v3_blockers or probe.v3_unclassified_files):
|
|
227
|
+
return None
|
|
228
|
+
project = probe.project or "the test project"
|
|
229
|
+
if _operator_gate is None: # pragma: no cover - degraded fallback
|
|
230
|
+
return {
|
|
231
|
+
"project": project,
|
|
232
|
+
"headline": (
|
|
233
|
+
f"shim-breaking xunit.v3 constructs in '{project}' "
|
|
234
|
+
f"({_blocking_constructs(probe)})"
|
|
235
|
+
),
|
|
236
|
+
"degraded": True,
|
|
237
|
+
"unclassified_files": list(probe.v3_unclassified_files),
|
|
238
|
+
}
|
|
239
|
+
question = _operator_gate.build_question(
|
|
240
|
+
project, probe.v3_blockers, probe.v3_unclassified_files
|
|
241
|
+
)
|
|
242
|
+
return question.as_dict() if question.blocking else None
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def render_operator_question(probe: ProbeResult) -> str:
|
|
246
|
+
"""The operator-facing text for ``probe``'s blockers (empty when none).
|
|
247
|
+
|
|
248
|
+
Rendered from the probe rather than from :func:`build_operator_question`'s
|
|
249
|
+
dict so the per-finding line numbers survive into the text the operator
|
|
250
|
+
actually reads.
|
|
251
|
+
"""
|
|
252
|
+
if _operator_gate is None: # pragma: no cover - degraded fallback
|
|
253
|
+
return ""
|
|
254
|
+
if not (probe.v3_blockers or probe.v3_unclassified_files):
|
|
255
|
+
return ""
|
|
256
|
+
question = _operator_gate.build_question(
|
|
257
|
+
probe.project or "the test project",
|
|
258
|
+
probe.v3_blockers,
|
|
259
|
+
probe.v3_unclassified_files,
|
|
260
|
+
)
|
|
261
|
+
return "\n".join(_operator_gate.render_question(question))
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def decide(probe: ProbeResult, *, budget_seconds: float | None = None) -> Decision:
|
|
265
|
+
"""Arbitrate between entering the loop, asking the operator, or degrading
|
|
266
|
+
from the shim-first probe.
|
|
267
|
+
|
|
268
|
+
Order matters: an operator's decline and a hard capture failure both make
|
|
269
|
+
the loop infeasible regardless of timing, so they short-circuit before the
|
|
270
|
+
(timing-based) budget check — which itself only means anything once per-test
|
|
271
|
+
capture is known to work. Shim-breaking v3 constructs sit between the two:
|
|
272
|
+
they are not a hard blocker (the operator has four ways out), so they ask
|
|
273
|
+
rather than degrade — but they take precedence over the budget question, and
|
|
274
|
+
when both fire the operator gets ONE decision point stating blockers and
|
|
275
|
+
timing together rather than a blockers question that hides an unaffordable
|
|
276
|
+
round.
|
|
277
|
+
"""
|
|
278
|
+
if budget_seconds is None:
|
|
279
|
+
budget_seconds = resolve_budget_seconds()
|
|
280
|
+
else:
|
|
281
|
+
budget_seconds = _clamp_budget_seconds(budget_seconds)
|
|
282
|
+
|
|
283
|
+
if probe.shim_declined:
|
|
284
|
+
return Decision(
|
|
285
|
+
Outcome.DEGRADE,
|
|
286
|
+
"operator declined the shim path at the v3-feature gate (#1160)",
|
|
287
|
+
)
|
|
288
|
+
if probe.capture_failed:
|
|
289
|
+
return Decision(
|
|
290
|
+
Outcome.DEGRADE,
|
|
291
|
+
"per-test coverage capture failed on the probe (#1157) — Stryker "
|
|
292
|
+
"fell back to whole-suite-per-mutant, so each loop round pays the "
|
|
293
|
+
"full-suite cost",
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
estimated = estimate_round_seconds(probe.probe_seconds, probe.scope_file_count)
|
|
297
|
+
|
|
298
|
+
question = build_operator_question(probe)
|
|
299
|
+
|
|
300
|
+
if question is None and not probe.v3_findings_known:
|
|
301
|
+
# #1870: the detector was never consulted for this xunit.v3 project —
|
|
302
|
+
# unlike a real, already-classified blocker/unclassified set (handled
|
|
303
|
+
# by `question is not None` below), there is nothing to build a
|
|
304
|
+
# question FROM here, only the fact that nobody asked the detector.
|
|
305
|
+
# Fail closed rather than silently proceeding as if it had found
|
|
306
|
+
# nothing. Same over-budget combination as a real blocker set below,
|
|
307
|
+
# so the operator gets one decision point, not two.
|
|
308
|
+
over_budget = estimated > budget_seconds
|
|
309
|
+
reason = _V3_FINDINGS_UNKNOWN_REASON
|
|
310
|
+
if over_budget:
|
|
311
|
+
reason += (
|
|
312
|
+
f"; the estimated round {estimated:.0f}s also exceeds the "
|
|
313
|
+
f"{budget_seconds:.0f}s budget"
|
|
314
|
+
)
|
|
315
|
+
return Decision(
|
|
316
|
+
Outcome.ASK_OPERATOR,
|
|
317
|
+
reason,
|
|
318
|
+
estimated_round_seconds=estimated,
|
|
319
|
+
budget_seconds=budget_seconds,
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
if question is not None:
|
|
323
|
+
over_budget = estimated > budget_seconds
|
|
324
|
+
reason = (
|
|
325
|
+
f"shim-breaking xunit.v3 constructs found ({_blocking_constructs(probe)}) "
|
|
326
|
+
"— the operator must choose port / exclude / skip / degrade before the "
|
|
327
|
+
"shim path proceeds (#1791, gate #1160)"
|
|
328
|
+
)
|
|
329
|
+
if over_budget:
|
|
330
|
+
reason += (
|
|
331
|
+
f"; the estimated round {estimated:.0f}s also exceeds the "
|
|
332
|
+
f"{budget_seconds:.0f}s budget"
|
|
333
|
+
)
|
|
334
|
+
return Decision(
|
|
335
|
+
Outcome.ASK_OPERATOR,
|
|
336
|
+
reason,
|
|
337
|
+
estimated_round_seconds=estimated,
|
|
338
|
+
budget_seconds=budget_seconds,
|
|
339
|
+
question=question,
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
if estimated > budget_seconds:
|
|
343
|
+
return Decision(
|
|
344
|
+
Outcome.ASK_OPERATOR,
|
|
345
|
+
f"estimated round {estimated:.0f}s exceeds the {budget_seconds:.0f}s "
|
|
346
|
+
"budget (per-test works but the suite is too slow to iterate)",
|
|
347
|
+
estimated_round_seconds=estimated,
|
|
348
|
+
budget_seconds=budget_seconds,
|
|
349
|
+
)
|
|
350
|
+
return Decision(
|
|
351
|
+
Outcome.ENTER_LOOP,
|
|
352
|
+
f"per-test capture works and the estimated round {estimated:.0f}s is "
|
|
353
|
+
f"within the {budget_seconds:.0f}s budget",
|
|
354
|
+
estimated_round_seconds=estimated,
|
|
355
|
+
budget_seconds=budget_seconds,
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def _load_v3_findings(source: str | None) -> tuple:
|
|
360
|
+
"""Read the detector's ``--json`` output into a findings tuple.
|
|
361
|
+
|
|
362
|
+
Accepts the full ``{"findings": [...], "summary": {...}}`` object or a bare
|
|
363
|
+
list. Raises ``OSError``/``ValueError``/``TypeError`` on anything
|
|
364
|
+
unreadable — see the caller for why that must not silently become
|
|
365
|
+
"no blockers".
|
|
366
|
+
"""
|
|
367
|
+
if not source:
|
|
368
|
+
return ()
|
|
369
|
+
raw = sys.stdin.read() if source == "-" else Path(source).read_text(encoding="utf-8")
|
|
370
|
+
data = json.loads(raw)
|
|
371
|
+
if isinstance(data, dict):
|
|
372
|
+
findings = data.get("findings")
|
|
373
|
+
else:
|
|
374
|
+
findings = data
|
|
375
|
+
if findings is None:
|
|
376
|
+
raise ValueError("no 'findings' key and not a bare findings list")
|
|
377
|
+
if not isinstance(findings, list):
|
|
378
|
+
raise TypeError(f"'findings' is {type(findings).__name__}, expected a list")
|
|
379
|
+
return tuple(findings)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def _cli(argv: Sequence[str]) -> int:
|
|
383
|
+
parser = argparse.ArgumentParser(
|
|
384
|
+
description="Arbitrate the mutant-kill loop's shim-first feasibility gate."
|
|
385
|
+
)
|
|
386
|
+
parser.add_argument(
|
|
387
|
+
"--shim-declined",
|
|
388
|
+
action="store_true",
|
|
389
|
+
help="operator declined the shim path at the #1160 v3-feature gate",
|
|
390
|
+
)
|
|
391
|
+
parser.add_argument(
|
|
392
|
+
"--capture-failed",
|
|
393
|
+
action="store_true",
|
|
394
|
+
help="the #1157 coverage-capture-failure signal fired on the probe",
|
|
395
|
+
)
|
|
396
|
+
parser.add_argument(
|
|
397
|
+
"--probe-seconds", type=float, default=0.0, help="measured one-file probe wall-clock"
|
|
398
|
+
)
|
|
399
|
+
parser.add_argument(
|
|
400
|
+
"--scope-files", type=int, default=1, help="number of files in the loop scope"
|
|
401
|
+
)
|
|
402
|
+
parser.add_argument(
|
|
403
|
+
"--budget-seconds",
|
|
404
|
+
type=float,
|
|
405
|
+
default=None,
|
|
406
|
+
help="override the per-round wall-clock budget",
|
|
407
|
+
)
|
|
408
|
+
parser.add_argument(
|
|
409
|
+
"--project",
|
|
410
|
+
default="",
|
|
411
|
+
help="test project name (csproj stem) the v3 findings belong to",
|
|
412
|
+
)
|
|
413
|
+
parser.add_argument(
|
|
414
|
+
"--v3-findings-json",
|
|
415
|
+
default=None,
|
|
416
|
+
help="xunit_v3_feature_detector.py --json output ('-' for stdin): either "
|
|
417
|
+
"the full {findings, summary} object or a bare findings list",
|
|
418
|
+
)
|
|
419
|
+
parser.add_argument(
|
|
420
|
+
"--v3-unclassified",
|
|
421
|
+
action="append",
|
|
422
|
+
default=[],
|
|
423
|
+
help="a file flagged as v3-only that the detector could not classify "
|
|
424
|
+
"(repeatable)",
|
|
425
|
+
)
|
|
426
|
+
args = parser.parse_args(list(argv))
|
|
427
|
+
|
|
428
|
+
try:
|
|
429
|
+
blockers = _load_v3_findings(args.v3_findings_json)
|
|
430
|
+
except (OSError, ValueError, TypeError) as exc:
|
|
431
|
+
# A detector output we cannot read must NOT be treated as "no blockers":
|
|
432
|
+
# that would hand back enter-loop and skip the operator gate entirely,
|
|
433
|
+
# which is the class of silent decision #1791 exists to stop.
|
|
434
|
+
print(f"error: cannot read --v3-findings-json: {exc}", file=sys.stderr)
|
|
435
|
+
return 2
|
|
436
|
+
|
|
437
|
+
probe = ProbeResult(
|
|
438
|
+
shim_declined=args.shim_declined,
|
|
439
|
+
capture_failed=args.capture_failed,
|
|
440
|
+
probe_seconds=args.probe_seconds,
|
|
441
|
+
scope_file_count=args.scope_files,
|
|
442
|
+
project=args.project,
|
|
443
|
+
v3_blockers=blockers,
|
|
444
|
+
v3_unclassified_files=tuple(args.v3_unclassified),
|
|
445
|
+
# #1870: only the CLI can tell "omitted" apart from "provided, found
|
|
446
|
+
# nothing" — every invocation of this CLI is for an xunit.v3 project
|
|
447
|
+
# by calling convention, so omission must not silently read as
|
|
448
|
+
# "known-empty".
|
|
449
|
+
v3_findings_known=args.v3_findings_json is not None,
|
|
450
|
+
)
|
|
451
|
+
decision = decide(probe, budget_seconds=args.budget_seconds)
|
|
452
|
+
payload = asdict(decision)
|
|
453
|
+
payload["outcome"] = decision.outcome.value
|
|
454
|
+
payload["waiver"] = decision.waiver
|
|
455
|
+
if decision.question is not None:
|
|
456
|
+
payload["question_text"] = render_operator_question(probe)
|
|
457
|
+
print(json.dumps(payload, indent=2))
|
|
458
|
+
# Exit 0 either way — this is an advisory arbiter, not a gate that fails a run.
|
|
459
|
+
return 0
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
if __name__ == "__main__": # pragma: no cover
|
|
463
|
+
sys.exit(_cli(sys.argv[1:]))
|