Skip to content

Release 0.8.0 — Oversight - #157

Merged
arpanghoshal merged 2 commits into
mainfrom
v0.8/8-release
Sep 12, 2026
Merged

arpanghoshal merged 2 commits into
mainfrom
v0.8/8-release

Conversation

@arpanghoshal

@arpanghoshal arpanghoshal commented Sep 12, 2026

Copy link
Copy Markdown
Member

Item 8 of v0.8. Version, changelog, citation, adapter ranges.

Every guarantee shipped before this milestone verifies the principal that acts. G7 refuses an action whose requester cannot be resolved; nothing whatever was asked of the principal that permits it. approver was a non-empty string, ctrlrun delegate --as was an assertion typed at a shell, and the operator MCP server authenticated who answered without checking they were entitled to. v0.8 asks the question all seven put only to the acting side: who may say yes, and can the kernel tell?

G17 an unentitled approver refused
G18 the requester cannot approve
G19 one principal counts once
G20 a credential revoked before its exp
G21 an unapproved policy decides nothing

Plus break-glass, which carries no guarantee id: the roadmap assigned five to v0.8 and G22–G24 to v0.9, so inventing a sixth would collide or renumber, and a renumber is the maintainer's change. Its evidence is its tests.

Definition of done, checked rather than asserted

  • import ctrlrun imports nothing from an extra, and neither verify nor conformance — asserted in a subprocess.
  • ctrlrun demo runs eight receipts in 0.1s with no network.
  • No setting relaxes a check. The shipped package is grepped for sixteen spellings a flag would take, and the control plants one and finds it. That test had to learn to read string literals as well as identifiers: seven of its patterns could only ever appear as strings and were being discarded, so they were unmatchable by construction.
  • A shipped example exercises the new paths. examples/authority/payments.yaml declares an approver_role and a threshold of two, and reports 19/19 with two not applicable — so G17 and G19 are graded against something this repository ships rather than N/A on everything.

Adapter ranges

Both adapters move to ctrlrun>=0.5,<0.9. The v0.5 contract is not reopened — ApprovalAnswer keeps its shape — and the one behavioural change in InterruptApprovalProvider appears only under approvals_required, a policy key that did not exist before this version: a partial grant is an ApprovalTimeout naming what is outstanding, never a denial, because None from the store means "recorded, short of N" while None from wait means a human's no. Four files state that range and the tests refused the bump until all four moved.

What v0.8 does not close, in one place

  • A persuaded approver gives a valid approval and the receipt records it as one.
  • An entitlement check is against what the granting surface recorded, not a re-derivation from a credential that no longer exists.
  • A revoked credential leaves a log line and no receipt — resolution happens before an action exists, where an expired one leaves a full receipt.
  • A feed is worth what its source is worth: whoever can write it can refuse the operator's own agents. They cannot admit a principal the issuer revoked.
  • A policy change that no verified principal other than the proposer approved decides nothing — which is not the same as "a policy cannot be changed by whoever holds the file".

Still open, and it is a decision rather than a defect

ctrlrun break-glass cannot succeed in any configuration the CLI can load. Control.from_file wires no ApproverIdentity and there is no configuration key for one, so the command always exits 1 saying an approver identity is needed — advice the CLI cannot act on. It fails closed, and delegate --parent <an envelope> is refused by name, so the gated path is the only path. But §5.3's shell example does not run today, and break-glass is reachable only from an embedding application that built its own Control.

Three ways out, each adding surface §11.1 does not list: a configuration key naming an approver identity provider; a credential option on that one command; or striking the shell example and saying the command serves deployments that configure one in code. Recorded in §14.5 as open rather than decided by a build item.

3952 tests, 3m27s with Postgres, plus 56 serial.

Merge order: this, then the tag, then CTRLRun/ctrlrun-docs#7 — the readiness block reads pyproject.toml and states 0.8.0 before it is on PyPI.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Release

    • Released version 0.8.0, focused on oversight and verifying the principal authorizing an action.
    • Added guarantees G17–G21 and documented fail-closed behavior when approver identity validation is enabled.
  • Compatibility

    • Expanded adapter compatibility to support kernel versions from 0.5 through 0.8.
    • Updated compatibility documentation and installation metadata accordingly.
  • Documentation

    • Updated release and citation metadata to reflect version 0.8.0.

Every guarantee before this one verifies the principal that acts. Nothing was
asked of the principal that permits. v0.8 asks the question all seven put only
to the acting side: who may say yes, and can the kernel tell?

  G17  an unentitled approver refused
  G18  the requester cannot approve
  G19  one principal counts once
  G20  a credential revoked before its exp
  G21  an unapproved policy decides nothing

plus break-glass, which carries no guarantee id because the roadmap assigned
five to v0.8 and G22 to G24 to v0.9; its evidence is its tests, one of which
greps the shipped package for sixteen spellings a flag would take.

