@danmoisan/drm-copilot-mcp 1.1.25 → 1.1.26

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.
Files changed (36) hide show
  1. package/package.json +1 -1
  2. package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +7 -3
  3. package/resources/claude-customizations/.claude/agents/parallel-planner.md +6 -2
  4. package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +41 -0
  5. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1 +481 -0
  6. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +3 -1
  7. package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier-helpers.ps1 +69 -3
  8. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +2 -2
  9. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.cleanup.ps1 +246 -0
  10. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +1 -0
  11. package/resources/claude-customizations/.claude/hooks/hook-cleanup-context.ps1 +343 -0
  12. package/resources/claude-customizations/.claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 +626 -0
  13. package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmission.psm1 +508 -0
  14. package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmissionJson.psm1 +141 -0
  15. package/resources/claude-customizations/.claude/lib/parallel-admission/ParallelAdmissionPrecedence.psm1 +508 -0
  16. package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +17 -1
  17. package/resources/claude-customizations/.claude/settings.json +1 -0
  18. package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +1 -1
  19. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +93 -14
  20. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup-worktrees.sh +23 -10
  21. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_lib.sh +54 -46
  22. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_merge_lib.sh +234 -0
  23. package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +15 -5
  24. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +71 -7
  25. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +26 -2
  26. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +82 -12
  27. package/resources/claude-customizations/pack-manifests/core.json +8 -0
  28. package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +15 -5
  29. package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
  30. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1 +481 -0
  31. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +4 -2
  32. package/resources/codex-and-agents-customizations/.codex/hooks/hook-cleanup-context.ps1 +343 -0
  33. package/resources/codex-and-agents-customizations/pack-manifests/core.json +2 -0
  34. package/resources/customizations/.github/skills/execution-environment/SKILL.md +15 -5
  35. package/resources/powershell/PoshQC/PoshQC.ScanConfig.psm1 +3 -1
  36. package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +12 -10
@@ -11,6 +11,14 @@ This brief states the environment facts that every researcher, planner, prefligh
11
11
 
12
12
  Maintenance rule: this brief is updated in the same change that alters any fact it states. It carries no line numbers and no commit identifiers; it cites files, symbols, headings, job names, and test names. The same text is byte-identical in six locations: `.claude/skills/execution-environment/SKILL.md`, `.agents/skills/execution-environment/SKILL.md`, `.github/skills/execution-environment/SKILL.md`, and their bundled copies under `extensions/drm-copilot/resources/`. Where the Claude and Codex runtimes differ, both paths are named (`.claude/hooks/...` and `.codex/hooks/...`).
13
13
 
14
+ ## Development Toolchain Baseline
15
+
16
+ The host manifest, both devcontainer Dockerfiles, and development CI use Python 3.13.17, Node.js 26.13.0/npm 11.20.0, PowerShell 7.6.9, and Poetry 2.3.2. Shell validation pins shfmt 3.14.1, ShellCheck 0.11.0, and actionlint 1.7.12. Host bootstrap treats manifest versions as minima and preserves equal/newer installations; the container verifier accepts later Python patches within 3.13 and checks the other selected pins.
17
+
18
+ The devcontainer minor image can lag the Python patch, so both Dockerfiles copy the verified official Python runtime stage and select it and NodeSource ahead of older base-feature shims. Full configuration builds include the selected devcontainer features; a raw Dockerfile image alone does not prove feature-provided commands. Runtime verification uses an isolated Linux virtual environment rather than the host Windows environment.
19
+
20
+ Python 3.11/3.12 compatibility jobs, consumer package engines, and independent release-publishing runtime pins remain unchanged. The shared version predicate lives in `scripts/bash/container_versions.sh`; `.devcontainer/verify-container.sh` resolves it relative to its own repository location.
21
+
14
22
  ## Tool Routes by Agent
15
23
 
16
24
  - `atomic-executor` has no PowerShell tool. Its `tools:` list is Read, Grep, Glob, Edit, Write, several `Bash(...)` entries, the four `mcp__drm-copilot__run_poshqc_*` tools, and `mcp__drm-copilot__validate_orchestration_artifacts`. A `(pattern)` suffix on a `tools:` entry admits the bare tool, so the executor has Bash, subject to the repository hooks and the runtime guard described under Command-Text Restrictions.
@@ -50,6 +58,8 @@ Two separate mechanisms restrict Bash command text. They are kept apart here bec
50
58
  - Hooks for an isolated subagent run inside the subagent's worktree with that worktree's hook scripts, which are `main`'s copies. A hook change on a branch is not exercised by isolated subagents until it merges.
51
59
  - Hook behavior on a branch is therefore proven by Pester suites, not by a live subagent run. A live check of a branch hook needs a non-isolated delegation from the item worktree.
52
60
  - The batch-budget hooks evaluate the checkpoint of the target worktree that `Resolve-HookTargetWorktree` resolves for the edited file, so an edit made from a coordinating session into an item worktree is evaluated against the item worktree's checkpoint. The preimplementation gate (#1010) resolves the file path of a Write or Edit call and the `-C` values and absolute operands of `git add` and `git commit` through the same resolver, and denies when the worktree listing fails or names no worktree; its delegation checks still resolve by portable identity. The PR authoring gate (#1011) resolves the branch that a `gh pr create` or `gh pr edit` command names (`--head`, `--branch`, or a `branch:` label) through the same resolver when the command carries no canonical issue number line, and otherwise keeps its portable-identity and current-branch resolution. The other gates that read `artifacts/orchestration/orchestrator-state.json` are unchanged and still use the root that holds the hook script.
