Problem
The current main branch mis-replays a valid approval-free allow prebind as denied. plutus_agent/prebind.py:122-132 computes:
approved = bool(state.get("approval_granted", prior.get("approval_ref") is not None))
When an approval is not required, approval_ref is absent and no approval_granted state is supplied, so replay defaults to approved=False. A live-main probe returned admission="not_admitted" and replayed_boundary_outcome="deny" for an unchanged approval-free allow prebind.
This contradicts the acceptance boundary recorded in #197, which explicitly requires approval-free allow coverage.
Proposed change
Represent approval requirement and approval decision distinctly during prebind construction/replay. An unchanged approval-free allow must replay as admitted/allow; approval-required cases must remain non-admitted until an explicit approval is present. Preserve the distinction among approval-free, approval-required, denied, expired, stale-evidence, and scope-changed states.
Acceptance criteria
- An unchanged approval-free
allow prebind replays as admission="admitted" and replayed_boundary_outcome="allow".
- An approval-required prebind without approval is not admitted.
- Denied, expired, stale-evidence, authority-changed, and scope-changed states remain non-admitted with explicit reason codes.
- Add a truth-table test covering approval-free, approval-required, missing, denied, and expired approval states.
- Existing receipt compatibility and hash binding remain intact.
- No raw prompts, context, tool arguments, credentials, or secrets enter receipts.
Grounding
- Current source:
plutus_agent/prebind.py:105-132 at main commit 1a7be9a37116d9b8225b787992d38e7de0435c6.
- Reproduction: live-main probe returned
not_admitted / deny for unchanged approval-free allow.
- Related acceptance contract: ledger#197, implemented by #198.
- Research lead: Atlas trust-state-machine pattern.
Non-goals
- This does not authorize actions; it corrects replay semantics for recorded state.
Problem
The current
mainbranch mis-replays a valid approval-freeallowprebind as denied.plutus_agent/prebind.py:122-132computes:When an approval is not required,
approval_refis absent and noapproval_grantedstate is supplied, so replay defaults toapproved=False. A live-main probe returnedadmission="not_admitted"andreplayed_boundary_outcome="deny"for an unchanged approval-freeallowprebind.This contradicts the acceptance boundary recorded in #197, which explicitly requires approval-free allow coverage.
Proposed change
Represent approval requirement and approval decision distinctly during prebind construction/replay. An unchanged approval-free allow must replay as admitted/allow; approval-required cases must remain non-admitted until an explicit approval is present. Preserve the distinction among approval-free, approval-required, denied, expired, stale-evidence, and scope-changed states.
Acceptance criteria
allowprebind replays asadmission="admitted"andreplayed_boundary_outcome="allow".Grounding
plutus_agent/prebind.py:105-132atmaincommit1a7be9a37116d9b8225b787992d38e7de0435c6.not_admitted/denyfor unchanged approval-free allow.Non-goals