Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ the framework's own interrupt, and a framework with no such primitive does not n

{/* generated from the suite, pyproject and the soak (mdx) — run the generator */}
- **Version 0.11.0**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later, tested on 3.11 to 3.14.
- **6,221 tests**, every version specified before it was written and every requirement mutation-tested.
- **6,232 tests**, every version specified before it was written and every requirement mutation-tested.
- **32 guarantees you can check in your own setup**, with `ctrlrun verify` against your policy, on your store's backend, in a scratch store it creates.
- **One host: a file.** SQLite, no server, no ops. **Many hosts: Postgres**, the same guarantees, graded by the same suite.
- **Soaked for 20m 0s on postgres**: 889,735 actions, 0 unattributed ambiguous outcomes, positive control fired. Nothing here establishes what only accumulates over days. [What it does not establish](https://ctrlrun.dev/docs/production/soak).
Expand Down
32 changes: 24 additions & 8 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,30 @@ cycle nobody had recorded, `jwt_identity` ⇄ `revocation`, where `revocation.py
handler. One copy was always right and the direction was wrong: the class now lives in
`revocation.py`, which `jwt_identity.py` already imports, and `jwt_identity` re-exports it.

**One layering cycle remains, named in the test rather than left to a reader.** `authority.py`
imports `Condition` and `parse_conditions` from `policy.py` deliberately, per the exception
above, and `policy.py` reaches back from `_canonical_authority` and `hash_with_authority`. That
edge cannot be removed by relocation: `_from_section` *constructs* an `Authority` and
`canonical_grants` *consumes* one, so neither moves below `policy.py`, and moving the two callers
up to `control.py` would change what `policy_hash` is taken over, which is evidence in every
receipt rather than an implementation detail. `RECORDED_LAYERING_CYCLES` holds that one pair and
nothing else, so a second one fails the suite.
**And then the last one went too, from the side that was actually loose.** `policy <-> authority`
looked unfixable, and the reason given was true but incomplete: `_from_section` *constructs* an
`Authority` and `canonical_grants` *consumes* one, so neither moves below `policy.py`, and moving
the two callers up to `control.py` would change what `policy_hash` is taken over, which is
evidence in every receipt rather than an implementation detail. All of that holds. It only
describes one side of the cycle.

The other side was `authority.py` importing eight names from `policy.py`, and not one of them is
`Policy`: the supported schemas, the strict YAML loader, the condition grammar, type-strict
equality, key validation. That is the policy **document grammar**, and it is shared vocabulary
rather than either axis's property. It now lives in `grammar.py`, below both, so `authority.py`
does not import `policy.py` at all.

The v0.3 exception above is not repealed by this, it is honoured more exactly. `SPEC-v0.3.md`
§4.5 requires the two axes to share **one** condition evaluator, because a second would be a
second place for `True` to start comparing equal to `1`. That one evaluator is now owned by
neither axis instead of by one of them.

Nothing moved but an address: every block was moved verbatim and `policy.py` re-exports all
thirty-four names, so `SPEC-v0.1.md` §8's frozen `__init__` block and `SPEC-v0.3.md` §8's
`from .policy import Condition, parse_conditions` both stay literally true.

**`RECORDED_LAYERING_CYCLES` is now empty, and it is meant to stay empty.** A new entry is a
decision rather than a fix, and it carries the reason the edge cannot be relocated.

## 7. What changes after v0.1 (and what doesn't)

Expand Down
54 changes: 27 additions & 27 deletions docs/CLAIMS.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/production/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ need. `test_the_first_line_of_the_section_says_which_store_and_why` asserts the

{/* generated from the suite, pyproject and the soak (full) — run the generator */}
- **Version 0.11.0**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later, tested on 3.11 to 3.14.
- **6,221 tests**, every version specified before it was written and every requirement mutation-tested. [Read more](/docs/how-this-is-built).
- **6,232 tests**, every version specified before it was written and every requirement mutation-tested. [Read more](/docs/how-this-is-built).
- **32 guarantees you can check in your own setup**, with `ctrlrun verify` against your policy, on your store's backend, in a scratch store it creates. [Read more](/docs/security/verify-guarantees).
- **One host: a file.** SQLite, no server, no ops. **Many hosts: Postgres**, the same guarantees, graded by the same suite. [Read more](/docs/production/postgres).
- **Soaked for 20m 0s on postgres**: 889,735 actions, 0 unattributed ambiguous outcomes, positive control fired. Nothing here establishes what only accumulates over days. [Read more](/docs/production/soak).
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/Authority.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "The `authority:` section, loaded and evaluable (SPEC-v0.3 §4)."

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.Authority` — class, defined at `src/ctrlrun/authority.py:1231`
`ctrlrun.Authority` — class, defined at `src/ctrlrun/authority.py:1235`

```python
from ctrlrun import Authority
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/AuthorityResult.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "What the authority axis decided, and which grant it decided on (§

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.AuthorityResult` — class, defined at `src/ctrlrun/authority.py:623`
`ctrlrun.AuthorityResult` — class, defined at `src/ctrlrun/authority.py:627`

```python
from ctrlrun import AuthorityResult
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/Condition.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "One `<argument>_<op>: operand` test against an action's arguments

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.Condition` — class, defined at `src/ctrlrun/policy.py:389`
`ctrlrun.Condition` — class, defined at `src/ctrlrun/grammar.py:189`

```python
from ctrlrun import Condition
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/Delegation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "A grant created at runtime by a principal who already holds one (S

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.Delegation` — class, defined at `src/ctrlrun/authority.py:583`
`ctrlrun.Delegation` — class, defined at `src/ctrlrun/authority.py:587`

```python
from ctrlrun import Delegation
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/Grant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "One permission: this subject may propose these actions, under thes

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.Grant` — class, defined at `src/ctrlrun/authority.py:433`
`ctrlrun.Grant` — class, defined at `src/ctrlrun/authority.py:437`

```python
from ctrlrun import Grant
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/Policy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "Action-level autonomy policy: which actions may run, and under whi

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.Policy` — class, defined at `src/ctrlrun/policy.py:750`
`ctrlrun.Policy` — class, defined at `src/ctrlrun/policy.py:479`

```python
from ctrlrun import Policy
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/Subject.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "Who a grant is addressed to: an agent pattern, a user pattern, or

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.Subject` — class, defined at `src/ctrlrun/authority.py:337`
`ctrlrun.Subject` — class, defined at `src/ctrlrun/authority.py:341`

```python
from ctrlrun import Subject
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/authority-Budget.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "How much, over what, in how long (SPEC-v0.9 §2.2)."

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.authority.Budget` — class, defined at `src/ctrlrun/authority.py:383`
`ctrlrun.authority.Budget` — class, defined at `src/ctrlrun/authority.py:387`

```python
from ctrlrun.authority import Budget
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/api/parse_conditions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "Parse a `when:`-shaped mapping into conditions, keyed by the raw c

{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */}

`ctrlrun.parse_conditions` — function, defined at `src/ctrlrun/policy.py:1317`
`ctrlrun.parse_conditions` — function, defined at `src/ctrlrun/grammar.py:433`

```python
from ctrlrun import parse_conditions
Expand Down
2 changes: 1 addition & 1 deletion generated/readiness.full.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{/* generated from the suite, pyproject and the soak (full) — run the generator */}
- **Version 0.11.0**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later, tested on 3.11 to 3.14.
- **6,221 tests**, every version specified before it was written and every requirement mutation-tested. [Read more](/docs/how-this-is-built).
- **6,232 tests**, every version specified before it was written and every requirement mutation-tested. [Read more](/docs/how-this-is-built).
- **32 guarantees you can check in your own setup**, with `ctrlrun verify` against your policy, on your store's backend, in a scratch store it creates. [Read more](/docs/security/verify-guarantees).
- **One host: a file.** SQLite, no server, no ops. **Many hosts: Postgres**, the same guarantees, graded by the same suite. [Read more](/docs/production/postgres).
- **Soaked for 20m 0s on postgres**: 889,735 actions, 0 unattributed ambiguous outcomes, positive control fired. Nothing here establishes what only accumulates over days. [Read more](/docs/production/soak).
Expand Down
2 changes: 1 addition & 1 deletion generated/readiness.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
"positive_control": true,
"unexplained": 0
},
"tests": 6221,
"tests": 6232,
"version": "0.11.0"
}
2 changes: 1 addition & 1 deletion generated/readiness.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{/* generated from the suite, pyproject and the soak (mdx) — run the generator */}
- **Version 0.11.0**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later, tested on 3.11 to 3.14.
- **6,221 tests**, every version specified before it was written and every requirement mutation-tested.
- **6,232 tests**, every version specified before it was written and every requirement mutation-tested.
- **32 guarantees you can check in your own setup**, with `ctrlrun verify` against your policy, on your store's backend, in a scratch store it creates.
- **One host: a file.** SQLite, no server, no ops. **Many hosts: Postgres**, the same guarantees, graded by the same suite.
- **Soaked for 20m 0s on postgres**: 889,735 actions, 0 unattributed ambiguous outcomes, positive control fired. Nothing here establishes what only accumulates over days. [What it does not establish](https://ctrlrun.dev/docs/production/soak).
Expand Down
2 changes: 1 addition & 1 deletion generated/readiness.readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!-- generated from the suite, pyproject and the soak (readme) — run the generator -->
- **Version 0.11.0**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later, tested on 3.11 to 3.14.
- **6,221 tests**, every version specified before it was written and every requirement mutation-tested.
- **6,232 tests**, every version specified before it was written and every requirement mutation-tested.
- **32 guarantees you can check in your own setup**, with `ctrlrun verify` against your policy, on your store's backend, in a scratch store it creates.
- **One host: a file.** SQLite, no server, no ops. **Many hosts: Postgres**, the same guarantees, graded by the same suite.
- **Soaked for 20m 0s on postgres**: 889,735 actions, 0 unattributed ambiguous outcomes, positive control fired. Nothing here establishes what only accumulates over days. [What it does not establish](https://ctrlrun.dev/docs/production/soak).
Expand Down