[0.1.x] feat(workflow): report every data reason of an unavailable affordance #65

Merged
claude merged 1 commit from MEDECA-655-affordance-all-reasons-0.1.x into release/0.1.x 2026-10-04 10:11:20 +00:00
Member

Summary

For MEDECA-655. An unavailable Affordance carried only the DFS-first data message of its guard failure. MEDECA must show every missing prerequisite under a disabled button (for example "plán projektu" and "plán nákladů").

  • Affordance gets an additive field failure: Option[GuardFailure] = None: the whole failure of the gated requires guard. None when available.
  • New public GuardFailure.dataMessages(f): List[UserMessage]:
    • Conjunction: all data leaves of all parts, DFS order, no duplicates.
    • Disjunction: only the data leaves of the first branch that has a data leaf (any one branch is enough to pass, so joining the branches would ask for every alternative).
    • Unauthorized leaves give no message.
    • The head always equals firstDataMessage, the message decide reports as Rejection.Invalid (property test over generated trees).
  • reason is unchanged.

Compatibility: source-compatible for callers that construct Affordance with 4 arguments or read its fields. A pattern match case Affordance(a, b, c, d) would no longer compile; no such match exists in this repository or in MEDECA.

Cherry-pick of the main PR (clean, no adaptation: the workflow module is identical on both lines).

0.1.25 is to carry this change together with the MEDECA-630 MongoFileStore change.

Tests

  • ./mill workflow.jvm.test: 76 passed, 0 failed (63 before; +10 GuardFailureSpec, +3 AffordancesSpec).
  • ./mill workflow.js.test: 76 passed, 0 failed.
  • Pre-push ./mill __.test: passed.
  • Mutation check: joining all Disjunction branches makes 2 GuardFailureSpec tests fail.

🤖 Generated with Claude Code

## Summary For **MEDECA-655**. An unavailable `Affordance` carried only the DFS-first data message of its guard failure. MEDECA must show every missing prerequisite under a disabled button (for example "plán projektu" and "plán nákladů"). - `Affordance` gets an additive field `failure: Option[GuardFailure] = None`: the whole failure of the gated `requires` guard. `None` when available. - New public `GuardFailure.dataMessages(f): List[UserMessage]`: - `Conjunction`: all data leaves of all parts, DFS order, no duplicates. - `Disjunction`: only the data leaves of the first branch that has a data leaf (any one branch is enough to pass, so joining the branches would ask for every alternative). - `Unauthorized` leaves give no message. - The head always equals `firstDataMessage`, the message `decide` reports as `Rejection.Invalid` (property test over generated trees). - `reason` is unchanged. **Compatibility:** source-compatible for callers that construct `Affordance` with 4 arguments or read its fields. A pattern match `case Affordance(a, b, c, d)` would no longer compile; no such match exists in this repository or in MEDECA. Cherry-pick of the `main` PR (clean, no adaptation: the `workflow` module is identical on both lines). **0.1.25 is to carry this change together with the MEDECA-630 `MongoFileStore` change.** ## Tests - `./mill workflow.jvm.test`: 76 passed, 0 failed (63 before; +10 `GuardFailureSpec`, +3 `AffordancesSpec`). - `./mill workflow.js.test`: 76 passed, 0 failed. - Pre-push `./mill __.test`: passed. - Mutation check: joining all `Disjunction` branches makes 2 `GuardFailureSpec` tests fail. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(workflow): report every data reason of an unavailable affordance
All checks were successful
CI / Check Formatting (pull_request) Successful in 59s
CI / Compile (pull_request) Successful in 2m15s
CI / Check Linting (pull_request) Successful in 2m31s
CI / Run Tests (pull_request) Successful in 3m24s
3899cb2892
An unavailable Affordance carried only the DFS-first data message of its
guard failure. A caller that shows why a command is withheld could name
one missing prerequisite, and the user found the others by trial.

- Affordance gets an additive field `failure: Option[GuardFailure]`
  (default None), set to the whole failure of the gated `requires` guard.
- GuardFailure.dataMessages collects every data message: all parts of a
  Conjunction, only the first data-bearing branch of a Disjunction (any
  one branch is enough to pass), auth leaves skipped, no duplicates.
  Its head is always firstDataMessage, the message decide reports.
- `reason` is unchanged.

For MEDECA-655. To be released in 0.1.25 with the MEDECA-630 change.

(cherry picked from commit 12502f8438)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude merged commit d8e4a2fa50 into release/0.1.x 2026-10-04 10:11:20 +00:00
mph referenced this pull request from a commit 2026-10-04 10:14:04 +00:00
Sign in to join this conversation.
No description provided.