61
+ - Cleanup legs (#1026): a `cleanup-merged-worktrees` run writes no checkpoint, so the preimplementation gate (`.claude/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1` and its `.codex/hooks/` twin), the PR-authoring gate (`.claude/hooks/enforce-pr-author-skill.cleanup.ps1`), and the model-routing gate (`.claude/hooks/enforce-model-routing-receipt.ps1`) carry allow-side cleanup legs, evaluated only where each gate would otherwise deny, that share the pure predicates of `hook-cleanup-context.ps1`. The legs admit a Write of the session-root manifest `artifacts/orchestration/cleanup-worktrees-manifest.json` with valid content (an Edit stays denied), Write or Edit of paths under `docs/` or `.claude/agent-memory/` and of the pr-author receipt inside the consolidation worktree on branch `documentationandmemories`, `git -C <consolidation root> add` and `commit` of those paths, `Agent(pr-author)` with `branch: documentationandmemories`, and `gh pr create --head documentationandmemories --base main` while a fresh valid manifest exists at the session root and the pushed `refs/remotes/origin/documentationandmemories` resolves to the same commit as the consolidation worktree `HEAD`. A preimplementation-gate denial appends a cleanup sub-code (`Cleanup leg not applied`) only after a cleanup leg has identified the consolidation worktree as the target and a later condition fails; a call rejected by a prefilter keeps the unchanged deny text even when its target is the consolidation worktree, as does every other call.
62
+ - Scratch rule (#1026): the preimplementation gate allows a Write or Edit of an absolute local path that lies outside every registered worktree and the session root and under a temporary root, read through the seam `Get-OrchestrationGateTemporaryRoot` (the long-name `GetTempPath()` value and the `TEMP`, `TMP`, and `TMPDIR` values, which can carry the 8.3 short-name spelling). The rule fails closed when any registered worktree lies under a temporary root.
53
63
  - Enforcement hooks do not invoke Python; bash is preferred and PowerShell is acceptable (`tests/scripts/claude-runtime/enforcement-hooks-no-python-invocation.Tests.ps1`).
54
64
 
55
65
  ## MCP Surfaces Run the Installed Extension
@@ -61,14 +71,14 @@ Two separate mechanisms restrict Bash command text. They are kept apart here bec
61
71
  ## CI Shape and Required Checks
62
72
 
63
73
  - `.github/workflows/ci.yml` triggers on `push` to `main` and `development`, on `pull_request` to `main`, `development`, and `epic/**`, on `workflow_dispatch`, and on `merge_group` (`types: [checks_requested]`, added by issue #952), with no path filters. When the merge queue on `main` is enabled, every required check is produced by a `merge_group` run of `ci.yml` as well as by the pull-request run; `.github/workflows/README.md` (`## Triggers`) records the trigger set.
64
- - Jobs in `ci.yml` and their check names: `Change scope` (job `changes`, the change-scope decision below); `CI full run` (job `full-run-marker`, which runs only on a full run, marks that run as a valid base for later decisions, and is not a required check); `quality-checks7 / Code Quality & Tests (<python-version>)` on Python 3.11, 3.12, and 3.13 (`_quality-checks.yml`: Black check, Ruff, Pyright, the Codex generator `--check`, the tier classification, and Pytest on every version; Pytest with line and branch coverage and the coverage-threshold check on the JSON report totals run on 3.13 only); `security-scan / Security Scanning` (its `safety check` step carries `continue-on-error: true` and does not fail the check); `docs-validation / Documentation Validation`; `build-check / Build Package`; `shell-coverage / Shell Coverage (Bats + kcov)`; `drm-copilot-extension-tests / drm-copilot Extension Tests (<os>)` on `ubuntu-latest` and `windows-latest`; `root-typescript-tests / Root TypeScript Tests (<os>)` on `ubuntu-latest` and `windows-latest`; `NPM Audit Gate / npm audit (<manifest>)` (the calling job carries the name `NPM Audit Gate`); and the `poshqc` group below.
74
+ - Jobs in `ci.yml` and their check names: `Change scope` (job `changes`, the change-scope decision below); `CI full run` (job `full-run-marker`, which runs only on a full run, marks that run as a valid base for later decisions, and is not a required check); `quality-checks7 / Code Quality & Tests (<python-version>)` on Python 3.11, 3.12, and 3.13 (`_quality-checks.yml`: Black check, Ruff, Pyright, the Codex generator `--check`, the tier classification, and Pytest on every version; Pytest with line and branch coverage and the coverage-threshold check on the JSON report totals run on 3.13 only); `security-scan / Security Scanning` (its `safety check` step carries `continue-on-error: true` and does not fail the check); `docs-validation / Documentation Validation`; `build-check / Build Package`; `shell-coverage / Shell Coverage (Bats + kcov)`; `drm-copilot-extension-tests / drm-copilot Extension Tests (<os>)` on `ubuntu-latest` and `windows-latest`; `root-typescript-tests / Root TypeScript Tests (<os>)` on `ubuntu-latest` and `windows-latest`; `NPM Audit Gate / npm audit (<manifest>)` (the calling job carries the name `NPM Audit Gate`); the `poshqc` group below; and `CI Required Gate` (job `ci-required-gate`, issue #1074), which needs every other `ci.yml` job, runs under `if: always()` on `ubuntu-latest`, and passes `toJSON(needs)` to `scripts/ci/Invoke-CiRequiredGate.ps1`. The gate is green on a full run only when every needed job is `success`, and on a docs-only run only when `CI full run`, `root-typescript-tests`, and `NPM Audit Gate` are `success` or `skipped` and every other needed job is `success`; a `failure`, `cancelled`, or unknown result, a `Change scope` result other than `success`, and unreadable input are red. `tests/scripts/workflows/CiRequiredGateWorkflow.Tests.ps1` pins its `needs:` set against the other job ids of `ci.yml`.
65
75
  - PowerShell CI (`_poshqc.yml`): `poshqc / PowerShell QC static` (format and analyze on `windows-latest`); the shard matrix `poshqc / PowerShell QC shard 1`, `shard 2`, and `shard 3` (`Invoke-PoshQCTest -ShardIndex -ShardCount` over the scan folders of `config/poshqc-scan.json`, with coverage, on `windows-latest`); the aggregator `poshqc / PowerShell QC`, which requires the static and shard jobs to succeed, verifies shard completeness against a Pester discovery count, and merges shard coverage; and `poshqc / PowerShell hook suites (Linux)`, which runs only `tests/scripts/claude-hooks` and `tests/scripts/codex-hooks` on `ubuntu-latest` with coverage disabled. A new test file under a scanned folder is assigned to a shard automatically and is counted by the completeness check.
66
76
  - Change-scope decision (issue #962): the `Change scope` job runs `scripts/ci/Invoke-CiChangeScope.ps1` and publishes the job output `code`. The decision is `code=false` (docs-only) only on a `pull_request` event from this repository, through one of two comparisons. Green-run base: every file changed since the newest successful `ci.yml` run on the pull-request branch whose `CI full run` job succeeded, and whose head commit is present and an ancestor of the current head, is on the allowlist `config/ci-docs-only-paths.json`; the reason is `DOCS_ONLY_SINCE_<green head sha>`. Merge-base fallback (issue #973): when the green-run step ends with no earlier full green run (`NO_FULL_GREEN_RUN`), a missing base (`BASE_NOT_PRESENT`), or a non-ancestor base (`BASE_NOT_ANCESTOR`), and the pull request's base ref is exactly `main`, the script computes `git merge-base` of the payload base SHA (`BASE_SHA`, from `github.event.pull_request.base.sha`; the base ref arrives as `BASE_REF`) and the head, lists the files changed since that merge base with the same diff arguments, and decides `DOCS_ONLY_SINCE_MERGE_BASE_<merge base sha>` when every changed file is allowlisted. Both comparisons run the diff with rename detection off, so both the old and the new path of a rename are classified. A path is allowlisted when it starts with `docs/features/active/`, `docs/features/archive/`, `docs/features/completed/`, `docs/features/epics/`, `docs/features/parallel/`, `docs/features/potential/`, or `docs/research/`, does not start with `docs/features/templates/` or `docs/features/potential/template.md`, and ends in `.md`, `.txt`, `.log`, `.json`, or `.xml`; the allowlist file itself is not allowlisted. Every other case is a full run (`code=true`): `push`, `merge_group`, and `workflow_dispatch` events, a fork pull request, unreadable run or job data, no earlier full green run or a missing or non-ancestor base when the base ref is not `main`, a merge base that cannot be resolved (`MERGE_BASE_UNRESOLVED`, for example a blank base SHA or a base commit missing from the checkout), a failed ancestry check, an empty diff, any path outside the allowlist, and any error. The decision step carries `continue-on-error: true` and the callers compare the output with `!= 'false'`, so a failed or missing decision also gives a full run.
67
- - Docs-only behavior (`code=false`): `ci.yml` passes `run-heavy: false` to `_quality-checks.yml`, `_security-scan.yml`, `_build-check.yml`, `_poshqc.yml`, `_shell-coverage.yml`, and `_drm-copilot-extension-tests.yml`. Each required job still starts under its full-run check name with every step skipped, so every required context reports `success` without running its suite. In `_poshqc.yml` the aggregator `poshqc / PowerShell QC` runs with every step gated, and `poshqc / PowerShell QC static`, the shard jobs, and `poshqc / PowerShell hook suites (Linux)` are skipped at job level. `docs-validation / Documentation Validation` runs in full. `root-typescript-tests`, `NPM Audit Gate`, and `CI full run` are skipped at job level. A `success` on a docs-only commit is therefore not evidence that the heavy suites pass for that commit; that evidence is the newest run whose `CI full run` job succeeded.
77
+ - Docs-only behavior (`code=false`): `ci.yml` passes `run-heavy: false` to `_quality-checks.yml`, `_security-scan.yml`, `_build-check.yml`, `_poshqc.yml`, `_shell-coverage.yml`, and `_drm-copilot-extension-tests.yml`. Each job that runs with its steps gated still starts under its full-run check name with every step skipped, so it reports `success` without running its suite. In `_poshqc.yml` the aggregator `poshqc / PowerShell QC` runs with every step gated, and `poshqc / PowerShell QC static`, the shard jobs, and `poshqc / PowerShell hook suites (Linux)` are skipped at job level. `docs-validation / Documentation Validation` runs in full. `root-typescript-tests`, `NPM Audit Gate`, and `CI full run` are skipped at job level. Eight currently required contexts therefore never report on a docs-only run: `poshqc / PowerShell QC shard 1`, `poshqc / PowerShell QC shard 2`, `poshqc / PowerShell QC shard 3`, `root-typescript-tests / Root TypeScript Tests (ubuntu-latest)`, `root-typescript-tests / Root TypeScript Tests (windows-latest)`, `NPM Audit Gate / npm audit (.)`, `NPM Audit Gate / npm audit (extensions/drm-copilot)`, and `NPM Audit Gate / npm audit (packages/mcp-server)`, so a docs-only head stays blocked under the 20-context ruleset. `CI Required Gate` passes on a docs-only run, because it accepts `skipped` for exactly those skipped callers. A `success` on a docs-only commit is therefore not evidence that the heavy suites pass for that commit; that evidence is the newest run whose `CI full run` job succeeded.
68
78
  - A commit that changes any path outside the allowlist (any code, workflow, configuration, script, test, or customization file) runs the full set of jobs, and its `CI full run` job marks it as a base for later docs-only decisions. A standalone `workflow_dispatch` of a reusable workflow, or a caller that omits `run-heavy`, also runs in full. `.github/workflows/README.md` (`## Change-Scope Decision (Issue #962)`) records the reason codes and the per-context behavior table.
69
- - Required contexts of ruleset 15241672, confirmed by the orchestrator through `gh api` on 2026-10-16: `drm-copilot-extension-tests / drm-copilot Extension Tests (ubuntu-latest)`, `drm-copilot-extension-tests / drm-copilot Extension Tests (windows-latest)`, `docs-validation / Documentation Validation`, `poshqc / PowerShell QC`, `shell-coverage / Shell Coverage (Bats + kcov)`, `security-scan / Security Scanning`, `quality-checks7 / Code Quality & Tests (3.11)`, `quality-checks7 / Code Quality & Tests (3.12)`, `quality-checks7 / Code Quality & Tests (3.13)`, `build-check / Build Package`.
70
- - Refresh rule: a change that renames a job, adds or removes a matrix entry, or changes the ruleset refreshes this list in the same change, and the orchestrator re-confirms the contexts with a read-only `gh api repos/drmoisan/drm-copilot/rulesets/15241672` call before relying on them.
71
- - Skipped-check semantics: a job skipped by an `if:` condition reports success to a required check; a workflow that does not run at all reports nothing, which leaves the required check pending.
79
+ - Required contexts of ruleset 15241672, read through a read-only `gh api` call on 2026-11-04 (20 contexts, each with `integration_id` 15368): `drm-copilot-extension-tests / drm-copilot Extension Tests (ubuntu-latest)`, `drm-copilot-extension-tests / drm-copilot Extension Tests (windows-latest)`, `docs-validation / Documentation Validation`, `poshqc / PowerShell QC`, `shell-coverage / Shell Coverage (Bats + kcov)`, `security-scan / Security Scanning`, `quality-checks7 / Code Quality & Tests (3.11)`, `quality-checks7 / Code Quality & Tests (3.12)`, `quality-checks7 / Code Quality & Tests (3.13)`, `build-check / Build Package`, `NPM Audit Gate / npm audit (extensions/drm-copilot)`, `NPM Audit Gate / npm audit (.)`, `NPM Audit Gate / npm audit (packages/mcp-server)`, `root-typescript-tests / Root TypeScript Tests (ubuntu-latest)`, `root-typescript-tests / Root TypeScript Tests (windows-latest)`, `poshqc / PowerShell QC shard 1`, `poshqc / PowerShell QC shard 2`, `poshqc / PowerShell QC shard 3`, `poshqc / PowerShell QC static`, `poshqc / PowerShell hook suites (Linux)`. After the owner's post-merge ruleset edit (issue #1074 runbook), the single required context is `CI Required Gate` (`integration_id` 15368), and the individual job contexts remain visible but are no longer required.
80
+ - Refresh rule: a change that renames a job, adds or removes a `ci.yml` job or a matrix entry, or changes the ruleset refreshes this list in the same change, and the orchestrator re-confirms the contexts with a read-only `gh api repos/drmoisan/drm-copilot/rulesets/15241672` call before relying on them. A new `ci.yml` job must also be added to the `needs:` list of `ci-required-gate`; `tests/scripts/workflows/CiRequiredGateWorkflow.Tests.ps1` fails until it is.
81
+ - Skipped-check semantics: a job skipped by an `if:` condition reports success to a required check; a workflow that does not run at all reports nothing, which leaves the required check pending. A matrix job skipped at job level reports no expanded context (its matrix name is never expanded), and a reusable-workflow caller skipped in `ci.yml` reports no nested contexts, so each such required context stays pending.
72
82
  - A pull request into a branch other than `main`, `development`, or `epic/**` gets no CI run; dispatch `ci.yml` manually for it.
73
83
 
74
84
  ## CI-Only Failure Classes
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: parallel-add
3
3
  description: Admit one new item into a running parallel run — preparation via a preparation-mode child orchestrator run, conflict-edge computation against all items including in-flight ones, and the admission decision that either places the item in the current cohort or defers it and recolors the unstarted subgraph. Appends exactly one mutations[] entry. In-flight items are never moved.
4
- argument-hint: "[issue|potential-entry]"
4
+ argument-hint: "[issue|potential-entry] [--after <earlier>] [--band <Cn>]"
5
5
  context: fork
6
6
  agent: parallel-orchestrator
7
7
  ---
@@ -28,7 +28,9 @@ this operation may and may not disturb. Read that section before applying anythi
28
28
  `/parallel-run` for that.
29
29
  - `$ARGUMENTS` names exactly one item: a GitHub issue number or reference, or a path to an entry
30
30
  under `docs/features/potential/`. An argument naming more than one item is rejected; admit one
31
- item per invocation so each admission decision and its mutation entry stay attributable.
31
+ item per invocation so each admission decision and its mutation entry stay attributable. The
32
+ `--after <earlier>` and `--band <Cn>` flags are not items, so the multi-item rejection applies to
33
+ positional items only.
32
34
  - The run-existence check is evaluated first, before any argument-shape check: a pending or
33
35
  not-started run, and a run whose `parallel_slug` no checkpoint tracks, are rejected before the
34
36
  argument is examined.
@@ -37,6 +39,15 @@ this operation may and may not disturb. Read that section before applying anythi
37
39
  the run's slug is known, put the line `parallel_slug: <slug>` before the signal, and end the
38
40
  final output with the literal line `PARALLEL_MUTATION_REJECTED: run_not_started` as its last
39
41
  line, with no formatting and no trailing text.
42
+ - After the run-existence check passes, apply the closed-run guard in code. Read the manifest mode
43
+ with `bash .claude/lib/bash/validate-parallel-manifest.sh --print-mode <manifest-path>`, then run
44
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 guard-run -CheckpointPath artifacts/orchestration/parallel-orchestrator-state.json -ManifestMode <mode>`.
45
+ The guard rejects when either mode is `closed`, when a `mutations[]` entry has `op` `close`, or
46
+ when the two modes disagree. On exit 1, stop with the helper's stderr line
47
+ (`PARALLEL_ADMISSION_REJECTED: run_closed: <detail>`) as the reported reason, change no state,
48
+ and emit no mutation rejection signal: `run_closed` is an admission rejection code defined in
49
+ `## Prepared-Item Admission (issue #1047)` of `.claude/rules/parallel-orchestration.md`, not a
50
+ mutation rejection code.
40
51
  - A closed run and an argument naming more than one item are rejected only after the run-existence
41
52
  check, while the run's checkpoint exists; each of these rejections emits no rejection signal, and
42
53
  the stop validates against that checkpoint.
@@ -61,13 +72,39 @@ re-derivation is mandatory and is not an optimization to skip when the checkpoin
61
72
  1. **Enter `proposed`.** Add the item to `items[]` in state `proposed` with its `issue_num` as the
62
73
  primary key. Item keys are integers throughout this surface; there is no string key.
63
74
 
64
- 2. **Prepare the item.** Run preparation through a preparation-mode child `Agent(orchestrator)`
75
+ 2. **Prepare the item.** First assess how far the item's pushed branch is already prepared:
76
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 assess -Branch origin/<item branch> -FeatureFolder <feature folder> -PlannerCheckpointPath artifacts/orchestration/parallel-planner-state.json`,
77
+ adding `-Band <Cn>` when the operator passed `--band`. The helper reads the branch by ref, selects
78
+ the newest preparation receipt or infers the stage from the branch files, compares the files the
79
+ plan cites against `origin/main` since the base commit, and prints `next_action`.
80
+ - When `next_action` is `admit_prepared` (stage `cleared`, verdict `fresh`), run no preparation
81
+ child, no preflight, and no plan revision. Record the output's `preparation_status`,
82
+ `plan_hash`, `base_commit`, `complexity_band` (the `band.value`), and `band_source` (the
83
+ `band.source`) on the item, and continue with step 3.
84
+ - Otherwise delegate the preparation child described below on the item's pushed branch, not on
85
+ a new branch, and append after the unchanged kickoff line the resume line
86
+ `Preparation resume: stage <stage>. Existing artifacts: <paths>. Do not repeat a completed stage; supersede with new timestamped files.`
87
+ with `<stage>` set to the output's `resume_stage` and `<paths>` listing the existing
88
+ `research_path`, `spec_path`, and `plan_path` relative to the feature folder. A stale item
89
+ (verdict `stale`) resumes at preflight with the output's `changed_cited_paths` as the findings,
90
+ under the single-pass rule of `.claude/skills/orchestrate/SKILL.md` `## Delegation Model`
91
+ (trivial defects fixed in place, one planner revision for substantive defects, and a halt with
92
+ the defect list when a second round still fails). A plan that never cleared preflight always
93
+ runs preflight. A contract change found by that preflight, or a `premise_falsified` verdict
94
+ (a cited path removed on `main`), resumes at `plan`: the new plan is a new timestamped file,
95
+ and no superseded artifact is deleted.
96
+ - The band source order is `--band` (`band_source: caller`), then the planner checkpoint item's
97
+ `complexity_band` (`planner_checkpoint`), then the `## Complexity Assessment` procedure below
98
+ (`assessment`).
99
+
100
+ Otherwise run preparation through a preparation-mode child `Agent(orchestrator)`
65
101
  run, reusing the existing `route_id: preparation` contract UNCHANGED: promotion, research,
66
102
  `spec.md`, `user-story.md`, the atomic plan, and preflight clearance. Do not fork a variant
67
103
  contract for parallel admission. Preparation yields the item's DECLARED blast radius, and only
68
104
  the planner-computed declared radius is authoritative for scheduling. The item's lifecycle
69
105
  advances `proposed` -> `admitted` -> `prepared` during this step, recorded as item-state updates in
70
- `items[]` with the checkpoint's lifecycle timestamps. After the admitted item's preflight
106
+ `items[]` with the checkpoint's lifecycle timestamps. When the band source is `assessment`, after
107
+ the admitted item's preflight
71
108
  clearance, perform the `parallel-plan` skill's `## Complexity Assessment` procedure for it, and
72
109
  record the resulting `complexity_band` on the admitted orchestrator-checkpoint item so step 3's
73
110
  edge derivation and the parent's model routing read the same band.
@@ -125,6 +162,11 @@ re-derivation is mandatory and is not an optimization to skip when the checkpoin
125
162
  `qualifies for combination; not combined (combination applies at planning time only)`. This
126
163
  step never combines items: it adds no checkpoint field and makes no `mutations[]` change for a
127
164
  qualifying pair.
165
+ Record each `--after <earlier>` flag as one top-level `precedence[]` entry
166
+ `{before, after, source, recorded_at}` with `before` the earlier item, `after` the candidate,
167
+ `source` `operator`, and `recorded_at` the current UTC minute. Each precedence pair is a
168
+ separating input, never a dependency key: add it to the edges passed to steps 4 and 5 as one
169
+ more `<a>:<b>` edge with `a < b`, so the coloring always separates the pair.
128
170
 
129
171
  4. **Decide admission.** Call the bundled entry point, which needs no Python interpreter:
130
172
 
@@ -166,12 +208,23 @@ re-derivation is mandatory and is not an optimization to skip when the checkpoin
166
208
  `.claude/skills/parallel-orchestrate/SKILL.md` — so the current cohort durably holds `scheduled`
167
209
  members that a candidate can contend with.
168
210
 
211
+ A candidate with an active unmerged predecessor (a `precedence[]` entry whose `before` item has a
212
+ `merge_status` other than `merged` or `worktree_removed` and a `state` other than `withdrawn`) is
213
+ forced to `defer_and_recolor` even when `admit` prints `admit_current_cohort`.
214
+
169
215
  A conflict with an unstarted member of the CURRENT cohort defers the candidate and recolors,
170
216
  because the next `max_concurrency` batch would otherwise launch the two concurrently. A conflict
171
217
  with an unstarted item OUTSIDE the current cohort does not defer: the cohort barrier keeps the
172
218
  two from running concurrently, so the coloring's existing separation already resolves it.
173
219
 
174
- 5. **Apply the recolor result.** Write the recolor output field `cohort_assignments` into
220
+ 5. **Apply the recolor result.** Before writing, pass the recolor result through the precedence
221
+ lift: `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 order-cohorts -Cohorts <table-json> -Edges "<a>:<b> ..." -Precedence "<before>:<after> ..." -Pinned "<k> ..." -Floor <current_cohort>`,
222
+ which moves an unstarted `after` item above its `before` items and never moves a pinned item.
223
+ After writing, and before step 6 appends the mutation entry, run
224
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 test-cohorts -CheckpointPath artifacts/orchestration/parallel-orchestrator-state.json`;
225
+ on exit 1 (`precedence_violated`, `precedence_cycle`, or `precedence_unknown_item`), restore the
226
+ prior `cohorts[]` and `recolor_generation` and stop with the helper's stderr line.
227
+ Write the recolor output field `cohort_assignments` (as lifted) into
175
228
  `cohorts[]` and set the top-level `recolor_generation` to the output field `generation`. The
176
229
  result's key set equals the
177
230
  unstarted set exactly and contains no pinned key: no in-flight item changes cohort or state as a
@@ -216,12 +269,23 @@ re-derivation is mandatory and is not an optimization to skip when the checkpoin
216
269
  "parallel-orchestrator-state"`. A non-empty error list means the admission was applied
217
270
  incorrectly; correct the checkpoint rather than proceeding.
218
271
 
272
+ 8. **Rewrite the durable scheduling record.** Build the record content with
273
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 record -RunFolder docs/features/parallel/<slug> -Entry <entry-json>`,
274
+ where the entry carries the checkpoint's `conflict_edges`, `tolerated_overlaps`, `precedence`,
275
+ and `items`. The helper prints the content and makes no git write. Write it to
276
+ `docs/features/parallel/<slug>/parallel-scheduling.json` on `parallel/<slug>-plan` and commit it
277
+ with a pathspec under `docs/features/parallel/`, so a re-seed from another checkout reads the
278
+ recorded edges and plan hashes by ref.
279
+
219
280
  ## Constraints
220
281
 
221
282
  - One admission per invocation, one `mutations[]` entry per successful admission. A failed
222
283
  preparation appends no entry and leaves `items[]` without the candidate.
223
- - No field and no enum member is added to `mutations[]`, `items[]`, or any state or merge-status
224
- enum. A `conflict_edges[]` entry may carry only the three tolerated extra fields `hard`, `cost`,
284
+ - No field and no enum member is added to `mutations[]` or any state or merge-status enum. The only
285
+ fields added to `items[]` are the four tolerated fields `preparation_status`, `plan_hash`,
286
+ `base_commit`, and `band_source` declared in `## Prepared-Item Admission (issue #1047)` of
287
+ `.claude/rules/parallel-orchestration.md`, which also declares the top-level `precedence[]` list
288
+ this skill records. A `conflict_edges[]` entry may carry only the three tolerated extra fields `hard`, `cost`,
225
289
  and `benefit` (tolerated-not-validated, returned by the scheduling entry point), and no reason
226
290
  member is added: the four `conflict_edges[].reason` members are unchanged. The nine parallel
227
291
  enums are owned by `.claude/rules/parallel-orchestration.md` and are consumed, never extended.
@@ -129,6 +129,16 @@ completion notification. A blocked item (`blocked_ci_loop_limit` or `blocked_dri
129
129
  `merged` nor `worktree_removed`, so it holds every conflicting later-cohort neighbour and,
130
130
  transitively, the tail of its own conflict component; items outside that component are unaffected.
131
131
 
132
+ **Precedence.** An item named as `after` in an active `precedence[]` entry (the operator ordering
133
+ input declared in `## Prepared-Item Admission (issue #1047)` of
134
+ `.claude/rules/parallel-orchestration.md`) may start only when its `before` item has `merge_status`
135
+ `merged` or `worktree_removed`, whatever the two items' cohorts. A `withdrawn` predecessor releases
136
+ the constraint, and a `blocked` predecessor holds its dependent. Layer 1 enforces this rule through
137
+ `Test-ParallelCohortBarrierClear` in `.claude/hooks/enforce-parallel-cohort-barrier-helpers.ps1`,
138
+ which denies a target whose predecessor is not released and fails closed on a missing predecessor
139
+ record. Layer 2 does not check precedence: the Python orchestrator-state validator reads
140
+ `conflict_edges[]` only.
141
+
132
142
  **`current_cohort` is a progress indicator, not a gate.** `current_cohort` is the LOWEST
133
143
  current-generation cohort index that still contains a non-terminal, non-withdrawn item. It is
134
144
  recomputed and written only on durable confirmation from `git worktree list --porcelain`,
@@ -265,6 +275,10 @@ carries exactly these five elements.
265
275
  execution from that plan rather than re-running promotion, research, or planning. The item's
266
276
  prepared feature folder and approved atomic plan are already committed and preflight-clear on the
267
277
  item's own pushed feature branch.
278
+ The prompt also carries the item's admitted plan hash as `plan-hash: <hex>` and instructs the child, before any other step, to run `git rev-parse HEAD:<plan-path>` and to stop with `blocked_reason: premise_falsified` when the printed hash differs from `<hex>`.
279
+ The `<hex>` value is the item's `plan_hash` from the orchestrator checkpoint item, else the
280
+ kickoff `## Integrity` row for its plan path. The check runs before the child reconciles with
281
+ `origin/main`, so a plan that changed after admission never reaches atomic execution.
268
282
  The execution child starts a new checkpoint in its own worktree, and the preparation checkpoint
269
283
  does not carry over, so the prompt also instructs the child to verify the item's GitHub issue
270
284
  read-only (gh issue view), not to call `potential_to_issue` or the promotion-entry tool, and to
@@ -404,6 +418,15 @@ Procedure, per item:
404
418
  CI-dependent acceptance criteria. When either check fails, do not record
405
419
  `merge_status: ci_green` and do not run `gh pr merge`; the item waits until its child pushes
406
420
  the check-off and re-runs S9, and the parent does not commit the check-off itself.
421
+ **Turn gap.** A child can end its turn with its pull request open and its CI green gate still
422
+ pending. On every child completion, read the child checkpoint
423
+ `<worktree>/artifacts/orchestration/orchestrator-state.json`, with the worktree path located by
424
+ `git worktree list --porcelain`. When its `step9_status` is not `passed` or its `blocked_reason`
425
+ is `awaiting_ci`, keep `merge_status: pr_open` and treat the item as not done: poll
426
+ `gh pr checks` through the parser above until the conclusion is terminal, then
427
+ re-delegate the child once to resume at the CI green gate, by the same re-delegation mechanism as
428
+ `## Per-Item Merge-Conflict Handling`; a CI-failure cycle counts toward `remediation_loop`.
429
+ Record `ci_green` only after that resumed run reports its CI green gate `passed`.
407
430
  3. Execute `gh pr merge --merge <PR>` for that item's pull request, whose base is `main`.
408
431
  Do not pass `--delete-branch` or `--auto`. A zero exit status does not prove a merge: when
409
432
  `main` uses a merge queue, `gh pr merge` exits 0 after it enqueues the pull request or enables
@@ -711,8 +734,9 @@ This section is consumption documentation only. The checkpoint schema is owned b
711
734
  as prose invariants in `.claude/rules/parallel-orchestration.md`, and enforced by
712
735
  `scripts/dev_tools/validate_parallel_orchestrator_state.py`. Consume that schema;
713
736
  add no field to it that `.claude/rules/parallel-orchestration.md` does not declare,
714
- and extend no enum in it. `mergeable_conflicts_resolved` is the one declared optional item
715
- field.
737
+ and extend no enum in it. The declared optional item fields are `mergeable_conflicts_resolved`,
738
+ `preparation_status`, `plan_hash`, `base_commit`, and `band_source`, and the declared optional
739
+ top-level field is `precedence[]` (`## Prepared-Item Admission (issue #1047)` of the rule).
716
740
 
717
741
  Fields `parallel-orchestrator` writes to `artifacts/orchestration/parallel-orchestrator-state.json`:
718
742
  `objective`, `route_id: "parallel"`, `parallel_slug`, `parallel_manifest_path`,
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: parallel-plan
3
3
  description: Prepare a set of thematically unrelated items for concurrent execution before any execution begins - item intake over issue numbers and potential-entry paths, concurrent preparation-mode child orchestrator delegations, blast-radius computation and V1-V3 validation, cohort seeding with a recomputation-parity check, run-manifest and planner-checkpoint authoring, and the parallel-orchestrator kickoff artifact.
4
- argument-hint: "[items: issue numbers and/or potential-entry paths]"
4
+ argument-hint: "[items: issue numbers and/or potential-entry paths] [--after <later>:<earlier> ...]"
5
5
  context: fork
6
6
  agent: parallel-planner
7
7
  ---
@@ -16,7 +16,8 @@ $ARGUMENTS
16
16
  This skill frames work for the `parallel-planner` agent, parallel to how
17
17
  `.claude/skills/epic-plan/SKILL.md` frames work for `epic-planner`. The `parallel` surface
18
18
  schedules thematically unrelated items by computed blast-radius contention: there is no worthiness
19
- assessment, no operator-supplied ordering, and no shared branch into which item work merges.
19
+ assessment, no operator-supplied ordering beyond the optional `--after <later>:<earlier>`
20
+ precedence flags, and no shared branch into which item work merges.
20
21
  Planning ends at preflight clearance and cohort seeding; no atomic execution, PR authoring, or CI
21
22
  monitoring occurs under this skill.
22
23
 
@@ -62,13 +63,29 @@ identical forms.
62
63
  - **`kind`.** Record `kind: feature | bug` at intake from the item source (issue labels, or the
63
64
  potential entry's declared kind). When the source is indeterminate, default to `feature` and note
64
65
  the choice `[recommendation, not upstream-constrained]`.
66
+ - **Admission assessment.** Run the same `assess` subcommand `/parallel-add` step 2 runs for every
67
+ item whose branch is pushed:
68
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 assess -Branch origin/<item branch> -FeatureFolder <feature folder>`.
69
+ An item with no pushed branch (an unpromoted potential entry) takes `full_preparation`. Fan-out
70
+ takes only the items whose `next_action` is not `admit_prepared`. An item whose `next_action` is
71
+ `admit_prepared` (stage `cleared`, verdict `fresh`) runs no preparation child: record its
72
+ `plan_path`, `research_path`, `plan_hash`, `base_commit`, `branch_name`, and
73
+ `preflight_status: PREFLIGHT: ALL CLEAR` from the branch, set `preparation_status: prepared`
74
+ (the planner ready value that corresponds to the admission stage `cleared`), and record
75
+ `topology_receipt` as not applicable, because no preparation child ran for it.
76
+ - **Precedence input.** Record each `--after <later>:<earlier>` flag as one top-level
77
+ `precedence[]` entry `{before, after, source, recorded_at}` with `source` `operator`, as
78
+ declared in `## Prepared-Item Admission (issue #1047)` of `.claude/rules/parallel-orchestration.md`.
79
+ The flags are optional and are never requested.
65
80
 
66
81
  The operator is never asked for ordering edges, cohort assignments, or a worthiness verdict.
67
82
  Intake proceeds directly to preparation fan-out.
68
83
 
69
84
  ## Preparation Fan-Out
70
85
 
71
- One preparation-mode `Agent(orchestrator)` run per item. Preparation produces documents and plans
86
+ One preparation-mode `Agent(orchestrator)` run per incomplete item, that is, per item whose
87
+ `assess` `next_action` is not `admit_prepared`; the waves below cover the incomplete items only.
88
+ Preparation produces documents and plans
72
89
  rather than code, and items carry no ordering constraint, so preparations may run concurrently —
73
90
  but they are BOUNDED, not unbounded.
74
91
 
@@ -84,6 +101,8 @@ JSON array of arrays, returns the batches in order, and sorts the keys itself, s
84
101
  does not depend on caller ordering. Launch wave *k* as one message carrying that wave's `Agent`
85
102
  calls, each `isolation: "worktree"` and `run_in_background: true`.
86
103
  Create each preparation worktree's branch from `origin/main`.
104
+ A resumed item (`next_action` `resume_preparation`) instead runs on its pushed branch, as
105
+ `## Issue Combination` step 3 does, so its completed stages stay on that branch.
87
106
  Launch wave *k+1* only after every child of wave *k* has TERMINATED — not merely reported
88
107
  progress. All of this happens inside a single `/parallel-plan` invocation with no operator action
89
108
  between waves.
@@ -107,13 +126,18 @@ invocations after the initial plan. Use `/parallel-plan` for intake and `/parall
107
126
  admit an item into a run that is already in flight.
108
127
 
109
128
  Each delegation prompt includes this literal kickoff line, followed by the model-budget marker
110
- line and, for an issue-number item only, the issue-adoption line:
129
+ line, for an issue-number item only, the issue-adoption line, for a resumed item only, the
130
+ preparation-resume line, and the preparation-receipt line:
111
131
 
112
132
  > `Preparation mode: true. route_id: preparation. parallel_slug: <slug>. Perform promotion, research, feature documents (spec.md, user-story.md), atomic planning, and preflight clearance only. Atomic execution, PR authoring, and CI monitoring are out of scope for this run and are executed later by parallel-orchestrator. After the atomic-executor preflight returns PREFLIGHT: ALL CLEAR, commit the feature folder and plan to the current branch, push the current branch to origin, set out-of-scope step statuses to not-applicable, set next_step to S5_atomic_execution, and stop, reporting the plan-path and preflight status.`
113
133
  >
114
134
  > `model_budget.fable_policy: <disabled|available|preferred>.`
115
135
  >
116
136
  > `Issue adoption: this item's GitHub issue already exists. Verify it read-only (gh issue view), do not call potential_to_issue or the promotion-entry tool, and record a top-level issue_adoption object in the checkpoint per .claude/rules/orchestrator-state.md with origin filed_before_orchestration (or transferred when the issue was transferred), waiving potential_to_issue and the promotion-entry tool for the checkpoint's promotion-type. When a lifecycle record for the item exists under docs/features/potential/promoted/, cite it as potential_record.`
137
+ >
138
+ > `Preparation resume: stage <stage>. Existing artifacts: <paths>. Do not repeat a completed stage; supersede with new timestamped files.`
139
+ >
140
+ > `Preparation receipt: before the commit, write <feature folder>/evidence/other/preparation-receipt.<yyyy-MM-ddTHH-mm>.json with schema_version, stage, research_path, spec_path, plan_path, plan_hash, base_commit, preflight_status, and recorded_at.`
117
141
 
118
142
  Properties of that line, each individually load-bearing:
119
143
 
@@ -144,6 +168,21 @@ to execution, so the execution child records its own adoption (see
144
168
  creates and commits the feature folder, the execution child's adoption also waives
145
169
  `new_active_feature_folder` and records `feature_folder_record` for that committed folder.
146
170
 
171
+ **Preparation-resume line.** The preparation-resume line is emitted only for a resumed item, after
172
+ the issue-adoption line (or after the model-budget marker line for a potential-entry item). Its
173
+ `<stage>` is the `assess` `resume_stage`, and its `<paths>` are the existing `research_path`,
174
+ `spec_path`, and `plan_path` written relative to the feature folder. The line carries no mode
175
+ marker and no active feature-folder path and does not match the hook issue-number pattern, so hook
176
+ target resolution and mode classification are unchanged. A stale item resumes at preflight with
177
+ the `assess` `changed_cited_paths` as findings under the unchanged single-pass rule of
178
+ `.claude/skills/orchestrate/SKILL.md` `## Delegation Model`; a falsified premise resumes at `plan`,
179
+ and a superseded artifact is replaced by a new timestamped file and never deleted.
180
+
181
+ **Preparation-receipt line.** The preparation-receipt line is emitted for every delegated item. The
182
+ child resolves `<feature folder>` to its own folder and writes the receipt declared in
183
+ `## Prepared-Item Admission (issue #1047)` of `.claude/rules/parallel-orchestration.md` before its
184
+ commit, so a later `assess` reads the stage, plan hash, and base commit from the branch.
185
+
147
186
  **No edit to shared surfaces.** No edit is made to `.claude/skills/orchestrate/SKILL.md` or to
148
187
  `config/orchestration-routing.json`, including the `preparation` route. The route mechanism is
149
188
  marker-driven; the child contract's "commit ... to the current branch" wording is satisfied by a
@@ -437,7 +476,13 @@ The library returns the partition; the planner supplies the record fields.
437
476
  (hard classes, integer cost, pairwise benefit, and the configured `conflict_tolerance`). It
438
477
  returns `edges` and `tolerated_overlaps`. The -Relation argument is required; pass the facade's
439
478
  Test-BlastRadiusConflict function object as shown. Pass the returned `edges` pairs as
440
- `--edges "<a>:<b> ..."` and the item keys as `--keys "<k1> <k2> ..."`.
479
+ `--edges "<a>:<b> ..."` and the item keys as `--keys "<k1> <k2> ..."`. Add each recorded
480
+ `precedence[]` pair to `--edges` as one more separating `<a>:<b>` edge with `a < b`, so the
481
+ coloring always separates the pair. Then pass the coloring through the precedence lift:
482
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 order-cohorts -Cohorts <compute-cohorts output> -Edges "<a>:<b> ..." -Precedence "<before>:<after> ..."`.
483
+ No item has started at seeding, so the call passes no option that holds an item in place, and
484
+ its `cohorts` output is the table steps 3 and 5 record. A `precedence_cycle` or
485
+ `precedence_unknown_item` rejection (exit 1) stops the run with the helper's stderr line.
441
486
  The detection relation inside the entry point contributes no `path_overlap` edge for a path
442
487
  matching the truth table's optional `mergeable_paths` list, and the path stays in the declared
443
488
  radius. When `Test-BlastRadiusConflict` is called directly (for example, while investigating a
@@ -482,6 +527,18 @@ The library returns the partition; the planner supplies the record fields.
482
527
  (the bash port of `compute_concurrency_batches(cohort_item_keys, max_concurrency)`), which fills
483
528
  slots in ascending item-key order. Recoloring under add, remove, or drift mutation is F6 and F8
484
529
  scope. This skill performs seeding only.
530
+ 7. **Durable scheduling record.** Build the record content with
531
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 record -RunFolder docs/features/parallel/<slug> -Entry <entry-json>`
532
+ from the recorded `conflict_edges`, `tolerated_overlaps`, `precedence`, and `items`; the helper
533
+ prints the content and makes no git write. Write it to
534
+ `docs/features/parallel/<slug>/parallel-scheduling.json` and commit it on `parallel/<slug>-plan`
535
+ with the manifest. A re-seed applies the reuse rule per item with
536
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 reuse-edges -Slug <slug> -IssueNum <issue> -PlanHash <plan_hash>`,
537
+ where `<plan_hash>` is the item's `plan_hash` from its `assess` output. The helper reads the
538
+ committed record by ref from `origin/parallel/<slug>-plan`, runs no fetch, and prints
539
+ `{action, edges, reason}`. On `action` `reuse` the printed `edges` are that item's recorded
540
+ edges and are reused; on `action` `recompute` (reason `record_missing`, `unknown_item`, or
541
+ `plan_hash_changed`) that item's edges are recomputed.
485
542
 
486
543
  ### Recomputation parity (planner-owned check)
487
544
 
@@ -492,12 +549,18 @@ skill discharges that obligation as documented procedure, not as a new module:
492
549
 
493
550
  1. After writing `cohorts[]` into the checkpoint and **before** emitting the kickoff artifact,
494
551
  re-invoke `compute_cohorts` over exactly the `item_keys` and `conflict_edges` recorded in the
495
- checkpoint.
552
+ checkpoint (through `compute-cohorts.sh`), plus the separating edges of the recorded
553
+ `precedence[]` pairs, and pass the result through `order-cohorts` with the recorded precedence,
554
+ exactly as `### Seeding procedure` step 1 does.
496
555
  2. Assert that the recomputed list of lists maps to exactly the recorded `cohorts[]` at
497
556
  `generation: 0`: the same partition, the same `index` assignment, and the same ascending
498
- `item_keys[]` ordering.
499
- 3. A mismatch is a **Blocking** condition. Stop the run and report the mismatch. Do not
500
- auto-correct the recorded cohorts, and do not emit the kickoff artifact.
557
+ `item_keys[]` ordering. Then run
558
+ `pwsh -NoProfile -NonInteractive -File .claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1 test-cohorts -CheckpointPath artifacts/orchestration/parallel-planner-state.json`,
559
+ which rejects with `precedence_violated` when a cohort places an `after` item at or before an
560
+ active `before` item.
561
+ 3. A mismatch is a **Blocking** condition, and so is a `test-cohorts` rejection. Stop the run and
562
+ report the mismatch or the rejection. Do not auto-correct the recorded cohorts, and do not emit
563
+ the kickoff artifact.
501
564
 
502
565
  No production module is added for this check; it is a re-invocation of the landed library.
503
566
 
@@ -558,20 +621,22 @@ Write `artifacts/orchestration/parallel-planner-state.json` after every complete
558
621
 
559
622
  Top-level fields: `objective`, `parallel_slug`, `parallel_manifest_path`, `mode`,
560
623
  `max_concurrency`, `plan_home_branch` (`parallel/<slug>-plan`), `items[]`, `cohorts[]`,
561
- `conflict_edges[]`, `recolor_generation`, `kickoff_prompt_path`
624
+ `conflict_edges[]`, `precedence[]` (the operator precedence entries, declared in
625
+ `## Prepared-Item Admission (issue #1047)` of the rule), `recolor_generation`, `kickoff_prompt_path`
562
626
  (`artifacts/orchestration/parallel-kickoff-<slug>.md`), `completed_steps`, `next_step`, and
563
627
  `last_updated`. F3's landed required-key set (planner invariant P1) is a strict subset of this
564
628
  list, and `plan_home_branch` is a permitted additional field.
565
629
 
566
630
  Per item: `issue_num`, `feature_folder`, `kind`, `state`, `complexity_band`, `complexity_assessment`,
567
631
  `preparation_status`,
568
- `research_path`, `plan_path`, `preflight_status`, `branch_name`, `worktree_path`, `blast_radius`
632
+ `research_path`, `plan_path`, `plan_hash`, `base_commit`, `preflight_status`, `branch_name`, `worktree_path`, `blast_radius`
569
633
  (with `source: "declared"`), `radius_validation` (the `v1`, `v2`, and `v3` results with their
570
634
  severities), `model_routing_receipt`, and `topology_receipt`.
571
635
 
572
636
  **Deliberately absent:** any `epic_worthiness` analogue, any `depends_on` field, and any `wave`
573
637
  field. The parallel surface renders no worthiness verdict and expresses ordering only as
574
- blast-radius overlap.
638
+ blast-radius overlap and as the operator `precedence[]` input, which is a separating input and not
639
+ a dependency field.
575
640
 
576
641
  **Readiness contract.** Before reporting completion the checkpoint must satisfy F3's
577
642
  `require_ready_for_execution` gate: at least two items (invariant P6); every item
@@ -674,6 +739,11 @@ Structural requirements enforced by the contract module:
674
739
  commit of `parallel/<slug>-plan` as run-level provenance and a per-item `plan-path | plan-hash`
675
740
  table whose hashes are 40 to 64 hex characters with no repeated plan path.
676
741
 
742
+ The planner writes the `## Integrity` section with one row per item, whose `plan-hash` is that
743
+ item's `assess` `plan_hash` (the plan blob hash at the item branch head), the same value recorded
744
+ on the checkpoint item and in the durable scheduling record. The parallel orchestrator passes it to
745
+ the item's execution child in kickoff element 4, which verifies it before any other step.
746
+
677
747
  Validate the artifact through `mcp__drm-copilot__validate_orchestration_artifacts` with
678
748
  `artifact_type: "parallel-kickoff"`. That artifact type dispatches to
679
749
  `scripts/dev_tools/parallel_kickoff_contract.py`, which this feature delivers.
@@ -47,6 +47,7 @@
47
47
  ".claude/hooks/enforce-file-size-limit.ps1",
48
48
  ".claude/hooks/enforce-model-routing-receipt.ps1",
49
49
  ".claude/hooks/enforce-orchestration-preimplementation-gate.ps1",
50
+ ".claude/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1",
50
51
  ".claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1",
51
52
  ".claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1",
52
53
  ".claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1",
@@ -60,6 +61,7 @@
60
61
  ".claude/hooks/enforce-powershell-batch-budget.ps1",
61
62
  ".claude/hooks/enforce-pr-author-command-allowlist.ps1",
62
63
  ".claude/hooks/enforce-pr-author-skill.artifact-root.ps1",
64
+ ".claude/hooks/enforce-pr-author-skill.cleanup.ps1",
63
65
  ".claude/hooks/enforce-pr-author-skill.current-branch.ps1",
64
66
  ".claude/hooks/enforce-pr-author-skill.docs-only.ps1",
65
67
  ".claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1",
@@ -71,6 +73,7 @@
71
73
  ".claude/hooks/enforce-python-batch-budget.ps1",
72
74
  ".claude/hooks/feature-folder-resolution.ps1",
73
75
  ".claude/hooks/feature-review-coverage-thresholds.ps1",
76
+ ".claude/hooks/hook-cleanup-context.ps1",
74
77
  ".claude/hooks/hook-command-heredoc.ps1",
75
78
  ".claude/hooks/hook-command-invocation.ps1",
76
79
  ".claude/hooks/hook-command-invocation-operands.ps1",
@@ -122,6 +125,7 @@
122
125
  ".claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_lib.sh",
123
126
  ".claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_eol_lib.sh",
124
127
  ".claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_lib.sh",
128
+ ".claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_merge_lib.sh",
125
129
  ".claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_report_records_lib.sh",
126
130
  ".claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh",
127
131
  ".claude/skills/commit-message/SKILL.md",
@@ -231,6 +235,10 @@
231
235
  ".claude/lib/parallel-drift/ParallelDriftHalt.psm1",
232
236
  ".claude/lib/parallel-drift/ParallelDrift.psm1",
233
237
  ".claude/lib/parallel-drift/Invoke-ParallelDriftDetection.ps1",
238
+ ".claude/lib/parallel-admission/ParallelAdmission.psm1",
239
+ ".claude/lib/parallel-admission/ParallelAdmissionPrecedence.psm1",
240
+ ".claude/lib/parallel-admission/Invoke-ParallelAdmission.ps1",
241
+ ".claude/lib/parallel-admission/ParallelAdmissionJson.psm1",
234
242
  ".claude/rules/parallel-orchestration.md",
235
243
  ".claude/rules/shell.md",
236
244
  ".claude/lib/bash/abandon-parallel-item.sh",
@@ -11,6 +11,14 @@ This brief states the environment facts that every researcher, planner, prefligh
11
11
 
12
12
  Maintenance rule: this brief is updated in the same change that alters any fact it states. It carries no line numbers and no commit identifiers; it cites files, symbols, headings, job names, and test names. The same text is byte-identical in six locations: `.claude/skills/execution-environment/SKILL.md`, `.agents/skills/execution-environment/SKILL.md`, `.github/skills/execution-environment/SKILL.md`, and their bundled copies under `extensions/drm-copilot/resources/`. Where the Claude and Codex runtimes differ, both paths are named (`.claude/hooks/...` and `.codex/hooks/...`).
13
13
 
14
+ ## Development Toolchain Baseline
15
+
16
+ The host manifest, both devcontainer Dockerfiles, and development CI use Python 3.13.17, Node.js 26.13.0/npm 11.20.0, PowerShell 7.6.9, and Poetry 2.3.2. Shell validation pins shfmt 3.14.1, ShellCheck 0.11.0, and actionlint 1.7.12. Host bootstrap treats manifest versions as minima and preserves equal/newer installations; the container verifier accepts later Python patches within 3.13 and checks the other selected pins.
17
+
18
+ The devcontainer minor image can lag the Python patch, so both Dockerfiles copy the verified official Python runtime stage and select it and NodeSource ahead of older base-feature shims. Full configuration builds include the selected devcontainer features; a raw Dockerfile image alone does not prove feature-provided commands. Runtime verification uses an isolated Linux virtual environment rather than the host Windows environment.
19
+
20
+ Python 3.11/3.12 compatibility jobs, consumer package engines, and independent release-publishing runtime pins remain unchanged. The shared version predicate lives in `scripts/bash/container_versions.sh`; `.devcontainer/verify-container.sh` resolves it relative to its own repository location.
21
+
14
22
  ## Tool Routes by Agent
15
23
 
16
24
  - `atomic-executor` has no PowerShell tool. Its `tools:` list is Read, Grep, Glob, Edit, Write, several `Bash(...)` entries, the four `mcp__drm-copilot__run_poshqc_*` tools, and `mcp__drm-copilot__validate_orchestration_artifacts`. A `(pattern)` suffix on a `tools:` entry admits the bare tool, so the executor has Bash, subject to the repository hooks and the runtime guard described under Command-Text Restrictions.
@@ -50,6 +58,8 @@ Two separate mechanisms restrict Bash command text. They are kept apart here bec
50
58
  - Hooks for an isolated subagent run inside the subagent's worktree with that worktree's hook scripts, which are `main`'s copies. A hook change on a branch is not exercised by isolated subagents until it merges.
51
59
  - Hook behavior on a branch is therefore proven by Pester suites, not by a live subagent run. A live check of a branch hook needs a non-isolated delegation from the item worktree.
52
60
  - The batch-budget hooks evaluate the checkpoint of the target worktree that `Resolve-HookTargetWorktree` resolves for the edited file, so an edit made from a coordinating session into an item worktree is evaluated against the item worktree's checkpoint. The preimplementation gate (#1010) resolves the file path of a Write or Edit call and the `-C` values and absolute operands of `git add` and `git commit` through the same resolver, and denies when the worktree listing fails or names no worktree; its delegation checks still resolve by portable identity. The PR authoring gate (#1011) resolves the branch that a `gh pr create` or `gh pr edit` command names (`--head`, `--branch`, or a `branch:` label) through the same resolver when the command carries no canonical issue number line, and otherwise keeps its portable-identity and current-branch resolution. The other gates that read `artifacts/orchestration/orchestrator-state.json` are unchanged and still use the root that holds the hook script.
61
+ - Cleanup legs (#1026): a `cleanup-merged-worktrees` run writes no checkpoint, so the preimplementation gate (`.claude/hooks/enforce-orchestration-preimplementation-gate-cleanup.ps1` and its `.codex/hooks/` twin), the PR-authoring gate (`.claude/hooks/enforce-pr-author-skill.cleanup.ps1`), and the model-routing gate (`.claude/hooks/enforce-model-routing-receipt.ps1`) carry allow-side cleanup legs, evaluated only where each gate would otherwise deny, that share the pure predicates of `hook-cleanup-context.ps1`. The legs admit a Write of the session-root manifest `artifacts/orchestration/cleanup-worktrees-manifest.json` with valid content (an Edit stays denied), Write or Edit of paths under `docs/` or `.claude/agent-memory/` and of the pr-author receipt inside the consolidation worktree on branch `documentationandmemories`, `git -C <consolidation root> add` and `commit` of those paths, `Agent(pr-author)` with `branch: documentationandmemories`, and `gh pr create --head documentationandmemories --base main` while a fresh valid manifest exists at the session root and the pushed `refs/remotes/origin/documentationandmemories` resolves to the same commit as the consolidation worktree `HEAD`. A preimplementation-gate denial appends a cleanup sub-code (`Cleanup leg not applied`) only after a cleanup leg has identified the consolidation worktree as the target and a later condition fails; a call rejected by a prefilter keeps the unchanged deny text even when its target is the consolidation worktree, as does every other call.
62
+ - Scratch rule (#1026): the preimplementation gate allows a Write or Edit of an absolute local path that lies outside every registered worktree and the session root and under a temporary root, read through the seam `Get-OrchestrationGateTemporaryRoot` (the long-name `GetTempPath()` value and the `TEMP`, `TMP`, and `TMPDIR` values, which can carry the 8.3 short-name spelling). The rule fails closed when any registered worktree lies under a temporary root.
53
63
  - Enforcement hooks do not invoke Python; bash is preferred and PowerShell is acceptable (`tests/scripts/claude-runtime/enforcement-hooks-no-python-invocation.Tests.ps1`).
54
64
 
55
65
  ## MCP Surfaces Run the Installed Extension
@@ -61,14 +71,14 @@ Two separate mechanisms restrict Bash command text. They are kept apart here bec
61
71
  ## CI Shape and Required Checks
62
72
 
63
73
  - `.github/workflows/ci.yml` triggers on `push` to `main` and `development`, on `pull_request` to `main`, `development`, and `epic/**`, on `workflow_dispatch`, and on `merge_group` (`types: [checks_requested]`, added by issue #952), with no path filters. When the merge queue on `main` is enabled, every required check is produced by a `merge_group` run of `ci.yml` as well as by the pull-request run; `.github/workflows/README.md` (`## Triggers`) records the trigger set.
64
- - Jobs in `ci.yml` and their check names: `Change scope` (job `changes`, the change-scope decision below); `CI full run` (job `full-run-marker`, which runs only on a full run, marks that run as a valid base for later decisions, and is not a required check); `quality-checks7 / Code Quality & Tests (<python-version>)` on Python 3.11, 3.12, and 3.13 (`_quality-checks.yml`: Black check, Ruff, Pyright, the Codex generator `--check`, the tier classification, and Pytest on every version; Pytest with line and branch coverage and the coverage-threshold check on the JSON report totals run on 3.13 only); `security-scan / Security Scanning` (its `safety check` step carries `continue-on-error: true` and does not fail the check); `docs-validation / Documentation Validation`; `build-check / Build Package`; `shell-coverage / Shell Coverage (Bats + kcov)`; `drm-copilot-extension-tests / drm-copilot Extension Tests (<os>)` on `ubuntu-latest` and `windows-latest`; `root-typescript-tests / Root TypeScript Tests (<os>)` on `ubuntu-latest` and `windows-latest`; `NPM Audit Gate / npm audit (<manifest>)` (the calling job carries the name `NPM Audit Gate`); and the `poshqc` group below.
74
+ - Jobs in `ci.yml` and their check names: `Change scope` (job `changes`, the change-scope decision below); `CI full run` (job `full-run-marker`, which runs only on a full run, marks that run as a valid base for later decisions, and is not a required check); `quality-checks7 / Code Quality & Tests (<python-version>)` on Python 3.11, 3.12, and 3.13 (`_quality-checks.yml`: Black check, Ruff, Pyright, the Codex generator `--check`, the tier classification, and Pytest on every version; Pytest with line and branch coverage and the coverage-threshold check on the JSON report totals run on 3.13 only); `security-scan / Security Scanning` (its `safety check` step carries `continue-on-error: true` and does not fail the check); `docs-validation / Documentation Validation`; `build-check / Build Package`; `shell-coverage / Shell Coverage (Bats + kcov)`; `drm-copilot-extension-tests / drm-copilot Extension Tests (<os>)` on `ubuntu-latest` and `windows-latest`; `root-typescript-tests / Root TypeScript Tests (<os>)` on `ubuntu-latest` and `windows-latest`; `NPM Audit Gate / npm audit (<manifest>)` (the calling job carries the name `NPM Audit Gate`); the `poshqc` group below; and `CI Required Gate` (job `ci-required-gate`, issue #1074), which needs every other `ci.yml` job, runs under `if: always()` on `ubuntu-latest`, and passes `toJSON(needs)` to `scripts/ci/Invoke-CiRequiredGate.ps1`. The gate is green on a full run only when every needed job is `success`, and on a docs-only run only when `CI full run`, `root-typescript-tests`, and `NPM Audit Gate` are `success` or `skipped` and every other needed job is `success`; a `failure`, `cancelled`, or unknown result, a `Change scope` result other than `success`, and unreadable input are red. `tests/scripts/workflows/CiRequiredGateWorkflow.Tests.ps1` pins its `needs:` set against the other job ids of `ci.yml`.
65
75
  - PowerShell CI (`_poshqc.yml`): `poshqc / PowerShell QC static` (format and analyze on `windows-latest`); the shard matrix `poshqc / PowerShell QC shard 1`, `shard 2`, and `shard 3` (`Invoke-PoshQCTest -ShardIndex -ShardCount` over the scan folders of `config/poshqc-scan.json`, with coverage, on `windows-latest`); the aggregator `poshqc / PowerShell QC`, which requires the static and shard jobs to succeed, verifies shard completeness against a Pester discovery count, and merges shard coverage; and `poshqc / PowerShell hook suites (Linux)`, which runs only `tests/scripts/claude-hooks` and `tests/scripts/codex-hooks` on `ubuntu-latest` with coverage disabled. A new test file under a scanned folder is assigned to a shard automatically and is counted by the completeness check.
66
76
  - Change-scope decision (issue #962): the `Change scope` job runs `scripts/ci/Invoke-CiChangeScope.ps1` and publishes the job output `code`. The decision is `code=false` (docs-only) only on a `pull_request` event from this repository, through one of two comparisons. Green-run base: every file changed since the newest successful `ci.yml` run on the pull-request branch whose `CI full run` job succeeded, and whose head commit is present and an ancestor of the current head, is on the allowlist `config/ci-docs-only-paths.json`; the reason is `DOCS_ONLY_SINCE_<green head sha>`. Merge-base fallback (issue #973): when the green-run step ends with no earlier full green run (`NO_FULL_GREEN_RUN`), a missing base (`BASE_NOT_PRESENT`), or a non-ancestor base (`BASE_NOT_ANCESTOR`), and the pull request's base ref is exactly `main`, the script computes `git merge-base` of the payload base SHA (`BASE_SHA`, from `github.event.pull_request.base.sha`; the base ref arrives as `BASE_REF`) and the head, lists the files changed since that merge base with the same diff arguments, and decides `DOCS_ONLY_SINCE_MERGE_BASE_<merge base sha>` when every changed file is allowlisted. Both comparisons run the diff with rename detection off, so both the old and the new path of a rename are classified. A path is allowlisted when it starts with `docs/features/active/`, `docs/features/archive/`, `docs/features/completed/`, `docs/features/epics/`, `docs/features/parallel/`, `docs/features/potential/`, or `docs/research/`, does not start with `docs/features/templates/` or `docs/features/potential/template.md`, and ends in `.md`, `.txt`, `.log`, `.json`, or `.xml`; the allowlist file itself is not allowlisted. Every other case is a full run (`code=true`): `push`, `merge_group`, and `workflow_dispatch` events, a fork pull request, unreadable run or job data, no earlier full green run or a missing or non-ancestor base when the base ref is not `main`, a merge base that cannot be resolved (`MERGE_BASE_UNRESOLVED`, for example a blank base SHA or a base commit missing from the checkout), a failed ancestry check, an empty diff, any path outside the allowlist, and any error. The decision step carries `continue-on-error: true` and the callers compare the output with `!= 'false'`, so a failed or missing decision also gives a full run.
67
- - Docs-only behavior (`code=false`): `ci.yml` passes `run-heavy: false` to `_quality-checks.yml`, `_security-scan.yml`, `_build-check.yml`, `_poshqc.yml`, `_shell-coverage.yml`, and `_drm-copilot-extension-tests.yml`. Each required job still starts under its full-run check name with every step skipped, so every required context reports `success` without running its suite. In `_poshqc.yml` the aggregator `poshqc / PowerShell QC` runs with every step gated, and `poshqc / PowerShell QC static`, the shard jobs, and `poshqc / PowerShell hook suites (Linux)` are skipped at job level. `docs-validation / Documentation Validation` runs in full. `root-typescript-tests`, `NPM Audit Gate`, and `CI full run` are skipped at job level. A `success` on a docs-only commit is therefore not evidence that the heavy suites pass for that commit; that evidence is the newest run whose `CI full run` job succeeded.
77
+ - Docs-only behavior (`code=false`): `ci.yml` passes `run-heavy: false` to `_quality-checks.yml`, `_security-scan.yml`, `_build-check.yml`, `_poshqc.yml`, `_shell-coverage.yml`, and `_drm-copilot-extension-tests.yml`. Each job that runs with its steps gated still starts under its full-run check name with every step skipped, so it reports `success` without running its suite. In `_poshqc.yml` the aggregator `poshqc / PowerShell QC` runs with every step gated, and `poshqc / PowerShell QC static`, the shard jobs, and `poshqc / PowerShell hook suites (Linux)` are skipped at job level. `docs-validation / Documentation Validation` runs in full. `root-typescript-tests`, `NPM Audit Gate`, and `CI full run` are skipped at job level. Eight currently required contexts therefore never report on a docs-only run: `poshqc / PowerShell QC shard 1`, `poshqc / PowerShell QC shard 2`, `poshqc / PowerShell QC shard 3`, `root-typescript-tests / Root TypeScript Tests (ubuntu-latest)`, `root-typescript-tests / Root TypeScript Tests (windows-latest)`, `NPM Audit Gate / npm audit (.)`, `NPM Audit Gate / npm audit (extensions/drm-copilot)`, and `NPM Audit Gate / npm audit (packages/mcp-server)`, so a docs-only head stays blocked under the 20-context ruleset. `CI Required Gate` passes on a docs-only run, because it accepts `skipped` for exactly those skipped callers. A `success` on a docs-only commit is therefore not evidence that the heavy suites pass for that commit; that evidence is the newest run whose `CI full run` job succeeded.
68
78
  - A commit that changes any path outside the allowlist (any code, workflow, configuration, script, test, or customization file) runs the full set of jobs, and its `CI full run` job marks it as a base for later docs-only decisions. A standalone `workflow_dispatch` of a reusable workflow, or a caller that omits `run-heavy`, also runs in full. `.github/workflows/README.md` (`## Change-Scope Decision (Issue #962)`) records the reason codes and the per-context behavior table.
69
- - Required contexts of ruleset 15241672, confirmed by the orchestrator through `gh api` on 2026-10-16: `drm-copilot-extension-tests / drm-copilot Extension Tests (ubuntu-latest)`, `drm-copilot-extension-tests / drm-copilot Extension Tests (windows-latest)`, `docs-validation / Documentation Validation`, `poshqc / PowerShell QC`, `shell-coverage / Shell Coverage (Bats + kcov)`, `security-scan / Security Scanning`, `quality-checks7 / Code Quality & Tests (3.11)`, `quality-checks7 / Code Quality & Tests (3.12)`, `quality-checks7 / Code Quality & Tests (3.13)`, `build-check / Build Package`.
70
- - Refresh rule: a change that renames a job, adds or removes a matrix entry, or changes the ruleset refreshes this list in the same change, and the orchestrator re-confirms the contexts with a read-only `gh api repos/drmoisan/drm-copilot/rulesets/15241672` call before relying on them.
71
- - Skipped-check semantics: a job skipped by an `if:` condition reports success to a required check; a workflow that does not run at all reports nothing, which leaves the required check pending.
79
+ - Required contexts of ruleset 15241672, read through a read-only `gh api` call on 2026-11-04 (20 contexts, each with `integration_id` 15368): `drm-copilot-extension-tests / drm-copilot Extension Tests (ubuntu-latest)`, `drm-copilot-extension-tests / drm-copilot Extension Tests (windows-latest)`, `docs-validation / Documentation Validation`, `poshqc / PowerShell QC`, `shell-coverage / Shell Coverage (Bats + kcov)`, `security-scan / Security Scanning`, `quality-checks7 / Code Quality & Tests (3.11)`, `quality-checks7 / Code Quality & Tests (3.12)`, `quality-checks7 / Code Quality & Tests (3.13)`, `build-check / Build Package`, `NPM Audit Gate / npm audit (extensions/drm-copilot)`, `NPM Audit Gate / npm audit (.)`, `NPM Audit Gate / npm audit (packages/mcp-server)`, `root-typescript-tests / Root TypeScript Tests (ubuntu-latest)`, `root-typescript-tests / Root TypeScript Tests (windows-latest)`, `poshqc / PowerShell QC shard 1`, `poshqc / PowerShell QC shard 2`, `poshqc / PowerShell QC shard 3`, `poshqc / PowerShell QC static`, `poshqc / PowerShell hook suites (Linux)`. After the owner's post-merge ruleset edit (issue #1074 runbook), the single required context is `CI Required Gate` (`integration_id` 15368), and the individual job contexts remain visible but are no longer required.
80
+ - Refresh rule: a change that renames a job, adds or removes a `ci.yml` job or a matrix entry, or changes the ruleset refreshes this list in the same change, and the orchestrator re-confirms the contexts with a read-only `gh api repos/drmoisan/drm-copilot/rulesets/15241672` call before relying on them. A new `ci.yml` job must also be added to the `needs:` list of `ci-required-gate`; `tests/scripts/workflows/CiRequiredGateWorkflow.Tests.ps1` fails until it is.
81
+ - Skipped-check semantics: a job skipped by an `if:` condition reports success to a required check; a workflow that does not run at all reports nothing, which leaves the required check pending. A matrix job skipped at job level reports no expanded context (its matrix name is never expanded), and a reusable-workflow caller skipped in `ci.yml` reports no nested contexts, so each such required context stays pending.
72
82
  - A pull request into a branch other than `main`, `development`, or `epic/**` gets no CI run; dispatch `ci.yml` manually for it.
73
83
 
74
84
  ## CI-Only Failure Classes
@@ -2,7 +2,7 @@ default_permissions = ":danger-full-access"
2
2
 
3
3
  [mcp_servers.drm-copilot]
4
4
  command = "npx"
5
- args = ["-y", "@danmoisan/drm-copilot-mcp@1.1.25"]
5
+ args = ["-y", "@danmoisan/drm-copilot-mcp@1.1.26"]
6
6
  required = true
7
7
  enabled_tools = [
8
8
  "collect_commit_context",