NW3 (CC-26 §6 PoC): delegate trekplan Phase 7 synthesis to a synthesis-agent, adopt only if Δ main-context ≥30% with no quality loss. Operator chose the deterministic-proof path (live ≥3-run bake-off was env-blocked: no API key; installed plugin is a cache copy so a new agent is invisible to `claude -p`). Decisive structural finding: trekplan Phase 5 runs the swarm FOREGROUND, so its outputs are already resident in main before Phase 7. Delegating only Phase 7 evicts nothing → Δ_faithful = 0% (BASE-independent). The ≥30% saving needs an out-of-scope Phase-5 redesign (swarm-writes-to-disk / nested orchestrator). VERDICT: DECLINED per measurement. - agents/synthesis-agent.md — dormant, schema-conformant deliverable (NOT wired) - lib/plan/synthesis-digest-schema.mjs — digest output contract (+ tests) - scripts/synthesis-measure.mjs — deterministic Δ-accounting core (+ tests) - tests/fixtures/synthesis/ — 7 exploration outputs + representative digest - docs/T1-synthesis-poc-results.md — measurement + verdict (reproducible) - CLAUDE.md — agent table row (doc-consistency: 24 agents) Tests 670 → 695 (693 pass / 2 skip / 0 fail). `claude plugin validate` clean (only the pre-existing root-CLAUDE.md warning). commands/trekplan.md untouched. [skip-docs] rationale: no user-facing feature ships (NW3 declined; agent dormant and unwired). The substantive doc is docs/T1-synthesis-poc-results.md; the README/CHANGELOG roll-up for NW1–NW3 is the S13 coordinated release per docs/W1-narrow-wins-plan.md §S13. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LqBYc8Ltrk7LipyJmGxXiB
76 lines
3.4 KiB
Markdown
76 lines
3.4 KiB
Markdown
# Dependency & Data-Flow Report — output of dependency-tracer
|
||
|
||
Task: Add a per-wave concurrency cap to trekexecute headless launches.
|
||
|
||
## Import / call chain relevant to the task
|
||
|
||
```
|
||
commands/trekexecute.md (Phase 2.6 prose)
|
||
└─ generates → templates/headless-launch-template.md (Bash here-doc)
|
||
├─ reads SHARED_CONTEXT_FILE (append-system-prompt-file)
|
||
├─ spawns claude -p ×N (one per wave member, backgrounded with &)
|
||
└─ waits via `wait` on collected PIDs
|
||
└─ consumes → .session-state.local.json (Handover 7; session graph)
|
||
```
|
||
|
||
## Data flow
|
||
|
||
1. session-decomposer emits a plan with wave groupings + a dependency graph.
|
||
2. trekexecute Phase 2.6 turns each independent wave into a launch batch.
|
||
3. The template loops over batch members and backgrounds each `claude -p`,
|
||
collecting PIDs into a Bash array, then `wait`s for the whole batch.
|
||
4. There is **no slot-limiting** between "background member" and "wait" — the
|
||
degree of parallelism equals the batch size.
|
||
|
||
## Side effects
|
||
|
||
- Each subprocess does `git` work under `GIT_OPTIONAL_LOCKS=0`; high concurrency
|
||
raises the chance of index-lock contention (mitigated, not eliminated).
|
||
- `--max-budget-usd` is per-subprocess; total spend scales with batch size, so a
|
||
concurrency cap also indirectly bounds burst spend.
|
||
|
||
## What a cap touches
|
||
|
||
- **Pure-addable:** a `maxParallel` resolver in `lib/` (reads plan/profile/flag,
|
||
returns an integer ≥ 1). No existing module imports would change.
|
||
- **Wire-in:** the template's loop must consume slots (e.g. a counting semaphore
|
||
in Bash, or `xargs -P <n>`). This is the only behavioral edit.
|
||
|
||
## No hidden dependents
|
||
|
||
Grepped for other call sites of the launch template — only trekexecute Phase 2.6
|
||
and the headless-launch-template test reference it. A cap is local in blast
|
||
radius.
|
||
|
||
## Resolver input provenance (what the cap reads)
|
||
|
||
The resolved integer must be derived from, in lookup order:
|
||
|
||
1. **CLI flag** `--max-parallel <n>` — parsed by `lib/parsers/arg-parser.mjs`;
|
||
highest precedence (operator override).
|
||
2. **Brief signal** — `phase_signals` already carries per-phase orchestration
|
||
shape; a `max_parallel` hint here is honoured if no flag.
|
||
3. **Profile** — `lib/profiles/` resolves `--profile economy|balanced|premium`;
|
||
each profile can carry a `max_parallel` default. This is the same lookup
|
||
order `phase_models` uses, so the resolver should *reuse* profile-resolver,
|
||
not re-implement precedence.
|
||
4. **Hard default** — `batchSize` (i.e. no cap / current behavior), so the change
|
||
is a strict no-op until someone opts in.
|
||
|
||
## Downstream of the cap
|
||
|
||
- **Budget:** total burst spend = `min(cap, batchSize) × per-member --max-budget-usd`.
|
||
A cap therefore tightens the worst-case spend envelope — worth noting in the
|
||
plan's risk/observability section.
|
||
- **Git contention:** fewer concurrent `git`-touching subprocesses → fewer
|
||
`index.lock` races. `GIT_OPTIONAL_LOCKS=0` reduces lock acquisition but does
|
||
not serialize ref updates; the cap is the structural mitigation.
|
||
- **Classifier exposure:** a smaller concurrent fan-out under `auto`/`bypass`
|
||
lowers the surface the proliferation classifier (S7 F4) scrutinises.
|
||
|
||
## Data-flow invariant to preserve
|
||
|
||
`SHARED_CONTEXT_FILE` is built once per wave and read by every member; the cap
|
||
must not cause it to be rebuilt per-slot (would defeat the cache prefix). Slot
|
||
limiting happens at spawn time only; the context file is wave-scoped, not
|
||
slot-scoped.
|