Skip to content

Regenerate for 0.10.0, and the pages that state released behaviour - #22

Merged
arpanghoshal merged 15 commits into
mainfrom
release/0.10.0
Sep 13, 2026
Merged

arpanghoshal merged 15 commits into
mainfrom
release/0.10.0

Conversation

@arpanghoshal

@arpanghoshal arpanghoshal commented Sep 13, 2026

Copy link
Copy Markdown
Member

Pairs with ctrlrun release/0.10.0 (CTRLRun/ctrlrun#188). main here is checked against main
there, so this merges right after it.

Generated

All seven generators, run against the release branch with the docs venv's editable install pointed
at that worktree:

  • 83 API pagesControl.hop, DecisionPoint, AuthorityResult.hop, Receipt.hop,
    upstream's register, and the signatures that grew a hop=.
  • cli.mdx--hop where it landed, and scan's root-grant line.
  • Readiness, pasted fresh into both docs.mdx and docs/production/index.mdx: version
    0.10.0, 6,048 tests, 27 guarantees.
  • scripts/repoint-claims.py, and the three quoted ctrlrun verify transcripts refreshed from a
    real run, not edited by hand.

Hand-written, because a generator cannot say these

docs/verify.md gains G25, G26, G27 with what each actually grades, including that G27
grades PASS only on the example that pins an upstream and N/A everywhere else.

OWASP: three guarantee rows added, one entry moved, and one self-contradiction removed.

  • G25, G26, G27 were missing from the guarantee table entirely. Added, each naming the
    entries it bears on and each carrying what it does not do in the "how" column.
  • ASI07 Insecure Inter-Agent Communication was Not yet. It is now partly, and the part is
    authority rather than the channel.
    A hop narrows and is named on both sides; CTRLRun still
    defines no wire format, secures no channel and authenticates no peer, and the row says so.
  • ASI04 Agentic Supply Chain Vulnerabilities stays out of scope, with no guarantee mapped to
    it.
    An earlier draft on this branch opened it with "one slice" while the disclaimer three
    paragraphs above said two entries are not addressed at all; both cannot be true. G27's
    pinning is mapped where binding a peer and a tool schema belongs, under ASI02 and
    ASI07. A supply chain is everything upstream of one connection, and this is one property
    about one connection.
  • The disclaimer moves from three uncovered entries to two, and says which one moved and when.

ROADMAP.md marks v0.10 shipped, with a "Reconciled against what shipped" note on the three
places the roadmap's description and the release differ. The roadmap is not quietly edited to match.

One defect, found by running the generators rather than reading them

render_cookbook.py strips the licence the kernel requires. The regeneration for this release
returned nineteen cookbook files modified, every one of them with two lines removed:

-# SPDX-FileCopyrightText: 2026 The CTRLRun contributors
-# SPDX-License-Identifier: Apache-2.0
 # Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from

The kernel's test_every_source_file_carries_its_copyright_and_license requires those two lines on
every .py and .sh under examples/. Nineteen of those files are written by this generator,
which never emitted them; they are committed over there because they were added by hand, so nothing
was red. The next --write from here would have stripped all nineteen and turned the kernel's own
suite red on output this repository produced.

.yaml is excluded, and the test asserts that direction too: the kernel's rule names the two
suffixes it checks, and the extracted policies have never carried the tags, so adding them would be
drift the other way.

The generator now reports 19 recipes, 0 drifted against the kernel's committed tree, which it did
not before, so there is no change to the kernel in this — it only stops producing one. Mutated:
the two emitting lines removed, both the new test and the existing drift test fail; restored, 24
pass.

A rule in one repository that holds only because of a hand edit in the other is the shape this
milestone kept finding. This is the connection, stated on the side that writes the files.

A fifth finding: a pair that merged on one side only

render_badges.py reported the kernel's README.md:20 drifted. It is a generated block, and
it had been hand-edited: ctrlrun.dev/docs/… replaced with docs.ctrlrun.dev/….

That edit is CTRLRun/ctrlrun#185, merged. Its docs pair is #21 in this repository, still
open
, and #21 is what moves the generator to the same URLs. One half of a pair merged and the
other did not, so the cross-repo check has been red on main since — exactly the failure mode
the branch-pairing rule exists to prevent, this
time from the merge order rather than from the workflow.

Merged readme/launch-sync in, so this branch carries the generator half and is green. #21 is
still worth merging on its own
— this only means the release does not wait for it.

Worth recording, since the choice is now made twice: both hosts serve, and docs.ctrlrun.dev/
301-redirects to ctrlrun.dev/docs/. So the merged badges take a redirect hop that the
generated ones did not. That is a deliberate branding choice and not this PR's to reverse; it is
written down here because nothing else writes it down.

Checked

main-vs-main is what CI compares, so the drift check here passes only once the kernel PR merges.
Every link in the changed pages resolves; the readiness block is identical in both files.

Not merging.

The kernel's main has carried item 1 (the hop) since PR #174 and item 2
(identity and the receipt across a hop) since PR #176, and these pages still
described 0.9.0. Every kernel run since then failed at `render_api.py --check`
against this repository's main, and PR #14 here, regenerated against the whole
five-item stack, was red the other way round. The pages on main now match the
kernel's main, which is what the next commit makes the rule.

Rendered, by the generators: 15 API pages (four signatures gained `hop`,
`Control.__init__` gained `upstream`, line numbers moved), the receipt and
event schemas page (`Receipt.hop`, `ctrlrun.receipt/v7`), the readiness block
(6,005 tests, 26 guarantees) and its copies on docs.mdx and
docs/production/index.mdx, and CLAIMS.md repointed (59 citations, none
unresolved).

Quoted, from a real run: the `ctrlrun verify` transcripts on docs/verify.md,
the CI guide and the GitHub Actions recipe now show catalogue v6 with G25 and
G26, 24/24 against the payments example and 15/15 with 11 N/A against the
guide's policy.

Written: the OWASP mapping gains G25 (a hop narrows or it is refused) and
G26 (a hop is named on both sides), each mapped partly to ASI03, ASI07 and
ASI10 with its limits stated in the row, and ASI07 moves from "Not yet" to the
partial half: authority across a hop is bounded and evidenced, the channel is
not CTRLRun's. Two entries are now unaddressed rather than three, and the test
that keeps that sentence true says so.

Not touched: ROADMAP.md, THREAT_MODEL.md and authority.md, which the release
item reconciles; G27 arrives with item 3 and gets its row on that branch.

Signed-off-by: arpan <contact@arpanghoshal.com>
The mirror image of CTRLRun/ctrlrun's `docs` job, which from the same-named
branch there checks out the branch here named after the kernel branch under
test, and main otherwise. A page describes a commit, and the page for a commit
that has not merged cannot be on main yet, so a branch here regenerated for a
kernel branch was red until that branch merged, by construction, for the
length of a release cycle; PR #14 is the example.

Now a branch here is checked against the kernel branch of the same name when
there is one. A dispatch still names its commit. Everything else, main
included, is checked against the kernel's main, so the pages on main are
expected to match it at all times: the docs branch merges when the kernel
branch does, the code first.

The branch name reaches the shell through `env:` and never inline in the
script, and the match is exact and fixed-string, for the reasons the kernel's
commit gives. README's "How the two repositories stay in step" says the rule.

Signed-off-by: arpan <contact@arpanghoshal.com>
Regenerated against CTRLRun/ctrlrun's v0.10/3-upstream-pinning, the branch
of the same name, which the kernel's docs job now checks this one against.

Rendered: the API pages and the errors page (the two upstream refusals), the
readiness block (6,019 tests, 27 guarantees) and its two copies, CLAIMS.md
repointed (54 citations, none unresolved), the three verify transcripts at
catalogue v6 with G27.

Written: docs/reference/policy-yaml.mdx names `upstream`, the action-entry key
`ctrlrun.policy/v8` adds, with its three pins and the three places one rule is
checked, and the version table gains the v7 and v8 rows it was missing. The
OWASP mapping gains G27 (a swapped upstream is denied), mapped partly to
ASI02 and ASI07 with its three limits in the row, and the ASI04 row keeps its
"out of scope" verdict and gains the one sentence SPEC-v0.10 §4.1 allows it.

Signed-off-by: arpan <contact@arpanghoshal.com>
Regenerated against CTRLRun/ctrlrun's v0.10/4-one-ordered-list, the branch
of the same name. Rendered only: API pages whose line numbers moved with the
refactor of control.py, the readiness block (6,033 tests) and its two copies,
CLAIMS.md repointed (48 citations, none unresolved). Item 4 adds no key, no
guarantee and no schema, so nothing here is written by hand.

Signed-off-by: arpan <contact@arpanghoshal.com>
Every generator against the release branch: 83 API pages, cli.mdx, the
capabilities and badge copies, the cookbook, and the readiness block pasted
fresh into docs.mdx and docs/production/index.mdx. Version 0.10.0, 6,048
tests, 27 guarantees.

The hand-written half, each of which states what shipped rather than what
was planned.

docs/verify.md gains G25, G26 and G27, all three PASS on
examples/authority-escalation.

OWASP ASI04 moves from "out of scope" to one slice, and the category stays
out of scope: a policy entry may pin the upstream it authorises, so a
swapped server behind the same name or a tool whose schema moved under an
approved action name is a DENY, and CTRLRun still never inspects a package,
a model, a build, a registry or a signature chain.

ASI07 moves from "Not yet" to partly, and the part is authority rather than
the channel. The envelope a second agent receives is a subset of the one
the first held, checked at the hop and at every evaluation, and an action
under a hop is decided against that hop alone. CTRLRun defines no wire
format, secures no channel and authenticates no peer, so message integrity,
transport security and agent identity stay the deployment's.

ROADMAP marks v0.10 shipped with a reconciled note on the three things that
differ from what the section promised: a hop is a record and not a token,
which costs cross-store propagation; pinning is enforced at the gateway and
refuses in-process; and the first hop is one-way while installing 0.10.0 is
not.

snippets, lint and links clean. Three CLAIMS references do not resolve and
predate v0.10: action.py:79 and migrations.py:107 twice, all three failing
identically on the tree before this milestone.

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

mintlify Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
ctrlrun 🟢 Ready View Preview Sep 13, 2026, 10:52 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 15 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: 213875ad-03dc-4d87-8655-24519adf4c22

📥 Commits

Reviewing files that changed from the base of the PR and between 42b3edd and 7260d51.

⛔ Files ignored due to path filters (4)
  • generated/readiness.full.mdx is excluded by !**/generated/**
  • generated/readiness.json is excluded by !**/generated/**
  • generated/readiness.mdx is excluded by !**/generated/**
  • generated/readiness.readme.md is excluded by !**/generated/**
📒 Files selected for processing (98)
  • .github/workflows/ci.yml
  • README.md
  • docs.mdx
  • docs/CLAIMS.md
  • docs/OWASP-AGENTIC-TOP10.md
  • docs/ROADMAP.md
  • docs/cookbook/verify-in-github-actions.mdx
  • docs/guides/verify-in-ci.mdx
  • docs/production/index.mdx
  • docs/reference/api/Action.mdx
  • docs/reference/api/ActionDenied.mdx
  • docs/reference/api/AmbiguousEffect.mdx
  • docs/reference/api/Approval.mdx
  • docs/reference/api/ApprovalAnswer.mdx
  • docs/reference/api/ApprovalMismatch.mdx
  • docs/reference/api/ApprovalProvider.mdx
  • docs/reference/api/ApprovalRequest.mdx
  • docs/reference/api/ApprovalRequired.mdx
  • docs/reference/api/ApprovalTimeout.mdx
  • docs/reference/api/ApproverIdentity.mdx
  • docs/reference/api/Authority.mdx
  • docs/reference/api/AuthorityDenied.mdx
  • docs/reference/api/AuthorityEscalation.mdx
  • docs/reference/api/AuthorityResult.mdx
  • docs/reference/api/CTRLRunError.mdx
  • docs/reference/api/Condition.mdx
  • docs/reference/api/Control.mdx
  • docs/reference/api/Decision.mdx
  • docs/reference/api/Delegation.mdx
  • docs/reference/api/DelegationRecord.mdx
  • docs/reference/api/DuplicateEffect.mdx
  • docs/reference/api/EffectKeyError.mdx
  • docs/reference/api/EffectRecord.mdx
  • docs/reference/api/EffectState.mdx
  • docs/reference/api/Event.mdx
  • docs/reference/api/EventSink.mdx
  • docs/reference/api/FrameworkInterrupt.mdx
  • docs/reference/api/Grant.mdx
  • docs/reference/api/HeaderIdentityProvider.mdx
  • docs/reference/api/IdentityContext.mdx
  • docs/reference/api/IdentityError.mdx
  • docs/reference/api/IdentityProvider.mdx
  • docs/reference/api/InMemoryStateStore.mdx
  • docs/reference/api/InterruptApprovalProvider.mdx
  • docs/reference/api/InvalidArgument.mdx
  • docs/reference/api/JSONLEventSink.mdx
  • docs/reference/api/LocalApprovalProvider.mdx
  • docs/reference/api/MissingDependency.mdx
  • docs/reference/api/NotExecuted.mdx
  • docs/reference/api/PendingApproval.mdx
  • docs/reference/api/Policy.mdx
  • docs/reference/api/PolicyError.mdx
  • docs/reference/api/Principal.mdx
  • docs/reference/api/Receipt.mdx
  • docs/reference/api/ReconcileOutcome.mdx
  • docs/reference/api/SQLiteStateStore.mdx
  • docs/reference/api/SchemaMismatch.mdx
  • docs/reference/api/ScriptedApprovalProvider.mdx
  • docs/reference/api/StateStore.mdx
  • docs/reference/api/StaticIdentityProvider.mdx
  • docs/reference/api/Subject.mdx
  • docs/reference/api/Suspended.mdx
  • docs/reference/api/VerifiedApprover.mdx
  • docs/reference/api/WebhookApprovalProvider.mdx
  • docs/reference/api/acs-AcsControlHook.mdx
  • docs/reference/api/action_hash.mdx
  • docs/reference/api/authority-Budget.mdx
  • docs/reference/api/banner.mdx
  • docs/reference/api/canonical_bytes.mdx
  • docs/reference/api/canonicalize.mdx
  • docs/reference/api/conformance-run.mdx
  • docs/reference/api/conformance-store-run.mdx
  • docs/reference/api/context.mdx
  • docs/reference/api/gateway-serve.mdx
  • docs/reference/api/idempotency_token.mdx
  • docs/reference/api/jwt_identity-JWTIdentityProvider.mdx
  • docs/reference/api/needs_approval.mdx
  • docs/reference/api/otel-OTelEventSink.mdx
  • docs/reference/api/parse_conditions.mdx
  • docs/reference/api/postgres-PostgresStateStore.mdx
  • docs/reference/api/protect.mdx
  • docs/reference/api/state-Charge.mdx
  • docs/reference/api/state-Consumption.mdx
  • docs/reference/api/state-check_charges.mdx
  • docs/reference/api/transport-HTTPConnection.mdx
  • docs/reference/api/transport-HTTPSConnection.mdx
  • docs/reference/api/transport-Transport.mdx
  • docs/reference/api/transport-effect_state.mdx
  • docs/reference/api/transport-urlopen.mdx
  • docs/reference/api/verify-run.mdx
  • docs/reference/api/with_approval.mdx
  • docs/reference/cli.mdx
  • docs/reference/policy-yaml.mdx
  • docs/reference/receipt-and-event-schemas.mdx
  • docs/verify.md
  • tests/test_cookbook_pages.py
  • tests/test_owasp_mapping.py
  • tools/docs_audit/render_cookbook.py

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.

…est says so

Found by running the generators for this release against the kernel worktree: nineteen files
came back modified, every one of them with the two SPDX lines **removed**.

The kernel's `test_every_source_file_carries_its_copyright_and_license` requires
`# SPDX-FileCopyrightText` and `# SPDX-License-Identifier` at the top of every `.py` and `.sh`
under `examples/`. Nineteen of those files are written by `render_cookbook.py` in this
repository, which never emitted them. They are committed in the kernel because they were added by
hand there, so nothing was red; the next `--write` from here would have stripped all nineteen and
turned the kernel's own suite red on output this repository produced.

`.yaml` is excluded because the kernel's rule names the two suffixes it checks, and the extracted
policies have never carried the tags. The test asserts that direction too, so adding them to the
policies is drift rather than tidiness.

`render_cookbook.py` now reports `19 recipes, 0 drifted` against the kernel's committed tree,
which it did not before. Mutated: the two emitting lines removed, both the new test and the
existing drift test fail; restored, 24 pass.

A rule in one repository that only holds because of a hand edit in the other is the shape this
milestone kept finding. This is the connection, stated on the side that writes the files.
…into release/0.10.0

# Conflicts:
#	docs.mdx
#	docs/OWASP-AGENTIC-TOP10.md
#	docs/production/index.mdx
#	docs/reference/api/Authority.mdx
#	docs/reference/api/AuthorityResult.mdx
#	docs/reference/api/Condition.mdx
#	docs/reference/api/Control.mdx
#	docs/reference/api/Decision.mdx
#	docs/reference/api/Delegation.mdx
#	docs/reference/api/Event.mdx
#	docs/reference/api/EventSink.mdx
#	docs/reference/api/Grant.mdx
#	docs/reference/api/JSONLEventSink.mdx
#	docs/reference/api/Policy.mdx
#	docs/reference/api/Receipt.mdx
#	docs/reference/api/Subject.mdx
#	docs/reference/api/authority-Budget.mdx
#	docs/reference/api/context.mdx
#	docs/reference/api/idempotency_token.mdx
#	docs/reference/api/parse_conditions.mdx
#	docs/reference/api/protect.mdx
#	docs/reference/api/with_approval.mdx
#	docs/verify.md
#	generated/readiness.full.mdx
#	generated/readiness.json
#	generated/readiness.mdx
#	generated/readiness.readme.md
Merging `ci/docs-job-follows-the-branch` gives this branch the pairing rule, so its CI checks these
pages against ctrlrun `release/0.10.0` rather than against `main`. Without it this PR is red by
construction until the kernel release merges, which is the ordering the pairing exists to fix.

Twenty-three conflicts were generated files, resolved by regenerating rather than by choosing a
side: all seven generators against the release worktree, `19 recipes, 0 drifted`, `83 pages`,
readiness re-pasted into both homes (`6,056` tests now, this branch added eight).

Four findings, each from running something rather than reading it.

**1. `docs/verify.md` quoted a transcript no run produces.** It carried `ctrlrun 0.9.0` in the
header and `G27 ... PASS payouts` in the body at once — G27 passes on
`examples/authority-escalation`, and that block is the run against `examples/authority/payments.yaml`,
where it is `N/A no action entry pins an upstream`. Replaced with the real 53 lines. I resolved this
conflict the wrong way first; the other branch had it right.

**2. Both CI pages leaked an absolute local path, and had before this branch.** `policy
/private/var/folders/gp/…/T/tmpdi6bvpqd/ctrlrun.yaml` was on `docs/guides/verify-in-ci.mdx` and
`docs/cookbook/verify-in-github-actions.mdx` in `HEAD`, from an earlier refresh that pasted a temp
directory into a published page. The test that guards these transcripts **skips lines starting
with `policy     `**, so it never saw it. Both now read `./ctrlrun.yaml`.

**3. 153 stale `CLAIMS.md` citations, and the three that were blocking all of them.** The SPDX
headers moved every line by two. `repoint-claims.py` is all-or-nothing and refused to write because
three citations could not be resolved: `action.py:79` and `migrations.py:107`, whose real lines are
`:81` and `:109` — the same +2, unresolvable only because the script's heuristic cannot anchor a
bare `if isinstance(...)`. Fixed by hand; the script then re-pointed the other 147.

**4. The OWASP page was missing G25, G26 and G27, and contradicted itself about `ASI04`.** The rows
are added. `ASI04` is **out of scope with no guarantee mapped to it**, and the pinning slice is
mapped where binding a peer and a tool schema belongs, under `ASI02` and `ASI07`. It previously
opened "one slice" while the disclaimer three paragraphs up said two entries are not addressed
**at all**; both cannot be true. The disclaimer now also says it was three until v0.10.

Whole suite green against the release worktree.
…ease branch

Main brought #1 (the Pythons CI tests, read rather than typed), #18 (the
assurance case) and #21 (the README test and the badge generator). The
readiness block conflicted on both sides' regenerations; regenerated once
more against the kernel's release/0.10.0 and pasted fresh.

Signed-off-by: arpan <contact@arpanghoshal.com>
`main` has been red since #18, #1 and #21 landed: three push runs failed in a row, all on
`docs/security/assurance-case.mdx`. Every branch cut afterwards inherits it, this one included, so
the release cannot go green without fixing it. Four are the page's, one is the list's.

- **The description was 198 characters**, and the limit is 155 because that is where a search
  result truncates. Rewritten to say the same thing in one sentence.
- **No `## Next`**, which every `.mdx` carries so a reader is never left at the bottom of a page
  with nowhere to go. Added, with four links.
- **No link to Why and none to Get started.** Both are in that section now.
- **`SEO.md` had no row.** The file is the plan, one row per page; a page with no row is a page
  nobody decided what it was for. Query and definitional sentence added beside the other
  `docs/security/` rows.
- **1,816 words against a 900 budget.** `security/assurance-case` joins `LONG_FORM`, where
  `THREAT_MODEL`, `ARCHITECTURE`, `CLAIMS` and the OWASP pages already are. Cutting an assurance
  case to 900 words means dropping either a claim or the evidence under one, and a claim without
  its evidence is what the page exists to refuse. The reason is in the list beside the entry.

Readiness regenerated after the merge: **6,066** tests, pasted into both homes.
# Conflicts:
#	docs.mdx
#	docs/production/index.mdx
#	generated/readiness.full.mdx
#	generated/readiness.json
#	generated/readiness.mdx
#	generated/readiness.readme.md
# Conflicts:
#	docs/security/assurance-case.mdx
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