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,301 @@
|
|
|
1
|
+
"""review_verdicts.py — per-lens review verdict store (#2166).
|
|
2
|
+
|
|
3
|
+
Records, per genuine review-agent dispatch, an outcome (`pass` | `findings`)
|
|
4
|
+
bound to `(lens, file_path, file_content_hash)` — NOT per-diff (Decision 3,
|
|
5
|
+
plans/2164-verdict-ledger-writer.md): a verdict row answers "did this lens
|
|
6
|
+
pass this exact file content", so it can be looked up again the next time the
|
|
7
|
+
same file content recurs, regardless of which diff produced it.
|
|
8
|
+
|
|
9
|
+
A deliberate sibling of `hooks/lib/boundary_events.py`, not an extension of
|
|
10
|
+
it (Decision 1): `boundary_events.py`'s own docstring forbids ever writing a
|
|
11
|
+
real `file_path` into that stream ("Never write free text ... file paths ...
|
|
12
|
+
must never appear"), so a per-file verdict needs its own store,
|
|
13
|
+
`.claude/metrics/review-verdicts.jsonl`, written via the same
|
|
14
|
+
`atomic_state.append_line_locked` primitive `boundary_events.py` uses.
|
|
15
|
+
|
|
16
|
+
ALWAYS-ON (Decision 2): unlike `telemetry.py`, this stream is not gated by
|
|
17
|
+
`DEV_TEAM_TELEMETRY`/`~/.claude/telemetry.json` consent — same posture as
|
|
18
|
+
`boundary-events.jsonl` itself, for the same reason (local-only, mechanical
|
|
19
|
+
accountability data: lens/path/hash/outcome, no prose).
|
|
20
|
+
|
|
21
|
+
Fail-open: every exception in `emit_review_verdict()` is swallowed. A full
|
|
22
|
+
disk, read-only `.claude/metrics/`, or malformed state must never change the
|
|
23
|
+
calling hook's stdout, stderr, or exit code. `load_verdicts()` never raises
|
|
24
|
+
either — an absent file, a corrupted line, or a stale `plugin_version` row
|
|
25
|
+
all degrade to "no usable rows" rather than an exception.
|
|
26
|
+
|
|
27
|
+
`hooks/review_verdict_recorder.py` is a writer only — it never calls
|
|
28
|
+
`load_verdicts()`. `scripts/verdict_scope.py` (#2167) is `load_verdicts()`'s
|
|
29
|
+
sanctioned reader: before scoping a review dispatch, it consults these rows
|
|
30
|
+
to decide which `(lens, file)` pairs an exact current-content `pass` match
|
|
31
|
+
already clears. See this module's own test
|
|
32
|
+
`test_load_verdicts_has_no_other_consumers` for the mechanical check that
|
|
33
|
+
enforces that boundary.
|
|
34
|
+
|
|
35
|
+
## Trust boundary: the ledger must never travel through version control
|
|
36
|
+
(#2167 security review)
|
|
37
|
+
|
|
38
|
+
Once a `pass` row can suppress a real dispatch, the ledger stops being pure
|
|
39
|
+
telemetry and becomes something a contributor benefits from forging: commit
|
|
40
|
+
a `.claude/metrics/review-verdicts.jsonl` (this repo's `.gitignore` excludes
|
|
41
|
+
`**/metrics/*`, but `git add -f` still works) claiming `security-review`
|
|
42
|
+
already passed a file whose content-hash the contributor can trivially
|
|
43
|
+
compute themselves (they wrote it), and a reviewer who checks out that
|
|
44
|
+
branch and runs `/code-review` never dispatches `security-review` against
|
|
45
|
+
it at all. `load_verdicts()` therefore refuses the file outright — treats it
|
|
46
|
+
exactly like "no ledger" — whenever it is tracked by git in `cwd`'s
|
|
47
|
+
repository (`_ledger_is_git_tracked`). This is the same self-certification
|
|
48
|
+
concern the epic (#2164) names for the PR gate ("a `pass` row must never
|
|
49
|
+
become a self-certification shortcut"), applied here to the ledger's OWN
|
|
50
|
+
provenance rather than to `pre_pr_review.py`'s corroboration. Any git error
|
|
51
|
+
(no `git` on `PATH`, `cwd` isn't a repository, a subprocess failure)
|
|
52
|
+
resolves toward TRUSTING the file, matching every other environment
|
|
53
|
+
assumption this plugin already makes about git being present — this check
|
|
54
|
+
adds a targeted distrust signal, it is not a general "can we run git"
|
|
55
|
+
capability probe.
|
|
56
|
+
|
|
57
|
+
Stdlib only, except for one deliberate `git` subprocess call in
|
|
58
|
+
`_ledger_is_git_tracked` — the read-side analogue of `hooks/lib/
|
|
59
|
+
review_gate_hash.py`'s own git subprocess use elsewhere in this plugin's
|
|
60
|
+
`hooks/lib/`. See ADR 0014 / ADR 0015.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
from __future__ import annotations
|
|
64
|
+
|
|
65
|
+
import hashlib
|
|
66
|
+
import json
|
|
67
|
+
import subprocess
|
|
68
|
+
import sys
|
|
69
|
+
from datetime import datetime, timezone
|
|
70
|
+
from pathlib import Path
|
|
71
|
+
|
|
72
|
+
_LIB_DIR = Path(__file__).resolve().parent
|
|
73
|
+
if str(_LIB_DIR) not in sys.path:
|
|
74
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
75
|
+
|
|
76
|
+
import artifact_paths
|
|
77
|
+
import atomic_state
|
|
78
|
+
import plugin_version
|
|
79
|
+
|
|
80
|
+
_LOG_NAME = "review-verdicts.jsonl"
|
|
81
|
+
|
|
82
|
+
# 50 MiB cap: bounds a content-hash read against a FIFO/device path or a
|
|
83
|
+
# multi-GB file hanging past a fail-open caller's exception wrapper — a hang
|
|
84
|
+
# is not an exception that wrapper can catch. Originally
|
|
85
|
+
# `review_verdict_recorder.py`'s own module-private constant (#2166 Fix #4,
|
|
86
|
+
# security review); promoted here (#2167) so `verdict_scope.py`'s read-side
|
|
87
|
+
# consult hashes files with the exact same algorithm and cap the writer used
|
|
88
|
+
# — two independently-maintained hash implementations could silently drift,
|
|
89
|
+
# making every lookup a guaranteed miss (correct, but wastefully so, and
|
|
90
|
+
# undetectable except by noticing the ledger never skips anything).
|
|
91
|
+
MAX_HASH_FILE_BYTES = 50 * 1024 * 1024
|
|
92
|
+
HASH_CHUNK_BYTES = 1 << 20 # 1 MiB incremental read
|
|
93
|
+
|
|
94
|
+
# The literal text prefix `skills/code-review/SKILL.md` step 4 renders into
|
|
95
|
+
# each per-agent dispatch prompt (`Files in scope for this review: <path>,
|
|
96
|
+
# ...`) and that Step 2.3's SubagentStop verdict recorder parses back out of
|
|
97
|
+
# the transcript. Sharing one constant between the renderer's test (Step 2.1)
|
|
98
|
+
# and the future parser (Step 2.3) keeps the marker format and its parser
|
|
99
|
+
# from silently drifting apart.
|
|
100
|
+
SCOPE_MARKER_PREFIX = "Files in scope for this review: "
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def canonical_path(file_path: str, root) -> str | None:
|
|
104
|
+
"""Resolve `file_path` against `root` to a `root`-relative, symlink-
|
|
105
|
+
resolved POSIX path, or `None` when it can't be resolved or escapes
|
|
106
|
+
`root` (an absolute path elsewhere on disk, a `..` traversal, or a
|
|
107
|
+
broken symlink chain raising `OSError`).
|
|
108
|
+
|
|
109
|
+
The single canonicalization both the writer
|
|
110
|
+
(`hooks/review_verdict_recorder.py`, which stamps each verdict row's
|
|
111
|
+
`file_path`) and the reader (`scripts/verdict_scope.py`, #2167) key the
|
|
112
|
+
ledger on — reported independently by three review lenses (correctness,
|
|
113
|
+
security, arch) as a real drift risk before this was shared: a caller
|
|
114
|
+
passing `./a.py`, an absolute path, or a path relative to a different
|
|
115
|
+
root than the writer used would silently never match a genuine row.
|
|
116
|
+
Failing toward `None` (never dispatch a hash for it) rather than a
|
|
117
|
+
best-effort guess keeps this on the module's existing fail-toward-
|
|
118
|
+
more-work side."""
|
|
119
|
+
try:
|
|
120
|
+
root_resolved = Path(root).resolve()
|
|
121
|
+
target = Path(file_path)
|
|
122
|
+
if not target.is_absolute():
|
|
123
|
+
target = root_resolved / target
|
|
124
|
+
resolved = target.resolve()
|
|
125
|
+
except OSError:
|
|
126
|
+
return None
|
|
127
|
+
if not resolved.is_relative_to(root_resolved):
|
|
128
|
+
return None
|
|
129
|
+
try:
|
|
130
|
+
return resolved.relative_to(root_resolved).as_posix()
|
|
131
|
+
except ValueError:
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def hash_file(path: Path) -> str | None:
|
|
136
|
+
"""Current-content sha256 hex digest of `path`, or `None` on any read
|
|
137
|
+
failure (deleted, unreadable, not a regular file — a directory, FIFO, or
|
|
138
|
+
device — or over `MAX_HASH_FILE_BYTES`).
|
|
139
|
+
|
|
140
|
+
Shared by `hooks/review_verdict_recorder.py` (the writer) and
|
|
141
|
+
`scripts/verdict_scope.py` (the #2167 reader): the writer stamps each
|
|
142
|
+
verdict row's `file_content_hash` with this function, and the reader
|
|
143
|
+
must recompute the SAME hash for the SAME bytes to ever find a match —
|
|
144
|
+
a second, independently-drifting implementation would make every lookup
|
|
145
|
+
silently miss."""
|
|
146
|
+
try:
|
|
147
|
+
if not path.is_file():
|
|
148
|
+
return None
|
|
149
|
+
if path.stat().st_size > MAX_HASH_FILE_BYTES:
|
|
150
|
+
return None
|
|
151
|
+
digest = hashlib.sha256()
|
|
152
|
+
with path.open("rb") as fh:
|
|
153
|
+
while chunk := fh.read(HASH_CHUNK_BYTES):
|
|
154
|
+
digest.update(chunk)
|
|
155
|
+
return digest.hexdigest()
|
|
156
|
+
except OSError:
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _isoformat_utc() -> str:
|
|
161
|
+
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def emit_review_verdict(
|
|
165
|
+
cwd,
|
|
166
|
+
lens: str,
|
|
167
|
+
file_path: str,
|
|
168
|
+
file_content_hash: str,
|
|
169
|
+
outcome: str,
|
|
170
|
+
session_id: str | None = None,
|
|
171
|
+
) -> None:
|
|
172
|
+
"""Append one compact JSON line to
|
|
173
|
+
`<cwd>/.claude/metrics/review-verdicts.jsonl`.
|
|
174
|
+
|
|
175
|
+
Unconditional (Decision 2) — no consent check. Fail-open: any error (bad
|
|
176
|
+
`cwd`, unwritable `.claude/metrics/`, disk full, etc.) is swallowed
|
|
177
|
+
silently, matching `emit_boundary_event`'s own contract.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
cwd: Directory whose `.claude/metrics/` subdirectory receives the
|
|
181
|
+
row. Accepts `str` or `Path`.
|
|
182
|
+
lens: The review agent's name (e.g. "security-review").
|
|
183
|
+
file_path: The in-scope file this verdict is about.
|
|
184
|
+
file_content_hash: Content hash of `file_path` at review time.
|
|
185
|
+
outcome: `"pass"` or `"findings"`.
|
|
186
|
+
session_id: Optional opaque session ID from the hook payload.
|
|
187
|
+
"""
|
|
188
|
+
try:
|
|
189
|
+
base = Path(cwd) if cwd else Path.cwd()
|
|
190
|
+
log = artifact_paths.resolve_file("metrics", _LOG_NAME, base)
|
|
191
|
+
log.parent.mkdir(parents=True, exist_ok=True)
|
|
192
|
+
|
|
193
|
+
payload = {
|
|
194
|
+
"ts": _isoformat_utc(),
|
|
195
|
+
"lens": lens,
|
|
196
|
+
"file_path": file_path,
|
|
197
|
+
"file_content_hash": file_content_hash,
|
|
198
|
+
"outcome": outcome,
|
|
199
|
+
"plugin_version": plugin_version.shipped_version(),
|
|
200
|
+
}
|
|
201
|
+
if session_id:
|
|
202
|
+
payload["session_id"] = session_id
|
|
203
|
+
|
|
204
|
+
line = json.dumps(payload, separators=(",", ":")) + "\n"
|
|
205
|
+
atomic_state.append_line_locked(log, line)
|
|
206
|
+
except Exception: # noqa: BLE001, S110 — fail-open by design, see module docstring
|
|
207
|
+
pass
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _ledger_is_git_tracked(log: Path, base: Path) -> bool:
|
|
211
|
+
"""True only when `log` is CONFIRMED tracked by git in `base`'s
|
|
212
|
+
repository — the one signal a forged, PR-committed ledger row would
|
|
213
|
+
need (see module docstring's "Trust boundary" section). Any inability
|
|
214
|
+
to confirm this either way — no `git` on `PATH`, `base` is not a git
|
|
215
|
+
repository, or any other subprocess failure — returns `False`: an
|
|
216
|
+
environment this check can't reason about is treated as "nothing
|
|
217
|
+
travelled through version control to distrust", not as a reason to
|
|
218
|
+
distrust every local, gitignored ledger that already exists in every
|
|
219
|
+
supported environment today. `--error-unmatch` is git's own "is this
|
|
220
|
+
path tracked" primitive; exit 0 means tracked, any non-zero exit means
|
|
221
|
+
untracked or not-a-repository, and both of those are indistinguishable
|
|
222
|
+
here on purpose — this check only ever needs the positive "yes, tracked"
|
|
223
|
+
signal, never the reason for a negative one."""
|
|
224
|
+
try:
|
|
225
|
+
result = subprocess.run(
|
|
226
|
+
["git", "-C", str(base), "ls-files", "--error-unmatch", "--", str(log)],
|
|
227
|
+
capture_output=True,
|
|
228
|
+
check=False,
|
|
229
|
+
)
|
|
230
|
+
except OSError:
|
|
231
|
+
return False
|
|
232
|
+
return result.returncode == 0
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _version_tuple(version: object) -> tuple[int, ...] | None:
|
|
236
|
+
"""Parse a dotted numeric version string into a comparable tuple, or
|
|
237
|
+
`None` when it isn't one (e.g. the `"unknown"` fallback
|
|
238
|
+
`plugin_version.shipped_version()` can return)."""
|
|
239
|
+
if not isinstance(version, str) or not version:
|
|
240
|
+
return None
|
|
241
|
+
parts: list[int] = []
|
|
242
|
+
for segment in version.split("."):
|
|
243
|
+
if not segment.isdigit():
|
|
244
|
+
return None
|
|
245
|
+
parts.append(int(segment))
|
|
246
|
+
return tuple(parts) if parts else None
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _is_usable_version(row_version: object, current_version: str) -> bool:
|
|
250
|
+
"""A row is usable when its `plugin_version` is the current one, or a
|
|
251
|
+
numerically parseable version no older than it. Anything else — a
|
|
252
|
+
strictly older version, or a value that fails to parse and isn't an
|
|
253
|
+
exact string match — is treated as stale/unusable (fail toward
|
|
254
|
+
excluding, never toward raising)."""
|
|
255
|
+
if row_version == current_version:
|
|
256
|
+
return True
|
|
257
|
+
row_tuple = _version_tuple(row_version)
|
|
258
|
+
current_tuple = _version_tuple(current_version)
|
|
259
|
+
if row_tuple is None or current_tuple is None:
|
|
260
|
+
return False
|
|
261
|
+
return row_tuple >= current_tuple
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def load_verdicts(cwd) -> list[dict]:
|
|
265
|
+
"""Read `<cwd>/.claude/metrics/review-verdicts.jsonl` and return its
|
|
266
|
+
usable rows.
|
|
267
|
+
|
|
268
|
+
"Usable" excludes: an absent file, a git-tracked ledger (see module
|
|
269
|
+
docstring's "Trust boundary" section — treated identically to "no
|
|
270
|
+
ledger"), a line that isn't valid JSON, a line that isn't a JSON object,
|
|
271
|
+
and a row whose `plugin_version` is older than
|
|
272
|
+
`plugin_version.shipped_version()`. Never raises — every failure mode
|
|
273
|
+
degrades to an empty (or partial) list.
|
|
274
|
+
"""
|
|
275
|
+
try:
|
|
276
|
+
base = Path(cwd) if cwd else Path.cwd()
|
|
277
|
+
log = artifact_paths.resolve_file("metrics", _LOG_NAME, base, migrate=False)
|
|
278
|
+
if not log.is_file():
|
|
279
|
+
return []
|
|
280
|
+
if _ledger_is_git_tracked(log, base):
|
|
281
|
+
return []
|
|
282
|
+
text = log.read_text(encoding="utf-8")
|
|
283
|
+
except Exception: # noqa: BLE001 — fail-open by design, see module docstring
|
|
284
|
+
return []
|
|
285
|
+
|
|
286
|
+
current_version = plugin_version.shipped_version()
|
|
287
|
+
rows: list[dict] = []
|
|
288
|
+
for raw_line in text.splitlines():
|
|
289
|
+
raw_line = raw_line.strip()
|
|
290
|
+
if not raw_line:
|
|
291
|
+
continue
|
|
292
|
+
try:
|
|
293
|
+
row = json.loads(raw_line)
|
|
294
|
+
except ValueError:
|
|
295
|
+
continue
|
|
296
|
+
if not isinstance(row, dict):
|
|
297
|
+
continue
|
|
298
|
+
if not _is_usable_version(row.get("plugin_version"), current_version):
|
|
299
|
+
continue
|
|
300
|
+
rows.append(row)
|
|
301
|
+
return rows
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""run_report.py — per-session run report (#1167).
|
|
3
|
+
|
|
4
|
+
Composes one `session_id`'s view across three existing streams:
|
|
5
|
+
`.claude/metrics/boundary-events.jsonl` (denials/bypasses),
|
|
6
|
+
`.claude/metrics/cost-metering.jsonl` (tokens/$), and
|
|
7
|
+
`.claude/metrics/workflow-states.jsonl` (#1166, state dwell times).
|
|
8
|
+
Pure composition of already-deterministic data — no model tokens spent
|
|
9
|
+
parsing transcripts.
|
|
10
|
+
|
|
11
|
+
Join limitation (cost): `cost-metering.jsonl` entries are keyed by transcript
|
|
12
|
+
filename (see `hooks/lib/cost_meter.py::cmd_record()`), not `session_id` — the
|
|
13
|
+
Stop hook that writes it never learns the session ID. There is no reliable
|
|
14
|
+
join key today, so `cost` in the report is explicitly marked `joinable:
|
|
15
|
+
false` rather than guessing an attribution the data doesn't support.
|
|
16
|
+
|
|
17
|
+
Stdlib only. See ADR 0014 / ADR 0015.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import argparse
|
|
23
|
+
import json
|
|
24
|
+
import sys
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
_LIB_DIR = Path(__file__).resolve().parent
|
|
28
|
+
if str(_LIB_DIR) not in sys.path:
|
|
29
|
+
sys.path.insert(0, str(_LIB_DIR))
|
|
30
|
+
|
|
31
|
+
import artifact_paths
|
|
32
|
+
import workflow_state
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _metrics_dir(cwd) -> Path:
|
|
36
|
+
# Read-only composition: a pure path-join, no migration/creation side
|
|
37
|
+
# effects (the three source streams are migrated by their own writers).
|
|
38
|
+
return artifact_paths.metrics_dir(Path(cwd) if cwd else Path.cwd())
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _read_jsonl(path: Path) -> list:
|
|
42
|
+
if not path.is_file():
|
|
43
|
+
return []
|
|
44
|
+
entries = []
|
|
45
|
+
for line in path.read_text(encoding="utf-8").splitlines():
|
|
46
|
+
line = line.strip()
|
|
47
|
+
if not line:
|
|
48
|
+
continue
|
|
49
|
+
try:
|
|
50
|
+
entries.append(json.loads(line))
|
|
51
|
+
except (json.JSONDecodeError, ValueError):
|
|
52
|
+
continue
|
|
53
|
+
return entries
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _most_recent_session_id(cwd) -> str | None:
|
|
57
|
+
"""Most recent `session_id` across boundary-events + workflow-states,
|
|
58
|
+
by event order within each stream (both are append-only chronological
|
|
59
|
+
logs, so the last matching entry is the most recent)."""
|
|
60
|
+
metrics = _metrics_dir(cwd)
|
|
61
|
+
candidates = _read_jsonl(metrics / "boundary-events.jsonl") + _read_jsonl(
|
|
62
|
+
metrics / "workflow-states.jsonl"
|
|
63
|
+
)
|
|
64
|
+
for event in reversed(candidates):
|
|
65
|
+
session_id = event.get("session_id")
|
|
66
|
+
if session_id:
|
|
67
|
+
return session_id
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _boundary_summary(cwd, session_id: str) -> dict:
|
|
72
|
+
metrics = _metrics_dir(cwd)
|
|
73
|
+
events = [
|
|
74
|
+
e
|
|
75
|
+
for e in _read_jsonl(metrics / "boundary-events.jsonl")
|
|
76
|
+
if e.get("session_id") == session_id
|
|
77
|
+
]
|
|
78
|
+
rejection_count = sum(1 for e in events if e.get("decision") == "block")
|
|
79
|
+
bypass_count = sum(1 for e in events if e.get("decision") == "bypass")
|
|
80
|
+
denials_by_cause: dict = {}
|
|
81
|
+
for e in events:
|
|
82
|
+
if e.get("decision") in ("block", "warn"):
|
|
83
|
+
cause = e.get("matched_rule", "unknown")
|
|
84
|
+
denials_by_cause[cause] = denials_by_cause.get(cause, 0) + 1
|
|
85
|
+
return {
|
|
86
|
+
"rejection_count": rejection_count,
|
|
87
|
+
"bypass_count": bypass_count,
|
|
88
|
+
"denials_by_cause": denials_by_cause,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _cost_summary(cwd) -> dict:
|
|
93
|
+
"""Best-effort cost section — see module docstring for why this can't be
|
|
94
|
+
a real per-session join today."""
|
|
95
|
+
metrics = _metrics_dir(cwd)
|
|
96
|
+
entries = _read_jsonl(metrics / "cost-metering.jsonl")
|
|
97
|
+
if not entries:
|
|
98
|
+
return {"joinable": False, "reason": "no cost-metering.jsonl entries recorded"}
|
|
99
|
+
latest = entries[-1]
|
|
100
|
+
return {
|
|
101
|
+
"joinable": False,
|
|
102
|
+
"reason": (
|
|
103
|
+
"cost-metering.jsonl is keyed by transcript filename, not "
|
|
104
|
+
"session_id — no reliable join key exists yet"
|
|
105
|
+
),
|
|
106
|
+
"most_recent_entry": {
|
|
107
|
+
"transcript": latest.get("transcript"),
|
|
108
|
+
"total": latest.get("total"),
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def build_report(cwd, session_id: str | None = None) -> dict:
|
|
114
|
+
if not session_id:
|
|
115
|
+
session_id = _most_recent_session_id(cwd)
|
|
116
|
+
|
|
117
|
+
metrics = _metrics_dir(cwd)
|
|
118
|
+
if session_id:
|
|
119
|
+
transitions = workflow_state._read_transitions(
|
|
120
|
+
metrics / "workflow-states.jsonl", session_id
|
|
121
|
+
)
|
|
122
|
+
boundary = _boundary_summary(cwd, session_id)
|
|
123
|
+
else:
|
|
124
|
+
transitions = []
|
|
125
|
+
boundary = {"rejection_count": 0, "bypass_count": 0, "denials_by_cause": {}}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
"session_id": session_id,
|
|
129
|
+
"current_state": workflow_state.derive_current_state(transitions),
|
|
130
|
+
"dwell_seconds": workflow_state.compute_dwell_times(transitions),
|
|
131
|
+
"rejection_count": boundary["rejection_count"],
|
|
132
|
+
"denials_by_cause": boundary["denials_by_cause"],
|
|
133
|
+
"bypass_count": boundary["bypass_count"],
|
|
134
|
+
"cost": _cost_summary(cwd),
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def cmd_report(args) -> int:
|
|
139
|
+
report = build_report(args.cwd, args.session)
|
|
140
|
+
print(json.dumps(report, indent=2))
|
|
141
|
+
return 0
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def main(argv=None) -> int:
|
|
145
|
+
ap = argparse.ArgumentParser(description=__doc__)
|
|
146
|
+
sub = ap.add_subparsers(dest="command", required=True)
|
|
147
|
+
|
|
148
|
+
p = sub.add_parser(
|
|
149
|
+
"report", help="Join boundary/cost/workflow-state streams for one session."
|
|
150
|
+
)
|
|
151
|
+
p.add_argument("--cwd", default=None)
|
|
152
|
+
p.add_argument("--session", default=None)
|
|
153
|
+
p.set_defaults(func=cmd_report)
|
|
154
|
+
|
|
155
|
+
parsed = ap.parse_args(argv)
|
|
156
|
+
return parsed.func(parsed)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__": # pragma: no cover
|
|
160
|
+
sys.exit(main())
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Capability taxonomy for docs/skills.md.
|
|
2
|
+
#
|
|
3
|
+
# build_skills_index.py groups the skills catalog by these capabilities, in this
|
|
4
|
+
# order. Each skill's row (name, description) is still derived from its own
|
|
5
|
+
# SKILL.md frontmatter — this file only decides *which capability section* it
|
|
6
|
+
# lands in. A skill on disk that is not listed here falls into a trailing
|
|
7
|
+
# "Other" section; the freshness gate then shows it as a diff, prompting you to
|
|
8
|
+
# file it under the right capability and regenerate.
|
|
9
|
+
#
|
|
10
|
+
# Regenerate after editing: bash plugins/dev-team/hooks/lib/build-skills-index.sh
|
|
11
|
+
|
|
12
|
+
categories:
|
|
13
|
+
- name: Specs & Planning
|
|
14
|
+
skills:
|
|
15
|
+
[
|
|
16
|
+
specs,
|
|
17
|
+
plan,
|
|
18
|
+
design-doc,
|
|
19
|
+
design-interrogation,
|
|
20
|
+
design-it-twice,
|
|
21
|
+
api-design,
|
|
22
|
+
gherkin-derive,
|
|
23
|
+
gherkin-public,
|
|
24
|
+
feature-file-validation,
|
|
25
|
+
issues-from-plan,
|
|
26
|
+
issues-from-assessment,
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
- name: Build & Ship
|
|
30
|
+
skills:
|
|
31
|
+
[build, test-driven-development, continue, pr, ship, branch-workflow, autoship]
|
|
32
|
+
|
|
33
|
+
- name: Code Review & Static Analysis
|
|
34
|
+
skills:
|
|
35
|
+
[
|
|
36
|
+
code-review,
|
|
37
|
+
review,
|
|
38
|
+
review-agent,
|
|
39
|
+
review-summary,
|
|
40
|
+
apply-fixes,
|
|
41
|
+
semgrep-analyze,
|
|
42
|
+
semantic-scan,
|
|
43
|
+
semantic-duplication-scan,
|
|
44
|
+
static-analysis-integration,
|
|
45
|
+
frontend-architecture,
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
- name: Testing & Coverage
|
|
49
|
+
skills:
|
|
50
|
+
[
|
|
51
|
+
test-design,
|
|
52
|
+
test-design-advisor,
|
|
53
|
+
test-health,
|
|
54
|
+
test-modernize,
|
|
55
|
+
test-upgrade,
|
|
56
|
+
test-audit-disable,
|
|
57
|
+
mutation-testing,
|
|
58
|
+
farley-score,
|
|
59
|
+
cd-test-architecture,
|
|
60
|
+
apply-test-doubles,
|
|
61
|
+
exploratory-testing,
|
|
62
|
+
explore,
|
|
63
|
+
coverage-baseline,
|
|
64
|
+
coverage-delta,
|
|
65
|
+
quality-targets-converge,
|
|
66
|
+
legacy-code,
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
- name: Security
|
|
70
|
+
skills: [threat-modeling, docker-image-audit, governance-compliance]
|
|
71
|
+
|
|
72
|
+
- name: Architecture & Domain Modeling
|
|
73
|
+
skills:
|
|
74
|
+
[
|
|
75
|
+
domain-driven-design,
|
|
76
|
+
domain-analysis,
|
|
77
|
+
hexagonal-architecture,
|
|
78
|
+
adr-tools,
|
|
79
|
+
ubiquitous-language,
|
|
80
|
+
mermaid-diagramming,
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
- name: Performance, Containers & Browser
|
|
84
|
+
skills:
|
|
85
|
+
[
|
|
86
|
+
docker-image-create,
|
|
87
|
+
benchmark,
|
|
88
|
+
performance-benchmark,
|
|
89
|
+
browse,
|
|
90
|
+
browser-testing,
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
- name: Debugging & Diagnostics
|
|
94
|
+
skills: [systematic-debugging, ci-debugging, triage, fix]
|
|
95
|
+
|
|
96
|
+
- name: Setup, Config & Plugin Management
|
|
97
|
+
skills: [setup, project-init, upgrade, version, help]
|
|
98
|
+
|
|
99
|
+
- name: Session, Context & Telemetry
|
|
100
|
+
skills:
|
|
101
|
+
[
|
|
102
|
+
context-loading-protocol,
|
|
103
|
+
handoff,
|
|
104
|
+
session-review,
|
|
105
|
+
telemetry,
|
|
106
|
+
cost-report,
|
|
107
|
+
artifact-lifecycle,
|
|
108
|
+
performance-metrics,
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
- name: Safety Modes
|
|
112
|
+
skills: [careful, freeze, unfreeze, guard]
|
|
113
|
+
|
|
114
|
+
- name: Harness Governance & Tuning
|
|
115
|
+
skills:
|
|
116
|
+
[
|
|
117
|
+
agent-audit,
|
|
118
|
+
agent-eval,
|
|
119
|
+
harness-audit,
|
|
120
|
+
agent-readiness,
|
|
121
|
+
competitive-analysis,
|
|
122
|
+
feedback-learning,
|
|
123
|
+
human-oversight-protocol,
|
|
124
|
+
quality-gate-pipeline,
|
|
125
|
+
]
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""stdin_json — single source of truth for the stdin-JSON-read helper.
|
|
2
|
+
|
|
3
|
+
Every Claude Code hook receives its payload as JSON on stdin. Seven hooks
|
|
4
|
+
(pre_commit_review.py, pre_commit_knowledge_index.py, knowledge_index.py,
|
|
5
|
+
mutation_testing_smoke_gate.py, code_intelligence_nudge.py, codegraph_bootstrap.py,
|
|
6
|
+
bash_retry_guard.py) each carried an identical copy of this read/parse/
|
|
7
|
+
validate step (#732). This module is the shared extraction. Also adopted by
|
|
8
|
+
several more hooks (code_intelligence_turn_mark.py,
|
|
9
|
+
contract_version_guard.py, cost_meter.py, destructive_guard.py,
|
|
10
|
+
eval_compliance_check.py, js_fp_review.py, task_completion_metrics.py) whose
|
|
11
|
+
own copies had drifted back in independently of the #732 migration.
|
|
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 pathlib import Path
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def read_stdin_json() -> dict | None:
|
|
25
|
+
"""Read stdin, parse as JSON, return the dict on success.
|
|
26
|
+
|
|
27
|
+
Returns None on:
|
|
28
|
+
- an OSError while reading stdin
|
|
29
|
+
- empty/whitespace-only input
|
|
30
|
+
- malformed JSON
|
|
31
|
+
- valid JSON that is not a dict (e.g. a list or scalar)
|
|
32
|
+
"""
|
|
33
|
+
try:
|
|
34
|
+
raw = sys.stdin.read()
|
|
35
|
+
except OSError:
|
|
36
|
+
return None
|
|
37
|
+
if not raw.strip():
|
|
38
|
+
return None
|
|
39
|
+
try:
|
|
40
|
+
parsed = json.loads(raw)
|
|
41
|
+
except json.JSONDecodeError:
|
|
42
|
+
return None
|
|
43
|
+
return parsed if isinstance(parsed, dict) else None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def resolve_cwd(payload: dict) -> str:
|
|
47
|
+
"""Return the hook payload's ``cwd`` if it names a real directory, else
|
|
48
|
+
the process's own working directory.
|
|
49
|
+
|
|
50
|
+
Previously copy-pasted verbatim in mcp_json_repowise_nudge.py,
|
|
51
|
+
repo_review_nudge.py, and pending_review_notify.py, alongside their own
|
|
52
|
+
(also copy-pasted) stdin-read preamble — now just `read_stdin_json()`.
|
|
53
|
+
"""
|
|
54
|
+
cwd = payload.get("cwd") or ""
|
|
55
|
+
if not isinstance(cwd, str) or not cwd or not Path(cwd).is_dir():
|
|
56
|
+
return os.getcwd()
|
|
57
|
+
return cwd
|