Skip to content

fix(mcp): skip parallel children, gate-respecting loops, end: steps - #131

Merged
5uck1ess merged 4 commits into
mainfrom
fix/mcp-parallel-loop-end
Nov 4, 2026
Merged

5uck1ess merged 4 commits into
mainfrom
fix/mcp-parallel-loop-end

Conversation

@5uck1ess

@5uck1ess 5uck1ess commented Nov 4, 2026

Copy link
Copy Markdown
Owner

Cause

The MCP path (devkit_start / devkit_advance, used by every skill) diverged from the CLI engine:

  • It never skipped parallel children. In all 8 parallel workflows the children sit before their dispatcher, so each child ran one by one, then the dispatcher asked for them all again. The dispatcher stored one consolidated string, so {{review-smart}} etc. were never set from it.
  • A passing loop gate ended the loop without checking until, and a failing gate let until end it. self-test asks the agent to say DONE, so it could finish with tests still red. Running out of iterations advanced silently. advancePastLoop ignored branch:.
  • feature.yml and bugfix.yml put the TINY quick-fix step last, with nothing ending the full path, so every full run fell through into quick-fix after its report (both executors).

Fix

  • Workflow.ParallelChildren / Workflow.NextIndex (src/engine/workflow.go) drive the sequential walk in both executors.
  • Parallel dispatch over MCP: the response shows each child's model, interpolated prompt and require:. devkit_advance takes an outputs object with one string per child (required), validates each child's require:, and stores them under the child ids.
  • Guard: a parallel dispatcher gets the prompt fence (Agent/Task allowed, Write/Edit/Bash blocked under hard). The old allow-all for parallel would otherwise switch off the tri-* fence now that MCP parks on the dispatcher. A dispatcher with no own enforce is soft if any child is soft (research/self-audit fan-outs).
  • Loops over MCP complete only when the gate passes and until appears in output supplied in that same advance. Retry responses include gate output and exit code. At max: halt with loop_exhausted if the gate is still failing, otherwise continue with a LOOP EXHAUSTED notice. Research loops cap at 2 rounds on purpose, so halting on every exhaustion would break them. Loop steps honour branch: and end:.
  • New end: true step field: complete after this step unless a branch matched. Set on feature.yml final-report and bugfix.yml summary. The CLI engine honours it on prompt, loop and dispatcher steps.
  • devkit_advance without output clears the step's earlier output (no branching on stale values).
  • Validation rejects non-prompt parallel children, children with loop/branch/end, gotos into a parallel child, and branch: on a dispatcher.
  • Docs: creating-workflows schema (real branch syntax, end, parallel outputs, loop completion), CLAUDE.md rows.

Tests

  • src/mcp/flow_test.go: children-before-dispatcher layout, leading children, per-child outputs, child require:, gate+until semantics, stale sentinel, exhaustion halt/notice, loop branch, end, stale branch output.
  • Engine: end (including on a dispatcher), NextIndex, validation rules, dispatcher enforce, shipped feature/bugfix end before quick-fix.
  • Guard: parallel+hard blocks Write and allows Agent.

…loops, end: steps

- Add Workflow.ParallelChildren/NextIndex and use them in both executors.
  devkit_start/devkit_advance now skip parallel children (they previously
  ran one by one and then again from the dispatcher). The dispatcher
  response carries each child's interpolated prompt, and devkit_advance
  takes an `outputs` object with one result per child so {{child-id}}
  resolves downstream.
- Loops over MCP complete only when the gate passes AND the until sentinel
  appears; a failing gate is no longer overridden by DONE. Retry responses
  include the gate output. On max: halt (loop_exhausted) if the gate is
  still failing, otherwise continue with a LOOP EXHAUSTED warning.
  advancePastLoop now honours branch rules like the CLI engine.
- New `end: true` step field: the workflow completes after that step
  unless a branch matched. Set on feature.yml final-report and bugfix.yml
  summary so the full paths no longer fall through into quick-fix.
- Validation rejects parallel children that are not plain prompt steps
  and branch gotos that target a parallel child.
- Docs: creating-workflows schema (branch syntax, end, parallel outputs,
  loop completion), CLAUDE.md rows.
… fresh loop sentinels

- devkit_advance checks each parallel child's require: contract against its
  reported output (children are skipped in the walk, so nothing else did).
- CLI engine: end: true on a parallel dispatcher now completes the workflow.
- MCP loops only accept the until sentinel from output supplied in the same
  advance; a DONE left over from a gate-failed iteration no longer completes
  the loop once the gate turns green.
…n halt

- Guard treats a parallel dispatcher like a prompt step (Agent/Task allowed,
  Write/Edit/Bash blocked under hard). MCP now parks on the dispatcher, and
  the old allow-all default turned the tri-* fence off.
- A dispatcher without its own enforce is soft if any child is soft, so
  research/self-audit fan-outs keep their WebSearch/Bash.
- devkit_advance without output clears the step's earlier output, so a
  revisited step can't branch on a stale value.
- Dispatch response shows each child's require: contract.
- haltWorkflow persists the halted status before clearing state.
- Validation rejects branch: on a parallel dispatcher.
@5uck1ess

5uck1ess commented Nov 4, 2026

Copy link
Copy Markdown
Owner Author

🛡️ Security review — Daybreak Blue

gpt-6-sol · daybreak_blue cyber access program · high effort · reviewed at bd73e3b

Clear — no security objection. No effect on the merge.

Reviewed head bd73e3b473ea7256d8ddeabf9d1c598ef59eda59 against dc024cdead038a12a972b4f1dd5242378f35f185. I found no PR-introduced security objections. I traced the changed MCP inputs, workflow validation, guard decisions, command and gate execution, and session transitions through their callers and callees. No dependencies changed.

SECURITY: CLEAR


Run by pr-merge-brief on every READY, before it is published.

@5uck1ess

5uck1ess commented Nov 4, 2026

Copy link
Copy Markdown
Owner Author

🔍 REVIEW — automated merge-readiness

Review only — a verdict on this PR; no code was changed. Corrections, when applied, arrive as a separate ## 🔧 Corrections applied comment.

gpt-6.1-sol · high effort · fast speed · reviewed at bd73e3b

Reviewed head bd73e3b473ea7256d8ddeabf9d1c598ef59eda59 against base dc024cdead038a12a972b4f1dd5242378f35f185.

No demonstrated merge-blocking defects found after reviewing the complete diff and affected code paths. Tests cover parallel outputs, gate/until behavior, stale outputs, and terminal steps.

CI is GREEN as supplied. Tests were not rerun in this read-only environment.

VERDICT: READY


Automated pre-merge review by pr-merge-brief. A full-context READY on the current head is auto-merged; a diff-only or failover review waits for the maintainer.

@5uck1ess
5uck1ess merged commit 90c2b8d into main Nov 4, 2026
9 checks passed
@5uck1ess
5uck1ess deleted the fix/mcp-parallel-loop-end branch November 4, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant