Skip to content

security: fail closed for unavailable Runtime capabilities - #44

Merged
stone16 merged 1 commit into
mainfrom
codex/issue-16-unavailable-capabilities
Jul 21, 2026
Merged

security: fail closed for unavailable Runtime capabilities#44
stone16 merged 1 commit into
mainfrom
codex/issue-16-unavailable-capabilities

Conversation

@stone16

@stone16 stone16 commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Closes #16

Outcome

  • closes the public Runtime request union over Acquire, Continue, and OpenCitation without implementing future carriers
  • rejects unavailable Continue, citation, federated, and source-native plans with generic typed outcomes before configured scope authority or content I/O
  • keeps every variant on the sealed Kernel path through trusted operands, PackageBudget, provenance, Organization Policy Epoch, and restricted internal audit gates
  • rejects unknown fields, request variants, caller-authored capability controls, and all resolve query strings with generic 422 responses
  • activates executable M0 refusal evidence for ACCEPT-005, ACCEPT-009, and ACCEPT-010 while preserving their real carriers as future

Acceptance evidence

  • Continue returns request_not_available and OpenCitation returns citation_not_available; neither response contains token, locator, carrier, category, Source, Resource, or audit detail.
  • Server-owned federated/source-native Acquire plans return non-retryable request_not_available.
  • Instrumented scope-authority, Provider, CandidateIndex, and source-content twins prove zero prohibited calls; active materialized Acquire still requires the configured scope authority.
  • Unknown request variants/body fields and any query string return 422 {"code":"invalid_request"} before Runtime.
  • OpenAPI freezes the closed request and response discriminated unions.
  • Restricted UNSUPPORTED_CAPABILITY remains internal: the mandatory audit gate retains only a typed count and zero detail; public outcomes expose no audit receipt.
  • Existing empty and exact-authorized Acquire regression suites remain green.
  • No skip/xfail marker remains anywhere under tests/.

Verification

Fresh local CI-equivalent evidence with the PostgreSQL 17 + pgvector harness running:

  • make check
    • build: wheel and sdist succeeded
    • Ruff: passed
    • strict mypy: 88 source files passed
    • unit: 675 passed
    • catalog: 45 passed; 15 invariants / 12 fixtures valid
    • process smoke: 4 passed
    • real PostgreSQL integration/security: 80 passed
  • two-axis review: Standards clean; Spec clean
  • final security regression review: clean

Scope boundaries

No continuation/citation issuance or redemption, federated Provider, source-native ACL carrier, File publication, durable DecisionAudit, or product capability UI is introduced.

Summary by CodeRabbit

  • New Features

    • Added support for continuation and citation-opening requests alongside existing acquisition requests.
    • Added clear “request not available” and “citation not available” responses when required runtime capabilities are unavailable.
    • Existing acquisition requests continue to return resolved packages when supported.
  • Bug Fixes

    • Unsupported requests now fail safely before downstream processing, preventing unnecessary data access.
    • Invalid or unknown request fields are rejected with appropriate client errors.
  • Documentation

    • Updated API, conformance, and security documentation for the expanded request and response formats.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The Runtime now supports closed Acquire, Continue, and OpenCitation requests, gates unavailable capabilities before I/O, returns typed generic refusal outcomes, records restricted internal audit data, and validates the behavior through HTTP, runtime, OpenAPI, and security-catalog tests.

Changes

Runtime capability fail-closed flow

