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,231 @@
|
|
|
1
|
+
"""Text/name classification vocabulary shared by both session-log
|
|
2
|
+
extractors (issue #2043, epic #2040) — the "shared classification core" ADR
|
|
3
|
+
0036 deliberately left as an open question, decided here.
|
|
4
|
+
|
|
5
|
+
ADR 0036 / issue #2043's own symbol list names 14 symbols. Two of them —
|
|
6
|
+
`_is_transcript_path` / `_is_subagent_transcript` — already landed in
|
|
7
|
+
`session_log.discovery` in slice #2042, because they are used only by
|
|
8
|
+
enumeration/path logic that belongs there; this module does not duplicate
|
|
9
|
+
them (grouping them under classify.py in the ADR's original text predates
|
|
10
|
+
that split). `_AGENT_TRANSCRIPT_RE` is the same story: it's used only inside
|
|
11
|
+
`discovery.is_transcript_path`, so it also lives in `discovery.py`, not
|
|
12
|
+
here. That leaves 12 symbols for this module, reconciled below.
|
|
13
|
+
|
|
14
|
+
Per-symbol reconciliation (measured by diffing the two forked copies
|
|
15
|
+
directly against the live tree, not from memory):
|
|
16
|
+
|
|
17
|
+
| symbol | similarity | chosen behavior / source |
|
|
18
|
+
|----------------------------|-----------|--------------------------------------------------------------|
|
|
19
|
+
| `_VERIFY_RE` | 1.00 | byte-identical constant — moved verbatim |
|
|
20
|
+
| `_CORRECTION_RE` | 1.00 | byte-identical constant — moved verbatim |
|
|
21
|
+
| `_PERMISSION_RE` | 1.00 | byte-identical constant — moved verbatim |
|
|
22
|
+
| `_OLDSTRING_RE` | 1.00 | byte-identical constant — moved verbatim |
|
|
23
|
+
| `_COMMIT_RE`/`_BYPASS_RE` | 1.00 | ADR 0036 names these two regexes; neither exists as a literal|
|
|
24
|
+
| | | symbol in the current tree (#2036 replaced a regex-based |
|
|
25
|
+
| | | commit/bypass detector with an argv-shaped one — the same |
|
|
26
|
+
| | | staleness class as the `_is_transcript_path` note above). The|
|
|
27
|
+
| | | modern equivalent — `_statement_break_newlines`, |
|
|
28
|
+
| | | `_bash_segments`, `_is_git_commit_argv`, |
|
|
29
|
+
| | | `_GIT_GLOBAL_OPTS_WITH_ARG`, `_COMMIT_BYPASS_TOKENS` — is |
|
|
30
|
+
| | | byte-identical between the two copies (confirmed by direct |
|
|
31
|
+
| | | diff) and lands here instead, under its current names. |
|
|
32
|
+
| `_strip_ns` | ~1.00 | logic identical; session_extract.py's docstring kept (more |
|
|
33
|
+
| | | detailed — extract_session_report.py's copy had none) |
|
|
34
|
+
| `_text_of` | 0.98 | logic identical; docstring wording merged (session_extract's |
|
|
35
|
+
| | | "digest" -> generic "output", correct for both callers) |
|
|
36
|
+
| `_safe_name` | 1.00 | byte-identical — moved verbatim, with its `_SAFE_NAME_RE`/ |
|
|
37
|
+
| | | `_UNSAFE_NAME` dependencies |
|
|
38
|
+
| `_basename` | logic | **the highest-stakes symbol**: ADR 0036 / issue #2043 flags |
|
|
39
|
+
| | 1.00, | this as carrying #1991's Windows-path privacy fix that the |
|
|
40
|
+
| | docstring | #1994 port allegedly dropped. Direct diff of the CURRENT tree |
|
|
41
|
+
| | differs | (not git archaeology) shows both copies already compute |
|
|
42
|
+
| | | `re.split(r"[\\/]", path_str)[-1] or path_str` — identical |
|
|
43
|
+
| | | logic, byte-identical behavior. The historical gap was closed |
|
|
44
|
+
| | | in a later commit (subagent-transcript-count fixes #1995/ |
|
|
45
|
+
| | | #2017) before this refactor started. session_extract.py's |
|
|
46
|
+
| | | docstring (which names the #1994 history) is kept as the |
|
|
47
|
+
| | | canonical one; pinned by the corpus's Windows-path fixture |
|
|
48
|
+
| | | (`C:\\Users\\SENTINEL_USER\\...` in |
|
|
49
|
+
| | | `tests/fixtures/session_log/projects/.../99999999….jsonl`) |
|
|
50
|
+
| | | via the golden harness AND this module's own unit test. |
|
|
51
|
+
| `_AGENT_TRANSCRIPT_RE` | n/a | already unified in `discovery.py` (#2042) — not duplicated |
|
|
52
|
+
| | | here; see module docstring above |
|
|
53
|
+
| `_HARNESS_ATTRIBUTIONS` | 1.00 | byte-identical constant — moved verbatim |
|
|
54
|
+
|
|
55
|
+
Golden diffs: none. This slice is behavior-preserving, same as #2042 — every
|
|
56
|
+
moved symbol is either byte-identical or logic-identical between the two
|
|
57
|
+
forked copies, so the golden harness stays byte-for-byte unchanged (verified
|
|
58
|
+
below in the test suite).
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
from __future__ import annotations
|
|
62
|
+
|
|
63
|
+
import re
|
|
64
|
+
import shlex
|
|
65
|
+
|
|
66
|
+
# --- verification / classification vocabularies (counted, never emitted) ---
|
|
67
|
+
VERIFY_RE = re.compile(
|
|
68
|
+
r"\b(npm (run )?(test|lint|build)|pytest|bats|eslint|tsc|go test|cargo "
|
|
69
|
+
r"(test|build)|mvn|gradle|make( |$)|vitest|jest|ruff|mypy|shellcheck)\b"
|
|
70
|
+
)
|
|
71
|
+
CORRECTION_RE = re.compile(
|
|
72
|
+
r"\b(no|actually|revert|undo|not what i (asked|wanted)|that's wrong|"
|
|
73
|
+
r"that is wrong|wrong|stop|don't|do not)\b"
|
|
74
|
+
)
|
|
75
|
+
PERMISSION_RE = re.compile(r"permission|denied|not allowed|blocked by", re.IGNORECASE)
|
|
76
|
+
OLDSTRING_RE = re.compile(r"old_string|not found|no match|string to replace", re.IGNORECASE)
|
|
77
|
+
|
|
78
|
+
# Gate signal (#111): a `git commit`, and whether it bypassed the pre-commit
|
|
79
|
+
# review gate (--no-verify, or a bare -n). #2036: the review-corroboration
|
|
80
|
+
# gate itself moved from `git commit` time to `gh pr create` time in #1886 —
|
|
81
|
+
# `hooks/telemetry.py` now keys its bypass signal off `PR_GATE_BYPASS_REASON`
|
|
82
|
+
# on a `gh pr create` invocation, an unrelated mechanism this no longer
|
|
83
|
+
# mirrors. This signal stays commit-time on purpose: it measures how often a
|
|
84
|
+
# commit itself skips local review, which is a real and different question
|
|
85
|
+
# from whether a PR was opened without one.
|
|
86
|
+
#
|
|
87
|
+
# Detection is argv-shaped, not a substring search over the whole command —
|
|
88
|
+
# see bash_segments()/is_git_commit_argv() below. A prior version searched
|
|
89
|
+
# `\bgit\s+commit\b` and `--no-verify|(^|\s)-n(\s|$)` against the raw string,
|
|
90
|
+
# which matched inside unrelated flags in a compound command (`grep -n`,
|
|
91
|
+
# `ls -n`) and even inside an unrelated string (`echo "git commit"`).
|
|
92
|
+
GIT_GLOBAL_OPTS_WITH_ARG = {"-C", "-c", "--git-dir", "--work-tree", "--namespace"}
|
|
93
|
+
COMMIT_BYPASS_TOKENS = {"--no-verify", "-n"}
|
|
94
|
+
|
|
95
|
+
# Every string that becomes a digest/report KEY passes safe_name: these
|
|
96
|
+
# arrive from transcript files this code does not author, and the privacy
|
|
97
|
+
# contract of both extractors is names-only.
|
|
98
|
+
SAFE_NAME_RE = re.compile(r"^[A-Za-z0-9._:-]{1,64}$")
|
|
99
|
+
UNSAFE_NAME = "other"
|
|
100
|
+
|
|
101
|
+
# `attributionAgent` values naming a harness ROLE rather than an agent. Every
|
|
102
|
+
# real Workflow-dispatched transcript carries "workflow-subagent"; unfiltered
|
|
103
|
+
# they become phantom agents while the agent that actually ran stays in
|
|
104
|
+
# never_observed_agents — the #1990 symptom itself.
|
|
105
|
+
HARNESS_ATTRIBUTIONS = frozenset({"workflow-subagent", "claude"})
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def statement_break_newlines(cmd: str) -> str:
|
|
109
|
+
"""Replace a bare (unquoted) newline with ';' so a tokenizer sees a
|
|
110
|
+
statement boundary there — a newline embedded inside a quoted argument
|
|
111
|
+
(e.g. a multi-line commit message) is left untouched."""
|
|
112
|
+
out = []
|
|
113
|
+
in_single = in_double = False
|
|
114
|
+
i, n = 0, len(cmd)
|
|
115
|
+
while i < n:
|
|
116
|
+
ch = cmd[i]
|
|
117
|
+
if ch == "'" and not in_double:
|
|
118
|
+
in_single = not in_single
|
|
119
|
+
out.append(ch)
|
|
120
|
+
elif ch == '"' and not in_single:
|
|
121
|
+
in_double = not in_double
|
|
122
|
+
out.append(ch)
|
|
123
|
+
elif ch == "\\" and in_double and i + 1 < n:
|
|
124
|
+
out.append(ch)
|
|
125
|
+
out.append(cmd[i + 1])
|
|
126
|
+
i += 1
|
|
127
|
+
elif ch == "\n" and not in_single and not in_double:
|
|
128
|
+
out.append(";")
|
|
129
|
+
else:
|
|
130
|
+
out.append(ch)
|
|
131
|
+
i += 1
|
|
132
|
+
return "".join(out)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def bash_segments(cmd: str) -> list[list[str]]:
|
|
136
|
+
"""Split `cmd` into argv-shaped segments at top-level shell operators
|
|
137
|
+
(&&, ||, ;, |, and bare newlines), respecting quoting throughout — a
|
|
138
|
+
quoted operator or newline inside a commit message never splits the
|
|
139
|
+
command, and a quoted flag never crosses a segment boundary."""
|
|
140
|
+
lex = shlex.shlex(statement_break_newlines(cmd), posix=True, punctuation_chars="&|;")
|
|
141
|
+
lex.whitespace_split = True
|
|
142
|
+
try:
|
|
143
|
+
tokens = list(lex)
|
|
144
|
+
except ValueError:
|
|
145
|
+
# Malformed shell syntax (e.g. an unbalanced quote) — cannot be
|
|
146
|
+
# segmented reliably. Fall back to a single opaque whitespace-split
|
|
147
|
+
# segment rather than losing the signal outright.
|
|
148
|
+
return [cmd.split()]
|
|
149
|
+
segments: list[list[str]] = []
|
|
150
|
+
current: list[str] = []
|
|
151
|
+
for tok in tokens:
|
|
152
|
+
if tok in ("&&", "||", ";", "|", "&"):
|
|
153
|
+
if current:
|
|
154
|
+
segments.append(current)
|
|
155
|
+
current = []
|
|
156
|
+
else:
|
|
157
|
+
current.append(tok)
|
|
158
|
+
if current:
|
|
159
|
+
segments.append(current)
|
|
160
|
+
return segments
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def is_git_commit_argv(tokens: list[str]) -> bool:
|
|
164
|
+
"""True if `tokens` invokes `git ... commit ...` — walks past git's
|
|
165
|
+
global options (including ones taking a separate argument, e.g. `-C`)
|
|
166
|
+
to find the subcommand, so `git -C path commit` is recognized."""
|
|
167
|
+
if not tokens or tokens[0] != "git":
|
|
168
|
+
return False
|
|
169
|
+
i = 1
|
|
170
|
+
while i < len(tokens):
|
|
171
|
+
tok = tokens[i]
|
|
172
|
+
if tok in GIT_GLOBAL_OPTS_WITH_ARG:
|
|
173
|
+
i += 2
|
|
174
|
+
continue
|
|
175
|
+
if tok.startswith("-"):
|
|
176
|
+
i += 1
|
|
177
|
+
continue
|
|
178
|
+
return tok == "commit"
|
|
179
|
+
return False
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def strip_ns(name: str) -> str:
|
|
183
|
+
"""Drop known plugin namespace prefixes so invoked names match the
|
|
184
|
+
registry (registry entries are bare dir/file stems). `dev-team:plan` ->
|
|
185
|
+
`plan`; `agentic-dev-team:plan` -> `plan`; other names pass through."""
|
|
186
|
+
for prefix in ("agentic-dev-team:", "dev-team:"):
|
|
187
|
+
if name.startswith(prefix):
|
|
188
|
+
return name[len(prefix) :]
|
|
189
|
+
return name
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def text_of(content) -> str:
|
|
193
|
+
"""Flatten a message ``content`` (str or list of blocks) to plain text.
|
|
194
|
+
Used only for keyword CLASSIFICATION; never emitted into either
|
|
195
|
+
extractor's output."""
|
|
196
|
+
if isinstance(content, str):
|
|
197
|
+
return content
|
|
198
|
+
if isinstance(content, list):
|
|
199
|
+
parts = []
|
|
200
|
+
for block in content:
|
|
201
|
+
if isinstance(block, dict):
|
|
202
|
+
if isinstance(block.get("text"), str):
|
|
203
|
+
parts.append(block["text"])
|
|
204
|
+
elif isinstance(block.get("content"), str):
|
|
205
|
+
parts.append(block["content"])
|
|
206
|
+
return " ".join(parts)
|
|
207
|
+
return ""
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def safe_name(value: str) -> str:
|
|
211
|
+
"""Reduce an input-derived string to something safe to emit as a key."""
|
|
212
|
+
# fullmatch, not match: `$` also matches immediately BEFORE a single
|
|
213
|
+
# trailing newline, so `.match()` admitted "name\n" through the allowlist
|
|
214
|
+
# and split the key space (#1994 review).
|
|
215
|
+
return value if SAFE_NAME_RE.fullmatch(value) else UNSAFE_NAME
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def basename(path_str: str) -> str:
|
|
219
|
+
"""Last component of a path recorded on ANY platform.
|
|
220
|
+
|
|
221
|
+
`os.path.basename` splits on `/` only, so a Windows-form path comes back
|
|
222
|
+
whole — an absolute path, username included, in a field both extractors'
|
|
223
|
+
docstrings promise is a basename. Reachable whenever Windows-written
|
|
224
|
+
transcripts are read under WSL, a devcontainer, or a bind-mounted
|
|
225
|
+
`~/.claude`. #1991 fixed this in the shipped extractor first; #1994's
|
|
226
|
+
port to session_extract.py initially left it behind (the same defect
|
|
227
|
+
class crossing the fork twice) but a later fix closed the gap — both
|
|
228
|
+
copies compute the same `re.split` before this module unified them (see
|
|
229
|
+
module docstring's reconciliation table).
|
|
230
|
+
"""
|
|
231
|
+
return re.split(r"[\\/]", path_str)[-1] or path_str
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Deterministic cause-data classification for correction turns (issue
|
|
2
|
+
#2013, part of epic #2008).
|
|
3
|
+
|
|
4
|
+
The corpus carries thousands of user corrections and no cause data: a
|
|
5
|
+
correction is the most direct signal the harness did the wrong thing, and
|
|
6
|
+
until now it was recorded as a bare count. This module attaches three
|
|
7
|
+
closed-vocabulary labels to each correction turn `signals.
|
|
8
|
+
detect_correction_turn` already detects:
|
|
9
|
+
|
|
10
|
+
what what kind of output was corrected -- `WHAT_VALUES` below.
|
|
11
|
+
component which component produced it -- `"main-loop"` or a specific
|
|
12
|
+
agent/skill name.
|
|
13
|
+
shape what kind of correction it was -- `SHAPE_VALUES` below.
|
|
14
|
+
|
|
15
|
+
Deterministic-first (CLAUDE.md's "deterministic tools over inference"
|
|
16
|
+
rule, and this issue's own "must be cheap" constraint): every label comes
|
|
17
|
+
from pattern-matching over tool-call shape and correction-turn keywords,
|
|
18
|
+
the same style `classify.CORRECTION_RE` already uses to DETECT a
|
|
19
|
+
correction turn in the first place. No model call is ever made here. When
|
|
20
|
+
`shape` can't be resolved confidently, it's reported as `"ambiguous"`
|
|
21
|
+
with `confidence: "low"` rather than guessed -- the inference share is a
|
|
22
|
+
queryable statistic (`accuracy.correction_causes.ambiguous_share` in
|
|
23
|
+
`session_report.py`), never hidden.
|
|
24
|
+
|
|
25
|
+
Privacy: only the four labels below are ever emitted to a digest. The
|
|
26
|
+
correction TEXT (`classify_shape`'s `text` argument) is read in memory
|
|
27
|
+
only, exactly like `classify.CORRECTION_RE`'s own detection pass -- never
|
|
28
|
+
written to output. See `redact.py`'s module docstring for the choke-point
|
|
29
|
+
this stays inside; this module composes on top of it, it does not open a
|
|
30
|
+
new privacy surface.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
import re
|
|
36
|
+
|
|
37
|
+
from . import classify
|
|
38
|
+
from .signals import EDIT_TOOLS
|
|
39
|
+
|
|
40
|
+
#: what-was-corrected vocabulary (issue #2013).
|
|
41
|
+
WHAT_VALUES = (
|
|
42
|
+
"code-edit",
|
|
43
|
+
"plan",
|
|
44
|
+
"review-finding",
|
|
45
|
+
"tool-choice",
|
|
46
|
+
"factual-claim",
|
|
47
|
+
"other",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
#: correction-shape vocabulary (issue #2013). "ambiguous" is the honest
|
|
51
|
+
#: fallback when no shape pattern below matches -- see module docstring.
|
|
52
|
+
SHAPE_VALUES = (
|
|
53
|
+
"reverted",
|
|
54
|
+
"redirected",
|
|
55
|
+
"narrowed-scope",
|
|
56
|
+
"flagged-wrong",
|
|
57
|
+
"not-what-asked",
|
|
58
|
+
"ambiguous",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
#: `component` value when no skill/agent is the currently-active dispatch
|
|
62
|
+
#: (`signals.accumulate_skill_agent_signals`'s `active["last"]`, `None`).
|
|
63
|
+
MAIN_LOOP_LABEL = "main-loop"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def is_review_agent_name(name: str | None) -> bool:
|
|
67
|
+
"""Whether a (already namespace-stripped) agent name follows this
|
|
68
|
+
repo's own review-agent naming convention: `<domain>-review`,
|
|
69
|
+
`<domain>-reviewer` (`quality-reviewer`, `spec-reviewer`), or
|
|
70
|
+
`plan-review-<facet>` (`plan-review-acceptance`, ...). Checked against
|
|
71
|
+
every review agent under `plugins/dev-team/agents/` at the time this
|
|
72
|
+
was written -- a naming-convention check, not a registry lookup, so it
|
|
73
|
+
needs no registry threaded through the classifier."""
|
|
74
|
+
if not name:
|
|
75
|
+
return False
|
|
76
|
+
return name.endswith(("-review", "-reviewer")) or name.startswith("plan-review-")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def new_context() -> dict:
|
|
80
|
+
"""Per-thread rolling "what" state. `what` is `None` until the first
|
|
81
|
+
assistant turn is observed (`classify_correction` falls back to
|
|
82
|
+
`"other"` for a correction with no preceding assistant turn at all --
|
|
83
|
+
a real, if unusual, transcript shape, not a guess). Reset once per
|
|
84
|
+
transcript file, same lifecycle as `signals.new_thread()`."""
|
|
85
|
+
return {"what": None}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def observe_assistant_turn(rec: dict, content) -> dict | None:
|
|
89
|
+
"""Recompute the rolling "what" context from ONE assistant record.
|
|
90
|
+
|
|
91
|
+
Returns `None` for a non-assistant record -- the caller should keep
|
|
92
|
+
its existing context unchanged, since `detect_correction_turn` only
|
|
93
|
+
ever fires on a `"user"` record and "what" answers "what did the
|
|
94
|
+
IMMEDIATELY PRECEDING assistant turn do" (issue #2013's own framing).
|
|
95
|
+
This is why the result REPLACES the context wholesale rather than
|
|
96
|
+
updating it in place, unlike the sticky `active` skill/agent pointer
|
|
97
|
+
`component` is built from below: a later text-only turn must
|
|
98
|
+
overwrite an earlier tool call's classification, not merely
|
|
99
|
+
supplement it.
|
|
100
|
+
"""
|
|
101
|
+
if rec.get("type") != "assistant":
|
|
102
|
+
return None
|
|
103
|
+
if not isinstance(content, list):
|
|
104
|
+
has_text = isinstance(content, str) and bool(content.strip())
|
|
105
|
+
return {"what": "factual-claim" if has_text else "other"}
|
|
106
|
+
|
|
107
|
+
candidates: set[str] = set()
|
|
108
|
+
saw_tool_use = False
|
|
109
|
+
for block in content:
|
|
110
|
+
if not isinstance(block, dict) or block.get("type") != "tool_use":
|
|
111
|
+
continue
|
|
112
|
+
saw_tool_use = True
|
|
113
|
+
name = block.get("name", "?")
|
|
114
|
+
inp = block.get("input", {}) if isinstance(block.get("input"), dict) else {}
|
|
115
|
+
if name in EDIT_TOOLS:
|
|
116
|
+
candidates.add("code-edit")
|
|
117
|
+
elif name == "Skill":
|
|
118
|
+
skill_name = classify.strip_ns(str(inp.get("skill") or inp.get("name") or ""))
|
|
119
|
+
if skill_name == "plan":
|
|
120
|
+
candidates.add("plan")
|
|
121
|
+
elif name in ("Agent", "Task"):
|
|
122
|
+
agent_name = classify.strip_ns(str(inp.get("subagent_type") or ""))
|
|
123
|
+
if is_review_agent_name(agent_name):
|
|
124
|
+
candidates.add("review-finding")
|
|
125
|
+
elif name == "Bash":
|
|
126
|
+
candidates.add("tool-choice")
|
|
127
|
+
|
|
128
|
+
if not saw_tool_use:
|
|
129
|
+
return {"what": "factual-claim"}
|
|
130
|
+
for label in ("code-edit", "plan", "review-finding", "tool-choice"):
|
|
131
|
+
if label in candidates:
|
|
132
|
+
return {"what": label}
|
|
133
|
+
return {"what": "other"}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
# Priority-ordered, most-specific-first: the FIRST pattern that matches the
|
|
137
|
+
# correction turn's own (lowercased) text wins. Every alternative here is a
|
|
138
|
+
# refinement of `classify.CORRECTION_RE`'s own keyword set (the same
|
|
139
|
+
# keyword-matching approach that already detects a correction turn), not a
|
|
140
|
+
# new detection mechanism -- a correction turn that matched CORRECTION_RE
|
|
141
|
+
# only via its bare "no" alternative (no "wrong"/"actually"/"revert"/...
|
|
142
|
+
# alongside it) matches none of these and correctly falls through to
|
|
143
|
+
# "ambiguous": that's a real, non-trivial subset of correction turns whose
|
|
144
|
+
# shape genuinely can't be told apart by keyword alone.
|
|
145
|
+
_SHAPE_PATTERNS: tuple[tuple[str, re.Pattern], ...] = (
|
|
146
|
+
("reverted", re.compile(r"\b(revert|undo|roll\s*back|put\s+(it\s+)?back)\b")),
|
|
147
|
+
("not-what-asked", re.compile(r"not what i (asked|wanted|meant)")),
|
|
148
|
+
("flagged-wrong", re.compile(r"\b(that'?s wrong|that is wrong|incorrect|wrong)\b")),
|
|
149
|
+
(
|
|
150
|
+
"narrowed-scope",
|
|
151
|
+
re.compile(
|
|
152
|
+
r"\b(just|only|too (much|broad|big)|narrow(er)?|smaller scope|"
|
|
153
|
+
r"don'?t need|no need)\b"
|
|
154
|
+
),
|
|
155
|
+
),
|
|
156
|
+
("redirected", re.compile(r"\b(actually|instead|rather|stop|don'?t|do not)\b")),
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def classify_shape(text: str) -> tuple[str, str]:
|
|
161
|
+
"""Correction SHAPE from the correction turn's own text (read in
|
|
162
|
+
memory only -- see module docstring). Returns `(shape, confidence)`;
|
|
163
|
+
`confidence` is `"low"` exactly when `shape == "ambiguous"` -- shape is
|
|
164
|
+
the one genuinely fuzzy dimension of this classifier (`what` and
|
|
165
|
+
`component` are read off structural facts -- tool names, dispatch
|
|
166
|
+
state -- not inferred from text, so they carry no comparable
|
|
167
|
+
ambiguity)."""
|
|
168
|
+
lowered = text.lower()
|
|
169
|
+
for label, pattern in _SHAPE_PATTERNS:
|
|
170
|
+
if pattern.search(lowered):
|
|
171
|
+
return label, "high"
|
|
172
|
+
return "ambiguous", "low"
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def classify_correction(turn_context: dict, dispatch: tuple[str, str] | None, text: str) -> dict:
|
|
176
|
+
"""The full cause-data record for one correction turn.
|
|
177
|
+
|
|
178
|
+
`turn_context`: the rolling "what" state (`new_context`/
|
|
179
|
+
`observe_assistant_turn`'s last non-`None` result).
|
|
180
|
+
`dispatch`: the currently-active `(kind, name)` skill/agent dispatch
|
|
181
|
+
(`signals.accumulate_skill_agent_signals`'s `active["last"]`), or
|
|
182
|
+
`None` when nothing has been dispatched yet in this thread.
|
|
183
|
+
`text`: the correction turn's own flattened text
|
|
184
|
+
(`classify.text_of(content)`) -- read in memory only, never returned.
|
|
185
|
+
|
|
186
|
+
Returns `{"what", "component", "shape", "confidence"}` -- the only
|
|
187
|
+
four values a caller should emit; never the raw text, dispatch name
|
|
188
|
+
provenance details, or tool-call sequence itself beyond what these
|
|
189
|
+
four labels already encode.
|
|
190
|
+
"""
|
|
191
|
+
what = (turn_context or {}).get("what") or "other"
|
|
192
|
+
component = dispatch[1] if dispatch else MAIN_LOOP_LABEL
|
|
193
|
+
shape, confidence = classify_shape(text)
|
|
194
|
+
return {"what": what, "component": component, "shape": shape, "confidence": confidence}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Transcript path classification and enumeration (issue #2042, epic #2040).
|
|
2
|
+
|
|
3
|
+
Answers one question: given a ``~/.claude/projects``-shaped tree, which
|
|
4
|
+
``.jsonl`` files under it are transcripts this extraction pipeline reads, and
|
|
5
|
+
which of those belong to a dispatched agent's own run rather than a
|
|
6
|
+
main-thread session.
|
|
7
|
+
|
|
8
|
+
Reconciliation (issue #2042):
|
|
9
|
+
|
|
10
|
+
- ``is_transcript_path`` was already byte-identical between
|
|
11
|
+
``scripts/session_extract.py`` and
|
|
12
|
+
``plugins/dev-team/scripts/extract_session_report.py`` — moved verbatim.
|
|
13
|
+
- ``is_subagent_transcript`` was semantically equivalent but structurally
|
|
14
|
+
divergent (0.22 similarity between the two copies). This module keeps the
|
|
15
|
+
shipped (``extract_session_report.py``) copy's shape: it factors out
|
|
16
|
+
``relative_parts`` — the path's components below the root, with a
|
|
17
|
+
``path.parts`` (not ``False``) fallback when the path isn't actually under
|
|
18
|
+
the root — and both original bodies computed exactly
|
|
19
|
+
``"subagents" in <that>``, so behavior is unchanged.
|
|
20
|
+
- ``_AGENT_TRANSCRIPT_RE`` is grouped under the classify.py 14-symbol list in
|
|
21
|
+
ADR 0036 / issue #2043, but it is used ONLY inside ``is_transcript_path``
|
|
22
|
+
above, which landed here in slice #2042 — so it lands here too rather than
|
|
23
|
+
being duplicated into classify.py. Issue #2043's commit body notes this
|
|
24
|
+
explicitly rather than silently deviating from the ADR's grouping.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from __future__ import annotations
|
|
28
|
+
|
|
29
|
+
import re
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
|
|
32
|
+
# Agent transcripts are named `agent-<id>.jsonl` (see is_transcript_path).
|
|
33
|
+
AGENT_TRANSCRIPT_RE = re.compile(r"^agent-[0-9A-Za-z_-]{1,64}\.jsonl$")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def relative_parts(root: Path, path: Path) -> tuple[str, ...]:
|
|
37
|
+
"""The path's components BELOW `root`.
|
|
38
|
+
|
|
39
|
+
Every layout question here is about the tree under the root, so never ask
|
|
40
|
+
it of the absolute path: `root` defaults to `~/.claude/projects` and
|
|
41
|
+
carries the user's home directory, so a matching segment anywhere in that
|
|
42
|
+
prefix would answer for the whole tree."""
|
|
43
|
+
try:
|
|
44
|
+
return path.relative_to(root).parts
|
|
45
|
+
except ValueError:
|
|
46
|
+
return path.parts
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def is_transcript_path(root: Path, path: Path) -> bool:
|
|
50
|
+
"""Whether a `.jsonl` under `root` is a transcript this extractor reads.
|
|
51
|
+
|
|
52
|
+
Decided by DEPTH, not by filename shape. A `.jsonl` sitting directly in a
|
|
53
|
+
project directory is a main-thread session whatever it is called — the
|
|
54
|
+
harness uses `<sessionId>.jsonl`, but nothing guarantees that and a
|
|
55
|
+
name-shape filter silently drops any session that differs, which is a
|
|
56
|
+
worse failure than the one it prevents.
|
|
57
|
+
|
|
58
|
+
Below `subagents/` the rule tightens, because that is the only place the
|
|
59
|
+
harness writes NON-transcript bookkeeping next to transcripts:
|
|
60
|
+
`subagents/workflows/<runId>/journal.jsonl` holds `{"type", "key",
|
|
61
|
+
"agentId"}` records with no `cwd`. Counting it as an agent run inflated the
|
|
62
|
+
run tally and, having no `cwd`, sent project labelling down a fallback that
|
|
63
|
+
leaked a path-derived slug (#1991). Agent transcripts are `agent-<id>.jsonl`.
|
|
64
|
+
"""
|
|
65
|
+
try:
|
|
66
|
+
parts = path.relative_to(root).parts
|
|
67
|
+
except ValueError:
|
|
68
|
+
return False
|
|
69
|
+
if len(parts) < 2:
|
|
70
|
+
return False
|
|
71
|
+
if "subagents" in parts:
|
|
72
|
+
return bool(AGENT_TRANSCRIPT_RE.match(path.name))
|
|
73
|
+
return len(parts) == 2
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def is_subagent_transcript(root: Path, path: Path) -> bool:
|
|
77
|
+
"""A dispatched agent's own run, at any nesting depth below `root`.
|
|
78
|
+
|
|
79
|
+
A plain Agent dispatch writes `<project>/<sessionId>/subagents/agent-*.jsonl`;
|
|
80
|
+
a Workflow's agents nest one level further under `subagents/workflows/<runId>/`.
|
|
81
|
+
Ask the path BELOW the root: `root` defaults to `~/.claude/projects` and
|
|
82
|
+
carries the user's home directory, so a matching segment in that prefix
|
|
83
|
+
would answer for the whole tree.
|
|
84
|
+
"""
|
|
85
|
+
return "subagents" in relative_parts(root, path)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def sorted_paths(paths) -> list[Path]:
|
|
89
|
+
"""Total order over transcript paths. Sorting on `Path.name` alone is not
|
|
90
|
+
a total order once subagent transcripts (a second directory level) are in
|
|
91
|
+
the mix — sort on the full path string instead, which both extractors'
|
|
92
|
+
determinism guarantee (byte-identical output for the same inputs)
|
|
93
|
+
depends on."""
|
|
94
|
+
return sorted(paths, key=lambda p: str(p))
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def all_transcripts(root: Path) -> list[Path]:
|
|
98
|
+
"""Every transcript under `root`, main-thread and subagent alike.
|
|
99
|
+
|
|
100
|
+
Globbing only `*/*.jsonl` made every dispatched agent invisible (#1990) —
|
|
101
|
+
silently, since subagent records ARE marked `isSidechain: true`; they simply
|
|
102
|
+
live in files nothing opened. Recurse rather than enumerate known depths.
|
|
103
|
+
"""
|
|
104
|
+
return sorted_paths(
|
|
105
|
+
p
|
|
106
|
+
for p in root.glob("*/**/*.jsonl")
|
|
107
|
+
if p.is_file() and not p.is_symlink() and is_transcript_path(root, p)
|
|
108
|
+
)
|