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,116 @@
|
|
|
1
|
+
"""hooks/lib/doc_classification.py — shared documentation-classification
|
|
2
|
+
literal tables (#1477).
|
|
3
|
+
|
|
4
|
+
`hooks/pre_commit_review.py`'s doc-only exemption predicate
|
|
5
|
+
(`hooks/lib/pre_commit_doc_classifier.py` as of this same change) and
|
|
6
|
+
`skills/code-review/scripts/change_shape.py`'s low-yield-lens gate both
|
|
7
|
+
classify a changed file as "documentation" — but for different purposes and
|
|
8
|
+
at different strictness levels (see `pre_commit_doc_classifier.py`'s module
|
|
9
|
+
docstring: the pre-commit gate's predicate is a deliberate STRICT SUBSET of
|
|
10
|
+
`change_shape.py`'s, never a superset, so the two must never be forced into
|
|
11
|
+
lockstep). Prior to this module the two call sites hand-duplicated the same
|
|
12
|
+
literal word lists, kept in sync only by comment convention — exactly the
|
|
13
|
+
class of gap that needed fixing across four separate `pre_commit_review.py`
|
|
14
|
+
hardening rounds (#1461) without anything forcing the `change_shape.py`
|
|
15
|
+
sibling copy to be checked too.
|
|
16
|
+
|
|
17
|
+
This module carries ONLY the literal data that is actually identical between
|
|
18
|
+
the two call sites today, with one exception: `is_functional_config` below
|
|
19
|
+
(#1923's third caller, `scripts/select_lenses.py`) IS shared logic, not just
|
|
20
|
+
data — but only because `change_shape.py` and `select_lenses.py` want the
|
|
21
|
+
exact same predicate over the exact same composed segment set (the
|
|
22
|
+
`"templates"` addition included), with no matching-semantics divergence
|
|
23
|
+
between them the way `pre_commit_doc_classifier.py` has from both (see the
|
|
24
|
+
`CORE_FUNCTIONAL_CONFIG_SEGMENTS` comment below). `pre_commit_doc_classifier.py`
|
|
25
|
+
does NOT call this function — it keeps its own inline check reading the raw
|
|
26
|
+
`CORE_FUNCTIONAL_CONFIG_SEGMENTS`/`FUNCTIONAL_CONFIG_NAMES` constants
|
|
27
|
+
directly, staying the strict subset its own docstring requires. Every other
|
|
28
|
+
matching *logic* here (exact-name vs. prefix match for doc detection) stays
|
|
29
|
+
local to each caller by design — unifying THAT, not just the data, would
|
|
30
|
+
re-introduce the subset/superset coupling the pre-commit gate's docstring
|
|
31
|
+
explicitly warns against.
|
|
32
|
+
|
|
33
|
+
Location: `hooks/lib/` rather than a new top-level `shared/` directory.
|
|
34
|
+
There is no existing precedent in this repo for a module living outside
|
|
35
|
+
both `hooks/` and `skills/*/scripts/` that either side imports — grepping
|
|
36
|
+
found no prior cross-boundary shared-constant mechanism. `hooks/lib/`
|
|
37
|
+
already hosts several business-logic-free utility modules other packages
|
|
38
|
+
reach into (`artifact_paths.py`, `stdin_json.py`, `minimal_yaml.py`), so a
|
|
39
|
+
neutral, pure-data module fits the same convention; `change_shape.py`
|
|
40
|
+
reaches it via the identical `sys.path.insert` pattern
|
|
41
|
+
`hooks/pre_commit_review.py` already uses for its own `hooks/lib/` imports
|
|
42
|
+
(see that module's top-of-file import block). This is a one-line documented
|
|
43
|
+
choice, not an established repo-wide convention — revisit if a genuine
|
|
44
|
+
`shared/` location emerges later.
|
|
45
|
+
|
|
46
|
+
Stdlib only.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
from __future__ import annotations
|
|
50
|
+
|
|
51
|
+
from pathlib import PurePosixPath # used by is_functional_config below
|
|
52
|
+
|
|
53
|
+
# Documentation extensions (lower-cased). Byte-identical set between
|
|
54
|
+
# `change_shape.py`'s `_DOC_EXTENSIONS` and
|
|
55
|
+
# `pre_commit_doc_classifier.py`'s `_DOC_EXTENSIONS` prior to this
|
|
56
|
+
# extraction.
|
|
57
|
+
DOC_EXTENSIONS = frozenset({".md", ".mdx", ".markdown", ".rst", ".txt", ".adoc"})
|
|
58
|
+
|
|
59
|
+
# Documentation root-file word list (lower-cased), identical set of 7 words
|
|
60
|
+
# between both call sites. NOTE: the two callers apply DIFFERENT matching
|
|
61
|
+
# semantics on top of this SAME word list, by deliberate design —
|
|
62
|
+
# `change_shape.py` does a stem PREFIX match (`stem.startswith(word)`,
|
|
63
|
+
# appropriate for its own lower-stakes lens-narrowing purpose);
|
|
64
|
+
# `pre_commit_doc_classifier.py` does an EXACT match (`stem in
|
|
65
|
+
# frozenset(DOC_ROOT_WORDS)`, required because it is the sole gate deciding
|
|
66
|
+
# a zero-dispatch-evidence exemption — see that module's docstring for why
|
|
67
|
+
# prefix matching was exploitable there). This module carries only the
|
|
68
|
+
# shared words; each caller keeps its own matching logic.
|
|
69
|
+
DOC_ROOT_WORDS = (
|
|
70
|
+
"readme",
|
|
71
|
+
"changelog",
|
|
72
|
+
"contributing",
|
|
73
|
+
"license",
|
|
74
|
+
"notice",
|
|
75
|
+
"authors",
|
|
76
|
+
"code_of_conduct",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Functional-config filenames anywhere in the tree. Byte-identical set
|
|
80
|
+
# between both call sites.
|
|
81
|
+
FUNCTIONAL_CONFIG_NAMES = frozenset({"claude.md", "agents.md"})
|
|
82
|
+
|
|
83
|
+
# Functional-config path segments COMMON to both call sites. `change_shape.py`
|
|
84
|
+
# additionally treats "templates" as functional-config (its own
|
|
85
|
+
# `_FUNCTIONAL_CONFIG_SEGMENTS` adds it on top of this core set);
|
|
86
|
+
# `pre_commit_doc_classifier.py` deliberately does not (staying the strict
|
|
87
|
+
# subset its docstring requires). That one-item divergence predates this
|
|
88
|
+
# extraction and is preserved exactly as it was — not resolved — here; each
|
|
89
|
+
# caller layers its own additions on top of this shared core.
|
|
90
|
+
CORE_FUNCTIONAL_CONFIG_SEGMENTS = frozenset({".claude", "agents", "skills", "prompts", "knowledge"})
|
|
91
|
+
|
|
92
|
+
# `change_shape.py`'s own "templates" addition, baked in here because
|
|
93
|
+
# `select_lenses.py` wants the identical composed set — see `is_functional_config`.
|
|
94
|
+
_FUNCTIONAL_CONFIG_SEGMENTS_WITH_TEMPLATES = CORE_FUNCTIONAL_CONFIG_SEGMENTS | {"templates"}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def is_functional_config(file_path: str) -> bool:
|
|
98
|
+
"""True when ``file_path`` drives agent/skill/command behavior and must
|
|
99
|
+
never be treated as inert documentation/config regardless of extension.
|
|
100
|
+
Shared by `change_shape.py` and `select_lenses.py` (#1923) — see this
|
|
101
|
+
module's docstring for why this one predicate is shared logic, not just
|
|
102
|
+
data, and why `pre_commit_doc_classifier.py` deliberately does not call
|
|
103
|
+
it."""
|
|
104
|
+
path = PurePosixPath(file_path)
|
|
105
|
+
if path.name.lower() in FUNCTIONAL_CONFIG_NAMES:
|
|
106
|
+
return True
|
|
107
|
+
return any(seg in _FUNCTIONAL_CONFIG_SEGMENTS_WITH_TEMPLATES for seg in path.parts)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
__all__ = (
|
|
111
|
+
"CORE_FUNCTIONAL_CONFIG_SEGMENTS",
|
|
112
|
+
"DOC_EXTENSIONS",
|
|
113
|
+
"DOC_ROOT_WORDS",
|
|
114
|
+
"FUNCTIONAL_CONFIG_NAMES",
|
|
115
|
+
"is_functional_config",
|
|
116
|
+
)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""hooks/lib/gh_pr_create_detect.py — detect a `gh pr create` invocation
|
|
2
|
+
(#1886).
|
|
3
|
+
|
|
4
|
+
`hooks/pre_pr_review.py`'s trigger-point detector: a single quote-aware
|
|
5
|
+
tokenizing pass over each shell-separator-delimited segment of the raw Bash
|
|
6
|
+
command, looking for `gh pr create` as the segment's real command words
|
|
7
|
+
(after skipping any leading `NAME=value` environment-variable prefixes and
|
|
8
|
+
resolving a path-qualified `gh` — e.g. `/usr/local/bin/gh` — by basename).
|
|
9
|
+
|
|
10
|
+
This is deliberately a MUCH lighter heuristic than
|
|
11
|
+
`hooks/lib/pre_commit_detect.py`'s `is_git_commit_command` — that module
|
|
12
|
+
went through five adversarial hardening rounds (`<shell> -c` unwrapping,
|
|
13
|
+
command substitution, I/O redirection before the command word, `-C`/global
|
|
14
|
+
option chaining, ...) specifically for `git commit`'s much larger and more
|
|
15
|
+
security-sensitive command-shape surface (a missed detection there let a
|
|
16
|
+
commit land with no review corroboration at all). `gh pr create` has a much
|
|
17
|
+
narrower realistic invocation shape in practice, and the trigger point this
|
|
18
|
+
module guards is a human/agent-driven "open a PR" action, not a background
|
|
19
|
+
`git commit` that fires many times per session — so the cost/benefit of
|
|
20
|
+
matching that same adversarial-hardening investment here is different.
|
|
21
|
+
|
|
22
|
+
KNOWN RESIDUAL GAP, disclosed rather than silently accepted (mirrors this
|
|
23
|
+
repo's own convention for `pre_commit_detect.py`'s own disclosed gaps): this
|
|
24
|
+
detector does NOT unwrap `<shell> -c '...'`, command substitution
|
|
25
|
+
(`$(...)`/backticks), `eval`/`xargs`, I/O redirection before the command
|
|
26
|
+
word, or a `gh` alias/wrapper script — any of those can still reach `gh pr
|
|
27
|
+
create` undetected. A future round of adversarial review (correctness-review
|
|
28
|
+
/ security-review) should extend this the same way #1801 extended
|
|
29
|
+
`pre_commit_detect.py`, if this trigger point proves to need it in practice.
|
|
30
|
+
|
|
31
|
+
Stdlib-only. See ADR 0014 / ADR 0015.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
import re
|
|
37
|
+
import shlex
|
|
38
|
+
|
|
39
|
+
# Bare shell separators — `;`, `&&`, `||`, `|`, and a bare newline — split one
|
|
40
|
+
# Bash payload into independently-evaluated segments. Quote-aware: a
|
|
41
|
+
# separator character INSIDE a quoted string is never a boundary.
|
|
42
|
+
_SEPARATOR_RE = re.compile(r"(;|&&|\|\||\||\n)")
|
|
43
|
+
|
|
44
|
+
_ENV_ASSIGNMENT_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*=")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _split_on_separators(command: str) -> list[str]:
|
|
48
|
+
"""Quote-aware split on `;`/`&&`/`||`/`|`/`&`/newline — a separator
|
|
49
|
+
INSIDE a single- or double-quoted string is never treated as a
|
|
50
|
+
boundary.
|
|
51
|
+
|
|
52
|
+
Two fixes (issue #1904 Bug 3 — this is the SOLE trigger point for the
|
|
53
|
+
entire review gate now that `pre_commit_review.py` is a no-op, so a
|
|
54
|
+
missed detection here is a complete, silent bypass):
|
|
55
|
+
|
|
56
|
+
1. Bare `&` (background) is a real shell separator — `true &
|
|
57
|
+
gh pr create --title x` used to stay one segment (with `true` as
|
|
58
|
+
`tokens[0]`), missing the `gh pr create` entirely. `&&` is checked
|
|
59
|
+
BEFORE bare `&` in the tuple below, so `&&` still matches as the
|
|
60
|
+
two-character operator it is; only a genuinely bare `&` falls
|
|
61
|
+
through to the new single-character case.
|
|
62
|
+
2. The backslash-escape exemption on a closing quote now applies ONLY
|
|
63
|
+
when the open quote is `"` (double quote). POSIX single quotes have
|
|
64
|
+
NO escape mechanism at all — `echo 'a\'` closes the quote at that
|
|
65
|
+
`'` in real bash regardless of the preceding backslash, so treating
|
|
66
|
+
it as still-open (the old, quote-character-agnostic check) let a
|
|
67
|
+
genuinely-closed single-quoted region swallow the rest of the
|
|
68
|
+
command, including a `;`-separated `gh pr create` that followed.
|
|
69
|
+
"""
|
|
70
|
+
segments: list[str] = []
|
|
71
|
+
current: list[str] = []
|
|
72
|
+
quote: str | None = None
|
|
73
|
+
i = 0
|
|
74
|
+
while i < len(command):
|
|
75
|
+
ch = command[i]
|
|
76
|
+
if quote is not None:
|
|
77
|
+
current.append(ch)
|
|
78
|
+
if ch == quote and (
|
|
79
|
+
quote == "'" or i == 0 or command[i - 1] != "\\"
|
|
80
|
+
):
|
|
81
|
+
quote = None
|
|
82
|
+
i += 1
|
|
83
|
+
continue
|
|
84
|
+
if ch in ("'", '"'):
|
|
85
|
+
quote = ch
|
|
86
|
+
current.append(ch)
|
|
87
|
+
i += 1
|
|
88
|
+
continue
|
|
89
|
+
matched = None
|
|
90
|
+
for sep in ("&&", "||", ";", "|", "\n", "&"):
|
|
91
|
+
if command.startswith(sep, i):
|
|
92
|
+
matched = sep
|
|
93
|
+
break
|
|
94
|
+
if matched is not None:
|
|
95
|
+
segments.append("".join(current))
|
|
96
|
+
current = []
|
|
97
|
+
i += len(matched)
|
|
98
|
+
continue
|
|
99
|
+
current.append(ch)
|
|
100
|
+
i += 1
|
|
101
|
+
segments.append("".join(current))
|
|
102
|
+
return segments
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _real_command_tokens(segment: str) -> list[str] | None:
|
|
106
|
+
"""Tokenize one segment and skip leading `NAME=value` env-assignment
|
|
107
|
+
prefixes, returning the remaining tokens (the command and its
|
|
108
|
+
arguments), or `None` if the segment doesn't tokenize (unbalanced
|
|
109
|
+
quoting)."""
|
|
110
|
+
try:
|
|
111
|
+
tokens = shlex.split(segment, posix=True)
|
|
112
|
+
except ValueError:
|
|
113
|
+
return None
|
|
114
|
+
i = 0
|
|
115
|
+
while i < len(tokens) and _ENV_ASSIGNMENT_RE.match(tokens[i]):
|
|
116
|
+
i += 1
|
|
117
|
+
return tokens[i:]
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def is_gh_pr_create_command(command: str) -> bool:
|
|
121
|
+
"""True if any shell-separator-delimited segment of `command` invokes
|
|
122
|
+
`gh pr create` (a path-qualified `gh`, e.g. `/usr/local/bin/gh`, is
|
|
123
|
+
recognized by basename)."""
|
|
124
|
+
for segment in _split_on_separators(command):
|
|
125
|
+
tokens = _real_command_tokens(segment)
|
|
126
|
+
if not tokens:
|
|
127
|
+
continue
|
|
128
|
+
gh_token = tokens[0].replace("\\", "/").rsplit("/", 1)[-1]
|
|
129
|
+
if gh_token != "gh":
|
|
130
|
+
continue
|
|
131
|
+
if len(tokens) >= 3 and tokens[1] == "pr" and tokens[2] == "create":
|
|
132
|
+
return True
|
|
133
|
+
return False
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
__all__ = ("is_gh_pr_create_command",)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""hooks/lib/git_safe_diff.py — shared security-pinned `git diff --cached`
|
|
2
|
+
flags (#1477, extracted from `pre_commit_review.py`'s `_staged_names()` and
|
|
3
|
+
`review_gate_hash.py`'s `review_gate_hash()`).
|
|
4
|
+
|
|
5
|
+
Both call sites need `git diff --cached` to see the FULL staged changeset —
|
|
6
|
+
not a config-narrowed or driver-rewritten view of it. Prior to this module
|
|
7
|
+
the two functions hand-duplicated the same security-critical flags, kept in
|
|
8
|
+
sync only by comment convention (each function's own docstring cross-
|
|
9
|
+
referenced the other's) — exactly the class of gap the #1461 fifth security
|
|
10
|
+
re-review had to catch for `--ignore-submodules` on both call sites
|
|
11
|
+
separately. A future flag fix applied to one call site and forgotten on the
|
|
12
|
+
other is now structurally impossible: there is only one place these flags
|
|
13
|
+
are written.
|
|
14
|
+
|
|
15
|
+
`-c diff.relative=false`: without it, a repo/global `diff.relative=true`
|
|
16
|
+
config silently scopes and relativizes `git diff` output to the
|
|
17
|
+
invocation's cwd, truncating the result when either hook runs from a
|
|
18
|
+
subdirectory.
|
|
19
|
+
|
|
20
|
+
`--ignore-submodules=none`: the config-only form (`-c
|
|
21
|
+
diff.ignoreSubmodules=none`) does NOT suffice — it is overridden by a
|
|
22
|
+
per-submodule `submodule.<name>.ignore` (in `.git/config`) OR by an
|
|
23
|
+
`ignore` key in a COMMITTED `.gitmodules` file, neither of which needs
|
|
24
|
+
local git-config write access (a hostile PR can ship the latter). Only the
|
|
25
|
+
command-line option beats both. Without it, a changeset consisting only of
|
|
26
|
+
a submodule pointer bump (importing arbitrary third-party code) is either
|
|
27
|
+
omitted from `_staged_names()`'s file list entirely, or hashed identically
|
|
28
|
+
to no change at all by `review_gate_hash()`.
|
|
29
|
+
|
|
30
|
+
`--no-color`/`--no-ext-diff`/`--no-textconv` are NOT included here — they
|
|
31
|
+
only matter to a caller that reads the diff's rendered CONTENT
|
|
32
|
+
(`review_gate_hash()`); `_staged_names()`'s `--name-only` output is
|
|
33
|
+
unaffected by diff rendering or textconv drivers, so it never needed them.
|
|
34
|
+
Each caller passes its own `extra_flags` for exactly this kind of
|
|
35
|
+
caller-specific need; only the flags both call sites actually share live
|
|
36
|
+
here.
|
|
37
|
+
|
|
38
|
+
`target` (#1476): defaults to `"--cached"` (HEAD vs. index — every caller
|
|
39
|
+
above needs this and none passed anything else, so the default preserves
|
|
40
|
+
their exact original argv). A caller can pass a different comparison —
|
|
41
|
+
`target=None` (bare `git diff` — index vs. working tree) or any other ref
|
|
42
|
+
expression (e.g. `review_gate_hash.py`'s `branch_diff_gate_hash()`, which
|
|
43
|
+
passes `f"{base_ref}...HEAD"`). Same shared safety flags either way — the
|
|
44
|
+
vulnerability class (`diff.relative`, submodule-ignore config, external
|
|
45
|
+
diff drivers) doesn't care which two trees are being compared.
|
|
46
|
+
|
|
47
|
+
`review_gate_hash.py`'s `working_tree_gate_hash()` (`target="HEAD"`, added
|
|
48
|
+
#1476 for `git commit -a`/pathspec-form-commit detection) was deleted in
|
|
49
|
+
#1904 once `pre_commit_review.py` — its sole caller — was retired to a
|
|
50
|
+
no-op by #1886's PR-time gate migration; `target`'s generality here is
|
|
51
|
+
otherwise unchanged.
|
|
52
|
+
|
|
53
|
+
Stdlib only.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
from __future__ import annotations
|
|
57
|
+
|
|
58
|
+
import subprocess
|
|
59
|
+
from collections.abc import Sequence
|
|
60
|
+
from pathlib import Path
|
|
61
|
+
|
|
62
|
+
# `-c diff.relative=false` must precede the `diff` subcommand — see module
|
|
63
|
+
# docstring.
|
|
64
|
+
GIT_CONFIG_OVERRIDES = ("-c", "diff.relative=false")
|
|
65
|
+
|
|
66
|
+
# Must come after the target and any caller-specific extra flags — see
|
|
67
|
+
# module docstring for why the command-line form is required.
|
|
68
|
+
GIT_IGNORE_SUBMODULES_FLAG = "--ignore-submodules=none"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def run_safe_git_diff(
|
|
72
|
+
extra_flags: Sequence[str],
|
|
73
|
+
cwd: str | Path | None = None,
|
|
74
|
+
text: bool = False,
|
|
75
|
+
target: str | None = "--cached",
|
|
76
|
+
timeout: float | None = None,
|
|
77
|
+
) -> subprocess.CompletedProcess:
|
|
78
|
+
"""Run `git diff [target]` with the shared safety flags, plus
|
|
79
|
+
caller-specific `extra_flags` inserted between the target and the
|
|
80
|
+
trailing `--ignore-submodules=none` — preserves each existing caller's
|
|
81
|
+
original argv order exactly (`_staged_names()`:
|
|
82
|
+
`[..., "--cached", "--name-only", "--ignore-submodules=none"]`;
|
|
83
|
+
`review_gate_hash()`:
|
|
84
|
+
`[..., "--cached", "--no-color", "--no-ext-diff", "--no-textconv",
|
|
85
|
+
"--ignore-submodules=none"]`).
|
|
86
|
+
|
|
87
|
+
`target=None` omits the target argument entirely (bare `git diff` —
|
|
88
|
+
index vs. working tree); any other string (`"--cached"`, `"HEAD"`, ...)
|
|
89
|
+
is inserted as-is right after `diff`.
|
|
90
|
+
|
|
91
|
+
`timeout` (#1663): seconds to wait before `subprocess.run` raises
|
|
92
|
+
`TimeoutExpired`. Defaults to `None` (wait forever), preserving every
|
|
93
|
+
pre-existing caller's behavior exactly. Only `normalized_gate_hash()`
|
|
94
|
+
passes a value today — it is the one caller that asks git for
|
|
95
|
+
whole-file context (`--unified=100000`), so it is the one caller whose
|
|
96
|
+
runtime scales with repository content rather than with changeset size.
|
|
97
|
+
`TimeoutExpired` propagates to the caller for the same reason a launch
|
|
98
|
+
failure does: this helper builds and runs the safe argv, it does not
|
|
99
|
+
decide what a given caller should do about a slow git.
|
|
100
|
+
|
|
101
|
+
Raises on subprocess launch failure — callers keep their own
|
|
102
|
+
try/except around this call, since `_staged_names()` and
|
|
103
|
+
`review_gate_hash()` intentionally differ in how they handle that
|
|
104
|
+
failure (fail-closed `None` vs. a byte-parity empty-input hash); this
|
|
105
|
+
helper only builds and runs the safe argv, it does not decide how a
|
|
106
|
+
launch failure should be reported.
|
|
107
|
+
"""
|
|
108
|
+
argv = ["git", *GIT_CONFIG_OVERRIDES, "diff"]
|
|
109
|
+
if target is not None:
|
|
110
|
+
argv.append(target)
|
|
111
|
+
argv.extend(extra_flags)
|
|
112
|
+
argv.append(GIT_IGNORE_SUBMODULES_FLAG)
|
|
113
|
+
return subprocess.run(
|
|
114
|
+
argv,
|
|
115
|
+
cwd=str(cwd) if cwd is not None else None,
|
|
116
|
+
capture_output=True,
|
|
117
|
+
check=False,
|
|
118
|
+
text=text,
|
|
119
|
+
timeout=timeout,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
__all__ = ("GIT_CONFIG_OVERRIDES", "GIT_IGNORE_SUBMODULES_FLAG", "run_safe_git_diff")
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""instrument_log — fail-open JSONL rows for benefit-measurement streams (#2201).
|
|
2
|
+
|
|
3
|
+
The smallest logging addition that makes a number exist: each caller appends
|
|
4
|
+
one compact row to a named ``.claude/metrics/<stream>.jsonl`` and nothing
|
|
5
|
+
else changes — no stdout, no exit code, no control flow. Any failure (bad
|
|
6
|
+
cwd, unwritable directory, disk full) is swallowed. Streams and row shapes
|
|
7
|
+
are documented in ``knowledge/telemetry-schema.md``.
|
|
8
|
+
|
|
9
|
+
Kept separate from ``boundary_events.py`` on purpose: a ``record`` row there
|
|
10
|
+
is read by the review-gate corroboration path, so observational measurement
|
|
11
|
+
rows must not share that stream.
|
|
12
|
+
|
|
13
|
+
Stdlib-only. See docs/python-hook-contract.md.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import sys
|
|
21
|
+
from datetime import datetime, timezone
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
_LIB_DIR = Path(__file__).resolve().parent
|
|
25
|
+
if str(_LIB_DIR) not in sys.path:
|
|
26
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
27
|
+
|
|
28
|
+
import artifact_paths
|
|
29
|
+
import plugin_version
|
|
30
|
+
|
|
31
|
+
#: Closed set of stream names this module may write.
|
|
32
|
+
STREAMS = frozenset({
|
|
33
|
+
"subagent-stops",
|
|
34
|
+
"skill-injection",
|
|
35
|
+
"ledger-skips",
|
|
36
|
+
"checkpoint-aborts",
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def append_row(stream: str, row: dict, cwd: str | Path | None = None,
|
|
41
|
+
session_id: str | None = None) -> bool:
|
|
42
|
+
"""Append ``row`` (plus ``ts``/``plugin_version``/``session_id``) to
|
|
43
|
+
``.claude/metrics/<stream>.jsonl``. Returns whether a row was written;
|
|
44
|
+
never raises."""
|
|
45
|
+
if stream not in STREAMS:
|
|
46
|
+
return False
|
|
47
|
+
try:
|
|
48
|
+
base = Path(cwd) if cwd else Path.cwd()
|
|
49
|
+
log = artifact_paths.resolve_file("metrics", f"{stream}.jsonl", base)
|
|
50
|
+
log.parent.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
payload = {
|
|
52
|
+
"ts": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
|
53
|
+
"plugin_version": plugin_version.shipped_version(),
|
|
54
|
+
**row,
|
|
55
|
+
}
|
|
56
|
+
if session_id:
|
|
57
|
+
payload["session_id"] = session_id
|
|
58
|
+
line = json.dumps(payload, separators=(",", ":")) + "\n"
|
|
59
|
+
fd = os.open(log, os.O_WRONLY | os.O_APPEND | os.O_CREAT, 0o644)
|
|
60
|
+
try:
|
|
61
|
+
os.write(fd, line.encode("utf-8"))
|
|
62
|
+
finally:
|
|
63
|
+
os.close(fd)
|
|
64
|
+
return True
|
|
65
|
+
except Exception: # noqa: BLE001 — fail-open by design, see module docstring
|
|
66
|
+
return False
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""iteration_journal_gate.py — hard per-iteration journal gate (#1168).
|
|
3
|
+
|
|
4
|
+
`/autoship`'s per-issue loop and `/ship`'s per-phase loop are model-authored
|
|
5
|
+
control flow inside a skill, not a tool call the PreToolUse/PostToolUse
|
|
6
|
+
harness intercepts — there is no hook-registration point distinct from any
|
|
7
|
+
other `Skill` invocation to gate specifically. This mirrors the same
|
|
8
|
+
constraint `workflow_state.py` (#1166) already documents for its
|
|
9
|
+
model-authored `record` append: enforcement lives in a library the skill's
|
|
10
|
+
prose invokes via CLI before it may advance, not in `settings.json`.
|
|
11
|
+
|
|
12
|
+
Two operations:
|
|
13
|
+
record — append a structured decision entry (what was attempted, the
|
|
14
|
+
outcome, the next action) for the current round/iteration to
|
|
15
|
+
`.claude/metrics/iteration-journal.jsonl`. Fail-open: an append error
|
|
16
|
+
never raises into the calling skill.
|
|
17
|
+
check — hard-block: exit 1 (and emit a `boundary-events.jsonl` "block"
|
|
18
|
+
record via `emit_boundary_event`) unless at least one entry
|
|
19
|
+
exists for the given `--round-id`. Exit 0 (allowed) otherwise.
|
|
20
|
+
|
|
21
|
+
Complements, does not replace, `progress-guardian` (advisory, plan-step-keyed).
|
|
22
|
+
This gate is per-iteration, hard-blocking, and scoped to `/autoship`/`/ship`.
|
|
23
|
+
|
|
24
|
+
Stdlib only. See ADR 0014 / ADR 0015.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import argparse
|
|
30
|
+
import json
|
|
31
|
+
import sys
|
|
32
|
+
from datetime import datetime, timezone
|
|
33
|
+
from pathlib import Path
|
|
34
|
+
|
|
35
|
+
_LIB_DIR = Path(__file__).resolve().parent
|
|
36
|
+
if str(_LIB_DIR) not in sys.path:
|
|
37
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
38
|
+
|
|
39
|
+
import artifact_paths
|
|
40
|
+
import plugin_version
|
|
41
|
+
from atomic_state import append_line_locked
|
|
42
|
+
from boundary_events import emit_boundary_event
|
|
43
|
+
|
|
44
|
+
_LOG_NAME = "iteration-journal.jsonl"
|
|
45
|
+
_DELAY_ENV_VAR = "DEV_TEAM_ITERATION_JOURNAL_TEST_DELAY_MS"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _isoformat_utc() -> str:
|
|
49
|
+
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _log_path(cwd, migrate: bool = True) -> Path:
|
|
53
|
+
base = Path(cwd) if cwd else Path.cwd()
|
|
54
|
+
return artifact_paths.resolve_file("metrics", _LOG_NAME, base, migrate=migrate)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def record_iteration_entry(
|
|
58
|
+
cwd,
|
|
59
|
+
round_id: str,
|
|
60
|
+
attempted: str,
|
|
61
|
+
outcome: str,
|
|
62
|
+
next_action: str,
|
|
63
|
+
session_id: str | None = None,
|
|
64
|
+
) -> None:
|
|
65
|
+
"""Append one compact JSON line recording this iteration's decision.
|
|
66
|
+
|
|
67
|
+
Fail-open: any error (bad `cwd`, unwritable `.claude/metrics/`, disk
|
|
68
|
+
full, etc.) is swallowed silently — an append failure must never crash
|
|
69
|
+
the autonomous loop calling this.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
cwd: Directory whose `.claude/metrics/` subdirectory receives the
|
|
73
|
+
entry.
|
|
74
|
+
round_id: Identifier for the current round/iteration (e.g.
|
|
75
|
+
`/autoship`'s round_id, `/ship`'s issue identifier).
|
|
76
|
+
attempted: Short structured string — what was attempted this
|
|
77
|
+
iteration.
|
|
78
|
+
outcome: Short structured string — what happened.
|
|
79
|
+
next_action: Short structured string — what happens next.
|
|
80
|
+
session_id: Optional opaque session ID, enabling joins with
|
|
81
|
+
`boundary-events.jsonl` / `cost-metering.jsonl`.
|
|
82
|
+
"""
|
|
83
|
+
try:
|
|
84
|
+
log = _log_path(cwd)
|
|
85
|
+
log.parent.mkdir(parents=True, exist_ok=True)
|
|
86
|
+
|
|
87
|
+
payload = {
|
|
88
|
+
"ts": _isoformat_utc(),
|
|
89
|
+
"round_id": round_id,
|
|
90
|
+
"attempted": attempted,
|
|
91
|
+
"outcome": outcome,
|
|
92
|
+
"next_action": next_action,
|
|
93
|
+
"plugin_version": plugin_version.shipped_version(),
|
|
94
|
+
}
|
|
95
|
+
if session_id:
|
|
96
|
+
payload["session_id"] = session_id
|
|
97
|
+
|
|
98
|
+
append_line_locked(
|
|
99
|
+
log, json.dumps(payload, separators=(",", ":")) + "\n", delay_env_var=_DELAY_ENV_VAR
|
|
100
|
+
)
|
|
101
|
+
except Exception: # noqa: BLE001, S110 — fail-open by design, see module docstring
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _read_entries(log: Path) -> list:
|
|
106
|
+
if not log.is_file():
|
|
107
|
+
return []
|
|
108
|
+
entries = []
|
|
109
|
+
for line in log.read_text(encoding="utf-8").splitlines():
|
|
110
|
+
line = line.strip()
|
|
111
|
+
if not line:
|
|
112
|
+
continue
|
|
113
|
+
try:
|
|
114
|
+
entries.append(json.loads(line))
|
|
115
|
+
except (json.JSONDecodeError, ValueError):
|
|
116
|
+
continue
|
|
117
|
+
return entries
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def check_iteration_journal(
|
|
121
|
+
round_id: str, cwd=None, log_path: str | None = None
|
|
122
|
+
) -> tuple[bool, str]:
|
|
123
|
+
"""Whether >=1 journal entry exists for `round_id`.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
`(True, "ok")` when a matching entry exists (advancement allowed).
|
|
127
|
+
`(False, "iteration-journal-missing")` otherwise (advancement
|
|
128
|
+
blocked).
|
|
129
|
+
"""
|
|
130
|
+
log = Path(log_path) if log_path else _log_path(cwd, migrate=False)
|
|
131
|
+
for entry in _read_entries(log):
|
|
132
|
+
if entry.get("round_id") == round_id:
|
|
133
|
+
return True, "ok"
|
|
134
|
+
return False, "iteration-journal-missing"
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def cmd_record(args) -> int:
|
|
138
|
+
record_iteration_entry(
|
|
139
|
+
args.cwd,
|
|
140
|
+
args.round_id,
|
|
141
|
+
args.attempted,
|
|
142
|
+
args.outcome,
|
|
143
|
+
args.next_action,
|
|
144
|
+
args.session,
|
|
145
|
+
)
|
|
146
|
+
return 0
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def cmd_check(args) -> int:
|
|
150
|
+
allowed, reason = check_iteration_journal(args.round_id, args.cwd, args.log)
|
|
151
|
+
print(json.dumps({"allowed": allowed, "reason": reason}))
|
|
152
|
+
if allowed:
|
|
153
|
+
return 0
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
emit_boundary_event(
|
|
157
|
+
args.cwd,
|
|
158
|
+
hook="iteration_journal_gate",
|
|
159
|
+
tool="Skill",
|
|
160
|
+
decision="block",
|
|
161
|
+
matched_rule="iteration-journal-missing",
|
|
162
|
+
session_id=args.session,
|
|
163
|
+
)
|
|
164
|
+
except Exception: # noqa: BLE001, S110 — fail-open by design
|
|
165
|
+
pass
|
|
166
|
+
return 1
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def main(argv=None) -> int:
|
|
170
|
+
ap = argparse.ArgumentParser(description=__doc__)
|
|
171
|
+
sub = ap.add_subparsers(dest="command", required=True)
|
|
172
|
+
|
|
173
|
+
p = sub.add_parser("record", help="Append one iteration decision entry.")
|
|
174
|
+
p.add_argument("--cwd", default=None)
|
|
175
|
+
p.add_argument("--round-id", dest="round_id", required=True)
|
|
176
|
+
p.add_argument("--attempted", required=True)
|
|
177
|
+
p.add_argument("--outcome", required=True)
|
|
178
|
+
p.add_argument("--next-action", dest="next_action", required=True)
|
|
179
|
+
p.add_argument("--session", default=None)
|
|
180
|
+
p.set_defaults(func=cmd_record)
|
|
181
|
+
|
|
182
|
+
p = sub.add_parser(
|
|
183
|
+
"check",
|
|
184
|
+
help="Hard-block unless a journal entry exists for --round-id.",
|
|
185
|
+
)
|
|
186
|
+
p.add_argument("--cwd", default=None)
|
|
187
|
+
p.add_argument("--log", default=None)
|
|
188
|
+
p.add_argument("--round-id", dest="round_id", required=True)
|
|
189
|
+
p.add_argument("--session", default=None)
|
|
190
|
+
p.set_defaults(func=cmd_check)
|
|
191
|
+
|
|
192
|
+
parsed = ap.parse_args(argv)
|
|
193
|
+
return parsed.func(parsed)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
if __name__ == "__main__": # pragma: no cover
|
|
197
|
+
sys.exit(main())
|