Layer / File(s) Summary
Runtime contracts and capability declarations
engine/runtime/contracts.py, engine/runtime/capabilities.py, engine/runtime/__init__.py, docs/decisions/..., README.md, CONTEXT.md
Adds closed request and outcome unions, opaque continuation/citation wrappers, capability declarations, unsupported-capability taxonomy, and corresponding documentation.
Pre-I/O runtime preflight and audit
engine/runtime/construction.py
Adds unavailable-request policy and budget preflight, mandatory capability gating, restricted unsupported-capability auditing, and typed Runtime resolution paths.
Closed HTTP resolve surface
adapters/http/contracts.py, adapters/http/app.py
Accepts the three closed request variants, rejects closed-schema violations, selects variant-specific purposes, and maps Runtime outcomes to HTTP response unions.
Security catalog activation and validation
eval/catalogs/*, scripts/validate_security_catalog.py, tests/catalog/test_validate_security_catalog.py
Adds Issue #16 activation records, canonical future-carrier validation, fixed schema ordering, and catalog integrity tests.
Runtime and HTTP behavior coverage
tests/unit/test_http_unavailable_capabilities.py, tests/unit/test_runtime_unavailable_capabilities.py, tests/unit/test_http_trust_boundary.py, tests/unit/test_runtime_authorized_evidence.py, tests/unit/test_runtime_empty_package.py, tests/unit/test_effective_scope_runtime.py
Tests zero-I/O refusals, authentication and validation boundaries, audit redaction, OpenAPI closure, and unchanged resolved Acquire behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ResolveEndpoint
  participant Runtime
  participant CapabilityGate
  participant ContentIO
  Client->>ResolveEndpoint: submit closed ResolveWire
  ResolveEndpoint->>Runtime: resolve RuntimeRequest
  Runtime->>CapabilityGate: require capability
  CapabilityGate-->>Runtime: available or unsupported
  alt capability available
    Runtime->>ContentIO: perform runtime I/O
    ContentIO-->>Runtime: resolution data
    Runtime-->>ResolveEndpoint: Resolved
  else capability unavailable
    Runtime-->>ResolveEndpoint: RequestNotAvailable or CitationNotAvailable
  end
  ResolveEndpoint-->>Client: ResolutionOutcomeWire
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.32% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fail-closed handling for unavailable Runtime capabilities.
Linked Issues check ✅ Passed The PR adds closed continue/citation request variants, typed not-available refusals, zero-I/O gating, and acceptance tests for the unavailable-capability fixtures.
Out of Scope Changes check ✅ Passed The changes stay within runtime capability handling, docs, schema, and tests; no unrelated feature work appears introduced.
✨ 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 codex/issue-16-unavailable-capabilities

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@stone16
stone16 merged commit 25dc813 into main Jul 21, 2026
1 of 2 checks passed
@stone16
stone16 deleted the codex/issue-16-unavailable-capabilities branch July 21, 2026 17:02

@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: 1

🧹 Nitpick comments (1)
engine/runtime/__init__.py (1)

65-94: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

RuntimeCapability isn't re-exported despite being a public Runtime.__init__ parameter type.

Runtime(..., acquire_capability: RuntimeCapability = ...) is a public constructor parameter, but RuntimeCapability is never added to this __all__/import list, so callers must reach into engine.runtime.capabilities directly instead of the package surface implied by this file. Confirm if that's intentional (e.g., capability selection is meant to stay internal/test-only for now); if not, add it here for surface completeness.

🤖 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 `@engine/runtime/__init__.py` around lines 65 - 94, Re-export the public
RuntimeCapability type through engine.runtime by adding it to the import and
__all__ list in __init__.py. Keep the existing Runtime constructor API unchanged
and use the defining capabilities module as the source.
🤖 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 `@tests/unit/test_runtime_authorized_evidence.py`:
- Line 405: Remove the redundant type assertions in
tests/unit/test_runtime_authorized_evidence.py at lines 405-405 and 436-436:
each duplicates an earlier assert type(outcome) is Resolved within its test
block. Delete both assertions, or replace them only if a distinct attribute
check was intended.

---

Nitpick comments:
In `@engine/runtime/__init__.py`:
- Around line 65-94: Re-export the public RuntimeCapability type through
engine.runtime by adding it to the import and __all__ list in __init__.py. Keep
the existing Runtime constructor API unchanged and use the defining capabilities
module as the source.
🪄 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

Run ID: 9c0392b3-2cea-4198-851d-b3947e44ae08

📥 Commits

Reviewing files that changed from the base of the PR and between c6a1114 and c8570bf.

📒 Files selected for processing (20)
  • CONTEXT.md
  • README.md
  • adapters/http/app.py
  • adapters/http/contracts.py
  • docs/decisions/0028-fail-closed-unavailable-runtime-capabilities.md
  • docs/decisions/README.md
  • engine/runtime/__init__.py
  • engine/runtime/capabilities.py
  • engine/runtime/construction.py
  • engine/runtime/contracts.py
  • eval/catalogs/security-catalog.schema.json
  • eval/catalogs/security-invariants.yaml
  • scripts/validate_security_catalog.py
  • tests/catalog/test_validate_security_catalog.py
  • tests/unit/test_effective_scope_runtime.py
  • tests/unit/test_http_trust_boundary.py
  • tests/unit/test_http_unavailable_capabilities.py
  • tests/unit/test_runtime_authorized_evidence.py
  • tests/unit/test_runtime_empty_package.py
  • tests/unit/test_runtime_unavailable_capabilities.py

assert outcome.scope_decision.is_empty is True
assert outcome.scope_decision.target_count == 0
assert outcome.package.blocks == ()
assert type(outcome) is Resolved

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the duplicate assert type(outcome) is Resolved. Each of these two tests asserts the same outcome type twice within the same block. It's harmless but redundant; if a distinct second check was intended (e.g. a different attribute), please add that instead.

  • tests/unit/test_runtime_authorized_evidence.py#L405-L405: this assert duplicates the one already at L401; drop it (or replace with the intended distinct assertion).
  • tests/unit/test_runtime_authorized_evidence.py#L436-L436: this assert duplicates the one already at L430; drop it (or replace with the intended distinct assertion).
📍 Affects 1 file
  • tests/unit/test_runtime_authorized_evidence.py#L405-L405 (this comment)
  • tests/unit/test_runtime_authorized_evidence.py#L436-L436
🤖 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 `@tests/unit/test_runtime_authorized_evidence.py` at line 405, Remove the
redundant type assertions in tests/unit/test_runtime_authorized_evidence.py at
lines 405-405 and 436-436: each duplicates an earlier assert type(outcome) is
Resolved within its test block. Delete both assertions, or replace them only if
a distinct attribute check was intended.

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.

security: fail closed for unavailable Runtime capabilities

1 participant