Skip to content

Merge-continuation dispatch destroyed by empty schema probe; #1766's prompt guard is insufficient #1772

Closed

Description

@bradygaster

Summary

The merge-continuation hop now fires correctly, but the dispatch payload is destroyed by a schema-discovery probe. #1766's prompt-level WRITE-ONCE guard is not sufficient — the fixture was running the fixed worker and the agent probed anyway.

This is the same failure class as #1765, but in workflows/squad-implement-worker.md's ## Continue Parent Epic After Merge path rather than the router.

Evidence

Live run in bradygaster/aspiregregator-squad-e2e, 2026-08-20:

  1. PR Add @copilot coding agent as a Squad member type #13 (implementing child Please Don't Lock squad into using GitHub #8) merged.
  2. Worker run 32394811753 → success. It posted the correct visible next-step comment on the PR, so finding B's fix is working.
  3. Worker's agent/safeoutputs.jsonl contains two entries, in this order:
{"type":"dispatch_workflow"}
{"type":"dispatch_workflow","inputs":{"command":"implement","issue_number":"5"},"workflow_name":"squad"}
  1. dispatch_workflow is configured max: 1. The collector keeps the first item, so the empty probe won and the real payload was discarded.
  2. Dispatched Squad run 32395290857 → success, but its own safe output was:

This workflow run was triggered via workflow_dispatch, but the required command input (github.event.inputs.command) was empty or not provided. […] there is no command to execute, so this run cannot proceed.

  1. Net effect: epic feat: Issue Assignment & Auto-Triage for Squad Members #5 got no new dispatch, child I don't see a tool called task in github copilot #9 was never picked up, and no comment was posted on the epic — the run looked green from the outside. This is the silent-no-op signature that has been unexplained across multiple sessions.

The fixture was NOT stale

Confirmed against bradygaster/aspiregregator-squad-e2e's installed .github/workflows/squad-implement-worker.md:

  • Contains probe or discover ✅
  • Contains the FIRST … wins language ✅

So the worker carried #1766's fix and the probe happened regardless. Prompt instructions alone do not prevent this. The fix must be structural.

Why this matters

This is the exact hop that stalled the original epic. The earlier e2e proved the implement-dispatch hop (/squad implement → worker) is probe-free. It did not prove the merge-continuation hop, which is what this run finally exercised — and it fails.

Suggested direction (needs investigation, not prescriptive)

The root hazard is that a malformed item consumes the single max: 1 slot. Candidate approaches, in rough order of preference:

  1. Raise max for dispatch_workflow on the worker so a probe cannot destroy the real payload. Needs verification of what gh-aw does with a second dispatch and with a malformed/empty one — if empty entries are rejected at validation rather than dispatched, this is safe and cheap.
  2. Assert the contract in CI — extend test/gh-aw-quality.test.ts so the worker's continuation dispatch spec is pinned structurally, not just by prompt phrasing.
  3. Post-dispatch verification — have the worker confirm its dispatch landed and fall back to add_comment on the epic if not, so a swallowed dispatch can never present as green.

Do not simply strengthen the prompt wording again. That was #1766 and it did not hold.

Acceptance

  • A merged child PR in bradygaster/aspiregregator-squad-e2e results in the epic receiving a dispatch that carries command and issue_number intact.
  • agent/safeoutputs.jsonl for the worker run contains no empty dispatch_workflow entry, or the empty entry provably does not suppress the real one.
  • A regression test covers the contract so this cannot silently return.
  • A run that fails to dispatch must not report success without a visible explanation.

Related


Goal and Success Criteria

Added 2026-08-20 during wave:1 triage. Criteria must be checkable from run artifacts without re-running.

Goal: When a child PR merges in the E2E fixture, the Squad epic always receives a dispatch_workflow call carrying command=implement and issue_number=<epic> as inputs — never an empty no-op that presents as green.

SC-1 — Structural guard on dispatch slot (no max: 1 without payload validation).
squad-implement-worker.md's Continue Parent Epic section has max: 1 removed or replaced by a structural guard that rejects an empty payload before consuming the slot. Fails if max: 1 remains at line 204 with no compensating structural check.

SC-2 — Compile-time test pins the dispatch contract (not wording).
test/gh-aw-quality.test.ts asserts the worker's continuation dispatch step has command and issue_number as required inputs, parsed structurally (not substring). Fails if the only coverage for this step is the existing lines 1069-1081 (wording presence only).

SC-3 — E2E artifact shows no empty dispatch entry winning the slot.
In a post-fix run, agent/safeoutputs.jsonl for the worker run contains no {"type":"dispatch_workflow"} entry that precedes the real payload entry, OR the real payload is the sole surviving entry. Fails if an empty dispatch entry appears first in the file and the dispatched Squad run receives no command input.

SC-4 — A failed dispatch is never silent.
If the worker run dispatches Squad and Squad receives an empty command, the worker posts a visible comment on the epic before exiting. Fails if a no-op Squad run exits green with no comment on the parent epic.

