Skip to content

Release v3.1.0: fail-closed policy outcomes, revocation, agent feedback, and validation of your own records - #7

Merged
renezander030 merged 10 commits into
mainfrom
release/v3.1.0
Oct 9, 2026
Merged

renezander030 merged 10 commits into
mainfrom
release/v3.1.0

Conversation

@renezander030

Copy link
Copy Markdown
Owner

Release 3.1.0: approval paths that fail closed, approvals that can be withdrawn until dispatch, and records you can verify in your own pipeline. Every addition is optional on existing records; schema IDs and schema_version move to 3.1.0.

What's in it

  1. Fail-closed policy outcome. ApprovalPolicySnapshot.outcome is one of require_approval, auto_approve or deny. Any other evaluator result (non-boolean, unknown, errored) is recorded as deny. Auto approval requires an explicit auto_approve under a policy that allows it. deny ends the request as policy_failed and never reaches a provider.
  2. Validate your own records. scripts/validate_contracts.py takes --envelope, --record KIND FILE, --schema-file, --audit-events/--audit-snapshot/--anchor and --json, and exits 0 (passed), 1 (refused) or 2 (unreadable). action.yml runs the same checks in any repository's CI.
  3. Checks across a set of envelopes. Passing several envelopes also checks that proposal, request, dispatch and audit-stream identities are unique, that each call has one approval request, and that each idempotency key binds one action.
  4. Revocation before consumption. New revoked request state with a revocation record (actor, time, reason), an approval.revoked audit event, approval_revoked dispatch reason, and a complete examples/revoked-envelope.json. A consumed request cannot be revoked, and a revoked one cannot invoke a provider.
  5. MCP elicitation channel. mcp_elicitation is accepted in policies, requests, records and audit events, and docs/mcp-elicitation.md documents the profile. Approved or rejected elicitation decisions must name a present, authenticated human. An answer needs a delivered elicitation, and a high-risk approval through this channel needs a signature.
  6. Agent feedback on refusals. ResolutionRecord.agent_feedback carries a closed reason code, a redacted message, requested changes (JSON Pointers inside /payload) and questions. Requested changes or questions require revise_and_resubmit + new_proposal. The feedback never reopens the decision.
  7. Offline audit export verification. Checks an exported event range (JSON or JSONL) against its AuditSnapshot without the rest of the lifecycle. This includes partial ranges that continue from a retained checkpoint hash.
  8. Review target binding for every action type. Action schemas declare x-review-target, and the review snapshot's target must equal exactly those reviewed arguments. This applies to built-in and trusted custom schemas, not only email.
  9. Reference payload schemas for every built-in action type. Adds strict schemas and example payloads for crm.update_record, ticket.create, db.update_row, api.call and n8n.trigger_workflow. They are wired into ProposedAction, use expected-version guards for record and row updates, and accept no raw URLs for API calls.

Plus portable vectors in tests/release-3.1.json, and README, contracts, architecture and CHANGELOG updates.

Verification

  • python scripts/generate_examples.py && git diff --exit-code -- examples: examples regenerate byte-for-byte.
  • python scripts/validate_contracts.py: all schemas, examples, negative vectors (including the new 3.1 corpus) and lifecycle invariants pass.
  • python -m unittest discover -s tests -v: 79 tests pass (38 existing + 41 new in tests/test_release_3_1.py). The new tests cover each action type end to end, revocation, feedback, elicitation, set checks, audit export ranges and command exit codes.
  • I ran the action's run step locally against the repository examples (4 inputs passed). The new action CI job exercises it on GitHub.

Review notes

  • Base: main @ 4fb3bba. One commit per item, plus the version pin and docs.
  • Touched: all schemas (version pin; additive fields and enums), scripts/validate_contracts.py, scripts/generate_examples.py, examples (regenerated, plus revoked-envelope.json and examples/actions/), docs, .github/workflows/validate.yml (new action job), new action.yml.
  • Untouched: canonicalization corpus, WebAuthn verification, the n8n reference workflow, and the v3.0 rules.
  • The rejected example now carries agent_feedback with revise_and_resubmit / new_proposal instead of do_not_execute / never.
  • The validator's no-argument behaviour is unchanged. File inputs and action.yml make it usable outside a clone; it is still conformance tooling, not a runtime. No package is added.
  • No other open PRs.

- validate_contracts.py accepts --envelope, --record KIND FILE,
  --schema-file, --audit-events/--audit-snapshot/--anchor and --json,
  with exit codes 0 (passed), 1 (refused) and 2 (unreadable input).
- Offline verification of an exported audit range, including partial
  exports that continue from a retained checkpoint hash.
- Two or more envelopes are checked for shared proposal, request,
  call, dispatch and audit-stream identities and for an idempotency key
  bound to two different actions.
- action.yml runs the same checks in any repository's CI.
@renezander030
renezander030 merged commit efae5af into main Oct 9, 2026
2 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.

1 participant