Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions test/gh-aw-quality.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,29 @@ describe('gh-aw: merge continuation dispatch contract', () => {
}
});

it('worker continuation warns dispatch_workflow is write-once and not schema-probed', () => {
const continuation = workerContent.match(
/## Continue Parent Epic After Merge([\s\S]*?)The remaining instructions apply only to `workflow_dispatch`/
)?.[1] ?? '';

expect(continuation, 'continuation should name the dispatch_workflow tool').toMatch(/dispatch_workflow/);
expect(continuation, 'dispatch_workflow should be called once only with the final payload').toMatch(
/exactly once[\s\S]*complete payload/i
);
expect(continuation, 'empty or placeholder schema probes should be forbidden').toMatch(
/NEVER[\s\S]*empty[\s\S]*(?:placeholder|partial)[\s\S]*(?:probe|discover)[\s\S]*schema/i
);
expect(continuation, 'the prompt should say the schema is already supplied').toMatch(
/full schema[\s\S]*already given[\s\S]*nothing to discover/i
);
expect(continuation, 'noop should be named as the alternative when not dispatching').toMatch(
/not ready to dispatch[\s\S]*noop/i
);
expect(continuation, 'the consequence of a probe should be explicit').toMatch(
/FIRST[\s\S]*wins[\s\S]*later calls[\s\S]*discarded[\s\S]*probe destroys/i
);
});

it('worker continuation comments on the parent epic instead of auto-targeting the merged PR', () => {
const continuation = workerContent.match(
/## Continue Parent Epic After Merge([\s\S]*?)The remaining instructions apply only to `workflow_dispatch`/
Expand Down
18 changes: 13 additions & 5 deletions workflows/squad-implement-worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,15 @@ For a merged pull request:
relationship, falling back to its `Parent: #N` body line.
3. If no parent epic exists, comment on the merged pull request saying its issue
is standalone and that no further work was queued, then stop.
4. Call the prompt-listed `dispatch_workflow` safe-output tool exactly once with
the workflow inputs nested under `inputs`:
4. WRITE-ONCE: call the prompt-listed `dispatch_workflow` safe-output tool
exactly once, and only when the complete payload is ready. NEVER call
`dispatch_workflow` with empty, partial, or placeholder arguments to probe or
discover its schema. The full schema is already given in this prompt; there
is nothing to discover. If you are not ready to dispatch, or there is no next
wave to dispatch, call `noop` instead of `dispatch_workflow`. The FIRST
`dispatch_workflow` call wins and all later calls are silently discarded, so
a probe destroys the real dispatch. When dispatching, nest the workflow
Comment on lines +229 to +233
inputs under `inputs`:

```json
{
Expand All @@ -250,9 +257,10 @@ comment — never a silent exit. Cover both terminal cases:
- No parent epic → state that the pull request's issue is standalone and that
nothing further was queued.

Never emit `noop` for a merge continuation. `noop` is not reported as a comment,
so it strands a merged pull request with no signal about what happens next — the
exact failure this procedure exists to prevent.
Never emit `noop` for a merge continuation as a substitute for the visible
continuation comment. `noop` is not reported as a comment, so it strands a
merged pull request with no signal about what happens next — the exact failure
this procedure exists to prevent.

The remaining instructions apply only to `workflow_dispatch`.

Expand Down
Loading