@danmoisan/drm-copilot-mcp 0.0.1
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/README.md +50 -0
- package/out/mcp-server.js +17323 -0
- package/package.json +36 -0
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/MEMORY.md +3 -0
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/feedback_repo_root_is_source_of_truth.md +11 -0
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/feedback_vsce_verify_package_location.md +19 -0
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/project_extension_location.md +11 -0
- package/resources/claude-customizations/.claude/agent-memory/prd-feature/MEMORY.md +1 -0
- package/resources/claude-customizations/.claude/agent-memory/prd-feature/project_push_down_pattern.md +13 -0
- package/resources/claude-customizations/.claude/agent-memory/task-researcher/MEMORY.md +3 -0
- package/resources/claude-customizations/.claude/agent-memory/task-researcher/project_push_down_claude_dir.md +11 -0
- package/resources/claude-customizations/.claude/agents/atomic-executor.md +135 -0
- package/resources/claude-customizations/.claude/agents/atomic-planner.md +71 -0
- package/resources/claude-customizations/.claude/agents/csharp-typed-engineer.md +69 -0
- package/resources/claude-customizations/.claude/agents/epic-review.md +40 -0
- package/resources/claude-customizations/.claude/agents/feature-review.md +136 -0
- package/resources/claude-customizations/.claude/agents/orchestrator.md +83 -0
- package/resources/claude-customizations/.claude/agents/powershell-typed-engineer.md +80 -0
- package/resources/claude-customizations/.claude/agents/prd-feature.md +42 -0
- package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +72 -0
- package/resources/claude-customizations/.claude/agents/staged-review.md +41 -0
- package/resources/claude-customizations/.claude/agents/status-updater.md +41 -0
- package/resources/claude-customizations/.claude/agents/task-researcher.md +81 -0
- package/resources/claude-customizations/.claude/agents/typescript-engineer.md +24 -0
- package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +111 -0
- package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +146 -0
- package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +150 -0
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +238 -0
- package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +147 -0
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +235 -0
- package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +69 -0
- package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +296 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +389 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +141 -0
- package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +288 -0
- package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +171 -0
- package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +142 -0
- package/resources/claude-customizations/.claude/rules/csharp.md +62 -0
- package/resources/claude-customizations/.claude/rules/general-code-change.md +71 -0
- package/resources/claude-customizations/.claude/rules/general-unit-test.md +60 -0
- package/resources/claude-customizations/.claude/rules/powershell.md +97 -0
- package/resources/claude-customizations/.claude/rules/python-suppressions.md +143 -0
- package/resources/claude-customizations/.claude/rules/python.md +99 -0
- package/resources/claude-customizations/.claude/rules/self-explanatory-code-commenting.md +97 -0
- package/resources/claude-customizations/.claude/rules/tonality.md +80 -0
- package/resources/claude-customizations/.claude/rules/typescript-suppressions.md +66 -0
- package/resources/claude-customizations/.claude/rules/typescript.md +45 -0
- package/resources/claude-customizations/.claude/settings.json +144 -0
- package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +102 -0
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +189 -0
- package/resources/claude-customizations/.claude/skills/commit-message/SKILL.md +65 -0
- package/resources/claude-customizations/.claude/skills/csharp-change-budget-router/SKILL.md +90 -0
- package/resources/claude-customizations/.claude/skills/csharp-orchestration-state-machine/SKILL.md +58 -0
- package/resources/claude-customizations/.claude/skills/csharp-qa-gate/SKILL.md +77 -0
- package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +164 -0
- package/resources/claude-customizations/.claude/skills/execute-hard-lock/SKILL.md +82 -0
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +115 -0
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +167 -0
- package/resources/claude-customizations/.claude/skills/fill-feature-docs/SKILL.md +22 -0
- package/resources/claude-customizations/.claude/skills/invoke-csharp-engineer/SKILL.md +64 -0
- package/resources/claude-customizations/.claude/skills/invoke-powershell-engineer/SKILL.md +65 -0
- package/resources/claude-customizations/.claude/skills/invoke-python-engineer/SKILL.md +64 -0
- package/resources/claude-customizations/.claude/skills/make-skill-template/SKILL.md +147 -0
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +132 -0
- package/resources/claude-customizations/.claude/skills/policy-audit-template-usage/SKILL.md +49 -0
- package/resources/claude-customizations/.claude/skills/policy-compliance-order/SKILL.md +40 -0
- package/resources/claude-customizations/.claude/skills/powershell-change-budget-router/SKILL.md +49 -0
- package/resources/claude-customizations/.claude/skills/powershell-orchestration-state-machine/SKILL.md +58 -0
- package/resources/claude-customizations/.claude/skills/powershell-qa-gate/SKILL.md +77 -0
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +50 -0
- package/resources/claude-customizations/.claude/skills/pr-base-branch-merge-base/SKILL.md +56 -0
- package/resources/claude-customizations/.claude/skills/pr-context-artifacts/SKILL.md +30 -0
- package/resources/claude-customizations/.claude/skills/python-change-budget-router/SKILL.md +79 -0
- package/resources/claude-customizations/.claude/skills/python-qa-gate/SKILL.md +77 -0
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +40 -0
- package/resources/claude-customizations/.claude/skills/research-issue/SKILL.md +67 -0
- package/resources/claude-customizations/.claude/skills/review-epic/SKILL.md +21 -0
- package/resources/claude-customizations/.claude/skills/review-feature/SKILL.md +25 -0
- package/resources/claude-customizations/.claude/skills/review-staged/SKILL.md +21 -0
- package/resources/claude-customizations/.claude/skills/skill-canonical-location-audit/SKILL.md +49 -0
- package/resources/claude-customizations/.claude/skills/translate-copilot-to-claude/SKILL.md +295 -0
- package/resources/claude-customizations/.claude/skills/update-status/SKILL.md +21 -0
- package/resources/claude-dir-customizations/.mcp.json +8 -0
- package/resources/codex-and-agents-customizations/.agents/README.md +86 -0
- package/resources/codex-and-agents-customizations/.agents/skills/README.md +49 -0
- package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +107 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +73 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +194 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +87 -0
- package/resources/codex-and-agents-customizations/.agents/skills/commit-message/SKILL.md +70 -0
- package/resources/codex-and-agents-customizations/.agents/skills/commit-message-conventions/SKILL.md +95 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +67 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-change-budget-router/SKILL.md +94 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-orchestration-state-machine/SKILL.md +64 -0
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +82 -0
- package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +168 -0
- package/resources/codex-and-agents-customizations/.agents/skills/execute-hard-lock/SKILL.md +88 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +129 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +106 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +181 -0
- package/resources/codex-and-agents-customizations/.agents/skills/fill-feature-docs/SKILL.md +27 -0
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-csharp-engineer/SKILL.md +73 -0
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-powershell-engineer/SKILL.md +74 -0
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-python-engineer/SKILL.md +73 -0
- package/resources/codex-and-agents-customizations/.agents/skills/make-skill-template/SKILL.md +152 -0
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +143 -0
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +317 -0
- package/resources/codex-and-agents-customizations/.agents/skills/policy-audit-template-usage/SKILL.md +53 -0
- package/resources/codex-and-agents-customizations/.agents/skills/policy-compliance-order/SKILL.md +49 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell/SKILL.md +102 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-change-budget-router/SKILL.md +53 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-orchestration-state-machine/SKILL.md +64 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-qa-gate/SKILL.md +83 -0
- package/resources/codex-and-agents-customizations/.agents/skills/pr-author/SKILL.md +55 -0
- package/resources/codex-and-agents-customizations/.agents/skills/pr-authoring/SKILL.md +124 -0
- package/resources/codex-and-agents-customizations/.agents/skills/pr-base-branch-merge-base/SKILL.md +60 -0
- package/resources/codex-and-agents-customizations/.agents/skills/pr-context-artifacts/SKILL.md +34 -0
- package/resources/codex-and-agents-customizations/.agents/skills/python/SKILL.md +104 -0
- package/resources/codex-and-agents-customizations/.agents/skills/python-change-budget-router/SKILL.md +84 -0
- package/resources/codex-and-agents-customizations/.agents/skills/python-qa-gate/SKILL.md +82 -0
- package/resources/codex-and-agents-customizations/.agents/skills/python-suppressions/SKILL.md +148 -0
- package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +49 -0
- package/resources/codex-and-agents-customizations/.agents/skills/repo-automation-adapter/SKILL.md +142 -0
- package/resources/codex-and-agents-customizations/.agents/skills/repo-automation-adapter/agents/openai.yaml +5 -0
- package/resources/codex-and-agents-customizations/.agents/skills/research-issue/SKILL.md +72 -0
- package/resources/codex-and-agents-customizations/.agents/skills/review-epic/SKILL.md +26 -0
- package/resources/codex-and-agents-customizations/.agents/skills/review-feature/SKILL.md +30 -0
- package/resources/codex-and-agents-customizations/.agents/skills/review-staged/SKILL.md +26 -0
- package/resources/codex-and-agents-customizations/.agents/skills/self-explanatory-code-commenting/SKILL.md +102 -0
- package/resources/codex-and-agents-customizations/.agents/skills/skill-canonical-location-audit/SKILL.md +52 -0
- package/resources/codex-and-agents-customizations/.agents/skills/translate-copilot-to-claude/SKILL.md +317 -0
- package/resources/codex-and-agents-customizations/.agents/skills/typescript/SKILL.md +50 -0
- package/resources/codex-and-agents-customizations/.agents/skills/typescript-suppressions/SKILL.md +71 -0
- package/resources/codex-and-agents-customizations/.agents/skills/update-status/SKILL.md +26 -0
- package/resources/codex-and-agents-customizations/.codex/agents/5.1-beast-adjusted.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/5.1-thinking-beast-mode-adjusted.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/api-architect.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +151 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +93 -0
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planning.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commentary-remediation.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/commit-steward.toml +20 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-executor.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-planning.toml +25 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-orchestrator.toml +56 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer.toml +97 -0
- package/resources/codex-and-agents-customizations/.codex/agents/epic-review.toml +52 -0
- package/resources/codex-and-agents-customizations/.codex/agents/expert-nextjs-developer.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/expert-react-frontend-engineer.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +149 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer.toml +60 -0
- package/resources/codex-and-agents-customizations/.codex/agents/gpt-5-beast-mode.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/hlbpa.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/mentor.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +121 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-executor.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-planning.toml +25 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-di-unit-test-engineer.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-orchestrator.toml +56 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer.toml +108 -0
- package/resources/codex-and-agents-customizations/.codex/agents/pr-author.toml +26 -0
- package/resources/codex-and-agents-customizations/.codex/agents/prd-feature.toml +53 -0
- package/resources/codex-and-agents-customizations/.codex/agents/prd.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/pytest-unit-test-coding.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-executor.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-planning.toml +25 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-execution-only-typed.toml +24 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-orchestrator.toml +54 -0
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +100 -0
- package/resources/codex-and-agents-customizations/.codex/agents/staged-review.toml +53 -0
- package/resources/codex-and-agents-customizations/.codex/agents/status-updater.toml +53 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher.toml +103 -0
- package/resources/codex-and-agents-customizations/.codex/agents/tdd-green.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/tdd-red.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/tdd-refactor.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/agents/typescript-engineer.toml +48 -0
- package/resources/codex-and-agents-customizations/.codex/agents/voidbeast-gpt41enhanced.toml +23 -0
- package/resources/codex-and-agents-customizations/.codex/codex-web-setup.plan.md +26 -0
- package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +384 -0
- package/resources/codex-and-agents-customizations/.codex/config.toml +137 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +113 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +149 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +153 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +241 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +150 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +238 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +72 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +265 -0
- package/resources/codex-and-agents-customizations/.codex/prompts/feature-review-remediate.md +10 -0
- package/resources/codex-and-agents-customizations/.codex/prompts/generate-commit-message-repo.md +11 -0
- package/resources/codex-and-agents-customizations/.codex/prompts/generate-pr.md +15 -0
- package/resources/codex-and-agents-customizations/.codex/prompts/orchestrate-work.md +22 -0
- package/resources/codex-and-agents-customizations/AGENTS.md +317 -0
- package/resources/customizations/.github/agents/5.1-Beast-adjusted.agent.md +181 -0
- package/resources/customizations/.github/agents/5.1-Thinking-Beast-Mode-adjusted.agent.md +361 -0
- package/resources/customizations/.github/agents/Powershell DI Unit Test Engineer.agent.md +192 -0
- package/resources/customizations/.github/agents/api-architect.agent.md +40 -0
- package/resources/customizations/.github/agents/atomic_executor.agent.md +251 -0
- package/resources/customizations/.github/agents/atomic_planning.agent.md +658 -0
- package/resources/customizations/.github/agents/commentary-remediation.agent.md +35 -0
- package/resources/customizations/.github/agents/commit-steward.agent.md +200 -0
- package/resources/customizations/.github/agents/csharp-atomic-executor.agent.md +288 -0
- package/resources/customizations/.github/agents/csharp-atomic-planning.agent.md +354 -0
- package/resources/customizations/.github/agents/csharp-orchestrator.agent.md +375 -0
- package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +285 -0
- package/resources/customizations/.github/agents/epic-review.agent.md +374 -0
- package/resources/customizations/.github/agents/expert-nextjs-developer.agent.md +477 -0
- package/resources/customizations/.github/agents/expert-react-frontend-engineer.agent.md +739 -0
- package/resources/customizations/.github/agents/feature-review.agent.md +49 -0
- package/resources/customizations/.github/agents/gpt-5-beast-mode.agent.md +116 -0
- package/resources/customizations/.github/agents/hlbpa.agent.md +219 -0
- package/resources/customizations/.github/agents/mentor.agent.md +32 -0
- package/resources/customizations/.github/agents/orchestrator.agent.md +449 -0
- package/resources/customizations/.github/agents/powershell-atomic-executor.agent.md +287 -0
- package/resources/customizations/.github/agents/powershell-atomic-planning.agent.md +647 -0
- package/resources/customizations/.github/agents/powershell-orchestrator.agent.md +382 -0
- package/resources/customizations/.github/agents/powershell-typed-engineer.agent.md +293 -0
- package/resources/customizations/.github/agents/pr-author.agent.md +138 -0
- package/resources/customizations/.github/agents/prd-feature.agent.md +52 -0
- package/resources/customizations/.github/agents/prd.agent.md +202 -0
- package/resources/customizations/.github/agents/pytest-unit-test-coding.agent.md +202 -0
- package/resources/customizations/.github/agents/python-atomic-executor.agent.md +289 -0
- package/resources/customizations/.github/agents/python-atomic-planning.agent.md +429 -0
- package/resources/customizations/.github/agents/python-execution-only-typed.agent.md +217 -0
- package/resources/customizations/.github/agents/python-orchestrator.agent.md +380 -0
- package/resources/customizations/.github/agents/python-typed-engineer.agent.md +271 -0
- package/resources/customizations/.github/agents/staged-review.agent.md +246 -0
- package/resources/customizations/.github/agents/status_updater.agent.md +279 -0
- package/resources/customizations/.github/agents/task-researcher.agent.md +298 -0
- package/resources/customizations/.github/agents/tdd-green.agent.md +60 -0
- package/resources/customizations/.github/agents/tdd-red.agent.md +66 -0
- package/resources/customizations/.github/agents/tdd-refactor.agent.md +94 -0
- package/resources/customizations/.github/agents/typescript-engineer.agent.md +167 -0
- package/resources/customizations/.github/agents/voidbeast-gpt41enhanced.agent.md +230 -0
- package/resources/customizations/.github/codex/execute-hard-lock.prompt.md +105 -0
- package/resources/customizations/.github/codex/resume-hard-lock.prompt.md +92 -0
- package/resources/customizations/.github/copilot-instructions.md +7 -0
- package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +184 -0
- package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +52 -0
- package/resources/customizations/.github/instructions/general-code-change.instructions.md +290 -0
- package/resources/customizations/.github/instructions/general-unit-test.instructions.md +106 -0
- package/resources/customizations/.github/instructions/github-actions-ci-cd-best-practices.instructions.md +607 -0
- package/resources/customizations/.github/instructions/github-actions.instructions.md +23 -0
- package/resources/customizations/.github/instructions/powershell-code-change.instructions.md +81 -0
- package/resources/customizations/.github/instructions/powershell-unit-test.instructions.md +69 -0
- package/resources/customizations/.github/instructions/python-code-change.instructions.md +232 -0
- package/resources/customizations/.github/instructions/python-suppressions.instructions.md +609 -0
- package/resources/customizations/.github/instructions/python-unit-test.instructions.md +71 -0
- package/resources/customizations/.github/instructions/self-explanatory-code-commenting.instructions.md +238 -0
- package/resources/customizations/.github/instructions/tonality.instructions.md +133 -0
- package/resources/customizations/.github/instructions/typescript-code-change.instructions.md +203 -0
- package/resources/customizations/.github/instructions/typescript-suppressions.instructions.md +157 -0
- package/resources/customizations/.github/instructions/typescript-unit-test.instructions.md +112 -0
- package/resources/customizations/.github/prompts/add-educational-comments.prompt.md +129 -0
- package/resources/customizations/.github/prompts/breakdown-bug-prd.prompt.md +29 -0
- package/resources/customizations/.github/prompts/breakdown-epic-arch.prompt.md +66 -0
- package/resources/customizations/.github/prompts/breakdown-epic-pm.prompt.md +58 -0
- package/resources/customizations/.github/prompts/breakdown-feature-implementation.prompt.md +128 -0
- package/resources/customizations/.github/prompts/breakdown-feature-prd.prompt.md +61 -0
- package/resources/customizations/.github/prompts/code-exemplars-blueprint-generator.prompt.md +126 -0
- package/resources/customizations/.github/prompts/drafts/create-github-issues-feature-from-implementation-plan.prompt.md +28 -0
- package/resources/customizations/.github/prompts/drafts/create-implementation-plan.prompt.md +158 -0
- package/resources/customizations/.github/prompts/drafts/create-technical-spike.prompt.md +231 -0
- package/resources/customizations/.github/prompts/drafts/potential-feature-prd.prompt.md +19 -0
- package/resources/customizations/.github/prompts/drafts/update-implementation-plan.prompt.md +158 -0
- package/resources/customizations/.github/prompts/execute-plan-template.md +21 -0
- package/resources/customizations/.github/prompts/export-chat.prompt.md +7 -0
- package/resources/customizations/.github/prompts/fillout-prd-feature.prompt.md +46 -0
- package/resources/customizations/.github/prompts/generate-atomic-plan.prompt.md +96 -0
- package/resources/customizations/.github/prompts/generate-commit-message-repo.prompt.md +108 -0
- package/resources/customizations/.github/prompts/generate-pr.prompt.md +151 -0
- package/resources/customizations/.github/prompts/javascript-typescript-jest.prompt.md +44 -0
- package/resources/customizations/.github/prompts/orchestrate-csharp-work.prompt.md +66 -0
- package/resources/customizations/.github/prompts/orchestrate-powershell-work.prompt.md +50 -0
- package/resources/customizations/.github/prompts/orchestrate-python-work.prompt.md +50 -0
- package/resources/customizations/.github/prompts/orchestrate-work.prompt.md +66 -0
- package/resources/customizations/.github/prompts/remediate-comments.prompt.md +53 -0
- package/resources/customizations/.github/prompts/research-issue.prompt.md +125 -0
- package/resources/customizations/.github/prompts/review-epic.prompt.md +94 -0
- package/resources/customizations/.github/prompts/review-feature.prompt.md +130 -0
- package/resources/customizations/.github/prompts/review-staged.prompt.md +43 -0
- package/resources/customizations/.github/prompts/update_status.prompt.md +68 -0
- package/resources/customizations/.github/skills/README.md +26 -0
- package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +102 -0
- package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +174 -0
- package/resources/customizations/.github/skills/csharp-change-budget-router/SKILL.md +48 -0
- package/resources/customizations/.github/skills/csharp-orchestration-state-machine/SKILL.md +57 -0
- package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +135 -0
- package/resources/customizations/.github/skills/feature-promotion-lifecycle/SKILL.md +121 -0
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +153 -0
- package/resources/customizations/.github/skills/make-skill-template/SKILL.md +147 -0
- package/resources/customizations/.github/skills/policy-audit-template-usage/SKILL.md +48 -0
- package/resources/customizations/.github/skills/policy-compliance-order/SKILL.md +37 -0
- package/resources/customizations/.github/skills/powershell-change-budget-router/SKILL.md +48 -0
- package/resources/customizations/.github/skills/powershell-orchestration-state-machine/SKILL.md +57 -0
- package/resources/customizations/.github/skills/pr-base-branch-merge-base/SKILL.md +55 -0
- package/resources/customizations/.github/skills/pr-context-artifacts/SKILL.md +29 -0
- package/resources/customizations/.github/skills/remediation-handoff-atomic-planner/SKILL.md +39 -0
- package/resources/customizations/.github/skills/skill-canonical-location-audit/SKILL.md +48 -0
- package/resources/feature-templates/bug/plan.yyyy-MM-ddTHH-mm.md +44 -0
- package/resources/feature-templates/bug/potential_bug.md +59 -0
- package/resources/feature-templates/bug/spec.md +99 -0
- package/resources/feature-templates/epic/initiative.md +43 -0
- package/resources/feature-templates/feature/plan.yyyy-MM-ddTHH-mm.md +53 -0
- package/resources/feature-templates/feature/spec.md +66 -0
- package/resources/feature-templates/feature/user-story.md +42 -0
- package/resources/feature-templates/potential/template.md +33 -0
- package/resources/feature-templates/refactor/plan.yyyy-MM-ddTHH-mm.md +52 -0
- package/resources/feature-templates/refactor/spec.md +69 -0
- package/resources/powershell/PoshQC/PoshQC.Analyzer.psm1 +254 -0
- package/resources/powershell/PoshQC/PoshQC.FileDiscovery.psm1 +138 -0
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +409 -0
- package/resources/powershell/PoshQC/PoshQC.psd1 +31 -0
- package/resources/powershell/PoshQC/PoshQC.psm1 +101 -0
- package/resources/powershell/PoshQC/README.md +80 -0
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +59 -0
- package/resources/powershell/PoshQC/settings/pssa.settings.psd1 +55 -0
- package/resources/scripts/dev_tools/__init__.py +0 -0
- package/resources/scripts/dev_tools/agentic_sync.py +819 -0
- package/resources/scripts/dev_tools/codex_native_converter/__init__.py +11 -0
- package/resources/scripts/dev_tools/codex_native_converter/__main__.py +6 -0
- package/resources/scripts/dev_tools/codex_native_converter/cli.py +11 -0
- package/resources/scripts/dev_tools/new_active_feature_folder.py +79 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_docs.py +268 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_flow.py +366 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_io.py +306 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_markdown.py +252 -0
- package/resources/scripts/dev_tools/new_active_feature_folder_models.py +136 -0
- package/resources/scripts/dev_tools/new_potential_bug_entry.py +465 -0
- package/resources/scripts/dev_tools/potential_to_issue.py +421 -0
- package/resources/scripts/dev_tools/potential_to_issue_content.py +212 -0
- package/resources/scripts/dev_tools/pr_context/__init__.py +0 -0
- package/resources/scripts/dev_tools/pr_context/collector.py +619 -0
- package/resources/scripts/dev_tools/pr_context/feature_docs.py +349 -0
- package/resources/scripts/dev_tools/pr_context/git.py +153 -0
- package/resources/scripts/dev_tools/pr_context/github.py +549 -0
- package/resources/scripts/dev_tools/pr_context/models.py +198 -0
- package/resources/scripts/dev_tools/pr_context/render.py +342 -0
- package/resources/scripts/dev_tools/pr_context/render_feature_excerpts.py +256 -0
- package/resources/scripts/dev_tools/pr_context/render_pr_helpers.py +291 -0
- package/resources/scripts/dev_tools/pr_context/summary_helpers.py +386 -0
- package/resources/scripts/dev_tools/pr_context/verification_evidence.py +171 -0
- package/resources/scripts/dev_tools/prompt_mode_contract.py +152 -0
- package/resources/scripts/dev_tools/push_down_claude_customizations.py +188 -0
- package/resources/scripts/dev_tools/push_down_codex_and_agents_customizations.py +139 -0
- package/resources/scripts/dev_tools/push_down_copilot_customizations.py +504 -0
- package/resources/scripts/dev_tools/push_down_copilot_customizations_filesystem.py +217 -0
- package/resources/scripts/dev_tools/push_down_copilot_customizations_rewrites.py +293 -0
- package/resources/scripts/dev_tools/resolve_file_prompt.py +457 -0
- package/resources/scripts/dev_tools/resolve_hard_lock_prompt.py +444 -0
- package/resources/scripts/dev_tools/validate_orchestration_artifacts.py +554 -0
- package/resources/templates/codex_native_converter.py +35 -0
- package/resources/templates/collect_commit_context.py +212 -0
- package/resources/templates/collect_pr_context.py +74 -0
- package/resources/templates/hello_pwsh.ps1 +3 -0
- package/resources/templates/hello_python.py +11 -0
- package/resources/templates/link-parent-child.ps1 +480 -0
- package/resources/templates/new-claude-worktree-session.ps1 +232 -0
- package/resources/templates/new-potential-entry.ps1 +187 -0
- package/resources/templates/new_active_feature_folder.py +67 -0
- package/resources/templates/new_potential_bug_entry.py +54 -0
- package/resources/templates/policy_audit/AGENTS.md +117 -0
- package/resources/templates/policy_audit/code-review.yyyy-MM-ddTHH-mm.md +165 -0
- package/resources/templates/policy_audit/feature-audit.yyyy-MM-ddTHH-mm.md +124 -0
- package/resources/templates/policy_audit/policy-audit.yyyy-MM-ddTHH-mm.md +649 -0
- package/resources/templates/potential_to_issue.py +55 -0
- package/resources/templates/push_down_claude_customizations.py +188 -0
- package/resources/templates/push_down_codex_and_agents_customizations.py +95 -0
- package/resources/templates/push_down_copilot_customizations.py +124 -0
- package/resources/templates/resolve_atomic_plan_prompt.py +75 -0
- package/resources/templates/resolve_hard_lock_prompt.py +65 -0
- package/resources/templates/run-poshqc-analyze-autofix.ps1 +16 -0
- package/resources/templates/run-poshqc-analyze.ps1 +26 -0
- package/resources/templates/run-poshqc-format.ps1 +26 -0
- package/resources/templates/run-poshqc-suite.ps1 +24 -0
- package/resources/templates/run-poshqc-test.ps1 +32 -0
- package/resources/templates/sync-agents-from-instructions.ps1 +400 -0
- package/resources/templates/validate_orchestration_artifacts.py +55 -0
- package/resources/templates/vscode-cli.helpers.ps1 +63 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
SubagentStop hook for the atomic-planner subagent.
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
Blocks termination of the atomic-planner subagent unless the agent's final
|
|
7
|
+
output advertises a plan-path, includes an exact preflight signal, and the
|
|
8
|
+
advertised plan file satisfies the repository's mechanical atomic-plan
|
|
9
|
+
structure requirements.
|
|
10
|
+
|
|
11
|
+
Enforced checks:
|
|
12
|
+
- hook payload is valid JSON and contains non-empty output,
|
|
13
|
+
- output advertises `plan-path: <path>` (or supported equivalent forms),
|
|
14
|
+
- output contains `PREFLIGHT: ALL CLEAR` or
|
|
15
|
+
`PREFLIGHT: REVISIONS REQUIRED`,
|
|
16
|
+
- the advertised plan exists on disk,
|
|
17
|
+
- the plan contains canonical `### Phase N - <Title>` headings,
|
|
18
|
+
- Phase 0 exists and includes policy-read and baseline tasks,
|
|
19
|
+
- each task uses `- [ ] [P#-T#]` (or checked equivalent),
|
|
20
|
+
- task numbering is sequential within each phase,
|
|
21
|
+
- every task includes at least one explicit path token,
|
|
22
|
+
- the final phase contains QA-oriented work.
|
|
23
|
+
|
|
24
|
+
.NOTES
|
|
25
|
+
Reads the hook payload from CLAUDE_HOOK_INPUT as JSON. Exits 0 to allow
|
|
26
|
+
termination; exits 1 with an error message to block. Filesystem reads go
|
|
27
|
+
through Get-PlanFileContent so tests can mock the boundary without writing
|
|
28
|
+
temporary files.
|
|
29
|
+
#>
|
|
30
|
+
|
|
31
|
+
[CmdletBinding()]
|
|
32
|
+
param()
|
|
33
|
+
|
|
34
|
+
Set-StrictMode -Version Latest
|
|
35
|
+
$ErrorActionPreference = 'Stop'
|
|
36
|
+
|
|
37
|
+
function Get-PlanFileContent {
|
|
38
|
+
[CmdletBinding()]
|
|
39
|
+
[OutputType([hashtable])]
|
|
40
|
+
param(
|
|
41
|
+
[Parameter(Mandatory = $true)]
|
|
42
|
+
[string] $Path
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
|
|
46
|
+
return @{ Exists = $false; Lines = @() }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
$lines = Get-Content -LiteralPath $Path -ErrorAction Stop
|
|
50
|
+
if ($null -eq $lines) {
|
|
51
|
+
$lines = @()
|
|
52
|
+
}
|
|
53
|
+
elseif ($lines -isnot [array]) {
|
|
54
|
+
$lines = @($lines)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return @{ Exists = $true; Lines = $lines }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function Get-PlanPathFromOutput {
|
|
61
|
+
[CmdletBinding()]
|
|
62
|
+
[OutputType([string])]
|
|
63
|
+
param(
|
|
64
|
+
[Parameter(Mandatory = $true)]
|
|
65
|
+
[string] $AgentOutput
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
$pattern = 'plan-path\s*[:=]\s*["'']?([^\s"''\)`]+)|\[plan-path\]\(([^)]+)\)'
|
|
69
|
+
$match = [regex]::Match(
|
|
70
|
+
$AgentOutput,
|
|
71
|
+
$pattern,
|
|
72
|
+
[System.Text.RegularExpressions.RegexOptions]::IgnoreCase
|
|
73
|
+
)
|
|
74
|
+
if (-not $match.Success) {
|
|
75
|
+
return $null
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
$value = if ($match.Groups[1].Success) { $match.Groups[1].Value } else { $match.Groups[2].Value }
|
|
79
|
+
$value = $value.Trim()
|
|
80
|
+
if ([string]::IsNullOrWhiteSpace($value)) {
|
|
81
|
+
return $null
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return $value
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function Test-TaskContainsExplicitPath {
|
|
88
|
+
[CmdletBinding()]
|
|
89
|
+
[OutputType([bool])]
|
|
90
|
+
param(
|
|
91
|
+
[Parameter(Mandatory = $true)]
|
|
92
|
+
[string] $TaskText
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
$pathPattern = '(?i)(?:[.\w*?-]+[\\/])+[.\w*?-]+'
|
|
96
|
+
return [regex]::IsMatch($TaskText, $pathPattern)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function Test-HasPreflightSignal {
|
|
100
|
+
[CmdletBinding()]
|
|
101
|
+
[OutputType([bool])]
|
|
102
|
+
param(
|
|
103
|
+
[Parameter(Mandatory = $true)]
|
|
104
|
+
[string] $AgentOutput
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return [regex]::IsMatch(
|
|
108
|
+
$AgentOutput,
|
|
109
|
+
'(?m)^\s*PREFLIGHT:\s*(ALL CLEAR|REVISIONS REQUIRED)\s*$'
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function Get-PlanStructureValidationReport {
|
|
114
|
+
[CmdletBinding()]
|
|
115
|
+
[OutputType([string[]])]
|
|
116
|
+
param(
|
|
117
|
+
[Parameter(Mandatory = $true)]
|
|
118
|
+
[string[]] $Lines
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
$phasePattern = '^### Phase (?<Phase>\d+)\s+-\s+(?<Title>.+)$'
|
|
122
|
+
$taskPattern = '^- \[(?<State>[ xX])\] \[P(?<Phase>\d+)-T(?<Task>\d+)\] (?<Text>.+)$'
|
|
123
|
+
$errors = [System.Collections.Generic.List[string]]::new()
|
|
124
|
+
$tasksByPhase = @{}
|
|
125
|
+
$phaseTitles = @{}
|
|
126
|
+
$currentPhase = $null
|
|
127
|
+
$expectedPhase = 0
|
|
128
|
+
$foundTask = $false
|
|
129
|
+
|
|
130
|
+
for ($i = 0; $i -lt $Lines.Count; $i++) {
|
|
131
|
+
$lineNumber = $i + 1
|
|
132
|
+
$line = $Lines[$i]
|
|
133
|
+
|
|
134
|
+
if ($line -match '^### Phase ') {
|
|
135
|
+
$phaseMatch = [regex]::Match($line, $phasePattern)
|
|
136
|
+
if (-not $phaseMatch.Success) {
|
|
137
|
+
$errors.Add("Line ${lineNumber}: phase heading must match `### Phase N - <Title>`.")
|
|
138
|
+
$currentPhase = $null
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
$phaseNumber = [int]$phaseMatch.Groups['Phase'].Value
|
|
143
|
+
if ($phaseNumber -ne $expectedPhase) {
|
|
144
|
+
$errors.Add("Line ${lineNumber}: expected Phase $expectedPhase but found Phase $phaseNumber.")
|
|
145
|
+
$expectedPhase = $phaseNumber
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
$currentPhase = $phaseNumber
|
|
149
|
+
$expectedPhase = $phaseNumber + 1
|
|
150
|
+
$tasksByPhase[$phaseNumber] = [System.Collections.Generic.List[string]]::new()
|
|
151
|
+
$phaseTitles[$phaseNumber] = $phaseMatch.Groups['Title'].Value.Trim()
|
|
152
|
+
continue
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if ($line -notmatch '^- \[') {
|
|
156
|
+
continue
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
$foundTask = $true
|
|
160
|
+
$taskMatch = [regex]::Match($line, $taskPattern)
|
|
161
|
+
if (-not $taskMatch.Success) {
|
|
162
|
+
$errors.Add("Line ${lineNumber}: task line must match `- [ ] [P#-T#] <description>`.")
|
|
163
|
+
continue
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if ($null -eq $currentPhase) {
|
|
167
|
+
$errors.Add("Line ${lineNumber}: task appears before the first canonical phase heading.")
|
|
168
|
+
continue
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
$taskPhase = [int]$taskMatch.Groups['Phase'].Value
|
|
172
|
+
$taskNumber = [int]$taskMatch.Groups['Task'].Value
|
|
173
|
+
$taskText = $taskMatch.Groups['Text'].Value.Trim()
|
|
174
|
+
|
|
175
|
+
if ($taskPhase -ne $currentPhase) {
|
|
176
|
+
$errors.Add("Line ${lineNumber}: task phase P$taskPhase does not match current phase $currentPhase.")
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (-not $tasksByPhase.ContainsKey($taskPhase)) {
|
|
180
|
+
$tasksByPhase[$taskPhase] = [System.Collections.Generic.List[string]]::new()
|
|
181
|
+
}
|
|
182
|
+
$expectedTaskNumber = $tasksByPhase[$taskPhase].Count + 1
|
|
183
|
+
if ($taskNumber -ne $expectedTaskNumber) {
|
|
184
|
+
$errors.Add("Line ${lineNumber}: expected task number T$expectedTaskNumber for phase $taskPhase, found T$taskNumber.")
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (-not (Test-TaskContainsExplicitPath -TaskText $taskText)) {
|
|
188
|
+
$errors.Add("Line ${lineNumber}: task [P$taskPhase-T$taskNumber] must include at least one explicit path.")
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
$tasksByPhase[$taskPhase].Add($taskText)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if ($phaseTitles.Count -eq 0) {
|
|
195
|
+
$errors.Add('Plan does not contain any canonical phase headings.')
|
|
196
|
+
return [string[]]@($errors)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (-not $foundTask) {
|
|
200
|
+
$errors.Add('Plan does not contain any canonical task lines.')
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (-not $tasksByPhase.ContainsKey(0) -or $tasksByPhase[0].Count -eq 0) {
|
|
204
|
+
$errors.Add('Plan must include Phase 0 with at least one baseline task.')
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
$phaseZeroText = ($tasksByPhase[0] -join "`n")
|
|
208
|
+
if ($phaseZeroText -notmatch '(?i)\b(policy|instruction|read)\b') {
|
|
209
|
+
$errors.Add('Phase 0 must include a policy-read task.')
|
|
210
|
+
}
|
|
211
|
+
if ($phaseZeroText -notmatch '(?i)\bbaseline\b') {
|
|
212
|
+
$errors.Add('Phase 0 must include a baseline task.')
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
$maxPhaseMeasure = ($phaseTitles.Keys | Measure-Object -Maximum).Maximum
|
|
217
|
+
$maxPhase = if ($null -eq $maxPhaseMeasure) { $null } else { [int]$maxPhaseMeasure }
|
|
218
|
+
$finalPhaseText = ''
|
|
219
|
+
if ($null -ne $maxPhase -and $tasksByPhase.ContainsKey($maxPhase)) {
|
|
220
|
+
$finalPhaseText = (($phaseTitles[$maxPhase]), ($tasksByPhase[$maxPhase] -join "`n")) -join "`n"
|
|
221
|
+
}
|
|
222
|
+
if ([string]::IsNullOrWhiteSpace($finalPhaseText) -or $finalPhaseText -notmatch '(?i)(qa|quality|toolchain|format|lint|type|test|coverage)') {
|
|
223
|
+
$errors.Add('The final phase must contain explicit QA or toolchain validation work.')
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return [string[]]@($errors)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function Invoke-PlannerOutputValidation {
|
|
230
|
+
[CmdletBinding()]
|
|
231
|
+
[OutputType([hashtable])]
|
|
232
|
+
param(
|
|
233
|
+
[string] $RawPayload
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
if ([string]::IsNullOrWhiteSpace($RawPayload)) {
|
|
237
|
+
return @{ Ok = $false; Message = 'atomic-planner hook: CLAUDE_HOOK_INPUT is empty; cannot validate planner output.' }
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
$payload = $RawPayload | ConvertFrom-Json -ErrorAction Stop
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
return @{ Ok = $false; Message = "atomic-planner hook: failed to parse CLAUDE_HOOK_INPUT as JSON: $($_.Exception.Message)" }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
$agentOutput = $null
|
|
248
|
+
if ($payload.PSObject.Properties.Name -contains 'output') {
|
|
249
|
+
$agentOutput = $payload.output
|
|
250
|
+
}
|
|
251
|
+
if ([string]::IsNullOrWhiteSpace($agentOutput)) {
|
|
252
|
+
return @{ Ok = $false; Message = 'atomic-planner hook: agent output is empty; planner must return plan-path and final preflight signal.' }
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (-not (Test-HasPreflightSignal -AgentOutput $agentOutput)) {
|
|
256
|
+
return @{ Ok = $false; Message = 'atomic-planner hook: agent output must include `PREFLIGHT: ALL CLEAR` or `PREFLIGHT: REVISIONS REQUIRED`.' }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
$planPath = Get-PlanPathFromOutput -AgentOutput $agentOutput
|
|
260
|
+
if ($null -eq $planPath) {
|
|
261
|
+
return @{ Ok = $false; Message = 'atomic-planner hook: agent output does not advertise a plan-path. Planner must report `plan-path: <path>` per atomic-plan-contract.' }
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
$file = Get-PlanFileContent -Path $planPath
|
|
265
|
+
if (-not $file.Exists) {
|
|
266
|
+
return @{ Ok = $false; Message = "atomic-planner hook: planner advertised plan-path '$planPath' but no file exists at that location." }
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
$errors = @(Get-PlanStructureValidationReport -Lines $file.Lines)
|
|
270
|
+
if ($errors.Count -gt 0) {
|
|
271
|
+
$message = "atomic-planner hook: plan '$planPath' violates the atomic plan contract:`n - " + ($errors -join "`n - ")
|
|
272
|
+
return @{ Ok = $false; Message = $message }
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return @{ Ok = $true; Message = $null }
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if ($MyInvocation.InvocationName -eq '.') {
|
|
279
|
+
return
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
$result = Invoke-PlannerOutputValidation -RawPayload $env:CLAUDE_HOOK_INPUT
|
|
283
|
+
if (-not $result.Ok) {
|
|
284
|
+
Write-Error $result.Message
|
|
285
|
+
exit 1
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
exit 0
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Generic SubagentStop hook for agents that must advertise exact artifact paths.
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
Validates that the hook payload is well-formed JSON, the agent output is
|
|
7
|
+
non-empty, each required artifact token is advertised in the output, the
|
|
8
|
+
advertised path matches the configured contract regex, and the file exists
|
|
9
|
+
on disk.
|
|
10
|
+
|
|
11
|
+
Each required artifact spec must use:
|
|
12
|
+
token|regex|description
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
spec-path|^docs/features/active/.+/spec\.md$|spec artifact
|
|
16
|
+
|
|
17
|
+
.NOTES
|
|
18
|
+
Reads the hook payload from CLAUDE_HOOK_INPUT as JSON. Exits 0 to allow
|
|
19
|
+
termination; exits 1 with an error message to block. Filesystem existence
|
|
20
|
+
checks go through Test-ArtifactFile so tests can mock the boundary without
|
|
21
|
+
writing temporary files.
|
|
22
|
+
#>
|
|
23
|
+
|
|
24
|
+
[CmdletBinding()]
|
|
25
|
+
param(
|
|
26
|
+
[string] $AgentName,
|
|
27
|
+
|
|
28
|
+
[string[]] $RequiredArtifact
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
Set-StrictMode -Version Latest
|
|
32
|
+
$ErrorActionPreference = 'Stop'
|
|
33
|
+
|
|
34
|
+
function Test-ArtifactFile {
|
|
35
|
+
[CmdletBinding()]
|
|
36
|
+
[OutputType([bool])]
|
|
37
|
+
param(
|
|
38
|
+
[Parameter(Mandatory = $true)]
|
|
39
|
+
[string] $Path
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
return [bool](Test-Path -LiteralPath $Path -PathType Leaf)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function ConvertTo-ArtifactSpec {
|
|
46
|
+
[CmdletBinding()]
|
|
47
|
+
[OutputType([hashtable])]
|
|
48
|
+
param(
|
|
49
|
+
[Parameter(Mandatory = $true)]
|
|
50
|
+
[string] $Spec
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
$parts = $Spec -split '\|', 3
|
|
54
|
+
if ($parts.Count -ne 3) {
|
|
55
|
+
throw "Invalid artifact spec '$Spec'. Expected format: token|regex|description."
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return @{
|
|
59
|
+
Token = $parts[0].Trim()
|
|
60
|
+
Pattern = $parts[1].Trim()
|
|
61
|
+
Description = $parts[2].Trim()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function Get-ArtifactPathFromOutput {
|
|
66
|
+
[CmdletBinding()]
|
|
67
|
+
[OutputType([string])]
|
|
68
|
+
param(
|
|
69
|
+
[Parameter(Mandatory = $true)]
|
|
70
|
+
[string] $AgentOutput,
|
|
71
|
+
|
|
72
|
+
[Parameter(Mandatory = $true)]
|
|
73
|
+
[string] $Token
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
$escapedToken = [regex]::Escape($Token)
|
|
77
|
+
$pattern = "$escapedToken\s*[:=]\s*[""']?([^\s""'\)`]+)|\[$escapedToken\]\(([^)]+)\)"
|
|
78
|
+
$match = [regex]::Match($AgentOutput, $pattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
79
|
+
if (-not $match.Success) {
|
|
80
|
+
return $null
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
$value = if ($match.Groups[1].Success) { $match.Groups[1].Value } else { $match.Groups[2].Value }
|
|
84
|
+
$value = $value.Trim()
|
|
85
|
+
if ([string]::IsNullOrWhiteSpace($value)) {
|
|
86
|
+
return $null
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return $value
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function Invoke-RequiredArtifactOutputValidation {
|
|
93
|
+
[CmdletBinding()]
|
|
94
|
+
[OutputType([hashtable])]
|
|
95
|
+
param(
|
|
96
|
+
[string] $RawPayload,
|
|
97
|
+
[string] $AgentName,
|
|
98
|
+
[string[]] $RequiredArtifact
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if ([string]::IsNullOrWhiteSpace($RawPayload)) {
|
|
102
|
+
return @{ Ok = $false; Message = "$AgentName hook: CLAUDE_HOOK_INPUT is empty; cannot validate required artifact output." }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
$payload = $RawPayload | ConvertFrom-Json -ErrorAction Stop
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return @{ Ok = $false; Message = "$AgentName hook: failed to parse CLAUDE_HOOK_INPUT as JSON: $($_.Exception.Message)" }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
$agentOutput = $null
|
|
113
|
+
if ($payload.PSObject.Properties.Name -contains 'output') {
|
|
114
|
+
$agentOutput = $payload.output
|
|
115
|
+
}
|
|
116
|
+
if ([string]::IsNullOrWhiteSpace($agentOutput)) {
|
|
117
|
+
return @{ Ok = $false; Message = "$AgentName hook: agent output is empty; artifact paths must be reported before termination." }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
$errors = [System.Collections.Generic.List[string]]::new()
|
|
121
|
+
foreach ($specText in $RequiredArtifact) {
|
|
122
|
+
try {
|
|
123
|
+
$spec = ConvertTo-ArtifactSpec -Spec $specText
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return @{ Ok = $false; Message = "$AgentName hook: $($_.Exception.Message)" }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
$path = Get-ArtifactPathFromOutput -AgentOutput $agentOutput -Token $spec.Token
|
|
130
|
+
if ($null -eq $path) {
|
|
131
|
+
$errors.Add("missing $($spec.Token): <path> for the required $($spec.Description)")
|
|
132
|
+
continue
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (-not [regex]::IsMatch($path, $spec.Pattern)) {
|
|
136
|
+
$errors.Add("$($spec.Token) '$path' does not match the required location for the $($spec.Description)")
|
|
137
|
+
continue
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (-not (Test-ArtifactFile -Path $path)) {
|
|
141
|
+
$errors.Add("$($spec.Token) '$path' was advertised for the $($spec.Description) but no file exists at that location")
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if ($errors.Count -gt 0) {
|
|
146
|
+
$message = "$AgentName hook: required artifact validation failed:`n - " + ($errors -join "`n - ")
|
|
147
|
+
return @{ Ok = $false; Message = $message }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return @{ Ok = $true; Message = $null }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if ($MyInvocation.InvocationName -eq '.') {
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if ([string]::IsNullOrWhiteSpace($AgentName) -or $null -eq $RequiredArtifact -or $RequiredArtifact.Count -eq 0) {
|
|
158
|
+
Write-Error 'validate-required-artifact-output hook: AgentName and at least one RequiredArtifact spec are required.'
|
|
159
|
+
exit 1
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
$result = Invoke-RequiredArtifactOutputValidation `
|
|
163
|
+
-RawPayload $env:CLAUDE_HOOK_INPUT `
|
|
164
|
+
-AgentName $AgentName `
|
|
165
|
+
-RequiredArtifact $RequiredArtifact
|
|
166
|
+
if (-not $result.Ok) {
|
|
167
|
+
Write-Error $result.Message
|
|
168
|
+
exit 1
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
exit 0
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
SubagentStop hook for the task-researcher subagent.
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
Blocks termination of the task-researcher subagent unless the agent's
|
|
7
|
+
final output advertises a `research-path` token, the path is rooted
|
|
8
|
+
under artifacts/research/, matches the documented filename convention,
|
|
9
|
+
and the file exists on disk.
|
|
10
|
+
|
|
11
|
+
.NOTES
|
|
12
|
+
Reads the hook payload from CLAUDE_HOOK_INPUT as JSON. Exits 0 to allow
|
|
13
|
+
termination; exits 1 with an error message to block. Filesystem reads go
|
|
14
|
+
through Test-ResearchFile so tests can mock the boundary without writing
|
|
15
|
+
temporary files.
|
|
16
|
+
#>
|
|
17
|
+
|
|
18
|
+
[CmdletBinding()]
|
|
19
|
+
param()
|
|
20
|
+
|
|
21
|
+
Set-StrictMode -Version Latest
|
|
22
|
+
$ErrorActionPreference = 'Stop'
|
|
23
|
+
|
|
24
|
+
function Test-ResearchFile {
|
|
25
|
+
[CmdletBinding()]
|
|
26
|
+
[OutputType([bool])]
|
|
27
|
+
param(
|
|
28
|
+
[Parameter(Mandatory = $true)]
|
|
29
|
+
[string] $Path
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
return [bool](Test-Path -LiteralPath $Path -PathType Leaf)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function Get-ResearchPathFromOutput {
|
|
36
|
+
[CmdletBinding()]
|
|
37
|
+
[OutputType([string])]
|
|
38
|
+
param(
|
|
39
|
+
[Parameter(Mandatory = $true)]
|
|
40
|
+
[string] $AgentOutput
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
$pattern = 'research-path\s*[:=]\s*["'']?([^\s"''\)`]+)|\[research-path\]\(([^)]+)\)'
|
|
44
|
+
$match = [regex]::Match($AgentOutput, $pattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
45
|
+
if (-not $match.Success) {
|
|
46
|
+
return $null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
$value = if ($match.Groups[1].Success) { $match.Groups[1].Value } else { $match.Groups[2].Value }
|
|
50
|
+
$value = $value.Trim()
|
|
51
|
+
if ([string]::IsNullOrWhiteSpace($value)) {
|
|
52
|
+
return $null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return $value
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function Test-IsUnderResearchRoot {
|
|
59
|
+
[CmdletBinding()]
|
|
60
|
+
[OutputType([bool])]
|
|
61
|
+
param(
|
|
62
|
+
[Parameter(Mandatory = $true)]
|
|
63
|
+
[string] $Path
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
$normalized = $Path -replace '\\', '/'
|
|
67
|
+
return $normalized.StartsWith('artifacts/research/', [System.StringComparison]::OrdinalIgnoreCase)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function Test-IsValidResearchFileName {
|
|
71
|
+
[CmdletBinding()]
|
|
72
|
+
[OutputType([bool])]
|
|
73
|
+
param(
|
|
74
|
+
[Parameter(Mandatory = $true)]
|
|
75
|
+
[string] $Path
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
$normalized = $Path -replace '\\', '/'
|
|
79
|
+
$fileName = [System.IO.Path]::GetFileName($normalized)
|
|
80
|
+
return [regex]::IsMatch(
|
|
81
|
+
$fileName,
|
|
82
|
+
'^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-[A-Za-z0-9][A-Za-z0-9-]*-research\.md$'
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function Invoke-TaskResearcherOutputValidation {
|
|
87
|
+
[CmdletBinding()]
|
|
88
|
+
[OutputType([hashtable])]
|
|
89
|
+
param(
|
|
90
|
+
[string] $RawPayload
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
if ([string]::IsNullOrWhiteSpace($RawPayload)) {
|
|
94
|
+
return @{ Ok = $false; Message = 'task-researcher hook: CLAUDE_HOOK_INPUT is empty; cannot validate task-researcher output.' }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
$payload = $RawPayload | ConvertFrom-Json -ErrorAction Stop
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return @{ Ok = $false; Message = "task-researcher hook: failed to parse CLAUDE_HOOK_INPUT as JSON: $($_.Exception.Message)" }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
$agentOutput = $null
|
|
105
|
+
if ($payload.PSObject.Properties.Name -contains 'output') {
|
|
106
|
+
$agentOutput = $payload.output
|
|
107
|
+
}
|
|
108
|
+
if ([string]::IsNullOrWhiteSpace($agentOutput)) {
|
|
109
|
+
return @{ Ok = $false; Message = 'task-researcher hook: agent output is empty; researcher must return research-path before termination.' }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
$researchPath = Get-ResearchPathFromOutput -AgentOutput $agentOutput
|
|
113
|
+
if ($null -eq $researchPath) {
|
|
114
|
+
return @{ Ok = $false; Message = 'task-researcher hook: agent output does not advertise a research-path. Researcher must report `research-path: <path>` pointing to artifacts/research/.' }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (-not (Test-IsUnderResearchRoot -Path $researchPath)) {
|
|
118
|
+
return @{ Ok = $false; Message = "task-researcher hook: research-path '$researchPath' is not under artifacts/research/. All research artifacts must be written to artifacts/research/." }
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (-not (Test-IsValidResearchFileName -Path $researchPath)) {
|
|
122
|
+
return @{ Ok = $false; Message = "task-researcher hook: research-path '$researchPath' does not match the required filename convention `artifacts/research/<timestamp>-<short-name>-research.md`." }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (-not (Test-ResearchFile -Path $researchPath)) {
|
|
126
|
+
return @{ Ok = $false; Message = "task-researcher hook: researcher advertised research-path '$researchPath' but no file exists at that location." }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return @{ Ok = $true; Message = $null }
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if ($MyInvocation.InvocationName -eq '.') {
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
$result = Invoke-TaskResearcherOutputValidation -RawPayload $env:CLAUDE_HOOK_INPUT
|
|
137
|
+
if (-not $result.Ok) {
|
|
138
|
+
Write-Error $result.Message
|
|
139
|
+
exit 1
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
exit 0
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "**/*.cs"
|
|
4
|
+
- "**/*.csproj"
|
|
5
|
+
description: C#-specific toolchain and coding standards.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# C# Code Standards
|
|
9
|
+
|
|
10
|
+
This rule file summarizes the C#-specific policies for this repository.
|
|
11
|
+
|
|
12
|
+
## Toolchain
|
|
13
|
+
|
|
14
|
+
1. **Formatting — CSharpier**: All C# source files must be formatted with CSharpier. Do not use `dotnet format`. Command: `dotnet tool run csharpier .` or `csharpier .`
|
|
15
|
+
2. **Linting — .NET Analyzers**: C# code must pass Roslyn/.NET analyzer diagnostics. Command: `msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true`
|
|
16
|
+
3. **Type Checking — Nullable Analysis**: Enable nullable reference types and fail on warnings. Command: `msbuild TaskMaster.sln /t:Build /p:Configuration=Debug /p:Platform="Any CPU" /p:Nullable=enable /p:TreatWarningsAsErrors=true`
|
|
17
|
+
4. **Testing — MSTest + Moq + FluentAssertions**: Run tests with: `vstest.console.exe <test-assembly-paths> /EnableCodeCoverage`
|
|
18
|
+
|
|
19
|
+
Run the toolchain in order: format → lint → type-check → test. Restart from step 1 if any step fails or changes files.
|
|
20
|
+
|
|
21
|
+
## Coding Standards
|
|
22
|
+
|
|
23
|
+
- **Naming**: `PascalCase` for types and public members. `camelCase` for locals and private fields/parameters.
|
|
24
|
+
- **Null safety**: Keep nullable reference types enabled. Model optional values with nullable annotations and guard clauses.
|
|
25
|
+
- **Composition over inheritance**: Keep classes cohesive and scoped to one responsibility. Favor composition unless polymorphism is a clear requirement.
|
|
26
|
+
- **Async/await**: Use `async`/`await` for I/O-bound operations. Prefer `using`/`await using` for disposable resources.
|
|
27
|
+
- **Exceptions**: Fail fast with explicit exceptions. Avoid broad `catch (Exception)` unless at a defined boundary with added context.
|
|
28
|
+
- **Public surface**: Keep public API surface intentional and minimal. Prefer `internal` for non-public APIs.
|
|
29
|
+
- **XML docs**: Public APIs should include XML documentation comments when behavior or contract is non-obvious.
|
|
30
|
+
|
|
31
|
+
## Testing Standards
|
|
32
|
+
|
|
33
|
+
- Use **MSTest** (`Microsoft.VisualStudio.TestTools.UnitTesting`) as the test framework.
|
|
34
|
+
- Use **Moq** for mocking.
|
|
35
|
+
- Prefer **FluentAssertions** for assertions; use MSTest `Assert` only when FluentAssertions is not practical.
|
|
36
|
+
- Use `[TestClass]` and `[TestMethod]` attributes.
|
|
37
|
+
- Follow Arrange–Act–Assert structure.
|
|
38
|
+
- No external dependencies in unit tests.
|
|
39
|
+
- Repository-wide line coverage must remain >= 80%.
|
|
40
|
+
- Any new module, class, or method must reach >= 90% coverage.
|
|
41
|
+
- Coverage regression on changed lines is a blocking finding.
|
|
42
|
+
|
|
43
|
+
## Deterministic Test Rules
|
|
44
|
+
|
|
45
|
+
Unit tests must not depend on network, mutable machine PATH or profile state, implicit working-directory assumptions, or external services. Use seam-based mocking for all external boundaries (processes, HTTP, filesystem, clocks). Tests must produce identical results in the IDE test runner and in CLI runs so local and CI behavior agree.
|
|
46
|
+
|
|
47
|
+
## DI Seams
|
|
48
|
+
|
|
49
|
+
Introduce the smallest seam that enables reliable unit testing. Apply in this order of preference:
|
|
50
|
+
|
|
51
|
+
1. **Interface seam (preferred)** — extract boundary calls into narrow purpose-specific interfaces (for example, `IProcessRunner`, `IFileSystem`, `IClock`). Keep interfaces minimal.
|
|
52
|
+
2. **Injectable delegate seam** — use a narrow `Func<>`/`Action<>` delegate for a single call path when a full interface is excessive. Default behavior must remain safe and deterministic.
|
|
53
|
+
3. **Adapter seam for static or third-party APIs** — wrap the static or third-party call behind a small adapter so tests can mock the adapter with Moq.
|
|
54
|
+
|
|
55
|
+
## Prohibited Behaviors
|
|
56
|
+
|
|
57
|
+
- Broad refactors across unrelated projects or files.
|
|
58
|
+
- Introducing heavy generic abstraction frameworks without need.
|
|
59
|
+
- Creating analyzer debt and deferring cleanup.
|
|
60
|
+
- Weakening assertions or relaxing test expectations to make tests pass.
|
|
61
|
+
- Adding sleeps, retries, or timing hacks to mask flaky behavior.
|
|
62
|
+
- Reporting success without running the required toolchain.
|