The definition of done, checked rather than asserted:

  - `import ctrlrun` imports nothing from an extra, and neither verify nor
    conformance: asserted in a subprocess.
  - `ctrlrun demo` runs eight receipts in 0.1s with no network.
  - No setting relaxes a check; T338's control plants one and finds it.
  - A shipped example exercises the new paths: examples/authority/payments.yaml
    reports 19/19 with two not applicable, so G17 and G19 are graded against
    something this repository ships rather than N/A on everything.

Both adapters' kernel range moves to `>=0.5,<0.9`. The v0.5 contract is not
reopened -- `ApprovalAnswer` keeps its shape -- and the one behavioural change
in `InterruptApprovalProvider` appears only under `approvals_required`, a
policy key that did not exist before this version: a partial grant is an
`ApprovalTimeout` naming what is outstanding, never a denial, because `None`
from the store means "recorded, short of N" and `None` from `wait` means a
human's no. Four files state that range and the tests refused the bump until
all four moved.

CITATION.cff moves to 0.8.0.

Signed-off-by: arpan <contact@arpanghoshal.com>
@coderabbitai

coderabbitai Bot commented Sep 12, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 34 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: d1f3ee53-7452-4ca1-bb5f-89cd6bf4dd8c

📥 Commits

Reviewing files that changed from the base of the PR and between 66565a1 and 7b1c760.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • docs/SPEC-v0.8.md
  • src/ctrlrun/cli/main.py
  • tests/test_demo.py
  • tests/test_policy_versioning.py

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 73466c6f-48f0-403c-81a6-01446dfc7eea

📥 Commits

Reviewing files that changed from the base of the PR and between 52ef979 and 66565a1.

📒 Files selected for processing (9)
  • CHANGELOG.md
  • CITATION.cff
  • adapters/langgraph/README.md
  • adapters/langgraph/pyproject.toml
  • adapters/langgraph/src/ctrlrun_langgraph/__init__.py
  • adapters/openai-agents/README.md
  • adapters/openai-agents/pyproject.toml
  • adapters/openai-agents/src/ctrlrun_openai_agents/__init__.py
  • pyproject.toml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The release metadata moves to 0.8.0, documents the Oversight guarantees, and widens both adapters' ctrlrun compatibility from <0.8 to <0.9.

Changes

Release metadata and adapter compatibility

Layer / File(s) Summary
Release version and changelog
pyproject.toml, CITATION.cff, CHANGELOG.md
The project and citation versions change to 0.8.0. The changelog documents the Oversight release and guarantees G17–G21.
Adapter compatibility ranges
adapters/langgraph/*, adapters/openai-agents/*
The adapters widen their documented and declared ctrlrun range from below 0.8 to below 0.9.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~5 minutes

Change: Other

Merge Risk: ⚪ Minimal · up to 66565

The release metadata and adapter version ranges are internally consistent, with no remaining merge-blocking risk.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the 0.8.0 release and its primary Oversight theme. It matches the documented release changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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 v0.8/8-release

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.

A command that cannot succeed in any configuration the CLI can load is a claim
the CLI makes that the code does not honour, and this project refuses that
shape everywhere else. `Control.from_file` -- what the CLI builds -- wires no
ApproverIdentity and there is no configuration key for one, so `ctrlrun
break-glass` always exited 1 telling an operator to build a Control with an
argument the CLI cannot pass.

It failed closed, and `delegate --parent <an envelope>` is refused by name, so
the gated path was the only path either way. Failing closed is the right
direction and not a reason to ship a door that does not open.

The other two ways out were worse, and §14.5 now records why rather than
listing them as open. A configuration key naming the approver's identity
provider would let whoever holds the policy file decide who verifies approvers,
which is the direction §8.4 refuses for require_approved_policy and for the
same reason. A credential option on the one command needs the whole JWT
configuration the CLI does not have -- issuer, audience, key source, algorithm
list -- so it is ten flags invented under release pressure and reviewed by
nobody.

The mechanism is untouched and fully tested: the envelope in the policy hash,
containment on every dimension, max_ttl re-checked on every evaluation,
created_via, the receipt field, revocation and attenuation. Only the shell
entry point defers, to the milestone that gives the CLI a way to verify an
approver.

What it costs is stated rather than hidden: break-glass in 0.8.0 is reachable
only from an application that builds its own Control, and an operator whose
incident response is a shell has nothing here yet.

3952 tests, 3m29s, plus 56 serial.

Signed-off-by: arpan <contact@arpanghoshal.com>
@arpanghoshal
arpanghoshal merged commit acf45c0 into main Sep 12, 2026
14 of 15 checks passed
@arpanghoshal
arpanghoshal deleted the v0.8/8-release branch September 12, 2026 19:14
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