Skip to content

[D][Security] Enforce typed dangerous-action blast-radius caps#316

Merged
gnanirahulnutakki merged 4 commits into
devfrom
gnanirahulnutakki/issue-311-blast-radius-caps
Jul 17, 2026
Merged

[D][Security] Enforce typed dangerous-action blast-radius caps#316
gnanirahulnutakki merged 4 commits into
devfrom
gnanirahulnutakki/issue-311-blast-radius-caps

Conversation

@gnanirahulnutakki

@gnanirahulnutakki gnanirahulnutakki commented Jul 15, 2026

Copy link
Copy Markdown
Member

Summary

Closes #311.

Adds an optional signed and attenuable risk_budget authority 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

  • define immutable, digest-bound ToolRiskContract schemas with a closed extractor vocabulary;
  • support numeric facts for destructive targets, objects affected, and bytes affected;
  • support closed categorical facts for secret sensitivity, destination risk, filesystem scope, and irreversibility;
  • normalize and attenuate optional signed passport risk_budget claims with subset-only delegation;
  • atomically reserve all numeric facts across session/agent/lineage scopes with flock, fsync, and same-filesystem atomic publication;
  • require explicit executor outcomes: commit successful/started work, release only work proven not started, and quarantine uncertain crash residue without refund;
  • preserve replay tombstones and retry-safe lifecycle receipt outbox state;
  • integrate preflight/outcome handling into the proxy and HTTP /risk/outcome boundary;
  • emit privacy-safe receipts and bounded metrics without paths, destinations, request IDs, account data, or secret values;
  • add ADR-026, operator/reference documentation, DRP mapping/inventory updates, and synchronized site mirrors.

Security and reliability properties

  • Prompt text, caller-provided labels, and unauthenticated MCP annotations cannot lower risk.
  • Unknown mandatory facts, contract digest mismatch, malformed facts, and current DRP projection all fail closed.
  • Reservation is durable before permit; crash, receipt failure, or missing outcome cannot silently restore destructive authority.
  • Cached sessions retain the originally persisted risk-policy snapshot across policy rotation.
  • Receipt append-once recovery uses thread and inter-process locking and reuses the persisted fact digest.
  • Existing passports without risk_budget preserve 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.
  • Supplemental isolated Python 3.12.8 suite: 1855 passed, 34 skipped, 6 warnings in 87.16s.
  • Ruff, formatter, JSON, private-key, hardcoded-secret, line-ending, and file-size hooks passed.
  • Documentation/site validation: 117 source pages, 113 mirrored artifacts, 287 rendered Hugo pages, 116 static files, 10 public claims, and clean rendered links.
  • Final CodeRabbit review covered all 31 files with no critical or warning [D][Security] Enforce typed dangerous-action blast-radius caps #311 findings.

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

Promotion boundary

This PR targets dev. Human review is mandatory. It does not modify or promote to main.

Summary by CodeRabbit

  • New Features
    • Added optional typed risk_budget support to Mission Passports, including delegated attenuation and stricter validation behavior.
    • Introduced a file-backed risk-budget ledger with atomic reservations, explicit committed vs released lifecycle outcomes, replay/quarantine handling, and privacy-bounded receipts.
    • Added risk-budget metrics plus governance proxy API support for recording risk outcomes (including risk_request_id and a /risk/outcome flow).
  • Bug Fixes
    • Hardened fail-closed enforcement for invalid/unknown risk states and improved denial/outcome mapping and bearer-auth edge cases.
  • Documentation
    • Published ADR-026 and updated reference/spec pages and public-facing README sections.
  • Tests
    • Added extensive lifecycle, delegation, and end-to-end HTTP coverage for contracts, reservations, replay, and quarantine semantics.

Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3d1e7472-065b-4f9e-8160-50e55fdc5900

📥 Commits

Reviewing files that changed from the base of the PR and between 4a2f316 and 262b80b.

📒 Files selected for processing (10)
  • README.md
  • docs/decisions/README.md
  • docs/reference/README.md
  • python/vibap/proxy.py
  • site/content/source/README.md
  • site/content/source/_index.md
  • site/content/source/docs/decisions/README.md
  • site/content/source/docs/reference/README.md
  • site/content/source/docs/reference/_index.md
  • site/data/source_routes.json
🚧 Files skipped from review as they are similar to previous changes (10)
  • site/content/source/docs/reference/_index.md
  • site/content/source/_index.md
  • site/content/source/docs/reference/README.md
  • site/data/source_routes.json
  • docs/reference/README.md
  • site/content/source/docs/decisions/README.md
  • docs/decisions/README.md
  • site/content/source/README.md
  • README.md
  • python/vibap/proxy.py

