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,106 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Autoship round bookkeeping log.
|
|
3
|
+
|
|
4
|
+
Appends one JSON line per autoship round to a caller-specified JSONL file,
|
|
5
|
+
mirroring the metrics/config-changelog.jsonl convention.
|
|
6
|
+
|
|
7
|
+
CLI usage:
|
|
8
|
+
python autoship_log.py --log-path <path> --json <json-string>
|
|
9
|
+
python autoship_log.py --log-path <path> --json-file <path-to-json-file>
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import json
|
|
14
|
+
import pathlib
|
|
15
|
+
import sys
|
|
16
|
+
from datetime import datetime, timezone
|
|
17
|
+
|
|
18
|
+
_LIB_DIR = pathlib.Path(__file__).resolve().parent
|
|
19
|
+
if str(_LIB_DIR) not in sys.path:
|
|
20
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
21
|
+
|
|
22
|
+
from atomic_state import append_line_locked
|
|
23
|
+
|
|
24
|
+
_DELAY_ENV_VAR = "DEV_TEAM_AUTOSHIP_LOG_TEST_DELAY_MS"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def append_round(log_path: str, record: dict) -> None:
|
|
28
|
+
"""Append a JSON line to log_path, adding a logged_at ISO timestamp.
|
|
29
|
+
|
|
30
|
+
Creates the file and any parent directories if they do not exist.
|
|
31
|
+
Serializes concurrent appends via `atomic_state.append_line_locked`
|
|
32
|
+
(#1889) so two overlapping `/autoship` rounds writing to the same log
|
|
33
|
+
are protected from interleaving their bytes into one corrupted line
|
|
34
|
+
while the lock is held (see `locked_state`'s own fail-open fallback for
|
|
35
|
+
when it might not be). Unlike the fail-open telemetry streams sharing
|
|
36
|
+
this pattern (`boundary_events.py`, `workflow_state.py`,
|
|
37
|
+
`iteration_journal_gate.py`), a write failure here is not swallowed —
|
|
38
|
+
`append_line_locked(fail_open=False)` re-raises it after the lock
|
|
39
|
+
releases, so the CLI still surfaces it as a real error.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
log_path: Path to the JSONL file.
|
|
43
|
+
record: Mapping of fields to include in the log entry.
|
|
44
|
+
"""
|
|
45
|
+
entry = dict(record)
|
|
46
|
+
entry["logged_at"] = datetime.now(timezone.utc).isoformat()
|
|
47
|
+
|
|
48
|
+
path = pathlib.Path(log_path)
|
|
49
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
50
|
+
|
|
51
|
+
line = json.dumps(entry) + "\n"
|
|
52
|
+
append_line_locked(path, line, delay_env_var=_DELAY_ENV_VAR, fail_open=False)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _build_parser() -> argparse.ArgumentParser:
|
|
56
|
+
parser = argparse.ArgumentParser(
|
|
57
|
+
description="Append one JSON line to an autoship round log."
|
|
58
|
+
)
|
|
59
|
+
parser.add_argument("--log-path", required=True, help="Path to the JSONL log file.")
|
|
60
|
+
source = parser.add_mutually_exclusive_group(required=True)
|
|
61
|
+
source.add_argument("--json", dest="json_str", help="JSON object string to append.")
|
|
62
|
+
source.add_argument(
|
|
63
|
+
"--json-file",
|
|
64
|
+
help=(
|
|
65
|
+
"Path to a file containing a JSON object to append — the "
|
|
66
|
+
"--body-file convention applied to this log write, so "
|
|
67
|
+
"agent-derived text (e.g. a synthesized blocked_reason) never "
|
|
68
|
+
"needs to be interpolated into an inline --json shell string."
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
return parser
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def main(argv=None) -> int:
|
|
75
|
+
parser = _build_parser()
|
|
76
|
+
args = parser.parse_args(argv)
|
|
77
|
+
|
|
78
|
+
if args.json_file is not None:
|
|
79
|
+
try:
|
|
80
|
+
with open(args.json_file, encoding="utf-8") as fh:
|
|
81
|
+
raw = fh.read()
|
|
82
|
+
except OSError as exc:
|
|
83
|
+
print(
|
|
84
|
+
f"error: could not read --json-file {args.json_file!r}: {exc}",
|
|
85
|
+
file=sys.stderr,
|
|
86
|
+
)
|
|
87
|
+
return 1
|
|
88
|
+
else:
|
|
89
|
+
raw = args.json_str
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
record = json.loads(raw)
|
|
93
|
+
except json.JSONDecodeError as exc:
|
|
94
|
+
print(f"error: invalid JSON: {exc}", file=sys.stderr)
|
|
95
|
+
return 1
|
|
96
|
+
|
|
97
|
+
if not isinstance(record, dict):
|
|
98
|
+
print("error: JSON must be an object (dict)", file=sys.stderr)
|
|
99
|
+
return 1
|
|
100
|
+
|
|
101
|
+
append_round(args.log_path, record)
|
|
102
|
+
return 0
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
if __name__ == "__main__":
|
|
106
|
+
sys.exit(main())
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""banned_scripts_policy — shared policy constants and checkout-shape probe
|
|
2
|
+
for the #1755 banned-script hook pair (`scan_bash_command_for_banned_scripts.py`,
|
|
3
|
+
`scan_worktree_for_banned_scripts.py`).
|
|
4
|
+
|
|
5
|
+
Both hooks independently defined identical `BANNED_EXTENSIONS`/
|
|
6
|
+
`SCOPED_PREFIX`/`ALLOWED_RELATIVE_PATHS` constants (#1850). This module is
|
|
7
|
+
the shared extraction so the policy can't drift between the PreToolUse
|
|
8
|
+
command-string scan and the PostToolUse working-tree backstop.
|
|
9
|
+
|
|
10
|
+
Stdlib-only. See ADR 0014/0015.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
# The extensions this repo's CLAUDE.md forbids under plugins/dev-team/.
|
|
18
|
+
BANNED_EXTENSIONS = (".sh", ".bash", ".bat", ".cmd", ".ps1")
|
|
19
|
+
|
|
20
|
+
SCOPED_PREFIX = "plugins/dev-team/"
|
|
21
|
+
|
|
22
|
+
# The two documented bootstrap-shim exceptions (repo CLAUDE.md § Script
|
|
23
|
+
# authoring — Python only): install.sh can't itself be Python because it
|
|
24
|
+
# must run before an interpreter is guaranteed on PATH, and hooks/py.sh is
|
|
25
|
+
# the trampoline that resolves one. Every other invocation under
|
|
26
|
+
# plugins/dev-team/ routes through py.sh, never a bare interpreter.
|
|
27
|
+
ALLOWED_RELATIVE_PATHS = {
|
|
28
|
+
"plugins/dev-team/install.sh",
|
|
29
|
+
"plugins/dev-team/hooks/py.sh",
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def looks_like_monorepo_checkout(start: Path) -> bool:
|
|
34
|
+
"""Cheap, non-git check: does ``plugins/dev-team/`` exist under ``start``
|
|
35
|
+
or any of its ancestors? Pure filesystem walk — never shells out — so a
|
|
36
|
+
downstream install (where this is always False) pays nothing before
|
|
37
|
+
either hook's early exit (#1861).
|
|
38
|
+
"""
|
|
39
|
+
start_resolved = start.resolve()
|
|
40
|
+
for candidate in (start_resolved, *start_resolved.parents):
|
|
41
|
+
if (candidate / "plugins" / "dev-team").is_dir():
|
|
42
|
+
return True
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
__all__ = (
|
|
47
|
+
"ALLOWED_RELATIVE_PATHS",
|
|
48
|
+
"BANNED_EXTENSIONS",
|
|
49
|
+
"SCOPED_PREFIX",
|
|
50
|
+
"looks_like_monorepo_checkout",
|
|
51
|
+
)
|
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
"""boundary_events.py — shared boundary-level telemetry emit helper (#859).
|
|
2
|
+
|
|
3
|
+
Records the decision process of the plugin's guard hooks (policy-gateway
|
|
4
|
+
events, per *Code as Agent Harness* §3.5.1): which hook, on which tool,
|
|
5
|
+
decided what, because of which rule. Complements `telemetry.py`
|
|
6
|
+
(command/skill/gate invocation counts) and `cost_meter.py` (per-agent
|
|
7
|
+
token/cost) as the third, boundary-level channel.
|
|
8
|
+
|
|
9
|
+
ALWAYS-ON: unlike `telemetry.py`, this stream is not gated by
|
|
10
|
+
`DEV_TEAM_TELEMETRY` consent — it is a local-only, rule-IDs-only safety /
|
|
11
|
+
accountability record (Ambiguity Log, issue #859). Never write free text:
|
|
12
|
+
command text, prompt text, file paths, or reasons must never appear in a
|
|
13
|
+
`matched_rule` value — only rule IDs from closed vocabularies.
|
|
14
|
+
|
|
15
|
+
Fail-open: every exception is swallowed. A full disk, read-only
|
|
16
|
+
`.claude/metrics/`, or malformed state must never change the calling
|
|
17
|
+
hook's stdout, stderr, or exit code.
|
|
18
|
+
|
|
19
|
+
Stdlib only. See ADR 0014 / ADR 0015.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import json
|
|
25
|
+
import sys
|
|
26
|
+
from datetime import datetime, timezone
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
|
|
29
|
+
_LIB_DIR = Path(__file__).resolve().parent
|
|
30
|
+
if str(_LIB_DIR) not in sys.path:
|
|
31
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
32
|
+
|
|
33
|
+
import artifact_paths
|
|
34
|
+
import atomic_state
|
|
35
|
+
import plugin_version
|
|
36
|
+
|
|
37
|
+
#: This stream's filename — the single source of truth every other reader
|
|
38
|
+
#: or guard that needs to name it (`review_dispatch_ledger.LEDGER_STREAM`,
|
|
39
|
+
#: `boundary_events_write_guard.py`, `review_gate_corroboration.py`) must
|
|
40
|
+
#: import from here rather than re-declaring its own literal (backstop
|
|
41
|
+
#: review finding, #2166 + #2171: this filename previously had three
|
|
42
|
+
#: independent homes). Public because this module is the one that actually
|
|
43
|
+
#: writes the ledger and therefore owns its name.
|
|
44
|
+
LOG_NAME = "boundary-events.jsonl"
|
|
45
|
+
|
|
46
|
+
# Test-only injection point (see `_write_jsonl_line` below and
|
|
47
|
+
# `atomic_state.race_window_delay`'s own docstring): unset in production, a
|
|
48
|
+
# no-op when absent.
|
|
49
|
+
_TEST_DELAY_ENV = "DEV_TEAM_BOUNDARY_EVENTS_TEST_DELAY_MS"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _append_line_locked(log: Path, line: str) -> None:
|
|
53
|
+
"""Serialize one JSONL append against concurrent writers (#1874),
|
|
54
|
+
delegating to `atomic_state.append_line_locked` (#1904 item 5) rather
|
|
55
|
+
than reimplementing the critical section here.
|
|
56
|
+
|
|
57
|
+
This module used to hold `atomic_state.locked_state`'s lock itself and
|
|
58
|
+
write through a plain `open(log, "a")` — that plain `open()` lacked the
|
|
59
|
+
`O_NOFOLLOW` hardening `atomic_state.append_line_locked` already applies
|
|
60
|
+
to its own append (a pre-planted symlink at this stream's path would
|
|
61
|
+
otherwise redirect every append). Delegating gives this stream that same
|
|
62
|
+
hardening for free, and leaves exactly ONE hardened append
|
|
63
|
+
implementation in the plugin rather than two that can drift out of sync.
|
|
64
|
+
|
|
65
|
+
`fail_open=True` (the default) matches this module's own fail-open
|
|
66
|
+
write-side contract (OSError swallowed); `delay_env_var=_TEST_DELAY_ENV`
|
|
67
|
+
preserves the test-only split-write determinism aid #1874 needs — see
|
|
68
|
+
`atomic_state.append_line_locked`'s own docstring for why a split,
|
|
69
|
+
not just a delay, is required to force real interleaving in a test.
|
|
70
|
+
"""
|
|
71
|
+
atomic_state.append_line_locked(log, line, delay_env_var=_TEST_DELAY_ENV)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# The single source of truth for this stream's `ts` format (#1461 structure
|
|
75
|
+
# review). `hooks/lib/review_gate_corroboration.py` imports this directly
|
|
76
|
+
# rather than re-declaring its own literal — its lexical since/until
|
|
77
|
+
# comparison over `ts` strings is only correct because every emitter uses
|
|
78
|
+
# this exact format, so a format change must move both modules in lockstep,
|
|
79
|
+
# not by convention/comment alone.
|
|
80
|
+
TS_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _isoformat_utc() -> str:
|
|
84
|
+
return datetime.now(timezone.utc).strftime(TS_FORMAT)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def emit_boundary_event(
|
|
88
|
+
cwd,
|
|
89
|
+
hook: str,
|
|
90
|
+
tool: str,
|
|
91
|
+
decision: str,
|
|
92
|
+
matched_rule: str,
|
|
93
|
+
session_id: str | None = None,
|
|
94
|
+
subject_hash: str | None = None,
|
|
95
|
+
subject_hash_normalized: str | None = None,
|
|
96
|
+
) -> None:
|
|
97
|
+
"""Append one compact JSON line to
|
|
98
|
+
`<cwd>/.claude/metrics/boundary-events.jsonl`.
|
|
99
|
+
|
|
100
|
+
Fail-open: any error (bad `cwd`, unwritable `.claude/metrics/`, disk
|
|
101
|
+
full, etc.) is swallowed silently — this must never affect the
|
|
102
|
+
caller's exit code, stdout, or stderr.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
cwd: Directory whose `.claude/metrics/` subdirectory receives the
|
|
106
|
+
event. Accepts `str` or `Path`.
|
|
107
|
+
hook: Emitting hook's module name (e.g. "destructive_guard").
|
|
108
|
+
tool: Hooked tool / event name (e.g. "Bash", "UserPromptSubmit").
|
|
109
|
+
decision: One of "block", "warn", "bypass", "intervention", "revert",
|
|
110
|
+
"record", "dispatch-failure". "record" (#1461) is a non-verdict,
|
|
111
|
+
observational entry — it does not block/warn/bypass/intervene/
|
|
112
|
+
revert anything, it merely notes that a genuine, registered
|
|
113
|
+
review-agent dispatch occurred (emitted by
|
|
114
|
+
`agent_dispatch_ledger.py`). "dispatch-failure" (#1763) is also
|
|
115
|
+
non-verdict-counted, observational — it notes that a dispatched
|
|
116
|
+
review agent failed to return a contract-valid result even after
|
|
117
|
+
one retry. Unlike "record" it is consumed ONLY as NEGATIVE
|
|
118
|
+
evidence, by the gate veto in
|
|
119
|
+
`hooks/lib/review_gate_corroboration.py`/`hooks/pre_pr_review.py`
|
|
120
|
+
(`_dispatch_failure_verdict`, #1763 — carried forward to the
|
|
121
|
+
PR-time gate by #1886; the cosmetic-delta carry-forward veto
|
|
122
|
+
this originally paired with, `_cosmetic_carry_forward_verdict`,
|
|
123
|
+
was specific to the retired commit-time gate and was deleted in
|
|
124
|
+
#1904), so a forged event can only ever narrow corroboration,
|
|
125
|
+
never widen it. Exclude both from verdict counts; see
|
|
126
|
+
`knowledge/telemetry-schema.md`.
|
|
127
|
+
matched_rule: A rule ID from a closed vocabulary — never free
|
|
128
|
+
text (no command text, prompt text, file paths, or reasons).
|
|
129
|
+
session_id: Optional opaque session ID from the hook payload,
|
|
130
|
+
enabling per-session joins with session-digest.jsonl.
|
|
131
|
+
subject_hash: Optional `review_gate_hash()` value (#1461) binding
|
|
132
|
+
this event to the specific staged-content hash it corroborates
|
|
133
|
+
— not free text (a hex digest carries no path/prompt/reason
|
|
134
|
+
information), but a derived value naming what was reviewed.
|
|
135
|
+
`hooks/lib/review_gate_corroboration.py` requires this to match
|
|
136
|
+
the gate's current hash before treating a "record" or exemption
|
|
137
|
+
event as corroborating evidence, so a genuine dispatch/exemption
|
|
138
|
+
for one diff can't satisfy the gate for a different, unrelated
|
|
139
|
+
one.
|
|
140
|
+
subject_hash_normalized: Optional `normalized_gate_hash()` value
|
|
141
|
+
(#1627) — the same binding, computed over the staged patch after
|
|
142
|
+
doc-hunk and indentation normalization. Lets the gate carry
|
|
143
|
+
corroboration forward across a re-stage that provably changed no
|
|
144
|
+
behavior, without a fresh dispatch whose only purpose is to feed
|
|
145
|
+
the ledger. Like `subject_hash`, a derived digest carrying no
|
|
146
|
+
path/prompt/reason information. Events written before this field
|
|
147
|
+
existed simply never match on the normalized path — the same
|
|
148
|
+
backward-compat posture `subject_hash` itself has.
|
|
149
|
+
"""
|
|
150
|
+
try:
|
|
151
|
+
base = Path(cwd) if cwd else Path.cwd()
|
|
152
|
+
log = artifact_paths.resolve_file("metrics", LOG_NAME, base)
|
|
153
|
+
log.parent.mkdir(parents=True, exist_ok=True)
|
|
154
|
+
|
|
155
|
+
payload = {
|
|
156
|
+
"ts": _isoformat_utc(),
|
|
157
|
+
"hook": hook,
|
|
158
|
+
"tool": tool,
|
|
159
|
+
"decision": decision,
|
|
160
|
+
"matched_rule": matched_rule,
|
|
161
|
+
"plugin_version": plugin_version.shipped_version(),
|
|
162
|
+
}
|
|
163
|
+
if session_id:
|
|
164
|
+
payload["session_id"] = session_id
|
|
165
|
+
if subject_hash:
|
|
166
|
+
payload["subject_hash"] = subject_hash
|
|
167
|
+
if subject_hash_normalized:
|
|
168
|
+
payload["subject_hash_normalized"] = subject_hash_normalized
|
|
169
|
+
|
|
170
|
+
line = json.dumps(payload, separators=(",", ":")) + "\n"
|
|
171
|
+
_append_line_locked(log, line)
|
|
172
|
+
except Exception: # noqa: BLE001, S110 — fail-open by design, see module docstring
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# Fixed (hook, tool, decision, matched_rule) tuples the CLI may emit — see
|
|
177
|
+
# `_main()`'s docstring. This is a closed set, not a free-form pass-through:
|
|
178
|
+
# a skill invoking this CLI picks one of these named events, it can never
|
|
179
|
+
# supply its own hook/tool/decision/matched_rule. In particular, "record"
|
|
180
|
+
# (the decision `agent_dispatch_ledger.py` uses) is not reachable from this
|
|
181
|
+
# CLI at all — only the real PreToolUse hook can emit it — closing a
|
|
182
|
+
# ledger-forgery vector security review found in an earlier draft (#1461):
|
|
183
|
+
# an unrestricted CLI writer could otherwise fabricate arbitrary dispatch
|
|
184
|
+
# evidence, including fake "record" rows for unregistered agent names,
|
|
185
|
+
# byte-identical to genuine hook output.
|
|
186
|
+
#
|
|
187
|
+
# Bounded exception (#1763): `--event dispatch-failure` (below, handled by
|
|
188
|
+
# its own branch in `_main()`, via `_CLI_AGENT_EVENTS`, not this dict) is
|
|
189
|
+
# deliberately NOT a fixed tuple — it carries one piece of caller-supplied,
|
|
190
|
+
# per-invocation data (the failed agent's name) as `matched_rule`, which a
|
|
191
|
+
# static tuple can't express. This is still safe: the decision value it
|
|
192
|
+
# writes ("dispatch-failure") is consumed ONLY as negative evidence, by the
|
|
193
|
+
# gate veto in `hooks/lib/review_gate_corroboration.py`/
|
|
194
|
+
# `hooks/pre_pr_review.py` (`_dispatch_failure_verdict`, carried forward to
|
|
195
|
+
# the PR-time gate by #1886) — never as corroborating evidence for a
|
|
196
|
+
# `.pr-review-passed` write — so a forged/hand-run invocation can only ever
|
|
197
|
+
# narrow corroboration (cause a false block on a gate that would otherwise
|
|
198
|
+
# pass), never widen it (cause a false pass). (The cosmetic-delta
|
|
199
|
+
# carry-forward veto this originally paired with,
|
|
200
|
+
# `_cosmetic_carry_forward_verdict`, was specific to the retired commit-time
|
|
201
|
+
# gate and was deleted in #1904.) The opposite forgery
|
|
202
|
+
# direction from "record" either way. The agent name is still validated at
|
|
203
|
+
# write time against the registered review-agent set
|
|
204
|
+
# (`review_agent_registry.registered_review_agent_names`, with the same
|
|
205
|
+
# plugin-prefix normalization `agent_dispatch_ledger.py` applies), matching
|
|
206
|
+
# that hook's own posture: an unregistered name is silently NOT recorded,
|
|
207
|
+
# never written even as a rejected/flagged entry.
|
|
208
|
+
_CLI_EVENTS = {
|
|
209
|
+
"doc-only": ("code-review", "Skill", "bypass", "doc-only-review-exempt"),
|
|
210
|
+
"single-agent": ("code-review", "Skill", "bypass", "single-agent-review-exempt"),
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
# (hook, tool, decision) for events whose `matched_rule` is supplied
|
|
214
|
+
# per-invocation via `--agent` rather than fixed in the tuple — a second,
|
|
215
|
+
# small registry alongside `_CLI_EVENTS` (not folded into it, since those
|
|
216
|
+
# tuples carry a fixed `matched_rule` and this one doesn't) so the set of
|
|
217
|
+
# CLI-constructible events stays declarable in one place per event shape.
|
|
218
|
+
# See the comment above `_CLI_EVENTS` for why a dynamic `matched_rule` here
|
|
219
|
+
# is still a bounded, safe exception to the closed-tuple design.
|
|
220
|
+
_CLI_AGENT_EVENTS = {
|
|
221
|
+
"dispatch-failure": ("code-review", "Skill", "dispatch-failure"),
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
# Verdict values a real, external (non-Claude-Code) gate can report about
|
|
225
|
+
# its own run (#2037): "allow" (ran, allowed the commit), "block" (ran,
|
|
226
|
+
# rejected the commit for a legitimate reason), "errored" (ran, but hit an
|
|
227
|
+
# internal/infra failure rather than evaluating the commit's own content —
|
|
228
|
+
# distinguishable from an ordinary "block" so a hook that fails silently and
|
|
229
|
+
# a hook that correctly rejects bad content don't collapse into one bucket).
|
|
230
|
+
# A closed, small vocabulary — not free text — so the `matched_rule` this
|
|
231
|
+
# produces (`gate-ran-<verdict>`) stays within this module's "rule IDs only"
|
|
232
|
+
# contract.
|
|
233
|
+
_GATE_RAN_VERDICTS = frozenset({"allow", "block", "errored"})
|
|
234
|
+
|
|
235
|
+
# (hook, tool, decision) for the `gate-ran` event — a third small registry
|
|
236
|
+
# alongside `_CLI_EVENTS`/`_CLI_AGENT_EVENTS` (see the comment above
|
|
237
|
+
# `_CLI_EVENTS` for why a per-invocation `matched_rule` is still a bounded,
|
|
238
|
+
# safe exception to the closed-tuple design): `--verdict` is constrained to
|
|
239
|
+
# `_GATE_RAN_VERDICTS` below, so the resulting `matched_rule` is still one of
|
|
240
|
+
# exactly three known strings, never free text. `decision` is `"record"` —
|
|
241
|
+
# the same non-verdict, observational shape `agent_dispatch_ledger.py`'s own
|
|
242
|
+
# "record" events use (see `emit_boundary_event`'s docstring): this event
|
|
243
|
+
# notes that the gate ran at all; its OWN internal outcome lives in
|
|
244
|
+
# `matched_rule`, not in `decision`. Unlike every other CLI event here, this
|
|
245
|
+
# one has no `session_id` to attach in the ordinary case — `.husky/pre-commit`
|
|
246
|
+
# is a REAL git hook invoked by git itself, outside Claude Code's own
|
|
247
|
+
# PreToolUse machinery entirely, so it never receives a Claude Code
|
|
248
|
+
# session_id to pass through. `--session-id`/`--subject-hash` remain accepted
|
|
249
|
+
# (a future caller that DOES have one can still supply it); the shipped
|
|
250
|
+
# caller simply omits both — see `session_report.py`'s "gate-run
|
|
251
|
+
# correlation (#2037)" section for why correlation is by TIME PROXIMITY
|
|
252
|
+
# instead.
|
|
253
|
+
_CLI_VERDICT_EVENTS = {
|
|
254
|
+
"gate-ran": ("pre-commit-gate", "Bash", "record"),
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def cli_event_names() -> list[str]:
|
|
259
|
+
"""The full, sorted `--event` choice set this CLI accepts — the same
|
|
260
|
+
union `_main()`'s own `argparse` `choices=` computes. Public so a
|
|
261
|
+
caller that needs to *describe* the CLI's invocable shape (e.g.
|
|
262
|
+
`boundary_events_write_guard.py`'s Bash-path remedy message, #2171)
|
|
263
|
+
reads this one source of truth instead of re-enumerating the three
|
|
264
|
+
closed-vocabulary dicts above by hand, which would silently go stale
|
|
265
|
+
the next time an event is added to any of them."""
|
|
266
|
+
return sorted({*_CLI_EVENTS, *_CLI_AGENT_EVENTS, *_CLI_VERDICT_EVENTS})
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def _main() -> int:
|
|
270
|
+
"""CLI entry point (#1461): lets a *skill's* bash-block prose emit one of
|
|
271
|
+
a small, fixed set of exemption events, the same way
|
|
272
|
+
`hooks/lib/iteration_journal_gate.py` and `hooks/lib/review_gate_hash.py`
|
|
273
|
+
are invoked from skill markdown — hooks read a stdin JSON payload, but a
|
|
274
|
+
skill step has no such payload to hand this module, only CLI-style
|
|
275
|
+
arguments. Used today by `skills/code-review/SKILL.md`'s doc-only
|
|
276
|
+
short-circuit (`--event doc-only`) and its `--agent <name>` single-agent
|
|
277
|
+
review path (`--event single-agent`), each recording their exemption
|
|
278
|
+
event contemporaneously with the `.review-passed` gate write, bound via
|
|
279
|
+
`--subject-hash` to that write's own `review_gate_hash()` value so the
|
|
280
|
+
exemption can't be replayed for a different, unrelated diff.
|
|
281
|
+
|
|
282
|
+
Deliberately NOT a generic `--hook/--tool/--decision/--matched-rule`
|
|
283
|
+
pass-through (see `_CLI_EVENTS`) — `--event` selects one of two fixed
|
|
284
|
+
tuples, or (#1763) `dispatch-failure` (see `_CLI_AGENT_EVENTS`), whose
|
|
285
|
+
`matched_rule` comes from `--agent` and is validated against the
|
|
286
|
+
registered review-agent set before being written; nothing else is
|
|
287
|
+
constructible from the command line.
|
|
288
|
+
|
|
289
|
+
`--event dispatch-failure --agent <name> --subject-hash <hash>
|
|
290
|
+
[--subject-hash-normalized <hash>]` (#1763): used by `SKILL.md` Step 4
|
|
291
|
+
when a dispatched review agent still fails to return a contract-valid
|
|
292
|
+
result after its single retry, recording that fact as negative evidence
|
|
293
|
+
for `hooks/lib/review_gate_corroboration.py`/`hooks/pre_pr_review.py`'s
|
|
294
|
+
gate veto (`_dispatch_failure_verdict`, #1763 — carried forward to the
|
|
295
|
+
PR-time gate by #1886). `--subject-hash-normalized` is accepted here for
|
|
296
|
+
call-shape symmetry with `agent_dispatch_ledger.py`'s own `"record"`
|
|
297
|
+
events, but has no current consumer: the cosmetic-delta carry-forward
|
|
298
|
+
lens it fed was specific to the retired commit-time gate and was
|
|
299
|
+
deleted in #1904 (along with `sliced-mode.md`'s own now-removed
|
|
300
|
+
`--subject-hash-normalized` emission — see that file for the #1904
|
|
301
|
+
cleanup). `<name>` must be a
|
|
302
|
+
registered `agents/*-review.md` stem — an unregistered name is silently
|
|
303
|
+
NOT recorded, matching `agent_dispatch_ledger.py`'s own validation
|
|
304
|
+
posture (including the same plugin-prefix normalization,
|
|
305
|
+
`strip_plugin_prefix`).
|
|
306
|
+
|
|
307
|
+
Fail-open, same posture as `emit_boundary_event` itself: the emit path
|
|
308
|
+
never raises — a missing `--agent`, a broken registry read, or an
|
|
309
|
+
unregistered name all degrade to a silent no-op (return 0), never an
|
|
310
|
+
exception or a nonzero exit. (Argument-parsing usage errors from
|
|
311
|
+
`argparse` itself — e.g. an unrecognized `--event` value — still exit
|
|
312
|
+
nonzero via `parser.error`, as for any CLI; that is a caller-code bug,
|
|
313
|
+
not a runtime condition this fail-open contract covers.)
|
|
314
|
+
|
|
315
|
+
KNOWN RESIDUAL GAP (#1763 security review), disclosed rather than
|
|
316
|
+
silently accepted: this fail-open posture is deliberately safe for
|
|
317
|
+
`"record"` (a lost POSITIVE-evidence write only over-blocks the gate)
|
|
318
|
+
but inverts for `"dispatch-failure"` — a lost NEGATIVE-evidence write
|
|
319
|
+
(a full disk, an unwritable `.claude/metrics/`, a registry read that
|
|
320
|
+
happens to fail exactly at write time, or an unregistered/mistyped
|
|
321
|
+
`--agent` value) means a genuine dispatch failure produces no evidence
|
|
322
|
+
at all, and the gate then evaluates on the other agents' `"record"`s
|
|
323
|
+
alone as if nothing failed. Not fixed here: giving this one event type
|
|
324
|
+
a non-fail-open write path would need a `strict` variant threaded
|
|
325
|
+
through `emit_boundary_event` and a corresponding change to how
|
|
326
|
+
`SKILL.md`/`sliced-mode.md` treat a nonzero exit from this CLI — a
|
|
327
|
+
larger change than this bounded exception's own scope.
|
|
328
|
+
"""
|
|
329
|
+
import argparse
|
|
330
|
+
|
|
331
|
+
parser = argparse.ArgumentParser(description=_main.__doc__)
|
|
332
|
+
parser.add_argument("--cwd", default=None)
|
|
333
|
+
parser.add_argument(
|
|
334
|
+
"--event",
|
|
335
|
+
required=True,
|
|
336
|
+
choices=cli_event_names(),
|
|
337
|
+
)
|
|
338
|
+
# Required for every event EXCEPT `gate-ran` (#2037), which has no diff
|
|
339
|
+
# content to bind to — a real git hook has no staged/branch diff to hash
|
|
340
|
+
# at the point it runs. Enforced per-event below rather than via
|
|
341
|
+
# argparse's own `required=True`, since that constraint no longer holds
|
|
342
|
+
# for every event this parser accepts.
|
|
343
|
+
parser.add_argument("--subject-hash", default=None, dest="subject_hash")
|
|
344
|
+
parser.add_argument(
|
|
345
|
+
"--subject-hash-normalized", default=None, dest="subject_hash_normalized"
|
|
346
|
+
)
|
|
347
|
+
parser.add_argument("--session-id", default=None, dest="session_id")
|
|
348
|
+
parser.add_argument("--agent", default=None, dest="agent")
|
|
349
|
+
parser.add_argument(
|
|
350
|
+
"--verdict", choices=sorted(_GATE_RAN_VERDICTS), default=None, dest="verdict"
|
|
351
|
+
)
|
|
352
|
+
args = parser.parse_args()
|
|
353
|
+
|
|
354
|
+
if args.event in _CLI_VERDICT_EVENTS:
|
|
355
|
+
if not args.verdict:
|
|
356
|
+
parser.error(f"--event {args.event} requires --verdict")
|
|
357
|
+
hook, tool, decision = _CLI_VERDICT_EVENTS[args.event]
|
|
358
|
+
emit_boundary_event(
|
|
359
|
+
args.cwd,
|
|
360
|
+
hook,
|
|
361
|
+
tool,
|
|
362
|
+
decision,
|
|
363
|
+
f"gate-ran-{args.verdict}",
|
|
364
|
+
args.session_id,
|
|
365
|
+
subject_hash=args.subject_hash,
|
|
366
|
+
)
|
|
367
|
+
return 0
|
|
368
|
+
|
|
369
|
+
if not args.subject_hash:
|
|
370
|
+
parser.error(f"--event {args.event} requires --subject-hash")
|
|
371
|
+
|
|
372
|
+
if args.event in _CLI_AGENT_EVENTS:
|
|
373
|
+
if not args.agent:
|
|
374
|
+
# Fail-open: a caller that forgot --agent gets a silent no-op,
|
|
375
|
+
# not a nonzero exit from a telemetry emitter — matches this
|
|
376
|
+
# function's own "always exits 0" contract for the emit path.
|
|
377
|
+
return 0
|
|
378
|
+
try:
|
|
379
|
+
# Local import: only this branch needs this sibling module, so
|
|
380
|
+
# callers that merely import `emit_boundary_event` (every guard
|
|
381
|
+
# hook) never pay for it, and copy-into-tmp-dir test harnesses
|
|
382
|
+
# that stage a minimal subset of hooks/lib/ alongside the hook
|
|
383
|
+
# under test (see test_contract_version_guard.py::_run_hook_from,
|
|
384
|
+
# which stages boundary_events.py + artifact_paths.py +
|
|
385
|
+
# atomic_state.py) keep working unmodified. Inside the
|
|
386
|
+
# try/except below so an ImportError from a partial install
|
|
387
|
+
# degrades the same way a broken registry
|
|
388
|
+
# read does, rather than raising.
|
|
389
|
+
import review_agent_registry
|
|
390
|
+
except Exception: # noqa: BLE001 - fail-open: an unavailable registry module never records
|
|
391
|
+
return 0
|
|
392
|
+
# `is_registered_review_lens()` (review_agent_registry.py) owns the
|
|
393
|
+
# strip-prefix + registry-read + membership check, including the
|
|
394
|
+
# "unreadable registry collapses to skip" posture — previously
|
|
395
|
+
# hand-rolled independently here, in `agent_dispatch_ledger.py`, and
|
|
396
|
+
# in `review_verdict_recorder.py` (backstop review finding, #2166 +
|
|
397
|
+
# #2171 consolidation).
|
|
398
|
+
if not review_agent_registry.is_registered_review_lens(args.agent):
|
|
399
|
+
# Unregistered name, or the registry could not be read at all ->
|
|
400
|
+
# silently NOT recorded (matches agent_dispatch_ledger.py's own
|
|
401
|
+
# posture; see module comment).
|
|
402
|
+
return 0
|
|
403
|
+
# Normalize the plugin-qualified form ("dev-team:security-review")
|
|
404
|
+
# to the bare stem the registry's closed set uses, matching
|
|
405
|
+
# agent_dispatch_ledger.py's own normalization exactly — otherwise
|
|
406
|
+
# the plugin's normal, installed invocation form would be silently
|
|
407
|
+
# dropped as "unregistered".
|
|
408
|
+
agent = review_agent_registry.strip_plugin_prefix(args.agent)
|
|
409
|
+
hook, tool, decision = _CLI_AGENT_EVENTS[args.event]
|
|
410
|
+
emit_boundary_event(
|
|
411
|
+
args.cwd,
|
|
412
|
+
hook,
|
|
413
|
+
tool,
|
|
414
|
+
decision,
|
|
415
|
+
agent,
|
|
416
|
+
args.session_id,
|
|
417
|
+
subject_hash=args.subject_hash,
|
|
418
|
+
subject_hash_normalized=args.subject_hash_normalized,
|
|
419
|
+
)
|
|
420
|
+
return 0
|
|
421
|
+
|
|
422
|
+
hook, tool, decision, matched_rule = _CLI_EVENTS[args.event]
|
|
423
|
+
emit_boundary_event(
|
|
424
|
+
args.cwd,
|
|
425
|
+
hook,
|
|
426
|
+
tool,
|
|
427
|
+
decision,
|
|
428
|
+
matched_rule,
|
|
429
|
+
args.session_id,
|
|
430
|
+
subject_hash=args.subject_hash,
|
|
431
|
+
)
|
|
432
|
+
return 0
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
if __name__ == "__main__":
|
|
436
|
+
raise SystemExit(_main())
|