design: expected domain outcomes ("not found", "approval rejected", "still pending") as typed values with branches, not error kinds — the application model that typed composition and reusable modules should carry
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 9
- Forks
- 0
- Avg merge
- 3h 3m
- Merged PRs (30d)
- 509
Description
Written against b015dc6.
Observed behavior
An expected business result has no typed spelling. A plugin's own reason for failing crosses as the engine's kind and prose, so a switch: on "channel not found" versus "not in channel" matches text (#1495). An http step whose API returns 404 for a legitimate "no such customer" is InvalidInput and permanent, and the only way to branch on it is to make the 404 a success with expect: and then read status_code. The checker knows every task output's declared type and still says dyn (#1383), and typed step outputs are a validate-time program of their own (#1634).
Infrastructure failure classification (ErrorKind) is the wrong tool for these: "not found", "rejected" and "pending" are values the application reasons about, not failures the engine retries or surfaces.
Desired outcome
A design record deciding how an expected outcome is declared, produced and consumed:
- A task or
call:declares its outcome set as part of its signature (the descriptor #1571 derives), so a callee's "rejected" is a typed value the caller'sswitch:matches by name and the checker verifies is handled. httpmaps a status or a body field to a declared outcome in the step (the shape ofexpect:extended to name outcomes rather than a boolean), and a plugin returns one through itsoutput_messagerather than an error.- Unhandled outcomes are a validate-time diagnostic, which is what makes a reusable module (#1546's distribution,
call:composition) safer than a copied YAML fragment. - The attempt-outcome model filed beside this owns infrastructure outcomes; this record owns domain outcomes; the boundary is that a domain outcome is never retried by the engine.
Acceptance criteria
- One example (the approval-driven service from the assessing pass's three prove applications) branches on
approved,rejectedandpendingwithout matching text, andflow validaterefuses the file whenrejectedis unhandled. - A plugin conformance case returns a declared outcome and the workflow switches on it on both drivers.
- The checker types the outcome value, proven by a diagnostic when a branch reads a field the outcome does not have.
Constraints and dependencies
- Adjacent: #1495, #1383, #1634, #1571, #1546, #1554 (
with:bindings typed against the callee), the attempt-outcome model. - Invariant 8: the outcome must be expressible, validated, executed by both drivers, and taught in
docs/DSL.md.
Open questions
- Is an outcome a closed enum on the signature or a tagged union carrying a payload?
- How does a
retry:interact with a "pending" outcome the author wants to poll, given the operation-handle record wants to own waiting?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the adjacent issues (#1495, #1383, #1634, #1571, #1546, and #1554) and the attempt-outcome model, then inspect flow validate, both drivers, plugin conformance cases, and docs/DSL.md. Done means the design supports the approval example, validates unhandled outcomes and invalid fields, works for plugins on both drivers, and documents the boundary with infrastructure outcomes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- compilers, devtools, documentation
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100