Skip to content

How a run ends: cancelled, why it stopped, how a called agent ended; the egress boundary said; a mixed model list refused - #32

Merged
dittops merged 4 commits into
masterfrom
rulings/egress-cancelled-ended-rungs
Nov 14, 2026
Merged

dittops merged 4 commits into
masterfrom
rulings/egress-cancelled-ended-rungs

Conversation

@dittops

@dittops dittops commented Nov 14, 2026

Copy link
Copy Markdown
Member

Four rulings from the owner, each made with Bud Agent Flow's engine and corpus in front of it.

What changes

A run something outside it ended is cancelled. A workflow's run ended final, parked or stopped. A run that a port ended (if-still-running: stop or cancel-previous), or that a person at the host ended, was reported stopped with the runs that failed. It is now cancelled: between stages, with undo: yes taking back what it wrote newest first and then-run: starting what the port says. run_workflow(..., ended=), Callers.start, WorkflowResult.cancelled_by.

stopped says why. WorkflowResult.why is one of eight words (said-so, declined, nobody-answered, nobody-decided, a-call-failed, reached-a-limit, does-not-fit, not-runnable), so a person's no is not read as a broken call.

Two defects in the reference runtime, fixed. A no, or silence, with no exit written for it ended the block instead of stopping the run (a workflow that gives nothing finished final after a person said no). A run that calls a workflow that waits for a person was stopped; it is parked, at its own stage.

A stage says how its agent ended. steps.<stage>.ended is ran-out when the agent reached a limit and answered with what it had, finished otherwise. A word and not a new exit: the stage did answer, a word can be shown to a person and handed back, and no existing workflow changes.

A classifier and a language model in one model: list on a rung are refused. loader/a-rung-with-two-kinds-of-reader was a warning. Measured on Bud Agent Flow's corpus, 13 of 136 trees write it meaning a cascade; a model: list is a fallback for a failed call, and the framework under that engine treats an unsure classifier as a failed call, so one file ran two ways. The ladder is the cascade: two agents on two rungs.

pact check and pact discover say where the egress boundary is. One line after a clean check (not a diagnostic, so --deny-warnings is unaffected), and egress: {boundary, allows} in the inventory.

What a runtime must match

  • Twelve new shared cases (43 workflow cases), five on a new tree tests/conformance/trees/booked-visits.
  • Every workflow case's expect gains why, cancelled-by, started. The 31 existing cases are otherwise unchanged (verified key by key).
  • digests.json: triaged-defects moves because the tree was edited (every existing contract-digest is as it was); booked-visits is new.

Verified

  • scripts/test-all.sh: 5,081 tests (1,687 Rust + 3,394 adapter), clippy, every shipped tree under --deny-warnings, TypeScript, seven adapter targets.
  • mkdocs build --strict.
  • Live on gpt-4o-mini: 13 of 13.

🤖 Generated with Claude Code

jithinAB and others added 4 commits November 14, 2026 23:48
…oundary

Leaving `allow-egress:` out draws no boundary (Q17), which is also what a
forgotten line looks like: both printed `OK — loaded cleanly`, and the
inventory carried neither an absent line nor an empty list.

- `pact check` prints one line after the result of a clean check: no line
  written (everything may talk outside), `[]` (nothing may), or the parts
  listed. On stdout, never a diagnostic, so `--deny-warnings` is unaffected.
  An agent checked on its own is told the boundary of the workspace around it.
- `pact discover` carries `egress: {boundary: open|closed|listed, allows}`
  on each workspace.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…d, and a mixed model list refused

- `cancelled`: a run something outside it ended (a port's `if-still-running:
  stop` or `cancel-previous`, or the host). Between stages; `undo: yes` takes
  back what it wrote, newest first; `then-run:` starts what the port says.
  `run_workflow(..., ended=)`, `Callers.start`, `WorkflowResult.cancelled_by`.
- `WorkflowResult.why`: the one word for why a `stopped` run stopped, of eight.
- The reference ended the block on a no, or silence, with no exit written for
  it; it now stops the run. A run that calls a workflow that waits was
  `stopped`; it is `parked`, at its own stage.
- `steps.<stage>.ended` on a stage an agent answered: `ran-out` when the agent
  reached a limit and answered with what it had (`RanOut`), else `finished`.
- `loader/a-rung-with-two-kinds-of-reader` is an error: a classifier and a
  language model in one `model:` list read as a cascade and are a fallback.
  Measured on Bud Agent Flow's corpus, 13 of 136 trees write it.
- Twelve shared cases (43 workflow cases), a new tree `booked-visits`, and
  three new keys in every workflow case's `expect`.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
`assign-only` shared `assigner` with `fix-item`, and the checker's tests
that edit `assigner` then broke a second workflow.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@dittops
dittops merged commit b946056 into master Nov 14, 2026
4 of 5 checks passed
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.

2 participants