Activity

  1. bradygaster commented on Aug 20, 2026

    @bradygaster
    CollaboratorAuthor

    Flight sequencing note — revised graph anchor, 2026-08-20.

    Wave: 1, highest-value correctness fix.

    Depends on: nothing open in this stream. #1766 is merged, and #1767 proved the implement-dispatch hop is clean before surfacing this merge-continuation defect.

    Blocks:

    Safe to run in parallel with: #1770, #1760, #1761, #1762, #1768, #1756, #1759, and #1748 after #1762. It touches workflows/squad-implement-worker.md, not the main workflows/squad.md prompt blocks. Avoid overlapping with any other change to the worker safe-output/continuation section.

    Why / evidence: workflows/squad-implement-worker.md currently allows only one dispatch-workflow item at lines 202-205. The continuation prompt tries to forbid probes at lines 226-233, and tests only pin that prompt wording at test/gh-aw-quality.test.ts lines 1069-1081. The latest #1767 outcome showed the fixture had that wording but still emitted an empty {"type":"dispatch_workflow"} before the real payload; max: 1 kept the probe. That makes this a structural defect, not another prompt-polish task.

    Revised wave table

    Wave Work Notes
    1 #1772 · #1770 · #1760 · #1761 · #1762 · #1768 Parallel. #1772 fixes the core merge-continuation correctness hole. #1770 is independent CI/reporting reliability. #1760 is Scribe heading hygiene. #1761 docs and #1762 preflight decision are disjoint. #1768 is fixture-role cleanup; aspiregregator-squad-e2e is now the honest fixture.
    2 #1748 after #1762 · #1756 ∥ #1759 #1748 rides the adoption/preflight decision from #1762. #1756 and #1759 are disjoint workflows/squad.md hunks: research lines 577-609 vs plan lines 611-637 and implementation lines 832-863.
    3 #1758 after #1759 and #1772 #1758 overlaps #1759 in implementation planning and needs #1772 for a meaningful live end-to-end continuation proof.
    4 #1757 after #1756 and #1758 Validate needs the richer research/spec artifact and the corrected validation-before-acceptance order.
    5 #1763 after #1772 is fixed/green A green e2e no longer exists; that strengthens the case to defer the bots: decision. #1772 does not prove bots: is wrong, it removes the known payload-loss defect before trigger semantics are changed.
    Excluded #1764 · #1769 #1764 is stale branch-debt triage, not the gh-aw continuation/findings stream. #1769 is response format/frequency framework work, unrelated to this dependency graph.

    Current hard edges

    Removed/kept-out edges: #1767 does not depend on #1768 and is now closed; #1768 blocks nothing. #1770 blocks nothing. #1760 blocks no numbered issue here. #1763 is deferred because the workflow-dispatch activation path is still hazardous; #1772 strengthens that deferral by showing the baseline is currently red, but it does not change the hazard's cause from workflow-dispatch/trigger semantics to bot slash comments.

  2. bradygaster commented on Aug 20, 2026

    @bradygaster
    CollaboratorAuthor

    Prior decision record — relevant guardrail, now merged

    While draining .squad/decisions/inbox I found an unmerged Booster decision record that bears directly on this issue. It is being merged into .squad/decisions.md in #1773 so it survives a fresh clone. Summarizing here because it proposes the structural direction this issue needs.

    It documents an earlier, different failure against the same single-slot dispatch budget. In run 32316227601 the agent called the generic dispatch_workflow safe-job with top-level keys:

    {"command":"implement","issue_number":"5"}

    while the compiled schema expected workflow_name plus a nested inputs object. Result: the call was accepted and Squad was dispatched with no inputs. Contributing cause — the compiled prompt's safe-output tool summary advertised the generic dispatch_workflow, so the prompt and the visible schema disagreed.

    That specific shape error was fixed. This issue is a distinct failure mode — a well-formed payload preceded by an empty probe that consumes the single slot. Same budget, same silent-success outcome, different cause. Worth keeping distinct so a fix for one is not mistaken for a fix for both.

    The decision's guardrail clause is the part worth carrying forward:

    Static gates should check both sides of this contract: action-like workflow-dispatch inputs must not have destructive defaults, and continuation dispatch payload keys must be nested under inputs and match the receiving workflow's declared input names.

    Two things follow for this issue:

    1. There is a precedent for a static gate over dispatch payload shape. scripts/check-workflow-input-interpolation.mjs already exists from fix(workflows): interpolate dispatch inputs so merge continuation resolves the epic #1741. Extending that class of gate is more consistent with how this repo has handled the problem than adding another prompt assertion.
    2. The related decision also rejected destructive defaults — specifically, workflows/squad.md must not default workflow_dispatch.inputs.command to cast, because that masks a missing input instead of surfacing it. That is the same principle as this issue's acceptance criterion that a run which fails to dispatch must not report success without a visible explanation. Whatever fix lands here should not reintroduce a masking default.

    Note the existing test at test/gh-aw-quality.test.ts:1069-1081 asserts only that the continuation prompt contains the anti-probe wording. The live run confirmed that wording was present and the probe happened anyway, so that test cannot detect this class of defect.

  3. added
    gh-awGitHub Agentic Workflows integration
    type:bugSomething broken
    triagedIssue has been triaged
    wave:1-nextWave 1 — immediate next sprint
    and removed
    bugSomething isn't working
    on Aug 20, 2026
  4. added
    squadSquad triage inbox — Lead will assign to a member
    on Aug 20, 2026
  5. github-actions commented on Aug 20, 2026

    @github-actions
    Contributor

    📋 Assigned to EECOM (Core Dev)

    Issue: #1772 — Merge-continuation dispatch destroyed by empty schema probe; #1766's prompt guard is insufficient

    EECOM will pick this up in the next Copilot session.

    For Copilot coding agent: If enabled, this issue will be worked automatically.
    Otherwise, start a Copilot session and say:
    EECOM, work on issue #1772

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    gh-awGitHub Agentic Workflows integrationpriority:p0Blocking releasesquadSquad triage inbox — Lead will assign to a membertriagedIssue has been triagedtype:bugSomething brokenwave:1-nextWave 1 — immediate next sprint

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions