[D][Security] Enforce typed dangerous-action blast-radius caps#316
Conversation
Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (10)
🚧 Files skipped from review as they are similar to previous changes (10)
📝 WalkthroughWalkthroughThis change adds typed dangerous-action risk budgets across mission passports, delegation, governance enforcement, durable ledgers, receipts, HTTP APIs, tests, and protocol documentation. It also defines fail-closed DRP handling for unsupported ChangesTyped dangerous-action risk budgets
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant GovernanceProxy
participant ToolRiskRegistry
participant FileRiskBudgetLedger
participant ReceiptLog
Caller->>GovernanceProxy: evaluate_tool_call with risk_request_id
GovernanceProxy->>ToolRiskRegistry: resolve registered tool contract
ToolRiskRegistry-->>GovernanceProxy: authenticated contract
GovernanceProxy->>FileRiskBudgetLedger: reserve typed numeric facts
FileRiskBudgetLedger-->>GovernanceProxy: permit or denial
GovernanceProxy-->>Caller: evaluation result
Caller->>GovernanceProxy: record_risk_outcome committed or released
GovernanceProxy->>FileRiskBudgetLedger: reconcile reservation
FileRiskBudgetLedger->>ReceiptLog: persist lifecycle receipt
ReceiptLog-->>GovernanceProxy: durable receipt status
Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
python/vibap/passport.py (1)
674-697: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winPost-validation claim overrides can break the signed risk-policy binding.
python/vibap/passport.py#L674-L697: reject or revalidate overrides ofjti,sub,allowed_tools, andrisk_budget.python/tests/test_risk_budget.py#L726-L743: coverjtiandallowed_toolsoverride attempts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/vibap/passport.py` around lines 674 - 697, The post-validation extra_claims update in the passport creation flow can override policy-bound claims. In python/vibap/passport.py lines 674-697, reject or revalidate extra_claims overrides for jti, sub, allowed_tools, and risk_budget before claims.update, preserving the existing risk_budget protection. In python/tests/test_risk_budget.py lines 726-743, add coverage confirming jti and allowed_tools override attempts are rejected.python/vibap/proxy.py (4)
6718-6727: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winFail closed when TLS setup returns no context.
Without
--no-tls, missing configured certificates orARDUR_NO_TLScan still makeresolve_tls_paths()returnNone; the server then silently starts over HTTP without the plaintext warning. Refuse startup unless plaintext was explicitly selected.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/vibap/proxy.py` around lines 6718 - 6727, Update the TLS setup flow around resolve_tls_paths and create_ssl_context so that, when no_tls is false, a missing TLS result or SSL context aborts startup instead of continuing with the HTTP server. Preserve the existing plain-HTTP warning and behavior only when no_tls is explicitly enabled.
4308-4316: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winBlock finalization while lifecycle receipts await delivery.
unresolved_for_session()excludes committed/released outcomes whose lifecycle receipt remains pending. Since attestation finalizes without flushing the outbox, it can anchor a receipt-chain head that was never appended. Flush first or reject whilepending_lifecycles_for_session()is non-empty.Also applies to: 4358-4380
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/vibap/proxy.py` around lines 4308 - 4316, Update the session finalization flow around _finalize_session_locked and its corresponding attestation path to check pending_lifecycles_for_session() before creating or anchoring the attestation. Flush pending lifecycle receipts first, or reject finalization while any remain undelivered, ensuring no receipt-chain head is finalized before its lifecycle receipt is appended.
2607-2628: 🔒 Security & Privacy | 🔴 Critical | ⚡ Quick winDo not treat projected-away risk policies as legacy ungoverned sessions.
MissionDeclaration.policy_claims()omitsrisk_budget, so mission-ref resolution removes the signed policy and Lines 3518-3520 bypass the registry and ledger. Preserve the mission’s normalized risk policy in authoritative claims or fail closed when the session originally carried one.Also applies to: 3518-3520
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/vibap/proxy.py` around lines 2607 - 2628, The _resolve_authoritative_policy_claims method drops the signed risk_budget when replacing passport claims with MissionDeclaration.policy_claims(), causing governed sessions to bypass risk enforcement. Preserve the mission’s normalized risk policy in the authoritative claims, or fail closed when the original session included a risk policy; ensure the downstream registry and ledger logic at the referenced handling remains engaged.
4016-4053: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy liftSerialize receipt append with session-chain advancement.
The session lock is released before append. With shared state/logs, a second proxy can build a child receipt and append it before its parent because
_log_receiptonly uses an instance-local lock. Append under the session coordination lock or use an ordered durable outbox for every receipt.Also applies to: 5895-5977
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/vibap/proxy.py` around lines 4016 - 4053, The receipt append currently occurs after session coordination is released, allowing concurrent proxies to append child receipts before parents. Update the receipt handling in the surrounding session-processing method, including the corresponding flow around the referenced duplicate section, so _log_receipt_once and _log_receipt execute under the same session coordination lock that advances the session chain; alternatively route every receipt through an ordered durable outbox. Preserve lifecycle delivery and ledger updates while ensuring receipt append order follows session advancement.
🧹 Nitpick comments (4)
site/content/source/docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md (1)
42-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAvoid embedding a temporary PR number in durable documentation.
The note will become stale once PR
#314lands or is renumbered. Prefer a branch-neutral explanation of the temporary ordering, or remove the note when ADR-025 is merged.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@site/content/source/docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md` around lines 42 - 45, Remove the temporary PR-specific reference from ADR-026’s durable documentation, or replace it with a branch-neutral explanation of the ordering relationship. Keep the risk-budget reference and surrounding Decision section intact, and ensure no mention of PR `#314` remains.python/tests/test_risk_budget.py (3)
319-334: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAdd a tool-removal attenuation regression.
Use a parent with two tools and a numeric fact unique to the removed tool. Verify the child can retain only the other tool and omit the unused ceiling.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/tests/test_risk_budget.py` around lines 319 - 334, Extend test_child_policy_can_only_reduce_authority with a parent policy containing two tools and a numeric max fact unique to one tool. Build a child policy that retains only the other tool and omits the unused ceiling, then assert attenuate_risk_budget accepts it and preserves the reduced policy.
726-743: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winTest protected-claim overrides through
extra_claims.Add cases overriding
jtiandallowed_tools, including a risk policy whose omitted lineage was bound to the original generatedjti.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/tests/test_risk_budget.py` around lines 726 - 743, Extend test_extra_claims_cannot_replace_validated_risk_policy with cases proving extra_claims cannot override jti or allowed_tools, and include a risk policy whose omitted lineage is bound to the originally generated jti. Preserve the existing risk_budget override assertion and verify each protected-claim attempt raises the expected “cannot override” ValueError.
437-465: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winExercise the agent ceiling across distinct lineages.
The current concurrency test shares one lineage. Add two concurrent reservations with the same
agent_idbut different lineage IDs and assert their combined usage cannot exceed the agent ceiling.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/tests/test_risk_budget.py` around lines 437 - 465, Update test_concurrent_workers_cannot_oversubscribe_lineage_ceiling to create concurrent reservations with the same agent_id but distinct lineage IDs, then assert their combined accepted usage cannot exceed the agent ceiling. Keep the existing barrier, threading, failure checks, and request-level result validation while ensuring the test exercises the agent-wide limit rather than a shared lineage limit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/decisions/README.md`:
- Around line 25-28: Resolve the numbering-rule contradiction in the ADR README:
update the permanent sequential-numbering convention to explicitly allow
temporary branch-local gaps, or remove the PR `#314` allocation note before
publication. Ensure the final guidance does not retain stale PR-specific context
or conflicting ADR numbering requirements.
In `@python/vibap/denial.py`:
- Around line 20-26: Add the RISK_REQUEST_ID_INVALID denial-code constant
alongside the existing risk codes in denial.py, then update the request-ID
validation path in proxy.py to use it instead of RISK_STATE_UNAVAILABLE. Ensure
invalid caller request IDs produce the new code while ledger-state failures
retain RISK_STATE_UNAVAILABLE.
In `@python/vibap/risk_budget.py`:
- Around line 656-661: The agent ceiling must be enforced across all lineages,
not independently per lineage. In python/vibap/risk_budget.py lines 656-661,
move agent accounting to a shared global-agent scope; in lines 1147-1151,
atomically coordinate locks for the global agent account and the lineage
account. In python/tests/test_risk_budget.py lines 437-465, add concurrent
reservations for the same agent across distinct lineages to verify the shared
ceiling.
- Around line 499-521: Update python/vibap/risk_budget.py lines 499-521 to
permit removing ceiling facts that are no longer referenced by retained child
tools, while preserving attenuation checks for retained facts; update lines
464-473 to compare ceiling coverage against the child policy rather than the
parent policy. In python/vibap/passport.py lines 1227-1256, project inherited
policies onto child_allowed_tools so removed tools and their unique facts are
excluded. In python/tests/test_risk_budget.py lines 319-334, add a multi-tool
regression covering removal of a tool with a unique numeric fact.
- Around line 229-231: Update the validation flow around _require_object in the
risk-contract handling path to call _bounded_json_bytes for risk_contract as
well as input_schema, using the risk_contract label and MAX_CONTRACT_BYTES limit
before further processing.
- Around line 661-708: Persist the payload after _prune_payload mutates it and
before every early exit in the reservation flow, including tombstone replay,
reservation conflict/replay, retention-limit failure, and budget-rejection
returns. Update the surrounding method to call the existing persistence
mechanism while holding _locked, while preserving each existing exception and
RiskReservationResult behavior.
---
Outside diff comments:
In `@python/vibap/passport.py`:
- Around line 674-697: The post-validation extra_claims update in the passport
creation flow can override policy-bound claims. In python/vibap/passport.py
lines 674-697, reject or revalidate extra_claims overrides for jti, sub,
allowed_tools, and risk_budget before claims.update, preserving the existing
risk_budget protection. In python/tests/test_risk_budget.py lines 726-743, add
coverage confirming jti and allowed_tools override attempts are rejected.
In `@python/vibap/proxy.py`:
- Around line 6718-6727: Update the TLS setup flow around resolve_tls_paths and
create_ssl_context so that, when no_tls is false, a missing TLS result or SSL
context aborts startup instead of continuing with the HTTP server. Preserve the
existing plain-HTTP warning and behavior only when no_tls is explicitly enabled.
- Around line 4308-4316: Update the session finalization flow around
_finalize_session_locked and its corresponding attestation path to check
pending_lifecycles_for_session() before creating or anchoring the attestation.
Flush pending lifecycle receipts first, or reject finalization while any remain
undelivered, ensuring no receipt-chain head is finalized before its lifecycle
receipt is appended.
- Around line 2607-2628: The _resolve_authoritative_policy_claims method drops
the signed risk_budget when replacing passport claims with
MissionDeclaration.policy_claims(), causing governed sessions to bypass risk
enforcement. Preserve the mission’s normalized risk policy in the authoritative
claims, or fail closed when the original session included a risk policy; ensure
the downstream registry and ledger logic at the referenced handling remains
engaged.
- Around line 4016-4053: The receipt append currently occurs after session
coordination is released, allowing concurrent proxies to append child receipts
before parents. Update the receipt handling in the surrounding
session-processing method, including the corresponding flow around the
referenced duplicate section, so _log_receipt_once and _log_receipt execute
under the same session coordination lock that advances the session chain;
alternatively route every receipt through an ordered durable outbox. Preserve
lifecycle delivery and ledger updates while ensuring receipt append order
follows session advancement.
---
Nitpick comments:
In `@python/tests/test_risk_budget.py`:
- Around line 319-334: Extend test_child_policy_can_only_reduce_authority with a
parent policy containing two tools and a numeric max fact unique to one tool.
Build a child policy that retains only the other tool and omits the unused
ceiling, then assert attenuate_risk_budget accepts it and preserves the reduced
policy.
- Around line 726-743: Extend
test_extra_claims_cannot_replace_validated_risk_policy with cases proving
extra_claims cannot override jti or allowed_tools, and include a risk policy
whose omitted lineage is bound to the originally generated jti. Preserve the
existing risk_budget override assertion and verify each protected-claim attempt
raises the expected “cannot override” ValueError.
- Around line 437-465: Update
test_concurrent_workers_cannot_oversubscribe_lineage_ceiling to create
concurrent reservations with the same agent_id but distinct lineage IDs, then
assert their combined accepted usage cannot exceed the agent ceiling. Keep the
existing barrier, threading, failure checks, and request-level result validation
while ensuring the test exercises the agent-wide limit rather than a shared
lineage limit.
In
`@site/content/source/docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md`:
- Around line 42-45: Remove the temporary PR-specific reference from ADR-026’s
durable documentation, or replace it with a branch-neutral explanation of the
ordering relationship. Keep the risk-budget reference and surrounding Decision
section intact, and ensure no mention of PR `#314` remains.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 7aac67a0-2b76-4002-a983-9127d2f41ca0
📒 Files selected for processing (31)
README.mddocs/decisions/ADR-026-typed-dangerous-action-risk-budgets.mddocs/decisions/README.mddocs/reference/README.mddocs/reference/risk-budgets.mddocs/specs/ardur-drp-implementation-interop-v0.1.mddocs/specs/ardur-drp-mapping-v0.1.jsondocs/specs/ardur-drp-mapping-v0.1.mdpython/README.mdpython/tests/test_http.pypython/tests/test_risk_budget.pypython/vibap/__init__.pypython/vibap/denial.pypython/vibap/metrics.pypython/vibap/passport.pypython/vibap/proxy.pypython/vibap/receipt.pypython/vibap/risk_budget.pysite/content/source/README.mdsite/content/source/_index.mdsite/content/source/docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.mdsite/content/source/docs/decisions/README.mdsite/content/source/docs/decisions/_index.mdsite/content/source/docs/reference/README.mdsite/content/source/docs/reference/_index.mdsite/content/source/docs/reference/risk-budgets.mdsite/content/source/docs/specs/ardur-drp-implementation-interop-v0.1.mdsite/content/source/docs/specs/ardur-drp-mapping-v0.1.mdsite/content/source/python/README.mdsite/data/source_routes.jsonsite/static/repo/docs/specs/ardur-drp-mapping-v0.1.json
Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>
|
Review-closure update on exact head
Fresh CI and CodeRabbit on |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
python/vibap/risk_budget.py (1)
1224-1287: 🚀 Performance & Scalability | 🔵 TrivialGlobal single-file/lock ledger: correctness fix, but now a proxy-wide contention point.
Moving to one
global.json+ one lock (_path()ignoreslineage_id) correctly closes the per-lineage agent-ceiling gap flagged previously, but it also means every risk-governed tool call across all lineages/sessions/agents on this proxy now serializes through the samefcntl.flockand shares oneMAX_RESERVATIONSretention budget. For a busy multi-tenant deployment this could become a throughput bottleneck and make the reservation-retention cap exhaust faster than before. Worth documenting as an operational trade-off (and revisiting if profiling shows contention), e.g. sharding by an orthogonal dimension while still centralizing agent-scope accounting, or increasingMAX_RESERVATIONSproportionally to expected tenant count.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/vibap/risk_budget.py` around lines 1224 - 1287, The global _path and _locked implementation intentionally serializes all lineages through one ledger and reservation-retention budget, so document this operational trade-off near these symbols. Explain the cross-lineage contention and shared MAX_RESERVATIONS implications, and note that sharding or increasing the cap should be revisited based on deployment scale or profiling; do not alter the current global locking behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@python/vibap/risk_budget.py`:
- Around line 1224-1287: The global _path and _locked implementation
intentionally serializes all lineages through one ledger and
reservation-retention budget, so document this operational trade-off near these
symbols. Explain the cross-lineage contention and shared MAX_RESERVATIONS
implications, and note that sharding or increasing the cap should be revisited
based on deployment scale or profiling; do not alter the current global locking
behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 534d125e-f557-4e30-ba23-5aa2904f0862
📒 Files selected for processing (21)
docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.mddocs/decisions/README.mddocs/reference/risk-budgets.mdpython/tests/conftest.pypython/tests/test_aat_adapter.pypython/tests/test_claude_code_hook.pypython/tests/test_delegation.pypython/tests/test_http.pypython/tests/test_mic_conformance.pypython/tests/test_mission_binding.pypython/tests/test_risk_budget.pypython/vibap/aat_adapter.pypython/vibap/denial.pypython/vibap/mission.pypython/vibap/passport.pypython/vibap/policy_conformance.pypython/vibap/proxy.pypython/vibap/risk_budget.pysite/content/source/docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.mdsite/content/source/docs/decisions/README.mdsite/content/source/docs/reference/risk-budgets.md
🚧 Files skipped from review as they are similar to previous changes (8)
- site/content/source/docs/decisions/README.md
- python/vibap/denial.py
- docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md
- docs/decisions/README.md
- docs/reference/risk-budgets.md
- site/content/source/docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md
- site/content/source/docs/reference/risk-budgets.md
- python/vibap/proxy.py
Clears the CONFLICTING state after #303, #320 and #322 landed on dev. proxy.py conflicted in ten regions, almost all formatting noise: #320 ruff-formatted the file, so the merge base was unformatted while both sides were formatted. Normalising all three sides with ruff format before the three-way merge reduced ten regions to one. That one real conflict was the import block. #320 relocated the metrics, rate_limiter and tls imports while this branch added risk_budget beside them; resolved by keeping only risk_budget, after verifying the other three already exist elsewhere in the merged file and would have been duplicated. Verified no control was dropped, counting ours/dev/merged occurrences: approval_fatigue_threshold 2/2/2 and max_approvals_per_hour_per_operator 2/2/2 (dev's control preserved), TLSConfigurationError 0/5/5 (gained from dev), _risk_preflight 2/0/2, _is_internal_risk_event 5/0/5, child_risk_budget 12/0/12, validate_action_risk 2/0/2. The docs/reference index conflict was additive on both sides and resolved as a union. Hugo mirrors were regenerated rather than hand-picked, and each source_sha256 verified against its source. Checkpoint: architect/sessions/issue-311-blast-radius-caps/2026-07-14-journal.md Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>
| return decision, reason, target.events[-1] | ||
| else: | ||
| tracker = None | ||
| operator_id = None |
Second dev merge, after #316 landed the risk-budget bullet in the README. This lane's first bullet is dev's bullet plus the governed-subagent-adapter clause, so it was kept and dev's separate risk-budget bullet appended rather than picking either side. Hugo mirrors regenerated; --check verifies 119 source-backed pages and 113 mirrored artifacts. Checkpoint: architect/sessions/issue-312-governed-subagent-adapter/2026-07-14-journal.md Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>
Second dev merge, after #316 landed. Only the generated site/content/source/README.md mirror conflicted; regenerated with sync_source_docs.py rather than hand-picking either side. --check verifies 118 source-backed pages and 113 mirrored artifacts. Checkpoint: architect/sessions/issue-300-recognition-fingerprints/2026-07-14-journal.md Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>
Summary
Closes #311.
Adds an optional signed and attenuable
risk_budgetauthority for dangerous tool actions. Trusted, JSON-Schema-bound tool contracts extract typed blast-radius facts before execution; one durable transaction reserves numeric impact across session, agent, and delegation-lineage scopes before ordinary policy can permit the action.What changed
ToolRiskContractschemas with a closed extractor vocabulary;risk_budgetclaims with subset-only delegation;flock,fsync, and same-filesystem atomic publication;/risk/outcomeboundary;Security and reliability properties
risk_budgetpreserve current behavior.Validation
44 passed— focused risk-budget suite, including multiprocessing deduplication, crash recovery, policy rotation/cache refresh, immutable contracts, replay tombstones, and quarantine non-refund.291 passed in 9.03s— risk budget, HTTP, passport, delegation, lineage, proxy, receipt, DRP conformance, and mapping tests on the exact post-formatter commit.1855 passed, 34 skipped, 6 warnings in 87.16s.Review disposition
The final independent review found one minor pre-existing gap: the CLI API-token trim test bypasses CLI argument loading. It is not caused by this branch and is tracked separately in #315 with focused security/test acceptance criteria.
Cost and operability
Risk extraction is local, bounded, and deterministic: it performs no inventory scan or network request, avoiding external request charges, data egress, and runtime availability coupling. Ledger/tombstone retention is bounded, but operators should still monitor the private state directory and receipt storage for volume growth.
Standards references
-01: https://datatracker.ietf.org/doc/draft-niyikiza-oauth-attenuating-agent-tokens/-10: https://datatracker.ietf.org/doc/html/draft-nelson-agent-delegation-receipts-10Promotion boundary
This PR targets
dev. Human review is mandatory. It does not modify or promote tomain.Summary by CodeRabbit
risk_budgetsupport to Mission Passports, including delegated attenuation and stricter validation behavior.risk_request_idand a/risk/outcomeflow).