📝 Walkthrough

Walkthrough

This 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 risk_budget claims.

Changes

Typed dangerous-action risk budgets

Layer / File(s) Summary
Risk contracts and durable ledger
python/vibap/risk_budget.py, python/vibap/__init__.py, python/vibap/denial.py, python/vibap/metrics.py
Adds authenticated tool contracts, typed fact extraction, normalized and attenuated policies, atomic multi-scope reservations, lifecycle reconciliation, quarantine, pruning, integrity validation, metrics, and public exports.
Passport issuance and delegation
python/vibap/passport.py, python/vibap/mission.py, python/vibap/policy_conformance.py
Adds signed risk_budget claims, lineage binding, protected claim issuance, mission loading, and attenuated child policies.
Governance enforcement and lifecycle APIs
python/vibap/proxy.py, python/vibap/receipt.py, python/vibap/aat_adapter.py
Adds risk preflight reservations, lifecycle outcomes, quarantine and outbox handling, risk-aware session events, HTTP endpoints, receipt denial mapping, and related validation updates.
Risk and HTTP validation
python/tests/test_risk_budget.py, python/tests/test_http.py, python/tests/*
Covers contract validation, attenuation, concurrency, replay, persistence, quarantine, privacy, receipts, delegation, caps, HTTP evaluation/outcome flows, and regression coverage.
Protocol and reference documentation
docs/*, README.md, python/README.md, site/content/source/*, site/data/source_routes.json, site/static/repo/*
Documents the risk-budget decision, runtime APIs, hosted references, generated mirrors, indexes, and DRP fail-closed boundary.

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
Loading

Possibly related issues

Possibly related PRs

  • ArdurAI/ardur#314: Both PRs extend the governance tool-evaluation and reservation lifecycle, but this PR applies it to typed risk budgets while that PR addresses spend budgets.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR also adds a --no-tls CLI option in the proxy, which appears unrelated to the risk-budget work and was split out as issue #317. Move the TLS startup/--no-tls change to the separate #317 PR and keep this branch focused on risk-budget enforcement.
Docstring Coverage ⚠️ Warning Docstring coverage is 15.79% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately describes the main change: typed dangerous-action cap enforcement.
Linked Issues check ✅ Passed The implementation and tests cover typed risk contracts, caps, delegation attenuation, fail-closed validation, receipts, and metrics required by #311.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gnanirahulnutakki/issue-311-blast-radius-caps

Comment @coderabbitai help to get the list of available commands.

Comment thread python/tests/test_risk_budget.py Fixed
Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Post-validation claim overrides can break the signed risk-policy binding.

  • python/vibap/passport.py#L674-L697: reject or revalidate overrides of jti, sub, allowed_tools, and risk_budget.
  • python/tests/test_risk_budget.py#L726-L743: cover jti and allowed_tools override 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 win

Fail closed when TLS setup returns no context.

Without --no-tls, missing configured certificates or ARDUR_NO_TLS can still make resolve_tls_paths() return None; 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 win

Block 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 while pending_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 win

Do not treat projected-away risk policies as legacy ungoverned sessions.

MissionDeclaration.policy_claims() omits risk_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 lift

Serialize 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_receipt only 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 win

Avoid embedding a temporary PR number in durable documentation.

The note will become stale once PR #314 lands 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 win

Add 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 win

Test protected-claim overrides through extra_claims.

Add cases overriding jti and allowed_tools, including a risk policy whose omitted lineage was bound to the original generated jti.

🤖 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 win

Exercise the agent ceiling across distinct lineages.

The current concurrency test shares one lineage. Add two concurrent reservations with the same agent_id but 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

📥 Commits

Reviewing files that changed from the base of the PR and between eb63d22 and bd20583.

📒 Files selected for processing (31)
  • README.md
  • docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md
  • docs/decisions/README.md
  • docs/reference/README.md
  • docs/reference/risk-budgets.md
  • docs/specs/ardur-drp-implementation-interop-v0.1.md
  • docs/specs/ardur-drp-mapping-v0.1.json
  • docs/specs/ardur-drp-mapping-v0.1.md
  • python/README.md
  • python/tests/test_http.py
  • python/tests/test_risk_budget.py
  • python/vibap/__init__.py
  • python/vibap/denial.py
  • python/vibap/metrics.py
  • python/vibap/passport.py
  • python/vibap/proxy.py
  • python/vibap/receipt.py
  • python/vibap/risk_budget.py
  • site/content/source/README.md
  • site/content/source/_index.md
  • site/content/source/docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md
  • site/content/source/docs/decisions/README.md
  • site/content/source/docs/decisions/_index.md
  • site/content/source/docs/reference/README.md
  • site/content/source/docs/reference/_index.md
  • site/content/source/docs/reference/risk-budgets.md
  • site/content/source/docs/specs/ardur-drp-implementation-interop-v0.1.md
  • site/content/source/docs/specs/ardur-drp-mapping-v0.1.md
  • site/content/source/python/README.md
  • site/data/source_routes.json
  • site/static/repo/docs/specs/ardur-drp-mapping-v0.1.json

Comment thread docs/decisions/README.md Outdated
Comment thread python/vibap/denial.py
Comment thread python/vibap/risk_budget.py
Comment thread python/vibap/risk_budget.py
Comment thread python/vibap/risk_budget.py
Comment thread python/vibap/risk_budget.py
Signed-off-by: Gnani Rahul Nutakki <gnani.nutakki@gmail.com>
@gnanirahulnutakki

Copy link
Copy Markdown
Member Author

Review-closure update on exact head 4a2f3160cb63b9e24630bdf12978d3336d43de65:

  • Fixed the valid [D][Security] Enforce typed dangerous-action blast-radius caps #311 findings: complete issuer-owned claim protection; canonical UUID overrides; Mission Declaration and mission-ref risk-policy preservation; retained-tool policy projection; lineage-namespaced request identity; global cross-lineage agent accounting; copy-then-persist pruning; receipt append under session-chain coordination; and pending-lifecycle finalization guards.
  • Decomposed the independent fail-open TLS startup seam as [D][Security] Fail closed when proxy TLS configuration is unavailable #317 instead of expanding this focused PR.
  • No migration is included for the prior per-lineage draft ledger because [D][Security] Enforce typed dangerous-action blast-radius caps #311 and that storage shape have never merged or shipped. The final global ledger makes agent ceilings atomic across lineages; ADR-026 records the serialization/throughput trade-off.
  • Local CodeRabbit final review: zero findings.
  • Exact final local gates: 52 focused risk tests; 373 compatibility tests; supplemental full Python suite 1,863 passed / 34 skipped / 6 known warnings; all repository hooks green; 117 source pages / 113 mirrors / 10 public claims; Hugo 287 pages / 116 static files.
  • Commit signature is good ED25519 and DCO is present. The owned branch was pushed by normal fast-forward; dev and main are untouched.

Fresh CI and CodeRabbit on 4a2f316 are still required. Earlier green checks on b34713f4 are historical only.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
python/vibap/risk_budget.py (1)

1224-1287: 🚀 Performance & Scalability | 🔵 Trivial

Global single-file/lock ledger: correctness fix, but now a proxy-wide contention point.

Moving to one global.json + one lock (_path() ignores lineage_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 same fcntl.flock and shares one MAX_RESERVATIONS retention 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 increasing MAX_RESERVATIONS proportionally 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

📥 Commits

Reviewing files that changed from the base of the PR and between b34713f and 4a2f316.

📒 Files selected for processing (21)
  • docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md
  • docs/decisions/README.md
  • docs/reference/risk-budgets.md
  • python/tests/conftest.py
  • python/tests/test_aat_adapter.py
  • python/tests/test_claude_code_hook.py
  • python/tests/test_delegation.py
  • python/tests/test_http.py
  • python/tests/test_mic_conformance.py
  • python/tests/test_mission_binding.py
  • python/tests/test_risk_budget.py
  • python/vibap/aat_adapter.py
  • python/vibap/denial.py
  • python/vibap/mission.py
  • python/vibap/passport.py
  • python/vibap/policy_conformance.py
  • python/vibap/proxy.py
  • python/vibap/risk_budget.py
  • site/content/source/docs/decisions/ADR-026-typed-dangerous-action-risk-budgets.md
  • site/content/source/docs/decisions/README.md
  • site/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>
Comment thread python/vibap/proxy.py
return decision, reason, target.events[-1]
else:
tracker = None
operator_id = None
@gnanirahulnutakki
gnanirahulnutakki merged commit b52a193 into dev Jul 17, 2026
42 checks passed
gnanirahulnutakki pushed a commit that referenced this pull request Jul 17, 2026
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>
gnanirahulnutakki pushed a commit that referenced this pull request Jul 17, 2026
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>
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.

[D][Security] Enforce typed dangerous-action blast-radius caps

2 participants