@danmoisan/drm-copilot-mcp 1.1.22 → 1.1.24
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/out/mcp-server.js +18758 -12030
- package/package.json +1 -1
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/MEMORY.md +1 -1
- package/resources/claude-customizations/.claude/agent-memory/orchestrator/feedback_test_files_count_against_500_cap.md +4 -4
- package/resources/claude-customizations/.claude/agents/csharp-typed-engineer.md +1 -1
- package/resources/claude-customizations/.claude/agents/discovery-capability-sentinel.md +34 -0
- package/resources/claude-customizations/.claude/agents/feature-review.md +8 -0
- package/resources/claude-customizations/.claude/agents/legacy-parity-analyst.md +101 -43
- package/resources/claude-customizations/.claude/agents/migration-coverage-reviewer.md +107 -43
- package/resources/claude-customizations/.claude/agents/orchestrator.md +1 -1
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +60 -6
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +21 -1
- package/resources/claude-customizations/.claude/agents/powershell-typed-engineer.md +1 -1
- package/resources/claude-customizations/.claude/agents/pr-author.md +48 -7
- package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +1 -1
- package/resources/claude-customizations/.claude/agents/requirements-reconciler.md +117 -42
- package/resources/claude-customizations/.claude/agents/runtime-characterization-analyst.md +103 -43
- package/resources/claude-customizations/.claude/hooks/discovery-capability-probe.ps1 +102 -0
- package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +69 -194
- package/resources/claude-customizations/.claude/hooks/enforce-discovery-planning-gate.ps1 +87 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-green-ci.ps1 +325 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +29 -7
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +23 -10
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +29 -21
- package/resources/claude-customizations/.claude/hooks/enforce-file-size-limit.ps1 +244 -0
- package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +51 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +168 -48
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +1 -1
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +22 -11
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +59 -20
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +51 -4
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +72 -11
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.current-branch.ps1 +149 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1 +4 -2
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +59 -20
- package/resources/claude-customizations/.claude/hooks/record-discovery-agent-start.ps1 +132 -0
- package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +56 -212
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-feature-folder.ps1 +146 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-rejection.ps1 +172 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +34 -4
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadius.psm1 +9 -3
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusAggregate.psm1 +154 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusCombination.psm1 +228 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +1 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusNormalization.psm1 +4 -2
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusScheduling.psm1 +63 -16
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +56 -1
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusWriteIntent.psm1 +4 -1
- package/resources/claude-customizations/.claude/lib/cleanup-manifest/CleanupWorktreeManifest.psm1 +33 -6
- package/resources/claude-customizations/.claude/lib/codex-routing/CodexDeployment.psm1 +5 -1
- package/resources/claude-customizations/.claude/lib/codex-routing/CodexDiscoveryRouting.psm1 +161 -0
- package/resources/claude-customizations/.claude/lib/codex-routing/CodexTopology.psm1 +25 -2
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthority.psd1 +90 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthority.psm1 +493 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthorization.psm1 +479 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryCapability.psm1 +468 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryEncoding.psm1 +156 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryManifest.psm1 +384 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryObservation.psm1 +217 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryPayload.psm1 +276 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryPlanning.psm1 +336 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryRootGrant.psm1 +164 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStart.psm1 +440 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStartRecord.psm1 +296 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStop.psm1 +336 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryToolRouting.psm1 +228 -0
- package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryValidation.psm1 +188 -341
- package/resources/claude-customizations/.claude/lib/file-size-policy/FileSizePolicy.psm1 +434 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateFeatureFolderRecord.psm1 +166 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +8 -3
- package/resources/claude-customizations/.claude/lib/worktree-resolution/HookTargetWorktree.psm1 +391 -0
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunRecordPath.psm1 +185 -0
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +11 -21
- package/resources/claude-customizations/.claude/rules/general-code-change.md +4 -1
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +29 -5
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +152 -20
- package/resources/claude-customizations/.claude/rules/powershell.md +1 -1
- package/resources/claude-customizations/.claude/rules/shell.md +1 -1
- package/resources/claude-customizations/.claude/settings.json +36 -3
- package/resources/claude-customizations/.claude/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
- package/resources/claude-customizations/.claude/skills/characterize-runtime-behavior/SKILL.md +134 -0
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +2 -2
- package/resources/claude-customizations/.claude/skills/discovery-behavior-reconciliation/SKILL.md +28 -47
- package/resources/claude-customizations/.claude/skills/discovery-coverage-ledger/SKILL.md +32 -48
- package/resources/claude-customizations/.claude/skills/discovery-parity-matrix/SKILL.md +28 -45
- package/resources/claude-customizations/.claude/skills/discovery-repo-inventory/SKILL.md +28 -62
- package/resources/claude-customizations/.claude/skills/discovery-runtime-characterization/SKILL.md +28 -45
- package/resources/claude-customizations/.claude/skills/discovery-validate-artifacts/SKILL.md +28 -61
- package/resources/claude-customizations/.claude/skills/discovery-workflow/SKILL.md +55 -139
- package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +25 -10
- package/resources/claude-customizations/.claude/skills/extract-feature-contract/SKILL.md +133 -0
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +1 -0
- package/resources/claude-customizations/.claude/skills/generate-acceptance-scenarios/SKILL.md +132 -0
- package/resources/claude-customizations/.claude/skills/initialize-discovery-workspace/SKILL.md +131 -0
- package/resources/claude-customizations/.claude/skills/inventory-legacy-system/SKILL.md +131 -0
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +15 -7
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +25 -2
- package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +11 -1
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +124 -14
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +72 -7
- package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +15 -0
- package/resources/claude-customizations/.claude/skills/parallel-run/SKILL.md +6 -0
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +56 -9
- package/resources/claude-customizations/.claude/skills/reconcile-parity-matrix/SKILL.md +131 -0
- package/resources/claude-customizations/.claude/skills/review-discovery-coverage/SKILL.md +129 -0
- package/resources/claude-customizations/.claude/skills/validate-discovery-artifacts/SKILL.md +127 -0
- package/resources/claude-customizations/.claude-variants/csharp-legacy/agents/csharp-typed-engineer.md +1 -1
- package/resources/claude-customizations/config/blast-radius.json +6 -5
- package/resources/claude-customizations/config/orchestration-routing.json +61 -1
- package/resources/claude-customizations/pack-manifests/core.json +40 -1
- package/resources/codex-and-agents-customizations/.agents/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +7 -0
- package/resources/codex-and-agents-customizations/.agents/skills/characterize-runtime-behavior/SKILL.md +134 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-behavior-reconciliation/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-coverage-ledger/SKILL.md +50 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-parity-matrix/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-repo-inventory/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-runtime-characterization/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-validate-artifacts/SKILL.md +46 -0
- package/resources/codex-and-agents-customizations/.agents/skills/discovery-workflow/SKILL.md +62 -0
- package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +25 -10
- package/resources/codex-and-agents-customizations/.agents/skills/extract-feature-contract/SKILL.md +133 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +8 -0
- package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +4 -1
- package/resources/codex-and-agents-customizations/.agents/skills/generate-acceptance-scenarios/SKILL.md +132 -0
- package/resources/codex-and-agents-customizations/.agents/skills/initialize-discovery-workspace/SKILL.md +131 -0
- package/resources/codex-and-agents-customizations/.agents/skills/inventory-legacy-system/SKILL.md +131 -0
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +8 -0
- package/resources/codex-and-agents-customizations/.agents/skills/powershell/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/reconcile-parity-matrix/SKILL.md +131 -0
- package/resources/codex-and-agents-customizations/.agents/skills/review-discovery-coverage/SKILL.md +129 -0
- package/resources/codex-and-agents-customizations/.agents/skills/validate-discovery-artifacts/SKILL.md +127 -0
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c1.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c2.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3-elevated.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c4.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/discovery-capability-sentinel.toml +51 -0
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +8 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c1.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c2.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c3-elevated.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c3.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c4.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst.toml +148 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c1.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c2.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c3-elevated.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c3.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c4.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer.toml +154 -0
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c1.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c2.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3-elevated.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c4.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c1.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c2.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3-elevated.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c4.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c1.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c2.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c3-elevated.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c3.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c4.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler.toml +164 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c1.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c2.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c3-elevated.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c3.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c4.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst.toml +150 -0
- package/resources/codex-and-agents-customizations/.codex/config.toml +39 -3
- package/resources/codex-and-agents-customizations/.codex/hooks/codex-agent-profile-attestation.ps1 +22 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/discovery-capability-probe.ps1 +97 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/discovery-start-attestation.ps1 +171 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +4 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-discovery-artifact-gate.ps1 +187 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-discovery-planning-gate.ps1 +149 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-file-size-limit.ps1 +282 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +239 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +6 -15
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +54 -15
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +54 -15
- package/resources/codex-and-agents-customizations/.codex/hooks/file-size-policy.ps1 +421 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-target-worktree.ps1 +369 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/record-subagent-routing-attestation.ps1 +8 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +22 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-discovery-agent-output.ps1 +178 -0
- package/resources/codex-and-agents-customizations/.codex/scripts/Resolve-CodexTopology.ps1 +11 -1
- package/resources/codex-and-agents-customizations/.codex-variants/csharp-legacy/agents/csharp-typed-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/AGENTS.md +4 -1
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +65 -1
- package/resources/config/orchestration-routing.json +61 -1
- package/resources/customizations/.github/agents/commentary-remediation.agent.md +1 -1
- package/resources/customizations/.github/agents/discovery-capability-sentinel.agent.md +34 -0
- package/resources/customizations/.github/agents/legacy-parity-analyst.agent.md +122 -0
- package/resources/customizations/.github/agents/migration-coverage-reviewer.agent.md +128 -0
- package/resources/customizations/.github/agents/python-execution-only-typed.agent.md +1 -1
- package/resources/customizations/.github/agents/python-typed-engineer.agent.md +1 -1
- package/resources/customizations/.github/agents/requirements-reconciler.agent.md +138 -0
- package/resources/customizations/.github/agents/runtime-characterization-analyst.agent.md +124 -0
- package/resources/customizations/.github/hooks/discovery-agent-start.ps1 +139 -0
- package/resources/customizations/.github/hooks/discovery-agent-stop.ps1 +123 -0
- package/resources/customizations/.github/hooks/discovery-capability-probe.ps1 +98 -0
- package/resources/customizations/.github/hooks/discovery-planning.ps1 +91 -0
- package/resources/customizations/.github/hooks/discovery-pre-tool.ps1 +123 -0
- package/resources/customizations/.github/hooks/discovery.json +35 -0
- package/resources/customizations/.github/instructions/general-code-change.instructions.md +5 -2
- package/resources/customizations/.github/instructions/mermaid.instructions.md +85 -0
- package/resources/customizations/.github/instructions/powershell-code-change.instructions.md +1 -1
- package/resources/customizations/.github/prompts/execute-hard-lock.prompt.md +105 -0
- package/resources/customizations/.github/prompts/remediate-comments.prompt.md +1 -1
- package/resources/customizations/.github/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
- package/resources/customizations/.github/skills/characterize-runtime-behavior/SKILL.md +134 -0
- package/resources/customizations/.github/skills/discovery-behavior-reconciliation/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-coverage-ledger/SKILL.md +50 -0
- package/resources/customizations/.github/skills/discovery-parity-matrix/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-repo-inventory/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-runtime-characterization/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-validate-artifacts/SKILL.md +46 -0
- package/resources/customizations/.github/skills/discovery-workflow/SKILL.md +62 -0
- package/resources/customizations/.github/skills/execution-environment/SKILL.md +25 -10
- package/resources/customizations/.github/skills/extract-feature-contract/SKILL.md +133 -0
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +8 -0
- package/resources/customizations/.github/skills/generate-acceptance-scenarios/SKILL.md +132 -0
- package/resources/customizations/.github/skills/initialize-discovery-workspace/SKILL.md +131 -0
- package/resources/customizations/.github/skills/inventory-legacy-system/SKILL.md +131 -0
- package/resources/customizations/.github/skills/reconcile-parity-matrix/SKILL.md +131 -0
- package/resources/customizations/.github/skills/review-discovery-coverage/SKILL.md +129 -0
- package/resources/customizations/.github/skills/validate-discovery-artifacts/SKILL.md +127 -0
- package/resources/lib/codex-routing/CodexDeployment.psm1 +5 -1
- package/resources/lib/codex-routing/CodexDiscoveryRouting.psm1 +161 -0
- package/resources/lib/codex-routing/CodexTopology.psm1 +25 -2
- package/resources/lib/discovery-validation/DiscoveryAuthority.psd1 +90 -0
- package/resources/lib/discovery-validation/DiscoveryAuthority.psm1 +493 -0
- package/resources/lib/discovery-validation/DiscoveryAuthorization.psm1 +479 -0
- package/resources/lib/discovery-validation/DiscoveryCapability.psm1 +468 -0
- package/resources/lib/discovery-validation/DiscoveryEncoding.psm1 +156 -0
- package/resources/lib/discovery-validation/DiscoveryManifest.psm1 +384 -0
- package/resources/lib/discovery-validation/DiscoveryObservation.psm1 +217 -0
- package/resources/lib/discovery-validation/DiscoveryPayload.psm1 +276 -0
- package/resources/lib/discovery-validation/DiscoveryPlanning.psm1 +336 -0
- package/resources/lib/discovery-validation/DiscoveryRootGrant.psm1 +164 -0
- package/resources/lib/discovery-validation/DiscoveryStart.psm1 +440 -0
- package/resources/lib/discovery-validation/DiscoveryStartRecord.psm1 +296 -0
- package/resources/lib/discovery-validation/DiscoveryStop.psm1 +336 -0
- package/resources/lib/discovery-validation/DiscoveryToolRouting.psm1 +228 -0
- package/resources/powershell/PoshQC/PoshQC.Parallel.psm1 +452 -0
- package/resources/powershell/PoshQC/PoshQC.Shard.psm1 +106 -8
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +12 -0
- package/resources/powershell/PoshQC/PoshQC.psd1 +6 -1
- package/resources/powershell/PoshQC/PoshQC.psm1 +7 -1
- package/resources/powershell/PoshQC/README.md +20 -1
- package/resources/templates/policy_audit/code-review.yyyy-MM-ddTHH-mm.md +4 -4
- package/resources/templates/policy_audit/policy-audit.yyyy-MM-ddTHH-mm.md +4 -4
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Planning-time issue combination over the scheduling pair data (issue #1013).
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
Destination-runtime PowerShell mirror of
|
|
7
|
+
scripts/dev_tools/_blast_radius_combination.py (spec D-5). Finds the pairs
|
|
8
|
+
of work items whose integration cost is high enough that delivering them as
|
|
9
|
+
one item costs less than merging them, and groups them into combinations.
|
|
10
|
+
|
|
11
|
+
Rules:
|
|
12
|
+
1. Disabled when conflict_tolerance is absent or tolerance_percent is 0.
|
|
13
|
+
2. Get-BlastRadiusPairDecision supplies each conflicting pair's reasons,
|
|
14
|
+
cost (including the D-7 contract term), and benefit; edges and
|
|
15
|
+
tolerated pairs are both evaluated.
|
|
16
|
+
3. A pair is a candidate when its full reasons contain
|
|
17
|
+
contract_dependency or it has a same-file overlap: an overlapping entry
|
|
18
|
+
pair, after the mergeable exclusion, of two equal concrete entries that
|
|
19
|
+
do not match append_only_paths.
|
|
20
|
+
4. A candidate qualifies when
|
|
21
|
+
cost * 100 >= benefit * combination_threshold_percent.
|
|
22
|
+
5. Qualifying pairs are grouped into connected components (union-find);
|
|
23
|
+
each becomes one combination with ascending members, primary equal to
|
|
24
|
+
the smallest member, pairs sorted by (a, b), and estimated_savings equal
|
|
25
|
+
to the sum of its pair costs.
|
|
26
|
+
|
|
27
|
+
Parity notes for maintainers:
|
|
28
|
+
- The Python module is the reference implementation; the committed
|
|
29
|
+
combination fixtures bind the two runtimes together.
|
|
30
|
+
- Every function is pure: no filesystem, subprocess, network, or clock
|
|
31
|
+
access, and no input is mutated.
|
|
32
|
+
CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
|
|
33
|
+
#>
|
|
34
|
+
|
|
35
|
+
Set-StrictMode -Version Latest
|
|
36
|
+
$ErrorActionPreference = 'Stop'
|
|
37
|
+
|
|
38
|
+
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force -ErrorAction Stop
|
|
39
|
+
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConflict.psm1') -Force -ErrorAction Stop
|
|
40
|
+
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusValidation.psm1') -Force -ErrorAction Stop
|
|
41
|
+
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusScheduling.psm1') -Force -ErrorAction Stop
|
|
42
|
+
|
|
43
|
+
# The threshold is a percentage of the pair benefit.
|
|
44
|
+
$script:Percent = 100
|
|
45
|
+
$script:ContractDependency = 'contract_dependency'
|
|
46
|
+
|
|
47
|
+
# Port of has_same_file_overlap: two equal, non-mergeable, non-append-only
|
|
48
|
+
# concrete entries among the overlapping pairs the relation enumerates.
|
|
49
|
+
function Test-SameFileOverlap {
|
|
50
|
+
[CmdletBinding()]
|
|
51
|
+
[OutputType([bool])]
|
|
52
|
+
param(
|
|
53
|
+
[Parameter(Mandatory = $true)]
|
|
54
|
+
[AllowNull()]
|
|
55
|
+
[object] $RadiusA,
|
|
56
|
+
[Parameter(Mandatory = $true)]
|
|
57
|
+
[AllowNull()]
|
|
58
|
+
[object] $RadiusB,
|
|
59
|
+
[Parameter(Mandatory = $true)]
|
|
60
|
+
[AllowNull()]
|
|
61
|
+
[object] $Config,
|
|
62
|
+
[Parameter(Mandatory = $true)]
|
|
63
|
+
[hashtable] $Tolerance
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
$left = ConvertTo-NormalizedBlastRadius -Radius $RadiusA
|
|
67
|
+
$right = ConvertTo-NormalizedBlastRadius -Radius $RadiusB
|
|
68
|
+
$mergeable = [string[]]@(Get-ConfigMergeablePath -Config $Config)
|
|
69
|
+
$pathsA = @(Get-NonMergeablePathEntry -Entry ([string[]]@($left['paths'])) -MergeablePath $mergeable)
|
|
70
|
+
$pathsB = @(Get-NonMergeablePathEntry -Entry ([string[]]@($right['paths'])) -MergeablePath $mergeable)
|
|
71
|
+
$appendOnly = [string[]]@($Tolerance['append_only_paths'])
|
|
72
|
+
foreach ($pair in @(Get-OverlappingPathPair -PathA $pathsA -PathB $pathsB)) {
|
|
73
|
+
$entry = [string]$pair['EntryA']
|
|
74
|
+
$isEqual = [string]::Equals($entry, [string]$pair['EntryB'], [System.StringComparison]::Ordinal)
|
|
75
|
+
if ($isEqual -and -not (Test-GlobEntry -Entry $entry) -and -not (Test-MergeablePath -Entry $entry -MergeablePath $appendOnly)) {
|
|
76
|
+
return $true
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return $false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Validate item keys (distinct integers) and return records sorted by key.
|
|
83
|
+
function Get-CombinationOrderedItem {
|
|
84
|
+
[CmdletBinding()]
|
|
85
|
+
[OutputType([System.Object[]])]
|
|
86
|
+
param(
|
|
87
|
+
[Parameter(Mandatory = $true)]
|
|
88
|
+
[AllowEmptyCollection()]
|
|
89
|
+
[object[]] $Item
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
$seen = [System.Collections.Generic.HashSet[long]]::new()
|
|
93
|
+
$record = foreach ($entry in $Item) {
|
|
94
|
+
$key = [long]$entry['key']
|
|
95
|
+
if (-not $seen.Add($key)) {
|
|
96
|
+
throw "combination item keys must be distinct: $key."
|
|
97
|
+
}
|
|
98
|
+
$band = if ($entry.Contains('band')) { $entry['band'] } else { $null }
|
|
99
|
+
@{ key = $key; radius = $entry['radius']; band = $band }
|
|
100
|
+
}
|
|
101
|
+
return @(@($record) | Where-Object { $null -ne $_ } | Sort-Object -Property { $_['key'] })
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Return the union-find root of Key, registering Key as its own root when new.
|
|
105
|
+
# Parent is the component's working map, owned by Get-CombinationComponent.
|
|
106
|
+
function Get-UnionFindRoot {
|
|
107
|
+
[CmdletBinding()]
|
|
108
|
+
[OutputType([long])]
|
|
109
|
+
param(
|
|
110
|
+
[Parameter(Mandatory = $true)]
|
|
111
|
+
[hashtable] $Parent,
|
|
112
|
+
[Parameter(Mandatory = $true)]
|
|
113
|
+
[long] $Key
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if (-not $Parent.ContainsKey($Key)) { $Parent[$Key] = $Key }
|
|
117
|
+
$root = $Key
|
|
118
|
+
while ($Parent[$root] -ne $root) { $root = $Parent[$root] }
|
|
119
|
+
return $root
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# Group qualifying pairs into connected components with union-find.
|
|
123
|
+
function Get-CombinationComponent {
|
|
124
|
+
[CmdletBinding()]
|
|
125
|
+
[OutputType([System.Object[]])]
|
|
126
|
+
param(
|
|
127
|
+
[Parameter(Mandatory = $true)]
|
|
128
|
+
[AllowEmptyCollection()]
|
|
129
|
+
[object[]] $Pair
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
$parent = @{}
|
|
133
|
+
foreach ($entry in $Pair) {
|
|
134
|
+
$rootA = Get-UnionFindRoot -Parent $parent -Key $entry['a']
|
|
135
|
+
$rootB = Get-UnionFindRoot -Parent $parent -Key $entry['b']
|
|
136
|
+
if ($rootA -ne $rootB) {
|
|
137
|
+
$parent[[System.Math]::Max($rootA, $rootB)] = [System.Math]::Min($rootA, $rootB)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
$grouped = @{}
|
|
142
|
+
foreach ($entry in $Pair) {
|
|
143
|
+
$root = Get-UnionFindRoot -Parent $parent -Key $entry['a']
|
|
144
|
+
if (-not $grouped.ContainsKey($root)) { $grouped[$root] = [System.Collections.Generic.List[object]]::new() }
|
|
145
|
+
$grouped[$root].Add($entry)
|
|
146
|
+
}
|
|
147
|
+
$combination = foreach ($root in @($grouped.Keys | Sort-Object)) {
|
|
148
|
+
$component = @($grouped[$root].ToArray() | Sort-Object -Property { $_['a'] }, { $_['b'] })
|
|
149
|
+
[long[]]$member = @($component | ForEach-Object { $_['a']; $_['b'] } | Sort-Object -Unique)
|
|
150
|
+
[long]$savings = 0
|
|
151
|
+
foreach ($entry in $component) { $savings += $entry['cost'] }
|
|
152
|
+
[ordered]@{ members = $member; primary = $member[0]; pairs = $component; estimated_savings = $savings }
|
|
153
|
+
}
|
|
154
|
+
return @($combination)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function Get-BlastRadiusCombination {
|
|
158
|
+
<#
|
|
159
|
+
.SYNOPSIS
|
|
160
|
+
Find the qualifying pairs of a set of items and group them.
|
|
161
|
+
|
|
162
|
+
.DESCRIPTION
|
|
163
|
+
Port of find_combinations. Visits every unordered pair once in ascending
|
|
164
|
+
key order and applies D-5 rules 1 to 5.
|
|
165
|
+
|
|
166
|
+
.PARAMETER Item
|
|
167
|
+
The run's items: records carrying key (an integer issue number), radius,
|
|
168
|
+
and an optional band.
|
|
169
|
+
|
|
170
|
+
.PARAMETER Config
|
|
171
|
+
Parsed truth table.
|
|
172
|
+
|
|
173
|
+
.PARAMETER Relation
|
|
174
|
+
The detection relation passed to every pair decision; pass
|
|
175
|
+
${function:Test-BlastRadiusConflict}.
|
|
176
|
+
|
|
177
|
+
.OUTPUTS
|
|
178
|
+
System.Collections.Hashtable. Keys pairs (ordered records a, b, cost,
|
|
179
|
+
benefit, sorted by (a, b)) and combinations (ordered records members,
|
|
180
|
+
primary, pairs, estimated_savings, sorted by primary). Both are empty
|
|
181
|
+
when combination is disabled.
|
|
182
|
+
#>
|
|
183
|
+
[CmdletBinding()]
|
|
184
|
+
[OutputType([hashtable])]
|
|
185
|
+
param(
|
|
186
|
+
[Parameter(Mandatory = $true)]
|
|
187
|
+
[AllowEmptyCollection()]
|
|
188
|
+
[object[]] $Item,
|
|
189
|
+
[Parameter(Mandatory = $true)]
|
|
190
|
+
[AllowNull()]
|
|
191
|
+
[object] $Config,
|
|
192
|
+
[scriptblock] $Relation
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
if ($null -eq $Relation) {
|
|
196
|
+
throw '-Relation is required: pass ${function:Test-BlastRadiusConflict} from the facade module BlastRadius.psm1.'
|
|
197
|
+
}
|
|
198
|
+
$tolerance = Get-ConfigConflictTolerance -Config $Config
|
|
199
|
+
$ordered = @(Get-CombinationOrderedItem -Item $Item)
|
|
200
|
+
# The absent key reads as the strict tolerance, whose percent is 0.
|
|
201
|
+
if ([long]$tolerance['tolerance_percent'] -eq 0) {
|
|
202
|
+
return @{ pairs = @(); combinations = @() }
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
$threshold = [long]$tolerance['combination_threshold_percent']
|
|
206
|
+
$qualifying = [System.Collections.Generic.List[object]]::new()
|
|
207
|
+
for ($first = 0; $first -lt $ordered.Count; $first++) {
|
|
208
|
+
for ($second = $first + 1; $second -lt $ordered.Count; $second++) {
|
|
209
|
+
$a = $ordered[$first]
|
|
210
|
+
$b = $ordered[$second]
|
|
211
|
+
$decision = Get-BlastRadiusPairDecision -RadiusA $a['radius'] -RadiusB $b['radius'] -Config $Config -BandA $a['band'] -BandB $b['band'] -Relation $Relation
|
|
212
|
+
if (-not $decision['conflict']) { continue }
|
|
213
|
+
# The full reasons are read, because contract_dependency is never first.
|
|
214
|
+
$isCandidate = @($decision['reasons']) -ccontains $script:ContractDependency
|
|
215
|
+
if (-not $isCandidate) {
|
|
216
|
+
$isCandidate = Test-SameFileOverlap -RadiusA $a['radius'] -RadiusB $b['radius'] -Config $Config -Tolerance $tolerance
|
|
217
|
+
}
|
|
218
|
+
if ($isCandidate -and ($decision['cost'] * $script:Percent -ge $decision['benefit'] * $threshold)) {
|
|
219
|
+
$qualifying.Add([ordered]@{ a = $a['key']; b = $b['key']; cost = [long]$decision['cost']; benefit = [long]$decision['benefit'] })
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
$pair = @($qualifying.ToArray())
|
|
225
|
+
return @{ pairs = $pair; combinations = @(Get-CombinationComponent -Pair $pair) }
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
Export-ModuleMember -Function Get-BlastRadiusCombination
|
package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusNormalization.psm1
CHANGED
|
@@ -120,10 +120,12 @@ function Get-ContractIdentifier {
|
|
|
120
120
|
# Inside a qualifying section an inline-code token without a separator is
|
|
121
121
|
# a contract identifier; a token with one is a path reference and is
|
|
122
122
|
# recorded at the paths level instead. A token carrying no ASCII letter
|
|
123
|
-
# is notation, not an identifier, and is dropped (issue #489)
|
|
123
|
+
# is notation, not an identifier, and is dropped (issue #489), as is a
|
|
124
|
+
# default spreadsheet sheet-tab name such as Sheet1 (issue #1006).
|
|
124
125
|
foreach ($token in @(Get-InlineCodeToken -Line $line)) {
|
|
125
126
|
if ($token.IndexOf('/') -lt 0 -and
|
|
126
|
-
$script:ContractLetterPattern.IsMatch($token)
|
|
127
|
+
$script:ContractLetterPattern.IsMatch($token) -and
|
|
128
|
+
-not (Test-GenericContractToken -Token $token)) {
|
|
127
129
|
$identifier.Add($token)
|
|
128
130
|
}
|
|
129
131
|
}
|
|
@@ -38,6 +38,7 @@ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1')
|
|
|
38
38
|
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConfig.psm1') -Force -ErrorAction Stop
|
|
39
39
|
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConflict.psm1') -Force -ErrorAction Stop
|
|
40
40
|
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusValidation.psm1') -Force -ErrorAction Stop
|
|
41
|
+
Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusAggregate.psm1') -Force -ErrorAction Stop
|
|
41
42
|
|
|
42
43
|
# Truth-table key and the label every reader error carries.
|
|
43
44
|
$script:ToleranceKey = 'conflict_tolerance'
|
|
@@ -46,9 +47,15 @@ $script:ToleranceLabel = 'config["conflict_tolerance"]'
|
|
|
46
47
|
# Member names of the key and of its two nested maps. Each must be carried
|
|
47
48
|
# exactly, so a misspelled name fails fast instead of reading as absent.
|
|
48
49
|
$script:MemberName = @('tolerance_percent', 'weights', 'band_durations', 'default_band', 'append_only_paths')
|
|
49
|
-
$script:WeightName = @('same_file', 'possible_overlap', 'append_only', 'module')
|
|
50
|
+
$script:WeightName = @('same_file', 'possible_overlap', 'append_only', 'module', 'contract')
|
|
50
51
|
$script:BandName = @('C1', 'C2', 'C3', 'C4')
|
|
51
52
|
|
|
53
|
+
# The one optional member (issue #1013): the issue-combination threshold, read
|
|
54
|
+
# as this default when absent. Pinned to COMBINATION_THRESHOLD_DEFAULT in the
|
|
55
|
+
# Python reference by a Pester parity row.
|
|
56
|
+
$script:CombinationThresholdName = 'combination_threshold_percent'
|
|
57
|
+
$script:CombinationThresholdDefault = 400
|
|
58
|
+
|
|
52
59
|
# Reason kinds that make a conflict an edge at every tolerance: a shared surface
|
|
53
60
|
# or a contract dependency cannot be reconciled by a merge step.
|
|
54
61
|
$script:HardReasonKind = @('shared_surface_overlap', 'contract_dependency')
|
|
@@ -140,15 +147,18 @@ function Get-ConfigConflictTolerance {
|
|
|
140
147
|
.DESCRIPTION
|
|
141
148
|
Port of config_conflict_tolerance. An absent or null key returns the
|
|
142
149
|
strict semantics: tolerance 0, every weight 1, every band duration 1,
|
|
143
|
-
default_band C1,
|
|
150
|
+
default_band C1, no append-only paths, and the default combination
|
|
151
|
+
threshold. combination_threshold_percent is optional: when present it
|
|
152
|
+
must be an integer of at least 0, and when absent it reads as 400.
|
|
144
153
|
|
|
145
154
|
.PARAMETER Config
|
|
146
155
|
Parsed config/blast-radius.json.
|
|
147
156
|
|
|
148
157
|
.OUTPUTS
|
|
149
158
|
System.Collections.Hashtable. Keys tolerance_percent, weights,
|
|
150
|
-
band_durations, default_band,
|
|
151
|
-
names the
|
|
159
|
+
band_durations, default_band, append_only_paths, and
|
|
160
|
+
combination_threshold_percent. Every error message names the
|
|
161
|
+
conflict_tolerance key.
|
|
152
162
|
#>
|
|
153
163
|
[CmdletBinding()]
|
|
154
164
|
[OutputType([hashtable])]
|
|
@@ -165,22 +175,32 @@ function Get-ConfigConflictTolerance {
|
|
|
165
175
|
foreach ($entry in $script:WeightName) { $unit[$entry] = [long]1 }
|
|
166
176
|
$band = @{}
|
|
167
177
|
foreach ($entry in $script:BandName) { $band[$entry] = [long]1 }
|
|
168
|
-
return @{ tolerance_percent = [long]0; weights = $unit; band_durations = $band; default_band = $script:BandName[0]; append_only_paths = [string[]]@() }
|
|
178
|
+
return @{ tolerance_percent = [long]0; weights = $unit; band_durations = $band; default_band = $script:BandName[0]; append_only_paths = [string[]]@(); combination_threshold_percent = [long]$script:CombinationThresholdDefault }
|
|
169
179
|
}
|
|
170
180
|
|
|
171
181
|
$member = Get-RequiredMapping -Value $value -FieldName $script:ToleranceLabel
|
|
172
|
-
|
|
182
|
+
# The optional member joins the exact name set only when it is present, so
|
|
183
|
+
# every other unknown name is still rejected.
|
|
184
|
+
$hasThreshold = $member.ContainsKey($script:CombinationThresholdName)
|
|
185
|
+
$names = if ($hasThreshold) { @($script:MemberName) + $script:CombinationThresholdName } else { $script:MemberName }
|
|
186
|
+
Assert-ExactMemberName -Mapping $member -Name $names -FieldName $script:ToleranceLabel
|
|
173
187
|
$defaultBand = $member['default_band']
|
|
174
188
|
if ($defaultBand -isnot [string] -or $script:BandName -cnotcontains $defaultBand) {
|
|
175
189
|
throw "$script:ToleranceLabel[""default_band""] must be one of $($script:BandName -join ', ')."
|
|
176
190
|
}
|
|
177
191
|
|
|
192
|
+
$threshold = [long]$script:CombinationThresholdDefault
|
|
193
|
+
if ($hasThreshold) {
|
|
194
|
+
$threshold = Get-RequiredInteger -Value $member[$script:CombinationThresholdName] -FieldName "$script:ToleranceLabel[""$script:CombinationThresholdName""]" -Minimum 0
|
|
195
|
+
}
|
|
196
|
+
|
|
178
197
|
return @{
|
|
179
|
-
tolerance_percent
|
|
180
|
-
weights
|
|
181
|
-
band_durations
|
|
182
|
-
default_band
|
|
183
|
-
append_only_paths
|
|
198
|
+
tolerance_percent = Get-RequiredInteger -Value $member['tolerance_percent'] -FieldName "$script:ToleranceLabel[""tolerance_percent""]" -Minimum 0
|
|
199
|
+
weights = Get-RequiredIntegerMap -Value $member['weights'] -Name $script:WeightName -Member 'weights'
|
|
200
|
+
band_durations = Get-RequiredIntegerMap -Value $member['band_durations'] -Name $script:BandName -Member 'band_durations'
|
|
201
|
+
default_band = [string]$defaultBand
|
|
202
|
+
append_only_paths = [string[]]@(Get-RequiredStringList -Value $member['append_only_paths'] -FieldName "$script:ToleranceLabel[""append_only_paths""]")
|
|
203
|
+
combination_threshold_percent = $threshold
|
|
184
204
|
}
|
|
185
205
|
}
|
|
186
206
|
|
|
@@ -221,7 +241,10 @@ function Get-BlastRadiusPairCost {
|
|
|
221
241
|
.DESCRIPTION
|
|
222
242
|
Port of pair_cost. Sums the weight of every overlapping path pair left
|
|
223
243
|
after the mergeable exclusion, then adds the module weight times the
|
|
224
|
-
number of shared modules
|
|
244
|
+
number of shared modules and the contract weight times the number of
|
|
245
|
+
distinct shared contract identifiers (the ordinal intersection the
|
|
246
|
+
relation reads for contract_dependency, each identifier counted once).
|
|
247
|
+
Mergeable paths therefore contribute 0.
|
|
225
248
|
|
|
226
249
|
.PARAMETER RadiusA
|
|
227
250
|
First radius record.
|
|
@@ -269,7 +292,10 @@ function Get-BlastRadiusPairCost {
|
|
|
269
292
|
$cost += Get-PathPairWeight -EntryA $pair['EntryA'] -EntryB $pair['EntryB'] -Tolerance $Tolerance
|
|
270
293
|
}
|
|
271
294
|
$sharedModule = @(@($left['modules']) | Where-Object { @($right['modules']) -ccontains $_ })
|
|
272
|
-
|
|
295
|
+
# Distinct shared contract identifiers, compared ordinally like the relation.
|
|
296
|
+
$sharedContract = [System.Collections.Generic.HashSet[string]]::new([string[]]@($left['contracts']), [StringComparer]::Ordinal)
|
|
297
|
+
$sharedContract.IntersectWith([string[]]@($right['contracts']))
|
|
298
|
+
return $cost + ([long]$Tolerance['weights']['module'] * $sharedModule.Count) + ([long]$Tolerance['weights']['contract'] * $sharedContract.Count)
|
|
273
299
|
}
|
|
274
300
|
|
|
275
301
|
function Get-BlastRadiusPairBenefit {
|
|
@@ -423,7 +449,9 @@ function Get-BlastRadiusConflictEdge {
|
|
|
423
449
|
Port of schedule_conflict_edges. Visits every unordered pair once in
|
|
424
450
|
ascending key order. A pair whose decision is an edge is recorded as an
|
|
425
451
|
edge; a conflict within tolerance is recorded as a tolerated overlap; a
|
|
426
|
-
pair that does not conflict appears in neither list.
|
|
452
|
+
pair that does not conflict appears in neither list. The aggregate cap
|
|
453
|
+
of BlastRadiusAggregate.psm1 (issue #1013) then promotes tolerated
|
|
454
|
+
overlaps until every item is within its cap.
|
|
427
455
|
|
|
428
456
|
.PARAMETER Item
|
|
429
457
|
The run's items: records carrying key (an integer issue number), radius,
|
|
@@ -454,7 +482,7 @@ function Get-BlastRadiusConflictEdge {
|
|
|
454
482
|
)
|
|
455
483
|
|
|
456
484
|
if ($null -eq $Relation) { throw $script:RelationRequired }
|
|
457
|
-
|
|
485
|
+
$tolerance = Get-ConfigConflictTolerance -Config $Config
|
|
458
486
|
$ordered = @(Get-OrderedSchedulingItem -Item $Item)
|
|
459
487
|
|
|
460
488
|
$edge = [System.Collections.Generic.List[object]]::new()
|
|
@@ -472,7 +500,26 @@ function Get-BlastRadiusConflictEdge {
|
|
|
472
500
|
}
|
|
473
501
|
}
|
|
474
502
|
|
|
475
|
-
|
|
503
|
+
# Aggregate cap post-pass (issue #1013, D-2): promote each cap-selected
|
|
504
|
+
# tolerated overlap to a non-hard edge carrying its first reason, then
|
|
505
|
+
# re-sort both lists by (a, b). At tolerance 0 nothing is tolerated.
|
|
506
|
+
$band = @{}
|
|
507
|
+
foreach ($entry in $ordered) { $band[$entry['key']] = $entry['band'] }
|
|
508
|
+
$promoted = [System.Collections.Generic.HashSet[string]]::new()
|
|
509
|
+
foreach ($pair in @(Get-AggregateCappedPair -ToleratedOverlap @($tolerated.ToArray()) -Band $band -Tolerance $tolerance)) {
|
|
510
|
+
[void]$promoted.Add(('{0}-{1}' -f $pair['a'], $pair['b']))
|
|
511
|
+
}
|
|
512
|
+
$kept = [System.Collections.Generic.List[object]]::new()
|
|
513
|
+
foreach ($overlap in $tolerated) {
|
|
514
|
+
if ($promoted.Contains(('{0}-{1}' -f $overlap['a'], $overlap['b']))) {
|
|
515
|
+
$edge.Add([ordered]@{ a = $overlap['a']; b = $overlap['b']; reason = @($overlap['reasons'])[0]; hard = $false; cost = $overlap['cost']; benefit = $overlap['benefit'] })
|
|
516
|
+
} else {
|
|
517
|
+
$kept.Add($overlap)
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
$sortedEdge = @($edge.ToArray() | Sort-Object -Property { $_['a'] }, { $_['b'] })
|
|
521
|
+
|
|
522
|
+
return @{ edges = $sortedEdge; tolerated_overlaps = @($kept.ToArray()) }
|
|
476
523
|
}
|
|
477
524
|
|
|
478
525
|
Export-ModuleMember -Function `
|
|
@@ -55,6 +55,12 @@
|
|
|
55
55
|
from the Python source and pins them equal. A non-ASCII extension is
|
|
56
56
|
rejected before lower-casing (issue #903); ToLowerInvariant then matches
|
|
57
57
|
Python's str.lower on ASCII input, and known-name membership is ordinal.
|
|
58
|
+
- Test-GenericContractToken (issue #1006) ports is_generic_contract_token.
|
|
59
|
+
Its stem array equals GENERIC_CONTRACT_STEMS; a Pester parity test reads
|
|
60
|
+
the Python constant from the source and pins $script:GenericContractStem
|
|
61
|
+
equal to it. A token is first checked ordinally to be ASCII, because a
|
|
62
|
+
.NET case-insensitive match folds the Kelvin sign and the long s to
|
|
63
|
+
ASCII letters while Python re.ASCII does not (the issue #903 precedent).
|
|
58
64
|
CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
|
|
59
65
|
#>
|
|
60
66
|
|
|
@@ -114,6 +120,20 @@ $script:KnownFileName = [System.Collections.Generic.HashSet[string]]::new(
|
|
|
114
120
|
),
|
|
115
121
|
[StringComparer]::Ordinal)
|
|
116
122
|
|
|
123
|
+
# Default spreadsheet sheet-tab stems (issue #1006). A spreadsheet application
|
|
124
|
+
# names a new worksheet or chart sheet with one of these stems followed by a
|
|
125
|
+
# number, so a spec that mentions Sheet1 names a worksheet, not a contract. The
|
|
126
|
+
# array is closed and is pinned equal to GENERIC_CONTRACT_STEMS in the Python
|
|
127
|
+
# reference by a Pester parity test, so edit both files together. The pattern is
|
|
128
|
+
# anchored with \A and \z to match Python's re.fullmatch, and the ASCII pattern
|
|
129
|
+
# is applied first with -cmatch so the comparison is ordinal.
|
|
130
|
+
$script:GenericContractStem = [string[]]@('Sheet', 'Chart')
|
|
131
|
+
$script:GenericContractPattern = [regex]::new(
|
|
132
|
+
'\A(?:' + ($script:GenericContractStem -join '|') + ')[0-9]+\z',
|
|
133
|
+
[System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor
|
|
134
|
+
[System.Text.RegularExpressions.RegexOptions]::CultureInvariant)
|
|
135
|
+
$script:AsciiOnlyPattern = '\A[\x00-\x7F]*\z'
|
|
136
|
+
|
|
117
137
|
function Test-PlaceholderMarker {
|
|
118
138
|
<#
|
|
119
139
|
.SYNOPSIS
|
|
@@ -263,7 +283,42 @@ function Test-FileShapedComponent {
|
|
|
263
283
|
return $script:FileExtensionPattern.IsMatch($extension.ToLowerInvariant())
|
|
264
284
|
}
|
|
265
285
|
|
|
286
|
+
function Test-GenericContractToken {
|
|
287
|
+
<#
|
|
288
|
+
.SYNOPSIS
|
|
289
|
+
Report whether a contract token is a default sheet-tab name (issue #1006).
|
|
290
|
+
|
|
291
|
+
.DESCRIPTION
|
|
292
|
+
Port of is_generic_contract_token. Two unrelated work items whose specs
|
|
293
|
+
both named the worksheet Sheet1 in an interface section were given a
|
|
294
|
+
hard contract_dependency edge, because the contract harvest accepts any
|
|
295
|
+
separator-free token carrying a letter. A default sheet-tab name
|
|
296
|
+
identifies no exported symbol, schema, or CLI identifier, so every
|
|
297
|
+
contract-filtering site rejects it with this predicate.
|
|
298
|
+
|
|
299
|
+
.PARAMETER Token
|
|
300
|
+
One candidate contract identifier. The empty string is accepted and
|
|
301
|
+
reports false.
|
|
302
|
+
|
|
303
|
+
.OUTPUTS
|
|
304
|
+
System.Boolean. True only when the token is ASCII and fully matches a
|
|
305
|
+
stem of $script:GenericContractStem followed by one or more ASCII
|
|
306
|
+
digits, compared case-insensitively; otherwise false.
|
|
307
|
+
#>
|
|
308
|
+
[CmdletBinding()]
|
|
309
|
+
[OutputType([bool])]
|
|
310
|
+
param(
|
|
311
|
+
[Parameter(Mandatory = $true)]
|
|
312
|
+
[AllowEmptyString()]
|
|
313
|
+
[string] $Token
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
if ($Token -cnotmatch $script:AsciiOnlyPattern) { return $false }
|
|
317
|
+
return $script:GenericContractPattern.IsMatch($Token)
|
|
318
|
+
}
|
|
319
|
+
|
|
266
320
|
Export-ModuleMember -Function `
|
|
267
321
|
Test-PlaceholderMarker, `
|
|
268
322
|
Test-MultipleFeatureFolderSpan, `
|
|
269
|
-
Test-FileShapedComponent
|
|
323
|
+
Test-FileShapedComponent, `
|
|
324
|
+
Test-GenericContractToken
|
package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusWriteIntent.psm1
CHANGED
|
@@ -343,9 +343,12 @@ function Get-WriteIntentSpecContract {
|
|
|
343
343
|
continue
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
+
# A default spreadsheet sheet-tab name such as Sheet1 is not a contract
|
|
347
|
+
# (issue #1006).
|
|
346
348
|
foreach ($token in @(Get-SingleWordToken -Line $line)) {
|
|
347
349
|
if ($token.IndexOf('/') -lt 0 -and $token.IndexOf('*') -lt 0 -and
|
|
348
|
-
$token.IndexOf('?') -lt 0 -and $script:ContractLetterPattern.IsMatch($token)
|
|
350
|
+
$token.IndexOf('?') -lt 0 -and $script:ContractLetterPattern.IsMatch($token) -and
|
|
351
|
+
-not (Test-GenericContractToken -Token $token)) {
|
|
349
352
|
$identifier.Add($token)
|
|
350
353
|
}
|
|
351
354
|
}
|
package/resources/claude-customizations/.claude/lib/cleanup-manifest/CleanupWorktreeManifest.psm1
CHANGED
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
throwing.
|
|
25
25
|
|
|
26
26
|
.NOTES
|
|
27
|
-
Compatible with PowerShell 7+.
|
|
28
|
-
and no network. The single filesystem read and the single wall-clock read each
|
|
27
|
+
Compatible with PowerShell 7+. Imports only the in-repository sibling
|
|
28
|
+
WorktreeRunRecordPath.psm1 (issue #995); no subprocess and no network. The single filesystem read and the single wall-clock read each
|
|
29
29
|
sit behind an injectable seam so tests drive them without writing a temporary
|
|
30
30
|
file. Mirrored byte-identically under
|
|
31
31
|
extensions/drm-copilot/resources/claude-customizations/.
|
|
@@ -35,6 +35,9 @@
|
|
|
35
35
|
Set-StrictMode -Version Latest
|
|
36
36
|
$ErrorActionPreference = 'Stop'
|
|
37
37
|
|
|
38
|
+
# The shared recorded-path matcher (issue #995), used by the checkpoint-coverage test.
|
|
39
|
+
Import-Module (Join-Path $PSScriptRoot '../worktree-resolution/WorktreeRunRecordPath.psm1') -ErrorAction Stop
|
|
40
|
+
|
|
38
41
|
# Repo-relative location of the sanctioned-removal manifest. Kept as a script-scope
|
|
39
42
|
# constant so the read seam is the only function that names the path.
|
|
40
43
|
$script:CleanupWorktreeManifestPath = 'artifacts/orchestration/cleanup-worktrees-manifest.json'
|
|
@@ -355,6 +358,14 @@ function Test-CleanupManifestCheckpointCoversPath {
|
|
|
355
358
|
the gate's existing deny. Reusing the gates' merge_status predicate here
|
|
356
359
|
would reopen the one path by which the manifest could widen what the gates
|
|
357
360
|
protect.
|
|
361
|
+
|
|
362
|
+
Case rule: a record covers the target when the shared matcher holds on the
|
|
363
|
+
inputs as given, or holds on the same inputs lower-cased with the invariant
|
|
364
|
+
culture. This keeps the exclusion at parity with
|
|
365
|
+
Find-CleanupWorktreeManifestRemovalRecord, which ignores case for every path,
|
|
366
|
+
so a record that differs from the target only by case still blocks the
|
|
367
|
+
manifest branch. The shared matcher itself stays ordinal for single-slash
|
|
368
|
+
POSIX paths because the gates' allow lookups must remain fail-closed.
|
|
358
369
|
.PARAMETER Checkpoint
|
|
359
370
|
Parsed checkpoint object, or $null when absent or unreadable.
|
|
360
371
|
.PARAMETER RecordArrayName
|
|
@@ -362,6 +373,10 @@ function Test-CleanupManifestCheckpointCoversPath {
|
|
|
362
373
|
for the parallel checkpoint.
|
|
363
374
|
.PARAMETER WorktreePath
|
|
364
375
|
The removal target extracted from the command text.
|
|
376
|
+
.PARAMETER BaseRoot
|
|
377
|
+
Optional. The roots a relative recorded worktree_path is joined to: the main
|
|
378
|
+
checkout root and the root that holds the checkpoint (issue #995). With none, a
|
|
379
|
+
relative record covers nothing and a rooted record compares as before.
|
|
365
380
|
.OUTPUTS
|
|
366
381
|
System.Boolean
|
|
367
382
|
#>
|
|
@@ -377,7 +392,11 @@ function Test-CleanupManifestCheckpointCoversPath {
|
|
|
377
392
|
|
|
378
393
|
[AllowNull()]
|
|
379
394
|
[AllowEmptyString()]
|
|
380
|
-
[string] $WorktreePath
|
|
395
|
+
[string] $WorktreePath,
|
|
396
|
+
|
|
397
|
+
[AllowNull()]
|
|
398
|
+
[AllowEmptyCollection()]
|
|
399
|
+
[string[]] $BaseRoot = @()
|
|
381
400
|
)
|
|
382
401
|
|
|
383
402
|
if ($null -eq $Checkpoint -or [string]::IsNullOrWhiteSpace($WorktreePath)) {
|
|
@@ -388,8 +407,10 @@ function Test-CleanupManifestCheckpointCoversPath {
|
|
|
388
407
|
return $false
|
|
389
408
|
}
|
|
390
409
|
|
|
391
|
-
$
|
|
410
|
+
$lowerBaseRoot = [string[]] @(@($BaseRoot) | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | ForEach-Object { $_.ToLowerInvariant() })
|
|
392
411
|
|
|
412
|
+
# Every record is compared through the shared matcher, so a relative record covers
|
|
413
|
+
# the absolute target it names under a base root, and an unsafe one covers nothing.
|
|
393
414
|
foreach ($record in @($Checkpoint.PSObject.Properties[$RecordArrayName].Value)) {
|
|
394
415
|
if ($null -eq $record) {
|
|
395
416
|
continue
|
|
@@ -398,8 +419,14 @@ function Test-CleanupManifestCheckpointCoversPath {
|
|
|
398
419
|
if ($recordProperties -notcontains 'worktree_path') {
|
|
399
420
|
continue
|
|
400
421
|
}
|
|
401
|
-
$
|
|
402
|
-
if ($
|
|
422
|
+
$recordedPath = [string]$record.worktree_path
|
|
423
|
+
if (Test-WorktreeRunRecordedPathMatchesTarget -RecordedPath $recordedPath -TargetPath $WorktreePath -BaseRoot $BaseRoot) {
|
|
424
|
+
return $true
|
|
425
|
+
}
|
|
426
|
+
# Case-insensitive parity with Find-CleanupWorktreeManifestRemovalRecord: the same
|
|
427
|
+
# inputs lower-cased with the invariant culture, so the exclusion is never narrower
|
|
428
|
+
# than the manifest lookup it guards.
|
|
429
|
+
if (Test-WorktreeRunRecordedPathMatchesTarget -RecordedPath $recordedPath.ToLowerInvariant() -TargetPath $WorktreePath.ToLowerInvariant() -BaseRoot $lowerBaseRoot) {
|
|
403
430
|
return $true
|
|
404
431
|
}
|
|
405
432
|
}
|
|
@@ -75,7 +75,11 @@ $script:GENERATED_AGENT_FAMILIES = @(
|
|
|
75
75
|
'python-typed-engineer',
|
|
76
76
|
'powershell-typed-engineer',
|
|
77
77
|
'csharp-typed-engineer',
|
|
78
|
-
'typescript-engineer'
|
|
78
|
+
'typescript-engineer',
|
|
79
|
+
'legacy-parity-analyst',
|
|
80
|
+
'runtime-characterization-analyst',
|
|
81
|
+
'requirements-reconciler',
|
|
82
|
+
'migration-coverage-reviewer'
|
|
79
83
|
)
|
|
80
84
|
$script:LOGICAL_AGENT_ALIASES = @{ 'feature-review' = 'feature-reviewer' }
|
|
81
85
|
|