@danmoisan/drm-copilot-mcp 1.0.22 → 1.0.23
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 +164 -7
- package/package.json +1 -1
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +27 -8
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +44 -10
- package/resources/claude-customizations/.claude/lib/bash/compute-cohorts.sh +143 -0
- package/resources/claude-customizations/.claude/lib/bash/compute-concurrency-batches.sh +122 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-cohorts.sh +330 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-common.sh +238 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-items-validate.sh +244 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-manifest-validate.sh +187 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-yaml-emit.sh +340 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-yaml-scan.sh +335 -0
- package/resources/claude-customizations/.claude/lib/bash/validate-parallel-manifest.sh +134 -0
- package/resources/claude-customizations/.claude/rules/shell.md +7 -2
- package/resources/claude-customizations/.claude/settings.json +3 -0
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +9 -5
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +24 -13
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +62 -21
- package/resources/claude-customizations/config/blast-radius.json +16 -0
- package/resources/claude-customizations/config/orchestration-routing.json +355 -0
- package/resources/claude-customizations/pack-manifests/core.json +14 -1
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# validate-parallel-manifest.sh: destination-portable command-line entry point
|
|
3
|
+
# for parallel-run manifest validation and the two default-resolving accessors.
|
|
4
|
+
# It exists so a workspace that received the Claude customization payload can
|
|
5
|
+
# validate a manifest with nothing but bash -- no Python, no Poetry, no yq, and
|
|
6
|
+
# no repository checkout.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# bash .claude/lib/bash/validate-parallel-manifest.sh <manifest-path>
|
|
10
|
+
# bash .claude/lib/bash/validate-parallel-manifest.sh --print-mode <manifest-path>
|
|
11
|
+
# bash .claude/lib/bash/validate-parallel-manifest.sh --print-max-concurrency <manifest-path>
|
|
12
|
+
#
|
|
13
|
+
# Output contract:
|
|
14
|
+
# stdout validation errors one per line (empty for a valid manifest), or the
|
|
15
|
+
# resolved accessor value under --print-mode / --print-max-concurrency
|
|
16
|
+
# exit 0 the manifest is valid, or the accessor resolved
|
|
17
|
+
# exit 1 the manifest is invalid
|
|
18
|
+
# exit 2 usage error, unreadable manifest, or a YAML construct outside the
|
|
19
|
+
# supported subset
|
|
20
|
+
#
|
|
21
|
+
# The accessors resolve the documented defaults -- `closed` and `4` -- when the
|
|
22
|
+
# manifest omits the key or carries a malformed value, matching
|
|
23
|
+
# manifest_mode and manifest_max_concurrency in the Python authority.
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
# Resolve this script's own directory so the library sources regardless of cwd.
|
|
27
|
+
VM_SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
|
28
|
+
# shellcheck source=.claude/lib/bash/parallel-manifest-validate.sh
|
|
29
|
+
# shellcheck disable=SC1091
|
|
30
|
+
source "$VM_SCRIPT_DIR/parallel-manifest-validate.sh"
|
|
31
|
+
|
|
32
|
+
pc_enforce_c_locale
|
|
33
|
+
|
|
34
|
+
vm_usage() {
|
|
35
|
+
# Print the entry point's usage text.
|
|
36
|
+
cat <<'EOF'
|
|
37
|
+
Usage: validate-parallel-manifest.sh [--print-mode | --print-max-concurrency] <manifest-path>
|
|
38
|
+
|
|
39
|
+
Validates a parallel-run manifest against invariants M1 through M7 and prints
|
|
40
|
+
one error per line on stdout; a valid manifest prints nothing and exits 0.
|
|
41
|
+
|
|
42
|
+
Options:
|
|
43
|
+
--print-mode Print the resolved run mode (default: closed).
|
|
44
|
+
--print-max-concurrency Print the resolved fan-out cap (default: 4).
|
|
45
|
+
EOF
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
vm_require_readable() {
|
|
49
|
+
# Return 0 when the manifest path names a readable file.
|
|
50
|
+
#
|
|
51
|
+
# Args: $1 = manifest path. A missing manifest is an operator error rather
|
|
52
|
+
# than a validation verdict, so the caller exits 2 instead of reporting it
|
|
53
|
+
# as a manifest defect.
|
|
54
|
+
local path="$1"
|
|
55
|
+
if [[ ! -f $path || ! -r $path ]]; then
|
|
56
|
+
printf 'validate-parallel-manifest.sh: manifest not found or not readable: %s\n' "$path" >&2
|
|
57
|
+
return 1
|
|
58
|
+
fi
|
|
59
|
+
return 0
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
vm_report_subset_refusal() {
|
|
63
|
+
# Print the out-of-subset refusal and exit 2.
|
|
64
|
+
#
|
|
65
|
+
# Refusing to answer is deliberate: a guessed parse could disagree with the
|
|
66
|
+
# Python authority silently, whereas an explicit refusal is visible.
|
|
67
|
+
printf 'validate-parallel-manifest.sh: manifest uses a YAML construct outside the supported subset: %s\n' \
|
|
68
|
+
"$PM_SUBSET_DETAIL" >&2
|
|
69
|
+
exit 2
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
vm_main() {
|
|
73
|
+
# Dispatch on the optional accessor flag and run the requested operation.
|
|
74
|
+
local mode="validate" path="" status=0 text
|
|
75
|
+
# Routing table: the two accessor flags each consume the following path
|
|
76
|
+
# argument; anything else is treated as the manifest path itself.
|
|
77
|
+
case "${1-}" in
|
|
78
|
+
--print-mode)
|
|
79
|
+
mode="print-mode"
|
|
80
|
+
path="${2-}"
|
|
81
|
+
;;
|
|
82
|
+
--print-max-concurrency)
|
|
83
|
+
mode="print-max-concurrency"
|
|
84
|
+
path="${2-}"
|
|
85
|
+
;;
|
|
86
|
+
--help | -h)
|
|
87
|
+
vm_usage
|
|
88
|
+
return 0
|
|
89
|
+
;;
|
|
90
|
+
-*)
|
|
91
|
+
vm_usage >&2
|
|
92
|
+
return 2
|
|
93
|
+
;;
|
|
94
|
+
*)
|
|
95
|
+
path="${1-}"
|
|
96
|
+
;;
|
|
97
|
+
esac
|
|
98
|
+
[[ -n $path ]] || {
|
|
99
|
+
vm_usage >&2
|
|
100
|
+
return 2
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
vm_require_readable "$path" || return 2
|
|
104
|
+
text=$(cat -- "$path")
|
|
105
|
+
pm_validate_text "$text" || status=$?
|
|
106
|
+
if ((status == 2)); then
|
|
107
|
+
vm_report_subset_refusal
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# The accessors read the parsed node table, which pm_validate_text has
|
|
111
|
+
# already populated, so a malformed-but-parseable manifest still resolves.
|
|
112
|
+
if [[ $mode == "print-mode" ]]; then
|
|
113
|
+
pm_manifest_mode
|
|
114
|
+
printf '\n'
|
|
115
|
+
return 0
|
|
116
|
+
fi
|
|
117
|
+
if [[ $mode == "print-max-concurrency" ]]; then
|
|
118
|
+
pm_manifest_max_concurrency
|
|
119
|
+
printf '\n'
|
|
120
|
+
return 0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
pc_errors_print
|
|
124
|
+
(($(pc_errors_count) == 0)) || return 1
|
|
125
|
+
return 0
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# Guard so the file can be sourced without executing main. main's return code
|
|
129
|
+
# is captured and re-exited explicitly as the final statement.
|
|
130
|
+
if [[ ${BASH_SOURCE[0]} == "${0}" ]]; then
|
|
131
|
+
vm_rc=0
|
|
132
|
+
vm_main "$@" || vm_rc=$?
|
|
133
|
+
exit "$vm_rc"
|
|
134
|
+
fi
|
|
@@ -45,8 +45,10 @@ single pass. Do not substitute the VS Code task wrappers for the native command
|
|
|
45
45
|
|
|
46
46
|
## Discovery Contract
|
|
47
47
|
|
|
48
|
-
- Search roots: `tools
|
|
49
|
-
root is silently skipped.
|
|
48
|
+
- Search roots: `tools/`, `scripts/`, and `.claude/lib/bash/`, relative to the current working
|
|
49
|
+
directory; a missing root is silently skipped. The `.claude/lib/bash/` root carries the
|
|
50
|
+
destination-portable bash library published by push-down, so those scripts are held to the
|
|
51
|
+
same format, lint, test, and coverage standards as `tools/` and `scripts/`.
|
|
50
52
|
- A file is a shell script when its suffix (lowercased) is `.sh` or its first line is a
|
|
51
53
|
shebang whose resolved interpreter is `bash` or `sh` (including `env` and `env -S`/`-flag`
|
|
52
54
|
forms; the shebang is lowercased before parsing, so `#!/usr/bin/env BASH` qualifies).
|
|
@@ -60,6 +62,9 @@ single pass. Do not substitute the VS Code task wrappers for the native command
|
|
|
60
62
|
- Coverage is measured with kcov, which emits a single merged Cobertura report `cov.xml` under
|
|
61
63
|
`artifacts/pester/kcov` (or `SHELL_QC_KCOV_OUT_DIR`). The run prints
|
|
62
64
|
`Bash coverage (lines): NN.N%`.
|
|
65
|
+
- The kcov include pattern covers all three discovery roots — `tools/`, `scripts/`, and
|
|
66
|
+
`.claude/lib/bash/` — so the Claude bash library is measured, not merely discovered. The
|
|
67
|
+
`tests/` tree remains excluded.
|
|
63
68
|
- kcov reports **line coverage only**. The uniform line-coverage threshold (>= 85% per
|
|
64
69
|
`.claude/rules/quality-tiers.md`) applies. Branch coverage is not measurable by kcov for
|
|
65
70
|
bash; there is no bash branch-coverage gate.
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
"Bash(git *)",
|
|
6
6
|
"Bash(poetry run *)",
|
|
7
7
|
"Bash(pwsh *)",
|
|
8
|
+
"Bash(bash .claude/lib/bash/compute-cohorts.sh*)",
|
|
9
|
+
"Bash(bash .claude/lib/bash/compute-concurrency-batches.sh*)",
|
|
10
|
+
"Bash(bash .claude/lib/bash/validate-parallel-manifest.sh*)",
|
|
8
11
|
"Read",
|
|
9
12
|
"Edit(/docs/**)",
|
|
10
13
|
"Write(/docs/**)",
|
|
@@ -56,11 +56,15 @@ re-derivation is mandatory and is not an optimization to skip when the checkpoin
|
|
|
56
56
|
advances `proposed` -> `admitted` -> `prepared` during this step, recorded as item-state updates in
|
|
57
57
|
`items[]` with the checkpoint's lifecycle timestamps.
|
|
58
58
|
|
|
59
|
-
3. **Compute conflict edges over ALL items, including in-flight ones.** Invoke the
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
`BlastRadius
|
|
63
|
-
|
|
59
|
+
3. **Compute conflict edges over ALL items, including in-flight ones.** Invoke the contention
|
|
60
|
+
relation `Test-BlastRadiusConflict` from the destination-runtime PowerShell port
|
|
61
|
+
`.claude/lib/blast-radius/BlastRadius.psm1`, which is published by push-down and needs no Python
|
|
62
|
+
interpreter (`Import-Module .claude/lib/blast-radius/BlastRadius.psm1 -Force`). Its two radius
|
|
63
|
+
arguments are the two items' radius hashtables, not strings, and the third argument is the
|
|
64
|
+
required parsed `config/blast-radius.json` mapping, which push-down publishes into the
|
|
65
|
+
destination workspace. `conflicts(a, b, config)` in `scripts/dev_tools/compute_blast_radius.py`
|
|
66
|
+
(defined in `scripts/dev_tools/_blast_radius_conflicts.py`) remains the repository authority and
|
|
67
|
+
the parity reference. Map each conflicting pair onto an `(int, int)` conflict edge
|
|
64
68
|
of `items[].issue_num` values, normalized so `a < b`. Do not reimplement the relation and do not
|
|
65
69
|
compute edges over the unstarted subset only: an in-flight conflict is precisely what the
|
|
66
70
|
admission decision turns on.
|
|
@@ -54,7 +54,8 @@ only run-level artifacts under `docs/features/parallel/<slug>/`.
|
|
|
54
54
|
nine parallel enums are defined once as prose invariants in
|
|
55
55
|
`.claude/rules/parallel-orchestration.md` (manifest invariants M1 through M7) and are enforced by
|
|
56
56
|
the F3-owned validators `scripts/dev_tools/parallel_manifest_contract.py` and
|
|
57
|
-
`scripts/dev_tools/validate_parallel_orchestrator_state.py
|
|
57
|
+
`scripts/dev_tools/validate_parallel_orchestrator_state.py`, with the manifest half reachable on the
|
|
58
|
+
destination-runtime path as `bash .claude/lib/bash/validate-parallel-manifest.sh`. This is a deliberate delta from
|
|
58
59
|
`.claude/skills/epic-orchestrate/SKILL.md`, whose manifest section carries its schema inline. Read
|
|
59
60
|
the schema from the rule file and the validators; consume it here and never redefine or extend it.
|
|
60
61
|
|
|
@@ -72,13 +73,17 @@ Consumption rules:
|
|
|
72
73
|
Presence of either is an explicit rejection, not a tolerated extra field.
|
|
73
74
|
- A malformed manifest is rejected before any kickoff, recorded as a synthetic Blocking finding in
|
|
74
75
|
the checkpoint. Do not guess a repair, do not silently skip the offending item, and do not launch
|
|
75
|
-
a partial cohort. Validate
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
a partial cohort. Validate with the destination-runtime bash entry point, which needs no Python
|
|
77
|
+
interpreter and is published by push-down alongside `.claude`:
|
|
78
|
+
`bash .claude/lib/bash/validate-parallel-manifest.sh docs/features/parallel/<slug>/parallel.md`.
|
|
79
|
+
Its non-zero exit is the rejection signal and its printed error list, one error per line on
|
|
80
|
+
stdout, is the content of the Blocking finding; exit 1 means the manifest is invalid and exit 2
|
|
81
|
+
means the file is unreadable or uses a YAML construct outside the supported subset. Consume
|
|
82
|
+
`mode` and `max_concurrency` through the same entry point's `--print-mode` and
|
|
83
|
+
`--print-max-concurrency` subcommands rather than reading the frontmatter directly.
|
|
84
|
+
`validate_parallel_manifest_text` in `scripts/dev_tools/parallel_manifest_contract.py` remains the
|
|
85
|
+
repository authority and the parity reference. Manifest validation is deliberately not an MCP
|
|
86
|
+
artifact type.
|
|
82
87
|
|
|
83
88
|
## Cohort Consumption and Ordering
|
|
84
89
|
|
|
@@ -122,10 +127,13 @@ items independently of cohort size: a cohort of twelve items executes at most `m
|
|
|
122
127
|
items at a time. Fill slots in ascending item-key order, keyed on `issue_num`, and refill each
|
|
123
128
|
freed slot with the next unstarted item of the current cohort in that same ascending item-key
|
|
124
129
|
order. A cohort larger than `max_concurrency` therefore launches in several batches from the same
|
|
125
|
-
recorded `main` tip. The batching is a pure function
|
|
130
|
+
recorded `main` tip. The batching is a pure function, reached on the destination-runtime path as
|
|
131
|
+
`bash .claude/lib/bash/compute-concurrency-batches.sh --keys "<k1> <k2> ..." --max-concurrency <n>`.
|
|
132
|
+
It prints a compact JSON array of arrays, returns the batches in order, and sorts the keys itself,
|
|
133
|
+
so determinism does not depend on caller ordering.
|
|
126
134
|
`compute_concurrency_batches(cohort_item_keys, max_concurrency)` in
|
|
127
|
-
`scripts/dev_tools/parallel_cohort_computation.py`
|
|
128
|
-
|
|
135
|
+
`scripts/dev_tools/parallel_cohort_computation.py` remains the repository authority and the parity
|
|
136
|
+
reference.
|
|
129
137
|
|
|
130
138
|
**Mechanical enforcement of the barrier is F7 scope, not this feature's.** F7 delivers a two-layer
|
|
131
139
|
design, because no single `PreToolUse` hook can validate a batch of concurrent `Agent` calls: hooks
|
|
@@ -484,8 +492,11 @@ carries exactly ONE current-generation entry per index, so returned keys landing
|
|
|
484
492
|
`current_cohort` JOIN the pinned members of that one entry instead of forming a second entry with
|
|
485
493
|
the same index, which F3 invariant 13 rejects.
|
|
486
494
|
|
|
487
|
-
Coloring is delegated in full to the Welsh-Powell entry point
|
|
488
|
-
`
|
|
495
|
+
Coloring is delegated in full to the Welsh-Powell entry point
|
|
496
|
+
`bash .claude/lib/bash/compute-cohorts.sh --keys "<k1> ..." --edges "<a>:<b> ..."`, the
|
|
497
|
+
destination-runtime port of `compute_cohorts` in
|
|
498
|
+
`scripts/dev_tools/parallel_cohort_computation.py`, which remains the repository authority and the
|
|
499
|
+
parity reference. No part of the coloring, the vertex ordering, or
|
|
489
500
|
the tie-break is reimplemented by the mutation engine, and the offset is applied entirely inside the
|
|
490
501
|
mutation engine's own recolor function.
|
|
491
502
|
|
|
@@ -142,15 +142,27 @@ Three residual risks are recorded rather than eliminated:
|
|
|
142
142
|
|
|
143
143
|
## Radius Computation and Validation
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
Reach blast-radius derivation, validation, and contention through the **destination-runtime
|
|
146
|
+
PowerShell port** under `.claude/lib/blast-radius/`, which is published by push-down and needs no
|
|
147
|
+
Python interpreter:
|
|
148
148
|
|
|
149
|
-
```
|
|
150
|
-
|
|
149
|
+
```powershell
|
|
150
|
+
Import-Module .claude/lib/blast-radius/BlastRadius.psm1 -Force
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
The facade re-exports the five functions this skill needs: `Get-PlanPaths` (port of
|
|
154
|
+
`extract_plan_paths`), `Get-BlastRadius` (port of `derive_blast_radius`),
|
|
155
|
+
`Get-BlastRadiusFromObservedPaths` (port of `radius_from_observed_paths`), `Test-BlastRadius`
|
|
156
|
+
(port of `validate_blast_radius`), and `Test-BlastRadiusConflict` (port of `conflicts`). Wrap a
|
|
157
|
+
call to `Test-BlastRadius` in `@(...)`: it writes its findings to the pipeline, so a zero-element
|
|
158
|
+
result writes nothing and a one-element result writes a single object.
|
|
159
|
+
|
|
160
|
+
The truth table the port reads is `config/blast-radius.json`, which push-down publishes into the
|
|
161
|
+
destination workspace alongside `.claude`.
|
|
162
|
+
|
|
163
|
+
The Python modules named below remain the repository authority and the parity reference; they are
|
|
164
|
+
cited for their contract, not invoked on the destination-runtime path. Landed contract, consumed
|
|
165
|
+
as-is and never reimplemented here:
|
|
154
166
|
|
|
155
167
|
- **Derivation.**
|
|
156
168
|
`derive_blast_radius(plan_text, spec_text, feature_folder, config, *, source, computed_at) -> BlastRadius`
|
|
@@ -201,19 +213,26 @@ them; it defines none of them.
|
|
|
201
213
|
|
|
202
214
|
## Cohort Seeding
|
|
203
215
|
|
|
204
|
-
|
|
205
|
-
|
|
216
|
+
Reach cohort computation through the **destination-runtime bash entry point** under
|
|
217
|
+
`.claude/lib/bash/`, which is published by push-down and needs no Python interpreter:
|
|
206
218
|
|
|
207
219
|
```bash
|
|
208
|
-
|
|
220
|
+
bash .claude/lib/bash/compute-cohorts.sh --keys "<k1> <k2> ..." --edges "<a>:<b> <a>:<b> ..."
|
|
209
221
|
```
|
|
210
222
|
|
|
211
|
-
|
|
223
|
+
`--edges` is optional; omitting it, or passing an empty string, means the conflict graph has no
|
|
224
|
+
edges. The entry point prints a compact JSON array of arrays on stdout, identical to Python
|
|
225
|
+
`json.dumps(..., separators=(",", ":"))`. On malformed input it prints the reference
|
|
226
|
+
implementation's exact message on stderr and exits 1; a token outside the accepted integer lexis
|
|
227
|
+
`-?(0|[1-9][0-9]*)` is rejected fail-closed with exit 2.
|
|
228
|
+
|
|
229
|
+
Landed contract, mirrored byte for byte by the bash entry point:
|
|
212
230
|
|
|
213
231
|
- `compute_cohorts(item_keys, conflict_edges) -> list[list[int]]` in
|
|
214
|
-
`scripts/dev_tools/parallel_cohort_computation.py
|
|
215
|
-
`item_keys: Iterable[int]` and
|
|
216
|
-
parameter and nothing further to
|
|
232
|
+
`scripts/dev_tools/parallel_cohort_computation.py` is the repository authority and the parity
|
|
233
|
+
reference. The signature accepts exactly two parameters, `item_keys: Iterable[int]` and
|
|
234
|
+
`conflict_edges: Iterable[tuple[int, int]]`. There is no third parameter and nothing further to
|
|
235
|
+
supply at seeding time.
|
|
217
236
|
- The return value is a plain list of lists in deterministic Welsh-Powell order: vertices are
|
|
218
237
|
visited by the composite key `(-degree, item_key)` ascending — descending distinct-neighbour
|
|
219
238
|
degree with ties broken by ascending item key — and each vertex takes the lowest cohort index not
|
|
@@ -227,17 +246,19 @@ The library returns the partition; the planner supplies the record fields.
|
|
|
227
246
|
|
|
228
247
|
### Seeding procedure
|
|
229
248
|
|
|
230
|
-
1. Invoke `
|
|
249
|
+
1. Invoke `compute-cohorts.sh` exactly once per plan run, over the full conflict graph, after every
|
|
231
250
|
item is `prepared` and radius-validated. Derive the conflict edge set by applying
|
|
232
|
-
`
|
|
251
|
+
`Test-BlastRadiusConflict` to every unordered pair of `declared` radii, then pass the pairs as
|
|
252
|
+
`--edges "<a>:<b> ..."` and the item keys as `--keys "<k1> <k2> ..."`.
|
|
233
253
|
2. Record `cohorts[]` at `generation: 0`, each cohort's `item_keys[]` sorted ascending.
|
|
234
254
|
3. Record `conflict_edges[]` as `{a, b, reason}` entries for auditability.
|
|
235
255
|
4. Record `recolor_generation: 0` and `current_cohort: 0`.
|
|
236
256
|
5. Record `max_concurrency` — default 4, bounded 1 through 8 by the F3 schema — without enforcing
|
|
237
257
|
it. Enforcement is F5's, through
|
|
238
|
-
`
|
|
239
|
-
|
|
240
|
-
|
|
258
|
+
`bash .claude/lib/bash/compute-concurrency-batches.sh --keys "<k1> ..." --max-concurrency <n>`
|
|
259
|
+
(the bash port of `compute_concurrency_batches(cohort_item_keys, max_concurrency)`), which fills
|
|
260
|
+
slots in ascending item-key order. Recoloring under add, remove, or drift mutation is F6 and F8
|
|
261
|
+
scope. This skill performs seeding only.
|
|
241
262
|
|
|
242
263
|
### Recomputation parity (planner-owned check)
|
|
243
264
|
|
|
@@ -276,9 +297,29 @@ field; both are prohibited-key rejections in the schema. Commit it to `parallel/
|
|
|
276
297
|
fully resolved form — every negative placeholder `issue_num` replaced by its promoted number —
|
|
277
298
|
before the kickoff artifact is written.
|
|
278
299
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
300
|
+
Validate the manifest with the **destination-runtime bash entry point**, which is published by
|
|
301
|
+
push-down and needs no Python interpreter:
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
bash .claude/lib/bash/validate-parallel-manifest.sh <manifest-path>
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
It prints validation errors one per line on stdout and exits 0 for a valid manifest, 1 for an
|
|
308
|
+
invalid one, and 2 for an unreadable file or a YAML construct outside the supported subset. The two
|
|
309
|
+
default-resolving accessors are subcommands of the same entry point:
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
bash .claude/lib/bash/validate-parallel-manifest.sh --print-mode <manifest-path>
|
|
313
|
+
bash .claude/lib/bash/validate-parallel-manifest.sh --print-max-concurrency <manifest-path>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
They resolve the documented defaults `closed` and `4` when the manifest omits the key or carries a
|
|
317
|
+
malformed value. Consume `mode` and `max_concurrency` through these accessors rather than reading
|
|
318
|
+
the frontmatter directly.
|
|
319
|
+
|
|
320
|
+
`scripts/dev_tools/parallel_manifest_contract.py` (`validate_parallel_manifest_text`,
|
|
321
|
+
`manifest_mode`, `manifest_max_concurrency`) remains the repository authority and the parity
|
|
322
|
+
reference. Manifest validation is deliberately not an MCP `artifact_type`; do not attempt to
|
|
282
323
|
validate the manifest through `mcp__drm-copilot__validate_orchestration_artifacts`.
|
|
283
324
|
|
|
284
325
|
## Checkpoint Persistence
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"shared_surfaces": [
|
|
4
|
+
".claude/settings.json",
|
|
5
|
+
"config/orchestration-routing.json",
|
|
6
|
+
"config/blast-radius.json"
|
|
7
|
+
],
|
|
8
|
+
"shared_surface_globs": [],
|
|
9
|
+
"modules": {
|
|
10
|
+
"claude-runtime": [".claude/**"],
|
|
11
|
+
"config": ["config/**"],
|
|
12
|
+
"docs": ["docs/**"],
|
|
13
|
+
"tests": ["tests/**"]
|
|
14
|
+
},
|
|
15
|
+
"over_breadth_fraction": 0.25
|
|
16
|
+
}
|