@danmoisan/drm-copilot-mcp 1.1.25 → 1.1.27
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 +170 -52
- package/package.json +1 -1
- package/resources/claude-customizations/.claude/agents/atomic-executor.md +3 -3
- package/resources/claude-customizations/.claude/agents/atomic-planner.md +2 -2
- package/resources/claude-customizations/.claude/agents/csharp-typed-engineer.md +7 -7
- package/resources/claude-customizations/.claude/agents/feature-review.md +6 -3
- package/resources/claude-customizations/.claude/agents/orchestrator.md +11 -7
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +7 -3
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +6 -2
- package/resources/claude-customizations/.claude/agents/powershell-typed-engineer.md +7 -7
- package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +6 -6
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-review.ps1 +699 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +16 -1
- package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +41 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1 +481 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +3 -1
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier-helpers.ps1 +69 -3
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +2 -2
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.cleanup.ps1 +246 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +1 -0
- package/resources/claude-customizations/.claude/hooks/hook-cleanup-context.ps1 +343 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +50 -16
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1 +6 -1
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCompletion.psm1 +4 -2
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCompletionChecks.psm1 +51 -2
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateReceipts.psm1 +5 -2
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRemediationAccounting.psm1 +116 -4
- package/resources/claude-customizations/.claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 +626 -0
- package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmission.psm1 +508 -0
- package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmissionJson.psm1 +141 -0
- package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmissionPrecedence.psm1 +508 -0
- package/resources/claude-customizations/.claude/rules/csharp.md +8 -8
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +28 -2
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +17 -1
- package/resources/claude-customizations/.claude/rules/powershell.md +2 -2
- package/resources/claude-customizations/.claude/settings.json +1 -0
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +9 -13
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +93 -14
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup-worktrees.sh +23 -10
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_lib.sh +54 -46
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_merge_lib.sh +234 -0
- package/resources/claude-customizations/.claude/skills/csharp-qa-gate/SKILL.md +14 -15
- package/resources/claude-customizations/.claude/skills/epic-progress-report/SKILL.md +338 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.Logic.ps1 +248 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.Metrics.ps1 +232 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.Render.ps1 +196 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.State.ps1 +286 -0
- package/resources/claude-customizations/.claude/skills/epic-progress-report/scripts/Get-EpicProgressReport.ps1 +475 -0
- package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +31 -16
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +21 -9
- package/resources/claude-customizations/.claude/skills/invoke-csharp-engineer/SKILL.md +5 -5
- package/resources/claude-customizations/.claude/skills/invoke-powershell-engineer/SKILL.md +4 -4
- package/resources/claude-customizations/.claude/skills/invoke-python-engineer/SKILL.md +4 -4
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +24 -2
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +71 -7
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +34 -2
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +82 -12
- package/resources/claude-customizations/.claude/skills/powershell-qa-gate/SKILL.md +16 -17
- package/resources/claude-customizations/.claude/skills/python-qa-gate/SKILL.md +15 -16
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +1 -1
- package/resources/claude-customizations/.claude-variants/csharp-legacy/agents/csharp-typed-engineer.md +6 -6
- package/resources/claude-customizations/.claude-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +13 -14
- package/resources/claude-customizations/.claude-variants/csharp-legacy/skills/invoke-csharp-engineer/SKILL.md +4 -4
- package/resources/claude-customizations/pack-manifests/core.json +15 -0
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +8 -12
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +13 -14
- package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +31 -16
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +5 -1
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +18 -5
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-csharp-engineer/SKILL.md +4 -4
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-powershell-engineer/SKILL.md +4 -4
- package/resources/codex-and-agents-customizations/.agents/skills/invoke-python-engineer/SKILL.md +4 -4
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +24 -2
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-state/SKILL.md +16 -1
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +3 -3
- package/resources/codex-and-agents-customizations/.agents/skills/powershell/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-qa-gate/SKILL.md +15 -16
- package/resources/codex-and-agents-customizations/.agents/skills/python-qa-gate/SKILL.md +14 -15
- package/resources/codex-and-agents-customizations/.agents/skills/repo-automation-adapter/SKILL.md +2 -0
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +13 -14
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/invoke-csharp-engineer/SKILL.md +4 -4
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +3 -3
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-executor.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-orchestrator.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c1.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c2.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3-elevated.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c4.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-executor.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-di-unit-test-engineer.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-orchestrator.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c1.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c2.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3-elevated.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c4.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer.toml +7 -7
- package/resources/codex-and-agents-customizations/.codex/agents/pytest-unit-test-coding.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-executor.toml +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-execution-only-typed.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-orchestrator.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c1.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c2.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3-elevated.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c4.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate-review.ps1 +699 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +29 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1 +481 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +4 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-cleanup-context.ps1 +343 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +51 -4
- package/resources/codex-and-agents-customizations/.codex-variants/csharp-legacy/agents/csharp-typed-engineer.toml +6 -6
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +3 -0
- package/resources/customizations/.github/agents/5.1-Beast-adjusted.agent.md +1 -1
- package/resources/customizations/.github/agents/Powershell DI Unit Test Engineer.agent.md +20 -26
- package/resources/customizations/.github/agents/atomic_executor.agent.md +4 -4
- package/resources/customizations/.github/agents/atomic_planning.agent.md +4 -4
- package/resources/customizations/.github/agents/commentary-remediation.agent.md +1 -1
- package/resources/customizations/.github/agents/commit-steward.agent.md +1 -1
- package/resources/customizations/.github/agents/csharp-atomic-executor.agent.md +14 -14
- package/resources/customizations/.github/agents/csharp-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/csharp-orchestrator.agent.md +4 -4
- package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +19 -22
- package/resources/customizations/.github/agents/epic-review.agent.md +1 -1
- package/resources/customizations/.github/agents/gpt-5-beast-mode.agent.md +3 -3
- package/resources/customizations/.github/agents/orchestrator.agent.md +8 -8
- package/resources/customizations/.github/agents/powershell-atomic-executor.agent.md +12 -12
- package/resources/customizations/.github/agents/powershell-atomic-planning.agent.md +4 -4
- package/resources/customizations/.github/agents/powershell-orchestrator.agent.md +6 -6
- package/resources/customizations/.github/agents/powershell-typed-engineer.agent.md +21 -24
- package/resources/customizations/.github/agents/pytest-unit-test-coding.agent.md +13 -17
- package/resources/customizations/.github/agents/python-atomic-executor.agent.md +11 -11
- package/resources/customizations/.github/agents/python-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/python-execution-only-typed.agent.md +14 -17
- package/resources/customizations/.github/agents/python-orchestrator.agent.md +7 -7
- package/resources/customizations/.github/agents/python-typed-engineer.agent.md +17 -20
- package/resources/customizations/.github/agents/staged-review.agent.md +2 -2
- package/resources/customizations/.github/agents/tdd-green.agent.md +1 -1
- package/resources/customizations/.github/agents/tdd-red.agent.md +3 -3
- package/resources/customizations/.github/agents/tdd-refactor.agent.md +2 -2
- package/resources/customizations/.github/agents/typescript-engineer.agent.md +3 -3
- package/resources/customizations/.github/codex/execute-hard-lock.prompt.md +3 -3
- package/resources/customizations/.github/instructions/general-code-change.instructions.md +1 -1
- package/resources/customizations/.github/instructions/powershell-unit-test.instructions.md +1 -1
- package/resources/customizations/.github/instructions/python-code-change.instructions.md +5 -5
- package/resources/customizations/.github/instructions/python-suppressions.instructions.md +3 -3
- package/resources/customizations/.github/instructions/python-unit-test.instructions.md +1 -1
- package/resources/customizations/.github/prompts/execute-hard-lock.prompt.md +2 -2
- package/resources/customizations/.github/prompts/generate-commit-message-repo.prompt.md +2 -2
- package/resources/customizations/.github/prompts/remediate-comments.prompt.md +2 -2
- package/resources/customizations/.github/prompts/review-feature.prompt.md +1 -1
- package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +8 -12
- package/resources/customizations/.github/skills/execution-environment/SKILL.md +31 -16
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +15 -2
- package/resources/feature-templates/bug/plan.yyyy-MM-ddTHH-mm.md +4 -4
- package/resources/feature-templates/feature/plan.yyyy-MM-ddTHH-mm.md +3 -3
- package/resources/feature-templates/refactor/plan.yyyy-MM-ddTHH-mm.md +2 -2
- package/resources/powershell/PoshQC/PoshQC.ScanConfig.psm1 +3 -1
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +14 -12
- package/resources/powershell/PoshQC/PoshQC.psm1 +3 -3
- package/resources/powershell/PoshQC/README.md +8 -8
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +2 -2
- package/resources/templates/policy_audit/AGENTS.md +9 -10
- package/resources/templates/policy_audit/policy-audit.yyyy-MM-ddTHH-mm.md +19 -20
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Pure cleanup-context predicates shared by the cleanup legs of the enforcement gates (issue #1026).
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
The cleanup-merged-worktrees skill writes no per-feature, epic, or parallel checkpoint, so
|
|
7
|
+
the checkpoint-based gates cannot recognize its writes, commits, delegation, and pull
|
|
8
|
+
request. Its integrity record is the sanctioned-removal manifest. This file holds the pure
|
|
9
|
+
decisions the gates' cleanup legs share:
|
|
10
|
+
|
|
11
|
+
Test-CleanupManifestText - the manifest header (tool, schema_version) and,
|
|
12
|
+
with -UtcNow, its freshness and run_id.
|
|
13
|
+
Test-CleanupConsolidationRelativePath - the allowlist: the repository-relative prefixes
|
|
14
|
+
docs/ and .claude/agent-memory/ (ordinal,
|
|
15
|
+
case-sensitive), plus the pr-author receipt
|
|
16
|
+
artifacts/pr_body_<digits>.receipt.json with
|
|
17
|
+
-AllowReceipt.
|
|
18
|
+
Find-CleanupConsolidationRecord - the consolidation worktree, identified by its
|
|
19
|
+
porcelain branch, never by its path.
|
|
20
|
+
Test-CleanupScratchPath - the scratch rule: an absolute path outside every
|
|
21
|
+
registered worktree and the session root, under a
|
|
22
|
+
temporary root.
|
|
23
|
+
Test-CleanupConsolidationBranchLabel - the delegation label rule of the model-routing leg.
|
|
24
|
+
|
|
25
|
+
Every function fails closed: a malformed or ambiguous input answers $false or $null.
|
|
26
|
+
|
|
27
|
+
The literals below restate values owned elsewhere: the branch equals
|
|
28
|
+
CLEANUP_WT_CONSOLIDATION_BRANCH in
|
|
29
|
+
.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_actions_lib.sh, and the
|
|
30
|
+
manifest tool, schema version, and freshness bound equal $script:ExpectedManifestTool,
|
|
31
|
+
$script:ExpectedManifestSchemaVersion, and $script:ManifestFreshnessBound in
|
|
32
|
+
.claude/lib/cleanup-manifest/CleanupWorktreeManifest.psm1. The Codex hooks cannot import
|
|
33
|
+
.claude/lib, so the values are restated here and pinned equal by
|
|
34
|
+
tests/scripts/claude-hooks/hook-cleanup-context.Parity.Tests.ps1. The names avoid the
|
|
35
|
+
removal gates' $script:CleanupWorktreeManifestPath.
|
|
36
|
+
|
|
37
|
+
.NOTES
|
|
38
|
+
PowerShell 7+. Functions and literals only: no file, process, network, clock, or
|
|
39
|
+
environment access, no dot-source, and no import. Byte-identical at .claude/hooks,
|
|
40
|
+
.codex/hooks, and both bundle mirrors under extensions/drm-copilot/resources/.
|
|
41
|
+
#>
|
|
42
|
+
|
|
43
|
+
$script:CleanupContextBranch = 'documentationandmemories'
|
|
44
|
+
$script:CleanupContextManifestRelativePath = 'artifacts/orchestration/cleanup-worktrees-manifest.json'
|
|
45
|
+
$script:CleanupContextManifestTool = 'cleanup-merged-worktrees'
|
|
46
|
+
$script:CleanupContextManifestSchemaVersion = 1
|
|
47
|
+
$script:CleanupContextFreshnessHours = 24
|
|
48
|
+
|
|
49
|
+
function Test-CleanupManifestText {
|
|
50
|
+
<#
|
|
51
|
+
.SYNOPSIS
|
|
52
|
+
Return $true when the text is a cleanup manifest with the expected header.
|
|
53
|
+
.DESCRIPTION
|
|
54
|
+
The text must parse as a JSON object whose tool is the string cleanup-merged-worktrees
|
|
55
|
+
(ordinal) and whose schema_version is the integer 1. When -UtcNow is supplied, the
|
|
56
|
+
manifest must also carry a generated_at that parses, is not after UtcNow, and lies
|
|
57
|
+
within the freshness bound, and a run_id that is a non-blank string. The generated_at
|
|
58
|
+
value is read exactly as CleanupWorktreeManifest.psm1 reads it, so the PR and
|
|
59
|
+
delegation legs agree with the removal gates on freshness.
|
|
60
|
+
.PARAMETER Raw
|
|
61
|
+
The manifest text, or $null when no manifest exists.
|
|
62
|
+
.PARAMETER UtcNow
|
|
63
|
+
The current UTC time from the caller's clock seam.
|
|
64
|
+
.OUTPUTS
|
|
65
|
+
System.Boolean
|
|
66
|
+
#>
|
|
67
|
+
[CmdletBinding()]
|
|
68
|
+
[OutputType([bool])]
|
|
69
|
+
param(
|
|
70
|
+
[AllowNull()][AllowEmptyString()][string] $Raw,
|
|
71
|
+
[datetime] $UtcNow
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
if ([string]::IsNullOrWhiteSpace($Raw)) {
|
|
75
|
+
return $false
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
$manifest = $Raw | ConvertFrom-Json -ErrorAction Stop
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return $false
|
|
82
|
+
}
|
|
83
|
+
if ($manifest -isnot [System.Management.Automation.PSCustomObject]) {
|
|
84
|
+
return $false
|
|
85
|
+
}
|
|
86
|
+
$names = @($manifest.PSObject.Properties.Name)
|
|
87
|
+
if ($names -notcontains 'tool' -or $names -notcontains 'schema_version') {
|
|
88
|
+
return $false
|
|
89
|
+
}
|
|
90
|
+
if ($manifest.tool -isnot [string] -or $manifest.tool -cne $script:CleanupContextManifestTool) {
|
|
91
|
+
return $false
|
|
92
|
+
}
|
|
93
|
+
$schemaVersion = $manifest.schema_version
|
|
94
|
+
if (($schemaVersion -isnot [int] -and $schemaVersion -isnot [long]) -or [long]$schemaVersion -ne $script:CleanupContextManifestSchemaVersion) {
|
|
95
|
+
return $false
|
|
96
|
+
}
|
|
97
|
+
if (-not $PSBoundParameters.ContainsKey('UtcNow')) {
|
|
98
|
+
return $true
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if ($names -notcontains 'generated_at' -or $names -notcontains 'run_id') {
|
|
102
|
+
return $false
|
|
103
|
+
}
|
|
104
|
+
$generatedAt = [datetime]::MinValue
|
|
105
|
+
$styles = [System.Globalization.DateTimeStyles]::AdjustToUniversal -bor [System.Globalization.DateTimeStyles]::AssumeUniversal
|
|
106
|
+
if (-not [datetime]::TryParse([string]$manifest.generated_at, [cultureinfo]::InvariantCulture, $styles, [ref] $generatedAt)) {
|
|
107
|
+
return $false
|
|
108
|
+
}
|
|
109
|
+
if ($generatedAt -gt $UtcNow -or ($UtcNow - $generatedAt) -gt [timespan]::FromHours($script:CleanupContextFreshnessHours)) {
|
|
110
|
+
return $false
|
|
111
|
+
}
|
|
112
|
+
return ($manifest.run_id -is [string] -and -not [string]::IsNullOrWhiteSpace($manifest.run_id))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function Test-CleanupConsolidationRelativePath {
|
|
116
|
+
<#
|
|
117
|
+
.SYNOPSIS
|
|
118
|
+
Return $true when a repository-relative path is on the consolidation allowlist.
|
|
119
|
+
.DESCRIPTION
|
|
120
|
+
The path must use only the plain characters A-Z a-z 0-9 . _ / -, must not be rooted,
|
|
121
|
+
must carry no '..' segment, and must start with docs/ or .claude/agent-memory/ under
|
|
122
|
+
ordinal, case-sensitive comparison with at least one character after the prefix. Any
|
|
123
|
+
other Markdown path, such as CLAUDE.md or .claude/rules/x.md, is not admitted. With
|
|
124
|
+
-AllowReceipt the pr-author receipt artifacts/pr_body_<digits>.receipt.json is also
|
|
125
|
+
admitted; it never enters the staging allowlist.
|
|
126
|
+
.PARAMETER RelativePath
|
|
127
|
+
The repository-relative path or operand.
|
|
128
|
+
.PARAMETER AllowReceipt
|
|
129
|
+
Admit the pr-author receipt path (Write and Edit leg only).
|
|
130
|
+
.OUTPUTS
|
|
131
|
+
System.Boolean
|
|
132
|
+
#>
|
|
133
|
+
[CmdletBinding()]
|
|
134
|
+
[OutputType([bool])]
|
|
135
|
+
param(
|
|
136
|
+
[AllowNull()][AllowEmptyString()][string] $RelativePath,
|
|
137
|
+
[switch] $AllowReceipt
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
$path = [string]$RelativePath
|
|
141
|
+
if ($path -cnotmatch '^[A-Za-z0-9._/-]+$' -or $path.StartsWith('/')) {
|
|
142
|
+
return $false
|
|
143
|
+
}
|
|
144
|
+
if (@($path -split '/') -contains '..') {
|
|
145
|
+
return $false
|
|
146
|
+
}
|
|
147
|
+
if ($AllowReceipt -and $path -cmatch '^artifacts/pr_body_[0-9]+\.receipt\.json$') {
|
|
148
|
+
return $true
|
|
149
|
+
}
|
|
150
|
+
foreach ($prefix in @('docs/', '.claude/agent-memory/')) {
|
|
151
|
+
if ($path.Length -gt $prefix.Length -and $path.StartsWith($prefix, [System.StringComparison]::Ordinal)) {
|
|
152
|
+
return $true
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return $false
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function Find-CleanupConsolidationRecord {
|
|
159
|
+
<#
|
|
160
|
+
.SYNOPSIS
|
|
161
|
+
Return the registered consolidation worktree record, or $null.
|
|
162
|
+
.DESCRIPTION
|
|
163
|
+
Takes the records ConvertFrom-HookTargetWorktreePorcelain emits. The first record (the
|
|
164
|
+
main worktree stanza), prunable records, and detached records are skipped. The single
|
|
165
|
+
remaining record whose Branch is ordinal-equal to documentationandmemories is returned;
|
|
166
|
+
none, or more than one, returns $null. The path is never consulted, because the
|
|
167
|
+
consolidation path can be overridden by CLEANUP_WT_CONSOLIDATION_PATH.
|
|
168
|
+
.PARAMETER Record
|
|
169
|
+
The porcelain records, in listing order.
|
|
170
|
+
.OUTPUTS
|
|
171
|
+
System.Management.Automation.PSCustomObject or $null
|
|
172
|
+
#>
|
|
173
|
+
[CmdletBinding()]
|
|
174
|
+
[OutputType([pscustomobject])]
|
|
175
|
+
param(
|
|
176
|
+
[AllowNull()][AllowEmptyCollection()][object[]] $Record
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
$records = @($Record | Where-Object { $null -ne $_ })
|
|
180
|
+
$found = [System.Collections.Generic.List[object]]::new()
|
|
181
|
+
for ($index = 1; $index -lt $records.Count; $index++) {
|
|
182
|
+
$candidate = $records[$index]
|
|
183
|
+
if ([bool]$candidate.Prunable -or $null -eq $candidate.Branch) {
|
|
184
|
+
continue
|
|
185
|
+
}
|
|
186
|
+
if ([string]$candidate.Branch -ceq $script:CleanupContextBranch) {
|
|
187
|
+
$found.Add($candidate)
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if ($found.Count -ne 1) {
|
|
191
|
+
return $null
|
|
192
|
+
}
|
|
193
|
+
return $found[0]
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function ConvertTo-CleanupContextPath {
|
|
197
|
+
<#
|
|
198
|
+
.SYNOPSIS
|
|
199
|
+
Normalize a path to forward slashes with one trailing slash removed (bare roots kept).
|
|
200
|
+
.OUTPUTS
|
|
201
|
+
System.String
|
|
202
|
+
#>
|
|
203
|
+
[CmdletBinding()]
|
|
204
|
+
[OutputType([string])]
|
|
205
|
+
param(
|
|
206
|
+
[AllowNull()][AllowEmptyString()][string] $Path
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
$normalized = ([string]$Path).Replace('\', '/')
|
|
210
|
+
if ($normalized.Length -gt 1 -and $normalized.EndsWith('/') -and $normalized -notmatch '^[A-Za-z]:/$') {
|
|
211
|
+
$normalized = $normalized.Substring(0, $normalized.Length - 1)
|
|
212
|
+
}
|
|
213
|
+
return $normalized
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function Test-CleanupContextPathUnder {
|
|
217
|
+
<#
|
|
218
|
+
.SYNOPSIS
|
|
219
|
+
Return $true when a normalized path equals a root or lies beneath it (OrdinalIgnoreCase).
|
|
220
|
+
.OUTPUTS
|
|
221
|
+
System.Boolean
|
|
222
|
+
#>
|
|
223
|
+
[CmdletBinding()]
|
|
224
|
+
[OutputType([bool])]
|
|
225
|
+
param(
|
|
226
|
+
[Parameter(Mandatory)][AllowEmptyString()][string] $Path,
|
|
227
|
+
[AllowNull()][AllowEmptyString()][string] $Root
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
$normalizedRoot = ConvertTo-CleanupContextPath -Path $Root
|
|
231
|
+
if ([string]::IsNullOrEmpty($normalizedRoot)) {
|
|
232
|
+
return $false
|
|
233
|
+
}
|
|
234
|
+
if ([string]::Equals($Path, $normalizedRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
235
|
+
return $true
|
|
236
|
+
}
|
|
237
|
+
$prefix = if ($normalizedRoot.EndsWith('/')) { $normalizedRoot } else { $normalizedRoot + '/' }
|
|
238
|
+
return $Path.StartsWith($prefix, [System.StringComparison]::OrdinalIgnoreCase)
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function Test-CleanupScratchPath {
|
|
242
|
+
<#
|
|
243
|
+
.SYNOPSIS
|
|
244
|
+
Return $true when a path is a scratch path under a temporary root and outside every worktree.
|
|
245
|
+
.DESCRIPTION
|
|
246
|
+
The path must be absolute (drive-rooted or slash-rooted, not UNC), carry no '.' or '..'
|
|
247
|
+
segment and no surrounding whitespace, lie outside every registered worktree root and
|
|
248
|
+
outside the session root, and lie under at least one accepted temporary-root spelling.
|
|
249
|
+
Comparisons use forward-slash normalization and OrdinalIgnoreCase. The rule fails
|
|
250
|
+
closed when no registered root or no temporary root is supplied, and when any
|
|
251
|
+
registered worktree root lies under an accepted temporary root, because a path under
|
|
252
|
+
such a worktree could then be spelled so that it matches no registered root.
|
|
253
|
+
.PARAMETER Path
|
|
254
|
+
The Write or Edit file path.
|
|
255
|
+
.PARAMETER RegisteredRoot
|
|
256
|
+
Every registered worktree root from the listing, prunable ones included.
|
|
257
|
+
.PARAMETER SessionRoot
|
|
258
|
+
The session root.
|
|
259
|
+
.PARAMETER TemporaryRoot
|
|
260
|
+
Every accepted spelling of the operating-system temporary root.
|
|
261
|
+
.OUTPUTS
|
|
262
|
+
System.Boolean
|
|
263
|
+
#>
|
|
264
|
+
[CmdletBinding()]
|
|
265
|
+
[OutputType([bool])]
|
|
266
|
+
param(
|
|
267
|
+
[AllowNull()][AllowEmptyString()][string] $Path,
|
|
268
|
+
[AllowNull()][AllowEmptyCollection()][string[]] $RegisteredRoot,
|
|
269
|
+
[AllowNull()][AllowEmptyString()][string] $SessionRoot,
|
|
270
|
+
[AllowNull()][AllowEmptyCollection()][string[]] $TemporaryRoot
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
$raw = [string]$Path
|
|
274
|
+
if ([string]::IsNullOrEmpty($raw) -or $raw.Trim() -cne $raw) {
|
|
275
|
+
return $false
|
|
276
|
+
}
|
|
277
|
+
$normalized = ConvertTo-CleanupContextPath -Path $raw
|
|
278
|
+
if ($normalized -notmatch '^([A-Za-z]:/|/(?!/))') {
|
|
279
|
+
return $false
|
|
280
|
+
}
|
|
281
|
+
$segments = @($normalized -split '/')
|
|
282
|
+
if ($segments -contains '.' -or $segments -contains '..') {
|
|
283
|
+
return $false
|
|
284
|
+
}
|
|
285
|
+
$roots = @($RegisteredRoot | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
|
|
286
|
+
$temporary = @($TemporaryRoot | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
|
|
287
|
+
if ($roots.Count -eq 0 -or $temporary.Count -eq 0 -or [string]::IsNullOrWhiteSpace($SessionRoot)) {
|
|
288
|
+
return $false
|
|
289
|
+
}
|
|
290
|
+
foreach ($registeredCandidate in $roots) {
|
|
291
|
+
$normalizedRoot = ConvertTo-CleanupContextPath -Path $registeredCandidate
|
|
292
|
+
foreach ($temporaryCandidate in $temporary) {
|
|
293
|
+
if (Test-CleanupContextPathUnder -Path $normalizedRoot -Root $temporaryCandidate) {
|
|
294
|
+
return $false
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (Test-CleanupContextPathUnder -Path $normalized -Root $registeredCandidate) {
|
|
298
|
+
return $false
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (Test-CleanupContextPathUnder -Path $normalized -Root $SessionRoot) {
|
|
302
|
+
return $false
|
|
303
|
+
}
|
|
304
|
+
foreach ($temporaryCandidate in $temporary) {
|
|
305
|
+
$normalizedTemporary = ConvertTo-CleanupContextPath -Path $temporaryCandidate
|
|
306
|
+
if (-not [string]::Equals($normalized, $normalizedTemporary, [System.StringComparison]::OrdinalIgnoreCase) -and
|
|
307
|
+
(Test-CleanupContextPathUnder -Path $normalized -Root $normalizedTemporary)) {
|
|
308
|
+
return $true
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return $false
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function Test-CleanupConsolidationBranchLabel {
|
|
315
|
+
<#
|
|
316
|
+
.SYNOPSIS
|
|
317
|
+
Return $true when a delegation prompt names the consolidation branch by exactly one label.
|
|
318
|
+
.DESCRIPTION
|
|
319
|
+
The prompt must contain exactly one 'branch:' label (case-insensitive count), on its own
|
|
320
|
+
line in the lowercase form 'branch: <value>', with the value ordinal-equal to
|
|
321
|
+
documentationandmemories, and no --head or --branch token anywhere, so the worktree
|
|
322
|
+
resolvers that read the first branch signal cannot select a different branch.
|
|
323
|
+
.PARAMETER PromptText
|
|
324
|
+
The delegation prompt.
|
|
325
|
+
.OUTPUTS
|
|
326
|
+
System.Boolean
|
|
327
|
+
#>
|
|
328
|
+
[CmdletBinding()]
|
|
329
|
+
[OutputType([bool])]
|
|
330
|
+
param(
|
|
331
|
+
[AllowNull()][AllowEmptyString()][string] $PromptText
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
$text = [string]$PromptText
|
|
335
|
+
if ([regex]::Matches($text, '(?i)\bbranch:').Count -ne 1) {
|
|
336
|
+
return $false
|
|
337
|
+
}
|
|
338
|
+
if ([regex]::IsMatch($text, '(?i)(?<![\w-])--(?:head|branch)(?![\w-])')) {
|
|
339
|
+
return $false
|
|
340
|
+
}
|
|
341
|
+
$label = [regex]::Match($text, '(?m)^[ \t]*branch:[ \t]*(?<value>[^\r\n]*?)[ \t]*\r?$')
|
|
342
|
+
return ($label.Success -and $label.Groups['value'].Value -ceq $script:CleanupContextBranch)
|
|
343
|
+
}
|
package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
<#
|
|
2
2
|
.SYNOPSIS
|
|
3
|
-
Artifact-path rules, changed-language set, and coverage-row rule for the
|
|
3
|
+
Artifact-path rules, changed-language set, narrowing-line reader, and coverage-row rule for the
|
|
4
|
+
feature-review coverage hook.
|
|
4
5
|
|
|
5
6
|
.DESCRIPTION
|
|
6
7
|
Dot-sourced by validate-feature-review-coverage.ps1. Defines the advertised-path reader
|
|
7
8
|
(Get-ReviewArtifactPathFromOutput), the active-feature location rule (Get-ReviewArtifactInfo),
|
|
8
|
-
the changed-language reader for the PR context summary (Get-ChangedLanguageSet),
|
|
9
|
-
per-language coverage-row
|
|
9
|
+
the changed-language reader for the PR context summary (Get-ChangedLanguageSet), the
|
|
10
|
+
scope-narrowing line reader (Get-CoverageNarrowingLine), and the per-language coverage-row
|
|
11
|
+
rule (Test-LanguageCoverageRow).
|
|
10
12
|
|
|
11
13
|
The file has no param() block, writes nothing to the output stream, and runs no top-level
|
|
12
14
|
statement other than function definitions.
|
|
@@ -95,6 +97,50 @@ function Get-ChangedLanguageSet {
|
|
|
95
97
|
return $langs
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
function Get-CoverageNarrowingLine {
|
|
101
|
+
[CmdletBinding()]
|
|
102
|
+
[OutputType([string])]
|
|
103
|
+
param(
|
|
104
|
+
[Parameter(Mandatory = $true)]
|
|
105
|
+
[AllowEmptyString()]
|
|
106
|
+
[string[]]$Lines,
|
|
107
|
+
|
|
108
|
+
[Parameter(Mandatory = $true)]
|
|
109
|
+
[string]$LabelPattern,
|
|
110
|
+
|
|
111
|
+
[Parameter(Mandatory = $true)]
|
|
112
|
+
[string]$Language
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# Sanctioned narrowing text is not a scope narrowing by the audit: a line inside a
|
|
116
|
+
# '## Rejected Scope Narrowing' section (caller text recorded verbatim), and a PowerShell
|
|
117
|
+
# line naming branch coverage but not line coverage (Pester measures no branch coverage).
|
|
118
|
+
# The policy-audit template prescribes the no-pre-change-run record in three positions only,
|
|
119
|
+
# so the record is removed there and stays a narrowing form everywhere else.
|
|
120
|
+
$narrowingPattern = '(?i)(informational only|context only|out of plan scope|out of scope|not applicable|\bN/A\b|\bUNVERIFIED\b)'
|
|
121
|
+
$recordPatterns = @(
|
|
122
|
+
'(?<=(?:\bBaseline|\bbaseline coverage artifact):\s*)N/A - no pre-change run'
|
|
123
|
+
'(?<=^\s*\|(?:[^|]*\|){4}\s*)N/A - no pre-change run(?=\s*\|)'
|
|
124
|
+
'(?<!:\s*)`N/A - no pre-change run`'
|
|
125
|
+
)
|
|
126
|
+
$insideRejectedSection = $false
|
|
127
|
+
foreach ($line in $Lines) {
|
|
128
|
+
if ($line -match '^##\s') { $insideRejectedSection = $line -match '^##\s+Rejected Scope Narrowing\b' }
|
|
129
|
+
elseif ($insideRejectedSection) { continue }
|
|
130
|
+
if ($line -notmatch $LabelPattern -or $line -notmatch '(?i)(coverage|lcov|line[s]?\s+hit|pester)') { continue }
|
|
131
|
+
$reducedLine = $line
|
|
132
|
+
foreach ($recordPattern in $recordPatterns) { $reducedLine = [regex]::Replace($reducedLine, $recordPattern, '') }
|
|
133
|
+
# Tested on the original line, because the removals above strip the record it names.
|
|
134
|
+
if ($line.Contains('Baseline: N/A - no pre-change run')) {
|
|
135
|
+
$reducedLine = [regex]::Replace($reducedLine, '(?<![\w/-])Change: N/A', '')
|
|
136
|
+
$reducedLine = $reducedLine.Replace('New/changed-code coverage: N/A - no production file changed', '')
|
|
137
|
+
}
|
|
138
|
+
if ($reducedLine -notmatch $narrowingPattern) { continue }
|
|
139
|
+
if ($Language -eq 'PowerShell' -and $line -match '(?i)\bbranch\b' -and $line -notmatch '(?i)\bline\s+coverage\b') { continue }
|
|
140
|
+
$line
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
98
144
|
function Test-LanguageCoverageRow {
|
|
99
145
|
[OutputType([System.Collections.Hashtable])]
|
|
100
146
|
param(
|
|
@@ -141,19 +187,7 @@ function Test-LanguageCoverageRow {
|
|
|
141
187
|
}
|
|
142
188
|
}
|
|
143
189
|
|
|
144
|
-
|
|
145
|
-
# '## Rejected Scope Narrowing' section (caller text recorded verbatim), and a PowerShell
|
|
146
|
-
# line naming branch coverage but not line coverage (Pester measures no branch coverage).
|
|
147
|
-
$narrowingPattern = '(?i)(informational only|context only|out of plan scope|out of scope|not applicable|\bN/A\b|\bUNVERIFIED\b)'
|
|
148
|
-
$insideRejectedSection = $false
|
|
149
|
-
$narrowing = foreach ($line in $lines) {
|
|
150
|
-
if ($line -match '^##\s') { $insideRejectedSection = $line -match '^##\s+Rejected Scope Narrowing\b' }
|
|
151
|
-
elseif ($insideRejectedSection) { continue }
|
|
152
|
-
if ($line -notmatch $labelPattern -or $line -notmatch '(?i)(coverage|lcov|line[s]?\s+hit|pester)' -or $line -notmatch $narrowingPattern) { continue }
|
|
153
|
-
if ($Language -eq 'PowerShell' -and $line -match '(?i)\bbranch\b' -and $line -notmatch '(?i)\bline\s+coverage\b') { continue }
|
|
154
|
-
$line
|
|
155
|
-
}
|
|
156
|
-
$narrowing = @($narrowing)
|
|
190
|
+
$narrowing = @(Get-CoverageNarrowingLine -Lines $lines -LabelPattern $labelPattern -Language $Language)
|
|
157
191
|
if ($narrowing.Count -gt 0) {
|
|
158
192
|
$first = ($narrowing | Select-Object -First 1).ToString().Trim()
|
|
159
193
|
return @{
|
package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1
CHANGED
|
@@ -297,7 +297,8 @@ function Get-OrchestratorStatePrCreationReadinessError {
|
|
|
297
297
|
.DESCRIPTION
|
|
298
298
|
Private readiness check mirroring validate_orchestrator_state_pr_creation_readiness in
|
|
299
299
|
_orchestrator_state_pr_creation_readiness.py: steps 5-8 must not be pending, blocked, or
|
|
300
|
-
blocked_remediation_loop_limit
|
|
300
|
+
blocked_remediation_loop_limit, except a pending step 7 under review_mode concurrent;
|
|
301
|
+
blocked_reason must be `none` or absent; and the
|
|
301
302
|
local_execution_overrides / delegation_bypasses lists must be empty when present. It does
|
|
302
303
|
not enforce completion, CI, PR, or routing-contract gates.
|
|
303
304
|
.PARAMETER State
|
|
@@ -313,11 +314,15 @@ function Get-OrchestratorStatePrCreationReadinessError {
|
|
|
313
314
|
)
|
|
314
315
|
|
|
315
316
|
$errors = [System.Collections.Generic.List[string]]::new()
|
|
317
|
+
$stateNames = @($State.PSObject.Properties | ForEach-Object { $_.Name })
|
|
318
|
+
$reviewMode = if ($stateNames -ccontains 'review_mode') { (Get-OrchestratorStateField -State $State -Name 'review_mode').Value } else { $null }
|
|
316
319
|
|
|
317
320
|
# Reject an upstream step recorded as pending, blocked, or blocked_remediation_loop_limit; steps
|
|
318
321
|
# 5-8 must have finished before the first PR of a branch is created.
|
|
319
322
|
foreach ($key in $script:PR_CREATION_READY_STEP_KEYS) {
|
|
320
323
|
$field = Get-OrchestratorStateField -State $State -Name $key
|
|
324
|
+
# Under review_mode concurrent the review runs beside CI and the merge guard holds the merge.
|
|
325
|
+
if ($key -ceq 'step7_status' -and $field.Value -ceq 'pending' -and $reviewMode -is [string] -and $reviewMode -ceq 'concurrent') { continue }
|
|
321
326
|
if ($field.Present -and (@('pending', 'blocked', 'blocked_remediation_loop_limit') -contains $field.Value)) {
|
|
322
327
|
$errors.Add("Checkpoint PR-creation readiness validation failed: $key is $($field.Value).")
|
|
323
328
|
}
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
C5 mandatory route phases
|
|
24
24
|
C6 the routing contract, from `OrchestratorStateRoutingContract.psm1`
|
|
25
25
|
C7 the preparation terminal contract
|
|
26
|
+
C8 the review record under review_mode concurrent
|
|
26
27
|
M1 model-routing receipt required once delegated
|
|
27
28
|
M2 a complexity assessment for every matched receipt phase
|
|
28
29
|
M3 per-entry re-validation of the U6.C and U6.M families
|
|
@@ -408,8 +409,8 @@ function Test-OrchestratorStateCompletionReadiness {
|
|
|
408
409
|
$errors.AddRange([string[]]@(Get-OrchestratorStateUnconditionalError -State $state))
|
|
409
410
|
|
|
410
411
|
# C family, in the reference's require_complete order: step statuses,
|
|
411
|
-
# blocked_reason, pr_gate, ci_gate, phase completeness, routing contract,
|
|
412
|
-
#
|
|
412
|
+
# blocked_reason, pr_gate, ci_gate, phase completeness, routing contract, the
|
|
413
|
+
# preparation terminal contract, and the concurrent review record.
|
|
413
414
|
$errors.AddRange([string[]]@(Get-OrchestratorStateCompletionStepStatusError -State $state))
|
|
414
415
|
$errors.AddRange([string[]]@(Get-OrchestratorStateCompletionBlockedReasonError -State $state))
|
|
415
416
|
$errors.AddRange([string[]]@(Get-OrchestratorStateCompletionPrGateError -State $state))
|
|
@@ -417,6 +418,7 @@ function Test-OrchestratorStateCompletionReadiness {
|
|
|
417
418
|
$errors.AddRange([string[]]@(Get-OrchestratorStatePhaseCompletenessError -State $state))
|
|
418
419
|
$errors.AddRange([string[]]@(Get-OrchestratorStateRoutingContractError -State $state))
|
|
419
420
|
$errors.AddRange([string[]]@(Get-OrchestratorStatePreparationTerminalError -State $state))
|
|
421
|
+
$errors.AddRange([string[]]@(Get-OrchestratorStateCompletionConcurrentReviewError -State $state))
|
|
420
422
|
|
|
421
423
|
# M family. The gate's M3 leg re-invokes the U6.C and U6.M validators, so its
|
|
422
424
|
# output is merged under the PD-2 single-emission rule rather than appended
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<#
|
|
2
2
|
.SYNOPSIS
|
|
3
|
-
Portable completion-gate checks C1, C2, C3, C4, C5, and
|
|
3
|
+
Portable completion-gate checks C1, C2, C3, C4, C5, C7, and C8.
|
|
4
4
|
|
|
5
5
|
.DESCRIPTION
|
|
6
6
|
Destination-runtime PowerShell port of the `--require-complete` checks the
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
C5.1 mandatory route phases, from a static map
|
|
20
20
|
C7.1 preparation terminal next_step (value-gated, repr rendering)
|
|
21
21
|
C7.2 preparation terminal step statuses (value-gated, repr rendering)
|
|
22
|
+
C8 last review outcome under review_mode concurrent (value-gated)
|
|
22
23
|
|
|
23
24
|
Route gating for C3 and C4 is resolved through
|
|
24
25
|
`OrchestratorStateRoutingMatrix.psm1`, implementing deviation PD-1: the gate
|
|
@@ -407,6 +408,53 @@ function Get-OrchestratorStatePreparationTerminalError {
|
|
|
407
408
|
return $errors.ToArray()
|
|
408
409
|
}
|
|
409
410
|
|
|
411
|
+
function Get-OrchestratorStateCompletionConcurrentReviewError {
|
|
412
|
+
<#
|
|
413
|
+
.SYNOPSIS
|
|
414
|
+
Return the review-record error under review_mode concurrent (row C8).
|
|
415
|
+
.DESCRIPTION
|
|
416
|
+
Mirrors validate_concurrent_review_completion. Only the exact string concurrent
|
|
417
|
+
activates the check, and only the final review_outcomes element counts. The head
|
|
418
|
+
error is reported only when the verdict error does not apply. The check does no
|
|
419
|
+
git work: head currency stays with the merge guard.
|
|
420
|
+
.PARAMETER State
|
|
421
|
+
The parsed checkpoint object.
|
|
422
|
+
.OUTPUTS
|
|
423
|
+
System.String[] - zero or one error string.
|
|
424
|
+
#>
|
|
425
|
+
[CmdletBinding()]
|
|
426
|
+
[OutputType([string[]])]
|
|
427
|
+
param(
|
|
428
|
+
[Parameter(Mandatory = $true)]
|
|
429
|
+
[psobject] $State
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
$mode = $null
|
|
433
|
+
if ((Get-CheckpointObjectMemberName -Owner $State) -ccontains 'review_mode') { $mode = (Get-CheckpointObjectMember -Owner $State -Name 'review_mode').Value }
|
|
434
|
+
if (-not (($mode -is [string]) -and ($mode -ceq 'concurrent'))) {
|
|
435
|
+
return [string[]]@()
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
# A missing loop, a non-list value, an empty list, and a non-object last entry all
|
|
439
|
+
# leave $last unset, so each reports the verdict error.
|
|
440
|
+
$last = $null
|
|
441
|
+
$loop = (Get-CheckpointObjectMember -Owner $State -Name 'remediation_loop').Value
|
|
442
|
+
$outcomes = (Get-CheckpointObjectMember -Owner $loop -Name 'review_outcomes').Value
|
|
443
|
+
if ((Test-CheckpointListValue -Value $outcomes) -and $outcomes.Count -gt 0) {
|
|
444
|
+
$last = $outcomes[$outcomes.Count - 1]
|
|
445
|
+
}
|
|
446
|
+
$verdict = (Get-CheckpointObjectMember -Owner $last -Name 'verdict').Value
|
|
447
|
+
if (-not (($verdict -is [string]) -and ($verdict -ceq 'PASS'))) {
|
|
448
|
+
return [string[]]@('Checkpoint completion validation failed: review_mode concurrent requires a last review_outcomes entry with verdict PASS.')
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
$head = (Get-CheckpointObjectMember -Owner $last -Name 'head_sha').Value
|
|
452
|
+
if (-not (($head -is [string]) -and ($head -cmatch '\A[0-9a-f]{40}([0-9a-f]{24})?\z'))) {
|
|
453
|
+
return [string[]]@('Checkpoint completion validation failed: review_mode concurrent requires head_sha on the last review_outcomes entry.')
|
|
454
|
+
}
|
|
455
|
+
return [string[]]@()
|
|
456
|
+
}
|
|
457
|
+
|
|
410
458
|
# Each check family is exported individually so the completion entry point can
|
|
411
459
|
# compose them in the Python reference's order; the gate-key helper stays private.
|
|
412
460
|
Export-ModuleMember -Function `
|
|
@@ -415,4 +463,5 @@ Export-ModuleMember -Function `
|
|
|
415
463
|
Get-OrchestratorStateCompletionPrGateError, `
|
|
416
464
|
Get-OrchestratorStateCompletionCiGateError, `
|
|
417
465
|
Get-OrchestratorStatePhaseCompletenessError, `
|
|
418
|
-
Get-OrchestratorStatePreparationTerminalError
|
|
466
|
+
Get-OrchestratorStatePreparationTerminalError, `
|
|
467
|
+
Get-OrchestratorStateCompletionConcurrentReviewError
|
|
@@ -264,9 +264,12 @@ function Get-RemediationCycleError {
|
|
|
264
264
|
|
|
265
265
|
# Invariant 2: an execution status in the blocked set requires the nested
|
|
266
266
|
# preflight to report exactly the cleared status; a missing or non-object
|
|
267
|
-
# preflight cannot satisfy it.
|
|
267
|
+
# preflight cannot satisfy it. An exact light cycle runs no preflight and is
|
|
268
|
+
# checked by invariant 8 instead.
|
|
268
269
|
$executionStatus = (Get-CheckpointObjectMember -Owner $Cycle -Name 'execution_status').Value
|
|
269
|
-
|
|
270
|
+
$remediationPath = (Get-CheckpointObjectMember -Owner $Cycle -Name 'remediation_path').Value
|
|
271
|
+
$isLightCycle = ($remediationPath -is [string]) -and ([string]$remediationPath -ceq 'light')
|
|
272
|
+
if (-not $isLightCycle -and $executionStatus -is [string] -and
|
|
270
273
|
($script:EXECUTION_STATUSES_REQUIRING_CLEAR_PREFLIGHT -contains [string]$executionStatus)) {
|
|
271
274
|
$preflight = (Get-CheckpointObjectMember -Owner $Cycle -Name 'preflight').Value
|
|
272
275
|
$preflightStatus = (Get-CheckpointObjectMember -Owner $preflight -Name 'final_status').Value
|