From d39a99042dcff24ff60a12029c90fb9ff6d46169 Mon Sep 17 00:00:00 2001 From: arpan Date: Wed, 9 Sep 2026 18:35:08 +0530 Subject: [PATCH] Move the documentation site to CTRLRun/ctrlrun-docs A clone of this repository was 529 files and more than half of them were the website: 163 pages, the Mintlify configuration, the renderers, the browser demos and the Vercel function behind the site's form. The sdist carried them too, video included. They are CTRLRun/ctrlrun-docs now, with their history; this repository keeps the library, its specifications, its README assets and its tests. 529 files becomes 291, and the sdist 2.9M becomes 1.4M. `pip install ctrlrun` is unchanged: pyyaml and click, and nothing else. `griffe` leaves the dev extra with the reference generator that needed it. What did not move is the guarantee that a page describes the shipped library. Every check that needs both trees runs in the other repository, which resolves a checkout of this one from $CTRLRUN_SOURCE and **raises** when there is none, and this repository's CI runs those checks from there against the commit being proposed -- the `docs` job. So a change here that makes a page wrong is red on this repository's own pull request, and there is still one implementation of every rule rather than two that drift. Five test files were split rather than moved, each along a line that was already there: - `test_cookbook.py` keeps the three tests that only run `examples/cookbook/`; - `test_packaging.py` keeps the dependency rule and loses four tests that read a page; - `test_release_v0_6.py` keeps T181, the packaging half, and T180 goes where it can read all five documents it scans; - `test_verify_action.py` keeps the composite action's twenty-seven tests; - `test_readme_assets.py` keeps what this repository ships and loses the comparison with the site's copies of it. **Four of those tests had begun skipping rather than failing** once the pages moved: each guarded its read with `pytest.skip("no repository checkout")`, written for an sdist where the pages are pruned, which after the move read as "nothing to check". They fail on a missing page now, in the repository that has one. The suite's skip count and every skip reason are back to exactly what they were before this change. The test-count badge is written in the `docs` job, which `needs: check` -- a stronger ordering than the two steps in one job it replaces, because a step's order is a convention and `needs:` is enforced. `notify-docs` needs a DOCS_DISPATCH_TOKEN secret to tell the other repository that the library changed. Until it is set the step warns and does nothing, and the backstop is that repository's weekly scheduled run. The network guard that `test_examples.py` and `test_cookbook.py` had each written for themselves is one definition in `tests/conftest.py` now. --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- .github/ISSUE_TEMPLATE/feature.yml | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 4 +- .github/workflows/ci.yml | 163 ++- CONTRIBUTING.md | 19 +- MANIFEST.in | 24 +- README.md | 10 +- SECURITY.md | 4 +- VISION.md | 4 +- action.yml | 2 +- docs/.mintignore | 17 - docs/IA.md | 420 ------ docs/README.md | 60 - docs/SEO.md | 155 --- docs/STYLE.md | 105 -- docs/assets/browser-demo.verified.json | 7 - docs/assets/verify-browser-demo.mjs | 84 -- docs/assets/verify-browser-wiring.mjs | 194 --- docs/assets/verify-medical-workbench.cjs | 86 -- docs/assets/verify-website.cjs | 116 -- docs/capabilities.yaml | 334 ----- docs/docs.json | 1183 ----------------- docs/docs.mdx | 291 ---- docs/docs/ACS.md | 244 ---- docs/docs/ARCHITECTURE.md | 242 ---- docs/docs/CLAIMS.md | 309 ----- docs/docs/OWASP-AGENTIC-TOP10.md | 116 -- docs/docs/ROADMAP.md | 239 ---- docs/docs/THREAT_MODEL.md | 195 --- docs/docs/adapters.md | 127 -- docs/docs/architecture/specifications.mdx | 51 - docs/docs/authority.md | 183 --- docs/docs/compare/durable-workflows.mdx | 56 - docs/docs/compare/framework-hitl.mdx | 55 - docs/docs/compare/governance-toolkits.mdx | 52 - docs/docs/compare/guardrail-libraries.mdx | 55 - docs/docs/compare/idempotency-keys.mdx | 66 - docs/docs/concepts/action-and-hash.mdx | 55 - docs/docs/concepts/approval-binding.mdx | 62 - .../concepts/authority-and-delegation.mdx | 87 -- docs/docs/concepts/decisions.mdx | 59 - docs/docs/concepts/effect-keys.mdx | 73 - docs/docs/concepts/fail-closed.mdx | 53 - docs/docs/concepts/observe-mode.mdx | 71 - docs/docs/concepts/outcomes-and-ambiguous.mdx | 104 -- docs/docs/concepts/receipts-and-evidence.mdx | 84 -- .../cookbook/credential-rotation-agent.mdx | 129 -- docs/docs/cookbook/crm-update-agent.mdx | 152 --- .../cookbook/customer-notification-agent.mdx | 127 -- docs/docs/cookbook/data-deletion-agent.mdx | 136 -- .../cookbook/database-migration-agent.mdx | 136 -- docs/docs/cookbook/deploy-agent.mdx | 139 -- docs/docs/cookbook/iam-agent.mdx | 136 -- docs/docs/cookbook/index.mdx | 65 - docs/docs/cookbook/langgraph-interrupt.mdx | 99 -- docs/docs/cookbook/manager-and-worker.mdx | 193 --- docs/docs/cookbook/observe-then-enforce.mdx | 136 -- .../cookbook/openai-agents-tool-approval.mdx | 90 -- docs/docs/cookbook/outbound-email-agent.mdx | 135 -- docs/docs/cookbook/payout-maker-checker.mdx | 211 --- docs/docs/cookbook/protect-an-mcp-server.mdx | 174 --- .../cookbook/receipts-to-opentelemetry.mdx | 128 -- .../cookbook/reconcile-against-the-remote.mdx | 157 --- docs/docs/cookbook/refund-agent.mdx | 137 -- .../cookbook/resolve-an-ambiguous-effect.mdx | 136 -- docs/docs/cookbook/slack-approvals.mdx | 142 -- docs/docs/cookbook/sqlite-to-postgres.mdx | 119 -- .../cookbook/verify-in-github-actions.mdx | 122 -- docs/docs/demos/index.mdx | 39 - docs/docs/demos/medical-affairs.mdx | 132 -- docs/docs/faq.mdx | 139 -- docs/docs/get-started/choosing.mdx | 50 - docs/docs/get-started/install.mdx | 59 - docs/docs/get-started/quickstart.mdx | 186 --- docs/docs/get-started/three-ways-in.mdx | 83 -- docs/docs/guides/approvals-in-slack.mdx | 143 -- docs/docs/guides/export-to-opentelemetry.mdx | 110 -- docs/docs/guides/gateway-in-front-of-mcp.mdx | 141 -- docs/docs/guides/langgraph-adapter.mdx | 111 -- docs/docs/guides/observe-to-enforce.mdx | 145 -- docs/docs/guides/openai-agents-adapter.mdx | 106 -- docs/docs/guides/protect-a-function.mdx | 153 --- docs/docs/guides/reconcile-automatically.mdx | 120 -- .../guides/resolve-an-ambiguous-effect.mdx | 113 -- docs/docs/guides/run-on-postgres.mdx | 111 -- docs/docs/guides/verify-in-ci.mdx | 135 -- docs/docs/how-this-is-built.md | 108 -- docs/docs/mcp/approve-from-your-assistant.mdx | 121 -- docs/docs/mcp/gateway-in-5-minutes.mdx | 130 -- docs/docs/mcp/overview.mdx | 86 -- .../mcp/use-the-docs-from-your-editor.mdx | 59 - docs/docs/not-only-agents.mdx | 83 -- docs/docs/postgres.md | 317 ----- .../docs/production/how-reservation-works.mdx | 80 -- docs/docs/production/index.mdx | 89 -- docs/docs/production/migrations.mdx | 81 -- docs/docs/production/operations.mdx | 74 -- docs/docs/production/postgres.mdx | 80 -- docs/docs/production/receipt-integrity.mdx | 76 -- docs/docs/production/recovery.mdx | 78 -- docs/docs/production/soak.mdx | 99 -- docs/docs/reference/api/Action.mdx | 28 - docs/docs/reference/api/ActionDenied.mdx | 25 - docs/docs/reference/api/AmbiguousEffect.mdx | 29 - docs/docs/reference/api/Approval.mdx | 27 - docs/docs/reference/api/ApprovalAnswer.mdx | 37 - docs/docs/reference/api/ApprovalMismatch.mdx | 28 - docs/docs/reference/api/ApprovalProvider.mdx | 29 - docs/docs/reference/api/ApprovalRequest.mdx | 25 - docs/docs/reference/api/ApprovalRequired.mdx | 28 - docs/docs/reference/api/ApprovalTimeout.mdx | 25 - docs/docs/reference/api/Authority.mdx | 28 - docs/docs/reference/api/AuthorityDenied.mdx | 32 - .../reference/api/AuthorityEscalation.mdx | 30 - docs/docs/reference/api/AuthorityResult.mdx | 31 - docs/docs/reference/api/CTRLRunError.mdx | 24 - docs/docs/reference/api/Condition.mdx | 29 - docs/docs/reference/api/Control.mdx | 28 - docs/docs/reference/api/Decision.mdx | 29 - docs/docs/reference/api/Delegation.mdx | 30 - docs/docs/reference/api/DelegationRecord.mdx | 34 - docs/docs/reference/api/DuplicateEffect.mdx | 28 - docs/docs/reference/api/EffectKeyError.mdx | 27 - docs/docs/reference/api/EffectRecord.mdx | 25 - docs/docs/reference/api/EffectState.mdx | 34 - docs/docs/reference/api/Event.mdx | 32 - docs/docs/reference/api/EventSink.mdx | 36 - .../docs/reference/api/FrameworkInterrupt.mdx | 35 - docs/docs/reference/api/Grant.mdx | 31 - .../reference/api/HeaderIdentityProvider.mdx | 35 - docs/docs/reference/api/IdentityContext.mdx | 33 - docs/docs/reference/api/IdentityError.mdx | 30 - docs/docs/reference/api/IdentityProvider.mdx | 34 - .../docs/reference/api/InMemoryStateStore.mdx | 31 - .../api/InterruptApprovalProvider.mdx | 41 - docs/docs/reference/api/InvalidArgument.mdx | 28 - docs/docs/reference/api/JSONLEventSink.mdx | 36 - .../reference/api/LocalApprovalProvider.mdx | 29 - docs/docs/reference/api/MissingDependency.mdx | 29 - docs/docs/reference/api/NotExecuted.mdx | 27 - docs/docs/reference/api/PendingApproval.mdx | 33 - docs/docs/reference/api/Policy.mdx | 28 - docs/docs/reference/api/PolicyError.mdx | 24 - docs/docs/reference/api/Principal.mdx | 30 - docs/docs/reference/api/Receipt.mdx | 25 - docs/docs/reference/api/ReconcileOutcome.mdx | 29 - docs/docs/reference/api/SQLiteStateStore.mdx | 33 - docs/docs/reference/api/SchemaMismatch.mdx | 30 - .../api/ScriptedApprovalProvider.mdx | 34 - docs/docs/reference/api/StateStore.mdx | 51 - .../reference/api/StaticIdentityProvider.mdx | 29 - docs/docs/reference/api/Subject.mdx | 29 - docs/docs/reference/api/Suspended.mdx | 33 - .../reference/api/WebhookApprovalProvider.mdx | 34 - .../docs/reference/api/acs-AcsControlHook.mdx | 31 - docs/docs/reference/api/action_hash.mdx | 24 - docs/docs/reference/api/banner.mdx | 34 - docs/docs/reference/api/canonical_bytes.mdx | 37 - docs/docs/reference/api/canonicalize.mdx | 28 - docs/docs/reference/api/conformance-run.mdx | 36 - .../reference/api/conformance-store-run.mdx | 37 - docs/docs/reference/api/context.mdx | 36 - docs/docs/reference/api/gateway-serve.mdx | 32 - docs/docs/reference/api/index.mdx | 88 -- .../api/jwt_identity-JWTIdentityProvider.mdx | 36 - docs/docs/reference/api/needs_approval.mdx | 48 - .../docs/reference/api/otel-OTelEventSink.mdx | 32 - docs/docs/reference/api/parse_conditions.mdx | 33 - .../api/postgres-PostgresStateStore.mdx | 45 - docs/docs/reference/api/protect.mdx | 38 - docs/docs/reference/api/verify-run.mdx | 31 - docs/docs/reference/api/with_approval.mdx | 27 - docs/docs/reference/authority-yaml.mdx | 108 -- docs/docs/reference/cli.mdx | 411 ------ docs/docs/reference/errors.mdx | 164 --- docs/docs/reference/exit-codes.mdx | 58 - docs/docs/reference/policy-yaml.mdx | 140 -- .../reference/receipt-and-event-schemas.mdx | 115 -- docs/docs/security/disclosure.mdx | 56 - docs/docs/security/receipt-chain.mdx | 69 - docs/docs/security/verify-guarantees.mdx | 68 - .../does-your-framework-double-execute.mdx | 88 -- docs/docs/try-it.mdx | 274 ---- docs/docs/verify.md | 358 ----- docs/docs/verify/get-the-badge.mdx | 124 -- docs/docs/why.mdx | 79 -- docs/generated/badges.readme.md | 15 - docs/generated/capabilities.mdx | 86 -- docs/generated/capabilities.readme.md | 10 - docs/generated/capabilities.txt | 28 - docs/generated/readiness.full.mdx | 15 - docs/generated/readiness.json | 14 - docs/generated/readiness.mdx | 15 - docs/generated/readiness.readme.md | 15 - docs/images/demo-poster.jpg | Bin 31532 -> 0 bytes docs/images/demo.mp4 | Bin 1152268 -> 0 bytes docs/images/favicon.svg | 1 - docs/images/social-preview.png | Bin 78334 -> 0 bytes docs/images/wordmark-dark.svg | 6 - docs/images/wordmark-light.svg | 6 - docs/images/wordmark.svg | 7 - docs/index.mdx | 93 -- docs/medical-demo.js | 431 ------ docs/medical-workbench.js | 350 ----- docs/protect-my-agent.mdx | 37 - docs/risk-check.mdx | 10 - docs/snippets/architecture-review.jsx | 67 - docs/snippets/demo-film.jsx | 40 - docs/snippets/risk-check.jsx | 51 - docs/snippets/scenario-explorer.jsx | 316 ----- docs/style.css | 532 -------- docs/try-it.js | 474 ------- docs/try.mdx | 29 - docs/website-events.js | 22 - examples/acs/README.md | 2 +- examples/authority/README.md | 2 +- .../credential-rotation-agent/ctrlrun.yaml | 4 +- .../credential-rotation-agent/main.py | 4 +- .../cookbook/crm-update-agent/ctrlrun.yaml | 4 +- examples/cookbook/crm-update-agent/main.py | 4 +- .../customer-notification-agent/ctrlrun.yaml | 4 +- .../customer-notification-agent/main.py | 4 +- .../cookbook/data-deletion-agent/ctrlrun.yaml | 4 +- examples/cookbook/data-deletion-agent/main.py | 4 +- .../database-migration-agent/ctrlrun.yaml | 4 +- .../cookbook/database-migration-agent/main.py | 4 +- examples/cookbook/deploy-agent/ctrlrun.yaml | 4 +- examples/cookbook/deploy-agent/main.py | 4 +- examples/cookbook/iam-agent/ctrlrun.yaml | 4 +- examples/cookbook/iam-agent/main.py | 4 +- .../cookbook/manager-and-worker/ctrlrun.yaml | 4 +- examples/cookbook/manager-and-worker/main.py | 4 +- .../observe-then-enforce/ctrlrun.yaml | 4 +- .../cookbook/observe-then-enforce/main.py | 4 +- .../outbound-email-agent/ctrlrun.yaml | 4 +- .../cookbook/outbound-email-agent/main.py | 4 +- .../payout-maker-checker/ctrlrun.yaml | 4 +- .../cookbook/payout-maker-checker/main.py | 4 +- .../protect-an-mcp-server/ctrlrun.yaml | 4 +- .../cookbook/protect-an-mcp-server/main.py | 4 +- .../receipts-to-opentelemetry/ctrlrun.yaml | 4 +- .../receipts-to-opentelemetry/main.py | 4 +- .../reconcile-against-the-remote/ctrlrun.yaml | 4 +- .../reconcile-against-the-remote/main.py | 4 +- examples/cookbook/refund-agent/ctrlrun.yaml | 4 +- examples/cookbook/refund-agent/main.py | 4 +- .../resolve-an-ambiguous-effect/ctrlrun.yaml | 4 +- .../resolve-an-ambiguous-effect/main.py | 4 +- .../cookbook/slack-approvals/ctrlrun.yaml | 4 +- examples/cookbook/slack-approvals/main.py | 4 +- .../cookbook/sqlite-to-postgres/ctrlrun.yaml | 4 +- examples/cookbook/sqlite-to-postgres/main.py | 4 +- .../verify-in-github-actions/ctrlrun.yaml | 4 +- .../cookbook/verify-in-github-actions/run.sh | 4 +- examples/policies/devops.yaml | 2 +- examples/policies/e-commerce.yaml | 2 +- examples/policies/government.yaml | 2 +- examples/policies/healthcare.yaml | 2 +- examples/policies/hr.yaml | 2 +- examples/policies/insurance.yaml | 2 +- examples/policies/legal.yaml | 2 +- examples/policies/payments.yaml | 2 +- examples/policies/security.yaml | 2 +- integrations/website-form/.gitignore | 4 - integrations/website-form/.vercelignore | 3 - integrations/website-form/README.md | 28 - integrations/website-form/api/review.mjs | 83 -- integrations/website-form/package.json | 7 - integrations/website-form/public/robots.txt | 2 - integrations/website-form/review.test.mjs | 61 - integrations/website-form/vercel.json | 27 - pyproject.toml | 7 - research/soak/README.md | 2 +- scripts/repoint-claims.py | 145 -- src/ctrlrun/acs.py | 4 +- tests/conftest.py | 49 +- tests/test_claims_citations.py | 107 -- tests/test_cookbook.py | 59 +- tests/test_docs_audit.py | 597 --------- tests/test_docs_medical_demo.py | 214 --- tests/test_docs_production.py | 690 ---------- tests/test_docs_reference.py | 388 ------ tests/test_docs_seo.py | 178 --- tests/test_docs_site.py | 407 ------ tests/test_docs_travelling.py | 511 ------- tests/test_examples.py | 41 +- tests/test_framework_probe.py | 4 +- tests/test_medical_workbench.py | 130 -- tests/test_owasp_mapping.py | 212 --- tests/test_packaging.py | 166 +-- tests/test_readme_assets.py | 10 +- tests/test_release_v0_6.py | 186 +-- tests/test_repository_signals.py | 19 +- tests/test_verify_action.py | 123 +- tools/docs_audit/__init__.py | 12 - tools/docs_audit/_files.py | 163 --- tools/docs_audit/claims.py | 120 -- tools/docs_audit/links.py | 210 --- tools/docs_audit/lint-allowlist.txt | 89 -- tools/docs_audit/lint.py | 212 --- tools/docs_audit/render_api.py | 411 ------ tools/docs_audit/render_badges.py | 225 ---- tools/docs_audit/render_capabilities.py | 333 ----- tools/docs_audit/render_cli.py | 106 -- tools/docs_audit/render_cookbook.py | 109 -- tools/docs_audit/render_probe.py | 229 ---- tools/docs_audit/render_readiness.py | 301 ----- tools/docs_audit/render_schemas.py | 231 ---- tools/docs_audit/render_soak.py | 239 ---- tools/docs_audit/snippets.py | 264 ---- 310 files changed, 346 insertions(+), 27180 deletions(-) delete mode 100644 docs/.mintignore delete mode 100644 docs/IA.md delete mode 100644 docs/README.md delete mode 100644 docs/SEO.md delete mode 100644 docs/STYLE.md delete mode 100644 docs/assets/browser-demo.verified.json delete mode 100644 docs/assets/verify-browser-demo.mjs delete mode 100644 docs/assets/verify-browser-wiring.mjs delete mode 100644 docs/assets/verify-medical-workbench.cjs delete mode 100644 docs/assets/verify-website.cjs delete mode 100644 docs/capabilities.yaml delete mode 100644 docs/docs.json delete mode 100644 docs/docs.mdx delete mode 100644 docs/docs/ACS.md delete mode 100644 docs/docs/ARCHITECTURE.md delete mode 100644 docs/docs/CLAIMS.md delete mode 100644 docs/docs/OWASP-AGENTIC-TOP10.md delete mode 100644 docs/docs/ROADMAP.md delete mode 100644 docs/docs/THREAT_MODEL.md delete mode 100644 docs/docs/adapters.md delete mode 100644 docs/docs/architecture/specifications.mdx delete mode 100644 docs/docs/authority.md delete mode 100644 docs/docs/compare/durable-workflows.mdx delete mode 100644 docs/docs/compare/framework-hitl.mdx delete mode 100644 docs/docs/compare/governance-toolkits.mdx delete mode 100644 docs/docs/compare/guardrail-libraries.mdx delete mode 100644 docs/docs/compare/idempotency-keys.mdx delete mode 100644 docs/docs/concepts/action-and-hash.mdx delete mode 100644 docs/docs/concepts/approval-binding.mdx delete mode 100644 docs/docs/concepts/authority-and-delegation.mdx delete mode 100644 docs/docs/concepts/decisions.mdx delete mode 100644 docs/docs/concepts/effect-keys.mdx delete mode 100644 docs/docs/concepts/fail-closed.mdx delete mode 100644 docs/docs/concepts/observe-mode.mdx delete mode 100644 docs/docs/concepts/outcomes-and-ambiguous.mdx delete mode 100644 docs/docs/concepts/receipts-and-evidence.mdx delete mode 100644 docs/docs/cookbook/credential-rotation-agent.mdx delete mode 100644 docs/docs/cookbook/crm-update-agent.mdx delete mode 100644 docs/docs/cookbook/customer-notification-agent.mdx delete mode 100644 docs/docs/cookbook/data-deletion-agent.mdx delete mode 100644 docs/docs/cookbook/database-migration-agent.mdx delete mode 100644 docs/docs/cookbook/deploy-agent.mdx delete mode 100644 docs/docs/cookbook/iam-agent.mdx delete mode 100644 docs/docs/cookbook/index.mdx delete mode 100644 docs/docs/cookbook/langgraph-interrupt.mdx delete mode 100644 docs/docs/cookbook/manager-and-worker.mdx delete mode 100644 docs/docs/cookbook/observe-then-enforce.mdx delete mode 100644 docs/docs/cookbook/openai-agents-tool-approval.mdx delete mode 100644 docs/docs/cookbook/outbound-email-agent.mdx delete mode 100644 docs/docs/cookbook/payout-maker-checker.mdx delete mode 100644 docs/docs/cookbook/protect-an-mcp-server.mdx delete mode 100644 docs/docs/cookbook/receipts-to-opentelemetry.mdx delete mode 100644 docs/docs/cookbook/reconcile-against-the-remote.mdx delete mode 100644 docs/docs/cookbook/refund-agent.mdx delete mode 100644 docs/docs/cookbook/resolve-an-ambiguous-effect.mdx delete mode 100644 docs/docs/cookbook/slack-approvals.mdx delete mode 100644 docs/docs/cookbook/sqlite-to-postgres.mdx delete mode 100644 docs/docs/cookbook/verify-in-github-actions.mdx delete mode 100644 docs/docs/demos/index.mdx delete mode 100644 docs/docs/demos/medical-affairs.mdx delete mode 100644 docs/docs/faq.mdx delete mode 100644 docs/docs/get-started/choosing.mdx delete mode 100644 docs/docs/get-started/install.mdx delete mode 100644 docs/docs/get-started/quickstart.mdx delete mode 100644 docs/docs/get-started/three-ways-in.mdx delete mode 100644 docs/docs/guides/approvals-in-slack.mdx delete mode 100644 docs/docs/guides/export-to-opentelemetry.mdx delete mode 100644 docs/docs/guides/gateway-in-front-of-mcp.mdx delete mode 100644 docs/docs/guides/langgraph-adapter.mdx delete mode 100644 docs/docs/guides/observe-to-enforce.mdx delete mode 100644 docs/docs/guides/openai-agents-adapter.mdx delete mode 100644 docs/docs/guides/protect-a-function.mdx delete mode 100644 docs/docs/guides/reconcile-automatically.mdx delete mode 100644 docs/docs/guides/resolve-an-ambiguous-effect.mdx delete mode 100644 docs/docs/guides/run-on-postgres.mdx delete mode 100644 docs/docs/guides/verify-in-ci.mdx delete mode 100644 docs/docs/how-this-is-built.md delete mode 100644 docs/docs/mcp/approve-from-your-assistant.mdx delete mode 100644 docs/docs/mcp/gateway-in-5-minutes.mdx delete mode 100644 docs/docs/mcp/overview.mdx delete mode 100644 docs/docs/mcp/use-the-docs-from-your-editor.mdx delete mode 100644 docs/docs/not-only-agents.mdx delete mode 100644 docs/docs/postgres.md delete mode 100644 docs/docs/production/how-reservation-works.mdx delete mode 100644 docs/docs/production/index.mdx delete mode 100644 docs/docs/production/migrations.mdx delete mode 100644 docs/docs/production/operations.mdx delete mode 100644 docs/docs/production/postgres.mdx delete mode 100644 docs/docs/production/receipt-integrity.mdx delete mode 100644 docs/docs/production/recovery.mdx delete mode 100644 docs/docs/production/soak.mdx delete mode 100644 docs/docs/reference/api/Action.mdx delete mode 100644 docs/docs/reference/api/ActionDenied.mdx delete mode 100644 docs/docs/reference/api/AmbiguousEffect.mdx delete mode 100644 docs/docs/reference/api/Approval.mdx delete mode 100644 docs/docs/reference/api/ApprovalAnswer.mdx delete mode 100644 docs/docs/reference/api/ApprovalMismatch.mdx delete mode 100644 docs/docs/reference/api/ApprovalProvider.mdx delete mode 100644 docs/docs/reference/api/ApprovalRequest.mdx delete mode 100644 docs/docs/reference/api/ApprovalRequired.mdx delete mode 100644 docs/docs/reference/api/ApprovalTimeout.mdx delete mode 100644 docs/docs/reference/api/Authority.mdx delete mode 100644 docs/docs/reference/api/AuthorityDenied.mdx delete mode 100644 docs/docs/reference/api/AuthorityEscalation.mdx delete mode 100644 docs/docs/reference/api/AuthorityResult.mdx delete mode 100644 docs/docs/reference/api/CTRLRunError.mdx delete mode 100644 docs/docs/reference/api/Condition.mdx delete mode 100644 docs/docs/reference/api/Control.mdx delete mode 100644 docs/docs/reference/api/Decision.mdx delete mode 100644 docs/docs/reference/api/Delegation.mdx delete mode 100644 docs/docs/reference/api/DelegationRecord.mdx delete mode 100644 docs/docs/reference/api/DuplicateEffect.mdx delete mode 100644 docs/docs/reference/api/EffectKeyError.mdx delete mode 100644 docs/docs/reference/api/EffectRecord.mdx delete mode 100644 docs/docs/reference/api/EffectState.mdx delete mode 100644 docs/docs/reference/api/Event.mdx delete mode 100644 docs/docs/reference/api/EventSink.mdx delete mode 100644 docs/docs/reference/api/FrameworkInterrupt.mdx delete mode 100644 docs/docs/reference/api/Grant.mdx delete mode 100644 docs/docs/reference/api/HeaderIdentityProvider.mdx delete mode 100644 docs/docs/reference/api/IdentityContext.mdx delete mode 100644 docs/docs/reference/api/IdentityError.mdx delete mode 100644 docs/docs/reference/api/IdentityProvider.mdx delete mode 100644 docs/docs/reference/api/InMemoryStateStore.mdx delete mode 100644 docs/docs/reference/api/InterruptApprovalProvider.mdx delete mode 100644 docs/docs/reference/api/InvalidArgument.mdx delete mode 100644 docs/docs/reference/api/JSONLEventSink.mdx delete mode 100644 docs/docs/reference/api/LocalApprovalProvider.mdx delete mode 100644 docs/docs/reference/api/MissingDependency.mdx delete mode 100644 docs/docs/reference/api/NotExecuted.mdx delete mode 100644 docs/docs/reference/api/PendingApproval.mdx delete mode 100644 docs/docs/reference/api/Policy.mdx delete mode 100644 docs/docs/reference/api/PolicyError.mdx delete mode 100644 docs/docs/reference/api/Principal.mdx delete mode 100644 docs/docs/reference/api/Receipt.mdx delete mode 100644 docs/docs/reference/api/ReconcileOutcome.mdx delete mode 100644 docs/docs/reference/api/SQLiteStateStore.mdx delete mode 100644 docs/docs/reference/api/SchemaMismatch.mdx delete mode 100644 docs/docs/reference/api/ScriptedApprovalProvider.mdx delete mode 100644 docs/docs/reference/api/StateStore.mdx delete mode 100644 docs/docs/reference/api/StaticIdentityProvider.mdx delete mode 100644 docs/docs/reference/api/Subject.mdx delete mode 100644 docs/docs/reference/api/Suspended.mdx delete mode 100644 docs/docs/reference/api/WebhookApprovalProvider.mdx delete mode 100644 docs/docs/reference/api/acs-AcsControlHook.mdx delete mode 100644 docs/docs/reference/api/action_hash.mdx delete mode 100644 docs/docs/reference/api/banner.mdx delete mode 100644 docs/docs/reference/api/canonical_bytes.mdx delete mode 100644 docs/docs/reference/api/canonicalize.mdx delete mode 100644 docs/docs/reference/api/conformance-run.mdx delete mode 100644 docs/docs/reference/api/conformance-store-run.mdx delete mode 100644 docs/docs/reference/api/context.mdx delete mode 100644 docs/docs/reference/api/gateway-serve.mdx delete mode 100644 docs/docs/reference/api/index.mdx delete mode 100644 docs/docs/reference/api/jwt_identity-JWTIdentityProvider.mdx delete mode 100644 docs/docs/reference/api/needs_approval.mdx delete mode 100644 docs/docs/reference/api/otel-OTelEventSink.mdx delete mode 100644 docs/docs/reference/api/parse_conditions.mdx delete mode 100644 docs/docs/reference/api/postgres-PostgresStateStore.mdx delete mode 100644 docs/docs/reference/api/protect.mdx delete mode 100644 docs/docs/reference/api/verify-run.mdx delete mode 100644 docs/docs/reference/api/with_approval.mdx delete mode 100644 docs/docs/reference/authority-yaml.mdx delete mode 100644 docs/docs/reference/cli.mdx delete mode 100644 docs/docs/reference/errors.mdx delete mode 100644 docs/docs/reference/exit-codes.mdx delete mode 100644 docs/docs/reference/policy-yaml.mdx delete mode 100644 docs/docs/reference/receipt-and-event-schemas.mdx delete mode 100644 docs/docs/security/disclosure.mdx delete mode 100644 docs/docs/security/receipt-chain.mdx delete mode 100644 docs/docs/security/verify-guarantees.mdx delete mode 100644 docs/docs/study/does-your-framework-double-execute.mdx delete mode 100644 docs/docs/try-it.mdx delete mode 100644 docs/docs/verify.md delete mode 100644 docs/docs/verify/get-the-badge.mdx delete mode 100644 docs/docs/why.mdx delete mode 100644 docs/generated/badges.readme.md delete mode 100644 docs/generated/capabilities.mdx delete mode 100644 docs/generated/capabilities.readme.md delete mode 100644 docs/generated/capabilities.txt delete mode 100644 docs/generated/readiness.full.mdx delete mode 100644 docs/generated/readiness.json delete mode 100644 docs/generated/readiness.mdx delete mode 100644 docs/generated/readiness.readme.md delete mode 100644 docs/images/demo-poster.jpg delete mode 100644 docs/images/demo.mp4 delete mode 100644 docs/images/favicon.svg delete mode 100644 docs/images/social-preview.png delete mode 100644 docs/images/wordmark-dark.svg delete mode 100644 docs/images/wordmark-light.svg delete mode 100644 docs/images/wordmark.svg delete mode 100644 docs/index.mdx delete mode 100644 docs/medical-demo.js delete mode 100644 docs/medical-workbench.js delete mode 100644 docs/protect-my-agent.mdx delete mode 100644 docs/risk-check.mdx delete mode 100644 docs/snippets/architecture-review.jsx delete mode 100644 docs/snippets/demo-film.jsx delete mode 100644 docs/snippets/risk-check.jsx delete mode 100644 docs/snippets/scenario-explorer.jsx delete mode 100644 docs/style.css delete mode 100644 docs/try-it.js delete mode 100644 docs/try.mdx delete mode 100644 docs/website-events.js delete mode 100644 integrations/website-form/.gitignore delete mode 100644 integrations/website-form/.vercelignore delete mode 100644 integrations/website-form/README.md delete mode 100644 integrations/website-form/api/review.mjs delete mode 100644 integrations/website-form/package.json delete mode 100644 integrations/website-form/public/robots.txt delete mode 100644 integrations/website-form/review.test.mjs delete mode 100644 integrations/website-form/vercel.json delete mode 100755 scripts/repoint-claims.py delete mode 100644 tests/test_claims_citations.py delete mode 100644 tests/test_docs_audit.py delete mode 100644 tests/test_docs_medical_demo.py delete mode 100644 tests/test_docs_production.py delete mode 100644 tests/test_docs_reference.py delete mode 100644 tests/test_docs_seo.py delete mode 100644 tests/test_docs_site.py delete mode 100644 tests/test_docs_travelling.py delete mode 100644 tests/test_medical_workbench.py delete mode 100644 tests/test_owasp_mapping.py delete mode 100644 tools/docs_audit/__init__.py delete mode 100644 tools/docs_audit/_files.py delete mode 100644 tools/docs_audit/claims.py delete mode 100644 tools/docs_audit/links.py delete mode 100644 tools/docs_audit/lint-allowlist.txt delete mode 100644 tools/docs_audit/lint.py delete mode 100644 tools/docs_audit/render_api.py delete mode 100644 tools/docs_audit/render_badges.py delete mode 100644 tools/docs_audit/render_capabilities.py delete mode 100644 tools/docs_audit/render_cli.py delete mode 100644 tools/docs_audit/render_cookbook.py delete mode 100644 tools/docs_audit/render_probe.py delete mode 100644 tools/docs_audit/render_readiness.py delete mode 100644 tools/docs_audit/render_schemas.py delete mode 100644 tools/docs_audit/render_soak.py delete mode 100644 tools/docs_audit/snippets.py diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index ad31e6d..d3e8039 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -18,7 +18,7 @@ body: id: expected attributes: label: What the documentation says should happen - description: Quote the sentence, with a link. Every sentence in the README has a row in `docs/docs/CLAIMS.md`; if you found the row, name it. + description: Quote the sentence, with a link. Every sentence in the README has a row in `https://ctrlrun.dev/docs/CLAIMS`; if you found the row, name it. validations: required: true - type: textarea diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index 76485f8..9bf11c0 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -5,7 +5,7 @@ body: - type: markdown attributes: value: | - Every addition answers one question first: *does this improve control or correctness of an agent action that can affect the real world?* If it helps a model think, improves prompts, stores memory, retrieves documents, chooses models or visualises traces, it belongs somewhere else. `docs/docs/ROADMAP.md` lists what is planned and `VISION.md` what is not a build spec. + Every addition answers one question first: *does this improve control or correctness of an agent action that can affect the real world?* If it helps a model think, improves prompts, stores memory, retrieves documents, chooses models or visualises traces, it belongs somewhere else. `https://ctrlrun.dev/docs/ROADMAP` lists what is planned and `VISION.md` what is not a build spec. - type: dropdown id: guarantee attributes: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index cd2f236..f848981 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,8 +9,8 @@ - [ ] **Specification first.** The section this implements is named above; a change to a frozen name or a new entry point amends the spec in this same PR. - [ ] **Tests first.** The acceptance tests were red before the implementation and are green after it; every polling or waiting test bounds its clock or iteration count. - [ ] **Mutation table.** Each MUST in the touched sections was removed, its named test confirmed red, and the guard restored. The table is in the description, checked against the four shapes in CONTRIBUTING.md. -- [ ] **`docs/docs/CLAIMS.md`.** Every new or changed README sentence has a row with code and a test; every removed capability took its row and its sentence with it. -- [ ] **Docs audit green.** `python tools/docs_audit/snippets.py`, `lint.py`, `links.py` and `render_capabilities.py --check` pass; a capability table was edited in `docs/capabilities.yaml`, never by hand. +- [ ] **`CLAIMS.md`.** Every new or changed README sentence has a row with code and a test; every removed capability took its row and its sentence with it. The table lives in [CTRLRun/ctrlrun-docs](https://github.com/CTRLRun/ctrlrun-docs), so a README change here is a pull request there too. +- [ ] **Docs audit green.** In a `ctrlrun-docs` checkout with `CTRLRUN_SOURCE` pointing at this one: `python tools/docs_audit/snippets.py`, `lint.py`, `links.py` and `render_capabilities.py --check` pass. A capability table was edited in that repository's `capabilities.yaml`, never by hand. CI here runs the same checks against this commit, so a stale page is red on this pull request and not on somebody else's. - [ ] **`scripts/check.sh` green** under the project's interpreter. - [ ] **Independent review** requested for anything touching authorization, identity, delegation, the gateway, an adapter or the store. - [ ] **Nothing in `src/` merges on green CI alone**; a maintainer reads it. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55c3791..603609a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -78,20 +78,6 @@ jobs: CTRLRUN_REQUIRE_RELEASE_FIXTURES: "1" run: ./scripts/check.sh - # The badge is written **after** `check.sh`, and the order is the whole claim: a count - # produced before the run would be the size of a suite that might be red. It is uploaded - # from one matrix leg only — two would race for the same artifact name — and published by - # the `badge` job, which runs on a push to `main` and on nothing else. - - name: The test-count badge - if: matrix.python-version == '3.11' - run: python tools/docs_audit/render_badges.py --write-count tests-badge.json - - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - if: matrix.python-version == '3.11' - with: - name: ctrlrun-tests-badge - path: tests-badge.json - # SPEC-v0.4 §5, T118. The composite action, run against this repository's own # configurations, with `install: .` so it dogfoods the checkout rather than the last # release. Two runs, because the second is the one that matters: the N/A path has to be @@ -157,7 +143,10 @@ jobs: # rather than regenerated. §5.1's rule holds across the job boundary: the badge, the job # summary and the uploaded report all come from one verify run. badge: - needs: [verify, check] + # `docs` as well as the two it always needed: the test-count artifact is produced there + # now, and a `badge` job that did not wait for it would download nothing and publish a + # stale count -- or fail on a race, which is the same bug on a good day. + needs: [verify, check, docs] if: github.event_name == 'push' && github.ref == 'refs/heads/main' runs-on: ubuntu-latest permissions: @@ -258,22 +247,35 @@ jobs: assert skipped == 0, f"{skipped} adapter tests skipped; the frameworks did not install" PY - # The documentation audit (docs/STYLE.md). One job of its own so a docs PR gets a docs answer, - # and every step in it is now a hard failure: + # The documentation audit, and the test-count badge that only a green suite may produce. # - # - nine generators, each with `--check`, so no rendered table, reference page, recipe - # directory, readiness block, badge row or study table can be hand-edited; - # - runnable snippets, the forbidden-words lint and the link check. + # The pages moved to `CTRLRun/ctrlrun-docs`, and the checks moved with them -- but what they + # check is *this* commit, so the job runs them there against a checkout of here. One + # implementation of every rule, two triggers: this job on a change to the library, and that + # repository's own CI on a change to a page. # - # The last three carried `continue-on-error: true` from session 0 to session 6. They were - # wired in against the documentation as it stood, and the findings they raised that day were - # the baseline the writing sessions had to clear; a job that was red on arrival would have - # taught everyone to ignore it. The baseline is clear, so the flags are gone -- a red step - # that is allowed to be red is documentation, not a guard. + # Every step is a hard failure. Three of them carried `continue-on-error: true` from session + # 0 to session 6, while a baseline nobody had cleared yet would have made the job red on + # arrival and taught everyone to ignore it. The baseline is clear, so the flags are gone: a + # red step that is allowed to be red is documentation, not a guard. docs: + # **The badge below is the reason for this dependency, and the dependency is the claim.** + # `--write-count` publishes the size of the suite, and a count produced before the suite + # ran would be the size of a run that might be red. It used to be a later *step* in the + # same job as `check.sh`; the audit lives in another repository now, so the ordering is a + # job dependency instead -- which is the stronger form, because a step's ordering is a + # convention and `needs:` is enforced. + needs: check runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: ctrlrun + + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: CTRLRun/ctrlrun-docs + path: ctrlrun-docs - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: @@ -285,47 +287,80 @@ jobs: # sample nobody ran. run: | python -m pip install --upgrade pip - pip install -e ".[dev,gateway,otel,identity]" - - - name: Rendered capability tables match docs/capabilities.yaml - run: python tools/docs_audit/render_capabilities.py --check - - - name: The CLI reference matches click's help text - run: python tools/docs_audit/render_cli.py --check - - - name: The receipt, event and error references match the code - run: python tools/docs_audit/render_schemas.py --check - - - name: The Python API reference matches the docstrings - run: python tools/docs_audit/render_api.py --check - - - name: The cookbook directories are what their pages show - run: python tools/docs_audit/render_cookbook.py --check - - - name: The framework-probe page is the render of the published results - run: python tools/docs_audit/render_probe.py --check - - - name: The soak page is the render of the published results - run: python tools/docs_audit/render_soak.py --check - - - name: The readiness block is the same in all three places - run: python tools/docs_audit/render_readiness.py --check - - - name: The badge row matches the generator - run: python tools/docs_audit/render_badges.py --check - - # The three audits landed `continue-on-error` in session 0, because a baseline nobody had - # cleared yet would have made the job red on arrival and taught everyone to ignore it. - # The baseline is clear -- 96 runnable blocks, 182 documents, 0 findings and 0 broken - # links -- so the flags come off here. An audit that cannot fail is an audit nobody runs. - - name: Runnable snippets execute offline - run: python tools/docs_audit/snippets.py + pip install -e "./ctrlrun[dev,gateway,otel,identity]" + pip install griffe pyyaml + + # `_core.py` raises when it cannot find the library, so this prints a path or the job + # stops here. A documentation check that ran against no source would be green and + # would have verified nothing. + - name: The audit can see this checkout + working-directory: ctrlrun-docs + env: + CTRLRUN_SOURCE: ${{ github.workspace }}/ctrlrun + run: python -c "import sys; sys.path.insert(0, 'tools/docs_audit'); from _core import CORE_ROOT; print(CORE_ROOT)" + + # Nine generators, each with `--check`, so no rendered table, reference page, recipe + # directory, readiness block, badge row or study table can be hand-edited; then the + # runnable snippets, the forbidden-words lint and the link check. + - name: The audit + working-directory: ctrlrun-docs + env: + CTRLRUN_SOURCE: ${{ github.workspace }}/ctrlrun + run: | + set -eu + python tools/docs_audit/render_capabilities.py --check + python tools/docs_audit/render_cli.py --check + python tools/docs_audit/render_schemas.py --check + python tools/docs_audit/render_api.py --check + python tools/docs_audit/render_cookbook.py --check + python tools/docs_audit/render_probe.py --check + python tools/docs_audit/render_soak.py --check + python tools/docs_audit/render_readiness.py --check + python tools/docs_audit/render_badges.py --check + python tools/docs_audit/snippets.py + python tools/docs_audit/lint.py + python tools/docs_audit/links.py + + # Uploaded from here and published by the `badge` job, which runs on a push to `main` + # and on nothing else. + - name: The test-count badge + working-directory: ctrlrun-docs + env: + CTRLRUN_SOURCE: ${{ github.workspace }}/ctrlrun + run: python tools/docs_audit/render_badges.py --write-count "$GITHUB_WORKSPACE/tests-badge.json" - - name: Forbidden words - run: python tools/docs_audit/lint.py + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ctrlrun-tests-badge + path: tests-badge.json - - name: Internal links and anchors resolve - run: python tools/docs_audit/links.py + # A change here can make a page there wrong without anything there changing, so a push to + # `main` tells that repository to re-run its checks against this commit. + # + # **It needs `DOCS_DISPATCH_TOKEN`**, a token with `contents: write` on CTRLRun/ctrlrun-docs; + # `GITHUB_TOKEN` cannot reach another repository. Without the secret this step warns and does + # nothing, and that is a gap rather than a design -- the backstop is the weekly `schedule:` + # run in `ctrlrun-docs/.github/workflows/ci.yml`, which turns a dispatch that stopped + # arriving into a red run within a week instead of into silence. + notify-docs: + needs: [check, docs] + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Tell ctrlrun-docs the library changed + env: + TOKEN: ${{ secrets.DOCS_DISPATCH_TOKEN }} + run: | + set -eu + if [ -z "${TOKEN:-}" ]; then + echo "::warning::DOCS_DISPATCH_TOKEN is not set; ctrlrun-docs re-checks on its weekly schedule instead" + exit 0 + fi + curl -sS -f -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $TOKEN" \ + https://api.github.com/repos/CTRLRun/ctrlrun-docs/dispatches \ + -d "{\"event_type\":\"library-changed\",\"client_payload\":{\"sha\":\"$GITHUB_SHA\"}}" # The definition of done says the demo runs with no network and the README quick start # works verbatim. Both were only ever checked by hand, which is how a README stops being diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0f9d051..00e6354 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,7 +16,7 @@ Not every contribution carries every rule below. In rough order of what they ask and cannot take for itself; so is telling us where the policy template for your sector is wrong. Neither needs the suite installed. - **Documentation** — a cookbook recipe, a `ctrlrun verify` snippet for a CI that is not GitHub - Actions — is held to `docs/STYLE.md` and the audit below, and not to the mutation table. + Actions — is held to `CTRLRun/ctrlrun-docs`'s `STYLE.md` and the audit below, and not to the mutation table. - **Anything under `src/`** is where the rest of this file applies in full, and a maintainer reads it whatever CI says. @@ -103,8 +103,8 @@ mutants (say so in the table instead of claiming to have closed one). ## Every claim maps to a test -`docs/docs/CLAIMS.md` maps every sentence in the README to the code that implements it and the -test that proves it. A sentence with no row is cut. A row whose test disappears takes its +`CLAIMS.md`, in [CTRLRun/ctrlrun-docs](https://github.com/CTRLRun/ctrlrun-docs), maps every sentence in +the README to the code that implements it and the test that proves it. A sentence with no row is cut. A row whose test disappears takes its sentence with it in the same commit. A test resolves every `file.py:NNN` in the table against the line it cites and fails if the named symbol is not on it. @@ -124,7 +124,14 @@ downgraded from prevention to attribution is renamed everywhere it was called a ## How documentation pull requests are checked -The words are held to the same standard as the code, by `tools/docs_audit/`: +The documentation is [CTRLRun/ctrlrun-docs](https://github.com/CTRLRun/ctrlrun-docs), and the words +there are held to the same standard as the code here, by that repository's `tools/docs_audit/`. +The checks read **both** trees -- a page that says the CLI prints X is only true if the CLI +prints X -- so they run in two places: on a pull request there, and from the `docs` job of +this repository's CI against the commit you are proposing. A change to the code that makes a +page wrong is red here. + +What they check: - every fenced block marked `runnable` is executed offline, with a socket guard, and must exit 0; a sample either runs or is not marked; @@ -132,9 +139,9 @@ The words are held to the same standard as the code, by `tools/docs_audit/`: proof that does not exist, with an allowlist that carries a reason per entry; - internal links and anchors must resolve; - the capability tables in the README and the docs are rendered from - `docs/capabilities.yaml`, and a hand edit to a rendered copy fails CI. + `CTRLRun/ctrlrun-docs`'s `capabilities.yaml`, and a hand edit to a rendered copy fails CI. -`docs/STYLE.md` has the writing rules. Run the four checks from its last section before +`CTRLRun/ctrlrun-docs`'s `STYLE.md` has the writing rules. Run the four checks from its last section before opening the pull request. ## Pull requests diff --git a/MANIFEST.in b/MANIFEST.in index d013c72..2536c1b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -11,22 +11,18 @@ include ctrlrun.example.yaml include CHANGELOG.md include SECURITY.md include VISION.md +# `docs/` is the six specifications and the two implementation ones: the implementer's +# contract, and the thing `# SPEC:` comments in `src/` cite. They ship. +# +# What used to be here as well -- the documentation site, the tools that render it, its +# capability source and its rendered fragments -- is `CTRLRun/ctrlrun-docs` now, and the +# lines that carried it are gone rather than repointed. An sdist cannot include a file from +# another repository, and `test_the_sdist_carries_everything_the_tests_read` is what would +# have caught a line left behind naming a path that no longer exists. recursive-include docs *.md -# The documentation audit reads these: `docs/capabilities.yaml` is the source the capability -# tables are rendered from and `docs/generated/` holds the renders, and -# `tests/test_docs_audit.py` compares the two. `tools/docs_audit/` is the generator and the -# three checks, imported by that test, so an sdist that ran its tests without them would be -# the same failure as shipping tests without their data. -recursive-include docs *.yaml *.mdx *.txt *.json *.svg *.png *.js *.mjs *.jsx *.css *.cjs -include docs/.mintignore -recursive-include tools *.py *.txt -# The README's header assets, and the sources they are rendered from. +# The README's header assets, and the sources they are rendered from. These stayed: the README +# is this repository's, and so is what it renders on PyPI. recursive-include docs/assets *.svg *.png *.gif *.tape *.sh *.txt -# The website's media. Mintlify deploys from `docs/`, so a page's video has to live under it, -# and `test_the_sdist_carries_everything_the_tests_read` then requires it to ship. That test -# is checked against `git ls-files`, so the only way out would be to untrack the file, which -# would take it off the site. The sdist carries the megabyte. -recursive-include docs/images *.mp4 *.jpg recursive-include tests *.py # SPEC-v0.4 §4.3 — T115 validates `--junit` against a checked-in schema, and reads the README # beside it for the schema's provenance and licence. A test that ships without its data is a diff --git a/README.md b/README.md index 93020bc..8719264 100644 --- a/README.md +++ b/README.md @@ -127,8 +127,8 @@ refuses to *knowingly* act twice, and it rolls nothing back. Receipts are chaine is detected. They are not signed: alteration is not authorship. The badge above means the **declared guarantees pass** in the setup they ran against, and it does not mean secure, safe, compliant, certified or audited: -[what the badge means](https://github.com/CTRLRun/ctrlrun/blob/main/docs/docs/verify.md#what-the-badge-means) -· [`OWASP-AGENTIC-TOP10.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/docs/OWASP-AGENTIC-TOP10.md) +[what the badge means](https://ctrlrun.dev/docs/verify#what-the-badge-means) +· [`OWASP-AGENTIC-TOP10.md`](https://ctrlrun.dev/docs/OWASP-AGENTIC-TOP10) names the four entries this does not address. If an agent only reads and answers, you do not need CTRLRun. The moment it can **send, pay, @@ -257,7 +257,7 @@ host writes: `pip install "ctrlrun[postgres]"`, one URL, the same guarantees gra suite. Prove it in your own setup with `ctrlrun verify`, which runs the kernel's own failure scenarios against *your* policy in a scratch store, with no network. - + | Guarantee | `@protect` | Gateway | Adapter | |---|---|---|---| | **Approval binding** — An approval is bound to the exact action; a mutated or replayed one is refused. | yes | yes | prevention or attribution, per adapter | @@ -335,7 +335,7 @@ full reference, and a browser demo that runs with no install. | MCP | [Overview](https://ctrlrun.dev/docs/mcp/overview) · [The gateway in five minutes](https://ctrlrun.dev/docs/mcp/gateway-in-5-minutes) | | Running it for real | [Production](https://ctrlrun.dev/docs/production/index) · [Postgres](https://ctrlrun.dev/docs/production/postgres) · [Recovery](https://ctrlrun.dev/docs/production/recovery) · [Operations](https://ctrlrun.dev/docs/production/operations) | | Every key, flag and error | [Reference](https://ctrlrun.dev/docs/reference/policy-yaml) · [FAQ](https://ctrlrun.dev/docs/faq) | -| What holds, and what does not | [Threat model](https://ctrlrun.dev/docs/THREAT_MODEL) · [What `verify` proves](https://github.com/CTRLRun/ctrlrun/blob/main/docs/docs/verify.md) · [`CLAIMS.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/docs/CLAIMS.md), every sentence mapped to its test · [How this is built](https://github.com/CTRLRun/ctrlrun/blob/main/docs/docs/how-this-is-built.md) | +| What holds, and what does not | [Threat model](https://ctrlrun.dev/docs/THREAT_MODEL) · [What `verify` proves](https://ctrlrun.dev/docs/verify) · [`CLAIMS.md`](https://ctrlrun.dev/docs/CLAIMS), every sentence mapped to its test · [How this is built](https://ctrlrun.dev/docs/how-this-is-built) | ## Contributing @@ -347,7 +347,7 @@ working agreement, and vulnerability. Every claim in this file has a test behind it, so a change to the prose usually means a change to the suite. [`CHANGELOG.md`](https://github.com/CTRLRun/ctrlrun/blob/main/CHANGELOG.md) and -[`docs/docs/ROADMAP.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/docs/ROADMAP.md) say +[`https://ctrlrun.dev/docs/ROADMAP`](https://ctrlrun.dev/docs/ROADMAP) say where it is going. Releases carry PyPI provenance attestations from GitHub Actions. ## License diff --git a/SECURITY.md b/SECURITY.md index 9e2460e..50eb6b8 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -16,7 +16,7 @@ warranted you will be credited in the release notes unless you ask not to be. Releases carry PyPI provenance attestations from GitHub Actions. Distributions are published through trusted publishing, so there is no API token to leak or replay, and each wheel and sdist carries an attestation naming the workflow that built it. Every GitHub Action the workflows use -is pinned to a commit. `docs/docs/how-this-is-built.md` says what has and has not been reviewed. +is pinned to a commit. `https://ctrlrun.dev/docs/how-this-is-built` says what has and has not been reviewed. From v0.6.0, every GitHub Release also carries signed SLSA build provenance for the same distributions — `ctrlrun-.intoto.jsonl` (the DSSE envelopes) and @@ -64,7 +64,7 @@ these as a security issue, not a bug: - An unknown execution outcome is recorded as `failed` rather than `ambiguous`. - A receipt does not reflect what happened. -`docs/docs/THREAT_MODEL.md` states what is deliberately out of scope — a compromised host, a +`https://ctrlrun.dev/docs/THREAT_MODEL` states what is deliberately out of scope — a compromised host, a malicious administrator with write access to the state database, a lying external service, or code that bypasses the decorator entirely. Those are documented limits rather than vulnerabilities, but if you think one is stated too generously, say so. diff --git a/VISION.md b/VISION.md index abd2668..62a52d2 100644 --- a/VISION.md +++ b/VISION.md @@ -1,6 +1,6 @@ # VISION.md -> **This is not a build spec, and it is not the state of the code.** It was written before v0.1 shipped, so that the long-term shape is written down once and stops leaking into READMEs, schemas, and PRs. What has actually shipped is in [`docs/docs/ROADMAP.md`](docs/docs/ROADMAP.md) and in each version's `docs/SPEC-v0.x.md`; where a section below has since been built, a *Status* line says which version built it and where it differs from the sketch. Everything without one is still a sketch, and nothing here is a commitment. Do not derive tasks from this file. +> **This is not a build spec, and it is not the state of the code.** It was written before v0.1 shipped, so that the long-term shape is written down once and stops leaking into READMEs, schemas, and PRs. What has actually shipped is in [`https://ctrlrun.dev/docs/ROADMAP`](https://ctrlrun.dev/docs/ROADMAP) and in each version's `docs/SPEC-v0.x.md`; where a section below has since been built, a *Status* line says which version built it and where it differs from the sketch. Everything without one is still a sketch, and nothing here is a commitment. Do not derive tasks from this file. --- @@ -106,7 +106,7 @@ Delegation attenuates, never amplifies: `child ⊆ parent`. Human €100k → fi **Verify** — `ctrlrun verify` runs deterministic adversarial scenarios against a real configuration and reports per-guarantee pass/fail with counterexamples. Badge means "declared guarantees pass", never "secure". -*Status: built in v0.4 (`docs/SPEC-v0.4.md`, `docs/docs/verify.md`). One thing the sketch did not have: a guarantee the configuration cannot exercise reports `not_applicable` with a reason, and not applicable is not a pass.* +*Status: built in v0.4 (`docs/SPEC-v0.4.md`, `https://ctrlrun.dev/docs/verify`). One thing the sketch did not have: a guarantee the configuration cannot exercise reports `not_applicable` with a reason, and not applicable is not a pass.* ## 6. Standards posture diff --git a/action.yml b/action.yml index 006b2f1..6e1c173 100644 --- a/action.yml +++ b/action.yml @@ -49,7 +49,7 @@ inputs: description: >- Where to write the Shields endpoint JSON. The action writes it and never publishes it: publishing is your decision, in your own workflow, with whatever permissions you choose - (SPEC-v0.4 §5.2, `docs/docs/verify.md`). + (SPEC-v0.4 §5.2, `https://ctrlrun.dev/docs/verify`). required: false default: verify-badge.json upload-artifact: diff --git a/docs/.mintignore b/docs/.mintignore deleted file mode 100644 index a5ec714..0000000 --- a/docs/.mintignore +++ /dev/null @@ -1,17 +0,0 @@ -# Files under docs/ that are not pages of the site. -BUILD-PROMPTS-*.md -README.md -IA.md -STYLE.md -SEO.md -capabilities.yaml -generated/ -assets/ -# The six specifications are the implementers' contract, not user documentation: 111,000 -# words written for somebody building against the kernel, and they stay public on GitHub. -# docs/architecture/specifications.mdx links to each one. -SPEC-v*.md - -# Implementation specifications remain linked on GitHub, outside the reader-facing site. -SPEC-mcp-operator.md -SPEC-scan.md diff --git a/docs/IA.md b/docs/IA.md deleted file mode 100644 index 32ba4b0..0000000 --- a/docs/IA.md +++ /dev/null @@ -1,420 +0,0 @@ -# Information architecture for the documentation site - -The target shape of the docs site, one line per page: what it is for and the query it should -answer. Later sessions write the pages; this file is what they write against, and -`docs/capabilities.yaml` names pages by the paths below. - -**The fixed copy**, quoted here so every page quotes the same words: - -| Slot | Text | Where it goes | -|---|---|---| -| Tagline | The last check before an AI agent does something it can't undo. | README line 1, Home hero, social preview | -| Principle | Autonomy belongs to the action, not the agent. | Second sentence everywhere; the line people quote | -| Category | The execution safety layer for AI agents. | GitHub About, PyPI summary, site ``, directory listings | -| Opener (long-form only) | Everyone is rushing to ship AI agents without thinking about consequences. | First line of Why and of launch posts; never a heading | -| Promise | A consequential action happens at most once, exactly as approved, and leaves a receipt — and when the outcome is unknown, CTRLRun says so instead of guessing. | Hero subline, README paragraph 2 | -| Hook (posts) | Agents can retry. The real world can't. | Social, talk titles; not the README header | - -The rules every page is held to are in `docs/STYLE.md`. The tools that hold them are in -`tools/docs_audit/`. - -## Conventions - -- Paths are root-relative on the site: `docs/concepts/effect-keys` is `docs/docs/concepts/effect-keys.mdx`. -- **Purpose** is the page's first-paragraph answer, compressed. **Query** is the search a - stranger types, and the first sentence of the page is written to answer it. -- The existing Markdown documents that stay where they are — the specifications, - `ARCHITECTURE.md`, `THREAT_MODEL.md`, the OWASP and ACS readings — are linked from the pages - that own them and are not rewritten. -- Sessions are named where a page belongs to a later session, so a session knows what it owes. - -## The tree - -``` -Home index -Why why -Get started - ├─ Install get-started/install - ├─ 60-second quickstart get-started/quickstart - ├─ Three ways in get-started/three-ways-in - └─ Choosing between them get-started/choosing -Production - ├─ Run it in production production/index - ├─ SQLite or Postgres production/postgres - ├─ How reservation works production/how-reservation-works - ├─ Migrations and schema versions production/migrations - ├─ Recovery after a crash production/recovery - ├─ Receipt integrity in practice production/receipt-integrity - ├─ The soak production/soak - ├─ Operations production/operations - └─ Running on Postgres (reference) postgres -MCP - ├─ Overview mcp/overview - ├─ The gateway in five minutes mcp/gateway-in-5-minutes - └─ Use the docs from your editor mcp/use-the-docs-from-your-editor -Concepts - ├─ Action and hash concepts/action-and-hash - ├─ Decisions concepts/decisions - ├─ Approval binding concepts/approval-binding - ├─ Effect keys concepts/effect-keys - ├─ Outcomes and AMBIGUOUS concepts/outcomes-and-ambiguous - ├─ Receipts and evidence concepts/receipts-and-evidence - ├─ Authority and delegation concepts/authority-and-delegation - ├─ Observe mode concepts/observe-mode - └─ Fail closed concepts/fail-closed -Guides - ├─ Protect a function guides/protect-a-function - ├─ Put the gateway in front of MCP guides/gateway-in-front-of-mcp - ├─ Approve in Slack guides/approvals-in-slack - ├─ Resolve an AMBIGUOUS effect guides/resolve-an-ambiguous-effect - ├─ Reconcile automatically guides/reconcile-automatically - ├─ Roll out observe, then enforce guides/observe-to-enforce - ├─ Run on Postgres guides/run-on-postgres - ├─ Verify in CI guides/verify-in-ci - ├─ Export to OpenTelemetry guides/export-to-opentelemetry - ├─ Use the LangGraph adapter guides/langgraph-adapter - └─ Use the OpenAI Agents SDK adapter guides/openai-agents-adapter -Cookbook cookbook/index (session 4; recipes listed below) -Reference - ├─ Policy YAML reference/policy-yaml - ├─ Authority YAML reference/authority-yaml - ├─ CLI reference/cli - ├─ Python API reference/api/index (+ one page per public name) - ├─ Receipt and event schemas reference/receipt-and-event-schemas - ├─ Exit codes reference/exit-codes - └─ Errors reference/errors -Compare - ├─ vs framework human-in-the-loop compare/framework-hitl - ├─ vs guardrail libraries compare/guardrail-libraries - ├─ vs agent governance toolkits compare/governance-toolkits - ├─ vs durable workflow engines compare/durable-workflows - └─ vs idempotency keys compare/idempotency-keys -FAQ faq -Security - ├─ Threat model security/threat-model - ├─ What verify guarantees security/verify-guarantees - ├─ The receipt chain security/receipt-chain - ├─ How this is built security/how-this-is-built (session 1b) - └─ Reporting a vulnerability security/disclosure -Architecture and specifications - ├─ Architecture architecture/overview - └─ Specifications architecture/specifications -Changelog changelog -Demos - ├─ Overview demos/index - ├─ Try it in your browser try-it - └─ Medical affairs demos/medical-affairs -Research: does your framework - double-execute? study/does-your-framework-double-execute -Get the badge verify/get-the-badge -``` - -## Home and Why - -| Path | Purpose | Query | -|---|---|---| -| `docs` | The tagline, the principle, the promise; the demo; the capability grid rendered from `capabilities.yaml`; the three ways in; three start-here cards; the one line that adds this site as an MCP server to a coding tool. | *ctrlrun* · *AI agent safety layer* | -| `docs/why` | Opens with the opener line. Five sections, one principle each: FAILED is not UNKNOWN · an approval is bound to what the human saw · autonomy belongs to the action · unknown means no · evidence leaves the building. Ends at How this is built. | *why do AI agents double execute actions* · *AI agent consequential actions* | -| `docs/not-only-agents` | For the reader who runs a task queue, a webhook handler or a cron job rather than an agent: the same failure with no model in it, the three examples under `examples/without-an-agent/`, what an agent actually changes, and the two guarantees that do the work when nobody is delegating authority to a worker. | *celery task retried twice* · *webhook delivered twice duplicate* · *retry safe background job python* | - -## Get started - -| Path | Purpose | Query | -|---|---|---| -| `docs/get-started/install` | `pip install ctrlrun`; what it installs (pyyaml, click, nothing else); the extras and what each adds; Python 3.11+. | *install ctrlrun* | -| `docs/get-started/quickstart` | Protect one function end to end in sixty seconds, with the real output: a policy, a decorator, a refused mutation, a receipt. | *ctrlrun quickstart* · *protect an AI agent action python* | -| `docs/get-started/three-ways-in` | Decorator, gateway, adapter: what each covers and what each needs. The negative sentence: most readers need the decorator and should not look for an adapter. | *ctrlrun langgraph* · *ctrlrun mcp* · *do I need an adapter* | -| `docs/get-started/choosing` | The decision table: in-process Python → decorator; tools behind MCP → gateway; a framework with its own approval UI → adapter. What you do not need for the single-host case: a server, a database, a dashboard. | *ctrlrun decorator vs gateway* | - -## Production - -The question a stranger asks after the demo convinces them, and the one the rest of this site -answered only in pieces: **can I run this for real, and what happens when the parts that fail, -fail?** It sits third, above MCP and Concepts, because a reader deciding whether to adopt asks -it before they ask what an effect key is. - -**The first line of the section is load-bearing.** SQLite is the default and is production-grade -on one host; Postgres is for many hosts. Written in that order, because a reader with one host -must not be told they are not really in production. - -`docs/production/soak` is a **render** of `research/soak/results/*.json` and is never hand-edited, on -`docs/study/does-your-framework-double-execute`'s precedent: the duration on the page is the measured -one, and the page says in the same paragraph that the roadmap's exit criterion is not met by it. - -| Path | Purpose | Query | -|---|---|---| -| `docs/production/index` | The section's front door: which store and why, what this section answers, the generated readiness block with its **Not yet** list, and the four things the store holds. | *is ctrlrun production ready* | -| `docs/production/postgres` | The choice, in one table: SQLite until a second host writes, Postgres after. What changes (a URL and a schema) and what does not (everything else). | *ctrlrun sqlite vs postgres* | -| `docs/production/how-reservation-works` | One winner per effect key, and the two rows nobody merges: an exception before `COMMIT` is a failed write to retry; one during it is unknown and is re-read. | *lost commit ambiguous* · *exactly once database* | -| `docs/production/migrations` | Five shapes, three of them a refusal; nothing half-applies; the backward direction that corrupts; what a rolling deploy can and cannot do. | *ctrlrun schema migration* | -| `docs/production/recovery` | A restarted process repairs nothing and cannot know the holder is dead. Nothing sweeps; an expired lease is a refusal, not a reclaim. | *agent crashed mid action* | -| `docs/production/receipt-integrity` | The runbook: run `--verify-chain`, read the six names, know what each means. `docs/security/receipt-chain` keeps *what it proves*; this page is *what to do*. | *verify receipt chain* | -| `docs/production/soak` | Generated. One published run: how long, how many actions, how many unattributed ambiguous outcomes, and what it is not evidence of. | *ctrlrun soak test* | -| `docs/production/operations` | What to watch, what to page on, what to back up, and the fact that there is nothing to run. | *ctrlrun monitoring* | -| `docs/postgres` | The operational reference that already existed: connection strings, grants, pooling, failover, the throughput ceiling. Moved here from Architecture, because this is where a reader looks for it. | *ctrlrun postgres connection* | - -## MCP - -Four things are true today and the pages say exactly that. Added by session 3b; the fourth -row landed with `docs/SPEC-mcp-operator.md`, which is when it stopped being planned. - -| Path | Purpose | Query | -|---|---|---| -| `docs/mcp/overview` | CTRLRun works with MCP in four ways: enforcement (the gateway in front of any MCP server), answering (the operator server, for approvers), learning (this site is an MCP server), discovery (the registries, once listed). | *MCP gateway* · *MCP server human approval* | -| `docs/mcp/gateway-in-5-minutes` | For a reader who already runs an MCP server: before/after, the two commands, what the agent sees on deny and on approval-required, the supported revisions, the principal-flag choice and its security note. | *protect MCP server* · *MCP tool call approval gateway* | -| `docs/mcp/approve-from-your-assistant` | For the person who answers approvals rather than the one who deploys: what `ctrlrun mcp-operator` is, the two flags, a client configuration, a real transcript ending in the receipt that names the approver, and the five things it will not do. | *approve MCP tool call from an assistant* · *MCP human approval server* | -| `docs/mcp/use-the-docs-from-your-editor` | The exact configuration for this site's MCP server, three questions an assistant can then answer, a screenshot spec. | *ctrlrun mcp docs* | - -## Concepts - -Each Concepts page opens with one definitional sentence an assistant can quote standalone, -has one diagram or code block, names the guarantee it supports and what it does not do, and -ends with Next links. Every claim on a Concepts page has a `docs/docs/CLAIMS.md` row. - -| Path | Purpose | Query | -|---|---|---| -| `docs/concepts/action-and-hash` | An action is a named operation with canonical arguments, and its hash is what everything binds to: sorted keys, no whitespace, no floats. | *ctrlrun action hash* · *canonical action hash AI agent* | -| `docs/concepts/decisions` | Three decisions — allow, approve, deny — decided per action by a policy that cannot see who is asking. First matching rule wins; unknown is denied. | *AI agent action policy allow approve deny* | -| `docs/concepts/approval-binding` | An approval is bound to the exact action hash a human saw, is single-use, expires, and is consumed atomically with the reservation. A mutated action is refused. | *human-in-the-loop approval bound to action* · *approval mutation AI agent* | -| `docs/concepts/effect-keys` | An effect key names the real-world consequence, so the same intent from a retry, a second agent or a second host is one effect. This is the page that says *idempotency* once. | *idempotency key AI agent* · *prevent duplicate execution agent tool call* | -| `docs/concepts/outcomes-and-ambiguous` | Three outcomes — COMMITTED, FAILED, AMBIGUOUS — and why a timeout is not a failure. Only `NotExecuted` means failed; everything else after the first byte is unknown, and unknown blocks a blind retry. The page that explains the product. | *what happens when an agent tool call times out* · *double execution AI agent retry* | -| `docs/concepts/receipts-and-evidence` | Every executed action leaves a portable JSON receipt: who, what, decision, approval, effect key, outcome, and the policy hash that decided it. Chained, not signed. | *AI agent audit trail receipts* | -| `docs/concepts/authority-and-delegation` | Authority is the second axis: opt-in, then fail-closed. A grant says who may ask; the policy says how much autonomy the action has. Delegation only narrows, at creation and at every evaluation. Identity is consumed, never issued. | *AI agent authorization delegation* · *least privilege AI agents* | -| `docs/concepts/observe-mode` | One line runs every real decision against real traffic and records what enforcement would have blocked, without blocking. It executes; it is not a dry run. | *AI agent policy shadow mode* | -| `docs/concepts/fail-closed` | Unknown action, missing policy, malformed policy, missing principal, missing or mismatched approval, inconsistent state: all deny. No flag makes a consequential action permissive by default. | *fail closed AI agent* | - -## Guides - -Each guide is a task with a verb in the title: prerequisites, numbered steps with runnable -blocks, expected output, and *if it didn't work* with the two or three real failure messages. -The gateway guide and the observe-to-enforce guide get the most room; they are the two that -turn readers into users. - -| Path | Purpose | Query | -|---|---|---| -| `docs/guides/protect-a-function` | Decorate a function, declare an effect key, write the policy, see a refund refused and a Kubernetes delete sent for approval. | *protect python function AI agent approval* | -| `docs/guides/gateway-in-front-of-mcp` | Two commands put every guarantee in front of an existing MCP server with no agent changes: the alias, the principal, the effect templates, the banner that names writes with no effect key. | *MCP gateway human approval* · *MCP server tool call approval* | -| `docs/guides/approvals-in-slack` | `WebhookApprovalProvider`: the request goes to a webhook, a human answers in Slack, the answer comes back through the same grant calls the CLI uses. | *slack approval AI agent actions* | -| `docs/guides/resolve-an-ambiguous-effect` | Reading `ctrlrun effects --state ambiguous`, asking the remote, `ctrlrun resolve --committed` or `--failed`, and what the receipt then says, including who resolved it. | *ctrlrun resolve ambiguous* | -| `docs/guides/reconcile-automatically` | `@protect(reconcile=...)`: a hook that asks the remote what happened, and the only thing besides a human that moves a record out of AMBIGUOUS. | *reconcile AI agent action stripe kubernetes* | -| `docs/guides/observe-to-enforce` | `mode: observe` for a week, `ctrlrun stats` to read the cost of enforcement, then `mode: enforce`. | *roll out AI agent policy without breaking production* | -| `docs/guides/run-on-postgres` | `pip install "ctrlrun[postgres]"`, the connection string, what to grant, migrations at open, the lost-COMMIT case. | *ctrlrun postgres* | -| `docs/guides/verify-in-ci` | The GitHub Action, the two shapes of report, the N/A line and what it means, the badge. | *verify AI agent safety configuration CI* | -| `docs/guides/export-to-opentelemetry` | `OTelEventSink`: one span per action, one event per step, argument values opt-in. | *opentelemetry AI agent actions* | -| `docs/guides/langgraph-adapter` | Route an approval through `interrupt()`: the operator builds the `Control`, `wait=True`, `Command(resume=...)`, and prevention versus attribution. | *langgraph interrupt human approval tool call* | -| `docs/guides/openai-agents-adapter` | Route an approval through the SDK's tool-approval interruption: `protected_tool`, `gate.run`, why a rejection leaves no CTRLRun evidence. | *openai agents sdk tool approval* | - -## Cookbook (session 4) - -One recipe per situation: the situation in two sentences, the policy, the code, what the agent -sees when refused or asked, the receipt, and what to do when an AMBIGUOUS appears. Every block -runs offline against a fake remote, and every recipe is also a directory under -`examples/cookbook/<name>/` with the examples' guard: a refusal that stops being refused exits -non-zero. - -| Path | Situation | -|---|---| -| `docs/cookbook/refund-agent` | money — a refund agent with amount tiers | -| `docs/cookbook/payout-maker-checker` | money — a payout agent with maker/checker via delegation | -| `docs/cookbook/deploy-agent` | infrastructure — restart auto, apply-prod approve, delete-namespace deny | -| `docs/cookbook/database-migration-agent` | infrastructure — a migration agent | -| `docs/cookbook/iam-agent` | permissions — grant read, never admin | -| `docs/cookbook/credential-rotation-agent` | permissions — rotate, with approval to revoke | -| `docs/cookbook/crm-update-agent` | records — update a record, approve a merge | -| `docs/cookbook/data-deletion-agent` | records — deletion under a retention rule | -| `docs/cookbook/outbound-email-agent` | communications — external recipients need approval | -| `docs/cookbook/customer-notification-agent` | communications — batch notifications, one effect each | -| `docs/cookbook/manager-and-worker` | multi-agent — a manager delegates bounded authority to a worker | -| `docs/cookbook/protect-an-mcp-server` | integrations — an existing MCP server in five minutes | -| `docs/cookbook/langgraph-interrupt` | integrations — LangGraph with `interrupt()` | -| `docs/cookbook/openai-agents-tool-approval` | integrations — the OpenAI Agents SDK's tool approval | -| `docs/cookbook/slack-approvals` | integrations — approvals in Slack via webhook | -| `docs/cookbook/receipts-to-opentelemetry` | integrations — receipts into a tracing backend | -| `docs/cookbook/observe-then-enforce` | operations — observe for a week, then enforce | -| `docs/cookbook/resolve-an-ambiguous-effect` | operations — a human resolves an unknown outcome | -| `docs/cookbook/reconcile-against-the-remote` | operations — reconcile against Stripe or Kubernetes automatically | -| `docs/cookbook/verify-in-github-actions` | operations — the composite action in a workflow | -| `docs/cookbook/sqlite-to-postgres` | operations — move the store | - -## Reference - -Reference pages are generated from the code where the code can say it, and a drift test fails -CI where it cannot. - -| Path | Purpose | Query | -|---|---|---| -| `docs/reference/policy-yaml` | Every key of `ctrlrun.policy/v1`–`v4`: type, default, example, and the fail-closed behaviour when omitted. `controls:` and `data:` documented as registry primitives; the word *pack* does not appear. | *ctrlrun.yaml reference* · *ctrlrun policy schema* | -| `docs/reference/authority-yaml` | Every key of `authority:`: grants, subjects, constraints, `delegable`, `expires_at`, `max_delegation_depth`, and the omission rule. | *ctrlrun authority grants yaml* | -| `docs/reference/cli` | Every command and flag, generated from click's help; a test asserts the page matches `--help`. | *ctrlrun cli* · *ctrlrun resolve* | -| `docs/reference/api/index` | Every frozen public name from SPEC §8 and §11 across versions, generated from docstrings into one page per name. | *ctrlrun Control* · *ctrlrun protect decorator* | -| `docs/reference/receipt-and-event-schemas` | `ctrlrun.receipt/v3` and the event types, field by field, from the code. | *ctrlrun receipt json schema* | -| `docs/reference/exit-codes` | Every CLI exit code and what it means, from the code. | *ctrlrun verify exit code* | -| `docs/reference/errors` | The closed error hierarchy: `ActionDenied`, `ApprovalRequired`, `ApprovalMismatch`, `DuplicateEffect`, `AmbiguousEffect`, `NotExecuted` and the rest, with when each is raised. | *ctrlrun ApprovalMismatch* · *ctrlrun AmbiguousEffect* | - -## Compare - -Each: what the other thing is good at, honestly; what it does not do; when to use both; a -short table. No vendor name in a heading. - -| Path | Purpose | Query | -|---|---|---| -| `docs/compare/framework-hitl` | A framework's interrupt lets a human say yes; it does not bind the yes to the arguments that execute, refuse a retry after a lost response, or leave a receipt. Use both: the adapter routes through the interrupt. | *langgraph human in the loop vs* · *agent framework approval limitations* | -| `docs/compare/guardrail-libraries` | Guardrails inspect inputs and outputs; CTRLRun sits at the boundary between intention and effect. Different layer; use both. | *AI guardrails vs execution control* | -| `docs/compare/governance-toolkits` | Governance toolkits catalogue, monitor and report; CTRLRun refuses, in the execution path, per action. | *AI agent governance vs runtime enforcement* | -| `docs/compare/durable-workflows` | Durable workflow engines retry until success and make that safe with idempotent activities; CTRLRun refuses to retry an unknown outcome and binds approvals. Complementary. | *temporal vs ctrlrun* · *durable execution AI agents idempotency* | -| `docs/compare/idempotency-keys` | An idempotency key deduplicates at one remote that supports it; an effect key deduplicates at the agent side across remotes, refuses on unknown, and is bound to an approval. The page that says *idempotency* precisely. | *idempotency keys AI agents* · *stripe idempotency key vs* | - -## FAQ - -`docs/faq` — the twelve questions engineers ask, answer-first, at most eighty words each, marked up -as FAQ structured data: isn't this idempotency keys · why not a workflow engine · do I need an -adapter · is it exactly-once · what happens on timeout · can I bypass it · does it phone home · -what if the human takes an hour · single host or many · what's in a receipt · is the chain a -signature · what is not covered. Query: *ctrlrun faq* and each question verbatim. - -## Security - -| Path | Purpose | Query | -|---|---|---| -| `security/threat-model` | What CTRLRun defends against, what it does not, and the fail-closed rules that follow; renders `docs/docs/THREAT_MODEL.md`. | *ctrlrun threat model* | -| `docs/security/verify-guarantees` | The guarantee catalogue G1–G11, what each exercises, what N/A means, what verify cannot see. | *ctrlrun verify guarantees* | -| `docs/security/receipt-chain` | Each receipt carries the hash of the one before; what the chain detects, what it does not prove, and the two statements that erase the end of the log. Alteration, not authorship. | *tamper evident audit log AI agent* | -| `security/how-this-is-built` | Spec-first, every MUST mutation-tested with the real numbers, independent review sessions, CLAIMS.md, N/A is not a pass, AI coding agents used throughout with the constraints that make that safe, and what has not been done: no external audit yet. Session 1b. | *is ctrlrun trustworthy* · *how ctrlrun is tested* | -| `docs/security/disclosure` | How to report a vulnerability and what happens to the report; renders `SECURITY.md`. | *ctrlrun security report* | - -## Architecture and specifications - -| Path | Purpose | Query | -|---|---|---| -| `architecture/overview` | The boundary CTRLRun owns, the canonical flow (normalize · decide · approve · reserve · execute · record), the module map; renders `docs/docs/ARCHITECTURE.md`. | *ctrlrun architecture* | -| `docs/architecture/specifications` | The six specifications, unchanged, with one line each on what the version asked; plus the OWASP and ACS readings. | *ctrlrun spec* | - -## Changelog - -`changelog` — renders `CHANGELOG.md`. Query: *ctrlrun changelog* · *ctrlrun 0.6*. - -## The three things that travel - -| Path | Purpose | Query | -|---|---|---| -| `docs/demos/index` | The two pages that run the released wheel in the reader's own browser, and the one line that runs the same thing faster offline. | *ctrlrun demo online* | -| `docs/demos/medical-affairs` | An approval bound to revision A of a letter to a physician, and the send of revision B refused after new evidence redrafts it — the browser demo under a policy whose consequential action is a document rather than a payment. | *AI medical information letter review · agent citation drift* | -| `docs/try-it` | `ctrlrun demo` in the browser via Pyodide, the same five refusals the README shows, a run-again button, and one line to install it for real. Any scenario the browser cannot run says so by name. | *try ctrlrun* | -| `docs/study/does-your-framework-double-execute` | The framework-probe results, rendered from `research/framework-probe/results/*.json` by script; *No published results yet* until a file exists. Behaviour, not quality. | *does langgraph retry tool calls* · *agent framework double execution study* | -| `docs/verify/get-the-badge` | The two-minute version of adding the verified badge: the workflow, what *declared guarantees pass* means, what N/A means. No gallery until a repo carries it. | *ctrlrun verified badge* | - ---- - -## What was read, and what was decided - -Read on **2026-09-06** unless stated. Everything below was checked against the source that -day; nothing here is from memory. - -### (a) Mintlify's current configuration format - -- **`docs.json` replaced `mint.json`.** Mintlify's blog post *Refactoring mint.json into - docs.json* (7 February 2025) describes the change: navigation used to be spread across - `navigation`, `tabs`, `anchors` and `versions`; in `docs.json` it is one recursive - `navigation` object. The settings page states `mint.json` is deprecated and the CLI converts - it. — <https://www.mintlify.com/blog/refactoring-mint-json-into-docs-json>, - <https://www.mintlify.com/docs/organize/settings> -- **Required top-level fields:** `name`, `theme`, `colors.primary`, `navigation`. Optional: - `logo`, `favicon`, `navbar`, `footer`, `banner`, `redirects` (entries of `source`, - `destination`, `permanent`), `seo` (`metatags`, `indexing`), `search`, `integrations`, `api` - (OpenAPI and AsyncAPI), `fonts`, `styling`. `$schema` is recommended for editor validation, - and a `docs.json` may be split with `$ref`. — <https://www.mintlify.com/docs/organize/settings> -- **Navigation divisions:** `pages`, `groups`, `tabs`, `anchors`, `dropdowns`, `products`, - `versions`, `languages`, nesting arbitrarily. A group is `{group, pages, icon?, tag?, root?, - expanded?}`; a tab is `{tab, icon?, pages | groups | menu | href}`; `global.anchors` holds - persistent external links. Pages left out of `navigation` are hidden but reachable. — - <https://www.mintlify.com/docs/organize/navigation> -- **Page frontmatter:** `title`, `description`, `sidebarTitle`, `icon`, `iconType`, `tag`, - `mode`, `url`, `keywords`, `noindex`, plus any meta tag as a quoted key - (`"og:image": …`, `"twitter:card": …`). Global defaults live in `seo.metatags`; `canonical` - can be set there. `sitemap.xml` and `robots.txt` are generated. — - <https://www.mintlify.com/docs/organize/pages>, <https://www.mintlify.com/docs/optimize/seo> -- **Components** the pages will use: `Card` and `Columns` (`cols` 1–4), `Steps`/`Step`, - `Accordion`, `Tabs`, callouts, `CodeGroup`, `Frame`, `Expandable`, fields, `Update`, - `Tooltip`. `Columns` is the current name for the card grid; the generator in this PR emits - it. — <https://www.mintlify.com/docs/components/cards>, - <https://www.mintlify.com/docs/components/steps> -- **AI surfaces are automatic:** `/llms.txt` and `/llms-full.txt` (also under `/.well-known/`), - a Markdown copy of every page at its URL with `.md` appended, `Link` and `X-Llms-Txt` HTTP - headers, and MCP server discovery at `/.well-known/mcp/server-card.json`. Oversized indexes - split under `/_llms/`. — <https://www.mintlify.com/docs/ai/llmstxt> -- **Monorepo deployment:** dashboard → Git Settings → *Set up as monorepo* → path `/docs`, no - trailing slash; one `docs.json` per deployment. — <https://www.mintlify.com/docs/deploy/monorepo> -- **Local preview:** the CLI package is `mint` (`npm i -g mint`, Node 20.17+), `mint dev` to - preview, `mint update` to upgrade. — <https://www.mintlify.com/docs/installation> - -### (b) Python API reference: no native support; generate MDX with griffe - -Mintlify's API reference support is OpenAPI and AsyncAPI, and the playground page names no -other source (<https://www.mintlify.com/docs/api-playground/overview>). The request for -docstring-generated pages, Mintlify discussion #1639, had no Mintlify response and only -community workarounds as of December 2025 -(<https://github.com/orgs/mintlify/discussions/1639>). - -**Decision: a script of this repository's own, `tools/docs_audit/render_api.py` (session 3), -loads the package with griffe and emits one MDX page per frozen public name into -`docs/reference/api/`.** Reasons: - -- griffe parses Google-style docstrings into a data model with named sections (arguments, - raises, returns, examples), which is what the Reference page needs to turn into fields; it - is the extractor behind mkdocstrings, so the docstring conventions it wants are the common - ones. — <https://mkdocstrings.github.io/griffe/> -- pdoc renders HTML with its own templates; its output is a site, not a set of fragments, and - bending it to `docs.json` navigation is more work than emitting MDX from a data model. -- griffe2md exists but renders to plain Markdown for MkDocs; the Reference pages want - Mintlify's field components and frontmatter, so the last mile is ours either way. -- A test asserts every frozen public name has a docstring and a page, so the generator cannot - silently skip one. - -griffe is a documentation-build dependency and goes in the `dev` extra, never in core; the -kernel's dependency rule is unchanged. - -### (c) How three infrastructure docs sites are organised - -Top-level navigation only, read 2026-09-06. - -| Site | Top level | -|---|---| -| Temporal (<https://docs.temporal.io/>) | Quickstart · Developer guide · Production deployment · Cloud · Community and learning. Also `llms.txt` and raw Markdown per page. | -| Cerbos (<https://docs.cerbos.dev/cerbos/latest/index.html>) | Platform · Getting started (what it is, quickstart, tutorial, installation) · API · Policies (one page per policy concept, plus best practices and debugging) · Configuration · Deployment patterns · CLI · Recipes · Release notes and reference | -| Stripe (<https://docs.stripe.com/>) | Start here by use case · Browse by product · Development environment · Agent skills and a terminal reader for the docs | - -What carried into the tree above: a task-first *Get started* separate from concept pages -(all three); a *Recipes* / cookbook section distinct from guides and from reference (Cerbos, -Stripe); a CLI page of its own (Cerbos); one page per policy concept rather than one long -policy page (Cerbos); and the docs being readable by an agent — `llms.txt`, per-page Markdown, -an agent-skills entry point — treated as a feature on the front page (all three). - -### (d) What generative engine optimisation means for a docs site in 2026 - -Two sources with opposite emphases, and the tree above follows both: - -- **Google's *AI features and your website* guide** (last updated 10 July 2026) says the - fundamentals are what matter: unique, people-first content with clear structure; crawlable, - indexable pages with good page experience and semantic HTML; and that `llms.txt`, content - chunking, special writing styles and extra structured data are *not* needed for Google's - generative features. — - <https://developers.google.com/search/docs/fundamentals/ai-optimization-guide> -- **LLMrefs' GEO guide** (undated, read 2026-09-06) gives the practices that help pages get - cited by assistants: lead each section with a direct answer, keep paragraphs to two or three - sentences, keep entity names consistent, use lists and comparison tables, cite sources and - name statistics, and refresh important pages. — <https://llmrefs.com/generative-engine-optimization> -- Mintlify's own position, for the assistants that do read them: `llms.txt`, `llms-full.txt` - and an MCP server are generated for every site. — <https://www.mintlify.com/docs/ai/llmstxt> - -What this means concretely for these pages, and what `docs/STYLE.md` enforces: **answer-first -first paragraphs** and one **definitional sentence** per Concepts page, written for a human; -**consistent entity naming** (CTRLRun, effect key, action hash, AMBIGUOUS); **comparison -tables** on every Compare page; **FAQ structured data** on the FAQ page; quotable, plain -claims with a `CLAIMS.md` row behind each; and the generated `llms.txt` left to Mintlify. What -it does not mean: keyword density, chunked pages, or a second writing style for machines. - -## Next - -- `docs/STYLE.md` — the rules every page follows. -- `docs/capabilities.yaml` — the single source the capability tables are rendered from. -- `tools/docs_audit/` — the three checks and the generator. diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index f48f8d9..0000000 --- a/docs/README.md +++ /dev/null @@ -1,60 +0,0 @@ -# The Mintlify website - -One Mintlify project, deployed from this repository's `/docs` directory. - -- `index.mdx` serves `/`: the product homepage, the hallucinated-refund example, the execution boundary and its four rules, and the integration entry point. -- `try.mdx` serves `/try`: the interactive scenario explorer. Controls and a decision come first; the agent/boundary/system context sits in a disclosure below them. -- `docs.mdx` serves `/docs`: the preserved technical overview. -- `docs/` contains all technical pages, published under `/docs/...`. The three technical navigation tabs retain their full sidebar structure. -- `risk-check.mdx` and `protect-my-agent.mdx` are custom-mode product pages. -- `snippets/` holds small client-side React components. Mintlify injects React hooks; do not add cross-snippet imports or third-party browser dependencies. -- `style.css` scopes product styling to `.cr-site`; documentation keeps the native Mintlify layout. -- `docs.json` defines navigation, metadata, and permanent redirects from the former technical URLs. -- `images/` contains public assets. `assets/` contains source assets and browser verification scripts. -- `capabilities.yaml` and `generated/` retain their source/render workflow. Generators now target technical pages in `docs/`. - -## Preview and validate - -```bash -cd docs -mint dev -``` - -The preview runs at `http://localhost:3000`. From the repository root: - -```bash -python tools/docs_audit/snippets.py -python tools/docs_audit/lint.py -python tools/docs_audit/links.py -python tools/docs_audit/render_capabilities.py --check -node --test integrations/website-form/review.test.mjs -NODE_PATH="$(npm root -g)" node docs/assets/verify-website.cjs -cd docs && mint validate && mint broken-links -``` - -The browser harness requires Playwright and the preview server. It covers the demo state transitions, keyboard picker, mobile overflow, risk scoring, form validation, mocked email failure/retry/success, documentation sidebar, and key canonical URLs. It never sends an email. Set `WEBSITE_BASE_URL` to the hosted Mintlify preview URL to run the same checks against a deployment. Hosted checks also catch redirect normalization that differs from the local server. Do not add `/index` → `/` or `/docs/index` → `/docs` redirects: Mintlify normalizes those sources to their destinations, causing self-redirects. - -## Scenario and conversion behavior - -The Medical Affairs workbench uses `medical-workbench.js`, styles scoped to -`#cr-medical-workbench`, and `examples/medical_workbench.py`. Keep its embedded `MODULE` -equivalent to the Python source; `tests/test_medical_workbench.py` checks the copy. The browser -loads CTRLRun 0.6.1 on demand. Evidence and synthesis are synthetic; release decisions and -receipts execute in Python. `assets/verify-medical-workbench.cjs` exports a Playwright check -function accepting a page and an optional preview base URL. It exercises browser Python, both -downloads, error recovery and all six stages at three viewport widths. The letter demo remains -independent. - -The scenario explorer contains 48 domains and 238 actions. All rules are illustrative, client-side simulations. The original Python runtime demos remain at `/docs/try-it` and `/docs/demos/medical-affairs`; they load their runtime only when invoked. - -The risk check stores no answers and sends no form data until the visitor submits an architecture review. Its result distinguishes indicated patterns from unknown answers and explains the scoring rule. - -The review form uses the private Vercel Function in `../integrations/website-form`, which calls Resend. Work email is required for follow-up. The recipient is fixed server-side. No API key appears in the Mintlify files. A mailto/copy fallback remains available. Browser retries reuse a request ID; success appears only after the server confirms Resend accepted the message. - -`website-events.js` and the components emit `ctrlrun:conversion` custom events for page visits, CTA clicks, selections, scenario outcomes, risk-check completion, and review submission. No analytics provider was configured, so these are integration hooks, not stored analytics. A consent-aware listener can connect an existing provider later. Event payloads exclude contact details and free-text form contents. - -## Deployment - -The Mintlify GitHub App deploys the website from `main`, with content directory `/docs`. The redesign stays on its review branch until merged. The Vercel project serves only the form API; it does not host a second frontend. - -Keep the `/mcp` platform endpoint unchanged. The `/docs/mcp/...` pages document MCP integrations; they are separate from Mintlify's generated documentation search endpoint. diff --git a/docs/SEO.md b/docs/SEO.md deleted file mode 100644 index e141e8b..0000000 --- a/docs/SEO.md +++ /dev/null @@ -1,155 +0,0 @@ -# Search, per page - -One line per page: the query it should answer, and the sentence written to answer it. That -sentence is the page's first paragraph or its definitional opener, so a search snippet, an -assistant's quote and a reader's first impression are the same words. - -The rules this file follows are in `docs/STYLE.md`; the tree is `docs/IA.md`. What is enforced -by tests lives in `tests/test_docs_site.py` and `tests/test_docs_seo.py`. - -## What is enforced - -| Rule | Where | -|---|---| -| A `title` at most 60 characters, and a `description` at most 155 | `test_every_title_and_description_fits_a_search_result` | -| One H1 per page, the frontmatter title; no second H1 in the body | `test_no_page_has_a_second_h1` | -| Every Concepts page opens with a standalone definitional sentence | `test_every_concepts_page_opens_with_a_definitional_sentence` | -| Every page links to Why and to Get started | `test_every_page_links_to_why_and_to_get_started_or_is_one_of_them` | -| Every page ends with Next links | `test_every_page_ends_with_next_links` | -| The FAQ carries FAQ structured data whose questions match the page | `test_the_faq_structured_data_matches_the_page` | -| Consistent entity naming: CTRLRun, effect key, action hash, AMBIGUOUS | the forbidden-words lint and review | - -`llms.txt`, `llms-full.txt`, `sitemap.xml` and `robots.txt` are generated by Mintlify for every -site; nothing here writes them. The Open Graph defaults and the social image are set once in -`docs.json` under `seo.metatags`, and the image URL is **absolute on this domain** — a relative -one resolves against the deployment origin, so every share card pointed at the `mintlify.app` -subdomain until the launch audit fetched one and read it. - -**Nothing site-wide sets `canonical` or `og:url`.** Both were there, and a site-wide metatag is -stamped on every page, so all 180 of them declared themselves duplicates of the home page — an -instruction to a search engine to index one and drop the rest. Mintlify emits a per-page -canonical of its own, which is the correct one. If a page ever needs an override it belongs in -that page's frontmatter, never here. - -## Per page - -| Page | Target query | The sentence that answers it | -|---|---|---| -| `docs` | ctrlrun · AI agent safety layer | The last check before an AI agent does something it can't undo. | -| `docs/why` | why do AI agents double execute · AI agent consequential actions | Everyone is rushing to ship AI agents without thinking about consequences. | -| `docs/not-only-agents` | celery task retried twice · webhook delivered twice duplicate · retry safe background job python | Every page on this site says agent, and the failure underneath them does not require one. | -| `docs/get-started/install` | install ctrlrun | `pip install ctrlrun` installs the kernel and exactly two dependencies, `pyyaml` and `click`. | -| `docs/get-started/quickstart` | protect an AI agent action python · ctrlrun quickstart | In sixty seconds you will write a policy, protect a refund function, and watch a mutated approval be refused. | -| `docs/get-started/three-ways-in` | do I need a ctrlrun adapter · ctrlrun langgraph | There are three ways to put CTRLRun in front of a consequential action, and only one of them is an adapter. | -| `docs/get-started/choosing` | ctrlrun decorator vs gateway | In-process Python takes the decorator, tools behind MCP take the gateway, and a framework with its own approval UI takes an adapter. | -| `docs/production/index` | is ctrlrun production ready | SQLite is the default and is production-grade on one host; Postgres is for many hosts. | -| `docs/production/postgres` | ctrlrun sqlite vs postgres | Choose by how many machines write to the store, not by how serious you are. | -| `docs/production/how-reservation-works` | lost commit ambiguous outcome | An exception before COMMIT is a failed write to retry; one during COMMIT is unknown and is re-read. | -| `docs/production/migrations` | ctrlrun schema migration | Migrations run at open, forward only, with no flag that opens a database un-migrated. | -| `docs/production/recovery` | agent crashed mid action | A restarted process repairs nothing and cannot know the holder is dead. | -| `docs/production/receipt-integrity` | verify receipt chain | Run ctrlrun receipts --verify-chain and read the six names it can report. | -| `docs/production/soak` | ctrlrun soak test results | One published run, its measured duration, and the exit criterion it does not meet. | -| `docs/production/operations` | ctrlrun monitoring | Watch how many effects are sitting in an unknown outcome that nobody has answered. | -| `docs/mcp/overview` | MCP gateway human approval | CTRLRun works with MCP in four ways. | -| `docs/mcp/gateway-in-5-minutes` | protect MCP server · MCP tool call approval | Point the MCP client at `ctrlrun gateway` instead of the tool server. | -| `docs/mcp/approve-from-your-assistant` | approve MCP tool call from an assistant · MCP human approval server | Run `ctrlrun mcp-operator` and answer a pending approval from an MCP client, under your own name. | -| `docs/mcp/use-the-docs-from-your-editor` | ctrlrun docs mcp server | This documentation is an MCP server, hosted with the site. | -| `docs/concepts/action-and-hash` | canonical action hash AI agent | An action is one proposed operation, normalized. | -| `docs/concepts/decisions` | AI agent action policy allow approve deny | A decision is what the policy says may happen to one action. | -| `docs/concepts/approval-binding` | approval bound to action · approval mutation AI agent | An approval is a human's yes to one exact action, bound to that action's hash. | -| `docs/concepts/effect-keys` | idempotency key AI agent · prevent duplicate tool execution | An effect key is the name of a consequence in the real world. | -| `docs/concepts/outcomes-and-ambiguous` | agent tool call timeout · double execution AI agent retry | An outcome is what CTRLRun knows about the consequence, and there are three. | -| `docs/concepts/receipts-and-evidence` | AI agent audit trail receipts | A receipt is the portable JSON record of one action that reached the executor. | -| `docs/concepts/authority-and-delegation` | AI agent authorization delegation · least privilege AI agents | Authority answers the question the policy cannot: may this principal propose this action at all? | -| `docs/concepts/observe-mode` | AI agent policy shadow mode | Observe mode is one top-level line that evaluates every action and executes it regardless. | -| `docs/concepts/fail-closed` | fail closed AI agent | Fail closed means that anything CTRLRun cannot decide, it denies. | -| `docs/guides/protect-a-function` | protect python function approval | Decorate the function that acts, name the action and the consequence. | -| `docs/guides/gateway-in-front-of-mcp` | MCP gateway policy | Point the MCP client at `ctrlrun gateway` instead of the tool server. | -| `docs/guides/approvals-in-slack` | slack approval AI agent | `WebhookApprovalProvider` sends one signed POST to a URL you own for every approval request. | -| `docs/guides/resolve-an-ambiguous-effect` | ctrlrun resolve ambiguous | An `AMBIGUOUS` effect is one whose executor raised something other than `NotExecuted`. | -| `docs/guides/reconcile-automatically` | reconcile agent action stripe kubernetes | A `reconcile` hook asks the remote what happened to an effect key. | -| `docs/guides/observe-to-enforce` | roll out agent policy safely | Start with `mode: observe`: every action is decided exactly as enforce mode would decide it. | -| `docs/guides/run-on-postgres` | ctrlrun postgres | Use Postgres when workers on more than one host must share one store. | -| `docs/guides/verify-in-ci` | verify agent safety configuration CI | `ctrlrun verify` runs the kernel's own failure scenarios against your policy. | -| `docs/guides/export-to-opentelemetry` | opentelemetry AI agent actions | `OTelEventSink` turns every action into one OpenTelemetry span. | -| `docs/guides/langgraph-adapter` | langgraph interrupt human approval | `ctrlrun-langgraph` makes an `approve` decision surface as a LangGraph `interrupt()`. | -| `docs/guides/openai-agents-adapter` | openai agents sdk tool approval | `ctrlrun-openai-agents` makes an `approve` decision stop the run with the SDK's own `ToolApprovalItem`. | -| `docs/cookbook/index` | AI agent policy examples | Each recipe is a situation an agent is put in. | -| `docs/cookbook/refund-agent` | AI agent refund approval tiers | A support agent issues refunds: small ones run, larger ones wait for a human. | -| `docs/cookbook/payout-maker-checker` | maker checker AI agent payout | A payout agent acts on a delegated slice; above the desk limit a second person approves. | -| `docs/cookbook/deploy-agent` | AI agent kubernetes deploy approval | Restart runs, production apply waits for a human, namespace delete is refused. | -| `docs/cookbook/database-migration-agent` | AI agent database migration safety | Staging migrations run; every production migration waits; a dropped connection stays unknown. | -| `docs/cookbook/iam-agent` | AI agent grant role approval | Read roles run on their own, admin is refused, and an approval for one role is not another. | -| `docs/cookbook/credential-rotation-agent` | AI agent rotate api key safely | Minting a key runs; revoking the old one waits; a lost mint is never repeated. | -| `docs/cookbook/crm-update-agent` | AI agent update crm record | A field update runs, a merge waits for a human, a delete is refused. | -| `docs/cookbook/data-deletion-agent` | AI agent data deletion retention | Past retention purges run, inside retention waits, legal hold is refused. | -| `docs/cookbook/outbound-email-agent` | AI agent send email approval | Internal mail goes; external mail waits, bound to the exact recipient. | -| `docs/cookbook/customer-notification-agent` | AI agent notify customers once | One effect per customer per incident, so a retry or a second worker sends once. | -| `docs/cookbook/manager-and-worker` | multi agent delegation bounded authority | A manager delegates a narrower slice; the worker cannot exceed or widen it. | -| `docs/cookbook/protect-an-mcp-server` | protect existing MCP server | Name the tools in a policy and put the gateway between the agent and the server. | -| `docs/cookbook/langgraph-interrupt` | langgraph approval refund | The approval surfaces as LangGraph's own interrupt and the resumption carries the arguments. | -| `docs/cookbook/openai-agents-tool-approval` | openai agents sdk approval refund | The run stops with the SDK's own tool-approval interruption. | -| `docs/cookbook/slack-approvals` | slack approve AI agent action | One signed POST out, a signed answer back, and the same grant call the CLI makes. | -| `docs/cookbook/receipts-to-opentelemetry` | AI agent actions in traces | One span per action, one event per step, argument values kept out. | -| `docs/cookbook/observe-then-enforce` | test agent policy without blocking | Everything executes and the receipts record what enforcement would have blocked. | -| `docs/cookbook/resolve-an-ambiguous-effect` | resolve unknown agent action outcome | Ask the remote, then record the answer with ctrlrun resolve. | -| `docs/cookbook/reconcile-against-the-remote` | reconcile agent effect stripe kubernetes | A hook asks the remote and moves the record only the way the answer points. | -| `docs/cookbook/verify-in-github-actions` | verify agent policy CI | One workflow step proves the declared guarantees still hold against your policy. | -| `docs/cookbook/sqlite-to-postgres` | share agent state across hosts | One line changes: the store, and the guarantee now holds across hosts. | -| `docs/compare/framework-hitl` | langgraph human in the loop limitations | A framework's human-in-the-loop primitive is the right place for a human to answer, and CTRLRun uses it rather than replacing it. | -| `docs/compare/guardrail-libraries` | AI guardrails vs execution control | A guardrail library reads text; CTRLRun sits one layer down, where a decision becomes an effect. | -| `docs/compare/governance-toolkits` | AI agent oversight vs enforcement | A toolkit describes; CTRLRun refuses. | -| `docs/compare/durable-workflows` | temporal vs ctrlrun · durable execution agents | One drives work forward; the other decides whether the work may happen. | -| `docs/compare/idempotency-keys` | idempotency keys AI agents · stripe idempotency vs | An idempotency key deduplicates at one API; an effect key deduplicates at the agent, across every API it touches. | -| `docs/demos/index` | ctrlrun demo online · try agent safety library | Every demo here runs real Python in your tab. | -| `docs/demos/medical-affairs` | AI medical information letter review · agent citation drift · medical affairs LLM harness | A harness that retrieves biomedical evidence, reasons over it, cites it and drafts a reply is four problems, and CTRLRun solves none of them. | -| `docs/try-it` | try ctrlrun in browser · ctrlrun demo online | Press the button and `ctrlrun demo` runs in this tab: real Python, the released wheel. | -| `docs/verify/get-the-badge` | ctrlrun verified badge | Two minutes, three steps: verify on every push, publish the badge JSON, point Shields at it. | -| `docs/study/does-your-framework-double-execute` | does langgraph retry tool calls · agent framework double execution | When a remote commits a refund and the reply is lost, what does an agent framework do? | -| `docs/faq` | ctrlrun faq, and each question verbatim | The twelve questions that come up first, answered in under eighty words each. | -| `docs/security/receipt-chain` | tamper evident audit log AI agent | The receipt chain is a hash chain over the evidence log. | -| `docs/security/verify-guarantees` | ctrlrun verify guarantees | `ctrlrun verify` runs eleven guarantees against the configuration in front of it. | -| `docs/security/disclosure` | ctrlrun security report | Report vulnerabilities privately to contact@arpanghoshal.com. | -| `docs/how-this-is-built` | is ctrlrun trustworthy · how ctrlrun is tested | CTRLRun is built specification-first, every requirement in it is mutation-tested. | -| `docs/reference/policy-yaml` | ctrlrun.yaml reference · ctrlrun policy schema | `ctrlrun.yaml` is one document: a `schema`, an `actions` map, and from v3 the `mode`, `environment` and `docs/authority` keys. | -| `docs/reference/authority-yaml` | ctrlrun authority grants yaml | The `authority:` section says which principal may propose which action. | -| `docs/reference/cli` | ctrlrun cli | The `ctrlrun` command reads the policy in the working directory and the store beside it. | -| `docs/reference/errors` | ctrlrun ApprovalMismatch · ctrlrun AmbiguousEffect | Every refusal is an exception of its own, raised as itself before the executor runs. | -| `docs/reference/exit-codes` | ctrlrun verify exit code | Every `ctrlrun` command exits 0 when it did what it was asked, 1 when CTRLRun refused, 2 on a usage error. | -| `docs/reference/receipt-and-event-schemas` | ctrlrun receipt json schema | A receipt is one executed action; an event is one step on the way. | -| `docs/reference/api/index` | ctrlrun Control · ctrlrun protect decorator | Every frozen public name of the package and its extras, one page each. | -| `docs/architecture/specifications` | ctrlrun specification | Every version of CTRLRun was a specification before it was code. | -| `docs/ARCHITECTURE` | ctrlrun architecture | The boundary CTRLRun owns, and the six steps every protected call takes. | -| `docs/THREAT_MODEL` | ctrlrun threat model | What CTRLRun defends against, and what it deliberately does not. | -| `docs/how-this-is-built` | is ctrlrun trustworthy · how ctrlrun is tested | Specification first, every requirement mutation-tested, every claim mapped to a test. | -| `docs/verify` | ctrlrun verify guarantees badge | Running the guarantee catalogue against your own configuration. | -| `docs/adapters` | ctrlrun adapter langgraph openai | The three ways in, and when you do not need an adapter. | -| `docs/authority` | ctrlrun authority delegation grants | Grants, containment and the omission rule, in plain language. | -| `docs/postgres` | ctrlrun postgres store | Connection strings, what to grant, migrations, and failover. | -| `docs/CLAIMS` | ctrlrun claims tests | Every README sentence mapped to the code and the test that proves it. | -| `docs/ROADMAP` | ctrlrun roadmap v1.0 | What each version asked and answered, and what is not on the list. | -| `docs/ACS` | agent control standard ctrlrun | What was read, what maps, and where the standard is silent. | -| `docs/OWASP-AGENTIC-TOP10` | OWASP agentic top 10 mapping | A reading of somebody else's taxonomy against the guarantees CTRLRun tests. | - -## The words that appear once - -`idempotency` on `docs/concepts/effect-keys` and `docs/compare/idempotency-keys`; `human-in-the-loop` on -`docs/get-started/three-ways-in` and `docs/compare/framework-hitl`; `MCP gateway` on `docs/mcp/overview`; -`double execution` on `docs/concepts/outcomes-and-ambiguous`; `AI agent safety` on `docs`. Anywhere -else they are noise. - -## What is deliberately not done - -No keyword density targets, no repeated phrases across pages, no content written for a crawler -rather than a reader, and no `llms.txt` hand-maintained beside the generated one. Google's own -guidance (July 2026) is that the fundamentals are what matter and that extra machine files are -not needed; the assistants that do read `llms.txt` get Mintlify's. - -## Product pages - -| Page | Search intent | -|---|---| -| `index` | Execution safety for AI agents | -| `try` | try AI agent guardrails demo · what stops an agent action | -| `risk-check` | AI agent execution risk assessment | -| `protect-my-agent` | AI agent architecture review and integration help | diff --git a/docs/STYLE.md b/docs/STYLE.md deleted file mode 100644 index f1a8489..0000000 --- a/docs/STYLE.md +++ /dev/null @@ -1,105 +0,0 @@ -# Style sheet for the documentation - -Every page on the docs site and every sentence in the README follows this sheet. The audit -tools under `tools/docs_audit/` enforce the parts a machine can check; the rest is what a -reviewer reads for. - -## The page - -- **Answer first.** The first paragraph answers the question the title asks, with no preamble. - That paragraph is what a search snippet, an AI assistant and an impatient engineer read, and - often the only thing they read. -- **One definitional sentence** on every Concepts page, phrased so it stands alone when - quoted: *An effect key is …*. Write it for a person; if it reads badly aloud it reads badly to - a model. -- **At most 900 words**, except Reference pages. A page that needs more is two pages. -- **Code before prose** wherever the code can carry the point. Show the policy, then say what - it does. -- **Every page ends with "Next"**: two or three links to where the reader goes from here. Every - page links to Why and to Get started somewhere in its body or its Next block. -- **Headings are the questions people search.** *What happens on a timeout?* rather than - *Timeouts*. One H1 per page, and it is the title. - -## The sentence - -- **Second person, present tense.** *You declare an effect key* — not *the user will declare*. -- **One idea per paragraph.** Two or three sentences is a paragraph; six is two. -- **No exclamation marks.** No *we're excited*, no *simply*, no *just*, no *easy*. -- **Plain claims.** A sentence either describes what the shipped code does, and has a row in - `docs/docs/CLAIMS.md`, or it is marked *(design)*, or it is cut. -- **Numbers travel with their units.** Amounts are integer minor units and the page says so - the first time one appears. - -## The words - -- **CTRLRun**, always in that capitalisation. Never *Ctrlrun*, *ctrlrun* in prose, or *CTRL Run*. - In code, the package and command are `ctrlrun`. -- **The fixed copy** is fixed. The tagline, the principle, the category line, the promise and - the opener are quoted from `docs/IA.md` and are not paraphrased. -- **The forbidden list** is enforced by `tools/docs_audit/lint.py`. In a heading, a title, a - description or a hero line: never *runtime control*, *governance*, *guardrails*, - *compliant*, *secure* as a bare adjective, *exactly-once*, *transaction*. Anywhere at all: - never a compliance or standards claim, never *pack* or *sector*, never a regulation named as - supported, never social proof that does not exist. -- **The definitional words appear once each**, in the sentence written for search: - *idempotency*, *human-in-the-loop*, *MCP gateway*, *double execution*, *AI agent safety*. -- **Outcomes are spelled as the code spells them**: `COMMITTED`, `FAILED`, `AMBIGUOUS`. - Decisions likewise: `allow`, `approve`, `deny`. - -## The examples - -- **Three domains minimum on every list of examples**, from: money, infrastructure, - permissions, records, communications. The refund is the first example because everyone - understands it. It is never the only one. -- **Real names, invented values.** `stripe.refund`, `k8s.delete_namespace`, `iam.grant_role`, - `crm.update_record`, `email.send`. Amounts, ids and addresses are obviously invented. -- **The share unit is a failure.** An example shows an agent doing something wrong and CTRLRun - refusing. A list of features is not an example. - -## The code blocks - -- **A block either runs or makes no promise.** A fence marked `runnable` is executed offline by - `tools/docs_audit/snippets.py` on every CI run. A block without the marker is illustration, - and it says so in the prose beside it or elides visibly (`...`). -- **The marker is a word on the fence's info string**: ```` ```python runnable ````, - ```` ```bash runnable ````, ```` ```yaml runnable ````. -- **All runnable blocks on one page share one temporary directory**, in page order. A - `yaml runnable` block is validated by the real loaders and then written as `ctrlrun.yaml`, - so a later block can read it. Add `file=name.yaml` to the info string to write it elsewhere. -- **A `python runnable` block is its own script.** Add `continue` to run it appended to the - page's previous runnable Python blocks, so a function defined above can be called below. -- **Bash runs under `-euo pipefail`** with the checkout's `ctrlrun` on `PATH`. A line that - needs the network — `pip install`, a webhook, a real remote — is not runnable and is not - marked. -- **Expected output is shown as `text` or `console`**, never marked runnable, and quoted from a - real run. Where a test already quotes it (the demo, the verify report), the page quotes the - same lines. - -## Links - -- Internal links are relative paths or root-relative docs paths, never absolute GitHub URLs - unless the target is a file that has no page. `tools/docs_audit/links.py` resolves every one, - anchors included. -- A link's text says where it goes: *the effect-keys concept*, not *here*. - -## What the tools check - -| Tool | Checks | Runs | -|---|---|---| -| `snippets.py` | every `runnable` block executes offline and exits 0 | CI, `docs` job | -| `lint.py` | the forbidden words, in their scope, minus `lint-allowlist.txt` | CI, `docs` job | -| `links.py` | internal links and anchors resolve | CI, `docs` job | -| `render_capabilities.py --check` | every rendered capability table matches `capabilities.yaml` | CI, and `tests/test_docs_audit.py` | - -Run them by hand from the repository root: - -```bash -python tools/docs_audit/snippets.py -python tools/docs_audit/lint.py -python tools/docs_audit/links.py -python tools/docs_audit/render_capabilities.py --check -``` - -## Product experience - -The `/`, `/risk-check`, and `/protect-my-agent` pages use Mintlify custom mode. The product brief governs their concise copy and layout; the documentation-only Next section, fixed-copy, and three-domain-list rules do not apply to these pages. Technical pages under `/docs` retain the rules above. diff --git a/docs/assets/browser-demo.verified.json b/docs/assets/browser-demo.verified.json deleted file mode 100644 index 806f832..0000000 --- a/docs/assets/browser-demo.verified.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "date": "2026-09-07", - "pyodide": "314.0.6", - "python": "3.14.2", - "sqlite": "3.39.0", - "ctrlrun": "0.5.0" -} diff --git a/docs/assets/verify-browser-demo.mjs b/docs/assets/verify-browser-demo.mjs deleted file mode 100644 index 2e9643b..0000000 --- a/docs/assets/verify-browser-demo.mjs +++ /dev/null @@ -1,84 +0,0 @@ -// Does the Try-it page's Python run in Pyodide? The honest test behind docs/docs/try-it.mdx: -// -// npm install pyodide -// node docs/assets/verify-browser-demo.mjs -// -// It runs the page's own Python, read out of docs/try-it.js: the PLAYGROUND module, driven -// through the six steps the page tells the reader to try, and then PROGRAM, which is -// `ctrlrun demo`. It did not always: until 2026-09-06 this file carried its own copy of the -// program, so it verified code the page never ran, and the copy that shipped ended a line on a -// trailing `+` — a SyntaxError, which every reader got instead of the demo. A harness with its -// own copy of the artifact verifies the copy. `tests/test_docs_travelling.py` compiles the demo -// and runs the playground natively on every commit, so that class of break fails in CI without -// Node or the network; this file is what proves both *run under Pyodide*. -// -// Last run 2026-09-07: Pyodide 314.0.6, Python 3.14.2, SQLite 3.39.0, ctrlrun 0.5.0 from PyPI, -// the playground sequence and all five scenarios. `sqlite3` is bundled into Pyodide 314 and -// must NOT be passed to loadPackage, which is the one thing that failed the first time. -import { readFileSync, writeFileSync } from "node:fs"; -import { loadPyodide } from "pyodide"; - -// The page's arrays are JSON by construction, so this is a parse and not an eval: a harness -// that re-implemented the extraction could drift the same way the copy did. -const here = new URL(".", import.meta.url).pathname; -const script = readFileSync(`${here}../try-it.js`, "utf8"); - -function pythonIn(name) { - const body = new RegExp(`var ${name} = \\[(.*?)\\]\\.join`, "s").exec(script); - if (!body) throw new Error(`docs/try-it.js: no ${name} array — the page's Python moved`); - return JSON.parse(`[${body[1]}]`).join("\n"); -} -const PLAYGROUND = pythonIn("PLAYGROUND"); -const PROGRAM = pythonIn("PROGRAM"); -console.log("programs read from docs/try-it.js:", PLAYGROUND.split("\n").length, "+", PROGRAM.split("\n").length, "lines"); - -const pyodide = await loadPyodide(); -console.log("pyodide", pyodide.version, "python", pyodide.runPython("import sys; sys.version")); - -console.log("sqlite3 bundled:", pyodide.runPython("import sqlite3; sqlite3.sqlite_version")); -await pyodide.loadPackage(["micropip", "pyyaml"]); -const micropip = pyodide.pyimport("micropip"); -await micropip.install("ctrlrun"); -const versions = { - date: new Date().toLocaleDateString("en-CA"), // YYYY-MM-DD, local - pyodide: pyodide.version, - python: pyodide.runPython("import platform; platform.python_version()"), - sqlite: pyodide.runPython("import sqlite3; sqlite3.sqlite_version"), - ctrlrun: pyodide.runPython("import importlib.metadata; importlib.metadata.version('ctrlrun')"), -}; -console.log("ctrlrun", versions.ctrlrun); - -// --- the playground: the same calls the page's JavaScript makes, the same sequence the page -// tells the reader to try, and the outcome each step must report. -pyodide.runPython(PLAYGROUND); -function step(request) { - pyodide.globals.set("PLAYGROUND_REQUEST", JSON.stringify(request)); - return JSON.parse(pyodide.runPython("step(PLAYGROUND_REQUEST)")); -} -function expect(label, result, outcome, extra = {}) { - const ok = result.outcome === outcome && Object.entries(extra).every(([k, v]) => result[k] === v); - console.log(`${ok ? "ok " : "FAIL"} ${label}: ${result.outcome}${result.reason ? " (" + result.reason + ")" : ""} remote_calls=${result.remote_calls}`); - if (!ok) throw new Error(`${label}: expected ${outcome} ${JSON.stringify(extra)}, got ${JSON.stringify(result)}`); - return result; -} -expect("1 €500 txn_1", step({ op: "refund", payment_id: "txn_1", amount: 50000, lose_reply: false }), "executed", { remote_calls: 1 }); -const asked = expect("2 €2,000 txn_2", step({ op: "refund", payment_id: "txn_2", amount: 200000, lose_reply: false }), "approval_required", { remote_calls: 0 }); -const granted = step({ op: "approve", request_id: asked.request_id }); -if (granted.approval_id !== asked.request_id) throw new Error("approve did not grant the request"); -console.log("ok 2 human approves", granted.approval_id); -expect("2 €5,000 on that approval", step({ op: "refund", payment_id: "txn_2", amount: 500000, approval_id: asked.request_id }), "approval_mismatch", { reason: "mismatch", remote_calls: 0 }); -expect("2 €2,000 on that approval", step({ op: "refund", payment_id: "txn_2", amount: 200000, approval_id: asked.request_id }), "executed", { remote_calls: 1 }); -expect("3 the approval again", step({ op: "refund", payment_id: "txn_2", amount: 200000, approval_id: asked.request_id }), "approval_mismatch", { reason: "consumed", remote_calls: 1 }); -expect("4 €20,000 txn_3", step({ op: "refund", payment_id: "txn_3", amount: 2000000, lose_reply: false }), "denied", { remote_calls: 0 }); -expect("5 €500 txn_4, reply lost", step({ op: "refund", payment_id: "txn_4", amount: 50000, lose_reply: true }), "reply_lost", { remote_calls: 1 }); -expect("5 retry txn_4", step({ op: "refund", payment_id: "txn_4", amount: 50000, lose_reply: false }), "ambiguous_retry", { remote_calls: 1 }); -expect("6 €500 txn_1 again", step({ op: "refund", payment_id: "txn_1", amount: 50000, lose_reply: false }), "duplicate", { remote_calls: 1 }); - -// --- the demo -const out = pyodide.runPython(PROGRAM); -console.log(out); - -// What ran, for the page to quote and a test to hold it to: the transcript on the page names -// a ctrlrun version and a Python version, and this is the only place those numbers come from. -writeFileSync(`${here}browser-demo.verified.json`, JSON.stringify(versions, null, 2) + "\n"); -console.log("wrote browser-demo.verified.json:", JSON.stringify(versions)); diff --git a/docs/assets/verify-browser-wiring.mjs b/docs/assets/verify-browser-wiring.mjs deleted file mode 100644 index 827c9c0..0000000 --- a/docs/assets/verify-browser-wiring.mjs +++ /dev/null @@ -1,194 +0,0 @@ -// Does docs/try-it.js wire the page's controls when the containers appear *after* the script -// has run? That is the single-page-app case the deployed site hit: Mintlify runs a custom -// script once, when the page becomes interactive, which on this site is before React paints -// the page and never again on a client-side navigation. The button did nothing. -// -// npm install jsdom -// node docs/assets/verify-browser-wiring.mjs -// -// Last run 2026-09-07, every check true. The first is the one that keeps the script harmless: -// Mintlify injects it on every page of the site, so a page without a container must see -// nothing happen at all. The playground checks stub Pyodide with a `step` that answers like the -// module does, so what is verified here is the JavaScript's half — which control builds which -// request, which outcome shows the Approve button, which line the reader gets. -import { readFileSync } from "node:fs"; -import { JSDOM } from "jsdom"; - -const here = new URL(".", import.meta.url).pathname; -const script = readFileSync(`${here}../try-it.js`, "utf8"); - -function fresh() { - const dom = new JSDOM("<!doctype html><html><body><main></main></body></html>", { - runScripts: "outside-only", - pretendToBeVisual: true, - }); - // The page is "interactive" before the container exists, which is the whole point. - dom.window.eval(script); - return dom; -} - -const DEMO = - '<div id="ctrlrun-browser-demo"><button type="button"><span>Run ctrlrun demo</span></button><pre>idle</pre></div>'; -const PLAYGROUND = - '<div id="ctrlrun-playground">' + - '<input type="number" name="amount" value="500">' + - '<input type="text" name="payment_id" value="txn_1">' + - '<input type="checkbox" name="lose_reply">' + - '<button type="button" name="run">Refund</button>' + - '<button type="button" name="approve">Approve</button>' + - "<pre>idle</pre></div>"; - -function mount(dom, html = DEMO) { - dom.window.document.querySelector("main").innerHTML = html; -} - -async function settle(dom) { - await new Promise((resolve) => dom.window.setTimeout(resolve, 50)); -} - -let failures = 0; -function check(label, ok) { - console.log(`${ok ? "ok " : "FAIL"} ${label}`); - if (!ok) failures += 1; -} - -// 1. No container: the script must touch nothing at all. -{ - const dom = fresh(); - await settle(dom); - check("no container, body untouched", dom.window.document.body.innerHTML === "<main></main>"); -} - -// 2. Demo container mounted after the script ran: the button must end up wired, and clicking -// it must reach the loader rather than doing nothing. -{ - const dom = fresh(); - let asked = false; - dom.window.loadPyodide = async () => { - asked = true; - throw new Error("stub: not loading a real runtime here"); - }; - mount(dom); - await settle(dom); - const container = dom.window.document.getElementById("ctrlrun-browser-demo"); - check("demo wired after late mount", container.dataset.wired === "yes"); - - container.querySelector("button").dispatchEvent(new dom.window.MouseEvent("click")); - await settle(dom); - check("demo click reached the loader", asked); - check("demo failure told the reader what to do", - container.querySelector("pre").textContent.includes("pip install ctrlrun && ctrlrun demo")); -} - -// 3. A second mount, as a single-page navigation would produce: wired again. -{ - const dom = fresh(); - mount(dom); - await settle(dom); - dom.window.document.querySelector("main").innerHTML = ""; - await settle(dom); - mount(dom); - await settle(dom); - check("demo re-wired after navigation", - dom.window.document.getElementById("ctrlrun-browser-demo").dataset.wired === "yes"); -} - -// 4. The playground: every control builds the request the module expects, and every outcome -// the module can return has a line. Pyodide is a stub whose `step` answers by shape. -{ - const dom = fresh(); - const requests = []; - const stub = { - loadPackage: async () => undefined, - pyimport: () => ({ install: async () => undefined }), - globals: { set: (name, value) => { stub.request = JSON.parse(value); } }, - runPython(code) { - if (code !== "step(PLAYGROUND_REQUEST)") return undefined; // the module load - const r = stub.request; - requests.push(r); - if (r.op === "approve") return JSON.stringify({ op: "approve", approval_id: r.request_id, action_hash: "sha256:abc" }); - let outcome = "executed"; - if (r.approval_id && r.amount !== 200000) outcome = "approval_mismatch"; - else if (r.amount > 1000000 || r.amount < 0) outcome = "denied"; - else if (r.amount > 100000 && !r.approval_id) outcome = "approval_required"; - else if (r.lose_reply) outcome = "reply_lost"; - else if (r.payment_id === "dup") outcome = "duplicate"; - else if (r.payment_id === "amb") outcome = "ambiguous_retry"; - return JSON.stringify({ op: "refund", outcome, reason: outcome === "approval_mismatch" ? "mismatch" : "rule[2]", request_id: "apr_1", remote_calls: 0, receipt: { decision: "allow", result: "committed" } }); - }, - }; - dom.window.loadPyodide = async () => stub; - mount(dom, PLAYGROUND); - await settle(dom); - const panel = dom.window.document.getElementById("ctrlrun-playground"); - check("playground wired after late mount", panel.dataset.wired === "yes"); - const amount = panel.querySelector('input[name="amount"]'); - const payment = panel.querySelector('input[name="payment_id"]'); - const lose = panel.querySelector('input[name="lose_reply"]'); - const run = panel.querySelector('button[name="run"]'); - const approve = panel.querySelector('button[name="approve"]'); - const log = () => panel.querySelector("pre").textContent; - check("approve hidden until something is pending", approve.hidden === true); - - const click = async (button) => { - button.dispatchEvent(new dom.window.MouseEvent("click")); - await settle(dom); - }; - await click(run); - check("€500 builds a 50000-cent request", requests[0].amount === 50000 && requests[0].payment_id === "txn_1" && requests[0].lose_reply === false); - check("executed line names the receipt", log().includes("executed; receipt committed")); - - amount.value = "2000"; - payment.value = "txn_2"; - await click(run); - check("€2,000 asks a human and shows Approve", log().includes("ApprovalRequired") && approve.hidden === false); - await click(approve); - check("Approve sends op=approve with the request id", requests.at(-1).op === "approve" && requests.at(-1).request_id === "apr_1"); - check("Approve hides itself and names the grant", approve.hidden === true && log().includes("human approves apr_1")); - amount.value = "5000"; - await click(run); - check("€5,000 presents the approval and is refused", requests.at(-1).approval_id === "apr_1" && log().includes("ApprovalMismatch")); - amount.value = "2000"; - await click(run); - check("€2,000 presents the same approval and executes", requests.at(-1).approval_id === "apr_1" && log().includes("executed")); - - payment.value = "txn_3"; - amount.value = "20000"; - await click(run); - check("€20,000 does not present txn_2's approval", requests.at(-1).approval_id === undefined); - check("denied line", log().includes("ActionDenied")); - - payment.value = "txn_4"; - amount.value = "500"; - lose.checked = true; - await click(run); - check("lose the reply is sent", requests.at(-1).lose_reply === true && log().includes("AMBIGUOUS")); - payment.value = "amb"; - lose.checked = false; - await click(run); - check("ambiguous retry line", log().includes("AmbiguousEffect")); - payment.value = "dup"; - await click(run); - check("duplicate line", log().includes("DuplicateEffect")); - amount.value = "abc"; - await click(run); - check("a non-number is refused by the page, not sent", log().includes("enter a number") && requests.at(-1).payment_id === "dup"); -} - -// 5. A playground whose runtime fails to load tells the reader what to do. -{ - const dom = fresh(); - dom.window.loadPyodide = async () => { throw new Error("stub: no runtime"); }; - mount(dom, PLAYGROUND); - await settle(dom); - const panel = dom.window.document.getElementById("ctrlrun-playground"); - panel.querySelector('button[name="run"]').dispatchEvent(new dom.window.MouseEvent("click")); - await settle(dom); - check("playground failure told the reader what to do", - panel.querySelector("pre").textContent.includes("pip install ctrlrun && ctrlrun demo")); -} - -if (failures) { - console.log(`${failures} check(s) failed`); - process.exit(1); -} diff --git a/docs/assets/verify-medical-workbench.cjs b/docs/assets/verify-medical-workbench.cjs deleted file mode 100644 index 7b34198..0000000 --- a/docs/assets/verify-medical-workbench.cjs +++ /dev/null @@ -1,86 +0,0 @@ -/* Browser acceptance checks against a Mintlify preview. All destinations are in memory. */ -module.exports = async function verifyMedicalWorkbench(page, base = 'http://localhost:3000') { - const checks = []; - const errors = []; - page.on('pageerror', error => errors.push(error.message)); - await page.goto(base + '/docs/demos/medical-affairs'); - const root = page.locator('#cr-medical-workbench'); - await root.waitFor(); - const click = async action => { - await root.locator('[data-action="' + action + '"]').click(); - await root.locator('[data-step="0"]').waitFor({ state: 'visible' }); - await page.waitForFunction(() => document.querySelector('#cr-medical-workbench')?.getAttribute('aria-busy') === 'false', null, { timeout: 60000 }); - }; - const stage = async number => { - await root.locator('[data-step="' + number + '"]').click(); - await page.waitForFunction(() => document.querySelector('#cr-medical-workbench')?.getAttribute('aria-busy') === 'false', null, { timeout: 60000 }); - }; - const expect = async (label, text) => { - if (!(await root.innerText()).includes(text)) throw new Error(label + ': missing ' + text); - checks.push(label); - }; - await stage(2); - await root.locator('[data-claim="1"]').click(); - await expect('Claim selection reveals its source passage', 'CLAIM REVIEW · C2'); - await click('toggle-claim'); - await stage(3); - await expect('Unsupported claim fails Python fixture validation', '1 blocking issue'); - await stage(5); - await click('release'); - await expect('Policy denies unsupported release', 'Validation blocked release'); - await expect('Denied release never writes', '0 simulated destination writes'); - await stage(3); - await click('toggle-claim'); - await stage(4); - await root.locator('[data-action="reviewed"]').check(); - await click('approve'); - await expect('Python grants current document approval', 'Version 3 approved'); - await click('edit'); - await stage(5); - await click('release'); - await expect('Real approval hash rejects the changed document', 'Approval mismatch · release blocked'); - await expect('Mismatch never writes', '0 simulated destination writes'); - await click('go-review'); - await root.locator('[data-action="reviewed"]').check(); - await click('approve'); - await stage(5); - await root.locator('[data-action="lose-reply"]').check(); - await click('release'); - await expect('Lost reply is ambiguous', 'Reply lost · outcome AMBIGUOUS'); - await click('release'); - await expect('A used approval cannot authorize a retry', 'Approval already used · retry blocked'); - await expect('Retry leaves destination writes at one', '1 simulated destination writes'); - await click('reconcile'); - await expect('Destination confirmation resolves without a second write', 'Destination confirms receipt'); - for (const action of ['download-brief', 'download-audit']) { - const pending = page.waitForEvent('download'); - await click(action); - const download = await pending; - if (!download.suggestedFilename().startsWith('medical-evidence-')) throw new Error('Missing export'); - checks.push(action + ' produces a local file'); - } - await click('restart'); - await stage(4); - await root.locator('[data-action="reviewed"]').check(); - await click('approve'); - await stage(5); - await click('release'); - await expect('New case supports a normal committed release', 'Reviewed brief released'); - for (const width of [375, 768, 1280]) { - await page.setViewportSize({ width, height: 1000 }); - for (const scheme of ['light', 'dark']) { - await page.emulateMedia({ colorScheme: scheme }); - for (let i = 0; i < 6; i++) { - await stage(i); - if (await page.evaluate(() => document.documentElement.scrollWidth > innerWidth)) throw new Error('Overflow at ' + width + ', step ' + i); - } - checks.push('All six stages fit ' + width + 'px in ' + scheme); - } - } - await page.setViewportSize({ width: 1280, height: 1000 }); - await page.emulateMedia({ colorScheme: 'light' }); - await stage(2); - if (errors.length) throw new Error(errors.join('\n')); - checks.push('No browser runtime errors'); - return checks; -}; diff --git a/docs/assets/verify-website.cjs b/docs/assets/verify-website.cjs deleted file mode 100644 index 981823a..0000000 --- a/docs/assets/verify-website.cjs +++ /dev/null @@ -1,116 +0,0 @@ -/* Run with Mintlify preview on port 3000 and Playwright installed: - * NODE_PATH="$(npm root -g)" node docs/assets/verify-website.cjs - * No emails are opened or sent. No real actions or network-backed demo runs. - */ -module.exports = async function verifyWebsite(page, base = 'http://localhost:3000') { - const checks = []; - const assert = (value, message) => { if (!value) throw new Error(message); checks.push(message); }; - const result = () => page.locator('.cr-result').innerText(); - const choose = value => page.getByLabel('Explore a situation').selectOption(value); - const errors = []; - page.on('pageerror', error => errors.push(error.message)); - await page.setViewportSize({ width: 1280, height: 900 }); - assert((await page.goto(base)).status() === 200, 'Homepage responds without a redirect loop'); - await page.getByRole('button', { name: 'Approve this exact action →' }).waitFor(); - assert(await page.locator('h1').count() === 1, 'Homepage has one H1'); - assert(await page.locator('.cr-footer').isVisible(), 'Final CTAs render in custom mode'); - assert(await page.locator('link[rel=canonical]').getAttribute('href') === 'https://ctrlrun.dev/', 'Homepage canonical points to /'); - await page.evaluate(() => { window.crTestEvents = []; window.addEventListener('ctrlrun:conversion', event => window.crTestEvents.push(event.detail)); }); - await page.getByRole('button', { name: 'Approve this exact action →' }).click(); - assert((await result()).includes('Exact action approved'), 'Approval binds to the exact action'); - await page.getByRole('button', { name: 'Change to $5,000' }).click(); - assert((await result()).includes('Approval was for $500, not $5,000.'), 'Changing $500 to $5,000 is blocked'); - await choose('allowed'); - await page.getByRole('button', { name: 'Execute action →' }).click(); - await page.getByRole('button', { name: 'Retry the same action →' }).click(); - assert((await result()).includes('Duplicate blocked'), 'A completed action cannot execute twice'); - await choose('blocked'); - assert((await result()).includes('does not have permission'), 'Permission denial is explained'); - await choose('uncertain'); - assert((await result()).includes('Outcome uncertain'), 'A lost response does not imply failure'); - await page.getByRole('button', { name: 'Try again →' }).click(); - assert((await result()).includes('Reconciliation required'), 'Unconfirmed retries remain blocked'); - await page.getByRole('button', { name: 'Simulate provider confirming success →' }).click(); - await page.getByRole('button', { name: 'Retry the same action →' }).click(); - assert((await result()).includes('Duplicate blocked'), 'Confirmed success retains duplicate protection'); - await page.getByRole('button', { name: 'Choose your domain Finance' }).click(); - assert(await page.getByRole('option').count() >= 48, 'Industry breadth is discoverable'); - await page.getByRole('combobox', { name: 'Search domains' }).fill('DevOps'); - await page.keyboard.press('Enter'); - assert(await page.getByRole('combobox', { name: /^Choose an action/ }).inputValue() === '0', 'Changing domain resets the selected action'); - assert((await page.locator('.cr-domain-cta').innerText()).includes('production infrastructure'), 'Commercial CTA follows the selected domain'); - await page.getByRole('combobox', { name: /^Choose an action/ }).selectOption('2'); - assert((await page.locator('.cr-request').innerText()).includes('Delete infrastructure'), 'Changing action updates the request'); - await page.getByRole('button', { name: 'Choose your domain DevOps' }).click(); - await page.getByRole('combobox', { name: 'Search domains' }).fill('does-not-exist'); - assert(await page.getByText('No matching domain.').isVisible(), 'Empty search has a useful recovery message'); - await page.keyboard.press('Escape'); - assert(await page.getByRole('button', { name: 'Choose your domain DevOps' }).evaluate(node => node === document.activeElement), 'Escape restores focus to the domain button'); - assert((await page.evaluate(() => window.crTestEvents)).some(event => event.name === 'scenario_completed'), 'Scenario conversion events are emitted'); - for (const width of [375, 768, 1280]) { - await page.setViewportSize({ width, height: 900 }); - assert(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth), 'Homepage fits viewport ' + width); - } - await page.goto(base + '/risk-check'); - await page.getByLabel('Move money', { exact: true }).check(); - for (let index = 0; index < 5; index++) await page.locator('input[name="risk-' + index + '"][value="' + ([2, 4].includes(index) ? 'No' : 'Yes') + '"]').check(); - await page.getByRole('button', { name: 'Check my execution risk →' }).click(); - assert((await page.locator('.cr-risk-result').innerText()).includes('5 execution-risk patterns'), 'All five indicated patterns appear in the risk result'); - assert((await page.locator('.cr-risk-result').innerText()).includes('Execution risk: High'), 'High result has a transparent threshold'); - await page.locator('input[name="risk-0"][value="Unsure"]').check(); - assert(await page.locator('.cr-risk-result').count() === 0, 'Changing an answer clears the stale result'); - for (let index = 0; index < 5; index++) await page.locator('input[name="risk-' + index + '"][value="' + ([2, 4].includes(index) ? 'Yes' : 'No') + '"]').check(); - await page.getByRole('button', { name: 'Check my execution risk →' }).click(); - assert((await page.locator('.cr-risk-result').innerText()).includes('Lower indicated risk'), 'Controls present produce a lower indicated result'); - await page.setViewportSize({ width: 375, height: 812 }); - assert(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth), 'Risk check fits mobile'); - await page.goto(base + '/protect-my-agent?domain=DevOps&risk=High&patterns=4&unknowns=1'); - assert((await page.locator('.cr-domain-context').innerText()).includes('DevOps'), 'Domain context carries into the review form'); - await page.getByRole('button', { name: 'Review my request →' }).click(); - assert(await page.locator('.cr-email-preview').count() === 0, 'Empty form cannot prepare a request'); - await page.getByLabel('Work email', { exact: true }).fill('engineer@example.com'); - await page.getByLabel('Company', { exact: true }).fill('Example test company'); - await page.getByLabel('What does your agent do?').fill('Test deployment workflow'); - await page.getByLabel('Which actions can it execute?').fill('Deploy production releases'); - await page.getByLabel('Retry safety', { exact: true }).check(); - await page.getByRole('button', { name: 'Review my request →' }).click(); - const href = await page.getByRole('link', { name: 'Use my email app instead ↗' }).getAttribute('href'); - assert(href.startsWith('mailto:contact@arpanghoshal.com?'), 'Review handoff uses the approved recipient'); - const body = decodeURIComponent(href.split('&body=')[1]); - assert(body.includes('Example test company') && body.includes('Deploy production releases') && body.includes('Retry safety') && body.includes('High'), 'Email brief includes qualification and risk context'); - assert((await page.locator('.cr-email-preview').innerText()).includes('has not been sent'), 'The form never falsely claims delivery'); - assert(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth), 'Review form fits mobile'); - await page.getByLabel('Company', { exact: true }).fill('Updated test company'); - assert(await page.locator('.cr-email-preview').count() === 0, 'Editing the brief clears the prepared handoff'); - await page.getByRole('button', { name: 'Review my request →' }).click(); - const submissions = []; - await page.route('https://ctrlrun-review-form.vercel.app/api/review', async route => { - submissions.push(route.request().postDataJSON()); - await route.fulfill({ status: submissions.length === 1 ? 502 : 200, contentType: 'application/json', headers: { 'Access-Control-Allow-Origin': '*' }, body: JSON.stringify(submissions.length === 1 ? { error: 'Provider temporarily unavailable.' } : { ok: true, id: 'mock-only-no-email-sent' }) }); - }); - await page.getByRole('button', { name: 'Send review request →' }).click(); - await page.getByRole('alert').filter({ hasText: 'Provider temporarily unavailable.' }).waitFor(); - assert((await page.locator('.cr-email-preview').innerText()).includes('has not been sent'), 'Provider failure never claims success'); - await page.getByRole('button', { name: 'Retry submission →' }).click(); - await page.getByRole('heading', { name: 'Review request submitted.' }).waitFor(); - assert(submissions.length === 2 && submissions[0].requestId === submissions[1].requestId, 'Uncertain email retries reuse the same idempotency key'); - assert(submissions[1].email === 'engineer@example.com', 'Work email is included for replies'); - assert(await page.getByRole('button', { name: 'Send review request →' }).count() === 0, 'Successful submission cannot be double-clicked'); - await page.unroute('https://ctrlrun-review-form.vercel.app/api/review'); - await page.setViewportSize({ width: 1280, height: 900 }); - assert((await page.goto(base + '/docs')).status() === 200, 'Documentation landing responds without a redirect loop'); - await page.locator('#sidebar').waitFor(); - assert(await page.locator('#sidebar').isVisible(), 'Documentation retains the native sidebar'); - assert((await page.locator('main').innerText()).includes('Protect one function'), 'The original technical overview remains at /docs'); - const docLinks = await page.locator('#sidebar a[href]').evaluateAll(nodes => nodes.map(node => node.getAttribute('href')).filter(href => href.startsWith('/'))); - assert(docLinks.every(href => href === '/docs' || href.startsWith('/docs/')), 'Technical sidebar links stay under /docs'); - await page.goto(base + '/docs/get-started/quickstart'); - assert(await page.locator('main h1').count() === 1, 'Quickstart renders at its migrated route'); - assert(await page.locator('link[rel=canonical]').getAttribute('href') === 'https://ctrlrun.dev/docs/get-started/quickstart', 'Documentation canonical uses the migrated route'); - assert(errors.length === 0, 'No browser runtime errors: ' + errors.join('; ')); - return { passed: checks.length, checks }; -}; -if (typeof require !== 'undefined' && require.main === module) { - const { chromium } = require('playwright'); - (async () => { const browser = await chromium.launch(); try { const page = await browser.newPage(); console.log(JSON.stringify(await module.exports(page, process.env.WEBSITE_BASE_URL), null, 2)); } finally { await browser.close(); } })().catch(error => { console.error(error); process.exitCode = 1; }); -} diff --git a/docs/capabilities.yaml b/docs/capabilities.yaml deleted file mode 100644 index 5553bb8..0000000 --- a/docs/capabilities.yaml +++ /dev/null @@ -1,334 +0,0 @@ -# What 0.6 does — the single source the README table, the docs home grid and the PyPI text -# are rendered from. Edit this file; never a rendered copy. -# -# python tools/docs_audit/render_capabilities.py --write # refresh docs/generated/ -# python tools/docs_audit/render_capabilities.py --check # what CI runs -# -# One entry per capability. Fields: -# -# id kebab-case, unique -# name what a reader would call it -# description one sentence, at most 15 words, no exclamation mark -# guarantee true for exactly six entries — the six rows of the README matrix, one per -# group of the verify catalogue (G1–G2, G3–G4, G5+G10, G6–G7, G8–G9, G11) -# ways_in decorator / gateway / adapter: true, false, or a short note for a qualified yes -# since the version that shipped it, v0.1 … v0.6 -# page the docs-site path that owns it (docs/IA.md), without extension -# claim the exact quoted text of the docs/docs/CLAIMS.md row that proves it, or null with a -# claim_note saying which session adds the sentence and its row -# -# Entries are rendered in this order. The six guarantees come first because the README -# matrix is the first table a stranger reads. - -capabilities: - - id: approval-binding - name: Approval binding - description: An approval is bound to the exact action; a mutated or replayed one is refused. - guarantee: true - ways_in: - decorator: true - gateway: true - adapter: prevention or attribution, per adapter - since: v0.1 - page: docs/concepts/approval-binding - claim: An approval is bound to the exact action; a mutated or replayed one is refused. - - - id: one-effect-once - name: One effect, once - description: One logical effect happens at most once, across threads, processes and hosts. - guarantee: true - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.1 - page: docs/concepts/effect-keys - claim: One logical effect happens at most once, across threads, processes and hosts. - - - id: ambiguous-outcomes - name: Unknown is not failed - description: An unknown outcome is AMBIGUOUS, never FAILED, and blocks a blind retry. - guarantee: true - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.1 - page: docs/concepts/outcomes-and-ambiguous - claim: An unknown outcome is AMBIGUOUS, never FAILED, and blocks a blind retry. - - - id: fail-closed - name: Fail closed - description: An unknown action, a missing policy or a missing principal is denied. - guarantee: true - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.1 - page: docs/concepts/fail-closed - claim: An unknown action, a missing policy or a missing principal is denied. - - - id: authority-containment - name: Authority and delegation - description: With authority on, every principal needs a grant, and delegation cannot widen one. - guarantee: true - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.3 - page: docs/concepts/authority-and-delegation - claim: provably a subset of its parent on every dimension, at creation and again at every evaluation - - - id: receipts - name: Receipts - description: Every executed action leaves a portable JSON receipt of who, what and outcome. - guarantee: true - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.1 - page: docs/concepts/receipts-and-evidence - claim: Every executed action leaves a portable JSON receipt - - - id: per-action-policy - name: Per-action policy - description: One YAML file decides allow, approve or deny per action and argument. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.1 - page: docs/reference/policy-yaml - claim: cheap to undo is autonomous, anything that leaves the building needs a human, money is by amount with both ends bound - - - id: operator-cli - name: Operator CLI - description: Approve, deny, resolve, inspect and count from the shell, against any store. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.1 - page: docs/reference/cli - claim: "`ctrlrun approve`, `deny`, `resolve`, `inspect`, `receipts` and `stats` work from the shell against any store" - - - id: mcp-gateway - name: MCP gateway - description: Every guarantee in front of an MCP tool server, with no agent changes. - guarantee: false - ways_in: - decorator: false - gateway: true - adapter: false - since: v0.2 - page: docs/guides/gateway-in-front-of-mcp - claim: No agent changes - - - id: reconciliation - name: Reconciliation - description: A reconcile hook asks the remote what happened and resolves an AMBIGUOUS effect. - guarantee: false - ways_in: - decorator: true - gateway: false - adapter: true - since: v0.2 - page: docs/guides/reconcile-automatically - claim: the only thing besides a human permitted to move a record out of `AMBIGUOUS` - - - id: webhook-approvals - name: Webhook approvals - description: Approval requests go to a webhook, such as Slack, and the answer comes back. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: false - since: v0.2 - page: docs/guides/approvals-in-slack - claim: "`WebhookApprovalProvider` sends an approval request to a webhook, such as Slack, and takes the answer back through the same grant calls" - - - id: otel-export - name: OpenTelemetry export - description: One span per action, one span event per step; argument values are opt-in. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.2 - page: docs/guides/export-to-opentelemetry - claim: one OpenTelemetry span per action, one span event per step - - - id: identity - name: Consumed identity - description: A principal comes from a verified header or JWT; CTRLRun issues nothing. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.3 - page: docs/concepts/authority-and-delegation - claim: CTRLRun issues no credential and defines no identity format - - - id: delegation - name: Runtime delegation - description: A principal narrows its own grant at runtime; one revocation cuts the chain. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.3 - page: docs/concepts/authority-and-delegation - claim: "`ctrlrun revoke` cuts a chain of any depth with one write" - - - id: observe-mode - name: Observe mode - description: Records what enforcement would have blocked, blocks nothing, and counts it. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.3 - page: docs/concepts/observe-mode - claim: "`mode: observe` … records what *would* have been blocked, without blocking anything" - - - id: verify - name: Verify - description: Runs the guarantee catalogue against your policy and store; N/A is not a pass. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.4 - page: docs/guides/verify-in-ci - claim: Not applicable is not a pass - - - id: verify-badge - name: The verified badge - description: A GitHub Action and a badge that means the declared guarantees pass. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.4 - page: docs/verify/get-the-badge - claim: means the **declared guarantees pass** - - - id: framework-adapters - name: Framework adapters - description: An approval routed through the framework's own interrupt; never a second path. - guarantee: false - ways_in: - decorator: false - gateway: false - adapter: true - since: v0.5 - page: docs/get-started/three-ways-in - claim: There is never a second place to say yes - - - id: durable-runtime - name: Runs on one host or many - description: SQLite on one host, Postgres across hosts, the same guarantees either way. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.6 - page: docs/production/index - claim: Runs in production on a single file, or on Postgres across hosts - - - id: postgres - name: Postgres store - description: The same store on Postgres, graded by the suite written for SQLite. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.6 - page: docs/production/postgres - claim: Same `StateStore` protocol, extended by nothing - - - id: migrations - name: Versioned schema - description: Migrations run at open, forward only, and an unknown schema is refused. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.6 - page: docs/production/migrations - claim: migrations are automatic at open, forward-only - - - id: recovery - name: Recovery on restart - description: A dead worker's effect stays AMBIGUOUS until a human or a hook resolves it. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.6 - page: docs/production/recovery - claim: A crashed worker's effect stays `AMBIGUOUS` until a human runs `ctrlrun resolve` or a `reconcile` hook asks the remote what happened - - - id: receipt-chain - name: Receipt chain - description: Each receipt carries the hash of the one before; alteration is detected and named. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.6 - page: docs/security/receipt-chain - claim: Each receipt carries the hash of the one before it - - - id: policy-versioning - name: Policy versioning - description: Every receipt names the policy hash and version that decided it. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.6 - page: docs/concepts/receipts-and-evidence - claim: every receipt records which policy decided it - - - id: control-registry - name: Control registry - description: Name the house controls an action satisfies, and receipts cite them. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.6 - page: docs/reference/policy-yaml - claim: Receipts in a `ctrlrun.policy/v4` document can cite the `controls:` an action satisfies - - - id: data-scope - name: Data scope - description: Label arguments by data class and condition a rule on the labels present. - guarantee: false - ways_in: - decorator: true - gateway: true - adapter: true - since: v0.6 - page: docs/reference/policy-yaml - claim: a rule can condition on the `data:` labels present in an action's arguments diff --git a/docs/docs.json b/docs/docs.json deleted file mode 100644 index 2850cdb..0000000 --- a/docs/docs.json +++ /dev/null @@ -1,1183 +0,0 @@ -{ - "$schema": "https://mintlify.com/docs.json", - "name": "CTRLRun", - "theme": "mint", - "colors": { - "primary": "#B8730A", - "light": "#F5A623", - "dark": "#8A5606" - }, - "logo": { - "light": "/images/wordmark-light.svg", - "dark": "/images/wordmark-dark.svg", - "href": "/" - }, - "favicon": "/images/favicon.svg", - "description": "Execution safety for AI agents. Control consequential actions before they affect real systems.", - "navbar": { - "links": [ - { - "href": "/#how-it-works", - "label": "How it works" - }, - { - "href": "/docs", - "label": "Documentation" - }, - { - "label": "GitHub", - "href": "https://github.com/CTRLRun/ctrlrun" - } - ], - "primary": { - "type": "button", - "label": "Get a safety review", - "href": "/protect-my-agent" - } - }, - "navigation": { - "tabs": [ - { - "tab": "CTRLRun", - "pages": [ - "index", - "try", - "risk-check", - "protect-my-agent" - ] - }, - { - "tab": "Documentation", - "groups": [ - { - "group": "Start", - "pages": [ - "docs", - "docs/why", - "docs/not-only-agents" - ] - }, - { - "group": "Get started", - "pages": [ - "docs/get-started/install", - "docs/get-started/quickstart", - "docs/get-started/three-ways-in", - "docs/get-started/choosing" - ] - }, - { - "group": "Demos", - "pages": [ - "docs/demos/index", - "docs/try-it", - "docs/demos/medical-affairs" - ] - }, - { - "group": "Production", - "pages": [ - "docs/production/index", - "docs/production/postgres", - "docs/postgres", - "docs/production/how-reservation-works", - "docs/production/migrations", - "docs/production/recovery", - "docs/production/receipt-integrity", - "docs/production/soak", - "docs/production/operations" - ] - }, - { - "group": "MCP", - "pages": [ - "docs/mcp/overview", - "docs/mcp/gateway-in-5-minutes", - "docs/mcp/approve-from-your-assistant", - "docs/mcp/use-the-docs-from-your-editor" - ] - }, - { - "group": "Concepts", - "pages": [ - "docs/concepts/action-and-hash", - "docs/concepts/decisions", - "docs/concepts/approval-binding", - "docs/concepts/effect-keys", - "docs/concepts/outcomes-and-ambiguous", - "docs/concepts/receipts-and-evidence", - "docs/concepts/authority-and-delegation", - "docs/concepts/observe-mode", - "docs/concepts/fail-closed" - ] - }, - { - "group": "Guides", - "pages": [ - "docs/guides/protect-a-function", - "docs/guides/gateway-in-front-of-mcp", - "docs/guides/approvals-in-slack", - "docs/guides/resolve-an-ambiguous-effect", - "docs/guides/reconcile-automatically", - "docs/guides/observe-to-enforce", - "docs/guides/run-on-postgres", - "docs/guides/verify-in-ci", - "docs/guides/export-to-opentelemetry", - "docs/guides/langgraph-adapter", - "docs/guides/openai-agents-adapter" - ] - }, - { - "group": "Cookbook", - "pages": [ - "docs/cookbook/index", - { - "group": "Money", - "pages": [ - "docs/cookbook/refund-agent", - "docs/cookbook/payout-maker-checker" - ] - }, - { - "group": "Infrastructure", - "pages": [ - "docs/cookbook/deploy-agent", - "docs/cookbook/database-migration-agent" - ] - }, - { - "group": "Permissions", - "pages": [ - "docs/cookbook/iam-agent", - "docs/cookbook/credential-rotation-agent" - ] - }, - { - "group": "Records", - "pages": [ - "docs/cookbook/crm-update-agent", - "docs/cookbook/data-deletion-agent" - ] - }, - { - "group": "Communications", - "pages": [ - "docs/cookbook/outbound-email-agent", - "docs/cookbook/customer-notification-agent" - ] - }, - { - "group": "Multi-agent", - "pages": [ - "docs/cookbook/manager-and-worker" - ] - }, - { - "group": "Integrations", - "pages": [ - "docs/cookbook/protect-an-mcp-server", - "docs/cookbook/langgraph-interrupt", - "docs/cookbook/openai-agents-tool-approval", - "docs/cookbook/slack-approvals", - "docs/cookbook/receipts-to-opentelemetry" - ] - }, - { - "group": "Operations", - "pages": [ - "docs/cookbook/observe-then-enforce", - "docs/cookbook/resolve-an-ambiguous-effect", - "docs/cookbook/reconcile-against-the-remote", - "docs/cookbook/verify-in-github-actions", - "docs/cookbook/sqlite-to-postgres" - ] - } - ], - "expanded": false - }, - { - "group": "Compare", - "pages": [ - "docs/compare/framework-hitl", - "docs/compare/guardrail-libraries", - "docs/compare/governance-toolkits", - "docs/compare/durable-workflows", - "docs/compare/idempotency-keys" - ] - }, - { - "group": "FAQ", - "pages": [ - "docs/faq" - ] - }, - { - "group": "More", - "pages": [ - "docs/verify/get-the-badge", - "docs/study/does-your-framework-double-execute" - ] - } - ] - }, - { - "tab": "Reference", - "groups": [ - { - "group": "Reference", - "pages": [ - "docs/reference/policy-yaml", - "docs/reference/authority-yaml", - "docs/reference/cli", - "docs/reference/receipt-and-event-schemas", - "docs/reference/exit-codes", - "docs/reference/errors" - ] - }, - { - "group": "Python API", - "pages": [ - "docs/reference/api/index", - "docs/reference/api/Action", - "docs/reference/api/ActionDenied", - "docs/reference/api/AmbiguousEffect", - "docs/reference/api/Approval", - "docs/reference/api/ApprovalAnswer", - "docs/reference/api/ApprovalMismatch", - "docs/reference/api/ApprovalProvider", - "docs/reference/api/ApprovalRequest", - "docs/reference/api/ApprovalRequired", - "docs/reference/api/ApprovalTimeout", - "docs/reference/api/Authority", - "docs/reference/api/AuthorityDenied", - "docs/reference/api/AuthorityEscalation", - "docs/reference/api/AuthorityResult", - "docs/reference/api/CTRLRunError", - "docs/reference/api/Condition", - "docs/reference/api/Control", - "docs/reference/api/Decision", - "docs/reference/api/Delegation", - "docs/reference/api/DelegationRecord", - "docs/reference/api/DuplicateEffect", - "docs/reference/api/EffectKeyError", - "docs/reference/api/EffectRecord", - "docs/reference/api/EffectState", - "docs/reference/api/Event", - "docs/reference/api/EventSink", - "docs/reference/api/FrameworkInterrupt", - "docs/reference/api/Grant", - "docs/reference/api/HeaderIdentityProvider", - "docs/reference/api/IdentityContext", - "docs/reference/api/IdentityError", - "docs/reference/api/IdentityProvider", - "docs/reference/api/InMemoryStateStore", - "docs/reference/api/InterruptApprovalProvider", - "docs/reference/api/InvalidArgument", - "docs/reference/api/JSONLEventSink", - "docs/reference/api/LocalApprovalProvider", - "docs/reference/api/MissingDependency", - "docs/reference/api/NotExecuted", - "docs/reference/api/PendingApproval", - "docs/reference/api/Policy", - "docs/reference/api/PolicyError", - "docs/reference/api/Principal", - "docs/reference/api/Receipt", - "docs/reference/api/ReconcileOutcome", - "docs/reference/api/SQLiteStateStore", - "docs/reference/api/SchemaMismatch", - "docs/reference/api/ScriptedApprovalProvider", - "docs/reference/api/StateStore", - "docs/reference/api/StaticIdentityProvider", - "docs/reference/api/Subject", - "docs/reference/api/Suspended", - "docs/reference/api/WebhookApprovalProvider", - "docs/reference/api/acs-AcsControlHook", - "docs/reference/api/action_hash", - "docs/reference/api/banner", - "docs/reference/api/canonical_bytes", - "docs/reference/api/canonicalize", - "docs/reference/api/conformance-run", - "docs/reference/api/conformance-store-run", - "docs/reference/api/context", - "docs/reference/api/gateway-serve", - "docs/reference/api/jwt_identity-JWTIdentityProvider", - "docs/reference/api/needs_approval", - "docs/reference/api/otel-OTelEventSink", - "docs/reference/api/parse_conditions", - "docs/reference/api/postgres-PostgresStateStore", - "docs/reference/api/protect", - "docs/reference/api/verify-run", - "docs/reference/api/with_approval" - ], - "expanded": false - } - ] - }, - { - "tab": "Architecture", - "groups": [ - { - "group": "Architecture", - "pages": [ - "docs/ARCHITECTURE", - "docs/architecture/specifications" - ] - }, - { - "group": "Security", - "pages": [ - "docs/security/verify-guarantees", - "docs/security/receipt-chain", - "docs/security/disclosure", - "docs/THREAT_MODEL", - "docs/how-this-is-built" - ] - }, - { - "group": "Readings and references", - "pages": [ - "docs/OWASP-AGENTIC-TOP10", - "docs/ACS", - "docs/adapters", - "docs/authority", - "docs/verify", - "docs/CLAIMS", - "docs/ROADMAP" - ] - } - ] - } - ] - }, - "footer": { - "socials": { - "github": "https://github.com/CTRLRun/ctrlrun" - } - }, - "seo": { - "metatags": { - "og:site_name": "CTRLRun", - "og:image": "https://ctrlrun.dev/images/social-preview.png", - "twitter:card": "summary_large_image", - "twitter:image": "https://ctrlrun.dev/images/social-preview.png" - }, - "indexing": "navigable" - }, - "redirects": [ - { - "source": "/why", - "destination": "/docs/why", - "permanent": true - }, - { - "source": "/not-only-agents", - "destination": "/docs/not-only-agents", - "permanent": true - }, - { - "source": "/get-started/install", - "destination": "/docs/get-started/install", - "permanent": true - }, - { - "source": "/get-started/quickstart", - "destination": "/docs/get-started/quickstart", - "permanent": true - }, - { - "source": "/get-started/three-ways-in", - "destination": "/docs/get-started/three-ways-in", - "permanent": true - }, - { - "source": "/get-started/choosing", - "destination": "/docs/get-started/choosing", - "permanent": true - }, - { - "source": "/demos/index", - "destination": "/docs/demos/index", - "permanent": true - }, - { - "source": "/try-it", - "destination": "/docs/try-it", - "permanent": true - }, - { - "source": "/demos/medical-affairs", - "destination": "/docs/demos/medical-affairs", - "permanent": true - }, - { - "source": "/production/index", - "destination": "/docs/production/index", - "permanent": true - }, - { - "source": "/production/postgres", - "destination": "/docs/production/postgres", - "permanent": true - }, - { - "source": "/postgres", - "destination": "/docs/postgres", - "permanent": true - }, - { - "source": "/production/how-reservation-works", - "destination": "/docs/production/how-reservation-works", - "permanent": true - }, - { - "source": "/production/migrations", - "destination": "/docs/production/migrations", - "permanent": true - }, - { - "source": "/production/recovery", - "destination": "/docs/production/recovery", - "permanent": true - }, - { - "source": "/production/receipt-integrity", - "destination": "/docs/production/receipt-integrity", - "permanent": true - }, - { - "source": "/production/soak", - "destination": "/docs/production/soak", - "permanent": true - }, - { - "source": "/production/operations", - "destination": "/docs/production/operations", - "permanent": true - }, - { - "source": "/mcp/overview", - "destination": "/docs/mcp/overview", - "permanent": true - }, - { - "source": "/mcp/gateway-in-5-minutes", - "destination": "/docs/mcp/gateway-in-5-minutes", - "permanent": true - }, - { - "source": "/mcp/approve-from-your-assistant", - "destination": "/docs/mcp/approve-from-your-assistant", - "permanent": true - }, - { - "source": "/mcp/use-the-docs-from-your-editor", - "destination": "/docs/mcp/use-the-docs-from-your-editor", - "permanent": true - }, - { - "source": "/concepts/action-and-hash", - "destination": "/docs/concepts/action-and-hash", - "permanent": true - }, - { - "source": "/concepts/decisions", - "destination": "/docs/concepts/decisions", - "permanent": true - }, - { - "source": "/concepts/approval-binding", - "destination": "/docs/concepts/approval-binding", - "permanent": true - }, - { - "source": "/concepts/effect-keys", - "destination": "/docs/concepts/effect-keys", - "permanent": true - }, - { - "source": "/concepts/outcomes-and-ambiguous", - "destination": "/docs/concepts/outcomes-and-ambiguous", - "permanent": true - }, - { - "source": "/concepts/receipts-and-evidence", - "destination": "/docs/concepts/receipts-and-evidence", - "permanent": true - }, - { - "source": "/concepts/authority-and-delegation", - "destination": "/docs/concepts/authority-and-delegation", - "permanent": true - }, - { - "source": "/concepts/observe-mode", - "destination": "/docs/concepts/observe-mode", - "permanent": true - }, - { - "source": "/concepts/fail-closed", - "destination": "/docs/concepts/fail-closed", - "permanent": true - }, - { - "source": "/guides/protect-a-function", - "destination": "/docs/guides/protect-a-function", - "permanent": true - }, - { - "source": "/guides/gateway-in-front-of-mcp", - "destination": "/docs/guides/gateway-in-front-of-mcp", - "permanent": true - }, - { - "source": "/guides/approvals-in-slack", - "destination": "/docs/guides/approvals-in-slack", - "permanent": true - }, - { - "source": "/guides/resolve-an-ambiguous-effect", - "destination": "/docs/guides/resolve-an-ambiguous-effect", - "permanent": true - }, - { - "source": "/guides/reconcile-automatically", - "destination": "/docs/guides/reconcile-automatically", - "permanent": true - }, - { - "source": "/guides/observe-to-enforce", - "destination": "/docs/guides/observe-to-enforce", - "permanent": true - }, - { - "source": "/guides/run-on-postgres", - "destination": "/docs/guides/run-on-postgres", - "permanent": true - }, - { - "source": "/guides/verify-in-ci", - "destination": "/docs/guides/verify-in-ci", - "permanent": true - }, - { - "source": "/guides/export-to-opentelemetry", - "destination": "/docs/guides/export-to-opentelemetry", - "permanent": true - }, - { - "source": "/guides/langgraph-adapter", - "destination": "/docs/guides/langgraph-adapter", - "permanent": true - }, - { - "source": "/guides/openai-agents-adapter", - "destination": "/docs/guides/openai-agents-adapter", - "permanent": true - }, - { - "source": "/cookbook/index", - "destination": "/docs/cookbook/index", - "permanent": true - }, - { - "source": "/cookbook/refund-agent", - "destination": "/docs/cookbook/refund-agent", - "permanent": true - }, - { - "source": "/cookbook/payout-maker-checker", - "destination": "/docs/cookbook/payout-maker-checker", - "permanent": true - }, - { - "source": "/cookbook/deploy-agent", - "destination": "/docs/cookbook/deploy-agent", - "permanent": true - }, - { - "source": "/cookbook/database-migration-agent", - "destination": "/docs/cookbook/database-migration-agent", - "permanent": true - }, - { - "source": "/cookbook/iam-agent", - "destination": "/docs/cookbook/iam-agent", - "permanent": true - }, - { - "source": "/cookbook/credential-rotation-agent", - "destination": "/docs/cookbook/credential-rotation-agent", - "permanent": true - }, - { - "source": "/cookbook/crm-update-agent", - "destination": "/docs/cookbook/crm-update-agent", - "permanent": true - }, - { - "source": "/cookbook/data-deletion-agent", - "destination": "/docs/cookbook/data-deletion-agent", - "permanent": true - }, - { - "source": "/cookbook/outbound-email-agent", - "destination": "/docs/cookbook/outbound-email-agent", - "permanent": true - }, - { - "source": "/cookbook/customer-notification-agent", - "destination": "/docs/cookbook/customer-notification-agent", - "permanent": true - }, - { - "source": "/cookbook/manager-and-worker", - "destination": "/docs/cookbook/manager-and-worker", - "permanent": true - }, - { - "source": "/cookbook/protect-an-mcp-server", - "destination": "/docs/cookbook/protect-an-mcp-server", - "permanent": true - }, - { - "source": "/cookbook/langgraph-interrupt", - "destination": "/docs/cookbook/langgraph-interrupt", - "permanent": true - }, - { - "source": "/cookbook/openai-agents-tool-approval", - "destination": "/docs/cookbook/openai-agents-tool-approval", - "permanent": true - }, - { - "source": "/cookbook/slack-approvals", - "destination": "/docs/cookbook/slack-approvals", - "permanent": true - }, - { - "source": "/cookbook/receipts-to-opentelemetry", - "destination": "/docs/cookbook/receipts-to-opentelemetry", - "permanent": true - }, - { - "source": "/cookbook/observe-then-enforce", - "destination": "/docs/cookbook/observe-then-enforce", - "permanent": true - }, - { - "source": "/cookbook/resolve-an-ambiguous-effect", - "destination": "/docs/cookbook/resolve-an-ambiguous-effect", - "permanent": true - }, - { - "source": "/cookbook/reconcile-against-the-remote", - "destination": "/docs/cookbook/reconcile-against-the-remote", - "permanent": true - }, - { - "source": "/cookbook/verify-in-github-actions", - "destination": "/docs/cookbook/verify-in-github-actions", - "permanent": true - }, - { - "source": "/cookbook/sqlite-to-postgres", - "destination": "/docs/cookbook/sqlite-to-postgres", - "permanent": true - }, - { - "source": "/compare/framework-hitl", - "destination": "/docs/compare/framework-hitl", - "permanent": true - }, - { - "source": "/compare/guardrail-libraries", - "destination": "/docs/compare/guardrail-libraries", - "permanent": true - }, - { - "source": "/compare/governance-toolkits", - "destination": "/docs/compare/governance-toolkits", - "permanent": true - }, - { - "source": "/compare/durable-workflows", - "destination": "/docs/compare/durable-workflows", - "permanent": true - }, - { - "source": "/compare/idempotency-keys", - "destination": "/docs/compare/idempotency-keys", - "permanent": true - }, - { - "source": "/faq", - "destination": "/docs/faq", - "permanent": true - }, - { - "source": "/verify/get-the-badge", - "destination": "/docs/verify/get-the-badge", - "permanent": true - }, - { - "source": "/study/does-your-framework-double-execute", - "destination": "/docs/study/does-your-framework-double-execute", - "permanent": true - }, - { - "source": "/reference/policy-yaml", - "destination": "/docs/reference/policy-yaml", - "permanent": true - }, - { - "source": "/reference/authority-yaml", - "destination": "/docs/reference/authority-yaml", - "permanent": true - }, - { - "source": "/reference/cli", - "destination": "/docs/reference/cli", - "permanent": true - }, - { - "source": "/reference/receipt-and-event-schemas", - "destination": "/docs/reference/receipt-and-event-schemas", - "permanent": true - }, - { - "source": "/reference/exit-codes", - "destination": "/docs/reference/exit-codes", - "permanent": true - }, - { - "source": "/reference/errors", - "destination": "/docs/reference/errors", - "permanent": true - }, - { - "source": "/reference/api/index", - "destination": "/docs/reference/api/index", - "permanent": true - }, - { - "source": "/reference/api/Action", - "destination": "/docs/reference/api/Action", - "permanent": true - }, - { - "source": "/reference/api/ActionDenied", - "destination": "/docs/reference/api/ActionDenied", - "permanent": true - }, - { - "source": "/reference/api/AmbiguousEffect", - "destination": "/docs/reference/api/AmbiguousEffect", - "permanent": true - }, - { - "source": "/reference/api/Approval", - "destination": "/docs/reference/api/Approval", - "permanent": true - }, - { - "source": "/reference/api/ApprovalAnswer", - "destination": "/docs/reference/api/ApprovalAnswer", - "permanent": true - }, - { - "source": "/reference/api/ApprovalMismatch", - "destination": "/docs/reference/api/ApprovalMismatch", - "permanent": true - }, - { - "source": "/reference/api/ApprovalProvider", - "destination": "/docs/reference/api/ApprovalProvider", - "permanent": true - }, - { - "source": "/reference/api/ApprovalRequest", - "destination": "/docs/reference/api/ApprovalRequest", - "permanent": true - }, - { - "source": "/reference/api/ApprovalRequired", - "destination": "/docs/reference/api/ApprovalRequired", - "permanent": true - }, - { - "source": "/reference/api/ApprovalTimeout", - "destination": "/docs/reference/api/ApprovalTimeout", - "permanent": true - }, - { - "source": "/reference/api/Authority", - "destination": "/docs/reference/api/Authority", - "permanent": true - }, - { - "source": "/reference/api/AuthorityDenied", - "destination": "/docs/reference/api/AuthorityDenied", - "permanent": true - }, - { - "source": "/reference/api/AuthorityEscalation", - "destination": "/docs/reference/api/AuthorityEscalation", - "permanent": true - }, - { - "source": "/reference/api/AuthorityResult", - "destination": "/docs/reference/api/AuthorityResult", - "permanent": true - }, - { - "source": "/reference/api/CTRLRunError", - "destination": "/docs/reference/api/CTRLRunError", - "permanent": true - }, - { - "source": "/reference/api/Condition", - "destination": "/docs/reference/api/Condition", - "permanent": true - }, - { - "source": "/reference/api/Control", - "destination": "/docs/reference/api/Control", - "permanent": true - }, - { - "source": "/reference/api/Decision", - "destination": "/docs/reference/api/Decision", - "permanent": true - }, - { - "source": "/reference/api/Delegation", - "destination": "/docs/reference/api/Delegation", - "permanent": true - }, - { - "source": "/reference/api/DelegationRecord", - "destination": "/docs/reference/api/DelegationRecord", - "permanent": true - }, - { - "source": "/reference/api/DuplicateEffect", - "destination": "/docs/reference/api/DuplicateEffect", - "permanent": true - }, - { - "source": "/reference/api/EffectKeyError", - "destination": "/docs/reference/api/EffectKeyError", - "permanent": true - }, - { - "source": "/reference/api/EffectRecord", - "destination": "/docs/reference/api/EffectRecord", - "permanent": true - }, - { - "source": "/reference/api/EffectState", - "destination": "/docs/reference/api/EffectState", - "permanent": true - }, - { - "source": "/reference/api/Event", - "destination": "/docs/reference/api/Event", - "permanent": true - }, - { - "source": "/reference/api/EventSink", - "destination": "/docs/reference/api/EventSink", - "permanent": true - }, - { - "source": "/reference/api/FrameworkInterrupt", - "destination": "/docs/reference/api/FrameworkInterrupt", - "permanent": true - }, - { - "source": "/reference/api/Grant", - "destination": "/docs/reference/api/Grant", - "permanent": true - }, - { - "source": "/reference/api/HeaderIdentityProvider", - "destination": "/docs/reference/api/HeaderIdentityProvider", - "permanent": true - }, - { - "source": "/reference/api/IdentityContext", - "destination": "/docs/reference/api/IdentityContext", - "permanent": true - }, - { - "source": "/reference/api/IdentityError", - "destination": "/docs/reference/api/IdentityError", - "permanent": true - }, - { - "source": "/reference/api/IdentityProvider", - "destination": "/docs/reference/api/IdentityProvider", - "permanent": true - }, - { - "source": "/reference/api/InMemoryStateStore", - "destination": "/docs/reference/api/InMemoryStateStore", - "permanent": true - }, - { - "source": "/reference/api/InterruptApprovalProvider", - "destination": "/docs/reference/api/InterruptApprovalProvider", - "permanent": true - }, - { - "source": "/reference/api/InvalidArgument", - "destination": "/docs/reference/api/InvalidArgument", - "permanent": true - }, - { - "source": "/reference/api/JSONLEventSink", - "destination": "/docs/reference/api/JSONLEventSink", - "permanent": true - }, - { - "source": "/reference/api/LocalApprovalProvider", - "destination": "/docs/reference/api/LocalApprovalProvider", - "permanent": true - }, - { - "source": "/reference/api/MissingDependency", - "destination": "/docs/reference/api/MissingDependency", - "permanent": true - }, - { - "source": "/reference/api/NotExecuted", - "destination": "/docs/reference/api/NotExecuted", - "permanent": true - }, - { - "source": "/reference/api/PendingApproval", - "destination": "/docs/reference/api/PendingApproval", - "permanent": true - }, - { - "source": "/reference/api/Policy", - "destination": "/docs/reference/api/Policy", - "permanent": true - }, - { - "source": "/reference/api/PolicyError", - "destination": "/docs/reference/api/PolicyError", - "permanent": true - }, - { - "source": "/reference/api/Principal", - "destination": "/docs/reference/api/Principal", - "permanent": true - }, - { - "source": "/reference/api/Receipt", - "destination": "/docs/reference/api/Receipt", - "permanent": true - }, - { - "source": "/reference/api/ReconcileOutcome", - "destination": "/docs/reference/api/ReconcileOutcome", - "permanent": true - }, - { - "source": "/reference/api/SQLiteStateStore", - "destination": "/docs/reference/api/SQLiteStateStore", - "permanent": true - }, - { - "source": "/reference/api/SchemaMismatch", - "destination": "/docs/reference/api/SchemaMismatch", - "permanent": true - }, - { - "source": "/reference/api/ScriptedApprovalProvider", - "destination": "/docs/reference/api/ScriptedApprovalProvider", - "permanent": true - }, - { - "source": "/reference/api/StateStore", - "destination": "/docs/reference/api/StateStore", - "permanent": true - }, - { - "source": "/reference/api/StaticIdentityProvider", - "destination": "/docs/reference/api/StaticIdentityProvider", - "permanent": true - }, - { - "source": "/reference/api/Subject", - "destination": "/docs/reference/api/Subject", - "permanent": true - }, - { - "source": "/reference/api/Suspended", - "destination": "/docs/reference/api/Suspended", - "permanent": true - }, - { - "source": "/reference/api/WebhookApprovalProvider", - "destination": "/docs/reference/api/WebhookApprovalProvider", - "permanent": true - }, - { - "source": "/reference/api/acs-AcsControlHook", - "destination": "/docs/reference/api/acs-AcsControlHook", - "permanent": true - }, - { - "source": "/reference/api/action_hash", - "destination": "/docs/reference/api/action_hash", - "permanent": true - }, - { - "source": "/reference/api/banner", - "destination": "/docs/reference/api/banner", - "permanent": true - }, - { - "source": "/reference/api/canonical_bytes", - "destination": "/docs/reference/api/canonical_bytes", - "permanent": true - }, - { - "source": "/reference/api/canonicalize", - "destination": "/docs/reference/api/canonicalize", - "permanent": true - }, - { - "source": "/reference/api/conformance-run", - "destination": "/docs/reference/api/conformance-run", - "permanent": true - }, - { - "source": "/reference/api/conformance-store-run", - "destination": "/docs/reference/api/conformance-store-run", - "permanent": true - }, - { - "source": "/reference/api/context", - "destination": "/docs/reference/api/context", - "permanent": true - }, - { - "source": "/reference/api/gateway-serve", - "destination": "/docs/reference/api/gateway-serve", - "permanent": true - }, - { - "source": "/reference/api/jwt_identity-JWTIdentityProvider", - "destination": "/docs/reference/api/jwt_identity-JWTIdentityProvider", - "permanent": true - }, - { - "source": "/reference/api/needs_approval", - "destination": "/docs/reference/api/needs_approval", - "permanent": true - }, - { - "source": "/reference/api/otel-OTelEventSink", - "destination": "/docs/reference/api/otel-OTelEventSink", - "permanent": true - }, - { - "source": "/reference/api/parse_conditions", - "destination": "/docs/reference/api/parse_conditions", - "permanent": true - }, - { - "source": "/reference/api/postgres-PostgresStateStore", - "destination": "/docs/reference/api/postgres-PostgresStateStore", - "permanent": true - }, - { - "source": "/reference/api/protect", - "destination": "/docs/reference/api/protect", - "permanent": true - }, - { - "source": "/reference/api/verify-run", - "destination": "/docs/reference/api/verify-run", - "permanent": true - }, - { - "source": "/reference/api/with_approval", - "destination": "/docs/reference/api/with_approval", - "permanent": true - }, - { - "source": "/ARCHITECTURE", - "destination": "/docs/ARCHITECTURE", - "permanent": true - }, - { - "source": "/architecture/specifications", - "destination": "/docs/architecture/specifications", - "permanent": true - }, - { - "source": "/security/verify-guarantees", - "destination": "/docs/security/verify-guarantees", - "permanent": true - }, - { - "source": "/security/receipt-chain", - "destination": "/docs/security/receipt-chain", - "permanent": true - }, - { - "source": "/security/disclosure", - "destination": "/docs/security/disclosure", - "permanent": true - }, - { - "source": "/THREAT_MODEL", - "destination": "/docs/THREAT_MODEL", - "permanent": true - }, - { - "source": "/how-this-is-built", - "destination": "/docs/how-this-is-built", - "permanent": true - }, - { - "source": "/OWASP-AGENTIC-TOP10", - "destination": "/docs/OWASP-AGENTIC-TOP10", - "permanent": true - }, - { - "source": "/ACS", - "destination": "/docs/ACS", - "permanent": true - }, - { - "source": "/adapters", - "destination": "/docs/adapters", - "permanent": true - }, - { - "source": "/authority", - "destination": "/docs/authority", - "permanent": true - }, - { - "source": "/verify", - "destination": "/docs/verify", - "permanent": true - }, - { - "source": "/CLAIMS", - "destination": "/docs/CLAIMS", - "permanent": true - }, - { - "source": "/ROADMAP", - "destination": "/docs/ROADMAP", - "permanent": true - } - ] -} diff --git a/docs/docs.mdx b/docs/docs.mdx deleted file mode 100644 index c545e99..0000000 --- a/docs/docs.mdx +++ /dev/null @@ -1,291 +0,0 @@ ---- -title: "The execution safety layer for AI agents" -sidebarTitle: "Overview" -description: "The last check before an AI agent does something it can't undo. Autonomy belongs to the action, not the agent." -mode: "wide" -"og:title": "CTRLRun: the execution safety layer for AI agents" -"twitter:title": "CTRLRun: the execution safety layer for AI agents" -canonical: "https://ctrlrun.dev/docs" ---- - -CTRLRun is a Python library that sits between an agent's decision to act and the call that acts. -A consequential action happens at most once, exactly as approved, and leaves a receipt, and when -the outcome is unknown, CTRLRun says so instead of guessing. - -```bash -pip install ctrlrun && ctrlrun demo -``` - -<Columns cols={2}> - <Card title="Break a protected action in your browser" icon="play" href="/docs/try-it"> - No install. Approve €2,000, execute €5,000, lose a reply, retry: real refusals, in this tab. - </Card> - <Card title="Protect your first action" icon="shield" href="/docs/get-started/quickstart"> - One policy file, one decorator, one approval from the shell, three receipts. - </Card> -</Columns> - -**Runs in production on a single file, or on Postgres across hosts.** SQLite is the default and -is production-grade on one host; Postgres is for many. Apache-2.0. - -## Protect one function - -CTRLRun wraps the call that has the consequence, and a YAML file says how much autonomy that -call gets. This is the whole integration for a function in your own process: - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } # up to €500: autonomous - decision: allow - - when: { amount_gte: 0, amount_lte: 500000 } # up to €5,000: a human decides - decision: approve - - decision: deny # above that: never -``` - -```python runnable -import ctrlrun - - -class Stripe: # stands in for the real client so this block runs offline - def refund(self, payment_id: str, amount: int) -> dict: - return {"status": "succeeded"} - - -stripe = Stripe() - - -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}") -def refund(payment_id: str, amount: int) -> dict: - return stripe.refund(payment_id, amount) - - -with ctrlrun.context(agent="refund-agent"): - refund(payment_id="txn_1", amount=10000) # €100: runs, and leaves a receipt - try: - refund(payment_id="txn_2", amount=200000) # €2,000: waits for a human - except ctrlrun.ApprovalRequired as pending: - print("a human decides:", pending.request_id) - else: - raise SystemExit("the €2,000 refund ran without a human; the policy is not in force") -``` - -What the same function does next, and what stops it: - -| The agent | CTRLRun | -|---|---| -| refunds €100 | runs it; one receipt | -| refunds €2,000 | raises `ApprovalRequired`; `ctrlrun approve <id>` from the shell lets it through | -| has €2,000 approved, executes €5,000 | `ApprovalMismatch`: the approval is bound to the action a human saw | -| refunds €20,000 | `ActionDenied`; no request is created | -| retries a refund whose reply was lost | `AmbiguousEffect`: the remote may have committed; a human or a reconcile hook decides | -| runs the same refund from two workers | one reserves `refund:txn_1`, the other gets `DuplicateEffect` | - -The refund is the first example because everyone understands it; the same file protects a -`kubectl delete`, an IAM grant, a record deletion or an outbound email, and the -[cookbook](/docs/cookbook/index) has each of those as a runnable recipe. - -## What the demo shows - -Five ways an agent action goes wrong, and what stops each one, in under a second with no network. -The first scenario is the one that explains the product: a refund commits at the remote, the -reply is lost, the agent retries, and the retry is refused. The customer was refunded once. - -```console -$ ctrlrun demo -CTRLRun demo — five ways an agent action goes wrong, and what stops it. -Policy: refunds up to €1,000 are autonomous, up to €10,000 need a human, above that are denied. - -1. Duplicate effect after a lost response - - refund €500 → remote commits → response lost → effect: AMBIGUOUS - agent retries the same refund - ✗ BLOCKED — effect may already have committed; blind retry refused - remote refund calls: 1 - only a human moves it on: ctrlrun resolve refund:txn_1 --committed|--failed -``` - -The other four are approval mutation, two agents racing for one effect, approval replay, and an -agent trying to act outside what was delegated to it. [Try it in your browser](/docs/try-it) runs -the same demo without an install and lets you break one refund yourself, or read the full transcript in the -[repository README](https://github.com/CTRLRun/ctrlrun#what-ctrlrun-demo-shows). - -## What it does - -{/* generated from docs/capabilities.yaml (mdx) — edit the YAML, never this grid */} -<Columns cols={2}> - <Card title="Approval binding" href="/docs/concepts/approval-binding"> - An approval is bound to the exact action; a mutated or replayed one is refused. Since v0.1. - </Card> - <Card title="One effect, once" href="/docs/concepts/effect-keys"> - One logical effect happens at most once, across threads, processes and hosts. Since v0.1. - </Card> - <Card title="Unknown is not failed" href="/docs/concepts/outcomes-and-ambiguous"> - An unknown outcome is AMBIGUOUS, never FAILED, and blocks a blind retry. Since v0.1. - </Card> - <Card title="Fail closed" href="/docs/concepts/fail-closed"> - An unknown action, a missing policy or a missing principal is denied. Since v0.1. - </Card> - <Card title="Authority and delegation" href="/docs/concepts/authority-and-delegation"> - With authority on, every principal needs a grant, and delegation cannot widen one. Since v0.3. - </Card> - <Card title="Receipts" href="/docs/concepts/receipts-and-evidence"> - Every executed action leaves a portable JSON receipt of who, what and outcome. Since v0.1. - </Card> -</Columns> -<Accordion title="Everything else it does (20 more)"> - <Columns cols={2}> - <Card title="Per-action policy" href="/docs/reference/policy-yaml"> - One YAML file decides allow, approve or deny per action and argument. Since v0.1. - </Card> - <Card title="Operator CLI" href="/docs/reference/cli"> - Approve, deny, resolve, inspect and count from the shell, against any store. Since v0.1. - </Card> - <Card title="MCP gateway" href="/docs/guides/gateway-in-front-of-mcp"> - Every guarantee in front of an MCP tool server, with no agent changes. Since v0.2. - </Card> - <Card title="Reconciliation" href="/docs/guides/reconcile-automatically"> - A reconcile hook asks the remote what happened and resolves an AMBIGUOUS effect. Since v0.2. - </Card> - <Card title="Webhook approvals" href="/docs/guides/approvals-in-slack"> - Approval requests go to a webhook, such as Slack, and the answer comes back. Since v0.2. - </Card> - <Card title="OpenTelemetry export" href="/docs/guides/export-to-opentelemetry"> - One span per action, one span event per step; argument values are opt-in. Since v0.2. - </Card> - <Card title="Consumed identity" href="/docs/concepts/authority-and-delegation"> - A principal comes from a verified header or JWT; CTRLRun issues nothing. Since v0.3. - </Card> - <Card title="Runtime delegation" href="/docs/concepts/authority-and-delegation"> - A principal narrows its own grant at runtime; one revocation cuts the chain. Since v0.3. - </Card> - <Card title="Observe mode" href="/docs/concepts/observe-mode"> - Records what enforcement would have blocked, blocks nothing, and counts it. Since v0.3. - </Card> - <Card title="Verify" href="/docs/guides/verify-in-ci"> - Runs the guarantee catalogue against your policy and store; N/A is not a pass. Since v0.4. - </Card> - <Card title="The verified badge" href="/docs/verify/get-the-badge"> - A GitHub Action and a badge that means the declared guarantees pass. Since v0.4. - </Card> - <Card title="Framework adapters" href="/docs/get-started/three-ways-in"> - An approval routed through the framework's own interrupt; never a second path. Since v0.5. - </Card> - <Card title="Runs on one host or many" href="/docs/production/index"> - SQLite on one host, Postgres across hosts, the same guarantees either way. Since v0.6. - </Card> - <Card title="Postgres store" href="/docs/production/postgres"> - The same store on Postgres, graded by the suite written for SQLite. Since v0.6. - </Card> - <Card title="Versioned schema" href="/docs/production/migrations"> - Migrations run at open, forward only, and an unknown schema is refused. Since v0.6. - </Card> - <Card title="Recovery on restart" href="/docs/production/recovery"> - A dead worker's effect stays AMBIGUOUS until a human or a hook resolves it. Since v0.6. - </Card> - <Card title="Receipt chain" href="/docs/security/receipt-chain"> - Each receipt carries the hash of the one before; alteration is detected and named. Since v0.6. - </Card> - <Card title="Policy versioning" href="/docs/concepts/receipts-and-evidence"> - Every receipt names the policy hash and version that decided it. Since v0.6. - </Card> - <Card title="Control registry" href="/docs/reference/policy-yaml"> - Name the house controls an action satisfies, and receipts cite them. Since v0.6. - </Card> - <Card title="Data scope" href="/docs/reference/policy-yaml"> - Label arguments by data class and condition a rule on the labels present. Since v0.6. - </Card> - </Columns> -</Accordion> -{/* end generated */} - -## Three ways in - -| You have | Use | Needs | -|---|---|---| -| Python in this process: a raw model call, a LangChain tool, a hand-rolled loop, a cron job | the `@protect` decorator | nothing beyond `pip install ctrlrun` | -| Tools behind an MCP server, in any language | the gateway, `ctrlrun gateway` | `pip install "ctrlrun[gateway]"` | -| A framework with its own approval interrupt, and a place where humans already answer | an adapter | the framework to have a human-in-the-loop primitive | - -Most readers need the decorator. An adapter buys exactly one thing, routing an approval through -the framework's own interrupt, and a framework with no such primitive does not need one. -[Choosing between them](/docs/get-started/choosing) has the decision table. - -## Where it stands - -{/* generated from the suite, pyproject and the soak (mdx) — run the generator */} -- **Version 0.6.1**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later. -- **4,404 tests**, every version specified before it was written and every requirement mutation-tested. -- **11 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). -- **Each receipt carries the hash of the one before it**, so an alteration is detected and named. -- **Apache-2.0**, and the enforcement kernel stays open source. Releases carry PyPI provenance attestations from GitHub Actions. - -**Not yet:** - -- No external security audit. (planned for v0.8 or v0.9) -- No third-party review of the kernel. (every review so far was run inside this project) -- No sector packs. (the policy templates are starting points, not a product) -{/* end generated */} - -## Start here - -<Columns cols={3}> - <Card title="Protect your first action" icon="play" href="/docs/get-started/quickstart"> - Protect one function end to end and read the receipt. Ten minutes. - </Card> - <Card title="Try it in your browser" icon="flask" href="/docs/try-it"> - One refund you can break six ways, and the five demo scenarios, on the released wheel. - </Card> - <Card title="Cookbook" icon="book" href="/docs/cookbook/index"> - Refunds, deploys, IAM, deletions, email, MCP, LangGraph: each a recipe that runs. - </Card> -</Columns> - -<Columns cols={3}> - <Card title="Three ways in" icon="signpost" href="/docs/get-started/three-ways-in"> - Decorator, gateway, adapter: what each covers and what each needs. - </Card> - <Card title="MCP" icon="plug" href="/docs/mcp/overview"> - The gateway in front of any MCP server, and this site as an MCP server. - </Card> - <Card title="Run it for real" icon="server" href="/docs/production/index"> - Which store, what a lost `COMMIT` does, what survives a crash, and what to watch. - </Card> -</Columns> - -<Columns cols={2}> - <Card title="Why" icon="book-open" href="/docs/why"> - The five principles, in 700 words. The page people link to. - </Card> - <Card title="Outcomes and AMBIGUOUS" icon="circle-help" href="/docs/concepts/outcomes-and-ambiguous"> - The idea that explains the product: a timeout is not a failure. - </Card> -</Columns> - -## Ask your coding tool - -This site is an MCP server. Add it to Cursor or any MCP client that takes an `mcpServers` -entry, and the assistant answers from these pages rather than from memory: - -```json -{ - "mcpServers": { - "ctrlrun-docs": { "type": "http", "url": "https://ctrlrun.dev/mcp" } - } -} -``` - -The server exposes one tool, a search across this documentation. When the site moves to its own -domain the URL moves with it; the current one is always in this block. - -## Next - -- [Why](/docs/why): what CTRLRun believes and why. -- [Install](/docs/get-started/install): what `pip install ctrlrun` puts on your machine, and what it does not. -- [How this is built](/docs/how-this-is-built): the discipline behind the guarantees. diff --git a/docs/docs/ACS.md b/docs/docs/ACS.md deleted file mode 100644 index 86e7361..0000000 --- a/docs/docs/ACS.md +++ /dev/null @@ -1,244 +0,0 @@ ---- -title: "The Agent Control Standard" -description: "What was read, what maps onto CTRLRun's guarantees, where the standard is silent, and how the adapter is built." ---- - -What was read, what maps, what does not, and how the adapter is built. - -## What was read - -The [Agent Control Standard](https://agentcontrolstandard.org/), a project of the OWASP GenAI -Security Project, in -[`GenAI-Security-Project/agent-control-standard`](https://github.com/GenAI-Security-Project/agent-control-standard) -at commit **`c7ad162f69386daac94b89073e3b751e8cdf28b2`** (2026-08-11, *"Raise the Python floor -to unblock Dependabot security updates"*). The repository was at release **v0.1.1**, with the -specification version decoupled from the release version at commit `1af1f92` (2026-08-11) and -tracked separately at **v0.1.0**. Code is Apache-2.0; documentation is CC BY-SA 4.0. - -Specifically: - -| File | What it gave | -|---|---| -| `specification/ACS/acs_schema.json` | the v0.1.0 aggregator; 22 hooks; `oneOf` a RequestEnvelope or a ResponseEnvelope | -| `specification/v0.1.0/request-envelope.json` | JSON-RPC 2.0; method namespaces; `AcsParams` and its `metadata` identity fields | -| `specification/v0.1.0/response-envelope.json` | `AcsResult`, and the five decisions | -| `specification/v0.1.0/hooks/tool-call-request.json` | `steps/toolCallRequest` — `tool`, `arguments`, `operation`, `capability`, `intent` | -| `specification/v0.1.0/hooks/tool-call-result.json` | `steps/toolCallResult` — `exit_status`, `outputs`, `request_id_ref`, `duration_ms` | -| `specification/v0.1.0/ask-details.json` | what an `ask` decision must carry | -| `CONTRIBUTING.md` | DCO required (`git commit -s`); spec changes open a Discussion first; no CLA | - -Two things the repository does **not** have at that commit, both of which shaped this work: - -- **No reference implementation.** The README's roadmap places a Guardian Agent sample and - FastMCP instrumentation at v1. There is a `pyproject.toml`, but it serves the docs and - version-sync tooling. So there is nothing to conform *to* except the schemas, and this - adapter is written against them directly. -- **No `examples/` directory**, and so no house format for a community example. `examples/acs/` - therefore follows CTRLRun's own convention. - -## What ACS defines - -Three layers: **Instrument** (runtime hooks and the Guardian Agent pattern), **Trace** -(OpenTelemetry and OCSF with agent-specific conventions), and **Inspect** (CycloneDX, SPDX and -SWID for a dynamic Agent BOM). Only Instrument is relevant here. - -The wire format is JSON-RPC 2.0. A host fires a hook as a request whose `method` is -`steps/<hookName>`; a Guardian answers with an `AcsResult` carrying one of five decisions: - -```text -allow · deny · modify · ask · defer -``` - -`deny` requires `reasoning`. `modify` requires `reasoning` and `modifications`. `ask` requires -`reasoning` and `ask_details`. `defer` requires `reasoning` and `defer_details`. - -Of the 22 hooks, CTRLRun answers **two**, and it is worth being explicit that it declines the -other twenty: `SessionStart`, `SessionEnd`, `AgentTrigger`, `TurnStart`, `TurnEnd`, -`UserMessage`, `AgentResponse`, `KnowledgeRetrieval`, `MemoryContextRetrieval`, `MemoryStore`, -`PreCompact`, `PostCompact`, `SubagentStart`, `SubagentStop`, `SkillRegister`, `SkillLoad`, -`SkillUnload`, `SystemPing`, `AgbomSnapshot`, `AgbomChanged`. Those are checkpoints about what -the model is thinking, remembering or composed of. CTRLRun's product rule is that it decides -actions that can affect the real world, and nothing else — so an unanswered method returns a -JSON-RPC error in ACS's reserved range rather than an opinion. - -## The mapping, hook by hook - -### `steps/toolCallRequest` → build the Action, decide it, take the reservation - -| ACS field | CTRLRun | -|---|---| -| `params.metadata.agent_id` | `Principal.agent` — **only where no `identity` provider is configured**. With one it is **ignored**: not merged, not a fallback, not compared (SPEC-v0.3 §8.4) | -| `params.metadata.user_context.user_id` | `Principal.user`, under the same rule | -| `params.metadata.environment` | **ignored.** `Action.environment` is the hook's own configuration (SPEC-v0.3 §2.5, §8.4) | -| the transport's request headers | `IdentityContext.headers`, which is what an `identity` provider reads. `AcsControlHook.handle(envelope, headers=...)` | -| `payload.tool.name`, `payload.tool.provider`, `payload.operation` | `Action.name`, as `<prefix>.<provider>.<tool>[.<operation>]` | -| `payload.arguments` | `Action.arguments`, unwrapped from `{name: {value, provenance}}` to `{name: value}` | -| — *(ACS has no resource field)* | `Action.resource`, from the policy's `resource:` template (SPEC-v0.2 §3) | -| `params.request_id` | the continuation that joins this hook to its result | - -**Two fields stopped being read, and it is worth saying why.** Under v0.2 both `agent_id` and -`environment` came off the envelope, on exactly the argument `v0.2 §6.5` made for MCP's -`clientInfo`: a policy could not address the principal, so a self-reported one misattributed a -receipt and could not widen an outcome. SPEC-v0.3 §4 ends that — the principal is an -authorization input now, and a grant may scope to an environment — so a value the caller sets -would let the caller choose what it is authorized as and where. §8.1 removes -`ctrlrun gateway --principal-from-client-info` over the same sentence; the ACS hook was that -flag in a different module. - -The consequence is a **required argument**: an `AcsControlHook` built against a `Control` that -holds an `Authority`, with no `identity` provider, raises `InvalidArgument` at construction. -A hook with **no provider** still reads `agent_id`, unchanged, because there is then no -authorization decision for it to widen — and a hook holding an `Authority` cannot be in that -state. The branch is on the *provider*, not on the authority section: configuring one without -an `authority:` section also stops `agent_id` being read, which is the less surprising of the -two possible rules and the one that makes "with a provider, `agent_id` is display data" true -without a footnote. - -A configured provider that names nobody is a **refusal** — `deny`, -`reason_codes: ["no_principal"]`, no receipt and no events — and never a fall back to the -envelope: falling back would reach `agent_id` by an easier route than forging a credential. A -credential that was verified and has since **lapsed** is a different refusal and says so: -`reason_codes: ["principal_expired"]`, matching the `decision_reason` on the receipt -`Control` has already written. The two are told apart structurally — one is raised while the -Action is being built, the other by `Control.execute` — and never by reading a message. - -**One rule of §8.2 the hook does not import.** §3.1's repeated-identity-header refusal is the -gateway's, and it lives in `do_POST` because that is where a repeated HTTP field is still -visible. `AcsControlHook.handle(envelope, headers=...)` is handed a `Mapping[str, str]`, which -holds one value per name — so whatever built that mapping already chose. A deployment putting -this hook behind an HTTP server is responsible for that check, exactly as it is responsible -for the transport. Stated because it is a real gap rather than an argued omission. - -`operation` is part of the name because two verbs on one tool are two actions, and a policy has -to be able to say different things about `create` and `void`. - -The decision maps out: - -| CTRLRun | ACS | -|---|---| -| `ALLOW` | `allow` | -| `DENY` | `deny` + `reasoning` + `reason_codes` | -| `APPROVE` (`ApprovalRequired`) | `ask` + `reasoning` + `ask_details` | -| `DuplicateEffect` | `deny`, `reason_codes: ["ctrlrun.duplicate_effect", <state>]` | -| `AmbiguousEffect` | `deny`, `reason_codes: ["ctrlrun.ambiguous_effect"]` | -| `ApprovalMismatch` | `deny`, `reason_codes: ["ctrlrun.blocked", <reason>]` | -| `AuthorityDenied` | `deny`, `reason_codes: [<§4.3 reason>]` — it subclasses `ActionDenied`, and the reason is what tells the two apart | -| `IdentityError` | `deny`, `reason_codes: ["no_principal"]`. Deliberately a decision and not a protocol `error`: an error envelope says "the Guardian could not answer", and a platform is free to decide what to do with that | - -`ask_details` carries `approver` (`{type: "human", id}`), a `question` naming the request id a -human answers with `ctrlrun approve`, and `timeout_seconds`. All three are required by -`ask-details.json`. - -`ask_details.intent_extension` is **not** used. It grants capabilities for `this_request` or -`session`, which is an authority model — CTRLRun has none until v0.3, and a grant it cannot -represent is one it must not claim to honour. - -### `steps/toolCallResult` → close the reservation - -ACS describes this hook as *"fires after tool execution, before results reach the agent, -serving as an output redaction checkpoint"*. CTRLRun redacts nothing, so it always answers -`allow`; the work is the outcome it records. - -`exit_status` is `success | failure | timeout | blocked`. **ACS does not say what any of them -means for the side effect.** This is the fail-closed reading, and it is the same one -SPEC-v0.2 §6.8 applies to MCP: - -| `exit_status` | Effect state | Why | -|---|---|---| -| `success` | `COMMITTED` | the only status that asserts the effect happened | -| `blocked` | `FAILED` | a control refused it before dispatch — this is what `NotExecuted` means | -| `failure` | `AMBIGUOUS` | a tool that failed *after* acting and one that failed *before* send the same string | -| `timeout` | `AMBIGUOUS` | the same, and the case this library exists for | -| `failure` **with** `mcp.not_executed_on_error: true` | `FAILED` | an operator's per-tool assertion (SPEC-v0.2 §3.1) | - -A result whose `request_id_ref` matches no held reservation — a restarted Guardian, a result -fired twice, one arriving out of order — is logged and nothing is written about an effect. -Guessing which call it meant is how a duplicate gets committed. - -## Where ACS is silent - -These are not criticisms of ACS; they are the seam. ACS governs *whether an action may -proceed*. It has almost nothing to say about *what happened afterwards*, because that is not -what the Instrument layer was built for. - -**1. No effect identity.** `params.request_id` is a per-hook-invocation UUID and -`request_id_ref` links a result to its request. Neither identifies the *effect*: two calls that -would refund the same payment get two unrelated UUIDs. There is no idempotency key, no -`capability`-plus-argument identity, nothing an implementer could use to recognise that a retry -is a repeat. CTRLRun supplies one from the policy's `effect:` template. - -**2. `exit_status` is a status of the call, not an outcome of the effect.** Four values, and -the vocabulary itself carries the confusion: `timeout` sits alongside `failure` as though both -were kinds of not-working. The distinction that matters — *did the side effect land?* — has no -representation. A conformant Guardian reading `timeout` has no way to say "unknown, and a -retry is unsafe until a human resolves it". - -**3. Nothing binds an approval to the exact action.** `ask_details` carries a question and an -approver. What comes back is a decision on *the request*, and `intent_extension` can widen a -capability for the session. Neither pins the approval to a canonical form of the arguments, so -nothing in ACS prevents an agent from getting `refund(2000)` approved and then calling -`refund(5000)`. CTRLRun binds to `action_hash`, which covers the principal, the arguments, the -resource and the environment. - -**4. No terminal unknown state.** ACS's decisions are about the future of a call. There is no -way for a Guardian to record that an effect's outcome is unresolved and that *no* further call -on that effect may proceed until a human says which way it went. `AMBIGUOUS` has no ACS -counterpart, and it is the state most of CTRLRun's design exists to protect. - -**5. The Guardian does not execute.** ACS is advisory by construction — the platform runs the -tool. That is a reasonable separation, but it means a Guardian cannot make reserve-and-execute -atomic. The best available is what this adapter does: reserve at the request hook, close at the -result hook, and accept that a platform which never fires the result hook leaves a reservation -to lease-expire into `AMBIGUOUS` by the ordinary path of v0.1 §5.3 E3. - -## The adapter's design - -`ctrlrun.acs.AcsControlHook`, in `ctrlrun[gateway]` — it needs no new dependency, and it is -kept out of core for the same reason the gateway is: `import ctrlrun` must not grow. - -The shape is forced by the seam above. ACS is advisory and CTRLRun is executing, so one action -is split across two hooks and the reservation is held between them. That is exactly the shape -`Suspended` and `Control.resume` were built for in SPEC-v0.2 §6.9 — a reservation held across a -round trip the kernel does not control — so the adapter reuses them rather than reaching for -the store itself: - -```text -steps/toolCallRequest - → Action ← envelope metadata + payload + policy templates - → Control.execute(action, executor=raise Suspended(request_id), effect_key) - · policy decided, approval consumed, effect reserved, EXECUTION_STARTED - · executor suspends: no outcome, no receipt, lease extended, continuation held - → allow | deny | ask - -steps/toolCallResult - → Control.resume(request_id_ref, executor=report(exit_status)) - · the same outcome mapping execute uses (v0.1 §5.5) - · commit / fail / ambiguous, one receipt, same action_id and attempt - → allow -``` - -`Control` remains the only module that composes the others (ARCHITECTURE §6). The adapter -translates two vocabularies and decides nothing. - -**What it does not do.** It does not use `modify` — CTRLRun refuses or permits an action as -proposed, and rewriting an agent's arguments is a different product. It does not use `defer`. -It does not answer the other twenty hooks. It makes no claim of conformance: the schemas are -`v0.1.0`, the repository is a public preview, there is no reference implementation to test -against, and there is no conformance suite. **The words "ACS-compatible" do not appear in this -repository's README, docstrings or CLI output**, and should not until something exists to be -compatible *with*. - -## What the OTel attributes would have to become - -SPEC-v0.2 §8's sink emits `ctrlrun.*` attributes. ACS's Trace layer extends OpenTelemetry with -its own agent conventions and maps security events to OCSF; `acs_schema.json` carries -`TraceOtelMapping` and `TraceOcsfMapping` definitions for that purpose. - -Aligning would mean renaming `ctrlrun.action.name`, `ctrlrun.principal.agent`, -`ctrlrun.decision` and the rest onto ACS's conventions. The cost is not the rename: it is that -receipts already written carry the old names, and a receipt is evidence that has to outlive the -tool that wrote it. Any alignment is therefore additive — emit both, deprecate neither — or it -is a schema version bump on the receipt, which SPEC-v0.2 §11 explicitly does not do. - -That work is not in this release, and the mapping table is deliberately not written yet: it -would be a compliance claim with nothing behind it. diff --git a/docs/docs/ARCHITECTURE.md b/docs/docs/ARCHITECTURE.md deleted file mode 100644 index a773bd3..0000000 --- a/docs/docs/ARCHITECTURE.md +++ /dev/null @@ -1,242 +0,0 @@ ---- -title: "Architecture" -description: "The boundary CTRLRun owns, the six steps every protected call takes, the data model, and the key design decisions with their trade-offs." ---- - -Context: agent frameworks model work as `model → tool call → response`. That is fine for reads. For writes it is missing the semantics every serious system has around consequential operations: authorization bound to the exact operation, identity of the effect (not the request), atomic reservation, and an honest distinction between *failed* and *unknown*. CTRLRun adds those semantics around the dangerous part and nothing else. - -The contract is in [`SPEC-v0.1.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.1.md). This document explains the shape and the reasoning. - -## 1. The boundary CTRLRun owns - -``` -Agent reasoning (not ours) - │ "I want to do X" - ▼ -┌──────────────────────────────┐ -│ CTRLRun │ -│ normalize → decide → │ -│ approve → reserve → │ -│ execute → resolve → record │ -└──────────────────────────────┘ - │ - ▼ -Real-world effect (not ours either) -``` - -CTRLRun sits between *intention* and *consequence*. It does not sit between prompt and model. Everything upstream (planning, prompting, retrieval, memory) and everything downstream (the remote system's own semantics) is out of scope. - -## 2. Canonical flow - -``` -function call (kwargs) - │ - ▼ - ACTION ──────────── canonicalize ──► action_hash - │ - ▼ - POLICY ──► ALLOW / APPROVE / DENY (unknown → DENY) - │ │ │ - │ ▼ └──► receipt(denied) - │ approval request - │ │ - │ human grants (bound to action_hash) - │ │ - ▼ ▼ - consume approval + reserve effect (one transaction) - │ - ▼ - EXECUTING ──► executor runs - │ - ├── returns ──► COMMITTED - ├── raises NotExecuted ──► FAILED (retry permitted) - └── raises anything ──► AMBIGUOUS (retry refused; human resolves) - │ - ▼ - RECEIPT + events -``` - -## 3. Four public concepts - -Internally the machinery has a dozen types. Publicly a developer needs four: - -| Concept | Question it answers | -|---|---| -| **Action** | What exactly does the agent want to do? | -| **Decision** | Can it happen — automatically, with a human, or not at all? | -| **Effect** | What happened in the real world? | -| **Receipt** | Can we prove it? | - -Every other type is subordinate to one of these. Don't promote a fifth to the public surface before v0.3. - -## 4. Key decisions and trade-offs - -### 4.1 Autonomy is per action, not per agent -The same agent is autonomous for `customer.read`, supervised for `stripe.refund` over €500, and prohibited from `iam.grant_admin`. This is the product's central idea. There are no "modes"; there is one policy file. - -*Trade-off:* the policy language must stay tiny or this becomes OPA. v0.1 has six comparison ops and first-match-wins. That is deliberate. - -### 4.2 Approval binds to a hash, not a request ID -A human approves a *canonical action*, not a ticket. If the agent changes any material field between approval and execution, the hash differs and the approval is void. This is what makes human oversight mean something. - -*Trade-off:* canonicalization becomes security-critical. Floats are rejected because equal money can hash differently. Argument order must not matter. A schema version is embedded so future changes can't silently invalidate old approvals. - -### 4.3 Effect identity is separate from action identity -A retry is a new proposal (`action_id`) for the same logical effect (`effect_key`). Idempotency keyed on the request would let a retry through. Idempotency keyed on the *intent* (`refund:{payment_id}`) catches it. - -*Trade-off:* the developer has to declare the key. We make that one decorator argument and fail loudly on a bad template rather than silently degrading. - -### 4.4 AMBIGUOUS is a first-class terminal state -A timeout after a request was sent is not a failure. The remote may have committed. Frameworks that map timeout → failed → retry are how double refunds happen. CTRLRun refuses to guess: `AMBIGUOUS` blocks retries until a human resolves it. - -*Trade-off:* this creates operational work (someone must run `ctrlrun resolve`). That is the correct place for the work to land. v0.2 adds a `reconcile` hook (`SPEC-v0.2.md` §2) for executors that can ask the remote what happened: it is the second — and only other — authority permitted to move a record out of `AMBIGUOUS`, and only where its answer points. An answer it cannot give is `"unknown"`, which changes nothing. - -### 4.5 The executor opts into FAILED -Only `NotExecuted` maps to `FAILED`. Every other exception is `AMBIGUOUS`. The library cannot know whether an arbitrary exception fired before or after the side effect; the executor author can. Making the safe outcome the default means a lazy integration is a safe integration. - -### 4.6 Reservation is atomic across processes -Agents run as separate workers. Thread locks are not enough. SQLite with `BEGIN IMMEDIATE` and a unique constraint gives a real cross-process lock for a single host; Postgres (v0.6) extends it across hosts. The concurrency test spawns processes, not threads, so this can't regress unnoticed. - -### 4.7 Fail closed, not configurable -Unknown action, missing policy, expired approval, inconsistent state → `DENY`. There is no `default: allow`. Permissive defaults are the one thing that must be impossible by accident. If a user wants reads to be free, they list them. - -### 4.8 Receipts are portable JSON, not a dashboard -Evidence has to leave the system to be useful (audit, SIEM, a PR comment). JSONL on disk plus SQLite. No UI in v0.1, no server, no lock-in. - -### 4.9 Leases, not locks -A reservation that never completes (worker crash) can't hold the key forever, but it can't be silently released either — the effect may have happened. Expired lease → `AMBIGUOUS`. Same principle as 4.4. - -The length is the caller's (`Control(lease=...)`, `@protect(lease=...)`, five minutes by default) because only they know how long the work takes; the meaning of expiry is not. A default that is too short for a slow action would make every success ambiguous, and the user's remedy would be to drop the effect key and lose duplicate protection altogether — so we make the knob, not the escape hatch, the obvious move. - -## 5. Data model (SQLite) - -```sql -effects( - effect_key TEXT PRIMARY KEY, - state TEXT NOT NULL, - action_id TEXT NOT NULL, -- current/last attempt - attempt INTEGER NOT NULL DEFAULT 1, - lease_expires_at TEXT, - result_json TEXT, error TEXT, - created_at TEXT, updated_at TEXT -); -approvals( - approval_id TEXT PRIMARY KEY, - action_hash TEXT NOT NULL, - status TEXT NOT NULL, -- pending|granted|denied|expired|consumed - action_json TEXT NOT NULL, - approver TEXT, created_at TEXT, granted_at TEXT, expires_at TEXT, consumed_at TEXT -); -receipts(receipt_id TEXT PRIMARY KEY, action_id TEXT, effect_key TEXT, result TEXT, json TEXT, ts TEXT); -events(event_id INTEGER PRIMARY KEY AUTOINCREMENT, ts TEXT, type TEXT, action_id TEXT, effect_key TEXT, approval_id TEXT, data_json TEXT); -delegations( -- v0.3; a new table, which is why v0.3 needed no migration - delegation_id TEXT PRIMARY KEY, -- "dlg_" + 32 hex - parent_id TEXT NOT NULL, -- a root grant's id, or another delegation_id - depth INTEGER NOT NULL, -- recorded, never trusted: evaluation walks to the root - grant_json TEXT NOT NULL, -- the child grant; `state.py` stores the string, `authority.py` parses it - created_by_agent TEXT NOT NULL, created_by_user TEXT, - created_via TEXT NOT NULL, -- api|cli: an act, or an assertion at a terminal - created_at TEXT NOT NULL, revoked_at TEXT, revoked_by TEXT -); -schema_version( -- v0.6; SPEC-v0.6 §3. Applied migration ids, RECORDED and - migration_id TEXT PRIMARY KEY, -- never inferred: `PRAGMA table_info` answers "what is - applied_at TEXT NOT NULL, -- there", which is not "what has been applied", and the two - ctrlrun_version TEXT NOT NULL -- diverge the moment a migration does a backfill or a repair -); -receipt_chain( -- v0.6; SPEC-v0.6 §6.3. One row. The chain head, so that - id INTEGER PRIMARY KEY CHECK (id = 1), -- truncation at the END is detectable: deleting the - seq INTEGER NOT NULL, -- last N receipts leaves an internally consistent chain, and - hash TEXT NOT NULL -- only a head naming a seq no row carries catches it -); --- and `receipts` gains `seq`, `prev_hash` and `hash`, NULL for every row written before the --- chain existed. `0002_receipt_chain` does not backfill them (SPEC-v0.6 §3.7). -``` - -**The schema lives in `migrations.py`**, not here and not in `state.py`: from v0.6 a database is -brought to it by an ordered, forward-only runner rather than by replaying a script on open, and -two copies of the schema is the drift that item exists to prevent. - -`delegations` holds rows, not grants. `grant_json` stays a string in `state.py` so the store does -not import `authority.py` and transitively acquire `policy.py`, which is the edge §6 puts in -`state.py`'s "must not know about" column. - -Pragmas: `journal_mode=WAL`, `busy_timeout=5000`, `synchronous=NORMAL`. - -## 6. Module map - -| Module | Owns | Must not know about | -|---|---|---| -| `action.py` | model, canonicalization, hash | policy, storage | -| `policy.py` | YAML → rules → Decision; `effect:`/`resource:` templates | approvals, effect *state* | -| `identity.py` | `IdentityProvider`, `IdentityContext`, static and header providers | policy, authority, storage | -| `authority.py` | `Grant`, `Subject`, `Authority`, matching, containment, delegation planning | approvals, effect state, executors, sinks | -| `approval.py` | request/grant/consume, providers | executors | -| `adapter.py` | `FrameworkInterrupt`, `PendingApproval`, `ApprovalAnswer`, `InterruptApprovalProvider`, `needs_approval`, `banner` | the policy evaluator, authority, effect state, executors, sinks, any framework | -| `effect.py` | key templating, state enum, transition rules | SQLite | -| `migrations.py` | the schema, the ordered migration list, the runner, and whether a database may open at all | policy, decorator, sinks, `Control` | -| `state.py` | `StateStore` protocol + SQLite/in-memory impls | policy, decorator, sinks | -| `control.py` | `Control` orchestration, decorator, context, suspend/resume | CLI | -| `receipt.py` | Receipt/Event models, `EventSink`, JSONL sink | everything else | -| `verify/` | the guarantee registry, scenario derivation, the scratch store, reporting | the gateway, `otel`, `jwt_identity`; anything from an extra | -| `conformance/` | the adapter suites, the broken-adapter fixtures, the report | the gateway, `otel`, `jwt_identity`; anything from an extra | -| `cli/` | click commands, demo | internals beyond `Control` | - -Dependencies point downward only. `Control` is the only module that composes the others. - -`migrations.py` (v0.6) sits **beside** `state.py` rather than above it, and imports only stdlib -and `errors.py`. It is what decides whether a store may open, and a store whose admission check -lived somewhere else would be a store with two front doors. - -`verify/` (v0.4) sits **above** `control.py`, beside `cli/`: it composes `Control`, `Policy` and -`Authority` the way an application does, and nothing in the kernel imports it. `import ctrlrun` -does not import `ctrlrun.verify`, which is asserted in a subprocess — a verification tool in the -execution path is a dependency nobody meant to take. - -The gateway (v0.2) does not change this. It builds an Action and calls `Control` — including -`Control.resume` for an elicitation's second leg — rather than reserving and committing for -itself. A gateway that owned the reservation would be a second module composing the others, -and a second implementation of SPEC-v0.1 §5.5's asymmetry, which is the one rule in this -codebase that must not drift. - -The same holds for authority (v0.3). `authority.py` reads the store through the `StateStore` -protocol and **writes nothing and appends nothing**: `Authority.evaluate` returns a result and -`plan_delegation` returns the record it *would* write, and `Control` performs every write and -fans every event out to the sinks. An `Authority` that wrote for itself would be a second module -composing storage and evidence, and it would leave the highest-privilege operations in the -release as the only ones invisible to the export path (SPEC-v0.3 §4.8). - -One exception, added in v0.2 and worth stating rather than discovering: `policy.py` imports the -template grammar (`template_placeholders`) from `effect.py`, because SPEC-v0.2 §3.1 requires an -`effect:` / `resource:` template to be validated when the policy loads and the grammar is -security-critical enough that a second copy of it is worse than the import. Policy still knows -nothing of effect state — no records, no transitions, no reservations — and `effect.py` does not -import `policy.py`, so there is no cycle. - -v0.5 adds `conformance/` beside `verify/` and `cli/`, above `control.py`: it composes the -kernel the way an application does, nothing in the kernel imports it, and `import ctrlrun` does -not reach it. It is core, and adds no dependency, for `verify/`'s reason — a check somebody has to -remember to install is a check that does not run — and `SPEC-v0.5.md` §12.1 records why it is -not the extra it was planned as. - -v0.5 adds `adapter.py` below `control.py` and does not change the direction. It imports -`action.py`, `approval.py`, `effect.py`, `errors.py` and two names from `policy.py` — `OBSERVE` -for the banner and `Decision` for the predicate — and takes a `Control` as a **parameter** in -`needs_approval` and `banner` rather than importing it at module scope, so there is no cycle and no second composer: -it appends no event, owns no sink, and reserves nothing. The one place it writes is -`grant_approval`/`deny_approval` in `InterruptApprovalProvider.wait`, which is the same call -`ctrlrun approve` and the webhook make — and it is the *only* place, so no adapter can grow a -second approval path even by accident (SPEC-v0.5 §2.4). - -v0.3 makes the same exception once more, for the same reason: `authority.py` imports the -condition parser and evaluator (`Condition`, `parse_conditions`) from `policy.py`, because a -grant's `constraints:` is in exactly a rule's `when:` syntax and the two axes MUST share one -evaluator (SPEC-v0.3 §4.5). A second condition evaluator would be a second place for `True` to -start comparing equal to `1`. `policy.py` does not import `authority.py`, so there is no cycle, -and policy still cannot see a principal: `agent_eq` and every other reserved name are still -refused at load (§4.7). - -## 7. What changes after v0.1 (and what doesn't) - -Stable from v0.1 onward: the four public concepts, the action canonical form (versioned), the effect state machine, fail-closed defaults, the executor outcome mapping. - -Expected to change: policy language (providers), StateStore backends, approval providers, receipt fields (additive only). See [`ROADMAP.md`](/docs/ROADMAP). diff --git a/docs/docs/CLAIMS.md b/docs/docs/CLAIMS.md deleted file mode 100644 index ffde802..0000000 --- a/docs/docs/CLAIMS.md +++ /dev/null @@ -1,309 +0,0 @@ ---- -title: "Claims" -description: "Every sentence of the README mapped to the code that implements it and the test that proves it, re-derived at every release." ---- - -Every sentence of the README that asserts something about the shipped code, mapped to the code -that implements it and the test that proves it. - -**This table is regenerated at every release.** A claim that loses its code or its test is -removed from the README in the same commit — the README is not allowed to describe behaviour -that no longer ships. If you find a row here that does not hold against the version you -installed, that is a bug: please open an issue. - -Regenerated for: **v0.6.0**. Line numbers refer to the commit this file was regenerated on, and `scripts/repoint-claims.py` re-derives them for the commits in between — it **refuses** rather than guessing when a symbol has no definition, because a row pointing at a docstring that happens to contain the right word makes the guard green and the claim false. `test_the_claims_table_line_numbers_point_at_what_they_name` resolves every one against the line it cites. - -The rows follow the README's sections. `docs/capabilities.yaml` names one row per capability -by its quoted claim, and `tests/test_docs_audit.py` fails if a named row is not here. - -## The header - -> The last check before an AI agent does something it can't undo. Autonomy belongs to the -> action, not the agent. A consequential action happens at most once, exactly as approved, and -> leaves a receipt — and when the outcome is unknown, CTRLRun says so instead of guessing. -> A Python library that sits between the decision to act and the call that acts. - -| Claim | Code | Proof | -|---|---|---| -| "The last check before an AI agent does something it can't undo." | `Control.execute` — `control.py:547` — resolves the principal, evaluates authority and policy, consumes the approval and reserves the effect key **before** the executor runs; nothing in the wrapper calls the function first | `test_T1_a_blind_retry_is_refused_and_never_reaches_the_remote`, `test_T3_the_fake_remote_is_called_exactly_once` | -| "Autonomy belongs to the action, not the agent." | `Policy.evaluate(action)` — `policy.py:495` — passes only the action's **name and arguments** to `_ActionPolicy.evaluate` (`policy.py:495`), whose signature has no principal in it. A rule cannot read who is acting even by accident. `agent_eq` and `user_eq` are refused at load by `RESERVED_ARGUMENTS` (`policy.py:150`) rather than silently matching nothing. | `test_T6_an_action_name_is_matched_exactly`, `test_a_condition_naming_an_action_field_is_refused_at_load` | -| "A consequential action happens at most once, exactly as approved, and leaves a receipt — and when the outcome is unknown, CTRLRun says so instead of guessing." | At most once: `plan_reservation` — `effect.py:163`. Exactly as approved: the approval is bound to `action_hash` and consumed with the reservation — `_authorize_and_reserve` — `state.py:832`. Or not at all: a refusal raises before the executor — `Control.execute` — `control.py:547`. Says so instead of guessing: only `NotExecuted` maps to `FAILED` — `control.py:1067` — and everything else is `AMBIGUOUS`. A receipt: `Receipt` — `receipt.py:245`. **This sentence read *happens once … or not at all* until 0.6**, a two-way disjunction that excluded the third outcome the product exists for: a lost reply is neither, and the README's own first section says so. | `test_T3_exactly_one_agent_reserves_and_seven_are_blocked`, `test_T2_a_mutated_action_presenting_the_approval_raises_ApprovalMismatch`, `test_T1_a_lost_response_leaves_the_effect_ambiguous`, `test_T11_every_demo_receipt_carries_every_field_in_the_spec` | -| "A Python library that sits between the decision to act and the call that acts." | `@protect` — `control.py` — wraps the callable that acts, and `Control.execute` runs every check before invoking it. The category noun was on `docs/docs.mdx` and in `pyproject.toml`'s `description` and nowhere in the README until 0.6, so a reader had to infer what CTRLRun **is** from three slogans. | `test_the_header_carries_the_fixed_copy_and_the_five_badges`, `test_T1_a_blind_retry_is_refused_and_never_reaches_the_remote` | -| "Runs in production on a single file, or on Postgres across hosts" | SQLite: `SQLiteStateStore` reserves inside the `BEGIN IMMEDIATE` of `_authorize_and_reserve` — `state.py:1006` — which is a write lock on the file and holds across OS processes. Postgres: `PostgresStateStore` over `UNIQUE(effect_key)` with `INSERT … ON CONFLICT DO NOTHING` and checked row counts (SPEC-v0.6 §4.2), the same `StateStore` protocol, extended by nothing | `test_T3_exactly_one_agent_reserves_and_seven_are_blocked` (8 OS processes, both backends), `test_T141_the_shipped_backends_pass`, `test_T154_postgres_passes_the_store_conformance_suite` | - -## The refund that happened twice - -| Claim | Code | Proof | -|---|---|---| -| "A lost reply is `AMBIGUOUS`, never `FAILED`, and a retry against an `AMBIGUOUS` effect is refused — until a human, or a `reconcile` hook, says what happened." | Only `NotExecuted` maps to `FAILED` — `control.py:1067`; a retry against an `AMBIGUOUS` key is refused by `plan_reservation` — `effect.py:163`; the two things permitted to move the record on and nothing else — `resolve` — `cli/main.py:518` — and `Control._reconciled` — `control.py:1495` | `test_T1_a_lost_response_leaves_the_effect_ambiguous`, `test_T1_a_blind_retry_is_refused_and_never_reaches_the_remote`, `test_T160_there_is_no_reaper`, `test_T13_a_hook_answering_not_executed_moves_the_record_to_failed` | -| "The customer is refunded twice, and nothing in the stack noticed." — said of a stack without CTRLRun; the demo runs the same sequence with it, and counts the calls the remote received | `ctrlrun demo` scenario 1, which retries against a fake remote that counts its calls and prints the count | `test_T3_the_fake_remote_is_called_exactly_once`, `test_T1_a_blind_retry_is_refused_and_never_reaches_the_remote` | - -## Protect your first action - -| Claim | Code | Proof | -|---|---|---| -| the starter says a namespace delete needs a human, and holds a refund by amount | `EXAMPLE_POLICY` — `cli/main.py` — is `ctrlrun.example.yaml`, byte for byte | `test_the_shipped_example_policy_is_the_one_in_the_repository`, `test_the_shipped_example_policy_loads_and_evaluates` | -| the `ctrlrun init` and decorator blocks, and the `else:` that fails if the delete ran without a human | the blocks are `runnable` and run in one temporary directory, in document order, offline | `test_the_readme_and_docs_snippets_run` | -| the six-row table: allowed, `ApprovalRequired`, `ApprovalMismatch`, `ActionDenied`, `AmbiguousEffect`, `DuplicateEffect` | one exception per row — `errors.py`; each is the matrix row that names it, below | the "What it guarantees" rows, and `test_T2_a_mutated_action_presenting_the_approval_raises_ApprovalMismatch`, `test_T6_unknown_action_is_denied_with_reason_unknown_action`, `test_T1_a_blind_retry_is_refused_and_never_reaches_the_remote`, `test_T3_exactly_one_agent_reserves_and_seven_are_blocked` | - -## The problem, and how it works - -| Claim | Code | Proof | -|---|---|---| -| "A lost reply is `AMBIGUOUS`, never `FAILED`, and a retry against an `AMBIGUOUS` effect is refused." | Only `NotExecuted` maps to `FAILED` — `control.py:1067`; `plan_reservation` — `effect.py:163` | `test_T1_a_lost_response_leaves_the_effect_ambiguous`, `test_T1_a_blind_retry_is_refused_and_never_reaches_the_remote` | -| "reserved atomically across processes and hosts; one worker wins" | `reserve_effect` — `state.py:405`; `PostgresStateStore.reserve_effect` — `postgres.py:528` | `test_T3_exactly_one_agent_reserves_and_seven_are_blocked`, `test_T154_postgres_passes_the_store_conformance_suite` | -| "bound to the hash of the exact action a human saw, used once, and refused for anything else" | `_authorize_and_reserve` — `state.py:832` | `test_T2_a_mutated_action_presenting_the_approval_raises_ApprovalMismatch`, `test_T4_replaying_the_approval_raises_ApprovalMismatch_with_reason_consumed` | -| "An action the policy does not list is denied" | `Policy.evaluate` — `policy.py:495` | `test_T6_unknown_action_is_denied_with_reason_unknown_action` | -| "Authority first ... then policy" / "authority first" | `Control.execute` evaluates authority before policy and a denial appends `AUTHORITY_DENIED` and never `POLICY_EVALUATED` — `control.py:547` | `test_T74_a_denial_leaves_no_pending_approval_request` | -| "Neither axis reads the agent's instructions" | `Policy.evaluate` — `policy.py:495` — sees the action's name and arguments; `Authority.evaluate` — `authority.py:806` — sees the action and the principal; neither is handed a prompt, a message or a tool result | `test_T6_an_action_name_is_matched_exactly`, `test_T67_a_principal_with_no_grant_is_denied` | -| "canonical arguments (sorted keys, no floats) ... Its SHA-256 is the action hash" | `canonicalize` / `action_hash` — `action.py`; `float` refused at any depth — `action.py:71` | `test_T7_canonical_form_is_exactly_the_specified_serialization`, `test_T7_nested_dicts_are_sorted_recursively` | -| "The approval is single-use, expires, and matches nothing but that exact action." | `_authorize_and_reserve` — `state.py:832` — checks expiry at consumption | `test_T5_expiry_is_checked_at_consumption_not_only_at_grant`, `test_T4_replaying_the_approval_raises_ApprovalMismatch_with_reason_consumed` | -| "Only `NotExecuted`, raised by you, means `FAILED`." | `control.py:1067`; `NotExecuted` — `errors.py:157` | `test_T1_a_lost_response_leaves_the_effect_ambiguous` | -| "the hash of the policy that decided it, chained to the receipt before it" | `Policy.policy_hash` — `policy.py:609`; `prev_hash`, `GENESIS_HASH` for the first — `receipt.py:284` | `test_T172_every_receipt_carries_the_hash_and_the_declared_version`, `test_T164_an_altered_receipt_is_content_altered_at_its_seq` | - -## Three ways to use it - -| Claim | Code | Proof | -|---|---|---| -| "You probably do not need an adapter" | Three ways in, and `@protect` (`control.py:2006`) covers this process while the gateway covers MCP — an adapter buys only the interrupt | `test_T139_the_adapter_section_says_when_you_do_not_need_one_up_front` | -| "`ctrlrun init` writes a starter" | `init` — `cli/main.py:340` | CI's `package` job runs `ctrlrun init` from the wheel and asserts `ctrlrun.yaml` exists | -| "The human runs `ctrlrun approve <request id>` and the agent calls again inside `ctrlrun.with_approval(request_id)`" | `approve` — `cli/main.py:364`; `with_approval` — `control.py:164`; `ApprovalRequired` (`errors.py:88`) carries `request_id` | `test_T2_a_mutated_action_presenting_the_approval_raises_ApprovalMismatch` (the granted path first), `test_T4_replaying_the_approval_raises_ApprovalMismatch_with_reason_consumed` | -| "No agent changes" | `INTERCEPTED_METHOD` is `tools/call` and every other method is relayed unchanged — `gateway/mcp.py:40` | `test_a_non_intercepted_method_is_relayed_with_no_ctrlrun_outcome` | -| "Point the MCP client at the gateway instead of at the tool server" | `Gateway.handle` — `gateway/server.py:385`; `serve` — `gateway/__init__.py:41` | `test_T19_the_upstream_receives_the_canonical_arguments` | -| "Tools become actions named `mcp.<alias>.<tool>`" | `Gateway._intercept` — `gateway/server.py:442` | `test_T19_the_action_is_named_for_the_alias_and_the_tool` | -| "they are declared in the policy" (effect and resource templates for a tool call) | `Policy.effect_template` / `resource_template` — `policy.py:705`; `McpOptions` — `policy.py:460` | `test_T16_a_v2_document_loads_and_exposes_its_templates`, `test_T16_a_decorator_and_a_policy_template_produce_the_same_action_hash` | -| "Everything but `tools/call` is relayed untouched" | `parse_request(...).intercept` — `gateway/mcp.py:84` | `test_every_other_method_is_relayed_not_intercepted` | -| "A lost response over the wire blocks the retry exactly as it does in process" | `classify` — `gateway/outcome.py:144`, translated into v0.1 §5.5's own vocabulary by the gateway's executor | `test_T23_the_identical_call_sent_again_is_refused_and_the_upstream_called_once` | -| "the gateway prints, on the line that starts it, every action in your policy that has no `effect:` template" | `_announce` — `gateway/__init__.py:146` | `test_the_startup_block_names_the_environment_identity_and_authority`, `test_the_startup_block_says_so_when_there_is_no_authority_section` | -| "route an `approve` decision through **the framework's own interrupt**" | `FrameworkInterrupt` — `adapter.py:180` — is a Protocol with one method returning a value; it holds no state and writes nothing | `test_T135b_the_adapter_reuses_the_sdks_primitive_and_reimplements_nothing` | -| "one core provider writes the grant through the same calls `ctrlrun approve` makes" / "There is never a second place to say yes" | `InterruptApprovalProvider.wait` — `adapter.py:254` — calls `grant_approval` / `deny_approval`, and an adapter calls neither | `test_T130_each_broken_fixture_fails_the_suite_named_for_it` | -| "an adapter never constructs one and never supplies a principal" | `needs_approval` — `adapter.py:408` — resolves the principal from the `Control` so no adapter builds an `Action` | `test_T129_no_public_callable_takes_a_principal`, `test_T129_the_module_exposes_no_way_to_construct_a_control` | -| "prevention" / "attribution" | `carries_approved_arguments` gates §3.4's rebuild in `_check_answer` — `adapter.py:320` | `test_T137b_the_readme_says_the_binding_is_attribution_and_why` | -| "Adapters ship on their own version line" | `adapters/*/pyproject.toml`, never in the `ctrlrun` wheel or sdist | `test_T136_the_ctrlrun_distributions_contain_no_adapter` | - -## Write down what the agent may do - -| Claim | Code | Proof | -|---|---|---| -| "cheap to undo is autonomous, anything that leaves the building needs a human, money is by amount with both ends bound" | `Decision` — `policy.py:234` — is exactly `allow`, `approve`, `deny`; rules match first-wins over `Condition` (`policy.py:298`) with the operators `eq`, `neq`, `in`, `lt`, `lte`, `gt`, `gte` — `_OPERATORS` — `policy.py:83` | `test_T6_an_action_name_is_matched_exactly`, `test_T176_the_operators_behave_as_they_do_everywhere_else` | -| "Unknown actions are denied; there is no default-allow." | `Policy.evaluate` — `policy.py:495` | `test_T6_unknown_action_is_denied_with_reason_unknown_action` | -| "Amounts are integer minor units; floats are rejected outright" | `float` refused at any depth — `action.py:71` | `test_T7_canonical_form_is_exactly_the_specified_serialization` | -| "The policy cannot see who is asking — deliberately, since v0.1" | `Policy.evaluate` still takes only the action's name and arguments; `RESERVED_ARGUMENTS` — `policy.py:150` — refuses `agent_eq` and every other principal-addressing condition at load, in a document of **every** schema version | `test_T74b_a_reserved_name_in_a_policy_rule_is_a_load_error`, `test_T74b_a_reserved_name_in_a_grant_constraint_is_a_load_error` | -| "the second axis, `authority:`" | `Authority.evaluate` — `authority.py:798`; `Control._authority_result` — `control.py:408` | `test_T67_a_principal_with_no_grant_is_denied` | -| "opt-in, and then fail-closed" | `_optional_authority` returns `None` for a document with no section — `control.py`; `Control.authority is None` is v0.2 behaviour exactly | `test_T66_a_document_with_no_authority_section_leaves_control_authority_none`, `test_T66_no_authority_event_is_appended_without_a_section`, and T66's session-wide guard in `tests/conftest.py` | -| "every principal needs a grant and no grant means denied" | `NO_AUTHORITY` — the fail-closed default of `Authority.evaluate` (`authority.py:64`), reached for reads and for actions with no effect key alike | `test_T67_an_action_the_policy_allows_outright_still_needs_a_grant` | -| "A grant carries no `decision:`" | `_GRANT_KEYS` — `authority.py` — is a closed set that does not contain `decision` | `test_T73b_grant_refuses_what_the_loader_refuses` | -| "combine as the **stricter of the two**" | `Control.evaluate` returns the combined result — `control.py`; a denial on either axis is a denial | `test_T70_the_stricter_of_the_two_wins` | -| "narrow it at runtime with `ctrlrun delegate`" | `Control.delegate` — `control.py:1673`; `Authority.plan_delegation` — `authority.py:877`; `ctrlrun delegate` — `cli/main.py:898` | `test_t75_the_delegation_authorizes_an_action_within_its_limits` | -| "provably a subset of its parent on every dimension, at creation and again at every evaluation" | `contained_dimension` — `authority.py:603` — runs from `plan_delegation` (`authority.py:877`) **and** from the chain walk in `Authority.evaluate` (`authority.py:806`) | `test_t76_each_dimension_violated_alone`, `test_t77b_a_narrowed_parent_narrows_its_children` | -| "omitting a dimension the parent constrains is rejected rather than inherited" | `contained_dimension` treats an absent child dimension as unconstrained and therefore wider — `authority.py:603`; the subject half is `_subject_contained` (`authority.py:634`) | `test_t81_omission_is_not_unlimited`, `test_T73b_a_subject_addressed_to_every_principal_is_refused`, `test_t76_each_dimension_violated_alone` | -| "`ctrlrun revoke` cuts a chain of any depth with one write" | `Control.revoke` — `control.py:1689` — writes one row — `revoke_delegation` — `state.py:554` and visits no children; every evaluation walks to the root | `test_t78_a_revoked_parent_denies_its_grandchild`, `test_put_delegation_is_never_an_upsert` | -| "`mode: observe` … records what *would* have been blocked, without blocking anything" | `_parse_mode` — `policy.py:594`; `Control._observed` — `control.py:743`; `_WouldHave` — `receipt.py:191`; `ReceiptResult.OBSERVED` — `receipt.py:191` | `test_T82_observe_executes_what_enforce_would_deny`, `test_T83_a_duplicate_is_recorded_and_still_runs` | -| "One top-level line" | `mode:` is refused anywhere but the top level — `reject_nested_mode`, `policy.py:594` | `test_T84_mode_is_refused_anywhere_but_the_top_level` | -| "`ctrlrun stats` gives you the numbers" | `stats` — `cli/main.py:727`; counted from `would_have.blocked_reason` and nothing else | `test_T86_stats_counts_what_observe_mode_recorded`, `test_T86_stats_reaches_no_network` | -| "It is not a dry run: it executes" | `_observed` runs the executor on every path, including the ones enforce mode would have refused — `control.py:743` | `test_T82_observe_executes_what_enforce_would_deny`, `test_T83_an_executor_that_fails_on_a_held_key_still_writes_the_record` | - -## Prove it holds in your setup - -| Claim | Code | Proof | -|---|---|---| -| "runs the kernel's own failure scenarios against the configuration in front of it" | `ctrlrun.verify.run` — `verify/__init__.py:154`; the eleven guarantees — `GUARANTEES` — `verify/guarantees.py:39`; the scenarios — `verify/scenarios.py` | `test_T100_the_authority_example_passes_every_non_authority_guarantee` (11/11), `test_T100_a_v1_document_with_no_templates_and_no_grants` | -| "in a scratch store, with fake executors, and no network" | One scratch store per guarantee under a temporary directory — `verify/scenarios.py`, `Engine.control`; `state_path()` is never called and `Control.from_file()` is never used | `test_T103_the_operators_store_is_byte_identical_before_and_after`, `test_T103_a_store_that_does_not_exist_is_not_created`, `test_T107_a_full_run_completes_with_no_network` | -| "Your `.ctrlrun/state.db` is byte-identical before and after" | The scratch path is a `tempfile.mkdtemp` removed in a `finally` — `verify/__init__.py` | `test_T103_the_operators_store_is_byte_identical_before_and_after` (SHA-256 and `st_mtime_ns`), `test_T103_CTRLRUN_STATE_is_not_read_and_not_created` | -| "Not applicable is not a pass" | `Report.applicable` is passes plus failures — `verify/report.py`; every N/A reason is a statement about the document — `verify/guarantees.py` | `test_T101_a_policy_with_no_approve_rule_makes_G1_and_G2_not_applicable`, `test_T102_a_policy_with_no_effect_templates_makes_G3_G4_and_G5_not_applicable` | -| "`6/6 (5 not applicable)`, never `11/11`" | `Report.summary_line` — the N/A ids are a separate sentence, never a parenthesis inside the fraction | `test_T113_the_summary_is_the_last_line_and_names_the_not_applicable_ids` (asserts `11/11` appears nowhere in an N/A run) | -| "There is no flag that folds one into the count" | There is no such parameter on `run()` (§9.1 freezes the signature) and no such option on the CLI | `test_T101b_zero_applicable_guarantees_is_not_a_pass` — `0/0` exits **2** | -| The quoted report | A real run, asserted line by line against `run(examples/authority/payments.yaml)`. The README carried a second copy until the 2026-09-09 rewrite; `docs/docs/verify.md` is now its only home, and the README keeps the badge sentence | `test_the_verify_page_quotes_the_real_verify_output`, `test_the_readme_says_what_the_badge_does_not_mean` | -| "means the **declared guarantees pass**" | `badge_from_document` — `verify/report.py`; the phrase is the first sentence under `docs/docs/verify.md#what-the-badge-means` | `test_T119_the_rendered_badge_text_is_exactly_CTRLRun_verified_N_over_M`, `test_T119_the_link_target_carries_the_exact_phrase` | -| "It does not mean secure, safe, compliant, certified or audited" | Those words appear in `docs/docs/verify.md` only inside the sentence that refuses them, and nowhere in the badge, the summary, `action.yml` or the workflow | `test_T119_no_claim_uses_the_forbidden_vocabulary`, `test_T119_the_action_and_the_workflow_make_no_forbidden_claim` | -| "There is a GitHub Action" | `action.yml` at the repository root — composite, one verify run, summary and badge rendered from its JSON | `test_T118_the_action_is_a_composite_action_at_the_repository_root`, and CI's own `verify` job against both example configurations | -| "verify has no flag that relaxes a check" | No argument and no environment variable changes what `verify` builds — SPEC-v0.4 §3.9 | `test_T101b_zero_applicable_guarantees_is_not_a_pass`, `test_T107_a_full_run_completes_with_no_network` | - -And the four things the verify section deliberately does **not** claim, each with the test that -keeps it honest: - -| Not claimed | Why | Where the limit is asserted | -|---|---|---| -| That verify checks the operator's executors | It never calls the function behind `@protect` and never imports the module it lives in | `docs/docs/verify.md`, "What it does not mean"; `THREAT_MODEL.md`, "Known v0.4 limitations" | -| That a green badge means the configuration is a good one | The guarantees are about the kernel doing what it says *under* that configuration | `test_T119_no_claim_uses_the_forbidden_vocabulary` | -| That a guarantee reported N/A was checked | It was not, and the reason is on the line | `test_T113_every_not_applicable_line_carries_its_reason` | -| That a partial run means anything about the whole | `--only` writes no badge at all | `test_T120_a_partial_run_writes_no_badge` | - -## The capability matrix - -Rendered from `docs/capabilities.yaml`; the six rows are the six groups of the verify -catalogue, `GUARANTEES` (`verify/guarantees.py:39`). - -| Claim | Code | Proof | -|---|---|---| -| "An approval is bound to the exact action; a mutated or replayed one is refused." | `action_hash` — `action.py`; the approval record stores it and `_authorize_and_reserve` compares it — `state.py:418`; single use is the `granted → consumed` transition in the same `BEGIN IMMEDIATE` | `test_T2_a_mutated_action_presenting_the_approval_raises_ApprovalMismatch`, `test_T4_replaying_the_approval_raises_ApprovalMismatch_with_reason_consumed`, `test_T5_expiry_is_checked_at_consumption_not_only_at_grant` | -| "One logical effect happens at most once, across threads, processes and hosts." | `reserve_effect` — `state.py:405`, decided inside the `BEGIN IMMEDIATE` of `_authorize_and_reserve` (`state.py:832`) against `effect_key TEXT PRIMARY KEY` (`migrations.py:107`; `COLLATE "C"` on Postgres, §4.4) | `test_T3_exactly_one_agent_reserves_and_seven_are_blocked` (8 OS processes, both backends), `test_T3_the_fake_remote_is_called_exactly_once` | -| "An unknown outcome is AMBIGUOUS, never FAILED, and blocks a blind retry." | Only `NotExecuted` maps to `FAILED` — `control.py:1067`. Every other exception, timeouts included, yields `AMBIGUOUS`. A retry against an `AMBIGUOUS` key is refused — `effect.py:163`, the one place `plan_reservation` decides it for every store | `test_T1_a_blind_retry_writes_a_blocked_receipt`, `test_T1_the_ambiguous_record_survives_the_blocked_retry`, `test_T1_a_lost_response_leaves_the_effect_ambiguous` | -| "An unknown action, a missing policy or a missing principal is denied." | Unknown action: `Policy.evaluate` — `policy.py:678` — answers `deny` for a name the document does not list. Missing or malformed policy: `Policy.from_file` — `policy.py:628` — raises `PolicyError`, and there is no `Control` without a policy. Missing principal: `_refuse_no_principal` — `control.py:1888` | `test_T6_unknown_action_raises_ActionDenied_with_reason_unknown_action`, `test_missing_policy_file_is_a_policy_error`, `test_malformed_policy_document_is_a_policy_error`, `test_T62_a_declining_provider_with_no_context_is_no_principal` | -| "With authority on, every principal needs a grant, and delegation cannot widen one." | `NO_AUTHORITY` — the fail-closed default of `Authority.evaluate` (`authority.py:64`); `contained_dimension` — `authority.py:603` — runs from `plan_delegation` (`authority.py:877`) and from the chain walk in `Authority.evaluate` | `test_T67_a_principal_with_no_grant_is_denied`, `test_t76_each_dimension_violated_alone` | -| "Every executed action leaves a portable JSON receipt" | `ReceiptResult` — `receipt.py:429`; `Event` — `receipt.py:429`; the store is authoritative — `append_event` — `state.py:565`; the JSONL export — `JSONLEventSink` — `receipt.py:429` | `test_T11_every_demo_receipt_carries_every_field_in_the_spec`, `test_T11_every_demo_receipt_parses_back_into_a_Receipt` | - -## What it guarantees - -| Claim | Code | Proof | -|---|---|---| -| "On SQLite that is `BEGIN IMMEDIATE`" | `_authorize_and_reserve` — `state.py:832` | `test_T3_exactly_one_agent_reserves_and_seven_are_blocked` | -| "a unique index on the effect key and compare-and-set updates whose row counts are checked" | `reserve_effect` — `postgres.py:528` — `INSERT … ON CONFLICT DO NOTHING` against `effect_key TEXT PRIMARY KEY COLLATE "C"` (`migrations.py:107`) | `test_T3_exactly_one_agent_reserves_and_seven_are_blocked` (8 OS processes, both backends) | -| "Same `StateStore` protocol, extended by nothing" | `PostgresStateStore.reserve_effect` — `postgres.py:528` — and every other method implement `v0.1 §5.3`'s frozen protocol; the decisions stay in `plan_reservation` (`effect.py:163`) | `test_T154_postgres_passes_the_store_conformance_suite` | -| "graded by the suite written for SQLite" | `ctrlrun.conformance.store.run` — `conformance/store/__init__.py:52` | `test_T140_every_fixture_fails_the_suite_named_for_it` | -| "It will not *knowingly* execute the same logical effect twice, and will never treat an unknown outcome as a failure." | `plan_reservation` — `effect.py:163` (refuse retry on `AMBIGUOUS`) and `control.py:1067` (only `NotExecuted` → `FAILED`) | `test_T1_a_blind_retry_is_refused_and_never_reaches_the_remote`, `test_T1_a_lost_response_leaves_the_effect_ambiguous` | -| "a lost connection during `COMMIT` ... are `AMBIGUOUS`" | `_resolve_lost_insert` — `postgres.py:670`; `_resolve_lost_update` — `postgres.py:1017`; only `NotExecuted` maps to `FAILED` — `control.py:1067` | `test_T155_a_connection_killed_during_commit_is_resolved_by_the_re_read`, `test_T155_no_effect_is_ever_recorded_failed_by_a_lost_commit` | -| "the store re-reads the row to find out which" | The six branches, named and logged — `A2_LANDED` — `postgres.py:127` | `test_T155b_a_landed_commit_on_a_transition_is_seen_as_landed`, `test_T155d_a_commit_the_server_never_received_retries_the_insert` | -| "A crashed worker's effect stays `AMBIGUOUS` until a human runs `ctrlrun resolve` or a `reconcile` hook asks the remote what happened" | An expired lease is `AMBIGUOUS` and nothing sweeps it — `LEASE_EXPIRED` — `effect.py:63`; who resolved it — `resolved_by` — `effect.py:63`; `resolve` — `cli/main.py:518` | `test_T159_ambiguous_survives_a_restart_and_still_refuses_a_blind_retry`, `test_T160_there_is_no_reaper`, `test_T161_a_human_resolution_records_who` | -| "the only thing besides a human permitted to move a record out of `AMBIGUOUS`" | `Control._reconciled` — `control.py:1495`; `RECONCILED_STATES` — `effect.py` | `test_T13_a_hook_answering_not_executed_moves_the_record_to_failed`, `test_T14_a_hook_answering_committed_refuses_the_retry_as_a_duplicate` | -| "and only in the direction its answer points" | `"unknown"` is absent from `RECONCILED_STATES` — `effect.py` | `test_T15_a_hook_that_cannot_answer_leaves_the_record_ambiguous` | -| "Unknown action, missing policy, malformed policy, missing principal, missing or mismatched approval and inconsistent state are all `deny`." | `Policy.evaluate` — `policy.py:495`; `Policy.from_file` — `policy.py:628`; `_refuse_no_principal` — `control.py:1888`; `_authorize_and_reserve` — `state.py:832` | `test_T6_unknown_action_raises_ActionDenied_with_reason_unknown_action`, `test_malformed_policy_document_is_a_policy_error`, `test_T62_a_declining_provider_with_no_context_is_no_principal`, `test_T2_a_mutated_action_presenting_the_approval_raises_ApprovalMismatch` | -| "No flag makes a consequential action permissive by default" | There is no such option on `Control`, on `@protect`, on the CLI or in the policy schema's closed key sets — `_TOP_LEVEL_KEYS` — `policy.py:87` | `test_T84_mode_is_refused_anywhere_but_the_top_level`, `test_T101b_zero_applicable_guarantees_is_not_a_pass` | -| "With `authority:` on, every principal needs a grant, delegation cannot widen one, and `ctrlrun revoke` cuts a chain with one write." | `Authority.evaluate` — `authority.py:798`; `contained_dimension` — `authority.py:603`; `Control.revoke` — `control.py:1689` | `test_T67_a_principal_with_no_grant_is_denied`, `test_t76_each_dimension_violated_alone`, `test_t78_a_revoked_parent_denies_its_grandchild` | -| "verifies a bearer token against a JWKS or a pinned key" | `JWTIdentityProvider._verified` — `jwt_identity.py:175`; the algorithm comes from the configured list and never from the token | `test_T88_a_valid_token_becomes_a_principal`, `test_T89_every_invalid_token_is_refused_by_cause` | -| "maps the verified claims onto a principal" | `_principal` — `jwt_identity.py` — copies only the claims named in `claim_names` | `test_T88_only_the_named_claims_reach_the_principal` | -| "`pip install \"ctrlrun[identity]\"`" | `identity = ["pyjwt[crypto]>=2.8"]` in `pyproject.toml`; imported lazily by `_jwt()` — `jwt_identity.py` | `test_T92_constructing_without_the_extra_names_the_install_command`, `test_T92_importing_ctrlrun_pulls_in_no_jwt_module` | -| "CTRLRun issues no credential and defines no identity format" | There is no minting, signing or issuing code path in the package: `jwt_identity.py` calls `decode` and never `encode` | `test_the_package_never_encodes_a_token` | -| "every receipt records which policy decided it" | `Policy.policy_hash` — `policy.py:609`, over `_canonical_policy` — `policy.py:744`; carried into the receipt by `_record` — `control.py:1802` | `test_T172_every_receipt_carries_the_hash_and_the_declared_version`, `test_T172_two_policies_sharing_a_version_string_are_told_apart_by_the_hash` | -| "the policy's declared `version:` and a hash of its canonical content" | `version:` is recorded and never authoritative; `policy_hash` is what tells two documents apart — `policy.py:599` | `test_T171_the_declared_version_alone_does_not_change_the_hash`, `test_T171_comments_key_order_and_whitespace_do_not_change_the_hash` | -| "the approval is re-checked against the policy in force at execution" | `Control.execute` — `control.py:547`; `_spend_unneeded_approval` — `control.py:1435` | `test_T173_the_DENY_row_refuses_and_leaves_the_approval_granted`, `test_T173_the_ALLOW_row_invalidates_the_approval_it_did_not_need` | -| "Each receipt carries the hash of the one before it" | `Receipt.chain_hash` — `receipt.py:284`; `prev_hash` — `receipt.py:41`; `GENESIS_HASH` — `receipt.py:41`; `put_receipt` takes the head row's lock first — `postgres.py:1486` | `test_T164_an_altered_receipt_is_content_altered_at_its_seq`, `test_T164_reordering_two_receipts_is_detected_either_way` | -| "`ctrlrun receipts --verify-chain` reports it by `seq`" | `verify_chain` — `receipt.py:479`; the six names — `CHAIN_BREAKS` — `receipt.py:479` | `test_the_verify_chain_flag_reports_a_break_by_seq_and_by_name`, `test_verify_chain_reads_a_postgres_store_through_store_url` | -| "migrations are automatic at open, forward-only" | `migrate` — `migrations.py:525`, called from both stores' constructors; `HEAD` — `migrations.py:306` | `test_T147_a_v05_database_migrates_and_keeps_every_row`, `test_T150_reopening_does_not_rerun` | -| "An older binary against a newer schema refuses immediately" | `_refuse` — `migrations.py:451`; `SchemaMismatch` — `errors.py` | `test_T148_an_older_binary_refuses_a_newer_database`, `test_T148_no_other_table_is_read_before_the_refusal` | -| "Releases carry PyPI provenance attestations from GitHub Actions" | `.github/workflows/publish.yml` — `pypa/gh-action-pypi-publish` pinned at v1.14.2, which generates and uploads PEP 740 attestations by default since v1.11.0 (its release notes, read 2026-09-06), with no `attestations: false`; the `pypi` job's only permission is `id-token: write` | `test_the_publish_workflow_attests_through_trusted_publishing`, `test_every_action_is_pinned_to_a_commit` | -| "`ctrlrun approve`, `deny`, `resolve`, `inspect`, `receipts` and `stats` work from the shell against any store" | `approve` — `cli/main.py:366`; `receipts` — `cli/main.py:426`; `effects` — `cli/main.py:500`; `resolve` — `cli/main.py:518`; `inspect` — `cli/main.py:554`; `stats` — `cli/main.py:727`; every one takes `--store-url` (SPEC-v0.6 §9.4) | `test_T10_resolve_failed_permits_a_retry`, `test_T18_inspect_json_emits_the_inspection_schema`, `test_T86_stats_counts_what_observe_mode_recorded`, `test_verify_chain_reads_a_postgres_store_through_store_url` | -| "`WebhookApprovalProvider` sends an approval request to a webhook, such as Slack, and takes the answer back through the same grant calls" | `WebhookApprovalProvider` — `webhook.py:141` — one signed POST on `APPROVAL_REQUESTED`; the inbound answer lands through `grant_approval` / `deny_approval` like the CLI's | `test_T27_the_outbound_post_carries_a_signature_over_the_exact_bytes_sent`, `test_T27_the_payload_carries_what_the_spec_names` | -| "one OpenTelemetry span per action, one span event per step" | `OTelEventSink` — `otel.py:45` | `test_T29_one_action_produces_one_span_named_for_the_action`, `test_T29_every_event_becomes_a_span_event_named_by_its_type` | -| "argument values stay out of it unless you ask for them" | `OTelEventSink(arguments=...)` — `otel.py:45` | `test_T29_argument_values_are_not_attributes_by_default` | -| "Receipts in a `ctrlrun.policy/v4` document can cite the `controls:` an action satisfies" | `PolicyControl` — `policy.py:420`; `Receipt` — `receipt.py:245` — carries `controls`; attribution only, never a decision | `test_T175_the_receipt_carries_the_union_of_the_action_and_the_matched_rule`, `test_T175_a_control_is_attribution_and_changes_no_decision` | -| "a rule can condition on the `data:` labels present in an action's arguments" | `DataLabel` — `policy.py:403`; `Policy.data_scope` — `policy.py:487`; `data_scope_in` in `v0.1 §3.2`'s grammar with no new operator | `test_T176_the_derived_set_is_the_labels_of_the_arguments_actually_supplied`, `test_T176_the_derived_set_drives_a_decision` | - -## What it can't, stated as limits - -The README also makes negative claims. They matter as much as the positive ones. - -| Claim | Where it holds | -|---|---| -| "CTRLRun cannot guarantee exactly-once execution against external systems it doesn't control." | Stated, not implemented — see `THREAT_MODEL.md`, "Out of scope". CTRLRun never asserts what a remote did; only `NotExecuted`, raised by the executor, claims that. | -| "CTRLRun is not a transaction manager: it rolls nothing back" | There is no compensation, saga or rollback code path in the package; an `AMBIGUOUS` effect is resolved by a human or a reconcile hook and never undone — `RECONCILED_STATES` — `effect.py` | -| "The receipt chain detects alteration, and alteration is not authorship." | n/a — a disclaimer, and the scan that keeps it one: `test_T180_the_release_documents_do_not_blur_alteration_and_authorship` | -| "erasing the end of the log costs two statements" | No code — this is what the chain does **not** cover, and it is asserted rather than argued: `test_erasing_a_suffix_and_rewinding_the_head_is_two_statements_and_undetected` | -| "CTRLRun does not detect prompt injection" | No code — and that is the point. Nothing in the package reads the agent's instructions: `Policy.evaluate` takes the action's name and arguments (`policy.py:495`) and `Authority` matches a grant against the action, so neither axis has the prompt to inspect. The README's problem table claims containment of the consequence, and this row is the sentence that stops it being read as detection. | `test_T6_an_action_name_is_matched_exactly`, `test_a_condition_naming_an_action_field_is_refused_at_load` | -| "`ctrlrun verify` cannot see your executors" | `docs/docs/verify.md`, "What it does not mean"; `THREAT_MODEL.md`, "Known v0.4 limitations" | -| "`ctrlrun scan` … reports the consequential call sites and policy entries CTRLRun is **not** covering" and "has no score, no percentage and no badge" | `ctrlrun/scan/` reads the tree with `ast` and never imports it, resolves no principal, evaluates no policy and opens no store (SPEC-scan §9.2); the limits sentence is emitted on every run including a clean one, and no percentage is computed anywhere | `test_T194_scan_never_imports_the_tree_it_reads`, `test_T205_scan_resolves_no_principal_evaluates_no_policy_and_opens_no_store`, `test_T203_the_limits_sentence_is_in_every_run_including_a_clean_one` | -| "`ctrlrun mcp-operator` … It authenticates who answered and records it; it does not check that they were entitled to." | the write tools refuse without a principal and attribute the answer to the verified one; there is no entitlement check, and `docs/SPEC-mcp-operator.md` §10 says so | `test_T184_approve_refuses_without_a_principal`, `test_T184_approve_succeeds_with_one_and_is_attributed`, `test_T183_there_is_no_flag_that_permits_a_remote_bind` | -| "it makes no claim about any standard" | No standards vocabulary outside a sentence that negates it, in the README, in a docstring or in CLI output: `test_T139_the_readme_makes_no_conformance_claim`, and `tools/docs_audit/lint.py` on every document | - -## Running it in production: beyond one process - -| Claim | Code | Proof | -|---|---|---| -| "the same `StateStore` protocol, extended by nothing, graded by the suite written for SQLite rather than one written for it" | `PostgresStateStore` — `postgres.py` — satisfies `StateStore` and adds no method (SPEC-v0.6 §9.1); `ctrlrun.conformance.store.SUITES` is the SQLite suite, run against both | `test_T141_the_shipped_backends_pass`, `test_T154_postgres_passes_the_store_conformance_suite` | -| "automatic at open and forward-only, with no flag that opens a database un-migrated. An older binary against a newer schema refuses immediately." | `migrate` — `migrations.py:525` — called from both stores' constructors; `_refuse` — `migrations.py:451` — raises `SchemaMismatch` on a newer `user_version` | `test_T147_a_v05_database_migrates_and_keeps_every_row`, `test_T148_an_older_binary_refuses_a_newer_database`, `test_T152b_no_flag_opens_a_database_without_migrating` | -| "an edit, a deletion from the middle or a reordering is detected and named by `seq`" | `verify_chain` — `receipt.py:479` — and the six break names in `CHAIN_BREAKS` | `test_T164_an_altered_receipt_is_content_altered_at_its_seq`, `test_T164_reordering_two_receipts_is_detected_either_way`, `test_the_verify_chain_flag_reports_a_break_by_seq_and_by_name` | -| "It detects **alteration**, which is not authorship: receipts are not signed." | No signing code, and a release scan keeps the vocabulary out | `test_T180_the_release_documents_do_not_blur_alteration_and_authorship` | -| "every receipt records the policy that decided it, so a receipt from six months ago says what the rules were" | `Policy.policy_hash` — `policy.py:609` — over the parsed decision inputs, recorded on the receipt | `test_T172_every_receipt_carries_the_hash_and_the_declared_version`, `test_T171_any_decision_input_changes_the_hash`, `test_T171_the_declared_version_alone_does_not_change_the_hash` | - -## The docs site: Home and Concepts - -Every claim on the docs site's Home page and Concepts pages, mapped the same way. Most of them -are the README's claims in a second place, so the rows point at the rows above rather than -restating the code; the ones that are new to the site carry their own code and proof. - -| Page | Claim | Proved by | -|---|---|---| -| `index` | the hero, the promise, the demo transcript and the capability grid | the header rows above; the grid is the generator's output for `docs/capabilities.yaml`, checked by `test_the_generated_copies_match_the_generator` | -| `index` | "This site is an MCP server" | Mintlify hosts one at `/mcp` for every site (its documentation, read 2026-09-06); the URL is the site's and changes with the domain, and `test_the_documentation_root_preserves_the_technical_overview` asserts the configuration line is present | -| `get-started/install` | "installs the kernel and exactly two dependencies, `pyyaml` and `click`" | `test_core_declares_only_pyyaml_and_click`, `test_the_core_dependencies_have_not_grown` | -| `get-started/install` | "importing `ctrlrun` imports nothing from an extra" | `test_T30_a_subprocess_importing_ctrlrun_pulls_in_no_module_from_an_extra` | -| `get-started/install` | "raises `MissingDependency` with the install command in the message" | `test_a_missing_extra_raises_MissingDependency_naming_the_install_command` | -| `get-started/quickstart` | every block on the page, and the outputs shown | the blocks are `runnable` and pass `tools/docs_audit/snippets.py` in one temporary directory, in order; the outputs are pasted from one run of the same blocks | -| `concepts/action-and-hash` | "The action hash is the SHA-256 of that canonical form"; sorted keys, no whitespace, UTF-8, `float` rejected; `action_id` excluded | `canonicalize` / `action_hash` — `action.py`; `float` refused — `action.py:71`; `test_T7_canonical_form_is_exactly_the_specified_serialization`, `test_T7_nested_dicts_are_sorted_recursively`, `test_T60_claims_do_not_change_the_action_hash` | -| `concepts/decisions` | three decisions, first match wins, unknown denied, principal-addressing conditions refused at load | the "Write down what the agent may do" rows above | -| `concepts/approval-binding` | A1–A4, the mismatch leaving the approval granted, one core provider writing every grant | the matrix row "An approval is bound to the exact action…", the "Three ways to use it" adapter rows, and `test_T2_a_mutated_action_leaves_the_approval_granted` | -| `concepts/approval-binding` | the `DENY` and `ALLOW` rows when the policy changed between grant and consumption | "the approval is re-checked against the policy in force at execution" above | -| `concepts/effect-keys` | reservation atomic across threads, processes and hosts; an expired lease is `AMBIGUOUS`, never free; `COMMITTED` refuses, `FAILED` permits, `AMBIGUOUS` refuses a blind retry | the matrix row "One logical effect happens at most once…"; `LEASE_EXPIRED` — `effect.py:63`; `test_T160_an_expired_lease_frees_nothing_and_no_read_transitions_it`, `test_T8_a_failed_attempt_permits_a_retry_that_commits` | -| `concepts/outcomes-and-ambiguous` | the outcome table; only a human or a reconcile hook moves a record on, and only in the direction the answer points; nothing sweeps; a lost `COMMIT` on Postgres is `AMBIGUOUS` | the matrix row "An unknown outcome is AMBIGUOUS…", the reconciliation rows, "A crashed worker's effect stays `AMBIGUOUS`…" and the Postgres rows above; `test_T160_there_is_no_reaper` | -| `concepts/receipts-and-evidence` | the receipt's fields, the JSONL sink, the policy hash and version, the chain and what it does not prove | the matrix row "Every executed action leaves a portable JSON receipt", the receipt-chain and policy-versioning rows above, and `test_T11_every_demo_receipt_carries_every_field_in_the_spec` | -| `concepts/authority-and-delegation` | opt-in then fail-closed, no `decision:` on a grant, stricter of the two, containment at creation and at every evaluation, omission rejected, one-write revocation, identity consumed | the authority rows under "Write down what the agent may do" and "What it guarantees" above | -| `concepts/observe-mode` | executes, records `would_have`, one top-level line, counted by `ctrlrun stats`, never asks a human | the observe-mode rows above; `_observed` — `control.py:743` | -| `concepts/fail-closed` | the refusal table, one exception per row | the matrix row "An unknown action, a missing policy or a missing principal is denied.", `ActionDenied` — `errors.py:29`, `DuplicateEffect` — `errors.py:126`, `AmbiguousEffect` — `errors.py:141`, and `test_a_policy_deny_is_denied_the_same_way_as_an_unknown_action` | - -## The docs site: Production - -The section a stranger reads to decide whether to adopt. Two things on it are generated and one -is a statement about what has **not** happened; all three are here because each is the kind of -sentence that rots quietly. - -| Page | Claim | Proved by | -|---|---|---| -| `production/index` | the readiness block — version, test count, guarantee count, the two stores, the soak, the chain, the licence | rendered by `tools/docs_audit/render_readiness.py` from `pyproject.toml`, `pytest --collect-only`, the `GUARANTEES` catalogue — `verify/guarantees.py:39` — and `research/soak/results/`; `test_the_readiness_block_is_the_generators_in_every_place_it_appears` asserts the same block in the README, the docs home and this page, and `test_the_readiness_block_refuses_a_shrunken_suite_and_accepts_a_grown_one` makes the count a floor | -| `production/index` | the **Not yet** list: no external security audit, no third-party review of the kernel, no sector packs | stated rather than measured, because nothing in a repository can measure an absence. A fourth line — *no soak of the length the roadmap asks for* — was **derived** from the published run until `SPEC-v0.6.md` §8.1 removed the duration from the criterion on 2026-09-07, which removed the thing being derived; the run's own duration is still printed on the soak line above the list. The list lives inside the generated block so it cannot be scrolled past. `test_the_not_yet_list_is_inside_the_block_and_not_below_it`, `test_the_not_yet_list_is_the_constant_and_derives_nothing_from_the_soak` and `test_the_readiness_block_does_not_report_the_soak_as_an_unmet_gate` assert all of it; removing a stated line is its own pull request with the row that makes the new sentence true | -| `production/index` | "SQLite is the default and it is production-grade on one host… Postgres is for many hosts" | the header row above; `test_the_first_line_of_the_section_says_which_store_and_why` asserts the order, because Postgres first would tell a reader with one host something false | -| `production/how-reservation-works` | the two rows: an exception before `COMMIT` is a failed write; one during it is unknown and is re-read | SPEC-v0.6 §4.3 Tables A, A1 and A2; `test_T155_a_connection_killed_during_commit_is_resolved_by_the_re_read`, `test_T155e_a_commit_the_server_never_received_re_issues_the_update`, `test_T155c_the_re_read_identity_check_is_not_an_action_id_match`, `test_T156_a_failed_re_read_refuses_to_proceed`; `test_the_two_rows_of_the_lost_commit_are_not_merged` asserts the page keeps them apart | -| `production/migrations` | five shapes, three refusals, nothing half-applies, no flag that opens a database un-migrated | the "migrations are automatic at open, forward-only" row above; `test_T149_a_half_applied_migration_rolls_back`, `test_T152b_no_flag_opens_a_database_without_migrating` | -| `production/recovery` | nothing sweeps; an expired lease is a refusal and not a reclaim; no process identity is inferable | the "A crashed worker's effect stays `AMBIGUOUS`…" row above; `test_T160_an_expired_lease_frees_nothing_and_no_read_transitions_it`, `test_T162_no_process_identity_is_inferable_from_a_record`, `test_T177d_an_expired_lease_is_displayed_as_expired_and_the_display_transitions_nothing` | -| `production/receipt-integrity` | the six names, `unchained` never a pass, a failed receipt write raises and leaves no gap | the receipt-chain rows above; `test_T164_an_altered_receipt_is_content_altered_at_its_seq`, `test_T168_pre_chain_receipts_are_unchained_and_never_a_pass`, `test_T170_a_failed_receipt_write_raises_and_leaves_no_gap` | -| `production/soak` | every number on the page, the measured duration, and what a run of that length does **not** establish | rendered by `tools/docs_audit/render_soak.py` from `research/soak/results/*.json`, which **recomputes** the exit criterion from the published counts rather than reading `exit_criterion_met` out of the same file — a weaker gate checked twice; `test_the_soak_page_is_the_render_of_the_published_results`, `test_the_soak_page_states_the_measured_duration_and_what_it_does_not_establish` and `test_the_soak_page_derives_the_criterion_and_agrees_with_the_harness` | -| `production/operations` | the signals table, and that there is nothing to run | the recovery rows above and `reference/cli`; `test_T177c_the_command_list_is_exactly_the_one_the_spec_froze` asserts the command list these are drawn from | -| the badge row | the test-count badge | written by `tools/docs_audit/render_badges.py --write-count` in CI **after** `scripts/check.sh` has passed, published to the `badges` branch only on a push to `main`; `test_ci_publishes_the_test_count_badge_after_the_suite_has_passed` asserts the order | - -## The browser playground - -The Try-it page says every line in its box was produced by `ctrlrun` in the tab, and that the -sequence it tells the reader to try ends the way it says. - -| Claim | Code | Proof | -|---|---|---| -| "Every line in the box was produced by `ctrlrun` here: the page owns the controls and nothing else." | `PLAYGROUND` in `docs/try-it.js` is a module over `Control`, `InMemoryStateStore`, `LocalApprovalProvider` and `@protect`; the JavaScript builds a request and prints the JSON `step()` returns | `test_the_playground_runs_the_sequence_the_page_tells_the_reader_to_try` runs that module natively through the six steps and asserts each outcome; `docs/assets/verify-browser-demo.mjs` runs the same module and sequence under Pyodide | -| the six steps: allowed · `ApprovalRequired` then `ApprovalMismatch` then executed · `consumed` · `ActionDenied` with no request · `AMBIGUOUS` then a refused retry with one remote call · `DuplicateEffect` | the same kernel paths the matrix rows above cite | the same test, and `test_the_page_names_every_outcome_the_module_can_return`, which holds the page's vocabulary to the module's | -| an approval is the reader pressing *Approve*, recorded by `grant_approval`; no auto-approve, no dry run | one `grant_approval(` in the module and nothing else that grants | `test_the_playground_has_no_way_to_grant_but_the_human_button` | -| the policy shown is the policy that ran | `POLICY` in the module | `test_the_playground_policy_on_the_page_is_the_policy_in_the_module` | -| the versions and date the page quotes are a run's | `docs/assets/browser-demo.verified.json`, written by the harness after a passing run | `test_the_page_quotes_the_run_the_harness_recorded` | - -## Demo output - -The README quotes `ctrlrun demo` verbatim. -`test_the_readme_demo_section_quotes_the_demo_output_verbatim` runs the demo and asserts every -line it prints appears in the README, masking only the generated approval and delegation ids. -The animation at the top of the README ends on lines `docs/assets/demo.expected.txt` lists, and -`tests/test_readme_assets.py` asserts each is a line the demo prints and the README quotes. - -## How these line numbers are kept honest - -They are not, automatically — a citation is prose, and prose drifts. Every row above was -re-derived against the tree at the tag named at the top of this file by reading the line each -one names. - -The v0.6 pass moved **fifteen** of them, and none for an interesting reason: the v0.1 and v0.2 -rows were written against v0.3.0 and the files have grown since. The two that had drifted -*semantically* were fixed in the previous pass and still point where their sentences say — -the `BEGIN IMMEDIATE` citation at the reservation path rather than `grant_approval`'s, and the -"no principal" claim at the public `Policy.evaluate` rather than the private -`_ActionPolicy.evaluate`. One row moved between files: "blocks duplicate execution attempts" -cited `state.py` for the `AMBIGUOUS` refusal, which now lives in `effect.py`'s -`plan_reservation`, decided once for both stores. - -If you are regenerating this file, re-derive every row. Do not carry one forward on trust. - -**And from v0.5, you do not have to take that on trust either.** -`test_the_claims_table_line_numbers_point_at_what_they_name` resolves every `file.py:NNN` in -this document against the line it cites and fails if the symbol the cell names is not on it. -It found **nine** stale references the first time it ran, four of which pointed at a string -literal, a comment or the middle of another function. The instruction above had been followed -by hand at three releases and the table had drifted anyway, which is the argument for the test -rather than against the instruction. - -## Medical Affairs workbench - -These claims describe a demonstration using curated synthetic evidence and an in-memory archive. -They do not describe biomedical retrieval, LLM synthesis or clinical validation capabilities. - -| Claim | Code | Proof | -| --- | --- | --- | -| Unsupported fixture claims are denied before release, even with a client-supplied pass flag. | `validate` and `invoke` in `examples/medical_workbench.py`; the `medical.brief.release` policy | `test_invalid_evidence_is_denied_even_with_a_client_pass_flag` | -| The reviewed action binds document content, evidence versions, validation version and destination. | `invoke` serializes the document into protected action arguments. | `test_edited_document_cannot_use_original_approval`, `test_reviewed_document_releases_and_produces_real_receipts` | -| Approval reuse and an already committed effect do not create another archive write. | The example calls the real `@protect` boundary and records simulated writes in `deliveries`. | `test_approval_reuse_and_duplicate_effect_never_write_twice` | -| An unknown delivery remains `AMBIGUOUS` until the simulated destination confirms receipt. | `release` raises after recording a write; `step` resolves only an existing ambiguous effect with a recorded delivery. | `test_unknown_delivery_remains_ambiguous_until_destination_confirmation`, `test_reconciliation_never_invents_a_delivery` | -| The browser executes the same Python as the checked-in example. | `MODULE` in `docs/medical-workbench.js` | `test_browser_and_local_example_execute_identical_python` | diff --git a/docs/docs/OWASP-AGENTIC-TOP10.md b/docs/docs/OWASP-AGENTIC-TOP10.md deleted file mode 100644 index 1265e4c..0000000 --- a/docs/docs/OWASP-AGENTIC-TOP10.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: "OWASP Top 10 for Agentic Applications" -description: "A reading of somebody else's taxonomy against the guarantees CTRLRun tests, naming the four entries it does not address." ---- - -This is a **reading** of somebody else's taxonomy against the guarantees CTRLRun tests. It is -not a compliance claim, a conformance claim, a certification, or a statement that CTRLRun -covers the OWASP Top 10 for Agentic Applications. Three of the ten entries are not addressed -by CTRLRun at all, and they are listed by name below. - -Every row maps a guarantee to an entry, and every guarantee is backed by a passing acceptance -test — so each row points at code and at a test. A row whose test disappears is a row that -comes out. - ---- - -## The edition this was written against - -| | | -|---|---| -| **Document** | OWASP Top 10 for Agentic Applications | -| **Edition** | 2026 | -| **Publisher** | OWASP GenAI Security Project, OWASP Foundation | -| **Announced** | 2025-12-09 | -| **Entry codes** | `ASI01:2026` – `ASI10:2026` | -| **Landing page** | [https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/) | -| **Read on** | 2026-09-04 | - -**How the codes and titles below were derived, stated plainly because it matters.** The -published document itself is a PDF behind a download form on the landing page above and could -not be retrieved. The ten codes and titles were taken from -[`OWASP/secure-agent-playbook`](https://github.com/OWASP/secure-agent-playbook/blob/main/plugins/ai-security-skills/plays/agentic-ai-risk-assess.md), -an OWASP-owned repository that enumerates them, and corroborated against two independent -third-party summaries that agree with it in every entry. Where a third summary disagreed — -`ASI02` as "Tool Misuse & Exploitation", `ASI04` as "…Compromise", `ASI08` as "Cascading Agent -Failures" — the OWASP-owned repository's wording is the one used here. - -### The ten entries - -| Code | Title | -|---|---| -| `ASI01:2026` | Agent Goal Hijack | -| `ASI02:2026` | Tool Misuse | -| `ASI03:2026` | Identity & Privilege Abuse | -| `ASI04:2026` | Agentic Supply Chain Vulnerabilities | -| `ASI05:2026` | Unexpected Code Execution | -| `ASI06:2026` | Memory & Context Poisoning | -| `ASI07:2026` | Insecure Inter-Agent Communication | -| `ASI08:2026` | Cascading Failures | -| `ASI09:2026` | Human-Agent Trust Exploitation | -| `ASI10:2026` | Rogue Agents | - -Anyone with the published PDF in front of them should check these ten strings against it. If -one differs, this table is what is wrong, not the mapping. - ---- - -## Guarantee → entries mitigated - -Each guarantee is one sentence about what the kernel **refuses**. The "how" column names the -mechanism, not the entry. - -| Guarantee | Invariant | Entries | How | -|---|---|---|---| -| **G1** mutated approval refused | An approval is bound to one `action_hash`; presenting it for any other action is refused, and the approval is not consumed. | `ASI09:2026`, `ASI01:2026` (partly), `ASI06:2026` (partly) | The approval a human granted is bound to the exact canonical form of the action they were shown, so an action that changed after the approval — by a hijacked goal or by anything else — has no approval to present. | -| **G2** replayed approval refused | An approval is single-use; the second presentation is refused and does not execute. | `ASI09:2026` | The approval record is consumed in the same transaction that admits it, so one human decision authorizes exactly one execution and a loop cannot spend it twice. | -| **G3** duplicate effect refused | A second attempt on an effect key whose record is `COMMITTED` is refused, and the remote is not called. | `ASI08:2026`, `ASI02:2026` | Effects are identified by a key derived from the action's own arguments, and a committed key is refused rather than retried — so a retry loop cannot turn one intended effect into several. | -| **G4** one winner under concurrency | Reservation is atomic across processes, not merely across threads. | `ASI08:2026` | The reservation is taken inside a `BEGIN IMMEDIATE` against a unique constraint on the effect key, so two agents that picked up the same task produce one effect and one refusal. | -| **G5** ambiguous blocks a blind retry | An executor that raises anything other than `NotExecuted` leaves the effect `AMBIGUOUS`, and the retry is refused rather than executed. | `ASI08:2026` | A lost response is recorded as an *unknown* outcome rather than a failure, and an unknown outcome is a state only a human or a reconciliation hook may leave — so the failure does not cascade into a second execution of something that may already have happened. | -| **G6** unknown action refused | Unknown action → DENY. There is no default-allow. | `ASI02:2026`, `ASI01:2026` (partly), `ASI06:2026` (partly) | The policy is the list of what an agent may do; anything not written in it is refused, so a tool an agent was talked into reaching for is refused whether or not the reasoning that reached for it was sound. | -| **G7** no principal refused | An action proposed with no principal is refused, and no receipt and no events are written. | `ASI03:2026` | Every action carries a principal or it does not run, so there is no path on which an action executes with nobody attributable to it. | -| **G8** expired authority refused | A grant is authority only until its `expires_at`; after that the action it covered is denied, by name. | `ASI03:2026`, `ASI10:2026` | Authority is evaluated on every action against the clock, not at the start of a session, so an agent still running after its grant lapsed is denied on its next proposal. | -| **G9** delegation cannot escalate | A delegated grant is valid only if it is provably a subset of its parent on every dimension — and a child that **drops** a dimension its parent constrains is rejected rather than treated as unconstrained. | `ASI03:2026`, `ASI10:2026` | Containment is checked at creation and again on every evaluation by walking the chain to its root, and omission is never inheritance — so an agent handed authority cannot mint itself more of it, and a revocation anywhere in the chain cuts everything beneath it. | -| **G10** unknown exception is ambiguous | `NotExecuted` is the only outcome that means "the remote did nothing". Everything else, timeouts included, is `AMBIGUOUS`. | `ASI08:2026` | The mapping from an executor's exception to an outcome is asymmetric on purpose: a timeout is not a failure, so a framework's retry-on-error cannot be the thing that decides whether money moved twice. | -| **G11** an altered receipt is detected | Each receipt carries the hash of the one before it. Altering, deleting or reordering one breaks the chain, and the break is reported by name — `content_altered`, `hash_missing`, `link_broken`, `missing`, `head_mismatch`, `unchained` — and by `seq`. | `ASI09:2026` (partly) | The evidence an operator reads after an incident is the thing an attacker who got that far has the most reason to edit. This does not stop them: it makes **changing what a receipt says, while keeping the receipts after it**, cost a rewrite of all of them plus the head, rather than one statement. What it does not close is the end of the log — erasing a suffix, or appending to it, each cost two statements and are undetected, because the head is a row in the same database and not an external anchor. v0.6 has no anchor and claims none. It is **not** a signature and says nothing about who wrote the log; somebody who can rewrite every row including the head recomputes the chain and it verifies, and `THREAT_MODEL.md` still lists a malicious administrator as out of scope. | - ---- - -## Not covered by CTRLRun - -The half that makes the table above credible. One honest sentence each; nothing aspirational. - -| Entry | Title | Why not | -|---|---|---| -| `ASI04:2026` | Agentic Supply Chain Vulnerabilities | Out of scope. CTRLRun never inspects a package, a model, a tool registry or an MCP server's provenance; it decides actions, and a poisoned dependency reaches it as an ordinary caller. | -| `ASI05:2026` | Unexpected Code Execution | Out of scope. Nothing here sandboxes an interpreter or constrains what a process may run. CTRLRun sits between an agent and one remote effect, not between an agent and its own runtime. | -| `ASI07:2026` | Insecure Inter-Agent Communication | Not yet. Authority does not propagate across agent hops in this release — a grant is evaluated where the action is proposed, and there is no A2A model. `docs/docs/ROADMAP.md` puts that in v0.8; until then, an agent handing work to another agent is outside what these guarantees say anything about. | - -And the three entries where the mapping above is **partial**, with the part that is not covered -stated here rather than left implied: - -| Entry | Title | Covered | Not covered | -|---|---|---|---| -| `ASI06:2026` | Memory & Context Poisoning | G6 and G1 constrain what an agent acting on a poisoned context can *do*: the action must still be named in the policy, so a belief an attacker planted cannot reach a tool the agent was never entitled to use, and an approval granted for one action cannot be spent on another. This is the same downstream constraint that makes `ASI01` partial, and it is here for the same reason. | CTRLRun never reads a model's memory, its context or its prompt, so it neither detects nor prevents the poisoning. And the shape poisoning most often takes is the one the kernel has least to say about: **corrupted arguments to an action the agent is entitled to take** — the right operation against the wrong record. Policy conditions, resource patterns and v0.6 data scope bite on part of that; nothing bites on an identifier an attacker chose. | -| `ASI01:2026` | Agent Goal Hijack | G1 and G6 constrain what a hijacked agent can *do*: it still meets the policy, and it still cannot present an approval granted for a different action. | CTRLRun does not detect or prevent the hijack. It never sees the prompt, the plan or the reasoning, so an agent whose goal was replaced proposes actions exactly as a healthy one would — and every action inside its policy and its grants will run. | -| `ASI09:2026` | Human-Agent Trust Exploitation | G1 and G2 close the shape where an approval a human gave for one action is spent on another, or spent twice. | CTRLRun does not authenticate the *approver*, does not model separation of duties, and has no opinion on whether the human was misled into approving. A human persuaded to approve the right action for the wrong reason gets a valid approval, and the receipt records it as one. | - ---- - -## Where the guarantees are actually checked - -The mapping is only worth what the tests behind it are worth. `ctrlrun verify` runs these ten -against a configuration and reports which of them that configuration can exercise at all — -**not applicable is not a pass**, so a mapping row whose guarantee your policy cannot exercise -shows up as `N/A` with the reason rather than as a green tick. See -[`docs/docs/verify.md`](/docs/verify). - -Each guarantee also descends from an acceptance test in `docs/SPEC-v0.1.md §7`, -`docs/SPEC-v0.2.md §10` or `docs/SPEC-v0.3.md §10`, named in the registry and carried into -every report as `descends_from`. - ---- - -This document is regenerated when the guarantee catalogue changes, and when OWASP publishes a -new edition. It was written against `ctrlrun.guarantees/v2` and the **2026** edition of the -OWASP Top 10 for Agentic Applications. diff --git a/docs/docs/ROADMAP.md b/docs/docs/ROADMAP.md deleted file mode 100644 index 0bd1656..0000000 --- a/docs/docs/ROADMAP.md +++ /dev/null @@ -1,239 +0,0 @@ ---- -title: "Roadmap" -description: "What each version asked and answered, from the v0.1 kernel to v1.0, and what is deliberately not on the list." ---- - -Dependency-first: every layer depends on the one below being correct. Milestones ship when their tests pass, not on dates. Nothing below v0.1 is in scope for code today. - -Standards rule: integrate first, map second, never claim compliance. A standard appears in a mapping doc only after code touches it and a test proves the guarantee. - -Sector rule: every pack cites its sources and ships its `REVIEW.md`. No compliance claims. - -Track rule: kernel versions ship correctness; the tracks that ship beside it (packs, templates, mappings, adapters) ship on their own cadence and never block or share a version with the kernel. - -## v0.1 — Kernel ✅ shipped - -Action · Policy (ALLOW/APPROVE/DENY) · `@protect` · exact-action approval (hash, single-use, expiry) · effect key · SQLite atomic reservation · COMMITTED/FAILED/AMBIGUOUS · receipts + events (JSONL) · CLI · `ctrlrun demo` with four scenarios. - -Exit: all acceptance tests in `SPEC-v0.1.md §7` pass; demo < 60 s; README literally true. - -Standards: none. `THREAT_MODEL.md` is the only compliance-adjacent claim. - -## v0.2 — Zero-friction deployment ✅ shipped - -- MCP adapter and `ctrlrun gateway --upstream <mcp server>` so an existing MCP tool server gets CTRLRun semantics with no agent changes. -- OpenTelemetry export of events (align with ACS observability; don't invent a tracing format). -- Webhook approval provider (Slack/Teams/anything that can POST back). -- `ctrlrun inspect <action_id>`. -- Reconciliation hook: `@protect(..., reconcile=...)` resolves AMBIGUOUS automatically, and only where its answer points. -- `examples/` directory with standalone scripts per scenario (`double-refund/`, `approval-mutation/`, `agent-race/`, `approval-replay/`). In v0.1 `ctrlrun demo` is the example; separate scripts earn their keep once there is more than one way to wire CTRLRun in. -- Sector policy templates: `examples/policies/<sector>.yaml` for devops, payments, e-commerce, insurance, healthcare, legal, security, government, hr. Header comment: *"Starting point on the v0.1 kernel. Adapt before use."* Uses only v0.1 primitives. Tier one of the sector-pack content track below. - -Adoption story: *existing MCP server + one CTRLRun gateway = action safety.* - -**Reconciled against what shipped.** Three things arrived earlier than this file expected, and -one arrived that it did not list: - -- The **OWASP ACS adapter** was a v0.3 standards line. Reading the v0.1.0 schemas showed a - stable enough interface to build against, so it shipped here — with no compliance claim, and - `docs/docs/ACS.md` recording where the standard is silent. -- **`Suspended` / `Control.resume`** were not on any milestone. MCP elicitation (§6.9) needs a - reservation held across a round trip the kernel does not control, and so does an advisory - hook model like ACS. It is public API now, frozen in `SPEC-v0.2.md` §11. -- **Policy `schema: ctrlrun.policy/v2`** grew out of the gateway rather than being planned: - a tool call has no decorator to carry an effect template. -- **`EventSink`** replaced the store's file writing, which the v0.1 kernel had owned. - -Standards: OpenTelemetry export (code), MCP gateway. The OWASP ACS adapter shipped in v0.2 (see `docs/docs/ACS.md`); "ACS-compatible" is still unearned and waits on an ACS conformance suite to measure against. - -## v0.3 — Authority ✅ shipped - -- Principal abstraction and `IdentityProvider` interface — `StaticIdentityProvider`, - `HeaderIdentityProvider` in core, `JWTIdentityProvider` in `ctrlrun[identity]`. -- Authority grants: subject, permitted actions, resource patterns, constraints, environments, - expiry. Opt-in, then fail-closed. -- Delegation with attenuation: `child ⊆ parent`, at creation **and** at every evaluation; - escalation → DENY. Omission is rejected rather than inherited. -- Fifth signature demo: authority escalation, plus `examples/authority-escalation/` and - `examples/authority/`. - -**Two things were delivered that this line did not anticipate**, and they are recorded here -rather than left as a surprise in the changelog: - -- **Observe mode and `ctrlrun stats`.** An enforcement kernel nobody dares turn on is not - enforcement, so v0.3 ships the rollout path with the model: `mode: observe` runs every real - decision and records what *would* have been blocked. It was scoped as build-list item 4 once - the shape of the authority denial made it obvious that operators would need the numbers - before they would accept the refusals. -- **`ctrlrun verify` exists as a stub that exits 2.** It runs nothing and claims nothing. It is - here because observe mode's whole purpose is to lead somewhere, and the command an operator - reaches for next should not be a `No such command` error that suggests they mistyped. The - real one is v0.4, below, unchanged. - -This is the first point at which `VISION.md` was opened for design input, and only §5's -authority-grant shape was taken from it. - -Standards: v0.3 **consumes** identities and issues none — no token minting, no OAuth flow, no -authorization server, no introspection. It verifies a JWT (RFC 7519) against a JWKS (RFC 7517) -with RFC 8725's algorithm and explicit-typing rules applied, and it claims no conformance with -any of them. `--principal-from-client-info` is removed, and `AcsControlHook` gained the same -requirement for the same reason: a self-reported name cannot be an authorization input. - -## v0.4 — Verification ✅ shipped - -- `ctrlrun verify`: runs the kernel's own failure scenarios against the operator's config and reports pass, fail or **not applicable** per guarantee. Ten of them, `ctrlrun.guarantees/v1`: mutated approval · replayed approval · duplicate effect · concurrent reservation across real OS processes · ambiguous blocks a blind retry · unknown action fail-close · no principal · expired authority · delegation escalation on every dimension including omission · unknown exception is ambiguous, never failed. -- **Not applicable is not a pass.** A guarantee this configuration cannot exercise is reported `N/A` with the reason, excluded from the denominator and listed separately. There is no flag that folds one into the count. -- **Every guarantee carries a positive control.** A refusal asserted against a scenario in which nothing ran passes on a kernel with the guard deleted, so a control that misbehaves is `fail` with `reason: "control failed"` — never a pass, and never an N/A. -- Counterexample output on failure: the ordered events, receipts and effect records that show the violation. -- GitHub Action + badge, "CTRLRun verified N/M", where M is **applicable** guarantees. The badge means *declared guarantees pass*, never "this agent is secure." -- `research/framework-probe/`, outside `src/` and never packaged: what an agent stack does with a lost response when nothing guards the effect. Behaviour, not quality. - -Exit: every acceptance test in `SPEC-v0.4.md §8` passes, and every one in v0.1, v0.2 and v0.3 still does. `ctrlrun verify` against `examples/authority/payments.yaml` reports 11/11; against `examples/policies/payments.yaml`, 6/6 with five not applicable — the N/A rule dogfooded rather than described. - -Standards: first mapping doc — `docs/docs/OWASP-AGENTIC-TOP10.md`, each guarantee mapped to the OWASP Top 10 for Agentic Applications entries it mitigates, and the four entries CTRLRun does not address listed by name. A reading of somebody else's taxonomy, and it says so on its first line. - -## v0.5 — Adapter contract (Released 2026-09-05) - -- The adapter contract, documented. It is one of the six contracts v1.0 freezes, so it is written to be lived with. -- Two reference adapters, to prove the contract is real rather than aspirational: OpenAI Agents SDK and LangGraph. Each reuses the framework's own HITL primitives — LangGraph's `interrupt()` and checkpointers, the Agents SDK's tool-approval interruption — mapped onto **`ApprovalRequired` / `with_approval`**, which v0.1 has shipped since the kernel. Never a second approval path beside the framework's own. They ship on the adapters track under their own versions like every other adapter; what v0.5 owns is the requirement that two exist and that the contract survived writing them. - - **This line said `Suspended` / `Control.resume` until `SPEC-v0.5.md` was written, and it was wrong.** `Suspended` exists for the remote asking a question *mid-execution*, where the reservation is already taken and must stay taken; an approval gate has none to hold, because v0.1 consumes the approval in the same transaction as the reservation and a human deliberating for an hour must pin nothing. `SPEC-v0.5.md` §3.1 argues it in full. The correction is recorded here rather than made silently, on the rule `SPEC-v0.4.md` §9.4 set for the threat model's sentence about a check verify could not deliver. -- LangGraph and not LangChain, deliberately. LangGraph owns the primitive the adapter reuses, and LangChain's agent path runs on LangGraph, so one adapter covers both. A separate LangChain adapter would buy only the legacy `AgentExecutor` path. -- An adapter is an entry point, so each one is a `SPEC` §4.3.1 row before it is code: principal validity and expiry, then authority, then policy. - -Exit: two adapters pass the v0.1 and v0.3 acceptance suites through the adapter surface; and a third is written against the contract alone, in a session that may not read the kernel, because a contract that only its author can implement is not a contract. - -Standards: none new. - -## Adapters — their own version line - -**Three ways in, and only one of them is an adapter.** `@protect` covers anything running in this process, today, with no adapter and no framework support: a raw OpenAI call or a LangChain tool is a decorated function. The gateway covers anything reaching its tools over MCP, in any language, also with no adapter. An adapter exists for one reason — to route an APPROVE through a framework's own interrupt instead of raising past it — so a framework with no human-in-the-loop primitive of its own has nothing for an adapter to reuse and does not need one. That is the answer to "what about X" for every X, and it is why this list is short rather than growing by one each time a framework is named. - -Versioned as `adapters-<framework>-MAJOR.MINOR` — `adapters-crewai-1.0`, `adapters-google-adk-1.0` — and never as a kernel version. An adapter answers to two upstreams and neither is this roadmap: it breaks when its framework makes a breaking release, on that project's schedule, for reasons that have nothing to do with what the kernel is doing. Each adapter's README states a supported kernel range and a supported framework range, and its major version tracks whichever of the two forced the break. Each is reviewed in a session that did not write it, on the rule that covers every adapter already. - -**The frameworks.** Every adapter is Python and in-process. OpenAI Agents SDK · LangGraph · Google ADK · Microsoft Agent Framework (Python) · Claude Agent SDK (Python) · PydanticAI · CrewAI · Strands Agents · LlamaIndex. The first two are v0.5's references and arrive with the contract; they are on this track and not in that milestone's version, because an OpenAI or LangGraph breaking release is no more a kernel event than a CrewAI one. Each reuses its framework's own approval and interrupt primitives where they exist and reimplements none of them, ships when its own review is clean, and gates no kernel release. The order they arrive in is demand, not this list. - -**Everything else.** The contract, so the community writes the rest. - -Standards: none of its own. - -## v0.6 — Durable runtime ✅ shipped - -- Postgres StateStore (cross-host reservation). -- Schema migrations, recovery on restart, policy versioning, receipt integrity — a hash chain, which detects **alteration** and not authorship. - - **This line said "hash chain / signatures" until `SPEC-v0.6.md` was written, and the slash was the problem.** A chain says the log was not altered after the fact; a signature proves origin, and proving origin brings key generation, rotation and revocation with it — which is *issuing*, and this project verifies what it is handed (`SPEC-v0.3.md` §1.1). Signing is out of scope for v0.6 and `SPEC-v0.6.md` §11 argues it, noting that a chain plus an external timestamp or anchor gets most of the benefit without keys, as a v0.8+ option rather than a gap. The correction is recorded here rather than made silently, on the rule `SPEC-v0.4.md` §9.4 set for the threat model's sentence about a check verify could not deliver. -- Control registry and data-scope primitives: the kernel-side objects a sector pack configures, shipped here so that a pack is configuration rather than code. - -Exit: the v0.1 concurrency and mutation standard met against a real Postgres on two hosts under failure injection; a published soak with no unexplained AMBIGUOUS and a positive control that fired; a receipt chain tamper test. - -**All three are met, and the third was met by amending it rather than by meeting it as written — which is recorded here rather than quietly rephrased.** - -- *The concurrency and mutation standard against a real Postgres* — met, with one narrowing stated in item 4's PR and repeated here: it was run as **separate OS processes against one Postgres, with the connection broken by a proxy the tests own**, not as two hosts, because this build environment has no container runtime. Separate processes give separate connections, no shared memory and no shared file locks, which is what `BEGIN IMMEDIATE` was silently relying on and what a second host removes, so the reservation guarantee is exercised. A **network partition between hosts** is not, and stays unclaimed. -- *The receipt chain tamper test* — met. Six cases, each asserting **which** break was reported and **where**; `SPEC-v0.6.md` §6.5 names all six, and §6.4 says what the chain does not cover before saying what it does. -- *A soak with no unexplained AMBIGUOUS* — met, and **the criterion it is measured against was changed on 2026-09-07, downwards.** It read *at least one week of calendar time*, and the week was removed rather than waited out. `SPEC-v0.6.md` §8.1 carries the amendment in full: what was traded, what it costs, and what did not change. In short — elapsed hours were a proxy for the wrong question, since whether an unattributed `AMBIGUOUS` exists is settled by the injection ledger and the positive control and not by the clock; what a week would have bought is whether anything **accumulates**, and that is now unestablished by anything here and is claimed by nothing. The published run is twenty minutes, 889,735 actions, 0 unattributed, control fired, and the duration is printed everywhere the run is quoted so a reader can discount it. **This is a release gate that was relaxed by the person it was blocking, and the honest version of that sentence is this one rather than its absence.** - -Standards: `docs/CONTROL-MAPPING.md` — clause-level mapping of receipt integrity/retention to EU AI Act Art. 12 and SOC 2 CC6/CC7, and of exact-action approval to Art. 14. Each row points at a test. Written only when a design partner asks. - -## Sector packs — their own version line - -Versioned as `packs-<sector>-MAJOR.MINOR` — `packs-payments-1.0`, `packs-healthcare-1.0` — and never as a kernel version. A pack depends on the v0.6 control registry and data-scope primitives and on nothing after them, which is why the track is listed here; it is not a step in the chain. It appears in no kernel milestone's exit criteria, and v0.7 follows v0.6 whether or not a single pack exists. - -**Templates (shipped in v0.2).** `examples/policies/<sector>.yaml`, written against v0.1 primitives only, each headed *"Starting point on the v0.1 kernel. Adapt before use."* - -**Full depth (after v0.6).** The same nine sectors — devops, payments, e-commerce, insurance, healthcare, legal, security, government, hr — each pack shipping a control registry, approver roles, data scope, consequence defaults, and worked examples. Each pack is authored in one AI session and reviewed in a separate AI session that did not author it, against the cited public sources for that sector (PCI DSS and PSD2 for payments; HIPAA Security Rule for healthcare; SOX/COSO and maker-checker guidance for finance and insurance; ABA Model Rules for legal; NIST SP 800-53 AC/AU families for security; CIS Kubernetes benchmarks for devops; public-sector records-management rules for government; employment-law basics for hr). The review produces `packs/<sector>/REVIEW.md` listing every control, the source clause it derives from, and each gap or uncertainty found; unresolved gaps stay listed. Each pack README states: *"Authored and reviewed by AI against the cited public sources."* No pack describes itself as compliant with any regulation. - -Released individually as `packs/<sector>/`, each when its own review is clean. A pack's major version tracks its own breaking changes — a renamed control, a removed approver role, a narrowed data scope — and never the kernel's; a pack and the kernel it runs on are two independent version numbers, and the compatibility statement is a supported kernel range in the pack's README. A pack never gates a kernel release and is never gated by one: nine packs is a list, not a milestone, and eight unwritten packs do not hold up v0.7. - -Standards: none of its own. The sector rule above applies in full. - -## The operator MCP server ✅ shipped - -Not a kernel milestone, and listed here because a reader will look for it. `ctrlrun mcp-operator` -exposes the operator's read and write commands as MCP tools, so the person who has to answer an -approval can answer it from their own assistant. It gates no kernel release and none gates it, -and it lands in whichever release comes next — it is a subcommand of the `ctrlrun` distribution, -so unlike an adapter it carries no version line of its own. `docs/SPEC-mcp-operator.md` is the -contract and `docs/SPEC-v0.3.md` §4.3.1 carries its two entry-point rows. - -It authenticates *who* answered and records it. It does not check that they were entitled to — -that is separation of duties, which is still not built, and the specification says so in the -place a reader would otherwise assume otherwise. - -Standards: none new. - -## `ctrlrun scan` ✅ shipped - -Not a kernel milestone, and listed here because the question it answers had no command. -`ctrlrun scan` reads a Python tree and a policy document and reports the consequential call -sites and policy entries CTRLRun is **not** covering — the gap between *installed* and *in the -path*. `docs/SPEC-scan.md` is the contract; it was written first and its §8 tests were red -before any of it existed. - -It gates no release and none gates it, and it lands in whichever release comes next. **It is -not a v0.6 feature**, and lands before that tag no more than the operator server does: -`SPEC-v0.6.md` §9.4's claim is about the surface *that milestone* grew, and a subcommand -arriving before the tag does not retroactively make it one. `test_T177c` holds v0.6's list -frozen and names anything added afterwards separately, which is where `scan` sits. Like the operator server it is a subcommand of the -`ctrlrun` distribution and carries no version line of its own; unlike the operator server it -adds no entry point at all, and `SPEC-scan.md` §9.2 states that as a rule rather than a fact -about the first implementation, because the tempting version of this tool builds an action for -each call site it finds and asks the policy what would happen to it — which would be a principal -invented by a tool from a source file. - -The honest half is the load-bearing half: a scanner reports what it found where it looked, and -a clean result is not a verdict. §4 enumerates what it misses by construction — dynamic -dispatch, reachability, anything outside the tree, and a deployment whose protection is entirely -the gateway — and requires that the report say so on every run, including the run with no -findings. A number that improves when the vocabulary is shortened is a number that will be, so -there is no score, no percentage and no badge (§10). - -Five sections of the specification carry a paragraph beginning *Found by*, and they are the -record of what writing the tests and running the command changed about the design: the plural -rule that separates `stripe.refunds.create` from `refunds_report`; `execute` dropped from the -vocabulary, because `cursor.execute` was 90 of 208 findings against this repository's own -`src/`; a policy action whose decorator supplies its own effect template no longer reported as -missing one; a call on an expression matched rather than filed as undetermined, which took that -list from 216 entries to 10; and `undetermined` removed from the finding kinds it was listed -among and contradicted by. - -Standards: none new. - -## v0.7 — Execution boundary - -Every guarantee shipped so far is a guarantee about what happens *inside* CTRLRun. But the kernel does not decide whether the remote side acted — an executor does, by raising `NotExecuted` or not. It does not own the clock its leases are measured against, once the store is on another host. It does not know whether the world still looks the way it did when a human said yes. v0.7 asks what the kernel owes at each of those edges. - -- **A transport classifier in core.** `FAILED` versus `AMBIGUOUS` is the one decision this project exists to get right, and the kernel does not make it — the user's executor does. The correct rule is already written and already implemented, in the gateway's `outcome.py`: the connection was never established, or the peer said in band and before dispatch that it rejected the request; everything after the first byte is `AMBIGUOUS`. It is reachable today only by installing `ctrlrun[gateway]`, while `@protect` — the surface the README leads with — gets a docstring. One rule, one implementation, reachable from core. -- **Clock-skew detection.** v0.6 moved the store to another host so several hosts could share it; lease liveness stayed on the application clock. Skew is fail-closed and therefore quiet — a host running ahead marks a live reservation `AMBIGUOUS` while its real holder is mid-flight and about to succeed, and nothing names the cause. This makes divergence observable. It does not change how a lease is evaluated. -- **A provider idempotency token**, derived from the effect key *and the attempt number*. Derived from the effect key alone it would be stable across v0.1 §5.4's renewal, and a provider would replay its cached failure for the one retry the kernel permits precisely because the executor proved nothing happened. Its main value is a deterministic handle for reconciliation to observe with — not a licence for anything to act twice. -- **A ceiling on renewal after `FAILED`.** There is none today: one human approval plus an executor that always reports "nothing happened" is unlimited dispatches, each recorded as an ordinary retry. An operator-set policy key, and an amendment to §5.4 written as an amendment. -- **Precondition fingerprints.** An approval binds to an action hash and an expiry, and to nothing about the world it was granted against. A human approves a deletion when the balance is zero; thirty minutes later it is not, and the action hash has not moved. The operator supplies a fingerprint, it is hashed through the canonicalizer so raw resource state never reaches a receipt, and it is rechecked before the reservation. **It narrows the window between decision and execution; it does not close it** — the recheck cannot run inside the atomic reservation write, so a residual gap remains, and that sentence appears wherever the feature does. - -Exit: a classifier that observes rather than infers, with a test that writes a byte, kills the peer and asserts `AMBIGUOUS`; a skew detector with a positive control that stays silent when the clocks agree; a token that provably changes across a renewal; and the precondition recheck documented as narrowing everywhere it is described. - -**A2A moved from v0.7 to v0.8 on 2026-09-08, and the reason is recorded here rather than made silently**, on the rule this file already follows for the v0.6 receipt-integrity line and the soak criterion. Multi-agent authority propagation builds on a kernel whose executor boundary is sound. Three of the five items above are weaknesses in guarantees the project already sells — the classifier most of all — and shipping a hop-counting authority model on top of an outcome mapping the primary surface leaves undefended would be building the next floor before the joists. Nothing about A2A changed; only its position. - -Standards: none new. - -## v0.8 — Multi-agent - -- A2A integration: task-bound delegated authority with limits, expiry, and depth. -- Authority propagation across agent hops. - -Standards: none new. - -## v0.9 — Hardening - -Fuzzing, property tests, concurrency stress, failure injection, benchmarks, external security review, upgrade testing, compatibility guarantees, CodeQL/SAST/SBOM/signed artifacts. - -Standards: none new. - -## v1.0 — Stable contracts - -1.0 means stable contracts, not feature count: Action schema, Receipt schema, effect semantics, Policy API, StateStore API, Adapter API. MCP production-grade. Authority model documented. Threat model published. Security audit complete. Upgrade path tested. - -Standards: external security audit, then an EU controls pack. Phrased as "technical controls supporting a compliance program". - -## Beyond v1.0 - -A management plane — organization-wide policy, approval center, fleet views, central evidence — is not on this roadmap. It gets built only if users pull toward it, and `VISION.md` describes the shape it would take. diff --git a/docs/docs/THREAT_MODEL.md b/docs/docs/THREAT_MODEL.md deleted file mode 100644 index d9d18aa..0000000 --- a/docs/docs/THREAT_MODEL.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: "Threat model" -description: "What CTRLRun defends against, what it deliberately does not, and the fail-closed rules that follow from both." ---- - -CTRLRun sits in the execution path of consequential actions. This document states what it defends against, what it explicitly does not, and the fail-closed rules that follow. It covers every shipped version through v0.6, and grows with the roadmap. - -## Assets - -- **Correctness of consequential effects** — an effect happens at most once per intent, and only as authorized. -- **Integrity of human approval** — what a human approved is what executes. -- **Integrity of evidence** — receipts reflect what happened. - -## Trust boundaries - -``` - untrusted ─────────────┐ trusted ──────────────────┐ - agent reasoning │ CTRLRun process │ - LLM outputs │ policy file │ - tool outputs │ StateStore (SQLite file) │ - retry logic │ approver's shell │ - other agents │ │ -``` - -The agent is treated as a potentially compromised or hallucinating principal. Everything it proposes is verified; nothing it asserts is trusted. - -## In scope — CTRLRun v0.1 defends against - -| Threat | Control | -|---|---| -| Hallucinated or unlisted action | Unknown action → DENY | -| Prompt-injected agent proposing a forbidden action | Policy DENY; approval required for sensitive ones | -| Agent mutates action after human approval | Approval bound to `action_hash`; mismatch → DENY | -| Agent replays a consumed approval | Single-use, atomic consumption | -| Stale approval | Expiry checked at consumption | -| Duplicate execution on retry after timeout | Effect key + AMBIGUOUS + retry refused | -| Duplicate execution from concurrent agents | Atomic cross-process reservation | -| Silent loss of in-flight effect (worker crash) | Lease expiry → AMBIGUOUS, never released | -| Misclassifying unknown outcome as failure | Only `NotExecuted` → FAILED; else AMBIGUOUS | -| Malformed or missing policy | Load-time error; no Control without valid policy | -| Float-based hash collisions/mismatches | Floats rejected in arguments | - -## In scope — CTRLRun v0.3 adds - -The authority model answers a question v0.1 and v0.2 could not: *who is acting, and what are -they entitled to?* Everything above still holds; these are the threats the second axis closes. - -| Threat | Control | -|---|---| -| A principal proposing an action nobody granted them | `authority:` present → no grant means DENY, including for actions the policy allows outright | -| An agent widening its own authority by delegating | Containment on every dimension, at creation **and** at every evaluation | -| A delegated grant that silently inherits what it does not name | Omission is rejected, never treated as unconstrained or inherited (§5.4) | -| A delegation handed to a wider population than its parent covered | A child subject may not carry a wildcard or drop its parent's `user` | -| A compromised chain that has to be cut in a hurry | `ctrlrun revoke` is transitive by structure: one write cuts a chain of any depth | -| Authority outliving the credential that created it | `delegable: true` requires `expires_at`; `Control.delegate` refuses an expired `by` | -| A credential that has expired mid-action | Refused before authority and before policy; a lease extension is refused and the record becomes `AMBIGUOUS` by the ordinary path | -| A forged or tampered token | `JWTIdentityProvider` verifies the signature against a JWKS or a pinned key, with the algorithm taken from its own allow-list and never from the token (RFC 8725 §3.1) | -| An ID token presented as an access token | `token_type` is required and `typ` is checked — the cross-JWT confusion of RFC 8725 §2 | -| A token for another audience or issuer | `aud` by exact membership on either wire shape, `iss` exact, `exp` required | -| Signing keys fetched from somewhere else | JWKS over HTTPS only, redirects refused outright, a duplicate `kid` refused rather than resolved, a failed fetch never emptying the cache | -| An unauthenticated principal reaching an authorization decision | `--principal-from-client-info` removed; `AcsControlHook` refuses an `Authority` without an `identity` provider | -| An environment chosen by the caller | The environment is set once on the `Control` and is never read off the wire | - -## Out of scope — CTRLRun does not defend against - -- A compromised CTRLRun process, host, or Python environment. -- A root attacker or a malicious administrator with write access to the policy file or SQLite database. -- A compromised external service (Stripe lying about outcomes). -- A compromised approver, or social engineering of the approver. CTRLRun proves *what* was approved, not that the human was right. -- Executors that raise `NotExecuted` incorrectly (asserting no side effect when one occurred). This is an integration bug, and it is the most dangerous one available: `NotExecuted` is the one exception that makes an effect retryable, so an executor that raises it after the remote acted turns the one guarantee CTRLRun is built around into a licence to act twice. **`ctrlrun verify` does not and cannot check for it.** Verify reads the operator's configuration and supplies its own executors; it never calls the one behind `@protect` and never imports the module it lives in (SPEC-v0.4 §1.2). An earlier version of this line said v0.4 verify would include such a check. It does not, and the sentence was wrong when it was written. -- Data exfiltration through *read* actions the policy allows. CTRLRun is not DLP. -- Denial of service by flooding approval requests. -- Bypassing the decorator entirely (calling the raw function). v0.2 gateway mode narrows this; process-level enforcement is out of scope. -- **A compromised identity provider.** CTRLRun *consumes* identities: it verifies a token somebody else issued and maps the verified claims onto a `Principal`. It issues nothing, and an issuer that signs a token for the wrong subject has told CTRLRun the truth as far as CTRLRun can tell. Everything downstream — grants, delegation, receipts — is then wrong, correctly and consistently. -- **A `HeaderIdentityProvider` behind a proxy that does not overwrite the header.** It is worth exactly what the thing setting it is worth, and RFC 7239 §8.1 says the same of the header it standardizes. If the agent can set the header, the agent chooses its own authority. It warns at construction and it is still the operator's call. -- **A revoked token before its `exp`.** There is no revocation channel: a verified token is valid until it expires, which is why one with no `exp` is refused. Shared-signals mechanisms exist and v0.3 implements none of them. Short lifetimes are the whole of the story. -- **A tenant-templated issuer.** `issuer` is matched as an exact string, so a multi-tenant endpoint cannot be configured correctly here. Pointing it at one without pinning the tenant makes every tenant on that platform a valid issuer — stated because the fail-open is inviting. -- **Authority across an agent-to-agent hop.** A grant covers the principal CTRLRun resolved for *this* call. Propagating attenuated authority across hops is v0.8. -- **Approving an authority change.** `ctrlrun delegate --as` is an assertion typed at a shell, not an authentication; the record keeps `created_via` so a reader can tell an act from an assertion. Authenticating the *approver* remains out of scope, as in v0.1. - -## Known v0.4 limitations — what `ctrlrun verify` does not see - -`ctrlrun verify` runs the kernel's own failure scenarios against an operator's configuration -and reports what passed, what failed, and what could not be tested at all. The list of what it -cannot see matters more than the feature does, so it is here as well as in -[`docs/docs/verify.md`](/docs/verify) — verify sees **the configuration, not the code**. - -- **Not the operator's executors.** The function behind `@protect` is never called. The - `NotExecuted` integration bug above is invisible here, because verify supplies its own - executors and never imports the operator's module. -- **Not the operator's `reconcile` hooks**, for the same reason: a hook is a Python callable - passed to `@protect`, and it does not appear in any file verify reads. -- **Not where the decorator was placed.** Code that calls the raw function bypasses CTRLRun - entirely — the "bypassing the decorator" line above — and no amount of configuration-reading - finds that. -- **Not the deployment.** Whether the proxy in front of `HeaderIdentityProvider` overwrites the - header, whether `$CTRLRUN_STATE` points where the operator thinks, whether two gateways share - a state file: none of it is in the document. -- **Not whether the policy is the *right* policy.** Verify has no opinion on whether - `stripe.refund` should be autonomous to €500 or to €5. It is not a linter, it does not score, - and it never says a configuration is too permissive. A configuration that permits everything - and constrains nobody can pass every guarantee in the catalogue, because the guarantees are about the - kernel doing what it says under that configuration. - -And the corollary, stated because a badge invites the opposite reading: **the badge means -"declared guarantees pass"** and nothing else. Not secure, not safe, not compliant, not -certified, not audited. - -## Fail-closed rules (v0.1, not configurable) - -| Condition | Result | -|---|---| -| action not in policy | DENY | -| policy missing / malformed | cannot start | -| approval missing / expired / mismatched / consumed | DENY | -| effect key template unresolvable | DENY | -| effect COMMITTED / AMBIGUOUS / in-progress | reservation refused | -| lease expired mid-execution | AMBIGUOUS | -| executor raised non-`NotExecuted` | AMBIGUOUS | -| StateStore unavailable | exception; no execution | - -## Known v0.1 limitations - -- **Effect key templates do not escape placeholder values.** A template is literal text with values substituted in, so `refund:{tenant}:{payment_id}` resolves `tenant="acme:evil", payment_id="p1"` and `tenant="acme", payment_id="evil:p1"` to the same key. Arguments come from the agent, which this model treats as untrusted, so a crafted argument can make two distinct logical effects share one identity. The consequence is a refusal, not a double execution — the second attempt is blocked as a duplicate — so this costs availability, not correctness, and it fails in the safe direction. Until values are escaped, put the untrusted placeholder last, or use a delimiter the value cannot contain. -- Single-host reservation only (SQLite). Multi-host needs Postgres (v0.6). -- Approver identity is free text; no authentication of the approver (v0.3). -- Receipts are not signed, and they are not signed after v0.6 either. v0.6 adds a **hash chain** (`SPEC-v0.6.md` §6): each receipt carries the hash of the one before it, with `seq` inside the hashed content, so a partial tamper is detected and named — an `UPDATE` on one row, a `DELETE` from the middle, a reordering. What that closes is **alteration that keeps the receipts after it**: changing what receipt *n* says while leaving the rest in place costs a rewrite of all of them plus the head, rather than one statement. **Not a truncation at the end, and not an append.** Two earlier versions of this line claimed the first; a review measured both at **two statements, undetected** — delete the rows and rewind the head, or insert a well-formed row and advance it. The head is a row in the same database as the receipts, so it raises the cost of *forgetting* and not the cost of erasing; an anchor outside the database is what would close that, and v0.6 has none. What it does **not** close is authorship, and it does not close a database admin who can rewrite every row including the chain head: such an adversary recomputes the chain and it verifies. The malicious-administrator line above is unchanged; v0.6 narrows it rather than removing it. Nor does the chain prove that every action wrote a receipt — a receipt whose write failed leaves no gap in `seq` and is invisible to the chain by construction; the events log is where that is reconciled. -- No reconciliation; AMBIGUOUS always needs a human (v0.2 adds the executor `reconcile` hook). -- The decorator can be bypassed by code that doesn't use it. - -## Known v0.2 limitations - -These follow from `SPEC-v0.2.md`. They were written here **before** the code landed, which is -the point — a limitation recorded only after somebody hits it is a postmortem, not a threat -model. They shipped in 0.2.0 and every one of them describes behaviour you can run today. - -- **A lazily-validating upstream can win a retry it should not have.** The gateway maps the - JSON-RPC errors that the specification defines as emitted *before dispatch* — `-32700`, - `-32600`, `-32601`, `-32602`, and MCP's `-32020` / `-32021` / `-32022`, plus HTTP `401` and a - scope-challenge `403` — to `FAILED`, permitting an automatic retry. They are the closest - thing MCP offers to an executor raising `NotExecuted` (SPEC-v0.1 §5.5): the peer is stating - in band that it rejected the request rather than running the method. An upstream that does - work and *then* returns `-32602` violates JSON-RPC 2.0, and CTRLRun will retry against a side - effect that already landed. The alternative — mapping every error to `AMBIGUOUS` — makes a - routine token expiry or a typo'd tool name cost a human `ctrlrun resolve`, which is how a - guarantee becomes something people switch off. The asymmetry stays where v0.1 put it: - `-32603 Internal error` and every unrecognized code are `AMBIGUOUS`. -- **`not_executed_on_error: true` is an operator's assertion, and is not checked.** It maps a - tool result carrying `isError: true` to `FAILED` for one tool. It is `NotExecuted` expressed - in YAML by the person who knows their upstream, and it is wrong in exactly the same way if - they are wrong. -- **An approval does not cover input elicited mid-call.** A tool call held open across an MCP - multi round-trip exchange executes with `inputResponses` the approver never saw. Two of the - three mutation paths are closed — the continuation must present the exact `requestState` the - gateway relayed, and its arguments must canonicalize identically to the approved ones — so - the approved call cannot be altered. What remains is the content of the elicited answer - itself, which a compromised upstream chooses the question for. It is recorded - (`EXECUTION_RESUMED` carries the keys and a digest) but not approved. Deny the tool if that - is unacceptable. Binding an approval across an elicitation round trip was asked of v0.3 and - deliberately not answered there (`SPEC-v0.3.md` §13); it stands. -- **The gateway's principal is not authenticated — ~~and `clientInfo` is one of its sources~~.** - *Closed in part by 0.3.0.* `--principal-from-client-info` is **removed**: it read a field the - MCP specification says implementations *"SHOULD NOT rely on … for security decisions"*, and it - was survivable only while a policy could not address the principal at all. The authority model - ended that, so the flag exits non-zero naming `--principal-header`. What remains is the - original sentence: `--principal-header` is worth whatever the proxy that sets it is worth. A - deployment that wants the principal *verified* rather than asserted uses `--identity-jwt` - (0.3.0), which is the only option here that checks a credential. -- **Reservation is still single-host.** Two gateways in front of one upstream share no - reservations unless they share a state file on one machine. - -## Known v0.3 limitations - -- **`Authority` is built at load time and is not hot-reloaded.** Revocation and expiry are - live — read from the store and the clock on every evaluation — but an *edit to the file* is - not. Narrowing a ceiling, bringing an expiry forward, removing `delegable` or deleting a - grant takes effect when the process next loads the document, which for `ctrlrun gateway` - means a restart. The runtime lever is `ctrlrun revoke`, one delegation at a time, by id. -- **There is no way to list delegations**, so there is no way to sweep a subtree. The ids are - in the events file. Cutting a chain of *unknown* width means setting `delegable: false` on - the root grant and restarting, after which §5.6 rule 6 denies every descendant. -- **Observe mode executes.** It is the rollout path, not a sandbox: effects land at remotes - and the records of them are real. What it suspends is CTRLRun's refusals, wholesale — every - ⚠ row of `SPEC-v0.3.md` §9 at once. It is not a per-action opt-out and cannot be made one. -- **A `mode: observe` writer and a ≤ 0.2 reader do not mix.** `ReceiptResult` gains - `observed`, and `Receipt.from_dict` parses `result` into a closed enum — so an older process - reading the same store raises. Upgrade every reader before switching any writer. -- **Claims are receipt data, not action identity.** They are deliberately outside the action - hash, so an approval survives a token rotation — and equally, a claim that changed between - proposal and execution does not invalidate one. Matching a grant on a claim is out of scope - (§13): it needs an answer to "what does a missing claim mean" that v0.3 does not have. - -## Disclosure - -Report vulnerabilities privately to contact@arpanghoshal.com. Do not open public issues for security reports. `SECURITY.md` has the process and what counts as a vulnerability. diff --git a/docs/docs/adapters.md b/docs/docs/adapters.md deleted file mode 100644 index 0d4abe8..0000000 --- a/docs/docs/adapters.md +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: "Adapters" -description: "The three ways in, when you do not need an adapter, what an adapter is allowed to do, and how to write one for a framework not listed." ---- - -## You probably do not need one - -There are **three ways to put CTRLRun in front of a consequential action**, and only one of them -is an adapter. - -| | Covers | Needs | -|---|---|---| -| **`@protect`** | Anything running in this process — a raw OpenAI call, a LangChain tool, a hand-rolled loop, a cron job | Nothing. A decorator. | -| **The MCP gateway** | Anything reaching its tools over MCP, in any language | `pip install "ctrlrun[gateway]"` | -| **An adapter** | Routing an `approve` decision through the framework's **own interrupt** instead of raising past it | The framework to have a human-in-the-loop primitive | - -An adapter exists for exactly one reason: so that a human answers where they already answer. It -buys nothing else. **A framework with no HITL primitive has nothing for an adapter to reuse and -does not need one** — `@protect` already covers it, and an adapter would be inventing a second -approval path, which is the one thing this contract forbids outright. - -That is the answer to *"what about framework X?"* for every X, and it is why this list is short -rather than growing by one each time a framework is named. - -## What ships - -| Distribution | Framework | Shape | Reuses | Binding | -|---|---|---|---|---| -| `ctrlrun-langgraph` | LangGraph | resumed in place | `interrupt()` + `Command(resume=...)`, and the checkpointer | **prevention** | -| `ctrlrun-openai-agents` | OpenAI Agents SDK | decided before invocation | the tool-approval interruption | **attribution** | - -Each has its own README with the two supported ranges, the primitive it reuses with a link and -the date read, and every place its framework's behaviour shows through the contract. - -**Prevention or attribution** is the sentence to read first. `carries_approved_arguments = True` -means the framework's resumption carries the arguments a human answered against, and core -re-checks them against the proposal's `action_hash` — a mutated action is *refused*. -`False` means the framework carries nothing an adapter can inspect: CTRLRun records **who -answered** and cannot re-check **what they answered about**. Neither is a defect; they are -different frameworks. An adapter that blurred the two would be the false-green problem in prose. - -## Versioning - -Adapters ship on their own version line — `adapters-langgraph-1.0`, never `0.5.1`. An adapter -answers to two upstreams and neither is the kernel's roadmap: it breaks when its framework makes -a breaking release, on that project's schedule. Each README states a supported kernel range and -a supported framework range, and the major version tracks whichever forced the break. - -An adapter gates no kernel release, and a kernel release does not re-cut adapters. - -## Writing one - -`docs/SPEC-v0.5.md` is the contract. The short version: - -1. **Implement `FrameworkInterrupt`** — a `framework` name, `carries_approved_arguments`, and - `interrupt(pending) -> ApprovalAnswer`. It is a Protocol; do not inherit from it. -2. **The operator wires it.** They build the `Control` with - `approvals=InterruptApprovalProvider(store, YourInterrupt())` and hand it over. An adapter - never constructs a `Control`, never constructs the provider, and never supplies a principal — - §2.3 has the whole never-list with a reason on every row. -3. **Return the answer; write nothing.** `InterruptApprovalProvider` records it, through the same - `grant_approval` / `deny_approval` calls `ctrlrun approve` makes. This is what makes "never a - second approval path" structural rather than advisory. -4. **Run the kit.** `from ctrlrun.conformance import run; assert run(adapter).ok` inside your own - pytest. It is core — nothing extra to install. It is **not** a certification and passing it is - not a claim about quality: it answers one question, *does an action driven through this - adapter get the same refusals as one driven through `@protect`?* -5. **Report every suite** in your README as `pass` or `not_applicable` **with the reason**. Not - applicable is not a pass, and no adapter describes itself as "conformant". - -### The two shapes, and which one you have - -**Resumed in place.** The tool runs, the interrupt raises out of it, the framework checkpoints, -and the resumed run re-enters the same code with the answer available. You need the provider and -nothing else. Read §3.2.1: the node runs twice, so `action_id` is not continuous, the first -pass's request is orphaned, and the approval TTL does not bound the human's deliberation. - -**Decided before invocation.** The framework asks whether a call needs approval *before* it -invokes the tool. Answer with `ctrlrun.adapter.needs_approval` and nothing else — never by -building an `Action` yourself, which would need a `Principal` you are not allowed to supply. -Three things bite here, and all three were found the hard way: - -- **Observe mode.** Your predicate must return "no approval needed" when - `control.policy.mode` is `observe` (§3.6). Otherwise a human is asked, and because your - framework will not invoke a declined tool, their *no* **stops an action that observe mode - promises to let run**. -- **The framework's answer is keyed to *its* unit, not to a CTRLRun action.** A tool body can - raise `ApprovalRequired` more than once. Bind the answer to the action you gated, and to one - request, or one human "yes" authorizes everything raised under that call. -- **Exceptions.** If your framework wraps or swallows what a tool raised, restore it (§12.7). - A refusal that reaches the model as text invites the retry the refusal exists to prevent. - -## What the contract could not answer - -Item 6 of v0.5 wrote a third adapter against `SPEC-v0.5.md` alone, in a session that could not -read the kernel or either reference adapter. **The adapter was disposable; this list is what it -was for.** A contract only its author can implement is not a contract, so the list had to be -emptied before v0.5 could ship — every row below is answered by an edit to `SPEC-v0.5.md`. - -It chose the **decided-before-invocation** shape deliberately, because that shape must touch -`needs_approval`, `banner`, `refuses_before_invoking` and `Control.policy` and so loads more of -the contract. Six of the fourteen exist only because of that choice, and that is the finding -rather than an artefact of it: **this document was written from one shape and read from the -other, and that is where it broke.** - -| # | The question | Severity | Answered by | -|---|---|---|---| -| Q1 | Is `ctrlrun.context()` on the never-list? It supplies a principal without naming the type, and passes T129 because that test runs against a `Control` **with** an identity provider | **security** | §2.3 never-list row | -| Q2 | May an adapter construct an `InterruptApprovalProvider`? §9 rested a security argument on "it does not", and nothing forbade it — a `build_provider()` helper could inject a frozen clock and defeat §2.4 | **security** | §2.3 never-list row | -| Q3 | §3.6's "never interrupts in observe mode" is false for this shape: the primitive is reached from the *predicate*, and a human's *no* then **stops** an action observe mode promises to run | **correctness** | §3.6 now requires it; §12.9 | -| Q4 | §3.4 rebuilds the request's `Action` "with those arguments" — replace or overlay? Under replace, a tool with a defaulted parameter can never match, so the honest adapter with the honest declaration is the one that breaks | **correctness** | §3.5, with a README requirement | -| Q5 | Nothing in five specifications addresses `async` — may `interrupt()` be called inside a running loop? Does `@protect` wrap a coroutine? | **correctness** | §3.5.1 | -| Q6 | What does `invoke` do when the framework refuses *before* invoking? Returning a value is `never-executes`; returning `None` is undefined | correctness | §5.2 code block | -| Q7 | `needs_approval` cannot see the effect key, so an unresolvable template asks a human and *then* fails — the waste `v0.1 §5.1` exists to prevent | correctness | §3.5, stated as a cost | -| Q8 | Is `resource` a template core resolves, or a literal? The whole contract answered this once, in a parenthesis of `ARCHITECTURE.md` | correctness | §3.5 | -| Q9 | The kit's executor signature is an unstated contract — must arguments be spread as keywords? | correctness | §5.2 | -| Q10 | `@protect(wait=True)` is mandatory and §2.3's *must call* paragraph did not say so | correctness | §2.3 | -| Q11 | Six names the may-call list is written in are frozen nowhere, including `ApprovalStore` in a §9 signature | correctness | §2.3 | -| Q12 | `Case` is public in `SUITES`' type and defined nowhere | style | §5.2 | -| Q13 | A Protocol class-attribute default cannot reach a non-inheriting adapter, so `refuses_before_invoking`'s default must mean `getattr(..., False)` | style | §5.2 | -| Q14 | "May raise its own type" — of its own choosing, or one it defined? It decides whether `except CTRLRunError` catches it | style | §10 | - -`SPEC-v0.5.md` §12.10 records what the exercise says about the document as a whole, and §12.9 is -the observe-mode defect it found in a **shipping** adapter without reading a line of it. - -If you write an adapter and the contract cannot answer something, that is a defect in the -contract. Please open an issue saying what you were writing when you got stuck. diff --git a/docs/docs/architecture/specifications.mdx b/docs/docs/architecture/specifications.mdx deleted file mode 100644 index 1fad20a..0000000 --- a/docs/docs/architecture/specifications.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "The specifications" -description: "Six documents, one per version, each a delta over the ones before and each still binding. They live in the repository; this page says what each asked." ---- - -Every version of CTRLRun was a specification before it was code: what it must do, the -acceptance tests it is judged by, the public names it freezes, and what is deliberately out of -scope. All six are still binding in full, and nothing in a later one relaxes an earlier one. - -They are written for somebody implementing against the kernel, and they are long: a hundred and -eleven thousand words between them. So they live in the repository rather than on this site, -where the pages are written for somebody using it. Read a concept page first; open a -specification when you need the contract. - -| Version | The question it asked | Document | -|---|---|---| -| v0.1 | Can an action be decided, approved, executed once, and recorded? | [`SPEC-v0.1.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.1.md) | -| v0.2 | Can it work with no code change, over MCP, with reconciliation and evidence that leaves the process? | [`SPEC-v0.2.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.2.md) | -| v0.3 | Who is acting, and what are they entitled to? | [`SPEC-v0.3.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.3.md) | -| v0.4 | Does it hold in *my* setup? | [`SPEC-v0.4.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.4.md) | -| v0.5 | Can somebody else implement this? | [`SPEC-v0.5.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.5.md) | -| v0.6 | Does it still hold when the process dies, the host goes away, and the database is somewhere else? | [`SPEC-v0.6.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.6.md) | - -## How to read one - -Each is a delta. Start at the version that introduced what you care about, and read the -sections it names in the earlier ones: the acceptance tests are numbered continuously (`T1` -onward), the public names are frozen in a numbered section per version, and a rule that moved -says where it moved from. - -Two conventions worth knowing before you open one. **MUST, MUST NOT and SHOULD are used in the -RFC 2119 sense.** And every specification carries a section on what building that version -settled, including the defects an independent review found and what was done about each: those -sections are the honest part, and they are where a reader learns what the document got wrong -before it was right. - -## What is on this site instead - -| You want | Read | -|---|---| -| what a thing is, in one page | [Concepts](/docs/concepts/action-and-hash) | -| how to do something | [Guides](/docs/guides/protect-a-function) | -| every key, flag, field and error | [Reference](/docs/reference/policy-yaml) | -| what is guaranteed and what is not | [What verify guarantees](/docs/security/verify-guarantees), [Threat model](/docs/THREAT_MODEL) | -| how the guarantees are held up | [How this is built](/docs/how-this-is-built) | -| every README sentence, mapped to its code and test | [Claims](/docs/CLAIMS) | - -## Next - -- [Architecture](/docs/ARCHITECTURE): how the kernel is shaped, and why. -- [How this is built](/docs/how-this-is-built) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/authority.md b/docs/docs/authority.md deleted file mode 100644 index 375584b..0000000 --- a/docs/docs/authority.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: "Authority and delegation" -description: "Grants, containment and the omission rule in plain language: who may propose an action, and how a delegated grant can only narrow." ---- - -Until v0.3, a CTRLRun policy could see the action and nothing else. It answered *how much -autonomy does this action have* — run it, ask a human, refuse it — and the principal was -attribution on a receipt. That is a real question and it is still the one `actions:` answers. - -It is not the only question. "May a €50,000 refund run without a human?" and "may *this agent* -propose a €50,000 refund at all?" are different, and a system that can only ask the first will -eventually answer the second by accident. - -Authority is the second axis. This page is the model in plain language; the contract is -[`SPEC-v0.3.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.3.md) §4 and §5. - ---- - -## Opt in, and then it is closed - -A document with **no `authority:` section behaves exactly as v0.2 did**. Nothing is evaluated, -no `AUTHORITY_*` event is written, and no decision changes. - -The moment the section exists, **every principal needs a grant, and no grant means denied** — -including for actions the policy allows outright, including reads, including actions with no -effect key. There is no `default: allow`, no per-action opt-out, and no flag that makes a -missing grant permissive. Half-configured authority is the failure mode this rule exists to -prevent: it is the state in which nobody can say whether an action was permitted or merely -unlisted. - -```yaml -schema: ctrlrun.policy/v3 # `authority:` needs v3, or a v1 reader would ignore it - -authority: - grants: - - id: head-of-support - subject: { agent: "head-of-support", user: "dana@example.com" } - actions: ["stripe.refund"] - resources: ["payment:*"] - constraints: { amount_gte: 0, amount_lte: 10000000 } - environments: ["production"] -``` - -`grants: []` is valid and permits nothing. A **missing** `grants` key is a load error, because -inferring "nothing" from an absent key would make a truncated edit look deliberate. - -## A grant carries no decision - -There is no `decision:` in a grant, and this is the design rather than an omission. - -How much autonomy `stripe.refund` has is the same for the head of support and for the newest -agent in the fleet: it is a property of the action and of the amount, and it lives in -`actions:`. What differs between principals is **whether they may propose it at all**. - -The two axes are evaluated separately — authority first — and combine as **the stricter of the -pair**. Authority cannot make a denied action allowed. Policy cannot make an unauthorized -action permitted. Neither can loosen the other, which is what lets you read either one on its -own and be right about what it does. - -And policy still cannot see the principal. `agent_eq` and every other principal-addressing -condition is refused at load, exactly as in v0.1. Authority is a separate vocabulary, on -purpose. - -## What a grant matches on - -| Key | Matches | -|---|---| -| `subject` | the principal: `agent`, and optionally `user` | -| `actions` | action names, as patterns | -| `resources` | the action's resource string, as patterns | -| `constraints` | the action's arguments, in the same syntax a rule's `when:` uses | -| `environments` | the deployment the action is running in | -| `expires_at` | when the grant stops working | - -**Patterns are deliberately small**, because containment between two of them has to be -decidable: a literal, a `prefix*` that cannot cross a separator, and a final `**`. So -`stripe.*` matches `stripe.refund` and **not** `stripe.refund.partial`. There is no `?` and no -character class. Granting the whole surface of a system is spelled `**` — one token, greppable -in review, and impossible to write by accident. - -**The environment is not the caller's to state.** It is set once on the `Control` and stamped -on every Action, so a grant scoped to `["staging"]` cannot be satisfied by a call that -describes itself as staging. An authorization dimension the subject can set is not one. - -## Delegation, and the rule that makes it safe - -A principal holding a `delegable` grant can create a narrower one at runtime: - -```console -$ ctrlrun delegate --parent head-of-support --file finance.yaml --as head-of-support/dana@example.com -created dlg_1f0c… parent head-of-support at depth 1 -revoke it with: ctrlrun revoke dlg_1f0c… -``` - -A delegated grant is valid only if it is **provably a subset of its parent, on every -dimension** — checked when it is created, and again every single time it is evaluated. - -The re-check is not belt-and-braces. It is what makes revocation transitive, what makes an -expiring parent stop authorizing without anyone having to find its children, and what makes a -narrowed root grant narrow everything beneath it. A containment check performed only at -creation would leave every delegation exactly as wide as the file used to be — which is the -shape of every stale-permission incident there has ever been. - -`delegable: true` **requires `expires_at`**. Authority that can mint more authority and never -lapses is the one shape this model refuses to write down. - -## The omission rule - -This is the part that surprises people, so it gets its own section. - -**A child that drops a dimension its parent constrains is rejected.** Not inherited. Certainly -not unconstrained. - -```yaml -# parent -constraints: { amount_lte: 2500000 } -resources: ["payment:EU-*"] - -# child — REJECTED, dimension "resources" -constraints: { amount_lte: 200000 } -# (no `resources:` key at all) -``` - -Read the child on its own and it looks narrower: the amount came down. But a grant with no -`resources` places no resource limit, so the child would authorize `payment:US-*`, which the -parent never could. Silence widened it. - -Most permission systems read an omitted field as "inherit the parent's". That is a reasonable -convention and it is not this one, because it makes the safe reading of a document depend on a -document you are not looking at. Here, **a delegated grant means exactly what it says**, and -saying less is refused rather than resolved. The cost is that every link states every -dimension; the benefit is that a chain can be reviewed one file at a time. - -The same rule applies to the subject: a delegation may not carry a wildcard grantee, and may -not drop its parent's `user`. Both hand the grant to a wider population than the parent -covered. - -## Revocation - -```console -$ ctrlrun revoke dlg_1f0c… -revoked dlg_1f0c… by cli:local -every delegation beneath it is denied from the next evaluation -``` - -**Transitive by structure.** Nothing is rewritten and no children are visited — every -evaluation walks to the root anyway, so a chain of any depth is cut by one write. It is -idempotent, and there is no `unrevoke`: the operation whose safety matters is the one taken in -a hurry. - -Two limits worth knowing before you need them: - -- **`Authority` is built when the document is loaded, and v0.3 does not hot-reload.** - Revocation and expiry are live — they are read from the store and the clock on every - evaluation. An *edit to the file* is not: narrowing a ceiling, bringing an expiry forward or - removing `delegable` takes effect when the process next loads the document, which for - `ctrlrun gateway` means a restart. -- **There is no way to list delegations in v0.3**, so there is no way to sweep a subtree. - `ctrlrun revoke` works one id at a time, and the ids are in the events file. The operation - that cuts a chain of *unknown* width is setting `delegable: false` on the root grant and - restarting: every descendant is then denied on the next evaluation. - -## Reading the evidence - -Every action that passes authority appends `AUTHORITY_RESOLVED` — not only delegated ones, -because a deployment with a permissive grant has to be distinguishable from one with no -section at all. A denial appends `AUTHORITY_DENIED` and **never** `POLICY_EVALUATED`: policy is -not evaluated, so no approval request is created and no human is left holding a request for an -action that could never run. - -The reason is one of a closed set — `no_authority`, `authority_constraint`, -`authority_expired`, `authority_escalation`, `authority_revoked`, `authority_unreadable` — and -never a grant id. A grant may legally be named `no_authority`, and evidence that can be spoofed -by naming a grant is not evidence. The ids travel in `data.grant_id` and -`data.delegation_id`. - -## Try it - -- `ctrlrun demo`, scenario 5 — the chain, the escalation, and the refusal, in process. -- [`examples/authority-escalation/`](https://github.com/CTRLRun/ctrlrun/tree/main/examples/authority-escalation) — the same story as a - standalone script, including the delegation that is refused at *creation*. -- [`examples/authority/`](https://github.com/CTRLRun/ctrlrun/tree/main/examples/authority) — a payments chain and a DevOps chain, as - complete documents to read rather than run. diff --git a/docs/docs/compare/durable-workflows.mdx b/docs/docs/compare/durable-workflows.mdx deleted file mode 100644 index 4fd0188..0000000 --- a/docs/docs/compare/durable-workflows.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: "CTRLRun and durable workflow engines" -sidebarTitle: "vs durable workflows" -description: "A workflow engine makes a workflow finish, retrying until it succeeds. CTRLRun decides whether an effect may happen at all, and never retries an unknown." ---- - -A durable workflow engine guarantees that a workflow finishes: it persists every step, replays -after a crash, and retries an activity until it succeeds. CTRLRun guarantees that a consequential -effect is authorized and happens at most once, and refuses to retry when nobody knows whether it -already happened. One drives work forward; the other decides whether the work may happen. They -compose, and the second question is not the first one's job. - -## What durable engines are good at - -Long-running processes that must survive a crash, a deploy or a week of waiting. Deterministic -replay. Timers, signals, child workflows, fan-out. Visibility into where a workflow is. An -activity that fails transiently and should be retried until the network cooperates. If your -agent's work is a multi-step process with state, that is exactly the problem they solve, and -CTRLRun does not solve it. - -## What they do not do - -| | Durable engines | CTRLRun | -|---|---|---| -| Guarantee | the workflow progresses; activities run at least once | the effect happens at most once per intent, or not at all | -| Retry policy | retry until success is the default | a retry against an unknown outcome is refused | -| Idempotency | your activity must be idempotent, by convention | the effect key is enforced by the store, across processes and hosts | -| A human's yes | a signal, or a wait | an approval bound to the action's hash, single-use, expiring | -| Who may act | not their question | authority: a grant per principal, delegable and revocable | -| A lost reply | retried | `AMBIGUOUS`, and only a human or a reconcile hook moves it | -| Evidence | the workflow history | a receipt per action, portable, chained, readable without the engine | - -The sharp edge is the retry default. Retry until it succeeds is right for a read and wrong for a -refund, and the usual advice, make your activities idempotent, is exactly the work CTRLRun does -for you: an effect key per consequence, reserved atomically, enforced by the store rather than -by convention. - -## When to use both - -Run the workflow in the engine, and decorate the activity that acts. The engine retries; the -decorator refuses the retry that would double an effect, and turns a lost reply into an -`AMBIGUOUS` record with a receipt rather than a silent second call. Nothing about the engine's -replay changes: a replayed activity proposes the same action, hashes the same, and finds its -effect key already reserved. - -## The distinction that matters - -An engine asks *has this step finished*. CTRLRun asks *did this effect happen, and may it happen -now*. An engine that cannot get an answer retries. CTRLRun that cannot get an answer stops and -says so. - -## Next - -- [Effect keys](/docs/concepts/effect-keys) · [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous). -- [Compare: idempotency keys](/docs/compare/idempotency-keys). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/compare/framework-hitl.mdx b/docs/docs/compare/framework-hitl.mdx deleted file mode 100644 index 52e1b5d..0000000 --- a/docs/docs/compare/framework-hitl.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: "CTRLRun and framework human-in-the-loop" -sidebarTitle: "vs framework HITL" -description: "A framework interrupt is where a human says yes. It does not bind that yes to the arguments that execute, or refuse a retry after a lost reply. Use both." ---- - -A framework's human-in-the-loop primitive is the right place for a human to answer, and CTRLRun -uses it rather than replacing it. What it does not do is bind that answer to the exact action -that executes, notice that the same effect already happened, or leave evidence outside the -framework's own run state. Those are different jobs, and an adapter joins them. - -## What a framework interrupt is good at - -LangGraph's `interrupt()` and the OpenAI Agents SDK's tool-approval interruption both stop a run -at exactly the right moment, carry the pending call to whatever console your operators use, and -resume the run where it stopped. They are integrated with the framework's state, its -checkpointing and its streaming, and they are what your users already know. Nothing here -replaces that; the adapters exist so a human keeps answering there. - -## What it does not do - -| | A framework interrupt | CTRLRun | -|---|---|---| -| Where the yes is given | in the framework's own console | the same place, through an adapter | -| What the yes authorizes | a tool call, identified by the framework's id | one canonical action, identified by a SHA-256 over its name, arguments, resource, principal and environment | -| A second, different call after the yes | usually still approved: the record is keyed to the tool or the call | refused, unless it hashes the same | -| The same effect twice | not its question | refused: one effect key, reserved atomically across processes and hosts | -| A lost reply | an error the loop may retry | `AMBIGUOUS`; a blind retry is refused until a human or a hook resolves it | -| Evidence afterwards | the run's own trace, in the framework's format | a portable JSON receipt, chained, readable without the framework | -| Coverage | that framework's tool calls | anything in the process, plus anything behind an MCP server, in any language | - -## When to use both - -If your agent runs on LangGraph or the Agents SDK and your operators answer there, install the -adapter: `@protect(wait=True)` sends the approval out through the framework's interrupt, the -answer comes back, and one core provider writes the grant through the same calls -`ctrlrun approve` makes. Two places to say yes would be one place nobody is watching, so there -is only ever one. - -If your framework has no such primitive, you need no adapter. `@protect` covers the call -anyway, and `ApprovalRequired` is raised for your own code to handle. - -## The distinction that matters - -A framework binds an approval to *a call it is about to make*. CTRLRun binds it to *what that -call would do*. Where the framework's resumption carries the arguments the human saw, an -adapter hands them back and CTRLRun re-checks the hash: prevention. Where it carries only a -verdict, CTRLRun records who answered and cannot re-check what about: attribution. Each -adapter's page says which it is, in that word. - -## Next - -- [Three ways in](/docs/get-started/three-ways-in): when an adapter is the answer and when it is not. -- [Use the LangGraph adapter](/docs/guides/langgraph-adapter) · [Use the OpenAI Agents SDK adapter](/docs/guides/openai-agents-adapter). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/compare/governance-toolkits.mdx b/docs/docs/compare/governance-toolkits.mdx deleted file mode 100644 index 5d69090..0000000 --- a/docs/docs/compare/governance-toolkits.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: "CTRLRun and agent oversight toolkits" -sidebarTitle: "vs oversight toolkits" -description: "Oversight toolkits catalogue agents, monitor their behaviour and report on it. CTRLRun refuses, in the execution path, per action, and emits the evidence." ---- - -An oversight toolkit answers questions about a fleet: which agents exist, what they are allowed -to touch, what they did last week, and whether anything looks unusual. CTRLRun answers one -question about one action, in the moment before it happens: may this run, has it already run, -and what is recorded. A toolkit describes; CTRLRun refuses. - -## What oversight toolkits are good at - -An inventory of agents and their owners. Central configuration across teams. Dashboards, -anomaly detection and reporting over what agents did. Mapping activity to internal control -frameworks. Answering someone who asks what runs in production. These are real problems, they -are organisational rather than per-call, and CTRLRun does none of them. - -## What they do not do - -| | Oversight toolkits | CTRLRun | -|---|---|---| -| Where it sits | beside the agent, reading its activity | in the call path, between the decision and the effect | -| When it acts | after, or at configuration time | before the executor runs | -| Granularity | the agent, the tool, the team | one action, with its arguments | -| A human's approval | routed and tracked | bound to the exact action's hash, used once, expiring | -| The same effect twice | reported, if noticed | refused | -| A lost reply | an error in a chart | `AMBIGUOUS`, and the retry is refused | -| Output | dashboards and reports | a portable JSON receipt per action, chained | -| Scope of the claim | the fleet | the boundary | - -## When to use both - -A fleet needs both kinds of answer. Use the toolkit for the inventory, the reporting and the -organisational questions, and put CTRLRun in the path of the actions that cannot be undone. The -receipts are portable JSON and go wherever your reporting lives; the OpenTelemetry sink puts -each action in the same traces your platform already collects. - -## What CTRLRun will not claim - -CTRLRun makes no standards claim and does not map itself to a control framework as a product -feature. `controls:` in a policy lets *you* name the house control an action satisfies and cites -it on the receipt, uninterpreted. The reading of the OWASP Top 10 for Agentic Applications in -this repository names the four entries it does not address. Enforcement in the path and evidence -out of it is what is on offer; the argument that this satisfies a given framework is yours to -make. - -## Next - -- [Receipts and evidence](/docs/concepts/receipts-and-evidence) · [Policy YAML reference](/docs/reference/policy-yaml). -- [How this is built](/docs/how-this-is-built): what the guarantees rest on. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/compare/guardrail-libraries.mdx b/docs/docs/compare/guardrail-libraries.mdx deleted file mode 100644 index dffdecf..0000000 --- a/docs/docs/compare/guardrail-libraries.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: "CTRLRun and guardrail libraries" -sidebarTitle: "vs guardrail libraries" -description: "Guardrail libraries inspect what goes into and comes out of a model. CTRLRun sits at the boundary between deciding to act and having acted." ---- - -A guardrail library reads text: the prompt going in, the completion coming out, sometimes a -tool call's arguments, and it blocks or rewrites what it does not like. CTRLRun does not read -text at all. It sits one layer down, where a decision becomes an effect, and asks whether this -exact action may run, whether it has already run, and what to record. - -## What guardrail libraries are good at - -Catching things that are visible in language: personal data in a completion, a jailbreak -attempt in a prompt, an off-topic answer, a toxic response, a schema a tool call does not -match. They run fast, they are model-aware, and they are the right tool for the failure modes -that live in the text. - -## What they do not do - -| | Guardrails | CTRLRun | -|---|---|---| -| Input | prompts, completions, tool arguments as text | one canonical action: name, arguments, resource, principal, environment | -| Question asked | is this content acceptable | may this action run, has this effect already happened, what happened | -| A refund that already committed | invisible: the text looks fine | refused: the effect key is reserved | -| A lost reply | invisible | `AMBIGUOUS`; the retry is refused | -| A human's approval | not their concern | bound to the action's hash, single-use, expiring | -| Evidence | a filter decision, if logged | a receipt per action, chained, portable | -| What it cannot see | the second execution | the injected instruction that reads as legitimate text | - -That last row is the pair. A guardrail can spot an injected instruction in the page an agent -read. CTRLRun cannot: the refund request that arrives looks exactly like a real one. What -CTRLRun does instead is make the *consequence* survivable: the refund needs a grant the agent -does not hold, the amount needs a human, the recipient is bound to what the human saw, and the -effect happens once. - -## When to use both - -Most deployments that matter want both, in this order: a guardrail on the model's input and -output, and CTRLRun in front of the calls that change the world. They fail differently, which is -the point of having two. A guardrail that misses one injection has let a request through; if -that request must still get past authority, policy, a human and an effect key, the injection has -not bought much. - -## The distinction that matters - -Guardrails are about what is *said*. CTRLRun is about what is *done*. A library that filters -text cannot tell you whether the refund happened twice, and a library that owns effects cannot -tell you whether the completion was rude. - -## Next - -- [Why](/docs/why): the boundary CTRLRun owns. -- [Fail closed](/docs/concepts/fail-closed) · [Effect keys](/docs/concepts/effect-keys). -- [Get started](/docs/get-started/quickstart). diff --git a/docs/docs/compare/idempotency-keys.mdx b/docs/docs/compare/idempotency-keys.mdx deleted file mode 100644 index 06a6d69..0000000 --- a/docs/docs/compare/idempotency-keys.mdx +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: "CTRLRun and idempotency keys" -sidebarTitle: "vs idempotency keys" -description: "An idempotency key deduplicates at one API that chose to support it. An effect key deduplicates at the agent, across every API it touches." ---- - -An idempotency key is a header one API honours so that the same request sent twice charges once. -An effect key is the name of a consequence on the agent's side, enforced before the call goes -out, across every API the agent touches, whether or not any of them support idempotency. Where -an API does support it, pass the effect key as the idempotency key and get both. - -## What idempotency keys are good at - -At the remote, they are the strongest thing available: the provider itself knows whether it has -seen the key, and can return the original response rather than acting again. Stripe's is the -canonical example and it works. If every call your agent makes is to one API that implements -them well, you have solved a large part of this problem. - -## What they do not do - -| | Idempotency keys | Effect keys | -|---|---|---| -| Where enforced | at the remote, if it supports them | at the agent, before the call | -| Coverage | that one API | every remote, including ones with no such feature | -| Two different APIs, one consequence | two unrelated keys | one effect key, one reservation | -| Two agents, same intent, same instant | both requests reach the remote; the remote resolves it | one reserves, the other is refused before the call | -| An unknown outcome | resend with the key and hope the remote deduplicates | `AMBIGUOUS`: the retry is refused until a human or a hook says what happened | -| Retention | the provider's window, often a day | your store, as long as you keep it | -| Bound to an approval | no | yes: the same atomic write consumes the approval and reserves the key | -| Bound to authority | no | yes: authority is evaluated before either | -| Evidence | the provider's dashboard | a receipt naming the key, the decision, the approver and the outcome | - -The row that matters most is the unknown outcome. Resending with an idempotency key is the right -move when the remote implements them and the window has not passed. It is a guess when the -remote does not, when the call went to a second API, when the window expired, or when the client -never learned whether the first request arrived. CTRLRun refuses to guess and makes someone -look. - -## When to use both - -Always, where the remote supports it. Pass the effect key as the idempotency key: - -```python -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}") -def refund(payment_id: str, amount: int) -> dict: - return stripe.Refund.create( - payment_intent=payment_id, - amount=amount, - idempotency_key=f"refund:{payment_id}", - ) -``` - -Now the agent refuses the second attempt before it leaves, and the remote refuses it if one ever -arrives. Two independent defences, and the receipt says which one acted. - -## The distinction that matters - -An idempotency key makes *a request* repeatable. An effect key makes *a consequence* -identifiable, before anything is sent, across the whole agent, and joined to who approved it and -what was recorded. - -## Next - -- [Effect keys](/docs/concepts/effect-keys): the definitional page. -- [Compare: durable workflows](/docs/compare/durable-workflows). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/concepts/action-and-hash.mdx b/docs/docs/concepts/action-and-hash.mdx deleted file mode 100644 index 144f25d..0000000 --- a/docs/docs/concepts/action-and-hash.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: "Action and hash" -description: "An action is a named operation with canonical arguments, a resource, a principal and an environment." ---- - -An action is one proposed operation, normalized: a name such as `stripe.refund`, its arguments -in canonical form, the resource it touches, the principal proposing it, and the environment it -runs in. The action hash is the SHA-256 of that canonical form, and it is the value every -approval is bound to. - -## What the canonical form is - -Two calls that mean the same thing must hash the same, and two that differ in anything a human -would care about must hash differently. So the form is fixed: - -- keys sorted, recursively; -- no insignificant whitespace, `separators=(",", ":")`; -- UTF-8, `ensure_ascii=False`; -- argument values are `str`, `int`, `bool`, `None`, or nested containers of those; -- **`float` is rejected at any depth.** `0.1` and `0.10` are the same money and different - bytes, so amounts are integer minor units: `200000` is €2,000.00. - -The `action_id`, a fresh identifier per proposal, is excluded from the hash on purpose. Two -proposals of the same action from the same principal hash the same, which is what lets an -approval granted against the first pass of a LangGraph node match the second. - -```python runnable -from ctrlrun import Action, Principal, action_hash - -who = Principal(agent="refund-agent") -first = Action(name="stripe.refund", arguments={"payment_id": "txn_2", "amount": 200000}, principal=who) -same = Action(name="stripe.refund", arguments={"amount": 200000, "payment_id": "txn_2"}, principal=who) -more = Action(name="stripe.refund", arguments={"payment_id": "txn_2", "amount": 500000}, principal=who) - -assert action_hash(first) == action_hash(same) -assert action_hash(first) != action_hash(more) -print(action_hash(first)[:16], "==", action_hash(same)[:16]) -``` - -## The guarantee it supports - -Approval binding. A human approves a hash, and only the action with that hash can consume the -approval. Change the amount, the payment, the principal or the environment and the hash moves. - -## What it does not do - -The hash does not identify a *consequence*. Two different actions can cause the same effect, -and one action can be proposed twice; the effect key, not the hash, is what stops a duplicate. -The hash also says nothing about whether the arguments are sensible; the policy does. - -## Next - -- [Approval binding](/docs/concepts/approval-binding): what the hash is for. -- [Effect keys](/docs/concepts/effect-keys): the other identity, for the consequence. -- [Why](/docs/why) · [Get started](/docs/get-started/quickstart). diff --git a/docs/docs/concepts/approval-binding.mdx b/docs/docs/concepts/approval-binding.mdx deleted file mode 100644 index 2bd86de..0000000 --- a/docs/docs/concepts/approval-binding.mdx +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: "Approval binding" -description: "An approval is bound to the hash of the exact action a human saw, is used once, expires." ---- - -An approval is a human's yes to one exact action, bound to that action's hash, single-use, and -expiring. It is consumed in the same atomic write that reserves the effect key, so an action -that differs from what the human saw matches nothing, and an action presenting an approval -that was already spent is refused. - -## The four invariants - -| | The rule | What it stops | -|---|---|---| -| A1 | An approval authorizes exactly one `action_hash` | An agent re-planning to €5,000 after a human approved €2,000; a prompt injection changing the recipient | -| A2 | An approval is used once | A loop presenting the same approval on every retry | -| A3 | An approval expires, and expiry is checked at consumption, not only at grant | A yes given on Monday authorizing a call on Friday | -| A4 | Consumption and reservation are one atomic write | Two workers both "using" one approval, or an approval consumed by an action that then failed to reserve | - -## What the human sees, and what executes - -```text -agent proposes stripe.refund txn_2 €2,000 → request apr_7f… (hash h1) -human approves apr_7f… (bound to h1) -agent executes stripe.refund txn_2 €5,000 → hash h2 ≠ h1 - ✗ ApprovalMismatch: approved action ≠ requested action -``` - -The approval is left `granted` after a mismatch. It still authorizes the €2,000 action, and -only that, until it expires. - -## Where the yes comes from - -`ctrlrun approve <request id>` writes the grant. So does a webhook answer from Slack, and so -does an adapter routing the request through LangGraph's `interrupt()` or the OpenAI Agents SDK's -tool-approval interruption: every path ends in the same two store calls, `grant_approval` and -`deny_approval`. There is never a second place to say yes, because a second approval path is -one nobody is watching. - -Where a framework carries the arguments the human answered against, the adapter hands them -back and CTRLRun rebuilds the hash and compares: that is *prevention*. Where it carries only -the verdict, CTRLRun records who answered and cannot re-check what they answered about: that -is *attribution*, and the adapter's page says which it is, in that word. - -## The guarantee it supports - -Approval binding, verified as G1 (mutated approval refused) and G2 (replayed approval refused) -by `ctrlrun verify` against your own policy, wherever it has an `approve` rule. - -## What it does not do - -An approval does not prove the human was right, or that the human was who they said; CTRLRun -records the approver as given and authenticates nobody. It does not survive a policy change in -one direction: if the policy now denies the action, the action is refused and the approval is -left granted; if the policy now allows it outright, the action runs and the approval is -invalidated so it cannot outlive the action it was for. - -## Next - -- [Action and hash](/docs/concepts/action-and-hash): what the approval binds to. -- [Effect keys](/docs/concepts/effect-keys): the reservation it is consumed with. -- [Approve in Slack](/docs/guides/approvals-in-slack) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/concepts/authority-and-delegation.mdx b/docs/docs/concepts/authority-and-delegation.mdx deleted file mode 100644 index 68c476a..0000000 --- a/docs/docs/concepts/authority-and-delegation.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: "Authority and delegation" -description: "Authority is the second axis: a grant says which principal may propose which action, opt-in and then fail-closed, evaluated before the policy." ---- - -Authority answers the question the policy cannot: may *this principal* propose this action at -all? A grant names a subject, the actions, resources and environments it covers, and the -constraints on the arguments. It is opt-in, and then fail-closed: a policy with no `authority:` -section behaves exactly as before, and the moment one exists every principal needs a grant and -no grant means denied. - -## Two axes, one action - -```yaml runnable -schema: ctrlrun.policy/v3 - -authority: - grants: - - id: head-of-support - subject: { agent: "head-of-support", user: "dana@example.com" } - actions: ["stripe.refund"] - resources: ["payment:*"] - constraints: { amount_gte: 0, amount_lte: 10000000 } # €0 to €100,000.00 - environments: ["production"] - delegable: true - expires_at: "2027-01-01T00:00:00Z" - -actions: - stripe.refund: - effect: "refund:{payment_id}" - resource: "payment:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 100000 } - decision: allow - - when: { amount_gte: 0, amount_lte: 1000000 } - decision: approve - - decision: deny -``` - -A grant carries no `decision:`. How much autonomy `stripe.refund` has is the same for everybody; -what differs is whether they may ask. The two are evaluated separately, authority first, and -combine as the stricter of the pair: a €50,000 refund from the head of support is within the -grant and denied by the policy; a €500 refund from an agent with no grant is allowed by the -policy and denied by authority, before any approval request is written. - -## Delegation only narrows - -A principal holding a `delegable` grant can hand a slice of it on at runtime with -`ctrlrun delegate`. The delegated grant is valid only if it is provably a subset of its parent -on every dimension, at creation **and again at every evaluation**, so narrowing the parent later -narrows every child. Omitting a dimension the parent constrains is rejected, not inherited: a -child that drops `resources:` would authorize resources its parent never could. `delegable: true` -requires `expires_at`, because authority that can mint more authority and never lapses is the one -shape this model refuses. `ctrlrun revoke` cuts a chain of any depth with one write; every -evaluation walks to the root. - -```text -human €100,000 delegable → finance agent €25,000 → support agent €2,000 -support agent requests €50,000 ✗ outside the delegated grant -finance agent delegates €50,000 ✗ containment: constraints -``` - -## Identity is consumed, never invented - -The principal comes from an identity provider the operator installs: `ctrlrun.context(agent=...)` -for a process that knows who it is, a `HeaderIdentityProvider` behind a proxy that authenticates, -or a `JWTIdentityProvider` that verifies a bearer token against a JWKS or a pinned key and maps -the verified claims onto a principal. CTRLRun issues no credential and defines no identity -format. An expired credential is refused before authority and before policy. - -## The guarantee it supports - -Authority and delegation: G7 (no principal refused), G8 (expired authority refused) and G9 -(delegation cannot escalate, six dimensions) in `ctrlrun verify`. - -## What it does not do - -Authority does not authenticate the approver, does not propagate across an agent-to-agent hop, -does not match a grant on a token claim, and does not hot-reload the file: revocation and -expiry are live, an edit takes effect when the process next loads it. A `HeaderIdentityProvider` -is worth exactly what the thing setting the header is worth. - -## Next - -- [Authority YAML reference](/docs/reference/authority-yaml). -- [Decisions](/docs/concepts/decisions): the axis authority sits beside. -- [Authority and delegation, in plain language](/docs/authority) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/concepts/decisions.mdx b/docs/docs/concepts/decisions.mdx deleted file mode 100644 index 9888bb2..0000000 --- a/docs/docs/concepts/decisions.mdx +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "Decisions" -description: "A rule matches first-wins over the action's arguments, never over who is asking. Three decisions: allow, approve, deny." ---- - -A decision is what the policy says may happen to one action: `allow` runs it, `approve` runs it -once a human has approved that exact action, and `deny` refuses it. There is no fourth value, and -an action the policy does not list is denied. - -## How a decision is reached - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - iam.grant_role: - effect: "grant:{principal}:{role}" - rules: - - when: { role_in: [reader, viewer] } - decision: allow - - when: { role_eq: admin } - decision: deny - - decision: approve -``` - -Rules are tried in order and the first match wins. A `when:` is a mapping of `<argument>_<op>` -keys, all of which must hold: `eq`, `neq`, `in`, `lt`, `lte`, `gt`, `gte`. A rule with no -`when:` always matches, which is how the last line becomes the default for that action. An -action with a bare `decision:` and no rules decides the same way for every argument. - -Granting `reader` runs on its own; granting `admin` is refused for everybody; anything else -waits for a person. - -## What the policy cannot see - -The policy sees the action's name and its arguments and nothing else. It cannot see the -principal: `agent_eq`, `user_eq` and every other principal-addressing condition is refused when -the file loads, not silently matched. That is deliberate and it is the second principle on the -[Why](/docs/why) page: how much autonomy `iam.grant_role` has is the same for everyone; who may -propose it at all is the job of authority. - -## The guarantee it supports - -Per-action policy, and fail closed. A rule cannot widen anything by omission: a missing rule -means the default, a missing action means denied, and a missing or malformed file means no -`Control` at all. - -## What it does not do - -A decision is not an authorization. `allow` says the action may run without a person; it does -not say this principal may propose it, which authority decides first. And a decision is not an -outcome: an allowed action can still be refused at reservation because its effect key is held, -or end `AMBIGUOUS` because the remote did not answer. - -## Next - -- [Approval binding](/docs/concepts/approval-binding): what `approve` sets in motion. -- [Authority and delegation](/docs/concepts/authority-and-delegation): the axis the policy cannot see. -- [Policy YAML reference](/docs/reference/policy-yaml) · [Get started](/docs/get-started/quickstart). diff --git a/docs/docs/concepts/effect-keys.mdx b/docs/docs/concepts/effect-keys.mdx deleted file mode 100644 index aa9de2a..0000000 --- a/docs/docs/concepts/effect-keys.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: "Effect keys" -description: "An effect key names the real-world consequence of an action, such as refund:txn_1, so a retry meets the first attempt instead of the remote." ---- - -An effect key is the name of a consequence in the real world: `refund:txn_1`, -`namespace:prod-eu:checkout`, `email:msg_8812`. It is declared as a template over the action's -arguments, reserved in one atomic write before the executor runs, and held until the outcome is -known, so that the same consequence proposed twice, by a retry, by a second agent or on a second -host, executes at most once. - -This is the idempotency key idea, applied on the agent's side of the call and across every -remote at once, and bound to the approval and the receipt rather than living in a header one -API happens to honour. - -## Declaring one - -```python -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}") -def refund(payment_id: str, amount: int) -> dict: ... -``` - -Or in the policy, for a tool call behind the gateway that has no decorator to carry it: - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - mcp.acme.create_refund: - effect: "refund:{payment_id}" - decision: approve -``` - -A template that cannot be resolved from the arguments fails the action before anything runs. A -write with no `effect:` at all gets no reservation, which is right for a read and wrong for -anything that changes the world; the gateway prints every such action on the line that starts -it. - -## What the reservation does - -```text -Agent A reserve refund:txn_123 → ACQUIRED → executes → COMMITTED -Agent B reserve refund:txn_123 → ✗ DuplicateEffect: already reserved (in_progress) -``` - -The reservation is a row keyed by the effect key, written under SQLite's `BEGIN IMMEDIATE` or -Postgres's unique index with compare-and-set updates, so it holds across threads, processes and -hosts. It carries a lease. A worker that dies mid-call never releases its key: past the lease the -effect is `AMBIGUOUS`, never free, because nobody knows what the dead worker did. - -Once the outcome is known the key stays in the store with its state, and a later attempt is -answered from it: `COMMITTED` refuses a duplicate, `FAILED` permits a retry, `AMBIGUOUS` refuses -a blind one. - -## The guarantee it supports - -One effect, once: G3 (duplicate effect refused) and G4 (one winner under concurrency, eight -processes) in `ctrlrun verify`. It is verified only where the policy declares templates, and -reported not applicable, with the reason, where it does not. - -## What it does not do - -An effect key deduplicates *intent*. It cannot know what the remote did after the reply was -lost, which is why an `AMBIGUOUS` effect is not retried on its own. It does not span two -different keys that happen to cause one consequence; naming the consequence well is the -operator's job. And it is not a lock on the resource: a call that bypasses the decorator -entirely is not reserved, which the threat model lists as out of scope. - -## Next - -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): what happens when the reply is lost. -- [Compare: idempotency keys](/docs/compare/idempotency-keys). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/concepts/fail-closed.mdx b/docs/docs/concepts/fail-closed.mdx deleted file mode 100644 index f69251e..0000000 --- a/docs/docs/concepts/fail-closed.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Fail closed" -description: "An unknown action, a missing or malformed policy, a missing or expired principal, a missing or mismatched approval: every one of them is denied." ---- - -Fail closed means that anything CTRLRun cannot decide, it denies. An unknown action, a missing -policy, a malformed policy, a missing or expired principal, a missing, expired, consumed or -mismatched approval, a template that cannot be resolved, a store whose schema it does not -recognise: all refused, before the executor runs. There is no flag that makes a consequential -action permissive by default, in the kernel, in `verify`, or in an adapter. - -## The table - -| Condition | Result | Where | -|---|---|---| -| Action name not in the policy | `ActionDenied`, reason `unknown_action` | policy | -| No `ctrlrun.yaml`, or one that does not parse or validate | `PolicyError`; no `Control` is built | load | -| No principal, or one whose credential has expired | `ActionDenied`, reason `no_principal` or `principal_expired` | before authority | -| `authority:` present and no grant matches | `AuthorityDenied` | before policy | -| `approve` decided and no approval presented | `ApprovalRequired` | before reservation | -| Approval presented for a different hash, already consumed, or expired | `ApprovalMismatch` | consumption | -| Effect key held by another in-progress or committed attempt | `DuplicateEffect` | reservation | -| Effect key `AMBIGUOUS` | `AmbiguousEffect` | reservation | -| Store schema newer than the binary understands | `SchemaMismatch` | open | -| Any exception from the executor other than `NotExecuted` | `AMBIGUOUS`, never `FAILED` | outcome | - -Each is an exception of its own, raised as itself so an agent loop can tell them apart, and -each writes a refused receipt and an event naming the reason. - -## Why it is not configurable - -A flag that relaxed one of these would be set in exactly the deployment where it mattered, and -the receipts from that deployment would say the guard was on. The same rule binds `ctrlrun -verify`, which has no argument that makes its `Control` behave differently from yours, and every -adapter, which ships no `auto_approve`, no `dry_run` and no development mode that grants. -Observe mode is the one way to run unprotected on purpose, and it says so on every receipt. - -## The guarantee it supports - -Fail closed: G6 (unknown action refused) and G7 (no principal refused) in `ctrlrun verify`, and -every row above has an acceptance test. - -## What it does not do - -Failing closed is about what CTRLRun decides. It cannot refuse a call that bypasses the decorator -entirely, a compromised host, or an executor that raises `NotExecuted` after the remote acted; -those are in the threat model as limits, not as vulnerabilities. - -## Next - -- [Decisions](/docs/concepts/decisions): the three that can be reached. -- [Errors reference](/docs/reference/errors): every exception and when it is raised. -- [Threat model](/docs/THREAT_MODEL) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/concepts/observe-mode.mdx b/docs/docs/concepts/observe-mode.mdx deleted file mode 100644 index 022379a..0000000 --- a/docs/docs/concepts/observe-mode.mdx +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: "Observe mode" -description: "mode: observe runs every real decision against real traffic and records what enforcement would have blocked, without blocking anything." ---- - -Observe mode is one top-level line, `mode: observe`, that makes CTRLRun evaluate every action -exactly as it would in enforce mode, execute it regardless, and record on the receipt what would -have been blocked and why. It is how a rollout measures before it enforces. It is not a dry run: -the executor runs and effects land at remotes. - -```yaml runnable -schema: ctrlrun.policy/v3 -mode: observe - -actions: - email.send: - effect: "email:{message_id}" - rules: - - when: { to_domain_eq: "example.com" } - decision: allow - - decision: approve -``` - -`mode:` is refused anywhere but the top level, so a file cannot observe one action and enforce -another; a deployment is in one mode. - -## What it records - -Every receipt carries `would_have`: the decision enforce mode would have reached and, where it -would have refused, the first reason, in the order enforce mode checks them, because enforce -mode stops at the first. A duplicate effect is recorded as one and still runs. After a week: - -```text -actions 1284 -would have been denied 6 - rule[2] 6 -would have needed approval 29 -would have been blocked 2 - duplicate 2 -ambiguous outcomes 0 -``` - -The numbers are counted from `would_have.blocked_reason` and nothing else, from the local store, -with no network. - -## What it never does - -Observe mode asks no human. An `approve` decision is recorded as *would have required approval* -and the action runs; a real approval request is never written, because a counterfactual is not a -place to spend a real grant. An adapter's pre-invocation predicate must answer "no approval -needed" in observe mode for the same reason: a framework that will not invoke a declined tool -would otherwise let a human's *no* stop an action observe mode promises to run. - -## The guarantee it supports - -None directly; observe mode is the way to reach the guarantees safely. What it preserves is the -evidence: every observed action leaves a receipt in the same shape as an enforced one, with the -counterfactual attached. - -## What it does not do - -It does not relax a check in enforce mode, and there is no per-action or per-principal observe. -It does not stop an effect that would have been refused, which is the point and the risk: run it -on traffic you would run unprotected today, read `ctrlrun stats`, then switch the line to -`enforce`. - -## Next - -- [Roll out observe, then enforce](/docs/guides/observe-to-enforce). -- [Fail closed](/docs/concepts/fail-closed): what enforce mode refuses. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/concepts/outcomes-and-ambiguous.mdx b/docs/docs/concepts/outcomes-and-ambiguous.mdx deleted file mode 100644 index 0e5a891..0000000 --- a/docs/docs/concepts/outcomes-and-ambiguous.mdx +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: "Outcomes and AMBIGUOUS" -description: "An executed action ends COMMITTED, FAILED or AMBIGUOUS. Only NotExecuted, raised by the executor, means FAILED." ---- - -An outcome is what CTRLRun knows about the consequence after the executor returns or raises, -and there are three: `COMMITTED`, the remote did it; `FAILED`, the remote definitely did not; -and `AMBIGUOUS`, nobody knows. A timeout is not a failure. A lost reply is not a failure. An -exception nobody expected is not a failure. All three are `AMBIGUOUS`, and an `AMBIGUOUS` effect -blocks a blind retry. - -This is the idea that explains the product. Every framework has two outcomes, success and -error, and retries on error. The real world has a third, and it is where double execution lives. - -## The asymmetry - -| The executor | The outcome | Why | -|---|---|---| -| returns | `COMMITTED` | the remote answered | -| raises `NotExecuted` | `FAILED` | the executor is asserting the remote did nothing, and only it can know | -| raises anything else | `AMBIGUOUS` | a `TimeoutError`, a `ConnectionResetError`, a `KeyError` in the response parser: none of them says what the remote did | -| never returns (worker died) | `AMBIGUOUS` when the lease lapses | the key is never released, because the dead worker may have acted | - -`NotExecuted` is the one exception that makes an effect retryable, which makes it the most -dangerous line in an integration: an executor that raises it after the remote acted has turned -the guarantee into a licence to act twice. `ctrlrun verify` cannot check that for you. Raise it -only where the remote told you, in band, that it rejected the request before doing anything. - -## What the lost reply looks like - -```python runnable -import ctrlrun -from ctrlrun import Control, InMemoryStateStore, Policy - -policy = Policy.from_yaml(""" -schema: ctrlrun.policy/v2 -actions: - stripe.refund: - effect: "refund:{payment_id}" - decision: allow -""") -control = Control(policy, InMemoryStateStore()) -calls: list[str] = [] - - -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}", control=control) -def refund(payment_id: str, amount: int) -> dict: - calls.append(payment_id) # the money has moved by now - raise TimeoutError("no response from api.stripe.com after 30s") - - -with ctrlrun.context(agent="refund-agent"): - try: - refund(payment_id="txn_1", amount=50000) - except TimeoutError: - pass # the agent's framework sees an error and retries - try: - refund(payment_id="txn_1", amount=50000) - except ctrlrun.AmbiguousEffect as blocked: - print("retry refused:", blocked) - else: - raise SystemExit("the retry ran; the customer was refunded twice") - -print("remote refund calls:", len(calls)) -``` - -```text -retry refused: effect refund:txn_1 is ambiguous ... -remote refund calls: 1 -``` - -## Who moves it on - -Exactly two things move a record out of `AMBIGUOUS`, and both have to say which way: - -- **A human**, with `ctrlrun resolve refund:txn_1 --committed` or `--failed`, after asking the - remote. The **effect record** keeps `cli:local` in `resolved_by`, and an `EFFECT_RESOLVED` - event carries the same string. No receipt changes: a receipt is written when the action ends, - a resolution happens afterwards, and editing one would be an alteration the chain reports. -- **A reconcile hook**, `@protect(..., reconcile=...)`, a function that asks the remote what - happened to an effect key and answers committed, not executed, or unknown. It moves the - record only in the direction its answer points, and an answer of unknown leaves it where it - was. - -Nothing sweeps. A process restarting reads the state and repairs nothing; an expired lease is -reported as expired and transitions nothing. The Postgres store applies the same rule to itself: -a connection lost during `COMMIT` is `AMBIGUOUS` until the store re-reads the row. - -## The guarantee it supports - -Unknown is not failed: G5 (ambiguous blocks a blind retry) and G10 (unknown exception is -ambiguous) in `ctrlrun verify`. - -## What it does not do - -CTRLRun cannot find out what the remote did. It refuses to guess, and it makes the question -impossible to skip. It also cannot tell that an executor lied with `NotExecuted`; that is the -integration bug the threat model names as the most dangerous one available. - -## Next - -- [Resolve an AMBIGUOUS effect](/docs/guides/resolve-an-ambiguous-effect). -- [Reconcile automatically](/docs/guides/reconcile-automatically). -- [Effect keys](/docs/concepts/effect-keys) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/concepts/receipts-and-evidence.mdx b/docs/docs/concepts/receipts-and-evidence.mdx deleted file mode 100644 index 38732df..0000000 --- a/docs/docs/concepts/receipts-and-evidence.mdx +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: "Receipts and evidence" -description: "A receipt is a portable JSON record of one executed action: who, what, the decision, the approval, the effect key." ---- - -A receipt is the portable JSON record of one action that reached the executor: who proposed it, -what it was, what the policy and authority decided, which approval it used, which effect key it -reserved, how it ended, and the hash and declared version of the policy that decided it. Every -executed action leaves one. Every step on the way, proposed, decided, approved, reserved, -committed, refused, leaves an event. - -## Where they go - -The store is authoritative: receipts and events are rows, and `ctrlrun receipts`, `inspect` and -`stats` read them from there. A `JSONLEventSink` also appends each to `.ctrlrun/receipts.jsonl` -and `.ctrlrun/events.jsonl` beside the store, one object per line, in order, so the evidence -survives the process and the file can be shipped anywhere. An `OTelEventSink` exports one span -per action and one span event per step to a tracing backend, with argument values kept out -unless you ask for them. - -```console -$ ctrlrun receipts --last 1 --json -``` - -```json -{ - "schema": "ctrlrun.receipt/v3", - "action_id": "act_…", - "action_hash": "sha256:…", - "action": "stripe.refund", - "principal": {"agent": "refund-agent", "user": null}, - "arguments": {"amount": 200000, "payment_id": "txn_2"}, - "decision": "approve", - "approval_id": "apr_…", - "approver": "cli:local", - "effect_key": "refund:txn_2", - "result": "committed", - "policy_hash": "sha256:…", - "policy_version": null, - "controls": [], - "seq": 3, - "prev_hash": "sha256:…" -} -``` - -The field names above are the receipt's; the values are the shape of a real one. The receipt -and event schemas page lists every field with its type. - -## Which policy decided it - -`policy_hash` is the SHA-256 of the policy's canonical decision inputs: the rules, the mode, the -environment and the authority grants, not the file's bytes, so a reformat changes nothing and a -changed rule changes everything. `policy_version` is the operator's own label, recorded and never -authoritative. A receipt from six months ago therefore says what the rules were rather than what -they are now, and where a policy changes between a human approving and an agent executing, the -approval is re-checked against the policy in force at execution. - -## The chain - -Each receipt carries `seq` and `prev_hash`, the hash of the receipt before it. An edit to a -receipt, a deletion from the middle, a reordering: each is detected and named by `seq` with -`ctrlrun receipts --verify-chain`. The chain detects alteration. It does not prove authorship: -receipts are not signed, and an administrator who can rewrite every row including the chain head -can rewrite history undetected. [The receipt chain](/docs/security/receipt-chain) says exactly what -it covers and what it does not. - -## The guarantee it supports - -Receipts: G11 (an altered receipt is detected) in `ctrlrun verify`, and every demo receipt is -asserted to carry every field the specification names. - -## What it does not do - -A receipt records what CTRLRun saw, not what the remote did after the reply was lost; an -`AMBIGUOUS` outcome is recorded as ambiguous, and the resolution, when it comes, is a further -event naming who resolved it. A receipt that failed to write leaves no gap in `seq`; the events -log is where that is reconciled. And receipts are evidence, not a dashboard: there is no UI, by -design. - -## Next - -- [The receipt chain](/docs/security/receipt-chain). -- [Export to OpenTelemetry](/docs/guides/export-to-opentelemetry). -- [Receipt and event schemas](/docs/reference/receipt-and-event-schemas) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/credential-rotation-agent.mdx b/docs/docs/cookbook/credential-rotation-agent.mdx deleted file mode 100644 index 3cb49f3..0000000 --- a/docs/docs/cookbook/credential-rotation-agent.mdx +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: "A credential-rotation agent" -description: "An agent rotates API keys: minting the new key runs on its own, revoking the old one waits for a human, and a lost reply is never repeated blindly." ---- - -An agent rotates service credentials on a schedule. Minting a new key is safe: nothing uses it -yet. Revoking the old one is the step that breaks a client that has not switched over, so it -waits for a person. And a mint whose reply was lost must not be minted again on a guess, because -each mint leaves a live credential somewhere. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - secrets.create_key: - effect: "key:{service}:{rotation_id}" - decision: allow - secrets.revoke_key: - effect: "revoke:{service}:{key_id}" - decision: approve -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -live_keys: list[str] = ["key_old"] - - -def mint(service: str, rotation_id: str, lose_reply: bool = False) -> str: - key_id = f"key_{rotation_id}" - live_keys.append(key_id) # the provider has it from here on - if lose_reply: - raise TimeoutError("no response from the secrets manager after 30s") - return key_id - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect("secrets.create_key", effect="key:{service}:{rotation_id}", control=control) -def create_key(service: str, rotation_id: str, lose_reply: bool = False) -> str: - return mint(service, rotation_id, lose_reply) - - -@ctrlrun.protect("secrets.revoke_key", effect="revoke:{service}:{key_id}", control=control) -def revoke_key(service: str, key_id: str) -> str: - live_keys.remove(key_id) - return "revoked" - - -with ctrlrun.context(agent="rotation-agent"): - print("mint 2026-09:", create_key(service="billing-api", rotation_id="2026-09")) - - try: - revoke_key(service="billing-api", key_id="key_old") - except ctrlrun.ApprovalRequired as pending: - print("revoke key_old: a human decides:", pending.request_id) - else: - raise SystemExit("a key was revoked without a human") - - try: - create_key(service="billing-api", rotation_id="2026-10", lose_reply=True) - except TimeoutError: - print("mint 2026-10: reply lost") - try: - create_key(service="billing-api", rotation_id="2026-10") - except ctrlrun.AmbiguousEffect: - print("mint 2026-10 again: refused; a key may already exist") - else: - raise SystemExit("a second key was minted for one rotation") - -print("live keys at the provider:", live_keys) -``` - -## What the agent sees - -```text -mint 2026-09: key_2026-09 -revoke key_old: a human decides: apr_… -mint 2026-10: reply lost -mint 2026-10 again: refused; a key may already exist -live keys at the provider: ['key_old', 'key_2026-09', 'key_2026-10'] -``` - -Three keys live, not four: the retry that would have minted a duplicate for the October -rotation was refused. `key_old` is still live because the revocation is waiting for a person. - -## The receipt - -```bash runnable -ctrlrun receipts --last 4 -ctrlrun effects --state ambiguous -``` - -## When an AMBIGUOUS appears - -List keys at the provider for the service. If a key for the rotation exists, -`ctrlrun resolve key:billing-api:2026-10 --committed` and use it; if not, `--failed` and mint -again. Never mint on the assumption that the first one did not happen: an orphaned live -credential is the worst outcome here. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/credential-rotation-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [An IAM agent that can grant read but never admin](/docs/cookbook/iam-agent). -- [Resolve an AMBIGUOUS effect](/docs/guides/resolve-an-ambiguous-effect) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/crm-update-agent.mdx b/docs/docs/cookbook/crm-update-agent.mdx deleted file mode 100644 index ba6b36f..0000000 --- a/docs/docs/cookbook/crm-update-agent.mdx +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: "A CRM-update agent" -description: "An agent updates customer records from conversations: a field update runs on its own, merging two records waits for a human, deleting a record is refused." ---- - -A support agent keeps the CRM current from conversations. Updating a phone number is cheap to -undo. Merging two customer records is not, so it waits for a person. Deleting a record destroys -the thing every receipt points at, so an agent never does it. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - crm.update_record: - effect: "crm:{record_id}:{field}:{revision}" - resource: "record:{record_id}" - decision: allow - crm.merge_records: - effect: "merge:{keep}:{drop}" - decision: approve - crm.delete_record: - decision: deny -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -records: dict[str, dict[str, str]] = {"c_1": {"phone": "+353 1 555 0100"}, "c_2": {}} -writes = 0 - - -def crm_update(record_id: str, field: str, value: str) -> str: - global writes - writes += 1 - records[record_id][field] = value - return "updated" - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect( - "crm.update_record", - effect="crm:{record_id}:{field}:{revision}", - resource="record:{record_id}", - control=control, -) -def update(record_id: str, field: str, value: str, revision: int) -> str: - return crm_update(record_id, field, value) - - -@ctrlrun.protect("crm.merge_records", effect="merge:{keep}:{drop}", control=control) -def merge(keep: str, drop: str) -> str: - return "merged" - - -@ctrlrun.protect("crm.delete_record", control=control) -def delete(record_id: str) -> str: - return "deleted" - - -with ctrlrun.context(agent="support-agent"): - print( - "update phone:", update(record_id="c_1", field="phone", value="+353 1 555 0199", revision=7) - ) - - # A second worker handling the same conversation proposes the same revision. - try: - update(record_id="c_1", field="phone", value="+353 1 555 0199", revision=7) - except ctrlrun.DuplicateEffect: - print("same update from a second worker: refused, already applied") - else: - raise SystemExit("one revision was written twice") - - # A later revision is a new effect and runs. - print( - "update phone, revision 8:", - update(record_id="c_1", field="phone", value="+353 1 555 0200", revision=8), - ) - - try: - merge(keep="c_1", drop="c_2") - except ctrlrun.ApprovalRequired as pending: - print("merge c_2 into c_1: a human decides:", pending.request_id) - else: - raise SystemExit("a merge ran without a human") - - try: - delete(record_id="c_2") - except ctrlrun.ActionDenied: - print("delete c_2: refused") - else: - raise SystemExit("a record was deleted") - -print("CRM writes:", writes) -``` - -## What the agent sees - -```text -update phone: updated -same update from a second worker: refused, already applied -update phone, revision 8: updated -merge c_2 into c_1: a human decides: apr_… -delete c_2: refused -CRM writes: 2 -``` - -The revision number in the effect key is what tells a duplicate from a change: the same -revision twice is one effect; a new revision is a new one. - -## The receipt - -```bash runnable -ctrlrun receipts --last 5 -``` - -## When an AMBIGUOUS appears - -Read the record back. If the field holds the new value, `ctrlrun resolve -crm:c_1:phone:8 --committed`; if not, `--failed`. For a merge whose reply was lost, check -which record still exists before resolving: a merge is the one update here that cannot be -undone by another update. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/crm-update-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [A data-deletion agent under a retention rule](/docs/cookbook/data-deletion-agent). -- [Effect keys](/docs/concepts/effect-keys) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/customer-notification-agent.mdx b/docs/docs/cookbook/customer-notification-agent.mdx deleted file mode 100644 index ba377b4..0000000 --- a/docs/docs/cookbook/customer-notification-agent.mdx +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: "A customer-notification agent" -description: "Notify each customer once about an incident: one effect per customer per incident, so a retry after a lost reply cannot send a second message." ---- - -An incident agent notifies affected customers. Each customer should hear once, however many -times the batch is retried or however many workers pick it up. A batch beyond a certain size is -a person's decision, because a wrong message to ten thousand customers is not cheap to undo. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - notify.customer: - effect: "notify:{incident_id}:{customer_id}" - decision: allow - notify.batch: - effect: "batch:{incident_id}" - rules: - - when: { size_lte: 500 } - decision: allow - - decision: approve -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -delivered: list[str] = [] -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect("notify.batch", effect="batch:{incident_id}", control=control) -def start_batch(incident_id: str, size: int) -> str: - return "started" - - -@ctrlrun.protect("notify.customer", effect="notify:{incident_id}:{customer_id}", control=control) -def notify(incident_id: str, customer_id: str) -> str: - delivered.append(customer_id) - return "delivered" - - -customers = ["c_1", "c_2", "c_3"] - -with ctrlrun.context(agent="incident-agent"): - print("batch of 3:", start_batch(incident_id="inc_7", size=3)) - for customer in customers: - notify(incident_id="inc_7", customer_id=customer) - print("first pass delivered:", len(delivered)) - - # The batch is retried after a crash, and a second worker runs it at the same time. - skipped = 0 - for customer in customers + customers: - try: - notify(incident_id="inc_7", customer_id=customer) - except ctrlrun.DuplicateEffect: - skipped += 1 - print("retry and second worker: skipped", skipped, "already-notified customers") - - try: - start_batch(incident_id="inc_8", size=12000) - except ctrlrun.ApprovalRequired as pending: - print("batch of 12,000: a human decides:", pending.request_id) - else: - raise SystemExit("a large batch started without a human") - -print("messages delivered:", len(delivered)) -``` - -## What the agent sees - -```text -batch of 3: started -first pass delivered: 3 -retry and second worker: skipped 6 already-notified customers -batch of 12,000: a human decides: apr_… -messages delivered: 3 -``` - -Three customers, three messages, after a retry and a racing worker. The effect key names the -customer and the incident, so the same customer in a different incident is a new effect. - -## The receipt - -```bash runnable -ctrlrun receipts --last 3 -ctrlrun effects -``` - -Ten receipts for the notifications: three committed, six blocked as duplicates, and the -batch. `ctrlrun effects` lists one effect per customer. - -## When an AMBIGUOUS appears - -A notification whose reply was lost may have been delivered. Check the provider's delivery log -for the customer, then `ctrlrun resolve notify:inc_7:c_N --committed` or `--failed`. If the -provider accepts an idempotency key, pass the effect key as it, and the resolution is nearly -always `--committed`. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/customer-notification-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [An outbound-email agent](/docs/cookbook/outbound-email-agent). -- [Effect keys](/docs/concepts/effect-keys) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/data-deletion-agent.mdx b/docs/docs/cookbook/data-deletion-agent.mdx deleted file mode 100644 index 8806524..0000000 --- a/docs/docs/cookbook/data-deletion-agent.mdx +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: "A data-deletion agent under a retention rule" -description: "An agent handles deletion requests: records past retention are purged on their own, records inside retention wait for a human." ---- - -An agent processes deletion requests against customer data. A record past its retention -period can go; a record still inside retention is a person's decision; a record under legal -hold is not deleted by an agent at all. The policy sees only the arguments, so the executor -passes the facts it decided on: how many days the record has been held, and whether a hold -applies. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - records.purge: - effect: "purge:{record_id}" - resource: "record:{record_id}" - rules: - - when: { legal_hold_eq: true } - decision: deny - - when: { age_days_gte: 730 } - decision: allow - - decision: approve -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -purged: list[str] = [] - - -def purge_at_warehouse(record_id: str, lose_reply: bool = False) -> str: - purged.append(record_id) - if lose_reply: - raise TimeoutError("warehouse did not answer in 30s") - return "purged" - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect( - "records.purge", effect="purge:{record_id}", resource="record:{record_id}", control=control -) -def purge(record_id: str, age_days: int, legal_hold: bool, lose_reply: bool = False) -> str: - return purge_at_warehouse(record_id, lose_reply) - - -with ctrlrun.context(agent="deletion-agent"): - print("r_100, 900 days old:", purge(record_id="r_100", age_days=900, legal_hold=False)) - - try: - purge(record_id="r_101", age_days=400, legal_hold=False) - except ctrlrun.ApprovalRequired as pending: - print("r_101, 400 days old: a human decides:", pending.request_id) - else: - raise SystemExit("a record inside retention was purged without a human") - - try: - purge(record_id="r_102", age_days=900, legal_hold=True) - except ctrlrun.ActionDenied: - print("r_102, under legal hold: refused") - else: - raise SystemExit("a record under legal hold was purged") - - try: - purge(record_id="r_103", age_days=900, legal_hold=False, lose_reply=True) - except TimeoutError: - print("r_103: reply lost") - try: - purge(record_id="r_103", age_days=900, legal_hold=False) - except ctrlrun.AmbiguousEffect: - print("r_103 again: refused until someone checks the warehouse") - else: - raise SystemExit("a purge of unknown outcome was repeated") - -print("purge calls at the warehouse:", purged) -``` - -## What the agent sees - -```text -r_100, 900 days old: purged -r_101, 400 days old: a human decides: apr_… -r_102, under legal hold: refused -r_103: reply lost -r_103 again: refused until someone checks the warehouse -purge calls at the warehouse: ['r_100', 'r_103'] -``` - -The rule order matters: the legal-hold check is first, so a held record is refused whatever -its age. Rules are first-match, and the receipt names which one decided. - -## The receipt - -```bash runnable -ctrlrun receipts --last 4 -``` - -## When an AMBIGUOUS appears - -A purge is the one action here you cannot repeat to be safe, because a second purge of a -record that is gone may error in a way that looks like a failure, and a second purge of one -that is not gone is what you wanted. Query the warehouse for `r_103`, then -`ctrlrun resolve purge:r_103 --committed` or `--failed`, and let the agent's next attempt -follow from that. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/data-deletion-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [A CRM-update agent](/docs/cookbook/crm-update-agent). -- [Decisions](/docs/concepts/decisions) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/database-migration-agent.mdx b/docs/docs/cookbook/database-migration-agent.mdx deleted file mode 100644 index b80215a..0000000 --- a/docs/docs/cookbook/database-migration-agent.mdx +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: "A database-migration agent" -description: "An agent runs schema migrations: forward migrations on staging run on their own, every production migration waits for a human, a rollback is refused." ---- - -An agent applies schema migrations from a migrations directory. Forward migrations on staging -are routine; every production migration is a human decision; a rollback that drops data is -not an agent action. The interesting case is the migration whose connection dropped: it may -have applied, and the agent must not run it again on a guess. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - db.migrate: - effect: "migration:{database}:{version}" - rules: - - when: { database_eq: staging } - decision: allow - - decision: approve - db.rollback: - decision: deny -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -applied: dict[str, list[str]] = {"staging": [], "production": []} - - -def run_migration(database: str, version: str, drop_connection: bool = False) -> str: - applied[database].append(version) # the DDL ran - if drop_connection: - raise ConnectionResetError("connection reset by peer") # ...and the reply was lost - return "applied" - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect("db.migrate", effect="migration:{database}:{version}", control=control) -def migrate(database: str, version: str, drop_connection: bool = False) -> str: - return run_migration(database, version, drop_connection) - - -@ctrlrun.protect("db.rollback", control=control) -def rollback(database: str, version: str) -> str: - return "rolled back" - - -with ctrlrun.context(agent="migration-agent"): - print("0042 on staging:", migrate(database="staging", version="0042")) - - try: - migrate(database="production", version="0042") - except ctrlrun.ApprovalRequired as pending: - print("0042 on production: a human decides:", pending.request_id) - else: - raise SystemExit("a production migration ran without a human") - - try: - rollback(database="production", version="0041") - except ctrlrun.ActionDenied: - print("rollback on production: refused") - else: - raise SystemExit("a rollback ran") - - try: - migrate(database="staging", version="0043", drop_connection=True) - except ConnectionResetError: - print("0043 on staging: the connection dropped; outcome unknown") - try: - migrate(database="staging", version="0043") - except ctrlrun.AmbiguousEffect: - print("0043 on staging again: refused; a human checks the schema first") - else: - raise SystemExit("a migration of unknown outcome was re-run") - -print("migrations applied on staging:", applied["staging"]) -``` - -## What the agent sees - -```text -0042 on staging: applied -0042 on production: a human decides: apr_… -rollback on production: refused -0043 on staging: the connection dropped; outcome unknown -0043 on staging again: refused; a human checks the schema first -migrations applied on staging: ['0042', '0043'] -``` - -`0043` ran once. The agent's retry would have run it a second time; the effect key -`migration:staging:0043` in the `AMBIGUOUS` state is what stopped it. - -## The receipt - -```bash runnable -ctrlrun receipts --last 3 -ctrlrun effects --state ambiguous -``` - -## When an AMBIGUOUS appears - -Query the migrations table in the database itself: if `0043` is recorded, -`ctrlrun resolve migration:staging:0043 --committed`; if not, `--failed`, and the agent's next -attempt runs. A `reconcile` hook that runs that query is the automatic form. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/database-migration-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [A deploy agent](/docs/cookbook/deploy-agent). -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/deploy-agent.mdx b/docs/docs/cookbook/deploy-agent.mdx deleted file mode 100644 index be3d90d..0000000 --- a/docs/docs/cookbook/deploy-agent.mdx +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: "A deploy agent" -description: "An agent operates a Kubernetes cluster: a rollout restart runs on its own, applying to production waits for a human." ---- - -An on-call agent operates a cluster from incident tickets. Restarting a deployment is cheap to -undo and should run without asking; applying a manifest to production should wait for a person; -deleting a namespace is not something an agent does, whatever the ticket says. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - k8s.rollout_restart: - effect: "restart:{cluster}:{deployment}" - decision: allow - k8s.apply: - effect: "apply:{cluster}:{manifest_hash}" - rules: - - when: { cluster_in: [staging, dev] } - decision: allow - - decision: approve - k8s.delete_namespace: - decision: deny -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -calls: list[str] = [] - - -def kubectl(*args: str) -> str: - calls.append(" ".join(args)) - return "ok" - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect("k8s.rollout_restart", effect="restart:{cluster}:{deployment}", control=control) -def restart(cluster: str, deployment: str) -> str: - return kubectl("rollout", "restart", f"deployment/{deployment}", "--context", cluster) - - -@ctrlrun.protect("k8s.apply", effect="apply:{cluster}:{manifest_hash}", control=control) -def apply(cluster: str, manifest_hash: str) -> str: - return kubectl("apply", "-f", manifest_hash, "--context", cluster) - - -@ctrlrun.protect("k8s.delete_namespace", control=control) -def delete_namespace(cluster: str, name: str) -> str: - return kubectl("delete", "namespace", name, "--context", cluster) - - -with ctrlrun.context(agent="oncall-agent"): - print("restart checkout on prod:", restart(cluster="prod-eu", deployment="checkout")) - print("apply to staging:", apply(cluster="staging", manifest_hash="sha256:9c1f")) - - try: - apply(cluster="prod-eu", manifest_hash="sha256:9c1f") - except ctrlrun.ApprovalRequired as pending: - print("apply to prod: a human decides:", pending.request_id) - else: - raise SystemExit("a production apply ran without a human") - - try: - delete_namespace(cluster="prod-eu", name="checkout") - except ctrlrun.ActionDenied as refused: - print("delete namespace: refused,", refused.reason) - else: - raise SystemExit("a namespace delete ran") - - # A second worker picks up the same ticket. - try: - restart(cluster="prod-eu", deployment="checkout") - except ctrlrun.DuplicateEffect: - print("second worker restarts checkout: refused, already done") - else: - raise SystemExit("the same restart ran twice") - -print("kubectl calls:", len(calls)) -``` - -## What the agent sees - -```text -restart checkout on prod: ok -apply to staging: ok -apply to prod: a human decides: apr_… -delete namespace: refused, decision -second worker restarts checkout: refused, already done -kubectl calls: 2 -``` - -## The receipt - -```bash runnable -ctrlrun receipts --last 5 -``` - -The `delete_namespace` receipt is `deny/denied` with no effect key: the action has none, -because it never runs. The duplicate restart is `allow/blocked` on `restart:prod-eu:checkout`. - -## When an AMBIGUOUS appears - -`kubectl apply` that timed out may have applied. Check the cluster (`kubectl diff`), then -`ctrlrun resolve apply:prod-eu:sha256:… --committed` or `--failed`. The effect key is the -manifest's hash, so a re-apply of the same manifest is the same effect and a changed manifest is -a new one, which is what you want. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/deploy-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [A database-migration agent](/docs/cookbook/database-migration-agent). -- [Effect keys](/docs/concepts/effect-keys) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/iam-agent.mdx b/docs/docs/cookbook/iam-agent.mdx deleted file mode 100644 index e12440a..0000000 --- a/docs/docs/cookbook/iam-agent.mdx +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: "An IAM agent that can grant read but never admin" -description: "An access-request agent grants roles: read and viewer roles run on their own, anything else waits for a human." ---- - -An access-request agent grants roles from tickets. Read-only roles are routine, write roles -need a person, and `admin` is never granted by an agent. The hazard is the one this recipe -shows last: a human approves `reader` and the agent, re-planning or told to by a ticket's -text, tries to execute `admin` with that approval. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - iam.grant_role: - effect: "grant:{principal}:{role}" - resource: "project:{project}" - rules: - - when: { role_eq: admin } - decision: deny - - when: { role_in: [reader, viewer] } - decision: allow - - decision: approve - iam.revoke_role: - effect: "revoke:{principal}:{role}" - decision: allow -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -bindings: list[tuple[str, str, str]] = [] - - -def bind(project: str, principal: str, role: str) -> str: - bindings.append((project, principal, role)) - return "bound" - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect( - "iam.grant_role", - effect="grant:{principal}:{role}", - resource="project:{project}", - control=control, -) -def grant(project: str, principal: str, role: str) -> str: - return bind(project, principal, role) - - -with ctrlrun.context(agent="access-agent"): - print( - "reader on billing:", grant(project="billing", principal="ana@example.com", role="reader") - ) - - try: - grant(project="billing", principal="ana@example.com", role="editor") - except ctrlrun.ApprovalRequired as pending: - print("editor on billing: a human decides:", pending.request_id) - request_id = pending.request_id - else: - raise SystemExit("editor was granted without a human") - - store.grant_approval(request_id, "human:security") - with ctrlrun.with_approval(request_id): - try: - grant(project="billing", principal="ana@example.com", role="admin") - except ctrlrun.ActionDenied: - print("admin with the editor approval: refused; admin is never an agent action") - else: - raise SystemExit("admin was granted on an approval for editor") - print( - "editor with the editor approval:", - grant(project="billing", principal="ana@example.com", role="editor"), - ) - -print("bindings:", bindings) -``` - -## What the agent sees - -```text -reader on billing: bound -editor on billing: a human decides: apr_… -admin with the editor approval: refused; admin is never an agent action -editor with the editor approval: bound -bindings: [('billing', 'ana@example.com', 'reader'), ('billing', 'ana@example.com', 'editor')] -``` - -`admin` is refused by the policy before the approval is even considered. Had the policy allowed -it with approval, the approval for `editor` would still not have matched: it is bound to the -hash of `editor`, and `admin` hashes differently. - -## The receipt - -```bash runnable -ctrlrun receipts --last 4 -``` - -## When an AMBIGUOUS appears - -An IAM call that timed out may have bound the role. Read the binding back from the provider, -then `ctrlrun resolve grant:ana@example.com:editor --committed` or `--failed`. Granting a role -twice is usually idempotent at the provider, but the receipt should say what happened, not what -was assumed. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/iam-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [A credential-rotation agent](/docs/cookbook/credential-rotation-agent). -- [Approval binding](/docs/concepts/approval-binding) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/index.mdx b/docs/docs/cookbook/index.mdx deleted file mode 100644 index e0791c5..0000000 --- a/docs/docs/cookbook/index.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: "Cookbook" -description: "One recipe per real situation: the policy, the code with a fake remote, what the agent sees when refused or asked, the receipt." ---- - -Each recipe is a situation an agent is put in, across money, infrastructure, permissions, -records and communications, and shows the policy, the code against a stand-in remote, what the -agent sees when it is refused or asked, the receipt, and what to do when an effect's outcome is -unknown. Every runnable block runs offline in this repository's CI, and every recipe with code -is also a directory under `examples/cookbook/` extracted from its page. To run one instead of -reading it: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/refund-agent -pip install ctrlrun && python main.py -``` - -## Money - -- [A refund agent with amount tiers](/docs/cookbook/refund-agent) -- [A payout agent with maker/checker via delegation](/docs/cookbook/payout-maker-checker) - -## Infrastructure - -- [A deploy agent](/docs/cookbook/deploy-agent) -- [A database-migration agent](/docs/cookbook/database-migration-agent) - -## Permissions - -- [An IAM agent that can grant read but never admin](/docs/cookbook/iam-agent) -- [A credential-rotation agent](/docs/cookbook/credential-rotation-agent) - -## Records - -- [A CRM-update agent](/docs/cookbook/crm-update-agent) -- [A data-deletion agent under a retention rule](/docs/cookbook/data-deletion-agent) - -## Communications - -- [An outbound-email agent with external-recipient approval](/docs/cookbook/outbound-email-agent) -- [A customer-notification agent](/docs/cookbook/customer-notification-agent) - -## Multi-agent - -- [A manager agent delegating bounded authority to a worker](/docs/cookbook/manager-and-worker) - -## Integrations - -- [Protect an existing MCP server in five minutes](/docs/cookbook/protect-an-mcp-server) -- [LangGraph with interrupt()](/docs/cookbook/langgraph-interrupt) -- [OpenAI Agents SDK tool approval](/docs/cookbook/openai-agents-tool-approval) -- [Approvals in Slack via webhook](/docs/cookbook/slack-approvals) -- [Receipts into OpenTelemetry](/docs/cookbook/receipts-to-opentelemetry) - -## Operations - -- [Observe for a week, then enforce](/docs/cookbook/observe-then-enforce) -- [Resolve an ambiguous effect](/docs/cookbook/resolve-an-ambiguous-effect) -- [Reconcile against Stripe or Kubernetes automatically](/docs/cookbook/reconcile-against-the-remote) -- [Run verify in GitHub Actions](/docs/cookbook/verify-in-github-actions) -- [Move from SQLite to Postgres](/docs/cookbook/sqlite-to-postgres) - -## Next - -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/langgraph-interrupt.mdx b/docs/docs/cookbook/langgraph-interrupt.mdx deleted file mode 100644 index daaaad6..0000000 --- a/docs/docs/cookbook/langgraph-interrupt.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "LangGraph with interrupt()" -description: "Route a refund's approval through LangGraph's own interrupt(): the operator builds the Control." ---- - -A LangGraph agent issues refunds from a node. When the policy says a human must approve, the -request should surface as the graph's own interrupt, where your operators already answer, and -the yes must not be reusable for a different amount. The adapter buys exactly that and nothing -else; `@protect` alone already covers the node. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - decision: approve -``` - -## The code - -This is the adapter's own example. It needs `pip install ctrlrun-langgraph` and a LangGraph -install, which the harness that runs the other recipes does not have; the adapter's tests run -this shape against a real `langgraph` in this repository's CI, and the adapter's README carries -the conformance results. - -```python -from langgraph.checkpoint.memory import InMemorySaver -from langgraph.graph import START, StateGraph -from langgraph.types import Command - -from ctrlrun import Control, InterruptApprovalProvider, Policy, SQLiteStateStore, context, protect -from ctrlrun_langgraph import LangGraphInterrupt - -store = SQLiteStateStore(".ctrlrun/state.db") -control = Control( - Policy.from_file("ctrlrun.yaml"), - store, - approvals=InterruptApprovalProvider(store, LangGraphInterrupt(carries_approved_arguments=True)), -) - - -@protect("stripe.refund", effect="refund:{payment_id}", wait=True, control=control) -def issue_refund(payment_id: str, amount: int) -> str: - return stripe.Refund.create(payment_intent=payment_id, amount=amount).status - - -def refund_node(state: dict) -> dict: - with context(agent="refund-agent"): - return {"status": issue_refund(payment_id=state["payment_id"], amount=state["amount"])} - - -graph = StateGraph(dict).add_node("refund", refund_node).add_edge(START, "refund").compile( - checkpointer=InMemorySaver() -) -config = {"configurable": {"thread_id": "ticket-4471"}} - -result = graph.invoke({"payment_id": "txn_2", "amount": 250000}, config) -if "__interrupt__" in result: - pending = graph.get_state(config).tasks[0].interrupts[0].value - # `pending` is JSON: request_id, action_id, action, action_hash, arguments, resource, - # environment, agent, user, created_at, expires_at. Show it to a human. - result = graph.invoke( - Command(resume={"approved": True, "approver": "ada@example.com", "arguments": pending["arguments"]}), - config, - ) -print(result["status"]) -``` - -## What the agent sees - -The €2,500 refund interrupts the graph with a payload naming the action and its arguments. -Resuming with `approved: True` and the arguments the human saw runs it once. Resuming with -different arguments is refused with `ApprovalMismatch`, the approval is left grantable, and -nothing runs. Resuming with `approved: False` refuses and records who said no. - -## The receipt - -The receipt is the same shape as one from `ctrlrun approve`: `approve/committed`, approver -`ada@example.com`. The node ran twice, once to ask and once on resume, so the log holds two -`action_id`s and two approval requests for one refund; the `action_hash` is continuous, which is -why the binding is about content and never about an id. - -## When an AMBIGUOUS appears - -If Stripe's reply is lost inside the resumed node, the effect is `AMBIGUOUS` and the graph's -retry, or a re-run of the thread, is refused. Resolve it with `ctrlrun resolve refund:txn_2 ---committed` or `--failed`; the approval was spent on the execution, so a retry after `--failed` -needs a new interrupt. - -## Next - -- [Use the LangGraph adapter](/docs/guides/langgraph-adapter): prevention versus attribution, and where LangGraph shows through. -- [Approval binding](/docs/concepts/approval-binding) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/manager-and-worker.mdx b/docs/docs/cookbook/manager-and-worker.mdx deleted file mode 100644 index e99fa87..0000000 --- a/docs/docs/cookbook/manager-and-worker.mdx +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: "A manager agent delegating bounded authority to a worker" -description: "A manager agent holds a delegable grant, hands a worker a narrower slice for one job, the worker cannot exceed or widen it." ---- - -A manager agent plans a job and hands parts of it to worker agents. Each worker should hold -exactly the authority its part needs, for the time the job takes, and nothing the manager -does not itself hold. When the job ends, one revocation should remove every worker's authority -at once. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v3 - -authority: - max_delegation_depth: 3 - grants: - - id: ops-manager - subject: { agent: "ops-manager" } - actions: ["k8s.rollout_restart", "k8s.scale"] - resources: ["cluster:*"] - constraints: { replicas_gte: 0, replicas_lte: 50 } - environments: ["production"] - delegable: true - expires_at: "2027-01-01T00:00:00Z" - -actions: - k8s.rollout_restart: - effect: "restart:{cluster}:{deployment}" - resource: "cluster:{cluster}" - decision: allow - k8s.scale: - effect: "scale:{cluster}:{deployment}:{replicas}" - resource: "cluster:{cluster}" - decision: allow -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -from ctrlrun import ( - Action, - Authority, - AuthorityDenied, - AuthorityEscalation, - Control, - Policy, - Principal, - SQLiteStateStore, -) -from ctrlrun.authority import grant_from_yaml - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -MANAGER = Principal(agent="ops-manager") -WORKER = Principal(agent="scale-worker") -document = (HERE / "ctrlrun.yaml").read_text(encoding="utf-8") -store = SQLiteStateStore(STATE / "state.db") -control = Control( - Policy.from_yaml(document, source="ctrlrun.yaml"), - store, - authority=Authority.from_yaml(document, source="ctrlrun.yaml"), - environment="production", -) -scaled: list[tuple[str, int]] = [] - - -def scale(who: Principal, cluster: str, deployment: str, replicas: int) -> None: - control.execute( - Action( - name="k8s.scale", - arguments={"cluster": cluster, "deployment": deployment, "replicas": replicas}, - principal=who, - resource=f"cluster:{cluster}", - ), - lambda: scaled.append((deployment, replicas)), - f"scale:{cluster}:{deployment}:{replicas}", - ) - - -# The worker gets scaling only, on one cluster, up to 10 replicas, for a day. -job = control.delegate( - "ops-manager", - grant_from_yaml(""" -subject: { agent: "scale-worker" } -actions: ["k8s.scale"] -resources: ["cluster:prod-eu"] -constraints: { replicas_gte: 0, replicas_lte: 10 } -environments: ["production"] -expires_at: "2026-12-01T00:00:00Z" -"""), - by=MANAGER, -) -print("worker's grant:", job.delegation_id) - -scale(WORKER, "prod-eu", "checkout", 6) -print("worker scales checkout to 6 on prod-eu: done") - -try: - scale(WORKER, "prod-eu", "checkout", 40) -except AuthorityDenied as refused: - print("worker scales to 40: refused,", refused.reason) -else: - raise SystemExit("the worker exceeded its slice") - -try: - scale(WORKER, "prod-us", "checkout", 6) -except AuthorityDenied as refused: - print("worker scales on prod-us: refused,", refused.reason) -else: - raise SystemExit("the worker acted outside its cluster") - -try: - control.delegate( - "ops-manager", - grant_from_yaml(""" -subject: { agent: "scale-worker" } -actions: ["k8s.scale"] -resources: ["cluster:prod-eu"] -environments: ["production"] -expires_at: "2026-12-01T00:00:00Z" -"""), - by=MANAGER, - ) -except AuthorityEscalation as refused: - print("a slice that omits constraints: refused,", refused.reason, refused.dimension) -else: - raise SystemExit("an omitted dimension was inherited as unlimited") - -# The job is over. -control.revoke(job.delegation_id, by="ops-manager") -try: - scale(WORKER, "prod-eu", "checkout", 4) -except AuthorityDenied as refused: - print("worker after revocation: refused,", refused.reason) -else: - raise SystemExit("a revoked worker still acted") - -print("scaling calls:", scaled) -store.close() -``` - -## What the agent sees - -```text -worker's grant: dlg_… -worker scales checkout to 6 on prod-eu: done -worker scales to 40: refused, authority_constraint -worker scales on prod-us: refused, no_authority -a slice that omits constraints: refused, containment constraints -worker after revocation: refused, authority_revoked -scaling calls: [('checkout', 6)] -``` - -Omitting `constraints:` in the second delegation was refused, not inherited: a slice that -names no replica limit would have authorized what the manager's own grant caps. - -## The receipt - -```bash runnable -ctrlrun receipts --last 2 -``` - -Every refusal is an `AUTHORITY_DENIED` event naming the grant it failed against; the delegation -and the revocation are `DELEGATION_CREATED` and `DELEGATION_REVOKED`, with who did each. - -## When an AMBIGUOUS appears - -A scale call that timed out may have applied. Read the deployment's replica count, then -`ctrlrun resolve scale:prod-eu:checkout:6 --committed` or `--failed`. A worker whose grant has -since been revoked cannot retry either way; the resolution is the manager's or a human's. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/manager-and-worker -pip install ctrlrun && python main.py -``` - -## Next - -- [A payout agent with maker/checker](/docs/cookbook/payout-maker-checker). -- [Authority and delegation](/docs/concepts/authority-and-delegation) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/observe-then-enforce.mdx b/docs/docs/cookbook/observe-then-enforce.mdx deleted file mode 100644 index db2b0be..0000000 --- a/docs/docs/cookbook/observe-then-enforce.mdx +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: "Observe for a week, then enforce" -description: "Run the real policy in observe mode against real traffic, execute everything, record what enforcement would have blocked." ---- - -You have an agent in production and no idea what a policy would cost. Put the policy in -front of it in observe mode: every action executes as before, every receipt says what enforce -mode would have done, and after a week `ctrlrun stats` gives you the refusals and approval -requests you would have fielded. Then change the one line. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v3 -mode: observe - -actions: - crm.update_record: - effect: "crm:{record_id}:{field}:{revision}" - decision: allow - email.send: - effect: "email:{message_id}" - rules: - - when: { to_domain_eq: "example.com" } - decision: allow - - decision: approve - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - when: { amount_gte: 0, amount_lte: 500000 } - decision: approve - - decision: deny -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -executed: list[str] = [] -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect("crm.update_record", effect="crm:{record_id}:{field}:{revision}", control=control) -def update(record_id: str, field: str, value: str, revision: int) -> str: - executed.append("update") - return "updated" - - -@ctrlrun.protect("email.send", effect="email:{message_id}", control=control) -def send(message_id: str, to_domain: str) -> str: - executed.append("send") - return "sent" - - -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}", control=control) -def refund(payment_id: str, amount: int) -> str: - executed.append("refund") - return "refunded" - - -# A week of traffic, compressed. -with ctrlrun.context(agent="support-agent"): - update(record_id="c_1", field="phone", value="+353 1 555 0100", revision=3) - send(message_id="m_1", to_domain="example.com") - send(message_id="m_2", to_domain="gmail.com") # would have needed a human - refund(payment_id="txn_1", amount=12000) - refund(payment_id="txn_2", amount=250000) # would have needed a human - refund(payment_id="txn_3", amount=900000) # would have been denied - refund(payment_id="txn_1", amount=12000) # would have been a duplicate - -print("actions executed:", len(executed)) -if len(executed) != 7: - raise SystemExit("observe mode blocked something; it must execute everything") - -for receipt in store.receipts(): - if receipt.would_have is not None and receipt.would_have.blocked_reason: - print(f"{receipt.action} would have been blocked: {receipt.would_have.blocked_reason}") -``` - -## What the agent sees - -```text -actions executed: 7 -email.send would have been blocked: approval_required -stripe.refund would have been blocked: approval_required -stripe.refund would have been blocked: rule[2] -stripe.refund would have been blocked: duplicate -``` - -Seven actions, seven executions. The mail to `gmail.com` went out; so did the €9,000 refund. -Observe mode asks no human and stops nothing. It only writes down what it would have done. - -## The receipt - -```bash runnable -ctrlrun stats -``` - -The numbers are counted from `would_have.blocked_reason` on the receipts in the local store, -nothing else. Change `mode: observe` to `mode: enforce` and the same receipts become `BLOCKED` -receipts and approval requests. - -## When an AMBIGUOUS appears - -Observe mode changes nothing about outcomes: a lost reply is `AMBIGUOUS` in observe mode too, -and the record is written. What differs is that observe mode records that a retry *would* have -been refused and lets it run, so resolve the effect before switching to enforce, or the first -enforced retry is refused. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/observe-then-enforce -pip install ctrlrun && python main.py -``` - -## Next - -- [Roll out observe, then enforce](/docs/guides/observe-to-enforce): the week, the numbers and the switch. -- [Observe mode](/docs/concepts/observe-mode) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/openai-agents-tool-approval.mdx b/docs/docs/cookbook/openai-agents-tool-approval.mdx deleted file mode 100644 index 21414b3..0000000 --- a/docs/docs/cookbook/openai-agents-tool-approval.mdx +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "OpenAI Agents SDK tool approval" -description: "Route a refund's approval through the OpenAI Agents SDK's own tool-approval interruption." ---- - -An Agents SDK agent has a refund tool. When the policy says a human must approve, the run -should stop with the SDK's own `ToolApprovalItem`, where this SDK's users already answer, and -a refusal must reach your code as an exception rather than the model as text to retry. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - decision: approve -``` - -## The code - -This is the adapter's own example. It needs `pip install ctrlrun-openai-agents` and the SDK, -which the harness that runs the other recipes does not have; the adapter's tests run this shape -against a real `openai-agents` in this repository's CI. - -```python -from agents import Agent - -import ctrlrun_openai_agents as gate -from ctrlrun import Control, InterruptApprovalProvider, Policy, SQLiteStateStore, protect -from ctrlrun_openai_agents import AgentsInterrupt, protected_tool - -store = SQLiteStateStore(".ctrlrun/state.db") -control = Control(Policy.from_file("ctrlrun.yaml"), store, approvals=InterruptApprovalProvider(store, AgentsInterrupt())) - - -@protect("stripe.refund", effect="refund:{payment_id}", wait=True, control=control) -def issue_refund(payment_id: str, amount: int) -> str: - return stripe.Refund.create(payment_intent=payment_id, amount=amount).status - - -async def refund_tool(payment_id: str, amount: int) -> str: - """Issue a refund for a payment. Amounts are in integer minor units.""" - return issue_refund(payment_id=payment_id, amount=amount) - - -agent = Agent(name="refunds", tools=[protected_tool(control, "stripe.refund", refund_tool)]) - -result = await gate.run(agent, "refund txn_2 by 2500 euros") -if result.interruptions: - state = result.to_state() - for item in result.interruptions: - print("a human decides on", item.name, item.arguments) - state.approve(item) # or state.reject(item) - result = await gate.run(agent, state) -print(result.final_output) -``` - -## What the agent sees - -The SDK asks before invoking, because `protected_tool` answers its `needs_approval` from the -policy; the run returns with one interruption naming the tool and its arguments. After -`state.approve(item)` the resumed run invokes the tool with exactly that call's arguments, and -CTRLRun records `openai-agents:tool-approval` as the approver. A refusal by CTRLRun, a -duplicate for instance, reaches your `except` as `DuplicateEffect` through `gate.run`, not the -model as "please try again". - -## The receipt - -`approve/committed`. The binding across the interrupt is the SDK's, keyed by `call_id`, so the -receipt attributes the approval and cannot re-check the arguments against the hash: that is -attribution, and the adapter's README says so in that word. A rejection leaves no CTRLRun -evidence at all, because the SDK never invokes a rejected tool; record it where you call -`state.reject(item)`. - -## When an AMBIGUOUS appears - -The SDK's default would surface a lost reply to the model as text, and the measured behaviour -is that the model retries until the refund lands three or four times. With `effect=` declared, -the retry is refused with `AmbiguousEffect`, which `gate.run` returns as itself; resolve with -`ctrlrun resolve refund:txn_2 --committed` or `--failed`. - -## Next - -- [Use the OpenAI Agents SDK adapter](/docs/guides/openai-agents-adapter): where the SDK shows through, and `ApprovalNotAsked`. -- [Three ways in](/docs/get-started/three-ways-in) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/outbound-email-agent.mdx b/docs/docs/cookbook/outbound-email-agent.mdx deleted file mode 100644 index 5552d16..0000000 --- a/docs/docs/cookbook/outbound-email-agent.mdx +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: "An outbound-email agent with external-recipient approval" -description: "An agent sends email: messages inside the company go on their own, any message to an external domain waits for a human who sees the exact recipient." ---- - -An assistant drafts and sends email on a team's behalf. Internal mail is routine. Anything -leaving the company waits for a person, who sees the exact recipient, and the approval is -bound to that recipient: an agent that re-plans the address after the yes finds its approval -matches nothing. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - email.send: - effect: "email:{message_id}" - rules: - - when: { to_domain_eq: "example.com" } - decision: allow - - decision: approve -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -sent: list[str] = [] - - -def smtp_send(message_id: str, to: str) -> str: - sent.append(to) - return "sent" - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect("email.send", effect="email:{message_id}", control=control) -def send(message_id: str, to: str, to_domain: str, subject: str) -> str: - return smtp_send(message_id, to) - - -with ctrlrun.context(agent="assistant"): - print( - "to a colleague:", - send(message_id="m_1", to="li@example.com", to_domain="example.com", subject="Q3 numbers"), - ) - - try: - send(message_id="m_2", to="press@partner.co", to_domain="partner.co", subject="Q3 numbers") - except ctrlrun.ApprovalRequired as pending: - print("to partner.co: a human decides:", pending.request_id) - request_id = pending.request_id - else: - raise SystemExit("external mail went out without a human") - - store.grant_approval(request_id, "human:li@example.com") - with ctrlrun.with_approval(request_id): - # The agent re-plans the recipient after the yes. - try: - send( - message_id="m_2", - to="tips@journalist.example", - to_domain="journalist.example", - subject="Q3 numbers", - ) - except ctrlrun.ApprovalMismatch: - print("to a different address with the same approval: refused") - else: - raise SystemExit("an approval for one recipient sent mail to another") - print( - "to partner.co, as approved:", - send( - message_id="m_2", - to="press@partner.co", - to_domain="partner.co", - subject="Q3 numbers", - ), - ) - -print("messages sent:", sent) -``` - -## What the agent sees - -```text -to a colleague: sent -to partner.co: a human decides: apr_… -to a different address with the same approval: refused -to partner.co, as approved: sent -messages sent: ['li@example.com', 'press@partner.co'] -``` - -The approval hashed `to`, `to_domain`, `subject` and `message_id` together. Any of them changing -after the yes is a different action. - -## The receipt - -```bash runnable -ctrlrun receipts --last 4 -``` - -## When an AMBIGUOUS appears - -An SMTP submission that timed out may have been accepted. Check the provider's message log for -`m_N`, then `ctrlrun resolve email:m_N --committed` or `--failed`. The effect key is the message -id, so a resend of the same message is one effect and a new message is a new one. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/outbound-email-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [A customer-notification agent](/docs/cookbook/customer-notification-agent). -- [Approval binding](/docs/concepts/approval-binding) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/payout-maker-checker.mdx b/docs/docs/cookbook/payout-maker-checker.mdx deleted file mode 100644 index c48e2b1..0000000 --- a/docs/docs/cookbook/payout-maker-checker.mdx +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: "A payout agent with maker/checker via delegation" -description: "A treasury lead holds a delegable grant, delegates a narrower slice to a payout agent." ---- - -A payout agent moves money out of the platform on behalf of a treasury lead. The lead may -delegate a bounded slice of that authority to the agent, the agent may never widen it, and -every payout above the desk limit still needs a second person before it runs. - -## The policy - -Authority and policy are separate axes. The grant says the lead may propose payouts to -€100,000 and may delegate; the policy says anything above €10,000 needs a human, whoever asks. - -```yaml runnable -schema: ctrlrun.policy/v3 - -authority: - grants: - - id: treasury-lead - subject: { agent: "treasury-lead", user: "mira@example.com" } - actions: ["bank.payout"] - resources: ["account:*"] - constraints: { amount_gte: 0, amount_lte: 10000000 } - environments: ["production"] - delegable: true - expires_at: "2027-01-01T00:00:00Z" - -actions: - bank.payout: - effect: "payout:{account}:{reference}" - resource: "account:{account}" - rules: - - when: { amount_gte: 0, amount_lte: 1000000 } - decision: allow - - decision: approve -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -from ctrlrun import ( - Action, - ApprovalRequired, - Authority, - AuthorityDenied, - AuthorityEscalation, - Control, - Policy, - Principal, - SQLiteStateStore, - with_approval, -) -from ctrlrun.authority import grant_from_yaml - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -LEAD = Principal(agent="treasury-lead", user="mira@example.com") -AGENT = Principal(agent="payout-agent", user="mira@example.com") -document = (HERE / "ctrlrun.yaml").read_text(encoding="utf-8") -store = SQLiteStateStore(STATE / "state.db") -control = Control( - Policy.from_yaml(document, source="ctrlrun.yaml"), - store, - authority=Authority.from_yaml(document, source="ctrlrun.yaml"), - environment="production", -) -paid: list[tuple[str, int]] = [] - - -def payout(account: str, reference: str, amount: int) -> dict: - paid.append((reference, amount)) - return {"reference": reference, "status": "sent"} - - -def proposal(who: Principal, account: str, reference: str, amount: int) -> Action: - return Action( - name="bank.payout", - arguments={"account": account, "reference": reference, "amount": amount}, - principal=who, - resource=f"account:{account}", - ) - - -# The lead hands the agent a €25,000 slice, itself delegable so the agent could pass a narrower -# one on. Every dimension is stated: omission is rejected, never inherited. -slice_ = grant_from_yaml(""" -subject: { agent: "payout-agent", user: "mira@example.com" } -actions: ["bank.payout"] -resources: ["account:ops-*"] -constraints: { amount_gte: 0, amount_lte: 2500000 } -environments: ["production"] -delegable: true -expires_at: "2026-12-31T00:00:00Z" -""") -delegation = control.delegate("treasury-lead", slice_, by=LEAD) -print("delegated to the payout agent:", delegation.delegation_id) - -# €8,000: inside the slice, inside the autonomous band. Runs. -control.execute( - proposal(AGENT, "ops-eu", "inv-1042", 800000), - lambda: payout("ops-eu", "inv-1042", 800000), - "payout:ops-eu:inv-1042", -) -print("€8,000 payout: sent") - -# €18,000: inside the slice, above the desk limit. A second person. -try: - control.execute( - proposal(AGENT, "ops-eu", "inv-1043", 1800000), - lambda: payout("ops-eu", "inv-1043", 1800000), - "payout:ops-eu:inv-1043", - ) -except ApprovalRequired as pending: - print("€18,000 payout: a checker decides:", pending.request_id) - store.grant_approval(pending.request_id, "checker:sam@example.com") - with with_approval(pending.request_id): - control.execute( - proposal(AGENT, "ops-eu", "inv-1043", 1800000), - lambda: payout("ops-eu", "inv-1043", 1800000), - "payout:ops-eu:inv-1043", - ) - print("€18,000 payout, checked: sent") -else: - raise SystemExit("a payout above the desk limit ran without a checker") - -# €40,000: outside the slice. Authority refuses before the policy is asked. -try: - control.execute( - proposal(AGENT, "ops-eu", "inv-1044", 4000000), - lambda: payout("ops-eu", "inv-1044", 4000000), - "payout:ops-eu:inv-1044", - ) -except AuthorityDenied as refused: - print("€40,000 payout: refused,", refused.reason) -else: - raise SystemExit("a payout outside the delegated grant ran") - -# The agent tries to widen its own slice. -try: - control.delegate( - delegation.delegation_id, - grant_from_yaml(""" -subject: { agent: "payout-agent", user: "mira@example.com" } -actions: ["bank.payout"] -resources: ["account:*"] -constraints: { amount_gte: 0, amount_lte: 9000000 } -environments: ["production"] -expires_at: "2026-12-31T00:00:00Z" -"""), - by=AGENT, - ) -except AuthorityEscalation as refused: - print("widening the slice: refused,", refused.reason, refused.dimension) -else: - raise SystemExit("an agent widened its own authority") - -print("payouts sent:", len(paid)) -store.close() -``` - -## What the agent sees - -```text -delegated to the payout agent: dlg_… -€8,000 payout: sent -€18,000 payout: a checker decides: apr_… -€18,000 payout, checked: sent -€40,000 payout: refused, authority_constraint -widening the slice: refused, containment resources -payouts sent: 2 -``` - -The maker is the agent, the checker is whoever answers the approval, and the delegation is what -bounds the maker. `ctrlrun revoke dlg_…` cuts it with one write. - -## The receipt - -```bash runnable -ctrlrun receipts --last 3 -``` - -Each receipt names the principal and, for the checked payout, the approver. The refusal for -€40,000 is an `AUTHORITY_DENIED` event with no approval request behind it: authority runs first, -and a denial there never leaves a pending request. - -## When an AMBIGUOUS appears - -A payout whose confirmation was lost is `AMBIGUOUS`. Ask the bank by reference, then -`ctrlrun resolve payout:ops-eu:inv-N --committed` or `--failed`. Never re-send on a guess. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/payout-maker-checker -pip install ctrlrun && python main.py -``` - -## Next - -- [A manager agent delegating to a worker](/docs/cookbook/manager-and-worker). -- [Authority and delegation](/docs/concepts/authority-and-delegation) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/protect-an-mcp-server.mdx b/docs/docs/cookbook/protect-an-mcp-server.mdx deleted file mode 100644 index 25b55e5..0000000 --- a/docs/docs/cookbook/protect-an-mcp-server.mdx +++ /dev/null @@ -1,174 +0,0 @@ ---- -title: "Protect an existing MCP server in five minutes" -description: "Put the gateway in front of an MCP server you already run: name its tools in a policy, start ctrlrun gateway." ---- - -You run an MCP server and an agent that calls it. In production the gateway is a process -between them, started with one command; here the same gateway object is driven in process -against a stand-in upstream, so the recipe runs offline and shows exactly what the agent gets -back. [The gateway in five minutes](/docs/mcp/gateway-in-5-minutes) has the production commands. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - mcp.ops.get_deployment: - decision: allow - mcp.ops.restart_deployment: - effect: "restart:{cluster}:{name}" - decision: allow - mcp.ops.delete_namespace: - effect: "namespace:{cluster}:{name}" - decision: approve -``` - -## The code - -```python runnable file=main.py -import json -from collections.abc import Mapping -from pathlib import Path -from typing import Any - -from ctrlrun import Control, Policy, SQLiteStateStore -from ctrlrun.gateway.mcp import CURRENT_REVISION -from ctrlrun.gateway.outcome import COMPLETE, UpstreamResult -from ctrlrun.gateway.server import Gateway, GatewayConfig - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -upstream_calls: list[dict] = [] - - -def upstream( - body: bytes, headers: Mapping[str, str], *, fresh: bool -) -> tuple[Any, bytes, int, dict[str, str]]: - """The MCP server, as the gateway sees it: a stand-in that answers every tools/call.""" - request = json.loads(body) - upstream_calls.append(request) - reply = { - "jsonrpc": "2.0", - "id": request["id"], - "result": {"content": [{"type": "text", "text": "ok"}]}, - } - return ( - UpstreamResult(result_type=COMPLETE), - json.dumps(reply).encode(), - 200, - {"content-type": "application/json"}, - ) - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) -config = GatewayConfig(upstream="http://localhost:8000/mcp", alias="ops", principal="oncall-agent") -gateway = Gateway(config, control, upstream) - - -def call(tool: str, arguments: dict, rpc_id: int) -> dict: - body = json.dumps( - { - "jsonrpc": "2.0", - "id": rpc_id, - "method": "tools/call", - "params": {"name": tool, "arguments": arguments}, - } - ).encode() - headers = { - "MCP-Protocol-Version": CURRENT_REVISION, - "Mcp-Method": "tools/call", - "Mcp-Name": tool, - "Content-Type": "application/json", - } - response = gateway.handle(body, headers) - return {"status": response.status, **json.loads(response.body)} - - -first = call("restart_deployment", {"cluster": "prod-eu", "name": "checkout"}, 1) -print("restart_deployment:", first["status"], first["result"]["content"][0]["text"]) - -again = call("restart_deployment", {"cluster": "prod-eu", "name": "checkout"}, 2) -print( - "the same restart again:", - again["status"], - again["error"]["code"], - again["error"]["data"]["error"], -) -if "error" not in again: - raise SystemExit("a duplicate restart reached the upstream") - -held = call("delete_namespace", {"cluster": "prod-eu", "name": "checkout"}, 3) -print( - "delete_namespace:", - held["status"], - held["error"]["code"], - held["error"]["data"]["error"], - "request", - held["error"]["data"]["request_id"][:4] + "…", -) -if "error" not in held: - raise SystemExit("a namespace delete reached the upstream without a human") - -unknown = call("drop_database", {"name": "prod"}, 4) -print( - "drop_database (not in the policy):", - unknown["status"], - unknown["error"]["code"], - unknown["error"]["data"]["error"], -) - -print("calls that reached the upstream:", len(upstream_calls)) -store.close() -``` - -## What the agent sees - -```text -restart_deployment: 200 ok -the same restart again: 409 -41004 ctrlrun.duplicate_effect -delete_namespace: 403 -41002 ctrlrun.approval_required request apr_… -drop_database (not in the policy): 403 -41001 ctrlrun.denied -calls that reached the upstream: 1 -``` - -One call reached the server. The other three came back as JSON-RPC errors with codes a client -can act on, never as tool results the model would read as text and retry. - -## The receipt - -```bash runnable -ctrlrun receipts --last 4 -``` - -Every `tools/call` that reaches a decision has a receipt named `mcp.ops.<tool>`, denied ones -included — which is why four protected calls above leave three receipts and not four: the one -waiting on a human is not decided yet. - -## When an AMBIGUOUS appears - -An upstream that commits and then drops the connection comes back as `-41010`, -`ctrlrun.upstream_ambiguous`, and the identical call is refused with `-41005` until a human -runs `ctrlrun resolve restart:prod-eu:checkout --committed` or `--failed`. For an upstream whose -in-band error means it did nothing, set `mcp: {not_executed_on_error: true}` on the action and -such errors become `FAILED` rather than unknown. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/protect-an-mcp-server -pip install ctrlrun && python main.py -``` - -## Next - -- [The gateway in five minutes](/docs/mcp/gateway-in-5-minutes): the production commands and the full code table. -- [Put the gateway in front of MCP](/docs/guides/gateway-in-front-of-mcp) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/receipts-to-opentelemetry.mdx b/docs/docs/cookbook/receipts-to-opentelemetry.mdx deleted file mode 100644 index 38aa231..0000000 --- a/docs/docs/cookbook/receipts-to-opentelemetry.mdx +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: "Receipts into OpenTelemetry" -description: "Attach OTelEventSink to the Control and every action becomes one span with one event per step in your tracing backend." ---- - -Your team already looks at traces. Put every protected action there: one span per action, -named for it, one span event per step, an error status for `failed` and `ambiguous`, and no -argument values unless you opt in, because a trace backend is not the receipt store. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - decision: deny -``` - -## The code - -```python runnable file=main.py -import contextlib -from pathlib import Path - -from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.sdk.trace.export import SimpleSpanProcessor -from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore -from ctrlrun.otel import OTelEventSink - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -exporter = InMemorySpanExporter() # your OTLP exporter in production -provider = TracerProvider() -provider.add_span_processor(SimpleSpanProcessor(exporter)) - -store = SQLiteStateStore(STATE / "state.db") -control = Control( - Policy.from_file(HERE / "ctrlrun.yaml"), - store, - sinks=[OTelEventSink(tracer_provider=provider)], -) - - -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}", control=control) -def refund(payment_id: str, amount: int) -> str: - if payment_id == "txn_lost": - raise TimeoutError("no response from api.stripe.com") - return "refunded" - - -with ctrlrun.context(agent="support-agent"): - refund(payment_id="txn_1", amount=12000) - try: - refund(payment_id="txn_2", amount=900000) - except ctrlrun.ActionDenied: - pass - else: - raise SystemExit("a €9,000 refund ran") - with contextlib.suppress(TimeoutError): - refund(payment_id="txn_lost", amount=12000) - -for span in exporter.get_finished_spans(): - events = [event.name for event in span.events] - result = span.attributes.get("ctrlrun.result") - print( - f"{span.name} status={span.status.status_code.name} result={result} events={len(events)}" - ) - if any("12000" in str(value) for value in span.attributes.values()): - raise SystemExit("an argument value leaked into the span attributes") -print("argument values in attributes: none") -``` - -## What the agent sees - -The agent sees nothing different; the sink never blocks and never changes an outcome. The -trace backend sees: - -```text -stripe.refund status=OK result=committed events=5 -stripe.refund status=UNSET result=denied events=3 -stripe.refund status=ERROR result=ambiguous events=5 -argument values in attributes: none -``` - -A refusal is `UNSET`, not an error: CTRLRun doing its job is not a fault in the trace. - -## The receipt - -```bash runnable -ctrlrun receipts --last 3 -``` - -The receipts are still in the store and the JSONL file, chained; the spans carry the receipt -id so a trace can be joined back to the evidence. Deleting a trace deletes nothing CTRLRun -relies on. - -## When an AMBIGUOUS appears - -The span's status is `ERROR` and its result attribute is `ambiguous`, which is the alert to -build: a span whose result is ambiguous is an effect waiting for `ctrlrun resolve`. The -resolution is a later event, not a change to the span. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/receipts-to-opentelemetry -pip install ctrlrun && python main.py -``` - -## Next - -- [Export to OpenTelemetry](/docs/guides/export-to-opentelemetry): the OTLP exporter and the gateway's `--otel`. -- [Receipts and evidence](/docs/concepts/receipts-and-evidence) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/reconcile-against-the-remote.mdx b/docs/docs/cookbook/reconcile-against-the-remote.mdx deleted file mode 100644 index 8f0b868..0000000 --- a/docs/docs/cookbook/reconcile-against-the-remote.mdx +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: "Reconcile against Stripe or Kubernetes automatically" -description: "A reconcile hook per action asks the remote what happened to an effect key, so a lost Stripe reply or a dropped kubectl connection resolves itself." ---- - -Two agents, two remotes that can be asked. Stripe can list refunds by payment; Kubernetes -can be read for a deployment's state. A `reconcile` hook per action turns a lost reply into a -question the remote answers, and the record moves only the way the answer points. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - decision: allow - k8s.scale: - effect: "scale:{cluster}:{deployment}:{replicas}" - decision: allow -``` - -## The code - -```python runnable file=main.py -import contextlib -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -stripe_refunds: dict[str, int] = {} # what Stripe holds -replicas: dict[str, int] = {"checkout": 3} # what the cluster holds -calls: list[str] = [] - - -def stripe_refund(payment_id: str, amount: int) -> str: - calls.append(f"refund {payment_id}") - stripe_refunds[payment_id] = amount # committed... - raise TimeoutError("no response from api.stripe.com") # ...reply lost - - -def kubectl_scale(deployment: str, count: int) -> str: - calls.append(f"scale {deployment}") - raise ConnectionResetError("connection reset by peer") # never reached the API server - - -def ask_stripe(effect_key: str) -> ctrlrun.ReconcileOutcome: - payment_id = effect_key.removeprefix("refund:") - return "committed" if payment_id in stripe_refunds else "not_executed" - - -def ask_kubernetes(effect_key: str) -> ctrlrun.ReconcileOutcome: - _, _, deployment, count = effect_key.split(":") - return "committed" if replicas.get(deployment) == int(count) else "not_executed" - - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect( - "stripe.refund", - effect="refund:{payment_id}", - reconcile=ask_stripe, - reconcile_eagerly=True, - control=control, -) -def refund(payment_id: str, amount: int) -> str: - return stripe_refund(payment_id, amount) - - -@ctrlrun.protect( - "k8s.scale", - effect="scale:{cluster}:{deployment}:{replicas}", - reconcile=ask_kubernetes, - reconcile_eagerly=True, - control=control, -) -def scale(cluster: str, deployment: str, replicas: int) -> str: - return kubectl_scale(deployment, replicas) - - -with ctrlrun.context(agent="ops-agent"): - try: - refund(payment_id="txn_9", amount=50000) - except TimeoutError: - print("refund txn_9: reply lost; the hook asked Stripe") - try: - refund(payment_id="txn_9", amount=50000) - except ctrlrun.DuplicateEffect: - print("refund txn_9 again: refused, Stripe has it") - else: - raise SystemExit("a refund Stripe already holds ran again") - - try: - scale(cluster="prod-eu", deployment="checkout", replicas=6) - except ConnectionResetError: - print("scale checkout to 6: connection reset; the hook asked the cluster") - replicas["checkout"] = 6 # the retry succeeds this time - with contextlib.suppress(ConnectionResetError): - scale(cluster="prod-eu", deployment="checkout", replicas=6) - print("scale checkout to 6 again: permitted, the cluster had not applied it") - -print("remote calls:", calls) -``` - -## What the agent sees - -```text -refund txn_9: reply lost; the hook asked Stripe -refund txn_9 again: refused, Stripe has it -scale checkout to 6: connection reset; the hook asked the cluster -scale checkout to 6 again: permitted, the cluster had not applied it -remote calls: ['refund txn_9', 'scale checkout', 'scale checkout'] -``` - -Two lost replies, two different answers from two remotes, no human in either, and no guess in -either: the hook that could not have answered would have returned `"unknown"` and left the -record where it was. - -## The receipt - -```bash runnable -ctrlrun receipts -``` - -Each reconciliation is a `RECONCILIATION_STARTED` and `RECONCILIATION_RESOLVED` pair with the -answer, so the log says the record moved because Stripe was asked, not because someone assumed. - -## When an AMBIGUOUS appears - -With eager reconciliation it appears and is resolved in the same call. It stays only when the -hook answers `"unknown"` or raises, which is the right outcome when the remote itself cannot be -reached: then a person resolves it, and the hook's failure is in the events. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/reconcile-against-the-remote -pip install ctrlrun && python main.py -``` - -## Next - -- [Reconcile automatically](/docs/guides/reconcile-automatically): the three answers and when to run the hook. -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/refund-agent.mdx b/docs/docs/cookbook/refund-agent.mdx deleted file mode 100644 index 1d0b846..0000000 --- a/docs/docs/cookbook/refund-agent.mdx +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: "A refund agent with amount tiers" -description: "A support agent refunds customers: small refunds run on their own, larger ones wait for a human, anything above a ceiling is refused." ---- - -A support agent issues refunds at Stripe from customer conversations. Small ones should run -without a person, larger ones should wait for one, and nothing above a ceiling should run at -all, whatever the customer said. - -## The policy - -Amounts are integer minor units. Both ends of each band are bound, because an upper bound alone -lets a negative amount through, and a refund of a negative amount is a charge. - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - resource: "payment:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } # up to €500.00: autonomous - decision: allow - - when: { amount_gte: 0, amount_lte: 500000 } # up to €5,000.00: a human - decision: approve - - decision: deny -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): # so the recipe repeats - (STATE / name).unlink(missing_ok=True) - - -calls: list[tuple[str, int]] = [] - - -class FakeStripe: - def refund(self, payment_id: str, amount: int) -> dict: - calls.append((payment_id, amount)) - return {"id": f"re_{payment_id}", "status": "succeeded"} - - -stripe = FakeStripe() -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) - - -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}", control=control) -def refund(payment_id: str, amount: int) -> dict: - return stripe.refund(payment_id, amount) - - -with ctrlrun.context(agent="support-agent"): - print("€120 refund:", refund(payment_id="txn_1", amount=12000)["status"]) - - try: - refund(payment_id="txn_2", amount=250000) - except ctrlrun.ApprovalRequired as pending: - print("€2,500 refund: a human decides:", pending.request_id) - store.grant_approval(pending.request_id, "human:ops") # what `ctrlrun approve` does - with ctrlrun.with_approval(pending.request_id): - print("€2,500 refund, approved:", refund(payment_id="txn_2", amount=250000)["status"]) - else: - raise SystemExit("a €2,500 refund ran without a human") - - try: - refund(payment_id="txn_3", amount=2000000) - except ctrlrun.ActionDenied as refused: - print("€20,000 refund: refused,", refused.reason) - else: - raise SystemExit("a €20,000 refund ran") - - try: - refund(payment_id="txn_1", amount=12000) - except ctrlrun.DuplicateEffect: - print("€120 refund again: refused as a duplicate") - else: - raise SystemExit("the same refund ran twice") - -print("remote refund calls:", len(calls)) -``` - -## What the agent sees - -```text -€120 refund: succeeded -€2,500 refund: a human decides: apr_… -€2,500 refund, approved: succeeded -€20,000 refund: refused, rule[2] -€120 refund again: refused as a duplicate -remote refund calls: 2 -``` - -Two calls reached Stripe. The refusal for €20,000 names the rule that decided it, and the -duplicate names nothing but the effect key, `refund:txn_1`, which had already committed. - -## The receipt - -```bash runnable -ctrlrun receipts --last 4 -``` - -Four receipts: `allow/committed`, `approve/committed` with the approver, `deny/denied`, and -`allow/blocked` for the duplicate. - -## When an AMBIGUOUS appears - -A refund whose reply was lost is `AMBIGUOUS` and a retry is refused. Look up the payment in the -Stripe dashboard, then `ctrlrun resolve refund:txn_N --committed` or `--failed`. A `reconcile` -hook that queries `stripe.Refund.list(payment_intent=...)` does the same automatically: -[Reconcile against the remote](/docs/cookbook/reconcile-against-the-remote). - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/refund-agent -pip install ctrlrun && python main.py -``` - -## Next - -- [A payout agent with maker/checker](/docs/cookbook/payout-maker-checker): the same money, two people. -- [Approval binding](/docs/concepts/approval-binding) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/resolve-an-ambiguous-effect.mdx b/docs/docs/cookbook/resolve-an-ambiguous-effect.mdx deleted file mode 100644 index 1c95142..0000000 --- a/docs/docs/cookbook/resolve-an-ambiguous-effect.mdx +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: "Resolve an ambiguous effect" -description: "An effect nobody knows the outcome of blocks its own retry; a human asks the remote, records the answer with ctrlrun resolve." ---- - -A worker died mid-call, or a reply was lost, and an effect sits at `AMBIGUOUS`. The agent's -retry is refused, an alert fires, and someone has to look. This recipe makes two such effects, -resolves one each way, and shows what the evidence says afterwards. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - dns.update_record: - effect: "dns:{zone}:{name}" - decision: allow - stripe.refund: - effect: "refund:{payment_id}" - decision: allow -``` - -## The code - -```python runnable file=main.py -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, EffectState, Policy, SQLiteStateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) -remote_calls: list[str] = [] - - -@ctrlrun.protect("dns.update_record", effect="dns:{zone}:{name}", control=control) -def update_record(zone: str, name: str, value: str) -> str: - remote_calls.append(f"dns {name}") - raise ConnectionResetError("connection reset by peer") - - -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}", control=control) -def refund(payment_id: str, amount: int) -> str: - remote_calls.append(f"refund {payment_id}") - if len(remote_calls) == 2: - raise TimeoutError("no response from api.stripe.com after 30s") - return "refunded" - - -with ctrlrun.context(agent="ops-agent"): - for call in ( - lambda: update_record(zone="example.com", name="api", value="203.0.113.7"), - lambda: refund(payment_id="txn_7", amount=50000), - ): - try: - call() - except (ConnectionResetError, TimeoutError) as lost: - print("the executor saw:", lost) - - ambiguous = [record.effect_key for record in store.list_effects(EffectState.AMBIGUOUS)] - print("ambiguous effects:", ambiguous) - - # A human asks the DNS provider: the record was updated. Asks Stripe: no refund exists. - # This is what `ctrlrun resolve <key> --committed` and `--failed` do. - store.resolve_effect("dns:example.com:api", EffectState.COMMITTED, "human:ops") - store.resolve_effect("refund:txn_7", EffectState.FAILED, "human:ops") - - try: - update_record(zone="example.com", name="api", value="203.0.113.7") - except ctrlrun.DuplicateEffect: - print("DNS update again: refused, it committed") - else: - raise SystemExit("a committed update ran again") - - print("refund again:", refund(payment_id="txn_7", amount=50000)) - -for record in store.list_effects(): - print(f"{record.effect_key}: {record.state.value}, resolved by {record.resolved_by}") -print("remote calls:", remote_calls) -``` - -## What the agent sees - -```text -the executor saw: connection reset by peer -the executor saw: no response from api.stripe.com after 30s -ambiguous effects: ['dns:example.com:api', 'refund:txn_7'] -DNS update again: refused, it committed -refund again: refunded -dns:example.com:api: committed, resolved by human:ops -refund:txn_7: committed, resolved by None -remote calls: ['dns api', 'refund txn_7', 'refund txn_7'] -``` - -The refund that was resolved `--failed` was retried and committed on its own; its record no -longer names a resolver, because the retry was the agent's action, not the human's. The DNS -update, resolved `--committed`, refuses its retry as a duplicate. - -## The receipt - -```bash runnable -ctrlrun effects -ctrlrun receipts --last 2 -``` - -From the shell, the same steps are `ctrlrun effects --state ambiguous`, then -`ctrlrun resolve dns:example.com:api --committed` and `ctrlrun resolve refund:txn_7 --failed`, -and `ctrlrun inspect <action_id>` shows the `EFFECT_RESOLVED` event with `resolved_by`. - -## When an AMBIGUOUS appears - -This recipe is what to do. Two rules: never resolve from memory or from a cache, ask the -remote; and resolve `--failed` only when the remote is authoritative for the absence, because -`--failed` licenses a second execution. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/resolve-an-ambiguous-effect -pip install ctrlrun && python main.py -``` - -## Next - -- [Reconcile against the remote](/docs/cookbook/reconcile-against-the-remote): the same answer from a hook. -- [Resolve an AMBIGUOUS effect](/docs/guides/resolve-an-ambiguous-effect) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/slack-approvals.mdx b/docs/docs/cookbook/slack-approvals.mdx deleted file mode 100644 index 1bdbc49..0000000 --- a/docs/docs/cookbook/slack-approvals.mdx +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: "Approvals in Slack via webhook" -description: "The approval request goes out as one signed POST, a human answers in Slack, the answer comes back signed to the gateway's endpoint." ---- - -A refund above the desk limit should be answered in the channel where the support lead -already lives. `WebhookApprovalProvider` sends the request to your Slack service as one signed -POST; your service turns the button click into a signed POST back. This recipe runs the -inbound half in process, with the real signing and the real handler, so what a Slack service -must send is shown exactly. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - decision: approve -``` - -## The code - -```python runnable file=main.py -import json -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore -from ctrlrun.webhook import handle_inbound, sign - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - -SECRET = "shared-with-the-slack-service" # from $CTRLRUN_WEBHOOK_SECRET in production -store = SQLiteStateStore(STATE / "state.db") -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) -refunds: list[int] = [] - - -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}", control=control) -def refund(payment_id: str, amount: int) -> str: - refunds.append(amount) - return "refunded" - - -with ctrlrun.context(agent="support-agent"): - try: - refund(payment_id="txn_5", amount=250000) - except ctrlrun.ApprovalRequired as pending: - request_id = pending.request_id - print("€2,500 refund: request", request_id[:4] + "…", "goes to Slack") - else: - raise SystemExit("a €2,500 refund ran without a human") - - # What the Slack service POSTs to /ctrlrun/approvals/<request_id> when the lead clicks. It - # echoes the action hash it showed the human: an answer for a different hash is refused. - shown = store.get_approval(request_id).request.action_hash - answer = json.dumps( - { - "request_id": request_id, - "action_hash": shown, - "decision": "grant", - "approver": "slack:dana", - } - ).encode() - status, message = handle_inbound(store, request_id, answer, sign(answer, SECRET), secret=SECRET) - print("the lead approves in Slack:", status, message) - - # A forged answer, signed with the wrong secret, changes nothing. - forged = json.dumps( - { - "request_id": request_id, - "action_hash": shown, - "decision": "grant", - "approver": "slack:nobody", - } - ).encode() - status, message = handle_inbound( - store, request_id, forged, sign(forged, "guess"), secret=SECRET - ) - print("a forged answer:", status, message) - if status == 200: - raise SystemExit("a forged answer was accepted") - - with ctrlrun.with_approval(request_id): - print("€2,500 refund, approved in Slack:", refund(payment_id="txn_5", amount=250000)) - -print("refunds:", refunds) -``` - -## What the agent sees - -```text -€2,500 refund: request apr_… goes to Slack -the lead approves in Slack: 200 ok -a forged answer: 400 the signature did not verify inside the replay window -€2,500 refund, approved in Slack: refunded -refunds: [250000] -``` - -The answer names the request, the hash the human saw, the decision and the approver; the approver is what the receipt records. The signature is an HMAC-SHA256 over -`timestamp.body` on the exact bytes, and a timestamp outside the five-minute window is refused -even with the right secret. - -## The receipt - -```bash runnable -ctrlrun receipts --last 1 -``` - -`approve/committed`, approver `slack:dana`. The same shape as an approval given with -`ctrlrun approve`, because it went through the same call. - -## When an AMBIGUOUS appears - -Approvals never make an effect ambiguous; the remote does. If the approved refund's reply is -lost, the effect is `AMBIGUOUS` and the approval is already spent: resolve the effect with -`ctrlrun resolve refund:txn_5 --committed` or `--failed`. On `--failed` a retry needs a new -approval, because the old one authorized one execution. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/slack-approvals -pip install ctrlrun && python main.py -``` - -## Next - -- [Approve in Slack](/docs/guides/approvals-in-slack): the outbound half, the payload and the flags. -- [Approval binding](/docs/concepts/approval-binding) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/sqlite-to-postgres.mdx b/docs/docs/cookbook/sqlite-to-postgres.mdx deleted file mode 100644 index 0cb023c..0000000 --- a/docs/docs/cookbook/sqlite-to-postgres.mdx +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: "Move from SQLite to Postgres" -description: "One line changes: the store. The code reads CTRLRUN_STORE_URL and builds a PostgresStateStore when it names a database, a SQLiteStateStore otherwise." ---- - -The agent has outgrown one host. Reservation on SQLite is a write lock on a local file; two -hosts need a store they share. The change is the store constructor, and nothing else: same -policy, same decorator, same receipts, same guarantees, graded on Postgres by the same suite -that grades SQLite. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - decision: allow -``` - -## The code - -This script runs on SQLite offline and on Postgres when `CTRLRUN_STORE_URL` names one; the -part that changes is `open_store`. - -```python runnable file=main.py -import os -from pathlib import Path - -import ctrlrun -from ctrlrun import Control, Policy, SQLiteStateStore, StateStore - -HERE = Path(__file__).resolve().parent -STATE = HERE / ".ctrlrun" -STATE.mkdir(exist_ok=True) -for name in ("state.db", "state.db-wal", "state.db-shm"): - (STATE / name).unlink(missing_ok=True) - - -def open_store() -> StateStore: - url = os.environ.get("CTRLRUN_STORE_URL") - if url and url.startswith(("postgresql://", "postgres://")): - from ctrlrun.postgres import PostgresStateStore # pip install "ctrlrun[postgres]" - - return PostgresStateStore(url, schema="ctrlrun") # migrates at open, forward only - return SQLiteStateStore(STATE / "state.db") - - -store = open_store() -control = Control(Policy.from_file(HERE / "ctrlrun.yaml"), store) -refunds: list[str] = [] - - -@ctrlrun.protect("stripe.refund", effect="refund:{payment_id}", control=control) -def refund(payment_id: str, amount: int) -> str: - refunds.append(payment_id) - return "refunded" - - -with ctrlrun.context(agent="refund-agent"): - print("store:", type(store).__name__) - print("refund txn_1:", refund(payment_id="txn_1", amount=12000)) - try: - refund(payment_id="txn_1", amount=12000) # a second host, same effect - except ctrlrun.DuplicateEffect: - print("refund txn_1 from another host: refused") - else: - raise SystemExit("one effect committed twice") - -print("remote refund calls:", len(refunds)) -store.close() -``` - -## What the agent sees - -```text -store: SQLiteStateStore -refund txn_1: refunded -refund txn_1 from another host: refused -remote refund calls: 1 -``` - -With `CTRLRUN_STORE_URL=postgresql://ctrlrun@db.internal/ctrlrun` the first line reads -`PostgresStateStore` and the rest is identical, and now it holds across hosts: the refusal -comes from a unique index on the effect key and compare-and-set updates whose row counts are -checked, instead of SQLite's file lock. - -## The receipt - -```bash runnable -ctrlrun receipts --last 2 -``` - -On Postgres the same command reads the shared store when `CTRLRUN_STORE_URL` is set, or with -`--store-url 'postgresql://db.internal/ctrlrun?ctrlrun_schema=ctrlrun'`. A read command -migrates nothing and creates nothing. - -## When an AMBIGUOUS appears - -One new case: a connection lost during `COMMIT`. Postgres very often did commit, so the store -treats it as unknown and re-reads the row to find out which; only if the re-read fails does it -refuse to proceed. Your executor's lost replies are handled as before. Resolve them with -`ctrlrun resolve --store-url …` from any host. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/sqlite-to-postgres -pip install ctrlrun && python main.py -``` - -## Next - -- [Run on Postgres](/docs/guides/run-on-postgres): the schema, the grants, failover. -- [Effect keys](/docs/concepts/effect-keys) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/cookbook/verify-in-github-actions.mdx b/docs/docs/cookbook/verify-in-github-actions.mdx deleted file mode 100644 index 5c025d1..0000000 --- a/docs/docs/cookbook/verify-in-github-actions.mdx +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: "Run verify in GitHub Actions" -description: "Run ctrlrun verify against your policy on every push with the CTRLRun action: the workflow, the report it produces, the N/A line, the exit codes." ---- - -Your policy lives in the repository with the agent. Every push should prove the guarantees it -declares still hold against it, in a scratch store, with no network, and fail the build if one -does not. That is one workflow step. - -## The policy - -```yaml runnable -schema: ctrlrun.policy/v2 - -actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - decision: approve - k8s.delete_namespace: - effect: "namespace:{cluster}:{name}" - decision: approve -``` - -## The code - -Locally, and in the recipe's directory, the check is one command: - -```bash runnable file=run.sh -ctrlrun verify -ctrlrun verify --json > verify-report.json -python -c "import json; s = json.load(open('verify-report.json'))['summary']; print('applicable', s['applicable'], 'passed', s['passed'], 'not applicable', s['not_applicable'])" -rm -f verify-report.json -``` - -In CI, the workflow: - -```yaml -name: CTRLRun verify - -on: [push, pull_request] - -jobs: - verify: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: CTRLRun/ctrlrun@v0.6.1 - with: - policy: ctrlrun.yaml -``` - -The ref pins the action's steps and not the package they install: `install` defaults to -`ctrlrun`, unpinned, so the job takes whatever PyPI serves that day. Add -`install: ctrlrun==0.6.1` to pin the tool too, and pin `CTRLRun/ctrlrun` by commit rather than -by tag where you want a ref nobody can move. - -## What the agent sees - -The agent sees nothing; this is the operator's check. The build sees: - -```text -CTRLRun verify — ctrlrun 0.6.1, catalogue ctrlrun.guarantees/v2 -policy /home/runner/work/agent/agent/ctrlrun.yaml (ctrlrun.policy/v2, mode: enforce) -authority none -store sqlite, scratch (created and destroyed for this run) - -G1 mutated approval refused PASS k8s.delete_namespace -G2 replayed approval refused PASS k8s.delete_namespace -G3 duplicate effect refused PASS k8s.delete_namespace -G4 one winner under concurrency PASS k8s.delete_namespace (8 processes) -G5 ambiguous blocks a blind retry PASS k8s.delete_namespace -G6 unknown action refused PASS -G7 no principal refused PASS k8s.delete_namespace -G8 expired authority refused N/A no authority section -G9 delegation cannot escalate N/A no authority section -G10 unknown exception is ambiguous PASS k8s.delete_namespace -G11 an altered receipt is detected PASS k8s.delete_namespace - -9/9 declared guarantees pass. 2 not applicable: G8, G9. -``` - -The first line is on stderr, from G7's own scenario driving an action with no principal — the -guarantee passing, not a problem. Every row names `k8s.delete_namespace` because verify takes -the first action that fits each scenario in alphabetical order; which one appears says nothing -about it. The `policy` line is the resolved absolute path, so yours will differ. - - -Two guarantees are not applicable because the policy has no `authority:` section; they are -listed with the reason and excluded from the denominator. Green means nothing that could be -checked was wrong. - -## The receipt - -The report is the receipt: `--json` writes a `ctrlrun.verify/v1` document and `--junit` a -JUnit file, and the action uploads both with the badge JSON as one artifact. Exit 0 means every -applicable guarantee passed; 1 a failure; 2 a refused or unusable configuration, including -`mode: observe` and a policy in which nothing can be exercised; 3 an internal error. - -## When an AMBIGUOUS appears - -Verify's G5 and G10 make an ambiguous effect on purpose, in the scratch store, and assert that a -blind retry is refused. Your store is never opened, so nothing here can leave a real effect -ambiguous. An `AMBIGUOUS` in your own store is the agent's, and the -[resolve recipe](/docs/cookbook/resolve-an-ambiguous-effect) is for it. - -## Run it - -The policy and the code above are also a directory in the repository, extracted from this page -and run in CI against a fake remote: - -```bash -git clone https://github.com/CTRLRun/ctrlrun && cd ctrlrun/examples/cookbook/verify-in-github-actions -pip install ctrlrun && bash run.sh -``` - -## Next - -- [Verify in CI](/docs/guides/verify-in-ci): inputs, outputs and publishing the badge. -- [Exit codes](/docs/reference/exit-codes) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/demos/index.mdx b/docs/docs/demos/index.mdx deleted file mode 100644 index ab26478..0000000 --- a/docs/docs/demos/index.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: "Demos" -sidebarTitle: "Overview" -description: "Two pages that run the released ctrlrun wheel in your browser, so you can break a protected action before you install anything." ---- - -Every demo here runs real Python in your tab. Pyodide loads, micropip installs the released -`ctrlrun` wheel from PyPI, and the remote is a fake in the same process — nothing you press is -sent anywhere, and every refusal you read is the library's own. - -<Columns cols={2}> - <Card title="Break a refund" href="/docs/try-it" icon="rotate-left"> - One protected refund under one policy. Change the amount, lose the reply, approve one amount - and execute another, and read what refused you. - </Card> - <Card title="Medical affairs" href="/docs/demos/medical-affairs" icon="microscope"> - Inspect synthetic evidence, trace cited claims, validate a brief and approve its release. - Change an approved document or lose a delivery reply, and inspect the real library's receipts. - </Card> -</Columns> - -More demos are coming: each one the same kernel under a different domain's policy, so you can -see what a refusal looks like closer to your own agent's actions. - -The refund demo is the shortest way to see all five refusals. The medical affairs demo is the -same kernel under a different policy, and it exists to answer a question people ask about their -own domain: what does this look like when the consequential action is a document rather than a -payment. Nothing in CTRLRun knows what a refund is, or what a letter is. - -Neither page is a substitute for running it yourself. Both take about ten megabytes of download -on the first press and cache after that; a laptop offline can run the same thing faster with -`pip install ctrlrun && ctrlrun demo`. - -## Next - -- [Why](/docs/why) — what these demos are demonstrating, in 700 words -- [Get started](/docs/get-started/quickstart) — the same guarantees around your own function -- [Cookbook](/docs/cookbook/index) — nineteen wirings you can copy -- [The scenario demo](/try) — the same checks across 48 domains, drawn rather than run diff --git a/docs/docs/demos/medical-affairs.mdx b/docs/docs/demos/medical-affairs.mdx deleted file mode 100644 index d051761..0000000 --- a/docs/docs/demos/medical-affairs.mdx +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: "Medical Affairs: evidence to reviewed work" -sidebarTitle: "Medical affairs" -description: "Explore source-linked evidence, draft validation, medical review and controlled release in an interactive Medical Affairs demonstration." -mode: "wide" ---- - -Build a reviewable Medical Affairs brief from evidence, inspect the source behind each claim, -and see what happens when an unsupported claim or an edited approval reaches the release step. -The workbench uses invented evidence and prewritten synthesis; its release decisions run the -real CTRLRun Python library in your browser. - -The product, condition, studies and findings are invented. Nothing on this page is medical -information about a real medicine. This is a demonstration of an application design, not a live -literature search or a clinically validated evidence service. - -<div id="medical-workbench-mount"> - <p>The evidence workbench loads here when JavaScript is enabled. It includes six stages: - retrieve, reason, cite, validate, review and release.</p> -</div> - -## What can you demonstrate? - -1. **Retrieve and reason.** Inspect three synthetic records. Keep the randomized trial and - extension; exclude the protocol from outcome claims. Compare the trial arms while retaining - adverse events, follow-up and study limitations. -2. **Cite and validate.** Select a sentence to open its supporting passage. Inject an unsupported - progression claim, then open Validate. Remove the claim to prepare a new version for review. -3. **Review and release.** Confirm that you reviewed the evidence and approve the current version. - Simulate an edit after approval, then attempt release. The original approval no longer matches. - Return to review to approve the revised version. -4. **Recover a lost reply.** Before release, select the lost-reply scenario. The simulated archive - receives the brief, but CTRLRun records `AMBIGUOUS`. A used approval cannot authorize a retry. - Check the simulated destination to confirm the original receipt without another write. - -Use **Start a new case** between independent demonstrations. Download the review brief as -Markdown, or the evidence and audit record as JSON. Downloads retain the synthetic-data label, -current document version and review status; the audit download includes actual CTRLRun receipts. -Starting a new case clears this browser session's records. - -## What is real, and what is illustrative? - -| Component | This demonstration | A working biomedical application | -| --- | --- | --- | -| Retrieval | Three fixed, explicitly synthetic source records | Search connectors, permitted full text, deduplication and dated source snapshots | -| Reasoning | Prewritten findings that preserve comparators and limitations | Evidence extraction and LLM-assisted synthesis evaluated by medical specialists | -| Citations | Claim-to-passage inspection | Stable source identifiers, locations and versioned evidence | -| Validation | Python checks the curated claim text, source mapping, versions and numerical fixture | Independent numerical checks, source-support evaluation and review of conflicting evidence | -| Review | A visitor acts as the demo medical reviewer | Authenticated reviewers, scientific judgment and an organizational review process | -| Release | Real CTRLRun policy, approval binding and effect records; an in-memory destination | The same controls around an authorized document or delivery service | - -The validator recomputes its result before release. It does not trust a client-supplied “passed” -flag. Unsupported fixture content is denied by policy. Passing these narrow checks does not -establish scientific correctness, completeness or clinical suitability. - -Approval covers the serialized document, evidence versions, validation version and destination. -A receipt records the action and outcome; it does not prove the medical reviewer was correct. -In production, keep the reviewed content immutable and enforce validation and reviewer identity -in a trusted service. The browser demonstration is inspectable and is not an authorization service. - -## How does the original letter example work? - -<Accordion title="Run the letter-change and safety-report examples"> - -A reviewer signs revision A of a fictional response letter. New evidence changes the -recommendation in revision B. Attempt delivery to see the real library refuse the changed action. -The safety-report example separately shows an ambiguous effect blocking a blind retry. - -<div id="ctrlrun-medical-demo"> - <div style={{ display: "flex", flexWrap: "wrap", gap: "8px", marginBottom: "16px" }}> - <button type="button" name="draft" style={{ background: "#F5A623", color: "#14161b", border: "1px solid #B8730A", borderRadius: "8px", padding: "9px 16px", fontSize: "14px", cursor: "pointer" }}>Retrieve and draft</button> - <button type="button" name="send" style={{ background: "#F5A623", color: "#14161b", border: "1px solid #B8730A", borderRadius: "8px", padding: "9px 16px", fontSize: "14px", cursor: "pointer" }}>Send to the physician</button> - <button type="button" name="approve" style={{ background: "#14161b", color: "#8bd5a0", border: "1px solid #8bd5a0", borderRadius: "8px", padding: "9px 16px", fontSize: "14px", cursor: "pointer" }}>Approve, as the medical reviewer</button> - <button type="button" name="refresh" style={{ background: "transparent", color: "inherit", border: "1px solid currentColor", borderRadius: "8px", padding: "9px 16px", fontSize: "14px", cursor: "pointer" }}>A newer study lands</button> - <button type="button" name="reset" style={{ background: "transparent", color: "inherit", border: "1px dashed currentColor", borderRadius: "8px", padding: "9px 16px", fontSize: "14px", cursor: "pointer" }}>Start over</button> - </div> - - <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))", gap: "16px" }}> - <div name="letter" style={{ border: "1px solid currentColor", borderRadius: "8px", padding: "16px", minHeight: "200px" }} /> - <pre name="transcript" style={{ background: "#14161b", color: "#c9ccd3", borderRadius: "8px", padding: "16px", margin: 0, minHeight: "200px", maxHeight: "340px", overflowY: "auto", fontSize: "13px", lineHeight: 1.5, whiteSpace: "pre-wrap" }} /> - </div> - - <div style={{ display: "flex", flexWrap: "wrap", gap: "8px", alignItems: "center", marginTop: "16px", fontSize: "13px" }}> - <button type="button" name="event" style={{ background: "transparent", color: "inherit", border: "1px solid currentColor", borderRadius: "8px", padding: "7px 14px", fontSize: "13px", cursor: "pointer" }}>File the safety case</button> - <label style={{ display: "flex", gap: "6px", alignItems: "center" }}> - <input type="checkbox" name="lose_reply" /> - lose the reply from the safety database - </label> - <button type="button" name="unapproved" style={{ background: "transparent", color: "inherit", border: "1px solid currentColor", borderRadius: "8px", padding: "7px 14px", fontSize: "13px", cursor: "pointer" }}>Cite an unapproved use</button> - </div> -</div> - -The following is this letter example's policy. Denying the illustrative unapproved-use action -is a configured example rule, not a universal Medical Affairs requirement. - -```yaml -schema: ctrlrun.policy/v2 -actions: - literature.search: - effect: "search:{inquiry_id}:{revision}" - decision: allow - safety.report_icsr: - effect: "icsr:{inquiry_id}" - decision: allow - response.send_to_hcp: - effect: "mi_response:{inquiry_id}" - decision: approve - response.cite_unapproved_use: - effect: "unapproved_use:{inquiry_id}" - decision: deny -``` - -</Accordion> - -## How would you build this for your team? - -Start with one therapeutic area, one internal evidence-brief template and a medically reviewed -source set. Add retrieval and structured extraction, retain uncertainty and contradictory -findings, then connect claim checking to the release preconditions. Expand to medical-information -response drafts, MSL briefings or literature updates after the evidence and review process works. - -The [workbench Python example](https://github.com/CTRLRun/ctrlrun/blob/main/examples/medical_workbench.py) -contains the executable fixture validator and protected release action. Both demonstrations load -Pyodide 314.0.6 and CTRLRun from PyPI on demand. Runtime downloads require a connection; document -content stays in the tab and the destinations are in-memory fakes. There is no LLM request and no -message is delivered to a physician. - -## Next - -- [Why](/docs/why): the execution problem underneath this workflow -- [Get started](/docs/get-started/quickstart): protect your application's release action -- [Approval binding](/docs/concepts/approval-binding): what the reviewer's decision authorizes diff --git a/docs/docs/faq.mdx b/docs/docs/faq.mdx deleted file mode 100644 index 967fd7a..0000000 --- a/docs/docs/faq.mdx +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: "Frequently asked questions" -sidebarTitle: "FAQ" -description: "Fourteen questions engineers ask: is it production-ready, SQLite or Postgres, idempotency keys, workflow engines, adapters, timeouts and receipts." ---- - -The fourteen questions that come up first, answered in under eighty words each. - -<AccordionGroup> - <Accordion title="Is it production-ready?"> - It runs in production on a single file or on Postgres across hosts, and every guarantee is - graded by one suite against both stores. What it has not had: an external security audit, a - third-party review of the kernel, and a soak of the length the roadmap asks for. Those are - listed on [Run it in production](/docs/production/index) rather than left for you to find. - </Accordion> - - <Accordion title="Is SQLite really enough?"> - On one host, yes. `BEGIN IMMEDIATE` is a write lock on the file, so one effect executes once - across threads and across OS processes on that machine, and the conformance suite grades - SQLite case for case beside Postgres. Move when a second host must write to the store, not - before. [The choice, in one table](/docs/production/postgres). - </Accordion> - - <Accordion title="Isn't this just idempotency keys?"> - No. An idempotency key deduplicates at one API that chose to support it, inside its - retention window. An effect key deduplicates at the agent, before the call, across every - remote it touches, is bound to the approval and the receipt, and refuses a retry when the - outcome is unknown rather than resending and hoping. Where a remote does support - idempotency keys, pass the effect key as one and get both. - [More](/docs/compare/idempotency-keys). - </Accordion> - - <Accordion title="Why not a durable workflow engine?"> - Different guarantee. An engine makes a workflow finish, retrying activities until they - succeed; CTRLRun decides whether a consequential effect is authorized and refuses to retry - an unknown outcome. Their advice, make activities idempotent, is the work CTRLRun does for - you and enforces in the store. Run the workflow in the engine and decorate the activity - that acts. [More](/docs/compare/durable-workflows). - </Accordion> - - <Accordion title="Do I need an adapter for my framework?"> - Probably not. `@protect` covers anything in your Python process, and the gateway covers - anything behind an MCP server in any language. An adapter buys exactly one thing: routing an - approval through the framework's own interrupt so a human answers where they already answer. - A framework with no such primitive needs none. [More](/docs/get-started/three-ways-in). - </Accordion> - - <Accordion title="Is it exactly-once?"> - No, and nothing can be against systems it does not control. CTRLRun guarantees it will not - knowingly execute the same logical effect twice, and never treats an unknown outcome as a - failure. The remote is the only thing that knows what the remote did; when nobody knows, - CTRLRun says so and stops. [More](/docs/concepts/outcomes-and-ambiguous). - </Accordion> - - <Accordion title="What happens on a timeout?"> - The effect becomes `AMBIGUOUS`, never `FAILED`, and a retry against it is refused. Only - `NotExecuted`, raised by your executor when it knows the remote did nothing, means failed. - A human runs `ctrlrun resolve --committed` or `--failed` after asking the remote, or a - `reconcile` hook asks for them. [More](/docs/concepts/outcomes-and-ambiguous). - </Accordion> - - <Accordion title="Can the agent bypass it?"> - It can call the undecorated function, and the threat model says so: process-level - enforcement is out of scope. Two things narrow it. The gateway sits between the agent and - its tools, where the agent has no choice; and CTRLRun is never a tool the agent decides to - call, because a check the agent opts into is not a check. - [Threat model](/docs/THREAT_MODEL). - </Accordion> - - <Accordion title="Does it phone home?"> - No. There is no telemetry, no licence check and no network call of any kind in the kernel. - `ctrlrun stats` counts the local SQLite file, and a test runs the demo in a subprocess whose - sockets are all refused. The extras reach the network only where you point them: your JWKS, - your webhook, your OTLP endpoint, your Postgres. - </Accordion> - - <Accordion title="What if the human takes an hour?"> - The approval request expires at its TTL, fifteen minutes by default, and a waiting call - raises `ApprovalTimeout` with nothing executed. Raise the TTL for slow approvals, or do not - wait: `ApprovalRequired` carries the request id, so an agent can surface it and come back - later with `with_approval(request_id)`. [More](/docs/concepts/approval-binding). - </Accordion> - - <Accordion title="One host or many?"> - Either. On one host the store is a SQLite file and reservation is atomic across processes - through `BEGIN IMMEDIATE`. Across hosts, `pip install "ctrlrun[postgres]"` and change the - store: a unique index on the effect key and compare-and-set updates give the same guarantee, - graded by the suite written for SQLite. [More](/docs/guides/run-on-postgres). - </Accordion> - - <Accordion title="What is in a receipt?"> - One executed action: who proposed it, the action and its canonical arguments, the decision - and why, the approval and approver, the effect key, the outcome, the timestamps, the hash - and declared version of the policy that decided it, and the hash of the receipt before it. - Portable JSON, one object per line. [More](/docs/reference/receipt-and-event-schemas). - </Accordion> - - <Accordion title="Is the receipt chain a signature?"> - No. Each receipt carries the hash of the one before, so an edit, a deletion from the middle - or a reordering is detected and named by `seq`. It does not prove who wrote a receipt, - receipts are not signed, and it does not survive an administrator who can rewrite every row - including the chain head. [More](/docs/security/receipt-chain). - </Accordion> - - <Accordion title="What is not covered?"> - A compromised host or process. A malicious administrator with write access to the store. A - lying remote. A compromised approver. An executor that raises `NotExecuted` after the remote - acted, which `ctrlrun verify` cannot see. Data exfiltration through reads. Authority across - an agent-to-agent hop. [Threat model](/docs/THREAT_MODEL). - </Accordion> -</AccordionGroup> - -<script type="application/ld+json"> -{JSON.stringify({ - "@context": "https://schema.org", - "@type": "FAQPage", - "mainEntity": [ - {"@type": "Question", "name": "Is CTRLRun production-ready?", "acceptedAnswer": {"@type": "Answer", "text": "It runs in production on a single file or on Postgres across hosts, and every guarantee is graded by one suite against both stores. It has not had an external security audit, a third-party review of the kernel, or a soak of the length the roadmap asks for."}}, - {"@type": "Question", "name": "Is SQLite really enough for production?", "acceptedAnswer": {"@type": "Answer", "text": "On one host, yes. BEGIN IMMEDIATE is a write lock on the file, so one effect executes once across threads and across OS processes on that machine. Move to Postgres when a second host must write to the store, not before."}}, - {"@type": "Question", "name": "Isn't this just idempotency keys?", "acceptedAnswer": {"@type": "Answer", "text": "No. An idempotency key deduplicates at one API that chose to support it, inside its retention window. An effect key deduplicates at the agent, before the call, across every remote it touches, is bound to the approval and the receipt, and refuses a retry when the outcome is unknown."}}, - {"@type": "Question", "name": "Why not a durable workflow engine?", "acceptedAnswer": {"@type": "Answer", "text": "A workflow engine makes a workflow finish, retrying activities until they succeed. CTRLRun decides whether a consequential effect is authorized and refuses to retry an unknown outcome. Run the workflow in the engine and decorate the activity that acts."}}, - {"@type": "Question", "name": "Do I need an adapter for my framework?", "acceptedAnswer": {"@type": "Answer", "text": "Probably not. The @protect decorator covers anything in your Python process and the gateway covers anything behind an MCP server in any language. An adapter only routes an approval through the framework's own interrupt."}}, - {"@type": "Question", "name": "Is CTRLRun exactly-once?", "acceptedAnswer": {"@type": "Answer", "text": "No, and nothing can be against systems it does not control. CTRLRun guarantees it will not knowingly execute the same logical effect twice, and never treats an unknown outcome as a failure."}}, - {"@type": "Question", "name": "What happens on a timeout?", "acceptedAnswer": {"@type": "Answer", "text": "The effect becomes AMBIGUOUS, never FAILED, and a retry against it is refused. Only NotExecuted, raised by your executor when it knows the remote did nothing, means failed. A human or a reconcile hook resolves it."}}, - {"@type": "Question", "name": "Can the agent bypass CTRLRun?", "acceptedAnswer": {"@type": "Answer", "text": "It can call the undecorated function; process-level enforcement is out of scope. The gateway narrows this by sitting between the agent and its tools, where the agent has no choice."}}, - {"@type": "Question", "name": "Does CTRLRun phone home?", "acceptedAnswer": {"@type": "Answer", "text": "No. There is no telemetry, licence check or network call in the kernel. ctrlrun stats counts the local SQLite file, and a test runs the demo in a subprocess whose sockets are all refused."}}, - {"@type": "Question", "name": "What if the human takes an hour to approve?", "acceptedAnswer": {"@type": "Answer", "text": "The approval request expires at its TTL, fifteen minutes by default, and a waiting call raises ApprovalTimeout with nothing executed. An agent can also surface the request id and come back later."}}, - {"@type": "Question", "name": "Does CTRLRun work across many hosts?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. On one host the store is a SQLite file. Across hosts, install the postgres extra and change the store: a unique index on the effect key and compare-and-set updates give the same guarantee."}}, - {"@type": "Question", "name": "What is in a CTRLRun receipt?", "acceptedAnswer": {"@type": "Answer", "text": "Who proposed the action, its canonical arguments, the decision and why, the approval and approver, the effect key, the outcome, the timestamps, the policy hash and version, and the hash of the receipt before it."}}, - {"@type": "Question", "name": "Is the receipt chain a signature?", "acceptedAnswer": {"@type": "Answer", "text": "No. The chain detects alteration and names it by seq. It does not prove who wrote a receipt, receipts are not signed, and it does not survive an administrator who can rewrite every row including the chain head."}}, - {"@type": "Question", "name": "What does CTRLRun not cover?", "acceptedAnswer": {"@type": "Answer", "text": "A compromised host, a malicious administrator with write access to the store, a lying remote, a compromised approver, an executor that raises NotExecuted after the remote acted, data exfiltration through reads, and authority across an agent-to-agent hop."}} - ] -})} -</script> - -## Next - -- [Why](/docs/why) · [Get started](/docs/get-started/quickstart). -- [Compare](/docs/compare/idempotency-keys): the five comparisons in full. diff --git a/docs/docs/get-started/choosing.mdx b/docs/docs/get-started/choosing.mdx deleted file mode 100644 index af0bf9a..0000000 --- a/docs/docs/get-started/choosing.mdx +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Choosing between them" -description: "In-process Python: the decorator. Tools behind MCP: the gateway. A framework with its own approval UI: an adapter." ---- - -In-process Python takes the decorator, tools behind MCP take the gateway, and a framework with -its own approval UI takes an adapter. The decision is about where the call that acts lives, not -about which framework you use. - -## The decision table - -| Where the call that acts lives | Use | Because | -|---|---|---| -| A Python function you can decorate, in the agent's process | `@protect` | It sees the real arguments, raises refusals as exceptions, and needs nothing installed | -| A tool server the agent reaches over MCP, in any language | the gateway | The agent and the server stay as they are; the gateway sits between them | -| A LangGraph graph whose humans answer with `Command(resume=...)` | `ctrlrun-langgraph` | The approval request goes through `interrupt()` rather than raising past the graph | -| An OpenAI Agents SDK run whose humans answer with `state.approve(item)` | `ctrlrun-openai-agents` | The approval request goes through the SDK's tool-approval interruption | -| A framework with no human-in-the-loop primitive | `@protect` | There is nothing for an adapter to reuse | -| Both a decorated function and an MCP server | both | They share one policy and one store; an effect key reserved by one is refused by the other | - -Two questions settle most cases. Can you decorate the function that acts? Then the decorator. -Does your framework already have a place where a human says yes? Then, and only then, an -adapter routes the request there. - -## What you don't need on one host - -For a single host, the whole of the default configuration is a policy file and a directory: - -| You do not need | Because | -|---|---| -| a server | the decorator and the store run in your process | -| a database | the store is a SQLite file, `.ctrlrun/state.db`, beside your policy; reservation is atomic across processes on that host through `BEGIN IMMEDIATE` | -| a dashboard | receipts are JSON lines beside the store, and `ctrlrun receipts`, `inspect` and `stats` read them | -| a message queue or an approval service | `ctrlrun approve` writes the grant; a webhook provider can route the request to Slack when you want that | -| an identity provider | `ctrlrun.context(agent=...)` names the principal; a header or JWT provider replaces it when the process is fronted by something that authenticates | - -When the store has to be shared across hosts, that is the one thing that changes: -[Run on Postgres](/docs/guides/run-on-postgres). - -## What changes nothing - -The three ways in share one policy, one store, one set of guarantees and one receipt format. A -refund refused by the gateway is refused for the same reason and recorded in the same shape as -one refused by the decorator, and `ctrlrun verify` checks the configuration behind all three. - -## Next - -- [Protect your first action](/docs/get-started/quickstart), for the decorator. -- [Put the gateway in front of MCP](/docs/guides/gateway-in-front-of-mcp). -- [Why](/docs/why). diff --git a/docs/docs/get-started/install.mdx b/docs/docs/get-started/install.mdx deleted file mode 100644 index 176076e..0000000 --- a/docs/docs/get-started/install.mdx +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "Install" -description: "pip install ctrlrun puts one package, pyyaml and click on your machine, nothing else. Python 3.11 or later." ---- - -`pip install ctrlrun` installs the kernel and exactly two dependencies, `pyyaml` and `click`. It -needs Python 3.11 or later and nothing running: no server, no database, no dashboard. State is a -SQLite file the library creates beside your policy. - -```bash -pip install ctrlrun -ctrlrun --version -``` - -## What is in the box - -| | | -|---|---| -| `ctrlrun` the package | the decorator, the policy loader, the SQLite store, approvals, authority, receipts, `verify` | -| `ctrlrun` the command | `init`, `demo`, `approve`, `deny`, `resolve`, `inspect`, `receipts`, `effects`, `stats`, `verify`, `delegate`, `revoke`, `gateway` | -| dependencies | `pyyaml`, `click` | - -A test asserts the dependency list has not grown, and another asserts that importing `ctrlrun` -imports nothing from an extra. - -## Extras - -Each extra is imported lazily. Using a feature without its extra raises `MissingDependency` -with the install command in the message. - -| Extra | Adds | Needed for | -|---|---|---| -| `ctrlrun[gateway]` | `httpx` | `ctrlrun gateway`, the MCP gateway | -| `ctrlrun[identity]` | `pyjwt[crypto]` | `JWTIdentityProvider`, verifying a bearer token against a JWKS or a pinned key | -| `ctrlrun[otel]` | the OpenTelemetry API, SDK and OTLP/HTTP exporter | `OTelEventSink` | -| `ctrlrun[postgres]` | `psycopg` | `PostgresStateStore` | - -```bash -pip install "ctrlrun[gateway,postgres]" -``` - -Adapters are separate distributions on their own version lines: `ctrlrun-langgraph` and -`ctrlrun-openai-agents`. Most readers do not need one; see -[Three ways in](/docs/get-started/three-ways-in). - -## Check it works - -```bash -ctrlrun demo -``` - -The demo runs five scenarios in process with no network and writes its evidence under -`.ctrlrun/demo/` in the current directory. It never touches a store you already have. - -## Next - -- [Protect your first action](/docs/get-started/quickstart): one function end to end. -- [Choosing between the three ways in](/docs/get-started/choosing). -- [Why](/docs/why): what the library believes. diff --git a/docs/docs/get-started/quickstart.mdx b/docs/docs/get-started/quickstart.mdx deleted file mode 100644 index da69ff4..0000000 --- a/docs/docs/get-started/quickstart.mdx +++ /dev/null @@ -1,186 +0,0 @@ ---- -title: "Protect your first action" -description: "Protect one function end to end in ten minutes: write a policy, decorate the call, watch a small refund run and a large one wait for a human." -canonical: "https://ctrlrun.dev/docs/get-started/quickstart" ---- - -In about ten minutes you will write a policy, protect a refund function, run one refund -autonomously, have a second one wait for a human, approve it from the shell, watch a mutated -call refused, and read the receipts. Every block on this page runs offline against a fake remote, -and the outputs shown are from a real run. - -**Prerequisites:** `pip install ctrlrun`, Python 3.11 or later, and an empty directory. If you -would rather see it before you type it, [Try it in your browser](/docs/try-it) runs the five demo -scenarios with no install. - -<Steps> - <Step title="Write the policy"> - In an empty directory, save this as `ctrlrun.yaml`. Amounts are integer minor units: cents, - not euros. Both ends of every band are bound, because an upper bound alone lets a negative - amount through, and a refund of a negative amount is a charge. - - ```yaml runnable - schema: ctrlrun.policy/v2 - - actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } # up to €500.00: autonomous - decision: allow - - when: { amount_gte: 0, amount_lte: 500000 } # up to €5,000.00: a human - decision: approve - - decision: deny - ``` - - Anything not listed here is denied. There is no default-allow. - </Step> - - <Step title="Protect the function"> - Save this as `agent.py`. The decorator names the action and the effect key; the context names - who is acting. `stripe` here is a stand-in that records calls instead of making them. - - ```python runnable file=agent.py - import sys - - import ctrlrun - - - class FakeStripe: - calls: list[tuple[str, int]] = [] - - def refund(self, payment_id: str, amount: int) -> dict: - self.calls.append((payment_id, amount)) - return {"id": f"re_{payment_id}", "amount": amount, "status": "succeeded"} - - - stripe = FakeStripe() - - - @ctrlrun.protect("stripe.refund", effect="refund:{payment_id}") - def refund(payment_id: str, amount: int) -> dict: - return stripe.refund(payment_id, amount) - - - if __name__ == "__main__": - with ctrlrun.context(agent="refund-agent"): - print("€100 refund:", refund(payment_id="txn_1", amount=10000)["status"]) - try: - refund(payment_id="txn_2", amount=200000) - except ctrlrun.ApprovalRequired as pending: - print("€2,000 refund: a human decides:", pending.request_id) - with open("request_id.txt", "w") as handle: - handle.write(pending.request_id) - else: - sys.exit("the €2,000 refund ran without a human; the policy is not in force") - ``` - - Run it once with `python agent.py`: - - ```text - €100 refund: succeeded - €2,000 refund: a human decides: apr_12b3d3175a95151b1a647df11727b999 - ``` - </Step> - - <Step title="Approve it from the shell"> - The request id is what `ctrlrun approve` takes. The approval is bound to the hash of the - exact action a human would see: `stripe.refund`, `txn_2`, €2,000, `refund-agent`. - - ```bash runnable - ctrlrun approve "$(cat request_id.txt)" - ``` - - ```text - granted apr_12b3d3175a95151b1a647df11727b999 for sha256:e8702b48316cdd7fd64d120fb2f41fc430d594c8e5c1999e9fa23765a161193c - expires 2026-09-06T07:21:18.331Z - ``` - - The grant names the hash it authorizes and when it lapses. Ids and hashes are generated per - run; yours differ. - </Step> - - <Step title="Present the approval, and try to abuse it"> - Save this as `approved.py`. The first call presents the approval for the action it was granted - for and runs. The second presents the same approval for a different amount, which matches - nothing: the approval was bound to €2,000 and has already been spent. - - ```python runnable file=approved.py - import sys - - import ctrlrun - - from agent import refund, stripe - - request_id = open("request_id.txt").read().strip() - - with ctrlrun.context(agent="refund-agent"), ctrlrun.with_approval(request_id): - print("€2,000 with approval:", refund(payment_id="txn_2", amount=200000)["status"]) - try: - refund(payment_id="txn_2", amount=500000) - except ctrlrun.ApprovalMismatch as refused: - print("€5,000 with the same approval: refused,", refused) - else: - sys.exit("a mutated action ran on a spent approval; that is the bug this exists to stop") - - print("remote refund calls:", len(stripe.calls)) - ``` - - Run it with `python approved.py`: - - ```text - €2,000 with approval: succeeded - €5,000 with the same approval: refused, approval apr_12b3d3175a95151b1a647df11727b999 authorizes sha256:e8702b48316cdd7fd64d120fb2f41fc430d594c8e5c1999e9fa23765a161193c, not sha256:641673c5e55775713bd90669ad09a2beafb10ee0a89e9a8573c5172abd4a1204 - remote refund calls: 1 - ``` - - One call reached the fake remote in this process, the approved €2,000. The €5,000 never did. - </Step> - - <Step title="Read the receipts"> - ```bash runnable - ctrlrun receipts --last 3 - ``` - - ```text - 2026-09-06T07:06:18.331Z ctr_f1f91aa263e46240b37d5fa593733e25 stripe.refund allow/committed refund:txn_1 refund-agent - 2026-09-06T07:06:18.476Z ctr_5f3ab5aa31cc3d7194b2340747e3d16e stripe.refund approve/committed refund:txn_2 refund-agent - 2026-09-06T07:06:18.477Z ctr_b9cb46cffd7de190777ea5fd14ef839f stripe.refund approve/blocked refund:txn_2 refund-agent - ``` - - Three receipts: the €100 refund that ran on its own, the €2,000 refund that ran on the - approval, and the €5,000 attempt, blocked. - - Every executed action has one: who, what, the decision, the approval it used, the effect key, - the outcome, and the hash of the policy that decided it. `ctrlrun inspect <action_id>` shows - one action's whole history. Both are in `.ctrlrun/receipts.jsonl` and `.ctrlrun/events.jsonl` - as one JSON object per line. - </Step> -</Steps> - -## What you just saw - -- **Per-action policy.** €100 ran, €2,000 waited, €5,000 would have been denied outright. -- **Approval binding.** The approval matched the exact action it was granted for and nothing else. -- **Effect keys.** `refund:txn_2` was reserved when the approved call ran; a second worker - presenting the same key would have been refused. -- **Receipts.** Everything above is in the evidence log, in order. - -What you did not see is a lost reply. That is the case CTRLRun exists for, and -[Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous) is where to read it next. - -## If it didn't work - -- `denied: no principal is available`: the call ran outside `ctrlrun.context(...)`. Every - protected call needs a principal, and a missing one is denied. -- `PolicyError: ... could not be read`: there is no `ctrlrun.yaml` in the working directory. - `ctrlrun init` writes a starter. -- `ActionDenied ... unknown_action`: the action name in the decorator does not match a key under - `actions:`. Unknown actions are denied. - -## Next - -- [Cookbook](/docs/cookbook/index): the same shape for a deploy, an IAM grant, a deletion, an email, an MCP server. -- [Three ways in](/docs/get-started/three-ways-in): decorator, gateway, adapter. -- [Effect keys](/docs/concepts/effect-keys): what the `effect=` template names, and why it is not a request id. -- [Why](/docs/why). diff --git a/docs/docs/get-started/three-ways-in.mdx b/docs/docs/get-started/three-ways-in.mdx deleted file mode 100644 index 3526de1..0000000 --- a/docs/docs/get-started/three-ways-in.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: "Three ways in" -description: "The @protect decorator covers anything in your Python process, the MCP gateway covers tools behind an MCP server in any language." ---- - -There are three ways to put CTRLRun in front of a consequential action, and only one of them is -an adapter. Most readers need the decorator and should not look for an adapter. - -| | Covers | Needs | -|---|---|---| -| **`@protect`** | anything running in this process: a raw model call, a LangChain tool, a hand-rolled loop, a cron job | nothing; it is a decorator | -| **The MCP gateway** | anything reaching its tools over MCP, in any language | `pip install "ctrlrun[gateway]"` | -| **An adapter** | routing an `approve` decision through the framework's **own interrupt** instead of raising past it | the framework to have a human-in-the-loop primitive | - -## The decorator - -Wrap the function that acts. Name the action, name the consequence with `effect=`, and say who -is acting with `context`. The policy beside your code decides. - -```python -import ctrlrun - - -@ctrlrun.protect("k8s.delete_namespace", effect="namespace:{cluster}:{name}") -def delete_namespace(cluster: str, name: str) -> str: - return kubectl("delete", "namespace", name, "--context", cluster) - - -with ctrlrun.context(agent="deploy-agent"): - delete_namespace(cluster="prod-eu", name="checkout") -``` - -`ApprovalRequired`, `ActionDenied`, `DuplicateEffect` and `AmbiguousEffect` are raised as -themselves, before the function body runs. [Protect a function](/docs/guides/protect-a-function) is -the full guide. - -## The gateway - -No agent changes and no server changes. Point the MCP client at the gateway instead of the tool -server, and every `tools/call` is decided, approved, reserved, executed and recorded like a -decorated call. Everything else on the wire is relayed untouched. - -```text -before agent ──▶ MCP server -after agent ──▶ CTRLRun gateway ──▶ MCP server -``` - -```bash -pip install "ctrlrun[gateway]" -ctrlrun gateway --upstream http://localhost:8000/mcp --alias acme --principal refund-agent -``` - -Tools become actions named `mcp.<alias>.<tool>`. A tool call has no decorator to carry its -effect template, so the template is declared in the policy, and the gateway prints on the line -that starts it every action that has none. -[Put the gateway in front of MCP](/docs/guides/gateway-in-front-of-mcp) is the guide. - -## Adapters - -An adapter exists for one reason: so that a human answers where they already answer. When the -policy says `approve`, the request goes out through LangGraph's `interrupt()` or the OpenAI -Agents SDK's tool-approval interruption instead of `ApprovalRequired` being raised past your -graph. The adapter returns the answer; one core provider writes the grant through the same calls -`ctrlrun approve` makes. There is never a second place to say yes. - -| | Reuses | Binding | -|---|---|---| -| `ctrlrun-langgraph` | `interrupt()` and the checkpointer | **prevention**: the resumption carries the arguments and core re-checks them against the hash | -| `ctrlrun-openai-agents` | the SDK's tool-approval interruption | **attribution**: the SDK records *that* a call was approved, not what its arguments were | - -You build the `Control` with your policy, store, identity provider and authority document, and -hand it over. An adapter never constructs one and never supplies a principal. Adapters ship on -their own version line, `adapters-langgraph-1.0` and never a kernel version, because they break -when their framework does. - -A framework with no human-in-the-loop primitive has nothing for an adapter to reuse and does not -need one. The decorator already covers it. - -## Next - -- [Choosing between them](/docs/get-started/choosing): the decision table. -- [Use the LangGraph adapter](/docs/guides/langgraph-adapter) · [Use the OpenAI Agents SDK adapter](/docs/guides/openai-agents-adapter). -- [Why](/docs/why). diff --git a/docs/docs/guides/approvals-in-slack.mdx b/docs/docs/guides/approvals-in-slack.mdx deleted file mode 100644 index 5be8233..0000000 --- a/docs/docs/guides/approvals-in-slack.mdx +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: "Approve in Slack" -description: "Route approval requests to a webhook with WebhookApprovalProvider: one signed POST per request, a human answers in Slack or any chat tool." ---- - -`WebhookApprovalProvider` sends one signed POST to a URL you own for every approval request, -and takes the answer back through a signed POST to the gateway's `/ctrlrun/approvals/` endpoint. -Your side is a small service that turns the request into a Slack message with two buttons and -turns the click into the answer. The grant is written by the same call `ctrlrun approve` makes; -there is no second approval path. - -**Prerequisites:** `pip install ctrlrun` (the outbound half is core); `pip install -"ctrlrun[gateway]"` for the inbound endpoint, which the gateway serves; a shared secret; a -URL that can receive the POST. - -<Steps> - <Step title="Configure the provider"> - In a process using the decorator: - - ```python - import os - from datetime import timedelta - - from ctrlrun import Control, Policy, SQLiteStateStore, WebhookApprovalProvider - - store = SQLiteStateStore(".ctrlrun/state.db") - control = Control( - Policy.from_file("ctrlrun.yaml"), - store, - approvals=WebhookApprovalProvider( - store, - url="https://approvals.example.com/ctrlrun", - secret=os.environ["CTRLRUN_WEBHOOK_SECRET"], - public_url="https://gateway.example.com", # where the answer is POSTed back - timeout=timedelta(seconds=10), - ), - ) - ``` - - With the gateway, the same thing is two flags: - - ```bash - ctrlrun gateway --upstream http://localhost:8000/mcp --alias acme --principal refund-agent \ - --webhook-url https://approvals.example.com/ctrlrun \ - --webhook-secret-file /run/secrets/ctrlrun-webhook \ - --public-url https://gateway.example.com - ``` - - The secret comes from `$CTRLRUN_WEBHOOK_SECRET` or a file, never from a flag value: a - secret on a command line is in every process listing on the host. An `http://` URL is - refused unless `--allow-insecure-webhook`, and then only on loopback. - </Step> - - <Step title="Receive the request"> - One POST per `APPROVAL_REQUESTED`, with a `CTRLRun-Signature` header. Verify it before you - read the body. The header is two comma-separated fields: - - ```text - CTRLRun-Signature: t=1757142078,v1=6f1c…8ad2 - ``` - - `t` is unix seconds and `v1` is the hex HMAC-SHA256, keyed on your secret, over the exact - bytes `f"{t}.{body}"` — the body as sent, not re-serialized. Compare it with a constant-time - comparison, and refuse a `t` outside your replay window (five minutes). - - ```json - { - "schema": "ctrlrun.approval_request/v1", - "request_id": "apr_…", - "action": { - "name": "stripe.refund", - "arguments": {"amount": 200000, "payment_id": "txn_2"}, - "principal": {"agent": "refund-agent", "user": null}, - "resource": "payment:txn_2", - "environment": "production", - "action_hash": "sha256:…" - }, - "expires_at": "2026-09-06T07:21:18.331Z", - "respond_to": "https://gateway.example.com/ctrlrun/approvals/apr_…" - } - ``` - - Show the human exactly what is in `action`: the name, every argument, who is asking. The - approval will be bound to that hash, so what they see is what will run. - </Step> - - <Step title="Send the answer back"> - POST to `respond_to`, signed the same way, with a timestamp within the replay window - (five minutes by default): - - ```json - { - "request_id": "apr_…", - "action_hash": "sha256:…", - "decision": "grant", - "approver": "dana@example.com" - } - ``` - - **All four are required.** `request_id` must equal the one in the path, and `action_hash` - must equal the one on the stored request — echo back what the request gave you. A body - carrying only `decision` and `approver` is refused with *the path and the body name - different requests*, which is the shape of this guide's own earlier example. - - `decision` is `grant` or `deny`; `approver` is a non-empty string recorded on the receipt. - A replayed grant inside the window is idempotent, because the record is already granted; - outside it, the timestamp check refuses. The endpoint answers 200 on success and a 4xx with - the reason on a bad signature, an unknown request id, a hash that does not match, an expired - request, or a request already answered the other way. - </Step> - - <Step title="Watch it land"> - ```bash - ctrlrun inspect act_… # the action's history, proposal through grant - ctrlrun receipts --last 1 --json # "approver": "dana@example.com" - ``` - - If the human never answers, the request expires at `expires_at` (the approval TTL, fifteen - minutes by default) and a waiting call raises `ApprovalTimeout`. Nothing runs. - </Step> -</Steps> - -## What the provider does not do - -It does not build the Slack message or the buttons; that is your service, which knows your -workspace. It does not authenticate the approver: `approver` is recorded as given, which is the -threat model's stated limit. It does not retry into the future: delivery is two retries with a -short backoff, and an undeliverable request is logged and left `pending` for `ctrlrun approve`. - -## If it didn't work - -- `signature does not verify`: the secret differs, or your side re-serialized the body before - signing. Sign the exact bytes. -- `timestamp outside the replay window`: clocks differ by more than five minutes. -- `ApprovalTimeout`: nobody answered within the TTL; the request is expired, not lost. -- The webhook never fires: the provider is not on the `Control` the protected function uses. - With the decorator, pass `control=control`. - -## Next - -- [Approval binding](/docs/concepts/approval-binding): what the answer authorizes. -- [Put the gateway in front of MCP](/docs/guides/gateway-in-front-of-mcp). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/export-to-opentelemetry.mdx b/docs/docs/guides/export-to-opentelemetry.mdx deleted file mode 100644 index 5f5a952..0000000 --- a/docs/docs/guides/export-to-opentelemetry.mdx +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: "Export to OpenTelemetry" -description: "Add OTelEventSink to a Control and every action becomes one span with one span event per step, in whatever tracing backend your process already exports to." ---- - -`OTelEventSink` turns every action into one OpenTelemetry span, named for the action, with one -span event per step: proposed, decided, reserved, executed, recorded. It hands spans to whatever -tracer provider your process configured and never blocks. Argument values are not attributes -unless you ask, because a trace backend is not the receipt store. - -**Prerequisites:** `pip install "ctrlrun[otel]"`, which brings the API, the SDK and the -OTLP/HTTP exporter, and a backend that speaks OTLP (or, below, an in-memory exporter to see -the spans without one). - -<Steps> - <Step title="Attach the sink"> - ```yaml runnable - schema: ctrlrun.policy/v2 - - actions: - crm.update_record: - effect: "crm:{record_id}:{field}" - decision: allow - ``` - - ```python runnable - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import SimpleSpanProcessor - from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter - - import ctrlrun - from ctrlrun import Control, Policy, SQLiteStateStore - from ctrlrun.otel import OTelEventSink - - exporter = InMemorySpanExporter() - provider = TracerProvider() - provider.add_span_processor(SimpleSpanProcessor(exporter)) - - control = Control( - Policy.from_file("ctrlrun.yaml"), - SQLiteStateStore(".ctrlrun/state.db"), - sinks=[OTelEventSink(tracer_provider=provider)], - ) - - - @ctrlrun.protect("crm.update_record", effect="crm:{record_id}:{field}", control=control) - def update(record_id: str, field: str, value: str) -> str: - return "updated" - - - with ctrlrun.context(agent="crm-agent"): - update(record_id="c_42", field="phone", value="+353 1 555 0100") - - (span,) = exporter.get_finished_spans() - print("span:", span.name) - print("events:", [event.name for event in span.events]) - print("arguments in attributes:", any("phone" in str(v) for v in span.attributes.values())) - ``` - - ```text - span: crm.update_record - events: ['ACTION_PROPOSED', 'POLICY_EVALUATED', 'EFFECT_RESERVED', 'EXECUTION_STARTED', 'EXECUTION_COMMITTED'] - arguments in attributes: False - ``` - </Step> - - <Step title="Export for real"> - Replace the in-memory exporter with the OTLP one your backend expects, or rely on the - provider your application already configured and pass nothing: with no `tracer_provider` - the sink uses the global one, and with none configured the API's no-op provider makes the - sink free. - - ```python - from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter - from opentelemetry.sdk.trace.export import BatchSpanProcessor - - provider = TracerProvider() - provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter())) # OTEL_EXPORTER_OTLP_ENDPOINT - ``` - - With the gateway, `--otel` does the same, and `--otel-arguments` opts argument values in. - </Step> - - <Step title="Read the span"> - The span's status is an error for `failed` and `ambiguous`, unset for a refusal (a refusal - is CTRLRun doing its job, not an error), and ok for `committed`. Attributes carry the action - name, the decision, the effect key, the outcome and the receipt id; the receipt itself stays - in the store. Open spans are bounded, so a process that dies mid-action leaves at most a - fixed number unended, stated rather than solved. - </Step> -</Steps> - -## What the sink is not - -It is not the evidence. Receipts live in the store and the JSONL file, are chained, and are -what `ctrlrun receipts --verify-chain` checks; a trace is a view of them for the people who -already look at traces. Deleting a trace deletes nothing CTRLRun relies on. - -## If it didn't work - -- `MissingDependency: pip install "ctrlrun[otel]"`: the extra is not installed. -- No spans arrive: no span processor is attached to the provider the sink was given, or the - batch processor has not flushed yet; `provider.force_flush()` before exit. -- Argument values appear: `arguments=True` was passed, or `--otel-arguments` on the gateway. - -## Next - -- [Receipts and evidence](/docs/concepts/receipts-and-evidence). -- [Receipt and event schemas](/docs/reference/receipt-and-event-schemas): the event names above. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/gateway-in-front-of-mcp.mdx b/docs/docs/guides/gateway-in-front-of-mcp.mdx deleted file mode 100644 index 299a21a..0000000 --- a/docs/docs/guides/gateway-in-front-of-mcp.mdx +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: "Put the gateway in front of MCP" -description: "Two commands put policy, approval binding, effect keys and receipts in front of an existing MCP server, in any language." ---- - -Point the MCP client at `ctrlrun gateway` instead of the tool server. Every `tools/call` is -then decided by your policy, bound to an approval where it says `approve`, reserved by effect -key, relayed to the server, and recorded; everything else on the wire passes through untouched. -The agent does not change. The server does not change. It works for a server written in any -language. - -```text -before agent ──▶ MCP server -after agent ──▶ CTRLRun gateway ──▶ MCP server -``` - -**Prerequisites:** an MCP server reachable over HTTP, `pip install "ctrlrun[gateway]"`, and a -directory for the policy and the store. The gateway speaks MCP revision `2026-07-28` and -accepts `2025-11-25`, `2025-06-18` and `2025-03-26`; the client's declared revision is -validated, never trusted. - -<Steps> - <Step title="Name the tools in the policy"> - A tool becomes the action `mcp.<alias>.<tool>`. A tool call has no decorator to carry an - effect template, so the policy carries it; a write with no `effect:` gets no reservation, - and the gateway names every such action on the line that starts it. - - ```yaml runnable - schema: ctrlrun.policy/v2 - - actions: - mcp.acme.list_payments: - decision: allow - mcp.acme.create_refund: - effect: "refund:{payment_id}" - resource: "payment:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - when: { amount_gte: 0, amount_lte: 500000 } - decision: approve - - decision: deny - mcp.acme.delete_customer: - decision: deny - ``` - - Argument names in `when:` and in templates are the tool's own parameter names, as the - client sends them. Floats are refused; if a tool takes a float amount, it cannot be fronted - until it takes minor units. - </Step> - - <Step title="Start the gateway"> - ```bash - pip install "ctrlrun[gateway]" - ctrlrun gateway --upstream http://localhost:8000/mcp --alias acme --principal refund-agent - ``` - - ```text - CTRLRun gateway → http://localhost:8000/mcp as mcp.acme.* - listening on http://127.0.0.1:8900/mcp environment: production - identity: fixed principal refund-agent authority: none - 1 action(s) have no effect: template and get no reservation: - mcp.acme.list_payments - That is right for a read, and wrong for anything that changes the world. - ``` - - Then point the client at `http://127.0.0.1:8900/mcp`. The gateway listens on loopback - unless `--allow-remote`, and its body limit and upstream timeout are flags. - </Step> - - <Step title="Choose how the principal is known"> - `--principal refund-agent` is one fixed name, right for one agent behind one gateway. - `--principal-header X-Agent` reads the agent from a header a proxy in front sets, and is - worth exactly what that proxy is worth: if the agent can set the header, the agent chooses - its own authority. `--identity-jwt ...` verifies a bearer token against a JWKS or a pinned - key, with the algorithms, issuer, audience and token type all required and none defaulted. - Whatever the source, the principal is consumed; the gateway never reads one off the request - body, and a `tools/call` with no principal is refused. - </Step> - - <Step title="What the agent sees"> - A refusal is a JSON-RPC error, not a tool result. A tool result with `isError` would reach - the model as text and invite the retry the refusal exists to prevent; an error with a code - the client can read does not. - - Denied, `-41001` (`ctrlrun.denied`, HTTP 403): - - ```json - {"jsonrpc": "2.0", "id": 7, - "error": {"code": -41001, "message": "mcp.acme.delete_customer: denied (policy)", - "data": {"error": "ctrlrun.denied"}}} - ``` - - Approval required, `-41002` (`ctrlrun.approval_required`, HTTP 403), carrying the request - id a human answers with `ctrlrun approve`: - - ```json - {"jsonrpc": "2.0", "id": 8, - "error": {"code": -41002, "message": "mcp.acme.create_refund: a human must approve", - "data": {"error": "ctrlrun.approval_required", "request_id": "apr_…"}}} - ``` - - The other codes: `-41003` approval denied, `-41004` duplicate effect (409), `-41005` - ambiguous effect (409), `-41006` blocked, `-41007` no principal, `-41012` this principal - holds no grant. A relayed result carries `_meta["com.ctrlrun/receipt"]` with the receipt - id, so a client can find what was recorded. - </Step> - - <Step title="A lost reply over the wire"> - The upstream commits, then the connection drops. The gateway records `AMBIGUOUS`, returns - `-41010` (`ctrlrun.upstream_ambiguous`, HTTP 502), and the identical call sent again is - refused with `-41005` until a human resolves the effect. `FAILED` over the wire means only - that the connection was never established or the upstream said in band that it rejected the - call before acting; everything after the first byte is unknown, and `mcp.not_executed_on_error` - in the policy is how you say an upstream's in-band error means it did nothing. - </Step> -</Steps> - -## What you get, in your terms - -- No code changes: the agent and the server are untouched. -- Any language: the gateway is a process in front of an HTTP endpoint. -- Approvals bound to the exact tool call, arguments included. -- Every call that **reaches a decision** leaves a receipt, denied ones included. A call still waiting on a human has not been decided yet and has none until it is. -- Measure first: `mode: observe` in the same policy records what enforcing would block. - -## If it didn't work - -- `unsupported protocol version`: the client declared a revision the gateway does not accept. -- `header mismatch` (`-32020`): the MCP header and the body disagree; the gateway routes on the - body and refuses the mismatch rather than guessing. -- `no principal is available` (`-41007`): none of `--principal`, `--principal-header` or - `--identity-jwt` produced one for this request. -- The gateway exits 2 at start: a non-loopback `--listen` without `--allow-remote`, a JWT flag - without `pip install "ctrlrun[identity]"`, or a policy that does not load. - -## Next - -- [Approve in Slack](/docs/guides/approvals-in-slack): where the request id goes. -- [Choosing between the three ways in](/docs/get-started/choosing). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/langgraph-adapter.mdx b/docs/docs/guides/langgraph-adapter.mdx deleted file mode 100644 index 99a018e..0000000 --- a/docs/docs/guides/langgraph-adapter.mdx +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: "Use the LangGraph adapter" -description: "Route an approve decision through LangGraph's own interrupt() with ctrlrun-langgraph." ---- - -`ctrlrun-langgraph` makes an `approve` decision surface as a LangGraph `interrupt()` instead of -an `ApprovalRequired` raised past your graph. The human answers where LangGraph users already -answer, with `Command(resume=...)`, and one core provider writes the grant through the same -calls `ctrlrun approve` makes. With `carries_approved_arguments=True` the resumption carries the -arguments the human saw and core re-checks them against the action hash: that is prevention. - -You probably do not need this. `@protect` already covers a LangChain tool or a graph node with -no adapter. Use it when your deployment has a place where a human answers a LangGraph interrupt -and you want approvals to land there. - -**Prerequisites:** `pip install ctrlrun-langgraph`, `langgraph>=1.0,<2.0`, a graph compiled -with a checkpointer. The blocks below are the adapter's own example; the adapter's tests run -them against a real LangGraph install in this repository's CI. - -<Steps> - <Step title="Build the Control, and hand it over"> - The operator chooses the policy, the store, the identity provider and the authority - document. The adapter is one argument to the approval provider and never constructs a - `Control` or supplies a principal. - - ```python - from ctrlrun import Control, InterruptApprovalProvider, protect - from ctrlrun_langgraph import LangGraphInterrupt - - control = Control( - policy, store, - approvals=InterruptApprovalProvider( - store, LangGraphInterrupt(carries_approved_arguments=True) - ), - identity=..., authority=..., - ) - - - @protect("stripe.refund", effect="refund:{payment_id}", wait=True, control=control) - def issue_refund(payment_id: str, amount: int) -> str: - return stripe.Refund.create(payment_intent=payment_id, amount=amount) - ``` - - `wait=True` is the whole difference: it routes the `approve` through the provider, and so - through `interrupt()`, instead of raising. - </Step> - - <Step title="Answer the interrupt"> - ```python - graph = builder.compile(checkpointer=InMemorySaver()) - config = {"configurable": {"thread_id": "..."}} - - result = graph.invoke({"payment_id": "txn_1", "amount": 2000}, config) - if "__interrupt__" in result: - pending = graph.get_state(config).tasks[0].interrupts[0].value - # `pending` is JSON: request_id, action_id, action, action_hash, arguments, resource, - # environment, agent, user, created_at, expires_at. There is no `principal` key and no - # `hash` key — the principal is split into `agent` and `user`, and the hash is - # `action_hash`. Put it in front of a human however you already do. - graph.invoke( - Command(resume={ - "approved": True, - "approver": "ada@example.com", - "arguments": pending["arguments"], # what they answered against - }), - config, - ) - ``` - - `Command(resume=True)` grants as `langgraph:interrupt`; `Command(resume=False)` refuses; - the mapping form carries the approver and the arguments. `approved` must be a real boolean; - a truthy string is refused with a message naming your resume value. - </Step> - - <Step title="Choose prevention"> - `carries_approved_arguments` has no default, because the default somebody assumes is the - one that does not check. `True`: the resumption must carry `arguments`, core rebuilds the - proposal with them and compares the hash, and an answer given against €5 that arrives for - a €5,000 action is refused with `ApprovalMismatch`. `False`: only the verdict comes back, - the binding across the interrupt is LangGraph's checkpoint, and CTRLRun records who - answered without being able to re-check what about; the conformance kit reports `binding` - as not applicable, never as a pass. Choose `False` only if your console cannot echo what it - displayed. - </Step> -</Steps> - -## Where LangGraph shows through - -- **The node runs twice**, once to ask and once on resume, so there are two `action_id`s and - two approval requests for one refund; the first stays `pending` for its TTL. `action_hash` is - continuous, which is why the binding is about content and never about an id. -- **The resumed pass re-checks everything**: principal expiry, authority and policy at - resumption time, so an authority revoked while the human deliberated refuses the action then. -- **The TTL does not bound deliberation**; your checkpoint does. Expire the thread if it - matters. -- **The kernel's exceptions arrive as themselves.** LangGraph propagates a node's exception, so - `except DuplicateEffect` works with nothing to unwrap. - -## If it didn't work - -- `ApprovalMismatch` on resume: the `arguments` you sent back are not the ones the human saw; - send `pending["arguments"]` verbatim. -- `ApprovalRequired` raised past the graph: the decorator lacks `wait=True`, or the function - is bound to a different `Control` than the one carrying the provider. -- `InvalidArgument: approved must be True or False`: the resume value carried a string. - -## Next - -- [Use the OpenAI Agents SDK adapter](/docs/guides/openai-agents-adapter): the other shape, and why its binding is attribution. -- [Approval binding](/docs/concepts/approval-binding). -- [The adapter's README](https://github.com/CTRLRun/ctrlrun/blob/main/adapters/langgraph/README.md) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/observe-to-enforce.mdx b/docs/docs/guides/observe-to-enforce.mdx deleted file mode 100644 index 85857e1..0000000 --- a/docs/docs/guides/observe-to-enforce.mdx +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: "Roll out observe, then enforce" -description: "Put mode: observe at the top of the policy, run real traffic for a week, read ctrlrun stats to see what enforcement would have blocked and why." ---- - -Start with `mode: observe`: every action is decided exactly as enforce mode would decide it, -executes regardless, and records what would have been blocked. After a week `ctrlrun stats` -tells you what enforcing will cost, in refusals and in approval requests, before a single -refund waits for a human. Then change one line. - -**Prerequisites:** a policy for the actions your agent already performs, and the decorator or -the gateway in front of them. The blocks below simulate a week in a few calls. - -<Steps> - <Step title="Observe"> - ```yaml runnable - schema: ctrlrun.policy/v3 - mode: observe - - actions: - crm.update_record: - effect: "crm:{record_id}:{field}" - decision: allow - email.send: - effect: "email:{message_id}" - rules: - - when: { to_domain_eq: "example.com" } - decision: allow - - decision: approve - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - when: { amount_gte: 0, amount_lte: 500000 } - decision: approve - - decision: deny - ``` - - ```python runnable - import ctrlrun - - sent: list[str] = [] - - - @ctrlrun.protect("crm.update_record", effect="crm:{record_id}:{field}") - def update(record_id: str, field: str, value: str) -> str: - return "updated" - - - @ctrlrun.protect("email.send", effect="email:{message_id}") - def send(message_id: str, to_domain: str) -> str: - sent.append(message_id) - return "sent" - - - @ctrlrun.protect("stripe.refund", effect="refund:{payment_id}") - def refund(payment_id: str, amount: int) -> str: - return "refunded" - - - with ctrlrun.context(agent="support-agent"): - update(record_id="c_1", field="phone", value="+353 1 555 0100") - send(message_id="m_1", to_domain="example.com") - send(message_id="m_2", to_domain="gmail.com") # would have needed a human - refund(payment_id="txn_1", amount=10000) - refund(payment_id="txn_2", amount=250000) # would have needed a human - refund(payment_id="txn_3", amount=900000) # would have been denied - refund(payment_id="txn_1", amount=10000) # would have been a duplicate - - print("emails actually sent:", len(sent)) - ``` - - ```text - emails actually sent: 2 - ``` - - Both emails went out, including the one to `gmail.com`. Observe mode is not a dry run: it - executes, and it asks no human. What it adds is the counterfactual on every receipt. - </Step> - - <Step title="Read the numbers"> - ```bash runnable - ctrlrun stats - ``` - - ```text - CTRLRun — 2026-09-06T10:55:05.474Z .. 2026-09-06T10:55:05.476Z (observe mode) - - actions 7 - would have been denied 1 - rule[2] 1 - would have needed approval 2 - would have been blocked 1 - duplicate 1 - ambiguous outcomes 0 - - Actions still awaiting a human have no receipt yet and are not counted. - ``` - - Counted from the local store and nothing else: no network, no upload. `--since 7d` narrows - the window and `--json` gives the same numbers to a script. - </Step> - - <Step title="Fix the policy, not the count"> - Each *would have needed approval* is a real approval request you will field once you - enforce. If the rate is wrong, the band is wrong: raise the autonomous limit for the action, - or add a rule for the case that dominates. Each *would have been denied* is an action your - agent performs today that will stop, named by the rule; decide whether that is the point. - A *duplicate* is a retry loop you did not know about. - </Step> - - <Step title="Enforce"> - Change the line, redeploy, and the same receipts now carry refusals instead of - counterfactuals: - - ```yaml - mode: enforce - ``` - - Nothing else changes: same policy, same store, same evidence format. Every `would_have` - becomes a `BLOCKED` receipt or an approval request, and `ctrlrun stats` reports less and says - so. - </Step> -</Steps> - -## What observe mode will not do - -It will not stop an action the policy would deny, and it will not ask a human. Run it on -traffic you would run unprotected today. It is one line for the whole deployment; there is no -per-action observe. An adapter's pre-invocation predicate answers "no approval needed" in observe -mode, for the same reason: a human's no must not stop what observe mode promises to run. - -## If it didn't work - -- `PolicyError: mode is refused anywhere but the top level`: `mode:` is inside an action entry. -- `ctrlrun stats` shows `enforce mode reports less`: the store was written in enforce mode; there - are refusals to count, not counterfactuals. -- A receipt has no `would_have`: it was written before `mode: observe` was in force. - -## Next - -- [Observe mode](/docs/concepts/observe-mode). -- [Fail closed](/docs/concepts/fail-closed): what enforce mode refuses. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/openai-agents-adapter.mdx b/docs/docs/guides/openai-agents-adapter.mdx deleted file mode 100644 index 6846241..0000000 --- a/docs/docs/guides/openai-agents-adapter.mdx +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: "Use the OpenAI Agents SDK adapter" -description: "Route an approve decision through the OpenAI Agents SDK's tool-approval interruption with ctrlrun-openai-agents." ---- - -`ctrlrun-openai-agents` makes an `approve` decision stop the run with the SDK's own -`ToolApprovalItem` instead of `ApprovalRequired` being raised past the runner. The human -answers with `state.approve(item)`, where this SDK's users already answer, and one core provider -writes the grant. The binding across the interrupt is the SDK's, keyed by `call_id`, so CTRLRun -records who answered and cannot re-check what they answered about: that is attribution, in that -word. - -You probably do not need this. A plain `@function_tool` body under `@protect` is already -covered. Use it when the SDK's approval interruption is where your humans answer. - -**Prerequisites:** `pip install ctrlrun-openai-agents`, `openai-agents>=0.20,<1.0`. The -blocks are the adapter's own example, run against a real SDK install in this repository's CI. - -<Steps> - <Step title="Build the Control, and wrap the tool"> - ```python - from ctrlrun import Control, InterruptApprovalProvider, protect - import ctrlrun_openai_agents as gate - from ctrlrun_openai_agents import AgentsInterrupt, protected_tool - - control = Control( - policy, store, - approvals=InterruptApprovalProvider(store, AgentsInterrupt()), - identity=..., authority=..., - ) - - - @protect("stripe.refund", effect="refund:{payment_id}", wait=True, control=control) - def issue_refund(payment_id: str, amount: int) -> str: - return stripe.Refund.create(payment_intent=payment_id, amount=amount) - - - async def refund_tool(payment_id: str, amount: int) -> str: - """Issue a refund for a payment. Amounts are in integer minor units.""" - return issue_refund(payment_id=payment_id, amount=amount) - - - agent = Agent(name="refunds", tools=[protected_tool(control, "stripe.refund", refund_tool)]) - ``` - - `protected_tool` builds the `function_tool` with `needs_approval=` answered by the policy - through `ctrlrun.adapter.needs_approval`, and with `failure_error_function=None`. That - second part is not optional: the SDK's default turns a tool's exception into "An error - occurred while running the tool. Please try again." for the model, which is exactly the - retry a refusal exists to prevent. - </Step> - - <Step title="Run, answer, resume"> - ```python - result = await gate.run(agent, "refund txn_1") - if result.interruptions: - state = result.to_state() - for item in result.interruptions: - state.approve(item) # or state.reject(item) - result = await gate.run(agent, state) - ``` - - `gate.run` and `gate.run_sync` are `Runner.run` with CTRLRun's exceptions arriving as - themselves: the SDK wraps a tool's exception in `UserError`, and these walk the chain back. - `unwrap(error)` does the same if you call `Runner` yourself. - </Step> - - <Step title="Know what a rejection leaves behind"> - The SDK does not invoke a tool whose approval was refused, so no CTRLRun action is - proposed: no `APPROVAL_DENIED`, no `ACTION_DENIED`, no receipt. The refusal is real and in - the SDK's run output; CTRLRun was never asked. Record it where you call `state.reject(item)` - if you need it in the evidence log. The conformance kit reports `denial` as not applicable - for the same reason. - </Step> -</Steps> - -## Where the SDK shows through - -- **The predicate and `@protect` can disagree.** `needs_approval` sees the raw arguments, not - the decorator's defaults or a `resource=` declared only there. A wrong yes asks a human about - something harmless; a wrong no means the interrupt finds no answer for a call nobody was - asked about and refuses it with `ApprovalNotAsked`, nothing written, the request left - `pending` for `ctrlrun approve`. In neither direction does an unapproved action execute. -- **One answer authorizes one request, for the action the tool gated.** A refund's yes does - not authorize a `bank.wire` raised beside it, and `always_approve=True` is refused as an - answer because it records a decision about the tool, not the call. -- **Observe mode**: the predicate answers "no approval needed", because the SDK would not - invoke a declined tool and a human's no would stop what observe mode promises to run. -- **Retries**: measured on `openai-agents` 0.22.0 against a remote that commits and then drops - the connection, with no effect-level guard, the model retried until the refund had landed - three or four times in one run, five runs out of five. Declare an `effect=`. - -## If it didn't work - -- `ApprovalNotAsked`: the tool was invoked without the SDK having asked; pass the same - `resource=` to `protected_tool`, give the tool no defaulted parameters, and route every - `@protect(wait=True)` on this `Control` through `protected_tool`. -- The model retries after a refusal: `failure_error_function` was left at its default; use - `protected_tool`. -- `except DuplicateEffect` never fires: you called `Runner.run`; use `gate.run` or `unwrap`. - -## Next - -- [Use the LangGraph adapter](/docs/guides/langgraph-adapter): the prevention shape. -- [Three ways in](/docs/get-started/three-ways-in). -- [The adapter's README](https://github.com/CTRLRun/ctrlrun/blob/main/adapters/openai-agents/README.md) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/protect-a-function.mdx b/docs/docs/guides/protect-a-function.mdx deleted file mode 100644 index 404c3c6..0000000 --- a/docs/docs/guides/protect-a-function.mdx +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: "Protect a function" -description: "Wrap the function that acts with @ctrlrun.protect, name the action and its effect key, say who is acting." ---- - -Decorate the function that acts, name the action and the consequence, and put the call inside -a context that names who is acting. From then on every call is decided, reserved, executed and -recorded, and a refusal is an exception raised before the function body runs. - -**Prerequisites:** `pip install ctrlrun`, Python 3.11 or later, an empty directory. Every block -below runs offline; the deploy tool is a stand-in that records calls. - -<Steps> - <Step title="Write the policy"> - Three actions across two domains: a rollout restart that is cheap to undo, a namespace - delete that needs a human, and a role grant that is autonomous for readers and needs a - human for anything else. - - ```yaml runnable - schema: ctrlrun.policy/v2 - - actions: - k8s.rollout_restart: - effect: "restart:{cluster}:{deployment}" - decision: allow - k8s.delete_namespace: - effect: "namespace:{cluster}:{name}" - decision: approve - iam.grant_role: - effect: "grant:{principal}:{role}" - rules: - - when: { role_in: [reader, viewer] } - decision: allow - - decision: approve - ``` - </Step> - - <Step title="Decorate the functions"> - `effect=` is a template over the function's own parameters. It names the consequence, so the - same delete proposed twice, by a retry or by a second worker, is one effect. - - ```python runnable file=infra.py - import sys - - import ctrlrun - - calls: list[str] = [] - - - def kubectl(*args: str) -> str: - calls.append(" ".join(args)) - return "ok" - - - @ctrlrun.protect("k8s.rollout_restart", effect="restart:{cluster}:{deployment}") - def restart(cluster: str, deployment: str) -> str: - return kubectl("rollout", "restart", f"deployment/{deployment}", "--context", cluster) - - - @ctrlrun.protect("k8s.delete_namespace", effect="namespace:{cluster}:{name}") - def delete_namespace(cluster: str, name: str) -> str: - return kubectl("delete", "namespace", name, "--context", cluster) - - - @ctrlrun.protect("iam.grant_role", effect="grant:{principal}:{role}") - def grant_role(principal: str, role: str) -> str: - return kubectl("create", "rolebinding", f"{principal}-{role}", "--role", role, "--user", principal) - - - with ctrlrun.context(agent="deploy-agent"): - print("restart:", restart(cluster="prod-eu", deployment="checkout")) - print("grant reader:", grant_role(principal="ana@example.com", role="reader")) - - try: - delete_namespace(cluster="prod-eu", name="checkout") - except ctrlrun.ApprovalRequired as pending: - print("delete namespace: a human decides:", pending.request_id) - else: - sys.exit("a namespace delete ran without a human") - - try: - restart(cluster="prod-eu", deployment="checkout") - except ctrlrun.DuplicateEffect as refused: - print("restart again:", type(refused).__name__) - else: - sys.exit("the same restart ran twice") - - try: - grant_role(principal="ana@example.com", role="admin") - except ctrlrun.ApprovalRequired: - print("grant admin: a human decides") - - print("kubectl calls:", len(calls)) - ``` - - Run it with `python infra.py`: - - ```text - restart: ok - grant reader: ok - delete namespace: a human decides: apr_… - restart again: DuplicateEffect - grant admin: a human decides - kubectl calls: 2 - ``` - - Two calls reached the stand-in: the restart and the reader grant. The delete and the admin - grant are waiting for a person, and the second restart was refused because - `restart:prod-eu:checkout` had already committed. - </Step> - - <Step title="Read what happened"> - ```bash runnable - ctrlrun receipts - ctrlrun effects - ``` - - Every call that reaches a decision has a receipt, denied ones included, and every effect - key has a state. A call waiting on a human has an approval request and no receipt yet. The - pending approvals are what `ctrlrun approve <request id>` answers; the - [quickstart](/docs/get-started/quickstart) walks through presenting one. - </Step> -</Steps> - -## The decorator's arguments - -| Argument | What it does | -|---|---| -| `name` | the action name the policy decides | -| `effect=` | a template over the parameters naming the consequence; without it the call gets no reservation, which is right for a read | -| `resource=` | a template for the resource, part of the hash and what a grant's `resources:` matches | -| `wait=True` | block on the approval provider instead of raising `ApprovalRequired`; what an adapter or a webhook provider needs | -| `lease=` | how long the reservation is held for a slow call; past it the effect is `AMBIGUOUS`, never released | -| `reconcile=` | a function that asks the remote what happened to an effect key; [Reconcile automatically](/docs/guides/reconcile-automatically) | -| `control=` | a `Control` you built, instead of the one discovered from `ctrlrun.yaml` | - -Template syntax is checked at decoration time, so a typo fails at import rather than mid-run. -A protected function may not take `*args` or `**kwargs`, and may not name a parameter after a -reserved subject. - -## If it didn't work - -- `ActionDenied: ... no principal is available`: the call is outside `ctrlrun.context(...)`. -- `ActionDenied: ... unknown_action`: the decorator's name is not a key under `actions:`. -- `EffectKeyError: ... {cluster}`: the template names a parameter the function does not have, - or the argument was `None`. -- `PolicyError: ... could not be read`: no `ctrlrun.yaml` in the working directory and - `$CTRLRUN_CONFIG` is unset. - -## Next - -- [Put the gateway in front of MCP](/docs/guides/gateway-in-front-of-mcp): the same guarantees with no code change. -- [Effect keys](/docs/concepts/effect-keys) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/reconcile-automatically.mdx b/docs/docs/guides/reconcile-automatically.mdx deleted file mode 100644 index df645a0..0000000 --- a/docs/docs/guides/reconcile-automatically.mdx +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: "Reconcile automatically" -description: "Give @protect a reconcile hook that asks the remote what happened to an effect key." ---- - -A `reconcile` hook is a function that takes an effect key, asks the remote what happened, and -answers `"committed"`, `"not_executed"` or `"unknown"`. It is the only thing besides a human -permitted to move a record out of `AMBIGUOUS`, and it moves the record only in the direction its -answer points: `"unknown"` leaves it where it was. - -**Prerequisites:** `pip install ctrlrun`, an empty directory. The remote is a stand-in with a -lookup the hook can call. - -<Steps> - <Step title="Write the hook beside the executor"> - The hook receives the effect key and nothing else. Parse what you need out of it; the key - was built from the arguments, so it carries the identifiers the remote indexes by. - - ```yaml runnable - schema: ctrlrun.policy/v2 - - actions: - stripe.refund: - effect: "refund:{payment_id}" - decision: allow - ``` - - ```python runnable - import ctrlrun - - ledger: dict[str, dict] = {} # what the remote holds - calls: list[str] = [] - - - def refund_at_stripe(payment_id: str, amount: int) -> dict: - calls.append(payment_id) - ledger[payment_id] = {"id": f"re_{payment_id}", "amount": amount} - raise TimeoutError("no response from api.stripe.com after 30s") - - - def ask_stripe(effect_key: str) -> ctrlrun.ReconcileOutcome: - payment_id = effect_key.removeprefix("refund:") - return "committed" if payment_id in ledger else "not_executed" - - - @ctrlrun.protect( - "stripe.refund", - effect="refund:{payment_id}", - reconcile=ask_stripe, - reconcile_eagerly=True, - ) - def refund(payment_id: str, amount: int) -> dict: - return refund_at_stripe(payment_id, amount) - - - with ctrlrun.context(agent="refund-agent"): - try: - refund(payment_id="txn_9", amount=50000) - except TimeoutError: - print("the reply was lost; the hook asked the remote") - try: - refund(payment_id="txn_9", amount=50000) - except ctrlrun.DuplicateEffect: - print("retry refused as a duplicate: the remote had it") - else: - raise SystemExit("the retry ran; the refund happened twice") - - print("remote refund calls:", len(calls)) - ``` - - ```text - the reply was lost; the hook asked the remote - retry refused as a duplicate: the remote had it - remote refund calls: 1 - ``` - </Step> - - <Step title="Choose when it runs"> - With `reconcile_eagerly=True` the hook runs as soon as the call produces an `AMBIGUOUS` - outcome. Without it, the hook runs when a later attempt is blocked by the ambiguous record, - which is the cheaper default when reconciliation costs a network call and most ambiguous - effects are never retried. - </Step> - - <Step title="Read the evidence"> - ```bash runnable - ctrlrun receipts - ``` - - The reconciliation is two events, `RECONCILIATION_STARTED` and `RECONCILIATION_RESOLVED`, - with the hook's answer. A hook that raises is recorded and the record stays `AMBIGUOUS`; it - is never read as an answer. - </Step> -</Steps> - -## The three answers - -| The hook returns | The record becomes | A retry is then | -|---|---|---| -| `"committed"` | `COMMITTED` | refused as a duplicate | -| `"not_executed"` | `FAILED` | permitted | -| `"unknown"` | `AMBIGUOUS`, unchanged | refused until a human resolves it | - -Answer `"not_executed"` only when the remote told you it has no record of the effect, and the -remote is authoritative for that. A hook that answers it from a cache, or from a lookup that -can lag, has the same failure as an executor raising `NotExecuted` too early: it licenses a -second execution. - -## If it didn't work - -- The record stayed `AMBIGUOUS` after an eager reconcile: the hook returned `"unknown"` or - raised. Both are recorded in the events. -- `InvalidArgument: reconcile must be callable`: `reconcile=` was given something other than a - function of one argument. - -## Next - -- [Resolve an AMBIGUOUS effect](/docs/guides/resolve-an-ambiguous-effect): the human path. -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/resolve-an-ambiguous-effect.mdx b/docs/docs/guides/resolve-an-ambiguous-effect.mdx deleted file mode 100644 index cf5ba7b..0000000 --- a/docs/docs/guides/resolve-an-ambiguous-effect.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: "Resolve an AMBIGUOUS effect" -description: "Find the effects nobody knows the outcome of with ctrlrun effects, ask the remote what happened, say so with ctrlrun resolve --committed or --failed." ---- - -An `AMBIGUOUS` effect is one whose executor raised something other than `NotExecuted`, timed -out, or never returned. CTRLRun will not guess, so a person asks the remote and records the -answer with `ctrlrun resolve`. This guide makes one, finds it, resolves it both ways, and shows -what the evidence says afterwards. - -**Prerequisites:** `pip install ctrlrun`, an empty directory. The remote is a stand-in that -commits and then loses the reply. - -<Steps> - <Step title="Make an ambiguous effect"> - ```yaml runnable - schema: ctrlrun.policy/v2 - - actions: - stripe.refund: - effect: "refund:{payment_id}" - decision: allow - dns.update_record: - effect: "dns:{zone}:{name}" - decision: allow - ``` - - ```python runnable - import ctrlrun - - - @ctrlrun.protect("stripe.refund", effect="refund:{payment_id}") - def refund(payment_id: str, amount: int) -> dict: - raise TimeoutError("no response from api.stripe.com after 30s") # after the money moved - - - @ctrlrun.protect("dns.update_record", effect="dns:{zone}:{name}") - def update_record(zone: str, name: str, value: str) -> dict: - raise ConnectionResetError("connection reset by peer") - - - with ctrlrun.context(agent="ops-agent"): - for call in ( - lambda: refund(payment_id="txn_7", amount=50000), - lambda: update_record(zone="example.com", name="api", value="203.0.113.7"), - ): - try: - call() - except (TimeoutError, ConnectionResetError) as lost: - print("the executor saw:", lost) - ``` - </Step> - - <Step title="Find it"> - ```bash runnable - ctrlrun effects --state ambiguous - ``` - - ```text - refund:txn_7 ambiguous … - dns:example.com:api ambiguous … - ``` - - A retry of either is refused with `AmbiguousEffect` until the record moves. A worker that - died mid-call ends here too, when its lease lapses; nothing sweeps and nothing releases. - </Step> - - <Step title="Ask the remote, then say what happened"> - Look in the Stripe dashboard, or query the DNS zone. Then record the answer. Exactly one of - the two flags, and only for an effect that is `AMBIGUOUS`: - - ```bash runnable - ctrlrun resolve refund:txn_7 --committed - ctrlrun resolve dns:example.com:api --failed - ctrlrun effects - ``` - - `--committed` means the remote did it: a retry is now refused as a duplicate. - `--failed` means it provably did not: a retry is now permitted. Neither undoes anything. - </Step> - - <Step title="Read who resolved it"> - The resolution is an `EFFECT_RESOLVED` event carrying `resolved_by`, and - `ctrlrun inspect <action_id>` shows it in the action's history: - - ```bash runnable - ctrlrun inspect "$(ctrlrun receipts --last 2 --json | head -1 | python -c 'import json,sys; print(json.loads(sys.stdin.readline())["action_id"])')" - ``` - - A retry after a resolution is a new action with its own receipt; it is never attributed to - the resolver. - </Step> -</Steps> - -## When to reach for a hook instead - -If the remote can be asked programmatically, a `reconcile` hook asks it for you and moves the -record the same way, with the same rule that it moves only in the direction the answer points: -[Reconcile automatically](/docs/guides/reconcile-automatically). - -## If it didn't work - -- `resolve` exits 1 with `is not ambiguous`: the effect already has a known outcome. A committed - effect cannot be moved back to failed, or the other way. -- `resolve` exits 1 with `nobody reserved`: the key is misspelled, or the effect belongs to - another store; check `--store-url` or `$CTRLRUN_STATE`. -- `exactly one of --committed and --failed`: pass one flag. - -## Next - -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): why there is a third outcome. -- [Reconcile automatically](/docs/guides/reconcile-automatically). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/run-on-postgres.mdx b/docs/docs/guides/run-on-postgres.mdx deleted file mode 100644 index f5a01eb..0000000 --- a/docs/docs/guides/run-on-postgres.mdx +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: "Run on Postgres" -description: "Move the store from SQLite to Postgres when more than one host must share it: pip install ctrlrun[postgres], a connection URL, a schema." ---- - -Use Postgres when workers on more than one host must share one store, because `BEGIN -IMMEDIATE` is a write lock on a local file and does not reach across hosts. The store is the -same protocol, graded by the same suite as SQLite; what changes is a URL. - -**Prerequisites:** a Postgres 14 or later server, a database, a role for CTRLRun, and -`pip install "ctrlrun[postgres]"`. - -<Steps> - <Step title="Install and connect"> - ```bash - pip install "ctrlrun[postgres]" - ``` - - ```python - from ctrlrun import Control, Policy - from ctrlrun.postgres import PostgresStateStore - - store = PostgresStateStore("postgresql://ctrlrun@db.internal:5432/ctrlrun", schema="ctrlrun") - control = Control(Policy.from_file("ctrlrun.yaml"), store) - ``` - - The URL goes to `psycopg.connect` unchanged, so `?sslmode=require`, `?connect_timeout=5`, a - `service=` name and the `PG*` environment variables all work. Put the password in - `~/.pgpass` or `PGPASSWORD`, not in the URL. On the command line the schema travels as - CTRLRun's own query parameter: - - ```bash - export CTRLRUN_STORE_URL='postgresql://db.internal/ctrlrun?ctrlrun_schema=ctrlrun' - ctrlrun effects --state ambiguous - ``` - </Step> - - <Step title="Create the schema and grant the role"> - The store does not create the schema, so a typo cannot become a second, empty, - authoritative-looking store. Create it once, and give the role what it needs: - - ```sql - CREATE SCHEMA ctrlrun AUTHORIZATION ctrlrun; - GRANT USAGE, CREATE ON SCHEMA ctrlrun TO ctrlrun; - ``` - - `CREATE` on the schema is what migrations need, and it is not optional: the store migrates - at open, so **a role without it cannot run the CLI at all** — `ctrlrun receipts - --verify-chain` is refused before a receipt is read, naming the missing privilege. A - read-only role with `USAGE` and `SELECT` is for your own queries against the tables. The - database's encoding must be UTF-8; a lossy encoding is refused at open, because a receipt - that cannot store the argument it records is not a receipt. - </Step> - - <Step title="Let the first writer migrate"> - The schema is versioned. A writer opens the store, reads `schema_version`, and applies any - migration forward, once, under a lock, so concurrent starts do not race. There is no flag - that opens a database un-migrated. A binary older than the schema refuses immediately with - `SchemaMismatch`, before reading any other table, so upgrade every reader before any writer. - - A read command (`receipts`, `effects`, `inspect`, `stats`, `approve`, `deny`, `resolve`) - migrates nothing: it opens only a database already at head, and names the missing migration - otherwise. - </Step> - - <Step title="Understand the one new ambiguity"> - A connection lost during `COMMIT` is the case worth naming: Postgres very often did commit, - and the client cannot know. The store treats it as unknown and re-reads the row to find - out which, and only if the re-read itself fails does it refuse to proceed. `FAILED` is - reserved for an abort the server stated. Nothing here changes what `AMBIGUOUS` means for - the remote your executor called; that path is unchanged. - </Step> -</Steps> - -## Verify against it - -`ctrlrun verify --store-url postgresql://…` runs the guarantee catalogue against a scratch -schema it creates and drops, never against yours. - -The store conformance suite grades your database with the same cases SQLite passes. It is not a -command — it is a function, because it takes a live backend: - -```python -from ctrlrun.conformance.store import run -from ctrlrun.conformance.store.backends import PostgresBackend - -report = run(PostgresBackend("postgresql://…")) -print(report.to_text()) -raise SystemExit(0 if report.ok else 1) -``` - -## Throughput - -Every reservation queues on one row per effect key and receipts append behind one chain head, -so the store serializes writes the way a ledger does. That is the design: a hundred agents -refunding a hundred different payments proceed in parallel; a hundred agents refunding the same -payment are one winner and ninety-nine refusals. - -## If it didn't work - -- `schema "ctrlrun" does not exist`: create it; the store will not. -- `SchemaMismatch: the database is at version N and this binary understands M`: upgrade the - binary, or downgrade nothing; there is no backward migration. -- `encoding ... is not UTF8`: create the database with `ENCODING 'UTF8'`. -- `permission denied for schema`: the role lacks `CREATE` on the first open. - -## Next - -- [Effect keys](/docs/concepts/effect-keys): what the unique index protects. -- [The operator's Postgres page](/docs/postgres): grants, failover and what the store does not do for you, in full. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/guides/verify-in-ci.mdx b/docs/docs/guides/verify-in-ci.mdx deleted file mode 100644 index 79ac64e..0000000 --- a/docs/docs/guides/verify-in-ci.mdx +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: "Verify in CI" -description: "Run ctrlrun verify against your policy on every push with the CTRLRun GitHub Action, read the two shapes of report, understand the N/A line." ---- - -`ctrlrun verify` runs the kernel's own failure scenarios against your policy, in a scratch -store, with fake executors and no network, and reports what passed, what failed, and what it -could not check. In CI that is one step, and the badge it writes means one thing: the declared -guarantees pass. - -**Prerequisites:** a repository with a `ctrlrun.yaml`, and GitHub Actions. - -<Steps> - <Step title="Run it locally first"> - ```yaml runnable - schema: ctrlrun.policy/v2 - - actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - decision: approve - k8s.delete_namespace: - effect: "namespace:{cluster}:{name}" - decision: approve - ``` - - ```bash runnable - ctrlrun verify - ``` - - ```text - CTRLRun verify — ctrlrun 0.6.1, catalogue ctrlrun.guarantees/v2 - policy /home/you/agent/ctrlrun.yaml (ctrlrun.policy/v2, mode: enforce) - authority none - store sqlite, scratch (created and destroyed for this run) - - G1 mutated approval refused PASS k8s.delete_namespace - G2 replayed approval refused PASS k8s.delete_namespace - G3 duplicate effect refused PASS k8s.delete_namespace - G4 one winner under concurrency PASS k8s.delete_namespace (8 processes) - G5 ambiguous blocks a blind retry PASS k8s.delete_namespace - G6 unknown action refused PASS - G7 no principal refused PASS k8s.delete_namespace - G8 expired authority refused N/A no authority section - G9 delegation cannot escalate N/A no authority section - G10 unknown exception is ambiguous PASS k8s.delete_namespace - G11 an altered receipt is detected PASS k8s.delete_namespace - - 9/9 declared guarantees pass. 2 not applicable: G8, G9. - ``` - - Two things about that output. The first line is on **stderr**, from G7's own scenario: it - drives an action with no principal and the refusal logs, which is the guarantee passing and - not a problem. And every row names `k8s.delete_namespace` rather than the refund — verify - exercises one action per guarantee and takes the **first that fits, in alphabetical order**, - so which of your actions appears is not a judgement about it. - - Two guarantees are not applicable: this policy has no `authority:` section, so nothing - about grants can be exercised. They are reported with the reason, excluded from the - denominator and listed separately. Never `11/11`, and no flag folds them in. - </Step> - - <Step title="Add the action"> - ```yaml - name: CTRLRun verify - - on: [push, pull_request] - - jobs: - verify: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: CTRLRun/ctrlrun@v0.6.1 - with: - policy: ctrlrun.yaml - ``` - - The action installs `ctrlrun`, runs `ctrlrun verify --json --junit`, renders the job summary - and the badge JSON from that one report, and uploads the three as an artifact. It fails the - job when a guarantee failed or the configuration was refused, and succeeds when guarantees - are N/A: green means nothing that could be checked was wrong. - </Step> - - <Step title="Read the outputs"> - | Input | Default | | - |---|---|---| - | `policy` | `ctrlrun.yaml` | the document to verify | - | `authority` | the policy's own section | a standalone authority document | - | `only` | all | comma-separated guarantee ids; a partial run writes no badge | - | `install` | `ctrlrun` | the pip requirement; `.` verifies with the checkout | - | `badge-path` | `verify-badge.json` | where the Shields endpoint JSON goes | - - Outputs: `passed`, `failed`, `applicable`, `not-applicable`, `badge-message`, `report-path`. - The ref pins the action's steps and **not** the package they install: `install` is - unpinned by default, so `@v0.6.1` still takes whatever PyPI serves on the day. Pin both — - `install: ctrlrun==0.6.1` — where the run has to be reproducible, and pin the action by - commit rather than by tag where the ref has to be immovable. - </Step> - - <Step title="Publish the badge, if you want it"> - The action writes the badge JSON and never publishes it, because publishing needs - `contents: write` and asking every user for that is a bad trade for a tool about least - privilege. Publish it yourself from a job that runs only on pushes to your default branch, - with `contents: write` on that job alone, and point Shields' endpoint badge at the raw file. - [Get the badge](/docs/verify/get-the-badge) has the copy-paste workflow. - </Step> -</Steps> - -## What verify cannot see - -Your executors, your `reconcile` hooks, where you put the decorator, your deployment, and -whether your policy is the right policy. An executor that raises `NotExecuted` after the remote -acted is invisible to it. The badge does not mean secure, safe, compliant, certified or audited. - -## If it didn't work - -- Exit 2, `mode: observe`: verify refuses an observed configuration, because observe mode - executes what enforce mode would refuse and nothing can be proved about it. -- Exit 2, *nothing was checked and nothing is claimed*: **no** guarantee was applicable, so - `0/0` — which is never a pass. In practice that means an `actions:` map with nothing in it. A - policy with one `allow` action and no `approve` rule, no `effect:` template and no grants is - not this case: it exits 0 with `4/4` and seven not applicable, because the fail-closed and - unknown-outcome guarantees still have something to exercise. -- Exit 1: a guarantee failed. The report names the scenario and the action; that is a bug - report, not a configuration problem. - -## Next - -- [Exit codes](/docs/reference/exit-codes). -- [What the badge means](/docs/verify): the guarantee catalogue in full. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/how-this-is-built.md b/docs/docs/how-this-is-built.md deleted file mode 100644 index 494367b..0000000 --- a/docs/docs/how-this-is-built.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: "How this is built" -description: "Specification first, every requirement mutation-tested, independent review, every claim mapped to a test, and what has not been done yet." ---- - -CTRLRun is built specification-first, every requirement in it is mutation-tested, anything -that touches authorization is reviewed by a session that did not write it, and every sentence -in the README maps to a test. That discipline is the reason to trust the code, and it is also -what makes it safe that AI coding agents write most of it. This page says both, plainly, with -the numbers that are written down and a pointer to where each one is. - -## Specification first - -Each version starts as a document: `SPEC-v0.1.md` through `SPEC-v0.6.md` under `docs/`, each a -delta over the ones before it and each still binding in full. A spec names its acceptance -tests, freezes its public names, and lists what is out of scope. The tests are written from the -acceptance section before the implementation exists, so the suite is red first and the -implementation's job is to make it green. - -A new entry point, table, column, event or error is a specification amendment before it is -code. That rule has a date on it. `Control.delegate` once let an expired credential mint -permanent, re-delegable authority, not because the expiry check was wrong but because the -spec listed it against one method and nothing enumerated the others. `SPEC-v0.3.md` §4.3.1 now -lists every entry point by name, and every one since has added its row first. - -## Every requirement is mutation-tested - -Before an item is called done, each MUST in its spec sections is removed, the test named for it -is confirmed red, and the guard is restored. The table goes in the pull request. A row that -stays green is not a passing check; it is a check nothing exercises, and the four shapes that -produce one are listed in `CONTRIBUTING.md` so every table is read against them. - -The numbers that are recorded: - -| Version | What the discipline found | Where it is written | -|---|---|---| -| v0.2 | The mutation tables found roughly thirty-five gaps, almost all of one of four shapes: subsumed guards, orphaned handlers, negative tests against behaviour the library refuses anyway, and windows not actually reproduced | `CONTRIBUTING.md`, "The four shapes of a false green" | -| v0.3 | A self-review of the specification found four defects; an independent review of the same two sections found two authorization holes the author had missed, both visible only from a file the spec did not mention | `CHANGELOG.md`, 0.3.0 | -| v0.5 | An independent review of the adapter contract found five defects that would each have produced an insecure or unimplementable adapter. Three further reviews and a third adapter written against the contract alone found five authorization defects in one reference adapter before it shipped, all of the same shape | `CHANGELOG.md`, 0.5.0; `docs/docs/adapters.md`, the fourteen questions | -| v0.6 | An independent review of the store work found twenty-one defects, four of them blockers, three of which were invisible from the diff and visible only from the shipped code | `CHANGELOG.md`, 0.6.0 | - -The suite today is 1,704 test functions, 3,944 cases with parametrisation, run on two Python -versions, against SQLite and Postgres, with the adapter suites run against real installations -of both frameworks and asserted not to have skipped. - -## Independent review - -Anything touching authorization, identity, delegation, the gateway, an adapter or the store is -reviewed before its pull request opens, by a session that did not write it, reading the -specification and every file that calls into the changed code rather than the diff. That is -where the defects in the table above were found. When a review declines a finding, the -reasoning goes in the document, and a guard that turns out to be attribution rather than -prevention is renamed everywhere it was called a defence. - -## Every claim maps to a test - -`docs/docs/CLAIMS.md` maps every sentence in the README to the code that implements it and the -test that proves it. A sentence with no row is cut; a row whose test disappears takes its -sentence with it. A test resolves every line number in the table against the line it cites and -fails if the named symbol is not there. It found nine stale references the first time it ran, -after the table had been maintained by hand for three releases, which is the argument for the -test. - -`ctrlrun verify` applies the same standard to your configuration: a guarantee it cannot -exercise is reported not applicable, with the reason, and never counted as a pass. - -## What is not done yet - -There has been no external security audit and no third-party review of the kernel. Every -review so far was run inside this project, by sessions that did not write the code under -review but that follow the same specifications and the same rules. An external audit is on the -roadmap for v0.8 to v0.9. Until it happens, the evidence for the guarantees is the suite, the -mutation tables, the review records in the changelog, and `ctrlrun verify` against your own -configuration. Read `docs/docs/THREAT_MODEL.md` for what the guarantees do not cover. - -## AI coding agents, and the constraints that make that safe - -AI coding agents write most of the code, the tests and the documentation in this repository. -That is stated here once, beside the discipline above, because a reader who discovers it alone -trusts less and a reader who is told trusts more, and because the discipline is what makes it -safe: - -- The specification comes first, written and read by a person, and the tests are written from - it before any implementation. -- Every MUST is mutation-tested, and the table is read against the four shapes of a false green - before it is believed. -- Anything touching authorization is reviewed by a separate session that did not write it, and - the findings are recorded in the changelog with what was done about each. -- Every default fails closed. There is no flag that makes a consequential action permissive, - in the kernel, in verify or in an adapter. -- A person tags and publishes every release, reads every measurement before it is published, - and merges nothing under `src/` on green CI alone. - -The tooling is a detail of the process. The verification is the story. - -## Provenance - -Releases are published to PyPI through trusted publishing from GitHub Actions: there is no API -token anywhere, and each distribution carries a PyPI provenance attestation from the workflow -that built it. The workflows pin every action to a commit, the OpenSSF Scorecard workflow -publishes a third party's reading of the repository's practices, and `release.yml` attaches the -same distributions to a GitHub Release with the tag's changelog entry. - -## Next - -- [`docs/docs/THREAT_MODEL.md`](/docs/THREAT_MODEL): what the guarantees do not cover. -- [`docs/docs/verify.md`](/docs/verify): running the guarantees against your own configuration. -- [`CONTRIBUTING.md`](https://github.com/CTRLRun/ctrlrun/blob/main/CONTRIBUTING.md): the rules, in the form a contributor follows them. diff --git a/docs/docs/mcp/approve-from-your-assistant.mdx b/docs/docs/mcp/approve-from-your-assistant.mdx deleted file mode 100644 index 8f73d04..0000000 --- a/docs/docs/mcp/approve-from-your-assistant.mdx +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: "Approve from your assistant" -description: "Run ctrlrun mcp-operator and answer a pending approval from an MCP client, with the answer recorded under your name." ---- - -`ctrlrun mcp-operator` exposes the operator's own commands as MCP tools. The person who has to -answer an approval asks their assistant what is waiting, reads the action and its arguments, and -answers — with no checkout, no shell and no store path. The answer goes through the same two -store calls `ctrlrun approve` and `ctrlrun deny` make, so there is one approval record and one -place its state changes. - -```text -approver's assistant ──▶ ctrlrun mcp-operator ──▶ the approval record the agent is waiting on -``` - -**Prerequisites:** `pip install "ctrlrun[gateway]"`, and a directory holding the `ctrlrun.yaml` -and the store your agents already use. It speaks MCP revision `2026-07-28` and accepts -`2025-11-25`, `2025-06-18` and `2025-03-26`. - -## Start it - -```bash -ctrlrun mcp-operator --principal-header x-approver --user-header x-approver-user -``` - -It binds `127.0.0.1:8901` and there is **no flag that changes that**. Its read tools answer -without a credential, so it must not be the process that opens a port to a network; put a proxy -in front of it on the same host, terminating authentication there and overwriting both headers -on every request. That proxy is what makes the headers worth anything. - -There is no `--principal` either. A fixed name would attribute every approval to the same -string whoever gave it, and an approver that distinguishes nobody is not attribution. With -`--identity-jwt` the approver comes from a verified bearer token instead, and -`--identity-jwt-user-claim` says which claim names the person. - -## Point a client at it - -```json -{ - "mcpServers": { - "ctrlrun-operator": { - "url": "http://127.0.0.1:8901/mcp", - "headers": { "x-approver": "approver-console", "x-approver-user": "dana" } - } - } -} -``` - -In a real deployment the client sends a bearer token and the proxy sets those two headers from -whoever it authenticated. Headers a client sets for itself are a demonstration, not a control. - -## A transcript - -Asking what is waiting needs no credential: - -```json ---> {"method": "tools/call", "params": {"name": "list_pending_approvals", "arguments": {}}} -<-- {"pending": [{ - "request_id": "apr_27a80d93bab5178f0b1b12ced9621bf6", - "action": "stripe.refund", - "action_hash": "sha256:0397f9a2a696c7d877f726525ff6d5f84a2bcd5fe6148e0c4f9f07851fddfa3b", - "arguments": {"amount": 248000, "payment_id": "pi_3QxNq"}, - "resource": "payment:pi_3QxNq", - "principal": {"agent": "refund-agent", "user": "customer-ops"}, - "expires_at": "2026-09-06T18:10:20.950Z", - "expires_in_seconds": 899 - }]} -``` - -Answering does. Without one: - -```json ---> {"method": "tools/call", "params": {"name": "approve", "arguments": {"request_id": "apr_27a8…"}}} -<-- {"error": {"code": -41007, "message": "no principal could be derived from the request", - "data": {"error": "ctrlrun.no_principal"}}} -``` - -With one: - -```json -<-- {"status": "granted", - "request_id": "apr_27a80d93bab5178f0b1b12ced9621bf6", - "action_hash": "sha256:0397f9a2a696c7d877f726525ff6d5f84a2bcd5fe6148e0c4f9f07851fddfa3b", - "approver": "mcp-operator:dana", - "expires_at": "2026-09-06T18:10:20.950Z"} -``` - -The agent then runs the refund it was waiting on, and the receipt says who let it: - -```json -{"action": "stripe.refund", "decision": "approve", "result": "committed", - "approval_id": "apr_27a80d93bab5178f0b1b12ced9621bf6", "approver": "mcp-operator:dana", - "effect_key": "refund:pi_3QxNq", "attempt": 1} -``` - -## What it will not do - -- **Make an agent act.** No tool proposes, executes or resumes an action, and there is no - auto-approve, dry-run or development mode. -- **Approve an action other than the one the request names.** The grant carries the - `action_hash` stored when the request was created; change an argument and the call is refused. -- **Take an answer from a machine.** A credential naming an agent and no person is `-41013`. -- **Take an expired credential.** `-41014`, distinct from `-41007`, because refreshing a token - and obtaining one are different fixes. -- **Decide whether you were allowed to answer.** It authenticates *who* answered and records it. - Any human whose credential the provider verifies can answer any pending request, exactly as - any human who can run `ctrlrun approve` can. That is attribution, not authorization. - -## If it did not work - -- Exits at start naming `--user-header` or `--identity-jwt-user-claim`: a write tool refuses a - credential that names no person, so a configuration that could never write is refused early. -- Exits at start naming loopback: there is no `--allow-remote`; put a proxy in front instead. -- `-41003` with reason `expired`: the request timed out. The agent proposes it again. -- `-32020`: a mirrored MCP header disagrees with the body. The body is believed and the request - is refused rather than guessed at. - -## Next - -- [CTRLRun and MCP](/docs/mcp/overview) · [The gateway in five minutes](/docs/mcp/gateway-in-5-minutes). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/mcp/gateway-in-5-minutes.mdx b/docs/docs/mcp/gateway-in-5-minutes.mdx deleted file mode 100644 index 2e960a4..0000000 --- a/docs/docs/mcp/gateway-in-5-minutes.mdx +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: "The gateway in five minutes" -description: "You already run an MCP server. Two commands put CTRLRun between the agent and it." ---- - -You already run an MCP server and an agent that calls it. Put `ctrlrun gateway` between them -and every `tools/call` is decided by a policy, bound to an approval where the policy says so, -reserved by effect key, relayed and recorded. The agent's configuration changes one URL. The -server does not change at all. - -```text -before agent ──▶ http://localhost:8000/mcp -after agent ──▶ http://127.0.0.1:8900/mcp (CTRLRun) ──▶ http://localhost:8000/mcp -``` - -**Prerequisites:** `pip install "ctrlrun[gateway]"`; the server reachable over HTTP; a -directory for `ctrlrun.yaml` and the store. The gateway speaks MCP revision `2026-07-28` and -accepts `2025-11-25`, `2025-06-18` and `2025-03-26`. - -<Steps> - <Step title="Name the tools"> - Every tool you want decided gets an entry `mcp.<alias>.<tool>`. A write gets an `effect:` - template over the tool's own parameter names; a tool not listed is denied. - - ```yaml runnable - schema: ctrlrun.policy/v2 - - actions: - mcp.ops.get_deployment: - decision: allow - mcp.ops.restart_deployment: - effect: "restart:{cluster}:{name}" - decision: allow - mcp.ops.delete_namespace: - effect: "namespace:{cluster}:{name}" - decision: approve - mcp.ops.grant_role: - effect: "grant:{principal}:{role}" - rules: - - when: { role_in: [reader, viewer] } - decision: allow - - decision: approve - ``` - </Step> - - <Step title="Start it, and repoint the agent"> - ```bash - ctrlrun gateway --upstream http://localhost:8000/mcp --alias ops --principal deploy-agent - ``` - - ```text - CTRLRun gateway → http://localhost:8000/mcp as mcp.ops.* - listening on http://127.0.0.1:8900/mcp environment: production - identity: fixed principal deploy-agent authority: none - 1 action(s) have no effect: template and get no reservation: - mcp.ops.get_deployment - That is right for a read, and wrong for anything that changes the world. - ``` - - Point the agent's MCP client at `http://127.0.0.1:8900/mcp`. That is the change. - </Step> - - <Step title="What the agent sees"> - A refusal is a JSON-RPC error with a code the client can read, never a tool result with - `isError`, because a tool result reaches the model as text and invites the retry the - refusal exists to prevent. - - ```json - {"jsonrpc": "2.0", "id": 12, - "error": {"code": -41001, "message": "mcp.ops.delete_namespace: denied (policy)", - "data": {"error": "ctrlrun.denied"}}} - ``` - - ```json - {"jsonrpc": "2.0", "id": 13, - "error": {"code": -41002, "message": "mcp.ops.delete_namespace: a human must approve", - "data": {"error": "ctrlrun.approval_required", "request_id": "apr_…"}}} - ``` - - A human runs `ctrlrun approve apr_…`, or answers in Slack through the webhook, and the - agent's next identical call runs. A different call, a different namespace, a different - cluster, does not: the approval is bound to the hash of what the human saw. - - | Code | Token | HTTP | Meaning | - |---|---|---|---| - | `-41001` | `ctrlrun.denied` | 403 | the policy denies this action for everyone | - | `-41002` | `ctrlrun.approval_required` | 403 | a human must approve; `data.request_id` | - | `-41003` | `ctrlrun.approval_denied` | 403 | a human said no | - | `-41004` | `ctrlrun.duplicate_effect` | 409 | this effect already committed | - | `-41005` | `ctrlrun.ambiguous_effect` | 409 | this effect's outcome is unknown; a human resolves it | - | `-41007` | `ctrlrun.no_principal` | 403 | no principal for this request | - | `-41010` | `ctrlrun.upstream_ambiguous` | 502 | the reply was lost after the first byte | - | `-41012` | `ctrlrun.unauthorized` | 403 | this principal holds no grant | - - A relayed result carries `_meta["com.ctrlrun/receipt"]` with the receipt id. - </Step> - - <Step title="Choose the principal, and read the note"> - | Flag | Principal comes from | Worth | - |---|---|---| - | `--principal NAME` | a fixed name | one agent behind one gateway: exact | - | `--principal-header X-Agent` | a header a proxy sets | exactly what the proxy is worth: if the agent can set the header, the agent chooses its own authority | - | `--identity-jwt …` | a verified bearer token; algorithms, issuer, audience and token type all required | the issuer's word, verified | - - The gateway never reads a principal off the request body, and `--principal-from-client-info` - was removed by name: a client's own claim about who it is was a way for the agent to pick - its authority. A `tools/call` with no principal is refused with `-41007`. - </Step> -</Steps> - -## What you get, in your terms - -- No code changes. -- Any language. -- Approvals bound to the exact tool call. -- Every call that **reaches a decision** leaves a receipt, denied ones included. A call still waiting on a human has not been decided yet and has none until it is. -- Measure first: `mode: observe` at the top of the same file. - -## If it didn't work - -- `-32020`, header mismatch: the MCP header and the body disagree; the gateway routes on the - body and refuses rather than guessing. -- `unsupported protocol version`: the client declared a revision outside the accepted set. -- The gateway exits 2 at start: a non-loopback `--listen` without `--allow-remote`, or a policy - that does not load. - -## Next - -- [Put the gateway in front of MCP](/docs/guides/gateway-in-front-of-mcp): the longer guide, with the lost-reply case. -- [CTRLRun and MCP](/docs/mcp/overview) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/mcp/overview.mdx b/docs/docs/mcp/overview.mdx deleted file mode 100644 index b8116aa..0000000 --- a/docs/docs/mcp/overview.mdx +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: "CTRLRun and MCP" -sidebarTitle: "Overview" -description: "Four ways: the gateway enforces policy in front of any MCP server, and the operator server lets an approver answer from their assistant." ---- - -CTRLRun works with MCP in four ways. The gateway sits in front of any MCP server and applies -your policy to every `tools/call`, with no change to the agent or the server. The operator -server lets the person who has to answer an approval answer it from the assistant they are -already talking to. This documentation is itself an MCP server your coding tool can search. And -the gateway is listed where MCP servers are discovered. - -## Enforcement: the gateway - -`ctrlrun gateway` is a process between the agent and the tool server. Every `tools/call` -becomes an action named `mcp.<alias>.<tool>`, decided by the same `ctrlrun.yaml` the decorator -uses, bound to a human's approval where the policy says so, reserved by effect key so the same -consequence runs once across retries and workers, relayed, and recorded. Everything else on the -wire is relayed untouched. - -```text -before agent ──▶ MCP server -after agent ──▶ CTRLRun gateway ──▶ MCP server -``` - -- No code changes: the agent and the server are untouched. -- Works in any language: the gateway fronts an HTTP endpoint. -- Approvals bound to the exact tool call, arguments included. -- Every call that **reaches a decision** leaves a receipt, denied ones included. A call still waiting on a human has not been decided yet and has none until it is. -- Measure first with observe mode, in the same policy file. - -[The gateway in five minutes](/docs/mcp/gateway-in-5-minutes) is the page for someone who already -runs an MCP server. - -## Learning: this site is an MCP server - -Every page here is reachable through an MCP server hosted with the site, with one tool, a -search across the documentation. Add it to Cursor, VS Code or any MCP client and the assistant -answers from these pages rather than from memory. -[Use the docs from your editor](/docs/mcp/use-the-docs-from-your-editor) has the configuration. - -## Discovery: the registries - -The gateway is what you run to put CTRLRun in front of an MCP server, and it is listed in the -MCP registries as such once the listing is live. Until then this section carries no link rather -than a placeholder; the registry entry is a launch-day item. - -## Answering: the operator server - -`ctrlrun mcp-operator` is an MCP server that exposes the operator's own commands as tools. An -approver asks their assistant what is waiting, reads the action and its arguments, and answers — -without a checkout, a shell or a store path. - -```text -approver's assistant ──▶ ctrlrun mcp-operator ──▶ the same approval record - the CLI and the webhook answer -``` - -- Read tools — `list_pending_approvals`, `inspect_action`, `receipts`, `effects`, `stats`. -- Write tools — `approve`, `deny`, `resolve`. Each needs a credential that names a **human**, - from the identity provider you configured; never a name the client asserts. -- Every answer is recorded under that person's name, and the name reaches the receipt the - action leaves. -- It is not a second approval path: `approve` and `deny` are the two store calls - `ctrlrun approve` and `ctrlrun deny` make, against the same record, with the same hash - binding, single use and expiry. -- Nothing here can make an agent act. There is no tool that proposes or executes an action, and - no auto-approve. -- It binds loopback and has no flag that changes that, because its read tools answer without a - credential. - -[Approve from your assistant](/docs/mcp/approve-from-your-assistant) is the page with the -configuration and a transcript. - -## What MCP does not change - -The guarantees are the same three ways in. A refund refused by the gateway is refused for the -same reason, recorded in the same receipt shape, and verified by the same `ctrlrun verify` as -one refused by the decorator. An agent that calls a CTRLRun tool to check its own actions would -not be enforcement, because a tool the agent chooses to call is a tool it can choose not to; the -gateway is in the path whether the agent likes it or not. - -## Next - -- [The gateway in five minutes](/docs/mcp/gateway-in-5-minutes) · [Approve from your assistant](/docs/mcp/approve-from-your-assistant). -- [Three ways in](/docs/get-started/three-ways-in) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/mcp/use-the-docs-from-your-editor.mdx b/docs/docs/mcp/use-the-docs-from-your-editor.mdx deleted file mode 100644 index 4ddd01c..0000000 --- a/docs/docs/mcp/use-the-docs-from-your-editor.mdx +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "Use the docs from your editor" -description: "This documentation is an MCP server. One configuration block adds it to Cursor, VS Code or any MCP client, so the assistant answers from these pages." ---- - -This documentation is an MCP server, hosted with the site by Mintlify at the site's `/mcp` -path, exposing one tool: a search across every page here. Add it to your coding tool and the -assistant answers from the current pages rather than from whatever it remembers. - -## The configuration - -For Cursor, in `mcp.json`: - -```json -{ - "mcpServers": { - "ctrlrun-docs": { "url": "https://ctrlrun.dev/mcp" } - } -} -``` - -For VS Code and other clients that take a `servers` block: - -```json -{ - "servers": { - "ctrlrun-docs": { "type": "http", "url": "https://ctrlrun.dev/mcp" } - } -} -``` - -Both shapes are the ones Mintlify's documentation gives for a hosted docs server (read -2026-09-06). The path is always `/mcp` on whatever host serves this site. - -## Three questions it can now answer - -- *What happens in CTRLRun when a tool call times out?* The assistant finds - [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous) and answers that a timeout is - `AMBIGUOUS`, not `FAILED`, and that a retry is refused until a human or a reconcile hook - resolves it. -- *How do I put an approval in front of one MCP tool but not another?* It finds the - [policy reference](/docs/reference/policy-yaml) and the - [gateway page](/docs/mcp/gateway-in-5-minutes): one entry per tool, `approve` on one, `allow` on - the other. -- *Does the receipt chain prove who wrote a receipt?* It finds - [Receipts and evidence](/docs/concepts/receipts-and-evidence) and answers no: the chain detects - alteration and is not a signature. - -## What it is not - -It is not enforcement. An assistant that can search this documentation can tell you what the -gateway does; it cannot stand in the agent's path. An agent that called a CTRLRun tool to check -its own actions could also choose not to, which is why the gateway is a process between the -agent and its tools and not a tool the agent picks. - -## Next - -- [CTRLRun and MCP](/docs/mcp/overview). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/not-only-agents.mdx b/docs/docs/not-only-agents.mdx deleted file mode 100644 index 827763b..0000000 --- a/docs/docs/not-only-agents.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: "Not only agents" -sidebarTitle: "Not only agents" -description: "The double-execution failure is older than agents: a task queue that retries, a webhook delivered twice, a merge job that lost its reply." ---- - -Every page on this site says *agent*, and the failure underneath them does not require one. A -retry that repeats a write whose outcome nobody knows is a bug in ordinary software, and it was -a bug in ordinary software for twenty years before anything called itself an agent. If you run -a task queue, a webhook handler or a cron job that moves money, sends mail or deletes records, -this is your problem too, and CTRLRun does not ask whether a model was involved. - -Three examples in the repository have no model, no prompt and no framework in them. - -## A task queue that retries - -A billing worker charges an invoice. The processor commits the charge and the reply is lost, so -the task raises — and the queue does exactly what it is configured to do. Celery's `max_retries`, -RQ, Sidekiq, `tenacity`, a Temporal activity, a Lambda whose failed invocation is re-delivered: -each of them re-runs the task when it raises, and none of them can tell *nothing happened* from -*I do not know what happened*. The customer is charged twice by a system working as designed. - -```bash -python examples/without-an-agent/retried-task/main.py -``` - -CTRLRun records the outcome as `AMBIGUOUS` rather than failed, and the second and third attempts -are refused before they reach the processor. -[`retried-task/main.py`](https://github.com/CTRLRun/ctrlrun/blob/main/examples/without-an-agent/retried-task/main.py). - -## A webhook delivered twice - -At-least-once delivery is a promise about the minimum. Stripe, GitHub, Shopify, Slack and every -queue behind them will re-deliver an event whose acknowledgement they did not see, and the -handler runs a second time with the same payload. An `Idempotency-Key` the handler generates -does not help: the second delivery is a different process, and it generates the key again. - -What is needed is a name for the consequence that both deliveries compute identically — an -[effect key](/docs/concepts/effect-keys) — and one atomic reservation of it. - -```bash -python examples/without-an-agent/redelivered-webhook/main.py -``` - -[`redelivered-webhook/main.py`](https://github.com/CTRLRun/ctrlrun/blob/main/examples/without-an-agent/redelivered-webhook/main.py). - -## A merge job that lost its reply - -A merge queue merges a pull request. GitHub merges it, the connection drops before the response, -and the job concludes the merge failed. It retries, and then it reaches for another way to the -same end: force-push the branch. The retry is refused because the effect may already have -committed. The force push is refused because the policy does not list it, and an action a policy -does not list is denied rather than allowed. - -```bash -python examples/without-an-agent/lost-merge/main.py -``` - -[`lost-merge/main.py`](https://github.com/CTRLRun/ctrlrun/blob/main/examples/without-an-agent/lost-merge/main.py). - -## What an agent actually changes - -Two things, and neither is the retry. An agent chooses the arguments, so an approval that is not -bound to the exact arguments a person saw approves something nobody read — which is why -[approval binding](/docs/concepts/approval-binding) exists. And an agent that fails at one route will -try another, which is the second half of the merge example: the defence that matters there is -not a better retry, it is a policy that is a list of what is permitted. - -Everything else on this page is the same code path either way. - -## What you need when there is no agent - -Less than the rest of the site suggests. No identity provider, no authority document, no -approvals: a worker is not a principal anyone delegates to. What you need is `@protect` on the -function that acts, an effect key that names the consequence, and a policy listing the actions -that may run. Two of the six guarantees do the work — one effect executes once, and an unknown -outcome is never a failure — and the other four are there when you want them. - -## Next - -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): why a timeout is not a failure. -- [Effect keys](/docs/concepts/effect-keys) · [Compare: idempotency keys](/docs/compare/idempotency-keys). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/postgres.md b/docs/docs/postgres.md deleted file mode 100644 index af2223c..0000000 --- a/docs/docs/postgres.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -title: "Running on Postgres" -description: "Connection strings, what to grant, migrations at open, what happens on failover, and what the store does not do for you." ---- - -`PostgresStateStore` puts the state store on a database instead of a local file. It implements -the same `StateStore` protocol as `SQLiteStateStore`, frozen in `SPEC-v0.1.md` §5.3, and extends -it by nothing. The guarantees are the ones `SPEC-v0.1.md` §7 already states; what changes is the -mechanism that earns them, because `BEGIN IMMEDIATE` is a write lock on a local file and there is -no file any more. - -This page is for whoever runs the database. It says what to grant, what happens when the -connection or the server goes away, and — the part that is easy to skip and expensive to assume — -what the store does **not** do for you. - -## Install - -```bash -pip install 'ctrlrun[postgres]' -``` - -`psycopg` version 3. `import ctrlrun` imports no `psycopg` module, and neither does anything in -the core; the driver is loaded when a `PostgresStateStore` is first constructed, and its absence -raises `MissingDependency` naming this install line. - -## Connect - -```python -from ctrlrun.postgres import PostgresStateStore - -store = PostgresStateStore("postgresql://ctrlrun@db.internal:5432/ctrlrun") -``` - -The URL is passed to `psycopg.connect` unchanged, so everything libpq accepts works: a -`postgres://` scheme, `?sslmode=require`, `?connect_timeout=5`, a `service=` name, or the -standard `PG*` environment variables with an otherwise-bare URL. CTRLRun parses none of it. - -A second schema is a keyword: - -```python -store = PostgresStateStore(url, schema="ctrlrun") -``` - -**Every statement names its schema**, so nothing in the store depends on `search_path` being set -for it, and two stores against two schemas in one database do not see each other. The schema must -be a plain identifier — letters, digits and underscores — which is what makes it safe to -interpolate; it is the only name in the module that reaches SQL, and it never comes from an -action, an argument or a request header. - -On the command line the schema travels in the URL, as CTRLRun's own query parameter, peeled off -before anything reaches the driver: - -```bash -ctrlrun effects --store-url 'postgresql://db.internal/ctrlrun?ctrlrun_schema=ctrlrun' -``` - -`ctrlrun_schema` defaults to `public`. It is the same spelling the store conformance suite uses, -so an operator who has seen one does not have to learn the other. - -**The store does not create the schema.** `PostgresStateStore.create_schema(url, name)` exists and -is used by the conformance backend and by `ctrlrun verify`'s scratch store, but constructing a -store against a schema that is not there is refused, naming the schema. Creating databases for -operators is not this library's job and doing it silently is how a typo becomes a second, empty, -authoritative-looking store. - -### Passwords - -Put the password in `~/.pgpass`, in `PGPASSWORD`, or in a secret your process manager injects — -not in a URL you commit or pass on a command line. A URL in a config file is a URL in a backup, -and `--store-url` also reads `CTRLRUN_STORE_URL`, which is the better place for it. - -## What to grant - -The database user needs, on the schema the store lives in: - -```sql -CREATE SCHEMA ctrlrun; -GRANT USAGE, CREATE ON SCHEMA ctrlrun TO ctrlrun_app; -``` - -`CREATE` is not optional and it is not only a first-run convenience. Migrations run **at open**, -automatically, and there is no flag that opens a database without migrating it (`SPEC-v0.6.md` -§3.6): a store that could run un-migrated would be a second configuration nobody tested. A user -without `CREATE` is refused at construction with the exact `GRANT` it is missing, rather than at -the first write with the SQL that failed. - -If your policy is that application users hold no DDL rights, the supported shape is to run one -start with a migrating role during the deployment and let the application role connect afterwards -— but understand what you have bought: the next upgrade fails closed at open, on every host, until -somebody runs the migrating role again. That is louder than a partial migration, which is the -direction this project chooses; it is still an outage if nobody expected it. - -Nothing else is needed. The store creates no extension, no function, no trigger, no role, and -touches no other schema. - -### The database's encoding - -**The store refuses a database whose `server_encoding` is not `UTF8`**, at open, naming it. - -This looks fussy and is not. CTRLRun hashes the exact code points it is given and applies no -Unicode normalization (`SPEC-v0.1.md` §2.3). An effect key that survives a round trip through -`SQL_ASCII` as different bytes is a **different identity**, so two attempts at one logical effect -would reserve two different keys and both would execute. That is a double execution reached -through the storage layer's character set — the exact failure the library exists to prevent, -arriving somewhere nobody looks. It is refused at open rather than discovered in an incident. - -For the same reason `effect_key`, `approval_id`, `action_id`, `delegation_id` and `continuation` -are declared `COLLATE "C"`: byte comparison, no locale. A non-deterministic collation would merge -two distinct keys into one, which is the safe direction — but the store should not depend on which -direction a deployment's `lc_collate` happens to fail in. - -## Connections and pooling - -- **One connection per thread.** `psycopg` connections are not thread-safe and the store does not - share one. `close()` releases every connection the store opened; it is a release of resources, - not a fence, and a caller that uses the store afterwards gets a fresh connection. -- **No pool ships.** Sizing a pool is a deployment decision and a library that guessed would be - wrong on most of them. -- **pgbouncer in `transaction` mode works**, and it works because the store deliberately holds - nothing session-scoped: no advisory lock, no temporary table, no prepared statement it needs to - survive, no `SET` it depends on. Reads run outside a transaction; writes re-assert their schema - with `SET LOCAL`, which reverts at the end of the transaction and cannot leak into a pooled - connection's next tenant. `session` mode also works and buys nothing here. -- **A host running agents on an unbounded number of threads will open an unbounded number of - connections.** Bound your worker pool, or put pgbouncer in front. The store does not bound it - for you, and `max_connections` is where you will find out. - -## What happens when things go away - -This is the section worth reading twice, because it is where a plausible-looking implementation -would be wrong and the wrongness would only show up in an incident. - -### The rule - -**`FAILED` means it definitely did not happen.** Anything else unknown is `AMBIGUOUS`. A -connection that dies during `COMMIT` tells you nothing about whether Postgres committed, and -Postgres very often did — so that is `AMBIGUOUS`, never `FAILED`, and an agent that read it as -`FAILED` and retried is the failure mode this library exists to prevent. - -### A store write whose outcome is unknown is re-read - -There are two kinds of ambiguity and they have different remedies, which is why `SPEC-v0.6.md` §4 -carries two tables rather than one. - -A Postgres transaction is atomic, so an ambiguous **store write** has exactly one truth and the -store can go and look at it. On a lost `COMMIT` the store re-reads the row: - -- it matches, **in every column the store was about to write**, the row we attempted → the - commit landed, and we hold the reservation. Not a match on `action_id`: that names an attempt - and is caller-supplyable, so a match on it alone is satisfied by another process's live - reservation, and that is a double execution; -- the row is absent → the commit did not land, and the insert is re-issued, once; -- anything else → it goes back through `plan_reservation` and the store obeys what that says. - -**Only if the re-read itself fails** does the store refuse to let execution proceed, writing no -effect state at all. Fail closed: the remote is not called, so there is nothing to be ambiguous -about. - -An ambiguous **remote effect** has no such move. Nothing you can read settles whether the refund -landed, which is why `AMBIGUOUS` is a terminal state there and why a blind retry against that key -is refused until a human or a reconciliation hook answers. - -Which branch ran is logged on the `ctrlrun.postgres` logger at `WARNING`, with a `branch` -attribute drawn from a closed set — `a1.row1.ours`, `a1.row2.reinsert`, `a1.row3.refuse`, -`a2.row1.landed`, `a2.row2.reissue`, `a2.row3.refuse`. Those are the values in the log; the -Python constants that carry them are spelled differently, so grep for the value. - -### Failover - -On a managed failover, a promotion, or a `pg_ctl restart`, in-flight connections break. What -follows depends on where each one was: - -- **Before `COMMIT` was issued** — nothing committed. The store write is `FAILED` and may be - retried, which is the one place `FAILED` is correct: the server stated, in band, that it never - got there. -- **During or after `COMMIT`** — the re-read above, against a new connection. If the new primary - is up, it answers and the ambiguity is resolved. If it is not up yet, the re-read fails and the - store refuses to proceed and writes nothing. -- **A broken connection is replaced only between transactions**, and for the re-read. The store - never silently reconnects mid-transaction; a reconnect is a new transaction, and pretending - otherwise is how a partial write becomes invisible. - -**Point the store at whatever your deployment uses to name the current primary** — a virtual IP, -a proxy, a `target_session_attrs=read-write` multi-host URL. The store does not discover a new -primary, does not retry a connection in a loop, and does not fail over between URLs. It reports -what it saw and fails closed. - -**Do not point it at a read replica.** Every guarantee here rests on a unique index on -`effect_key` and on compare-and-set updates whose row counts are checked, and a replica can do -neither. Reads would appear to work, which is the problem. - -### Losing the primary, honestly - -An asynchronous replica that is promoted after losing transactions loses effect records with -them, and CTRLRun cannot tell that this happened — a key that was reserved and executed comes -back absent, and the next attempt reserves it again and executes again. If you need the store's -guarantee to survive a failover, you need the *database's* durability to survive it: synchronous -commit to at least one standby. This is a property of your Postgres configuration and not -something a client library can add. - -## Concurrent starts, and restarts - -**Concurrent starts are safe and are not clever.** The migration transaction takes the backend's -own write lock, so a second process either finds the work done or waits for it. There is no -advisory lock, no leader election and no retry loop. - -**A restart does nothing on its own.** Opening a store migrates it and reads nothing else. A -process that came back does not scan, does not repair and does not report; it waits to be asked -about an effect key, exactly as it did before it died. - -**Nothing sweeps.** There is no background thread, no timer and no reaper. An expired lease -becomes `AMBIGUOUS` lazily, when the next contender plans a reservation against that key. An -expired lease nobody contends stays `EXECUTING` in the table, and `ctrlrun effects` shows it as -`executing (lease expired)` so that the display does not hide it. `get_effect` and `list_effects` -are reads and transition nothing. - -## Throughput, and the one row everything queues on - -Every receipt write serializes on a single row. - -`SPEC-v0.6.md` §6.3's chain advances a one-row head table, and `put_receipt` takes that row's lock -**first** and holds it across the receipt insert. That is deliberate — a compare-and-set with a -bounded retry silently dropped receipts under three concurrent writers, and a dropped receipt is -evidence loss — but it is a real ceiling and this is the first place in the kernel where two -unrelated actions contend with each other at all. - -What that means in practice: - -- Receipt writes are serialized per database. Effect reservations are not; they contend only per - effect key, which is the whole point of the key. -- The lock is held for one `INSERT`, so the ceiling is set by your round-trip time to the - database. Putting the store on another continent is the way to find it. -- Two schemas in one database have two head rows and do not contend. Sharding by schema works and - gives you two chains to verify rather than one. - -The soak in `research/soak/` is not a measurement of this. It publishes a duration and an action -count, on one host with four threads against a database on the same machine, and it names no -throughput figure on purpose — [what it does not establish](/docs/production/soak) says why. Size this -against your own hardware. - -## Verifying the chain - -```bash -ctrlrun receipts --store-url 'postgresql://db.internal/ctrlrun?ctrlrun_schema=ctrlrun' --verify-chain -``` - -Every break is reported by `seq` and by name — `content_altered`, `hash_missing`, `link_broken`, -`missing`, `head_mismatch`, `unchained` — rather than as one boolean, because *"receipt -41 was edited"* and *"the last nine were deleted"* are different incidents. - -`ctrlrun receipts --control <id>` filters the same listing down to the receipts citing one -control, which is how you get from a written expectation to the actions taken under it. It is a -filter and not a lookup: an id no receipt cites returns nothing rather than an error. - -`--store-url` is on every command that reads or resolves the operator's own store — `receipts`, -`effects`, `inspect`, `resolve`, `approve`, `deny` — and it reads `CTRLRUN_STORE_URL`. **It opens -the database you name and creates nothing**: a schema that is empty, or behind, or ahead is -refused with an instruction rather than migrated. A command an operator runs to read evidence must -not have a side effect on the database it reads. - -`ctrlrun verify --store-url postgresql://…` is different and is worth understanding before you run -it against production: it creates a `ctrlrun_verify_<hex>` schema of its own for each guarantee, -works inside it, and drops it when the run ends, including when the run ends by exception. It does -not migrate, read or write your schema. It needs `CREATE` on the database to do that and refuses, -naming the reason, when it cannot. - -## What the store does not do for you - -Stated plainly, because each of these is something an operator could reasonably assume and none of -them is true: - -- **It does not back anything up.** The receipts and effect records are your data in your - database, and they are exactly as durable as your backup policy. -- **It does not rehash a receipt written by an older build.** The chain hashes the whole receipt - document, so a release that *adds* a receipt field reports every receipt written before it as - `content_altered`. Migrations are forward-only and there is no rehash. An operator meeting this - accepts the break window — `--verify-chain` names the `seq` range, so it is legible — or - truncates. Receipts written before the chain existed at all report `unchained`, which is a - different and documented case. -- **It does not prune, roll or retain.** `effects`, `events`, `receipts`, `approvals`, - `delegations` and `continuations` grow without bound. Deciding what may be deleted is a - retention policy and this library does not have one; note that deleting receipts from the middle - or the end of the chain is detected as a break by design, so a retention job needs to be written - with that in mind, and `ctrlrun receipts --verify-chain` will report the boundary as a break - because it cannot know the deletion was deliberate. -- **It does not create the schema, the database, the user or the grants.** -- **It does not pool, discover a primary, retry a failed connection, or fail over.** -- **It does not sweep expired leases**, and nothing runs in the background at all. -- **It does not prove who wrote a receipt.** The chain in `SPEC-v0.6.md` §6 detects **alteration** - — an edited row, a deletion from the middle, a reordering — and that is all it detects. - Receipts are not signed, alteration is not authorship, and the chain is not tamper-proof - against an administrator with write access to every row including the chain head. - `docs/docs/THREAT_MODEL.md` states what remains open. -- **It does not make a read replica safe to use.** See above. -- **It is not a queue, a scheduler or a workflow engine.** It records decisions and outcomes for - actions somebody else is executing. - -## Running the store's own tests against your database - -The store conformance suite is this repository's acceptance tests, runnable against any -`StateStore` — including one pointed at a database configured the way yours is: - -```python -from ctrlrun.conformance.store import run -from ctrlrun.conformance.store.backends import PostgresBackend - -report = run(PostgresBackend("postgresql://…")) -print(report.to_text()) -raise SystemExit(0 if report.ok else 1) -``` - -The suite is core and stdlib — no extra beyond `ctrlrun[postgres]` itself — and it takes a private -schema per case, which it drops. Two of its cases contend from eight OS processes, so point it at -a database you are willing to have hammered briefly. - -Running it against a staging database that shares your production's encoding, collation, pooling -and Postgres version is the cheapest way to find out that one of them is not what you thought. diff --git a/docs/docs/production/how-reservation-works.mdx b/docs/docs/production/how-reservation-works.mdx deleted file mode 100644 index 07fdc98..0000000 --- a/docs/docs/production/how-reservation-works.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: "How reservation works" -description: "One effect key, one winner. And the two rows nobody merges: an exception before COMMIT, and an exception during it." ---- - -Before your executor runs, the store reserves the effect key, and exactly one attempt wins. On -SQLite that is `BEGIN IMMEDIATE`; on Postgres it is `INSERT … ON CONFLICT (effect_key) DO -NOTHING` with the row count checked, under the default isolation level. Every later transition is -a conditional `UPDATE` that matches on the state it expects, with the row count checked again. The -guarantee is the unique index, not the isolation level. - -## The two rows that must never be merged - -This is the part that decides whether a lost database connection costs you a refund or a -duplicate one. - -| The store saw | The write is | What happens | -|---|---|---| -| **Before `COMMIT`** — a connect failure, a statement error, a constraint violation, a statement timeout | **failed** — nothing committed | roll back, raise, and you may retry the write immediately | -| A serialization failure or a deadlock, at any point | **failed** — the server said so, in band | as above | -| **During or after `COMMIT`** — the connection lost mid-`COMMIT`, a timeout on `COMMIT`, the socket closing before the command tag arrives | **unknown** | **re-read the record on a fresh connection** and let the answer decide | -| The re-read itself fails | **unresolvable** | refuse; write no effect state; raise | - -**Before `COMMIT`: nothing committed, retry the write. During `COMMIT`: unknown, so re-read.** -Two rows, two behaviours, two tests. Reading the first as the second refuses work a single query -could have recovered. Reading the second as the first retries a write that already landed. - -A serialization failure sits in the first row on purpose: the server is telling you in band that -it rolled the transaction back, which is the closest a database gets to your executor raising -`NotExecuted`. A cancelled statement is **not** in that set, because a statement timeout during a -`COMMIT` is exactly the unknown case. - -## What the re-read looks for - -It is an identity check on the whole row, never a match on the action id. Two attempts *can* -share an id: it names an attempt rather than a process, and it is caller-supplyable — a caller -that rebuilds an action with the id it saved has handed the store two attempts wearing one name. -So *"a record carrying our id"* is satisfied by **another process's live reservation**, and -concluding you hold the key there is a double execution. - -- Finds the row you were about to write, column for column: the commit landed, proceed. -- Finds nothing: it did not land, retry the insert once. -- Finds anything else: hand it back to the same planner every reservation uses, and obey it. - -On a later transition the record always exists, so the interesting finding is different: an -**unchanged** record means the commit did not land, and the store re-issues the same conditional -`UPDATE` once. Refusing there would turn a committed effect into a human's problem, and a proven -failure into an unknown one. - -## What this does not do - -- **It does not tell you what the remote did.** Reservation is about the store. An executor that - raised something other than `NotExecuted` leaves an `AMBIGUOUS` effect that no query settles. -- **It does not reclaim a key.** A lease that lapsed becomes `AMBIGUOUS` when the next contender - arrives. [Nothing sweeps](/docs/production/recovery). -- **A failed re-read costs availability.** The key stays reserved by an attempt that will never - run, its lease lapses, and a person answers. That is the trade: it never costs a second - execution. -- **It does not hold a row lock across your executor.** Advisory locks, `SERIALIZABLE` and - `SELECT … FOR UPDATE` were each rejected, and the reasons are in the specification. - -**Verified by** `T155` — the connection is killed during `COMMIT` on purpose rather than raced -for — `T155b` for a landed commit seen as landed and `T155e` for the update the store re-issues -when it was not, `T155c` for the identity check that is not a match on the action id, `T156` for -the failed re-read that writes nothing, and `T157` -and `T158` for one winner under contention and a `kill -9` mid-transaction. `G4` in `ctrlrun -verify` contends real OS processes on your store's backend, in a scratch store of its own. - -**What those two actually ran, because the file says so and this page should too.** `T157` and -`T158` are **separate OS processes against one Postgres**, with the connection broken by a proxy -the tests own. They are **not two machines**. Separate processes give separate connections, no -shared memory and no shared file locks — which is what `BEGIN IMMEDIATE` was silently relying on -and what a second host removes — so the reservation guarantee is exercised. A **network partition -between two hosts** is not, and this project claims it nowhere. - -## Next - -- [Recovery after a crash](/docs/production/recovery): what a restarted process may conclude. -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): the other unknown, the one no query settles. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/production/index.mdx b/docs/docs/production/index.mdx deleted file mode 100644 index 439004b..0000000 --- a/docs/docs/production/index.mdx +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: "Run it in production" -description: "SQLite is the default and is production-grade on one host. Postgres is for many hosts. What survives a crash, and what you do yourself." ---- - -**SQLite is the default and it is production-grade on one host.** A file, no server, no ops, and -the one-effect-once guarantee held by `BEGIN IMMEDIATE` and a unique constraint across processes -rather than merely across threads. **Postgres is for many hosts**, and that is the whole of the -decision: choose by how many machines write to the store, not by how serious you are. - -{/* Keep this the first paragraph. A reader with one host must not be told they are not really -in production: it is false, and it is the reason most of them reach for a database they do not -need. `test_the_first_line_of_the_section_says_which_store_and_why` asserts the order. */} - -## What this section answers - -| If you are asking | Read | -|---|---| -| Which store, and what does each cost me? | [SQLite or Postgres](/docs/production/postgres) | -| What happens when the database write is lost mid-`COMMIT`? | [How reservation works](/docs/production/how-reservation-works) | -| What happens when I deploy a new version over an old database? | [Migrations](/docs/production/migrations) | -| The process died holding a key. Now what? | [Recovery after a crash](/docs/production/recovery) | -| Somebody edited a receipt. Would I know? | [Receipt integrity](/docs/production/receipt-integrity) | -| Has this been run under load? | [The soak](/docs/production/soak) | -| What do I watch, and what do I page on? | [Operations](/docs/production/operations) | - -## Where it stands - -{/* generated from the suite, pyproject and the soak (full) — run the generator */} -- **Version 0.6.1**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later. -- **4,404 tests**, every version specified before it was written and every requirement mutation-tested. [Read more](/docs/how-this-is-built). -- **11 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). -- **Each receipt carries the hash of the one before it**, so an alteration is detected and named. [Read more](/docs/production/receipt-integrity). -- **Apache-2.0**, and the enforcement kernel stays open source. Releases carry PyPI provenance attestations from GitHub Actions. - -**Not yet:** - -- No external security audit. (planned for v0.8 or v0.9) -- No third-party review of the kernel. (every review so far was run inside this project) -- No sector packs. (the policy templates are starting points, not a product) -{/* end generated */} - -## The shape of a deployment - -``` -your process ──► @protect / gateway ──► principal ──► authority ──► policy ──► approval - │ - reservation ◄────────┘ - │ - executor - │ - the store: a file, or Postgres, shared across hosts - effects · continuations · approvals · delegations - receipts · receipt_chain · events · schema_version -``` - -Authority and policy are evaluated independently and authority runs first, so a denial there -never leaves an approval request behind. - -The store is the only shared state, and it holds eight tables: the effect keys in flight and the -continuations holding some of them open, the approvals granted and consumed, the delegations that -say who may act, the receipt chain and its head, the event log, and the schema version. Everything -else is in your process and dies with it. That is why the questions in this section are all -questions about the store. - -## What this does not do - -- **It does not run anything for you.** There is no daemon, no scheduler and no background - thread. Nothing sweeps expired leases, nothing retries on your behalf, and a restarted process - repairs nothing. See [recovery](/docs/production/recovery) for why that is deliberate. -- **It does not make an external system idempotent.** CTRLRun refuses to knowingly act twice. - Whether the remote acted is a fact only the remote holds. -- **It does not roll anything back.** It is not a transaction manager and it never pretends a - remote write is undone. -- **It is not a dashboard.** Receipts are portable JSON; `ctrlrun effects`, `inspect`, `receipts` - and `stats` are the interface, and an OpenTelemetry exporter is the extra. - -**Verified by** `T141` and `T154` — the three shipped stores run the same store conformance -suite, every case a pass or a named not-applicable — and by `ctrlrun verify`, which grades `G1` -through `G11` against **your** policy, on **your** store's backend, in a scratch store it creates -and destroys. It never opens the store you run on. - -## Next - -- [SQLite or Postgres](/docs/production/postgres): the choice, and what each one costs. -- [How reservation works](/docs/production/how-reservation-works): the lost `COMMIT`, in two rows. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/production/migrations.mdx b/docs/docs/production/migrations.mdx deleted file mode 100644 index a14b95a..0000000 --- a/docs/docs/production/migrations.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: "Migrations and schema versions" -description: "Migrations run at open, forward only, and nothing half-applies. Five shapes a database can be in, and three of them are a refusal." ---- - -Deploy a newer CTRLRun over an existing database and it migrates at open, forward only, one -transaction per migration. You run no command and set no flag, because there is no flag: a -database that opened un-migrated would be a database serving reads it half understands. - -## The five shapes, and what each does - -Let *known* be the migration ids your binary ships, and *applied* be what the database records. - -| What the database records | What happens | -|---|---| -| Exactly *known* | opens, nothing applied | -| The first *n* of *known*, in order, with no gap | **the ordinary case**: the rest are applied, in order, at open | -| Known ids, but not a prefix — `0001` and `0003`, not `0002` | **refused**, naming the gap | -| An id the binary does not know — an older binary, a newer database | **refused at open**, naming the unknown id, your version, and the version that wrote it | -| Missing one it knows **and** carrying one it does not | **refused**, naming both sides | - -Those five are the shapes a database that already records a schema version can be in, and they -are exhaustive: the store classifies into exactly one, and anything it cannot place is refused -rather than opened. Three more sit in front of them. An **empty** database is migrated to head. -A database with **CTRLRun's tables and no version record** — anything from before v0.6 — is -adopted, given the record it never had, and migrated; that is the case an upgrade actually meets. -A database with **foreign tables and no effects table** is refused, naming what it found. - -**The fourth row is the direction that gets forgotten and the one that corrupts.** A binary that -reads a table it half understands does not fail. It succeeds, with the columns it knows, silently -dropping the ones it does not — and a receipt row whose chain fields it never wrote is a gap in -the chain nobody caused deliberately. Refusing to start is the cheap failure, and it is -`SchemaMismatch`, raised before a row is read from any other table. - -## Nothing half-applies - -Each migration runs in one transaction, and both engines have transactional DDL, so a migration -that raises part way rolls back to the previous version — including the row that would have -recorded it. That is a claim about database engines, so the test suite ships a deliberately broken -migration whose second statement raises, and proves the store refuses to open, the version is -unchanged, and every row is intact. - -Two rules follow for anyone writing one: a migration does nothing outside its transaction — no -file writes, no network, no concurrent index build — and it reads and writes columns rather than -your Python objects. - -## Rolling out - -``` -old binary + old database → fine -new binary + old database → migrates at open, automatically -old binary + new database → refuses at open, naming both versions -``` - -So a rolling deploy is safe in the forward direction and **stops** in the backward one. Plan a -rollback as a database restore, not as a redeploy of the previous image, and take the backup -before the first new process starts. - -## What this does not do - -- **There is no down migration.** Forward only. Reverting means restoring a backup. -- **There is no flag, keyword or environment variable that opens a database without migrating - it.** A test searches the CLI, the constructor and the environment for one. -- **A migration is not a data repair.** It moves the schema forward and preserves every row; it - does not correct rows that were already wrong. -- **A read command does not migrate a shared store.** `ctrlrun receipts`, `effects` and - `inspect` against a `postgresql://` URL refuse unless the schema is already at head, naming - what to do instead. One operator reading evidence must not apply a migration to a database - every other host is still running against. - -**Verified by** `T147` — a database built by the previous release's **own code**, migrated, and -every row compared by content rather than counted — `T148` for the refusal that names both -versions, `T149` for the broken migration that rolls back, `T150` for re-opening applying nothing, -`T151` and `T152` for the divergent and adoption shapes from four earlier releases, and `T152b` -for the flag that does not exist. - -## Next - -- [SQLite or Postgres](/docs/production/postgres): where the schema lives. -- [Operations](/docs/production/operations): what to check after a deploy. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/production/operations.mdx b/docs/docs/production/operations.mdx deleted file mode 100644 index 32dabae..0000000 --- a/docs/docs/production/operations.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: "Operations" -description: "What to watch once it is running: unknown outcomes, approvals nobody answered, the chain check, and what to back up." ---- - -Watch one number and you will catch almost everything: **how many effects are sitting in an -unknown outcome that nobody has answered.** Each one is a real-world action whose result nobody -knows, and each needs a person or a reconcile hook. Nothing frees them on its own. - -```bash -ctrlrun effects --state ambiguous # the queue that matters -ctrlrun inspect <action-id> # one action's whole history -ctrlrun receipts --verify-chain # after a restore, or any direct write -ctrlrun stats # what the receipts say -``` - -## What to watch, and what to do about it - -| Signal | Where it comes from | What it means | -|---|---|---| -| Effects in an unknown outcome | `ctrlrun effects --state ambiguous` | somebody must say what happened. This is the page-a-human number | -| `executing (lease expired)` | `ctrlrun effects` | a holder went away and nobody has contended the key since. Not yet a problem, and not self-healing | -| An approval granted long ago and never consumed | `ctrlrun inspect <action-id>` | a human answered and the agent never came back. There is no command that lists these: an action still awaiting one has no receipt, and `ctrlrun stats` counts receipts | -| A chain break, by name | `ctrlrun receipts --verify-chain` | see [receipt integrity](/docs/production/receipt-integrity) | -| A `WARNING` on the `ctrlrun.postgres` logger with a `branch` attribute | your logs | a `COMMIT` was lost and the re-read decided what to do. The attribute says which branch ran, including the two that end in a refusal | -| The store raising rather than deciding | your exception handler | the database is unreachable. Work stops; it is never quietly permitted | - -Set the alert on the first row and the last. The middle rows are for the dashboard. - -## Getting it somewhere you can see it - -Every executed action leaves a portable JSON receipt, and receipts are the export. With -`pip install "ctrlrun[otel]"` you get one OpenTelemetry span per action and one span event per -step, and argument values stay out of it unless you ask for them. There is no CTRLRun dashboard -and there will not be one. - -## Routine - -- **Back up the store.** It holds every in-flight effect key, every approval and the receipt - chain. Restoring a database from before an action ran is how a duplicate execution becomes - possible again. -- **Verify the chain after a restore**, and after any maintenance that wrote to the database - directly. -- **Take the backup before the first new process starts** on a deploy, because migrations run at - open and there is [no way back](/docs/production/migrations). -- **Size the lease to your slowest executor**, not to your average one. It defaults to five - minutes and is meant to be raised. A lease shorter than the work it covers turns healthy slow - actions into unknown outcomes. -- **A reporting role still needs `CREATE` on the schema.** Opening the store migrates it, so a - read-only role cannot run `--verify-chain` — it is refused before a receipt is read, naming - the missing privilege. Read-only is for your own queries against the tables, not for the CLI. - -## What this does not do - -- **There is nothing to run.** No agent, no sidecar, no scheduler. Every command above is a - one-shot read of the store. -- **It does not retry for you.** A proven non-execution leaves the key retryable — the next - attempt is admitted rather than refused — and nothing performs that attempt but your code. - Every other outcome refuses one. -- **It does not resolve unknown outcomes for you.** A person or a reconcile hook does, and only - where the hook's answer points. -- **It is not an audit product.** Receipts are evidence you can export; what you do with them is - outside this project. - -**Verified by** `T160` and `T177d` — an expired lease frees nothing, and displaying it changes -nothing — `T161` for the two authorities that can move an unknown outcome and what each is -recorded as, and `T177c` for the CLI surface these commands come from, asserted against the -command list so a new one cannot appear unnoticed. - -## Next - -- [Recovery after a crash](/docs/production/recovery): why nothing sweeps. -- [Reconcile automatically](/docs/guides/reconcile-automatically): the hook that answers without a person. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/production/postgres.mdx b/docs/docs/production/postgres.mdx deleted file mode 100644 index 994a5f5..0000000 --- a/docs/docs/production/postgres.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: "SQLite or Postgres" -description: "Choose by how many machines write to the store. SQLite holds the same guarantees on one host; Postgres holds them across hosts." ---- - -Use SQLite until workers on **more than one host** must share a store. `BEGIN IMMEDIATE` is a -write lock on a local file: it holds one-effect-once across threads and across processes on that -machine, and it does not reach the machine next to it. Postgres does, and nothing else about your -setup changes — the same `StateStore` protocol, and the same suite grading both. - -## The decision, in one table - -| | SQLite | Postgres | -|---|---|---| -| Install | in the standard library | `pip install "ctrlrun[postgres]"` | -| Configure | a file path | a connection URL and a schema you create | -| One effect once | `BEGIN IMMEDIATE`, across processes on this host | `UNIQUE(effect_key)` and checked row counts, which do not depend on a shared file | -| Approval binding, authority, receipts, the chain | identical | identical | -| Graded by | the store conformance suite | **that same suite**, not one written for it | -| Fails when | two hosts share the file over a network filesystem | the database is unreachable, which is a refusal and never a false outcome | -| Costs you | nothing | a server, a role, a schema, and backups | - -**A single host is not a smaller deployment.** One process, four workers and a file is the -configuration most agent deployments actually are, and it holds every guarantee this project -claims. Reach for Postgres when a second host appears, not before. - -## What changes when you move - -One line, and a schema you create yourself: - -```python -from ctrlrun.postgres import PostgresStateStore - -store = PostgresStateStore("postgresql://ctrlrun@db.internal:5432/ctrlrun", schema="ctrlrun") -``` - -You create the schema; the store does not. Its encoding must be UTF-8 and anything else is -refused at open, and migrations run at open, forward only, with no flag that suppresses them. - -[Run on Postgres](/docs/guides/run-on-postgres) is the step-by-step — the two SQL statements, the -grants, where to put the password. [The Postgres reference](/docs/postgres) has connection strings, -pooling, failover and the throughput ceiling, and says why each refusal is where it is. - -## What does not change - -Your policy, your authority document, your decorators, your gateway configuration and every -receipt already written. The move is a store swap, and the suite that grades it was written for -SQLite before Postgres existed — which is the point of running one suite rather than two. - -## What this does not do - -- **Postgres does not buy you a stronger guarantee.** It buys the same guarantee across more - machines. A deployment that did not need the second machine gains nothing and pays for a server. -- **Neither store makes a remote idempotent.** The reservation stops a second *attempt*; what the - remote already did is [a different question](/docs/concepts/outcomes-and-ambiguous). -- **The store never fails open when the database is unreachable.** It raises, and the caller sees - the store's exception rather than an outcome. An unreachable database stops work; it does not - quietly permit it. -- **There is no third backend.** `--store-url` takes a `sqlite://` path or a `postgresql://` - URL and refuses anything else, naming the two it knows. A bare file path is not one of them. -- **Nothing here was run on two machines.** The cross-host tests are separate OS processes - against one Postgres, with the connection broken by a proxy they own — separate connections, - no shared memory, no shared file locks, which is the part `BEGIN IMMEDIATE` was relying on and - a second host removes. A **network partition between hosts** is not exercised by anything in - this repository, and the mechanism's independence from a shared file is an argument, not a - measurement. [How reservation works](/docs/production/how-reservation-works) says the same in the - place it cites the tests. - -**Verified by** `T141` and `T154` — every case of the store conformance suite against SQLite, the -in-memory store and a real Postgres, with every not-applicable carrying its reason and none of -them counted as a pass — plus `T154b` for the URL -refusal, `T154c` for the encoding, and `T154f` for connection discipline and collation. `G3` and -`G4` in `ctrlrun verify` grade duplicate refusal and one-winner-under-concurrency on whichever -backend you configured, in a scratch store verify creates and destroys rather than in yours. - -## Next - -- [How reservation works](/docs/production/how-reservation-works): what happens when a `COMMIT` is lost. -- [Migrations](/docs/production/migrations): what a new binary does to an old database. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/production/receipt-integrity.mdx b/docs/docs/production/receipt-integrity.mdx deleted file mode 100644 index e3a1384..0000000 --- a/docs/docs/production/receipt-integrity.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: "Receipt integrity in practice" -description: "Run ctrlrun receipts --verify-chain, read the six names it can report, and know what each one means about your store and what to do next." ---- - -Each receipt carries the hash of the one before it, so an edit, a deletion from the middle or a -reordering is detected and **named**. Run the check against your own store: - -```bash -ctrlrun receipts --verify-chain -``` - -It reports **every** break by `seq` and by name, plus how many rows predate the chain — *receipt -41 was edited* and *the last nine were deleted* are different incidents and you need both. Put it -in the job that already runs after a restore, and after any maintenance that wrote to the -database directly. - -## The six names - -| Name | What it means | What to do | -|---|---|---| -| `content_altered` | receipt *n* no longer hashes to its stored hash | the row was edited; the stored hash says what it was, the row says what it is now | -| `hash_missing` | receipt *n* has a position and no stored hash | the hash column was cleared; nothing can be compared, and this is a failure rather than a skip | -| `link_broken` | receipt *n*'s link does not match what *n-1* hashes to | a neighbour changed, or two rows were reordered | -| `missing` | a gap in `seq` | a receipt was deleted from the middle | -| `head_mismatch` | the stored head does not match the last receipt | the end of the log was truncated | -| `unchained` | `seq` is empty — written before the chain existed | migrate-era rows; counted and reported, never counted as a pass | - -`hash_missing` exists because of one statement. An `UPDATE` with no `WHERE` clearing the hash -column destroyed every independent copy of every hash, and an earlier reader **skipped** the -comparison it could no longer make and called the chain intact. A check that cannot be evaluated -is not a check that passed. - -`unchained` is never a pass either. Rows from before the chain have no position, so they are read -separately and reported with their count, and the summary says how many of how many were -verified. Folding them into a green count would be the same false green in a new costume. - -**So a database migrated from before v0.6 makes this command exit non-zero, permanently.** That -is the honest answer and not a bug: those receipts were written before there was anything to -verify them against, and nothing can make them verifiable after the fact. Before you put the -command in a scheduled job, run it once and read the unchained count, so you are choosing what to -do about those rows rather than discovering them at three in the morning. - -## When a receipt cannot be written - -If the receipt insert itself fails, the exception reaches you and nothing swallows it. The effect -record is already committed, so a retry of that key is refused as a duplicate rather than executed -twice; the head is unadvanced and there is no gap in `seq`. You get an action that ran, an -exception you must handle, and a log with no hole in it. - -## What this does not do - -- **It does not tell you who wrote a receipt.** Alteration is not authorship, it does not survive - an administrator who can rewrite every row including the head, and it vouches for nothing that - was never recorded. [The receipt chain](/docs/security/receipt-chain) is where those limits are - argued and [the threat model](/docs/THREAT_MODEL) says what stays open; this page is what to run and - what to do with the answer. -- **It does not tell you a break was malicious.** A restore from backup, a hand-run `UPDATE` and - a retention job all produce the same names. The report says what changed, not why. -- **`ctrlrun verify` does not read your store.** `G11` runs against a scratch store verify itself - created, because a verification tool with a side effect on the thing it verifies is refused. - `--verify-chain` is the one that reads yours. - -**Verified by** `T164` — six tamper cases, each asserted on the **name** and the `seq` and not -merely on "invalid", the reordering case included — `T165` for the positive control without which -every one of those rows would pass against a detector that always says broken, `T167` for -truncation caught by the head and only by the head, `T168` for the unchained rows that are never -a pass, and `T170` for the failed receipt write that raises and leaves no gap. `G11` in `ctrlrun -verify` runs the same detection against a scratch store, with the unaltered chain as its -control. - -## Next - -- [The receipt chain](/docs/security/receipt-chain): what it proves, and what it does not. -- [Operations](/docs/production/operations): where this check belongs in a schedule. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/production/recovery.mdx b/docs/docs/production/recovery.mdx deleted file mode 100644 index 0e3e172..0000000 --- a/docs/docs/production/recovery.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Recovery after a crash" -description: "A restarted process repairs nothing and cannot know the holder is dead. An expired lease is a refusal, not a reclaim." ---- - -When a process dies holding an effect key, nothing happens. No sweeper frees it, no timer fires, -and the process that comes back does not scan or repair — it waits to be asked for an effect key, -exactly as it did before it died. That is deliberate, and this page is why. - -## What a process may conclude - -A process that finds a record reserved or executing may conclude exactly two things: **what state -the record is in**, and **whether its lease is still live**. It may not conclude that the holder -is gone. - -*"The holder is dead"* is not knowable from the store, and no column makes it knowable. The record -carries an action id, which names an **attempt** and not a process. There is deliberately no -holder host and no holder pid, because the first thing anyone writes against those columns is a -reclaimer — *if the holder is not alive, free the key* — and that reclaimer is wrong on the day it -matters, when a container that stopped answering a health check still has an open socket to a -payment API. A field that invites a false inference is worse than no field. - -## What actually happens - -``` -process dies holding refund:txn_9 → record stays EXECUTING, lease ticking - ↓ nobody contends -`ctrlrun effects` shows: executing (lease expired) ← a display, not a transition - ↓ the next attempt on that key arrives -plan refuses it, and the record becomes AMBIGUOUS ← a refusal, not a reclaim - ↓ -a person: ctrlrun resolve refund:txn_9 --committed|--failed → resolved_by cli:local -or a hook: asks the remote, and only where the answer points → resolved_by reconcile:<action> -``` - -An expired lease that is never contended stays executing in the table, and `ctrlrun effects` -prints it as `executing (lease expired)`. Reading is not a transition: listing effects, inspecting -one, or opening the store moves nothing. - -The effect record's `resolved_by` column holds `cli:local` for a person, not their username. -CTRLRun does not authenticate the person at the terminal, so a name there would be a claim about -somebody made from a value that somebody controls. `cli:local` says exactly what is known: -somebody with the operator's terminal. The `EFFECT_RESOLVED` event carries the same string in its -`resolver` field, which is what lets you join the two, and the coarser `human` or `reconcile` in -its own `resolved_by`. - -## A continuation held by a dead process - -An elicitation holds a reservation open across a round trip. The row survives the process, and -with a shared store a **different** process may finish it. One resumption is admitted and no -more, because the token is consumed in the transaction that admits it. If the lease lapsed first, the resumption is refused -and the effect becomes `AMBIGUOUS` by the ordinary path. - -## What this does not do - -- **Nothing sweeps.** No background thread, no timer, no cron, no reap command. The lapse is - noticed lazily, by the next contender, and never by anything running on a schedule. -- **An expired lease frees nothing.** It is a refusal, not a reclaim. The next attempt is refused - and the record is now unknown. -- **A restart repairs nothing and reports nothing.** Opening the store migrates it and reads - nothing else. -- **No receipt records the resolution.** A receipt is written when the action reaches a terminal - state; a resolution happens afterwards, often days later and by somebody who was not the actor. - Mutating the receipt would be an alteration the chain would correctly report. `ctrlrun effects` - and `ctrlrun inspect` are where you find it. - -**Verified by** `T159` — `AMBIGUOUS` survives a restart and still refuses a blind retry, against -every store — `T160` for the expired lease that frees nothing and the reads that transition -nothing, `T161` for the two authorities and what each is recorded as, `T162` for the process -identity that is deliberately absent, `T163` for the continuation held by a dead process, and -`T177d` for the display that is not a transition. `G5` in `ctrlrun verify` grades the blocked -blind retry on your store's backend, in a scratch store of its own. - -## Next - -- [Resolve an AMBIGUOUS effect](/docs/guides/resolve-an-ambiguous-effect): the commands, step by step. -- [Operations](/docs/production/operations): what to watch so you find these before a customer does. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/production/soak.mdx b/docs/docs/production/soak.mdx deleted file mode 100644 index e945f3c..0000000 --- a/docs/docs/production/soak.mdx +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: "The soak, and what it does not establish" -description: "One published run against a real Postgres: how long it lasted, how many actions it attempted, and how many ambiguous outcomes it could not attribute." ---- - -{/* generated by tools/docs_audit/render_soak.py from research/soak/results/ — publish a run, do not edit this page */} - -A soak asks one question, and it is not a performance question: **does an -`AMBIGUOUS` outcome ever appear that the harness did not cause?** Everything in the -run exists to make an unattributed ambiguity visible rather than rare. Here is the -one published run. - -| | | -|---|---| -| Ran for | 20m 0s (2026-09-05 19:05Z → 2026-09-05 19:25Z) | -| Backend | postgres (schema soak_968eae6651) | -| Actions attempted | 889,735 | -| Ended `AMBIGUOUS` | 133,393 | -| Explained by a recorded injection | 133,393 | -| **Unattributed** | **0** | -| Positive control fired | yes | - -The table is [`research/soak/results/2026-09-05-postgres-20m.json`](https://github.com/CTRLRun/ctrlrun/blob/main/research/soak/results/2026-09-05-postgres-20m.json), rendered. - -## What that is evidence of - -Across 889,735 attempts, every `AMBIGUOUS` the store held at the end had -a ledger entry written **before** the failure that produced it. Nothing became -ambiguous that the harness did not make ambiguous. The positive control fired, so -the run was capable of saying otherwise: a short control phase injects an ambiguity -it deliberately does not record, and the classifier has to report it. A run whose -control did not fire is not a result, and the table says which happened. - -**Unexplained is defined before the run starts**, or the question is unfalsifiable. -An `AMBIGUOUS` whose attempt has a recorded injection is explained; one with no -corresponding injection is unattributed. It is keyed on the attempt and never on the -effect key alone, because one key may be attempted more than once and an injection -against the first attempt says nothing about the second. - -**`ROADMAP.md`'s exit criterion is met by this run**: nothing unattributed, and -a positive control that fired, so the run was capable of reporting otherwise. -Those are the two halves and `SPEC-v0.6.md` §8.1 says they are the whole of it. -The criterion asks for no duration — §8.1 records when that stopped being true -and argues it — so what this run's length does **not** establish is the section -below rather than a footnote to a gate. - -`exit_criterion_met` in the results file is those same two halves, written by the -harness. This page **recomputes** them from the counts rather than reading the -field, and a test asserts the two agree: one derivation of a criterion is a claim, -two that match is a check. - -## What it is not evidence of - -**A long run.** This one lasted 20m 0s. Everything a soak finds by -*accumulating* is outside what that can see: a connection pool that degrades over -hours, table growth against the one-row chain head, a lease that only lapses under -load held longer than this, an operator restart in the middle. The duration is on -the table above and in every place this run is quoted, because a criterion that -stopped asking for one is not the same as a run that no longer has one. - -## What this does not do - -- **It is not a load test.** The throughput is a by-product, nothing here is tuned - for it, and no number on this page is a performance claim. -- **It is not a throughput figure you can plan against.** A policy denial writes a - receipt like any other outcome, so nearly every attempt above went through the - one-row chain head — but on one host, with four threads, against a database on - the same machine. [Postgres](/docs/postgres) describes that ceiling; this run does not - size it for your hardware. -- **It does not exercise a partition or a second host.** That is the cross-host - suite, and [how reservation works](/docs/production/how-reservation-works) says which - of those were actually run. -- **It says nothing about the receipt chain's integrity.** - [Receipt integrity](/docs/production/receipt-integrity) is that. - -## Run it yourself - -```bash -python research/soak/run.py --minutes 20 --postgres "$CTRLRUN_STORE_URL" --out soak.json -``` - -Worker threads share one schema, created for the run and dropped after it, and each -attempt is drawn from a fixed injection mix — mostly clean, the rest a timeout, an -unknown exception, a stated non-execution, or a lease short enough to lapse -mid-execution. The mix and the thread count live in the harness rather than here, -because a page that restated them would be a second copy nothing compares against: -[`research/soak/README.md`](https://github.com/CTRLRun/ctrlrun/blob/main/research/soak/README.md) has both. - -**Verified by** the soak harness's own suite: an injected ambiguity is explained, -one with no injection is a finding, an injection against another attempt explains -nothing, and the control cause never explains anything — four tests, and the fourth -is what stops the control from absorbing a real finding. `T160` covers what an -expired lease does and does not free. - -## Next - -- [Run it in production](/docs/production/index): the section this belongs to. -- [Recovery after a crash](/docs/production/recovery): what survives a restart, and what does not. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Action.mdx b/docs/docs/reference/api/Action.mdx deleted file mode 100644 index 250b3b6..0000000 --- a/docs/docs/reference/api/Action.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "Action" -description: "A proposed agent action: what, with which arguments, by whom, on what." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.Action` — class, defined at `src/ctrlrun/action.py:178` - -```python -from ctrlrun import Action -``` - - -```python -class Action - def __init__(name: str, arguments: Mapping[str, Any], principal: Principal, resource: str | None = None, environment: str = 'production', action_id: str = _new_action_id()) -``` - -A proposed agent action: what, with which arguments, by whom, on what. - -Equality and hashing follow the proposal, not the content: two Actions are equal iff -their `action_id` matches (SPEC-v0.1 §2.1). Identical content shares an `action_hash`. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ActionDenied.mdx b/docs/docs/reference/api/ActionDenied.mdx deleted file mode 100644 index b31afb3..0000000 --- a/docs/docs/reference/api/ActionDenied.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "ActionDenied" -description: "The action may not run. `reason` says why, e.g. `unknown_action` (SPEC-v0.1 §3.4)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ActionDenied` — class, defined at `src/ctrlrun/errors.py:29` - -```python -from ctrlrun import ActionDenied -``` - - -```python -class ActionDenied(CTRLRunError) - def __init__(message: str | None = None, *, reason: str, action_id: str | None = None) -``` - -The action may not run. `reason` says why, e.g. `unknown_action` (SPEC-v0.1 §3.4). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/AmbiguousEffect.mdx b/docs/docs/reference/api/AmbiguousEffect.mdx deleted file mode 100644 index 1f83ece..0000000 --- a/docs/docs/reference/api/AmbiguousEffect.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "AmbiguousEffect" -description: "The outcome of this effect is unknown; only a human may resolve it (SPEC-v0.1 §5.4)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.AmbiguousEffect` — class, defined at `src/ctrlrun/errors.py:141` - -```python -from ctrlrun import AmbiguousEffect -``` - - -```python -class AmbiguousEffect(CTRLRunError) - def __init__(message: str | None = None, *, effect_key: str, action_id: str | None = None) -``` - -The outcome of this effect is unknown; only a human may resolve it (SPEC-v0.1 §5.4). - -Raised for a record already in `AMBIGUOUS`, and for one whose lease expired mid-flight: -the worker may have died after the remote committed. A retry is refused either way, -until `ctrlrun resolve` says which it was. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Approval.mdx b/docs/docs/reference/api/Approval.mdx deleted file mode 100644 index c4a5cd0..0000000 --- a/docs/docs/reference/api/Approval.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "Approval" -description: "A human's grant, bound to one `action_hash` (SPEC-v0.1 §4.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.Approval` — class, defined at `src/ctrlrun/approval.py:111` - -```python -from ctrlrun import Approval -``` - - -```python -class Approval - def __init__(approval_id: str, action_hash: str, approver: str, granted_at: datetime, expires_at: datetime) -``` - -A human's grant, bound to one `action_hash` (SPEC-v0.1 §4.1). - -`approval_id == request_id` in v0.1: a request produces at most one approval. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ApprovalAnswer.mdx b/docs/docs/reference/api/ApprovalAnswer.mdx deleted file mode 100644 index e4e5189..0000000 --- a/docs/docs/reference/api/ApprovalAnswer.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "ApprovalAnswer" -description: "A human's answer, and who gave it (SPEC-v0.5 §2.2, §3.4)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ApprovalAnswer` — class, defined at `src/ctrlrun/adapter.py:157` - -```python -from ctrlrun import ApprovalAnswer -``` - - -```python -class ApprovalAnswer - def __init__(granted: bool, approver: str, approved_arguments: Mapping[str, Any] | None = None) -``` - -A human's answer, and who gave it (SPEC-v0.5 §2.2, §3.4). - -`approver` names a **channel** wherever the framework's primitive does not identify a -person -- `"langgraph:interrupt"`, in the same register as v0.1's `"cli:local"`. It is what -`grant_approval` writes on the record, and from there what reaches `APPROVAL_CONSUMED` and -the receipt's `approver` field. Authenticating the approver is not in scope (SPEC-v0.3 §13), -so no document may describe this field as *who* approved. - -`approved_arguments` are the arguments the answer was given against, as the adapter -recovered them from its framework's own record of it. Required where the interrupt declares -`carries_approved_arguments`; `None` only where it does not. **Never a copy of -`PendingApproval.arguments`**: handing back exactly what you were given makes every comparison -trivially pass, which is manufacturing the check. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ApprovalMismatch.mdx b/docs/docs/reference/api/ApprovalMismatch.mdx deleted file mode 100644 index 1885878..0000000 --- a/docs/docs/reference/api/ApprovalMismatch.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "ApprovalMismatch" -description: "The presented approval does not authorize this action (SPEC-v0.1 §4.2)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ApprovalMismatch` — class, defined at `src/ctrlrun/errors.py:111` - -```python -from ctrlrun import ApprovalMismatch -``` - - -```python -class ApprovalMismatch(CTRLRunError) - def __init__(message: str | None = None, *, reason: str, approval_id: str | None = None) -``` - -The presented approval does not authorize this action (SPEC-v0.1 §4.2). - -`reason` is one of `unknown`, `mismatch`, or the status the record was in — `consumed`, -`expired`, `pending`, `denied`. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ApprovalProvider.mdx b/docs/docs/reference/api/ApprovalProvider.mdx deleted file mode 100644 index aa83627..0000000 --- a/docs/docs/reference/api/ApprovalProvider.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "ApprovalProvider" -description: "How a human is asked, and how the answer comes back (SPEC-v0.1 §4.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ApprovalProvider` — class, defined at `src/ctrlrun/approval.py:304` - -```python -from ctrlrun import ApprovalProvider -``` - - -```python -class ApprovalProvider(Protocol) - def request(action: Action, ttl: timedelta) -> ApprovalRequest - def wait(request_id: str, timeout: timedelta | None) -> Approval | None -``` - -How a human is asked, and how the answer comes back (SPEC-v0.1 §4.3). - -`runtime_checkable` so a test can assert the shipped providers still answer to this -shape; it checks method names only, which is why the static check matters more. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ApprovalRequest.mdx b/docs/docs/reference/api/ApprovalRequest.mdx deleted file mode 100644 index 3ae214f..0000000 --- a/docs/docs/reference/api/ApprovalRequest.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "ApprovalRequest" -description: "A pending question for a human: may this exact action run? (SPEC-v0.1 §4.1)" ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ApprovalRequest` — class, defined at `src/ctrlrun/approval.py:78` - -```python -from ctrlrun import ApprovalRequest -``` - - -```python -class ApprovalRequest - def __init__(request_id: str, action_hash: str, action: Action, created_at: datetime, expires_at: datetime, policy_hash: str | None = None) -``` - -A pending question for a human: may this exact action run? (SPEC-v0.1 §4.1) - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ApprovalRequired.mdx b/docs/docs/reference/api/ApprovalRequired.mdx deleted file mode 100644 index 8be768e..0000000 --- a/docs/docs/reference/api/ApprovalRequired.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "ApprovalRequired" -description: "The action needs a human. `request_id` is what `ctrlrun approve` takes (SPEC §4.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ApprovalRequired` — class, defined at `src/ctrlrun/errors.py:88` - -```python -from ctrlrun import ApprovalRequired -``` - - -```python -class ApprovalRequired(CTRLRunError) - def __init__(message: str | None = None, *, request_id: str, action_id: str | None = None) -``` - -The action needs a human. `request_id` is what `ctrlrun approve` takes (SPEC §4.3). - -Raised instead of blocking, so an agent loop can surface the request and come back with -`ctrlrun.with_approval(request_id)` in context. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ApprovalTimeout.mdx b/docs/docs/reference/api/ApprovalTimeout.mdx deleted file mode 100644 index 0000a96..0000000 --- a/docs/docs/reference/api/ApprovalTimeout.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "ApprovalTimeout" -description: "Nobody answered the approval request in time (SPEC-v0.1 §4.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ApprovalTimeout` — class, defined at `src/ctrlrun/errors.py:103` - -```python -from ctrlrun import ApprovalTimeout -``` - - -```python -class ApprovalTimeout(CTRLRunError) - def __init__(message: str | None = None, *, request_id: str) -``` - -Nobody answered the approval request in time (SPEC-v0.1 §4.3). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Authority.mdx b/docs/docs/reference/api/Authority.mdx deleted file mode 100644 index e4f5df2..0000000 --- a/docs/docs/reference/api/Authority.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "Authority" -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:751` - -```python -from ctrlrun import Authority -``` - - -```python -class Authority - def __init__(grants: Mapping[str, Grant], *, max_delegation_depth: int = DEFAULT_MAX_DELEGATION_DEPTH, source: str = '<string>') -``` - -The `authority:` section, loaded and evaluable (SPEC-v0.3 §4). - -Pure: `evaluate` reads the store to resolve delegations and writes nothing to it, appends -no event, and has no other side effect. `Control` performs every write (§4.8). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/AuthorityDenied.mdx b/docs/docs/reference/api/AuthorityDenied.mdx deleted file mode 100644 index 9fd97c3..0000000 --- a/docs/docs/reference/api/AuthorityDenied.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "AuthorityDenied" -description: "The principal holds no grant that covers this action (SPEC-v0.3 §4.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.AuthorityDenied` — class, defined at `src/ctrlrun/errors.py:40` - -```python -from ctrlrun import AuthorityDenied -``` - - -```python -class AuthorityDenied(ActionDenied) - def __init__(message: str | None = None, *, reason: str, action_id: str | None = None, grant_id: str | None = None, delegation_id: str | None = None) -``` - -The principal holds no grant that covers this action (SPEC-v0.3 §4.3). - -A subclass of `ActionDenied`, because an authority denial *is* the action being denied and -an agent loop's existing `except ActionDenied` should keep working. `reason` is one of the -closed set in §4.3 — `no_authority`, `authority_constraint`, `authority_expired`, -`authority_escalation`, `authority_revoked`, `authority_unreadable` — never a grant id: a -grant may legally be named `no_authority`, and evidence that can be spoofed by naming a -grant is not evidence. The id travels in `grant_id`. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/AuthorityEscalation.mdx b/docs/docs/reference/api/AuthorityEscalation.mdx deleted file mode 100644 index 0281954..0000000 --- a/docs/docs/reference/api/AuthorityEscalation.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: "AuthorityEscalation" -description: "A delegation that may not exist: it is not contained in its parent (SPEC-v0.3 §5.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.AuthorityEscalation` — class, defined at `src/ctrlrun/errors.py:65` - -```python -from ctrlrun import AuthorityEscalation -``` - - -```python -class AuthorityEscalation(CTRLRunError) - def __init__(message: str | None = None, *, reason: str, parent_id: str | None = None, dimension: str | None = None) -``` - -A delegation that may not exist: it is not contained in its parent (SPEC-v0.3 §5.3). - -Not an `ActionDenied`: nothing was proposed. This is the creation-time vocabulary — -`containment`, `unknown_parent`, `parent_not_delegable`, `parent_not_valid`, -`not_the_subject`, `max_depth` — and it is disjoint from `AuthorityDenied`'s evaluation -reasons. The two are never used interchangeably. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/AuthorityResult.mdx b/docs/docs/reference/api/AuthorityResult.mdx deleted file mode 100644 index 43c9b60..0000000 --- a/docs/docs/reference/api/AuthorityResult.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "AuthorityResult" -description: "What the authority axis decided, and which grant it decided on (§4.8)." ---- - -{/* 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:456` - -```python -from ctrlrun import AuthorityResult -``` - - -```python -class AuthorityResult - def __init__(passed: bool, reason: str, grant_id: str | None = None, delegation_id: str | None = None, depth: int = 0, dimension: str | None = None, missing_parent_id: str | None = None, expired_parent_id: str | None = None, depth_exceeded: int | None = None, cycle_at: str | None = None) -``` - -What the authority axis decided, and which grant it decided on (§4.8). - -The four trailing fields carry §7's `AUTHORITY_DENIED` evidence: the `dimension` a §5.6 -rule-4 step failed on, the `missing_parent_id` of rule 1, the `expired_parent_id` of rule -3, and rule 5's `depth_exceeded` or `cycle_at`. They exist because rules 1, 3, 4, 5 and 6 -all report `authority_escalation`, so without them five guards would be indistinguishable -in evidence and no test could tell which had run. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/CTRLRunError.mdx b/docs/docs/reference/api/CTRLRunError.mdx deleted file mode 100644 index dd146c4..0000000 --- a/docs/docs/reference/api/CTRLRunError.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: "CTRLRunError" -description: "Base class for every error raised by CTRLRun." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.CTRLRunError` — class, defined at `src/ctrlrun/errors.py:4` - -```python -from ctrlrun import CTRLRunError -``` - - -```python -class CTRLRunError(Exception) -``` - -Base class for every error raised by CTRLRun. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Condition.mdx b/docs/docs/reference/api/Condition.mdx deleted file mode 100644 index 6a3d693..0000000 --- a/docs/docs/reference/api/Condition.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "Condition" -description: "One `<argument>_<op>: operand` test against an action's arguments (SPEC-v0.1 §3.2)." ---- - -{/* 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:297` - -```python -from ctrlrun import Condition -``` - - -```python -class Condition - def __init__(key: str, argument: str, op: str, operand: Any) -``` - -One `<argument>_<op>: operand` test against an action's arguments (SPEC-v0.1 §3.2). - -Public since SPEC-v0.3 §11, because a `Grant`'s constraints are made of them and the two -axes share one evaluator: a second implementation would be a second place for `True` to -start comparing equal to `1`. `key` is the raw condition key the author wrote. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Control.mdx b/docs/docs/reference/api/Control.mdx deleted file mode 100644 index fe8696c..0000000 --- a/docs/docs/reference/api/Control.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "Control" -description: "Policy, state and evidence composed around a single action (SPEC-v0.1 §8)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.Control` — class, defined at `src/ctrlrun/control.py:266` - -```python -from ctrlrun import Control -``` - - -```python -class Control - def __init__(policy: Policy, store: StateStore, approvals: ApprovalProvider | None = None, *, clock: Callable[[], datetime] = _utc_now, approval_ttl: timedelta = DEFAULT_APPROVAL_TTL, lease: timedelta = DEFAULT_LEASE, sinks: Sequence[EventSink] = (), suspend_timeout: timedelta = DEFAULT_SUSPEND_TIMEOUT, identity: IdentityProvider | None = None, authority: Authority | None = None, environment: str | None = None) -``` - -Policy, state and evidence composed around a single action (SPEC-v0.1 §8). - -`evaluate()` decides an action and touches nothing. `execute()` decides it, runs the -executor, and records a receipt and events for whatever happened. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Decision.mdx b/docs/docs/reference/api/Decision.mdx deleted file mode 100644 index aec0b55..0000000 --- a/docs/docs/reference/api/Decision.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "Decision" -description: "What may happen to an action: exactly three outcomes in v0.1 (SPEC-v0.1 §3.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.Decision` — class, defined at `src/ctrlrun/policy.py:234` - -```python -from ctrlrun import Decision -``` - - -```python -class Decision(StrEnum) - ALLOW - APPROVE - DENY -``` - -What may happen to an action: exactly three outcomes in v0.1 (SPEC-v0.1 §3.3). - -`StrEnum`, so a member renders as its value in receipts and CLI output (SPEC-v0.1 §6.1). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Delegation.mdx b/docs/docs/reference/api/Delegation.mdx deleted file mode 100644 index abd449d..0000000 --- a/docs/docs/reference/api/Delegation.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: "Delegation" -description: "A grant created at runtime by a principal who already holds one (SPEC-v0.3 §5.1)." ---- - -{/* 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:416` - -```python -from ctrlrun import Delegation -``` - - -```python -class Delegation - def __init__(delegation_id: str, parent_id: str, depth: int, grant: Grant, created_by: Principal, created_via: Literal['api', 'cli'], created_at: datetime, revoked_at: datetime | None = None, revoked_by: str | None = None) -``` - -A grant created at runtime by a principal who already holds one (SPEC-v0.3 §5.1). - -The parsed form of a `DelegationRecord`: `state.py` persists rows with `grant_json` as a -string, and this module is what parses a `Grant` out of one. `grant.id` **is** the -`delegation_id` — one namespace addresses root grants and delegations, and `--parent` -takes either (§5.2). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/DelegationRecord.mdx b/docs/docs/reference/api/DelegationRecord.mdx deleted file mode 100644 index 59367df..0000000 --- a/docs/docs/reference/api/DelegationRecord.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "DelegationRecord" -description: "One row of the `delegations` table (SPEC-v0.3 §5.2)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.DelegationRecord` — class, defined at `src/ctrlrun/state.py:372` - -```python -from ctrlrun import DelegationRecord -``` - - -```python -class DelegationRecord - def __init__(delegation_id: str, parent_id: str, depth: int, grant_json: str, created_by_agent: str, created_by_user: str | None, created_via: str, created_at: datetime, revoked_at: datetime | None = None, revoked_by: str | None = None) -``` - -One row of the `delegations` table (SPEC-v0.3 §5.2). - -**The store persists rows, not grants.** `grant_json` stays a string here and -`authority.py` is what parses a `Grant` out of it, so `state.py` does not import -`authority.py` and therefore does not transitively acquire `policy.py` — -`ARCHITECTURE.md` §6's dependency direction. `Delegation`, the parsed form, lives there. - -`depth` is recorded for reading and never trusted: evaluation derives it by walking to the -root (§5.5), so a row edited directly in the database cannot assert its way to a shorter -chain. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/DuplicateEffect.mdx b/docs/docs/reference/api/DuplicateEffect.mdx deleted file mode 100644 index 5aa4c66..0000000 --- a/docs/docs/reference/api/DuplicateEffect.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "DuplicateEffect" -description: "This logical effect already happened, or is happening now (SPEC-v0.1 §5.4)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.DuplicateEffect` — class, defined at `src/ctrlrun/errors.py:126` - -```python -from ctrlrun import DuplicateEffect -``` - - -```python -class DuplicateEffect(CTRLRunError) - def __init__(message: str | None = None, *, state: str, effect_key: str | None = None) -``` - -This logical effect already happened, or is happening now (SPEC-v0.1 §5.4). - -`state` is `committed` — the effect is done — or `in_progress`, meaning another attempt -holds a live reservation on the key. Neither permits a second execution. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/EffectKeyError.mdx b/docs/docs/reference/api/EffectKeyError.mdx deleted file mode 100644 index f43411b..0000000 --- a/docs/docs/reference/api/EffectKeyError.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "EffectKeyError" -description: "An effect template cannot be resolved to a key (SPEC-v0.1 §5.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.EffectKeyError` — class, defined at `src/ctrlrun/errors.py:21` - -```python -from ctrlrun import EffectKeyError -``` - - -```python -class EffectKeyError(CTRLRunError) -``` - -An effect template cannot be resolved to a key (SPEC-v0.1 §5.1). - -The action is refused rather than executed without an effect key: an action whose -logical effect cannot be identified cannot be protected against duplication. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/EffectRecord.mdx b/docs/docs/reference/api/EffectRecord.mdx deleted file mode 100644 index 86c432a..0000000 --- a/docs/docs/reference/api/EffectRecord.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "EffectRecord" -description: "What a StateStore holds for one effect key (ARCHITECTURE §5)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.EffectRecord` — class, defined at `src/ctrlrun/effect.py:99` - -```python -from ctrlrun import EffectRecord -``` - - -```python -class EffectRecord - def __init__(effect_key: str, state: EffectState, action_id: str, attempt: int, created_at: datetime, updated_at: datetime, lease_expires_at: datetime | None = None, result: Any = None, error: str | None = None, resolved_by: str | None = None) -``` - -What a StateStore holds for one effect key (ARCHITECTURE §5). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/EffectState.mdx b/docs/docs/reference/api/EffectState.mdx deleted file mode 100644 index 8f277ec..0000000 --- a/docs/docs/reference/api/EffectState.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "EffectState" -description: "Where a logical effect stands (SPEC-v0.1 §5.2)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.EffectState` — class, defined at `src/ctrlrun/effect.py:74` - -```python -from ctrlrun import EffectState -``` - - -```python -class EffectState(StrEnum) - NEW - RESERVED - EXECUTING - COMMITTED - FAILED - AMBIGUOUS -``` - -Where a logical effect stands (SPEC-v0.1 §5.2). - -`NEW` is the state of a key nobody has reserved: it is never written to a store, which -reports it as no record at all. `AMBIGUOUS` never collapses to `FAILED`; only a human -moves a record out of it. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Event.mdx b/docs/docs/reference/api/Event.mdx deleted file mode 100644 index 172bd82..0000000 --- a/docs/docs/reference/api/Event.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "Event" -description: "One ordered step in the life of an action (SPEC-v0.1 §6.2)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.Event` — class, defined at `src/ctrlrun/receipt.py:154` - -```python -from ctrlrun import Event -``` - - -```python -class Event - def __init__(type: EventType, action_id: str | None, ts: datetime, data: Mapping[str, Any] = dict(), effect_key: str | None = None, approval_id: str | None = None, event_id: int | None = None) -``` - -One ordered step in the life of an action (SPEC-v0.1 §6.2). - -`event_id` is assigned by the StateStore on append, not by the caller. - -`action_id` is `None` for the three `DELEGATION_*` types (SPEC-v0.3 §7): they are about an -authority record, created and revoked outside any action's life, and they name the -delegation in `data.delegation_id`. Inventing a synthetic `action_id` would put a value in -a field every reader takes to name a real proposal. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/EventSink.mdx b/docs/docs/reference/api/EventSink.mdx deleted file mode 100644 index f3a9b50..0000000 --- a/docs/docs/reference/api/EventSink.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "EventSink" -description: "Somewhere a copy of every `Event` and `Receipt` goes (SPEC-v0.2 §4.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.EventSink` — class, defined at `src/ctrlrun/receipt.py:410` - -```python -from ctrlrun import EventSink -``` - - -```python -class EventSink(Protocol) - def on_event(event: Event) -> None - def on_receipt(receipt: Receipt) -> None -``` - -Somewhere a copy of every `Event` and `Receipt` goes (SPEC-v0.2 §4.1). - -`Control` calls a sink *after* the authoritative store write for that record has -succeeded, in registration order, with the `event_id` the store assigned. A sink is the -interface for the copies; it is not the interface for the record — the store's own -`events` and `receipts` tables are written inside the store, in its transaction, before -any sink runs (§4.3). - -Sinks are not transactional, not ordered across processes, and not retried. A sink that -must not lose records buffers and retries inside itself. And a sink never raises into the -kernel: `Control` catches every `Exception` and carries on (§4.2). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/FrameworkInterrupt.mdx b/docs/docs/reference/api/FrameworkInterrupt.mdx deleted file mode 100644 index 4bcb7d0..0000000 --- a/docs/docs/reference/api/FrameworkInterrupt.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: "FrameworkInterrupt" -description: "One framework's human-in-the-loop primitive, and nothing else (SPEC-v0.5 §2.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.FrameworkInterrupt` — class, defined at `src/ctrlrun/adapter.py:179` - -```python -from ctrlrun import FrameworkInterrupt -``` - - -```python -class FrameworkInterrupt(Protocol) - framework: str - carries_approved_arguments: bool - def interrupt(pending: PendingApproval) -> ApprovalAnswer -``` - -One framework's human-in-the-loop primitive, and nothing else (SPEC-v0.5 §2.1). - -`interrupt()` **may exit non-locally**: LangGraph's raises, the graph catches it and -checkpoints, and the resumed run re-enters here and returns. The provider never catches it. - -An `interrupt()` that raises anything else is that framework's failure and not a decision. -Nothing is written and it propagates. There is no default, and in particular no default -`granted=False`: a denial is a human's answer, and manufacturing one from a crashed -interrupt puts a refusal in the evidence log that nobody made. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Grant.mdx b/docs/docs/reference/api/Grant.mdx deleted file mode 100644 index b5c24ce..0000000 --- a/docs/docs/reference/api/Grant.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "Grant" -description: "One permission: this subject may propose these actions, under these limits (§4.2)." ---- - -{/* 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:298` - -```python -from ctrlrun import Grant -``` - - -```python -class Grant - def __init__(id: str, subject: Subject, actions: tuple[str, ...] = (), resources: tuple[str, ...] | None = None, constraints: Mapping[str, Condition] = (lambda: NO_CONSTRAINTS)(), environments: tuple[str, ...] | None = None, expires_at: datetime | None = None, delegable: bool = False) -``` - -One permission: this subject may propose these actions, under these limits (§4.2). - -`__post_init__` validates everything the YAML loader validates, so the constructor refuses -exactly what the loader refuses. That is not decoration: `Control.delegate` takes a `Grant` -built in Python, and §5.5's segment relation is undefined on a segment like `a**`, so -without it item 3's containment check would be discharging a proof about a value nothing -validated. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/HeaderIdentityProvider.mdx b/docs/docs/reference/api/HeaderIdentityProvider.mdx deleted file mode 100644 index fbc75a1..0000000 --- a/docs/docs/reference/api/HeaderIdentityProvider.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: "HeaderIdentityProvider" -description: "The principal named by a trusted HTTP header (§3.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.HeaderIdentityProvider` — class, defined at `src/ctrlrun/identity.py:126` - -```python -from ctrlrun import HeaderIdentityProvider -``` - - -```python -class HeaderIdentityProvider - def __init__(agent_header: str, user_header: str | None = None, issuer: str | None = None) -``` - -The principal named by a trusted HTTP header (§3.3). - -**A trusted header is worth exactly what the thing that sets it is worth.** This is correct -behind a proxy that authenticates the caller and *overwrites* the header on every request, -and worthless anywhere else: if the agent can set the header, the agent chooses its own -authority. RFC 7239 §8.1 says the same of the header it standardizes — it "cannot be relied -upon to be correct, as it may be modified ... by every node on the way to the server, -including the client making the request". - -It carries no claims. A header is a name; manufacturing claims from one would be inventing -verified data, which is the one thing this module must not do. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/IdentityContext.mdx b/docs/docs/reference/api/IdentityContext.mdx deleted file mode 100644 index edeccca..0000000 --- a/docs/docs/reference/api/IdentityContext.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "IdentityContext" -description: "What a provider is told about the call it is resolving a principal for (§3.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.IdentityContext` — class, defined at `src/ctrlrun/identity.py:35` - -```python -from ctrlrun import IdentityContext -``` - - -```python -class IdentityContext - def __init__(action: str, environment: str, headers: Mapping[str, str] = (lambda: _NO_HEADERS)(), agent: str | None = None, user: str | None = None) -``` - -What a provider is told about the call it is resolving a principal for (§3.1). - -`headers` carries **lowercased** header names, because HTTP field names are -case-insensitive and a provider that had to guess the casing would be one that sometimes -worked. It is empty in-process; the gateway fills it. - -`agent` and `user` are what an active `context()` supplied. They are a **hint**, not an -identity: a provider may ignore them, and both providers here do. They are passed so a -custom provider can implement "look up the token for this agent" without a second channel. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/IdentityError.mdx b/docs/docs/reference/api/IdentityError.mdx deleted file mode 100644 index 37a929d..0000000 --- a/docs/docs/reference/api/IdentityError.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: "IdentityError" -description: "A credential was offered and rejected (SPEC-v0.3 §3.2)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.IdentityError` — class, defined at `src/ctrlrun/errors.py:194` - -```python -from ctrlrun import IdentityError -``` - - -```python -class IdentityError(CTRLRunError) -``` - -A credential was offered and rejected (SPEC-v0.3 §3.2). - -Not an `ActionDenied`: an agent loop's `except ActionDenied` is written to handle a policy -saying no, and a credential that stopped being valid is not that — the same distinction -v0.1 §5.1 draws for `EffectKeyError`. A *missing* principal stays -`ActionDenied(reason="no_principal")`; this is for one that was produced and found wanting, -which includes an expired `Principal` reaching `Control.execute` (§2.3). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/IdentityProvider.mdx b/docs/docs/reference/api/IdentityProvider.mdx deleted file mode 100644 index ecf7821..0000000 --- a/docs/docs/reference/api/IdentityProvider.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "IdentityProvider" -description: "Resolves the principal for one action (SPEC-v0.3 §3.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.IdentityProvider` — class, defined at `src/ctrlrun/identity.py:70` - -```python -from ctrlrun import IdentityProvider -``` - - -```python -class IdentityProvider(Protocol) - def resolve(context: IdentityContext) -> Principal | None -``` - -Resolves the principal for one action (SPEC-v0.3 §3.1). - -Returning `None` is a **decline** — "I have nothing to say about this call" — and leaves -the v0.1 `context()` path intact, unless an `authority:` section is loaded, in which case -§3.2 refuses rather than backfilling. - -Raising is a **refusal** — "I was given something and rejected it". `Control` never falls -back from one: doing so would turn a rejected token into a successful action, which is the -outcome §3 exists to prevent. Raise `IdentityError` to say so directly; anything else is -logged and re-raised as one with the original chained. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/InMemoryStateStore.mdx b/docs/docs/reference/api/InMemoryStateStore.mdx deleted file mode 100644 index 6a4039e..0000000 --- a/docs/docs/reference/api/InMemoryStateStore.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "InMemoryStateStore" -description: "Everything held in process memory: for tests and `ctrlrun demo`." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.InMemoryStateStore` — class, defined at `src/ctrlrun/state.py:631` - -```python -from ctrlrun import InMemoryStateStore -``` - - -```python -class InMemoryStateStore - def __init__(*, clock: Callable[[], datetime] = _utc_now) -``` - -Everything held in process memory: for tests and `ctrlrun demo`. - -Nothing here survives the process, and nothing here is shared between processes, so this -store cannot provide the cross-process half of SPEC-v0.1 §5.3 E1 — `SQLiteStateStore` is -the store for anything that matters. Within one process it refuses exactly what SQLite -refuses: the same `plan_reservation` and `check_consumable` decide, under one lock that -covers each whole check-and-write. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/InterruptApprovalProvider.mdx b/docs/docs/reference/api/InterruptApprovalProvider.mdx deleted file mode 100644 index c67da08..0000000 --- a/docs/docs/reference/api/InterruptApprovalProvider.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "InterruptApprovalProvider" -description: "An `ApprovalProvider` whose `wait()` routes through a framework's own primitive." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.InterruptApprovalProvider` — class, defined at `src/ctrlrun/adapter.py:209` - -```python -from ctrlrun import InterruptApprovalProvider -``` - - -```python -class InterruptApprovalProvider - def __init__(store: ApprovalStore, interrupt: FrameworkInterrupt, *, clock: Callable[[], datetime] = _utc_now) -``` - -An `ApprovalProvider` whose `wait()` routes through a framework's own primitive. - -That is the whole mechanism of SPEC-v0.5 §3: `@protect(wait=True)` raises `ApprovalRequired`, -catches it, calls `wait()`, and re-presents the same proposal under `with_approval`. The -reservation is taken only on that second pass, which is why an approval gate needs none of -`Suspended`'s machinery -- a human deliberating for an hour pins nothing. - -**The operator constructs it**, on the line where they choose the policy, the store and the -identity provider: - - control = Control(policy, store, - approvals=InterruptApprovalProvider(store, MyInterrupt()), - identity=..., authority=...) - -An adapter never constructs a `Control` (SPEC-v0.5 §2.3). Everything it must not choose -- -the identity provider, the authority document, the clock, the environment, the mode -- is -chosen there, by the person who deployed it. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/InvalidArgument.mdx b/docs/docs/reference/api/InvalidArgument.mdx deleted file mode 100644 index ad8090b..0000000 --- a/docs/docs/reference/api/InvalidArgument.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "InvalidArgument" -description: "An argument cannot be accepted as given." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.InvalidArgument` — class, defined at `src/ctrlrun/errors.py:8` - -```python -from ctrlrun import InvalidArgument -``` - - -```python -class InvalidArgument(CTRLRunError) -``` - -An argument cannot be accepted as given. - -An Action field or argument that cannot be canonicalized (SPEC-v0.1 §2.3), and — the -same kind of wiring bug — a StateStore transition no record can make, such as committing -an effect nobody reserved. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/JSONLEventSink.mdx b/docs/docs/reference/api/JSONLEventSink.mdx deleted file mode 100644 index fe87e81..0000000 --- a/docs/docs/reference/api/JSONLEventSink.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "JSONLEventSink" -description: "The JSONL half of the evidence: two append-only files in one directory (SPEC §6)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.JSONLEventSink` — class, defined at `src/ctrlrun/receipt.py:429` - -```python -from ctrlrun import JSONLEventSink -``` - - -```python -class JSONLEventSink - def __init__(directory: str | os.PathLike[str]) -``` - -The JSONL half of the evidence: two append-only files in one directory (SPEC §6). - -`receipts.jsonl` and `events.jsonl` beside the state database, so `.ctrlrun/` holds the -whole record of what an agent did. The store is authoritative — these files are the -portable copy, written after the store accepted the same record. - -Each write opens, appends one line and closes, so several processes sharing a store -(SPEC-v0.1 §5.3 E1) interleave whole lines rather than fragments of them. - -SPEC-v0.2 §4.3 — this used to live inside `SQLiteStateStore`, which wrote both halves. -`Control` owns it now, as one `EventSink` among however many an application registers. -The files it writes, and where, are unchanged. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/LocalApprovalProvider.mdx b/docs/docs/reference/api/LocalApprovalProvider.mdx deleted file mode 100644 index 6b644c5..0000000 --- a/docs/docs/reference/api/LocalApprovalProvider.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "LocalApprovalProvider" -description: "Requests go to the StateStore; `wait()` polls it (SPEC-v0.1 §4.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.LocalApprovalProvider` — class, defined at `src/ctrlrun/approval.py:369` - -```python -from ctrlrun import LocalApprovalProvider -``` - - -```python -class LocalApprovalProvider - def __init__(store: ApprovalStore, *, clock: Callable[[], datetime] = _utc_now, poll_interval: timedelta = DEFAULT_POLL_INTERVAL) -``` - -Requests go to the StateStore; `wait()` polls it (SPEC-v0.1 §4.3). - -The human answers out of band — `ctrlrun approve <id>` or `ctrlrun deny <id>` in another -shell. Waiting is bounded by the request's own expiry, so a request nobody answers ends -in `ApprovalTimeout` rather than a blocked agent. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/MissingDependency.mdx b/docs/docs/reference/api/MissingDependency.mdx deleted file mode 100644 index e99e0b6..0000000 --- a/docs/docs/reference/api/MissingDependency.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "MissingDependency" -description: "An optional extra is not installed (SPEC-v0.2 §1.1, §11)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.MissingDependency` — class, defined at `src/ctrlrun/errors.py:228` - -```python -from ctrlrun import MissingDependency -``` - - -```python -class MissingDependency(CTRLRunError) - def __init__(module: str, extra: str) -``` - -An optional extra is not installed (SPEC-v0.2 §1.1, §11). - -Never `ImportError` or `ModuleNotFoundError`: an operator reads those as a broken -package rather than as an option they did not select. The message names the module that -is missing and the command that installs it. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/NotExecuted.mdx b/docs/docs/reference/api/NotExecuted.mdx deleted file mode 100644 index 5250328..0000000 --- a/docs/docs/reference/api/NotExecuted.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "NotExecuted" -description: "Raised by an executor to assert the remote side did nothing (SPEC-v0.1 §5.5)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.NotExecuted` — class, defined at `src/ctrlrun/errors.py:157` - -```python -from ctrlrun import NotExecuted -``` - - -```python -class NotExecuted(CTRLRunError) -``` - -Raised by an executor to assert the remote side did nothing (SPEC-v0.1 §5.5). - -This is the *only* exception that maps to `FAILED` and therefore permits a retry. -Every other exception is an `AMBIGUOUS` outcome. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/PendingApproval.mdx b/docs/docs/reference/api/PendingApproval.mdx deleted file mode 100644 index a8aaa3b..0000000 --- a/docs/docs/reference/api/PendingApproval.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "PendingApproval" -description: "What the framework's interrupt is handed, and the only thing it is (SPEC-v0.5 §2.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.PendingApproval` — class, defined at `src/ctrlrun/adapter.py:92` - -```python -from ctrlrun import PendingApproval -``` - - -```python -class PendingApproval - def __init__(request_id: str, action_id: str, action: str, action_hash: str, arguments: Mapping[str, Any], resource: str | None, environment: str, agent: str, user: str | None, created_at: datetime, expires_at: datetime) -``` - -What the framework's interrupt is handed, and the only thing it is (SPEC-v0.5 §2.3). - -A value: the action's name, its canonical arguments, its resource, its environment, the -principal's `agent` and `user`, the `action_hash` and the request's expiry. It does **not** -carry the `Action`, the `Control`, the store or the executor -- nothing an adapter could act -on rather than display. - -`agent` and `user` are outputs. They are here so a human sees who is asking, and there is -no constructor, keyword or callback anywhere on this surface that puts one back in (§4.2). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Policy.mdx b/docs/docs/reference/api/Policy.mdx deleted file mode 100644 index e6b47f8..0000000 --- a/docs/docs/reference/api/Policy.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "Policy" -description: "Action-level autonomy policy: which actions may run, and under which conditions." ---- - -{/* 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:575` - -```python -from ctrlrun import Policy -``` - - -```python -class Policy - def __init__(actions: Mapping[str, _ActionPolicy], source: str, schema: str = POLICY_SCHEMA, environment: str | None = None, mode: Literal['observe', 'enforce'] = ENFORCE, version: str | None = None, controls: Mapping[str, PolicyControl] = dict(), _canonical: Mapping[str, Any] = dict()) -``` - -Action-level autonomy policy: which actions may run, and under which conditions. - -Load with `Policy.from_file()`. A policy that cannot be loaded is an error, never an -empty permissive policy (SPEC-v0.1 §3.4). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/PolicyError.mdx b/docs/docs/reference/api/PolicyError.mdx deleted file mode 100644 index 8f88305..0000000 --- a/docs/docs/reference/api/PolicyError.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: "PolicyError" -description: "The policy is missing, unreadable, or malformed. Raised at load time (SPEC-v0.1 §3.4)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.PolicyError` — class, defined at `src/ctrlrun/errors.py:17` - -```python -from ctrlrun import PolicyError -``` - - -```python -class PolicyError(CTRLRunError) -``` - -The policy is missing, unreadable, or malformed. Raised at load time (SPEC-v0.1 §3.4). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Principal.mdx b/docs/docs/reference/api/Principal.mdx deleted file mode 100644 index f7b584f..0000000 --- a/docs/docs/reference/api/Principal.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: "Principal" -description: "Who is acting: an agent, optionally on behalf of a human." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.Principal` — class, defined at `src/ctrlrun/action.py:139` - -```python -from ctrlrun import Principal -``` - - -```python -class Principal - def __init__(agent: str, user: str | None = None, claims: Mapping[str, ClaimValue] = (lambda: NO_CLAIMS)(), issuer: str | None = None, expires_at: datetime | None = None) -``` - -Who is acting: an agent, optionally on behalf of a human. - -`claims`, `issuer` and `expires_at` are what an `IdentityProvider` verified (SPEC-v0.3 §2.1). -None of the three is part of the canonical form (§2.2): an approval binds to an action hash, -and a hash that moved when a token rotated would invalidate it for a reason no human could -see and no agent could fix. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Receipt.mdx b/docs/docs/reference/api/Receipt.mdx deleted file mode 100644 index 8ebc099..0000000 --- a/docs/docs/reference/api/Receipt.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "Receipt" -description: "Portable evidence of one action that reached a terminal state (SPEC-v0.1 §6.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.Receipt` — class, defined at `src/ctrlrun/receipt.py:244` - -```python -from ctrlrun import Receipt -``` - - -```python -class Receipt - def __init__(receipt_id: str, action_id: str, action: str, action_hash: str, principal: Principal, resource: str | None, arguments: Mapping[str, Any], environment: str, decision: Decision, decision_reason: str, result: ReceiptResult, started_at: datetime, finished_at: datetime, approval_id: str | None = None, approver: str | None = None, effect_key: str | None = None, attempt: int = 1, error: str | None = None, execution: ReceiptResult | None = None, would_have: _WouldHave | None = None, seq: int | None = None, prev_hash: str | None = None, policy_hash: str | None = None, policy_version: str | None = None, controls: tuple[str, ...] = (), hash: str | None = None) -``` - -Portable evidence of one action that reached a terminal state (SPEC-v0.1 §6.1). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ReconcileOutcome.mdx b/docs/docs/reference/api/ReconcileOutcome.mdx deleted file mode 100644 index 38a1776..0000000 --- a/docs/docs/reference/api/ReconcileOutcome.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "ReconcileOutcome" -description: "What a `reconcile` hook may answer about an effect key (SPEC-v0.2 §2)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ReconcileOutcome` — attribute, defined at `src/ctrlrun/effect.py:45` - -```python -from ctrlrun import ReconcileOutcome -``` - - -```python -ReconcileOutcome -``` - -What a `reconcile` hook may answer about an effect key (SPEC-v0.2 §2). - -`"committed"` moves the record to `COMMITTED` and a retry is then refused as a duplicate; -`"not_executed"` moves it to `FAILED` and a retry is permitted; `"unknown"` leaves it -`AMBIGUOUS`. A hook moves a record only in the direction its answer points, and is the only -thing besides a human permitted to move one out of `AMBIGUOUS`. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/SQLiteStateStore.mdx b/docs/docs/reference/api/SQLiteStateStore.mdx deleted file mode 100644 index 49769d8..0000000 --- a/docs/docs/reference/api/SQLiteStateStore.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "SQLiteStateStore" -description: "Approvals, effects and evidence in one SQLite file (ARCHITECTURE §5)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.SQLiteStateStore` — class, defined at `src/ctrlrun/state.py:1006` - -```python -from ctrlrun import SQLiteStateStore -``` - - -```python -class SQLiteStateStore - def __init__(path: str | os.PathLike[str], *, clock: Callable[[], datetime] = _utc_now) -``` - -Approvals, effects and evidence in one SQLite file (ARCHITECTURE §5). - -This is the store that makes reservation atomic across processes (SPEC-v0.1 §5.3 E1): -every decision is taken inside `BEGIN IMMEDIATE`, which holds the database's write lock, -and `effects.effect_key` is a primary key — the `UNIQUE(effect_key)` constraint — so an -insert that races past the lock still fails rather than overwriting a reservation. - -A connection is opened per thread; `sqlite3` connections are not shareable. Separate -processes open the same file, which is the point. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/SchemaMismatch.mdx b/docs/docs/reference/api/SchemaMismatch.mdx deleted file mode 100644 index 5a0b1c3..0000000 --- a/docs/docs/reference/api/SchemaMismatch.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: "SchemaMismatch" -description: "A store met a database it does not recognise, in either direction (SPEC-v0.6 §3.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.SchemaMismatch` — class, defined at `src/ctrlrun/errors.py:205` - -```python -from ctrlrun import SchemaMismatch -``` - - -```python -class SchemaMismatch(CTRLRunError) - def __init__(message: str, *, applied: tuple[str, ...] = (), known: tuple[str, ...] = (), running: str = '') -``` - -A store met a database it does not recognise, in either direction (SPEC-v0.6 §3.3). - -Its own type rather than an `InvalidArgument`, and the bar it clears is that an operator's -process refusing to start needs a distinguishable exception: *"your database is from the -future"* and *"your lease is negative"* have entirely different remedies, and one bucket for -both would put a schema problem behind a wiring bug. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/ScriptedApprovalProvider.mdx b/docs/docs/reference/api/ScriptedApprovalProvider.mdx deleted file mode 100644 index d998e9e..0000000 --- a/docs/docs/reference/api/ScriptedApprovalProvider.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "ScriptedApprovalProvider" -description: "A human replaced by a fixed script: for tests and `ctrlrun demo` (SPEC-v0.1 §4.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.ScriptedApprovalProvider` — class, defined at `src/ctrlrun/approval.py:425` - -```python -from ctrlrun import ScriptedApprovalProvider -``` - - -```python -class ScriptedApprovalProvider - def __init__(store: ApprovalStore, script: Iterable[str | ScriptedOutcome], *, approver: str = 'cli:scripted', clock: Callable[[], datetime] = _utc_now) -``` - -A human replaced by a fixed script: for tests and `ctrlrun demo` (SPEC-v0.1 §4.3). - -Each `wait()` poll takes the next step. `PENDING` means "no answer yet", so a script can -make `wait=True` genuinely block. The script is one sequence shared by every request, in -poll order. An exhausted script raises `ApprovalTimeout`: a scripted approver never -grants by accident, and a test can never hang waiting for a step that will not come. - -The script does not outrank the clock. A step that lands after the request has expired -raises `ApprovalTimeout` and is not applied, so the double cannot grant something the -real provider would have refused (SPEC-v0.1 §4.3). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/StateStore.mdx b/docs/docs/reference/api/StateStore.mdx deleted file mode 100644 index 2603dc9..0000000 --- a/docs/docs/reference/api/StateStore.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: "StateStore" -description: "Durable state behind a `Control` (SPEC-v0.1 §5.3): approvals, effects, evidence." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.StateStore` — class, defined at `src/ctrlrun/state.py:402` - -```python -from ctrlrun import StateStore -``` - - -```python -class StateStore(ApprovalStore, Protocol) - def reserve_effect(effect_key: str, action_id: str, lease: timedelta = DEFAULT_LEASE) -> Reservation - def consume_approval_and_reserve(approval_id: str, action_hash: str, effect_key: str, action_id: str, lease: timedelta = DEFAULT_LEASE) -> tuple[Approval, Reservation] - def begin_execution(effect_key: str, action_id: str) -> None - def commit_effect(effect_key: str, action_id: str, result: Any) -> None - def fail_effect(effect_key: str, action_id: str, error: str) -> None - def mark_ambiguous(effect_key: str, action_id: str, error: str) -> None - def resolve_effect(effect_key: str, state: EffectState, resolver: str) -> EffectRecord - def get_effect(effect_key: str) -> EffectRecord | None - def list_effects(state: EffectState | None = None) -> tuple[EffectRecord, ...] - def extend_lease(effect_key: str, action_id: str, until: datetime) -> None - def find_granted_approval(action_hash: str) -> Approval | None - def find_denied_request(action_hash: str) -> ApprovalRequest | None - def hold_continuation(action: Action, effect_key: str, continuation: str, until: datetime) -> int - def take_continuation(continuation: str) -> HeldContinuation - def continuation_rounds(effect_key: str) -> int - def approvals_for(action_hash: str) -> tuple[ApprovalRecord, ...] - def put_delegation(record: DelegationRecord) -> None - def get_delegation(delegation_id: str) -> DelegationRecord | None - def delegations_for(parent_id: str) -> tuple[DelegationRecord, ...] - def delegations(*, include_revoked: bool = False) -> tuple[DelegationRecord, ...] - def revoke_delegation(delegation_id: str, *, by: str | None, at: datetime) -> bool - def append_event(event: Event) -> Event - def put_receipt(receipt: Receipt) -> Receipt - def chain_head() -> tuple[int, str] | None - def events() -> tuple[Event, ...] - def receipts() -> tuple[Receipt, ...] - def close() -> None -``` - -Durable state behind a `Control` (SPEC-v0.1 §5.3): approvals, effects, evidence. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/StaticIdentityProvider.mdx b/docs/docs/reference/api/StaticIdentityProvider.mdx deleted file mode 100644 index 3e21f01..0000000 --- a/docs/docs/reference/api/StaticIdentityProvider.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "StaticIdentityProvider" -description: "A fixed principal, for development, tests and single-tenant demonstrations (§3.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.StaticIdentityProvider` — class, defined at `src/ctrlrun/identity.py:87` - -```python -from ctrlrun import StaticIdentityProvider -``` - - -```python -class StaticIdentityProvider - def __init__(agent: str, user: str | None = None, claims: Mapping[str, ClaimValue] = (lambda: NO_CLAIMS)(), issuer: str | None = None, expires_at: datetime | None = None) -``` - -A fixed principal, for development, tests and single-tenant demonstrations (§3.3). - -It asserts an identity nobody verified, so it warns once — at construction, not per call. -A library that warns on every action is a library whose warnings get filtered, and the -operator who needs to see this needs to see it once, at the point they chose it. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Subject.mdx b/docs/docs/reference/api/Subject.mdx deleted file mode 100644 index f6501e8..0000000 --- a/docs/docs/reference/api/Subject.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "Subject" -description: "Who a grant is addressed to: an agent pattern, a user pattern, or both (§4.2)." ---- - -{/* 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:263` - -```python -from ctrlrun import Subject -``` - - -```python -class Subject - def __init__(agent: str | None = None, user: str | None = None) -``` - -Who a grant is addressed to: an agent pattern, a user pattern, or both (§4.2). - -Both `None` is refused. Without that, a holder of a narrow grant could mint a child -addressed to every principal in the deployment — widening the population rather than the -powers. "Any agent" is spelled `Subject(agent="*")`, which is greppable. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/Suspended.mdx b/docs/docs/reference/api/Suspended.mdx deleted file mode 100644 index ab9fdf1..0000000 --- a/docs/docs/reference/api/Suspended.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "Suspended" -description: "Raised by an executor: the remote asked for something before it will finish." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.Suspended` — class, defined at `src/ctrlrun/errors.py:165` - -```python -from ctrlrun import Suspended -``` - - -```python -class Suspended(CTRLRunError) - def __init__(continuation: bytes | str) -``` - -Raised by an executor: the remote asked for something before it will finish. - -SPEC-v0.2 §6.9 in the kernel's own terms, and modelled the way v0.1 §5.5 models "nothing -happened" — an explicit opt-in signal, never a default and never inferred. There is no -outcome to record: the effect record stays `EXECUTING`, its lease is extended, the -continuation is held, and the caller gets this back to relay. - -`continuation` is whatever the remote said to present again. It is opaque here — CTRLRun -never parses it, and only ever compares it with `hmac.compare_digest`. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/WebhookApprovalProvider.mdx b/docs/docs/reference/api/WebhookApprovalProvider.mdx deleted file mode 100644 index ac7777e..0000000 --- a/docs/docs/reference/api/WebhookApprovalProvider.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "WebhookApprovalProvider" -description: "Notify a human system on `APPROVAL_REQUESTED`, and let it answer (SPEC-v0.2 §7)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.WebhookApprovalProvider` — class, defined at `src/ctrlrun/webhook.py:141` - -```python -from ctrlrun import WebhookApprovalProvider -``` - - -```python -class WebhookApprovalProvider - def __init__(store: ApprovalStore, *, url: str, secret: object, timeout: timedelta = DEFAULT_TIMEOUT, retries: int = DEFAULT_RETRIES, backoff: timedelta = DEFAULT_BACKOFF, replay_window: timedelta = DEFAULT_REPLAY_WINDOW, public_url: str | None = None, allow_insecure: bool = False, clock: Callable[[], datetime] = lambda: datetime.now(UTC)) -``` - -Notify a human system on `APPROVAL_REQUESTED`, and let it answer (SPEC-v0.2 §7). - -An `ApprovalProvider` (v0.1 §4.3): `request()` records the request and posts it, `wait()` -polls the store exactly as `LocalApprovalProvider` does — the answer arrives out of band, -whether from the gateway's inbound endpoint or from `ctrlrun approve`. - -**An undelivered notification is not an approval.** If every attempt fails the request -stays `pending`, `ApprovalRequired` is raised as usual with a real `request_id` that -`ctrlrun approve` can still answer, and the failure is logged. The action is refused -either way, which is the only outcome that is safe when nobody was told. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/acs-AcsControlHook.mdx b/docs/docs/reference/api/acs-AcsControlHook.mdx deleted file mode 100644 index e7988ef..0000000 --- a/docs/docs/reference/api/acs-AcsControlHook.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "AcsControlHook" -description: "Answer ACS `steps/*` hooks with CTRLRun's decisions and outcomes." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.acs.AcsControlHook` — class, defined at `src/ctrlrun/acs.py:84` - -```python -from ctrlrun.acs import AcsControlHook -``` - -Needs the `gateway` extra: `pip install "ctrlrun[gateway]"`. Importing it without that raises `MissingDependency` carrying the install command. - - -```python -class AcsControlHook - def __init__(control: Control, *, prefix: str = 'acs', approver_id: str = 'cli:local', ask_timeout_seconds: int = DEFAULT_ASK_TIMEOUT_SECONDS, identity: IdentityProvider | None = None) -``` - -Answer ACS `steps/*` hooks with CTRLRun's decisions and outcomes. - -One `Control`, one prefix. `prefix` names the tool namespace in the action name, the way -the gateway's `--alias` does: `<prefix>.<provider>.<tool>` — so a policy addresses one -stable string and two providers exposing the same tool name stay distinguishable. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/action_hash.mdx b/docs/docs/reference/api/action_hash.mdx deleted file mode 100644 index 0ef1302..0000000 --- a/docs/docs/reference/api/action_hash.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: "action_hash" -description: "Return the action hash used to bind approvals to an exact action (SPEC-v0.1 §2.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.action_hash` — function, defined at `src/ctrlrun/action.py:327` - -```python -from ctrlrun import action_hash -``` - - -```python -def action_hash(action: Action) -> str -``` - -Return the action hash used to bind approvals to an exact action (SPEC-v0.1 §2.3). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/banner.mdx b/docs/docs/reference/api/banner.mdx deleted file mode 100644 index cfff3ec..0000000 --- a/docs/docs/reference/api/banner.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "banner" -description: "Log SPEC-v0.3 §6.5's observe banner, once per `Control`. An adapter MUST call it (§3.6)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.banner` — function, defined at `src/ctrlrun/adapter.py:453` - -```python -from ctrlrun import banner -``` - - -```python -def banner(control: Control) -> None -``` - -Log SPEC-v0.3 §6.5's observe banner, once per `Control`. An adapter MUST call it (§3.6). - -Logged and never printed. §6.5 puts the banner on stderr for every CLI command that loads -the operator's policy, and an adapter is not a CLI command: it is inside somebody else's -loop and may have no stream that reaches a human at all. Printing into a framework's channel -is at best noise and at worst a corrupted stream. - -Once per `Control`, because a warning that repeats per call is a warning nobody reads -- and -at all, because a deployment that has been observing for six months is exactly the one that -line is for, and an adapter that said nothing would be the quietest place in the system to -forget. A no-op under `mode: enforce`. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/canonical_bytes.mdx b/docs/docs/reference/api/canonical_bytes.mdx deleted file mode 100644 index 61d8883..0000000 --- a/docs/docs/reference/api/canonical_bytes.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "canonical_bytes" -description: "The canonical form of an arbitrary mapping: UTF-8 JSON, sorted keys, no whitespace." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.canonical_bytes` — function, defined at `src/ctrlrun/action.py:228` - -```python -from ctrlrun import canonical_bytes -``` - - -```python -def canonical_bytes(payload: Mapping[str, Any]) -> bytes -``` - -The canonical form of an arbitrary mapping: UTF-8 JSON, sorted keys, no whitespace. - -**This is the encoding half of `v0.1 §2.3`, promoted rather than written** (SPEC-v0.6 §6.2, -§9.1). `canonicalize(action)` builds a fixed six-key payload and calls this, so there is -provably one implementation rather than two that agree today: the receipt chain (§6.2) and -the policy hash (§7.1) both need the canonical form of a *document*, and the alternative was -a private second canonicalizer, which §6.2 forbids by name. - -Sorted keys recursively, `separators=(",", ":")`, `ensure_ascii=False`, UTF-8, and **`float` -rejected at any depth**. The rejection is not `json.dumps`'s doing -- `allow_nan=False` only -catches `NaN` and the infinities -- so it is checked here, because a canonicalizer that -silently encoded `0.1` would make two hosts with different libm disagree about a hash. - -`ctrlrun.action/v1` is unchanged by this promotion and T164b is the corpus that proves it. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/canonicalize.mdx b/docs/docs/reference/api/canonicalize.mdx deleted file mode 100644 index 5dcccd5..0000000 --- a/docs/docs/reference/api/canonicalize.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: "canonicalize" -description: "Return the canonical form of an Action: UTF-8 JSON, sorted keys, no whitespace." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.canonicalize` — function, defined at `src/ctrlrun/action.py:308` - -```python -from ctrlrun import canonicalize -``` - - -```python -def canonicalize(action: Action) -> bytes -``` - -Return the canonical form of an Action: UTF-8 JSON, sorted keys, no whitespace. - -`action_id` and timestamps are excluded; the schema tag is included (SPEC-v0.1 §2.2). The -encoding is `canonical_bytes`'s, and calling through is what makes that one implementation -rather than two (SPEC-v0.6 §6.2). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/conformance-run.mdx b/docs/docs/reference/api/conformance-run.mdx deleted file mode 100644 index ded0281..0000000 --- a/docs/docs/reference/api/conformance-run.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "run" -description: "Drive every suite through `adapter` and report what each came to (SPEC-v0.5 §5)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.conformance.run` — function, defined at `src/ctrlrun/conformance/suites.py:1083` - -```python -from ctrlrun.conformance import run -``` - - -```python -def run(adapter: ConformanceAdapter, deployment: Control | None = None) -> ConformanceReport -``` - -Drive every suite through `adapter` and report what each came to (SPEC-v0.5 §5). - -`deployment` is the operator's `Control`, where the kit is being run inside one. **The -suites do not run against it.** They run against scratch `Control`s the kit builds, for the -reason `v0.4 §3.5` gives about verify: a kit that reserved a real effect key would be a -defect of exactly the class it exists to find. The one thing read from it is the mode, and -an observing one is **refused** -- no suites, no denominator, `ok` is `False` -- because -running the suites in a synthetic enforce mode would report guarantees about a configuration -nobody deployed, and running them as-is would report a wall of failures that are true and -useless (§3.6). - -A case that raises out of its own body is reported as a failed case naming the exception, -never as a crashed run: one broken suite must not be able to hide the eight that worked. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/conformance-store-run.mdx b/docs/docs/reference/api/conformance-store-run.mdx deleted file mode 100644 index abef2f5..0000000 --- a/docs/docs/reference/api/conformance-store-run.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "run" -description: "Drive every case against `backend` and report what each came to (SPEC-v0.6 §2)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.conformance.store.run` — function, defined at `src/ctrlrun/conformance/store/__init__.py:52` - -```python -from ctrlrun.conformance.store import run -``` - - -```python -def run(backend: StoreBackend, *, only: Sequence[str] = (), processes: int = CONTENDERS) -> StoreReport -``` - -Drive every case against `backend` and report what each came to (SPEC-v0.6 §2). - -`only` selects case ids; an unknown name **raises** rather than silently running everything -or nothing. It is a keyword and not a CLI flag -- §9.4 adds no command, so there is nothing -for an unknown name to exit from. - -`processes` is how many contenders the two E1 cases run, in threads and in OS processes -respectively. It is `v0.1 §7` T3's eight by default. A review found it named in §2.4, §9.1 -and T143 while the code used a module constant, so the parameter that the specification -freezes did not exist. - -Every case gets a freshly `reset()` backend, so no case can see another's rows. A case that -raises out of its own body is reported as a failed case naming the exception, never as a -crashed run: one broken case must not hide the twenty that worked. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/context.mdx b/docs/docs/reference/api/context.mdx deleted file mode 100644 index 75f3a0f..0000000 --- a/docs/docs/reference/api/context.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "context" -description: "Bind the principal for calls made inside the block." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.context` — function, defined at `src/ctrlrun/control.py:140` - -```python -from ctrlrun import context -``` - - -```python -def context(agent: str, user: str | None = None) -> Iterator[None] -``` - -Bind the principal for calls made inside the block. - -A protected function called outside any `context()` has no principal and is denied -(SPEC-v0.1 §2.1). - -**`environment` was a parameter here until v0.3** and is gone (SPEC-v0.3 §2.5). A grant may -scope to an environment, which makes it an authorization input, and an authorization -dimension the subject sets is not one — the same argument that removes -`--principal-from-client-info` from the gateway. It is set once on the `Control` now, so -every Action a deployment proposes carries the deployment's own answer. - -Where an `IdentityProvider` is installed, the principal named here is a **hint** rather than -an identity: the provider wins where it answers (§3.2). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/gateway-serve.mdx b/docs/docs/reference/api/gateway-serve.mdx deleted file mode 100644 index 4798cb7..0000000 --- a/docs/docs/reference/api/gateway-serve.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "serve" -description: "Run a gateway in front of one upstream MCP server (SPEC-v0.2 §6.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.gateway.serve` — function, defined at `src/ctrlrun/gateway/__init__.py:41` - -```python -from ctrlrun.gateway import serve -``` - -Needs the `gateway` extra: `pip install "ctrlrun[gateway]"`. Importing it without that raises `MissingDependency` carrying the install command. - - -```python -def serve(*, upstream: str, alias: str, **options: Any) -> None -``` - -Run a gateway in front of one upstream MCP server (SPEC-v0.2 §6.1). - -The dependency check happens first and unconditionally, so an operator who has not -installed the extra learns it from one clear line rather than from a stack trace. - -Blocks until interrupted. `Control.from_file()` finds the policy and the store, so a -gateway and a decorator-based worker sharing a policy share reservations (§6.1). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/index.mdx b/docs/docs/reference/api/index.mdx deleted file mode 100644 index a31bfcd..0000000 --- a/docs/docs/reference/api/index.mdx +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: "Python API" -description: "Every frozen public name of the ctrlrun package and its extras, one page each, rendered from the docstrings." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -The names below are the ones the specifications freeze: `ctrlrun.__all__`, the entry -points of the extras, and `ctrlrun.verify.run`. Each page is rendered from the docstring; -a name with no docstring fails a test, so every page has one. - -| Name | Kind | Summary | -|---|---|---| -| [`ctrlrun.Action`](/docs/reference/api/Action) | class | A proposed agent action: what, with which arguments, by whom, on what. | -| [`ctrlrun.ActionDenied`](/docs/reference/api/ActionDenied) | class | The action may not run. `reason` says why, e.g. `unknown_action` (SPEC-v0.1 §3.4). | -| [`ctrlrun.AmbiguousEffect`](/docs/reference/api/AmbiguousEffect) | class | The outcome of this effect is unknown; only a human may resolve it (SPEC-v0.1 §5.4). | -| [`ctrlrun.Approval`](/docs/reference/api/Approval) | class | A human's grant, bound to one `action_hash` (SPEC-v0.1 §4.1). | -| [`ctrlrun.ApprovalAnswer`](/docs/reference/api/ApprovalAnswer) | class | A human's answer, and who gave it (SPEC-v0.5 §2.2, §3.4). | -| [`ctrlrun.ApprovalMismatch`](/docs/reference/api/ApprovalMismatch) | class | The presented approval does not authorize this action (SPEC-v0.1 §4.2). | -| [`ctrlrun.ApprovalProvider`](/docs/reference/api/ApprovalProvider) | class | How a human is asked, and how the answer comes back (SPEC-v0.1 §4.3). | -| [`ctrlrun.ApprovalRequest`](/docs/reference/api/ApprovalRequest) | class | A pending question for a human: may this exact action run? (SPEC-v0.1 §4.1) | -| [`ctrlrun.ApprovalRequired`](/docs/reference/api/ApprovalRequired) | class | The action needs a human. `request_id` is what `ctrlrun approve` takes (SPEC §4.3). | -| [`ctrlrun.ApprovalTimeout`](/docs/reference/api/ApprovalTimeout) | class | Nobody answered the approval request in time (SPEC-v0.1 §4.3). | -| [`ctrlrun.Authority`](/docs/reference/api/Authority) | class | The `authority:` section, loaded and evaluable (SPEC-v0.3 §4). | -| [`ctrlrun.AuthorityDenied`](/docs/reference/api/AuthorityDenied) | class | The principal holds no grant that covers this action (SPEC-v0.3 §4.3). | -| [`ctrlrun.AuthorityEscalation`](/docs/reference/api/AuthorityEscalation) | class | A delegation that may not exist: it is not contained in its parent (SPEC-v0.3 §5.3). | -| [`ctrlrun.AuthorityResult`](/docs/reference/api/AuthorityResult) | class | What the authority axis decided, and which grant it decided on (§4.8). | -| [`ctrlrun.CTRLRunError`](/docs/reference/api/CTRLRunError) | class | Base class for every error raised by CTRLRun. | -| [`ctrlrun.Condition`](/docs/reference/api/Condition) | class | One `<argument>_<op>: operand` test against an action's arguments (SPEC-v0.1 §3.2). | -| [`ctrlrun.Control`](/docs/reference/api/Control) | class | Policy, state and evidence composed around a single action (SPEC-v0.1 §8). | -| [`ctrlrun.Decision`](/docs/reference/api/Decision) | class | What may happen to an action: exactly three outcomes in v0.1 (SPEC-v0.1 §3.3). | -| [`ctrlrun.Delegation`](/docs/reference/api/Delegation) | class | A grant created at runtime by a principal who already holds one (SPEC-v0.3 §5.1). | -| [`ctrlrun.DelegationRecord`](/docs/reference/api/DelegationRecord) | class | One row of the `delegations` table (SPEC-v0.3 §5.2). | -| [`ctrlrun.DuplicateEffect`](/docs/reference/api/DuplicateEffect) | class | This logical effect already happened, or is happening now (SPEC-v0.1 §5.4). | -| [`ctrlrun.EffectKeyError`](/docs/reference/api/EffectKeyError) | class | An effect template cannot be resolved to a key (SPEC-v0.1 §5.1). | -| [`ctrlrun.EffectRecord`](/docs/reference/api/EffectRecord) | class | What a StateStore holds for one effect key (ARCHITECTURE §5). | -| [`ctrlrun.EffectState`](/docs/reference/api/EffectState) | class | Where a logical effect stands (SPEC-v0.1 §5.2). | -| [`ctrlrun.Event`](/docs/reference/api/Event) | class | One ordered step in the life of an action (SPEC-v0.1 §6.2). | -| [`ctrlrun.EventSink`](/docs/reference/api/EventSink) | class | Somewhere a copy of every `Event` and `Receipt` goes (SPEC-v0.2 §4.1). | -| [`ctrlrun.FrameworkInterrupt`](/docs/reference/api/FrameworkInterrupt) | class | One framework's human-in-the-loop primitive, and nothing else (SPEC-v0.5 §2.1). | -| [`ctrlrun.Grant`](/docs/reference/api/Grant) | class | One permission: this subject may propose these actions, under these limits (§4.2). | -| [`ctrlrun.HeaderIdentityProvider`](/docs/reference/api/HeaderIdentityProvider) | class | The principal named by a trusted HTTP header (§3.3). | -| [`ctrlrun.IdentityContext`](/docs/reference/api/IdentityContext) | class | What a provider is told about the call it is resolving a principal for (§3.1). | -| [`ctrlrun.IdentityError`](/docs/reference/api/IdentityError) | class | A credential was offered and rejected (SPEC-v0.3 §3.2). | -| [`ctrlrun.IdentityProvider`](/docs/reference/api/IdentityProvider) | class | Resolves the principal for one action (SPEC-v0.3 §3.1). | -| [`ctrlrun.InMemoryStateStore`](/docs/reference/api/InMemoryStateStore) | class | Everything held in process memory: for tests and `ctrlrun demo`. | -| [`ctrlrun.InterruptApprovalProvider`](/docs/reference/api/InterruptApprovalProvider) | class | An `ApprovalProvider` whose `wait()` routes through a framework's own primitive. | -| [`ctrlrun.InvalidArgument`](/docs/reference/api/InvalidArgument) | class | An argument cannot be accepted as given. | -| [`ctrlrun.JSONLEventSink`](/docs/reference/api/JSONLEventSink) | class | The JSONL half of the evidence: two append-only files in one directory (SPEC §6). | -| [`ctrlrun.LocalApprovalProvider`](/docs/reference/api/LocalApprovalProvider) | class | Requests go to the StateStore; `wait()` polls it (SPEC-v0.1 §4.3). | -| [`ctrlrun.MissingDependency`](/docs/reference/api/MissingDependency) | class | An optional extra is not installed (SPEC-v0.2 §1.1, §11). | -| [`ctrlrun.NotExecuted`](/docs/reference/api/NotExecuted) | class | Raised by an executor to assert the remote side did nothing (SPEC-v0.1 §5.5). | -| [`ctrlrun.PendingApproval`](/docs/reference/api/PendingApproval) | class | What the framework's interrupt is handed, and the only thing it is (SPEC-v0.5 §2.3). | -| [`ctrlrun.Policy`](/docs/reference/api/Policy) | class | Action-level autonomy policy: which actions may run, and under which conditions. | -| [`ctrlrun.PolicyError`](/docs/reference/api/PolicyError) | class | The policy is missing, unreadable, or malformed. Raised at load time (SPEC-v0.1 §3.4). | -| [`ctrlrun.Principal`](/docs/reference/api/Principal) | class | Who is acting: an agent, optionally on behalf of a human. | -| [`ctrlrun.Receipt`](/docs/reference/api/Receipt) | class | Portable evidence of one action that reached a terminal state (SPEC-v0.1 §6.1). | -| [`ctrlrun.ReconcileOutcome`](/docs/reference/api/ReconcileOutcome) | attribute | What a `reconcile` hook may answer about an effect key (SPEC-v0.2 §2). | -| [`ctrlrun.SQLiteStateStore`](/docs/reference/api/SQLiteStateStore) | class | Approvals, effects and evidence in one SQLite file (ARCHITECTURE §5). | -| [`ctrlrun.SchemaMismatch`](/docs/reference/api/SchemaMismatch) | class | A store met a database it does not recognise, in either direction (SPEC-v0.6 §3.3). | -| [`ctrlrun.ScriptedApprovalProvider`](/docs/reference/api/ScriptedApprovalProvider) | class | A human replaced by a fixed script: for tests and `ctrlrun demo` (SPEC-v0.1 §4.3). | -| [`ctrlrun.StateStore`](/docs/reference/api/StateStore) | class | Durable state behind a `Control` (SPEC-v0.1 §5.3): approvals, effects, evidence. | -| [`ctrlrun.StaticIdentityProvider`](/docs/reference/api/StaticIdentityProvider) | class | A fixed principal, for development, tests and single-tenant demonstrations (§3.3). | -| [`ctrlrun.Subject`](/docs/reference/api/Subject) | class | Who a grant is addressed to: an agent pattern, a user pattern, or both (§4.2). | -| [`ctrlrun.Suspended`](/docs/reference/api/Suspended) | class | Raised by an executor: the remote asked for something before it will finish. | -| [`ctrlrun.WebhookApprovalProvider`](/docs/reference/api/WebhookApprovalProvider) | class | Notify a human system on `APPROVAL_REQUESTED`, and let it answer (SPEC-v0.2 §7). | -| [`ctrlrun.action_hash`](/docs/reference/api/action_hash) | function | Return the action hash used to bind approvals to an exact action (SPEC-v0.1 §2.3). | -| [`ctrlrun.banner`](/docs/reference/api/banner) | function | Log SPEC-v0.3 §6.5's observe banner, once per `Control`. An adapter MUST call it (§3.6). | -| [`ctrlrun.canonical_bytes`](/docs/reference/api/canonical_bytes) | function | The canonical form of an arbitrary mapping: UTF-8 JSON, sorted keys, no whitespace. | -| [`ctrlrun.canonicalize`](/docs/reference/api/canonicalize) | function | Return the canonical form of an Action: UTF-8 JSON, sorted keys, no whitespace. | -| [`ctrlrun.context`](/docs/reference/api/context) | function | Bind the principal for calls made inside the block. | -| [`ctrlrun.needs_approval`](/docs/reference/api/needs_approval) | function | Does this call need a human? For a framework that asks before it invokes (SPEC-v0.5 §3.5). | -| [`ctrlrun.parse_conditions`](/docs/reference/api/parse_conditions) | function | Parse a `when:`-shaped mapping into conditions, keyed by the raw condition key. | -| [`ctrlrun.protect`](/docs/reference/api/protect) | function | Bind a function to an action name: every call becomes a decided, recorded Action. | -| [`ctrlrun.with_approval`](/docs/reference/api/with_approval) | function | Present a granted approval to the calls made inside the block (SPEC-v0.1 §4.3). | -| [`ctrlrun.postgres.PostgresStateStore`](/docs/reference/api/postgres-PostgresStateStore) | class | Approvals, effects and evidence in a Postgres schema (SPEC-v0.6 §4). | -| [`ctrlrun.otel.OTelEventSink`](/docs/reference/api/otel-OTelEventSink) | class | Export every `Event` and `Receipt` as OpenTelemetry spans (SPEC-v0.2 §8). | -| [`ctrlrun.jwt_identity.JWTIdentityProvider`](/docs/reference/api/jwt_identity-JWTIdentityProvider) | class | Verify a bearer JWT and map its verified claims onto a `Principal` (SPEC-v0.3 §3.4). | -| [`ctrlrun.acs.AcsControlHook`](/docs/reference/api/acs-AcsControlHook) | class | Answer ACS `steps/*` hooks with CTRLRun's decisions and outcomes. | -| [`ctrlrun.gateway.serve`](/docs/reference/api/gateway-serve) | function | Run a gateway in front of one upstream MCP server (SPEC-v0.2 §6.1). | -| [`ctrlrun.verify.run`](/docs/reference/api/verify-run) | function | Run the applicable guarantees against this configuration and report (§9.1). | -| [`ctrlrun.conformance.run`](/docs/reference/api/conformance-run) | function | Drive every suite through `adapter` and report what each came to (SPEC-v0.5 §5). | -| [`ctrlrun.conformance.store.run`](/docs/reference/api/conformance-store-run) | function | Drive every case against `backend` and report what each came to (SPEC-v0.6 §2). | - -## Next - -- [CLI reference](/docs/reference/cli). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/jwt_identity-JWTIdentityProvider.mdx b/docs/docs/reference/api/jwt_identity-JWTIdentityProvider.mdx deleted file mode 100644 index 251e155..0000000 --- a/docs/docs/reference/api/jwt_identity-JWTIdentityProvider.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "JWTIdentityProvider" -description: "Verify a bearer JWT and map its verified claims onto a `Principal` (SPEC-v0.3 §3.4)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.jwt_identity.JWTIdentityProvider` — class, defined at `src/ctrlrun/jwt_identity.py:87` - -```python -from ctrlrun.jwt_identity import JWTIdentityProvider -``` - -Needs the `identity` extra: `pip install "ctrlrun[identity]"`. Importing it without that raises `MissingDependency` carrying the install command. - - -```python -class JWTIdentityProvider - def __init__(*, jwks_url: str | None = None, public_key: str | None = None, secret: str | None = None, algorithms: Sequence[str], issuer: str, audience: str, token_type: str | None, header: str = DEFAULT_HEADER, agent_claim: str = DEFAULT_AGENT_CLAIM, user_claim: str | None = None, claim_names: Sequence[str] = (), leeway: timedelta = DEFAULT_LEEWAY, jwks_min_refresh_interval: timedelta = DEFAULT_JWKS_MIN_REFRESH, http_timeout: timedelta = DEFAULT_HTTP_TIMEOUT, clock: Callable[[], datetime] = _utc_now) -``` - -Verify a bearer JWT and map its verified claims onto a `Principal` (SPEC-v0.3 §3.4). - -Absent header → `None`, a **decline** (§3.2): in-process there are no headers at all, and -a provider with nothing to say must not break code that already uses `context()`. Present -and invalid → `IdentityError`, a **refusal**, which `Control` never backfills from. - -Every configuration mistake that can be caught before a token is seen is caught at -construction, because that is the end that can be refused: the token end is already -covered by the `algorithms` allow-list, and a check that only existed there would be a -negative test against behaviour the library refuses anyway. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/needs_approval.mdx b/docs/docs/reference/api/needs_approval.mdx deleted file mode 100644 index 9a47a88..0000000 --- a/docs/docs/reference/api/needs_approval.mdx +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: "needs_approval" -description: "Does this call need a human? For a framework that asks before it invokes (SPEC-v0.5 §3.5)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.needs_approval` — function, defined at `src/ctrlrun/adapter.py:408` - -```python -from ctrlrun import needs_approval -``` - - -```python -def needs_approval(control: Control, action: str, arguments: Mapping[str, Any], *, resource: str | None = None) -> bool -``` - -Does this call need a human? For a framework that asks before it invokes (SPEC-v0.5 §3.5). - -The OpenAI Agents SDK's shape: the framework asks whether a tool call needs approval -*before* it invokes the tool, surfaces its own approval item, and invokes only after a human -answers. This answers that question and nothing else -- `True` iff the combined -SPEC-v0.3 §4.6 decision is `APPROVE`. - -It is core's rather than each adapter's because the only way to write it in an adapter was -to build an `Action`, and `Action.principal` has no default: the principal would have come -from the framework's session, which is the one thing §4.2 forbids. Here it comes from -`Control.resolve_principal`, exactly as it does at every other entry point. - -**It writes nothing**: no event, no receipt, no request, no reservation. A framework may -call its predicate more than once, and a predicate that left evidence behind would put a -proposal in the log for every time the framework wondered. - -A `DENY` returns `False`, so the tool is invoked and `Control.execute` denies it with a -receipt, an `ACTION_DENIED` and the exception the caller catches. Refusing here would refuse -without evidence, and SPEC-v0.3 §4.3 is explicit that a denial with a principal to attribute -it to belongs in the evidence log. - -`resource` is a template over `arguments`, as `@protect`'s is (v0.1 §5.1), and the policy's -`resource:` is used where none is given -- the same precedence `@protect` applies. It -matters: authority matches on resource patterns (SPEC-v0.3 §4.2), so a predicate that -skipped it would evaluate a different action from the one that runs. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/otel-OTelEventSink.mdx b/docs/docs/reference/api/otel-OTelEventSink.mdx deleted file mode 100644 index 6338d0c..0000000 --- a/docs/docs/reference/api/otel-OTelEventSink.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "OTelEventSink" -description: "Export every `Event` and `Receipt` as OpenTelemetry spans (SPEC-v0.2 §8)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.otel.OTelEventSink` — class, defined at `src/ctrlrun/otel.py:45` - -```python -from ctrlrun.otel import OTelEventSink -``` - -Needs the `otel` extra: `pip install "ctrlrun[otel]"`. Importing it without that raises `MissingDependency` carrying the install command. - - -```python -class OTelEventSink - def __init__(*, tracer_provider: Any = None, arguments: bool = False, max_open_spans: int = DEFAULT_MAX_OPEN_SPANS) -``` - -Export every `Event` and `Receipt` as OpenTelemetry spans (SPEC-v0.2 §8). - -**Never blocks.** Spans are handed to whatever span processor the application configured -and nothing is flushed synchronously; with no configured tracer provider the API's no-op -provider makes the whole thing free. A process that dies mid-action leaves that span -unended — stated, not solved. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/parse_conditions.mdx b/docs/docs/reference/api/parse_conditions.mdx deleted file mode 100644 index 02ee7d2..0000000 --- a/docs/docs/reference/api/parse_conditions.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "parse_conditions" -description: "Parse a `when:`-shaped mapping into conditions, keyed by the raw condition key." ---- - -{/* 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:980` - -```python -from ctrlrun import parse_conditions -``` - - -```python -def parse_conditions(mapping: Mapping[Any, Any], *, where: str, allow_derived: bool = False) -> Mapping[str, Condition] -``` - -Parse a `when:`-shaped mapping into conditions, keyed by the raw condition key. - -Public since SPEC-v0.3 §11: a grant's `constraints:` is in exactly this syntax and MUST be -parsed by this code (§4.5). The key is injective given §3.2's longest-suffix split, which -is what lets `Grant`'s containment check look a dimension up by name. - -`allow_derived` admits §7.4's derived subjects and **defaults to off**, so `authority.py` -- -which calls this without it — sees exactly the surface it saw in v0.3. A grant naming -`data_scope` is refused as it always was, which is what keeps §11's *"matching a grant on a -data label"* out of v0.6 rather than letting it in through a shared parser. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/postgres-PostgresStateStore.mdx b/docs/docs/reference/api/postgres-PostgresStateStore.mdx deleted file mode 100644 index 6a3e926..0000000 --- a/docs/docs/reference/api/postgres-PostgresStateStore.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: "PostgresStateStore" -description: "Approvals, effects and evidence in a Postgres schema (SPEC-v0.6 §4)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.postgres.PostgresStateStore` — class, defined at `src/ctrlrun/postgres.py:218` - -```python -from ctrlrun.postgres import PostgresStateStore -``` - -Needs the `postgres` extra: `pip install "ctrlrun[postgres]"`. Importing it without that raises `MissingDependency` carrying the install command. - - -```python -class PostgresStateStore - def __init__(url: str, *, clock: Callable[[], datetime] = _utc_now, schema: str = 'public') -``` - -Approvals, effects and evidence in a Postgres schema (SPEC-v0.6 §4). - -One connection per thread, as `SQLiteStateStore` does: `psycopg` connections are not -thread-safe, and the thread-local shape is the one `close()` is already specified against -(§2.7). - -**A connection outlives the thread that opened it, and that is a real limit worth stating.** -A host running agents on a *bounded, recycled* thread pool is fine -- the same threads keep -reusing the same connections. A host that starts a fresh thread per unit of work accumulates -one connection per thread that ever touched the store, and Postgres connections are far -scarcer than SQLite file handles: `max_connections` defaults to 100. `close()` releases every -one, so the mitigation is to close a store you are done with. The conformance suite met this -for real -- ninety-six connections across twelve rounds of eight threads -- and the failure -surfaced in a case that had nothing to do with it. - -No pool ships. An operator may put pgbouncer in front in **transaction** mode, and it works -because this store holds nothing session-scoped: no advisory lock, no temp table, no prepared -statement it depends on surviving, no `SET`. That is the second reason §4.2.1 rejected -advisory locks, and it is a property worth keeping deliberately rather than by luck. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/protect.mdx b/docs/docs/reference/api/protect.mdx deleted file mode 100644 index 6d385ee..0000000 --- a/docs/docs/reference/api/protect.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: "protect" -description: "Bind a function to an action name: every call becomes a decided, recorded Action." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.protect` — function, defined at `src/ctrlrun/control.py:2006` - -```python -from ctrlrun import protect -``` - - -```python -def protect(name: str, *, effect: str | None = None, resource: str | None = None, wait: bool = False, lease: timedelta | None = None, reconcile: Callable[[str], ReconcileOutcome] | None = None, reconcile_eagerly: bool = False, control: Control | None = None) -> Callable[[Callable[P, R]], Callable[P, R]] -``` - -Bind a function to an action name: every call becomes a decided, recorded Action. - -The wrapped function is the executor (SPEC-v0.1 §5.5), and it is invoked with the -action's canonical arguments, never with the caller's own objects (§2.2). - -`effect` and `resource` are templates over the call's arguments (§5.1). Their syntax is -checked here, at decoration time, so a typo fails at import rather than mid-agent-run. - -`lease` is how long this action's reservation is held (§5.3 E3), for work that takes -longer than the Control's default; it overrides that default and nothing else. Expiry -means what it always meant: past the lease the effect is `AMBIGUOUS`, never released. - -`reconcile` asks the remote what happened to an effect whose outcome is unknown -(SPEC-v0.2 §2). With `reconcile_eagerly`, it also runs immediately after this call -produces an `AMBIGUOUS` outcome, rather than only when one blocks a later attempt. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/verify-run.mdx b/docs/docs/reference/api/verify-run.mdx deleted file mode 100644 index 9a8b618..0000000 --- a/docs/docs/reference/api/verify-run.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "run" -description: "Run the applicable guarantees against this configuration and report (§9.1)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.verify.run` — function, defined at `src/ctrlrun/verify/__init__.py:154` - -```python -from ctrlrun.verify import run -``` - - -```python -def run(config: str | os.PathLike[str] | None = None, *, authority: str | os.PathLike[str] | None = None, only: Sequence[str] = (), store_url: str | None = None) -> Report -``` - -Run the applicable guarantees against this configuration and report (§9.1). - -Raises `VerifyRefused` where the configuration is refused or unusable (exit 2) and -`VerifyInternalError` where verify itself is at fault (exit 3). Everything else — a -guarantee that failed, a guarantee that could not be exercised — is in the `Report`. - -The scratch directory is removed when the run ends, **including when it ends by -exception**. The operator's store is not opened, not read and not created (§3.5, T103). - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/api/with_approval.mdx b/docs/docs/reference/api/with_approval.mdx deleted file mode 100644 index e5e0e58..0000000 --- a/docs/docs/reference/api/with_approval.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "with_approval" -description: "Present a granted approval to the calls made inside the block (SPEC-v0.1 §4.3)." ---- - -{/* generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page */} - -`ctrlrun.with_approval` — function, defined at `src/ctrlrun/control.py:163` - -```python -from ctrlrun import with_approval -``` - - -```python -def with_approval(request_id: str) -> Iterator[None] -``` - -Present a granted approval to the calls made inside the block (SPEC-v0.1 §4.3). - -The approval still has to match: it authorizes the exact action a human saw, once, and -only until it expires. Presenting it is an offer, not a decision. - -## Next - -- [Python API index](/docs/reference/api/index). -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/authority-yaml.mdx b/docs/docs/reference/authority-yaml.mdx deleted file mode 100644 index 8d3c73f..0000000 --- a/docs/docs/reference/authority-yaml.mdx +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: "Authority YAML reference" -description: "Every key of the authority: section: max_delegation_depth and grants, and on a grant id, subject (agent, user), actions, resources, constraints." ---- - -The `authority:` section says which principal may propose which action. It lives at the top of -`ctrlrun.yaml` from `ctrlrun.policy/v3`, or in a standalone document passed with `--authority` -whose only keys are `schema` and `authority`. It is opt-in and then fail-closed: absent, nothing -changes; present, every principal needs a matching grant and no grant means denied. A test -asserts this page names every key the loader accepts. - -## The section - -| Key | Type | Default | Notes | -|---|---|---|---| -| `max_delegation_depth` | non-negative integer | `3` | how long a chain of delegations may be; recomputed on every evaluation by walking to the root, never read from the stored row | -| `grants` | list of grants | **error** if missing | the whole of who may ask | - -## A grant - -| Key | Type | When omitted | Notes | -|---|---|---|---| -| `id` | string, unique | **error** | what a delegation names as its parent and what receipts cite | -| `subject` | `{agent, user}` | **error** | who the grant is for; at least one of `agent` and `user`. Both absent is refused, because a subject matching every principal is not one anybody writes on purpose. *Any agent* is spelled `agent: "*"`, which greps | -| `actions` | list of action-name patterns | **error** | `stripe.refund`, or `stripe.*` | -| `resources` | list of resource patterns | any resource | `payment:*`, `payment:EU-*`; matched against the action's resolved `resource` template | -| `constraints` | map of condition → operand | no value limit | the same seven operators as a policy rule, over the action's arguments; `amount_lte: 10000000` | -| `environments` | list of environment names | any environment | `production`, `staging` | -| `delegable` | `true` or `false` | `false` | whether the holder may narrow this grant at runtime with `ctrlrun delegate`; `true` **requires** `expires_at` | -| `expires_at` | ISO-8601 timestamp with an offset | never expires | checked at every evaluation, and refused as a naive datetime | - -A grant carries no `decision:`. How much autonomy an action has is the policy's answer, the same -for everyone; the grant answers whether this principal may ask at all. - -```yaml runnable -schema: ctrlrun.policy/v3 - -authority: - max_delegation_depth: 3 - grants: - - id: head-of-support - subject: { agent: "head-of-support", user: "dana@example.com" } - actions: ["stripe.refund", "stripe.refund.partial"] - resources: ["payment:*"] - constraints: { amount_gte: 0, amount_lte: 10000000 } - environments: ["production"] - delegable: true - expires_at: "2027-01-01T00:00:00Z" - - id: reconciliation - subject: { agent: "reconciliation-agent" } - actions: ["stripe.charge.read", "stripe.refund.read"] - resources: ["payment:*"] - environments: ["production", "staging"] - -actions: - stripe.refund: - effect: "refund:{payment_id}" - resource: "payment:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 100000 } - decision: allow - - decision: approve - stripe.refund.partial: - effect: "refund:{payment_id}:{line_item}" - resource: "payment:{payment_id}" - decision: approve - stripe.charge.read: - decision: allow - stripe.refund.read: - decision: allow -``` - -## How a grant matches - -A grant covers an action when the subject matches the principal, the action name matches one -of `actions`, the resolved resource matches one of `resources`, the environment is in -`environments`, every constraint holds over the arguments, and `expires_at` has not passed. -Every failing reason is collected and the reported one follows a fixed order, so the evidence -for a configuration does not depend on the order grants appear in the file. Where several -grants match, the receipt names the lowest id. - -## Delegation - -`ctrlrun delegate --parent <id> --file grant.yaml --as AGENT[/USER]` writes a delegated grant -beneath a `delegable` one. The file has the keys above minus `id`. It is accepted only if it is -provably a subset of its parent on every dimension, at creation and again at every evaluation: - -- a narrower or equal subject (never a wildcard, never dropping the parent's `user`); -- `actions`, `resources`, `environments` each a subset; -- `constraints` no looser on any argument; -- `expires_at` no later than the parent's. - -**Omitting a dimension the parent constrains is rejected, not inherited.** A child that leaves -out `resources:` would authorize resources its parent never could. `ctrlrun revoke <id>` cuts a -chain of any depth with one write and is not reversible. - -## What the section does not do - -It does not authenticate anybody: the principal comes from the identity provider, and `--as` on -the command line is an assertion recorded as `created_via: cli`. It does not match on a token -claim, does not propagate across an agent-to-agent hop, and does not hot-reload: revocation and -expiry are live, an edited file takes effect when the process next loads it. - -## Next - -- [Authority and delegation](/docs/concepts/authority-and-delegation): the concept. -- [Policy YAML reference](/docs/reference/policy-yaml): the other axis. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/cli.mdx b/docs/docs/reference/cli.mdx deleted file mode 100644 index 3f7eb2f..0000000 --- a/docs/docs/reference/cli.mdx +++ /dev/null @@ -1,411 +0,0 @@ ---- -title: "CLI reference" -description: "Every ctrlrun command and option, from the command's own help text: init, demo, approve, deny, receipts, effects, resolve, inspect, stats, scan, verify." ---- - -{/* generated by tools/docs_audit/render_cli.py from click's help text — edit the command docstrings, never this page */} - -The `ctrlrun` command reads the policy in the working directory (`ctrlrun.yaml`, or the -file `$CTRLRUN_CONFIG` names) and the store beside it, `.ctrlrun/state.db`, unless -`--store-url` or `$CTRLRUN_STORE_URL` names another. A command that reads evidence creates -nothing and migrates nothing. Each section below is the command's own `--help`, verbatim. - -## ctrlrun - -```text -Usage: ctrlrun [OPTIONS] COMMAND [ARGS]... - - CTRLRun — the execution safety layer for AI agents. - -Options: - --version Show the version and exit. - --help Show this message and exit. - -Commands: - approve Grant a pending approval request. - delegate Create a delegated grant beneath an existing one. - demo Run the five scenarios, in process, with no network. - deny Refuse a pending approval request. - effects Show the logical effects this store knows about. - gateway Front an MCP server, applying this directory's policy to... - init Write a starter ctrlrun.yaml and create .ctrlrun/. - inspect Show one action's whole history: proposal, decision,... - mcp-operator Answer approvals from an MCP client, over loopback... - receipts Show the receipts this store holds. - resolve Say what actually happened to an effect with an unknown... - revoke Revoke a delegation, and with it every delegation beneath it. - scan Report the consequential call sites and policy entries... - stats Count what this store's receipts say, from the local store... - verify Run the declared guarantees against this configuration... -``` - -## ctrlrun init - -```text -Usage: ctrlrun init [OPTIONS] - - Write a starter ctrlrun.yaml and create .ctrlrun/. - -Options: - --help Show this message and exit. -``` - -## ctrlrun demo - -```text -Usage: ctrlrun demo [OPTIONS] - - Run the five scenarios, in process, with no network. - -Options: - --help Show this message and exit. -``` - -## ctrlrun approve - -```text -Usage: ctrlrun approve [OPTIONS] REQUEST_ID - - Grant a pending approval request. - -Options: - --store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the - SQLite database beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun deny - -```text -Usage: ctrlrun deny [OPTIONS] REQUEST_ID - - Refuse a pending approval request. - -Options: - --store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the - SQLite database beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun receipts - -```text -Usage: ctrlrun receipts [OPTIONS] - - Show the receipts this store holds. - -Options: - --last INTEGER RANGE Show only the last N. [x>=1] - --json Print the portable receipt JSON. - --verify-chain Check the receipt chain and report every break by seq - and by name. - --control ID Show only receipts citing this control id (SPEC-v0.6 - §7.3). - --store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the - SQLite database beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun effects - -```text -Usage: ctrlrun effects [OPTIONS] - - Show the logical effects this store knows about. - -Options: - --state [new|reserved|executing|committed|failed|ambiguous] - Show only effects in this state. - --store-url TEXT The store to open. Default: - $CTRLRUN_STORE_URL, else the SQLite database - beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun resolve - -```text -Usage: ctrlrun resolve [OPTIONS] EFFECT_KEY - - Say what actually happened to an effect with an unknown outcome. - -Options: - --committed The effect did happen at the remote. - --failed The effect provably did not happen. - --store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the - SQLite database beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun inspect - -```text -Usage: ctrlrun inspect [OPTIONS] ACTION_ID - - Show one action's whole history: proposal, decision, approval, effect, - receipt. - -Options: - --json Emit one JSON object instead. - --store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the - SQLite database beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun stats - -```text -Usage: ctrlrun stats [OPTIONS] - - Count what this store's receipts say, from the local store and nothing else. - - No network, no aggregation service, no upload: this reads the SQLite file the - process it is diagnosing has been writing (SPEC-v0.3 §6.4). - -Options: - --since TEXT Count only receipts finished at or after this: an ISO-8601 - timestamp with an offset, or <n>m / <n>h / <n>d. - --json Emit one JSON object instead. - --store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the - SQLite database beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun verify - -```text -Usage: ctrlrun verify [OPTIONS] - - Run the declared guarantees against this configuration (SPEC-v0.4). - - Every scenario runs against a scratch store created and destroyed for the run. - The store an agent is using is not opened, not read and not created. - - Exit codes: 0 every applicable guarantee passed and at least one was - applicable; 1 a guarantee FAILED; 2 the configuration was refused or is - unusable — which includes `mode: observe` and a configuration in which nothing - could be exercised; 3 an internal error in verify itself. - -Options: - --authority FILE A standalone authority document, as `ctrlrun gateway - --authority` takes. - --json Emit one ctrlrun.verify/v1 document. - --junit FILE Also write a JUnit XML file for CI. - --only TEXT Comma-separated guarantee ids, e.g. G1,G3. - --store-url TEXT The backend to grade against: 'sqlite' (the default) or a - postgresql:// URL. Verify runs in a scratch store it creates - there and never opens yours. - --help Show this message and exit. -``` - -## ctrlrun delegate - -```text -Usage: ctrlrun delegate [OPTIONS] - - Create a delegated grant beneath an existing one. - - `--as` is an **assertion**, not an authentication: it supplies the creating - principal for SPEC-v0.3 §5.3 rule 4, and it is free text typed by whoever runs - the command. The record keeps `created_via="cli"` so a reader of the evidence - can tell an act from an assertion. An agent name containing '/' cannot be - written here, because `--as a/b` would otherwise be ambiguous between the - agent `a/b` acting alone and the agent `a` acting for `b`. - -Options: - --parent TEXT The grant or delegation being narrowed. [required] - --file FILE A one-grant YAML document, with the keys of SPEC-v0.3 §4.2 - minus 'id'. [required] - --as TEXT The delegating principal: AGENT or AGENT/USER. Split on the - first '/'. [required] - --json Emit one JSON object instead. - --store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the - SQLite database beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun revoke - -```text -Usage: ctrlrun revoke [OPTIONS] DELEGATION_ID - - Revoke a delegation, and with it every delegation beneath it. - - Transitive by structure and not reversible: there is no `unrevoke`, because - the operation whose safety matters is the one taken in a hurry (SPEC-v0.3 - §5.7). Revoking an already-revoked delegation is idempotent and exits 0. - -Options: - --by TEXT Who revoked it. [default: cli:local] - --store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the - SQLite database beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun mcp-operator - -```text -Usage: ctrlrun mcp-operator [OPTIONS] - - Answer approvals from an MCP client, over loopback (SPEC-mcp-operator.md). - - There is no --principal and no --allow-remote, and both absences are load- - bearing: a static principal cannot attribute an answer to a person (§3.1), and - a server whose read tools answer without a credential must not be the one that - opens a port (§2.1). - -Options: - --listen TEXT HOST:PORT. [default: 127.0.0.1:8901] - --path TEXT The MCP endpoint path. [default: /mcp] - --principal-header TEXT Take the approver's agent from this header, - set by a proxy that authenticates them. - --user-header TEXT Take the approver's name from this header. - Required with --principal-header (SPEC-mcp- - operator §3.2). - --environment TEXT The deployment this console reads. Default: - $CTRLRUN_ENVIRONMENT, else the policy - document, else production (SPEC-v0.3 §2.5). - --max-body-bytes INTEGER [default: 1048576] - --allow-origin TEXT Repeatable. - --authority FILE Load the authority: section from a separate - YAML document (SPEC-v0.3 §8.3). - --identity-jwt Verify a bearer JWT (ctrlrun[identity]). - --identity-jwt-jwks-url TEXT Fetch keys from this JWKS (HTTPS). - --identity-jwt-public-key FILE A PEM public key file. - --identity-jwt-secret-file FILE - Read the HS* shared secret from here. Never a - flag value. - --identity-jwt-algorithms TEXT Repeatable, required. There is no default and - no wildcard. - --identity-jwt-issuer TEXT Matched exactly. Required. - --identity-jwt-audience TEXT Matched by membership. Required. - --identity-jwt-token-type TEXT Required. The token's typ, e.g. at+jwt. Pass - "" for "this issuer sets no typ". - --identity-jwt-header TEXT [default: authorization] - --identity-jwt-agent-claim TEXT - [default: sub] - --identity-jwt-user-claim TEXT Which claim names the human. Required with - --identity-jwt (SPEC-mcp-operator §3.2). - --identity-jwt-claim TEXT Repeatable: which verified claims reach the - receipt. An allow-list. - --identity-jwt-leeway FLOAT [default: 60.0] - --identity-jwt-jwks-min-refresh FLOAT - [default: 30.0] - --identity-jwt-http-timeout FLOAT - [default: 5.0] - --store-url TEXT The store to open. Default: - $CTRLRUN_STORE_URL, else the SQLite database - beside the policy (.ctrlrun/state.db, or - wherever $CTRLRUN_STATE points). - --help Show this message and exit. -``` - -## ctrlrun gateway - -```text -Usage: ctrlrun gateway [OPTIONS] - - Front an MCP server, applying this directory's policy to every tools/call. - -Options: - --upstream TEXT The MCP server this gateway fronts. - [required] - --alias TEXT Names the upstream in 'mcp.<alias>.<tool>'. - [required] - --listen TEXT HOST:PORT. [default: 127.0.0.1:8900] - --path TEXT The MCP endpoint path. [default: /mcp] - --principal TEXT A fixed agent name, for one tenant. - --principal-header TEXT Take the agent from this header. - --user-header TEXT Take principal.user from this header. - --environment TEXT The deployment this gateway acts in. Default: - $CTRLRUN_ENVIRONMENT, else the policy - document, else production (SPEC-v0.3 §2.5). - --upstream-timeout FLOAT [default: 30.0] - --max-body-bytes INTEGER [default: 1048576] - --allow-origin TEXT Repeatable. - --allow-remote Permit a non-loopback --listen. - --public-url TEXT Where the gateway is reachable, for - respond_to. - --webhook-url TEXT Notify this endpoint on APPROVAL_REQUESTED. - --webhook-secret-file FILE Read the shared secret from here instead of - $CTRLRUN_WEBHOOK_SECRET. - --allow-insecure-webhook Permit an http:// webhook url, loopback only. - --authority FILE Load the authority: section from a separate - YAML document (SPEC-v0.3 §8.3). - --identity-jwt Verify a bearer JWT (ctrlrun[identity]). - --identity-jwt-jwks-url TEXT Fetch keys from this JWKS (HTTPS). - --identity-jwt-public-key FILE A PEM public key file. - --identity-jwt-secret-file FILE - Read the HS* shared secret from here. Never a - flag value: a secret on a command line is in - every process listing on the host. - --identity-jwt-algorithms TEXT Repeatable, required. There is no default and - no wildcard. - --identity-jwt-issuer TEXT Matched exactly. Required. - --identity-jwt-audience TEXT Matched by membership. Required. - --identity-jwt-token-type TEXT Required. The token's typ, e.g. at+jwt. Pass - "" for "this issuer sets no typ". - --identity-jwt-header TEXT [default: authorization] - --identity-jwt-agent-claim TEXT - [default: sub] - --identity-jwt-user-claim TEXT Which claim is principal.user. - --identity-jwt-claim TEXT Repeatable: which verified claims reach the - receipt. An allow-list. - --identity-jwt-leeway FLOAT [default: 60.0] - --identity-jwt-jwks-min-refresh FLOAT - [default: 30.0] - --identity-jwt-http-timeout FLOAT - Bounds the JWKS fetch. Deliberately not - --upstream-timeout: the fetch runs on the - request thread before any decision, so the two - must not be one knob. [default: 5.0] - --otel Export one span per action (ctrlrun[otel]). - --otel-arguments Include argument values as span attributes. - Off by default: arguments carry customer - identifiers and amounts, and a trace backend - is not the receipt store. - --help Show this message and exit. -``` - -## ctrlrun scan - -```text -Usage: ctrlrun scan [OPTIONS] - - Report the consequential call sites and policy entries nothing is covering. - - Reads Python source and a policy document as text. It never imports the tree, - never builds an action, never resolves a principal and never opens a store - (SPEC-scan §2.1, §9.2). - - It is a finder and not a proof. Every run prints what it could not look at, - and a clean scan means nothing was found where it looked. - - Exit codes: 0 nothing was found; 1 something was, including a suppressed - finding or a call whose name could not be resolved; 2 the scan could not run. - -Options: - --path DIRECTORY The tree to read. Defaults to the working directory. - --policy FILE The policy to read. Defaults to ctrlrun.yaml beside the - tree, if there is one. - --exclude TEXT A glob, relative to the tree, not to read. Repeatable. - --vocabulary TEXT A file of verbs, one per line, replacing the built-in list. - With no value, print the list in force and exit. - --json Emit one ctrlrun.scan/v1 document. - --help Show this message and exit. -``` - -## Next - -- [Exit codes](/docs/reference/exit-codes): what each command's exit status means. -- [Resolve an AMBIGUOUS effect](/docs/guides/resolve-an-ambiguous-effect): `effects`, `resolve` and `inspect` in use. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/errors.mdx b/docs/docs/reference/errors.mdx deleted file mode 100644 index 17e8b9b..0000000 --- a/docs/docs/reference/errors.mdx +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: "Errors" -description: "The closed set of CTRLRun exceptions, each with its base class and when it is raised: ActionDenied, ApprovalRequired, DuplicateEffect and the rest." ---- - -{/* generated by tools/docs_audit/render_schemas.py from the code — edit the dataclasses and docstrings, never this page */} - -Every refusal is an exception of its own, raised as itself before the executor runs, so an -agent loop can tell them apart with `except`. All of them derive from `CTRLRunError`; the -set is closed by the specification and a new one is a specification amendment first. - -| Exception | Base | Raised when | -|---|---|---| -| `CTRLRunError` | `Exception` | Base class for every error raised by CTRLRun. | -| `InvalidArgument` | `CTRLRunError` | An argument cannot be accepted as given. | -| `PolicyError` | `CTRLRunError` | The policy is missing, unreadable, or malformed. Raised at load time (SPEC-v0.1 §3.4). | -| `EffectKeyError` | `CTRLRunError` | An effect template cannot be resolved to a key (SPEC-v0.1 §5.1). | -| `ActionDenied` | `CTRLRunError` | The action may not run. `reason` says why, e.g. `unknown_action` (SPEC-v0.1 §3.4). | -| `AuthorityDenied` | `ActionDenied` | The principal holds no grant that covers this action (SPEC-v0.3 §4.3). | -| `AuthorityEscalation` | `CTRLRunError` | A delegation that may not exist: it is not contained in its parent (SPEC-v0.3 §5.3). | -| `ApprovalRequired` | `CTRLRunError` | The action needs a human. `request_id` is what `ctrlrun approve` takes (SPEC §4.3). | -| `ApprovalTimeout` | `CTRLRunError` | Nobody answered the approval request in time (SPEC-v0.1 §4.3). | -| `ApprovalMismatch` | `CTRLRunError` | The presented approval does not authorize this action (SPEC-v0.1 §4.2). | -| `DuplicateEffect` | `CTRLRunError` | This logical effect already happened, or is happening now (SPEC-v0.1 §5.4). | -| `AmbiguousEffect` | `CTRLRunError` | The outcome of this effect is unknown; only a human may resolve it (SPEC-v0.1 §5.4). | -| `NotExecuted` | `CTRLRunError` | Raised by an executor to assert the remote side did nothing (SPEC-v0.1 §5.5). | -| `Suspended` | `CTRLRunError` | Raised by an executor: the remote asked for something before it will finish. | -| `IdentityError` | `CTRLRunError` | A credential was offered and rejected (SPEC-v0.3 §3.2). | -| `SchemaMismatch` | `CTRLRunError` | A store met a database it does not recognise, in either direction (SPEC-v0.6 §3.3). | -| `MissingDependency` | `CTRLRunError` | An optional extra is not installed (SPEC-v0.2 §1.1, §11). | - -## Each one - -### CTRLRunError - -Base class for every error raised by CTRLRun. - -### InvalidArgument - -An argument cannot be accepted as given. - -An Action field or argument that cannot be canonicalized (SPEC-v0.1 §2.3), and — the -same kind of wiring bug — a StateStore transition no record can make, such as committing -an effect nobody reserved. - -### PolicyError - -The policy is missing, unreadable, or malformed. Raised at load time (SPEC-v0.1 §3.4). - -### EffectKeyError - -An effect template cannot be resolved to a key (SPEC-v0.1 §5.1). - -The action is refused rather than executed without an effect key: an action whose -logical effect cannot be identified cannot be protected against duplication. - -### ActionDenied - -The action may not run. `reason` says why, e.g. `unknown_action` (SPEC-v0.1 §3.4). - -### AuthorityDenied - -The principal holds no grant that covers this action (SPEC-v0.3 §4.3). - -A subclass of `ActionDenied`, because an authority denial *is* the action being denied and -an agent loop's existing `except ActionDenied` should keep working. `reason` is one of the -closed set in §4.3 — `no_authority`, `authority_constraint`, `authority_expired`, -`authority_escalation`, `authority_revoked`, `authority_unreadable` — never a grant id: a -grant may legally be named `no_authority`, and evidence that can be spoofed by naming a -grant is not evidence. The id travels in `grant_id`. - -### AuthorityEscalation - -A delegation that may not exist: it is not contained in its parent (SPEC-v0.3 §5.3). - -Not an `ActionDenied`: nothing was proposed. This is the creation-time vocabulary — -`containment`, `unknown_parent`, `parent_not_delegable`, `parent_not_valid`, -`not_the_subject`, `max_depth` — and it is disjoint from `AuthorityDenied`'s evaluation -reasons. The two are never used interchangeably. - -### ApprovalRequired - -The action needs a human. `request_id` is what `ctrlrun approve` takes (SPEC §4.3). - -Raised instead of blocking, so an agent loop can surface the request and come back with -`ctrlrun.with_approval(request_id)` in context. - -### ApprovalTimeout - -Nobody answered the approval request in time (SPEC-v0.1 §4.3). - -### ApprovalMismatch - -The presented approval does not authorize this action (SPEC-v0.1 §4.2). - -`reason` is one of `unknown`, `mismatch`, or the status the record was in — `consumed`, -`expired`, `pending`, `denied`. - -### DuplicateEffect - -This logical effect already happened, or is happening now (SPEC-v0.1 §5.4). - -`state` is `committed` — the effect is done — or `in_progress`, meaning another attempt -holds a live reservation on the key. Neither permits a second execution. - -### AmbiguousEffect - -The outcome of this effect is unknown; only a human may resolve it (SPEC-v0.1 §5.4). - -Raised for a record already in `AMBIGUOUS`, and for one whose lease expired mid-flight: -the worker may have died after the remote committed. A retry is refused either way, -until `ctrlrun resolve` says which it was. - -### NotExecuted - -Raised by an executor to assert the remote side did nothing (SPEC-v0.1 §5.5). - -This is the *only* exception that maps to `FAILED` and therefore permits a retry. -Every other exception is an `AMBIGUOUS` outcome. - -### Suspended - -Raised by an executor: the remote asked for something before it will finish. - -SPEC-v0.2 §6.9 in the kernel's own terms, and modelled the way v0.1 §5.5 models "nothing -happened" — an explicit opt-in signal, never a default and never inferred. There is no -outcome to record: the effect record stays `EXECUTING`, its lease is extended, the -continuation is held, and the caller gets this back to relay. - -`continuation` is whatever the remote said to present again. It is opaque here — CTRLRun -never parses it, and only ever compares it with `hmac.compare_digest`. - -### IdentityError - -A credential was offered and rejected (SPEC-v0.3 §3.2). - -Not an `ActionDenied`: an agent loop's `except ActionDenied` is written to handle a policy -saying no, and a credential that stopped being valid is not that — the same distinction -v0.1 §5.1 draws for `EffectKeyError`. A *missing* principal stays -`ActionDenied(reason="no_principal")`; this is for one that was produced and found wanting, -which includes an expired `Principal` reaching `Control.execute` (§2.3). - -### SchemaMismatch - -A store met a database it does not recognise, in either direction (SPEC-v0.6 §3.3). - -Its own type rather than an `InvalidArgument`, and the bar it clears is that an operator's -process refusing to start needs a distinguishable exception: *"your database is from the -future"* and *"your lease is negative"* have entirely different remedies, and one bucket for -both would put a schema problem behind a wiring bug. - -### MissingDependency - -An optional extra is not installed (SPEC-v0.2 §1.1, §11). - -Never `ImportError` or `ModuleNotFoundError`: an operator reads those as a broken -package rather than as an option they did not select. The message names the module that -is missing and the command that installs it. - -## Next - -- [Fail closed](/docs/concepts/fail-closed): the table of what is refused, and where. -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): `NotExecuted` and why it is the dangerous one. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/exit-codes.mdx b/docs/docs/reference/exit-codes.mdx deleted file mode 100644 index 8c45417..0000000 --- a/docs/docs/reference/exit-codes.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: "Exit codes" -description: "What each ctrlrun command's exit status means: 0 done, 1 a refusal or a failed guarantee, 2 a usage error or an unusable configuration." ---- - -Every `ctrlrun` command exits 0 when it did what it was asked, 1 when CTRLRun refused -(a `CTRLRunError`, printed as one line), and 2 on a usage error. `ctrlrun verify` adds a third -code for its own failure, because a verifier that crashed must not look like one that refused. - -## Every command - -| Code | Meaning | Examples | -|---|---|---| -| `0` | the command did what it was asked | a grant written, a receipt printed, a revocation applied (revoking an already-revoked delegation is idempotent and exits 0) | -| `1` | CTRLRun refused, and said why on one line | `resolve` on an effect that is not `AMBIGUOUS`; `approve` on a request that expired; `delegate` beyond the parent's grant; a `--store-url` naming a database this binary does not recognise | -| `2` | the command line was wrong | a missing argument, an unknown option, `resolve` without exactly one of `--committed` and `--failed` | - -A refusal is the command's exit code and its last line. Nothing is retried on the operator's -behalf and nothing is written on a refusal. - -## `ctrlrun verify` - -| Code | Meaning | -|---|---| -| `0` | every applicable guarantee passed and at least one was applicable | -| `1` | a guarantee `FAILED` | -| `2` | the configuration was refused or is unusable — which includes `mode: observe` and a configuration in which nothing could be exercised | -| `3` | an internal error in verify itself | - -Not applicable never changes the code by itself, and zero applicable guarantees is exit 2, never -0: `0/0` reported as success is the same false green as `8/8` with five N/As. A partial run -(`--only`) writes no badge. The GitHub Action fails the job on any code but 0 and carries the -code through as an output. - -## `ctrlrun scan` - -| Code | Meaning | -|---|---| -| `0` | the scan ran and found nothing of any kind | -| `1` | it found a finding, a suppressed finding, or a call whose name it could not resolve | -| `2` | it could not run: the path is not a directory, it holds no Python file, the policy will not load | - -A file that will not parse is exit `1` and not `2` — the scan ran, and the file is a finding. A -suppressed finding keeps the code at `1`, because annotating a finding does not change the code -it points at, and there is no flag that turns `1` into `0`. - -## `ctrlrun gateway` - -The gateway runs until it is stopped. It exits 2 before listening when its configuration is -refused: a non-loopback `--listen` without `--allow-remote`, an `http://` webhook without -`--allow-insecure-webhook`, a JWT option set without the identity extra, or a policy that will -not load. - -## Next - -- [CLI reference](/docs/reference/cli). -- [Errors](/docs/reference/errors): the exception behind each exit 1. -- [Verify in CI](/docs/guides/verify-in-ci) · [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/policy-yaml.mdx b/docs/docs/reference/policy-yaml.mdx deleted file mode 100644 index 5bc9197..0000000 --- a/docs/docs/reference/policy-yaml.mdx +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: "Policy YAML reference" -description: "Every key of ctrlrun.yaml, from ctrlrun.policy/v1 to v4: schema, actions, decision, rules, when conditions and their seven operators." ---- - -`ctrlrun.yaml` is one document: a `schema`, an `actions` map, and from `ctrlrun.policy/v3` the -`mode`, `environment` and `authority` keys, and from `v4` `version` and `controls`. Every key -set is closed: an unknown key anywhere is a load error, never ignored, because a key an older -reader silently dropped would be a typo that never surfaced. A test asserts this page names -every key and operator the loader accepts. - -## Top level - -| Key | Type | Since | Default when omitted | Notes | -|---|---|---|---|---| -| `schema` | string | v1 | **error**: a document with no schema is an unknown schema, never "assume v1" | one of `ctrlrun.policy/v1`, `ctrlrun.policy/v2`, `ctrlrun.policy/v3`, `ctrlrun.policy/v4`; each accepts the keys below marked with its version or earlier, and refuses the rest | -| `actions` | map of action name → entry | v1 | **error** | the whole list of what an agent may do; an action not in it is denied | -| `mode` | `enforce` or `observe` | v3 | `enforce` | top level only; refused anywhere else | -| `environment` | string | v3 | `production`, unless `$CTRLRUN_ENVIRONMENT` or the gateway's `--environment` says otherwise | part of every action's hash and of authority matching; never read off the wire | -| `authority` | section | v3 | none: the document behaves as v2, with no authority check | the moment it exists, every principal needs a grant. See the [authority reference](/docs/reference/authority-yaml) | -| `version` | string | v4 | none recorded | your label for this document, carried on every receipt as `policy_version`; never authoritative, the hash is | -| `controls` | map of id → entry with `title` and `source` | v4 | empty | the registry an action or a rule may cite; `source` is cited on receipts and never interpreted; a cited id the registry does not define is a load error | - -A file that cannot be read, does not parse, or fails any check above raises `PolicyError`, and -no `Control` is built. There is no empty permissive policy. - -```yaml runnable -schema: ctrlrun.policy/v4 -version: "2026-09-refunds-3" -mode: enforce -environment: production - -controls: - maker-checker-refunds: - title: "A refund over the desk limit is approved by a second person" - source: "House policy FIN-4.2" - -actions: - stripe.refund: - effect: "refund:{payment_id}" - resource: "payment:{payment_id}" - controls: [maker-checker-refunds] - rules: - - when: { amount_gte: 0, amount_lte: 50000 } - decision: allow - - when: { amount_gte: 0, amount_lte: 500000 } - decision: approve - - decision: deny -``` - -## An action entry - -Exactly one of `decision` and `rules`, plus the optional keys. - -| Key | Type | Since | When omitted | Notes | -|---|---|---|---|---| -| `decision` | `allow`, `approve` or `deny` | v1 | required unless `rules` is present | the same answer for every argument | -| `rules` | non-empty list of rules | v1 | required unless `decision` is present | tried in order; the first match wins; **no match is `deny`** | -| `effect` | template | v2 | no reservation: the action runs unguarded against duplicates, and the gateway names it on the line that starts it | `"refund:{payment_id}"`; every placeholder must resolve from the arguments or the action is refused before it runs | -| `resource` | template | v2 | no resource in the hash, and a grant's `resources:` cannot match | `"payment:{payment_id}"`; the decorator's `resource=` wins where both exist | -| `mcp` | mapping with one key, `not_executed_on_error` (bool) | v2 | `false` | gateway only: whether an upstream's in-band error means the tool did nothing (`FAILED`) or nobody knows (`AMBIGUOUS`). Say `true` only for an upstream that rejects before acting | -| `controls` | list of ids | v4 | none | cited on every receipt for this action, in registry order | -| `data` | map of argument name → label, either a bare string or a mapping with the one key `label` | v4 | no labels; `data_scope` is empty | labels the arguments carry, for the `data_scope` condition below | - -## A rule - -| Key | Type | When omitted | Notes | -|---|---|---|---| -| `when` | map of condition → operand | the rule matches every action; put it last | all conditions must hold | -| `decision` | `allow`, `approve` or `deny` | **error** | | -| `controls` | list of ids | none | added to the action's own on the receipt when this rule matches | - -## Conditions - -A condition key is `<subject>_<operator>`. The subject is an argument name, or the derived -`data_scope`; the operator is one of seven, and there is no other syntax. Amounts and every -other numeric operand are integers: `float` is refused everywhere in CTRLRun. - -| Operator | Meaning | Example | -|---|---|---| -| `eq` | equal | `role_eq: admin` | -| `neq` | not equal | `to_domain_neq: example.com` | -| `in` | member of the list | `role_in: [reader, viewer]` | -| `lt` | less than | `amount_lt: 100` | -| `lte` | at most | `amount_lte: 50000` | -| `gt` | greater than | `amount_gt: 0` | -| `gte` | at least | `amount_gte: 0` | - -Bound both ends of a numeric band. `amount_lte: 50000` alone matches a negative amount, and a -refund of a negative amount is a charge. - -**Reserved subjects.** Ten names are refused as condition subjects at load, in a document of -every schema version. Five are the principal — `agent`, `user`, `claims`, `issuer`, -`expires_at` — because the policy cannot see who is asking. Five more name the action itself -rather than an argument of it: `action_id`, `environment`, `principal`, `resource` and -`data_scope`. So `when: { resource_eq: "payment:1" }` is a load error, not a rule that never -matches. `data_scope` is the one derived subject: it is the set of -labels the supplied arguments carry, `data_scope_in: [phi]` means the set intersects the list, -and `data_scope_eq` / `data_scope_neq` compare the whole set. `data_scope` may not be an -argument's name, an effect placeholder, or a protected function's parameter. - -```yaml runnable -schema: ctrlrun.policy/v4 - -actions: - patient.record.update: - effect: "record:{patient_id}" - data: - diagnosis: phi - patient_id: phi - note: internal - rules: - - when: { data_scope_in: [phi] } - decision: approve - - decision: allow -``` - -## What a version adds - -**Declare the lowest version that has every key you use.** `v2` for `effect:`, `v3` for `mode:` or -`authority:`, `v4` for `controls` or `data`. A newer number changes nothing until one of its keys -appears in the file, so a `ctrlrun.policy/v2` document on this site is not behind; it uses no key -that `v3` or `v4` added. What a version buys is the refusal in the third column: the key an older -reader would have silently misread is one it refuses instead. - -| Schema | Adds | An older reader would | -|---|---|---| -| `ctrlrun.policy/v1` | `schema`, `actions`, `decision`, `rules`, `when` | | -| `ctrlrun.policy/v2` | `effect`, `resource`, `mcp` on an entry | run a gateway tool with no reservation | -| `ctrlrun.policy/v3` | `mode`, `environment`, `authority` at the top | enforce an observed deployment, or run with no authority check | -| `ctrlrun.policy/v4` | `version`, `controls` at the top; `controls`, `data` on an entry and a rule | cite ids nothing defines, or evaluate a `data_scope` rule against nothing | - -That is why the key sets are closed by version: each key is refused by every reader that would -misread it. - -## Next - -- [Authority YAML reference](/docs/reference/authority-yaml). -- [Decisions](/docs/concepts/decisions): how a rule is matched. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/reference/receipt-and-event-schemas.mdx b/docs/docs/reference/receipt-and-event-schemas.mdx deleted file mode 100644 index 4bafaa0..0000000 --- a/docs/docs/reference/receipt-and-event-schemas.mdx +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: "Receipt and event schemas" -description: "Every field of a CTRLRun receipt and of an event, and every event type, rendered from the dataclasses that write them." ---- - -{/* generated by tools/docs_audit/render_schemas.py from the code — edit the dataclasses and docstrings, never this page */} - -A receipt is one executed action; an event is one step on the way. Both are written to the -store, appended to `.ctrlrun/receipts.jsonl` and `.ctrlrun/events.jsonl` as one JSON object -per line, and exported to any sink installed. Every enum renders by value, so a reader that -never imported CTRLRun can read the evidence. - -## Receipt - -`ctrlrun.receipt/v3`. `seq` and `prev_hash` are the chain; `policy_hash` and -`policy_version` say which policy decided the action; `controls` are the registry ids the -action and its matched rule cite. - -**Two rows are about the object rather than the document**, and the difference matters -when you are reading a JSONL line rather than a `Receipt`. Every line begins with -`"schema": "ctrlrun.receipt/v3"`, which is written by the serializer and is not a field -below. And `hash` **is** a field below and is *not* in the line: a document cannot -contain its own hash, so the store keeps it in a column and `chain_hash()` recomputes -it. A reader checking a chain compares those two. - -| Field | Type | Default | -|---|---|---| -| `receipt_id` | `str` | required | -| `action_id` | `str` | required | -| `action` | `str` | required | -| `action_hash` | `str` | required | -| `principal` | `Principal` | required | -| `resource` | `str | None` | required | -| `arguments` | `Mapping` | required | -| `environment` | `str` | required | -| `decision` | `Decision` | required | -| `decision_reason` | `str` | required | -| `result` | `ReceiptResult` | required | -| `started_at` | `datetime` | required | -| `finished_at` | `datetime` | required | -| `approval_id` | `str | None` | `None` | -| `approver` | `str | None` | `None` | -| `effect_key` | `str | None` | `None` | -| `attempt` | `int` | `1` | -| `error` | `str | None` | `None` | -| `execution` | `ctrlrun.receipt.ReceiptResult | None` | `None` | -| `would_have` | `ctrlrun.receipt._WouldHave | None` | `None` | -| `seq` | `int | None` | `None` | -| `prev_hash` | `str | None` | `None` | -| `policy_hash` | `str | None` | `None` | -| `policy_version` | `str | None` | `None` | -| `controls` | `tuple` | `()` | -| `hash` | `str | None` | `None` | - -### Result - -| Value | Meaning | -|---|---| -| `committed` | the executor returned; the remote did it | -| `failed` | the executor raised `NotExecuted`; the remote provably did nothing | -| `ambiguous` | the executor raised anything else, timed out, or never returned; nobody knows | -| `denied` | | -| `blocked` | refused before the executor ran: denied, mismatched approval, duplicate or ambiguous effect | -| `observed` | observe mode: executed, with what enforce mode would have done recorded in `would_have` | - -## Event - -| Field | Type | Default | -|---|---|---| -| `type` | `EventType` | required | -| `action_id` | `str | None` | required | -| `ts` | `datetime` | required | -| `data` | `Mapping` | `(empty)` | -| `effect_key` | `str | None` | `None` | -| `approval_id` | `str | None` | `None` | -| `event_id` | `int | None` | `None` | - -### Event types - -In the order the specification introduced them. The five authority types appear only in a -configuration with an `authority:` section. - -| Type | -|---| -| `ACTION_PROPOSED` | -| `POLICY_EVALUATED` | -| `APPROVAL_REQUESTED` | -| `APPROVAL_GRANTED` | -| `APPROVAL_DENIED` | -| `APPROVAL_EXPIRED` | -| `APPROVAL_INVALIDATED` | -| `APPROVAL_CONSUMED` | -| `EFFECT_RESERVED` | -| `EFFECT_RESERVATION_REFUSED` | -| `EXECUTION_STARTED` | -| `EXECUTION_COMMITTED` | -| `EXECUTION_FAILED` | -| `EXECUTION_AMBIGUOUS` | -| `EFFECT_RESOLVED` | -| `ACTION_DENIED` | -| `RECONCILIATION_STARTED` | -| `RECONCILIATION_RESOLVED` | -| `EXECUTION_SUSPENDED` | -| `EXECUTION_RESUMED` | -| `AUTHORITY_RESOLVED` | -| `AUTHORITY_DENIED` | -| `DELEGATION_CREATED` | -| `DELEGATION_REVOKED` | -| `DELEGATION_REJECTED` | - -## Next - -- [Receipts and evidence](/docs/concepts/receipts-and-evidence): what a receipt is for. -- [The receipt chain](/docs/security/receipt-chain): what `seq`, `prev_hash` and `hash` detect. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/security/disclosure.mdx b/docs/docs/security/disclosure.mdx deleted file mode 100644 index f970746..0000000 --- a/docs/docs/security/disclosure.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: "Reporting a vulnerability" -description: "Report privately to contact@arpanghoshal.com or through GitHub's private vulnerability reporting." ---- - -Report vulnerabilities privately to **contact@arpanghoshal.com**, or through GitHub's private -vulnerability reporting on the repository. Do not open a public issue for a security report. -Expect an acknowledgement within 72 hours and an assessment within seven days. - -Include what makes the problem reproducible: the version, the policy file, and the sequence of -actions. A failing test is the fastest possible report. - -## What counts as a vulnerability - -CTRLRun sits in the execution path of consequential actions, so anything that breaks one of -these is a security issue rather than a bug: - -- An action executes that the policy should have denied. -- An approval authorizes an action other than the exact one a human saw. -- A consumed, expired or mismatched approval is accepted. -- The same logical effect is reserved twice, in any interleaving, across threads, processes or - hosts. -- An unknown execution outcome is recorded as `failed`. -- A principal acts outside its grant, or a delegation widens one. -- A receipt does not reflect what happened. - -## What is a documented limit - -These are stated in the [threat model](/docs/THREAT_MODEL) and are not vulnerabilities, though if you -think one is stated too generously, say so: - -- A compromised process, host or Python environment. -- A malicious administrator with write access to the policy file or the store. -- A remote that lies about what it did. -- A compromised approver: CTRLRun proves what was approved, not that the human was right. -- An executor that raises `NotExecuted` after the remote acted. -- Code that bypasses the decorator entirely. -- Data exfiltration through reads the policy allows. - -## What happens to a report - -An assessment, then a fix with a test that fails before it and passes after, then a release. If -a fix is warranted you are credited in the release notes unless you ask not to be. Where the -finding is about a claim rather than the code, the claim changes: a sentence that promised more -than the code does is a defect in this project's terms, and -[how this is built](/docs/how-this-is-built) explains why. - -## Supported versions - -CTRLRun is pre-1.0 and only the latest release receives fixes. - -## Next - -- [Threat model](/docs/THREAT_MODEL) · [The receipt chain](/docs/security/receipt-chain). -- [How this is built](/docs/how-this-is-built): what has and has not been reviewed. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/security/receipt-chain.mdx b/docs/docs/security/receipt-chain.mdx deleted file mode 100644 index d18ee41..0000000 --- a/docs/docs/security/receipt-chain.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "The receipt chain" -description: "Each receipt carries the hash of the one before it, so an edit, a deletion from the middle or a reordering is detected and named by seq." ---- - -The receipt chain is a hash chain over the evidence log: receipt *n* carries `prev_hash`, the -hash of receipt *n − 1*, with `seq` inside the hashed content. Change what one receipt says, -delete one from the middle, or swap two, and the chain no longer verifies at that point. -`ctrlrun receipts --verify-chain` reports the break by `seq` and by name. - -## What it detects - -```console -$ ctrlrun receipts --verify-chain -chain: 41 receipts -seq 17: content altered -``` - -Six named breaks: `content_altered` where a receipt no longer hashes to its stored hash, -`hash_missing` where the stored hash is gone and nothing can be compared, `link_broken` between -two, `missing` where there is a gap, `head_mismatch` where the head does not match the last -receipt, and `unchained` for a receipt written before the chain existed. Each names the `seq`, -so a reader can go and look at that row rather than being told the log is bad, and -[Receipt integrity](/docs/production/receipt-integrity) says what to do about each. - -## What it does not prove - -**Alteration is not authorship.** Receipts are not signed. The chain says the log was not -edited after the fact; it says nothing about who wrote any receipt, and nothing here is -evidence of origin. Signing is not in this version. - -**It is not tamper-proof.** The head lives in the same database as the receipts, so an -administrator who can rewrite every row can recompute the chain and it will verify. What the -chain raises is the cost of *changing* history while keeping it: rewriting one receipt means -rewriting every receipt after it and the head. - -**It does not detect erasing the end.** Deleting the last receipts and rewinding the head is -two statements and leaves a chain that verifies. An anchor outside the database would close -that, and there is none. This is asserted by a test rather than argued, so the sentence cannot -quietly become optimistic. - -**It does not prove every action wrote a receipt.** A receipt whose write failed leaves no gap -in `seq` and is invisible to the chain by construction. The events log is where that is -reconciled. - -## Where it is checked - -- `ctrlrun receipts --verify-chain`, on either store backend, including through `--store-url`. -- `ctrlrun verify`'s G11, *an altered receipt is detected* — against a scratch store verify - creates on your backend, never against the store you run on. -- On Postgres, `put_receipt` takes the head row's lock first, so concurrent writers cannot - interleave into a chain that then fails to verify. - -## What to do with it - -Treat a break as an incident about the store rather than about CTRLRun: the chain is the alarm, -not the lock. If you need evidence of origin rather than of integrity, sign or anchor the -receipts outside the database yourself; they are portable JSON, one object per line, for exactly -that reason. - -[Receipt integrity in practice](/docs/production/receipt-integrity) is the runbook: when to run the -check, what each of the six names means for your store, and what an unchained count does to a -scheduled job. - -## Next - -- [Receipts and evidence](/docs/concepts/receipts-and-evidence): what a receipt holds. -- [Threat model](/docs/THREAT_MODEL): what remains open, in full. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/security/verify-guarantees.mdx b/docs/docs/security/verify-guarantees.mdx deleted file mode 100644 index c33afec..0000000 --- a/docs/docs/security/verify-guarantees.mdx +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "What verify guarantees" -description: "The eleven guarantees ctrlrun verify runs against your own policy and store, what each one exercises, what not applicable means and why it is never a pass." ---- - -`ctrlrun verify` runs eleven guarantees against the configuration in front of it, in a scratch -store, with fake executors and no network. Each is a failure scenario from the kernel's own -acceptance tests, replayed against your policy, your grants and your store backend. What it -reports is what your configuration can exercise, and what it cannot, with the reason. - -## The eleven - -| | Guarantee | What it exercises | -|---|---|---| -| G1 | mutated approval refused | an approval granted for one action, presented for another | -| G2 | replayed approval refused | the same approval presented twice | -| G3 | duplicate effect refused | the same effect key reserved twice | -| G4 | one winner under concurrency | eight OS processes racing for one effect key | -| G5 | ambiguous blocks a blind retry | a lost reply, then a retry | -| G6 | unknown action refused | an action the policy does not list | -| G7 | no principal refused | a call with no principal | -| G8 | expired authority refused | a grant past its `expires_at` | -| G9 | delegation cannot escalate | a child grant wider than its parent, on each of six dimensions | -| G10 | unknown exception is ambiguous | an executor that raises something unexpected | -| G11 | an altered receipt is detected | a receipt edited in the store | - -G1 and G2 need an `approve` rule. G3, G4 and G5 need an `effect:` template. G8 and G9 need an -`authority:` section. A configuration without them cannot exercise those guarantees, and verify -says so. - -## Not applicable is not a pass - -A guarantee this configuration cannot exercise is reported `N/A` with the reason, excluded from -the denominator, and listed separately: `6/6 (5 not applicable)`, never `11/11`. There is no -flag that folds one into the count, and zero applicable guarantees exits 2, because `0/0` -reported as success is the same false green as `8/8` with five N/As. - -The reason is always a statement about your document, not about the tool: *no action declares -an `effect:` template*, *no authority section*. That is what makes an N/A actionable: it tells -you what to add if you want the guarantee checked. - -## What the badge means - -The badge means the **declared guarantees pass**: every guarantee this configuration can -exercise was exercised, and none failed. It does not mean secure, safe, compliant, certified or -audited. A partial run with `--only` writes no badge at all. - -## What verify cannot see - -- **Your executors.** It never calls the function behind `@protect` and never imports the module - it lives in. An executor that raises `NotExecuted` after the remote acted is invisible to it, - and that is the most dangerous integration bug available. -- **Your `reconcile` hooks.** Same reason. -- **Where you put the decorator.** A consequential call with no decorator is not an action. -- **Whether your policy is the right policy.** It checks that the kernel does what it says under - your configuration, not that your configuration expresses your intent. - -## Running it - -`ctrlrun verify` locally, the GitHub Action in CI, `--json` and `--junit` for machines, and -`--store-url` to run against Postgres. Verify has no flag that relaxes a check: the moment one -existed, the thing verified would not be the thing that ships. - -## Next - -- [Verify in CI](/docs/guides/verify-in-ci) · [Get the badge](/docs/verify/get-the-badge). -- [The verify page](/docs/verify): the operator's reference, in full. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/study/does-your-framework-double-execute.mdx b/docs/docs/study/does-your-framework-double-execute.mdx deleted file mode 100644 index 2f1281b..0000000 --- a/docs/docs/study/does-your-framework-double-execute.mdx +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: "Does your framework double-execute?" -description: "What agent frameworks do when a remote commits and the reply is lost, measured with one harness, the same fake remote and framework defaults." ---- - -{/* generated by tools/docs_audit/render_probe.py from research/framework-probe/results/ — publish a run, do not edit this page */} - -When a remote commits a refund and the reply is lost, what does an agent framework do? -This page is the measurement, not an argument: one harness, one fake remote, framework -defaults, and a table rendered from the run's own JSON. - -**It reports behaviour, not quality.** None of these projects claims to solve duplicate -execution, and none is doing anything its documentation does not describe. The finding is -about what an agent stack does *without* an effect-level guard. - -## What the run of 2026-09-04 found - -| Framework | Version | Double execution | Approval mutation | -|---|---|---|---| -| stub-retrying | 0.4.0 | `executed_twice` | `executed_once` | -| stub-not-retrying | 0.4.0 | `executed_once` | `executed_once` | -| mcp-client | 0.4.0 | `executed_once` | `executed_once` | -| langgraph | 1.2.11 | `executed_once` | `executed_once` | -| openai-agents | 0.22.0 | `executed_twice` | `executed_once` | - -- **stub-retrying, double execution**: the response was lost on every attempt; 5 runs: executed_twice x5 -- **stub-retrying, approval mutation**: 5 runs: executed_once x5 -- **stub-not-retrying, double execution**: the response was lost on every attempt; 5 runs: executed_once x5 -- **stub-not-retrying, approval mutation**: 5 runs: executed_once x5 -- **mcp-client, double execution**: no retry: a bare client leaves that to its caller; 5 runs: executed_once x5 -- **mcp-client, approval mutation**: 5 runs: executed_once x5 -- **langgraph, double execution**: 5 runs: executed_once x5 -- **langgraph, approval mutation**: 5 runs: executed_once x5 -- **openai-agents, double execution**: 5 runs: executed_twice x5; effects 3-4; requests 3-4 -- **openai-agents, approval mutation**: 5 runs: executed_once x5 - -Run on 2026-09-04 against `fake-mcp/1` on Python 3.12.3. The file is [`research/framework-probe/results/2026-09-05.json`](https://github.com/CTRLRun/ctrlrun/blob/main/research/framework-probe/results/2026-09-05.json). - -**Read the approval-mutation column carefully.** `executed_once` there does not mean -the scenario was handled well: it means the *mutated* action, the refund the human -never approved, reached the remote and committed. Every row shows it, the stubs -included, because nothing in these stacks binds a human's approval to the exact action -that then runs. `outcome` is a closed set with no value for *the mutation landed*, -which is why that is said here rather than in a cell. - -**The double-execution column is the finding.** The two stub rows are the control: a -harness that reported `executed_twice` unconditionally would have said the same about -both of them. - -### Not run - -An adapter exists for each of these and **was never executed**, so this page says -nothing about them. They are listed by name rather than left out, because a reader -who knows the adapter exists should not have to wonder what happened to it. - -- **autogen**: autogen-agentchat is not installed. -- **crewai**: crewai is not installed. - -## The fairness rules - -Normative, because the table carries other projects' names. - -1. The same fake remote for every framework, a fresh instance per run. -2. The same scenario text: prompt, tool name, description and schema byte-identical wherever the framework's API admits it. -3. Framework defaults. No retry setting changed, no timeout tuned, no guard added. -4. At most one configuration change per framework, only where the scenario cannot run without it, and it appears in the table's own column. -5. The version is read at runtime from the installed distribution, never typed by hand. -6. The table reports behaviour, not quality. - -## Run it yourself - -The harness is in the repository, outside the package, and is never shipped in a wheel. -It needs the network, real API keys and a budget, which is why its results are published -by hand rather than by CI. - -```bash -python research/framework-probe/run.py --help -``` - -[`research/framework-probe/README.md`](https://github.com/CTRLRun/ctrlrun/blob/main/research/framework-probe/README.md) -has the scenarios, the fake remote, each framework's documented defaults with the date -read, and what a run does not establish. - -## Next - -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): what a lost reply is, and why a retry is refused. -- [Effect keys](/docs/concepts/effect-keys): the guard the frameworks above are running without. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/try-it.mdx b/docs/docs/try-it.mdx deleted file mode 100644 index 3fda2d0..0000000 --- a/docs/docs/try-it.mdx +++ /dev/null @@ -1,274 +0,0 @@ ---- -title: "Try it in your browser" -description: "Break a protected agent action with no install: real Python and the released ctrlrun wheel run in this tab, and every refusal you see is CTRLRun's own." -mode: "wide" ---- - -One protected refund, under one policy, with a fake Stripe that commits before its reply can go -missing. Change the amount, lose the reply, approve one amount and execute another, and read -what refused you. - -<Note> - Coming from the [scenario demo](/try)? That page draws the decisions across 48 domains. - This one runs them: real Python, the released wheel, and every exception is the library's own. -</Note> - -<div id="ctrlrun-playground"> - <div style={{ display: "flex", flexWrap: "wrap", gap: "12px", alignItems: "flex-end" }}> - <label style={{ display: "flex", flexDirection: "column", fontSize: "13px" }}> - Amount, in euros - <input type="number" name="amount" defaultValue="500" step="1" style={{ padding: "8px", fontSize: "15px", width: "140px", borderRadius: "6px", border: "1px solid #B8730A" }} /> - </label> - <label style={{ display: "flex", flexDirection: "column", fontSize: "13px" }}> - Payment id - <input type="text" name="payment_id" defaultValue="txn_1" style={{ padding: "8px", fontSize: "15px", width: "140px", borderRadius: "6px", border: "1px solid #B8730A" }} /> - </label> - <label style={{ display: "flex", gap: "6px", alignItems: "center", fontSize: "13px", paddingBottom: "10px" }}> - <input type="checkbox" name="lose_reply" /> - lose the reply after the remote commits - </label> - <button - type="button" - name="run" - style={{ - background: "#F5A623", - color: "#14161b", - border: "1px solid #B8730A", - borderRadius: "8px", - padding: "10px 18px", - fontSize: "15px", - cursor: "pointer", - }} - > - Refund - </button> - <button - type="button" - name="approve" - style={{ - background: "#14161b", - color: "#8bd5a0", - border: "1px solid #8bd5a0", - borderRadius: "8px", - padding: "10px 18px", - fontSize: "15px", - cursor: "pointer", - }} - > - Approve, as the human - </button> - </div> - <pre - style={{ - background: "#14161b", - color: "#c9ccd3", - borderRadius: "8px", - padding: "16px", - marginTop: "12px", - display: "block", - overflowX: "auto", - overflowY: "auto", - fontSize: "13px", - lineHeight: "1.5", - minHeight: "180px", - maxHeight: "min(60vh, 440px)", - whiteSpace: "pre", - }} - > -Press Refund. The first press downloads about 10 MB of Python; after that the browser caches it. - </pre> -</div> - -Real Python and the released `ctrlrun` wheel from PyPI load into this tab. Every line in the box -was produced by `ctrlrun` here: the page owns the controls and nothing else. Nothing is sent -anywhere; the store is in memory and no socket is opened. The policy the refund runs under, in -cents: - -```yaml -schema: ctrlrun.policy/v2 -actions: - stripe.refund: - effect: "refund:{payment_id}" - rules: - - when: { amount_gte: 0, amount_lte: 100000 } - decision: allow - - when: { amount_gte: 0, amount_lte: 1000000 } - decision: approve - - decision: deny -``` - -## Try this, in order - -1. **€500** on `txn_1` — allowed. It runs, and the receipt says `committed`. -2. Payment id **`txn_2`**, **€2,000** — `ApprovalRequired`, with the request id a human would - answer. Press *Approve*, change the amount to **€5,000**, press *Refund*: - `ApprovalMismatch`. The approval was bound to the action the human saw. Put **€2,000** back - and it executes on that same approval. -3. **€2,000** on `txn_2` once more — `ApprovalMismatch (consumed)`: the approval was single-use. -4. **`txn_3`**, **€20,000** — `ActionDenied`. No request is created; a human is not asked about - a refund the policy refuses at any size. -5. **`txn_4`**, **€500**, with *lose the reply* ticked — the remote commits, the reply is lost, - the effect is `AMBIGUOUS`. Untick and press *Refund* again: `AmbiguousEffect`, the blind - retry is refused, and `remote refund calls` is still 1. That is the case this library exists - for: [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous). -6. Back to **`txn_1`**, **€500** — `DuplicateEffect`. One logical effect, - [one reservation](/docs/concepts/effect-keys). - -Every refusal above is the exception your own code would catch, with the reason it carries. -[Approval binding](/docs/concepts/approval-binding) and [Decisions](/docs/concepts/decisions) are the two -pages behind steps 2 to 4. - -## The five scenarios, end to end - -Press the button and `ctrlrun demo` runs in this tab: the same five scenarios you would get -from `pip install ctrlrun && ctrlrun demo`, on the same wheel. - -<div id="ctrlrun-browser-demo"> - <button - type="button" - style={{ - background: "#F5A623", - color: "#14161b", - border: "1px solid #B8730A", - borderRadius: "8px", - padding: "10px 18px", - fontSize: "15px", - cursor: "pointer", - }} - > - Run ctrlrun demo - </button> - <pre - style={{ - background: "#14161b", - color: "#c9ccd3", - borderRadius: "8px", - padding: "16px", - marginTop: "12px", - display: "block", - overflowX: "auto", - overflowY: "auto", - fontSize: "13px", - lineHeight: "1.5", - minHeight: "180px", - maxHeight: "min(60vh, 440px)", - whiteSpace: "pre", - }} - > -Press the button. The first run downloads about 10 MB of Python; after that the browser caches it. - </pre> -</div> - -<Accordion title="What the demo prints"> - -This is the output from the verification run described below, with the generated ids masked: - -```text -ctrlrun 0.5.0 on Python 3.14.2 - -CTRLRun demo — five ways an agent action goes wrong, and what stops it. -Policy: refunds up to €1,000 are autonomous, up to €10,000 need a human, above that are denied. - -1. Duplicate effect after a lost response - - refund €500 → remote commits → response lost → effect: AMBIGUOUS - agent retries the same refund - ✗ BLOCKED — effect may already have committed; blind retry refused - remote refund calls: 1 - only a human moves it on: ctrlrun resolve refund:txn_1 --committed|--failed - -2. Approval mutation - - agent proposes refund €2,000 → human approves apr_… (bound to the action hash) - agent executes refund €5,000 → - ✗ BLOCKED — approved action ≠ requested action (mismatch) - -3. Concurrent agents, same effect - - Agent A reserve refund:txn_123 → ACQUIRED → executes - Agent B reserve refund:txn_123 → - ✗ BLOCKED — already reserved (in_progress) - -4. Approval replay - - approval apr_… used once → consumed - same approval presented again → - ✗ BLOCKED — single-use approval already consumed - -5. Authority escalation - - human €100,000 delegable → finance agent €25,000 → support agent €2,000 - support agent's grant: dlg_… - support agent requests €50,000 → - ✗ BLOCKED — outside the delegated grant (authority_constraint) - remote refund calls: 0 - finance agent tries to delegate €50,000 under its own €25,000 → refused (containment: constraints) - support agent requests €1,500 → authority permits it, and the policy asks a human (apr_…) - two axes, and an action needs both: the stricter of the pair wins -``` - -Scenario 1 is the one to read twice: **`remote refund calls: 1`**. The refund committed at the -fake remote, the reply was lost, the agent retried, and the retry was refused. The customer was -refunded once. - -</Accordion> - -## What is running - -| | | -|---|---| -| Runtime | [Pyodide](https://pyodide.org/) 314.0.6, CPython 3.14.2 compiled to WebAssembly, from the jsDelivr CDN | -| Package | `ctrlrun`, installed from PyPI by micropip: the released version, the same wheel `pip install ctrlrun` gives you | -| Storage | SQLite, bundled into Pyodide, writing to an in-memory filesystem that disappears when you close the tab | -| Network | the CDN and PyPI, to load Python and the wheel. The demo itself opens no socket: its remote is a fake in the same process | - -The version line in the output is the released version, so it can be behind `main`. Everything -else on this site describes the current release. - -<Accordion title="Verified, and how to check"> - -The Python this page runs was verified under Node against the same Pyodide build on -**2026-09-07**: Pyodide 314.0.6, Python 3.14.2, SQLite 3.39.0, `ctrlrun` 0.5.0 from PyPI, the -playground's whole sequence and all five demo scenarios. Not a copy of it — the harness reads -both programs out of `try-it.js` and runs those. It carried its own copy until 2026-09-06, which -is how a syntax error in the page's copy reached this page: both harnesses were green, one -having stubbed the Python and the other having verified a program the page never ran. Two -harnesses are committed, and you can run both: - -```bash -npm install pyodide jsdom -node docs/assets/verify-browser-demo.mjs # Python, the wheel, the playground sequence, the five scenarios -node docs/assets/verify-browser-wiring.mjs # this page's controls, against a real DOM -``` - -[`verify-browser-demo.mjs`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/assets/verify-browser-demo.mjs) -is the one that proved the demo runs. A third check needs neither Node nor the network: -`tests/test_docs_travelling.py` lifts both programs out of the JavaScript on every commit, -compiles the demo's, and **runs the playground's** through the six steps above against the -checkout's own `ctrlrun`, asserting each outcome. A refusal that stopped happening fails CI -rather than this page. -[`verify-browser-wiring.mjs`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/assets/verify-browser-wiring.mjs) -is the one that proves the controls on this page get wired: this site is a single-page -application, and the first version of the script looked for its container before the page had -rendered it, so the button did nothing. - -</Accordion> - -## If it does not run here - -The page tells you what failed and gives you the command that always works: - -```bash -pip install ctrlrun && ctrlrun demo -``` - -A browser can fail this for reasons that have nothing to do with CTRLRun: a blocked CDN, an -extension that stops WebAssembly, a very old browser, or a tab with no memory to spare. That is -this page failing, not the library. - -## Next - -- [Protect your first action](/docs/get-started/quickstart): the same thing, in your own process. -- [The scenario demo](/try): the same checks, in your domain, with nothing running. -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): what scenario 1 means. -- [Get started](/docs/get-started/install) · [Why](/docs/why). diff --git a/docs/docs/verify.md b/docs/docs/verify.md deleted file mode 100644 index 71fb53b..0000000 --- a/docs/docs/verify.md +++ /dev/null @@ -1,358 +0,0 @@ ---- -title: "ctrlrun verify" -description: "Running the guarantee catalogue against your own configuration: the report, the N/A rule, the badge, and what verify cannot see." ---- - -Everything CTRLRun guarantees is proven by this repository's tests against this repository's -configurations. That is the right place to start and the wrong place to stop, because the thing -you deploy is *your* policy, *your* grants and *your* store — and a guarantee that has never -been exercised against those is a guarantee nobody has checked. - -`ctrlrun verify` runs the kernel's own failure scenarios against the configuration in front of -it and reports what passed, what failed, and — the part that makes the number mean anything — -what could not be tested at all. - -```console -$ ctrlrun verify -CTRLRun verify — ctrlrun 0.6.1, catalogue ctrlrun.guarantees/v2 -policy examples/authority/payments.yaml (ctrlrun.policy/v3, mode: enforce) -authority same document, 3 grants -store sqlite, scratch (created and destroyed for this run) - -G1 mutated approval refused PASS stripe.refund -G2 replayed approval refused PASS stripe.refund -G3 duplicate effect refused PASS stripe.refund -G4 one winner under concurrency PASS stripe.refund (8 processes) -G5 ambiguous blocks a blind retry PASS stripe.refund -G6 unknown action refused PASS -G7 no principal refused PASS stripe.refund -G8 expired authority refused PASS head-of-support -G9 delegation cannot escalate PASS head-of-support (6 of 6 dimensions) -G10 unknown exception is ambiguous PASS stripe.refund -G11 an altered receipt is detected PASS stripe.refund - -11/11 declared guarantees pass. 0 not applicable. -``` - -It reads the policy document — `$CTRLRUN_CONFIG`, else `./ctrlrun.yaml` — and the authority -document beside it. It executes nothing real: every executor is an in-process fake, no scenario -opens a socket, and it writes nothing outside a temporary directory. - ---- - -## What the badge means - -> The badge means the **declared guarantees pass**: every guarantee in the catalogue that this -> configuration can exercise was exercised, and none of them failed. - -That is the whole claim. It is not a statement that your system is secure, that your policy is -a good policy, or that CTRLRun has audited anything. A configuration that permits everything -and constrains nobody can pass every guarantee in the catalogue, because they are about **the -kernel doing what it says under that configuration** — not about whether the configuration is -wise. - -### What it does not mean - -Verify sees **the configuration, not the code**. It does not check: - -- **Your executors.** The function behind `@protect` is never called. An executor that raises - `NotExecuted` when the remote *did* act — `THREAT_MODEL.md` calls this an integration bug, - and it is the most dangerous one available — is invisible here, because verify supplies its - own executors and never imports your module. -- **Your `reconcile` hooks**, for the same reason: a hook is a Python callable passed to - `@protect`, and it does not appear in any file verify reads. -- **Where you put the decorator.** Code that calls the raw function bypasses CTRLRun entirely, - and no amount of configuration-reading finds that. -- **Your deployment.** Whether the proxy in front of `HeaderIdentityProvider` overwrites the - header, whether `$CTRLRUN_STATE` points where you think, whether two gateways share a state - file — none of it is in the document. -- **Whether your policy is the *right* policy.** Verify has no opinion on whether - `stripe.refund` should be autonomous to €500 or to €5. It is not a linter, it does not score, - and it will never tell you a configuration is too permissive. That judgment belongs to the - person who wrote it, and a tool that pretended otherwise would be handing out an - authoritative-looking opinion it has no basis for. - -The words **secure**, **safe**, **compliant**, **certified** and **audited** do not appear as -claims about CTRLRun or about your system on the badge, in its JSON, in the job summary, or on -this page. - ---- - -## Not applicable is not a pass - -A configuration with no `approve` rule cannot exercise the approval-binding guarantees. Verify -reports them `N/A` with the reason that made them inapplicable, **excludes them from the -denominator**, and shows them separately: - -``` -G3 duplicate effect refused N/A no action declares an `effect:` template - (in a `ctrlrun.policy/v1` document the template - lives in the @protect decorator, which verify does - not read) -G4 one winner under concurrency N/A no action declares an `effect:` template -G5 ambiguous blocks a blind retry N/A no action declares an `effect:` template -G8 expired authority refused N/A no authority section -G9 delegation cannot escalate N/A no authority section - -6/6 declared guarantees pass. 5 not applicable: G3, G4, G5, G8, G9. -``` - -That run is `6/6`, never `11/11`. There is no flag that folds an N/A into the count, and there -will not be one: a number that counts guarantees nobody exercised is a number that means -nothing. - -An N/A is always a statement about your **document**, derived from it. A scenario verify could -not build for any other reason is an internal error and exits 3 — never an N/A, and never a -failure attributed to your kernel. - ---- - -## The guarantees - -Eleven, in `ctrlrun.guarantees/v2`. Every one is the deployed form of an acceptance test that -already exists and passes in this repository; verify adds no guarantee of its own and weakens -none. - -| id | invariant | N/A when | -|---|---|---| -| **G1** | An approval is bound to one `action_hash`; presenting it for any other action is refused, and the approval is not consumed. | No action reaches `approve` under any satisfiable argument vector. | -| **G2** | An approval is single-use; the second presentation is refused and does not execute. | As G1. | -| **G3** | A second attempt on an effect key whose record is `COMMITTED` is refused, and the remote is not called. | No action declares an `effect:` template. | -| **G4** | Reservation is atomic **across processes**, not merely across threads. | As G3, or the store backend cannot span processes. | -| **G5** | An executor that raises anything other than `NotExecuted` leaves the effect `AMBIGUOUS`, and the retry is refused rather than executed. | As G3. | -| **G6** | Unknown action → DENY. There is no default-allow. | `actions:` is empty. | -| **G7** | No principal, no action: an action proposed outside `context()` with no identity provider is refused, and no receipt and no events are written. | No action in the policy can run at all. | -| **G8** | A grant is authority only until its `expires_at`; after that the action it covered is denied, by name. | No `authority:` section, no grant with an `expires_at`, or no grant matching any action the policy lists. | -| **G9** | A delegated grant is valid only if it is provably a subset of its parent on every dimension — and a child that **drops** a dimension its parent constrains is rejected rather than treated as unconstrained. | No `authority:` section, or no grant is delegable. | -| **G10** | `NotExecuted` is the only outcome that means "the remote did nothing". Everything else, timeouts included, is `AMBIGUOUS`. | Every action in the policy is denied. | -| **G11** | Each receipt carries the hash of the one before it, so altering one is detected and **named** — `content_altered`, `hash_missing`, `link_broken`, `missing`, `head_mismatch`, `unchained`. Its positive control is that the unaltered chain verifies. | The policy declares no actions at all. A denied action still writes a receipt, so a policy that denies everything is still checked. | - -G9 reports **which dimensions it exercised**. A parent that constrains one dimension does not -score as though it had covered six, because that would be the N/A rule violated one level down. - -Two of these are worth a sentence on how they are exercised, because the answer is not the -obvious one; `SPEC-v0.4.md` §12 argues both at length. - -**G6 asserts the behaviour, not one reason string.** An action your policy does not list never -executes — but *which* check refuses it depends on your configuration. With an `authority:` -section, no grant covers it and authority refuses first, before policy is reached; without one, -policy refuses it as `unknown_action`. Both are the guarantee holding, so the report names the -reason that fired in `detail.refused_by` and the set it was checked against in -`detail.reachable_reasons`. A reason your configuration cannot produce is a failure. - -**G7 is `N/A` for a policy in which nothing can run at all**, because its control is "the same -call inside `context()` runs" and there is no such call. It is applicable to every configuration -in which anything can run, with or without grants. - -### Every guarantee carries a positive control - -A guarantee is a refusal, and "the second attempt was refused" is satisfied just as well by a -scenario in which **nothing ever ran**. Such a scenario would report PASS, every time, against -a kernel with the guard deleted. - -So every scenario runs a companion that establishes the observable would have been visible had -the guard not fired: the unmutated action commits, the first attempt reaches `COMMITTED`, eight -processes on eight distinct keys all commit, an executor raising `NotExecuted` **is** retried -and does execute. If the control does not behave as specified, the guarantee is reported -`FAIL` with `reason: "control failed"`. It is never a pass, and it is never an N/A: an N/A is a -statement about the configuration, and a failed control is a statement about the run. - ---- - -## Verify never touches your store - -Every scenario runs against a scratch store of the same backend type, created for the run and -destroyed with it. Your `.ctrlrun/state.db` is byte-identical before and after, and it is never -created where it did not exist. Verify does not call `state_path()`, does not read -`$CTRLRUN_STATE`, and does not use `Control.from_file()`. - -It writes no evidence files either. Evidence of a scenario that never happened, filed beside -evidence of actions that did, is a receipt trail nobody can read. - ---- - -## Options - -``` -ctrlrun verify [--authority PATH] [--json] [--junit PATH] [--only G1,G3] [--store-url URL] -``` - -| | | -|---|---| -| `--authority PATH` | A standalone authority document, the one `ctrlrun gateway --authority` already accepts. Declaring authority in two places is refused, naming both. | -| `--json` | One `ctrlrun.verify/v1` document on stdout, carrying the SHA-256 of both documents verify read, and on each failure a counterexample: the ordered events, receipts and effect records that show the violation. | -| `--junit PATH` | A JUnit XML file for CI. An N/A is `<skipped>` and never a pass. | -| `--only G1,G3` | Runs exactly those. Everything else is `skipped`, the report carries `"partial": true`, and **no badge is written** — a fraction computed over a subset somebody chose is a false green in a different costume. | -| `--store-url URL` | The backend to grade against: `sqlite` (the default) or a `postgresql://` URL. Verify creates a scratch schema per guarantee there, drops them all when the run ends, and never opens your store. Anything else exits 2 naming the two it knows. | - -There is **no flag that relaxes a check**. No argument and no environment variable makes -verify's `Control` behave differently from the one your deployment runs. The moment one exists, -the thing being verified is not the thing that ships. - -### Exit codes - -| | | -|---|---| -| **0** | Every applicable guarantee passed, and at least one was applicable. | -| **1** | At least one guarantee FAILED. | -| **2** | The configuration was refused or is unusable — a missing or malformed policy, authority declared twice, `mode: observe`, an unknown `--only` id, an unsupported `--store-url`, or **zero applicable guarantees**. | -| **3** | An internal error in verify itself. Never reported as a FAIL, and never as an N/A. | - -`mode: observe` is refused rather than run. Observe mode enforces nothing, so every refusal -these guarantees assert would be recorded rather than made; running the scenarios and reporting -ten failures would be true and useless, and running them in a synthetic enforce mode would -report guarantees about a configuration nobody deployed. - ---- - -## In CI - -```yaml -name: CTRLRun verify - -on: [push, pull_request] - -jobs: - verify: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: CTRLRun/ctrlrun@v0.6.1 - with: - policy: ctrlrun.yaml -``` - -The action installs `ctrlrun`, runs `ctrlrun verify --json --junit`, renders the job summary -and the badge JSON **from that report** — not from a second run, so they cannot disagree — and -uploads the three files as one artifact. - -**The ref pins the action's steps and not the package they install.** `install` defaults to -`ctrlrun`, unpinned, so `@v0.6.1` runs whatever version PyPI serves on the day the job runs — -pinning the action is not pinning the thing being verified with. Set `install: ctrlrun==0.6.1` -where you want the run to be reproducible, and pin the action by commit rather than by tag -where you want a ref that cannot be moved; this repository holds its own workflows to the -commit form and a test enforces it. - -It fails the job when a guarantee failed and when the configuration was refused, and succeeds -when guarantees are N/A. N/A is not a failure and it is not a pass; the job's green means -"nothing that could be checked was wrong", which is exactly what the badge says. - -**There is no input that makes a failure not fail the job.** A workflow that wants to tolerate -one puts `continue-on-error` on the step, where it is visible in the workflow rather than -hidden in an action's defaults. - -### Inputs - -| | | -|---|---| -| `policy` | Path to the policy document. Default `ctrlrun.yaml`. | -| `authority` | Path to a standalone authority document. Default: the policy document carries it. | -| `only` | Comma-separated guarantee ids. A partial run writes no badge. | -| `python-version` | Default `3.11`. | -| `install` | The pip requirement to install. Default `ctrlrun`; set it to `.` to verify with the checkout. | -| `badge-path` | Where to write the Shields endpoint JSON. Default `verify-badge.json`. | - -Outputs: `passed`, `failed`, `applicable`, `not-applicable`, `badge-message`, `report-path`. - -### Publishing the badge - -The action **writes** the endpoint JSON and never publishes it. Publishing it needs -`contents: write`, and asking for write access to your repository as the price of a -verification badge is a bad trade for a tool whose subject is least privilege. So the cost is -here, visible, once — and it is your decision. - -This repository publishes its own badge, and this is the job it uses. Three things about it are -load-bearing: - -- **`contents: write` is job-level.** The workflow itself is `contents: read`, so nothing else - in it can write to the repository. A workflow-level grant would hand every job write access - to buy one file. -- **It runs on a push to `main` and nothing else.** A pull request never reaches it. A PR from - a fork gets a read-only token anyway, but relying on that is relying on a default rather than - refusing. -- **It publishes the badge the verify job already produced**, downloaded as an artifact rather - than regenerated — so the badge, the job summary and the uploaded report all come from one - verify run and cannot disagree. - -```yaml -permissions: - contents: read # every job, unless it says otherwise - -jobs: - badge: - needs: verify - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - runs-on: ubuntu-latest - permissions: - contents: write # the one exception, and only here - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - name: ctrlrun-verify - path: badge - - name: Publish to the badges branch - run: | - set -eu - test -s badge/verify-badge.json - message=$(python -c 'import json;print(json.load(open("badge/verify-badge.json"))["message"])') - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - # Explicit destination ref: `actions/checkout` sets a single-branch refspec, so a - # plain `git fetch origin badges` leaves `refs/remotes/origin/badges` unset and the - # switch below would create a fresh orphan and be rejected on push — on the second - # publish, not the first. - if git fetch origin badges:refs/remotes/origin/badges 2>/dev/null; then - git switch -c badges refs/remotes/origin/badges - else - git switch --orphan badges - fi - # Nothing to clear: `git switch` replaces the working tree with the target's, - # and `--orphan` starts from an empty one. The downloaded artifact is - # untracked, so it survives either path - which is the only file that must. - cp badge/verify-badge.json verify-badge.json - git add -f verify-badge.json - git commit -m "verify: $message" || { echo "badge unchanged"; exit 0; } - git push origin badges -``` - -### What protecting the `badges` branch buys, and what it does not - -Worth being exact, because a badge is a claim and a branch nobody guards is a claim anybody can -write. This repository's `badges` branch blocks **deletion** and **force pushes**, so the -badge's history cannot be rewritten or removed. - -It does **not** restrict who may push. Anyone with write access can fast-forward a different -badge onto the branch. GitHub's classic branch protection cannot express "only the Actions -token may push" — adding `github-actions` to the push allowlist is silently dropped, which -leaves an allowlist that blocks *everyone*, including the job. A repository ruleset with a -bypass actor can express it; getting the bypass wrong breaks the publish in a way that only -surfaces the next time the badge's value changes, so it is a deliberate choice rather than a -default. - -The mitigation that does hold without any of that: **the job is self-healing.** It copies the -badge its own verify run produced over whatever is on the branch, so a falsified badge is -overwritten by the next push to `main` that changes the value. A badge is worth what the run -behind it is worth, and the run is in the workflow log. - -Then the badge is: - -```markdown -[![CTRLRun](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/OWNER/REPO/badges/verify-badge.json)](docs/docs/verify.md#what-the-badge-means) -``` - -It renders as **CTRLRun verified N/M**, where `N` is passes and `M` is **applicable** -guarantees — never the catalogue size. It is `brightgreen` when nothing failed and `red` -otherwise; there is no amber for N/A, because the badge's colour is about failures and the N/A -count lives in the report the badge links to. - -A partial run (`--only`) and a run that exited 2 or 3 write **no badge at all**. - ---- - -## Related - -- [`SPEC-v0.4.md`](https://github.com/CTRLRun/ctrlrun/blob/main/docs/SPEC-v0.4.md) — the contract this implements, guarantee by guarantee. -- [`OWASP-AGENTIC-TOP10.md`](/docs/OWASP-AGENTIC-TOP10) — a reading of somebody else's taxonomy - against these guarantees, with the entries CTRLRun does not address listed by name. -- [`THREAT_MODEL.md`](/docs/THREAT_MODEL) — what fail-closed means here, and what is out of scope. diff --git a/docs/docs/verify/get-the-badge.mdx b/docs/docs/verify/get-the-badge.mdx deleted file mode 100644 index 1c54763..0000000 --- a/docs/docs/verify/get-the-badge.mdx +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: "Get the verified badge" -description: "Two minutes: run ctrlrun verify in a workflow, publish the badge JSON, and point Shields at it. What the badge means, and what N/A means." ---- - -Two minutes, three steps: run `ctrlrun verify` on every push, publish the badge JSON it writes, -and point a Shields endpoint badge at the file. The badge then says what your own configuration -proved, and updates itself. - -<Steps> - <Step title="Verify on every push"> - ```yaml - name: CTRLRun verify - - on: - push: - branches: [main] - pull_request: - - jobs: - verify: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: CTRLRun/ctrlrun@v0.6.1 - id: verify - with: - policy: ctrlrun.yaml - badge-path: verify-badge.json - ``` - - The action installs `ctrlrun`, runs it against your policy in a scratch store with no - network, renders the job summary and the badge JSON from that one report, and fails the job - if a guarantee failed. - - The ref pins the action's steps and not the package they install: `install` defaults to - `ctrlrun`, unpinned. Add `install: ctrlrun==0.6.1` where you want the run reproducible. - </Step> - - <Step title="Publish the badge JSON"> - The action **writes** the badge and never publishes it: publishing needs `contents: write`, - and asking for write access to your repository as the price of a badge is a bad trade for a - tool whose subject is least privilege. So this job is yours, and the cost is visible. - - ```yaml - badge: - needs: verify - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - runs-on: ubuntu-latest - permissions: - contents: write # this job only; the workflow above is read-only - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - name: ctrlrun-verify - path: badge - - run: | - set -eu - test -s badge/verify-badge.json - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - if git fetch origin badges:refs/remotes/origin/badges 2>/dev/null; then - git switch -c badges refs/remotes/origin/badges - else - git switch --orphan badges - fi - cp badge/verify-badge.json verify-badge.json - git add -f verify-badge.json - git commit -m "verify" || { echo "badge unchanged"; exit 0; } - git push origin badges - ``` - - Three things about that job are load-bearing: `contents: write` is on the job and not the - workflow; it runs on a push to your default branch and never on a pull request, so a fork - cannot write your badge; and it publishes the badge the verify job already produced rather - than running verify a second time, so the badge and the report cannot disagree. - </Step> - - <Step title="Point Shields at it"> - ```markdown - [![CTRLRun verified](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/OWNER/REPO/badges/verify-badge.json)](https://github.com/CTRLRun/ctrlrun/blob/main/docs/docs/verify.md#what-the-badge-means) - ``` - - Link it to what the badge means, as above. A badge nobody can click through to is a claim - without a definition. - </Step> -</Steps> - -## What the badge means - -The badge means the **declared guarantees pass**: every guarantee in the catalogue that your -configuration can exercise was exercised, and none of them failed. It reads `verified N/M`, -where `M` is what your configuration can exercise, not the size of the catalogue. - -It does not mean secure, safe, compliant, certified or audited. It says nothing about your -executors, your `reconcile` hooks, where you put the decorator, your deployment, or whether your -policy is the right policy. - -## What N/A means - -A guarantee your configuration cannot exercise is reported not applicable, with the reason, and -**excluded from both sides of the fraction**. A policy with no `approve` rule cannot exercise -approval binding; one with no `effect:` templates cannot exercise the effect guarantees; one -with no `authority:` section cannot exercise the authority guarantees. - -So a badge reading `verified 6/6` on a policy with five N/As is honest, and `11/11` for the same -policy would not be. Not applicable is not a pass, there is no flag that folds one into the -count, and a run where nothing is applicable exits 2 and writes no badge at all. A partial run -with `--only` writes no badge either. - -## If the badge does not appear - -- The `badges` branch has no `verify-badge.json` yet: the badge job runs only on a push to your - default branch, so merge once. -- Shields caches for a few minutes. -- The badge URL and the branch the job pushes to must be the same; a mismatch is a 404 on your - front page. - -## Next - -- [Verify in CI](/docs/guides/verify-in-ci): the inputs, the outputs and the two report shapes. -- [What verify guarantees](/docs/security/verify-guarantees): the eleven, and the four things verify cannot see. -- [Get started](/docs/get-started/quickstart) · [Why](/docs/why). diff --git a/docs/docs/why.mdx b/docs/docs/why.mdx deleted file mode 100644 index ce76622..0000000 --- a/docs/docs/why.mdx +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: "Why CTRLRun" -sidebarTitle: "Why" -description: "Five principles for AI agents that act on the real world: a failure is not an unknown, an approval binds to what the human saw." ---- - -Everyone is rushing to ship AI agents without thinking about consequences. An agent that only -reads is wrong at no cost. An agent that can pay, delete, deploy, grant or send is wrong at the -cost of the thing it did, and its framework was built to make it act, not to act once. CTRLRun -exists for the boundary between intending an effect and having caused one. Five principles. - -## FAILED is not UNKNOWN - -A timeout tells you nothing. The refund may have committed at Stripe a millisecond before the -connection dropped. A framework that marks the call *failed* and retries has turned one unknown -into a probable double. CTRLRun has three outcomes: `COMMITTED`, `FAILED` and `AMBIGUOUS`. Only -the executor can say `FAILED`, by raising `NotExecuted`, and only when it knows the remote did -nothing. Everything else after the first byte is `AMBIGUOUS`, and an `AMBIGUOUS` effect blocks a -blind retry until a human or a reconcile hook says what happened. - -*Never map an unknown exception to a failure.* - -## An approval is bound to what the human saw - -A human who approved "refund €2,000 on txn_2" did not approve €5,000, and did not approve -€2,000 again next week. CTRLRun binds an approval to the SHA-256 of the exact action: name, -canonical arguments, resource, principal, environment. It is used once, expires, and is consumed -in the same atomic write that reserves the effect, so a mutated action matches nothing and a -replayed one finds its approval spent. - -*An approval authorizes one exact action, not a category of action.* - -## Autonomy belongs to the action, not the agent - -The question is not whether an agent is trusted. It is whether *this action*, with *these -arguments*, may run without a person. A €100 refund is autonomous, a €2,000 refund needs a human, -a €20,000 refund is refused, whichever agent proposes it. The policy decides per action and -cannot see who is asking. Who may ask at all is a second axis, authority, evaluated first and -separately, and the two combine as the stricter of the pair. Neither reads the agent's -instructions, which is why a prompt injection cannot talk its way past either. - -*Decide the action. Grant the principal. Never let one loosen the other.* - -## Unknown means no - -An action the policy does not list is denied. A missing policy, a malformed policy, a missing -principal, an expired credential, a mismatched approval, an inconsistent store: denied. There is -no flag that makes a consequential action permissive by default, in the kernel, in `verify` or -in an adapter, because the first deployment to set it would be the one that mattered. Observe -mode lets a rollout measure before it enforces; it is not a way to relax a check. - -*Fail closed is not configurable.* - -## Evidence leaves the building - -Every executed action leaves a portable JSON receipt: who, what, decision, approval, effect key, -outcome, and the hash of the policy that decided it, chained to the receipt before it. Receipts -go to a JSONL file beside the store and to any sink you give them, because evidence has to -survive the process that produced it. The chain detects alteration. It does not prove -authorship, and the page that describes it says so in the same breath. - -*A receipt is worth what it says when the process is gone.* - -## What follows - -CTRLRun does not host models, plan, prompt, retrieve, route, remember or orchestrate. It is not a -guardrail library, an IAM system, a workflow engine or a compliance product, and it issues no -credential. It cannot guarantee exactly-once execution against a remote it does not control; it -guarantees it will not *knowingly* act twice and will never call an unknown a failure. - -The reason to believe this is not this page: every README sentence has a row in `CLAIMS.md` -naming the code and the test, every requirement is mutation-tested, and `ctrlrun verify` runs the -guarantees against your own configuration and reports what it could not check. - -## Next - -- [How this is built](/docs/how-this-is-built): the discipline, the numbers, and what has not been done yet. -- [Get started](/docs/get-started/quickstart): protect one function, end to end. -- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): the first principle, in code. diff --git a/docs/generated/badges.readme.md b/docs/generated/badges.readme.md deleted file mode 100644 index 920799e..0000000 --- a/docs/generated/badges.readme.md +++ /dev/null @@ -1,15 +0,0 @@ -<!-- generated from tools/docs_audit/render_badges.py (readme) — edit the list, not this --> -<p align="center"> - <a href="https://pypi.org/project/ctrlrun/"><img src="https://img.shields.io/pypi/v/ctrlrun?color=B8730A&label=pypi" alt="PyPI"></a> - <a href="https://pypi.org/project/ctrlrun/"><img src="https://img.shields.io/pypi/pyversions/ctrlrun?color=B8730A" alt="Python versions"></a> - <a href="https://ctrlrun.dev"><img src="https://img.shields.io/badge/docs-ctrlrun.dev-B8730A" alt="Docs"></a> - <a href="https://github.com/CTRLRun/ctrlrun/actions/workflows/ci.yml"><img src="https://github.com/CTRLRun/ctrlrun/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a> - <a href="https://github.com/CTRLRun/ctrlrun/actions/workflows/codeql.yml"><img src="https://github.com/CTRLRun/ctrlrun/actions/workflows/codeql.yml/badge.svg?branch=main" alt="CodeQL"></a> - <a href="https://ctrlrun.dev/docs/how-this-is-built"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/CTRLRun/ctrlrun/badges/tests-badge.json" alt="Tests"></a> - <a href="https://ctrlrun.dev/docs/security/verify-guarantees"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/CTRLRun/ctrlrun/badges/verify-badge.json" alt="CTRLRun verified"></a> - <a href="https://scorecard.dev/viewer/?uri=github.com/CTRLRun/ctrlrun"><img src="https://api.scorecard.dev/projects/github.com/CTRLRun/ctrlrun/badge" alt="OpenSSF Scorecard"></a> - <a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff"></a> - <a href="https://github.com/CTRLRun/ctrlrun/blob/main/scripts/check.sh"><img src="https://img.shields.io/badge/mypy-strict-B8730A" alt="Checked with mypy --strict"></a> - <a href="https://github.com/CTRLRun/ctrlrun/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/ctrlrun?color=B8730A" alt="License"></a> -</p> -<!-- end generated --> diff --git a/docs/generated/capabilities.mdx b/docs/generated/capabilities.mdx deleted file mode 100644 index 4d309b5..0000000 --- a/docs/generated/capabilities.mdx +++ /dev/null @@ -1,86 +0,0 @@ -{/* generated from docs/capabilities.yaml (mdx) — edit the YAML, never this grid */} -<Columns cols={2}> - <Card title="Approval binding" href="/docs/concepts/approval-binding"> - An approval is bound to the exact action; a mutated or replayed one is refused. Since v0.1. - </Card> - <Card title="One effect, once" href="/docs/concepts/effect-keys"> - One logical effect happens at most once, across threads, processes and hosts. Since v0.1. - </Card> - <Card title="Unknown is not failed" href="/docs/concepts/outcomes-and-ambiguous"> - An unknown outcome is AMBIGUOUS, never FAILED, and blocks a blind retry. Since v0.1. - </Card> - <Card title="Fail closed" href="/docs/concepts/fail-closed"> - An unknown action, a missing policy or a missing principal is denied. Since v0.1. - </Card> - <Card title="Authority and delegation" href="/docs/concepts/authority-and-delegation"> - With authority on, every principal needs a grant, and delegation cannot widen one. Since v0.3. - </Card> - <Card title="Receipts" href="/docs/concepts/receipts-and-evidence"> - Every executed action leaves a portable JSON receipt of who, what and outcome. Since v0.1. - </Card> -</Columns> -<Accordion title="Everything else it does (20 more)"> - <Columns cols={2}> - <Card title="Per-action policy" href="/docs/reference/policy-yaml"> - One YAML file decides allow, approve or deny per action and argument. Since v0.1. - </Card> - <Card title="Operator CLI" href="/docs/reference/cli"> - Approve, deny, resolve, inspect and count from the shell, against any store. Since v0.1. - </Card> - <Card title="MCP gateway" href="/docs/guides/gateway-in-front-of-mcp"> - Every guarantee in front of an MCP tool server, with no agent changes. Since v0.2. - </Card> - <Card title="Reconciliation" href="/docs/guides/reconcile-automatically"> - A reconcile hook asks the remote what happened and resolves an AMBIGUOUS effect. Since v0.2. - </Card> - <Card title="Webhook approvals" href="/docs/guides/approvals-in-slack"> - Approval requests go to a webhook, such as Slack, and the answer comes back. Since v0.2. - </Card> - <Card title="OpenTelemetry export" href="/docs/guides/export-to-opentelemetry"> - One span per action, one span event per step; argument values are opt-in. Since v0.2. - </Card> - <Card title="Consumed identity" href="/docs/concepts/authority-and-delegation"> - A principal comes from a verified header or JWT; CTRLRun issues nothing. Since v0.3. - </Card> - <Card title="Runtime delegation" href="/docs/concepts/authority-and-delegation"> - A principal narrows its own grant at runtime; one revocation cuts the chain. Since v0.3. - </Card> - <Card title="Observe mode" href="/docs/concepts/observe-mode"> - Records what enforcement would have blocked, blocks nothing, and counts it. Since v0.3. - </Card> - <Card title="Verify" href="/docs/guides/verify-in-ci"> - Runs the guarantee catalogue against your policy and store; N/A is not a pass. Since v0.4. - </Card> - <Card title="The verified badge" href="/docs/verify/get-the-badge"> - A GitHub Action and a badge that means the declared guarantees pass. Since v0.4. - </Card> - <Card title="Framework adapters" href="/docs/get-started/three-ways-in"> - An approval routed through the framework's own interrupt; never a second path. Since v0.5. - </Card> - <Card title="Runs on one host or many" href="/docs/production/index"> - SQLite on one host, Postgres across hosts, the same guarantees either way. Since v0.6. - </Card> - <Card title="Postgres store" href="/docs/production/postgres"> - The same store on Postgres, graded by the suite written for SQLite. Since v0.6. - </Card> - <Card title="Versioned schema" href="/docs/production/migrations"> - Migrations run at open, forward only, and an unknown schema is refused. Since v0.6. - </Card> - <Card title="Recovery on restart" href="/docs/production/recovery"> - A dead worker's effect stays AMBIGUOUS until a human or a hook resolves it. Since v0.6. - </Card> - <Card title="Receipt chain" href="/docs/security/receipt-chain"> - Each receipt carries the hash of the one before; alteration is detected and named. Since v0.6. - </Card> - <Card title="Policy versioning" href="/docs/concepts/receipts-and-evidence"> - Every receipt names the policy hash and version that decided it. Since v0.6. - </Card> - <Card title="Control registry" href="/docs/reference/policy-yaml"> - Name the house controls an action satisfies, and receipts cite them. Since v0.6. - </Card> - <Card title="Data scope" href="/docs/reference/policy-yaml"> - Label arguments by data class and condition a rule on the labels present. Since v0.6. - </Card> - </Columns> -</Accordion> -{/* end generated */} diff --git a/docs/generated/capabilities.readme.md b/docs/generated/capabilities.readme.md deleted file mode 100644 index bf64b2b..0000000 --- a/docs/generated/capabilities.readme.md +++ /dev/null @@ -1,10 +0,0 @@ -<!-- generated from docs/capabilities.yaml (readme) — edit the YAML, never this table --> -| Guarantee | `@protect` | Gateway | Adapter | -|---|---|---|---| -| **Approval binding** — An approval is bound to the exact action; a mutated or replayed one is refused. | yes | yes | prevention or attribution, per adapter | -| **One effect, once** — One logical effect happens at most once, across threads, processes and hosts. | yes | yes | yes | -| **Unknown is not failed** — An unknown outcome is AMBIGUOUS, never FAILED, and blocks a blind retry. | yes | yes | yes | -| **Fail closed** — An unknown action, a missing policy or a missing principal is denied. | yes | yes | yes | -| **Authority and delegation** — With authority on, every principal needs a grant, and delegation cannot widen one. | yes | yes | yes | -| **Receipts** — Every executed action leaves a portable JSON receipt of who, what and outcome. | yes | yes | yes | -<!-- end generated --> diff --git a/docs/generated/capabilities.txt b/docs/generated/capabilities.txt deleted file mode 100644 index c2f40d1..0000000 --- a/docs/generated/capabilities.txt +++ /dev/null @@ -1,28 +0,0 @@ -generated from docs/capabilities.yaml (text) — edit the YAML, never this list -- Approval binding: An approval is bound to the exact action; a mutated or replayed one is refused. -- One effect, once: One logical effect happens at most once, across threads, processes and hosts. -- Unknown is not failed: An unknown outcome is AMBIGUOUS, never FAILED, and blocks a blind retry. -- Fail closed: An unknown action, a missing policy or a missing principal is denied. -- Authority and delegation: With authority on, every principal needs a grant, and delegation cannot widen one. -- Receipts: Every executed action leaves a portable JSON receipt of who, what and outcome. -- Per-action policy: One YAML file decides allow, approve or deny per action and argument. -- Operator CLI: Approve, deny, resolve, inspect and count from the shell, against any store. -- MCP gateway: Every guarantee in front of an MCP tool server, with no agent changes. -- Reconciliation: A reconcile hook asks the remote what happened and resolves an AMBIGUOUS effect. -- Webhook approvals: Approval requests go to a webhook, such as Slack, and the answer comes back. -- OpenTelemetry export: One span per action, one span event per step; argument values are opt-in. -- Consumed identity: A principal comes from a verified header or JWT; CTRLRun issues nothing. -- Runtime delegation: A principal narrows its own grant at runtime; one revocation cuts the chain. -- Observe mode: Records what enforcement would have blocked, blocks nothing, and counts it. -- Verify: Runs the guarantee catalogue against your policy and store; N/A is not a pass. -- The verified badge: A GitHub Action and a badge that means the declared guarantees pass. -- Framework adapters: An approval routed through the framework's own interrupt; never a second path. -- Runs on one host or many: SQLite on one host, Postgres across hosts, the same guarantees either way. -- Postgres store: The same store on Postgres, graded by the suite written for SQLite. -- Versioned schema: Migrations run at open, forward only, and an unknown schema is refused. -- Recovery on restart: A dead worker's effect stays AMBIGUOUS until a human or a hook resolves it. -- Receipt chain: Each receipt carries the hash of the one before; alteration is detected and named. -- Policy versioning: Every receipt names the policy hash and version that decided it. -- Control registry: Name the house controls an action satisfies, and receipts cite them. -- Data scope: Label arguments by data class and condition a rule on the labels present. -end generated diff --git a/docs/generated/readiness.full.mdx b/docs/generated/readiness.full.mdx deleted file mode 100644 index 8a071ae..0000000 --- a/docs/generated/readiness.full.mdx +++ /dev/null @@ -1,15 +0,0 @@ -{/* generated from the suite, pyproject and the soak (full) — run the generator */} -- **Version 0.6.1**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later. -- **4,404 tests**, every version specified before it was written and every requirement mutation-tested. [Read more](/docs/how-this-is-built). -- **11 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). -- **Each receipt carries the hash of the one before it**, so an alteration is detected and named. [Read more](/docs/production/receipt-integrity). -- **Apache-2.0**, and the enforcement kernel stays open source. Releases carry PyPI provenance attestations from GitHub Actions. - -**Not yet:** - -- No external security audit. (planned for v0.8 or v0.9) -- No third-party review of the kernel. (every review so far was run inside this project) -- No sector packs. (the policy templates are starting points, not a product) -{/* end generated */} diff --git a/docs/generated/readiness.json b/docs/generated/readiness.json deleted file mode 100644 index d885e82..0000000 --- a/docs/generated/readiness.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "guarantees": 11, - "released": "0.6.1", - "soak": { - "actions": 889735, - "backend": "postgres", - "elapsed": "20m 0s", - "elapsed_seconds": 1200.004, - "positive_control": true, - "unexplained": 0 - }, - "tests": 4404, - "version": "0.6.1" -} diff --git a/docs/generated/readiness.mdx b/docs/generated/readiness.mdx deleted file mode 100644 index bdbfb54..0000000 --- a/docs/generated/readiness.mdx +++ /dev/null @@ -1,15 +0,0 @@ -{/* generated from the suite, pyproject and the soak (mdx) — run the generator */} -- **Version 0.6.1**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later. -- **4,404 tests**, every version specified before it was written and every requirement mutation-tested. -- **11 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). -- **Each receipt carries the hash of the one before it**, so an alteration is detected and named. -- **Apache-2.0**, and the enforcement kernel stays open source. Releases carry PyPI provenance attestations from GitHub Actions. - -**Not yet:** - -- No external security audit. (planned for v0.8 or v0.9) -- No third-party review of the kernel. (every review so far was run inside this project) -- No sector packs. (the policy templates are starting points, not a product) -{/* end generated */} diff --git a/docs/generated/readiness.readme.md b/docs/generated/readiness.readme.md deleted file mode 100644 index 20b0d92..0000000 --- a/docs/generated/readiness.readme.md +++ /dev/null @@ -1,15 +0,0 @@ -<!-- generated from the suite, pyproject and the soak (readme) — run the generator --> -- **Version 0.6.1**, on [PyPI](https://pypi.org/project/ctrlrun/), Python 3.11 and later. -- **4,404 tests**, every version specified before it was written and every requirement mutation-tested. -- **11 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). -- **Each receipt carries the hash of the one before it**, so an alteration is detected and named. -- **Apache-2.0**, and the enforcement kernel stays open source. Releases carry PyPI provenance attestations from GitHub Actions. - -**Not yet:** - -- No external security audit. (planned for v0.8 or v0.9) -- No third-party review of the kernel. (every review so far was run inside this project) -- No sector packs. (the policy templates are starting points, not a product) -<!-- end generated --> diff --git a/docs/images/demo-poster.jpg b/docs/images/demo-poster.jpg deleted file mode 100644 index 84d38426bb85cfca09c9185d552ddf560bb0e52f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31532 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 diff --git a/docs/images/demo.mp4 b/docs/images/demo.mp4 deleted file mode 100644 index a8edd05fe3f56a983fe4b98b4940191b40ac8811..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1152268 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�O<`&e<k) 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�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�E4F1((- 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 o0oYQPTI(LNq)x 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%0AjuX><P4<C;$itEZapUQk?SQb~H@#vFg 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 NRbfCbI<mjR{|7%D9x?y` diff --git a/docs/images/favicon.svg b/docs/images/favicon.svg deleted file mode 100644 index 7dedf1a..0000000 --- a/docs/images/favicon.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><rect x="4" y="8" width="56" height="52" rx="13" fill="#B8730A"/><rect x="4" y="4" width="56" height="52" rx="13" fill="#F5A623"/><path d="M25 18 L43 30 L25 42 Z" fill="#14161b" stroke="#14161b" stroke-width="4" stroke-linejoin="round"/></svg> diff --git a/docs/images/social-preview.png b/docs/images/social-preview.png deleted file mode 100644 index 0f057fd2d284a0de17022628adf162de647078b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78334 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 diff --git a/docs/images/wordmark-dark.svg b/docs/images/wordmark-dark.svg deleted file mode 100644 index fd0b506..0000000 --- a/docs/images/wordmark-dark.svg +++ /dev/null @@ -1,6 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="600" height="120" viewBox="0 0 600 120" role="img" aria-label="CTRLRun"> - <rect x="8" y="18" width="94" height="88" rx="21" fill="#B8730A"/> - <rect x="8" y="10" width="94" height="88" rx="21" fill="#F5A623"/> - <path d="M44 34 L74 54 L44 74 Z" fill="#14161b" stroke="#14161b" stroke-width="7" stroke-linejoin="round"/> - <text class="t" x="124" y="84" font-family="Inter, -apple-system, 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="72" font-weight="800" letter-spacing="-2" fill="#f2f3f5">CTRL<tspan font-weight="400" letter-spacing="-1">Run</tspan></text> -</svg> diff --git a/docs/images/wordmark-light.svg b/docs/images/wordmark-light.svg deleted file mode 100644 index 5cd37c3..0000000 --- a/docs/images/wordmark-light.svg +++ /dev/null @@ -1,6 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="600" height="120" viewBox="0 0 600 120" role="img" aria-label="CTRLRun"> - <rect x="8" y="18" width="94" height="88" rx="21" fill="#B8730A"/> - <rect x="8" y="10" width="94" height="88" rx="21" fill="#F5A623"/> - <path d="M44 34 L74 54 L44 74 Z" fill="#14161b" stroke="#14161b" stroke-width="7" stroke-linejoin="round"/> - <text class="t" x="124" y="84" font-family="Inter, -apple-system, 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="72" font-weight="800" letter-spacing="-2" fill="#14161b">CTRL<tspan font-weight="400" letter-spacing="-1">Run</tspan></text> -</svg> diff --git a/docs/images/wordmark.svg b/docs/images/wordmark.svg deleted file mode 100644 index 0da3149..0000000 --- a/docs/images/wordmark.svg +++ /dev/null @@ -1,7 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="600" height="120" viewBox="0 0 600 120" role="img" aria-label="CTRLRun"> - <style>.t{fill:#14161b}@media (prefers-color-scheme: dark){.t{fill:#f2f3f5}}</style> - <rect x="8" y="18" width="94" height="88" rx="21" fill="#B8730A"/> - <rect x="8" y="10" width="94" height="88" rx="21" fill="#F5A623"/> - <path d="M44 34 L74 54 L44 74 Z" fill="#14161b" stroke="#14161b" stroke-width="7" stroke-linejoin="round"/> - <text class="t" x="124" y="84" font-family="Inter, -apple-system, 'Segoe UI', 'Helvetica Neue', Helvetica, Arial, sans-serif" font-size="72" font-weight="800" letter-spacing="-2" fill="#14161b">CTRL<tspan font-weight="400" letter-spacing="-1">Run</tspan></text> -</svg> diff --git a/docs/index.mdx b/docs/index.mdx deleted file mode 100644 index 1810995..0000000 --- a/docs/index.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: "Execution safety for AI agents" -sidebarTitle: "CTRLRun" -description: "Execution safety for AI agents: prevent duplicate effects, bind approval to the exact action, and stop blind retries when the outcome is uncertain." -mode: "custom" -"og:title": "CTRLRun: execution safety for AI agents" -"twitter:title": "CTRLRun: execution safety for AI agents" -canonical: "https://ctrlrun.dev/" -"og:url": "https://ctrlrun.dev/" ---- - -import { DemoFilm } from "/snippets/demo-film.jsx"; - -<div className="cr-site cr-home"> - <section className="cr-home-hero" aria-labelledby="cr-title"> - <div className="cr-home-pitch"> - <p className="cr-eyebrow">CONTROL THE ACTION. KEEP THE AUTONOMY.</p> - <h1 id="cr-title">Execution safety<br />for AI agents<span className="cr-dot">.</span></h1> - <p className="cr-lede">Control what agents deploy, delete, send, or change. Any domain. Your rules.</p> - <div className="cr-actions"> - <a className="cr-button" href="/try" data-cr-event="try_clicked">Try an action <span aria-hidden="true">→</span></a> - <a className="cr-button cr-github-badge" href="https://github.com/CTRLRun/ctrlrun" data-cr-event="github_clicked"><svg aria-hidden="true" focusable="false" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 .75a11.25 11.25 0 0 0-3.558 21.923c.563.104.77-.244.77-.542 0-.267-.01-.975-.015-1.913-3.13.68-3.79-1.508-3.79-1.508-.513-1.303-1.252-1.65-1.252-1.65-1.023-.7.077-.686.077-.686 1.132.08 1.727 1.162 1.727 1.162 1.006 1.724 2.64 1.226 3.283.938.102-.73.394-1.226.715-1.508-2.498-.284-5.124-1.25-5.124-5.563 0-1.228.44-2.233 1.162-3.02-.116-.285-.504-1.43.11-2.98 0 0 .945-.303 3.094 1.154a10.786 10.786 0 0 1 5.625 0c2.148-1.457 3.09-1.154 3.09-1.154.617 1.55.23 2.695.113 2.98.724.787 1.16 1.792 1.16 3.02 0 4.323-2.63 5.276-5.136 5.555.404.35.765 1.043.765 2.1 0 1.515-.014 2.737-.014 3.11 0 .3.203.65.774.54A11.252 11.252 0 0 0 12 .75Z" /></svg><span>GitHub</span><span aria-hidden="true">↗</span></a> - </div> - <a className="cr-text-link cr-hero-quickstart" href="/docs/get-started/quickstart" data-cr-event="integration_clicked">Read the quickstart ↗</a> - </div> - <div className="cr-example-wrap"> - <p className="cr-example-label">ONE EXAMPLE / THE MODEL HALLUCINATES AN AMOUNT</p> - <div className="cr-failure-chain" aria-labelledby="cr-failure-title"> - <h2 id="cr-failure-title">The model guesses.<br />CTRLRun does not.</h2> - <div className="cr-chain-setup"> - <p><span>The ticket says</span>refund $500</p> - <p><span>The agent asks for</span>$5,000</p> - </div> - <div className="cr-chain"> - <div className="cr-chain-row"> - <span className="cr-chain-label">Without CTRLRun</span> - <ol className="cr-chain-steps"> - <li>Nothing checks the amount</li><li>The call goes through</li><li className="cr-end cr-bad">$4,500 too much</li> - </ol> - </div> - <div className="cr-chain-row"> - <span className="cr-chain-label cr-good">With CTRLRun</span> - <ol className="cr-chain-steps"> - <li>Your rule checks the amount</li><li>The call never leaves</li><li className="cr-end cr-good">$0 wrongly paid</li> - </ol> - </div> - </div> - </div> - </div> - </section> - - <section className="cr-section cr-home-how" id="how-it-works" aria-labelledby="cr-how-title"> - <div className="cr-section-heading"><h2 id="cr-how-title">Any domain. Same control.</h2><a className="cr-text-link" href="/try">Explore 48 domains ↗</a></div> - <div className="cr-domain-actions" aria-label="Explore actions across domains"> - <a href="/try?domain=Finance&action=Transfer%20funds&situation=mismatch"><span className="cr-step">FINANCE</span><strong>Move money <span aria-hidden="true">↗</span></strong></a> - <a href="/try?domain=Healthcare%20Operations&action=Send%20patient%20communication&situation=duplicate"><span className="cr-step">HEALTHCARE</span><strong>Message a patient <span aria-hidden="true">↗</span></strong></a> - <a href="/try?domain=Insurance&action=Issue%20claim%20payment&situation=uncertain"><span className="cr-step">INSURANCE</span><strong>Pay a claim <span aria-hidden="true">↗</span></strong></a> - <a href="/try?domain=Pharmaceuticals%20and%20Life%20Sciences&action=Release%20controlled%20workflow&situation=blocked"><span className="cr-step">LIFE SCIENCES</span><strong>Release a workflow <span aria-hidden="true">↗</span></strong></a> - <a href="/try?domain=Legal&action=Submit%20filing&situation=approval"><span className="cr-step">LEGAL</span><strong>Submit a filing <span aria-hidden="true">↗</span></strong></a> - </div> - <div className="cr-boundary-flow" aria-label="Agent proposes an action. CTRLRun checks your rules. Allow, require approval, or block."> - <div className="cr-boundary-source"><span className="cr-step">YOUR AGENT</span><strong>Proposes an action</strong></div> - <span className="cr-boundary-arrow" aria-hidden="true">→</span> - <div className="cr-boundary-gate"><span className="cr-step">YOUR RULES</span><strong className="cr-gate-logo"><svg className="cr-gate-key" viewBox="0 0 64 64" width="34" height="34" aria-hidden="true" focusable="false"><rect x="4" y="8" width="56" height="52" rx="13" fill="#b8730a" /><rect x="4" y="4" width="56" height="52" rx="13" fill="#f5a623" /><path d="M25 18 L43 30 L25 42 Z" fill="#14161b" stroke="#14161b" strokeWidth="4" strokeLinejoin="round" /></svg><span className="cr-gate-word">CTRL<span>Run</span></span></strong></div> - <span className="cr-boundary-arrow" aria-hidden="true">→</span> - <div className="cr-boundary-decisions"><span className="cr-decision-allow">✓ Allow</span><span className="cr-decision-approve">◷ Ask a person</span><span className="cr-decision-deny">× Block</span></div> - </div> - <div className="cr-memory-rules"> - <div><span className="cr-step">EXACT APPROVAL</span><h3>Exact means exact.</h3><p>Changed arguments need a new approval.</p></div> - <div><span className="cr-step">DUPLICATE PREVENTION</span><h3>Once stays once.</h3><p>Same effect key. Shared store. No repeat.</p></div> - <div><span className="cr-step">UNCERTAIN OUTCOME</span><h3>Unknown means wait.</h3><p>Confirm the outcome before retrying.</p></div> - <div><span className="cr-step">A RECORD OF EACH DECISION</span><h3>Every answer is kept.</h3><p>Requests, decisions and results, refusals included. <a href="/docs/verify">Test rules before enforcing them.</a></p></div> - </div> - <p className="cr-not-llm">CTRLRun does not read prompts, choose models, rank tools, or judge whether the agent’s reasoning was any good. It is not an LLM, and it does not call one. <strong>It checks the action, not the thinking.</strong> <a className="cr-text-link" href="/docs/ARCHITECTURE">Read the architecture →</a></p> - </section> - - <section className="cr-section cr-demo-film" aria-labelledby="cr-film-title"> - <div className="cr-section-heading"><div><p className="cr-eyebrow">FORTY-NINE SECONDS</p><h2 id="cr-film-title">One policy file, and the refusals it produces.</h2></div><a className="cr-text-link" href="/try" data-cr-event="try_clicked">Or drive it yourself ↗</a></div> - <DemoFilm src="/images/demo.mp4" poster="/images/demo-poster.jpg" label="A terminal recording of a CTRLRun policy file and the decisions it produces. Captions are shown in the video." /> - <p className="cr-caption">Plays muted with captions. Use the controls for sound.</p> - </section> - - <section className="cr-section cr-integration" aria-labelledby="cr-integrate-title"> - <div><p className="cr-eyebrow">A LIBRARY INSIDE YOUR PROCESS</p><h2 id="cr-integrate-title">Wrap the action.<br />Set the rules.</h2><p>Protect the function that changes the world.</p><a className="cr-button" href="/docs/get-started/quickstart" data-cr-event="integration_clicked">Protect your first action →</a><ul className="cr-surfaces" aria-label="Where the boundary sits"><li><b>Python</b>The decorator, around the call that causes the effect.</li><li><b>MCP gateway</b>Point <code>ctrlrun gateway</code> at an existing MCP server. <a href="/docs/mcp/gateway-in-5-minutes">Five minutes ↗</a></li><li><b>Agent frameworks</b>LangGraph and OpenAI Agents, as separate packages. <a href="/docs/adapters">Adapters ↗</a></li><li><b>Not only agents</b>Workers, webhooks and scheduled jobs, same boundary. <a href="/docs/not-only-agents">How ↗</a></li><li className="cr-surface-planned"><b>HTTP API <span>PLANNED</span></b>Not built yet. The boundary is in-process today.</li></ul></div> - <div className="cr-code-col"> - <div className="cr-code"><div className="cr-install"><span aria-hidden="true">$ </span><code>pip install ctrlrun</code></div><pre aria-label="Python integration example"><code>{"import ctrlrun\n\n@ctrlrun.protect(\n \"cloud.deploy\",\n effect=\"deploy:{release_id}\"\n)\ndef deploy(release_id):\n return cloud.deploy(release_id)"}</code></pre><div className="cr-code-context"><p>Connect your policy and identity. <a href="/docs/get-started/quickstart">Full setup →</a></p></div></div> - <div className="cr-proof-links"><a href="/docs/try-it">Run real Python ↗</a><a href="/docs/ARCHITECTURE">Architecture ↗</a><a href="/docs/THREAT_MODEL">Limits ↗</a></div> - </div> - </section> - - <div className="cr-review-strip"><strong>Taking an agent into production?</strong><div><a href="https://adopt.ctrlrun.dev/" data-cr-event="adopt_clicked">How teams adopt CTRLRun ↗</a><a href="/protect-my-agent" data-cr-event="protect_clicked">Get a safety review ↗</a><a href="/risk-check">Free risk check ↗</a></div></div> - <div className="cr-footer" role="contentinfo"><span>Give agents autonomy.<br /><strong>Keep control of their actions.</strong></span><div><a href="/try" data-cr-event="try_clicked">Try the demo ↗</a><a href="/docs" data-cr-event="documentation_clicked">Docs →</a><a href="https://adopt.ctrlrun.dev/" data-cr-event="adopt_clicked">For businesses ↗</a><a href="https://github.com/CTRLRun/ctrlrun" data-cr-event="github_clicked">GitHub ↗</a><a href="mailto:contact@arpanghoshal.com?subject=CTRLRun" data-cr-event="contact_email_clicked">Contact ↗</a></div></div> -</div> diff --git a/docs/medical-demo.js b/docs/medical-demo.js deleted file mode 100644 index 70d7868..0000000 --- a/docs/medical-demo.js +++ /dev/null @@ -1,431 +0,0 @@ -/* - * The medical affairs portal, for docs/demos/medical-affairs.mdx. - * - * Mintlify includes every .js file in the content directory on every page and cannot scope one - * to a single page, so this does nothing at all unless the page it belongs to has mounted its - * container. Everything it touches lives inside that container. - * - * What it does: load Pyodide from the jsDelivr CDN, install `ctrlrun` from PyPI with micropip, - * and run real CTRLRun in the reader's own browser -- the same arrangement docs/try-it.js uses, - * over a different policy. Nothing is sent anywhere: the medical portal and the safety database - * are fakes in the same process, the state store is in memory, and no clinical data is transmitted. - * - * MODULE is a JSON array of lines so the test suite can read it out rather than carrying a - * copy. `tests/test_docs_medical_demo.py` runs it natively through the whole sequence the page - * tells the reader to press, on every commit, with no Node and no network. - * - * The product, the physician's question and the three references are invented. Nothing here is - * medical information about a real medicine, and the page says so above the fold. - */ -(function () { - "use strict"; - - var PYODIDE = "https://cdn.jsdelivr.net/pyodide/v314.0.6/full/"; - var CONTAINER = "ctrlrun-medical-demo"; - - // `sqlite3` is bundled into Pyodide 314 and is not a loadable package; `pyyaml` is one of - // Pyodide's own builds; `click` arrives as ctrlrun's dependency through micropip. - var PACKAGES = ["micropip", "pyyaml"]; - - // Public API only -- `Control`, `InMemoryStateStore`, `LocalApprovalProvider`, - // `Policy.from_yaml`, `@protect`, `context`, `with_approval`, and the exceptions -- so what a - // reader sees here is what the same calls do in their own process. An approval is a - // `grant_approval` on the store, the same write `ctrlrun approve` makes; there is no - // auto-approve and no dry run. Keep it JSON-parseable: double-quoted strings, no comment - // inside the array, no trailing comma. - var MODULE = [ - "import json", - "from ctrlrun import Control, InMemoryStateStore, LocalApprovalProvider, Policy", - "from ctrlrun import ActionDenied, AmbiguousEffect, ApprovalMismatch, ApprovalRequired, DuplicateEffect", - "from ctrlrun import context, protect, with_approval", - "", - "POLICY = \"\"\"", - "schema: ctrlrun.policy/v2", - "actions:", - " literature.search:", - " effect: \"search:{inquiry_id}:{revision}\"", - " decision: allow", - " safety.report_icsr:", - " effect: \"icsr:{inquiry_id}\"", - " decision: allow", - " response.send_to_hcp:", - " effect: \"mi_response:{inquiry_id}\"", - " decision: approve", - " response.cite_unapproved_use:", - " effect: \"unapproved_use:{inquiry_id}\"", - " decision: deny", - "\"\"\"", - "", - "INQUIRY = \"MI-2026-004471\"", - "", - "DRAFTS = [", - " {", - " \"revision\": \"A\",", - " \"retrieved\": \"2026-09-01\",", - " \"recommendation\": \"No dose adjustment is required in moderate hepatic impairment.\",", - " \"references\": [\"DEMO-LABEL-01\", \"DEMO-STUDY-02\", \"DEMO-REVIEW-03\"],", - " },", - " {", - " \"revision\": \"B\",", - " \"retrieved\": \"2026-09-07\",", - " \"recommendation\": \"A 50% dose reduction is recommended in moderate hepatic impairment.\",", - " \"references\": [\"DEMO-LABEL-01\", \"DEMO-STUDY-04\", \"DEMO-REVIEW-03\"],", - " },", - "]", - "", - "", - "class Portal:", - " def __init__(self):", - " self.letters = []", - " self.cases = []", - " self.lose_reply = False", - "", - " def send_letter(self, inquiry_id):", - " self.letters.append(inquiry_id)", - " return {\"document\": \"SRL-0442\", \"status\": \"sent\"}", - "", - " def report_case(self, inquiry_id):", - " self.cases.append(inquiry_id)", - " if self.lose_reply:", - " raise TimeoutError(\"no response from the safety database after 30s\")", - " return {\"case\": \"AER-2026-0881\", \"status\": \"received\"}", - "", - "", - "store = InMemoryStateStore()", - "control = Control(Policy.from_yaml(POLICY, source=\"<medical-demo>\"), store, LocalApprovalProvider(store))", - "portal = Portal()", - "draft_index = [0]", - "", - "", - "@protect(\"literature.search\", effect=\"search:{inquiry_id}:{revision}\", control=control)", - "def search(inquiry_id, revision, query):", - " return {\"hits\": 3}", - "", - "", - "@protect(\"response.send_to_hcp\", effect=\"mi_response:{inquiry_id}\", control=control)", - "def send_to_hcp(inquiry_id, recommendation, references):", - " return portal.send_letter(inquiry_id)", - "", - "", - "@protect(\"safety.report_icsr\", effect=\"icsr:{inquiry_id}\", control=control)", - "def report_icsr(inquiry_id, term):", - " return portal.report_case(inquiry_id)", - "", - "", - "@protect(\"response.cite_unapproved_use\", effect=\"unapproved_use:{inquiry_id}\", control=control)", - "def cite_unapproved_use(inquiry_id, claim):", - " return portal.send_letter(inquiry_id)", - "", - "", - "@protect(\"response.publish_unreviewed\", effect=\"unreviewed:{inquiry_id}\", control=control)", - "def publish_unreviewed(inquiry_id):", - " return portal.send_letter(inquiry_id)", - "", - "", - "def _draft():", - " return DRAFTS[draft_index[0]]", - "", - "", - "def _send(approval_id):", - " draft = _draft()", - " if approval_id:", - " with with_approval(approval_id):", - " return send_to_hcp(inquiry_id=INQUIRY, recommendation=draft[\"recommendation\"], references=draft[\"references\"])", - " return send_to_hcp(inquiry_id=INQUIRY, recommendation=draft[\"recommendation\"], references=draft[\"references\"])", - "", - "", - "def step(request_json):", - " request = json.loads(request_json)", - " op = request[\"op\"]", - " result = {\"op\": op, \"inquiry_id\": INQUIRY}", - " try:", - " with context(agent=\"mi-agent\", user=\"msl-de-0042\"):", - " if op == \"draft\":", - " draft = _draft()", - " search(inquiry_id=INQUIRY, revision=draft[\"revision\"], query=\"hepatic impairment\")", - " result[\"outcome\"] = \"executed\"", - " elif op == \"approve\":", - " approval = store.grant_approval(request[\"request_id\"], \"human:medical-reviewer\")", - " result[\"outcome\"] = \"approved\"", - " result[\"approval_id\"] = approval.approval_id", - " result[\"action_hash\"] = approval.action_hash", - " elif op == \"refresh\":", - " draft_index[0] = 1", - " result[\"outcome\"] = \"refreshed\"", - " result[\"superseded\"] = \"DEMO-STUDY-02 superseded by DEMO-STUDY-04\"", - " elif op == \"send\":", - " _send(request.get(\"approval_id\"))", - " result[\"outcome\"] = \"executed\"", - " elif op == \"event\":", - " portal.lose_reply = bool(request.get(\"lose_reply\"))", - " report_icsr(inquiry_id=INQUIRY, term=\"hepatic enzyme increased\")", - " result[\"outcome\"] = \"executed\"", - " elif op == \"unapproved\":", - " cite_unapproved_use(inquiry_id=INQUIRY, claim=\"use in an unapproved indication\")", - " result[\"outcome\"] = \"executed\"", - " elif op == \"unreviewed\":", - " publish_unreviewed(inquiry_id=INQUIRY)", - " result[\"outcome\"] = \"executed\"", - " else:", - " result[\"outcome\"] = \"unknown_op\"", - " except ApprovalRequired as pending:", - " record = store.get_approval(pending.request_id)", - " result[\"outcome\"] = \"approval_required\"", - " result[\"request_id\"] = pending.request_id", - " result[\"action_hash\"] = record.action_hash if record else \"\"", - " except ApprovalMismatch as refused:", - " result[\"outcome\"] = \"approval_mismatch\"", - " result[\"reason\"] = refused.reason", - " except ActionDenied as refused:", - " result[\"outcome\"] = \"denied\"", - " result[\"reason\"] = refused.reason", - " except DuplicateEffect as refused:", - " result[\"outcome\"] = \"duplicate\"", - " result[\"reason\"] = refused.state", - " except AmbiguousEffect as refused:", - " result[\"outcome\"] = \"ambiguous_retry\"", - " result[\"reason\"] = refused.effect_key", - " except TimeoutError as lost:", - " result[\"outcome\"] = \"reply_lost\"", - " result[\"reason\"] = str(lost)", - " draft = _draft()", - " result[\"revision\"] = draft[\"revision\"]", - " result[\"retrieved\"] = draft[\"retrieved\"]", - " result[\"recommendation\"] = draft[\"recommendation\"]", - " result[\"references\"] = draft[\"references\"]", - " result[\"letters\"] = len(portal.letters)", - " result[\"cases\"] = len(portal.cases)", - " return json.dumps(result)" - ].join("\n"); - - var MONO = "font-family:ui-monospace,SFMono-Regular,Menlo,monospace;"; - - //: The reference the newer study brings in. The panel marks it so a reader can see which - //: line moved without diffing two revisions by eye. - var NEW_REFERENCE = "DEMO-STUDY-04"; - - // Built as nodes rather than markup. Nothing here is attacker-controlled -- every string - // comes from the module in this file -- but a page whose whole subject is a boundary does - // not hand strings to an HTML parser to make a bulleted list. - function el(tag, style, text) { - var node = document.createElement(tag); - node.setAttribute("style", style); - if (text) node.textContent = text; - return node; - } - - function ready(fn) { - if (document.readyState !== "loading") fn(); - else document.addEventListener("DOMContentLoaded", fn); - } - - function load(src) { - return new Promise(function (resolve, reject) { - var tag = document.createElement("script"); - tag.src = src; - tag.onload = resolve; - tag.onerror = function () { - reject(new Error("could not load " + src)); - }; - document.head.appendChild(tag); - }); - } - - var runtimePromise = null; - - function runtime(say) { - if (runtimePromise) return runtimePromise; - runtimePromise = (async function () { - say("Loading Python in this tab. The first run downloads about 10 MB from the Pyodide\nCDN and the ctrlrun wheel from PyPI; after that the browser caches them."); - if (!window.loadPyodide) await load(PYODIDE + "pyodide.js"); - var pyodide = await window.loadPyodide({ indexURL: PYODIDE }); - say("Installing ctrlrun from PyPI…"); - await pyodide.loadPackage(PACKAGES); - var micropip = pyodide.pyimport("micropip"); - await micropip.install("ctrlrun"); - return pyodide; - })(); - runtimePromise.catch(function () { - runtimePromise = null; // a failed download is retried on the next click - }); - return runtimePromise; - } - - // What each outcome the module can return says to a reader, and which colour it is shown in. - // Every branch of `step`'s try/except is named here; a new one with no entry would print - // its raw outcome, which the test suite refuses. - var OUTCOMES = { - executed: ["ran", "ok"], - approved: ["the reviewer signed for this exact letter", "ok"], - refreshed: ["the draft changed under the signature", "warn"], - approval_required: ["a human decides", "warn"], - approval_mismatch: ["BLOCKED — the approved letter is not the letter being sent", "stop"], - denied: ["BLOCKED — the policy refuses this", "stop"], - duplicate: ["BLOCKED — this letter already went out", "stop"], - ambiguous_retry: ["BLOCKED — the case may already be filed; blind retry refused", "stop"], - reply_lost: ["the reply never came back — outcome AMBIGUOUS, not failed", "warn"], - unknown_op: ["nothing to do", "ok"], - }; - - // The site is a single-page app and this script runs once, when the page becomes - // interactive: on a first load that can be before React has painted the container, and on a - // navigation from another page the script does not run again at all. Both were true of the - // first version of this file, where every button did nothing. So wiring is attempted now and - // again on every DOM change; `wire` is a `getElementById` and a flag check when there is - // nothing to do, and the flag lives on the element, so a container React mounts afresh is - // wired afresh. - function wire() { - var root = document.getElementById(CONTAINER); - if (!root) return; // every other page on the site - if (root.getAttribute("data-wired") === "yes") return; - root.setAttribute("data-wired", "yes"); - - var find = function (name) { - return root.querySelector("[name='" + name + "']"); - }; - var buttons = {}; - ["draft", "send", "approve", "refresh", "event", "unapproved", "reset"].forEach(function (name) { - buttons[name] = find(name); - }); - var loseReply = find("lose_reply"); - var letter = find("letter"); - var transcript = find("transcript"); - if (!letter || !transcript || !buttons.draft) return; - - var pyodide = null; - var pending = null; - var approval = null; - var busy = false; - - function say(text) { - transcript.textContent += (transcript.textContent ? "\n" : "") + text; - transcript.scrollTop = transcript.scrollHeight; - } - - function stage(next) { - Object.keys(buttons).forEach(function (name) { - var button = buttons[name]; - if (!button) return; - var live = name === "reset" || name === "event" || name === "unapproved" || name === next; - button.disabled = !live; - button.style.opacity = live ? "1" : "0.35"; - button.style.cursor = live ? "pointer" : "not-allowed"; - button.style.boxShadow = name === next ? "0 0 0 3px rgba(184,115,10,0.35)" : "none"; - }); - } - - function render(result) { - var made = document.createDocumentFragment(); - made.appendChild( - el("div", MONO + "font-size:12px;opacity:0.7;letter-spacing:0.04em;text-transform:uppercase", - "Standard response letter · " + result.inquiry_id + " · revision " + result.revision + - " · evidence retrieved " + result.retrieved) - ); - made.appendChild(el("p", "font-size:16px;margin:12px 0 4px;font-weight:600", result.recommendation)); - made.appendChild(el("div", "font-size:12px;opacity:0.7;margin-bottom:4px", "References")); - var list = el("ul", "margin:0;padding-left:20px", ""); - (result.references || []).forEach(function (reference, index) { - var fresh = reference === NEW_REFERENCE; - list.appendChild( - el("li", MONO + "font-size:13px;" + (fresh ? "font-weight:600;" : ""), - "[" + (index + 1) + "] " + reference + (fresh ? " ← new" : "")) - ); - }); - made.appendChild(list); - letter.textContent = ""; - letter.appendChild(made); - } - - async function run(op, extra) { - if (busy) return; - busy = true; - try { - if (!pyodide) { - pyodide = await runtime(say); - pyodide.runPython(MODULE); - say("ctrlrun is running in this tab. Nothing leaves it.\n"); - } - var request = { op: op }; - if (extra) Object.keys(extra).forEach(function (key) { request[key] = extra[key]; }); - pyodide.globals.set("MEDICAL_REQUEST", JSON.stringify(request)); - var result = JSON.parse(pyodide.runPython("step(MEDICAL_REQUEST)")); - report(op, result); - render(result); - } catch (error) { - say( - "\nThis did not run in this browser:\n\n " + - (error && error.message ? error.message : String(error)) + - "\n\nThat is this page failing, not CTRLRun. Run it locally instead:\n\n pip install ctrlrun && ctrlrun demo" - ); - } finally { - busy = false; - } - } - - function report(op, result) { - var known = OUTCOMES[result.outcome] || [result.outcome, "warn"]; - var mark = known[1] === "stop" ? "✗" : known[1] === "warn" ? "○" : "✓"; - say("\n$ " + op); - say(" " + mark + " " + known[0] + (result.reason ? " (" + result.reason + ")" : "")); - - if (result.outcome === "approval_required") { - pending = result.request_id; - say(" request " + result.request_id); - say(" bound to " + (result.action_hash || "").slice(0, 27) + "…"); - stage("approve"); - } else if (result.outcome === "approved") { - approval = result.approval_id; - say(" approval " + result.approval_id); - say(" action hash " + (result.action_hash || "").slice(0, 27) + "…"); - say(" the reviewer read revision " + result.revision + " and signed for that one"); - stage("refresh"); - } else if (result.outcome === "refreshed") { - say(" " + result.superseded); - say(" the letter now recommends the opposite, under yesterday's signature"); - stage("send"); - } else if (result.outcome === "approval_mismatch") { - say(" the approval covers a letter with a different recommendation"); - say(" nothing but a new approval, on the new letter, moves this on"); - stage("reset"); - } else if (op === "draft") { - stage("send"); - } - say(" letters sent to the physician: " + result.letters + " safety cases filed: " + result.cases); - } - - buttons.draft.addEventListener("click", function () { run("draft"); }); - buttons.send.addEventListener("click", function () { run("send", approval ? { approval_id: approval } : null); }); - buttons.approve.addEventListener("click", function () { run("approve", { request_id: pending }); }); - buttons.refresh.addEventListener("click", function () { run("refresh"); }); - if (buttons.event) { - buttons.event.addEventListener("click", function () { - run("event", { lose_reply: !!(loseReply && loseReply.checked) }); - }); - } - if (buttons.unapproved) { - buttons.unapproved.addEventListener("click", function () { run("unapproved"); }); - } - if (buttons.reset) { - buttons.reset.addEventListener("click", function () { - pending = null; - approval = null; - transcript.textContent = ""; - if (pyodide) pyodide.runPython(MODULE); - stage("draft"); - letter.textContent = ""; - say("A fresh store, a fresh policy, revision A. Press Retrieve and draft."); - }); - } - - stage("draft"); - say("Press Retrieve and draft. The first press downloads Python and the ctrlrun wheel."); - } - - ready(wire); - if (window.MutationObserver) { - new MutationObserver(wire).observe(document.documentElement, { - childList: true, - subtree: true, - }); - } -})(); diff --git a/docs/medical-workbench.js b/docs/medical-workbench.js deleted file mode 100644 index d2afa0d..0000000 --- a/docs/medical-workbench.js +++ /dev/null @@ -1,350 +0,0 @@ -/* Medical evidence workflow. Synthetic fixtures; real CTRLRun release decisions. */ -(function(){ -"use strict"; -var TEMPLATE="<div id=\"cr-medical-workbench\" aria-label=\"CTRLRun Medical Affairs evidence workbench\">\n \n <header class=\"cr-top\">\n <div class=\"cr-brand\"><span class=\"cr-logo\" aria-hidden=\"true\">\u2713</span><span>CTRLRun</span><span class=\"cr-sep\">/</span><span>Medical Affairs</span></div>\n <span class=\"cr-badge\">Synthetic evidence \u00b7 real CTRLRun controls</span>\n </header>\n <div class=\"cr-body\">\n <div class=\"cr-title\">\n <div><div class=\"cr-small\">EVIDENCE WORKBENCH / DEMO-001</div><h2>From evidence to a reviewed brief</h2><div class=\"cr-small\">Compound X \u00b7 Condition Y \u00b7 Fictional products, studies and findings</div></div>\n <div class=\"cr-actions\"><span class=\"cr-badge\" id=\"cr-doc-status\">Draft \u00b7 v1</span><button type=\"button\" class=\"cr-button\" data-action=\"restart\">Start a new case</button></div>\n </div>\n <nav class=\"cr-steps\" aria-label=\"Evidence workflow\">\n <button class=\"cr-step\" type=\"button\" data-step=\"0\" aria-current=\"step\"><span class=\"cr-num\">01</span>Retrieve</button>\n <button class=\"cr-step\" type=\"button\" data-step=\"1\"><span class=\"cr-num\">02</span>Reason</button>\n <button class=\"cr-step\" type=\"button\" data-step=\"2\"><span class=\"cr-num\">03</span>Cite</button>\n <button class=\"cr-step\" type=\"button\" data-step=\"3\"><span class=\"cr-num\">04</span>Validate</button>\n <button class=\"cr-step\" type=\"button\" data-step=\"4\"><span class=\"cr-num\">05</span>Review</button>\n <button class=\"cr-step\" type=\"button\" data-step=\"5\"><span class=\"cr-num\">06</span>Release</button>\n </nav>\n <main id=\"cr-stage\" aria-label=\"Selected workflow stage\"></main>\n <div class=\"cr-next\"><span class=\"cr-small\" id=\"cr-stage-caption\"></span><button id=\"cr-next-button\" type=\"button\" class=\"cr-button primary\">Reason over evidence </button></div>\n <div class=\"cr-actions\"><button type=\"button\" class=\"cr-button\" data-action=\"download-brief\">Download review brief</button><button type=\"button\" class=\"cr-button\" data-action=\"download-audit\">Download evidence & audit record</button></div>\n<div id=\"cr-announcement\" class=\"cr-small\" aria-live=\"polite\" style=\"margin-top:10px\"></div>\n </div>\n <footer class=\"cr-footer\">\n <details open><summary>Build map \u00b7 what ctrlrun provides, and what you add</summary>\n <div class=\"cr-map\">\n <section><span class=\"cr-badge\">Build around CTRLRun</span><h4 style=\"margin-top:10px\">Biomedical evidence harness</h4><ul><li>PubMed / trial / licensed document connectors</li><li>Source snapshots and passage IDs</li><li>LLM extraction, synthesis and claim mapping</li><li>Independent checks and reviewer interface</li></ul></section>\n <section><span class=\"cr-badge ok\">Existing ctrlrun primitives</span><h4 style=\"margin-top:10px\">Control the release action</h4><ul><li>Allow / approve / deny policy</li><li>Approval bound to exact action arguments</li><li>Effect reservation and duplicate blocking</li><li>Ambiguous outcomes and audit receipts</li></ul></section>\n <section><span class=\"cr-badge\">Integration work</span><h4 style=\"margin-top:10px\">Trusted release service</h4><ul><li>Verify validation records on the server</li><li>Bind immutable content and evidence digests</li><li>Authenticate reviewers and restrict write access</li><li>Check destination status before retry</li></ul></section>\n </div>\n </details>\n </footer>\n</div>"; -var MODULE = [ - "\"\"\"Synthetic evidence workbench: real policy, approval, effects, and receipts.", - "", - "The curated fixture validator is deliberately narrow. It is not a scientific", - "entailment model. Every destination write stays in memory.", - "\"\"\"", - "", - "import json", - "", - "from ctrlrun import (", - " ActionDenied,", - " AmbiguousEffect,", - " ApprovalMismatch,", - " ApprovalRequired,", - " Control,", - " DuplicateEffect,", - " EffectState,", - " InMemoryStateStore,", - " LocalApprovalProvider,", - " Policy,", - " context,", - " protect,", - " with_approval,", - ")", - "", - "POLICY = \"\"\"", - "schema: ctrlrun.policy/v2", - "actions:", - " medical.brief.release:", - " effect: \"medical-brief:{inquiry_id}:archive\"", - " rules:", - " - when: { validation_ok_eq: false }", - " decision: deny", - " - decision: approve", - "\"\"\"", - "", - "CLAIMS = {", - " \"C1\": (", - " 0,", - " \"R1\",", - " [", - " \"At week 12, response occurred in 60% of the Compound X group and 40% of the \"", - " \"placebo group, an absolute difference of 20 percentage points.\",", - " \"In the 12-week randomized trial, 60 of 100 participants on Compound X and 40 \"", - " \"of 100 on placebo met the response endpoint (20 percentage points apart).\",", - " ],", - " ),", - " \"C2\": (", - " 0,", - " \"R1\",", - " [", - " \"Adverse events were reported in 12 of 100 Compound X participants and 8 of 100 \"", - " \"placebo participants during the 12-week trial.\"", - " ],", - " ),", - " \"C3\": (", - " 1,", - " \"E1\",", - " [\"The single-arm extension cannot establish long-term comparative safety.\"],", - " ),", - "}", - "SOURCES = [", - " {\"id\": \"DEMO-RCT-01\", \"version\": \"Fixture 1.0\"},", - " {\"id\": \"DEMO-EXT-02\", \"version\": \"Fixture 1.0\"},", - "]", - "", - "", - "def validate(snapshot: dict[str, object]) -> dict[str, object]:", - " \"\"\"Check exact curated passages, calculations, scope, and source versions.\"\"\"", - " issues = []", - " claims = snapshot.get(\"claims\", [])", - " if [claim.get(\"id\") for claim in claims] != list(CLAIMS):", - " issues.append(\"The evidence brief must contain C1, C2 and C3 without unsupported claims.\")", - " for claim in claims:", - " expected = CLAIMS.get(claim.get(\"id\"))", - " if expected is None or (", - " claim.get(\"source\"),", - " claim.get(\"span\"),", - " claim.get(\"text\") in expected[2],", - " ) != (expected[0], expected[1], True):", - " issues.append(f\"{claim.get('id', 'Claim')} does not match a supported fixture passage.\")", - " if snapshot.get(\"sources\") != SOURCES:", - " issues.append(\"The source snapshot changed; review the new evidence.\")", - " if snapshot.get(\"validationVersion\") != snapshot.get(\"version\"):", - " issues.append(\"The validation report belongs to a different document version.\")", - " if snapshot.get(\"destination\") != \"Internal medical review archive\":", - " issues.append(\"This demonstration only releases to the internal review archive.\")", - " if snapshot.get(\"inquiry\") != \"DEMO-001\":", - " issues.append(\"The inquiry is outside this demonstration.\")", - " return {\"passed\": not issues, \"issues\": issues, \"difference_pp\": 60 - 40}", - "", - "", - "store = InMemoryStateStore()", - "control = Control(Policy.from_yaml(POLICY), store, LocalApprovalProvider(store))", - "deliveries = []", - "approval = None", - "approval_version = None", - "lose_reply = False", - "", - "", - "@protect(\"medical.brief.release\", control=control)", - "def release(inquiry_id: str, document_json: str, validation_ok: bool) -> dict[str, str]:", - " deliveries.append(json.loads(document_json))", - " if lose_reply:", - " raise TimeoutError(\"The simulated archive accepted the brief but its reply was lost.\")", - " return {\"document\": inquiry_id, \"status\": \"received\"}", - "", - "", - "def invoke(snapshot: dict[str, object], approval_id: str | None = None) -> dict[str, str]:", - " # Recompute the decision input here; a client-provided passed flag is ignored.", - " args = {", - " \"inquiry_id\": snapshot.get(\"inquiry\", \"DEMO-001\"),", - " \"document_json\": json.dumps(snapshot, sort_keys=True, separators=(\",\", \":\")),", - " \"validation_ok\": validate(snapshot)[\"passed\"],", - " }", - " if approval_id:", - " with with_approval(approval_id):", - " return release(**args)", - " return release(**args)", - "", - "", - "def step(request_json: str) -> str:", - " global approval, approval_version, lose_reply", - " request = json.loads(request_json)", - " snapshot = request[\"snapshot\"]", - " op = request[\"op\"]", - " result = {\"outcome\": \"validated\", \"validation\": validate(snapshot)}", - " try:", - " with context(agent=\"medical-evidence-demo\"):", - " if op == \"approve\":", - " if not request.get(\"reviewed\"):", - " result[\"outcome\"] = \"review_required\"", - " else:", - " try:", - " invoke(snapshot)", - " except ApprovalRequired as pending:", - " approved = store.grant_approval(", - " pending.request_id, \"human:demo-medical-reviewer\"", - " )", - " approval = approved.approval_id", - " approval_version = snapshot[\"version\"]", - " result.update(outcome=\"approved\", action_hash=approved.action_hash)", - " elif op == \"release\":", - " lose_reply = bool(request.get(\"lose_reply\"))", - " invoke(snapshot, approval)", - " result[\"outcome\"] = \"committed\"", - " elif op == \"reconcile\":", - " key = \"medical-brief:DEMO-001:archive\"", - " effect = store.get_effect(key)", - " if deliveries and effect and effect.state == EffectState.AMBIGUOUS:", - " store.resolve_effect(key, EffectState.COMMITTED, \"human:demo-medical-reviewer\")", - " result[\"outcome\"] = \"reconciled\"", - " else:", - " result[\"outcome\"] = \"nothing_to_reconcile\"", - " except ApprovalRequired:", - " result[\"outcome\"] = \"approval_required\"", - " except ApprovalMismatch as exc:", - " result.update(outcome=\"approval_mismatch\", reason=exc.reason)", - " except ActionDenied as exc:", - " result.update(outcome=\"validation_blocked\", reason=exc.reason)", - " except DuplicateEffect as exc:", - " result.update(outcome=\"duplicate\", reason=str(exc.state))", - " except AmbiguousEffect:", - " result[\"outcome\"] = \"ambiguous_retry\"", - " except TimeoutError:", - " result[\"outcome\"] = \"reply_lost\"", - " effect = store.get_effect(\"medical-brief:DEMO-001:archive\")", - " result.update(", - " approval_id=approval,", - " approval_version=approval_version,", - " writes=len(deliveries),", - " effect_state=str(effect.state).upper() if effect else \"Not attempted\",", - " receipts=[receipt.to_dict() for receipt in store.receipts()],", - " events=[event.to_dict() for event in store.events()],", - " )", - " return json.dumps(result)" -].join("\n"); - - var runtimePromise=null; - function runtime(say){ - if(runtimePromise)return runtimePromise; - runtimePromise=(async function(){ - const base='https://cdn.jsdelivr.net/pyodide/v314.0.6/full/'; - if(!window.loadPyodide)await new Promise((resolve,reject)=>{const script=document.createElement('script');script.src=base+'pyodide.js';script.onload=resolve;script.onerror=()=>{script.remove();reject(new Error('Python download failed'));};document.head.appendChild(script);}); - const py=await window.loadPyodide({indexURL:base});say('Installing CTRLRun in this browser…'); - await py.loadPackage(['micropip','pyyaml']);const pip=py.pyimport('micropip');try{await pip.install('ctrlrun==0.6.1');}finally{pip.destroy();}return py; - })();runtimePromise.catch(()=>{runtimePromise=null;});return runtimePromise; - } - -function mount(){ -const host=document.getElementById('medical-workbench-mount'); -if(!host||host.dataset.medicalWired)return; -host.dataset.medicalWired='true'; -host.innerHTML=TEMPLATE; -const root = document.getElementById('cr-medical-workbench'); - const stage = root.querySelector('#cr-stage'); - const next = root.querySelector('#cr-next-button'); - const announcement = root.querySelector('#cr-announcement'); - const sources = [ - {id:'DEMO-RCT-01',title:'Compound X versus placebo in Condition Y',type:'Randomized trial · synthetic full text',location:'Table 2 · Results · passage R1',excerpt:'At week 12, the prespecified response endpoint was met by 60 of 100 participants receiving Compound X and 40 of 100 receiving placebo. Adverse events were reported in 12 of 100 and 8 of 100 participants, respectively.',use:'Efficacy and observed adverse events',scope:'Adults · 12 weeks · 100 per arm',version:'Fixture 1.0',retained:true}, - {id:'DEMO-EXT-02',title:'Open-label follow-up of Compound X',type:'Single-arm extension · synthetic full text',location:'Methods · passage E1',excerpt:'Eighty participants entered a 24-week open-label extension. No concurrent control group was included. This study was not designed to estimate long-term comparative safety.',use:'Limitations and evidence gaps',scope:'Selected completers · 24 weeks',version:'Fixture 1.0',retained:true}, - {id:'DEMO-PROT-03',title:'Planned study of disease progression',type:'Study protocol · synthetic abstract only',location:'Abstract · passage P1',excerpt:'A future randomized study will evaluate disease progression. Recruitment has not begun and no results are available.',use:'Excluded from outcome claims',scope:'Planned study · no outcomes',version:'Fixture 1.0',retained:false} - ]; - const state = {step:0,source:0,claim:0,unsupported:false,version:1,reviewed:0,approval:null,remoteCalls:0,outcome:'Not attempted',loseReply:false,events:[],status:null,receipts:[],engineEvents:[],busy:false}; - const labels = ['Retrieve','Reason','Cite','Validate','Review','Release']; - const captions = ['Fixture search · 3 records / 2 retained / 1 excluded','Prewritten synthesis · no LLM call · comparisons kept separate','Claim-level provenance · select a sentence to inspect support','Curated fixture checks · scientific support still needs human review','Human decision · approval covers this version and destination','Real CTRLRun decisions · in-memory archive · nothing is sent']; - const nextLabels = ['Reason over evidence','Inspect cited draft','Validate the draft','Open medical review','Open release gate','']; - const escape = value => String(value).replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); - const badge = (text, type='') => `<span class="cr-badge ${type}">${text}</span>`; - function claims(){ - const arr = [ - {id:'C1',text:'At week 12, response occurred in 60% of the Compound X group and 40% of the placebo group, an absolute difference of 20 percentage points.',source:0,span:'R1',note:'Endpoint, denominators, comparator and timepoint retained.'}, - {id:'C2',text:'Adverse events were reported in 12 of 100 Compound X participants and 8 of 100 placebo participants during the 12-week trial.',source:0,span:'R1',note:'Observed counts only; no claim of safety equivalence or causation.'}, - {id:'C3',text:'The single-arm extension cannot establish long-term comparative safety.',source:1,span:'E1',note:'Design limitation preserved; the extension is not pooled with the randomized trial.'} - ]; - if(state.version>1) arr[0].text='In the 12-week randomized trial, 60 of 100 participants on Compound X and 40 of 100 on placebo met the response endpoint (20 percentage points apart).'; - if(state.unsupported) arr.push({id:'C4',text:'Compound X prevents disease progression.',source:null,span:null,note:'No completed study in the source set reports this outcome.'}); - return arr; - } - function payload(){return JSON.stringify({inquiry:'DEMO-001',version:state.version,claims:claims(),sources:sources.filter(s=>s.retained).map(s=>({id:s.id,version:s.version})),destination:'Internal medical review archive',validationVersion:state.version});} - function matching(){return state.approval && state.approval.payload===payload();} - function log(title,detail){state.events.push({title,detail});} - function say(message){announcement.textContent=message;} - function sourceDetail(index){const s=sources[index];return `<div class="cr-small">SOURCE PASSAGE · SYNTHETIC</div><h3 style="margin-top:7px">${s.id}</h3><div class="cr-small">${s.location}</div><blockquote class="cr-quote">${s.excerpt}</blockquote><div class="cr-meta"><div><span class="cr-small">Population & follow-up</span><span>${s.scope}</span></div><div><span class="cr-small">Snapshot</span><span>${s.version}</span></div></div><div class="cr-rule"></div><span class="cr-small">${s.use}</span>`;} - function draft(interactive=false){return claims().map((c,i)=>interactive?`<button type="button" class="cr-claim ${c.source===null?'cr-error':''}" data-claim="${i}" aria-pressed="${state.claim===i}"><div class="cr-small">${c.id}${c.source===null?' · Missing support':''}</div>${c.text}<span class="cr-ref">${c.source===null?'No supporting passage':`[${sources[c.source].id} · ${c.span}]`}</span></button>`:`<p>${c.text}<br><span class="cr-ref">${c.source===null?'[Source missing]':`[${sources[c.source].id} · ${c.span}]`}</span></p>`).join('');} - function check(icon,title,detail,result,type){return `<div class="cr-check"><span class="${type==='bad'?'cr-danger':'cr-good'}">${icon}</span><div>${title}<div class="cr-small">${detail}</div></div>${badge(result,type)}</div>`;} - function status(){if(!state.status)return '';return `<div class="cr-status ${state.status.type}" role="status"><strong>${state.status.title}</strong><span>${state.status.detail}</span></div>`;} - function render(){ - root.querySelectorAll('[data-step]').forEach(btn=>{if(Number(btn.dataset.step)===state.step)btn.setAttribute('aria-current','step');else btn.removeAttribute('aria-current');}); - root.querySelector('#cr-doc-status').textContent=`${matching()?'Approved':'Draft'} · v${state.version}`; - root.querySelector('#cr-stage-caption').textContent=captions[state.step]; - next.hidden=state.step===5; - next.textContent=nextLabels[state.step]; - if(state.step===0){ - stage.innerHTML=`<div class="cr-stage-head"><h3>Retrieve a bounded evidence set</h3>${badge('Fixture workflow')}</div><div class="cr-panel" style="margin-bottom:16px"><div class="cr-small">MEDICAL AFFAIRS REQUEST</div><div style="margin-top:5px">Prepare an internal evidence brief on Compound X in adults with Condition Y: efficacy, reported adverse events and evidence gaps.</div></div><div class="cr-grid"><div class="cr-stack">${sources.map((s,i)=>`<button type="button" class="cr-source" data-source="${i}" aria-pressed="${state.source===i}"><span class="cr-row"><span class="cr-mono">${s.id}</span>${badge(s.retained?'Retained':'Excluded',s.retained?'ok':'')}</span><strong>${s.title}</strong><span class="cr-small">${s.type}</span></button>`).join('')}</div><aside class="cr-panel">${sourceDetail(state.source)}</aside></div>`; - }else if(state.step===1){ - stage.innerHTML=`<div class="cr-stage-head"><h3>Separate findings from interpretation</h3>${badge('Fixture workflow')}</div><div class="cr-grid"><section class="cr-panel"><h3>Structured evidence</h3><table class="cr-table"><thead><tr><th>12-week trial</th><th>Compound X</th><th>Placebo</th></tr></thead><tbody><tr><td>Participants</td><td>100</td><td>100</td></tr><tr><td>Responders</td><td>60 / 100</td><td>40 / 100</td></tr><tr><td>Adverse events</td><td>12 / 100</td><td>8 / 100</td></tr></tbody></table><div class="cr-note">Synthetic values · DEMO-RCT-01 / R1</div><div class="cr-rule"></div><div class="cr-row"><span>Absolute response difference</span>${badge('20 percentage points')}</div></section><section class="cr-panel"><h3>Synthesis decisions</h3><dl class="cr-facts"><div><dt>Comparable</dt><dd>Randomized arms at the same 12-week endpoint</dd></div><div><dt>Keep separate</dt><dd>24-week single-arm extension</dd></div><div><dt>Retain</dt><dd>Adverse events, study design and limitations</dd></div><div><dt>Unanswered</dt><dd>Disease progression and long-term comparative safety</dd></div></dl><div class="cr-rule"></div><span class="cr-small">Reviewable rationale · no hidden reasoning trace</span></section></div>`; - }else if(state.step===2){ - const c=claims()[Math.min(state.claim,claims().length-1)]; - stage.innerHTML=`<div class="cr-stage-head"><h3>Every claim has a visible evidence trail</h3>${badge(`${claims().filter(c=>c.source!==null).length} / ${claims().length} claims linked`,state.unsupported?'bad':'')}</div><div class="cr-grid"><section class="cr-panel"><div class="cr-row"><h3 style="margin:0">Evidence brief · v${state.version}</h3><span class="cr-small">Internal draft</span></div>${draft(true)}<div class="cr-actions"><button type="button" class="cr-button ${state.unsupported?'':'warn'}" data-action="toggle-claim">${state.unsupported?'Remove unsupported claim':'Inject an unsupported claim'}</button></div></section><aside class="cr-panel">${c.source===null?`<div class="cr-small">CLAIM ${c.id}</div><h3 style="margin-top:8px">No supporting passage</h3><div class="cr-status bad"><strong>Evidence gap</strong><span>The protocol describes a future study; it contains no progression result.</span></div><div class="cr-small">Validation should block this claim from release.</div>`:sourceDetail(c.source)}<div class="cr-rule"></div><div class="cr-small">CLAIM REVIEW · ${c.id}</div><div style="margin-top:5px">${c.note}</div></aside></div>`; - }else if(state.step===3){ - const resolved=claims().every(c=>c.source!==null&&sources[c.source].retained); - const delta=(60/100-40/100)*100; - stage.innerHTML=`<div class="cr-stage-head"><h3>Validate before asking for approval</h3>${badge(resolved?'Mechanical checks pass':'1 blocking issue',resolved?'ok':'bad')}</div><div class="cr-grid"><section class="cr-panel"><h3>Validation report · v${state.version}</h3>${status()}${check(resolved?'✓':'×','Citation references resolve',resolved?'Each claim maps to a retained source and passage.':'C4 has no supporting source passage.',resolved?'Pass':'Block',resolved?'ok':'bad')}${check('✓','Numerical consistency',`${delta.toFixed(0)} percentage points recomputed from 60/100 and 40/100.`,'Pass','ok')}${check('✓','Source scope retained','12-week trial and single-arm extension remain distinct.','Pass','ok')}${check('◇','Scientific support and balance','Reviewer must assess relevance, interpretation and missing evidence.',state.reviewed===state.version?'Reviewed':'Human review',state.reviewed===state.version?'ok':'')}</section><aside class="cr-panel"><h3>Release prerequisites</h3><dl class="cr-facts"><div><dt>Evidence</dt><dd>Resolvable passages for each claim</dd></div><div><dt>Checks</dt><dd>No unresolved blocking issue</dd></div><div><dt>Reviewer</dt><dd>Named approval for the current version</dd></div></dl>${resolved?`<div class="cr-status ok"><strong>Ready for medical review</strong><span>Mechanical checks do not establish medical correctness.</span></div>`:`<div class="cr-status bad" role="alert"><strong>Unsupported claim held</strong><span>“Compound X prevents disease progression.”</span></div><button type="button" class="cr-button" data-action="toggle-claim">Remove unsupported claim</button>`}<div class="cr-note">Python recomputes the curated fixture checks before release. A production application must supply scientific validation and authenticated review.</div></aside></div>`; - }else if(state.step===4){ - stage.innerHTML=`<div class="cr-stage-head"><h3>Review the work product and its sources</h3>${badge('Human review + ctrlrun approval')}</div><div class="cr-grid"><article class="cr-panel cr-letter"><div class="cr-small">INTERNAL EVIDENCE BRIEF · DEMO-001 · v${state.version}</div><h3 style="margin-top:12px">Compound X in Condition Y</h3>${draft()}<div class="cr-rule"></div><div class="cr-small">Review packet: brief · source snapshots · claim map · validation report</div></article><aside class="cr-panel"><h3>Medical reviewer</h3><dl class="cr-facts"><div><dt>Identity</dt><dd>Demo reviewer (simulated)</dd></div><div><dt>Destination</dt><dd>Internal medical review archive</dd></div><div><dt>Version</dt><dd>v${state.version}${state.approval?` · approval covers v${state.approval.version}`:''}</dd></div></dl><label class="cr-label"><input type="checkbox" data-action="reviewed" ${state.reviewed===state.version?'checked':''} ${state.unsupported?'disabled':''}><span>I reviewed claim support, limitations and the destination.</span></label>${state.unsupported?`<div class="cr-status bad"><strong>Approval blocked</strong><span>Resolve the unsupported claim in Validate.</span></div>`:''}<div class="cr-actions"><button type="button" class="cr-button primary" data-action="approve" ${state.reviewed!==state.version||state.unsupported||matching()?'disabled':''}>${matching()?'This version approved':'Approve this version'}</button><button type="button" class="cr-button" data-action="edit" ${!state.approval||state.remoteCalls?'disabled':''}>Simulate edit after approval</button></div>${status()}<div class="cr-note">The release action must bind the immutable document, evidence, validation record and destination.</div></aside></div>`; - }else{ - stage.innerHTML=`<div class="cr-stage-head"><h3>Release only the reviewed version</h3>${badge('ctrlrun control boundary')}</div><div class="cr-grid"><section class="cr-panel"><h3>Protected release</h3><dl class="cr-facts"><div><dt>Document</dt><dd>DEMO-001 · v${state.version}</dd></div><div><dt>Approval</dt><dd>${state.approval?(matching()?`Matches v${state.version}`:`Mismatch · covers v${state.approval.version}`):'Required'}</dd></div><div><dt>Destination</dt><dd>Internal medical review archive</dd></div><div><dt>Effect</dt><dd class="cr-mono">medical-brief:DEMO-001:archive</dd></div><div><dt>Outcome</dt><dd>${state.outcome}</dd></div><div><dt>Writes</dt><dd>${state.remoteCalls} simulated destination writes</dd></div></dl><label class="cr-label"><input type="checkbox" data-action="lose-reply" ${state.loseReply?'checked':''} ${state.remoteCalls?'disabled':''}><span>Simulate a lost destination reply</span></label><div class="cr-actions"><button type="button" class="cr-button primary" data-action="release">${state.remoteCalls?'Retry release':'Attempt release'}</button>${(!matching()||!state.approval)&&!state.remoteCalls?'<button type="button" class="cr-button" data-action="go-review">Return to review</button>':''}${state.outcome==='AMBIGUOUS'?'<button type="button" class="cr-button" data-action="reconcile">Check simulated destination</button>':''}</div>${status()}</section><aside class="cr-panel"><h3>Activity trail <span class="cr-small">· browser session</span></h3>${state.events.length?`<ol class="cr-log">${state.events.slice(-6).map((e,i)=>`<li><span class="cr-small">${String(Math.max(0,state.events.length-6)+i+1).padStart(2,'0')}</span><span>${escape(e.title)}<span class="cr-small" style="display:block">${escape(e.detail)}</span></span></li>`).join('')}</ol>`:'<div class="cr-small">Review decisions and release attempts appear here.</div>'}<div class="cr-note">${state.receipts.length} real CTRLRun receipts · included in the audit download</div></aside></div>`; - } - root.setAttribute('aria-busy', String(state.busy)); - root.querySelectorAll('button, input').forEach(node => { - if(state.busy){ - if(!node.hasAttribute('data-was-disabled'))node.dataset.wasDisabled=String(node.disabled); - node.disabled=true; - }else if(node.hasAttribute('data-was-disabled')){ - node.disabled=node.dataset.wasDisabled==='true'; - delete node.dataset.wasDisabled; - } - }); - } - - let namespace=null; - function download(name,content,type){const url=URL.createObjectURL(new Blob([content],{type:type+';charset=utf-8'}));const anchor=document.createElement('a');anchor.href=url;anchor.download=name;root.appendChild(anchor);anchor.click();anchor.remove();setTimeout(()=>URL.revokeObjectURL(url),1000);} - async function execute(op){ - state.busy=true; render(); say('Loading the Python runtime and CTRLRun, then checking this exact document…'); - try{ - const py=await runtime(say); - if(!namespace){namespace=py.toPy({});py.runPython(MODULE,{globals:namespace});} - const fn=namespace.get('step'); - let result; - try{result=JSON.parse(fn(JSON.stringify({op,snapshot:JSON.parse(payload()),reviewed:state.reviewed===state.version,lose_reply:state.loseReply})));}finally{fn.destroy();} - state.remoteCalls=result.writes;state.outcome=result.effect_state;state.receipts=result.receipts;state.engineEvents=result.events; - const outcomes={ - validated:['Fixture checks completed',result.validation.passed?'Known passages, numerical values and evidence versions match. Scientific interpretation still requires review.':result.validation.issues.join(' '),result.validation.passed?'ok':'bad'], - approved:['Approval recorded','CTRLRun bound the approval to the exact document, source versions, validation version and destination.','ok'], - review_required:['Reviewer confirmation required','Inspect the claims and sources before approving.','bad'], - approval_required:['Human approval required','CTRLRun held the release. No destination write occurred.',''], - approval_mismatch:[result.reason==='consumed'?'Approval already used · retry blocked':'Approval mismatch · release blocked',result.reason==='consumed'?'CTRLRun refused the consumed approval. The recorded delivery outcome is '+result.effect_state+'. Reconcile an unknown outcome before considering another attempt.':'The current action differs from what the reviewer approved. Return to review for a fresh approval.','bad'], - validation_blocked:['Validation blocked release',result.validation.issues.join(' '),'bad'], - committed:['Reviewed brief released','The approved document reached the simulated archive. CTRLRun recorded COMMITTED.','ok'], - duplicate:['Duplicate release blocked','CTRLRun refused an already committed effect. Destination writes remain at one.','bad'], - ambiguous_retry:['Blind retry blocked','CTRLRun refused an effect whose outcome is still AMBIGUOUS.','bad'], - reply_lost:['Reply lost · outcome AMBIGUOUS','The simulated archive accepted the document, but its response was lost. This is not a confirmed failure.',''], - reconciled:['Destination confirms receipt','The simulated lookup confirmed the original write. The effect is now COMMITTED without another delivery.','ok'], - nothing_to_reconcile:['No unresolved delivery','There is no ambiguous delivery to reconcile.',''] - }; - const message=outcomes[result.outcome]||['Unexpected outcome',result.outcome,'bad']; - state.status={title:message[0],detail:message[1],type:message[2]}; - log(message[0],message[1]);say(message[0]);return result; - }catch(error){state.status={title:'The Python runtime did not complete',detail:'Check the connection and try again. No successful action is being claimed. Local alternative: pip install ctrlrun && ctrlrun demo. '+String(error.message||error),type:'bad'};say(state.status.detail);return null;} - finally{state.busy=false;if(root.isConnected)render();} - } - root.addEventListener('click', async event=>{ - const btn=event.target.closest('button');if(!btn||!root.contains(btn)||state.busy)return; - if(btn.dataset.step!==undefined){state.step=Number(btn.dataset.step);render();say(`${labels[state.step]} stage selected.`);if(state.step===3)await execute('validate');return;} - if(btn.dataset.source!==undefined){state.source=Number(btn.dataset.source);render();say(`${sources[state.source].id} selected.`);return;} - if(btn.dataset.claim!==undefined){state.claim=Number(btn.dataset.claim);render();say(`Showing evidence for ${claims()[state.claim].id}.`);return;} - const action=btn.dataset.action; - if(action==='toggle-claim'){ - state.unsupported=!state.unsupported;state.version++;state.reviewed=0;state.claim=state.unsupported?3:0;state.status=null; - log(state.unsupported?'Unsupported claim injected':'Unsupported claim removed',`Draft advanced to v${state.version}.`); - say(state.unsupported?'Unsupported progression claim added. Open Validate to inspect the block.':'Unsupported claim removed. The revised draft requires review.'); - }else if(action==='approve'){ - if(state.unsupported||state.reviewed!==state.version)return; - const result=await execute('approve'); - if(result && result.outcome==='approved'){ - state.approval={payload:payload(),version:state.version,id:result.approval_id}; - state.status={title:`Version ${state.version} approved`,detail:'The demo reviewer approved this exact action. CTRLRun recorded the approval and action hash.',type:'ok'}; - log('Review approved',`Demo reviewer · v${state.version} · ${result.action_hash}`); - } - }else if(action==='edit'){ - state.version++;state.reviewed=0;state.status={title:'The approval no longer matches',detail:`Approval covers v${state.approval.version}; the document is now v${state.version}. Even a wording change needs fresh approval.`,type:'bad'}; - log('Document changed after approval',`Current v${state.version}; approval still covers v${state.approval.version}.`);say('Draft changed. Attempt release to see the approval mismatch.'); - }else if(action==='go-review'){state.step=4;state.status=null;say('Review the current version.'); - }else if(action==='release'){ - await execute('release'); - }else if(action==='reconcile'){ - await execute('reconcile'); - }else if(action==='restart'){ - if(namespace){namespace.destroy();namespace=null;} - Object.assign(state,{step:0,source:0,claim:0,unsupported:false,version:1,reviewed:0,approval:null,remoteCalls:0,outcome:'Not attempted',loseReply:false,events:[],status:null,receipts:[],engineEvents:[]}); - say('New case. Prior session data is cleared; download any records before starting over.'); - }else if(action==='download-brief'){ - const lines=['# Medical Affairs evidence brief','', 'SYNTHETIC DEMONSTRATION — not medical information about a real medicine.', '', `DEMO-001 · v${state.version} · ${matching()?'Reviewed by demo reviewer':'DRAFT — not approved'}`, '', '## Question', 'Compound X in adults with Condition Y: efficacy, reported adverse events and evidence gaps.', '', '## Findings']; - claims().forEach(c=>lines.push('',c.text,c.source===null?'[SOURCE MISSING]':`[${sources[c.source].id} / ${c.span}]`)); - lines.push('', '## Evidence and limitations'); - sources.forEach(s=>lines.push('',`### ${s.id} — ${s.title}`,s.type, s.scope, s.excerpt, `Disposition: ${s.use}. Snapshot: ${s.version}.`)); - lines.push('', '## Review scope','Prewritten findings and curated fixture checks. Scientific interpretation requires a qualified reviewer. Destination: internal medical review archive.'); - download('medical-evidence-brief-v'+state.version+'.md',lines.join('\n'),'text/markdown');say('Review brief downloaded with synthetic-data and review-status labels.'); - }else if(action==='download-audit'){ - download('medical-evidence-audit-v'+state.version+'.json',JSON.stringify({demonstration:'Synthetic evidence; real CTRLRun receipts; no external delivery',document:JSON.parse(payload()),source_passages:sources,activity:state.events,ctrlrun_receipts:state.receipts,ctrlrun_events:state.engineEvents},null,2),'application/json');say('Evidence and real CTRLRun audit records downloaded.'); - }else return; - render(); - }); - root.addEventListener('change',event=>{ - const action=event.target.dataset.action; - if(action==='reviewed'){state.reviewed=event.target.checked?state.version:0;render();} - if(action==='lose-reply'){state.loseReply=event.target.checked;} - }); - next.addEventListener('click',async()=>{state.step=Math.min(5,state.step+1);render();say(`${labels[state.step]} stage selected.`);if(state.step===3)await execute('validate');}); - render(); - -} -if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',mount);else mount(); -new MutationObserver(mount).observe(document.documentElement,{childList:true,subtree:true}); -})(); diff --git a/docs/protect-my-agent.mdx b/docs/protect-my-agent.mdx deleted file mode 100644 index 2d3daef..0000000 --- a/docs/protect-my-agent.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "Execution-safety review" -description: "Get a focused execution-safety review with a concrete action map and prioritized implementation plan for your production AI agent." -canonical: "https://ctrlrun.dev/protect-my-agent" -mode: "custom" ---- - -import { ArchitectureReview } from "/snippets/architecture-review.jsx"; - -<div className="cr-site cr-subpage"> - <a className="cr-text-link" href="/">← CTRLRun</a> - <p className="cr-eyebrow">FOR AGENTS MOVING INTO PRODUCTION</p> - <h1>Execution-safety review<span className="cr-dot">.</span></h1> - <p className="cr-lede">Know which actions are safe to automate.</p> - <p>Get a focused review of your agent’s actions, permissions, approval paths, duplicate-execution risks, and retry behavior. Leave with a concrete execution-control map and a prioritized implementation plan: what can run automatically, what needs a person, and what must stop until the outcome is known.</p> - <div className="cr-services"><details><summary>Execution-safety review</summary><p>A paid architecture review of tool boundaries, approval flows, duplicate execution, uncertain outcomes, and action records. A practical control map and prioritized implementation plan.</p></details><details><summary>Production Integration Sprint</summary><p>Hands-on integration, policy design, approval workflows, persistence, retry handling, reconciliation, and production testing. Scope agreed around your architecture.</p></details><details><summary>Ongoing Production Support</summary><p>A recurring engagement for new actions, policy changes, upgrades, incident analysis, and rollout reviews.</p></details></div> - - <section className="cr-review-example" aria-labelledby="cr-map-title"> - <p className="cr-eyebrow">WHAT YOU LEAVE WITH</p> - <h2 id="cr-map-title">A map for the actions your agent takes.</h2> - <p>Each action gets an execution decision and a recovery step. This refund example shows the shape of the deliverable.</p> - <p className="cr-caption">Illustrative example. Approval thresholds and controls are agreed for your architecture.</p> - <div className="cr-control-map" role="region" aria-label="Sample execution-control map" tabIndex={0}> - <table> - <thead><tr><th scope="col">Action</th><th scope="col">Execution decision</th><th scope="col">Recovery step</th></tr></thead> - <tbody> - <tr><th scope="row">Refund $25 within policy</th><td>Automatic</td><td>Record confirmed success; block another attempt for the same effect.</td></tr> - <tr><th scope="row">Refund $500 requiring approval</th><td>Approval</td><td>Wait for approval of the exact action. Changed arguments need a new approval.</td></tr> - <tr><th scope="row">Retry a refund after a lost response</th><td>Stop</td><td>Confirm the provider’s outcome before continuing. A confirmed refund stays blocked from executing again.</td></tr> - </tbody> - </table> - </div> - </section> - - <ArchitectureReview /> - <p className="cr-caption">Building it yourself? <a href="/docs/get-started/quickstart">Start integrating with CTRLRun OSS →</a></p> -</div> diff --git a/docs/risk-check.mdx b/docs/risk-check.mdx deleted file mode 100644 index 117d9ec..0000000 --- a/docs/risk-check.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Agent Execution Risk Check" -description: "Six questions to find where your agent architecture needs execution controls. A free check with practical next steps." -canonical: "https://ctrlrun.dev/risk-check" -mode: "custom" ---- - -import { RiskCheck } from "/snippets/risk-check.jsx"; - -<div className="cr-site cr-subpage"><a className="cr-text-link" href="/">← CTRLRun</a><p className="cr-eyebrow">SIX QUESTIONS. A CLEARER EXECUTION BOUNDARY.</p><h1>Agent Execution<br />Risk Check<span className="cr-dot">.</span></h1><p className="cr-lede">Find the gaps before your agent takes the next action.</p><p>Your answers stay in this browser. No email needed to see your result.</p><RiskCheck /></div> diff --git a/docs/snippets/architecture-review.jsx b/docs/snippets/architecture-review.jsx deleted file mode 100644 index 971e516..0000000 --- a/docs/snippets/architecture-review.jsx +++ /dev/null @@ -1,67 +0,0 @@ -export const ArchitectureReview = () => { - const [domain, setDomain] = useState(''); - const [risk, setRisk] = useState(''); - const endpoint = 'https://ctrlrun-review-form.vercel.app/api/review'; - const [emailAddress, setEmailAddress] = useState(''); - const [website, setWebsite] = useState(''); - const [sending, setSending] = useState(false); - const [sent, setSent] = useState(false); - const [error, setError] = useState(''); - const requestId = useRef(null); - const sendingRef = useRef(false); - const [company, setCompany] = useState(''); - const [purpose, setPurpose] = useState(''); - const [actions, setActions] = useState(''); - const [status, setStatus] = useState('Building'); - const [concerns, setConcerns] = useState([]); - const [started, setStarted] = useState(false); - const [prepared, setPrepared] = useState(false); - const [copied, setCopied] = useState(false); - const reviewRef = useRef(null); - const track = name => window.dispatchEvent(new CustomEvent('ctrlrun:conversion', { detail: { name } })); - useEffect(() => { - const params = new URLSearchParams(window.location.search); - setDomain((params.get('domain') || '').slice(0, 80)); - const level = params.get('risk'); - if (['High', 'Needs review', 'Lower indicated risk', 'Planning'].includes(level)) { - const count = Math.max(0, Math.min(5, Number(params.get('patterns')) || 0)); - const unknowns = Math.max(0, Math.min(5, Number(params.get('unknowns')) || 0)); - setRisk(level + ': ' + count + ' patterns, ' + unknowns + ' unknowns (self-reported)'); - } - }, []); - useEffect(() => { if (prepared && reviewRef.current) reviewRef.current.focus(); }, [prepared]); - const brief = ['Architecture review request', '', 'Company: ' + company, 'Reply email: ' + emailAddress, domain && 'Domain: ' + domain, 'Agent purpose: ' + purpose, 'Actions it can execute: ' + actions, 'Production status: ' + status, 'Primary concerns: ' + (concerns.join(', ') || 'Discuss during review'), risk && 'Execution risk check: ' + risk].filter(line => line !== false).join('\n'); - const email = 'mailto:contact@arpanghoshal.com?subject=' + encodeURIComponent('CTRLRun architecture review: ' + company) + '&body=' + encodeURIComponent(brief); - const sendReview = async () => { - if (sendingRef.current || sent) return; - sendingRef.current = true; setSending(true); setError(''); - try { - const response = await fetch(endpoint, { - method: 'POST', credentials: 'omit', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ company, email: emailAddress, purpose, actions, status, concerns, domain, risk, website, requestId: requestId.current }), - signal: AbortSignal.timeout(15000) - }); - const data = await response.json(); - if (!response.ok || data.ok !== true || typeof data.id !== 'string') throw new Error(data.error || 'We could not confirm submission. Please retry or email us directly.'); - setSent(true); track('architecture_review_form_submitted'); - } catch (failure) { - setError(failure.name === 'TimeoutError' || failure.name === 'TypeError' ? 'We could not confirm submission. You can retry the same request safely, or email us directly.' : failure.message); - } finally { sendingRef.current = false; setSending(false); } - }; - return <div className="cr-review"> - <h2>Tell us where your agent acts.</h2> - {domain && <p className="cr-domain-context">Execution-safety review for {domain}</p>} - {risk && <p className="cr-caption">Risk check: {risk}</p>} - <form onFocus={() => { if (!started) { setStarted(true); track('architecture_review_form_started'); } }} onChange={() => { setPrepared(false); setCopied(false); setSent(false); setError(''); requestId.current = null; }} onSubmit={event => { event.preventDefault(); if (!requestId.current) requestId.current = crypto.randomUUID(); setPrepared(true); track('architecture_review_form_prepared'); }}> - <fieldset disabled={sending || sent} className="cr-form-fields"><label className="cr-field">Work email<input name="email" type="email" autoComplete="email" required maxLength={254} value={emailAddress} onChange={event => setEmailAddress(event.target.value)} /></label> - <div className="cr-honeypot" aria-hidden="true"><label>Website<input tabIndex={-1} autoComplete="off" name="website" value={website} onChange={event => setWebsite(event.target.value)} /></label></div> - <label className="cr-field">Company<input name="company" autoComplete="organization" required maxLength={100} value={company} onChange={event => setCompany(event.target.value)} /></label> - <label className="cr-field">What does your agent do?<textarea name="purpose" required maxLength={400} rows={2} placeholder="For example, handles customer refund requests" value={purpose} onChange={event => setPurpose(event.target.value)} /></label> - <label className="cr-field">Which actions can it execute?<textarea name="actions" required maxLength={400} rows={2} placeholder="For example, issues refunds and cancels subscriptions" value={actions} onChange={event => setActions(event.target.value)} /></label> - <fieldset><legend>Production status</legend><div className="cr-radio-row">{['Exploring', 'Building', 'Already in production'].map(item => <label key={item}><input type="radio" name="production-status" value={item} checked={status === item} onChange={() => setStatus(item)} />{item}</label>)}</div></fieldset> - <fieldset><legend>Primary concerns <span className="cr-caption">(optional)</span></legend><div className="cr-check-grid">{['Wrong actions', 'Duplicate execution', 'Human approval', 'Retry safety', 'Permissions', 'Auditability', 'Other'].map(item => <label className="cr-check-option" key={item}><input type="checkbox" name="concerns" value={item} checked={concerns.includes(item)} onChange={() => setConcerns(previous => previous.includes(item) ? previous.filter(value => value !== item) : [...previous, item])} />{item}</label>)}</div></fieldset> - <p className="cr-caption">Review your brief before sending. Your contact details and responses will be emailed to the CTRLRun team through Resend, only to follow up on this request. Please leave out credentials and sensitive customer data.</p><button type="submit" className="cr-button">Review my request →</button></fieldset> - </form> - {prepared && <section className="cr-email-preview" ref={reviewRef} tabIndex={-1} aria-labelledby="cr-email-title"><h3 id="cr-email-title">{sent ? 'Review request submitted.' : 'Your request is ready to send.'}</h3><p>{sent ? "Thank you. The team will follow up at the work email you provided." : "Review the context below, then send it to the CTRLRun team."}</p><pre>{brief}</pre><div className="cr-actions">{!sent && <button type="button" className="cr-button" disabled={sending} onClick={sendReview}>{sending ? "Sending…" : error ? "Retry submission →" : "Send review request →"}</button>}{!sent && <a className="cr-text-link" href={email} onClick={() => track('architecture_review_email_opened')}>Use my email app instead ↗</a>}<button type="button" className="cr-button cr-secondary" onClick={async () => { try { await navigator.clipboard.writeText(brief); setCopied(true); } catch { setCopied(false); } }}>Copy brief</button></div><p role="status" className="cr-caption">{copied ? 'Brief copied. Paste it into an email when you’re ready.' : sent ? 'Your request was accepted for delivery. No further submission is needed.' : 'Your request has not been sent yet.'}</p>{error && <p role="alert" className="cr-form-error">{error} <a href="mailto:contact@arpanghoshal.com">contact@arpanghoshal.com</a></p>}</section>} - </div>; -}; diff --git a/docs/snippets/demo-film.jsx b/docs/snippets/demo-film.jsx deleted file mode 100644 index 5daeaca..0000000 --- a/docs/snippets/demo-film.jsx +++ /dev/null @@ -1,40 +0,0 @@ -export const DemoFilm = ({ src, poster, label }) => { - const ref = useRef(null); - const [started, setStarted] = useState(false); - - useEffect(() => { - const video = ref.current; - if (!video || typeof IntersectionObserver === 'undefined') return; - if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; - const observer = new IntersectionObserver(entries => { - entries.forEach(entry => { - if (entry.isIntersecting) { - const play = video.play(); - if (play && play.catch) play.catch(() => {}); - setStarted(true); - } else if (!video.paused) { - video.pause(); - } - }); - }, { threshold: 0.5 }); - observer.observe(video); - return () => observer.disconnect(); - }, []); - - return ( - <video - ref={ref} - className="cr-film" - controls - muted - loop - playsInline - preload={started ? 'auto' : 'none'} - poster={poster} - aria-label={label} - > - <source src={src} type="video/mp4" /> - Your browser cannot play this video. - </video> - ); -}; diff --git a/docs/snippets/risk-check.jsx b/docs/snippets/risk-check.jsx deleted file mode 100644 index b94b791..0000000 --- a/docs/snippets/risk-check.jsx +++ /dev/null @@ -1,51 +0,0 @@ -export const RiskCheck = () => { - const [actions, setActions] = useState([]); - const [answers, setAnswers] = useState(['', '', '', '', '']); - const [started, setStarted] = useState(false); - const [result, setResult] = useState(null); - const resultRef = useRef(null); - const actionOptions = ['Move money', 'Delete data', 'Send external communications', 'Modify permissions', 'Deploy infrastructure', 'Modify business records', 'None of these yet']; - const questions = [ - 'Can actions be retried automatically?', - 'Can a provider complete an action before your agent receives confirmation?', - 'Are approvals tied to the exact action and parameters?', - 'Can concurrent workers trigger the same business action?', - 'Can you reconstruct why a specific action executed?' - ]; - const patterns = [ - { label: 'Automatic retries', advice: 'Identify the same business action across retries and prevent a second execution.', href: '/docs/concepts/effect-keys' }, - { label: 'Missing provider confirmation', advice: 'Treat a missing response as uncertain. Confirm the original outcome before retrying.', href: '/docs/concepts/outcomes-and-ambiguous' }, - { label: 'Approval can drift from the action', advice: 'Tie approval to the exact amount, target, and other parameters. Require a new approval when they change.', href: '/docs/concepts/approval-binding' }, - { label: 'Concurrent execution', advice: 'Make workers share an execution record so only one can begin the same business action.', href: '/docs/production/how-reservation-works' }, - { label: 'Missing action evidence', advice: 'Record who requested the action, the rule applied, the approval, and the final outcome.', href: '/docs/concepts/receipts-and-evidence' } - ]; - const track = (name, extra = {}) => window.dispatchEvent(new CustomEvent('ctrlrun:conversion', { detail: { name, ...extra } })); - const begin = () => { if (!started) { setStarted(true); track('risk_check_started'); } setResult(null); }; - const check = event => { - event.preventDefault(); - const risky = answers.map((answer, index) => answer === ([2, 4].includes(index) ? 'No' : 'Yes')); - const count = risky.filter(Boolean).length; - const unknowns = answers.filter(answer => answer === 'Unsure').length; - const active = !actions.includes('None of these yet'); - const level = !active ? 'Planning' : count >= 3 ? 'High' : count > 0 || unknowns > 0 ? 'Needs review' : 'Lower indicated risk'; - setResult({ count, unknowns, risky, active, level }); - track('risk_check_completed', { risk_level: level, pattern_count: count, unknown_count: unknowns }); - }; - useEffect(() => { if (result && resultRef.current) resultRef.current.focus(); }, [result]); - return <div className="cr-risk-check"> - <form onSubmit={check} onChange={begin}> - <fieldset><legend><span className="cr-question-number">01</span> What can your agent do?</legend><div className="cr-check-grid">{actionOptions.map(action => <label className="cr-check-option" key={action}><input type="checkbox" checked={actions.includes(action)} onChange={() => setActions(previous => previous.includes(action) ? previous.filter(item => item !== action) : action === 'None of these yet' ? [action] : [...previous.filter(item => item !== 'None of these yet'), action])} />{action}</label>)}</div></fieldset> - {questions.map((question, index) => <fieldset key={question}><legend><span className="cr-question-number">0{index + 2}</span>{question}</legend><div className="cr-radio-row">{['Yes', 'No', 'Unsure'].map(answer => <label key={answer}><input type="radio" name={'risk-' + index} required value={answer} checked={answers[index] === answer} onChange={() => setAnswers(previous => previous.map((item, position) => position === index ? answer : item))} />{answer}</label>)}</div></fieldset>)} - <button className="cr-button" type="submit" disabled={actions.length === 0}>Check my execution risk →</button>{actions.length === 0 && <p className="cr-caption">Choose at least one action, or “None of these yet”.</p>} - </form> - {result && <section className="cr-risk-result" ref={resultRef} tabIndex={-1} aria-labelledby="cr-risk-result-title"> - <p className="cr-eyebrow">YOUR EXECUTION RISK CHECK</p><h2 id="cr-risk-result-title">{result.level === 'Planning' ? 'Plan your execution boundary' : 'Execution risk: ' + result.level}</h2> - <p>{result.active ? 'Your answers identify ' + result.count + ' execution-risk pattern' + (result.count === 1 ? '' : 's') + ' CTRLRun is designed to address.' : 'You have not selected a consequential action yet. Use these questions before granting agents permission to act.'}</p> - {result.unknowns > 0 && <p>{result.unknowns} answer{result.unknowns === 1 ? ' needs' : 's need'} confirmation. Uncertainty is a reason to inspect your architecture, not proof that a control is missing.</p>} - <ul>{patterns.map((pattern, index) => (result.risky[index] || answers[index] === 'Unsure') && <li key={pattern.label}><strong>{answers[index] === 'Unsure' ? 'Check: ' : ''}{pattern.label}</strong><p>{pattern.advice} <a href={pattern.href}>Implementation guide →</a></p></li>)}</ul> - {result.count === 0 && result.unknowns === 0 && <p>Your answers indicate fewer of these patterns. Validate the controls with concurrency, changed-approval, and lost-response tests before rollout.</p>} - <p className="cr-caption">A planning aid based on your answers, not an audit or a safety certification. High means at least three indicated patterns; “Needs review” means one or more patterns or unknowns.</p> - <a className="cr-button" href={'/protect-my-agent?risk=' + encodeURIComponent(result.level) + '&patterns=' + result.count + '&unknowns=' + result.unknowns} onClick={() => track('protect_clicked')}>Get a safety review ↗</a> - </section>} - </div>; -}; diff --git a/docs/snippets/scenario-explorer.jsx b/docs/snippets/scenario-explorer.jsx deleted file mode 100644 index 529b8b8..0000000 --- a/docs/snippets/scenario-explorer.jsx +++ /dev/null @@ -1,316 +0,0 @@ -export const ScenarioExplorer = ({ standalone = false }) => { - const domains = [{"name": "Finance", "actions": ["Refund customer", "Transfer funds", "Issue payout", "Approve withdrawal"]}, {"name": "Banking", "actions": ["Transfer funds", "Freeze account", "Change credit limit", "Release transaction"]}, {"name": "Payments", "actions": ["Charge customer", "Refund payment", "Issue payout", "Capture payment", "Retry payment"]}, {"name": "FinTech", "actions": ["Move funds", "Approve withdrawal", "Suspend account", "Release payment"]}, {"name": "Insurance", "actions": ["Issue claim payment", "Change policy", "Approve claim", "Cancel policy", "Escalate fraud review"]}, {"name": "E-commerce", "actions": ["Refund order", "Cancel order", "Modify shipment", "Issue store credit", "Change delivery address"]}, {"name": "Retail", "actions": ["Modify order", "Issue refund", "Apply discount", "Cancel fulfillment", "Replace order"]}, {"name": "Customer Support", "actions": ["Refund customer", "Cancel subscription", "Apply account credit", "Modify account", "Reset access"]}, {"name": "SaaS", "actions": ["Delete account", "Suspend account", "Change plan", "Change permissions", "Grant feature access"]}, {"name": "Enterprise Software", "actions": ["Update ERP record", "Modify CRM record", "Approve workflow", "Change master data", "Create vendor record"]}, {"name": "Sales", "actions": ["Approve discount", "Send proposal", "Create order", "Change opportunity stage", "Approve pricing"]}, {"name": "CRM and Revenue Operations", "actions": ["Modify customer record", "Reassign account", "Change lifecycle status", "Trigger outbound communication", "Create renewal"]}, {"name": "Marketing", "actions": ["Launch campaign", "Pause campaign", "Change ad budget", "Send bulk communication", "Modify audience"]}, {"name": "Advertising", "actions": ["Increase spend", "Pause ad set", "Change targeting", "Publish creative", "Change bidding configuration"]}, {"name": "HR", "actions": ["Send offer", "Withdraw offer", "Start onboarding", "Start offboarding", "Change employee status"]}, {"name": "Payroll", "actions": ["Issue bonus", "Adjust payroll", "Approve reimbursement", "Reverse payment", "Change deduction"]}, {"name": "Legal", "actions": ["Send contract", "Trigger signature", "Submit filing", "Send legal notice", "Change contract status"]}, {"name": "Compliance", "actions": ["Approve exception", "Block transaction", "Escalate review", "Release restricted workflow", "Change risk status"]}, {"name": "Cybersecurity", "actions": ["Disable account", "Revoke session", "Block IP", "Isolate endpoint", "Rotate credential"]}, {"name": "Identity and Access", "actions": ["Grant role", "Revoke role", "Elevate privilege", "Create privileged account", "Disable service account"]}, {"name": "IT Operations", "actions": ["Reset password", "Provision access", "Revoke access", "Restart service", "Execute remediation"]}, {"name": "DevOps", "actions": ["Deploy production", "Roll back deployment", "Delete infrastructure", "Restart production service", "Modify production configuration"]}, {"name": "Cloud Infrastructure", "actions": ["Terminate instance", "Modify firewall", "Scale infrastructure", "Rotate secret", "Change cloud resource"]}, {"name": "Software Engineering", "actions": ["Merge pull request", "Publish release", "Delete branch", "Modify repository settings", "Rotate secret"]}, {"name": "CI/CD", "actions": ["Deploy release", "Publish package", "Roll back release", "Modify pipeline", "Change protected branch settings"]}, {"name": "Data Engineering", "actions": ["Delete dataset", "Modify production table", "Execute migration", "Trigger production pipeline", "Grant database access"]}, {"name": "Machine Learning", "actions": ["Deploy model", "Roll back model", "Change serving configuration", "Promote model to production", "Trigger retraining"]}, {"name": "Healthcare Operations", "actions": ["Schedule appointment", "Cancel appointment", "Send patient communication", "Submit authorization workflow", "Update administrative workflow"]}, {"name": "Pharmaceuticals and Life Sciences", "actions": ["Release controlled workflow", "Update operational record", "Trigger regulatory process", "Update trial workflow status", "Escalate adverse-event workflow"]}, {"name": "Manufacturing", "actions": ["Stop production workflow", "Release batch", "Change machine configuration", "Trigger maintenance", "Change production order"]}, {"name": "Supply Chain", "actions": ["Reroute shipment", "Release inventory", "Modify supplier order", "Change warehouse allocation", "Cancel shipment"]}, {"name": "Logistics", "actions": ["Dispatch vehicle", "Cancel delivery", "Change destination", "Reroute shipment", "Release shipment"]}, {"name": "Travel", "actions": ["Cancel booking", "Issue refund", "Modify reservation", "Upgrade booking", "Issue travel credit"]}, {"name": "Airlines", "actions": ["Rebook passenger", "Refund ticket", "Modify itinerary", "Change seat", "Release compensation"]}, {"name": "Hospitality", "actions": ["Cancel reservation", "Issue credit", "Change booking", "Modify guest record", "Upgrade reservation"]}, {"name": "Telecom", "actions": ["Activate service", "Disable SIM", "Change customer plan", "Apply account credit", "Modify network configuration"]}, {"name": "Energy and Utilities", "actions": ["Restore service", "Disconnect service", "Trigger billing adjustment", "Dispatch field service", "Change customer tariff"]}, {"name": "Automotive", "actions": ["Unlock vehicle", "Change fleet assignment", "Trigger roadside workflow", "Approve repair", "Modify vehicle configuration"]}, {"name": "Robotics", "actions": ["Start machine", "Stop machine", "Unlock physical access", "Move robot", "Trigger physical process"]}, {"name": "Real Estate", "actions": ["Send lease", "Change listing status", "Release deposit workflow", "Modify tenant record", "Submit offer"]}, {"name": "Education", "actions": ["Enroll student", "Withdraw student", "Change registration", "Release certificate", "Modify administrative access"]}, {"name": "Public Sector", "actions": ["Approve application", "Change case status", "Release payment workflow", "Update citizen record", "Trigger permit workflow"]}, {"name": "Procurement", "actions": ["Create purchase order", "Approve purchase", "Change supplier", "Release payment workflow", "Cancel purchase order"]}, {"name": "Accounting", "actions": ["Approve invoice", "Issue payment", "Reverse journal entry", "Modify vendor details", "Approve reimbursement"]}, {"name": "Marketplace", "actions": ["Release seller payout", "Suspend seller", "Refund buyer", "Cancel transaction", "Change seller permissions"]}, {"name": "Fraud Operations", "actions": ["Freeze transaction", "Block account", "Release transaction", "Disable payment method", "Escalate investigation"]}, {"name": "Communication", "actions": ["Send email", "Send SMS", "Send Slack message", "Publish notification", "Send bulk communication"]}, {"name": "General Business Operations", "actions": ["Approve request", "Update business record", "Trigger payment", "Delete record", "Grant access", "Trigger downstream automation"]}]; - const quick = ['Payments', 'Customer Support', 'DevOps', 'Identity and Access', 'HR', 'Healthcare Operations']; - const situations = [ - { value: 'approval', label: 'A person has to say yes first' }, - { value: 'allowed', label: 'It is inside the agent’s limits' }, - { value: 'blocked', label: 'The agent is not allowed to do it' }, - { value: 'mismatch', label: 'The agent changed it after approval' }, - { value: 'duplicate', label: 'It already happened once' }, - { value: 'uncertain', label: 'The reply was lost' }, - { value: 'reconcile', label: 'The agent retries without knowing' } - ]; - const checks = [ - { key: 'authority', label: 'Authority', asks: 'Is this agent entitled to act at all?' }, - { key: 'policy', label: 'Policy', asks: 'For these exact arguments: allow, approve, or deny?' }, - { key: 'approval', label: 'Approval binding', asks: 'Does a human decision match this exact action?' }, - { key: 'effect', label: 'Effect reservation', asks: 'Could this action already have happened?' }, - { key: 'outcome', label: 'Outcome', asks: 'Did the real system act, and do we know for certain?' } - ]; - const [domain, setDomain] = useState('Payments'); - const [actionIndex, setActionIndex] = useState(0); - const [query, setQuery] = useState(''); - const [pickerOpen, setPickerOpen] = useState(false); - const [condition, setCondition] = useState('approval'); - const [stage, setStage] = useState('initial'); - const [trail, setTrail] = useState([]); - const [copied, setCopied] = useState(false); - const [activeOption, setActiveOption] = useState(0); - const searchRef = useRef(null); - const pickerRef = useRef(null); - const buttonRef = useRef(null); - const selected = domains.find(item => item.name === domain) || domains[0]; - const filtered = domains.filter(item => item.name.toLowerCase().includes(query.toLowerCase())); - const action = selected.actions[Math.min(actionIndex, selected.actions.length - 1)]; - const money = /refund|funds|payout|payment|charge|bonus|reimbursement|credit|withdrawal|invoice|discount|spend|budget/i.test(action); - const physical = ['Robotics', 'Automotive', 'Manufacturing', 'Energy and Utilities'].includes(domain); - const original = money ? '$500' : 'one approved target'; - const changed = money ? '$5,000' : 'all targets'; - const reference = money ? 'txn_4821' : 'rec_4821'; - const effectKey = action.toLowerCase().replace(/[^a-z0-9]+/g, '_') + ':' + reference; - const track = (name, extra = {}) => { - if (typeof window !== 'undefined') window.dispatchEvent(new CustomEvent('ctrlrun:conversion', { detail: { name, domain, action, ...extra } })); - }; - useEffect(() => { - if (typeof window === 'undefined') return; - const params = new URLSearchParams(window.location.search); - const wanted = (params.get('domain') || '').toLowerCase(); - const match = domains.find(item => item.name.toLowerCase() === wanted); - if (match) { - setDomain(match.name); - const index = match.actions.findIndex(item => item.toLowerCase() === (params.get('action') || '').toLowerCase()); - setActionIndex(index >= 0 ? index : 0); - } - const situation = params.get('situation'); - if (situations.some(item => item.value === situation)) setCondition(situation); - }, []); - useEffect(() => { - if (pickerOpen && searchRef.current) searchRef.current.focus(); - }, [pickerOpen]); - useEffect(() => { - if (pickerOpen) document.getElementById('cr-option-' + activeOption)?.scrollIntoView({ block: 'nearest' }); - }, [activeOption, pickerOpen]); - useEffect(() => { - const outside = event => { - if (pickerRef.current && !pickerRef.current.contains(event.target)) setPickerOpen(false); - }; - document.addEventListener('pointerdown', outside); - return () => document.removeEventListener('pointerdown', outside); - }, []); - const restart = () => { setStage('initial'); setTrail([]); }; - const chooseDomain = name => { - setDomain(name); setActionIndex(0); setQuery(''); setPickerOpen(false); setActiveOption(0); restart(); - track('domain_selected', { domain: name, action: undefined }); - if (buttonRef.current) buttonRef.current.focus(); - }; - const viaApproval = trail.some(item => item.indexOf('A person approved') === 0); - const states = { - allowed: { - title: 'Allowed, and reserved before the call', - code: 'ALLOW', - tone: 'green', - reason: 'This action is inside the autonomy you gave the agent, so no person is asked.', - llm: 'This is within my limits, so I will call the tool.', - kernel: 'Agreed, and the effect is reserved first, so a second worker proposing the same thing now waits.', - rule: money ? 'Example rule: this agent may act autonomously up to $1,000.' : 'Example rule: this agent may perform this action on the selected target.', - sees: 'decision=allow → your function runs', - doc: { href: '/docs/concepts/decisions', label: 'Decisions' }, - marks: ['pass', 'pass', 'skip', 'pass', 'wait'], - notes: ['The agent holds a grant covering this action.', 'Allowed at this size.', 'Not required at this size.', 'Reserved: ' + effectKey, 'Nothing has been executed yet.'] - }, - approval: { - title: 'A person has to answer first', - code: 'ApprovalRequired', - tone: 'amber', - reason: 'This action is higher risk than the agent may take on its own, so execution stops until a human answers.', - llm: 'I am confident this is right, so I will do it now.', - kernel: 'Confidence is not authorisation. Nothing is called until a person answers this exact request.', - rule: money ? 'Example rule: amounts above $250 require approval.' : 'Example rule: a person must approve this action and its exact target.', - sees: 'raise ApprovalRequired(request_id="apr_7f31…")', - doc: { href: '/docs/get-started/three-ways-in', label: 'Human in the loop' }, - marks: ['pass', 'stop', 'wait', 'wait', 'wait'], - notes: ['The agent holds a grant covering this action.', 'Decision: approve. A request is created for a human.', 'Waiting for an answer.', 'Nothing is reserved.', 'Nothing is executed.'] - }, - blocked: { - title: 'Refused before anything ran', - code: 'ActionDenied', - tone: 'red', - reason: 'The agent does not have permission to perform this action, so nobody is asked and nothing is called.', - llm: 'The tool is in my list, so I am allowed to call it.', - kernel: 'A tool being callable is not permission. Policy denies this action, and no approval request is created.', - rule: 'Example rule: this action is outside the permissions assigned to this agent.', - sees: 'raise ActionDenied("policy: deny")', - doc: { href: '/docs/concepts/fail-closed', label: 'Fail closed' }, - marks: ['pass', 'stop', 'wait', 'wait', 'wait'], - notes: ['The agent is a known principal.', 'Decision: deny.', 'No human is asked about an action policy refuses.', 'Nothing is reserved.', 'Nothing is executed.'] - }, - mismatch: { - title: 'The approval no longer matches', - code: 'ApprovalMismatch', - tone: 'red', - reason: 'A person approved ' + original + '. The agent is now presenting that same approval for ' + changed + '.', - llm: 'Same action, same approval, only the number changed.', - kernel: 'The approval was bound to the arguments the human read. Change one and it authorises nothing.', - rule: 'Changing the amount or the target requires a new approval.', - sees: 'raise ApprovalMismatch("approved hash ≠ requested hash")', - doc: { href: '/docs/concepts/approval-binding', label: 'Approval binding' }, - marks: ['pass', 'pass', 'stop', 'wait', 'wait'], - notes: ['The agent holds a grant covering this action.', 'Decision: approve, and one was obtained.', 'The approved action hash does not match the requested one.', 'Nothing is reserved.', 'Nothing is executed.'] - }, - duplicate: { - title: 'The second attempt is refused', - code: 'DuplicateEffect', - tone: 'green', - reason: 'This is the same business action as one already committed, so CTRLRun will not let it run twice.', - llm: 'I did not see a confirmation, so I will run it again.', - kernel: 'The effect key is already committed. The retry is refused, and the original receipt is returned.', - rule: 'One business action, one effect key, across retries, workers and restarts.', - sees: 'raise DuplicateEffect("' + effectKey + ' already committed")', - doc: { href: '/docs/concepts/effect-keys', label: 'Effect keys' }, - marks: ['pass', 'pass', 'skip', 'stop', 'wait'], - notes: ['The agent holds a grant covering this action.', 'Decision unchanged.', 'Not the check that stopped this.', effectKey + ' is already committed.', 'The first outcome stands. Nothing runs again.'] - }, - uncertain: { - title: 'The outcome is not known', - code: 'AMBIGUOUS', - tone: 'amber', - reason: 'The call left your process and the reply never came back. The real system may have done it.', - llm: 'The call raised an error, so it failed. I will try again.', - kernel: 'An error is not evidence of failure. Unless the executor proves nothing happened, the effect is AMBIGUOUS and stays reserved.', - rule: 'Only a definite “it did not happen” allows a retry. Everything else is unknown.', - sees: 'effect ' + effectKey + ' → AMBIGUOUS (held, not failed)', - doc: { href: '/docs/concepts/outcomes-and-ambiguous', label: 'Outcomes and AMBIGUOUS' }, - marks: ['pass', 'pass', 'skip', 'pass', 'stop'], - notes: ['The agent holds a grant covering this action.', 'Decision: allow.', 'Not the check that stopped this.', 'Reserved before the call, which is why the retry can be caught.', 'No reply. The outcome is unknown, so it is recorded as unknown.'] - }, - reconcile: { - title: 'The blind retry is refused', - code: 'AmbiguousEffect', - tone: 'amber', - reason: 'The first attempt may already have succeeded. CTRLRun will not run it again until that is settled.', - llm: 'Retrying is harmless. It probably failed.', - kernel: 'Probably is not good enough for an action that moves something real. Confirm at the provider, or have a person resolve it.', - rule: 'Reconciliation retries the observation, never the effect.', - sees: 'raise AmbiguousEffect("outcome unknown; blind retry refused")', - doc: { href: '/docs/guides/resolve-an-ambiguous-effect', label: 'Resolve an ambiguous effect' }, - marks: ['pass', 'pass', 'skip', 'stop', 'wait'], - notes: ['The agent holds a grant covering this action.', 'Decision unchanged.', 'Not the check that stopped this.', effectKey + ' is held in an unknown state.', 'Settled by asking the provider, or by an operator.'] - }, - approved: { - title: 'This exact action is approved', - code: 'ALLOW', - tone: 'green', - reason: 'A person approved ' + action.toLowerCase() + ' for ' + original + '. Only this exact request may continue.', - llm: 'I have an approval, so I can proceed.', - kernel: 'With these arguments, yes. The approval is single-use and bound to them.', - rule: 'Approval does not grant permission to change the amount or the target.', - sees: 'approval apr_7f31… matches → your function runs', - doc: { href: '/docs/concepts/approval-binding', label: 'Approval binding' }, - marks: ['pass', 'pass', 'pass', 'pass', 'wait'], - notes: ['The agent holds a grant covering this action.', 'Decision: approve.', 'The approved hash matches the requested one.', 'Reserved: ' + effectKey, 'Not executed yet.'] - }, - completed: { - title: 'Done once, and recorded', - code: 'COMMITTED', - tone: 'green', - reason: 'The real system confirmed the action. The outcome and the decision behind it are written to a receipt.', - llm: 'Done. I will report success.', - kernel: 'Committed. Any later attempt at the same business action now has something to be refused against.', - rule: 'A receipt records the action, the decision and the outcome, including who approved it.', - sees: 'outcome=committed · receipt rcp_4c2a…', - doc: { href: '/docs/concepts/receipts-and-evidence', label: 'Receipts and evidence' }, - marks: ['pass', 'pass', viaApproval ? 'pass' : 'skip', 'pass', 'pass'], - notes: ['The agent holds a grant covering this action.', 'Decision recorded.', viaApproval ? 'Approval consumed. It cannot be replayed.' : 'Not required at this size, so none was consumed.', effectKey + ' committed.', 'Confirmed by the real system.'] - } - }; - const stateKey = stage === 'initial' ? condition : stage; - const result = states[stateKey]; - const advance = (next, note) => { setStage(next); setTrail(trail.concat(note)); track('scenario_completed', { outcome: next }); }; - const symbols = { pass: '✓', stop: '✕', wait: '·', skip: '–' }; - const shareUrl = () => { - const origin = typeof window !== 'undefined' ? window.location.origin : 'https://ctrlrun.dev'; - return origin + '/try?domain=' + encodeURIComponent(domain) + '&action=' + encodeURIComponent(action) + '&situation=' + encodeURIComponent(condition); - }; - const copyLink = () => { - track('share_copied', { situation: condition }); - if (typeof navigator === 'undefined' || !navigator.clipboard) { setCopied(false); return; } - navigator.clipboard.writeText(shareUrl()).then(() => { - setCopied(true); - setTimeout(() => setCopied(false), 2500); - }, () => setCopied(false)); - }; - const reviewQuestion = money ? 'Letting agents move or refund money?' : domain === 'DevOps' || domain === 'Cloud Infrastructure' || domain === 'CI/CD' ? 'Letting agents change production infrastructure?' : domain === 'Customer Support' ? 'Letting agents refund, cancel, or change customer accounts?' : domain === 'HR' || domain === 'Payroll' ? 'Letting agents change employee records or payroll workflows?' : domain === 'SaaS' || domain === 'Identity and Access' ? 'Letting agents modify accounts, permissions, or customer data?' : 'Letting agents take action in ' + domain.toLowerCase() + '?'; - return ( - <div className="cr-explorer"> - <div className="cr-lanes"> - <div className="cr-lane"> - <span className="cr-step">YOUR AGENT · THE LLM</span> - <strong>Decides what to do</strong> - <p>An LLM reads the ticket and picks the tool and the arguments. It believes it is right. Sometimes it is not. CTRLRun never touches this part.</p> - </div> - <span className="cr-flow-arrow" aria-hidden="true">→</span> - <div className="cr-lane cr-lane-control"> - <span className="cr-step">CTRLRUN · THIS TOOL</span> - <strong>Decides whether it may run</strong> - <p>Sees no prompt and no reasoning. It sees the action about to leave your process, with its exact arguments, and answers whether it may execute now.</p> - </div> - <span className="cr-flow-arrow" aria-hidden="true">→</span> - <div className="cr-lane"> - <span className="cr-step">THE REAL SYSTEM</span> - <strong>Where it becomes real</strong> - <p>Stripe, your database, the Kubernetes API. None of them can tell a first attempt from a retry, and a lost reply looks exactly like a failure.</p> - </div> - </div> - <p className="cr-lane-note">CTRLRun is not a model, a prompt layer, or a guardrail on what the agent <em>says</em>. It is the check on what the agent <em>does</em>, in the last moment before the effect is real.</p> - <p className="cr-demo-prompt"><b>Now play the part of the agent.</b> Choose a domain, the action it proposes, and the moment it goes wrong.</p> - <div className="cr-demo-toolbar"> - <div className="cr-field cr-domain-picker" ref={pickerRef}> - <span id="cr-domain-label"><i>1</i>Choose your domain</span> - <button type="button" className="cr-select-button" ref={buttonRef} aria-haspopup="dialog" aria-expanded={pickerOpen} aria-labelledby="cr-domain-label cr-domain-value" onClick={() => { setPickerOpen(!pickerOpen); setActiveOption(0); }}><span id="cr-domain-value">{domain}</span><span aria-hidden="true">⌄</span></button> - {pickerOpen && <div className="cr-picker-menu" role="dialog" aria-label="Choose your domain" onKeyDown={event => { - if (event.key === 'Escape') { setPickerOpen(false); buttonRef.current.focus(); } - }}> - <label className="cr-sr-only" htmlFor="cr-domain-search">Search domains</label> - <input id="cr-domain-search" ref={searchRef} type="search" placeholder="Search 48 domains…" value={query} role="combobox" aria-expanded="true" aria-controls="cr-domain-options" aria-autocomplete="list" aria-activedescendant={filtered[activeOption] ? 'cr-option-' + activeOption : undefined} onChange={event => { setQuery(event.target.value); setActiveOption(0); }} onKeyDown={event => { - if (event.key === 'ArrowDown') { event.preventDefault(); setActiveOption(Math.min(activeOption + 1, filtered.length - 1)); } - if (event.key === 'ArrowUp') { event.preventDefault(); setActiveOption(Math.max(activeOption - 1, 0)); } - if (event.key === 'Enter' && filtered[activeOption]) { event.preventDefault(); chooseDomain(filtered[activeOption].name); } - }} /> - <div className="cr-domain-options" id="cr-domain-options" role="listbox" aria-label="Domains"> - {filtered.map((item, index) => <button type="button" role="option" id={'cr-option-' + index} aria-selected={domain === item.name} className={index === activeOption ? 'cr-option-active' : ''} key={item.name} onClick={() => chooseDomain(item.name)}>{item.name}{domain === item.name && <span aria-hidden="true">✓</span>}</button>)} - {filtered.length === 0 && <p role="status">No matching domain. Try “Payments” or “DevOps”.</p>} - </div> - </div>} - </div> - <label className="cr-field"><span><i>2</i>Choose an action</span><select value={Math.min(actionIndex, selected.actions.length - 1)} onChange={event => { const index = Number(event.target.value); setActionIndex(index); restart(); track('use_case_selected', { action: selected.actions[index] }); }}>{selected.actions.map((item, index) => <option key={item} value={index}>{item}</option>)}</select></label> - <label className="cr-field"><span><i>3</i>Choose what goes wrong</span><select value={condition} onChange={event => { setCondition(event.target.value); restart(); track('scenario_completed', { outcome: event.target.value }); }}>{situations.map(item => <option key={item.value} value={item.value}>{item.label}</option>)}</select></label> - </div> - <div className="cr-demo-stage"> - <div className="cr-request"> - <p className="cr-step">THE AGENT ASKS TO</p> - <h3>{action}</h3> - <p className="cr-request-value">{stateKey === 'mismatch' ? changed : original}</p> - <p className="cr-caption">{stateKey === 'mismatch' ? 'A person approved: ' + original : 'One consequential action, in ' + domain.toLowerCase() + '.'}</p> - <p className="cr-effect-key"><span className="cr-step">EFFECT KEY</span><code>{effectKey}</code></p> - <div className="cr-request-line" aria-hidden="true">↓</div> - <span className="cr-wordmark">CTRLRun<span className="cr-dot">_</span></span> - <ol className="cr-checks" aria-label="What CTRLRun checks, in order"> - {checks.map((item, index) => <li key={item.key} className={'cr-check-' + result.marks[index]}> - <span className="cr-check-mark" aria-hidden="true">{symbols[result.marks[index]]}</span> - <span><strong>{item.label}</strong><span className="cr-sr-only">: {result.marks[index] === 'stop' ? 'stopped here' : result.marks[index] === 'pass' ? 'passed' : result.marks[index] === 'skip' ? 'not applicable' : 'not reached'}. </span><em>{item.asks}</em><span>{result.notes[index]}</span></span> - </li>)} - </ol> - </div> - <div className={'cr-result cr-result-' + result.tone} aria-live="polite" aria-atomic="true"> - <p className="cr-check">✓ Action recognized</p> - <h3>{result.title}</h3> - <p>{result.reason}</p> - <div className="cr-split"> - <div><span className="cr-step">WHAT THE LLM BELIEVED</span><p>{result.llm}</p></div> - <div className="cr-safe"><span className="cr-step">WHAT CTRLRUN DID</span><p>{result.kernel}</p></div> - </div> - <p className="cr-rule">{result.rule}</p> - <p className="cr-sees"><span className="cr-step">WHAT YOUR CODE SEES</span><code>{result.sees}</code></p> - <p className="cr-code-label"><span>{result.code}</span> <a className="cr-text-link" href={result.doc.href}>{result.doc.label} →</a></p> - {trail.length > 0 && <div className="cr-trail"><span className="cr-step">WHAT HAPPENED SO FAR</span><ol>{trail.map((item, index) => <li key={index}>{item}</li>)}</ol></div>} - <div className="cr-demo-actions"> - {stateKey === 'approval' && <button type="button" className="cr-button" onClick={() => advance('approved', 'A person approved ' + action.toLowerCase() + ' for ' + original + '.')}>Approve this exact action →</button>} - {(stateKey === 'allowed' || stateKey === 'approved') && <button type="button" className="cr-button" onClick={() => advance('completed', 'The action executed once and the real system confirmed it.')}>Execute action →</button>} - {stateKey === 'approved' && <button type="button" className="cr-text-link" onClick={() => advance('mismatch', 'The agent changed the request to ' + changed + ' and presented the same approval.')}>Change {money ? 'to $5,000' : 'to all targets'}</button>} - {stateKey === 'completed' && <button type="button" className="cr-button" onClick={() => advance('duplicate', 'The agent retried the same business action.')}>Retry the same action →</button>} - {stateKey === 'uncertain' && <button type="button" className="cr-button" onClick={() => advance('reconcile', 'The agent tried again without confirming the first outcome.')}>Try again →</button>} - {stateKey === 'reconcile' && <button type="button" className="cr-button" onClick={() => advance('completed', 'The provider was asked. The first attempt had succeeded, so the effect is resolved, not repeated.')}>Ask the provider what happened →</button>} - {stage !== 'initial' && <button type="button" className="cr-text-link" onClick={restart}>Reset scenario</button>} - </div> - </div> - </div> - <div className="cr-chips"> - <span className="cr-step">48 DOMAINS. START WITH ONE</span> - {quick.map(name => <button type="button" key={name} className={'cr-chip' + (domain === name ? ' cr-chip-on' : '')} aria-pressed={domain === name} onClick={() => chooseDomain(name)}>{name}</button>)} - <button type="button" className="cr-chip cr-chip-more" onClick={() => { setPickerOpen(true); setActiveOption(0); }}>Browse all 48 →</button> - </div> - <div className="cr-demo-share"> - <div> - <span className="cr-step">SHARE THIS SCENARIO</span> - <input type="text" readOnly value={shareUrl()} aria-label="Link to this scenario" onFocus={event => event.target.select()} /> - </div> - <div className="cr-share-actions"> - <button type="button" className="cr-button cr-secondary" onClick={copyLink}>{copied ? 'Copied ✓' : 'Copy link'}</button> - {!standalone && <a className="cr-text-link" href={shareUrl()}>Open on its own page ↗</a>} - </div> - </div> - <p className="cr-demo-note">Nothing here executes: this is an illustration of the decisions, with example rules that are not industry defaults. To watch the real library refuse a real call, <a href="/docs/try-it">run the released wheel in your browser</a>: Python and CTRLRun load into the tab and every refusal there is the library's own.{physical ? ' CTRLRun governs the software authorization and execution workflow; physical safety controls remain separate.' : ''}{domain === 'Healthcare Operations' ? ' Administrative workflows only; no diagnosis or clinical decisions.' : ''}</p> - <div className="cr-domain-cta"><div><strong>{reviewQuestion}</strong><p>Review where execution controls belong in your architecture.</p></div><a className="cr-text-link" href={'/protect-my-agent?domain=' + encodeURIComponent(domain)} onClick={() => track('protect_clicked')}>Get a safety review ↗</a></div> - </div> - ); -}; diff --git a/docs/style.css b/docs/style.css deleted file mode 100644 index 729980b..0000000 --- a/docs/style.css +++ /dev/null @@ -1,532 +0,0 @@ -/* Scoped product pages: Mintlify documentation keeps its native layout. */ -.cr-site { --cr-ink:#20221f; --cr-muted:#656963; --cr-line:#e0e3dc; --cr-paper:#fafbf8; --cr-panel:#f2f4ee; --cr-accent:#a96308; color:var(--cr-ink); max-width:1120px; padding:0 32px; margin:0 auto; font-size:16px; line-height:1.65; } -.dark .cr-site { --cr-ink:#f0f1e9; --cr-muted:#b0b5a9; --cr-line:#343b30; --cr-paper:#171b15; --cr-panel:#20261e; --cr-accent:#efb752; } -.cr-site * { box-sizing:border-box; } -.cr-site h1,.cr-site h2,.cr-site h3,.cr-site p,.cr-site pre,.cr-site ul { margin:0; } -.cr-site h1 { font-size:clamp(42px,6.3vw,78px); letter-spacing:-.055em; line-height:1.07; font-weight:600; color:var(--cr-ink); text-wrap:balance; } -.cr-site h2 { font-size:clamp(28px,3vw,36px); letter-spacing:-.035em; line-height:1.2; font-weight:550; color:var(--cr-ink); } -.cr-site h3 { font-size:23px; letter-spacing:-.025em; line-height:1.3; font-weight:600; color:var(--cr-ink); } -.cr-site p { color:var(--cr-muted); } -.cr-site p+p { margin-top:12px; } -.cr-site a { color:inherit; text-decoration:none; } -.cr-site button,.cr-site input,.cr-site select,.cr-site textarea { font:inherit; } -.cr-site button,.cr-site select,.cr-site summary,.cr-site input[type=checkbox],.cr-site input[type=radio] { cursor:pointer; } -.cr-site button:disabled { opacity:.5; cursor:not-allowed; } -.cr-site :focus-visible { outline:3px solid var(--cr-accent); outline-offset:4px; } -.cr-site .cr-eyebrow,.cr-site .cr-step { font-size:10px; font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-weight:600; letter-spacing:.12em; line-height:1.6; color:var(--cr-muted); } -.cr-site .cr-eyebrow { margin-bottom:20px; } -.cr-dot { color:var(--cr-accent); } -.cr-hero { padding:80px 0 52px; max-width:830px; } -.cr-hero h1 { margin-bottom:25px; } -.cr-site .cr-lede { margin-top:24px; font-size:21px; color:var(--cr-ink); letter-spacing:-.015em; } -.cr-site .cr-intro { max-width:625px; margin-top:12px; font-size:17px; line-height:1.75; } -.cr-actions { display:flex; flex-wrap:wrap; align-items:center; gap:12px; margin:28px 0 16px; } -.cr-site .cr-button { display:inline-flex; justify-content:center; align-items:center; gap:28px; min-height:46px; padding:10px 18px; border:1px solid var(--cr-ink); border-radius:5px; background:var(--cr-ink); color:var(--cr-paper); font-size:13px; line-height:1.5; font-weight:600; text-decoration:none; transition:opacity .15s; } -.cr-site .cr-button:hover { opacity:.8; } -.cr-site .cr-secondary { color:var(--cr-ink); background:transparent; border-color:var(--cr-line); } -.cr-site .cr-github-badge { gap:10px; color:var(--cr-accent); background:var(--cr-panel); border-color:var(--cr-accent); } -.cr-github-badge svg { flex-shrink:0; } -.cr-site .cr-caption { font-size:12px; line-height:1.7; color:var(--cr-muted); } -.cr-flow-arrow { font-size:26px; color:var(--cr-muted); text-align:center; } -.cr-section { padding:64px 0; border-bottom:1px solid var(--cr-line); scroll-margin-top:100px; } -.cr-section h2+p { margin-top:18px; } -.cr-section-heading { display:flex; justify-content:space-between; gap:20px; align-items:flex-end; margin-bottom:28px; } -.cr-section-heading .cr-eyebrow { margin-bottom:12px; } -.cr-explorer { border:1px solid var(--cr-line); border-radius:8px; background:var(--cr-paper); } -.cr-demo-toolbar { display:grid; grid-template-columns:1fr 1.1fr 1.1fr; gap:16px; padding:22px; border-bottom:1px solid var(--cr-line); } -.cr-field { display:flex; flex-direction:column; gap:8px; font-size:12px; font-weight:550; min-width:0; } -.cr-site select,.cr-site input:not([type=checkbox]):not([type=radio]),.cr-site textarea,.cr-select-button { width:100%; border:1px solid var(--cr-line); border-radius:4px; background:var(--cr-paper); color:var(--cr-ink); padding:11px 12px; min-height:44px; font-size:13px; line-height:1.5; } -.cr-site textarea { resize:vertical; } -.cr-select-button { display:flex; justify-content:space-between; align-items:center; text-align:left; } -.cr-domain-picker { position:relative; } -.cr-picker-menu { position:absolute; top:100%; left:0; z-index:30; width:max(100%,280px); max-width:calc(100vw - 64px); border:1px solid var(--cr-line); border-radius:6px; background:var(--cr-paper); box-shadow:0 12px 25px #0002; padding:8px; margin-top:5px; } -.cr-domain-options { max-height:245px; overflow:auto; margin-top:6px; } -.cr-domain-options button { width:100%; display:flex; justify-content:space-between; gap:10px; padding:10px; min-height:42px; text-align:left; color:var(--cr-ink); font-size:13px; border:0; border-radius:3px; background:transparent; } -.cr-domain-options button:hover,.cr-domain-options .cr-option-active { background:var(--cr-panel); } -.cr-domain-options p { padding:12px; font-size:12px; } -.cr-demo-stage { display:grid; grid-template-columns:.9fr 1.2fr; min-height:320px; } -.cr-request { padding:35px 32px; } -.cr-request h3 { margin:15px 0 6px; } -.cr-site .cr-request-value { color:var(--cr-ink); font-size:19px; } -.cr-request .cr-caption { margin-top:12px; } -.cr-request-line { font-size:25px; padding:12px 0; color:var(--cr-muted); } -.cr-wordmark { font-size:22px; font-weight:600; letter-spacing:-.04em; } -.cr-result { padding:30px 32px; border-left:1px solid var(--cr-line); } -.cr-result h3 { margin:10px 0 12px; } -.cr-result>p { font-size:14px; } -.cr-result .cr-check { font-family:ui-monospace,monospace; font-size:11px; } -.cr-result-green .cr-check { color:#3c7041; } -.cr-result-red h3 { color:#a13d32; } -.cr-result-amber h3 { color:#98600e; } -.dark .cr-result-green .cr-check { color:#9ec793; } -.dark .cr-result-red h3 { color:#f5a198; } -.dark .cr-result-amber h3 { color:#edbd70; } -.cr-result .cr-rule { margin-top:18px; font-size:12px; } -.cr-code-label { display:inline-block; margin-top:10px; font-size:10px; color:var(--cr-muted); font-family:ui-monospace,monospace; } -.cr-demo-actions { display:flex; flex-wrap:wrap; gap:10px 18px; align-items:center; margin-top:20px; } -.cr-demo-actions .cr-button { font-size:11px; padding:9px 12px; gap:8px; } -.cr-site .cr-text-link { padding:0; background:none; border:0; color:var(--cr-ink); font-weight:550; font-size:13px; line-height:1.8; text-decoration:none; text-underline-offset:4px; } -.cr-site .cr-text-link:hover,.cr-footer a:hover { text-decoration:underline; } -.cr-demo-note { padding:12px 22px; border-top:1px solid var(--cr-line); font-size:10px; } -.cr-domain-cta { display:flex; align-items:center; justify-content:space-between; gap:25px; border-top:1px solid var(--cr-line); padding:20px 22px; } -.cr-domain-cta strong { font-size:13px; font-weight:550; } -.cr-domain-cta p { font-size:12px; margin-top:3px; } -.cr-domain-cta>a { flex-shrink:0; } -.cr-integration { display:grid; grid-template-columns:1fr 1fr; gap:64px; align-items:center; } -.cr-integration .cr-text-link { display:inline-block; margin-top:24px; } -.cr-code { border:1px solid var(--cr-line); border-radius:6px; overflow:hidden; background:var(--cr-paper); } -.cr-install { padding:15px 22px; border-bottom:1px solid var(--cr-line); font-family:ui-monospace,monospace; font-size:13px; } -.cr-install>span { color:var(--cr-accent); } -.cr-code pre { padding:22px; background:transparent; border:0; font-size:12px; line-height:1.85; overflow:auto; color:var(--cr-ink); } -.cr-site code { font-family:ui-monospace,SFMono-Regular,Consolas,monospace; background:transparent; color:inherit; font-weight:400; padding:0; } -.cr-code p { padding:0 22px 18px; font-size:10px; } -.cr-integration .cr-integration-scope { grid-column:1 / -1; } -.cr-integration-scope a { text-decoration:underline; text-underline-offset:3px; } -.cr-integration .cr-caption a { text-decoration:underline; text-underline-offset:3px; } -.cr-footer { display:flex; justify-content:space-between; gap:32px; padding:38px 0 50px; color:var(--cr-muted); font-size:13px; } -.cr-footer strong { color:var(--cr-ink); font-weight:500; } -.cr-footer>div { display:flex; flex-wrap:wrap; align-items:center; gap:24px; font-size:12px; } -.cr-subpage { max-width:850px; padding-top:40px; padding-bottom:70px; } -.cr-subpage>.cr-eyebrow { margin-top:50px; } -.cr-subpage h1 { font-size:clamp(40px,6vw,64px); } -.cr-subpage>.cr-lede { margin:25px 0 16px; } -.cr-services { margin:30px 0 45px; border-top:1px solid var(--cr-line); } -.cr-services details { border-bottom:1px solid var(--cr-line); padding:16px 0; } -.cr-services summary { font-size:15px; font-weight:550; } -.cr-services p { font-size:14px; padding:12px 0; } -.cr-review-example { margin-bottom:45px; } -.cr-review-example h2+p { margin-top:18px; } -.cr-control-map { margin-top:24px; overflow-x:auto; } -.cr-control-map table { width:100%; min-width:600px; border-collapse:collapse; text-align:left; font-size:13px; line-height:1.7; } -.cr-control-map th,.cr-control-map td { min-width:130px; padding:14px 16px; border:1px solid var(--cr-line); vertical-align:top; } -.cr-control-map thead { background:var(--cr-paper); } -.cr-control-map th { font-weight:550; } -.cr-review h2 { margin-bottom:20px; } -.cr-review form { margin:24px 0; } -.cr-review .cr-field { margin-bottom:22px; } -.cr-review form>.cr-caption { margin-bottom:18px; } -.cr-site fieldset { margin:0 0 24px; padding:0; border:0; } -.cr-site legend { font-size:14px; color:var(--cr-ink); font-weight:550; margin-bottom:14px; } -.cr-site input[type=checkbox],.cr-site input[type=radio] { width:17px; height:17px; flex-shrink:0; accent-color:var(--cr-accent); } -.cr-radio-row { display:flex; flex-wrap:wrap; gap:12px 26px; } -.cr-radio-row label,.cr-check-option { display:flex; align-items:center; gap:10px; font-size:13px; min-height:42px; cursor:pointer; } -.cr-check-grid { display:grid; grid-template-columns:1fr 1fr; gap:4px 24px; } -.cr-risk-check { margin-top:42px; } -.cr-risk-check fieldset { padding:24px 0; border-top:1px solid var(--cr-line); } -.cr-risk-check legend { float:left; width:100%; margin-bottom:14px; } -.cr-risk-check legend+.cr-check-grid,.cr-risk-check legend+.cr-radio-row { clear:both; } -.cr-question-number { display:inline-block; font-family:ui-monospace,monospace; color:var(--cr-accent); font-size:11px; margin-right:14px; } -.cr-email-preview,.cr-risk-result { margin-top:32px; border-top:2px solid var(--cr-accent); padding:28px 24px; background:var(--cr-paper); } -.cr-email-preview h3,.cr-risk-result h2 { margin-bottom:16px; } -.cr-email-preview pre { white-space:pre-wrap; overflow-wrap:anywhere; font-size:12px; background:var(--cr-panel); padding:20px; margin-top:20px; } -.cr-risk-result ul { list-style:none; padding:0; margin:25px 0; } -.cr-risk-result li { margin:18px 0; } -.cr-risk-result li p { margin-top:6px; font-size:14px; } -.cr-risk-result a:not(.cr-button),.cr-subpage .cr-caption a,.cr-email-preview p a { text-decoration:underline; text-underline-offset:3px; } -.cr-risk-result>.cr-button { margin-top:24px; } -.cr-sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; } -@media (max-width:800px) { - .cr-site { padding-left:24px; padding-right:24px; } - .cr-hero { padding-top:55px; } - .cr-integration { gap:30px; } - .cr-demo-toolbar { grid-template-columns:1fr 1fr; } - .cr-demo-toolbar>.cr-field:last-child { grid-column:1/-1; } - .cr-section-heading { align-items:flex-start; flex-direction:column; gap:10px; } -} -@media (max-width:600px) { - .cr-hero { padding:42px 0 35px; } - .cr-site .cr-lede { font-size:18px; } - .cr-site .cr-intro { font-size:15px; } - .cr-flow-arrow { transform:rotate(90deg); line-height:1; } - .cr-integration,.cr-demo-stage { grid-template-columns:1fr; } - .cr-section { padding:40px 0; } - .cr-demo-toolbar { grid-template-columns:1fr; padding:18px; gap:14px; } - .cr-demo-toolbar>.cr-field:last-child { grid-column:auto; } - .cr-request { padding:24px; } - .cr-request-line { display:none; } - .cr-wordmark { display:block; margin-top:14px; } - .cr-result { border-left:0; border-top:1px solid var(--cr-line); padding:24px; min-height:270px; } - .cr-demo-actions { align-items:flex-start; flex-direction:column; } - .cr-domain-cta { flex-direction:column; align-items:flex-start; gap:12px; } - .cr-footer { flex-direction:column; } - .cr-check-grid { grid-template-columns:1fr; } - .cr-radio-row { gap:8px 22px; } - .cr-subpage { padding-top:28px; } - .cr-subpage>.cr-eyebrow { margin-top:32px; } - .cr-email-preview,.cr-risk-result { padding:24px 16px; } -} -@media (prefers-reduced-motion:reduce) { .cr-site * { transition:none!important; scroll-behavior:auto!important; } } - -/* Product pages retain the top navbar; technical tab navigation belongs in docs. */ -body:has(.cr-site) #navbar.is-custom div:has(>.nav-tabs) { display:none; } -body:has(.cr-site) { --topbar-tabs-height:0px; } - -.cr-honeypot { position:absolute; left:-10000px; width:1px; height:1px; overflow:hidden; } -.cr-site .cr-form-error { color:#a13d32; margin-top:16px; font-size:14px; } -.dark .cr-site .cr-form-error { color:#f5a198; } -.cr-site .cr-form-fields { margin:0; padding:0; } - -/* Medical Affairs evidence workbench */ - - #cr-medical-workbench{--cr-bg:light-dark(#f6f7f9,#171b23);--cr-panel:light-dark(#ffffff,#202630);--cr-fg:light-dark(#192334,#edf1f7);--cr-muted:light-dark(#576579,#b2bdcd);--cr-line:light-dark(#d9e0e9,#3b4656);--cr-accent:light-dark(#805400,#ffc970);--cr-tint:light-dark(#fff1d5,#3b3020);--cr-ok:light-dark(#17654c,#86dfba);--cr-ok-bg:light-dark(#eaf7f0,#193a30);--cr-bad:light-dark(#a62f37,#ffadb4);--cr-bad-bg:light-dark(#fff0f0,#44292d);--cr-space:20px;--cr-round:10px;color:var(--cr-fg);background:var(--cr-bg);border:1px solid var(--cr-line);border-radius:12px;font-family:Inter,ui-sans-serif,system-ui,sans-serif;font-size:14px;line-height:1.5;overflow-wrap:anywhere;isolation:isolate} - #cr-medical-workbench *{box-sizing:border-box} - #cr-medical-workbench button,#cr-medical-workbench select,#cr-medical-workbench input{font:inherit} - #cr-medical-workbench button{cursor:pointer} - #cr-medical-workbench button:disabled{cursor:default;opacity:.5} - #cr-medical-workbench .cr-top{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;padding:16px 22px;background:var(--cr-panel);border-radius:12px 12px 0 0;border-bottom:1px solid var(--cr-line)} - #cr-medical-workbench .cr-brand{display:flex;align-items:center;gap:12px;font-weight:500;letter-spacing:-.3px} - #cr-medical-workbench .cr-logo{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:7px;background:var(--cr-tint);color:var(--cr-accent)} - #cr-medical-workbench .cr-sep{color:var(--cr-line)} - #cr-medical-workbench .cr-small{font-size:12px;color:var(--cr-muted)} - #cr-medical-workbench .cr-badge{font-size:12px;padding:3px 8px;border-radius:5px;background:var(--cr-tint);color:var(--cr-accent);display:inline-block;font-weight:500} - #cr-medical-workbench .cr-badge.ok{background:var(--cr-ok-bg);color:var(--cr-ok)} - #cr-medical-workbench .cr-badge.bad{background:var(--cr-bad-bg);color:var(--cr-bad)} - #cr-medical-workbench .cr-body{padding:22px} - #cr-medical-workbench .cr-title{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;flex-wrap:wrap;margin-bottom:20px} - #cr-medical-workbench h2{font-size:23px;font-weight:500;line-height:1.25;margin:5px 0 6px;letter-spacing:-.55px} - #cr-medical-workbench h3{font-size:16px;font-weight:500;margin:0 0 14px;line-height:1.4} - #cr-medical-workbench h4{font-size:14px;font-weight:500;margin:0 0 8px} - #cr-medical-workbench p{margin:0 0 14px} - #cr-medical-workbench .cr-steps{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:5px;padding:5px;border:1px solid var(--cr-line);background:var(--cr-panel);border-radius:var(--cr-round);margin-bottom:18px} - #cr-medical-workbench .cr-step{border:0;background:transparent;color:var(--cr-muted);border-radius:6px;padding:10px 5px;font-weight:500;display:flex;align-items:center;justify-content:center;gap:8px;white-space:nowrap} - #cr-medical-workbench .cr-step[aria-current="step"]{background:var(--cr-tint);color:var(--cr-accent)} - #cr-medical-workbench .cr-num{font-size:12px;opacity:.8} - #cr-medical-workbench .cr-stage-head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin:20px 0 12px;flex-wrap:wrap} - #cr-medical-workbench .cr-stage-head h3{margin:0} - #cr-medical-workbench .cr-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);gap:16px;align-items:start} - #cr-medical-workbench .cr-panel{background:var(--cr-panel);border:1px solid var(--cr-line);border-radius:var(--cr-round);padding:var(--cr-space);min-width:0} - #cr-medical-workbench .cr-stack{display:grid;gap:12px;min-width:0} - #cr-medical-workbench .cr-source{display:block;width:100%;text-align:left;padding:14px;background:var(--cr-panel);color:var(--cr-fg);border:1px solid var(--cr-line);border-radius:7px} - #cr-medical-workbench .cr-source[aria-pressed="true"],#cr-medical-workbench .cr-claim[aria-pressed="true"]{border-color:var(--cr-accent);background:var(--cr-tint)} - #cr-medical-workbench .cr-row{display:flex;gap:10px;align-items:center;justify-content:space-between;flex-wrap:wrap} - #cr-medical-workbench .cr-source strong{display:block;font-weight:500;margin:7px 0 3px} - #cr-medical-workbench .cr-quote{padding:15px;border-left:3px solid var(--cr-accent);margin:12px 0;background:var(--cr-tint);border-radius:0 6px 6px 0} - #cr-medical-workbench .cr-meta{display:grid;grid-template-columns:1fr 1fr;gap:15px;margin-top:18px} - #cr-medical-workbench .cr-meta span{display:block} - #cr-medical-workbench .cr-claim{display:block;width:100%;text-align:left;background:var(--cr-panel);color:var(--cr-fg);padding:13px;border:1px solid var(--cr-line);border-radius:7px;margin:10px 0} - #cr-medical-workbench .cr-claim.cr-error{border-color:var(--cr-bad)} - #cr-medical-workbench .cr-ref{display:block;font-size:12px;color:var(--cr-accent);font-weight:500;margin-top:7px} - #cr-medical-workbench .cr-rule{border-top:1px solid var(--cr-line);margin:16px 0} - #cr-medical-workbench .cr-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:16px} - #cr-medical-workbench .cr-button{display:inline-flex;align-items:center;justify-content:center;gap:7px;border:1px solid var(--cr-line);border-radius:6px;background:var(--cr-panel);color:var(--cr-fg);padding:8px 12px;font-weight:500} - #cr-medical-workbench .cr-button.primary{background:var(--cr-fg);color:var(--cr-panel);border-color:var(--cr-fg)} - #cr-medical-workbench .cr-button.warn{color:var(--cr-bad);border-color:var(--cr-bad)} - #cr-medical-workbench .cr-facts{margin:0;display:grid;gap:13px} - #cr-medical-workbench .cr-facts div{display:grid;grid-template-columns:110px minmax(0,1fr);gap:10px} - #cr-medical-workbench dt{color:var(--cr-muted)} - #cr-medical-workbench dd{margin:0} - #cr-medical-workbench .cr-table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums} - #cr-medical-workbench .cr-table th{text-align:left;font-size:12px;color:var(--cr-muted);font-weight:400} - #cr-medical-workbench .cr-table th,#cr-medical-workbench .cr-table td{padding:11px 8px;border-bottom:1px solid var(--cr-line);vertical-align:top} - #cr-medical-workbench .cr-table th:first-child,#cr-medical-workbench .cr-table td:first-child{padding-left:0} - #cr-medical-workbench .cr-check{display:grid;grid-template-columns:22px 1fr auto;gap:8px;padding:13px 0;border-bottom:1px solid var(--cr-line);align-items:start} - #cr-medical-workbench .cr-check:last-child{border:0} - #cr-medical-workbench .cr-good{color:var(--cr-ok)} - #cr-medical-workbench .cr-danger{color:var(--cr-bad)} - #cr-medical-workbench .cr-label{display:flex;align-items:flex-start;gap:9px;margin:16px 0} - #cr-medical-workbench .cr-label input{margin:4px 0 0;accent-color:var(--cr-accent);flex-shrink:0} - #cr-medical-workbench .cr-letter p{margin-top:15px} - #cr-medical-workbench .cr-status{border-radius:7px;padding:15px;background:var(--cr-tint);color:var(--cr-accent);margin:15px 0} - #cr-medical-workbench .cr-status.bad{background:var(--cr-bad-bg);color:var(--cr-bad)} - #cr-medical-workbench .cr-status.ok{background:var(--cr-ok-bg);color:var(--cr-ok)} - #cr-medical-workbench .cr-status strong{font-weight:500;display:block;margin-bottom:4px} - #cr-medical-workbench .cr-status span{font-size:12px} - #cr-medical-workbench .cr-log{display:grid;gap:10px;margin:10px 0 0;padding:0;list-style:none} - #cr-medical-workbench .cr-log li{display:grid;grid-template-columns:25px 1fr;gap:9px;padding:10px 0;border-bottom:1px solid var(--cr-line)} - #cr-medical-workbench .cr-next{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-top:18px} - #cr-medical-workbench .cr-footer{border-top:1px solid var(--cr-line);padding:13px 22px;background:var(--cr-panel);border-radius:0 0 12px 12px} - #cr-medical-workbench details>summary{cursor:pointer;font-weight:500;font-size:12px;color:var(--cr-muted)} - #cr-medical-workbench .cr-map{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin:18px 0 8px} - #cr-medical-workbench .cr-map ul{margin:8px 0;padding-left:18px;font-size:12px;color:var(--cr-muted)} - #cr-medical-workbench .cr-mono{font-family:ui-monospace,SFMono-Regular,monospace;font-size:12px;overflow-wrap:anywhere} - #cr-medical-workbench .cr-note{margin:16px 0 0;font-size:12px;color:var(--cr-muted)} - @media(max-width:720px){#cr-medical-workbench .cr-body{padding:16px}#cr-medical-workbench .cr-grid{grid-template-columns:1fr}#cr-medical-workbench .cr-steps{grid-template-columns:repeat(3,minmax(0,1fr))}#cr-medical-workbench .cr-map{grid-template-columns:1fr}#cr-medical-workbench .cr-top{padding:14px 16px}#cr-medical-workbench h2{font-size:21px}} - @media(max-width:400px){#cr-medical-workbench .cr-body{padding:12px}#cr-medical-workbench .cr-panel{padding:14px}#cr-medical-workbench .cr-meta{grid-template-columns:1fr}#cr-medical-workbench .cr-facts div{grid-template-columns:1fr;gap:2px}#cr-medical-workbench .cr-step{gap:5px}#cr-medical-workbench .cr-check{grid-template-columns:18px 1fr}#cr-medical-workbench .cr-check>.cr-badge{grid-column:2;width:max-content}} - @media(pointer:coarse){#cr-medical-workbench button{min-height:44px}#cr-medical-workbench .cr-label{min-height:44px}} - -#cr-medical-workbench [hidden]{display:none!important} - -/* Scenario explorer: the three lanes, the check ladder, the share row. */ -.cr-lanes { display:grid; grid-template-columns:1fr 26px 1.25fr 26px 1fr; gap:12px; align-items:stretch; padding:22px; background:var(--cr-panel); border-bottom:1px solid var(--cr-line); border-radius:8px 8px 0 0; } -.cr-lane { display:flex; flex-direction:column; gap:6px; padding:14px 16px; background:var(--cr-paper); border:1px solid var(--cr-line); border-radius:6px; } -.cr-lane strong { font-size:16px; font-weight:550; letter-spacing:-.02em; color:var(--cr-ink); } -.cr-site .cr-lane p { font-size:12px; line-height:1.65; } -.cr-lane-control { border-color:var(--cr-accent); border-left-width:2px; } -.cr-lanes .cr-flow-arrow { align-self:center; font-size:20px; } -.cr-site .cr-lane-note { padding:14px 22px; font-size:12.5px; line-height:1.7; border-bottom:1px solid var(--cr-line); color:var(--cr-muted); } -.cr-lane-note em { color:var(--cr-ink); font-style:normal; font-weight:600; } -.cr-chips { display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding:0 22px 18px; border-bottom:1px solid var(--cr-line); } -.cr-chips .cr-step { width:100%; margin-bottom:2px; } -.cr-site .cr-chip { min-height:34px; padding:6px 13px; border:1px solid var(--cr-line); border-radius:999px; background:transparent; color:var(--cr-ink); font-size:12px; font-weight:550; } -.cr-site .cr-chip:hover { border-color:var(--cr-accent); } -.cr-site .cr-chip-on { background:var(--cr-ink); color:var(--cr-paper); border-color:var(--cr-ink); } -.cr-site .cr-chip-more { border-style:dashed; color:var(--cr-muted); } -.cr-effect-key { display:flex; flex-direction:column; gap:4px; margin-top:16px; } -.cr-effect-key code { font-size:12px; color:var(--cr-accent); } -.cr-checks { list-style:none; margin:22px 0 0; padding:18px 0 0; border-top:1px solid var(--cr-line); display:grid; gap:13px; } -.cr-checks li { display:grid; grid-template-columns:18px 1fr; gap:10px; align-items:start; } -.cr-check-mark { font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-size:12px; line-height:1.5; color:var(--cr-muted); } -.cr-checks strong { display:block; font-size:12.5px; font-weight:550; color:var(--cr-ink); } -.cr-checks em { display:block; font-style:normal; font-size:11.5px; line-height:1.6; color:var(--cr-muted); } -.cr-checks li>span>span:not(.cr-sr-only) { display:block; margin-top:3px; font-size:11.5px; line-height:1.6; color:var(--cr-ink); } -.cr-check-pass .cr-check-mark { color:#3c7041; } -.cr-check-stop .cr-check-mark { color:#a13d32; font-weight:700; } -.cr-check-stop strong { color:#a13d32; } -.dark .cr-check-pass .cr-check-mark { color:#9ec793; } -.dark .cr-check-stop .cr-check-mark,.dark .cr-check-stop strong { color:#f5a198; } -.cr-check-wait,.cr-check-skip { opacity:.5; } -.cr-split { display:grid; grid-template-columns:1fr 1fr; gap:20px; margin-top:20px; padding-top:18px; border-top:1px solid var(--cr-line); } -.cr-split>div { padding-left:14px; border-left:2px solid var(--cr-line); } -.cr-split .cr-safe { border-color:var(--cr-accent); } -.cr-site .cr-split p { margin-top:6px; font-size:12.5px; line-height:1.65; } -.cr-site .cr-split .cr-safe p { color:var(--cr-ink); } -.cr-sees { display:flex; flex-direction:column; gap:6px; margin-top:18px; } -.cr-sees code { display:block; padding:10px 12px; border:1px solid var(--cr-line); border-radius:4px; background:var(--cr-panel); color:var(--cr-ink); font-size:11.5px; line-height:1.6; overflow-x:auto; } -.cr-result .cr-code-label { display:flex; flex-wrap:wrap; align-items:center; gap:6px 16px; margin-top:14px; } -.cr-code-label>span { font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-size:10px; color:var(--cr-muted); } -.cr-code-label a { text-decoration:underline; text-underline-offset:3px; font-size:12px; } -.cr-trail { margin:18px 0 0; padding:14px 0 0; border-top:1px dashed var(--cr-line); } -.cr-trail ol { margin:8px 0 0; padding-left:20px; display:grid; gap:6px; font-size:11.5px; line-height:1.6; color:var(--cr-muted); } -.cr-trail li { list-style:decimal; } -.cr-trail li::marker { color:var(--cr-accent); font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-size:10px; } -.cr-demo-share { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:flex-end; gap:14px 20px; padding:16px 22px; border-top:1px solid var(--cr-line); } -.cr-demo-share>div:first-child { flex:1 1 340px; display:flex; flex-direction:column; gap:6px; } -.cr-site .cr-demo-share input { font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-size:11.5px; min-height:40px; } -.cr-share-actions { display:flex; flex-wrap:wrap; align-items:center; gap:16px; } -.cr-share-actions .cr-button { min-height:40px; font-size:12px; } -.cr-demo-note a { text-decoration:underline; text-underline-offset:3px; } -@media (max-width:900px) { - .cr-lanes { grid-template-columns:1fr; } - .cr-lanes .cr-flow-arrow { transform:rotate(90deg); line-height:1; } -} -@media (max-width:600px) { - .cr-lanes { padding:16px; } - .cr-chips { padding:0 18px 16px; } - .cr-split { grid-template-columns:1fr; gap:16px; } - .cr-demo-share { padding:16px 18px; } - .cr-checks { gap:11px; } -} -.cr-site .cr-demo-note { padding:14px 22px; font-size:11.5px; line-height:1.7; } - -/* Homepage: the same failure as two chains, and the three control pillars. */ -.cr-failure-chain .cr-section-heading { margin-bottom:32px; } -.cr-chain { display:flex; flex-direction:column; gap:14px; } -.cr-chain-row { display:grid; grid-template-columns:132px 1fr; align-items:stretch; gap:14px; } -.cr-site .cr-chain-label { display:flex; align-items:center; font-family:ui-monospace,SFMono-Regular,Consolas,monospace; font-size:10px; font-weight:600; letter-spacing:.12em; text-transform:uppercase; color:var(--cr-muted); } -.cr-site .cr-chain-steps { list-style:none; display:flex; align-items:stretch; gap:22px; padding:0; margin:0; } -.cr-chain-steps li { position:relative; flex:1; display:flex; align-items:center; justify-content:center; text-align:center; padding:14px 10px; border:1px solid var(--cr-line); background:var(--cr-paper); font-size:13px; line-height:1.4; color:var(--cr-muted); } -.cr-chain-steps li:not(:last-child)::after { content:"→"; position:absolute; right:-17px; top:50%; transform:translateY(-50%); color:var(--cr-accent); font-size:13px; line-height:1; } -.cr-chain-steps .cr-end { font-weight:600; border-width:2px; } -.cr-chain-steps .cr-end.cr-bad { color:#a13d32; border-color:#a13d32; background:transparent; } -.cr-chain-steps .cr-end.cr-good,.cr-site .cr-chain-label.cr-good { color:#3c7041; } -.cr-chain-steps .cr-end.cr-good { border-color:#3c7041; background:transparent; } -.dark .cr-chain-steps .cr-end.cr-bad { color:#f5a198; border-color:#f5a198; } -.dark .cr-chain-steps .cr-end.cr-good,.dark .cr-site .cr-chain-label.cr-good { color:#9ec793; } -.dark .cr-chain-steps .cr-end.cr-good { border-color:#9ec793; } -@media (max-width:900px) { - .cr-chain-row { grid-template-columns:1fr; gap:8px; } - .cr-chain { gap:26px; } -} -@media (max-width:600px) { - .cr-site .cr-chain-steps { flex-direction:column; gap:16px; } - .cr-chain-steps li { padding:11px 10px; font-size:12.5px; } - .cr-chain-steps li:not(:last-child)::after { content:"↓"; right:auto; left:50%; top:auto; bottom:-14px; transform:translateX(-50%); } -} - -/* The wordmark carries the brand on every page; give it room to read. */ -#navbar img.nav-logo { height:40px; } -@media (max-width:600px) { #navbar img.nav-logo { height:32px; } } - -/* Product pages keep a natural document flow and readable type at every height. */ -.cr-home,.cr-try-page { max-width:1200px; } -.cr-home .cr-eyebrow,.cr-try-page .cr-eyebrow,.cr-home .cr-step,.cr-try-page .cr-step { font-size:12px; letter-spacing:.08em; } -.cr-home .cr-caption,.cr-try-page .cr-caption { font-size:14px; } -.cr-home .cr-button,.cr-try-page .cr-button,.cr-home .cr-text-link,.cr-try-page .cr-text-link { font-size:14px; } -.cr-home .cr-home-hero { display:grid; grid-template-columns:1fr 1.1fr; gap:72px; align-items:start; padding:64px 0 84px; } -.cr-home-pitch { padding-top:30px; } -.cr-home h1 { font-size:clamp(40px,4.7vw,60px); line-height:1.08; } -.cr-home .cr-lede { font-size:22px; line-height:1.55; max-width:430px; } -.cr-home .cr-actions { gap:18px 24px; margin:36px 0 0; } -.cr-hero-quickstart { display:inline-block; margin-top:24px; } -.cr-home .cr-integration { align-items:start; gap:80px; } -.cr-home .cr-integration .cr-button { margin-top:30px; } -.cr-film { display:block; width:100%; border:1px solid var(--cr-line); border-radius:10px; background:var(--cr-ink); aspect-ratio:16/9; } -.cr-site .cr-demo-film .cr-caption { margin-top:20px; max-width:820px; } -.cr-demo-film code { font-size:13px; } -.cr-code-col { min-width:0; } -.cr-home .cr-integration .cr-code-col { margin-top:8px; } -.cr-code-col .cr-proof-links { margin-top:26px; padding-left:2px; } -.cr-home .cr-code pre { font-size:14px; padding:24px; } -.cr-home .cr-install { font-size:14px; } -.cr-code-context { padding:20px 24px; border-top:1px solid var(--cr-line); } -.cr-code-context strong { font-weight:550; font-size:15px; } -.cr-site .cr-code-context p { font-size:14px; padding:0; margin-top:8px; } -.cr-home .cr-footer,.cr-home .cr-footer>div { font-size:14px; } -.cr-home .cr-section,.cr-try-workspace { scroll-margin-top:100px; } -.cr-home .cr-section { padding:92px 0; } -.cr-home .cr-section-heading { margin-bottom:40px; } -/* The illustration starts with a choice and result, with context available on demand. */ -.cr-try-header { padding:36px 0 18px; display:flex; justify-content:space-between; gap:32px; align-items:center; } -.cr-try-header>div { max-width:770px; } -.cr-try-header .cr-eyebrow { margin-bottom:10px; } -.cr-try-page h1 { font-size:clamp(30px,3.3vw,42px); line-height:1.15; } -.cr-try-header p:not(.cr-eyebrow) { font-size:16px; margin-top:14px; } -.cr-try-header>.cr-text-link { flex-shrink:0; } -.cr-site .cr-try-disclosure { font-size:14px; margin:0 0 20px; } -.cr-try-workspace { padding-bottom:36px; } -.cr-try-page .cr-demo-toolbar { padding:20px 24px; } -.cr-try-page .cr-field,.cr-try-page .cr-select-button,.cr-try-page select { font-size:14px; } -.cr-try-page .cr-request,.cr-try-page .cr-result { padding:24px; } -.cr-try-page .cr-request h3 { margin-top:8px; } -.cr-try-page .cr-request-line { padding:4px 0; } -.cr-try-page .cr-result>p,.cr-try-page .cr-split p { font-size:16px; } -.cr-try-page .cr-result .cr-rule { font-size:14px; } -.cr-try-page .cr-result .cr-check,.cr-try-page .cr-code-label { font-size:12px; } -.cr-try-page .cr-checks strong { font-size:14px; } -.cr-try-page .cr-checks em,.cr-try-page .cr-checks li>span>span { font-size:13px; } -.cr-try-page .cr-demo-stage { grid-template-columns:.85fr 1.15fr; } -.cr-try-page .cr-sees code { font-size:14px; overflow-wrap:anywhere; } -.cr-try-page .cr-chips { padding:20px 24px; border-top:1px solid var(--cr-line); } -.cr-try-page .cr-chip { min-height:44px; font-size:14px; } -.cr-try-page .cr-lanes { border-radius:0; border-bottom:1px solid var(--cr-line); } -.cr-try-page .cr-lane p { font-size:14px; } -.cr-site .cr-lane-note { padding:18px 24px 0; font-size:14px; } -.cr-site .cr-demo-prompt { padding:14px 24px 20px; font-size:15px; color:var(--cr-muted); } -.cr-demo-prompt b { color:var(--cr-ink); font-weight:600; } -/* The three controls are steps, not settings: number them. */ -.cr-field>span,.cr-field #cr-domain-label,.cr-domain-picker>span { display:flex; align-items:center; gap:9px; } -.cr-field i { display:inline-flex; align-items:center; justify-content:center; width:19px; height:19px; flex-shrink:0; border-radius:50%; background:var(--cr-accent); color:var(--cr-paper); font:600 11px/1 ui-monospace,SFMono-Regular,Consolas,monospace; font-style:normal; } -.dark .cr-field i { color:#171b15; } -.cr-try-page .cr-demo-note { font-size:13px; } -/* Keep documentation tools in documentation; product pages use the main links. */ -body:has(.cr-home) #search-bar-entry,body:has(.cr-home) #assistant-entry, -body:has(.cr-try-page) #search-bar-entry,body:has(.cr-try-page) #assistant-entry, -body:has(.cr-home) #search-bar-entry-mobile,body:has(.cr-home) #assistant-entry-mobile, -body:has(.cr-try-page) #search-bar-entry-mobile,body:has(.cr-try-page) #assistant-entry-mobile { display:none; } -@media (max-width:1000px) { - .cr-home .cr-home-hero { gap:32px; } - .cr-try-header { align-items:flex-start; flex-direction:column; gap:14px; } -} -@media (max-width:800px) { - .cr-home .cr-home-hero { grid-template-columns:1fr; padding:44px 0 60px; gap:40px; } - .cr-home .cr-section { padding:72px 0; } - .cr-home h1 { font-size:clamp(38px,7vw,56px); } - .cr-home .cr-section-heading { align-items:flex-start; flex-direction:column; } - .cr-try-page .cr-demo-stage { grid-template-columns:1fr; } - .cr-try-page .cr-result { border-left:0; border-bottom:1px solid var(--cr-line); grid-row:1; } - .cr-try-page .cr-demo-toolbar { grid-template-columns:1fr; } -} -@media (max-width:600px) { - .cr-home,.cr-try-page { padding:0 20px; } - .cr-home .cr-eyebrow { font-size:12px; letter-spacing:.05em; } - .cr-home .cr-lede { margin-top:20px; } - .cr-home .cr-actions { gap:12px; align-items:flex-start; } - .cr-hero-quickstart { padding:8px 0; } - .cr-home .cr-section { padding:56px 0; } - .cr-home .cr-section-heading { margin-bottom:28px; } - .cr-home .cr-failure-chain { padding:20px 16px; } - .cr-home .cr-code pre { font-size:12px; padding:18px; } - .cr-try-header { padding-top:26px; } - .cr-try-page .cr-demo-toolbar,.cr-try-page .cr-request,.cr-try-page .cr-result,.cr-try-page .cr-chips { padding:18px; } -} - -/* Preserve the original hallucination example, aligned for direct comparison. */ -.cr-home .cr-failure-chain { min-width:0; padding:30px 28px; border:1px solid var(--cr-line); border-radius:10px; background:var(--cr-paper); } -.cr-home .cr-failure-chain h2 { font-size:26px; } -/* Both endings share a premise: state it once, then fork. */ -.cr-chain-setup { margin:22px 0 26px; padding:15px 16px; border:1px solid var(--cr-line); border-radius:8px; background:var(--cr-panel); } -.cr-site .cr-chain-setup p { display:flex; justify-content:space-between; align-items:baseline; gap:16px; font-size:14px; font-weight:550; color:var(--cr-ink); } -.cr-site .cr-chain-setup p+p { margin-top:7px; padding-top:7px; border-top:1px solid var(--cr-line); } -.cr-chain-setup span { font-weight:400; color:var(--cr-muted); } -.cr-home .cr-chain { display:grid; grid-template-columns:1fr 1fr; gap:24px; } -.cr-home .cr-chain-row { display:flex; flex-direction:column; gap:14px; } -.cr-home .cr-chain-label { font-size:12px; letter-spacing:.05em; } -.cr-home .cr-chain-steps { display:grid; grid-template-rows:repeat(3,minmax(56px,auto)); gap:16px; } -.cr-home .cr-chain-steps li { font-size:14px; padding:12px 8px; line-height:1.4; color:var(--cr-ink); } -.cr-home .cr-chain-steps li:not(:last-child)::after { content:"↓"; right:auto; left:50%; top:auto; bottom:-15px; transform:translateX(-50%); } -.cr-home .cr-home-how { border-top:1px solid var(--cr-line); } -@media (max-width:600px) { - .cr-home .cr-failure-chain { padding:18px 14px; } - .cr-home .cr-failure-chain h2 { font-size:25px; } - .cr-home .cr-chain { gap:12px; } - .cr-home .cr-chain-label { font-size:12px; letter-spacing:0; } - .cr-home .cr-chain-steps { grid-template-rows:repeat(3,minmax(68px,auto)); } - .cr-home .cr-chain-steps li { padding:10px 6px; } -} -@media (max-width:600px) { - .cr-try-page .cr-demo-toolbar { grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px 10px; } - .cr-try-page .cr-demo-toolbar>.cr-field:last-child { grid-column:1 / -1; } -} - -/* Short visual story: many actions pass through one execution boundary. */ -.cr-example-wrap { min-width:0; } -.cr-site .cr-example-label { margin:0 0 12px; font:600 12px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace; letter-spacing:.07em; color:var(--cr-accent); } -.cr-domain-actions { display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:16px; } -.cr-domain-actions a { display:flex; flex-direction:column; gap:13px; padding:22px 18px; background:var(--cr-paper); border:1px solid var(--cr-line); border-radius:6px; min-width:0; } -.cr-domain-actions strong { font-size:16px; font-weight:550; letter-spacing:-.02em; display:flex; align-items:center; justify-content:space-between; gap:8px; } -.cr-domain-actions strong span { color:var(--cr-accent); } -.cr-domain-actions a:hover { border-color:var(--cr-accent); } -.cr-home .cr-domain-actions .cr-step { font-size:12px; letter-spacing:0; } -.cr-boundary-flow { display:grid; grid-template-columns:1fr 40px 1fr 40px 1fr; align-items:center; gap:32px; padding:52px 36px; margin:40px 0 56px; border:1px solid var(--cr-line); border-radius:8px; } -.cr-boundary-source,.cr-boundary-gate { text-align:center; display:flex; flex-direction:column; gap:8px; } -.cr-boundary-source strong { font-weight:550; font-size:20px; } -/* The gate carries the logo itself: the keycap mark, then the wordmark, under the label. */ -.cr-boundary-gate { background:var(--cr-ink); color:#f2f3f5; border-radius:8px; padding:22px 18px 24px; } -.cr-home .cr-boundary-gate .cr-step { color:#f2f3f5; opacity:.6; } -.cr-gate-logo { display:flex; align-items:center; justify-content:center; gap:11px; margin-top:4px; } -.cr-gate-key { flex-shrink:0; } -.cr-gate-word { font-size:30px; font-weight:800; letter-spacing:-.045em; line-height:1.1; } -.cr-gate-word span { font-weight:400; letter-spacing:-.025em; } -.cr-boundary-arrow { font-size:30px; text-align:center; color:var(--cr-accent); } -.cr-boundary-decisions { display:flex; flex-direction:column; gap:10px; font-size:17px; font-weight:550; } -.cr-decision-allow { color:#356339; } -.cr-decision-approve { color:#885508; } -.cr-decision-deny { color:#9c372e; } -.dark .cr-decision-allow { color:#9ec793; } -.dark .cr-decision-approve { color:#edbd70; } -.dark .cr-decision-deny { color:#f5a198; } -.cr-memory-rules { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:24px 36px; } -.cr-memory-rules>div { padding-top:24px; border-top:2px solid var(--cr-accent); } -.cr-memory-rules h3 { font-size:21px; margin:10px 0 8px; } -.cr-memory-rules p { font-size:15px; } -.cr-memory-rules a { text-decoration:underline; text-underline-offset:3px; } -.cr-site .cr-not-llm { margin-top:52px; padding-top:30px; border-top:1px solid var(--cr-line); max-width:820px; font-size:15px; line-height:1.7; color:var(--cr-muted); } -.cr-not-llm strong { color:var(--cr-ink); font-weight:550; } -.cr-not-llm .cr-text-link { display:inline-block; margin-left:6px; } -.cr-site .cr-surfaces { list-style:none; padding:0; margin:34px 0 0; display:flex; flex-direction:column; gap:20px; } -.cr-surfaces li { position:relative; padding-left:16px; font-size:14px; line-height:1.6; color:var(--cr-muted); } -.cr-surfaces li::before { content:""; position:absolute; left:0; top:.6em; width:6px; height:6px; border-radius:50%; background:var(--cr-accent); } -.cr-surfaces b { display:block; font-size:14.5px; font-weight:600; color:var(--cr-ink); } -.cr-surfaces code { font-size:13px; } -.cr-surfaces b span { display:inline-block; margin-left:8px; padding:2px 7px; border:1px solid var(--cr-line); border-radius:3px; font:600 10px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace; letter-spacing:.1em; color:var(--cr-muted); vertical-align:1px; } -.cr-surface-planned::before { opacity:.35; } -.cr-surfaces a { color:var(--cr-ink); font-weight:550; text-decoration:underline; text-underline-offset:3px; } -.cr-proof-links { display:flex; flex-wrap:wrap; gap:12px 22px; font-size:14px; font-weight:550; margin-top:34px; } -.cr-proof-links a:hover,.cr-review-strip a:hover { text-decoration:underline; text-underline-offset:4px; } -.cr-site .cr-code-context p { margin:0; } -.cr-code-context a { text-decoration:underline; text-underline-offset:4px; } -.cr-review-strip { display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:16px; padding:44px 0; border-bottom:1px solid var(--cr-line); } -.cr-review-strip strong { font-size:18px; font-weight:550; } -.cr-review-strip>div { display:flex; flex-wrap:wrap; gap:16px 24px; font-size:14px; font-weight:550; } -.cr-demo-next h2 { font-size:28px; } -@media (max-width:1000px) { - .cr-domain-actions { grid-template-columns:repeat(3,minmax(0,1fr)); } - .cr-boundary-flow { gap:16px; padding:28px 20px; grid-template-columns:1fr 24px 1fr 24px 1fr; } -} -@media (max-width:800px) { - .cr-home .cr-lede { max-width:520px; } - .cr-memory-rules { grid-template-columns:repeat(2,minmax(0,1fr)); gap:24px; } -} -@media (max-width:600px) { - .cr-home .cr-home-hero { padding:36px 0 52px; gap:34px; } - .cr-home .cr-lede { font-size:19px; } - .cr-domain-actions { grid-template-columns:repeat(2,minmax(0,1fr)); } - .cr-domain-actions a { padding:16px 12px; } - .cr-domain-actions strong { font-size:15px; } - .cr-boundary-flow { grid-template-columns:1fr; gap:12px; padding:24px 18px; margin-bottom:30px; } - .cr-boundary-arrow { transform:rotate(90deg); line-height:1; } - .cr-boundary-gate { width:100%; max-width:230px; justify-self:center; padding:18px; } - .cr-boundary-decisions { flex-direction:row; flex-wrap:wrap; justify-content:center; gap:8px 16px; font-size:15px; } - .cr-memory-rules { grid-template-columns:1fr; gap:22px; } - .cr-memory-rules h3 { font-size:21px; } -} diff --git a/docs/try-it.js b/docs/try-it.js deleted file mode 100644 index 847f659..0000000 --- a/docs/try-it.js +++ /dev/null @@ -1,474 +0,0 @@ -/* - * The browser playground and the browser demo, for docs/try-it.mdx. - * - * Mintlify includes every .js file in the content directory on every page and cannot scope one - * to a single page, so this does nothing at all unless the page it belongs to has mounted a - * container. Everything it touches lives inside those containers. - * - * What it does: load Pyodide from the jsDelivr CDN, install `ctrlrun` from PyPI with micropip, - * and run real CTRLRun in the reader's own browser. Nothing is sent anywhere: the remote is a - * fake in the same process, the state store is in memory, and no socket is opened. The version - * is whatever is released on PyPI, which is the version a reader would get from - * `pip install ctrlrun`. - * - * Two pieces of Python live in this file, each a JSON array of lines so that the harnesses and - * the test suite can read them out rather than carrying a copy: - * - * PLAYGROUND — a module defining `step(request_json) -> result_json` over one `Control`, one - * in-memory store and one fake Stripe. The page's controls build a request; the - * module runs the protected call and reports what CTRLRun did, as JSON. The - * JavaScript owns the DOM and nothing else — every outcome the reader sees was - * produced by `ctrlrun` in the tab. `tests/test_docs_travelling.py` runs this - * module natively through the whole sequence the page suggests, on every commit, - * with no Node and no network. - * PROGRAM — `ctrlrun demo`, the five scenarios, for the button below the playground. - * - * Verified against Pyodide 314.0.6 (Python 3.14.2) with ctrlrun 0.5.0 by docs/assets/verify-browser-demo.mjs, - * which reads both arrays out of this file and runs them under Node. It read its own copy - * until 2026-09-06, and a syntax error in the copy that shipped reached the deployed page. - */ -(function () { - "use strict"; - - var PYODIDE = "https://cdn.jsdelivr.net/pyodide/v314.0.6/full/"; - var CONTAINER = "ctrlrun-browser-demo"; - var PLAYGROUND_ID = "ctrlrun-playground"; - - // `sqlite3` is bundled into Pyodide 314 and is not a loadable package; `pyyaml` is one of - // Pyodide's own builds; `click` arrives as ctrlrun's dependency through micropip. - var PACKAGES = ["micropip", "pyyaml"]; - - // The playground module. Public API only — `Control`, `InMemoryStateStore`, - // `LocalApprovalProvider`, `Policy.from_yaml`, `@protect`, `context`, `with_approval`, and the - // exceptions — so what a reader sees here is what the same calls do in their own process. An - // approval is a `grant_approval` on the store, the same write `ctrlrun approve` makes; there - // is no auto-approve and no dry run. Keep it JSON-parseable: double-quoted strings, no comment - // inside the array, no trailing comma. The policy in it is the one the page shows, and a test - // holds the two equal. - var PLAYGROUND = [ - "import json", - "from ctrlrun import Control, InMemoryStateStore, LocalApprovalProvider, Policy", - "from ctrlrun import ActionDenied, AmbiguousEffect, ApprovalMismatch, ApprovalRequired, DuplicateEffect", - "from ctrlrun import context, protect, with_approval", - "", - "POLICY = \"\"\"", - "schema: ctrlrun.policy/v2", - "actions:", - " stripe.refund:", - " effect: \"refund:{payment_id}\"", - " rules:", - " - when: { amount_gte: 0, amount_lte: 100000 }", - " decision: allow", - " - when: { amount_gte: 0, amount_lte: 1000000 }", - " decision: approve", - " - decision: deny", - "\"\"\"", - "", - "", - "class FakeStripe:", - " def __init__(self):", - " self.calls = []", - " self.lose_reply = False", - "", - " def refund(self, payment_id, amount):", - " self.calls.append(payment_id)", - " if self.lose_reply:", - " raise TimeoutError(\"no response from api.stripe.com after 30s\")", - " return {\"id\": \"re_\" + payment_id, \"amount\": amount, \"status\": \"succeeded\"}", - "", - "", - "store = InMemoryStateStore()", - "control = Control(Policy.from_yaml(POLICY, source=\"<playground>\"), store, LocalApprovalProvider(store))", - "remote = FakeStripe()", - "", - "", - "@protect(\"stripe.refund\", effect=\"refund:{payment_id}\", control=control)", - "def refund(payment_id, amount):", - " return remote.refund(payment_id, amount)", - "", - "", - "def _run(payment_id, amount, approval_id):", - " if approval_id:", - " with with_approval(approval_id):", - " return refund(payment_id=payment_id, amount=amount)", - " return refund(payment_id=payment_id, amount=amount)", - "", - "", - "def step(request_json):", - " request = json.loads(request_json)", - " if request[\"op\"] == \"approve\":", - " approval = store.grant_approval(request[\"request_id\"], \"human:you\")", - " return json.dumps({\"op\": \"approve\", \"approval_id\": approval.approval_id, \"action_hash\": approval.action_hash})", - " payment_id = str(request[\"payment_id\"]).strip() or \"txn_1\"", - " amount = int(request[\"amount\"])", - " remote.lose_reply = bool(request.get(\"lose_reply\"))", - " result = {\"op\": \"refund\", \"payment_id\": payment_id, \"amount\": amount}", - " try:", - " with context(agent=\"refund-agent\"):", - " _run(payment_id, amount, request.get(\"approval_id\"))", - " result[\"outcome\"] = \"executed\"", - " except ApprovalRequired as pending:", - " result[\"outcome\"] = \"approval_required\"", - " result[\"request_id\"] = pending.request_id", - " except ApprovalMismatch as refused:", - " result[\"outcome\"] = \"approval_mismatch\"", - " result[\"reason\"] = refused.reason", - " except ActionDenied as refused:", - " result[\"outcome\"] = \"denied\"", - " result[\"reason\"] = refused.reason", - " except DuplicateEffect as refused:", - " result[\"outcome\"] = \"duplicate\"", - " result[\"reason\"] = str(refused)", - " except AmbiguousEffect as refused:", - " result[\"outcome\"] = \"ambiguous_retry\"", - " result[\"reason\"] = str(refused)", - " except TimeoutError as lost:", - " result[\"outcome\"] = \"reply_lost\"", - " result[\"reason\"] = str(lost)", - " result[\"remote_calls\"] = remote.calls.count(payment_id)", - " receipts = [r for r in store.receipts() if r.arguments.get(\"payment_id\") == payment_id]", - " if receipts:", - " last = receipts[-1]", - " result[\"receipt\"] = {\"decision\": str(last.decision), \"result\": str(last.result), \"effect_key\": last.effect_key, \"approval_id\": last.approval_id}", - " return json.dumps(result)" - ].join("\n"); - - // The Python the demo button runs. `runPython` returns the value of the last expression, so - // the last line is an expression rather than an assignment, and it is a single line: a - // trailing `+` outside brackets is a SyntaxError, which is exactly what shipped here and put a - // traceback in front of every reader. Two harnesses claimed to have verified this page and - // neither ran this string — `verify-browser-wiring.mjs` loads this script with Pyodide - // stubbed, and `verify-browser-demo.mjs` carried its own copy of the program. The demo - // harness now reads this array, and `tests/test_docs_travelling.py` compiles it on every - // commit, which needs no network and no Node. Keep it JSON-parseable: double-quoted strings, - // no comment inside the array, no trailing comma. - var PROGRAM = [ - "import importlib.metadata, io, platform", - "from contextlib import redirect_stdout", - "from pathlib import Path", - "from ctrlrun.cli.demo import run_demo", - "", - "buffer = io.StringIO()", - "with redirect_stdout(buffer):", - " run_demo(Path('/tmp/ctrlrun-demo'))", - "version = importlib.metadata.version('ctrlrun')", - "f'ctrlrun {version} on Python {platform.python_version()}\\n\\n' + buffer.getvalue()" - ].join("\n"); - - function ready(fn) { - if (document.readyState !== "loading") fn(); - else document.addEventListener("DOMContentLoaded", fn); - } - - function load(src) { - return new Promise(function (resolve, reject) { - var tag = document.createElement("script"); - tag.src = src; - tag.onload = resolve; - tag.onerror = function () { - reject(new Error("could not load " + src)); - }; - document.head.appendChild(tag); - }); - } - - // One runtime for both containers: the second one to ask waits on the first one's download. - var runtimePromise = null; - - function runtime(say) { - if (runtimePromise) return runtimePromise; - runtimePromise = (async function () { - say("Loading Python in this tab. The first run downloads about 10 MB from the Pyodide\nCDN and the ctrlrun wheel from PyPI; after that the browser caches them."); - if (!window.loadPyodide) await load(PYODIDE + "pyodide.js"); - var pyodide = await window.loadPyodide({ indexURL: PYODIDE }); - say("Installing ctrlrun from PyPI…"); - await pyodide.loadPackage(PACKAGES); - var micropip = pyodide.pyimport("micropip"); - await micropip.install("ctrlrun"); - return pyodide; - })(); - runtimePromise.catch(function () { - runtimePromise = null; // a failed download is retried on the next click - }); - return runtimePromise; - } - - function failure(error, command) { - return ( - "This did not run in this browser:\n\n " + - (error && error.message ? error.message : String(error)) + - "\n\nThat is this page failing, not CTRLRun. Run it locally instead:\n\n " + - command + - "\n" - ); - } - - var REFUSED = "#f28b82"; - var GRANTED = "#8bd5a0"; - - // The transcript goes inside one block child rather than straight into the <pre>. - // Mintlify's theme lays this <pre> out as `display: flex`, and in a flex container every - // appended child is a flex item in a *row*: the lines ran off to the right instead of - // down, and a coloured refusal landed beside its neighbours rather than under them. - // `say` never hit it because it sets a single text node, which is one item however the - // box is laid out. The page also asks for `display: block` — belt to this brace, since - // an inline style loses to an `!important` rule the theme does not have today. - function blockIn(output) { - output.textContent = ""; - var body = document.createElement("code"); - body.style.display = "block"; - body.style.whiteSpace = "pre"; - body.style.fontFamily = "inherit"; - body.style.fontSize = "inherit"; - output.appendChild(body); - return body; - } - - function lineNode(line) { - var node; - if (line.indexOf("BLOCKED") !== -1 || line.indexOf("refused") !== -1 || line.indexOf("denied") !== -1) { - node = document.createElement("span"); - node.style.color = REFUSED; - node.style.fontWeight = "700"; - node.textContent = line; - } else if (line.indexOf("approves") !== -1) { - node = document.createElement("span"); - node.style.color = GRANTED; - node.textContent = line; - } else { - node = document.createTextNode(line); - } - return node; - } - - // ---- the playground ------------------------------------------------------------------- - - function euros(cents) { - var whole = Math.floor(Math.abs(cents) / 100); - var rest = Math.abs(cents) % 100; - var text = "€" + whole.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); - if (rest) text += "." + (rest < 10 ? "0" : "") + rest; - return cents < 0 ? "-" + text : text; - } - - function wirePlayground() { - var panel = document.getElementById(PLAYGROUND_ID); - if (!panel || panel.dataset.wired === "yes") return; - - var amount = panel.querySelector('input[name="amount"]'); - var payment = panel.querySelector('input[name="payment_id"]'); - var lose = panel.querySelector('input[name="lose_reply"]'); - var run = panel.querySelector('button[name="run"]'); - var approve = panel.querySelector('button[name="approve"]'); - var log = panel.querySelector("pre"); - if (!amount || !payment || !lose || !run || !approve || !log) return; - panel.dataset.wired = "yes"; - - var pyodide = null; - var lines = null; // the block child the transcript lives in - var pending = null; // the request a human has not answered yet - var granted = null; // the approval the next run of that payment presents - - function say(text) { - lines = null; - log.textContent = text; - } - - function write(line) { - if (!lines) lines = blockIn(log); - var following = log.scrollHeight - log.scrollTop - log.clientHeight < 40; - lines.appendChild(lineNode(line)); - lines.appendChild(document.createTextNode("\n")); - if (following) log.scrollTop = log.scrollHeight; - } - - function step(request) { - pyodide.globals.set("PLAYGROUND_REQUEST", JSON.stringify(request)); - return JSON.parse(pyodide.runPython("step(PLAYGROUND_REQUEST)")); - } - - async function boot() { - var ready = await runtime(say); - ready.runPython(PLAYGROUND); - say(""); - return ready; - } - - function busy(on) { - run.disabled = on; - approve.disabled = on; - } - - async function refund() { - var cents = Math.round(Number(amount.value) * 100); - // A number input hands back "" for anything it could not parse, and Number("") is 0: - // a €0 refund is not what somebody who typed letters asked for. - if (amount.value.trim() === "" || !isFinite(cents)) { - write("amount: enter a number of euros"); - return; - } - var id = payment.value.trim() || "txn_1"; - var request = { op: "refund", payment_id: id, amount: cents, lose_reply: lose.checked }; - if (granted && granted.payment_id === id) request.approval_id = granted.approval_id; - var result = step(request); - var head = "refund " + id + " " + euros(cents) + (request.approval_id ? " (presenting " + request.approval_id + ")" : ""); - var receipt = result.receipt || {}; - switch (result.outcome) { - case "executed": - write(head + " → " + receipt.decision + " → executed; receipt " + receipt.result + "; remote refund calls: " + result.remote_calls); - // The approval stays on the panel so the next run presents it again and the reader - // sees `consumed`: single-use is something to watch, not something to be told. - break; - case "approval_required": - write(head + " → approve → ApprovalRequired: a human decides " + result.request_id); - write(" press Approve, then run again — or change the amount after approving and watch it refused"); - pending = { request_id: result.request_id, payment_id: id, amount: cents }; - approve.hidden = false; - break; - case "approval_mismatch": - if (result.reason === "consumed") { - write(head + " → refused: ApprovalMismatch (consumed) — a single-use approval, already spent"); - granted = null; - } else { - write(head + " → refused: ApprovalMismatch (" + result.reason + ") — the approval is bound to the action the human saw; remote refund calls: " + result.remote_calls); - write(" the approval is still unspent: run the approved amount and it executes"); - } - break; - case "denied": - write(head + " → deny → refused: ActionDenied (" + result.reason + "); no request created; remote refund calls: " + result.remote_calls); - break; - case "reply_lost": - write(head + " → allow → remote commits → reply lost → effect: AMBIGUOUS; receipt " + receipt.result + "; remote refund calls: " + result.remote_calls); - write(" run the same payment again: a blind retry is refused until a human or a reconcile hook says what happened"); - break; - case "ambiguous_retry": - write(head + " → refused: AmbiguousEffect — the remote may already have committed; remote refund calls: " + result.remote_calls); - write(" only a human moves it on: ctrlrun resolve refund:" + id + " --committed|--failed"); - break; - case "duplicate": - write(head + " → refused: DuplicateEffect — refund:" + id + " already happened; remote refund calls: " + result.remote_calls); - break; - default: - write(head + " → " + JSON.stringify(result)); - } - write(""); - } - - async function grant() { - if (!pending) return; - var result = step({ op: "approve", request_id: pending.request_id }); - write("human approves " + result.approval_id + " (bound to " + result.action_hash.slice(0, 19) + "…)"); - write(" run " + euros(pending.amount) + " for " + pending.payment_id + " and it executes; run any other amount on it and it is refused"); - write(""); - granted = { approval_id: result.approval_id, payment_id: pending.payment_id }; - pending = null; - approve.hidden = true; - } - - async function click(action) { - busy(true); - try { - if (!pyodide) pyodide = await boot(); - await action(); - } catch (error) { - say(failure(error, "pip install ctrlrun && ctrlrun demo")); - } finally { - busy(false); - } - } - - approve.hidden = true; - run.addEventListener("click", function () { - click(refund); - }); - approve.addEventListener("click", function () { - click(grant); - }); - payment.addEventListener("change", function () { - // A new payment id is a new effect; a pending answer belongs to the old one. - approve.hidden = !pending || pending.payment_id !== payment.value.trim(); - }); - } - - // ---- the demo --------------------------------------------------------------------------- - - function wire() { - wirePlayground(); - - var container = document.getElementById(CONTAINER); - if (!container || container.dataset.wired === "yes") return; - - var button = container.querySelector("button"); - var output = container.querySelector("pre"); - if (!button || !output) return; - container.dataset.wired = "yes"; - - var pyodide = null; - - function say(text) { - output.textContent = text; - } - - // The demo prints all five scenarios at once. Released a line at a time, as the README's - // recording does, a reader can follow each one. The text is what the demo printed and - // nothing else; the only thing added is time, and the colour on each refusal. - var LINE_MS = 380; - - function reveal(text) { - var body = blockIn(output); - var lines = text.split("\n"); - return new Promise(function (resolve) { - var index = 0; - function next() { - if (index === lines.length) return resolve(); - var line = lines[index++]; - var node = lineNode(line); - // Follow the newest line, but only for a reader who is already at the bottom: - // yanking somebody back who has scrolled up to re-read scenario 1 is worse than - // not following at all. The box has a max height, so this is a real scroll — it - // was dead code while the box could only grow, and the reader got a horizontal - // scrollbar and a page that got taller instead of a terminal that scrolled. - var following = output.scrollHeight - output.scrollTop - output.clientHeight < 40; - body.appendChild(node); - body.appendChild(document.createTextNode("\n")); - if (following) output.scrollTop = output.scrollHeight; - window.setTimeout(next, line.trim() === "" ? 0 : LINE_MS); - } - next(); - }); - } - - async function run() { - button.disabled = true; - var label = button.textContent; - button.textContent = "Running…"; - try { - if (!pyodide) pyodide = await runtime(say); - say("Running the five scenarios…"); - await reveal(pyodide.runPython(PROGRAM)); - button.textContent = "Run it again"; - } catch (error) { - say(failure(error, "pip install ctrlrun && ctrlrun demo")); - button.textContent = label; - } finally { - button.disabled = false; - } - } - - button.addEventListener("click", run); - } - - // The site is a single-page app and this script runs once, when the page becomes - // interactive: on a first load that can be before React has painted the container, and on a - // navigation from another page the script does not run again at all. Both were true on the - // deployed site, where the button did nothing. So wiring is attempted now and again on every - // DOM change; `wire` is a `getElementById` and a flag check when there is nothing to do, and - // the flag lives on the element, so a container React mounts afresh is wired afresh. - ready(wire); - if (window.MutationObserver) { - new MutationObserver(wire).observe(document.documentElement, { - childList: true, - subtree: true, - }); - } -})(); diff --git a/docs/try.mdx b/docs/try.mdx deleted file mode 100644 index 95c01df..0000000 --- a/docs/try.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "Try the execution boundary" -description: "Pick an agent action in your own domain and watch which check refuses it: policy, approval binding, effect reservation, or an unknown outcome." -canonical: "https://ctrlrun.dev/try" -"og:url": "https://ctrlrun.dev/try" -"og:title": "Try the execution boundary | CTRLRun" -"twitter:title": "Try the execution boundary | CTRLRun" -mode: "custom" ---- - -import { ScenarioExplorer } from "/snippets/scenario-explorer.jsx"; - -<div className="cr-site cr-try-page"> - <section className="cr-try-header" aria-labelledby="cr-try-page-title"> - <div><p className="cr-eyebrow">INTERACTIVE SCENARIOS</p><h1 id="cr-try-page-title">The model decides what.<br />CTRLRun decides whether<span className="cr-dot">.</span></h1><p>An LLM picks the action and the arguments, and it is confident either way. CTRLRun sits at the moment that action would leave your process and answers one question: may this execute now? Choose a domain below and watch it answer.</p></div> - <a className="cr-text-link" href="/docs/try-it">Run the real Python demo ↗</a> - </section> - <p className="cr-try-disclosure">This page is an illustration: the example rules are not industry defaults, nothing here executes, and no request is sent. No login or API key needed. <a href="/docs/try-it">Run the released wheel instead ↗</a></p> - <section className="cr-try-workspace" aria-label="Execution boundary scenario explorer"> - <ScenarioExplorer standalone={true} /> - </section> - - <section className="cr-section cr-demo-next" aria-labelledby="cr-try-next-title"> - <h2 id="cr-try-next-title">Take it into your code.</h2> - <div className="cr-proof-links"><a href="/docs/try-it">Run the real library ↗</a><a href="/docs/get-started/quickstart">Protect your first action ↗</a><a href="/docs/ARCHITECTURE">Read the architecture ↗</a></div> - </section> - - <div className="cr-footer" role="contentinfo"><span>Give agents autonomy.<br /><strong>Keep control of their actions.</strong></span><div><a href="/">CTRLRun ↗</a><a href="/docs" data-cr-event="documentation_clicked">Read the docs →</a><a href="https://github.com/CTRLRun/ctrlrun" data-cr-event="github_clicked">GitHub ↗</a></div></div> -</div> diff --git a/docs/website-events.js b/docs/website-events.js deleted file mode 100644 index 714283d..0000000 --- a/docs/website-events.js +++ /dev/null @@ -1,22 +0,0 @@ -/* Optional, consent-aware conversion hooks. No tracker, network calls, or storage. - * An existing analytics integration can subscribe to `ctrlrun:conversion`. - * Free-text form fields and email content are never included in event details. - */ -(() => { - if (window.__ctrlrunWebsiteEvents) return; - window.__ctrlrunWebsiteEvents = true; - const emit = name => window.dispatchEvent(new CustomEvent('ctrlrun:conversion', { detail: { name } })); - document.addEventListener('click', event => { - const target = event.target instanceof Element ? event.target.closest('[data-cr-event]') : null; - if (target) emit(target.getAttribute('data-cr-event')); - }); - let lastPath = ''; - const visit = () => { - if (lastPath !== location.pathname) { - lastPath = location.pathname; - if (lastPath === '/' || lastPath === '/index') emit('homepage_visited'); - } - }; - visit(); - new MutationObserver(visit).observe(document.documentElement, { childList: true, subtree: true }); -})(); diff --git a/examples/acs/README.md b/examples/acs/README.md index 7d99b43..c58e25c 100644 --- a/examples/acs/README.md +++ b/examples/acs/README.md @@ -20,5 +20,5 @@ The remote commits the refund and the response goes missing. ACS reports `exit_s records `AMBIGUOUS` and refuses the retry, because a tool that timed out after acting and one that timed out before acting send the same string. -See [`docs/docs/ACS.md`](../../docs/docs/ACS.md) for the full mapping and for where the two models +See [the ACS mapping](https://ctrlrun.dev/docs/ACS) for the full mapping and for where the two models disagree. diff --git a/examples/authority/README.md b/examples/authority/README.md index 67700dc..aa472dc 100644 --- a/examples/authority/README.md +++ b/examples/authority/README.md @@ -36,4 +36,4 @@ dimension the subject can set is not one. For the delegation chain these documents anticipate, run [`examples/authority-escalation/`](../authority-escalation/), and read -[`docs/docs/authority.md`](../../docs/docs/authority.md) for the model in plain language. +[the authority model](https://ctrlrun.dev/docs/authority) for the model in plain language. diff --git a/examples/cookbook/credential-rotation-agent/ctrlrun.yaml b/examples/cookbook/credential-rotation-agent/ctrlrun.yaml index adc1be1..7decc80 100644 --- a/examples/cookbook/credential-rotation-agent/ctrlrun.yaml +++ b/examples/cookbook/credential-rotation-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/credential-rotation-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/credential-rotation-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/credential-rotation-agent/main.py b/examples/cookbook/credential-rotation-agent/main.py index 0a6a34e..418f62e 100644 --- a/examples/cookbook/credential-rotation-agent/main.py +++ b/examples/cookbook/credential-rotation-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/credential-rotation-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/credential-rotation-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/crm-update-agent/ctrlrun.yaml b/examples/cookbook/crm-update-agent/ctrlrun.yaml index 459c4e4..aa7295e 100644 --- a/examples/cookbook/crm-update-agent/ctrlrun.yaml +++ b/examples/cookbook/crm-update-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/crm-update-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/crm-update-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/crm-update-agent/main.py b/examples/cookbook/crm-update-agent/main.py index 77a5452..e1828f7 100644 --- a/examples/cookbook/crm-update-agent/main.py +++ b/examples/cookbook/crm-update-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/crm-update-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/crm-update-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/customer-notification-agent/ctrlrun.yaml b/examples/cookbook/customer-notification-agent/ctrlrun.yaml index beb7808..e01a906 100644 --- a/examples/cookbook/customer-notification-agent/ctrlrun.yaml +++ b/examples/cookbook/customer-notification-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/customer-notification-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/customer-notification-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/customer-notification-agent/main.py b/examples/cookbook/customer-notification-agent/main.py index 9942908..237dd75 100644 --- a/examples/cookbook/customer-notification-agent/main.py +++ b/examples/cookbook/customer-notification-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/customer-notification-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/customer-notification-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/data-deletion-agent/ctrlrun.yaml b/examples/cookbook/data-deletion-agent/ctrlrun.yaml index 6c653a6..93ad4a1 100644 --- a/examples/cookbook/data-deletion-agent/ctrlrun.yaml +++ b/examples/cookbook/data-deletion-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/data-deletion-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/data-deletion-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/data-deletion-agent/main.py b/examples/cookbook/data-deletion-agent/main.py index 49c71e1..8a2dead 100644 --- a/examples/cookbook/data-deletion-agent/main.py +++ b/examples/cookbook/data-deletion-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/data-deletion-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/data-deletion-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/database-migration-agent/ctrlrun.yaml b/examples/cookbook/database-migration-agent/ctrlrun.yaml index 661e52e..052a28b 100644 --- a/examples/cookbook/database-migration-agent/ctrlrun.yaml +++ b/examples/cookbook/database-migration-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/database-migration-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/database-migration-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/database-migration-agent/main.py b/examples/cookbook/database-migration-agent/main.py index 919863d..b329daf 100644 --- a/examples/cookbook/database-migration-agent/main.py +++ b/examples/cookbook/database-migration-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/database-migration-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/database-migration-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/deploy-agent/ctrlrun.yaml b/examples/cookbook/deploy-agent/ctrlrun.yaml index df027c3..eb65a65 100644 --- a/examples/cookbook/deploy-agent/ctrlrun.yaml +++ b/examples/cookbook/deploy-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/deploy-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/deploy-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/deploy-agent/main.py b/examples/cookbook/deploy-agent/main.py index b53802b..724fc7f 100644 --- a/examples/cookbook/deploy-agent/main.py +++ b/examples/cookbook/deploy-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/deploy-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/deploy-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/iam-agent/ctrlrun.yaml b/examples/cookbook/iam-agent/ctrlrun.yaml index 3b85b99..25ab06b 100644 --- a/examples/cookbook/iam-agent/ctrlrun.yaml +++ b/examples/cookbook/iam-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/iam-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/iam-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/iam-agent/main.py b/examples/cookbook/iam-agent/main.py index 3714202..db27e3c 100644 --- a/examples/cookbook/iam-agent/main.py +++ b/examples/cookbook/iam-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/iam-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/iam-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/manager-and-worker/ctrlrun.yaml b/examples/cookbook/manager-and-worker/ctrlrun.yaml index fb7ea7c..d1832e9 100644 --- a/examples/cookbook/manager-and-worker/ctrlrun.yaml +++ b/examples/cookbook/manager-and-worker/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/manager-and-worker.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/manager-and-worker.mdx — edit the page, never this file. schema: ctrlrun.policy/v3 authority: diff --git a/examples/cookbook/manager-and-worker/main.py b/examples/cookbook/manager-and-worker/main.py index b9419fa..c53908f 100644 --- a/examples/cookbook/manager-and-worker/main.py +++ b/examples/cookbook/manager-and-worker/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/manager-and-worker.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/manager-and-worker.mdx — edit the page, never this file. from pathlib import Path from ctrlrun import ( diff --git a/examples/cookbook/observe-then-enforce/ctrlrun.yaml b/examples/cookbook/observe-then-enforce/ctrlrun.yaml index 2531a4b..960096c 100644 --- a/examples/cookbook/observe-then-enforce/ctrlrun.yaml +++ b/examples/cookbook/observe-then-enforce/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/observe-then-enforce.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/observe-then-enforce.mdx — edit the page, never this file. schema: ctrlrun.policy/v3 mode: observe diff --git a/examples/cookbook/observe-then-enforce/main.py b/examples/cookbook/observe-then-enforce/main.py index afa0ece..c2ec44e 100644 --- a/examples/cookbook/observe-then-enforce/main.py +++ b/examples/cookbook/observe-then-enforce/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/observe-then-enforce.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/observe-then-enforce.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/outbound-email-agent/ctrlrun.yaml b/examples/cookbook/outbound-email-agent/ctrlrun.yaml index c97c81d..c07aa26 100644 --- a/examples/cookbook/outbound-email-agent/ctrlrun.yaml +++ b/examples/cookbook/outbound-email-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/outbound-email-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/outbound-email-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/outbound-email-agent/main.py b/examples/cookbook/outbound-email-agent/main.py index 5b28df6..d5d3f08 100644 --- a/examples/cookbook/outbound-email-agent/main.py +++ b/examples/cookbook/outbound-email-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/outbound-email-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/outbound-email-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/payout-maker-checker/ctrlrun.yaml b/examples/cookbook/payout-maker-checker/ctrlrun.yaml index 535d460..1a7c4bb 100644 --- a/examples/cookbook/payout-maker-checker/ctrlrun.yaml +++ b/examples/cookbook/payout-maker-checker/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/payout-maker-checker.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/payout-maker-checker.mdx — edit the page, never this file. schema: ctrlrun.policy/v3 authority: diff --git a/examples/cookbook/payout-maker-checker/main.py b/examples/cookbook/payout-maker-checker/main.py index a8c3109..f97b15b 100644 --- a/examples/cookbook/payout-maker-checker/main.py +++ b/examples/cookbook/payout-maker-checker/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/payout-maker-checker.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/payout-maker-checker.mdx — edit the page, never this file. from pathlib import Path from ctrlrun import ( diff --git a/examples/cookbook/protect-an-mcp-server/ctrlrun.yaml b/examples/cookbook/protect-an-mcp-server/ctrlrun.yaml index cb536cf..7589b12 100644 --- a/examples/cookbook/protect-an-mcp-server/ctrlrun.yaml +++ b/examples/cookbook/protect-an-mcp-server/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/protect-an-mcp-server.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/protect-an-mcp-server.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/protect-an-mcp-server/main.py b/examples/cookbook/protect-an-mcp-server/main.py index 3962748..f1dbb74 100644 --- a/examples/cookbook/protect-an-mcp-server/main.py +++ b/examples/cookbook/protect-an-mcp-server/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/protect-an-mcp-server.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/protect-an-mcp-server.mdx — edit the page, never this file. import json from collections.abc import Mapping from pathlib import Path diff --git a/examples/cookbook/receipts-to-opentelemetry/ctrlrun.yaml b/examples/cookbook/receipts-to-opentelemetry/ctrlrun.yaml index 01a839e..20673c8 100644 --- a/examples/cookbook/receipts-to-opentelemetry/ctrlrun.yaml +++ b/examples/cookbook/receipts-to-opentelemetry/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/receipts-to-opentelemetry.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/receipts-to-opentelemetry.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/receipts-to-opentelemetry/main.py b/examples/cookbook/receipts-to-opentelemetry/main.py index 5d00220..b324834 100644 --- a/examples/cookbook/receipts-to-opentelemetry/main.py +++ b/examples/cookbook/receipts-to-opentelemetry/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/receipts-to-opentelemetry.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/receipts-to-opentelemetry.mdx — edit the page, never this file. import contextlib from pathlib import Path diff --git a/examples/cookbook/reconcile-against-the-remote/ctrlrun.yaml b/examples/cookbook/reconcile-against-the-remote/ctrlrun.yaml index a7f088a..39c3d84 100644 --- a/examples/cookbook/reconcile-against-the-remote/ctrlrun.yaml +++ b/examples/cookbook/reconcile-against-the-remote/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/reconcile-against-the-remote.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/reconcile-against-the-remote.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/reconcile-against-the-remote/main.py b/examples/cookbook/reconcile-against-the-remote/main.py index 15d2509..de1a294 100644 --- a/examples/cookbook/reconcile-against-the-remote/main.py +++ b/examples/cookbook/reconcile-against-the-remote/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/reconcile-against-the-remote.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/reconcile-against-the-remote.mdx — edit the page, never this file. import contextlib from pathlib import Path diff --git a/examples/cookbook/refund-agent/ctrlrun.yaml b/examples/cookbook/refund-agent/ctrlrun.yaml index 3f1a889..e88c00d 100644 --- a/examples/cookbook/refund-agent/ctrlrun.yaml +++ b/examples/cookbook/refund-agent/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/refund-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/refund-agent.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/refund-agent/main.py b/examples/cookbook/refund-agent/main.py index f0d8a20..9693efc 100644 --- a/examples/cookbook/refund-agent/main.py +++ b/examples/cookbook/refund-agent/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/refund-agent.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/refund-agent.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/resolve-an-ambiguous-effect/ctrlrun.yaml b/examples/cookbook/resolve-an-ambiguous-effect/ctrlrun.yaml index dd49952..75b0244 100644 --- a/examples/cookbook/resolve-an-ambiguous-effect/ctrlrun.yaml +++ b/examples/cookbook/resolve-an-ambiguous-effect/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/resolve-an-ambiguous-effect.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/resolve-an-ambiguous-effect.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/resolve-an-ambiguous-effect/main.py b/examples/cookbook/resolve-an-ambiguous-effect/main.py index f3904a5..d3c2d23 100644 --- a/examples/cookbook/resolve-an-ambiguous-effect/main.py +++ b/examples/cookbook/resolve-an-ambiguous-effect/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/resolve-an-ambiguous-effect.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/resolve-an-ambiguous-effect.mdx — edit the page, never this file. from pathlib import Path import ctrlrun diff --git a/examples/cookbook/slack-approvals/ctrlrun.yaml b/examples/cookbook/slack-approvals/ctrlrun.yaml index 96c58e4..48f2064 100644 --- a/examples/cookbook/slack-approvals/ctrlrun.yaml +++ b/examples/cookbook/slack-approvals/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/slack-approvals.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/slack-approvals.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/slack-approvals/main.py b/examples/cookbook/slack-approvals/main.py index 71a4bfc..4b304eb 100644 --- a/examples/cookbook/slack-approvals/main.py +++ b/examples/cookbook/slack-approvals/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/slack-approvals.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/slack-approvals.mdx — edit the page, never this file. import json from pathlib import Path diff --git a/examples/cookbook/sqlite-to-postgres/ctrlrun.yaml b/examples/cookbook/sqlite-to-postgres/ctrlrun.yaml index c0b4f05..bf9c2dd 100644 --- a/examples/cookbook/sqlite-to-postgres/ctrlrun.yaml +++ b/examples/cookbook/sqlite-to-postgres/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/sqlite-to-postgres.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/sqlite-to-postgres.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/sqlite-to-postgres/main.py b/examples/cookbook/sqlite-to-postgres/main.py index 3602109..a0625b3 100644 --- a/examples/cookbook/sqlite-to-postgres/main.py +++ b/examples/cookbook/sqlite-to-postgres/main.py @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/sqlite-to-postgres.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/sqlite-to-postgres.mdx — edit the page, never this file. import os from pathlib import Path diff --git a/examples/cookbook/verify-in-github-actions/ctrlrun.yaml b/examples/cookbook/verify-in-github-actions/ctrlrun.yaml index 1f03ab3..f336071 100644 --- a/examples/cookbook/verify-in-github-actions/ctrlrun.yaml +++ b/examples/cookbook/verify-in-github-actions/ctrlrun.yaml @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/verify-in-github-actions.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/verify-in-github-actions.mdx — edit the page, never this file. schema: ctrlrun.policy/v2 actions: diff --git a/examples/cookbook/verify-in-github-actions/run.sh b/examples/cookbook/verify-in-github-actions/run.sh index f470066..3208bb2 100644 --- a/examples/cookbook/verify-in-github-actions/run.sh +++ b/examples/cookbook/verify-in-github-actions/run.sh @@ -1,5 +1,5 @@ -# Extracted by tools/docs_audit/render_cookbook.py from -# docs/docs/cookbook/verify-in-github-actions.mdx — edit the page, never this file. +# Extracted by CTRLRun/ctrlrun-docs tools/docs_audit/render_cookbook.py from +# docs/cookbook/verify-in-github-actions.mdx — edit the page, never this file. ctrlrun verify ctrlrun verify --json > verify-report.json python -c "import json; s = json.load(open('verify-report.json'))['summary']; print('applicable', s['applicable'], 'passed', s['passed'], 'not applicable', s['not_applicable'])" diff --git a/examples/policies/devops.yaml b/examples/policies/devops.yaml index d16e7e4..25f2f62 100644 --- a/examples/policies/devops.yaml +++ b/examples/policies/devops.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. schema: ctrlrun.policy/v1 diff --git a/examples/policies/e-commerce.yaml b/examples/policies/e-commerce.yaml index f6e7e9a..d87171b 100644 --- a/examples/policies/e-commerce.yaml +++ b/examples/policies/e-commerce.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. # diff --git a/examples/policies/government.yaml b/examples/policies/government.yaml index 906fc40..fb238e5 100644 --- a/examples/policies/government.yaml +++ b/examples/policies/government.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. # diff --git a/examples/policies/healthcare.yaml b/examples/policies/healthcare.yaml index 512f13e..ede705c 100644 --- a/examples/policies/healthcare.yaml +++ b/examples/policies/healthcare.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. # diff --git a/examples/policies/hr.yaml b/examples/policies/hr.yaml index 54e98c8..221e0dd 100644 --- a/examples/policies/hr.yaml +++ b/examples/policies/hr.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. # diff --git a/examples/policies/insurance.yaml b/examples/policies/insurance.yaml index 6ef7557..ae144d7 100644 --- a/examples/policies/insurance.yaml +++ b/examples/policies/insurance.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. # diff --git a/examples/policies/legal.yaml b/examples/policies/legal.yaml index 0890382..146fd02 100644 --- a/examples/policies/legal.yaml +++ b/examples/policies/legal.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. # diff --git a/examples/policies/payments.yaml b/examples/policies/payments.yaml index 2c475aa..28e19d5 100644 --- a/examples/policies/payments.yaml +++ b/examples/policies/payments.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. # diff --git a/examples/policies/security.yaml b/examples/policies/security.yaml index 3b9556d..d8d5b35 100644 --- a/examples/policies/security.yaml +++ b/examples/policies/security.yaml @@ -9,7 +9,7 @@ # **No `authority:` section, deliberately** (SPEC-v0.3 §1.2). A grant names a real principal # in a real organization, and a template that shipped plausible ones would invite an operator # to adopt them. Add grants yourself, against names your directory actually holds; see -# `docs/docs/authority.md` and `examples/authority/`. +# `https://ctrlrun.dev/docs/authority` and `examples/authority/`. # Unknown actions are denied. There is no default-allow: this file is the list of what an # agent may do, and anything not written here is refused. # diff --git a/integrations/website-form/.gitignore b/integrations/website-form/.gitignore deleted file mode 100644 index 11d5362..0000000 --- a/integrations/website-form/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.vercel/ -.env* -node_modules/ -.vercel diff --git a/integrations/website-form/.vercelignore b/integrations/website-form/.vercelignore deleted file mode 100644 index 9d3d8ba..0000000 --- a/integrations/website-form/.vercelignore +++ /dev/null @@ -1,3 +0,0 @@ -.env* -review.test.mjs -README.md diff --git a/integrations/website-form/README.md b/integrations/website-form/README.md deleted file mode 100644 index 819ef24..0000000 --- a/integrations/website-form/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# CTRLRun review-form endpoint - -A dependency-free Vercel Node.js Function for the Mintlify website. There is no frontend here. - -- Project: `arpanghoshals-projects/ctrlrun-review-form` -- Endpoint: `https://ctrlrun-review-form.vercel.app/api/review` -- Sender: `CTRLRun <reviews@updates.arpanghoshal.com>` -- Recipient: `contact@arpanghoshal.com`, fixed in server code -- Reply-to: the validated work email submitted by the visitor -- Secret: `RESEND_API_KEY`, a sensitive Vercel production environment variable - -The sending domain was verified in Resend during setup. Do not commit API keys, `.env` files, or the Vercel authentication token. The function returns acceptance only after Resend returns a message ID; it does not claim inbox delivery. It sends no automatic email to visitors. - -## Validation and retries - -The handler restricts CORS to the production Mintlify domains and the exact redesign preview origin, validates and bounds every field, rejects a honeypot, caps request size, and fixes the sender and recipient. CORS is a browser boundary, not authentication. The per-instance limit of five requests per ten minutes is a backstop; it does not act as a shared global counter across Vercel instances. - -The browser generates a UUID per reviewed brief. The server uses it as Resend's idempotency key. Retry without changing the brief after an uncertain response; editing a brief creates a new request. No form contents or credentials are logged by the handler. - -```bash -node --test integrations/website-form/review.test.mjs -cd integrations/website-form -vercel link --project ctrlrun-review-form -vercel env add RESEND_API_KEY production --sensitive -vercel deploy --prod -``` - -Unit tests mock Resend and never send mail. The website browser harness also intercepts submission requests. Live validation checks only preflight and invalid requests. diff --git a/integrations/website-form/api/review.mjs b/integrations/website-form/api/review.mjs deleted file mode 100644 index 6254579..0000000 --- a/integrations/website-form/api/review.mjs +++ /dev/null @@ -1,83 +0,0 @@ -import { createHash } from 'node:crypto'; - -const ORIGINS = new Set(['https://ctrlrun.dev', 'https://www.ctrlrun.dev', 'https://ctrlrun-codex-website-redesign.mintlify.site']); -const CONCERNS = new Set(['Wrong actions', 'Duplicate execution', 'Human approval', 'Retry safety', 'Permissions', 'Auditability', 'Other']); -const RECIPIENT = 'contact@arpanghoshal.com'; -// A small per-instance backstop. Edge rate limiting should also protect /api/review. -const requests = new Map(); -const WINDOW_MS = 600_000; -const MAX_REQUESTS = 5; - -export function validate(input) { - if (!input || typeof input !== 'object' || Array.isArray(input)) throw new Error('Invalid request.'); - const field = (name, max, required = true) => { - const value = input[name]; - if (value === undefined && !required) return ''; - if (typeof value !== 'string' || value.length > max || (required && !value.trim()) || /[\x00-\x08\x0b\x0c\x0e-\x1f]/.test(value)) throw new Error('Please check ' + name + '.'); - return value.trim(); - }; - const email = field('email', 254); - if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) || /[\r\n]/.test(email)) throw new Error('Enter a valid work email.'); - const company = field('company', 100); - const purpose = field('purpose', 400); - const actions = field('actions', 400); - const domain = field('domain', 80, false); - const risk = field('risk', 120, false); - const status = field('status', 30); - if (!['Exploring', 'Building', 'Already in production'].includes(status)) throw new Error('Select a production status.'); - if (!Array.isArray(input.concerns) || input.concerns.length > 7 || input.concerns.some(item => !CONCERNS.has(item))) throw new Error('Select valid concerns.'); - const requestId = field('requestId', 36); - if (!/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(requestId)) throw new Error('Please reload the form and try again.'); - return { company, email, purpose, actions, domain, risk, status, concerns: [...new Set(input.concerns)], requestId }; -} - -export function createHandler({ env = process.env, fetcher = fetch, now = Date.now, rateStore = requests } = {}) { - return async function handler(req, res) { - const origin = req.headers.origin; - res.setHeader('Cache-Control', 'no-store'); - res.setHeader('Vary', 'Origin'); - if (!ORIGINS.has(origin)) return res.status(403).json({ error: 'Origin not allowed.' }); - res.setHeader('Access-Control-Allow-Origin', origin); - res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); - if (req.method === 'OPTIONS') return res.status(204).end(); - if (req.method !== 'POST') { res.setHeader('Allow', 'POST, OPTIONS'); return res.status(405).json({ error: 'Method not allowed.' }); } - if (!req.headers['content-type']?.startsWith('application/json')) return res.status(415).json({ error: 'Send JSON.' }); - if (Number(req.headers['content-length']) > 8192) return res.status(413).json({ error: 'Request is too large.' }); - let input; - try { - input = typeof req.body === 'string' ? JSON.parse(req.body) : req.body; - if (JSON.stringify(input || '').length > 8192) return res.status(413).json({ error: 'Request is too large.' }); - } catch { return res.status(400).json({ error: 'Invalid request.' }); } - // Honeypot never triggers an email. Do not report success for a rejected request. - if (input?.website) return res.status(400).json({ error: 'Unable to submit this request.' }); - let data; - try { data = validate(input); } catch (error) { return res.status(400).json({ error: error.message }); } - if (!env.RESEND_API_KEY) return res.status(503).json({ error: 'The review form is temporarily unavailable. Please email contact@arpanghoshal.com.' }); - const ip = req.headers['x-vercel-forwarded-for'] || req.headers['x-forwarded-for']?.split(',')[0] || req.socket?.remoteAddress || 'unknown'; - const rateKey = createHash('sha256').update(String(ip)).digest('hex'); - const time = now(); - for (const [key, entry] of rateStore) if (time - entry.start >= WINDOW_MS) rateStore.delete(key); - const entry = rateStore.get(rateKey) || { start: time, count: 0 }; - if (entry.count >= MAX_REQUESTS || rateStore.size >= 10_000) { res.setHeader('Retry-After', '600'); return res.status(429).json({ error: 'Too many requests. Please try again later or email us directly.' }); } - rateStore.set(rateKey, { start: entry.start, count: entry.count + 1 }); - const text = ['CTRLRun architecture review request', '', 'Company: ' + data.company, 'Reply email: ' + data.email, data.domain && 'Domain: ' + data.domain, 'Agent purpose: ' + data.purpose, 'Actions it can execute: ' + data.actions, 'Production status: ' + data.status, 'Primary concerns: ' + (data.concerns.join(', ') || 'Discuss during review'), data.risk && 'Execution risk check: ' + data.risk].filter(Boolean).join('\n'); - try { - const response = await fetcher('https://api.resend.com/emails', { - method: 'POST', - headers: { Authorization: 'Bearer ' + env.RESEND_API_KEY, 'Content-Type': 'application/json', 'Idempotency-Key': 'architecture-review/' + data.requestId }, - body: JSON.stringify({ from: 'CTRLRun <reviews@updates.arpanghoshal.com>', to: [RECIPIENT], reply_to: data.email, subject: 'CTRLRun architecture review — ' + data.company.replace(/[\r\n]/g, ' '), text }), - signal: AbortSignal.timeout(10_000) - }); - if (!response.ok) return res.status(502).json({ error: 'We could not confirm submission. Retry this request or email contact@arpanghoshal.com.' }); - const sent = await response.json(); - if (typeof sent.id !== 'string') return res.status(502).json({ error: 'We could not confirm submission. Please retry.' }); - return res.status(200).json({ ok: true, id: sent.id }); - } catch { - // Reuse the request ID on client retries: an uncertain response must not cause duplicate mail. - return res.status(502).json({ error: 'We could not confirm submission. Retry this request or email contact@arpanghoshal.com.' }); - } - }; -} - -export default createHandler(); diff --git a/integrations/website-form/package.json b/integrations/website-form/package.json deleted file mode 100644 index 37d2d37..0000000 --- a/integrations/website-form/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "ctrlrun-website-form", - "private": true, - "type": "module", - "engines": { "node": "22.x" }, - "scripts": { "test": "node --test review.test.mjs" } -} diff --git a/integrations/website-form/public/robots.txt b/integrations/website-form/public/robots.txt deleted file mode 100644 index 1f53798..0000000 --- a/integrations/website-form/public/robots.txt +++ /dev/null @@ -1,2 +0,0 @@ -User-agent: * -Disallow: / diff --git a/integrations/website-form/review.test.mjs b/integrations/website-form/review.test.mjs deleted file mode 100644 index e243b79..0000000 --- a/integrations/website-form/review.test.mjs +++ /dev/null @@ -1,61 +0,0 @@ -import test from 'node:test'; -import assert from 'node:assert/strict'; -import { createHandler } from './api/review.mjs'; - -const valid = { email: 'engineer@example.com', company: 'Example', purpose: 'Support agent', actions: 'Refund customer', status: 'Building', concerns: ['Retry safety'], requestId: '11111111-1111-4111-8111-111111111111' }; -const request = (body = valid, headers = {}) => ({ method: 'POST', headers: { origin: 'https://ctrlrun.dev', 'content-type': 'application/json', 'x-vercel-forwarded-for': '192.0.2.1', ...headers }, body }); -const response = () => ({ code: 200, headers: {}, body: null, setHeader(key, value) { this.headers[key] = value; }, status(code) { this.code = code; return this; }, json(body) { this.body = body; return this; }, end() { return this; } }); -const handler = (overrides = {}) => createHandler({ env: { RESEND_API_KEY: 'test-only' }, rateStore: new Map(), fetcher: async () => ({ ok: true, json: async () => ({ id: 'test-email' }) }), ...overrides }); - -test('validated lead is sent only to the fixed recipient with reply-to and idempotency', async () => { - let sent; - const fn = handler({ fetcher: async (url, options) => { sent = { url, ...options }; return { ok: true, json: async () => ({ id: 'test-email' }) }; } }); - const res = response(); await fn(request({ ...valid, to: 'attacker@example.com', from: 'spoof@example.com' }), res); - assert.equal(res.code, 200); assert.equal(res.body.ok, true); - const body = JSON.parse(sent.body); - assert.deepEqual(body.to, ['contact@arpanghoshal.com']); assert.equal(body.reply_to, valid.email); - assert.equal(body.from, 'CTRLRun <reviews@updates.arpanghoshal.com>'); - assert.equal(sent.headers['Idempotency-Key'], 'architecture-review/' + valid.requestId); -}); - -test('untrusted origins and malformed input cannot send mail', async () => { - let calls = 0; - const fn = handler({ fetcher: async () => { calls++; throw new Error('must not send'); } }); - for (const req of [request(valid, { origin: 'https://elsewhere.example' }), request({ ...valid, email: 'a@b.com\r\nBcc: x@y.com' }), request({ ...valid, company: '' }), request({ ...valid, concerns: ['unsupported'] }), request({ ...valid, requestId: 'invalid' }), request({ ...valid, website: 'spam' }), request('{'), request({ ...valid, purpose: 'x'.repeat(401) })]) { - const res = response(); await fn(req, res); assert.ok(res.code >= 400); - } - assert.equal(calls, 0); -}); - -test('preflight allows production and the exact review preview without sending', async () => { - const fn = handler({ fetcher: async () => { throw new Error('Preflight must not send'); } }); - for (const origin of ['https://ctrlrun.dev', 'https://www.ctrlrun.dev', 'https://ctrlrun-codex-website-redesign.mintlify.site', 'https://unrelated.mintlify.site']) { - const res = response(); await fn({ ...request(valid, { origin }), method: 'OPTIONS' }, res); - assert.equal(res.code, origin.includes('unrelated') ? 403 : 204); - assert.equal(res.headers['Access-Control-Allow-Origin'], origin.includes('unrelated') ? undefined : origin); - } -}); - -test('provider failure, timeout and malformed success never become success', async () => { - for (const fetcher of [async () => ({ ok: false }), async () => { throw new Error('timeout'); }, async () => ({ ok: true, json: async () => ({}) })]) { - const res = response(); await handler({ fetcher })(request(), res); assert.equal(res.code, 502); assert.equal(res.body.ok, undefined); assert.ok(!JSON.stringify(res.body).includes('test-only')); - } -}); - -test('missing server secret fails closed', async () => { - const res = response(); await handler({ env: {} })(request(), res); assert.equal(res.code, 503); -}); - -test('per-instance rate backstop rejects a sixth request and expires', async () => { - let time = 1; let calls = 0; - const fn = handler({ now: () => time, fetcher: async () => { calls++; return { ok: true, json: async () => ({ id: 'test-email' }) }; } }); - for (let i = 0; i < 6; i++) { const res = response(); await fn(request(), res); assert.equal(res.code, i < 5 ? 200 : 429); } - assert.equal(calls, 5); time = 600_002; - const res = response(); await fn(request(), res); assert.equal(res.code, 200); -}); - -test('oversized requests and non-JSON are rejected before sending', async () => { - for (const [headers, status] of [[{ 'content-length': '9000' }, 413], [{ 'content-type': 'text/plain' }, 415]]) { - const res = response(); await handler()(request(valid, headers), res); assert.equal(res.code, status); - } -}); diff --git a/integrations/website-form/vercel.json b/integrations/website-form/vercel.json deleted file mode 100644 index 8f4cbe6..0000000 --- a/integrations/website-form/vercel.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "$schema": "https://openapi.vercel.sh/vercel.json", - "framework": null, - "functions": { - "api/review.mjs": { - "maxDuration": 15 - } - }, - "headers": [ - { - "source": "/(.*)", - "headers": [ - { - "key": "Cache-Control", - "value": "no-store" - }, - { - "key": "X-Content-Type-Options", - "value": "nosniff" - } - ] - } - ], - "outputDirectory": "public", - "buildCommand": "", - "installCommand": "" -} diff --git a/pyproject.toml b/pyproject.toml index 0f32401..e8f20ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,10 +79,6 @@ dev = [ # four. A definition-of-done check that skips everywhere it runs is the false green this # repository keeps finding, so the dependency is named rather than assumed. "build>=1", - # The Python API reference under docs/reference/api/ is generated from docstrings by - # tools/docs_audit/render_api.py with griffe (docs/IA.md, decision (b)). A documentation - # build dependency; the kernel never imports it. - "griffe>=1.0", ] # SPEC-v0.2 §1: `pip install ctrlrun` must not grow. Anything needing an HTTP server or a # third-party SDK lands here, lazily imported, with `MissingDependency` when it is absent. @@ -236,9 +232,6 @@ select = ["E", "F", "W", "I", "N", "UP", "B", "ANN", "SIM", "RUF"] "research/soak/*.py" = ["ANN401", "N818", "PLC0415"] "fuzz/*.py" = ["ANN401", "N818", "PLC0415"] "research/soak/**/*.py" = ["ANN401", "N818", "PLC0415"] -# The reference generators carry the pages' own prose as string literals, and a page's line is -# not a code line: the rendered file is what has a width. Everything else about them is linted. -"tools/docs_audit/render_*.py" = ["E501"] # Type hints are a src/ constraint; tests stay cheap to write. N802 lets acceptance # tests carry the SPEC §7 identifier verbatim (test_T7_...). "tests/*" = ["ANN", "N802"] diff --git a/research/soak/README.md b/research/soak/README.md index caefcb7..33726b0 100644 --- a/research/soak/README.md +++ b/research/soak/README.md @@ -95,7 +95,7 @@ the harness is allowed to decide; the clock is reported and left to a human. The throughput figure is a by-product and is not a performance claim. Note in particular what it does **not** measure: most of these actions are denied or refused by policy before any receipt is written, so it says very little about the one-row head that `SPEC-v0.6.md` §6.3 serializes every -receipt write on. `docs/docs/postgres.md` describes that ceiling; this run does not size it. +receipt write on. `https://ctrlrun.dev/docs/postgres` describes that ceiling; this run does not size it. ## What it does not do diff --git a/scripts/repoint-claims.py b/scripts/repoint-claims.py deleted file mode 100755 index 2f1d1ca..0000000 --- a/scripts/repoint-claims.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env python -"""Re-derive every line number in `docs/docs/CLAIMS.md` from the code it cites. - -The table cites `file.py:NNN`, and `test_the_claims_table_line_numbers_point_at_what_they_name` -requires the cited line to be where a named symbol is **defined**. Every commit that shifts a -line in `policy.py`, `state.py`, `control.py` or `receipt.py` breaks some of them, and doing it -by hand is how a row ends up pointing at a docstring that happens to contain the right word -- -which makes the guard green and the claim false. Item 9 regenerates the table wholesale; this is -for the commits in between. - -**It refuses rather than guesses.** A reference it cannot resolve to a `def`, a `class` or an -assignment is reported, the file is left untouched, and the exit code is non-zero. - -Two defects an independent review found in the first version, both of which let it do exactly -what its docstring says it prevents: - -- it accepted any line **containing** a named token -- a comment, a docstring, a string literal -- - and consulted `_definition_of` only when that failed. A row aimed at a line inside a comment - about redaction was reported as fine; -- `IDENTIFIER` harvested `py` from every `` `file.py:NNN` `` reference, so **32 of 40 rows** - carried the bare token `py` and any line containing `copy`, `pyyaml` or `python` satisfied - them. - -Both are fixed here, and the identical regex in `tests/test_packaging.py` is fixed in the same -commit -- otherwise the guard stays fictional while this script is honest. -""" - -from __future__ import annotations - -import re -import sys -from pathlib import Path - -ROOT = Path(__file__).resolve().parents[1] -sys.path.insert(0, str(ROOT / "tools" / "docs_audit")) - -from claims import citations # noqa: E402 — the path above is what makes it importable - - -def main() -> int: - claims = ROOT / "docs" / "docs" / "CLAIMS.md" - rows = claims.read_text(encoding="utf-8").splitlines(keepends=True) - unresolved: list[str] = [] - repointed = 0 - - for index, row in enumerate(rows): - edits: list[tuple[int, int, str]] = [] - for cited in citations(row): - if not cited.names: - unresolved.append(f"{cited.filename}:{cited.line} names no symbol at all") - continue - source = ROOT / "src" / "ctrlrun" / cited.filename - if not source.exists(): - continue - lines = source.read_text(encoding="utf-8").splitlines() - # **This citation's own symbols**, not the row's. A row citing six commands used to - # accept any of the six on the cited line, so five wrong numbers looked right. - owned = cited.local or cited.names - here = lines[cited.line - 1] if 0 < cited.line <= len(lines) else "" - # Two stages. `local` is the tightening -- a row citing six commands no longer - # accepts any of the six on any of the lines. `names` is the documented fallback, - # because the nearest-citation assignment is a heuristic and a row may legitimately - # write `only `NotExecuted` maps to `FAILED` -- `control.py:1036``, where the symbol - # that identifies the line sits between two citations. A line matching neither is - # stale whichever way the symbols were assigned, which is the case worth catching. - if _resolves(owned, here) or _resolves(cited.names, here): - continue - found = _definition_of(owned + cited.names, lines) - if found is None: - unresolved.append(f"{cited.filename}:{cited.line} names {list(owned)}") - else: - edits.append((cited.start, cited.end, f"`{cited.filename}:{found}`")) - if edits: - # **Positional, right to left**, and never `str.replace`. Keying the rewrite on the - # citation's text and replacing every occurrence moved *correct* references too: - # `` `LEASE_EXPIRED` -- `effect.py:63`; ... `resolved_by` -- `effect.py:63` `` needs - # the second moved and the first left alone, and one global replace cannot do that. - for begin, finish, replacement in sorted(edits, reverse=True): - row = row[:begin] + replacement + row[finish:] - rows[index] = row - repointed += len(edits) - - if unresolved: - # **Refuse before writing.** A partial re-point plus a non-zero exit leaves the table in - # a state nobody chose, and the next run reports different rows. - for line in unresolved: - print(f"unresolved: {line}", file=sys.stderr) - print(f"re-pointed 0, unresolved {len(unresolved)} — nothing written", file=sys.stderr) - return 1 - - claims.write_text("".join(rows), encoding="utf-8") - print(f"re-pointed {repointed}, unresolved 0") - return 0 - - -def _patterns(name: str) -> tuple[str, ...]: - return ( - rf"^\s*(?:async )?def {re.escape(name)}\b", - rf"^\s*class {re.escape(name)}\b", - rf"^\s*{re.escape(name)}\s*[:=]", - ) - - -def _resolves(named: tuple[str, ...], line: str) -> bool: - """Does this line define, or at least *contain as a whole word*, one of `named`? - - **A definition would be the strict rule and it is too strict**, which is worth writing down - rather than discovering. Four rows in this table legitimately cite a statement and not a - definition: `effect_key TEXT PRIMARY KEY` inside a DDL string, the branch where only - `NotExecuted` maps to `FAILED`, the `INSERT` that makes `put_delegation` not an upsert. - Requiring a `def` would refuse all four and there is nothing wrong with them. - - So the tightening is **word boundaries**, and that is what closes the hole a review actually - demonstrated: with `py` no longer harvested from every `` `file.py:NNN` `` reference (see - `NOT_SYMBOLS`), a row naming `Decision.ALLOW / APPROVE / DENY` no longer matches a comment - line containing the word "copy", which is how a citation was aimed at a string literal about - redaction and reported as fine. - - **The residual, stated:** a line containing a named symbol as a whole word, in prose, still - satisfies this. That is narrower than "contains the substring" by a long way and is not - nothing; a table that pinned each cited line's text would close it completely and is not - what this is. - """ - if any(re.search(pattern, line) for name in named for pattern in _patterns(name)): - return True - return any(re.search(rf"\b{re.escape(name)}\b", line) for name in named) - - -def _definition_of(named: tuple[str, ...], lines: list[str]) -> int | None: - """Where one of `named` is *defined*, **nearest name first**. Never a mention in prose. - - The order is the caller's, not this function's: `claims.citations` sorts by distance from - the citation. It used to be longest-name-first over the whole row's symbols, which is how - six references to six different commands were all re-pointed at one definition. - """ - for name in named: - for pattern in _patterns(name): - for number, candidate in enumerate(lines, start=1): - if re.search(pattern, candidate): - return number - return None - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/src/ctrlrun/acs.py b/src/ctrlrun/acs.py index b290329..c45c0d2 100644 --- a/src/ctrlrun/acs.py +++ b/src/ctrlrun/acs.py @@ -4,7 +4,7 @@ `GenAI-Security-Project/agent-control-standard` at commit `c7ad162` (2026-08-11): `specification/v0.1.0/request-envelope.json`, `response-envelope.json`, `hooks/tool-call-request.json`, `hooks/tool-call-result.json` and `ask-details.json`. -`docs/docs/ACS.md` records what was read and where the two models disagree. +`https://ctrlrun.dev/docs/ACS` records what was read and where the two models disagree. **ACS is advisory; CTRLRun is executing.** A Guardian returns a decision and the *platform* runs the tool, which is the opposite way round from `@protect`. So one action is split across @@ -59,7 +59,7 @@ ASK: Final = "ask" #: `tool-call-result.json` — the four statuses ACS defines, and nothing about what any of -#: them means for the side effect. See `docs/docs/ACS.md`. +#: them means for the side effect. See `https://ctrlrun.dev/docs/ACS`. SUCCESS: Final = "success" FAILURE: Final = "failure" TIMEOUT: Final = "timeout" diff --git a/tests/conftest.py b/tests/conftest.py index c2f48a0..d45dff3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,8 +1,15 @@ -"""Fixtures shared by tests that must hold for *every* StateStore. +"""Fixtures shared across the suite. `state_store` is parametrized over both shipped implementations. A reservation test written once therefore runs against `InMemoryStateStore` and `SQLiteStateStore`, which is how the double is kept from drifting into refusing less than the real store (SPEC-v0.1 §5.3). + +`no_network` is the other shared double, and it is here for the same reason. "Runs with no +network" is a claim until something takes the network away, and the guard that takes it away +was written twice -- once in `test_examples.py`, once in the documentation tools -- which is +two chances for one copy to refuse less than the other and make one suite's claim quietly +weaker. The documentation tools are a separate repository now; this is the library's one +definition, and both suites that need it take it from here. """ from datetime import UTC, datetime, timedelta @@ -100,3 +107,43 @@ def recording(self, event, _original=original): declared=request.node.get_closest_marker("authority") is not None, nodeid=request.node.nodeid, ) + + +_REFUSE_EVERY_SOCKET = '''\ +"""Imported by `site` at startup: nothing under examples/ may open a socket.""" + +import socket + +_real = socket.socket + + +class _Refusing(_real): + """A socket that exists but will not connect, which is what a cut cable looks like. + + Replacing the *type* with a function breaks anything that subclasses it — `ssl` does — + so the refusal goes on the operations instead. + """ + + def connect(self, *args, **kwargs): + raise RuntimeError("an example tried to connect; examples must run with no network") + + def connect_ex(self, *args, **kwargs): + raise RuntimeError("an example tried to connect; examples must run with no network") + + +def _refuse(*args, **kwargs): + raise RuntimeError("an example tried to resolve a name; examples run with no network") + + +socket.socket = _Refusing +socket.create_connection = _refuse +socket.getaddrinfo = _refuse +''' + + +@pytest.fixture(scope="session") +def no_network(tmp_path_factory): + """A `PYTHONPATH` entry whose `sitecustomize` refuses every socket (SPEC-v0.2 §1.1).""" + directory = tmp_path_factory.mktemp("no-network") + (directory / "sitecustomize.py").write_text(_REFUSE_EVERY_SOCKET, encoding="utf-8") + return directory diff --git a/tests/test_claims_citations.py b/tests/test_claims_citations.py deleted file mode 100644 index 7c2a562..0000000 --- a/tests/test_claims_citations.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Which symbol a claims citation is about, and the false green that came of guessing. - -`scripts/repoint-claims.py` writes the line numbers and -`test_the_claims_table_line_numbers_point_at_what_they_name` checks them. They answered "which -symbol is this citation about" separately, and both answered it the same wrong way: with the -symbols of the whole **row**. - -So a row citing six commands had every reference re-pointed to one definition -- whichever the -repointer found first -- and the guard accepted all six, because that line does define a symbol -the row names. A row claiming to cite six commands cited one, six times, and nothing said so. -It was caught by reading the diff, which is not a check. -""" - -from __future__ import annotations - -import sys -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parents[1] -TOOLS = REPO_ROOT / "tools" / "docs_audit" - -if not TOOLS.exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout", allow_module_level=True) - -sys.path.insert(0, str(TOOLS)) - -import claims # noqa: E402 - -SIX = ( - '| "the commands work from the shell" | `approve` — `cli/main.py:295`; ' - "`receipts` — `cli/main.py:357`; `effects` — `cli/main.py:431`; " - "`resolve` — `cli/main.py:449`; `inspect` — `cli/main.py:483`; " - "`stats` — `cli/main.py:658` | `test_T10_resolve_failed_permits_a_retry` |" -) - - -def test_each_citation_owns_the_symbol_beside_it(): - """The regression, stated as the property it broke.""" - found = claims.citations(SIX) - - assert [c.line for c in found] == [295, 357, 431, 449, 483, 658] - # The nearest symbol, which is the one the citation is about. The last citation also owns - # the row's test column, because that column is nearest to it and there is nothing after - # it -- harmless, and stated rather than asserted away. - assert [c.local[0] for c in found] == [ - "approve", - "receipts", - "effects", - "resolve", - "inspect", - "stats", - ] - # And the property that broke: no citation owns a *different* command in the same row. - ordered = ["approve", "receipts", "effects", "resolve", "inspect", "stats"] - commands = set(ordered) - for cited, mine in zip(found, ordered, strict=True): - assert commands & set(cited.local) == {mine}, (cited.line, cited.local) - - -def test_a_symbol_between_two_citations_goes_to_the_nearer(): - """`` `stats` -- `cli/main.py:658` `` is about `stats`, not about the citation before it. - - Splitting the row at the *next* citation's start gave every symbol to the reference it - followed, which is the one it is not about. - """ - row = "| x | `approve` — `cli/main.py:295`; `stats` — `cli/main.py:658` |" - - assert [c.local for c in claims.citations(row)] == [("approve",), ("stats",)] - - -def test_a_multi_word_span_contributes_every_identifier_in_it(): - """`` `ctrlrun delegate` `` names `delegate`, and a tokenizer that took only the first - identifier in a span left the citation owning `ctrlrun` and looking stale.""" - row = "| x | `ctrlrun delegate` — `cli/main.py:822` |" - - assert "delegate" in claims.citations(row)[0].local - - -def test_a_citations_own_path_is_not_harvested_as_a_symbol(): - """`cli` out of `` `cli/main.py:295` `` would sort nearest to every citation in the row. - - `NOT_SYMBOLS` catches the extension; nothing caught the directory. - """ - for cited in claims.citations(SIX): - assert "cli" not in cited.names - assert "main" not in cited.names - - -def test_the_positions_let_two_citations_of_one_line_move_apart(): - """`` `LEASE_EXPIRED` -- `effect.py:63`; ... `resolved_by` -- `effect.py:63` `` needs the - second re-pointed and the first left alone. - - The repointer keyed its rewrite on the citation's *text* and called `str.replace`, which - moved both -- so fixing a stale reference broke a correct one in the same row. The spans - are what make the rewrite positional. - """ - row = "| x | `LEASE_EXPIRED` — `effect.py:63`; `resolved_by` — `effect.py:63` |" - first, second = claims.citations(row) - - assert first.line == second.line == 63 - assert first.start != second.start - assert row[first.start : first.end] == "`effect.py:63`" - assert row[second.start : second.end] == "`effect.py:63`" - assert first.local == ("LEASE_EXPIRED",) - assert second.local == ("resolved_by",) diff --git a/tests/test_cookbook.py b/tests/test_cookbook.py index c03a5f2..c720f7e 100644 --- a/tests/test_cookbook.py +++ b/tests/test_cookbook.py @@ -1,11 +1,16 @@ -"""The cookbook: every recipe runs, twice, offline, and its directory is what its page shows. - -A recipe page is the single source; `tools/docs_audit/render_cookbook.py` extracts the policy -and the script into `examples/cookbook/<name>/`. Here each directory is run in a subprocess -whose `sitecustomize` refuses every socket, twice in the same working directory so a second -run must refuse the same things rather than trip over a stale record, and the exit status must -be 0 — every recipe carries an `else: raise SystemExit` on the path where a refusal did not -happen, so a recipe that quietly starts succeeding fails here. +"""The cookbook: every recipe runs, twice, offline, and refuses something. + +A recipe page is the single source, and it lives in CTRLRun/ctrlrun-docs, where +`tools/docs_audit/render_cookbook.py` extracts the policy and the script into this +repository's `examples/cookbook/<name>/`. **That the directory is what its page shows is +checked there**, beside the page it is checked against; what is checked here is the half that +needs no page at all. + +Each directory is run in a subprocess whose `sitecustomize` refuses every socket, twice in the +same working directory so a second run must refuse the same things rather than trip over a +stale record, and the exit status must be 0 — every recipe carries an `else: raise SystemExit` +on the path where a refusal did not happen, so a recipe that quietly starts succeeding fails +here. """ from __future__ import annotations @@ -18,18 +23,11 @@ import pytest REPO_ROOT = Path(__file__).resolve().parents[1] -TOOLS = REPO_ROOT / "tools" / "docs_audit" COOKBOOK = REPO_ROOT / "examples" / "cookbook" -PAGES = REPO_ROOT / "docs" / "docs" / "cookbook" -if not (TOOLS.exists() and PAGES.exists()): # pragma: no cover - not a checkout +if not COOKBOOK.exists(): # pragma: no cover - not a checkout pytest.skip("no repository checkout", allow_module_level=True) -sys.path.insert(0, str(TOOLS)) - -import render_cookbook # noqa: E402 -from snippets import NO_NETWORK # noqa: E402 - RECIPES = sorted(p.name for p in COOKBOOK.iterdir() if p.is_dir() and p.name != "__pycache__") REQUIRED_SECTIONS = ( "## The policy", @@ -40,13 +38,6 @@ ) -@pytest.fixture(scope="session") -def no_network(tmp_path_factory): - directory = tmp_path_factory.mktemp("no-network") - (directory / "sitecustomize.py").write_text(NO_NETWORK, encoding="utf-8") - return directory - - def _run(recipe: str, no_network: Path) -> subprocess.CompletedProcess[str]: environment = dict(os.environ) environment["PYTHONPATH"] = os.pathsep.join( @@ -74,21 +65,6 @@ def _run(recipe: str, no_network: Path) -> subprocess.CompletedProcess[str]: ) -def test_every_recipe_directory_is_what_its_page_shows(): - assert render_cookbook.check(render_cookbook.recipes()) == [] - - -def test_a_hand_edit_to_an_extracted_file_is_drift(tmp_path, monkeypatch): - monkeypatch.setattr(render_cookbook, "EXAMPLES", tmp_path) - extracted = render_cookbook.recipes() - render_cookbook.write(extracted) - first = next(iter(extracted)) - target = tmp_path / first / "main.py" - target.write_text(target.read_text() + "\n# edited by hand\n") - - assert any(first in item for item in render_cookbook.check(extracted)) - - @pytest.mark.parametrize("recipe", RECIPES) def test_every_recipe_runs_offline_and_is_repeatable(recipe, no_network): first = _run(recipe, no_network) @@ -113,13 +89,6 @@ def test_every_recipe_refuses_something_and_says_so(recipe, no_network): assert any(word in output for word in refusals), output -@pytest.mark.parametrize("page", sorted(p.stem for p in PAGES.glob("*.mdx") if p.stem != "index")) -def test_every_recipe_page_has_the_five_sections(page): - text = (PAGES / f"{page}.mdx").read_text(encoding="utf-8") - for section in REQUIRED_SECTIONS: - assert section in text, f"{page}: missing {section!r}" - - def test_the_cookbook_directories_are_tracked_by_git(): listed = subprocess.run( ["git", "ls-files", "examples/cookbook"], diff --git a/tests/test_docs_audit.py b/tests/test_docs_audit.py deleted file mode 100644 index 4c3cbd5..0000000 --- a/tests/test_docs_audit.py +++ /dev/null @@ -1,597 +0,0 @@ -"""The documentation audit under `tools/docs_audit/`, and the capabilities generator. - -Three checks and one generator, each with a control: a check whose only evidence is a green -run is a check nothing exercises, so every guard here is shown catching the thing it exists -to catch before it is trusted to pass. -""" - -from __future__ import annotations - -import subprocess -import sys -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parents[1] -TOOLS = REPO_ROOT / "tools" / "docs_audit" - -if not TOOLS.exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout", allow_module_level=True) - -sys.path.insert(0, str(TOOLS)) - -#: `MANIFEST.in` prunes `.github` and `adapters` from the sdist, so from inside one the README's -#: links into `adapters/` cannot resolve and there is no workflow to read. The same signal the -#: packaging tests use: a checkout has `adapters/`; a distribution does not. -IN_CHECKOUT = (REPO_ROOT / "adapters").is_dir() and (REPO_ROOT / ".github").is_dir() -checkout_only = pytest.mark.skipif( - not IN_CHECKOUT, reason="not a repository checkout: the sdist prunes .github and adapters" -) - -import links # noqa: E402 -import lint # noqa: E402 -import render_capabilities as capabilities # noqa: E402 -import snippets # noqa: E402 -from _files import fences, outside_fences # noqa: E402 - -# --- the fence parser --------------------------------------------------------------------- - - -def test_fences_carry_their_language_tokens_and_line_numbers(tmp_path): - text = ( - "intro\n\n```python runnable continue\nx = 1\n```\n\n" - "````yaml runnable file=a.yaml\na: 1\n````\n" - ) - found = list(fences(text, tmp_path / "page.md")) - - assert [(f.line, f.language, f.tokens) for f in found] == [ - (3, "python", ("runnable", "continue")), - (7, "yaml", ("runnable", "file=a.yaml")), - ] - assert found[0].body == "x = 1\n" - - -def test_a_shorter_fence_inside_a_longer_one_does_not_close_it(tmp_path): - text = "````markdown\n```python\nx\n```\n````\n" - found = list(fences(text, tmp_path / "page.md")) - - assert len(found) == 1 - assert found[0].body == "```python\nx\n```\n" - - -def test_outside_fences_skips_code(): - text = "# Heading\n```\n# not a heading\n```\ntail\n" - - assert list(outside_fences(text)) == [(1, "# Heading"), (5, "tail")] - - -# --- the runnable-snippet harness --------------------------------------------------------- - - -def _page(tmp_path: Path, body: str) -> Path: - page = tmp_path / "page.md" - page.write_text(body, encoding="utf-8") - return page - - -def test_a_passing_python_block_passes(tmp_path): - outcome = snippets.run_document(_page(tmp_path, "```python runnable\nprint('ok')\n```\n")) - - assert outcome.ran == 1 - assert outcome.ok - - -def test_a_failing_python_block_is_reported_with_its_line(tmp_path): - outcome = snippets.run_document( - _page(tmp_path, "text\n\n```python runnable\nraise SystemExit('boom')\n```\n") - ) - - assert not outcome.ok - assert outcome.failures[0].location.endswith("page.md:3") - assert "boom" in outcome.failures[0].message - - -def test_an_unmarked_block_is_not_run(tmp_path): - outcome = snippets.run_document(_page(tmp_path, "```python\nraise SystemExit(1)\n```\n")) - - assert outcome.ran == 0 - - -def test_a_block_that_reaches_for_the_network_fails(tmp_path): - """The socket guard is the whole reason the harness runs offline, so it is shown biting.""" - outcome = snippets.run_document( - _page( - tmp_path, - "```python runnable\nimport socket\nsocket.getaddrinfo('example.invalid', 80)\n```\n", - ) - ) - - assert not outcome.ok - assert "offline" in outcome.failures[0].message - - -def test_the_network_guard_is_what_made_it_fail(tmp_path): - """The control for the test above: the same block passes with the guard removed.""" - guard = tmp_path / "no-guard" - guard.mkdir() - outcome = snippets.run_document( - _page( - tmp_path, - "```python runnable\nimport socket\nassert callable(socket.getaddrinfo)\n" - "assert socket.getaddrinfo.__module__ != 'sitecustomize'\n```\n", - ), - guard=guard, - ) - - assert outcome.ok, outcome.failures - - -def test_continue_appends_to_the_previous_python_blocks(tmp_path): - outcome = snippets.run_document( - _page( - tmp_path, - "```python runnable\ndef f():\n return 1\n```\n" - "```python runnable continue\nassert f() == 1\n```\n", - ) - ) - - assert outcome.ok, outcome.failures - - -def test_a_bash_block_runs_with_the_checkouts_cli_on_path(tmp_path): - outcome = snippets.run_document( - _page(tmp_path, "```bash runnable\nctrlrun --version\ntest ! -e /nonexistent\n```\n") - ) - - assert outcome.ok, outcome.failures - - -def test_a_failing_bash_block_fails(tmp_path): - outcome = snippets.run_document(_page(tmp_path, "```bash runnable\nfalse\n```\n")) - - assert not outcome.ok - - -def test_a_yaml_block_is_loaded_by_the_real_policy_loader(tmp_path): - outcome = snippets.run_document( - _page( - tmp_path, - "```yaml runnable\nschema: ctrlrun.policy/v1\nactions:\n a.b:\n" - " decision: nope\n```\n", - ) - ) - - assert not outcome.ok - assert "PolicyError" in outcome.failures[0].message - - -def test_a_yaml_policy_is_written_for_later_blocks_to_read(tmp_path): - outcome = snippets.run_document( - _page( - tmp_path, - "```yaml runnable\nschema: ctrlrun.policy/v1\nactions:\n a.b:\n" - " decision: allow\n```\n" - "```python runnable\nfrom ctrlrun import Policy\n" - "assert 'a.b' in Policy.from_file('ctrlrun.yaml').actions\n```\n", - ) - ) - - assert outcome.ok, outcome.failures - - -def test_a_yaml_authority_document_is_loaded_by_the_real_authority_loader(tmp_path): - outcome = snippets.run_document( - _page( - tmp_path, - "```yaml runnable\nschema: ctrlrun.policy/v3\nauthority:\n grants:\n" - " - id: x\n subject: { agent: a }\n actions: ['a.b']\n" - " delegable: true\n```\n", - ) - ) - - # `delegable: true` without `expires_at` is refused by the authority loader (SPEC-v0.3). - assert not outcome.ok - assert "expires_at" in outcome.failures[0].message - - -def test_the_readme_and_docs_snippets_run(tmp_path): - """The harness against the real documents. Zero runnable blocks today; that is the - baseline the writing sessions clear by marking blocks as they make them run.""" - outcome = snippets.run_documents(snippets.documents()) - - assert outcome.ok, [str(failure) for failure in outcome.failures] - - -# --- the forbidden-words lint ------------------------------------------------------------- - - -def _empty() -> lint.Allowlist: - return lint.Allowlist((), ()) - - -def test_a_positioning_word_in_a_heading_is_flagged(): - found = lint.lint_text("# Runtime governance for agents\n", "x.md", _empty()) - - assert {f.rule.id for f in found} == {"governance"} - - -def test_a_positioning_word_in_a_body_sentence_is_not(): - found = lint.lint_text("It is not a governance toolkit.\n", "x.md", _empty()) - - assert found == [] - - -def test_a_positioning_word_in_frontmatter_title_or_description_is_flagged(): - text = '---\ntitle: "Guardrails"\ndescription: A secure layer\n---\n\nbody secure\n' - found = lint.lint_text(text, "x.mdx", _empty()) - - assert [(f.line, f.rule.id) for f in found] == [(2, "guardrails"), (3, "secure")] - - -def test_a_claim_word_anywhere_is_flagged(): - text = "The finance sector pack is HIPAA ready.\n" - found = lint.lint_text(text, "x.md", _empty()) - - assert {f.rule.id for f in found} == {"sector", "pack", "hipaa"} - - -def test_the_planned_only_scope_still_works(monkeypatch): - """A page carrying the PLANNED label may name a thing that does not exist; any other page - naming it is describing something that is not there. - - The rule this used to test was `operator-mcp-server`, and it went when - `ctrlrun mcp-operator` shipped. Asserting the scope against a *removed* rule would have - left a test that passes because nothing matches — so the rule is defined here, and the - test is of the machinery the next planned thing will use. - """ - rule = lint._rule("not-yet", r"\bflux capacitor\b", "planned-only", "does not exist") - monkeypatch.setattr(lint, "RULES", (*lint.RULES, rule)) - named = "Use the flux capacitor to approve.\n" - - # The *same sentence* either side of the label, because the first version of this test - # wrote "a flux capacitor" under the label and "the flux capacitor" above it against a - # pattern that required "the". The second assertion could not fire whatever the scope did, - # and a mutation of the scope check left it green. - assert lint.lint_text(named, "x.mdx", _empty()) != [] - assert lint.lint_text("PLANNED: not yet.\n" + named, "x.mdx", _empty()) == [] - - -def test_no_rule_claims_a_thing_is_planned_that_has_shipped(): - """`RULES` carries no `planned-only` rule today, and this is the assertion that says the - absence is deliberate. Adding one is how a document describes something before it exists; - leaving a stale one is how a shipped feature becomes unmentionable.""" - planned = [rule.id for rule in lint.RULES if rule.scope == "planned-only"] - assert planned == [], planned - - -def test_a_word_inside_a_code_fence_is_not_linted(): - text = "```yaml\n# sector: finance\n```\n" - - assert lint.lint_text(text, "x.md", _empty()) == [] - - -def test_package_is_not_pack(): - assert lint.lint_text("pip installs the package.\n", "x.md", _empty()) == [] - - -def test_the_allowlist_permits_a_matching_line_in_a_matching_file(): - allowlist = lint.Allowlist((), (("docs/*.md", lint.re.compile("not a compliance claim")),)) - - assert lint.lint_text("This is not a compliance claim.\n", "docs/x.md", allowlist) == [] - assert lint.lint_text("This is not a compliance claim.\n", "README.md", allowlist) != [] - assert lint.lint_text("A compliance product.\n", "docs/x.md", allowlist) != [] - - -def test_the_allowlist_file_parses_and_names_only_known_keywords(tmp_path): - loaded = lint.load_allowlist() - assert loaded.allowed or loaded.excluded - - bad = tmp_path / "allow.txt" - bad.write_text("permit * foo\n", encoding="utf-8") - with pytest.raises(ValueError): - lint.load_allowlist(bad) - - -def test_the_two_documents_the_rule_exempts_are_skipped(tmp_path): - """The OWASP mapping and threat-model pages list what is *not* covered, so - they are allowed to name what they do not cover.""" - for name in lint.EXEMPT_BY_RULE: - path = REPO_ROOT / name - assert path.exists(), name - assert lint.lint_paths([REPO_ROOT / name for name in lint.EXEMPT_BY_RULE]) == [] - - -def test_the_lint_runs_against_the_real_documents(): - """The baseline: the findings that remain after the allowlist. Recorded in the PR that - added this file; the writing sessions clear them and this assertion then tightens to - `== []`.""" - findings = lint.lint_paths(lint.documents()) - - assert isinstance(findings, list) - - -# --- the link check ----------------------------------------------------------------------- - - -def test_slugs_follow_githubs_rule(): - assert links.slug("What the badge means") == "what-the-badge-means" - assert links.slug("`ctrlrun verify`") == "ctrlrun-verify" - assert links.slug("Not applicable is *not* a pass") == "not-applicable-is-not-a-pass" - assert links.slug("Two ways in (and a third)") == "two-ways-in-and-a-third" - - -def test_a_relative_link_to_a_missing_file_is_broken(tmp_path): - page = tmp_path / "a.md" - page.write_text("[x](b.md)\n", encoding="utf-8") - - broken = links.check_text(page.read_text(), page) - - assert len(broken) == 1 and "does not exist" in broken[0].reason - - -def test_a_relative_link_and_anchor_that_exist_pass(tmp_path): - (tmp_path / "b.md").write_text("## The `effect` key\n", encoding="utf-8") - page = tmp_path / "a.md" - page.write_text("[x](b.md#the-effect-key) [y](#own)\n\n## Own\n", encoding="utf-8") - - assert links.check_text(page.read_text(), page) == [] - - -def test_a_missing_anchor_is_broken(tmp_path): - (tmp_path / "b.md").write_text("## Real\n", encoding="utf-8") - page = tmp_path / "a.md" - page.write_text("[x](b.md#imaginary)\n", encoding="utf-8") - - broken = links.check_text(page.read_text(), page) - - assert len(broken) == 1 and "#imaginary" in broken[0].reason - - -def test_a_duplicate_heading_gets_a_numbered_anchor(tmp_path): - page = tmp_path / "a.md" - page.write_text("[x](#next-1)\n## Next\n## Next\n", encoding="utf-8") - - assert links.check_text(page.read_text(), page) == [] - - -def test_a_github_blob_url_into_this_repository_is_an_internal_link(tmp_path): - page = tmp_path / "a.md" - page.write_text( - "[ok](https://github.com/CTRLRun/ctrlrun/blob/main/docs/docs/verify.md#what-the-badge-means)\n" - "[bad](https://github.com/CTRLRun/ctrlrun/blob/main/docs/nope.md)\n" - "[external](https://example.com/anything)\n", - encoding="utf-8", - ) - - broken = links.check_text(page.read_text(), page) - - assert [b.target for b in broken] == [ - "https://github.com/CTRLRun/ctrlrun/blob/main/docs/nope.md" - ] - - -def test_a_root_relative_docs_path_resolves_under_docs(tmp_path, monkeypatch): - monkeypatch.setattr(links, "REPO_ROOT", tmp_path) - (tmp_path / "docs" / "docs" / "concepts").mkdir(parents=True) - (tmp_path / "docs" / "docs" / "concepts" / "effect-keys.mdx").write_text("# Effect keys\n") - page = tmp_path / "docs" / "index.mdx" - page.write_text('<Card href="/docs/concepts/effect-keys" /> [x](/concepts/missing)\n') - - broken = links.check_text(page.read_text(), page) - - assert [b.target for b in broken] == ["/concepts/missing"] - - -def test_a_query_string_is_not_part_of_the_page_path(tmp_path, monkeypatch): - """`/try?situation=uncertain` is the `/try` page. The checker looked for a file named after - the whole string and called a working link broken -- and the strip must not swallow a - genuinely missing page that happens to carry a query.""" - monkeypatch.setattr(links, "REPO_ROOT", tmp_path) - (tmp_path / "docs").mkdir() - (tmp_path / "docs" / "try.mdx").write_text("---\ntitle: Try\n---\n") - page = tmp_path / "docs" / "index.mdx" - page.write_text("[a](/try?situation=uncertain) [b](/nope?situation=uncertain)\n") - - broken = links.check_text(page.read_text(), page) - - assert [b.target for b in broken] == ["/nope?situation=uncertain"] - - -@checkout_only -def test_a_link_to_a_page_the_ia_plans_is_planned_not_broken(tmp_path, monkeypatch): - monkeypatch.setattr(links, "REPO_ROOT", tmp_path) - monkeypatch.setattr(links, "_IA", tmp_path / "docs" / "IA.md") - (tmp_path / "docs").mkdir() - (tmp_path / "docs" / "IA.md").write_text( - "Guides\n ├─ Protect a function docs/guides/protect-a-function\n" - ) - page = tmp_path / "docs" / "index.mdx" - page.write_text("[a](/docs/guides/protect-a-function) [b](/guides/never-planned)\n") - links.PLANNED.clear() - - broken = links.check_text(page.read_text(), page) - - assert [b.target for b in broken] == ["/guides/never-planned"] - assert [b.target for b in links.PLANNED] == ["/docs/guides/protect-a-function"] - - -@checkout_only -def test_the_real_documents_have_no_broken_internal_links(): - assert links.check_paths(links.documents_to_check()) == [] - - -def test_a_generated_fragment_is_not_checked_on_its_own_but_a_page_is(): - """The grid under `docs/generated/` links to pages later sessions write; it is checked - where it is embedded. The exclusion is narrow: a page under `docs/` is still checked.""" - checked = {links.relative(path) for path in links.documents_to_check()} - - assert not any(name.startswith("docs/generated/") for name in checked) - assert "README.md" in checked - assert any(name.startswith("docs/") for name in checked) - - -# --- the capabilities generator ----------------------------------------------------------- - - -def test_capabilities_yaml_loads_with_exactly_six_guarantees(): - loaded = capabilities.load() - - assert len([c for c in loaded if c.guarantee]) == 6 - assert len({c.id for c in loaded}) == len(loaded) - - -def test_every_description_is_at_most_fifteen_words(): - for entry in capabilities.load(): - assert len(entry.description.split()) <= 15, entry.id - - -def test_every_page_a_capability_names_is_in_the_information_architecture(): - ia = (REPO_ROOT / "docs" / "IA.md").read_text(encoding="utf-8") - for entry in capabilities.load(): - assert f"`{entry.page}`" in ia or f" {entry.page}\n" in ia, entry.page - - -def test_every_claim_a_capability_names_is_a_row_in_claims_md(): - claims = (REPO_ROOT / "docs" / "docs" / "CLAIMS.md").read_text(encoding="utf-8") - for entry in capabilities.load(): - if entry.claim is None: - assert entry.claim_note, entry.id - continue - assert f'"{entry.claim}"' in claims, f"{entry.id}: {entry.claim!r} is not a CLAIMS.md row" - - -def test_the_generated_copies_match_the_generator(): - """The drift test. Every rendered copy — the three files under `docs/generated/` and every - marker block in the README or a docs page — is the generator's output for that format.""" - drift = capabilities.check(capabilities.load()) - - assert drift == [], [str(d) for d in drift] - - -def test_a_hand_edit_to_a_generated_file_is_drift(tmp_path): - loaded = capabilities.load() - capabilities.write(loaded, tmp_path) - target = tmp_path / capabilities.FILENAMES["readme"] - target.write_text(target.read_text().replace("| yes |", "| YES |", 1), encoding="utf-8") - - drift = capabilities.check(loaded, directory=tmp_path, pages=[]) - - assert [d.path for d in drift] == [capabilities.relative(target)] - - -def test_a_marker_block_in_a_page_is_compared_with_the_render(tmp_path): - loaded = capabilities.load() - capabilities.write(loaded, tmp_path) - fresh = tmp_path / "fresh.md" - fresh.write_text("intro\n\n" + capabilities.render("readme", loaded) + "\nafter\n") - stale = tmp_path / "stale.md" - stale.write_text( - "intro\n\n" + capabilities.render("readme", loaded).replace("Fail closed", "Fails open") - ) - unclosed = tmp_path / "unclosed.md" - unclosed.write_text(capabilities.render("mdx", loaded).replace("{/* end generated */}", "")) - - drift = capabilities.check(loaded, directory=tmp_path, pages=[fresh, stale, unclosed]) - - assert sorted(d.path.rsplit("/", 1)[-1] for d in drift) == ["stale.md", "unclosed.md"] - - -def test_every_render_carries_the_generated_comment_and_the_close_marker(): - loaded = capabilities.load() - for fmt in capabilities.FORMATS: - text = capabilities.render(fmt, loaded) - assert f"generated from docs/capabilities.yaml ({fmt})" in text.splitlines()[0] - assert "end generated" in text.splitlines()[-1] - - -def test_the_readme_render_has_the_six_guarantees_and_the_three_ways_in(): - text = capabilities.render("readme", capabilities.load()) - rows = [line for line in text.splitlines() if line.startswith("| **")] - - assert len(rows) == 6 - assert "| Guarantee | `@protect` | Gateway | Adapter |" in text - - -def test_the_generator_refuses_a_malformed_entry(tmp_path): - bad = tmp_path / "capabilities.yaml" - bad.write_text( - "capabilities:\n - id: X\n name: n\n description: d\n guarantee: true\n" - " ways_in: {decorator: true, gateway: true, adapter: true}\n since: v0.1\n" - " page: p\n claim: c\n", - encoding="utf-8", - ) - with pytest.raises(capabilities.CapabilitiesError, match="kebab-case"): - capabilities.load(bad) - - -def test_the_generator_refuses_a_long_description(tmp_path): - bad = tmp_path / "capabilities.yaml" - bad.write_text( - "capabilities:\n - id: x\n name: n\n description: " - + " ".join(["word"] * 16) - + "\n guarantee: true\n" - " ways_in: {decorator: true, gateway: true, adapter: true}\n since: v0.1\n" - " page: p\n claim: c\n", - encoding="utf-8", - ) - with pytest.raises(capabilities.CapabilitiesError, match="16 words"): - capabilities.load(bad) - - -def test_the_generator_refuses_a_count_of_guarantees_other_than_six(tmp_path): - """The README matrix has six rows and the generator is where that is enforced, so a file - with five is refused rather than rendered five rows long.""" - entry = ( - " - id: g{n}\n name: n\n description: d\n guarantee: true\n" - " ways_in: {{decorator: true, gateway: true, adapter: true}}\n since: v0.1\n" - " page: p\n claim: c\n" - ) - bad = tmp_path / "capabilities.yaml" - bad.write_text("capabilities:\n" + "".join(entry.format(n=n) for n in range(5))) - with pytest.raises(capabilities.CapabilitiesError, match="exactly six"): - capabilities.load(bad) - - -def test_the_generator_refuses_a_null_claim_without_a_note(tmp_path): - bad = tmp_path / "capabilities.yaml" - bad.write_text( - "capabilities:\n - id: x\n name: n\n description: d\n guarantee: true\n" - " ways_in: {decorator: true, gateway: true, adapter: true}\n since: v0.1\n" - " page: p\n claim: null\n", - encoding="utf-8", - ) - with pytest.raises(capabilities.CapabilitiesError, match="claim_note"): - capabilities.load(bad) - - -# --- CI runs all four --------------------------------------------------------------------- - - -@checkout_only -def test_ci_runs_the_three_checks_and_the_drift_check(): - """`docs/STYLE.md` says the `docs` job runs them. A guard that CI does not run is prose.""" - workflow = (REPO_ROOT / ".github" / "workflows" / "ci.yml").read_text(encoding="utf-8") - - for script in ("snippets.py", "lint.py", "links.py", "render_capabilities.py --check"): - assert f"python tools/docs_audit/{script}" in workflow, script - - -@checkout_only -def test_the_scripts_run_as_scripts(): - """Each tool is documented as `python tools/docs_audit/<x>.py`; imported-from-tests is not - the same thing, so each is started the way a person starts it.""" - for script, arguments in ( - ("render_capabilities.py", ["--check"]), - ("links.py", ["README.md"]), - ("snippets.py", ["--list", "README.md"]), - ("lint.py", ["docs/STYLE.md"]), - ): - completed = subprocess.run( - [sys.executable, str(TOOLS / script), *arguments], - cwd=REPO_ROOT, - capture_output=True, - text=True, - check=False, - ) - assert completed.returncode == 0, f"{script}: {completed.stdout}{completed.stderr}" diff --git a/tests/test_docs_medical_demo.py b/tests/test_docs_medical_demo.py deleted file mode 100644 index 3815bfd..0000000 --- a/tests/test_docs_medical_demo.py +++ /dev/null @@ -1,214 +0,0 @@ -"""The medical affairs demo page, held to the module it claims to run. - -The page tells a reader to press four buttons and promises what each one does. The promise is -cheap to write and expensive to get wrong, so the module the browser runs is run here too -- -natively, with no Node and no network -- through that exact sequence. A page describing a -refusal nobody reproduced is the false green this repository keeps finding. -""" - -from __future__ import annotations - -import json -import re -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parents[1] -DOCS = REPO_ROOT / "docs" - -if not ( - DOCS / "docs" / "demos" / "medical-affairs.mdx" -).exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout", allow_module_level=True) - -PAGE = (DOCS / "docs" / "demos" / "medical-affairs.mdx").read_text(encoding="utf-8") -SCRIPT = (DOCS / "medical-demo.js").read_text(encoding="utf-8") - - -def _array(name: str) -> str: - """The JSON array of Python lines the script embeds, joined the way the script joins it.""" - body = SCRIPT.split(f"var {name} = [", 1)[1].split("].join", 1)[0] - return "\n".join(json.loads("[" + body + "]")) - - -MODULE = _array("MODULE") - - -@pytest.fixture -def harness(): - """The module, executed the way Pyodide executes it, with `step` exposed.""" - namespace: dict[str, object] = {} - exec(compile(MODULE, "<medical-demo>", "exec"), namespace) - step = namespace["step"] - - def call(op: str, **request: object) -> dict: - return json.loads(step(json.dumps({"op": op, **request}))) - - return call - - -# --- the module ---------------------------------------------------------------------------- - - -def test_the_module_is_valid_python_and_defines_step(): - namespace: dict[str, object] = {} - exec(compile(MODULE, "<medical-demo>", "exec"), namespace) - assert callable(namespace["step"]) - - -def test_the_module_runs_the_sequence_the_page_tells_the_reader_to_press(harness): - """Draft, send, approve, let a newer study land, send again. The last one is the page.""" - drafted = harness("draft") - assert drafted["outcome"] == "executed" - assert drafted["revision"] == "A" - - pending = harness("send") - assert pending["outcome"] == "approval_required" - assert pending["action_hash"].startswith("sha256:") - - approved = harness("approve", request_id=pending["request_id"]) - assert approved["outcome"] == "approved" - assert approved["action_hash"] == pending["action_hash"], "the reviewer signed another action" - - refreshed = harness("refresh") - assert refreshed["outcome"] == "refreshed" - assert refreshed["revision"] == "B" - assert refreshed["recommendation"] != drafted["recommendation"], "the letter did not change" - - refused = harness("send", approval_id=approved["approval_id"]) - assert refused["outcome"] == "approval_mismatch" - assert refused["reason"] == "mismatch" - assert refused["letters"] == 0, "the letter reached the physician" - - -def test_the_approval_that_matches_is_spent_once(harness): - """The positive control for the test above: the same approval, on the letter it covers, - sends -- and a second send under a fresh approval is refused as a duplicate. Without this, - a module that refused everything would pass.""" - pending = harness("send") - approved = harness("approve", request_id=pending["request_id"]) - sent = harness("send", approval_id=approved["approval_id"]) - assert sent["outcome"] == "executed" - assert sent["letters"] == 1 - - again = harness("send") - assert again["outcome"] == "approval_required" - granted = harness("approve", request_id=again["request_id"]) - duplicate = harness("send", approval_id=granted["approval_id"]) - assert duplicate["outcome"] == "duplicate" - assert duplicate["reason"] == "committed" - assert duplicate["letters"] == 1, "the same letter went out twice" - - -def test_a_lost_reply_from_the_safety_database_is_ambiguous_and_not_failed(harness): - lost = harness("event", lose_reply=True) - assert lost["outcome"] == "reply_lost" - assert lost["cases"] == 1 - - retried = harness("event") - assert retried["outcome"] == "ambiguous_retry" - assert retried["cases"] == 1, "the case was filed twice" - - -def test_the_policy_refuses_an_unapproved_use_and_an_action_nobody_wrote_down(harness): - denied = harness("unapproved") - assert denied["outcome"] == "denied" - assert denied["letters"] == 0 - - unknown = harness("unreviewed") - assert unknown["outcome"] == "denied" - assert unknown["reason"] == "unknown_action" - assert unknown["letters"] == 0 - - -def test_the_module_has_no_way_to_grant_but_the_reviewer_button(harness): - """`grant_approval` appears once, under the `approve` op. An auto-approve or a dry run in - here would make every refusal on the page a decoration.""" - assert MODULE.count("grant_approval") == 1 - for forbidden in ("auto_approve", "dry_run", "deny_approval", "reserve_effect"): - assert forbidden not in MODULE, forbidden - - -def test_the_policy_on_the_page_is_the_policy_in_the_module(): - """A reader reads the YAML on the page and believes it produced what they just saw.""" - shown = PAGE.split("```yaml", 1)[1].split("```", 1)[0].strip() - embedded = MODULE.split('POLICY = """', 1)[1].split('"""', 1)[0].strip() - assert shown == embedded - - -# --- the script ---------------------------------------------------------------------------- - - -def test_the_script_does_nothing_unless_the_page_mounts_it(): - """Mintlify includes every .js file on every page and cannot scope one, so the script must - find its container before it touches anything.""" - assert 'var CONTAINER = "ctrlrun-medical-demo";' in SCRIPT - assert "if (!root) return;" in SCRIPT - assert 'id="ctrlrun-medical-demo"' in PAGE - - -def test_the_script_wires_itself_after_the_page_renders(): - """Mintlify is a single-page application: wiring only on DOMContentLoaded misses every - client-side navigation, which is how a reader reaches this page from the sidebar.""" - assert "document.readyState" in SCRIPT - assert "MutationObserver" in SCRIPT, "a sidebar navigation would leave the buttons dead" - assert "data-wired" in SCRIPT, "wiring twice would double every click" - - -def test_the_script_does_not_load_sqlite3_as_a_package(): - """sqlite3 is built into Pyodide and asking micropip for it fails the whole boot.""" - packages = SCRIPT.split("var PACKAGES = ", 1)[1].split(";", 1)[0] - assert "sqlite3" not in packages - - -def test_the_page_and_the_script_name_one_pyodide_build(): - versions = set(re.findall(r"v?(\d+\.\d+\.\d+)", SCRIPT.split("PYODIDE =")[1].split("\n")[0])) - assert len(versions) == 1, versions - version = versions.pop() - assert version in PAGE, "the page does not name the build the script loads" - - -def test_the_reference_the_panel_marks_is_the_one_the_newer_study_brings_in(): - """The panel marks the line that moved. A module that renamed the reference without the - script following would draw revision B with nothing marked, which is the page's whole - point going quietly missing.""" - marked = SCRIPT.split('var NEW_REFERENCE = "', 1)[1].split('"', 1)[0] - revisions = re.findall(r'"references": \[([^\]]+)\]', MODULE) - assert len(revisions) == 2, "the module no longer holds two revisions of the letter" - assert marked not in revisions[0], f"{marked} is already in revision A" - assert marked in revisions[1], f"{marked} is not in revision B" - - -def test_the_script_builds_the_letter_from_nodes_and_not_from_markup(): - """`try-it.js` hands nothing to an HTML parser and neither does this. Not because a string - here is attacker-controlled -- every one comes from the module in the same file -- but - because a page about a boundary should not be the page that makes an exception.""" - assert "innerHTML" not in SCRIPT - assert "insertAdjacentHTML" not in SCRIPT - - -def test_the_script_names_every_outcome_the_module_can_return(): - """A new branch in `step` with no entry in OUTCOMES would print a raw enum at a reader.""" - outcomes = set(re.findall(r'result\["outcome"\] = "(\w+)"', MODULE)) - mapped = set(re.findall(r"^ (\w+): \[", SCRIPT, re.M)) - assert outcomes - mapped == set(), f"the script does not name: {sorted(outcomes - mapped)}" - - -def test_the_script_wires_every_control_the_page_mounts(): - """A button the page shows and the script never binds is a control that does nothing.""" - mounted = set(re.findall(r'<button[^>]*name="(\w+)"', PAGE)) - assert mounted, "the page mounts no buttons" - for name in mounted: - assert f"buttons.{name}.addEventListener" in SCRIPT or f'find("{name}")' in SCRIPT, name - - -def test_the_page_tells_a_reader_what_to_do_when_it_does_not_run(): - assert "pip install ctrlrun" in SCRIPT - - -def test_the_page_says_the_product_and_the_references_are_invented(): - """The one sentence that keeps an illustration from reading as medical information.""" - flowed = " ".join(PAGE.lower().split()) - assert "are invented" in flowed - assert "nothing on this page is medical information about a real medicine" in flowed diff --git a/tests/test_docs_production.py b/tests/test_docs_production.py deleted file mode 100644 index 17eed19..0000000 --- a/tests/test_docs_production.py +++ /dev/null @@ -1,690 +0,0 @@ -"""The Production section, and the first-glance signals that point at it. - -The section answers one question — *can I run this for real, and what happens when the parts -that fail, fail?* — so the rules a machine can check here are about **honesty** rather than -about shape. `test_docs_site.py` already holds every page in `docs/` to frontmatter, a word -budget, a `## Next` block and the navigation. What is asserted below is what this section -would be worth nothing without: - -- every page says what it does **not** do, and cites the acceptance tests it rests on **by an - id that exists in `docs/SPEC-v0.6.md` §8**, so a page cannot cite a test nobody wrote; -- the readiness block is the generator's, byte for byte, in all three places it appears, and - its **Not yet** list is inside it rather than below it, where a reader would stop first; -- the soak page states the measured duration and what a run of that length does **not** - establish, because "soaked" is the sentence a stranger will quote, and the gate it does - report is derived from the published counts rather than read out of the results file; -- the section does not reach for the vocabulary the third rule of `SPEC-v0.6.md` §1.2 refuses. -""" - -from __future__ import annotations - -import json -import re -import subprocess -import sys -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parents[1] -DOCS = REPO_ROOT / "docs" -PRODUCTION = DOCS / "docs" / "production" -TOOLS = REPO_ROOT / "tools" / "docs_audit" - -if not (DOCS / "docs.json").exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout", allow_module_level=True) - -PAGES = sorted(PRODUCTION.glob("*.mdx")) - -#: Paths this repository has and a **distribution deliberately does not**. `MANIFEST.in` prunes -#: `.github`, and `T181` asserts that no `research/` path is in the wheel or the sdist — so their -#: absence inside an sdist is the packaging rule working, not a deletion. -REPOSITORY_ONLY = ( - REPO_ROOT / ".github" / "workflows" / "ci.yml", - REPO_ROOT / "research" / "soak" / "results", -) - - -def _repository_only(path: Path) -> Path: - """A path that exists in a checkout and not in a distribution, or a skip saying why. - - **The skip is guarded so it cannot hide a deletion.** If one of these paths is missing and - another is present, we are in a checkout with a file removed, and that is a failure — which - is the whole risk of skipping on a missing file. Only when *every* repository-only path is - absent together is this the sdist job, running the suite from inside a distribution that - carries `docs/` and `tests/` and neither of these. - """ - if path.exists(): - return path - present = [candidate for candidate in REPOSITORY_ONLY if candidate.exists()] - names = [str(item.relative_to(REPO_ROOT)) for item in present] - assert not present, ( - f"{path.relative_to(REPO_ROOT)} is missing from a tree that still has {names}; " - "that is a deletion, not an sdist" - ) - pytest.skip(f"{path.relative_to(REPO_ROOT)} is not in a distribution, by design") - - -_FRONTMATTER = re.compile(r"\A---\n.*?\n---\n", re.S) -_FENCE = re.compile(r"^```.*?^```", re.M | re.S) - - -def _body(page: Path) -> str: - return _FRONTMATTER.sub("", page.read_text(encoding="utf-8"), count=1) - - -def _spec_test_ids() -> set[str]: - """Every acceptance-test id `SPEC-v0.6.md` and its predecessors define.""" - found: set[str] = set() - for spec in sorted(DOCS.glob("SPEC-v0.*.md")): - text = spec.read_text(encoding="utf-8") - found.update(re.findall(r"^#### (T\d+[a-z]*) ", text, re.M)) - return found - - -def _written_test_ids() -> set[str]: - """Every acceptance-test id a test function in `tests/` is named for.""" - found: set[str] = set() - for module in sorted((REPO_ROOT / "tests").glob("*.py")): - text = module.read_text(encoding="utf-8") - found.update(re.findall(r"^def test_(T\d+[a-z]*)_", text, re.M)) - return found - - -SPEC_TEST_IDS = _spec_test_ids() -WRITTEN_TEST_IDS = _written_test_ids() - - -def test_the_specs_and_the_suite_actually_define_test_ids(): - """The control: both scanners find something, or every citation check below is vacuous.""" - assert len(SPEC_TEST_IDS) > 100, len(SPEC_TEST_IDS) - assert len(WRITTEN_TEST_IDS) > 100, len(WRITTEN_TEST_IDS) - assert {"T155", "T155c", "T156", "T164", "T167"} <= SPEC_TEST_IDS & WRITTEN_TEST_IDS - - # And the two sets are **not** the same set, which is why checking against one of them was - # not enough: a specification may name a test that was written under another id or folded - # into a neighbour's assertions. - assert SPEC_TEST_IDS - WRITTEN_TEST_IDS, "every specified id has a test; this check is moot" - - -def test_the_section_exists_and_has_a_page_for_each_thing_that_breaks(): - expected = { - "index", - "postgres", - "how-reservation-works", - "migrations", - "recovery", - "receipt-integrity", - "soak", - "operations", - } - assert {page.stem for page in PAGES} == expected - - -@pytest.mark.parametrize("page", PAGES, ids=[p.stem for p in PAGES]) -def test_every_production_page_says_what_it_does_not_do(page: Path): - assert "## What this does not do" in _body(page), page.name - - -@pytest.mark.parametrize("page", PAGES, ids=[p.stem for p in PAGES]) -def test_every_production_page_cites_acceptance_tests_that_exist(page: Path): - """A page rests on named tests, and a citation resolves to a test the spec defines. - - Written because a "Verified by" line is the easiest sentence in this section to write and - the easiest to get wrong: an id that names nothing reads exactly like one that names the - test that would have caught the thing the paragraph promises. - """ - body = _body(page) - line = [row for row in body.splitlines() if row.startswith("**Verified by")] - assert line, f"{page.name} has no 'Verified by' line" - cited = set(re.findall(r"\bT\d+[a-z]*\b", body)) - - # **The id must name a test that exists**, and checking it against the specifications is - # not that check. An independent review found three pages citing `T166`, `T169` and `T178` - # — every one of them a `####` heading in a specification, and every one implemented under - # another id or folded into a neighbour's assertions. An id that names nothing reads - # exactly like one that names the test that would have caught the thing the paragraph - # promises, which is the only reason the line is there. - # - # The reverse direction is deliberately not asserted: `T155e` is a test the implementation - # added and the specification never headed, and a page citing it is citing the thing that - # runs. What is written is what a reader can go and read. - unwritten = cited - WRITTEN_TEST_IDS - assert not unwritten, f"{page.name} cites tests nobody wrote: {sorted(unwritten)}" - - -#: The vocabulary `SPEC-v0.6.md` §1.2's third rule refuses, on word boundaries so -#: `design`, `assign` and `security` are not hits. `exactly[ -]once` matches both spellings, -#: which `lint.py` already does and this scan did not. -FORBIDDEN: tuple[str, ...] = ( - "signed", - "signing", - "signature", - "signs?", - "authorship", - "tamper-proof", - "non-repudiation", - "secure", - "compliant", - "certified", - "exactly[ -]once", -) - -#: Sentences on a Production page that use one of those words to say what CTRLRun is **not**. -#: Lower-cased and whitespace-collapsed the way the scan sees them. Adding one is a deliberate -#: act with this list in the diff. -ALLOWED: frozenset[str] = frozenset( - { - # `receipt-integrity.mdx`. The sentence the rule exists to produce, and the reason - # this is an allow-list rather than a word list: a plain scan would flag it, somebody - # would remove the scan as a false positive, and the vocabulary would drift back in - # unwatched. `T180` allow-lists the same sentence, one line at a time, in - # `tests/test_release_v0_6.py`. - "## what this does not do - **it does not tell you who wrote a receipt.** alteration is not authorship, it does not survive an administrator who can rewrite every row including the head, and it vouches for nothing that was never recorded.", # noqa: E501 - } -) - - -def _sentences(text: str) -> list[str]: - return [" ".join(part.split()) for part in re.split(r"(?<=[.!?])\s+", text)] - - -def test_the_forbidden_scan_would_fire_on_the_claims_it_exists_to_catch(): - """The positive control. Every word above is absent from every page today, so without this - the whole scan is a check nothing exercises — `v0.4 §1.3`, and mutation pattern 3.""" - claims = ( - "CTRLRun gives you guaranteed exactly-once execution.", - "Receipts are signed, which proves authorship.", - "The chain is tamper-proof and gives you non-repudiation.", - "This makes your agent secure and compliant.", - "One effect runs exactly once against the remote.", - ) - for claim in claims: - hits = [w for w in FORBIDDEN if re.search(rf"\b{w}\b", claim.lower())] - assert hits, f"the scan would not fire on {claim!r}" - - # And not on the words that merely contain them. - innocent = "The design is assigned to a designated reviewer with security in mind." - assert not [w for w in FORBIDDEN if re.search(rf"\b{w}\b", innocent.lower())], innocent - - -@pytest.mark.parametrize("page", PAGES, ids=[p.stem for p in PAGES]) -def test_the_section_does_not_reach_for_the_words_it_refuses(page: Path): - """`SPEC-v0.6.md` §1.2's third rule, applied to the pages most tempted to break it. - - An **allow-list of exact sentences**, on `T180`'s design and for its reason: a plain - forbidden-word list would flag *"Alteration is not authorship"* — the sentence this rule - exists to produce — which would then be removed as a false positive, taking the check with - it. An allow-list fails on a **new** occurrence, and whoever adds one comes here and says - they meant it. - - Three things an independent review found wrong with the first version, all fixed here. - It omitted **`authorship`**, **`sign`** and **`signs`**, which are the words the rule is - actually about — `receipt-integrity.mdx` could have gained *"the chain proves authorship"* - and stayed green. Its `exactly-once` check was narrower than `lint.py`'s own - `\bexactly[ -]once\b`, so the un-hyphenated form on `recovery.mdx` was invisible to it. - And every one of its words was absent from every page, so nothing exercised any of them — - which the positive control below now settles. - """ - for sentence in _sentences(_FENCE.sub("", _body(page)).lower()): - hit = [word for word in FORBIDDEN if re.search(rf"\b{word}\b", sentence)] - if hit: - assert sentence in ALLOWED, f"{page.name} says {hit[0]!r}: {sentence[:130]!r}" - - -def test_the_first_line_of_the_section_says_which_store_and_why(): - """SQLite is the default and production-grade on one host; Postgres is for many hosts. - - The order matters as much as the content. A section that opened on Postgres would tell a - reader with one host that they are not really in production, which is false and is the - reason most of them would reach for a database they do not need. - """ - first = _FENCE.sub("", _body(PRODUCTION / "index.mdx")).strip().split("\n\n", 1)[0] - first = " ".join(first.split()) - assert "SQLite" in first and "Postgres" in first, first[:120] - assert first.index("SQLite") < first.index("Postgres"), "Postgres comes first: " + first[:120] - assert "one host" in first or "a single host" in first, first[:160] - - -def test_the_two_rows_of_the_lost_commit_are_not_merged(): - """Before `COMMIT` and during `COMMIT` are two behaviours, two rows, and two instructions. - - They are the pair a reader most wants collapsed into one sentence, and collapsing them is - the double execution `T155c` exists to catch: nothing committed and retry the write is not - the same instruction as unknown, so re-read. - - **This test was rewritten because it did not detect the merge it is named for.** It read - `"Before" in body and "During" in body`, and "Before" is satisfied by the page's own first - sentence — *"Before your executor runs"*. An independent review replaced the table with a - single row reading *"before, during or after `COMMIT` — any exception at all — retry the - write"* and all 47 tests passed. What is asserted now is the **table**: two distinct rows, - each naming one side of the boundary, and each carrying its own instruction. - """ - body = _body(PRODUCTION / "how-reservation-works.mdx") - rows = [row for row in body.splitlines() if row.startswith("| ") and row.count("|") >= 4] - before = [row for row in rows if "**Before `COMMIT`**" in row] - during = [row for row in rows if "**During or after `COMMIT`**" in row] - - assert len(before) == 1, f"the table has {len(before)} rows for the before-COMMIT case" - assert len(during) == 1, f"the table has {len(during)} rows for the during-COMMIT case" - assert before != during, "one row is carrying both cases" - - # And the two rows say different things. The before row is a retryable failed write; the - # during row is unknown and is re-read. A merged row cannot satisfy both of these. - assert "retry the write" in before[0], before[0] - assert "re-read" not in before[0], "the before-COMMIT row tells the reader to re-read" - assert "re-read the record on a fresh connection" in during[0], during[0] - assert "retry" not in during[0], "the during-COMMIT row tells the reader to retry" - - cited = set(re.findall(r"\bT\d+[a-z]*\b", body)) - assert {"T155", "T155c", "T156"} <= cited, sorted(cited) - - -def test_the_soak_page_is_the_render_of_the_published_results(): - """No hand-written number, and the duration is the measured one.""" - _repository_only(REPO_ROOT / "research" / "soak" / "results") - drift = subprocess.run( - [sys.executable, str(TOOLS / "render_soak.py"), "--check"], - cwd=REPO_ROOT, - capture_output=True, - text=True, - check=False, - ) - assert drift.returncode == 0, drift.stdout + drift.stderr - - -def test_the_soak_page_states_the_measured_duration_and_what_it_does_not_establish(): - """The clock stopped being a gate; it did not stop being twenty minutes. - - `SPEC-v0.6.md` §8.1 no longer asks for a week, so the page no longer calls the run short - of one — but a criterion that dropped a duration is exactly the moment the duration has - to keep being printed, and printed beside what a run of that length cannot establish. - "Soaked" is the sentence a stranger will quote, and this is the page they land on. - """ - results_dir = _repository_only(REPO_ROOT / "research" / "soak" / "results") - body = _body(PRODUCTION / "soak.mdx") - results = sorted(results_dir.glob("*.json")) - assert results, "no soak results to render" - measured = json.loads(results[-1].read_text(encoding="utf-8")) - assert measured["elapsed_human"] in body, measured["elapsed_human"] - assert "What it is not evidence of" in body, "the page does not say what it cannot show" - assert "exit_criterion_met" in body, "the page does not explain the JSON field" - assert "week" not in body.lower(), ( - "the page still measures itself against a criterion §8.1 no longer has; the " - "amendment is recorded there and in ROADMAP.md, not re-argued on every page" - ) - - -def test_the_soak_page_derives_the_criterion_and_agrees_with_the_harness(): - """The gate is computed twice from one run, and the two computations must agree. - - §8.1's criterion is now the two things a harness is allowed to decide — no unattributed - `AMBIGUOUS`, and a positive control that fired — and no clock at all. **A gate that got - weaker gets a stronger check**: the page recomputes it from the published counts instead - of reading `exit_criterion_met`, and this asserts the recomputation equals the field the - harness wrote. A hand-edited results file moves one and not the other, which is the whole - reason the generator does not simply trust the field. - """ - import sys - - _repository_only(REPO_ROOT / "research" / "soak" / "results") - sys.path.insert(0, str(TOOLS)) - try: - import render_soak - finally: - sys.path.pop(0) - - found = render_soak.latest() - assert found is not None, "no soak results to render" - _, run = found - met = render_soak.criterion(run) - assert met is run["exit_criterion_met"], ( - "the page's derivation and the harness's own field disagree about this run" - ) - assert not hasattr(render_soak, "CRITERION_DAYS"), ( - "the calendar half of the criterion is gone; SPEC-v0.6 §8.1 records why it went" - ) - - body = _body(PRODUCTION / "soak.mdx") - if met: - assert "exit criterion is met by this run" in body - assert "not met" not in body, "the page still says unmet for a run that met it" - else: - assert re.search(r"\bnot met\b", body), "the page does not say the criterion is unmet" - assert "criterion is met by this run" not in body - - # The control: the derivation is not a constant, and it turns on the two halves §8.1 - # names and on neither more nor fewer. The last line is the amendment itself under test — - # a twenty-second run meets the criterion now, and a test that did not say so would let - # the clock creep back in as an unwritten condition. - assert render_soak.criterion(dict(run, unexplained=1)) is False - assert render_soak.criterion(dict(run, positive_control_fired=False)) is False - assert render_soak.criterion(dict(run, elapsed_seconds=20.0)) is True - - -def test_production_is_a_top_level_group_between_get_started_and_guides(): - """First-glance signal A3: a reader scanning the sidebar finds it without opening anything.""" - document = json.loads((DOCS / "docs.json").read_text(encoding="utf-8")) - groups = [ - group["group"] - for tab in document["navigation"]["tabs"] - if tab["tab"] == "Documentation" - for group in tab.get("groups", []) - ] - assert "Production" in groups, groups - assert groups.index("Get started") < groups.index("Production") < groups.index("Guides") - - -def test_every_production_page_is_in_the_production_group(): - document = json.loads((DOCS / "docs.json").read_text(encoding="utf-8")) - listed = [ - page - for tab in document["navigation"]["tabs"] - for group in tab.get("groups", []) - if group["group"] == "Production" - for page in group["pages"] - ] - expected = {f"docs/production/{page.stem}" for page in PAGES} | {"docs/postgres"} - assert set(listed) == expected, listed - assert len(listed) == len(expected), f"a page is listed twice: {listed}" - assert listed[0] == "docs/production/index", "the section's front door comes first" - - -#: The README carried the readiness block until 2026-09-09, when the page was cut to what -#: CTRLRun does, how to use it and how it works. The block has two homes on the site, where a -#: reader who wants the numbers goes, and the generator still refuses a shrunken suite: what -#: was dropped is one embedding, not the guard. -READINESS_HOMES = ("docs/docs.mdx", "docs/docs/production/index.mdx") - - -@pytest.mark.parametrize("home", READINESS_HOMES) -def test_the_readiness_block_is_the_generators_in_every_place_it_appears(home: str): - """One block, three homes. A hand-edited copy in any of them is the drift this refuses.""" - sys.path.insert(0, str(TOOLS)) - try: - import render_readiness - finally: - sys.path.pop(0) - page = REPO_ROOT / home - blocks = render_readiness.marker_blocks(page.read_text(encoding="utf-8")) - assert len(blocks) == 1, f"{home} carries {len(blocks)} readiness blocks" - _, fmt, embedded = blocks[0] - assert embedded == render_readiness.render(fmt, render_readiness.state()), home - - -@pytest.mark.parametrize("home", READINESS_HOMES) -def test_the_not_yet_list_is_inside_the_block_and_not_below_it(home: str): - """The half a reader would skip if it were a separate section they could scroll past.""" - sys.path.insert(0, str(TOOLS)) - try: - import render_readiness - finally: - sys.path.pop(0) - _, _, embedded = render_readiness.marker_blocks((REPO_ROOT / home).read_text(encoding="utf-8"))[ - 0 - ] - assert "**Not yet:**" in embedded, home - for claim, _why in render_readiness.NOT_YET: - assert claim in embedded, f"{home} is missing {claim!r}" - - -@pytest.mark.parametrize("home", READINESS_HOMES) -def test_the_readiness_block_does_not_report_the_soak_as_an_unmet_gate(home: str): - """`SPEC-v0.6.md` §8.1 has no duration in it, so neither does the block that reports it. - - The soak line keeps its measured duration — that was never the gate's doing, and §8.1's - amendment removed a criterion rather than a fact. What goes is the clause calling the run - short of a week and the **Not yet** row derived from it, both of which describe a - criterion this project no longer holds itself to. A block that kept them would be - reporting an unmet gate that does not exist, which is the mirror image of the failure the - generator was written to prevent. - """ - sys.path.insert(0, str(TOOLS)) - try: - import render_readiness - finally: - sys.path.pop(0) - _, _, embedded = render_readiness.marker_blocks((REPO_ROOT / home).read_text(encoding="utf-8"))[ - 0 - ] - assert "Soaked for" in embedded, f"{home} no longer reports the run at all" - assert "week" not in embedded.lower(), home - assert not any("soak" in claim.lower() for claim, _ in render_readiness.NOT_YET), ( - "the Not yet list still carries a soak row for a criterion §8.1 no longer has" - ) - - -def test_the_recorded_readiness_still_matches_what_it_was_measured_from(): - """Everything in the block except the test count, re-measured here rather than trusted. - - Written because an independent review proved the gap by mutation: it set `pyproject.toml` - to `0.7.0` and every test in this file stayed green, because the two tests below compare - the pages to the **recorded** JSON rather than to reality. `render_readiness.py --check` - caught it — but that runs in the `docs` CI job, which is not one of the required status - checks, so it cannot block a merge. This runs in the suite that can. - - The test **count** is deliberately not re-measured here: it is a floor, it moves with every - pull request, and collecting the suite from inside the suite is not something to do per - test. `--check` owns that one; this owns everything that should never move on its own. - """ - import sys - import tomllib - - sys.path.insert(0, str(TOOLS)) - try: - import render_readiness - finally: - sys.path.pop(0) - from ctrlrun.verify.guarantees import GUARANTEES - - recorded = render_readiness.state() - with (REPO_ROOT / "pyproject.toml").open("rb") as handle: - assert recorded["version"] == tomllib.load(handle)["project"]["version"] - assert recorded["guarantees"] == len(GUARANTEES) - - if not (REPO_ROOT / "research" / "soak" / "results").exists(): - # In a distribution the results are pruned, so `soak()` reports none — which says - # nothing about whether the recorded figures drifted. The version and the guarantee - # count above are checked either way. - _repository_only(REPO_ROOT / "research" / "soak" / "results") - published = render_readiness.soak() - if published is None: - assert recorded["soak"] is None - else: - assert recorded["soak"] == { - "elapsed": published["elapsed_human"], - "elapsed_seconds": published["elapsed_seconds"], - "backend": published["backend"].split(" ")[0], - "actions": published["actions"], - "unexplained": published["unexplained"], - "positive_control": published["positive_control_fired"], - } - - -def test_the_readiness_block_does_not_say_an_unreleased_version_is_on_pypi(): - """`pyproject.toml` moves at the start of a milestone; PyPI moves at the end of one. - - The block said *"Version 0.6.0, on PyPI"* off `pyproject.toml` alone while the changelog - still read `## [0.6.0] - unreleased` and PyPI held 0.5.0 — a false sentence on the README, - produced by a generator, which is the one failure a generator exists to prevent. Found by - the launch-readiness audit, by fetching the badge and reading what it said. - """ - import sys - - sys.path.insert(0, str(TOOLS)) - try: - import render_readiness - finally: - sys.path.pop(0) - - recorded = render_readiness.state() - assert recorded["released"] == render_readiness.released() - line = render_readiness.render("readme", recorded).splitlines()[1] - - if recorded["released"] == recorded["version"]: - assert "on [PyPI]" in line, line - assert "in development" not in line, line - else: - assert "is in development" in line, line - assert f"has {recorded['released']}" in line, line - - # The control: the line is derived, and dating the changelog entry flips it. - dated = dict(recorded, released=recorded["version"]) - assert "on [PyPI]" in render_readiness.render("readme", dated).splitlines()[1] - ahead = dict(recorded, released="0.0.1") - assert "is in development" in render_readiness.render("readme", ahead).splitlines()[1] - - -def test_the_not_yet_list_is_the_constant_and_derives_nothing_from_the_soak(): - """The soak row was derived from a duration the criterion no longer has, so it is gone. - - Its derivation existed for a good reason — a hard-coded line would have kept saying a week - was owed on the day one was finally run, the flattering failure in the list whose whole job - is the unflattering half. `SPEC-v0.6.md` §8.1 removed the duration from the criterion - instead, which removes the thing being derived rather than the honesty of deriving it. What - is asserted here is that nothing grew back: the three remaining entries are statements - nothing in the repository can measure, and the block is the constant. - - The run's own duration is **not** what left. It is still printed on the soak line above the - list, in all three formats, and the test named for that line holds it there. - """ - import sys - - sys.path.insert(0, str(TOOLS)) - try: - import render_readiness - finally: - sys.path.pop(0) - - assert not hasattr(render_readiness, "not_yet"), ( - "a derivation is back in a list whose entries nothing can measure" - ) - assert not hasattr(render_readiness, "CRITERION_DAYS") - assert len(render_readiness.NOT_YET) == 3, render_readiness.NOT_YET - assert not any( - "soak" in claim.lower() or "week" in why.lower() for claim, why in render_readiness.NOT_YET - ), render_readiness.NOT_YET - - # The block is the constant whatever the published run says: a short run with findings - # produces the same list as a long clean one, because neither is what this list is about. - recorded = render_readiness.state() - for soak in ( - dict(recorded["soak"], elapsed_seconds=7 * 86_400, unexplained=0), - dict(recorded["soak"], elapsed_seconds=1.0, unexplained=3), - ): - rendered = render_readiness.render("readme", dict(recorded, soak=soak)) - for claim, _why in render_readiness.NOT_YET: - assert claim in rendered - assert "week" not in rendered.lower() - - -def test_the_readiness_block_refuses_a_shrunken_suite_and_accepts_a_grown_one(): - """The count is a floor. A suite that grew is fine; one that shrank is a claim that rotted. - - Without this, `--check` would either be regenerated by every pull request that adds a test - — and so regenerated without being read — or would never notice a suite that lost a third - of itself while the README kept the old number. - """ - sys.path.insert(0, str(TOOLS)) - try: - import render_readiness - finally: - sys.path.pop(0) - recorded = render_readiness.state() - grown = dict(recorded, tests=recorded["tests"] + 500) - shrunk = dict(recorded, tests=recorded["tests"] - 1) - assert render_readiness.check(grown, pages=[]) == [] - assert any("collects" in item for item in render_readiness.check(shrunk, pages=[])) - - -def test_the_badge_row_is_generated_and_carries_the_test_count_badge(): - sys.path.insert(0, str(TOOLS)) - try: - import render_badges - finally: - sys.path.pop(0) - assert render_badges.check() == [] - alts = [badge.alt for badge in render_badges.BADGES] - assert "Tests" in alts and "CTRLRun verified" in alts, alts - document = render_badges.tests_badge(3825) - assert document == { - "schemaVersion": 1, - "label": "tests", - "message": "3,825", - "color": "B8730A", - } - assert "passing" not in json.dumps(document), "the badge says a count, not an outcome" - - -def test_ci_publishes_the_test_count_badge_after_the_suite_has_passed(): - """Order is the whole claim: a badge written before the run would count a red suite. - - **Asserted against the parsed workflow, not against substring positions in the file.** The - first version compared `workflow.index(...)` of two strings, which says nothing about - execution — two steps in different jobs have a text order and no run order. An independent - review changed the step's condition to `always() && …`, which makes it run after a red - suite, and the test passed. What is asserted now is the thing that decides it: the step is - in the same job, at a later index, and its condition contains no status function, so it - inherits the implicit `success()` and is skipped when the suite is red. - """ - import yaml - - ci = _repository_only(REPO_ROOT / ".github" / "workflows" / "ci.yml") - workflow = yaml.safe_load(ci.read_text(encoding="utf-8")) - steps = workflow["jobs"]["check"]["steps"] - ran = [i for i, step in enumerate(steps) if "./scripts/check.sh" in str(step.get("run", ""))] - wrote = [ - i - for i, step in enumerate(steps) - if "render_badges.py --write-count" in str(step.get("run", "")) - ] - assert len(ran) == 1 and len(wrote) == 1, (ran, wrote) - assert ran[0] < wrote[0], "the badge is written before the suite runs" - - condition = str(steps[wrote[0]].get("if", "")) - for override in ("always(", "success(", "failure(", "cancelled(", "!"): - assert override not in condition, ( - f"the write step overrides the implicit success(): {condition!r}" - ) - - # And the publishing job waits on that job, so a red matrix leg publishes nothing. - badge = workflow["jobs"]["badge"] - assert "check" in badge["needs"] and "verify" in badge["needs"], badge["needs"] - assert badge["if"] == "github.event_name == 'push' && github.ref == 'refs/heads/main'" - - # The matrix leg the step is guarded on has to be one the matrix actually runs, or the - # artifact is never uploaded and the *verify* badge's download fails on the next push. - guarded = re.search(r"matrix\.python-version == '([^']+)'", condition) - assert guarded, condition - assert guarded.group(1) in workflow["jobs"]["check"]["strategy"]["matrix"]["python-version"] - - -def test_the_readme_says_where_it_runs_before_the_badges(): - readme = (REPO_ROOT / "README.md").read_text(encoding="utf-8") - header = "Runs in production on a single file, or on Postgres across hosts. Apache-2.0." - assert header in readme - assert readme.index(header) < readme.index("img.shields.io") - - -def test_the_home_page_offers_to_run_it_for_real(): - home = (DOCS / "docs.mdx").read_text(encoding="utf-8") - assert "Run it for real" in home - assert "/docs/production/index" in home - - -def test_capabilities_names_the_two_stores_and_what_each_is_for(): - capabilities = (DOCS / "capabilities.yaml").read_text(encoding="utf-8") - assert "durable" in capabilities.lower() - assert "Postgres" in capabilities and "SQLite" in capabilities - - -def test_the_faq_answers_the_two_questions_this_section_provokes(): - faq = (DOCS / "docs" / "faq.mdx").read_text(encoding="utf-8") - assert "Is SQLite really enough" in faq - assert "production-ready" in faq.lower() - - -def test_claims_carries_a_row_for_the_readiness_block(): - claims = (DOCS / "docs" / "CLAIMS.md").read_text(encoding="utf-8") - assert "readiness" in claims.lower() - assert "production" in claims.lower() diff --git a/tests/test_docs_reference.py b/tests/test_docs_reference.py deleted file mode 100644 index 49ecbfa..0000000 --- a/tests/test_docs_reference.py +++ /dev/null @@ -1,388 +0,0 @@ -"""The Reference pages: generated where the code can say it, and tested against the code where -it cannot. - -- The CLI page, the receipt and event page, the errors page and the Python API pages are the - generators' output, byte for byte. -- Every frozen public name has a docstring and a page. -- The policy and authority YAML pages name every key the loaders accept and every operator. -- The exit-codes page says what `ctrlrun verify --help` says. -""" - -from __future__ import annotations - -import re -import sys -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parents[1] -TOOLS = REPO_ROOT / "tools" / "docs_audit" -DOCS = REPO_ROOT / "docs" - -if not (TOOLS.exists() and (DOCS / "docs" / "reference").exists()): # pragma: no cover - pytest.skip("no repository checkout", allow_module_level=True) - -sys.path.insert(0, str(TOOLS)) - -import render_api # noqa: E402 -import render_cli # noqa: E402 -import render_schemas # noqa: E402 - -# --- generated pages match the code ------------------------------------------------------ - - -def test_the_cli_reference_matches_clicks_help_text(): - assert render_cli.TARGET.read_text(encoding="utf-8") == render_cli.render() - - -def test_the_cli_reference_would_notice_a_changed_option(): - page = render_cli.TARGET.read_text(encoding="utf-8") - assert "--verify-chain" in page and "--store-url" in page - assert render_cli.render().replace("--verify-chain", "--verify-chan") != page - - -def test_the_schema_and_error_pages_match_the_code(): - assert render_schemas.SCHEMAS.read_text(encoding="utf-8") == render_schemas.render_schemas() - assert render_schemas.ERRORS.read_text(encoding="utf-8") == render_schemas.render_errors() - - -def test_the_schema_page_names_every_receipt_field_and_event_type(): - import dataclasses - - from ctrlrun import Receipt - from ctrlrun.receipt import EventType - - page = render_schemas.SCHEMAS.read_text(encoding="utf-8") - for item in dataclasses.fields(Receipt): - assert f"`{item.name}`" in page, item.name - for member in EventType: - assert f"`{member.value}`" in page, member.value - - -def test_the_errors_page_names_every_exception(): - import inspect - - from ctrlrun import errors - - page = render_schemas.ERRORS.read_text(encoding="utf-8") - for name, obj in inspect.getmembers(errors, inspect.isclass): - if obj.__module__ == errors.__name__: - assert f"### {name}" in page, name - - -def test_the_api_reference_matches_the_docstrings(): - assert render_api.check(render_api.render()) == [] - - -def test_every_rendered_api_signature_is_the_one_python_would_accept(): - """A reader copies the signature off the page and calls it. It has to work. - - The renderer used to emit `name: annotation` and nothing else, which dropped the `*` and - every default — so `protect('stripe.refund', 'refund:{id}')`, taken straight off - `reference/api/protect.mdx`, raised `TypeError: takes 1 positional argument but 2 were - given`. The launch-readiness audit tried thirteen of these pages and all thirteen raised. - - This compares the rendered parameter list against `inspect.signature`, name by name and - marker by marker, for every public callable. It is stricter than "the page exists" and it - is the check that would have caught it. - """ - import inspect - - import ctrlrun - - checked = 0 - for name in sorted(ctrlrun.__all__): - member = getattr(ctrlrun, name) - if not inspect.isfunction(member) and not inspect.isclass(member): - continue - page = DOCS / "docs" / "reference" / "api" / f"{name}.mdx" - if not page.exists(): - continue - # The first python block is the import line; the signature is the one that declares. - blocks = re.findall( - r"^```python\n(.*?)^```$", page.read_text(encoding="utf-8"), re.M | re.S - ) - declaring = [b for b in blocks if b.lstrip().startswith(("def ", "class "))] - assert declaring, f"{name}.mdx has no signature block" - rendered = declaring[0] - - if inspect.isfunction(member): - declared = f"def {name}(" - assert rendered.startswith(declared), rendered[:80] - params = rendered[len(declared) : rendered.rindex(")")] - else: - found = re.search(r"def __init__\((.*)\)", rendered) - if found is None: - continue # a Protocol or a dataclass with no __init__ of its own - params = found.group(1) - - target = member if inspect.isfunction(member) else member.__init__ - expected = [ - p.name - for p in inspect.signature(target).parameters.values() - if p.name not in {"self", "cls"} - ] - rendered_names = [ - piece.strip().split(":")[0].split("=")[0].strip().lstrip("*") - for piece in _split_parameters(params) - if piece.strip() not in {"", "*", "/"} - ] - assert rendered_names == expected, ( - f"{name}: page says {rendered_names}, code says {expected}" - ) - - # The marker itself: everything after a keyword-only parameter's `*` must be one. - signature = inspect.signature(target) - keyword_only = [p.name for p in signature.parameters.values() if p.kind is p.KEYWORD_ONLY] - if keyword_only and not any( - p.kind is p.VAR_POSITIONAL for p in signature.parameters.values() - ): - assert "*" in _split_parameters(params) or any( - piece.strip().startswith("*") for piece in _split_parameters(params) - ), f"{name}: {keyword_only} are keyword-only and the page shows no `*`" - checked += 1 - - assert checked >= 20, f"only {checked} signatures compared; this check found nothing to do" - - -def _split_parameters(text: str) -> list[str]: - """Split on the commas that separate parameters, not the ones inside brackets.""" - pieces, depth, current = [], 0, "" - for character in text: - if character in "[({": - depth += 1 - elif character in "])}": - depth -= 1 - if character == "," and depth == 0: - pieces.append(current) - current = "" - continue - current += character - if current.strip(): - pieces.append(current) - return pieces - - -def test_every_frozen_public_name_has_a_docstring_and_a_page(): - import importlib - - import ctrlrun - - names = [(ctrlrun, name) for name in ctrlrun.__all__] - for module_path, name in render_api.EXTRA_NAMES: - try: - names.append((importlib.import_module(module_path), name)) - except ImportError: # pragma: no cover - an extra not installed here - continue - missing_doc = [name for module, name in names if not _documented(getattr(module, name))] - assert missing_doc == [], f"public names with no docstring: {missing_doc}" - - pages = {p.stem for p in (DOCS / "docs" / "reference" / "api").glob("*.mdx")} - for module_path, name in [("ctrlrun", n) for n in ctrlrun.__all__] + list( - render_api.EXTRA_NAMES - ): - assert render_api._slug(module_path, name) in pages, f"{module_path}.{name} has no page" - - -def _documented(obj: object) -> bool: - import inspect - import typing - - if typing.get_origin(obj) is typing.Literal: - # A Literal alias has no `__doc__`; its docstring is the string statement after the - # assignment, which griffe reads and the API page shows. - page = DOCS / "docs" / "reference" / "api" / "ReconcileOutcome.mdx" - return page.exists() and "No docstring" not in page.read_text(encoding="utf-8") - return bool(inspect.getdoc(obj)) - - -# --- hand-written pages cover what the loaders accept ------------------------------------- - - -def _keys_in(page: Path) -> set[str]: - return set(re.findall(r"`([A-Za-z_][\w./:-]*)`", page.read_text(encoding="utf-8"))) - - -def test_the_policy_reference_names_every_key_and_operator_the_loader_accepts(): - from ctrlrun import policy - - named = _keys_in(DOCS / "docs" / "reference" / "policy-yaml.mdx") - expected = ( - set(policy._TOP_LEVEL_KEYS) - | set(policy._ENTRY_KEYS) - | set(policy._RULE_KEYS) - | set(policy._MCP_KEYS) - | set(policy._CONTROL_KEYS) - | set(policy._DATA_KEYS) - | set(policy._OPERATORS) - | { - policy.POLICY_SCHEMA, - policy.POLICY_SCHEMA_V2, - policy.POLICY_SCHEMA_V3, - policy.POLICY_SCHEMA_V4, - } - | set(policy.DERIVED_SUBJECTS) - ) - assert expected - named == set(), f"policy-yaml.mdx does not name: {sorted(expected - named)}" - - -def test_the_authority_reference_names_every_grant_key(): - from ctrlrun import authority - - named = _keys_in(DOCS / "docs" / "reference" / "authority-yaml.mdx") - expected = ( - set(authority._AUTHORITY_KEYS) | set(authority._GRANT_KEYS) | set(authority._SUBJECT_KEYS) - ) - assert expected - named == set(), ( - f"authority-yaml.mdx does not name: {sorted(expected - named)}" - ) - assert str(authority.DEFAULT_MAX_DELEGATION_DEPTH) in ( - DOCS / "docs" / "reference" / "authority-yaml.mdx" - ).read_text(encoding="utf-8") - - -def test_the_exit_codes_page_says_what_verify_says(): - from click.testing import CliRunner - - from ctrlrun.cli.main import main - - help_text = " ".join(CliRunner().invoke(main, ["verify", "--help"]).output.split()) - page = " ".join( - (DOCS / "docs" / "reference" / "exit-codes.mdx").read_text(encoding="utf-8").split() - ) - for sentence in ( - "0 every applicable guarantee passed and at least one was applicable", - "1 a guarantee FAILED", - "2 the configuration was refused or is unusable", - "3 an internal error in verify itself", - ): - assert sentence in help_text, sentence - assert "every applicable guarantee passed and at least one was applicable" in page - assert "an internal error in verify itself" in page - assert "`0/0`" in page - - -def test_the_exit_codes_page_matches_the_report(): - from ctrlrun.verify.report import Report - - source = Path(__import__("inspect").getsourcefile(Report)).read_text(encoding="utf-8") - assert "return 2" in source and "self.applicable == 0" in source - - -def test_every_quoted_verify_transcript_is_one_verify_actually_prints(): - """The pages that quote `ctrlrun verify` are checked against a real run of their own policy. - - Both of them were **written rather than captured**. Each showed eight `PASS stripe.refund` - rows; the policy on the same page makes verify exercise `k8s.delete_namespace` on every one - of them, because it takes the first action that fits in alphabetical order. Each also - dropped the stderr line G7's own scenario logs, and one misaligned a column. Found by the - launch-readiness audit, which ran them. - - That is the false-green problem this project spends thousands of words warning about, - arriving in its own quoted evidence. So the transcript is compared with a run: every line - except the `policy` line, whose absolute path is machine-specific and is labelled as such - on both pages. - """ - import subprocess - import sys - import tempfile - - pages = [ - DOCS / "docs" / "guides" / "verify-in-ci.mdx", - DOCS / "docs" / "cookbook" / "verify-in-github-actions.mdx", - ] - for page in pages: - text = page.read_text(encoding="utf-8") - # The guide indents its blocks inside `<Steps>`, so the fence and the document are - # both offset; the cookbook page's are flush. - policy = re.search(r"```yaml[^\n]*\n(\s*schema: ctrlrun\.policy.*?)```", text, re.S) - assert policy, f"{page.name} quotes no policy" - quoted = re.search(r"```text\n(.*?CTRLRun verify.*?)```", text, re.S) - assert quoted, f"{page.name} quotes no transcript" - - with tempfile.TemporaryDirectory() as directory: - indent = " " * (len(policy.group(1)) - len(policy.group(1).lstrip(" "))) - document = "\n".join( - line[len(indent) :] if line.startswith(indent) else line - for line in policy.group(1).splitlines() - ) - (Path(directory) / "ctrlrun.yaml").write_text(document, encoding="utf-8") - result = subprocess.run( - [sys.executable, "-m", "ctrlrun.cli.main", "verify"], - cwd=directory, - capture_output=True, - text=True, - check=False, - ) - printed = (result.stderr + result.stdout).splitlines() - - page_indent = " " * (len(quoted.group(1)) - len(quoted.group(1).lstrip(" "))) - shown = [ - line[len(page_indent) :] if line.startswith(page_indent) else line - for line in quoted.group(1).splitlines() - ] - skip = ("policy ",) - shown = [line for line in shown if line.strip() and not line.startswith(skip)] - printed = [line for line in printed if line.strip() and not line.startswith(skip)] - assert shown == printed, ( - f"{page.name} quotes a transcript verify does not print:\n" - + "\n".join(f" page: {line}" for line in shown if line not in printed) - + "\n" - + "\n".join(f" real: {line}" for line in printed if line not in shown) - ) - - -def test_every_api_page_says_how_to_import_the_thing_it_documents(): - """Zero of seventy-one carried an import line, and the five behind an extra never named it. - - A reference page that gives a class name and no route to it is browsable and not usable — - the audit's phrase, and the right one. `PostgresStateStore`, `OTelEventSink`, - `JWTIdentityProvider`, `AcsControlHook` and `serve` all raise `MissingDependency` without - their extra, and no page said which. - """ - - pages = sorted((DOCS / "docs" / "reference" / "api").glob("*.mdx")) - assert len(pages) > 50, len(pages) - for page in pages: - if page.stem == "index": - continue - text = page.read_text(encoding="utf-8") - dotted = re.search(r"^`(ctrlrun[\w.]*)\.(\w+)` — ", text, re.M) - assert dotted, f"{page.name} does not name what it documents" - module, name = dotted.group(1), dotted.group(2) - assert f"from {module} import {name}" in text, f"{page.name} has no import line" - - # Read the generator's own map rather than a second copy of it. The copy that used - # to be here listed a `conformance` extra that had been reversed, so the test asserted - # the same false install line the generator emitted and the drift was invisible from - # both sides. `test_every_extra_the_reference_names_is_an_extra_that_exists` is what - # checks that map against the extras `pyproject.toml` actually declares. - extra = render_api.EXTRA_FOR.get(module) - if extra is not None: - assert f'pip install "ctrlrun[{extra}]"' in text, ( - f"{page.name} needs the {extra} extra and does not say so" - ) - - -def test_every_extra_the_reference_names_is_an_extra_that_exists(): - """A reference page that says `pip install "ctrlrun[conformance]"` sends a reader to a - command that installs nothing. - - SPEC-v0.5 §5.1 planned the conformance kit as an extra and then reversed it -- the kit - needs nothing `ctrlrun` does not already install, and `conformance/__init__.py` records - why. `EXTRA_FOR` was not updated, so two generated pages kept promising an extra that - `pyproject.toml` does not declare, plus a `MissingDependency` that can never fire. Both - halves of that sentence were false. - """ - import tomllib - - with (REPO_ROOT / "pyproject.toml").open("rb") as handle: - declared = set(tomllib.load(handle)["project"].get("optional-dependencies", {})) - - named = set(render_api.EXTRA_FOR.values()) - - assert named <= declared, ( - f"the API reference names extras that pyproject.toml does not declare: " - f"{sorted(named - declared)}" - ) diff --git a/tests/test_docs_seo.py b/tests/test_docs_seo.py deleted file mode 100644 index 897f6ce..0000000 --- a/tests/test_docs_seo.py +++ /dev/null @@ -1,178 +0,0 @@ -"""What search engines and assistants read: titles, descriptions, one H1, and the FAQ data. - -`docs/SEO.md` names the target query per page and the sentence written to answer it. The rules -a machine can hold are here; the sentences themselves are what a reviewer reads for. -""" - -from __future__ import annotations - -import json -import re -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parents[1] -DOCS = REPO_ROOT / "docs" - -if not (DOCS / "docs.json").exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout", allow_module_level=True) - -import test_docs_site # noqa: E402 - one definition of "a site page", not two - -PAGES = test_docs_site.PAGES -TITLE_LIMIT = 60 -DESCRIPTION_LIMIT = 155 -_FRONTMATTER = re.compile(r"\A---\n(.*?)\n---\n", re.S) -_FENCE = re.compile(r"^```.*?^```", re.M | re.S) -_IDS = [p.relative_to(DOCS).as_posix() for p in PAGES] - - -def _field(page: Path, name: str) -> str: - matched = re.search(rf'^{name}: "(.*)"$', page.read_text(encoding="utf-8"), re.M) - return matched.group(1) if matched else "" - - -def _body(page: Path) -> str: - return _FRONTMATTER.sub("", page.read_text(encoding="utf-8"), count=1) - - -@pytest.mark.parametrize("page", PAGES, ids=_IDS) -def test_every_title_and_description_fits_a_search_result(page: Path): - """A title over 60 characters and a description over 155 are truncated where a stranger - reads them, which is the one place the words have to work.""" - title, description = _field(page, "title"), _field(page, "description") - - assert title and len(title) <= TITLE_LIMIT, f"{page.name}: title is {len(title)} characters" - assert description, page.name - assert len(description) <= DESCRIPTION_LIMIT, ( - f"{page.name}: description is {len(description)} characters" - ) - - -@pytest.mark.parametrize("page", PAGES, ids=_IDS) -def test_no_page_has_a_second_h1(page: Path): - """Mintlify renders the frontmatter title as the page's H1, so a `# ` in the body is a - second one. Code blocks are stripped first: a `#` there is a comment.""" - prose = _FENCE.sub("", _body(page)) - - assert not re.search(r"^# ", prose, re.M), f"{page.name} has an H1 in its body" - - -@pytest.mark.parametrize("page", PAGES, ids=_IDS) -def test_the_description_is_not_the_title_again(page: Path): - assert _field(page, "description").lower() != _field(page, "title").lower() - - -def test_the_faq_structured_data_matches_the_page(): - """The FAQ carries FAQ structured data. Every question in it is a question on the page, so - the markup cannot answer something the reader never sees.""" - text = (DOCS / "docs" / "faq.mdx").read_text(encoding="utf-8") - block = text.split("application/ld+json", 1)[1].split("</script>", 1)[0] - document = json.loads(block.split("JSON.stringify(", 1)[1].rsplit(")", 1)[0].strip()) - - assert document["@type"] == "FAQPage" - questions = [entry["name"] for entry in document["mainEntity"]] - on_page = re.findall(r'<Accordion title="([^"]+)">', text) - - # Fourteen since the Production section added the two questions it provokes. The count is - # pinned rather than derived so that dropping an accordion and leaving its markup behind -- - # which is how structured data comes to answer something the reader cannot see -- fails - # here instead of shipping. - assert len(questions) == 14, f"{len(questions)} questions in the structured data" - assert len(on_page) == 14, f"{len(on_page)} accordions on the page" - - # The two lists are the same questions in the same order and not the same strings: an - # accordion is read with the page around it and says "Is it production-ready?", while a - # search result carries the question alone and has to name the product. What must not - # happen is a question in the markup that the reader cannot find on the page, so the counts - # are pinned and every answer must be non-empty. - assert len(set(questions)) == 14, "the structured data asks the same question twice" - for entry in document["mainEntity"]: - assert entry["acceptedAnswer"]["text"].strip(), entry["name"] - - -def test_seo_md_names_every_page_and_its_query(): - """`docs/SEO.md` is the plan: one row per page. A page with no row is a page nobody decided - what it was for.""" - plan = (DOCS / "SEO.md").read_text(encoding="utf-8") - missing = [] - for page in PAGES: - slug = page.relative_to(DOCS).with_suffix("").as_posix() - if slug.startswith("docs/reference/api/") and slug != "docs/reference/api/index": - continue # one row covers the generated API pages - if f"`{slug}`" not in plan: - missing.append(slug) - assert missing == [], f"docs/SEO.md has no row for: {missing}" - - -def test_the_definitional_words_appear_where_the_plan_says(): - """The words written once, for search, are on the pages that own them.""" - for slug, word in ( - ("concepts/effect-keys", "idempotency"), - ("get-started/three-ways-in", "human-in-the-loop"), - ("concepts/outcomes-and-ambiguous", "double execution"), - ): - text = (DOCS / "docs" / f"{slug}.mdx").read_text(encoding="utf-8").lower() - assert word in text, f"{slug} does not carry {word!r}" - - -SITE = "https://ctrlrun.dev" - - -def test_the_site_declares_its_social_image_and_indexing(): - """The share image is an **absolute URL on the site's own domain**. - - It was `/images/social-preview.png`, and Mintlify expanded that against the deployment's - origin rather than the custom domain, so every share card on the internet pointed at - `ctrlrun.mintlify.app`. Found by fetching the deployed home page and reading its `og:image`. - A relative path is not wrong so much as it is resolved by somebody else. - """ - document = json.loads((DOCS / "docs.json").read_text(encoding="utf-8")) - seo = document["seo"] - - for tag in ("og:image", "twitter:image"): - assert seo["metatags"][tag] == f"{SITE}/images/social-preview.png", tag - assert seo["metatags"]["twitter:card"] == "summary_large_image" - - # **No site-wide `canonical` or `og:url`.** A metatag set here is stamped on every page, so - # both of them made all 180 pages declare themselves duplicates of the home page — an - # instruction to a search engine to index one and drop the rest. Mintlify emits a correct - # per-page canonical of its own. An override belongs in a page's frontmatter, never here. - for forbidden in ("canonical", "og:url"): - assert forbidden not in seo["metatags"], ( - f"{forbidden} is site-wide, so every page claims to be the home page" - ) - assert (DOCS / "images" / "social-preview.png").exists() - - -def test_the_home_pages_share_title_is_not_the_site_name_twice(): - """Mintlify renders `<title> - <site name>`, so a home page titled `CTRLRun` on a site - named `CTRLRun` shared as **"CTRLRun - CTRLRun"**. The override says something instead.""" - text = (DOCS / "index.mdx").read_text(encoding="utf-8") - document = json.loads((DOCS / "docs.json").read_text(encoding="utf-8")) - for tag in ("og:title", "twitter:title"): - found = re.search(rf'^"{tag}": "(.*)"$', text, re.M) - assert found, f"the home page sets no {tag}" - assert found.group(1) != document["name"], f"{tag} is the site name again" - assert len(found.group(1)) <= 60, f"{tag} is {len(found.group(1))} characters" - - -def test_no_description_is_cut_off_mid_sentence(): - """A description is the search snippet and the gallery subtitle. Four ended mid-clause. - - *"…so that a retry."* and *"…and cannot see who is."* were shipping as the one sentence a - stranger reads before deciding to click. The length limit above catches a long one; nothing - caught a truncated one, because a truncated sentence is short. - """ - dangling = re.compile( - r"\b(so that a|so a|and cannot see who|a missing|which is the|because the|and the)\.$" - ) - cut: list[str] = [] - for page in PAGES: - description = _field(page, "description") - if not description: - continue - if dangling.search(description) or description.rstrip().endswith((" a.", " the.", " is.")): - cut.append(f"{page.name}: …{description[-58:]!r}") - assert cut == [], cut diff --git a/tests/test_docs_site.py b/tests/test_docs_site.py deleted file mode 100644 index 11378a9..0000000 --- a/tests/test_docs_site.py +++ /dev/null @@ -1,407 +0,0 @@ -"""The documentation site's pages, held to `docs/STYLE.md` and `docs/IA.md`. - -The rules a machine can check: frontmatter, the word budget, the closing Next block, the -navigation, and on every Concepts page a definitional first sentence. The rest is what a -reviewer reads for. -""" - -from __future__ import annotations - -import json -import re -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parents[1] -DOCS = REPO_ROOT / "docs" - -if not (DOCS / "docs.json").exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout", allow_module_level=True) - - -def _published() -> set[str]: - """Every page path `docs.json` lists, so a Markdown document that is a site page is tested - like one and a Markdown document that is not is left alone.""" - - found: set[str] = set() - - def walk(node: object) -> None: - # Only the strings inside a `pages` array are page paths. A group's own label is a - # string too, and on a case-insensitive filesystem the label "Architecture" resolved - # to ARCHITECTURE.md and was tested as a page that does not exist. - if isinstance(node, list): - for item in node: - walk(item) - elif isinstance(node, dict): - for key, value in node.items(): - if key == "pages": - found.update(item for item in value if isinstance(item, str)) - walk(value) - - walk(json.loads((DOCS / "docs.json").read_text(encoding="utf-8"))["navigation"]) - return found - - -#: Site pages: the MDX ones, and the Markdown documents `docs.json` publishes. The second half -#: was missing until the deployed site showed a filename title above each document's own H1 -- -#: eighteen pages no test looked at, because the glob said `*.mdx`. -PAGES = sorted( - [path for path in DOCS.rglob("*.mdx") if "generated" not in path.parts] - + [DOCS / f"{slug}.md" for slug in sorted(_published()) if (DOCS / f"{slug}.md").exists()] -) - -#: Long-form documents that predate the site and are read the way a specification is. The word -#: budget is for pages written to be read in one sitting. -LONG_FORM = frozenset( - { - "ARCHITECTURE", - "THREAT_MODEL", - "CLAIMS", - "ROADMAP", - "verify", - "postgres", - "adapters", - "authority", - "ACS", - "OWASP-AGENTIC-TOP10", - "how-this-is-built", - } -) -CONCEPTS = sorted((DOCS / "docs" / "concepts").glob("*.mdx")) -WORD_BUDGET = 900 -_FRONTMATTER = re.compile(r"\A---\n(.*?)\n---\n", re.S) -_FENCE = re.compile(r"^```.*?^```", re.M | re.S) - - -def _frontmatter(page: Path) -> dict[str, str]: - matched = _FRONTMATTER.match(page.read_text(encoding="utf-8")) - assert matched, f"{page.name} has no frontmatter" - fields: dict[str, str] = {} - for line in matched.group(1).splitlines(): - key, _, value = line.partition(":") - fields[key.strip()] = value.strip().strip('"') - return fields - - -def _body(page: Path) -> str: - return _FRONTMATTER.sub("", page.read_text(encoding="utf-8"), count=1) - - -# The end tag is matched the way a browser's parser reads one, not the way it is usually typed. -# Tag names are case-insensitive; whitespace is allowed around the slash and the name; and an -# end tag carrying attribute-like text -- `</script bar>` -- still closes the element, because -# the parser ignores what it finds there rather than refusing the tag. A filter that misses any -# of those spellings leaves the block in the text, where a structured-data payload counts -# against the page's prose budget, which is the one thing this helper exists to prevent. -# -# `\bscript\b` on both ends so that a tag merely beginning with those letters -- `<scriptish>` -# -- neither opens nor closes a block. -_SCRIPT = re.compile(r"<\s*script\b.*?<\s*/\s*script\b[^>]*>", re.S | re.I) - - -def _prose(page: Path) -> str: - """The page with code blocks, structured data, JSX tags and frontmatter removed. - - A `<script type="application/ld+json">` block is markup for a search engine, not words a - reader reads, so it does not count against the page's budget. - """ - text = _SCRIPT.sub("", _FENCE.sub("", _body(page))) - return re.sub(r"<[^>]+>", "", text) - - -def _navigation_pages() -> set[str]: - document = json.loads((DOCS / "docs.json").read_text(encoding="utf-8")) - found: set[str] = set() - - def walk(node: object) -> None: - if isinstance(node, str): - found.add(node) - elif isinstance(node, list): - for item in node: - walk(item) - elif isinstance(node, dict): - for key in ("pages", "groups", "tabs", "anchors", "dropdowns"): - if key in node: - walk(node[key]) - - walk(document["navigation"]) - return found - - -@pytest.mark.parametrize("page", PAGES, ids=[p.relative_to(DOCS).as_posix() for p in PAGES]) -def test_every_page_has_a_title_and_a_description(page: Path): - fields = _frontmatter(page) - assert fields.get("title"), page.name - assert fields.get("description"), page.name - assert "!" not in fields["title"] and "!" not in fields["description"] - - -@pytest.mark.parametrize("page", PAGES, ids=[p.relative_to(DOCS).as_posix() for p in PAGES]) -def test_every_page_ends_with_next_links(page: Path): - if page.suffix == ".md" or _frontmatter(page).get("mode") == "custom": - return # a document read on GitHub too ends where its own text ends - body = _body(page).rstrip() - assert "## Next" in body, page.name - tail = body.split("## Next", 1)[1] - assert tail.count("](/") + tail.count("](http") >= 2, f"{page.name}: Next needs two links" - - -@pytest.mark.parametrize("page", PAGES, ids=[p.relative_to(DOCS).as_posix() for p in PAGES]) -def test_every_page_links_to_why_and_to_get_started_or_is_one_of_them(page: Path): - if page.suffix == ".md" or _frontmatter(page).get("mode") == "custom": - return # same reason: read on GitHub too, where a site path resolves to nothing - slug = page.relative_to(DOCS).with_suffix("").as_posix() - text = _body(page) - if slug != "docs/why": - assert "](/docs/why)" in text, f"{page.name} does not link to Why" - if not slug.startswith("docs/get-started/") and slug != "docs": - assert "](/docs/get-started/" in text, f"{page.name} does not link to Get started" - - -@pytest.mark.parametrize("page", PAGES, ids=[p.relative_to(DOCS).as_posix() for p in PAGES]) -def test_every_page_is_in_the_navigation(page: Path): - slug = page.relative_to(DOCS).with_suffix("").as_posix() - assert slug in _navigation_pages(), f"{slug} is not in docs.json" - - -@pytest.mark.parametrize("page", PAGES, ids=[p.relative_to(DOCS).as_posix() for p in PAGES]) -def test_every_page_but_a_reference_page_fits_the_word_budget(page: Path): - slug = page.relative_to(DOCS).with_suffix("").as_posix() - if ( - slug.startswith("docs/reference/") - or slug in {"index", "docs"} - or slug.removeprefix("docs/") in LONG_FORM - ): - return - words = len(_prose(page).split()) - assert words <= WORD_BUDGET, f"{page.name}: {words} words of prose, budget {WORD_BUDGET}" - - -@pytest.mark.parametrize("page", CONCEPTS, ids=[p.stem for p in CONCEPTS]) -def test_every_concepts_page_opens_with_a_definitional_sentence(page: Path): - """The sentence an assistant can quote standalone: the page's subject, then *is*.""" - first = _prose(page).strip().split("\n\n", 1)[0].replace("\n", " ") - assert re.match( - r"^(An?|The|Authority|Observe mode|Fail closed|A decision)\b.*?\b(is|means|answers)\b", - first, - ), f"{page.name} does not open with a definition: {first[:80]!r}" - - -@pytest.mark.parametrize("page", CONCEPTS, ids=[p.stem for p in CONCEPTS]) -def test_every_concepts_page_says_what_it_does_not_do(page: Path): - assert "## What it does not do" in _body(page) or "## What it never does" in _body(page) - - -def test_the_documentation_root_preserves_the_technical_overview(): - text = (DOCS / "docs.mdx").read_text(encoding="utf-8") - assert "The last check before an AI agent does something it can't undo." in text - assert "Autonomy belongs to the action, not the agent." in text - assert "generated from docs/capabilities.yaml (mdx)" in text - assert '"mcpServers"' in text and "/mcp" in text - - -def test_the_why_page_opens_with_the_opener_and_stays_under_700_words(): - page = DOCS / "docs" / "why.mdx" - prose = _prose(page).strip() - assert prose.startswith( - "Everyone is rushing to ship AI agents without thinking about consequences." - ) - assert len(prose.split()) <= 700, len(prose.split()) - assert "](/docs/how-this-is-built)" in _body(page) - - -def test_the_site_ignores_what_is_not_a_page(): - ignored = (DOCS / ".mintignore").read_text(encoding="utf-8") - for name in ("BUILD-PROMPTS-*.md", "README.md", "IA.md", "STYLE.md", "generated/", "assets/"): - assert name in ignored, name - - -def test_no_page_states_a_guarantee_count_the_catalogue_does_not_have(): - """`ctrlrun verify` grew from ten guarantees to eleven and four pages kept saying ten. - - Found by the launch-readiness audit, which ran verify and read the number. A count in - prose is a claim like any other, and this is the cheapest way to hold one: scan for a - number-of-guarantees phrase and compare it with the catalogue. - """ - from ctrlrun.verify.guarantees import GUARANTEES - - words = { - "one": 1, - "two": 2, - "three": 3, - "four": 4, - "five": 5, - "six": 6, - "seven": 7, - "eight": 8, - "nine": 9, - "ten": 10, - "eleven": 11, - "twelve": 12, - } - # Only a count **of the catalogue**. "Two guarantees are not applicable" is a count of the - # N/As in one run and is not this claim, so the pattern needs the determiner that makes it - # about the whole set — which is exactly how the wrong ones were written: *all ten - # guarantees*. - number = r"(\d+|" + "|".join(words) + r")" - pattern = re.compile( - rf"\b(?:all|every one of the|the whole set of)\s+{number}\s+guarantees\b" - rf"|\b{number}\s+guarantees (?:you can check|in the catalogue)\b", - re.I, - ) - wrong: list[str] = [] - for page in PAGES: - for line in _prose(page).splitlines(): - for found in pattern.finditer(line): - token = next(group for group in found.groups() if group).lower() - stated = words.get(token, int(token) if token.isdigit() else None) - if stated is not None and stated != len(GUARANTEES): - wrong.append(f"{page.name}: {line.strip()[:90]!r}") - assert wrong == [], f"the catalogue has {len(GUARANTEES)}; these say otherwise: {wrong}" - - -def test_the_verify_shapes_the_roadmap_quotes_are_the_ones_verify_reports(): - """`ROADMAP.md` is a site page and quoted `10/10` and `5/5` long after both moved.""" - roadmap = (DOCS / "docs" / "ROADMAP.md").read_text(encoding="utf-8") - assert "10/10" not in roadmap and "5/5" not in roadmap, "a stale verify shape is quoted" - assert "11/11" in roadmap and "6/6" in roadmap - - -def test_how_this_is_built_does_not_undercount_the_suite_it_describes(): - """Its thesis is that every claim maps to a test, so its own count has to be one. - - A floor, like the readiness block's and for the same reason: the suite only grows, and a - number every pull request had to regenerate would be regenerated without being read. It - was 1,625 functions and 2,442 cases against a real 1,704 and 3,944 — off by fifteen - hundred, on the page that argues the tests are the evidence. - """ - functions: set[str] = set() - for module in (REPO_ROOT / "tests").glob("*.py"): - functions.update(re.findall(r"^def (test_\w+)", module.read_text(encoding="utf-8"), re.M)) - - text = (DOCS / "docs" / "how-this-is-built.md").read_text(encoding="utf-8") - found = re.search(r"([\d,]+) test functions, ([\d,]+) cases", text) - assert found, "the page no longer states a suite size" - stated_functions = int(found.group(1).replace(",", "")) - stated_cases = int(found.group(2).replace(",", "")) - - assert stated_functions <= len(functions), ( - f"the page claims {stated_functions:,} test functions and there are {len(functions):,}" - ) - assert stated_cases >= stated_functions, "cases cannot be fewer than functions" - # The stated case count is a floor too, and 3,900 is the size of the suite when this was - # written. A drop below it is a suite that lost a tenth of itself unnoticed. - assert stated_cases >= 3_900, stated_cases - - -def test_no_page_says_every_call_leaves_a_receipt(): - """It does not. An approval-required call has no receipt until somebody decides it. - - Five pages said *"every call leaves a receipt, refused ones too"*. A receipt is written - when an action reaches a **terminal** state, and *waiting on a human* is not one — so a - reader following `cookbook/protect-an-mcp-server` counted four protected calls and three - receipts and had no way to tell whether that was the docs or a bug. Reproduced by the - launch-readiness audit and again below, so this is a measurement rather than an opinion. - """ - import tempfile - - import ctrlrun - from ctrlrun import Control, Policy, SQLiteStateStore - from ctrlrun.errors import ActionDenied, ApprovalRequired - - document = """schema: ctrlrun.policy/v2 -actions: - a.small: - effect: "e:{id}" - rules: - - when: { amount_gte: 0, amount_lte: 10 } - decision: allow - - decision: approve - a.nope: - decision: deny -""" - with tempfile.TemporaryDirectory() as directory: - policy_path = Path(directory) / "ctrlrun.yaml" - policy_path.write_text(document, encoding="utf-8") - store = SQLiteStateStore(Path(directory) / "state.db") - control = Control(Policy.from_file(policy_path), store) - - @ctrlrun.protect("a.small", effect="e:{id}", control=control) - def small(id: str, amount: int) -> str: - return "ok" - - @ctrlrun.protect("a.nope", control=control) - def nope() -> str: - return "ok" - - with ctrlrun.context(agent="ag"): - small(id="1", amount=5) - try: - nope() - except ActionDenied: - pass - else: - raise AssertionError("the deny rule did not deny") - try: - small(id="2", amount=500) - except ApprovalRequired: - pass - else: - raise AssertionError("the approve rule did not ask") - - written = len(list(store.receipts())) - assert written == 2, f"three calls, {written} receipts — the shape of this claim changed" - - forbidden = re.compile(r"every (?:`?tools/call`?|call) (?:leaves|has) a receipt", re.I) - wrong = [] - for page in PAGES: - for line in _prose(page).splitlines(): - found = forbidden.search(line) - if found and "reaches a decision" not in line: - wrong.append(f"{page.name}: {line.strip()[:90]!r}") - assert wrong == [], wrong - - -@pytest.mark.parametrize( - ("opening", "closing"), - [ - ("<script", "</script>"), - ("<SCRIPT", "</SCRIPT>"), - ("<script", "</script >"), - ("<script", "</ script>"), - ("<script", "</SCRIPT\n>"), - ("<script", "</script bar>"), - ("< script", "</script\t\n bar>"), - ], - ids=[ - "plain", - "upper-case", - "space-before-gt", - "space-after-slash", - "newline", - "attribute-like-text", - "space-in-start-tag-and-junk-in-end-tag", - ], -) -def test_the_prose_filter_strips_a_script_block_however_its_tags_are_written( - tmp_path: Path, opening: str, closing: str -): - """Every spelling of the tags closes the same block, and the word budget must see none of it. - - HTML tag names are case-insensitive and an end tag may carry whitespace before its `>`. A - filter that misses a spelling leaves the block in the text, where a structured-data payload - -- markup for a search engine, not words a reader reads -- is counted against the page's - budget and can push a page over it for a reason no author could see. - """ - page = tmp_path / "page.mdx" - page.write_text( - f'---\ntitle: t\n---\n\nvisible prose\n\n{opening} type="application/ld+json">\n' - f'{{"@type": "SoftwareApplication", "hidden": "wordone wordtwo"}}\n{closing}\n', - encoding="utf-8", - ) - - prose = _prose(page) - - assert "visible prose" in prose - assert "wordone" not in prose, f"{opening} ... {closing} reached the word budget" diff --git a/tests/test_docs_travelling.py b/tests/test_docs_travelling.py deleted file mode 100644 index e0bcc61..0000000 --- a/tests/test_docs_travelling.py +++ /dev/null @@ -1,511 +0,0 @@ -"""The three pages meant to travel: the browser demo, the study, and the badge. - -Each makes a claim that is easy to fake and expensive to get wrong, so each is held to what it -rests on: the browser demo to the harness that proved it runs, the study to the published -results and nothing else, and the badge page to the exact phrase the badge means. -""" - -from __future__ import annotations - -import json -import re -import sys -from pathlib import Path - -import pytest - -REPO_ROOT = Path(__file__).resolve().parents[1] -DOCS = REPO_ROOT / "docs" -TOOLS = REPO_ROOT / "tools" / "docs_audit" - -if not (DOCS / "docs" / "try-it.mdx").exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout", allow_module_level=True) - -sys.path.insert(0, str(TOOLS)) - -import render_probe # noqa: E402 - -#: `MANIFEST.in` prunes `research/` from the distributions, and two release guards assert it -#: is absent, so from inside an sdist there are no published results to render the study page -#: from. The page is edited in a checkout, which is where these two run; CI's `check` job and -#: every developer run are checkouts. -IN_CHECKOUT = (REPO_ROOT / "research" / "framework-probe" / "results").is_dir() -needs_results = pytest.mark.skipif( - not IN_CHECKOUT, - reason="no research/framework-probe/results: the distributions prune it by design", -) - -TRY_IT = (DOCS / "docs" / "try-it.mdx").read_text(encoding="utf-8") -SCRIPT = (DOCS / "try-it.js").read_text(encoding="utf-8") -HARNESS = (DOCS / "assets" / "verify-browser-demo.mjs").read_text(encoding="utf-8") -BADGE = (DOCS / "docs" / "verify" / "get-the-badge.mdx").read_text(encoding="utf-8") - - -# --- the browser demo ---------------------------------------------------------------------- - - -def test_the_page_the_script_and_the_harness_name_one_pyodide_build(): - """The page says which build it was verified against; the script loads that build; the - harness is what verified it. Three places, one version, or the page is describing something - nobody ran.""" - versions = set(re.findall(r"v?(\d+\.\d+\.\d+)", SCRIPT.split("PYODIDE =")[1].split("\n")[0])) - assert len(versions) == 1, versions - version = versions.pop() - - assert version in TRY_IT, f"the page does not name Pyodide {version}" - assert version in HARNESS, f"the harness does not name Pyodide {version}" - - -def test_the_script_does_nothing_unless_the_page_mounts_it(): - """Mintlify includes every .js file on every page and cannot scope one, so the script must - find its container or return. Without this it would run on the whole site.""" - assert "getElementById(CONTAINER)" in SCRIPT - assert "if (!container" in SCRIPT - container = re.search(r'CONTAINER = "([^"]+)"', SCRIPT).group(1) - assert f'id="{container}"' in TRY_IT, ( - "the page does not mount the container the script looks for" - ) - - -def test_the_script_does_not_load_sqlite3_as_a_package(): - """The one thing that failed the first time: sqlite3 is bundled into Pyodide 314 and is not - a loadable package, so passing it to loadPackage throws before anything runs.""" - packages = re.search(r"PACKAGES = \[([^\]]*)\]", SCRIPT).group(1) - - assert "sqlite3" not in packages - assert "micropip" in packages and "pyyaml" in packages - assert "sqlite3" in HARNESS, "the harness no longer proves sqlite3 is there" - - -def test_the_script_wires_itself_after_the_page_renders(): - """The site is a single-page app: the script runs once, before React paints the container, - and not again on a client-side navigation. Wiring only on DOMContentLoaded left the button - dead on the deployed site, so the script watches the DOM as well. - `docs/assets/verify-browser-wiring.mjs` proves both halves against a real DOM.""" - assert "MutationObserver" in SCRIPT - assert "subtree: true" in SCRIPT - assert (DOCS / "assets" / "verify-browser-wiring.mjs").exists() - - -def test_the_page_tells_a_reader_what_to_do_when_it_does_not_run(): - """A page that can fail in somebody's browser owes them the command that always works. - - Asserted with the line wrapping removed: a sentence that reads correctly and wraps across - two lines is still the sentence, and a test that could not see it would push prose onto one - long line. - """ - assert "pip install ctrlrun && ctrlrun demo" in TRY_IT - assert "pip install ctrlrun && ctrlrun demo" in SCRIPT - assert "That is this page failing, not the library." in " ".join(TRY_IT.split()) - - -VERIFIED = json.loads((DOCS / "assets" / "browser-demo.verified.json").read_text(encoding="utf-8")) - - -def test_the_page_says_it_runs_the_released_version_and_where_the_proof_is(): - assert "verify-browser-demo.mjs" in TRY_IT - assert "released version" in TRY_IT - - -def test_the_page_quotes_the_run_the_harness_recorded(): - """`browser-demo.verified.json` is written by the harness at the end of a run that passed, - and it is the only source for the numbers the page quotes: the date, the Pyodide, Python - and SQLite versions in the "Verified" paragraph, and the `ctrlrun X on Python Y` line at - the top of the transcript. A page that quoted a version nothing had run would be the copy - problem again, one level up.""" - for key in ("date", "pyodide", "python", "sqlite", "ctrlrun"): - assert VERIFIED.get(key), f"browser-demo.verified.json has no {key}" - verified = TRY_IT.split("Verified, and how to check", 1)[1].split("</Accordion>", 1)[0] - assert f"**{VERIFIED['date']}**" in verified, "the page's verified date is not the run's" - assert f"Pyodide {VERIFIED['pyodide']}" in verified - assert f"Python {VERIFIED['python']}" in verified - assert f"SQLite {VERIFIED['sqlite']}" in verified - assert f"`ctrlrun` {VERIFIED['ctrlrun']} from PyPI" in verified - transcript = TRY_IT.split("```text", 1)[1].split("```", 1)[0] - assert transcript.strip().startswith( - f"ctrlrun {VERIFIED['ctrlrun']} on Python {VERIFIED['python']}" - ), transcript.strip().splitlines()[0] - assert f"Last run {VERIFIED['date']}" in HARNESS, "the harness comment names another run" - assert "browser-demo.verified.json" in HARNESS - - -def _python_in_the_script(name: str) -> str: - """One of the Python programs the Try-it page runs, lifted out of the JavaScript.""" - body = re.search(rf"var {name} = \[(.*?)\]\.join", SCRIPT, re.S) - assert body, f"docs/try-it.js: no {name} array — the page's Python moved" - try: - lines = json.loads(f"[{body.group(1)}]") - except json.JSONDecodeError as exc: # pragma: no cover - a malformed array is the failure - raise AssertionError( - f"docs/try-it.js: {name} is no longer JSON-parseable ({exc}). Keep it to " - "double-quoted strings with no comment inside the array and no trailing comma: " - "verify-browser-demo.mjs parses it the same way." - ) from exc - return "\n".join(lines) - - -def _browser_demo_program() -> str: - return _python_in_the_script("PROGRAM") - - -def _playground_module() -> str: - return _python_in_the_script("PLAYGROUND") - - -def test_the_browser_demo_program_is_valid_python(): - """The page's Python is a string inside a JavaScript file, which nothing else compiles. - - It shipped ending a line on a trailing `+` outside brackets. That is a SyntaxError, so - every reader who pressed the button got a traceback where the demo should have been, and - both harnesses stayed green: the wiring one stubs Pyodide, and the demo one carried its own - copy of the program. This compiles the string the page actually runs, on every commit, - with no network and no Node. - """ - program = _browser_demo_program() - compile(program, "docs/try-it.js PROGRAM", "exec") - - -def test_the_program_ends_on_an_expression_pyodide_can_return(): - """`runPython` returns the value of the last expression. An assignment there returns - `None`, and the page would reveal an empty transcript with nothing raised.""" - last = _browser_demo_program().rstrip().splitlines()[-1] - assert not last.startswith((" ", "\t")), f"the last line is indented, not a value: {last!r}" - assert re.match(r"^\w+\s*=[^=]", last) is None, f"the last line assigns: {last!r}" - assert "buffer.getvalue()" in last, f"the last line does not return the demo: {last!r}" - - -def test_the_transcript_box_scrolls_down_rather_than_growing(): - """A `min-height` with no `max-height` is a box that can only get taller. - - That is what shipped. The transcript grew the page instead of scrolling, `scrollTop` - stayed 0 so the script's follow-the-newest-line was dead code, and the only scrollbar the - reader got was the horizontal one the long lines need. Measured in a browser at 820px: the - box grew to 910px with `scrollHeight == clientHeight`. With both bounds it holds at 452px - and scrolls to 458. - """ - style = re.search(r"<pre\s*\n\s*style=\{\{(.*?)\}\}", TRY_IT, re.S) - assert style, "docs/docs/try-it.mdx: the transcript box is no longer a <pre> with inline style" - box = dict(re.findall(r"(\w+):\s*\"([^\"]*)\"", style.group(1))) - - assert "maxHeight" in box, "minHeight without maxHeight is a box that can only grow" - assert box.get("overflowY") == "auto", "the box cannot scroll vertically" - assert box.get("overflowX") == "auto", "the long lines must scroll inside the box" - assert box.get("whiteSpace") == "pre", "the demo's columns are aligned; do not wrap them" - - -def test_the_transcript_does_not_depend_on_how_the_theme_lays_the_box_out(): - """The site's theme sets `display: flex` on this `<pre>`, and we do not own that rule. - - In a flex container every appended child is a flex item in a *row*, so a reveal that - appended a node per line laid the whole transcript out sideways: measured on the deployed - page, all five refusals sat at the same y and the box scrolled 6530px wide against a 529px - frame. `say` never hit it, because setting `textContent` makes one item however the box is - laid out. So the lines go inside a single block child, which is one flex item, and the - page also asks for `display: block`. Either alone fixes it; both together mean a theme - that changes its mind cannot put the transcript in a row again. - """ - assert 'body.style.display = "block"' in SCRIPT - assert "output.appendChild(body)" in SCRIPT, "the transcript needs one container child" - assert "body.appendChild(node)" in SCRIPT - assert "output.appendChild(node)" not in SCRIPT, "a line appended straight into the <pre>" - - style = re.search(r"<pre\s*\n\s*style=\{\{(.*?)\}\}", TRY_IT, re.S) - assert style, "docs/docs/try-it.mdx: the transcript box is no longer a <pre> with inline style" - box = dict(re.findall(r"(\w+):\s*\"([^\"]*)\"", style.group(1))) - assert box.get("display") == "block", "the theme's flex would lay the lines out in a row" - - -def test_the_reveal_follows_the_newest_line_only_for_a_reader_at_the_bottom(): - """Following the output is right until somebody scrolls up to re-read, and then it is - yanking them away from what they are reading.""" - assert "output.scrollHeight - output.scrollTop - output.clientHeight" in SCRIPT - assert "if (following) output.scrollTop = output.scrollHeight;" in SCRIPT - - -def test_the_harness_runs_the_program_the_page_runs(): - """A harness with its own copy of the artifact verifies the copy. This one reads - docs/try-it.js, so the program it proves is the program the reader gets.""" - assert "try-it.js" in HARNESS, "the harness no longer reads the page's script" - assert "runPython(PROGRAM)" in HARNESS - assert "run_demo(" not in HARNESS, "the harness has grown its own copy of the program again" - - -# --- the playground ------------------------------------------------------------------------ - - -def _playground_step(): - """`step`, from the module the page runs, executed here against the checkout's ctrlrun. - - The page's JavaScript owns the DOM and nothing else: every outcome a reader sees is the JSON - this function returns. So the sequence the page tells the reader to try is run here, natively, - and each outcome asserted — with no Node, no Pyodide and no network. This is the third check - the page describes, and it exists because the first two once both stayed green while the - page's own copy of the Python was broken. - """ - namespace: dict[str, object] = {} - exec(compile(_playground_module(), "docs/try-it.js PLAYGROUND", "exec"), namespace) - step = namespace["step"] - - def call(**request): - return json.loads(step(json.dumps(request))) - - return call - - -def test_the_playground_module_is_valid_python_and_defines_step(): - namespace: dict[str, object] = {} - exec(compile(_playground_module(), "docs/try-it.js PLAYGROUND", "exec"), namespace) - assert callable(namespace.get("step")) - - -def test_the_playground_runs_the_sequence_the_page_tells_the_reader_to_try(): - """Steps 1 to 6 of "Try this, in order", each outcome as the page states it.""" - step = _playground_step() - - # 1. €500 on txn_1: allowed and committed. - first = step(op="refund", payment_id="txn_1", amount=50000, lose_reply=False) - assert first["outcome"] == "executed", first - assert first["receipt"]["decision"] == "allow" - assert first["receipt"]["result"] == "committed" - assert first["remote_calls"] == 1 - - # 2. €2,000 on txn_2: a human decides; approve; €5,000 on it is refused; €2,000 executes. - asked = step(op="refund", payment_id="txn_2", amount=200000, lose_reply=False) - assert asked["outcome"] == "approval_required", asked - assert asked["remote_calls"] == 0 - granted = step(op="approve", request_id=asked["request_id"]) - assert granted["approval_id"] == asked["request_id"] - assert granted["action_hash"].startswith("sha256:") - mutated = step(op="refund", payment_id="txn_2", amount=500000, approval_id=asked["request_id"]) - assert mutated["outcome"] == "approval_mismatch", mutated - assert mutated["reason"] == "mismatch" - assert mutated["remote_calls"] == 0, "the mutated amount reached the remote" - assert mutated["receipt"]["result"] == "blocked" - approved = step(op="refund", payment_id="txn_2", amount=200000, approval_id=asked["request_id"]) - assert approved["outcome"] == "executed", approved - assert approved["receipt"]["decision"] == "approve" - assert approved["receipt"]["approval_id"] == asked["request_id"] - assert approved["remote_calls"] == 1 - - # 3. The same approval presented again: consumed. - replayed = step(op="refund", payment_id="txn_2", amount=200000, approval_id=asked["request_id"]) - assert replayed["outcome"] == "approval_mismatch", replayed - assert replayed["reason"] == "consumed" - assert replayed["remote_calls"] == 1 - - # 4. €20,000 on txn_3: denied, and no request was created. - denied = step(op="refund", payment_id="txn_3", amount=2000000, lose_reply=False) - assert denied["outcome"] == "denied", denied - assert "request_id" not in denied - assert denied["remote_calls"] == 0 - assert denied["receipt"]["result"] == "denied" - - # 5. €500 on txn_4 with the reply lost: AMBIGUOUS; the retry is refused; one remote call. - lost = step(op="refund", payment_id="txn_4", amount=50000, lose_reply=True) - assert lost["outcome"] == "reply_lost", lost - assert lost["receipt"]["result"] == "ambiguous" - assert lost["remote_calls"] == 1 - retried = step(op="refund", payment_id="txn_4", amount=50000, lose_reply=False) - assert retried["outcome"] == "ambiguous_retry", retried - assert retried["remote_calls"] == 1, "the blind retry reached the remote" - assert retried["receipt"]["result"] == "blocked" - - # 6. €500 on txn_1 again: the effect already happened. - duplicate = step(op="refund", payment_id="txn_1", amount=50000, lose_reply=False) - assert duplicate["outcome"] == "duplicate", duplicate - assert duplicate["remote_calls"] == 1 - - -def test_the_playground_refuses_a_negative_amount_as_the_policy_says(): - """Both ends of every band are bound; a refund of a negative amount is a charge.""" - step = _playground_step() - charged = step(op="refund", payment_id="txn_1", amount=-500, lose_reply=False) - assert charged["outcome"] == "denied", charged - assert charged["remote_calls"] == 0 - - -def test_the_playground_has_no_way_to_grant_but_the_human_button(): - """No auto-approve, no dry run, no flag: the only path to a grant is `op: approve` with a - request id, which is `grant_approval` on the store — the write `ctrlrun approve` makes.""" - module = _playground_module() - assert "grant_approval(" in module - assert module.count("grant_approval(") == 1 - for forbidden in ("auto_approve", "dry_run", "ScriptedApprovalProvider", "mode"): - assert forbidden not in module, forbidden - step = _playground_step() - with pytest.raises(Exception): # noqa: B017 - an unknown request id is not a grant - step(op="approve", request_id="apr_0000") - - -def test_the_playground_policy_on_the_page_is_the_policy_in_the_module(): - """The page shows a YAML block and the module carries one; a reader reasons from the block - they can see, so the two are held equal rather than described as equal.""" - module = _playground_module() - in_module = re.search(r'POLICY = """\n(.*?)"""', module, re.S) - assert in_module, "the module no longer carries POLICY as a triple-quoted string" - shown = TRY_IT.split("```yaml", 1)[1].split("```", 1)[0] - - assert shown.strip() == in_module.group(1).strip() - - -def test_the_page_names_every_outcome_the_module_can_return(): - """Each `outcome` the module reports has the line the page tells the reader to expect.""" - module = _playground_module() - outcomes = set(re.findall(r'result\["outcome"\] = "(\w+)"', module)) - assert outcomes == { - "executed", - "approval_required", - "approval_mismatch", - "denied", - "duplicate", - "ambiguous_retry", - "reply_lost", - } - for exception in ( - "ApprovalRequired", - "ApprovalMismatch", - "ActionDenied", - "DuplicateEffect", - "AmbiguousEffect", - "AMBIGUOUS", - "consumed", - ): - assert exception in TRY_IT, exception - assert 'case "' in SCRIPT - for outcome in outcomes: - assert f'case "{outcome}":' in SCRIPT, f"the page has no branch for {outcome}" - - -def test_the_playground_wires_every_control_the_page_mounts(): - playground = re.search(r'PLAYGROUND_ID = "([^"]+)"', SCRIPT).group(1) - assert f'id="{playground}"' in TRY_IT - for name in ("amount", "payment_id", "lose_reply", "run", "approve"): - assert f'name="{name}"' in TRY_IT, name - assert f'[name="{name}"]' in SCRIPT, f"the script never selects {name}" - assert "runPython(PLAYGROUND)" in SCRIPT - assert "runPython(PLAYGROUND)" in HARNESS, "the harness does not run the playground" - assert "step(" in HARNESS - - -@pytest.mark.authority -def test_the_page_quotes_lines_the_demo_prints(): - """The transcript on the page is the demo's own output, not a sketch of it. - - Generated ids are masked as `apr_…` and `dlg_…` on the page, so each quoted line is - compared up to where its id begins — the same masking the README's own verbatim test does, - for the same reason: ids differ per run and everything else must not. - """ - from click.testing import CliRunner - - from ctrlrun.cli.main import main - - with CliRunner().isolated_filesystem(): - result = CliRunner().invoke(main, ["demo"]) - assert result.exit_code == 0, result.output - printed = [line.rstrip() for line in result.output.splitlines() if line.strip()] - - quoted = TRY_IT.split("```text", 1)[1].split("```", 1)[0] - checked = 0 - for line in quoted.splitlines(): - if not line.strip() or line.startswith("ctrlrun "): - continue - prefix = re.split(r"(?:apr|dlg)_…", line)[0].rstrip() - checked += 1 - assert any(actual.startswith(prefix) for actual in printed), line - assert checked > 15, f"only {checked} transcript lines checked" - - -# --- the study ----------------------------------------------------------------------------- - - -@needs_results -def test_the_study_page_is_the_render_of_the_published_results(): - assert render_probe.main(["--check"]) == 0 - - -@needs_results -def test_the_study_page_names_no_framework_the_harness_did_not_run(): - """The rule this page exists under: never populated from unrun adapters. CrewAI and AutoGen - have adapters and were never executed, so they appear only under 'Not run'.""" - page = render_probe.TARGET.read_text(encoding="utf-8") - table = page.split("| Framework |", 1)[1].split("\n\n", 1)[0] - - found = render_probe.latest() - assert found is not None, "there is a results file; this test is about what it contains" - _, document = found - unrun = {entry["framework"] for entry in document["results"] if render_probe.unrun(entry)} - assert unrun, "the fixture no longer contains an unrun adapter; this guard is unexercised" - - for framework in unrun: - assert framework not in table, f"{framework} was never run and is in the table" - assert f"**{framework}**" in page.split("### Not run", 1)[1], framework - - -def test_the_study_page_says_no_published_results_when_there_are_none(monkeypatch, tmp_path): - """The page renders honestly on a repository with no run at all.""" - monkeypatch.setattr(render_probe, "RESULTS", tmp_path) - text = render_probe.render() - - assert render_probe.NO_RESULTS in text - assert "| Framework |" not in text - - -@needs_results -def test_the_study_page_quotes_the_fairness_rules_and_links_the_harness(): - page = render_probe.TARGET.read_text(encoding="utf-8") - - assert "behaviour, not quality" in page - assert "## The fairness rules" in page - assert len(render_probe.FAIRNESS) == 6 - for rule in render_probe.FAIRNESS: - assert rule in page - assert "research/framework-probe/README.md" in page - - -# --- the badge ----------------------------------------------------------------------------- - - -def test_the_badge_page_uses_the_exact_phrase_and_explains_n_a(): - assert "declared guarantees pass" in BADGE - assert "Not applicable is not a pass" in BADGE - assert "does not mean secure, safe, compliant, certified or audited" in BADGE - - -def test_the_badge_page_keeps_the_write_permission_where_it_belongs(): - """The action writes the badge and never publishes it. A page that told a reader to give the - whole workflow `contents: write` would undo the reason for that.""" - assert "permissions:\n contents: write" in BADGE - assert "github.event_name == 'push'" in BADGE - assert "this job only" in BADGE - - -def test_the_badge_page_has_no_empty_gallery(): - """A gallery of repositories carrying the badge appears when one exists. Until then the - section is absent, not empty: an empty one is worse than none.""" - for word in ("gallery", "Gallery", "trusted by", "Used by", "Adopters"): - assert word not in BADGE, f"the badge page has a {word!r} section with nothing in it" - - -def test_all_three_pages_are_in_the_navigation_and_the_search_plan(): - document = json.loads((DOCS / "docs.json").read_text(encoding="utf-8")) - plan = (DOCS / "SEO.md").read_text(encoding="utf-8") - found: set[str] = set() - - def walk(node: object) -> None: - if isinstance(node, str): - found.add(node) - elif isinstance(node, list): - for item in node: - walk(item) - elif isinstance(node, dict): - for value in node.values(): - walk(value) - - walk(document["navigation"]) - for slug in ( - "docs/try-it", - "docs/verify/get-the-badge", - "docs/study/does-your-framework-double-execute", - ): - assert slug in found, f"{slug} is not in docs.json" - assert f"`{slug}`" in plan, f"{slug} has no row in docs/SEO.md" diff --git a/tests/test_examples.py b/tests/test_examples.py index 8b20845..407b1f6 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -40,7 +40,7 @@ } #: Directories under `examples/` that are not one of §1.1's failure scenarios: the sector -#: templates, and item 8's ACS integration example (SPEC-v0.2 §9, `docs/docs/ACS.md`). +#: templates, and item 8's ACS integration example (SPEC-v0.2 §9, `https://ctrlrun.dev/docs/ACS`). NOT_A_SCENARIO = ( "policies", "acs", @@ -113,45 +113,6 @@ "aligned with", ) -_REFUSE_EVERY_SOCKET = '''\ -"""Imported by `site` at startup: nothing under examples/ may open a socket.""" - -import socket - -_real = socket.socket - - -class _Refusing(_real): - """A socket that exists but will not connect, which is what a cut cable looks like. - - Replacing the *type* with a function breaks anything that subclasses it — `ssl` does — - so the refusal goes on the operations instead. - """ - - def connect(self, *args, **kwargs): - raise RuntimeError("an example tried to connect; examples must run with no network") - - def connect_ex(self, *args, **kwargs): - raise RuntimeError("an example tried to connect; examples must run with no network") - - -def _refuse(*args, **kwargs): - raise RuntimeError("an example tried to resolve a name; examples run with no network") - - -socket.socket = _Refusing -socket.create_connection = _refuse -socket.getaddrinfo = _refuse -''' - - -@pytest.fixture(scope="session") -def no_network(tmp_path_factory): - """A `PYTHONPATH` entry whose `sitecustomize` refuses every socket (SPEC-v0.2 §1.1).""" - directory = tmp_path_factory.mktemp("no-network") - (directory / "sitecustomize.py").write_text(_REFUSE_EVERY_SOCKET, encoding="utf-8") - return directory - def _run(scenario: str, cwd: Path, no_network: Path) -> subprocess.CompletedProcess[str]: environment = dict(os.environ) diff --git a/tests/test_framework_probe.py b/tests/test_framework_probe.py index 4a0f656..88d5408 100644 --- a/tests/test_framework_probe.py +++ b/tests/test_framework_probe.py @@ -546,8 +546,8 @@ def test_no_top_level_document_claims_the_harness_was_run_against_a_framework(): checked = [ "README.md", "CHANGELOG.md", - "docs/docs/verify.md", - "docs/docs/OWASP-AGENTIC-TOP10.md", + "https://ctrlrun.dev/docs/verify", + "https://ctrlrun.dev/docs/OWASP-AGENTIC-TOP10", ] offending = [] diff --git a/tests/test_medical_workbench.py b/tests/test_medical_workbench.py deleted file mode 100644 index 73b914f..0000000 --- a/tests/test_medical_workbench.py +++ /dev/null @@ -1,130 +0,0 @@ -"""Exercise the actual Python used by the Medical Affairs browser workbench.""" - -import copy -import json -import re -import runpy -from pathlib import Path - -import pytest - -ROOT = Path(__file__).resolve().parents[1] -SOURCE = ROOT / "examples/medical_workbench.py" - - -@pytest.fixture -def workbench(): - module = runpy.run_path(str(SOURCE)) - snapshot = { - "inquiry": "DEMO-001", - "version": 1, - "validationVersion": 1, - "destination": "Internal medical review archive", - "sources": copy.deepcopy(module["SOURCES"]), - "claims": [ - {"id": key, "source": item[0], "span": item[1], "text": item[2][0]} - for key, item in module["CLAIMS"].items() - ], - } - - def call(op, **extra): - return json.loads(module["step"](json.dumps({"op": op, "snapshot": snapshot, **extra}))) - - return snapshot, call - - -def test_browser_and_local_example_execute_identical_python(): - script = (ROOT / "docs/medical-workbench.js").read_text() - encoded = re.search(r'var MODULE = (\[.*?\])\.join\("\\n"\);', script, re.S) - assert encoded - assert "\n".join(json.loads(encoded[1])) == SOURCE.read_text().rstrip("\n") - - -def test_reviewed_document_releases_and_produces_real_receipts(workbench): - _, call = workbench - assert call("validate")["validation"]["passed"] - assert call("release")["outcome"] == "approval_required" - assert call("approve")["outcome"] == "review_required" - approved = call("approve", reviewed=True) - assert approved["outcome"] == "approved" - assert approved["action_hash"].startswith("sha256:") - released = call("release") - assert released["outcome"] == "committed" - assert released["writes"] == 1 - assert released["effect_state"] == "COMMITTED" - assert released["receipts"][-1]["approval_id"] == approved["approval_id"] - assert released["receipts"][-1]["action_hash"] == approved["action_hash"] - assert released["receipts"][-1]["approver"] == "human:demo-medical-reviewer" - - -def test_edited_document_cannot_use_original_approval(workbench): - snapshot, call = workbench - call("approve", reviewed=True) - snapshot["version"] = snapshot["validationVersion"] = 2 - result = call("release") - assert result["outcome"] == "approval_mismatch" - assert result["reason"] == "mismatch" - assert result["writes"] == 0 - assert call("approve", reviewed=True)["outcome"] == "approved" - assert call("release")["writes"] == 1 - - -@pytest.mark.parametrize("change", ["unsupported", "numbers", "source", "version", "destination"]) -def test_invalid_evidence_is_denied_even_with_a_client_pass_flag(workbench, change): - snapshot, call = workbench - call("approve", reviewed=True) - if change == "unsupported": - snapshot["claims"].append({"id": "C4", "text": "Prevents disease progression."}) - elif change == "numbers": - snapshot["claims"][0]["text"] = snapshot["claims"][0]["text"].replace("60%", "90%") - elif change == "source": - snapshot["sources"][0]["version"] = "Fixture 2.0" - elif change == "version": - snapshot["validationVersion"] = 0 - else: - snapshot["destination"] = "External destination" - snapshot["validation_ok"] = True - result = call("release") - assert result["outcome"] == "validation_blocked" - assert result["validation"]["issues"] - assert result["writes"] == 0 - assert result["receipts"][-1]["decision"] == "deny" - - -def test_approval_reuse_and_duplicate_effect_never_write_twice(workbench): - _, call = workbench - call("approve", reviewed=True) - call("release") - reused = call("release") - assert reused["outcome"] == "approval_mismatch" - assert reused["reason"] == "consumed" - assert reused["writes"] == 1 - call("approve", reviewed=True) - duplicate = call("release") - assert duplicate["outcome"] == "duplicate" - assert duplicate["writes"] == 1 - - -def test_unknown_delivery_remains_ambiguous_until_destination_confirmation(workbench): - _, call = workbench - call("approve", reviewed=True) - lost = call("release", lose_reply=True) - assert lost["outcome"] == "reply_lost" - assert lost["effect_state"] == "AMBIGUOUS" - assert lost["writes"] == 1 - call("approve", reviewed=True) - retry = call("release") - assert retry["outcome"] == "ambiguous_retry" - assert retry["effect_state"] == "AMBIGUOUS" - assert retry["writes"] == 1 - resolved = call("reconcile") - assert resolved["outcome"] == "reconciled" - assert resolved["effect_state"] == "COMMITTED" - assert resolved["writes"] == 1 - - -def test_reconciliation_never_invents_a_delivery(workbench): - _, call = workbench - result = call("reconcile") - assert result["outcome"] == "nothing_to_reconcile" - assert result["writes"] == 0 diff --git a/tests/test_owasp_mapping.py b/tests/test_owasp_mapping.py deleted file mode 100644 index f603d81..0000000 --- a/tests/test_owasp_mapping.py +++ /dev/null @@ -1,212 +0,0 @@ -"""`docs/docs/OWASP-AGENTIC-TOP10.md`. SPEC-v0.4 §6; T121. - -The mapping is complete in **both** directions, and the second direction is the one that makes -the first credible: every entry with no guarantee is listed by name under "Not covered by -CTRLRun", so a reader can see the size of what is left out without counting rows. -""" - -from __future__ import annotations - -import re -from pathlib import Path - -import pytest - -from ctrlrun.verify import guarantees as reg - -REPO_ROOT = Path(__file__).resolve().parents[1] -MAPPING = REPO_ROOT / "docs" / "docs" / "OWASP-AGENTIC-TOP10.md" -README = REPO_ROOT / "README.md" -VERIFY_DOC = REPO_ROOT / "docs" / "docs" / "verify.md" - -#: The edition this document is written against, as recorded in it. Derived from the -#: OWASP-owned `OWASP/secure-agent-playbook` repository and corroborated against two -#: independent third-party summaries; the published PDF is behind a download form, which the -#: document says in as many words rather than implying a reading nobody made. -EDITION = "2026" -ENTRIES = { - "ASI01:2026": "Agent Goal Hijack", - "ASI02:2026": "Tool Misuse", - "ASI03:2026": "Identity & Privilege Abuse", - "ASI04:2026": "Agentic Supply Chain Vulnerabilities", - "ASI05:2026": "Unexpected Code Execution", - "ASI06:2026": "Memory & Context Poisoning", - "ASI07:2026": "Insecure Inter-Agent Communication", - "ASI08:2026": "Cascading Failures", - "ASI09:2026": "Human-Agent Trust Exploitation", - "ASI10:2026": "Rogue Agents", -} - -#: §6.1 — every ASI code in the document has to look like one, so a typo is not silently a -#: new entry. -CODE = re.compile(r"ASI\d{2}:\d{4}") - -#: `v0.2 §10` T31's list, unchanged. A mapping table presented as coverage is a compliance -#: claim wearing a table's clothes, so the same words are refused here. -COMPLIANCE_WORDS = ( - "compliant", - "compliance", - "certified", - "certification", - "accredited", - "attestation", - "conforms to", - "aligned with", -) - - -def _document() -> str: - return MAPPING.read_text(encoding="utf-8") - - -def _flat() -> str: - """The document with its line wrapping removed, so a phrase can be asserted whole. - - A sentence that reads correctly and wraps across two lines is still the sentence; a test - that could not see it would be a test that pushes prose into one long line to satisfy it. - """ - return " ".join(_document().split()) - - -def _sections() -> tuple[str, str]: - """The mapping table and the `Not covered by CTRLRun` half, as text.""" - text = _document() - split = text.index("## Not covered by CTRLRun") - return text[:split], text[split:] - - -def _guarantee_table() -> str: - """Just the `Guarantee -> entries mitigated` table. - - Narrower than `_sections()[0]` on purpose. That half opens with the enumeration of all ten - entries, so every code is in it and a membership test against it says nothing. What says - something is whether a code is cited by a guarantee row. - """ - text = _document() - start = text.index("## Guarantee") - return text[start : text.index("## Not covered by CTRLRun")] - - -# --- T121: the mapping is complete in both directions -------------------------------------- - - -def test_T121_every_guarantee_in_the_registry_appears_in_the_mapping(): - mapping, _ = _sections() - - for guarantee in reg.GUARANTEES: - assert f"**{guarantee.id}**" in mapping, guarantee.id - assert guarantee.title in mapping, guarantee.id - - -def test_T121_every_code_in_the_document_is_one_of_the_ten_in_the_cited_edition(): - found = set(CODE.findall(_document())) - - assert found, "the document names no entry at all" - assert found <= set(ENTRIES), sorted(found - set(ENTRIES)) - for code in found: - assert CODE.fullmatch(code), code - - -def test_T121_every_entry_in_the_cited_edition_appears_in_one_half_or_the_other(): - """None appears in neither. An entry silently absent would read as covered.""" - mapping, not_covered = _sections() - - for code in ENTRIES: - assert code in mapping or code in not_covered, code - - -def test_T121_the_three_uncovered_entries_are_listed_by_name(): - """§6.1's disclaimer says three of the ten are not addressed at all, and this is the test - that keeps that sentence true rather than merely written. - - `code in not_covered` on its own does not say it: a *partly* addressed entry appears in - that half too, by the design the next test asserts, so the membership check cannot tell - the two apart and the sentence was carrying this test alone. What separates them is that a - fully uncovered entry is cited by **no guarantee row** — which is a test against the - guarantee table and not against the half containing it, since that half opens by - enumerating all ten. - """ - _, not_covered = _sections() - - fully_uncovered = {"ASI04:2026", "ASI05:2026", "ASI07:2026"} - for code in fully_uncovered: - assert code in not_covered, code - assert ENTRIES[code] in not_covered, code - assert code not in _guarantee_table(), code - assert "Three of the ten entries are not addressed by CTRLRun at all" in _flat() - - -def test_T121_a_partly_addressed_entry_appears_in_both_halves(): - """§6.2 item 4 — the honest place for a hedge is next to the thing it qualifies.""" - mapping, not_covered = _sections() - - for code in ("ASI01:2026", "ASI06:2026", "ASI09:2026"): - assert code in mapping, code - assert code in not_covered, code - assert "Not covered" in not_covered - - -def test_T121_every_entry_title_is_the_one_the_cited_edition_uses(): - document = _document() - - for code, title in ENTRIES.items(): - if code not in document: - continue - # The title has to appear somewhere the code does, so a code cannot drift onto a - # different entry's sentence without the pair going out of step. - assert title in document, (code, title) - - -def test_T121_the_document_makes_no_compliance_claim(): - text = _document().lower() - - for word in COMPLIANCE_WORDS: - if word not in text: - continue - # The disclaimer names the words in order to refuse them. Every occurrence has to sit - # in a paragraph that does. - offending = [ - paragraph - for paragraph in _document().split("\n\n") - if word in paragraph.lower() - and not any(marker in paragraph.lower() for marker in ("not ", "never", "no ")) - ] - assert not offending, f"{word!r} used as a claim: {offending}" - - -def test_T121_the_first_line_before_any_table_is_the_disclaimer(): - text = _document() - first_table = text.index("|") - - disclaimer = " ".join(text[:first_table].split()) - assert "is a **reading** of somebody else's taxonomy" in disclaimer - assert "not a compliance claim" in disclaimer - - -def test_T121_the_edition_and_the_date_it_was_read_are_recorded(): - text = _document() - - assert EDITION in text - assert "2025-12-09" in text - assert "2026-09-04" in text - assert "genai.owasp.org" in text - # And how the codes were derived, because the published PDF could not be retrieved and - # saying so is the difference between a citation and a claim. - assert "could not be retrieved" in _flat() - assert "secure-agent-playbook" in text - - -@pytest.mark.parametrize("guarantee", reg.GUARANTEES, ids=lambda g: g.id) -def test_T121_every_guarantee_row_names_at_least_one_entry(guarantee): - mapping, _ = _sections() - row = next(line for line in mapping.split("\n") if line.startswith(f"| **{guarantee.id}**")) - - assert CODE.search(row), guarantee.id - - -# --- linked from where a reader will be ----------------------------------------------------- - - -def test_the_mapping_is_linked_from_the_readme_and_from_the_verify_page(): - assert "OWASP-AGENTIC-TOP10.md" in README.read_text(encoding="utf-8") - assert "OWASP-AGENTIC-TOP10.md" in VERIFY_DOC.read_text(encoding="utf-8") diff --git a/tests/test_packaging.py b/tests/test_packaging.py index 67891f0..e6c7378 100644 --- a/tests/test_packaging.py +++ b/tests/test_packaging.py @@ -426,7 +426,8 @@ def test_the_manifest_check_would_notice_a_file_it_does_not_ship(): def test_the_package_never_encodes_a_token(): - """`docs/docs/CLAIMS.md` — "CTRLRun issues no credential and defines no identity format". + """The claims table — "CTRLRun issues no credential and defines no identity format" + (https://ctrlrun.dev/docs/CLAIMS). A claim in the README needs a test, and this one is structural: the package verifies tokens and never mints one, so no module may call `jwt.encode`, and only `jwt_identity` @@ -444,29 +445,6 @@ def test_the_package_never_encodes_a_token(): assert not minting, f"the package appears to sign a token: {minting}" -def test_every_test_docs_claims_cites_exists(): - """`docs/docs/CLAIMS.md` maps every README sentence to the test that proves it, and a citation - naming a test that does not exist is the same false claim the file exists to prevent. - - It has been regenerated by hand at three releases now, and the names drift: a test gets - renamed, the row keeps the old one, and the table reads as evidence while pointing at - nothing. This is cheap and it is the only thing standing between the two. - """ - - claims = REPO_ROOT / "docs" / "docs" / "CLAIMS.md" - if not claims.exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout") - cited = set(re.findall(r"`(test_[A-Za-z0-9_]+)`", claims.read_text(encoding="utf-8"))) - defined: set[str] = set() - for path in (REPO_ROOT / "tests").glob("*.py"): - defined.update(re.findall(r"^def (test_[A-Za-z0-9_]+)", path.read_text(), re.M)) - - assert cited, "CLAIMS.md cites no tests at all, which is not a table of evidence" - assert not cited - defined, ( - f"CLAIMS.md cites tests that do not exist: {sorted(cited - defined)}" - ) - - # --- T136: `adapters/` is packaged by neither the wheel nor the sdist ----------------------- @@ -653,13 +631,13 @@ def test_the_readme_carries_no_relative_link_and_no_relative_image(): def test_the_relative_link_check_would_see_one(): """The negative test above proves nothing unless a relative link would actually fail it.""" - text = "![logo](docs/assets/logo.svg) and [docs](docs/docs/CLAIMS.md) and [ok](https://x.test)" + text = "![logo](docs/assets/logo.svg) and [spec](docs/SPEC-v0.1.md) and [ok](https://x.test)" targets = re.findall(r"\]\(([^)]+)\)", text) relative = [t for t in targets if not t.startswith(("https://", "http://", "mailto:", "#"))] - assert relative == ["docs/assets/logo.svg", "docs/docs/CLAIMS.md"] + assert relative == ["docs/assets/logo.svg", "docs/SPEC-v0.1.md"] -# --- T139: the README's adapter section, and `docs/docs/adapters.md` ----------------------------- +# --- T139: the README's adapter section, and the adapters page ----------------------------- def _readme() -> str: @@ -747,91 +725,6 @@ def test_T139_the_claim_check_can_see_a_claim(): assert _claims("No adapter describes itself as conformant.") == [] -def test_T139_docs_adapters_exists_and_leads_with_the_three_ways_in(): - path = REPO_ROOT / "docs" / "docs" / "adapters.md" - if not path.exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout") - text = path.read_text(encoding="utf-8") - - assert "You probably do not need one" in text - assert "@protect" in text and "gateway" in text - # Item 6's list is the evidence the contract was read by somebody who could not read the code. - assert "§12.10" in text - assert _claims(text) == [] - - -def test_the_claims_table_line_numbers_point_at_what_they_name(): - """The claims page says *"Line numbers refer to that tag"*, and until this test they did not: - seven of twenty-nine resolvable references had drifted by the time v0.5 was cut, pointing at - a string literal, a comment, or the middle of another function. - - A claims table is evidence, and a reference that lands on the wrong line is the same failure - as a cited test that does not exist -- which the test below this one has caught since v0.4. - Both are cheap and both are the only thing standing between the table and rot. - - Only references whose cell **names** a symbol are checked, since those are the ones that can - be resolved mechanically. A drifted line for a reference with no symbol is not caught here, - which is stated rather than left to be assumed. - """ - - claims = REPO_ROOT / "docs" / "docs" / "CLAIMS.md" - if not claims.exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout") - - text = claims.read_text(encoding="utf-8") - # `cli/main.py:400` as well as `state.py:400`. The first version's `[a-z_]+\.py` matched no - # path with a directory in it, so **every** `cli/main.py` reference was invisible to this - # guard -- and a review found two of them stale, one broken by the commit that added this - # very check to the rows beside it. A guard that cannot see a whole class of reference is - # attribution dressed as prevention. - import sys - - sys.path.insert(0, str(REPO_ROOT / "tools" / "docs_audit")) - from claims import citations - - # **One producer for "which symbol is this citation about".** `scripts/repoint-claims.py` - # writes these numbers and this checks them, and they used to answer that question - # separately: both collected the symbols of the whole *row*. So a row citing six commands - # had every reference re-pointed at one definition, and this guard accepted all six, - # because that line does define a symbol the row names. A row claiming to cite six - # commands cited one, six times, and the check said it was fine. - stale = [] - checked = 0 - for row in text.splitlines(): - for cited in citations(row): - if not cited.names: - stale.append(f"{cited.filename}:{cited.line} cites code and names no symbol") - continue - source = REPO_ROOT / "src" / "ctrlrun" / cited.filename - if not source.exists(): - continue - lines = source.read_text(encoding="utf-8").splitlines() - line = lines[cited.line - 1] if 0 < cited.line <= len(lines) else "" - checked += 1 - - # **Whole words, not substrings**, and this citation's own symbols first. A - # definition would be the strict rule and it is too strict: rows here legitimately - # cite a statement rather than a `def` -- `effect_key TEXT PRIMARY KEY` inside a - # DDL string, the branch where only `NotExecuted` maps to `FAILED`. The row's - # symbols are the documented fallback, because assigning each symbol to its nearest - # citation is a heuristic; a line matching neither is stale whichever way they were - # assigned, which is the case worth catching. - # - # The residual, stated: a named symbol appearing as a whole word *in prose* still - # satisfies this. - def names_on(line: str, names: tuple[str, ...]) -> bool: - return any(re.search(rf"\b{re.escape(name)}\b", line) for name in names) - - if not names_on(line, cited.local) and not names_on(line, cited.names): - stale.append( - f"{cited.filename}:{cited.line} is {line.strip()[:60]!r}, " - f"names {list(cited.local) or list(cited.names)}" - ) - - assert checked, "CLAIMS.md cites no code locations at all" - assert stale == [], stale - - def test_every_documented_install_names_a_distribution_this_repository_builds(): """`pip install ctrlrun-langgraph` shipped in the README of a release where no such distribution existed, so the line 404s for anyone who follows it. @@ -883,55 +776,6 @@ def test_every_documented_install_names_a_distribution_this_repository_builds(): assert unknown == [], unknown -def test_T138_item_sixs_questions_are_recorded_and_each_is_answered(): - """SPEC-v0.5 §8 T138: a third adapter was written against the contract alone, and **the list - of questions it could not answer is the deliverable**, recorded in `docs/docs/adapters.md` with - each answered by an edit to `SPEC-v0.5.md`. - - *"If the list cannot be emptied, v0.5 is not done."* So this asserts the list exists, that - every entry names where it was answered, and that the sections it names are real. The - adapter itself is disposable and is deliberately not in the repository — asserting its - existence would be asserting the wrong half. - - This test was missing when v0.5 was otherwise complete, and `docs/docs/adapters.md` carried a - summary of the list rather than the list. A summary cannot be checked against the spec. - """ - adapters = REPO_ROOT / "docs" / "docs" / "adapters.md" - spec = REPO_ROOT / "docs" / "SPEC-v0.5.md" - if not adapters.exists() or not spec.exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout") - - text = adapters.read_text(encoding="utf-8") - # The answer column is `(.*?)` and not `(.+?)` on purpose: an **empty** answer must still - # match, so the "every row says where it was answered" check below is what catches it. With - # `(.+?)` the row simply stopped being a row and the count assertion caught it instead -- - # a subsumed guard, found by mutating an answer to empty and watching the wrong test fail. - rows = re.findall(r"^\| (Q\d+) \| (.+?) \| (.+?) \|(.*?)\|$", text, re.M) - - assert len(rows) >= 14, f"item 6 raised fourteen questions; {len(rows)} are recorded" - assert [q for q, *_ in rows] == [f"Q{n}" for n in range(1, len(rows) + 1)], [ - q for q, *_ in rows - ] - - # Every row says where it was answered, and every section it names exists in the spec. - spec_text = spec.read_text(encoding="utf-8") - unanswered = [q for q, _, _, answer in rows if not answer.strip()] - assert unanswered == [], unanswered - - cited = { - section for _, _, _, answer in rows for section in re.findall(r"§(\d+(?:\.\d+)*)", answer) - } - assert cited, "no row names a section of SPEC-v0.5" - missing = [ - s for s in sorted(cited) if f"### {s} " not in spec_text and f"## {s}. " not in spec_text - ] - assert missing == [], f"rows cite sections that do not exist: {missing}" - - # The four the report called security- or correctness-critical are marked as such. - severities = {severity.strip().strip("*").lower() for _, _, severity, _ in rows} - assert "security" in severities, severities - - def test_the_throwaway_sector_configuration_ships_nowhere(): """SPEC-v0.6 §7.5, §8's T177b: *"it lives in the test suite and in no `packs/` directory, no `examples/`, and no distribution."* diff --git a/tests/test_readme_assets.py b/tests/test_readme_assets.py index 731bfd2..954337e 100644 --- a/tests/test_readme_assets.py +++ b/tests/test_readme_assets.py @@ -84,9 +84,9 @@ def test_the_wordmark_ships_for_both_themes_and_the_readme_uses_both(): "favicon.svg", ): assert "#F5A623" in (ASSETS / name).read_text(encoding="utf-8"), f"{name} lacks the accent" - for name in ("wordmark-light.svg", "wordmark-dark.svg", "favicon.svg"): - site = (REPO_ROOT / "docs" / "images" / name).read_text(encoding="utf-8") - assert site == (ASSETS / name).read_text(encoding="utf-8"), f"docs/images/{name} drifted" + # That the site's copies are byte-identical to these is checked in CTRLRun/ctrlrun-docs, + # by `test_the_sites_wordmarks_are_the_librarys`. It is the only checkout that has both, + # and the check went there whole rather than being weakened to fit here. head = README.read_text(encoding="utf-8").split("\n## ", 1)[0] assert 'srcset="' + RAW + 'docs/assets/wordmark-dark.svg"' in head assert 'src="' + RAW + 'docs/assets/wordmark-light.svg"' in head @@ -175,7 +175,7 @@ def test_the_header_carries_the_fixed_copy_and_the_five_badges(): ) assert "When the outcome is unknown, CTRLRun says so instead of guessing." in head # The category noun, which the hero went without until 0.6: a reader had to reverse-engineer - # what CTRLRun *is* from three slogans. `docs/docs.mdx` carried it and the README did not. + # what CTRLRun *is* from three slogans. The documentation root carried it; the README did not. assert "A Python library that sits between the decision to act and the call that acts." in head for badge in ( "pypi/v/ctrlrun", @@ -185,7 +185,7 @@ def test_the_header_carries_the_fixed_copy_and_the_five_badges(): "pypi/l/ctrlrun", ): assert badge in head, badge - marker = "generated from docs/capabilities.yaml (readme)" + marker = "generated from capabilities.yaml (readme)" assert marker not in head, "the capability matrix is not the first screen" assert marker in text, "the capability matrix was moved, not dropped" assert head.count("\n|---|") == 0, "no table above the first H2" diff --git a/tests/test_release_v0_6.py b/tests/test_release_v0_6.py index 221953b..b3d9a32 100644 --- a/tests/test_release_v0_6.py +++ b/tests/test_release_v0_6.py @@ -1,14 +1,16 @@ -"""The v0.6 release pass. Item 9; SPEC-v0.6 §8's T180 and T181. - -Two claims about the *documents*, made testable because they are the two the release is most -likely to get wrong quietly. - -**T180 — alteration is not authorship.** §1.2's third rule, and §6.4's whole argument: a hash -chain says the log was not altered after the fact and says nothing about who wrote it. A README -that blurs the two would be the false-green problem in prose, and prose has no CI of its own. +"""The v0.6 release pass, packaging half. Item 9; SPEC-v0.6 §8's T181. **T181 — core still installs nothing new.** v0.6 adds `ctrlrun[postgres]`, and an extra is only -an extra while `pip install ctrlrun` does not pull it in. +an extra while `pip install ctrlrun` does not pull it in. The wheel and the sdist carry no +adapter, no research tree and no sector pack. + +T180 — that no release document blurs alteration with authorship — is **not** here, and its +absence is deliberate rather than a deletion. It scans five documents and three of them are +pages now, so it runs in `CTRLRun/ctrlrun-docs`, the one checkout that can read both trees, as +`tests/test_release_documents.py`. It still covers this repository's `README.md` and +`CHANGELOG.md`, and this repository's CI runs it from there against the commit being proposed: +the `docs` job. Splitting the scan in two would have been two implementations of one rule, and +two rules that eventually disagree. """ from __future__ import annotations @@ -26,172 +28,6 @@ REPO_ROOT = Path(__file__).resolve().parents[1] -#: SPEC-v0.6 §8's T180. Word boundaries, so `design`, `assign`, `assignment` and `designated` -#: are not hits -- a substring list would flag those, be softened, and stop failing on the thing -#: it exists for. -FORBIDDEN = re.compile( - r"\b(sign|signs|signed|signing|signature|signatures|authorship|" - r"non-repudiation|tamper-proof)\b", - re.IGNORECASE, -) - -#: The documents the rule binds. `docs/SPEC-v0.6.md` is deliberately **not** here: it is the -#: place the distinction is argued at length, and scanning it would make the allow-list a copy -#: of §6. -SCANNED = ( - "README.md", - "CHANGELOG.md", - "docs/docs/postgres.md", - "docs/docs/THREAT_MODEL.md", - # Added with the Production section, by the independent review that noticed the gap. This - # page is now the site's principal statement of §1.2's third rule -- it says what the chain - # detects, what it does not survive, and that alteration is not authorship -- and it was in - # neither this scan nor the section's own narrower one. If the Postgres guide earned a place - # here for carrying one disclaiming sentence, a page carrying three has a stronger claim. - "docs/docs/production/receipt-integrity.mdx", -) - - -def _lines(name: str) -> list[str]: - """One scanned document's lines. - - A **missing** file is a failure and not a skip: `docs/docs/postgres.md` is required by §8 and by - this milestone's definition of done, and skipping on its absence would make the scan - disappear exactly when somebody deleted the document it covers. The only skip admitted is - the whole repository being absent, which is the sdist job running this suite from inside a - distribution that carries `docs/` but not `pyproject.toml`. - """ - if not (REPO_ROOT / "pyproject.toml").exists(): # pragma: no cover - not a checkout - pytest.skip("no repository checkout") - path = REPO_ROOT / name - assert path.exists(), f"{name} is required by SPEC-v0.6 §8 and is not here" - return path.read_text(encoding="utf-8").splitlines() - - -def _load(name: str) -> set[str]: - """The allow-listed lines of one file, stripped, as a set.""" - return {line.strip() for line in ALLOWED.get(name, ())} - - -#: **Every line below is allow-listed because somebody wrote it down here on purpose.** -#: -#: §8's T180 describes the list as sentences that *disclaim* one of the words, and most of these -#: are. Some are not, and saying so is the point of splitting the list rather than pretending: -#: a historical changelog entry about JWT signature verification, an HMAC on a webhook, and the -#: Python word for a function's parameters are all `\bsignature\b` and none of them is a claim -#: about receipts. `docs/SPEC-v0.6.md` §8's T180 is amended in this item's PR to say so, on the -#: rule that a contract defect found while implementing it is fixed in the contract. -#: -#: What the list is *for* is unchanged and is the whole design: it fails on a **new** occurrence, -#: which is the event worth failing on, and forces whoever adds one to come here and say what -#: they meant. A plain forbidden-word list would flag §6.4's own "Not authorship", be removed as -#: a false positive, and be gone. -#: Sentences that **disclaim** one of the words. §8's T180 describes the whole -#: list this way, and this half of it is. -DISCLAIMS: dict[str, tuple[str, ...]] = { - # The 2026-09-09 rewrite cut the README to what CTRLRun does, how to use it and how it - # works, and the two paragraphs that used to carry this are now one bullet in "What it does - # not do". Both halves survived the cut, which is the half §6.4 cares about: the chain - # detects alteration, and the same sentence says alteration is not authorship. - "README.md": ( - "is detected. They are not signed: alteration is not authorship. The badge above means the", - ), - "CHANGELOG.md": ( - '- **`docs/docs/ROADMAP.md`\'s v0.6 bullet said "receipt integrity (hash chain / signatures)", and the', # noqa: E501 - "slash was the problem.** A chain detects **alteration**; a signature proves **origin**, and", # noqa: E501 - "this project verifies what it is handed. Signing is out of scope for v0.6 (`SPEC-v0.6.md` §11).", # noqa: E501 - "- **`docs/docs/THREAT_MODEL.md`'s \"Receipts are not signed; a database admin can alter history", # noqa: E501 - "which half it does not: **truncation at the end**, authorship, an adversary who can rewrite", # noqa: E501 - '- Receipts are not signed. A database administrator can alter history. **This line read "(v0.6)" until v0.6 was built, and that was a promise v0.6 does not keep**: v0.6 adds a hash chain, which detects alteration and is not evidence of authorship, and it does not stop an administrator who can rewrite every row including the chain head. Signing is out of scope (`SPEC-v0.6.md` §11).', # noqa: E501 - ), - "docs/docs/postgres.md": ( - "Receipts are not signed, alteration is not authorship, and the chain is not tamper-proof", - ), - "docs/docs/production/receipt-integrity.mdx": ( - "- **It does not tell you who wrote a receipt.** Alteration is not authorship, it does not survive", # noqa: E501 - ), - "docs/docs/THREAT_MODEL.md": ( - "- Receipts are not signed, and they are not signed after v0.6 either. v0.6 adds a **hash chain** (`SPEC-v0.6.md` §6): each receipt carries the hash of the one before it, with `seq` inside the hashed content, so a partial tamper is detected and named — an `UPDATE` on one row, a `DELETE` from the middle, a reordering. What that closes is **alteration that keeps the receipts after it**: changing what receipt *n* says while leaving the rest in place costs a rewrite of all of them plus the head, rather than one statement. **Not a truncation at the end, and not an append.** Two earlier versions of this line claimed the first; a review measured both at **two statements, undetected** — delete the rows and rewind the head, or insert a well-formed row and advance it. The head is a row in the same database as the receipts, so it raises the cost of *forgetting* and not the cost of erasing; an anchor outside the database is what would close that, and v0.6 has none. What it does **not** close is authorship, and it does not close a database admin who can rewrite every row including the chain head: such an adversary recomputes the chain and it verifies. The malicious-administrator line above is unchanged; v0.6 narrows it rather than removing it. Nor does the chain prove that every action wrote a receipt — a receipt whose write failed leaves no gap in `seq` and is invisible to the chain by construction; the events log is where that is reconciled.", # noqa: E501 - ), -} - -#: Sentences about something else entirely, which the word-boundary pattern cannot -#: tell apart: JWT signature verification, an HMAC on a webhook, and the Python word for a -#: function's parameters. §8's T180 did not anticipate these and is amended in item 9's PR. -#: They are allow-listed for the same reason the others are -- so that a **new** occurrence -#: fails and somebody has to come here and say which kind it is. -ANOTHER_SUBJECT: dict[str, tuple[str, ...]] = { - "CHANGELOG.md": ( - "as widening, expired and revoked authority, token forgery, cross-JWT confusion, and signing", # noqa: E501 - "token from the same issuer, signed with the same key, carrying the configured `aud`, passes", # noqa: E501 - "fetch its signing keys in cleartext from wherever it pointed, cache them for the life of", - "the process, and verify every token the attacker then signed.", - "- **`Control.evaluate` returns the combined decision**, not the policy axis alone. Its signature", # noqa: E501 - "one `Control` each. `SPEC-v0.1.md` §8's frozen signature is amended in the same change, as the", # noqa: E501 - "- **`WebhookApprovalProvider`** — core, over stdlib `urllib.request`. One signed POST on", - "`APPROVAL_REQUESTED`; the gateway serves the signed inbound grant/deny at", - ), - "docs/docs/THREAT_MODEL.md": ( - "| A forged or tampered token | `JWTIdentityProvider` verifies the signature against a JWKS or a pinned key, with the algorithm taken from its own allow-list and never from the token (RFC 8725 §3.1) |", # noqa: E501 - "| Signing keys fetched from somewhere else | JWKS over HTTPS only, redirects refused outright, a duplicate `kid` refused rather than resolved, a failed fetch never emptying the cache |", # noqa: E501 - "- **A compromised identity provider.** CTRLRun *consumes* identities: it verifies a token somebody else issued and maps the verified claims onto a `Principal`. It issues nothing, and an issuer that signs a token for the wrong subject has told CTRLRun the truth as far as CTRLRun can tell. Everything downstream — grants, delegation, receipts — is then wrong, correctly and consistently.", # noqa: E501 - ), -} - - -#: The two groups, merged. Both are allow-listed; the split is what keeps the reason for each -#: entry visible instead of averaging them into one undifferentiated list. -ALLOWED: dict[str, tuple[str, ...]] = { - name: DISCLAIMS.get(name, ()) + ANOTHER_SUBJECT.get(name, ()) - for name in set(DISCLAIMS) | set(ANOTHER_SUBJECT) -} - - -def test_T180_the_release_documents_do_not_blur_alteration_and_authorship() -> None: - """SPEC-v0.6 §1.2's third rule, as a test rather than an intention.""" - unexpected: list[str] = [] - for name in SCANNED: - allowed = _load(name) - for number, line in enumerate(_lines(name), start=1): - if FORBIDDEN.search(line) and line.strip() not in allowed: - unexpected.append(f"{name}:{number} {line.strip()[:110]}") - assert unexpected == [], ( - "a release document gained a sentence about signing, signatures or authorship that " - "nobody allow-listed. If it disclaims one of them, add the exact line to ALLOWED with " - "the reason. If it claims one of them, SPEC-v0.6 §6.4 says it is not true:\n" - + "\n".join(unexpected) - ) - - -def test_T180_the_allow_list_is_not_stale() -> None: - """An allow-list nobody prunes becomes a list of lines that no longer exist, and the next - person to edit one of these sentences would find the guard silently not covering it. - - So every entry must still resolve to a line in its file **and** still contain a forbidden - word: an entry that stopped matching is an entry doing nothing. - """ - orphaned: list[str] = [] - for name, entries in ALLOWED.items(): - present = {line.strip() for line in _lines(name)} - for entry in entries: - if entry.strip() not in present: - orphaned.append(f"{name}: no longer present — {entry.strip()[:90]}") - elif not FORBIDDEN.search(entry): - orphaned.append(f"{name}: allow-listed but matches nothing — {entry.strip()[:90]}") - assert orphaned == [], orphaned - - -def test_T180_the_scan_would_see_a_new_claim() -> None: - """The positive control (`v0.4 §1.3`). A guard whose pattern never matched anything would - pass this file on any content at all, and the two tests above would both stay green.""" - assert FORBIDDEN.search("Receipts are signed, which proves authorship.") - assert FORBIDDEN.search("The chain is tamper-proof.") - assert FORBIDDEN.search("CTRLRun gives you non-repudiation.") - # And the words it must not fire on, which is why it is a word-boundary pattern. - assert not FORBIDDEN.search("the design of the store") - assert not FORBIDDEN.search("assign the lease to the caller") - assert not FORBIDDEN.search("a designated approver") - def test_T181_core_still_installs_pyyaml_and_click_and_nothing_else() -> None: """SPEC-v0.6 §8's T181. v0.6 adds `ctrlrun[postgres]`, and `psycopg` is only an extra diff --git a/tests/test_repository_signals.py b/tests/test_repository_signals.py index 4b3de63..8cb174f 100644 --- a/tests/test_repository_signals.py +++ b/tests/test_repository_signals.py @@ -174,7 +174,11 @@ def test_the_community_files_exist_and_say_what_they_must(): "scripts/check.sh", "Specification first", "mutation-tested", - "docs/docs/CLAIMS.md", + # Named rather than linked: a contributor has to know the claims table exists and + # which repository holds it, and a bare URL in this list would still pass if the + # sentence around it stopped saying what the table is for. + "CLAIMS.md", + "CTRLRun/ctrlrun-docs", "tools/docs_audit", "trusted publishing", ): @@ -231,11 +235,16 @@ def test_the_citation_names_the_repository_the_version_and_the_tagline(): def test_how_this_is_built_states_the_review_gap_and_the_tooling_once(): - page = (REPO_ROOT / "docs" / "docs" / "how-this-is-built.md").read_text(encoding="utf-8") - assert "no external security audit" in page - assert 1 <= page.count("AI coding agents") <= 3, "stated plainly, not hyped" + """What the *page* says -- that there was no external audit, and how plainly it says who + wrote the code -- is asserted in `CTRLRun/ctrlrun-docs`, by + `test_how_this_is_built_states_the_review_gap_and_the_tooling_once` there. The page is a + page now, and this repository's CI runs that suite against this commit. + + What is left here is what this repository ships: the README sends a reader to it, and the + provenance sentence appears in both the README and `SECURITY.md`. + """ readme = (REPO_ROOT / "README.md").read_text(encoding="utf-8") - assert "docs/docs/how-this-is-built.md" in readme + assert "https://ctrlrun.dev/docs/how-this-is-built" in readme assert "Releases carry PyPI provenance attestations from GitHub Actions" in readme assert "Releases carry PyPI provenance attestations from GitHub Actions" in ( REPO_ROOT / "SECURITY.md" diff --git a/tests/test_verify_action.py b/tests/test_verify_action.py index 39a859e..abf97c0 100644 --- a/tests/test_verify_action.py +++ b/tests/test_verify_action.py @@ -1,9 +1,9 @@ -"""The composite action, the badge and `docs/docs/verify.md`. SPEC-v0.4 §5; T118-T120. +"""The composite action, the badge and `https://ctrlrun.dev/docs/verify`. SPEC-v0.4 §5; T118-T120. The badge is the shortest sentence this project makes, and the one most likely to be read without the report behind it. So its text is asserted as a *concatenation* and against a regex rather than a word list — no adjective can be appended to it later — and the vocabulary -it is not allowed to use is asserted against the badge, the job summary and `docs/docs/verify.md` +it is not allowed to use is asserted against the badge, the job summary and `https://ctrlrun.dev/docs/verify` together. T118's substance runs in this repository's CI, where the action actually executes. What is @@ -34,7 +34,6 @@ REPO_ROOT = Path(__file__).resolve().parents[1] ACTION = REPO_ROOT / "action.yml" WORKFLOW = REPO_ROOT / ".github" / "workflows" / "ci.yml" -VERIFY_DOC = REPO_ROOT / "docs" / "docs" / "verify.md" README = REPO_ROOT / "README.md" AUTHORITY_PAYMENTS = REPO_ROOT / "examples" / "authority" / "payments.yaml" V1_PAYMENTS = REPO_ROOT / "examples" / "policies" / "payments.yaml" @@ -220,21 +219,17 @@ def test_T119_the_colour_is_about_failures_and_has_no_amber_for_not_applicable( assert failing.badge["color"] == BADGE_FAIL_COLOR -def test_T119_the_link_target_carries_the_exact_phrase(): - page = _repository_file(VERIFY_DOC) - - assert "declared guarantees pass" in page - # And it is the anchor the badge links to, not a phrase buried somewhere else. - heading = page.index("## What the badge means") - assert "declared guarantees pass" in page[heading : heading + 600] - - @pytest.mark.parametrize("word", FORBIDDEN) def test_T119_no_claim_uses_the_forbidden_vocabulary(tmp_path, word): - """Asserted against the badge, its JSON, the job summary and `docs/docs/verify.md` together. - - `docs/docs/verify.md` names the words in order to refuse them, and the sentence that does is the - only place any of them may appear on the page. + """Asserted against the badge and its JSON, and against the job summary. + + **The page's half of this is in `CTRLRun/ctrlrun-docs`**, as + `test_T119_the_page_uses_no_forbidden_word_as_a_claim`. `verify.md` is a page now, and + reading it from here would mean skipping when it is absent -- which is what the sdist + guard below already does for `action.yml`, and would have been wrong here: absent means + moved, not pruned, and a skip would have made this whole test disappear quietly. The five + words are the same five in both halves, and between them every place one could appear is + covered. """ report = run(_write(tmp_path, ALL_APPLICABLE)) document = json.loads(report.to_json()) @@ -242,18 +237,6 @@ def test_T119_no_claim_uses_the_forbidden_vocabulary(tmp_path, word): assert word not in json.dumps(badge_from_document(document)).lower() assert word not in summary_from_document(document).lower() - # On the page, each of these words appears only inside a sentence that refuses it. The - # unit is the paragraph rather than the line, because the refusal and the word it refuses - # are often on different lines of the same wrapped sentence. - page = _repository_file(VERIFY_DOC) - offending = [ - paragraph - for paragraph in page.split("\n\n") - if word in paragraph.lower() - and not any(marker in paragraph.lower() for marker in ("not ", "never", "no ")) - ] - assert not offending, f"{word!r} used as a claim: {offending}" - def test_T119_the_action_and_the_workflow_make_no_forbidden_claim(): text = (_repository_file(ACTION) + _repository_file(WORKFLOW)).lower() @@ -368,13 +351,13 @@ def test_the_readme_carries_the_badge_and_links_it_to_what_it_means(): assert "img.shields.io/endpoint" in readme assert "verify-badge.json" in readme - assert "docs/docs/verify.md#what-the-badge-means" in readme + assert "https://ctrlrun.dev/docs/verify#what-the-badge-means" in readme def test_the_readme_documentation_table_links_the_verify_page(): readme = _repository_file(README) - assert "docs/docs/verify.md" in readme + assert "https://ctrlrun.dev/docs/verify" in readme assert "declared guarantees pass" in readme @@ -394,59 +377,11 @@ def test_the_job_summary_carries_the_not_applicable_rows_in_full(): #: The README carried a copy of this report until 2026-09-09, when the page was cut to what #: CTRLRun does, how to use it and how it works, and the report went with the rest of the -#: verify section. The guard moved rather than went: `docs/docs/verify.md` is now the single +#: verify section. The guard moved rather than went: the verify page is now the single #: home of the verbatim output, so the "two copies can drift" test below has nothing left to #: compare and is gone, and this one reads the page instead of the README. -def _quoted_report() -> list[str]: - block = _repository_file(VERIFY_DOC).split("```console")[1].split("```")[0] - return [line for line in block.splitlines() if line.strip() and not line.startswith("$")] - - -@pytest.mark.authority -def test_the_verify_page_quotes_the_real_verify_output(): - """The demo transcript has had this guard since v0.1; the verify report gets the same one. - - Every line the page quotes has to be a line `ctrlrun verify` actually prints, so a change - to the report that nobody carried across fails here rather than shipping a page that lies. - The version line is normalised: it moves at every release, and a document is not the place - that number is kept honest — `pyproject.toml` is. - """ - - report = run(AUTHORITY_PAYMENTS) - printed = { - re.sub(r"ctrlrun \S+,", "ctrlrun <version>,", line) - for line in report.to_text().splitlines() - } - # The page quotes a path relative to the repository root; the report prints the path it - # was given. Compare on the same footing rather than on how the test invoked it. - printed = { - line.replace(str(AUTHORITY_PAYMENTS), "examples/authority/payments.yaml") - for line in printed - } - - missing = [ - line - for line in _quoted_report() - if re.sub(r"ctrlrun \S+,", "ctrlrun <version>,", line) not in printed - ] - - assert not missing, f"the page quotes lines verify does not print: {missing}" - - -def test_the_verify_page_says_what_not_applicable_means(): - """The N/A semantics, on the page the badge links to. Asserted with the line wrapping - removed: a sentence that reads correctly and wraps across two lines is still the sentence, - and a test that could not see it would push prose onto one long line.""" - page = " ".join(_repository_file(VERIFY_DOC).split()) - - assert "Not applicable is not a pass" in page - assert "never `11/11`" in page - assert "no flag that folds an N/A into the count" in page - assert "declared guarantees pass" in page - - def test_the_readme_says_what_the_badge_does_not_mean(): """What the README keeps of the verify section: the badge, and the sentence that stops a reader reading it as more than it is. The report itself lives on the page above.""" @@ -494,11 +429,12 @@ def test_the_badge_job_publishes_the_badge_the_verify_job_produced(): ] script = "\n".join(step.get("run", "") for step in steps) - # Two upstreams since the test-count badge joined it: the verify run that produced the - # guarantee badge, and the `check` job whose suite the count is the size of. Both are - # downloaded rather than regenerated, for the same reason -- a number this job computed - # itself would be a number no run stands behind. - assert set(badge["needs"]) == {"verify", "check"} + # Three upstreams. The verify run that produced the guarantee badge; the `check` job whose + # suite the count is the size of; and `docs`, which is where the count is now written, the + # generator having moved to CTRLRun/ctrlrun-docs. Both artifacts are downloaded rather than + # regenerated, for the same reason -- a number this job computed itself would be a number + # no run stands behind. + assert set(badge["needs"]) == {"verify", "check", "docs"} assert downloads, "the badge job regenerates the badge instead of downloading it" assert {step["with"]["name"] for step in downloads} == { "ctrlrun-verify-authority", @@ -519,14 +455,6 @@ def test_the_readme_badge_points_at_the_branch_the_job_publishes(): assert "verify-badge.json" in script -def test_the_verify_page_documents_the_permission_the_publish_costs(): - """§5.2 — the cost is shown once, where the reader can see it, and not buried.""" - page = " ".join(_repository_file(VERIFY_DOC).split()) - - assert "contents: write" in page - assert "least privilege" in page - - def _publish_script() -> str: """The badge job's publish step, lifted out of the workflow so it can be **run**.""" for step in _workflow()["jobs"]["badge"]["steps"]: @@ -703,14 +631,3 @@ def publish(index: int) -> subprocess.CompletedProcess[str]: check=True, ) assert len(log.stdout.strip().splitlines()) == 1, log.stdout - - -def test_the_verify_page_is_honest_about_what_branch_protection_buys(): - """A badge is a claim, and a branch nobody guards is a claim anybody can write. The page - says which half is protected rather than implying both: deletion and force pushes are - blocked, and a fast-forward push by anyone with write access is not.""" - page = " ".join(_repository_file(VERIFY_DOC).split()) - - assert "It does **not** restrict who may push" in page - assert "silently dropped" in page - assert "self-healing" in page diff --git a/tools/docs_audit/__init__.py b/tools/docs_audit/__init__.py deleted file mode 100644 index 7d9aed3..0000000 --- a/tools/docs_audit/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -"""The documentation audit: three checks and one generator, run by CI and by hand. - -- `snippets.py` — every fenced block marked `runnable` is executed offline and must succeed. -- `lint.py` — the forbidden-words lint, with `lint-allowlist.txt` beside it. -- `links.py` — internal links and anchors resolve. -- `render_capabilities.py` — renders `docs/capabilities.yaml` three ways and checks that no - rendered copy has drifted from the generator. - -Each is a script with a `main()` returning an exit status, and a function the tests call -directly. None of them imports anything outside the standard library, `pyyaml` and `ctrlrun` -itself, so they run wherever the kernel's own test suite runs. -""" diff --git a/tools/docs_audit/_files.py b/tools/docs_audit/_files.py deleted file mode 100644 index e15a518..0000000 --- a/tools/docs_audit/_files.py +++ /dev/null @@ -1,163 +0,0 @@ -"""What the audit reads, and how it reads a fenced block. - -The set of documents is taken from **git**, not from the filesystem, for the reason the -packaging tests give: a file that exists on disk and is not tracked is not in a fresh clone, -and a check that passed against it has checked nothing a reader will see. Outside a checkout -the audit falls back to a glob, so the same scripts run from an sdist. -""" - -from __future__ import annotations - -import re -import subprocess -from collections.abc import Iterable, Iterator -from dataclasses import dataclass -from fnmatch import fnmatch -from pathlib import Path - -REPO_ROOT = Path(__file__).resolve().parents[2] - -#: The documents a reader is sent to. Specs, the roadmap and the changelog are deliberately -#: not here: they are the historical record, and the audit is about the pages that describe -#: the shipped version to a stranger. Each check may narrow this further. -DOCUMENT_PATTERNS: tuple[str, ...] = ( - "README.md", - "docs/*.md", - "docs/**/*.md", - "docs/**/*.mdx", - "adapters/*/README.md", - "examples/**/*.md", -) - - -def tracked_files(root: Path = REPO_ROOT) -> list[Path] | None: - """Every path git tracks under `root`, or `None` outside a checkout.""" - try: - listed = subprocess.run( - ["git", "ls-files", "-z"], - cwd=root, - capture_output=True, - check=False, - ) - except OSError: - return None - if listed.returncode != 0: - return None - return [root / name for name in listed.stdout.decode("utf-8").split("\0") if name] - - -def documents( - root: Path = REPO_ROOT, - patterns: Iterable[str] = DOCUMENT_PATTERNS, - exclude: Iterable[str] = (), -) -> list[Path]: - """The documents matching `patterns` relative to `root`, tracked by git where possible.""" - patterns = tuple(patterns) - exclude = tuple(exclude) - candidates = tracked_files(root) - if candidates is None: - candidates = sorted({path for pattern in patterns for path in root.glob(pattern)}) - chosen: list[Path] = [] - for path in candidates: - relative = path.relative_to(root).as_posix() - if not any(_match(relative, pattern) for pattern in patterns): - continue - if any(_match(relative, pattern) for pattern in exclude): - continue - if path.is_file(): - chosen.append(path) - return sorted(set(chosen)) - - -def _match(relative: str, pattern: str) -> bool: - """`fnmatch` with `**` meaning any depth, which `fnmatch` alone does not give.""" - if "**" not in pattern: - return fnmatch(relative, pattern) - head, _, tail = pattern.partition("**/") - if not relative.startswith(head): - return False - remainder = relative[len(head) :] - return any(fnmatch(part, tail) for part in _suffixes(remainder)) - - -def _suffixes(relative: str) -> Iterator[str]: - parts = relative.split("/") - for index in range(len(parts)): - yield "/".join(parts[index:]) - - -@dataclass(frozen=True) -class Fence: - """One fenced code block: where it is, what its info string says, and its body.""" - - path: Path - line: int - language: str - tokens: tuple[str, ...] - body: str - - @property - def location(self) -> str: - return f"{relative(self.path)}:{self.line}" - - -_OPEN = re.compile(r"^(?P<indent>\s*)(?P<fence>`{3,}|~{3,})(?P<info>[^`]*)$") - - -def fences(text: str, path: Path) -> Iterator[Fence]: - """Every fenced block in `text`, with 1-based line numbers for its opening fence. - - An opening fence closes at the first line consisting of the same fence character, at least - as long, and nothing else — which is CommonMark's rule and also what GitHub renders. - """ - lines = text.splitlines() - index = 0 - while index < len(lines): - opened = _OPEN.match(lines[index]) - if opened is None: - index += 1 - continue - fence = opened.group("fence") - indent = len(opened.group("indent")) - info = opened.group("info").strip().split() - language = info[0].lower() if info else "" - tokens = tuple(info[1:]) - start = index - index += 1 - body: list[str] = [] - while index < len(lines): - stripped = lines[index].strip() - if stripped and set(stripped) == {fence[0]} and len(stripped) >= len(fence): - break - body.append(_dedent(lines[index], indent)) - index += 1 - yield Fence(path, start + 1, language, tokens, "\n".join(body) + "\n") - index += 1 - - -def _dedent(line: str, indent: int) -> str: - """Strip up to `indent` leading spaces: a fence opened inside a list item or a component - is indented, and CommonMark removes that indentation from its content lines.""" - removable = len(line) - len(line.lstrip(" ")) - return line[min(removable, indent) :] - - -def outside_fences(text: str) -> Iterator[tuple[int, str]]: - """Every (1-based line number, line) that is not inside a fenced block.""" - lines = text.splitlines() - fence: str | None = None - for number, line in enumerate(lines, start=1): - if fence is None: - opened = _OPEN.match(line) - if opened is not None: - fence = opened.group("fence") - continue - yield number, line - else: - stripped = line.strip() - if stripped and set(stripped) == {fence[0]} and len(stripped) >= len(fence): - fence = None - - -def relative(path: Path) -> str: - return path.relative_to(REPO_ROOT).as_posix() if path.is_relative_to(REPO_ROOT) else str(path) diff --git a/tools/docs_audit/claims.py b/tools/docs_audit/claims.py deleted file mode 100644 index 29edc4c..0000000 --- a/tools/docs_audit/claims.py +++ /dev/null @@ -1,120 +0,0 @@ -"""Which symbol each `file.py:NNN` citation in `docs/docs/CLAIMS.md` belongs to. - -One producer, imported by both `scripts/repoint-claims.py`, which **writes** the line numbers, -and `test_the_claims_table_line_numbers_point_at_what_they_name`, which **checks** them. They -disagreed, and the disagreement was invisible in exactly the way this repository keeps finding: - - | ... | `approve` -- `cli/main.py:295`; `receipts` -- `cli/main.py:357`; - `effects` -- `cli/main.py:431`; `resolve` -- `cli/main.py:449`; ... | - -Both sides collected the symbols of the **whole row** and resolved every citation against the -set. So the repointer sent all six references to one line -- whichever definition it happened to -find first -- and the guard accepted them, because that line does define a symbol the row names. -A row claiming to cite six commands cited one, six times, and the check said it was fine. - -The fix is that a citation belongs to the symbols **near it**, not to the row. `citations` pairs -each reference with the identifiers around it, nearest first, so `cli/main.py:295` is resolved -against `approve` and not against `stats`. -""" - -from __future__ import annotations - -import re -from dataclasses import dataclass - -#: `cli/main.py:400` as well as `state.py:400`. A first version matched no path with a directory -#: in it, so every `cli/main.py` reference was invisible to the guard -- and a review found two -#: of them stale, one broken by the very commit that added the guard to the rows beside it. -REFERENCE = re.compile(r"`((?:[a-z_]+/)*[a-z_]+\.py):(\d+)`") - -#: A backtick-quoted span, and every identifier inside it. Matching only the identifier that -#: begins a span missed the second word of `` `ctrlrun delegate` ``, so a citation aimed at -#: `def delegate` owned only the token `ctrlrun` and looked stale when it was not. -SPAN = re.compile(r"`([^`]+)`") -IDENTIFIER = re.compile(r"[A-Za-z_][\w.]*") - -#: Extensions and other tokens a citation contributes that are never symbols. Without this, -#: **32 of 40 rows** carried the bare token `py`, so any line containing `copy`, `pyyaml` or -#: `python` satisfied them. -NOT_SYMBOLS = frozenset({"py", "md", "yaml", "yml", "json", "sql", "toml"}) - - -@dataclass(frozen=True) -class Citation: - """One `file.py:NNN` reference, and the symbols it is about.""" - - filename: str - line: int - #: Where the citation sits in the row, so a rewrite can be positional rather than a global - #: `str.replace` of its text -- two citations to the same `file.py:NNN` in one row must be - #: able to move independently. - start: int - end: int - #: Nearest first. A resolver should try them in this order and stop at the first that - #: resolves, so a row citing several files sends each reference to its own symbol. - names: tuple[str, ...] - #: The symbols **this** citation owns: those not separated from it by another citation. - #: A row citing six commands gives each reference only the names beside it, so a line that - #: defines a *different* command in the same row no longer satisfies it. `names` stays the - #: whole row, nearest first, because re-pointing a stale reference needs somewhere to look - #: when the local names are all statements rather than definitions. - local: tuple[str, ...] - - -def _bare(name: str) -> str: - """`Control.delegate` names `delegate`: the table writes the qualified name, the source - defines the last segment.""" - return name.split(".")[-1] - - -def citations(row: str) -> list[Citation]: - """Every citation in one table row, each paired with the symbols nearest to it. - - Distance is measured in characters from the reference to the identifier, so a symbol - immediately before a reference beats one at the other end of the row. Both directions - count: a row may write `` `plan_reservation` -- `effect.py:163` ... and `control.py:1036` - (only `NotExecuted` maps to `FAILED`) ``, where the symbol that identifies the second - reference comes **after** it. Requiring the symbol to precede the citation would refuse - that row, and it is a legitimate one. - """ - # Spans a reference occupies, so `cli` is not harvested as a symbol out of - # `` `cli/main.py:295` ``. `NOT_SYMBOLS` catches the extension; nothing caught the - # directory, and a stray `cli` sorts nearest to every citation in the row. - spans = [(m.start(), m.end()) for m in REFERENCE.finditer(row)] - symbols = [] - for span in SPAN.finditer(row): - if any(start <= span.start() < end for start, end in spans): - continue # the span *is* a `file.py:NNN` citation, not a list of symbols - for found in IDENTIFIER.finditer(span.group(1)): - name = _bare(found.group(0)) - if name not in NOT_SYMBOLS: - symbols.append((span.start(1) + found.start(), name)) - found = [] - for reference in REFERENCE.finditer(row): - at = reference.start() - nearest = tuple( - name for _, name in sorted(symbols, key=lambda pair: (abs(pair[0] - at), pair[0])) - ) - # `dict.fromkeys` rather than a set: the order is the whole point. - ordered = tuple(dict.fromkeys(nearest)) - owned = tuple( - dict.fromkeys( - name - for position, name in symbols - # A symbol belongs to the citation it is closest to. Splitting on the *next* - # citation's start instead gave `` `stats` -- `cli/main.py:658` `` to the - # reference before it, which is the one it is not about. - if min(spans, key=lambda span: abs(position - span[0]))[0] == reference.start() - ) - ) - found.append( - Citation( - reference.group(1), - int(reference.group(2)), - reference.start(), - reference.end(), - ordered, - owned, - ) - ) - return found diff --git a/tools/docs_audit/links.py b/tools/docs_audit/links.py deleted file mode 100644 index 4dd6c5f..0000000 --- a/tools/docs_audit/links.py +++ /dev/null @@ -1,210 +0,0 @@ -"""Internal links and anchors resolve. - -Checked, with no network: - -- `[text](relative/path.md)` and `[text](relative/path.md#anchor)`, resolved against the - linking file's directory; -- `[text](#anchor)`, against the linking file's own headings; -- `[text](/path)` and `href="/path"` — the docs site's own root-relative form, resolved against - `docs/` with `.mdx` then `.md` appended, and against the repository root as a fallback; -- `https://github.com/CTRLRun/ctrlrun/blob/<ref>/<path>` and `/tree/<ref>/<path>`, which are - internal links wearing an absolute URL, resolved against the checkout. - -Every other absolute URL is skipped: an external link is somebody else's to keep, and a check -that opened sockets would be a check that failed in CI for reasons nobody here can fix. - -Anchors use GitHub's slug rule — lowercase, formatting stripped, punctuation removed, spaces to -hyphens, duplicates suffixed `-1`, `-2` — which is also close enough to Mintlify's for the -headings this repository writes. An explicit `{#id}` on a heading and an `id="…"` attribute -inside the page are accepted as well. -""" - -from __future__ import annotations - -import argparse -import re -import sys -from collections.abc import Iterable, Iterator -from dataclasses import dataclass -from pathlib import Path -from urllib.parse import unquote - -from _files import DOCUMENT_PATTERNS, REPO_ROOT, documents, outside_fences, relative - -#: A render under `docs/generated/` is a fragment, embedded into a page by a later session and -#: never published on its own. Its links are checked on the page that embeds it, where they -#: either resolve or fail with that page — and until a page embeds it, a link to a page not -#: yet written is a plan, not a broken link. -EXCLUDED: tuple[str, ...] = ("docs/generated/*",) - - -def documents_to_check() -> list[Path]: - return documents(patterns=DOCUMENT_PATTERNS, exclude=EXCLUDED) - - -_MARKDOWN_LINK = re.compile(r"(?<!!)\[[^\]]*\]\(([^)\s]+)(?:\s+\"[^\"]*\")?\)") -_HREF = re.compile(r"""href=["']([^"']+)["']""") -_GITHUB = re.compile(r"^https://github\.com/CTRLRun/ctrlrun/(?:blob|tree)/[^/]+/(.*)$") -_HEADING = re.compile(r"^\s{0,3}(#{1,6})\s+(.*?)\s*#*\s*$") -_EXPLICIT_ID = re.compile(r"\{#([A-Za-z0-9_-]+)\}\s*$") -_ID_ATTRIBUTE = re.compile(r"""\bid=["']([A-Za-z0-9_-]+)["']""") - - -_IA = REPO_ROOT / "docs" / "IA.md" - - -def planned_pages() -> frozenset[str]: - """Every site path `docs/IA.md` lists. A link to one that does not exist yet is a plan the - next session owes, reported as such and not as broken; the launch audit has to drive the - count to zero, and a link to a path the IA never named is broken today.""" - if not _IA.exists(): - return frozenset() - text = _IA.read_text(encoding="utf-8") - return frozenset( - re.findall(r"(?m)^\s*[├└│─\s]*[^`\n]*?\s{2,}([a-z0-9][a-z0-9/-]*)\s*(?:\(.*\))?\s*$", text) - ) | frozenset(re.findall(r"`([a-z0-9][a-z0-9/-]*)`", text)) - - -@dataclass(frozen=True) -class Broken: - path: str - line: int - target: str - reason: str - - def __str__(self) -> str: - return f"{self.path}:{self.line}: {self.target} — {self.reason}" - - -def slug(heading: str) -> str: - """GitHub's heading slug: what `#anchor` has to match.""" - text = re.sub(r"`([^`]*)`", r"\1", heading) - text = re.sub(r"\[([^\]]*)\]\([^)]*\)", r"\1", text) - text = re.sub(r"[*_~]", "", text) - text = _EXPLICIT_ID.sub("", text) - text = text.strip().lower() - text = re.sub(r"[^\w\- ]", "", text) - return text.replace(" ", "-") - - -def anchors(text: str) -> set[str]: - seen: dict[str, int] = {} - found: set[str] = set() - for _, line in outside_fences(text): - matched = _HEADING.match(line) - if matched is not None: - explicit = _EXPLICIT_ID.search(matched.group(2)) - if explicit is not None: - found.add(explicit.group(1)) - base = slug(matched.group(2)) - count = seen.get(base, 0) - seen[base] = count + 1 - found.add(base if count == 0 else f"{base}-{count}") - for attribute in _ID_ATTRIBUTE.findall(line): - found.add(attribute) - return found - - -def links(text: str) -> Iterator[tuple[int, str]]: - for number, line in outside_fences(text): - for target in _MARKDOWN_LINK.findall(line): - yield number, target - for target in _HREF.findall(line): - yield number, target - - -def _resolve(target: str, source: Path) -> tuple[Path | None, str | None] | None: - """The file a target names and its anchor, or `None` when it is not ours to check.""" - if target.startswith(("mailto:", "tel:")): - return None - path_part, _, anchor = target.partition("#") - anchor = unquote(anchor) or None - # A query string is not part of the path. `/try?situation=uncertain` is the same page as - # `/try`, and the site serves it that way; a checker that kept the query looked for a file - # named after the whole string and reported a working link as broken. - path_part = path_part.partition("?")[0] - if path_part.startswith(("http://", "https://")): - matched = _GITHUB.match(path_part) - if matched is None: - return None - return REPO_ROOT / unquote(matched.group(1)), anchor - if not path_part: - return source, anchor - path_part = unquote(path_part) - if path_part.startswith("/"): - for candidate in ( - REPO_ROOT / "docs" / (path_part.lstrip("/") + ".mdx"), - REPO_ROOT / "docs" / (path_part.lstrip("/") + ".md"), - REPO_ROOT / "docs" / path_part.lstrip("/"), - REPO_ROOT / path_part.lstrip("/"), - ): - if candidate.exists(): - return candidate, anchor - return REPO_ROOT / "docs" / (path_part.lstrip("/") + ".mdx"), anchor - return (source.parent / path_part).resolve(), anchor - - -PLANNED: list[Broken] = [] - - -def check_text(text: str, source: Path) -> list[Broken]: - """Broken links in one page. Links to planned pages are collected in `PLANNED` instead.""" - broken: list[Broken] = [] - planned = PLANNED - name = relative(source) - own_anchors: set[str] | None = None - for number, target in links(text): - resolved = _resolve(target, source) - if resolved is None: - continue - path, anchor = resolved - if path is None: - continue - if not path.exists(): - site_path = target.partition("#")[0].partition("?")[0].lstrip("/") - if target.startswith("/") and site_path in planned_pages(): - planned.append( - Broken(name, number, target, "planned in docs/IA.md, not written yet") - ) - continue - broken.append(Broken(name, number, target, f"{relative(path)} does not exist")) - continue - if anchor is None or path.is_dir(): - continue - if path.suffix.lower() not in {".md", ".mdx"}: - continue - if path == source: - if own_anchors is None: - own_anchors = anchors(text) - available = own_anchors - else: - available = anchors(path.read_text(encoding="utf-8")) - if anchor not in available: - broken.append(Broken(name, number, target, f"no heading #{anchor} in {relative(path)}")) - return broken - - -def check_paths(paths: Iterable[Path]) -> list[Broken]: - broken: list[Broken] = [] - for path in paths: - broken.extend(check_text(path.read_text(encoding="utf-8"), path)) - return broken - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("paths", nargs="*", type=Path, help="documents to check; default: all") - arguments = parser.parse_args(argv) - paths = [p.resolve() for p in arguments.paths] or documents_to_check() - PLANNED.clear() - broken = check_paths(paths) - for item in broken: - print(item) - for item in PLANNED: - print(f"PLANNED {item}") - print(f"links: {len(paths)} document(s), {len(broken)} broken, {len(PLANNED)} planned") - return 0 if not broken else 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/lint-allowlist.txt b/tools/docs_audit/lint-allowlist.txt deleted file mode 100644 index 03389c2..0000000 --- a/tools/docs_audit/lint-allowlist.txt +++ /dev/null @@ -1,89 +0,0 @@ -# The forbidden-words lint's allowlist. Read by tools/docs_audit/lint.py. -# -# exclude <glob> the lint does not read files matching the glob -# allow <glob> <regex> a line matching the regex, in a file matching the glob, is -# permitted whatever words it contains -# -# Every entry carries its reason. An `allow` line is for a sentence that uses a forbidden -# word to say what CTRLRun is *not* — a negation — and never for a sentence that makes the -# claim. The regex is deliberately narrow: it names the negating phrase, not the word. -# -# Two documents are exempt by the rule itself and are not listed here: -# docs/docs/OWASP-AGENTIC-TOP10.md and docs/docs/THREAT_MODEL.md, which exist to list what is not -# covered. The lint hard-codes them (EXEMPT_BY_RULE) so that this file cannot un-exempt them -# by accident or exempt a third by analogy. - -# --- files the lint does not read --------------------------------------------------------- - -# The specifications are the historical record of each version and are not rewritten for the -# docs site. They name sector packs as out of scope, standards as things not claimed, and -# `transaction` in its database sense; a reader is sent to them from Architecture only. -exclude docs/SPEC-*.md - -# The roadmap says what later versions may add, including a version line for sector packs -# that does not exist yet. A roadmap that could not name future work would not be one. -# -# **Re-decided in session 6, because the fact under it changed.** `ROADMAP.md` is now a page on -# the public site, not only a repository file, so a stranger can land on it from search and read -# `EU AI Act Art. 12`, `SOC 2 CC6/CC7`, `PCI DSS`, `HIPAA` and an H2 headed *Sector packs*. The -# exclusion stands, and the reason it stands is in the document rather than in this file: every -# one of those names is future work, the standards line says it is written *"only when a design -# partner asks"*, and the packs section says in its own words that **no pack describes itself as -# compliant with any regulation**. If a line there ever asserts support rather than naming an -# intention, the answer is to fix the line, not to widen this. -exclude docs/docs/ROADMAP.md - -# The style sheet and the information architecture name the forbidden words in order to -# forbid them, and name the sections (Compare) whose titles carry a competitor's phrase. -exclude docs/STYLE.md -exclude docs/IA.md - -# --- sentences that negate a claim --------------------------------------------------------- - -# README and docs/docs/CLAIMS.md: the verify badge's meaning is stated by listing the words it -# does not mean. -allow * does not mean secure, safe, compliant, certified or audited - -# docs/docs/verify.md says the same thing as a rule about which words never appear. -allow docs/docs/verify.md do not appear as - -# "It is not a guardrail library, an IAM system, a workflow engine, or a compliance product." -allow * It is not a .* compliance product - -# Adapter READMEs and docs/docs/adapters.md: the conformance kit is named and then denied as a claim. -allow * not a compliance claim -allow * not\*\* a certification -allow * no adapter describes itself as "conformant" - -# docs/docs/CLAIMS.md: the list of claims the README deliberately does not make. -allow docs/docs/CLAIMS.md Nothing about compliance, conformance or alignment - -# docs/docs/ACS.md reads somebody else's standard. "A conformant Guardian" is the standard's own -# term for one of its roles, and the second line says what a mapping would be if it claimed -# more than it can show. -allow docs/docs/ACS.md A conformant Guardian -allow docs/docs/ACS.md a compliance claim with nothing behind it - -# The Compare pages name the other thing they are compared with, in the heading of the section -# that says what it is good at. That is the page's whole job, and the fixed copy permits a -# category name where it is accurate; what it still forbids is CTRLRun describing *itself* that -# way, which the body of each page does the opposite of. -allow docs/docs/compare/guardrail-libraries.mdx guardrail -allow docs/docs/compare/governance-toolkits.mdx oversight toolkits - -# The readiness block's "Not yet" list names sector packs in order to say there are none. It is -# generated by tools/docs_audit/render_readiness.py, so the sentence appears in six files: the -# three renders under docs/generated/ and the three pages that embed one. NOT_YET is where the -# sentence lives, and removing it is a pull request with the CLAIMS.md row that makes the new -# sentence true. -# -# **Named files rather than `*`, and the difference matters twice.** A `*` would grant the -# exemption to every file in the repository, present and future, so a page nobody reviewed -# could carry the sentence. And `permits` matches an allow regex against the line **and its two -# neighbours**, so under `*` a real sector-pack claim written directly above or below it would -# be permitted anywhere. An independent review found the wider glob. -allow README.md No sector packs\. \(the policy templates are starting points -allow docs/docs.mdx No sector packs\. \(the policy templates are starting points -allow docs/docs/production/index.mdx No sector packs\. \(the policy templates are starting points -allow docs/generated/readiness.* No sector packs\. \(the policy templates are starting points -allow docs/docs/CLAIMS.md no external security audit, no third-party review of the kernel, no sector packs diff --git a/tools/docs_audit/lint.py b/tools/docs_audit/lint.py deleted file mode 100644 index 29a7fbe..0000000 --- a/tools/docs_audit/lint.py +++ /dev/null @@ -1,212 +0,0 @@ -"""The forbidden-words lint. - -Two lists, because the rules that produced them are different rules. - -**Positioning words** — *runtime control*, *governance*, *guardrails*, *compliant*, *secure* as a -bare adjective, *exactly-once*, *transaction* — never appear where a stranger forms a first -impression: a heading, a page title, a description, a hero line. They are allowed in a body -sentence that explains what CTRLRun is not, or names the thing it is being compared with. So -these are checked in **headline scope**: Markdown headings and the frontmatter fields Mintlify -renders as the page's title, description and social preview. - -**Claim words** — *compliance*, *conformant*, *certified*, *aligned with*, *pack*, *sector*, the -named regulations, and social proof that does not exist — are checked **everywhere**, because a -body sentence is where a compliance claim or a sector product gets asserted. Two documents are -exempt by name, because they exist to list what is *not* covered: `docs/docs/OWASP-AGENTIC-TOP10.md` -and `docs/docs/THREAT_MODEL.md`. Everything else negates such a word through the allowlist beside -this file, one regex per legitimate sentence, with the reason. - -`lint-allowlist.txt` also names the files the lint does not read, with a reason on each line. -""" - -from __future__ import annotations - -import argparse -import re -import sys -from collections.abc import Iterable -from dataclasses import dataclass -from fnmatch import fnmatch -from pathlib import Path - -from _files import DOCUMENT_PATTERNS, documents, outside_fences, relative - -ALLOWLIST = Path(__file__).with_name("lint-allowlist.txt") - -#: The two documents the rules exempt by name. Not in the allowlist file, because an entry -#: there could be deleted by a session that found it inconvenient; these are the rule. -EXEMPT_BY_RULE: tuple[str, ...] = ("docs/docs/OWASP-AGENTIC-TOP10.md", "docs/docs/THREAT_MODEL.md") - - -@dataclass(frozen=True) -class Rule: - id: str - pattern: re.Pattern[str] - scope: str # "headline", "everywhere" or "planned-only" - why: str - - -def _rule(id: str, pattern: str, scope: str, why: str) -> Rule: - return Rule(id, re.compile(pattern, re.IGNORECASE), scope, why) - - -RULES: tuple[Rule, ...] = ( - _rule("runtime-control", r"\bruntime[ -]control\b", "headline", "a competitor's phrase"), - _rule("governance", r"\bgovernance\b", "headline", "a competitor's phrase"), - _rule("guardrails", r"\bguard-?rails?\b", "headline", "a competitor's phrase"), - _rule("compliant", r"\bcompliant\b", "headline", "a claim this project does not make"), - _rule( - "secure", - r"\bsecure\b(?!\s+(?:by|against|from))", - "headline", - "a bare adjective that promises what verify cannot see", - ), - _rule("exactly-once", r"\bexactly[ -]once\b", "headline", "what CTRLRun cannot guarantee"), - _rule( - "transaction", - r"\btransactions?\b", - "headline", - "allowed once, in the sentence that says CTRLRun is not one", - ), - _rule("compliance", r"\bcompliance\b", "everywhere", "no compliance claims"), - _rule("conformant", r"\bconformant\b", "everywhere", "no standards claims"), - _rule("certified", r"\bcertif(?:ied|ication)\b", "everywhere", "no standards claims"), - _rule("aligned-with", r"\baligned with\b", "everywhere", "no standards claims"), - _rule("pack", r"\bpacks?\b", "everywhere", "0.6 ships no sector packs"), - _rule("sector", r"\bsectors?\b", "everywhere", "0.6 ships no sector packs"), - _rule("hipaa", r"\bHIPAA\b", "everywhere", "no regulation is supported"), - _rule("soc2", r"\bSOC\s?2\b", "everywhere", "no regulation is supported"), - _rule("eu-ai-act", r"\bEU AI Act\b", "everywhere", "no regulation is supported"), - _rule("trusted-by", r"\btrusted by\b", "everywhere", "no social proof that does not exist"), - _rule("testimonial", r"\btestimonials?\b", "everywhere", "no social proof"), - _rule("excited", r"\bwe(?:'re| are) excited\b", "everywhere", "docs/STYLE.md"), -) - -#: There is no `planned-only` rule in `RULES` right now, and that is a statement about the -#: product rather than about this file: the one there was, `operator-mcp-server`, existed -#: because `ctrlrun mcp-operator` did not, and it went when the server shipped -#: (`docs/SPEC-mcp-operator.md`). The scope survives for the next thing this repository -#: describes before it builds it, and `test_the_planned_only_scope_still_works` exercises it -#: against a rule the test defines -- otherwise the machinery would be dead code that every -#: `lint_text` call trivially satisfied. - -#: The label a page must carry, verbatim, before a `planned-only` rule lets it name the thing. -PLANNED_LABEL = "PLANNED" - -_HEADING = re.compile(r"^\s{0,3}#{1,6}\s") -_FRONTMATTER_HEADLINE = re.compile( - r"""^\s*"?(?:title|sidebarTitle|description|og:title|og:description|twitter:title|twitter:description)"?\s*:""" -) - - -@dataclass(frozen=True) -class Finding: - path: str - line: int - rule: Rule - text: str - - def __str__(self) -> str: - return f"{self.path}:{self.line}: [{self.rule.id}] {self.text.strip()[:100]}" - - -@dataclass(frozen=True) -class Allowlist: - excluded: tuple[str, ...] - allowed: tuple[tuple[str, re.Pattern[str]], ...] - - def excludes(self, path: str) -> bool: - return any(fnmatch(path, pattern) for pattern in self.excluded) - - def permits(self, path: str, line: str) -> bool: - return any(fnmatch(path, glob) and pattern.search(line) for glob, pattern in self.allowed) - - -def load_allowlist(path: Path = ALLOWLIST) -> Allowlist: - """`exclude <glob>` and `allow <glob> <regex>` lines; `#` comments; blank lines ignored. - - An `allow` line's regex is everything after the glob, so it may contain spaces. - """ - excluded: list[str] = [] - allowed: list[tuple[str, re.Pattern[str]]] = [] - if not path.exists(): - return Allowlist((), ()) - for number, raw in enumerate(path.read_text(encoding="utf-8").splitlines(), start=1): - line = raw.split(" #", 1)[0].strip() if not raw.lstrip().startswith("#") else "" - if not line: - continue - keyword, _, rest = line.partition(" ") - if keyword == "exclude": - excluded.append(rest.strip()) - elif keyword == "allow": - glob, _, regex = rest.strip().partition(" ") - if not regex: - raise ValueError(f"{path}:{number}: `allow` needs a glob and a regex") - allowed.append((glob, re.compile(regex.strip(), re.IGNORECASE))) - else: - raise ValueError(f"{path}:{number}: unknown keyword {keyword!r}") - return Allowlist(tuple(excluded), tuple(allowed)) - - -def lint_text(text: str, path: str, allowlist: Allowlist) -> list[Finding]: - """Every finding in one document. - - An `allow` regex is matched against the line **and its two neighbours**, because prose is - hard-wrapped and a negation like *does not mean secure, safe, compliant, certified or - audited* breaks across lines wherever the wrap happens to fall. The rules themselves stay - line-scoped, so widening the allow window can only permit, never miss. - """ - findings: list[Finding] = [] - lines = list(outside_fences(text)) - in_frontmatter = False - carries_planned = PLANNED_LABEL in text - for position, (number, line) in enumerate(lines): - window = " ".join(text for _, text in lines[max(position - 1, 0) : position + 2]) - if number == 1 and line.strip() == "---": - in_frontmatter = True - continue - if in_frontmatter and line.strip() == "---": - in_frontmatter = False - continue - headline = bool(_HEADING.match(line)) or ( - in_frontmatter and bool(_FRONTMATTER_HEADLINE.match(line)) - ) - for rule in RULES: - if rule.scope == "headline" and not headline: - continue - if rule.scope == "planned-only" and carries_planned: - continue - if not rule.pattern.search(line): - continue - if allowlist.permits(path, window): - continue - findings.append(Finding(path, number, rule, line)) - return findings - - -def lint_paths(paths: Iterable[Path], allowlist: Allowlist | None = None) -> list[Finding]: - allowlist = allowlist if allowlist is not None else load_allowlist() - findings: list[Finding] = [] - for path in paths: - name = relative(path) - if name in EXEMPT_BY_RULE or allowlist.excludes(name): - continue - findings.extend(lint_text(path.read_text(encoding="utf-8"), name, allowlist)) - return findings - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("paths", nargs="*", type=Path, help="documents to lint; default: all") - arguments = parser.parse_args(argv) - paths = [p.resolve() for p in arguments.paths] or documents(patterns=DOCUMENT_PATTERNS) - findings = lint_paths(paths) - for finding in findings: - print(finding) - print(f"lint: {len(paths)} document(s), {len(findings)} finding(s)") - return 0 if not findings else 1 - - -if __name__ == "__main__": - sys.path.insert(0, str(Path(__file__).parent)) - sys.exit(main()) diff --git a/tools/docs_audit/render_api.py b/tools/docs_audit/render_api.py deleted file mode 100644 index 3b1894f..0000000 --- a/tools/docs_audit/render_api.py +++ /dev/null @@ -1,411 +0,0 @@ -"""Render the Python API reference from docstrings, one page per frozen public name. - -`docs/IA.md`, decision (b): Mintlify has no native docstring reference, so griffe loads the -package statically (no import, so the lazy extras render without their dependencies), parses -Google-style docstrings, and this script emits MDX under `docs/reference/api/` plus the index -page and the *Python API* group of `docs.json`. `--check` refuses any of them that drifted. - - python tools/docs_audit/render_api.py --write - python tools/docs_audit/render_api.py --check - -The names come from `ctrlrun.__all__` (frozen by the specifications' public-name sections) -plus the entry points of the extras and of verify, listed in `EXTRA_NAMES`. -""" - -from __future__ import annotations - -import argparse -import json -import re -import sys -from collections.abc import Iterable -from pathlib import Path - -from _files import REPO_ROOT, relative - -API_DIR = REPO_ROOT / "docs" / "docs" / "reference" / "api" -DOCS_JSON = REPO_ROOT / "docs" / "docs.json" -GROUP = "Python API" -MARKER = "generated by tools/docs_audit/render_api.py from the docstrings — edit the docstring, never this page" - -#: Public names that live behind an extra or above the kernel and are not in `ctrlrun.__all__`. -EXTRA_NAMES: tuple[tuple[str, str], ...] = ( - ("ctrlrun.postgres", "PostgresStateStore"), - ("ctrlrun.otel", "OTelEventSink"), - ("ctrlrun.jwt_identity", "JWTIdentityProvider"), - ("ctrlrun.acs", "AcsControlHook"), - ("ctrlrun.gateway", "serve"), - ("ctrlrun.verify", "run"), - ("ctrlrun.conformance", "run"), - ("ctrlrun.conformance.store", "run"), -) - - -#: Which extra installs each module that needs one. A reference page that named a class and -#: not the install line was browsable and not usable: nothing on -#: `postgres-PostgresStateStore` or `otel-OTelEventSink` said `pip install "ctrlrun[postgres]"`, -#: and none of the seventy-one pages carried an import line at all. -#: -#: Only modules that actually live behind an extra belong here. `ctrlrun.conformance` and -#: `ctrlrun.conformance.store` were listed under a `conformance` extra that SPEC-v0.5 §12.1 -#: reversed and `pyproject.toml` never declared, so two pages published an install command -#: that installs nothing and a `MissingDependency` that can never fire. -EXTRA_FOR: dict[str, str] = { - "ctrlrun.postgres": "postgres", - "ctrlrun.otel": "otel", - "ctrlrun.jwt_identity": "identity", - "ctrlrun.acs": "gateway", - "ctrlrun.gateway": "gateway", -} - - -def _how_to_import(module_path: str, name: str) -> list[str]: - """The two lines a reader needs before any of the rest of the page is usable.""" - lines = ["```python", f"from {module_path} import {name}", "```", ""] - extra = EXTRA_FOR.get(module_path) - if extra is not None: - lines += [ - f'Needs the `{extra}` extra: `pip install "ctrlrun[{extra}]"`. ' - "Importing it without that raises `MissingDependency` carrying the install command.", - "", - ] - return lines - - -def _load(): # noqa: ANN202 - griffe's types are the return value - import griffe - - return griffe.load("ctrlrun", search_paths=[str(REPO_ROOT / "src")], docstring_parser="google") - - -def _public_names(package) -> list[tuple[str, str]]: # noqa: ANN001 - from ctrlrun import __all__ - - names = [("ctrlrun", name) for name in __all__] - names += list(EXTRA_NAMES) - return names - - -def _resolve(package, module_path: str, name: str): # noqa: ANN001, ANN202 - module = package - for part in module_path.split(".")[1:]: - module = module.members[part] - member = module.members[name] - while getattr(member, "is_alias", False): - try: - member = member.final_target - except Exception: - break - return member - - -def _slug(module_path: str, name: str) -> str: - if module_path == "ctrlrun": - return name - return module_path.removeprefix("ctrlrun.").replace(".", "-") + "-" + name - - -def _kind(member) -> str: # noqa: ANN001 - return str(member.kind.value) if hasattr(member.kind, "value") else str(member.kind) - - -def _parameters(parameters, *, drop_self: bool = False) -> str: # noqa: ANN001 - """A parameter list a reader can call, markers and defaults included. - - This used to render `name: annotation` and nothing else, which dropped two things and - broke every call on the page. It dropped the **`*`**, so twenty-seven keyword-only - signatures read as positional — `protect('stripe.refund', 'refund:{id}')` raises - `TypeError: takes 1 positional argument but 2 were given`, from the reference page for - `protect`. And it dropped **defaults**, so forty-four optional parameters read as - required. The launch-readiness audit tried thirteen of these pages and all thirteen - raised. `*args` and `**options` were rendered bare too, which is how - `serve(*, upstream, alias, **options)` became `serve(upstream, alias, options)`. - """ - rendered: list[str] = [] - seen_var_positional = False - for parameter in parameters: - kind = getattr(parameter.kind, "value", str(parameter.kind)) - name = str(parameter.name) - if drop_self and name in {"self", "cls"}: - continue - if kind == "variadic positional": - seen_var_positional = True - name = f"*{name}" - elif kind == "variadic keyword": - name = f"**{name}" - elif kind == "keyword-only" and not seen_var_positional: - rendered.append("*") - seen_var_positional = True - piece = name if parameter.annotation is None else f"{name}: {parameter.annotation}" - if parameter.default is not None and kind not in { - "variadic positional", - "variadic keyword", - }: - piece += f" = {parameter.default}" - rendered.append(piece) - return ", ".join(rendered) - - -#: Rendered under a class that has no `__init__` of its own, so a Protocol says what it asks -#: an implementer for. `FrameworkInterrupt` rendered as `class FrameworkInterrupt(Protocol)` -#: and nothing else, while a neighbouring page required one of the attributes it never named. -_MEMBER_KINDS = ("function", "attribute") - - -def _members(member) -> list[str]: # noqa: ANN001 - lines: list[str] = [] - for name, child in member.members.items(): - if name.startswith("_"): - continue - kind = _kind(child) - if kind == "function": - returns = f" -> {child.returns}" if child.returns is not None else "" - lines.append( - f" def {name}({_parameters(child.parameters, drop_self=True)}){returns}" - ) - elif kind == "attribute": - annotation = f": {child.annotation}" if child.annotation is not None else "" - lines.append(f" {name}{annotation}") - return lines - - -def _signature(member) -> str: # noqa: ANN001 - kind = _kind(member) - if kind == "function": - returns = f" -> {member.returns}" if member.returns is not None else "" - return f"def {member.name}({_parameters(member.parameters)}){returns}" - if kind == "class": - bases = ", ".join(str(b) for b in member.bases) - header = f"class {member.name}({bases})" if bases else f"class {member.name}" - init = member.members.get("__init__") - if init is not None and _kind(init) == "function": - params = _parameters(init.parameters, drop_self=True) - return f"{header}\n def __init__({params})" - body = _members(member) - return "\n".join([header, *body]) if body else header - return f"{member.name}" - - -def _sections(member) -> list[str]: # noqa: ANN001 - docstring = member.docstring - if docstring is None: - return ["_No docstring._"] - out: list[str] = [] - for section in docstring.parse("google"): - kind = str(section.kind.value) - if kind == "text": - out.append(_prose(section.value)) - elif kind in {"parameters", "other parameters", "attributes"}: - out.append(f"**{kind.capitalize()}**") - out.append("") - out.append("| Name | Type | Description |") - out.append("|---|---|---|") - for item in section.value: - annotation = str(item.annotation) if item.annotation is not None else "" - out.append(f"| `{item.name}` | `{annotation}` | {_cell(item.description)} |") - elif kind == "raises": - out.append("**Raises**") - out.append("") - out.append("| Exception | When |") - out.append("|---|---|") - for item in section.value: - out.append(f"| `{item.annotation}` | {_cell(item.description)} |") - elif kind == "returns": - out.append("**Returns**") - out.append("") - for item in section.value: - annotation = str(item.annotation) if item.annotation is not None else "" - out.append(f"- `{annotation}` {_prose(item.description)}".rstrip()) - elif kind == "examples": - out.append("**Example**") - out.append("") - for _, value in section.value: - out.append("```python") - out.append(str(value).strip()) - out.append("```") - else: - out.append(f"**{kind.capitalize()}**") - out.append("") - out.append(_prose(str(section.value))) - out.append("") - return out - - -def _prose(text: str) -> str: - """Docstring prose as MDX: outside inline code, braces and angle brackets would be parsed - as JSX, so they are escaped; inside a code span they are shown as written.""" - parts = re.split(r"(`[^`]*`)", text) - for index, part in enumerate(parts): - if part.startswith("`"): - continue - parts[index] = ( - part.replace("{", "{") - .replace("}", "}") - .replace("<", "<") - .replace(">", ">") - ) - return "".join(parts) - - -def _cell(text: str) -> str: - return _prose(text).replace("\n", " ").replace("|", "\\|") - - -def _page(member, module_path: str, name: str) -> str: # noqa: ANN001 - summary = "" - if member.docstring is not None: - summary = member.docstring.value.strip().split("\n\n")[0].replace("\n", " ") - summary = summary.replace('"', "'") - where = "" - try: - where = f"{relative(Path(str(member.filepath)))}:{member.lineno}" - except Exception: - where = "" - lines = [ - "---", - f'title: "{name}"', - f'description: "{summary or name}"', - "---", - "", - "{/* " + MARKER + " */}", - "", - f"`{module_path}.{name}` — {_kind(member)}" + (f", defined at `{where}`" if where else ""), - "", - *_how_to_import(module_path, name), - "", - "```python", - _signature(member), - "```", - "", - *_sections(member), - "## Next", - "", - "- [Python API index](/docs/reference/api/index).", - "- [Get started](/docs/get-started/quickstart) · [Why](/docs/why).", - "", - ] - return "\n".join(lines) - - -def render() -> dict[str, str]: - """Every page to write, keyed by path relative to `API_DIR`.""" - package = _load() - pages: dict[str, str] = {} - index_rows: list[tuple[str, str, str, str]] = [] - for module_path, name in _public_names(package): - member = _resolve(package, module_path, name) - slug = _slug(module_path, name) - pages[f"{slug}.mdx"] = _page(member, module_path, name) - summary = "" - if member.docstring is not None: - summary = member.docstring.value.strip().split("\n")[0] - index_rows.append((slug, f"{module_path}.{name}", _kind(member), _cell(summary))) - lines = [ - "---", - 'title: "Python API"', - 'description: "Every frozen public name of the ctrlrun package and its extras, one ' - 'page each, rendered from the docstrings."', - "---", - "", - "{/* " + MARKER + " */}", - "", - "The names below are the ones the specifications freeze: `ctrlrun.__all__`, the entry", - "points of the extras, and `ctrlrun.verify.run`. Each page is rendered from the docstring;", - "a name with no docstring fails a test, so every page has one.", - "", - "| Name | Kind | Summary |", - "|---|---|---|", - ] - for slug, qualified, kind, summary in index_rows: - lines.append(f"| [`{qualified}`](/docs/reference/api/{slug}) | {kind} | {summary} |") - lines += [ - "", - "## Next", - "", - "- [CLI reference](/docs/reference/cli).", - "- [Get started](/docs/get-started/quickstart) · [Why](/docs/why).", - "", - ] - pages["index.mdx"] = "\n".join(lines) - return pages - - -def navigation_pages(pages: Iterable[str]) -> list[str]: - slugs = sorted(p.removesuffix(".mdx") for p in pages if p != "index.mdx") - return ["docs/reference/api/index", *(f"docs/reference/api/{slug}" for slug in slugs)] - - -def _docs_json_group(document: dict) -> dict | None: - def walk(node): # noqa: ANN001, ANN202 - if isinstance(node, dict): - if node.get("group") == GROUP: - return node - for value in node.values(): - found = walk(value) - if found is not None: - return found - if isinstance(node, list): - for item in node: - found = walk(item) - if found is not None: - return found - return None - - return walk(document.get("navigation")) - - -def check(pages: dict[str, str]) -> list[str]: - drift: list[str] = [] - for name, text in pages.items(): - target = API_DIR / name - if not target.exists() or target.read_text(encoding="utf-8") != text: - drift.append(f"{relative(target)} differs from the docstrings; run --write") - for existing in API_DIR.glob("*.mdx"): - if existing.name not in pages: - drift.append(f"{relative(existing)} is not a public name; remove it") - document = json.loads(DOCS_JSON.read_text(encoding="utf-8")) - group = _docs_json_group(document) - if group is None: - drift.append(f"docs.json has no '{GROUP}' group") - elif group.get("pages") != navigation_pages(pages): - drift.append(f"docs.json '{GROUP}' pages differ from the rendered set; run --write") - return drift - - -def write(pages: dict[str, str]) -> None: - API_DIR.mkdir(parents=True, exist_ok=True) - for name, text in pages.items(): - (API_DIR / name).write_text(text, encoding="utf-8") - for existing in API_DIR.glob("*.mdx"): - if existing.name not in pages: - existing.unlink() - document = json.loads(DOCS_JSON.read_text(encoding="utf-8")) - group = _docs_json_group(document) - if group is None: - raise SystemExit(f"docs.json has no '{GROUP}' group to fill") - group["pages"] = navigation_pages(pages) - DOCS_JSON.write_text( - json.dumps(document, indent=2, ensure_ascii=False) + "\n", encoding="utf-8" - ) - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("--write", action="store_true") - parser.add_argument("--check", action="store_true") - arguments = parser.parse_args(argv) - pages = render() - if arguments.write: - write(pages) - print(f"wrote {len(pages)} pages under {relative(API_DIR)} and the docs.json group") - if arguments.check or not arguments.write: - drift = check(pages) - for item in drift: - print(f"DRIFT {item}") - print(f"api reference: {len(pages)} pages, {len(drift)} drifted") - return 0 if not drift else 1 - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/render_badges.py b/tools/docs_audit/render_badges.py deleted file mode 100644 index 72f186e..0000000 --- a/tools/docs_audit/render_badges.py +++ /dev/null @@ -1,225 +0,0 @@ -"""Render the badge row, and write the one badge this repository produces itself. - -A stranger reads the badges before the first sentence, so the row is a claim like any other and -is generated rather than typed. One list, one render — the README's centred HTML — because that -is the only place a badge row appears; a second format with no consumer would be a generated -artifact nobody reads, and an independent review is what noticed the first version shipping one. - - python tools/docs_audit/render_badges.py readme # print one render - python tools/docs_audit/render_badges.py --write # refresh docs/generated/ - python tools/docs_audit/render_badges.py --check # CI - -Most of the row is rendered by somebody else — PyPI, GitHub Actions, OpenSSF, Astral. Two are -this repository's own, published to the orphan `badges` branch by a job that runs only on a -push to `main`: - -- `verify-badge.json`, written by the composite action from a real `ctrlrun verify` run; -- `tests-badge.json`, written by `--write-count` **after** `scripts/check.sh` has passed, so no - number is published for a run whose suite was red. - -Two are static, and a static badge is a self-assertion unless something enforces it. These two -are enforced: `scripts/check.sh` runs `ruff format --check`, `ruff check` and `mypy --strict -src`, CI calls that file rather than naming the tools itself, and `test_ci_runs_the_check_script` -fails if it stops. The `docs` badge is a link and claims nothing. - -Downloads and stars are deliberately absent. `docs/STYLE.md` forbids social proof that does not -exist, and a count published four days after the first release measures mirrors. - -`--write-count` is what CI calls, and what it counts is what `pytest` **collects**. That is not -the same as what passed: the suite skips a handful of tests on a machine without a framework -installed, and a collected count includes them. So the badge is labelled `tests` and carries a -count, never "passing" — a count is what was measured, and the ordering is what makes it a count -of a suite that went green rather than of one that might not have. -""" - -from __future__ import annotations - -import argparse -import json -import re -import sys -from dataclasses import dataclass -from pathlib import Path - -from _files import REPO_ROOT, documents, relative -from render_readiness import collected - -GENERATED = REPO_ROOT / "docs" / "generated" -FILENAMES = {"readme": "badges.readme.md"} -FORMATS = tuple(FILENAMES) -BADGES_BRANCH = "https://raw.githubusercontent.com/CTRLRun/ctrlrun/badges" -_OPEN = re.compile(r"generated from tools/docs_audit/render_badges\.py \((?P<format>[a-z]+)\)") -_CLOSE = re.compile(r"end generated") - - -@dataclass(frozen=True) -class Badge: - """One badge: what it shows, where the image comes from, and what it links to.""" - - alt: str - image: str - href: str - - -#: The row, in reading order: what it is, where it is documented, that it builds and is -#: analysed, that its own suite is this big, that its guarantees were checked, how its supply -#: chain scores, how it is written, and the licence. -BADGES: tuple[Badge, ...] = ( - Badge( - "PyPI", - "https://img.shields.io/pypi/v/ctrlrun?color=B8730A&label=pypi", - "https://pypi.org/project/ctrlrun/", - ), - Badge( - "Python versions", - "https://img.shields.io/pypi/pyversions/ctrlrun?color=B8730A", - "https://pypi.org/project/ctrlrun/", - ), - Badge( - "Docs", - "https://img.shields.io/badge/docs-ctrlrun.dev-B8730A", - "https://ctrlrun.dev", - ), - Badge( - "CI", - "https://github.com/CTRLRun/ctrlrun/actions/workflows/ci.yml/badge.svg?branch=main", - "https://github.com/CTRLRun/ctrlrun/actions/workflows/ci.yml", - ), - Badge( - "CodeQL", - "https://github.com/CTRLRun/ctrlrun/actions/workflows/codeql.yml/badge.svg?branch=main", - "https://github.com/CTRLRun/ctrlrun/actions/workflows/codeql.yml", - ), - Badge( - "Tests", - f"https://img.shields.io/endpoint?url={BADGES_BRANCH}/tests-badge.json", - "https://ctrlrun.dev/docs/how-this-is-built", - ), - Badge( - "CTRLRun verified", - f"https://img.shields.io/endpoint?url={BADGES_BRANCH}/verify-badge.json", - "https://ctrlrun.dev/docs/security/verify-guarantees", - ), - Badge( - "OpenSSF Scorecard", - "https://api.scorecard.dev/projects/github.com/CTRLRun/ctrlrun/badge", - "https://scorecard.dev/viewer/?uri=github.com/CTRLRun/ctrlrun", - ), - Badge( - "Ruff", - "https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json", - "https://github.com/astral-sh/ruff", - ), - Badge( - "Checked with mypy --strict", - "https://img.shields.io/badge/mypy-strict-B8730A", - "https://github.com/CTRLRun/ctrlrun/blob/main/scripts/check.sh", - ), - Badge( - "License", - "https://img.shields.io/pypi/l/ctrlrun?color=B8730A", - "https://github.com/CTRLRun/ctrlrun/blob/main/LICENSE", - ), -) - - -def tests_badge(count: int) -> dict[str, object]: - """The shields.io endpoint document for the test-count badge.""" - return { - "schemaVersion": 1, - "label": "tests", - "message": f"{count:,}", - "color": "B8730A", - } - - -def _readme() -> list[str]: - lines = ['<p align="center">'] - for badge in BADGES: - lines.append(f' <a href="{badge.href}"><img src="{badge.image}" alt="{badge.alt}"></a>') - lines.append("</p>") - return lines - - -def render(fmt: str) -> str: - comment = f"generated from tools/docs_audit/render_badges.py ({fmt}) — edit the list, not this" - return "\n".join([f"<!-- {comment} -->", *_readme(), "<!-- end generated -->"]) + "\n" - - -def marker_blocks(text: str) -> list[tuple[int, str, str]]: - lines = text.splitlines() - blocks: list[tuple[int, str, str]] = [] - index = 0 - while index < len(lines): - opened = _OPEN.search(lines[index]) - if opened is None: - index += 1 - continue - start, fmt = index, opened.group("format") - index += 1 - while index < len(lines) and not _CLOSE.search(lines[index]): - index += 1 - if index >= len(lines): - blocks.append((start + 1, fmt, "")) - break - blocks.append((start + 1, fmt, "\n".join(lines[start : index + 1]) + "\n")) - index += 1 - return blocks - - -def check(pages: list[Path] | None = None) -> list[str]: - drift: list[str] = [] - for fmt in FORMATS: - target = GENERATED / FILENAMES[fmt] - if not target.exists() or target.read_text(encoding="utf-8") != render(fmt): - drift.append(f"{relative(target)} differs from the generator; run --write") - if pages is None: - pages = documents(patterns=("README.md", "docs/**/*.md", "docs/**/*.mdx")) - for page in pages: - if page.parent == GENERATED: - continue - for line, fmt, embedded in marker_blocks(page.read_text(encoding="utf-8")): - if fmt not in FORMATS: - drift.append(f"{relative(page)}:{line}: unknown badge format {fmt!r}") - elif embedded != render(fmt): - drift.append(f"{relative(page)}:{line}: badge row differs; paste it fresh") - return drift - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("format", nargs="?", choices=FORMATS) - parser.add_argument("--write", action="store_true") - parser.add_argument("--check", action="store_true") - parser.add_argument( - "--write-count", - metavar="PATH", - help="write the shields.io endpoint document for the test-count badge", - ) - arguments = parser.parse_args(argv) - if arguments.write_count: - count = collected() - Path(arguments.write_count).write_text( - json.dumps(tests_badge(count), indent=2) + "\n", encoding="utf-8" - ) - print(f"tests badge: {count:,}") - return 0 - if arguments.format: - sys.stdout.write(render(arguments.format)) - return 0 - if arguments.write: - GENERATED.mkdir(parents=True, exist_ok=True) - for fmt in FORMATS: - (GENERATED / FILENAMES[fmt]).write_text(render(fmt), encoding="utf-8") - print(f"badges: {len(BADGES)} written") - if arguments.check or not arguments.write: - drift = check() - for item in drift: - print(f"DRIFT {item}") - print(f"badges: {len(drift)} drifted") - return 0 if not drift else 1 - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/render_capabilities.py b/tools/docs_audit/render_capabilities.py deleted file mode 100644 index 01bbd7e..0000000 --- a/tools/docs_audit/render_capabilities.py +++ /dev/null @@ -1,333 +0,0 @@ -"""Render `docs/capabilities.yaml` three ways, and refuse a rendered copy that drifted. - -One source, several renders. The README's capability matrix, the docs home page's capability -grid and the plain-text list PyPI and directory listings carry are never edited by hand: each -is the output of this script for one `format`, and `--check` fails when any of them differs. - - python tools/docs_audit/render_capabilities.py readme # print one render - python tools/docs_audit/render_capabilities.py --write # refresh docs/generated/ - python tools/docs_audit/render_capabilities.py --check # CI - -`--check` compares two things: - -1. the three files under `docs/generated/`, byte for byte; -2. every **marker block** in `README.md` and under `docs/`, which is how a page embeds a render - in place. A block opens with the generated-comment line this script emits — it names the - format — and closes with an `end generated` comment. What lies between must equal the render. - - <!-- generated from docs/capabilities.yaml (readme) — edit the YAML, never this table --> - | Guarantee | … | - <!-- end generated --> - -MDX pages use `{/* … */}` for both lines. -""" - -from __future__ import annotations - -import argparse -import re -import sys -from collections.abc import Mapping, Sequence -from dataclasses import dataclass -from pathlib import Path - -import yaml -from _files import REPO_ROOT, documents, relative - -SOURCE = REPO_ROOT / "docs" / "capabilities.yaml" -GENERATED = REPO_ROOT / "docs" / "generated" -FORMATS: tuple[str, ...] = ("readme", "mdx", "text") -FILENAMES: Mapping[str, str] = { - "readme": "capabilities.readme.md", - "mdx": "capabilities.mdx", - "text": "capabilities.txt", -} -WAYS_IN: tuple[str, ...] = ("decorator", "gateway", "adapter") -WAY_LABELS: Mapping[str, str] = { - "decorator": "`@protect`", - "gateway": "Gateway", - "adapter": "Adapter", -} -VERSIONS: frozenset[str] = frozenset({"v0.1", "v0.2", "v0.3", "v0.4", "v0.5", "v0.6"}) -MAX_DESCRIPTION_WORDS = 15 - -_OPEN_COMMENT = ( - "generated from docs/capabilities.yaml ({format}) — edit the YAML, never this {what}" -) -_MARKER_OPEN = re.compile(r"generated from docs/capabilities\.yaml \((?P<format>[a-z]+)\)") -_MARKER_CLOSE = re.compile(r"end generated") - - -@dataclass(frozen=True) -class Capability: - id: str - name: str - description: str - guarantee: bool - ways_in: Mapping[str, bool | str] - since: str - page: str - claim: str | None - claim_note: str | None - - -class CapabilitiesError(ValueError): - """`docs/capabilities.yaml` says something the generator refuses to render.""" - - -def load(path: Path = SOURCE) -> tuple[Capability, ...]: - document = yaml.safe_load(path.read_text(encoding="utf-8")) - if not isinstance(document, Mapping) or not isinstance(document.get("capabilities"), list): - raise CapabilitiesError(f"{path}: expected a mapping with a `capabilities:` list") - entries: list[Capability] = [] - seen: set[str] = set() - for index, raw in enumerate(document["capabilities"]): - where = f"{path}: capabilities[{index}]" - entries.append(_parse(raw, where, seen)) - guarantees = [entry for entry in entries if entry.guarantee] - if len(guarantees) != 6: - raise CapabilitiesError( - f"{path}: {len(guarantees)} entries carry `guarantee: true`; the README matrix has " - "exactly six rows, one per group of the verify catalogue" - ) - return tuple(entries) - - -def _parse(raw: object, where: str, seen: set[str]) -> Capability: - if not isinstance(raw, Mapping): - raise CapabilitiesError(f"{where}: not a mapping") - required = {"id", "name", "description", "guarantee", "ways_in", "since", "page", "claim"} - allowed = required | {"claim_note"} - missing = required - set(raw) - unknown = set(raw) - allowed - if missing or unknown: - raise CapabilitiesError(f"{where}: missing {sorted(missing)}, unknown {sorted(unknown)}") - identifier = raw["id"] - if not isinstance(identifier, str) or not re.fullmatch(r"[a-z][a-z0-9-]*", identifier): - raise CapabilitiesError(f"{where}: id must be kebab-case, got {identifier!r}") - if identifier in seen: - raise CapabilitiesError(f"{where}: duplicate id {identifier!r}") - seen.add(identifier) - description = raw["description"] - if not isinstance(description, str) or not description.strip(): - raise CapabilitiesError(f"{where}: description must be a non-empty string") - words = len(description.split()) - if words > MAX_DESCRIPTION_WORDS: - raise CapabilitiesError( - f"{where}: description is {words} words; the limit is {MAX_DESCRIPTION_WORDS}" - ) - if description.rstrip().endswith("!"): - raise CapabilitiesError(f"{where}: no exclamation marks (docs/STYLE.md)") - ways = raw["ways_in"] - if not isinstance(ways, Mapping) or set(ways) != set(WAYS_IN): - raise CapabilitiesError(f"{where}: ways_in must name exactly {list(WAYS_IN)}") - for way, value in ways.items(): - if not isinstance(value, bool | str) or (isinstance(value, str) and not value.strip()): - raise CapabilitiesError(f"{where}: ways_in.{way} must be true, false or a short note") - if raw["since"] not in VERSIONS: - raise CapabilitiesError(f"{where}: since must be one of {sorted(VERSIONS)}") - page = raw["page"] - if not isinstance(page, str) or not re.fullmatch(r"[a-z0-9-]+(/[a-z0-9-]+)*", page): - raise CapabilitiesError(f"{where}: page must be a docs-site path like concepts/effect-keys") - claim = raw["claim"] - note = raw.get("claim_note") - if claim is None and not (isinstance(note, str) and note.strip()): - raise CapabilitiesError(f"{where}: a null claim needs a claim_note saying who adds the row") - if claim is not None and (not isinstance(claim, str) or not claim.strip()): - raise CapabilitiesError(f"{where}: claim must be a CLAIMS.md row's quoted text, or null") - if not isinstance(raw["guarantee"], bool): - raise CapabilitiesError(f"{where}: guarantee must be true or false") - if not isinstance(raw["name"], str) or not raw["name"].strip(): - raise CapabilitiesError(f"{where}: name must be a non-empty string") - return Capability( - id=identifier, - name=raw["name"].strip(), - description=description.strip(), - guarantee=raw["guarantee"], - ways_in=dict(ways), - since=raw["since"], - page=page, - claim=claim, - claim_note=note, - ) - - -def _cell(value: bool | str) -> str: - if value is True: - return "yes" - if value is False: - return "—" - return value - - -def render(fmt: str, capabilities: Sequence[Capability]) -> str: - if fmt == "readme": - return _render_readme(capabilities) - if fmt == "mdx": - return _render_mdx(capabilities) - if fmt == "text": - return _render_text(capabilities) - raise CapabilitiesError(f"unknown format {fmt!r}; one of {FORMATS}") - - -def _render_readme(capabilities: Sequence[Capability]) -> str: - lines = [ - f"<!-- {_OPEN_COMMENT.format(format='readme', what='table')} -->", - "| Guarantee | " + " | ".join(WAY_LABELS[way] for way in WAYS_IN) + " |", - "|---|" + "---|" * len(WAYS_IN), - ] - for entry in capabilities: - if not entry.guarantee: - continue - cells = " | ".join(_cell(entry.ways_in[way]) for way in WAYS_IN) - lines.append(f"| **{entry.name}** — {entry.description} | {cells} |") - lines.append("<!-- end generated -->") - return "\n".join(lines) + "\n" - - -def _render_mdx(capabilities: Sequence[Capability]) -> str: - """The six guarantees as cards a reader sees; everything else folded under one accordion. - - A front door with twenty-six cards is an inventory, and a stranger reads none of it. The - six that are guarantees are what the README matrix shows; the rest stay one click away.""" - lines = ["{/* " + _OPEN_COMMENT.format(format="mdx", what="grid") + " */}"] - guarantees = [entry for entry in capabilities if entry.guarantee] - others = [entry for entry in capabilities if not entry.guarantee] - lines.extend(_mdx_cards(guarantees, indent=" ")) - lines.append(f'<Accordion title="Everything else it does ({len(others)} more)">') - lines.extend(_mdx_cards(others, indent=" ")) - lines.append("</Accordion>") - lines.append("{/* end generated */}") - return "\n".join(lines) + "\n" - - -def _mdx_cards(entries: Sequence[Capability], *, indent: str) -> list[str]: - outer = indent[:-2] - lines = [f"{outer}<Columns cols={{2}}>"] - for entry in entries: - lines.append(f'{indent}<Card title="{_attribute(entry.name)}" href="/{entry.page}">') - lines.append(f"{indent} {entry.description} Since {entry.since}.") - lines.append(f"{indent}</Card>") - lines.append(f"{outer}</Columns>") - return lines - - -def _render_text(capabilities: Sequence[Capability]) -> str: - lines = [_OPEN_COMMENT.format(format="text", what="list")] - for entry in capabilities: - lines.append(f"- {entry.name}: {entry.description}") - lines.append("end generated") - return "\n".join(lines) + "\n" - - -def _attribute(value: str) -> str: - return value.replace("&", "&").replace('"', """) - - -def write(capabilities: Sequence[Capability], directory: Path = GENERATED) -> list[Path]: - directory.mkdir(parents=True, exist_ok=True) - written: list[Path] = [] - for fmt in FORMATS: - target = directory / FILENAMES[fmt] - target.write_text(render(fmt, capabilities), encoding="utf-8") - written.append(target) - return written - - -@dataclass(frozen=True) -class Drift: - path: str - line: int | None - reason: str - - def __str__(self) -> str: - where = f"{self.path}:{self.line}" if self.line is not None else self.path - return f"{where}: {self.reason}" - - -def marker_blocks(text: str) -> list[tuple[int, str, str]]: - """Every (opening line number, format, embedded text) marker block in a page.""" - lines = text.splitlines() - blocks: list[tuple[int, str, str]] = [] - index = 0 - while index < len(lines): - opened = _MARKER_OPEN.search(lines[index]) - if opened is None: - index += 1 - continue - start = index - fmt = opened.group("format") - index += 1 - while index < len(lines) and not _MARKER_CLOSE.search(lines[index]): - index += 1 - if index >= len(lines): - blocks.append((start + 1, fmt, "")) - break - blocks.append((start + 1, fmt, "\n".join(lines[start : index + 1]) + "\n")) - index += 1 - return blocks - - -def check( - capabilities: Sequence[Capability], - *, - directory: Path = GENERATED, - pages: Sequence[Path] | None = None, -) -> list[Drift]: - drift: list[Drift] = [] - for fmt in FORMATS: - target = directory / FILENAMES[fmt] - expected = render(fmt, capabilities) - if not target.exists(): - drift.append(Drift(relative(target), None, "missing; run --write")) - elif target.read_text(encoding="utf-8") != expected: - drift.append(Drift(relative(target), None, "differs from the generator; run --write")) - if pages is None: - pages = documents(patterns=("README.md", "docs/**/*.md", "docs/**/*.mdx")) - for page in pages: - if page.parent == directory and page.name in FILENAMES.values(): - continue - for line, fmt, embedded in marker_blocks(page.read_text(encoding="utf-8")): - if fmt not in FORMATS: - drift.append(Drift(relative(page), line, f"unknown format {fmt!r}")) - elif not embedded: - drift.append(Drift(relative(page), line, "marker block never closes")) - elif embedded != render(fmt, capabilities): - drift.append( - Drift( - relative(page), - line, - f"embedded {fmt} render differs from the generator; paste it fresh", - ) - ) - return drift - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("format", nargs="?", choices=FORMATS, help="print one render") - parser.add_argument("--write", action="store_true", help="refresh docs/generated/") - parser.add_argument("--check", action="store_true", help="fail if a rendered copy drifted") - arguments = parser.parse_args(argv) - try: - capabilities = load() - except CapabilitiesError as exc: - print(f"capabilities: {exc}") - return 1 - if arguments.format: - sys.stdout.write(render(arguments.format, capabilities)) - return 0 - if arguments.write: - for path in write(capabilities): - print(f"wrote {relative(path)}") - if arguments.check or not arguments.write: - drift = check(capabilities) - for item in drift: - print(f"DRIFT {item}") - print(f"capabilities: {len(capabilities)} entries, {len(drift)} drifted copy(ies)") - return 0 if not drift else 1 - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/render_cli.py b/tools/docs_audit/render_cli.py deleted file mode 100644 index e2f532e..0000000 --- a/tools/docs_audit/render_cli.py +++ /dev/null @@ -1,106 +0,0 @@ -"""Render `docs/docs/reference/cli.mdx` from click's own help text, and refuse a copy that drifted. - -The CLI reference is `ctrlrun --help` and every subcommand's `--help`, verbatim, so the page -cannot say something the command does not. Edit a command's docstring or option help in -`src/ctrlrun/cli/main.py`; never this page. - - python tools/docs_audit/render_cli.py --write - python tools/docs_audit/render_cli.py --check - -Help text wraps to the terminal width, so the width is pinned here: the page is the same on a -laptop and in CI. -""" - -from __future__ import annotations - -import argparse -import os -import sys - -from _files import REPO_ROOT, relative - -TARGET = REPO_ROOT / "docs" / "docs" / "reference" / "cli.mdx" -COLUMNS = "88" -MARKER = "generated by tools/docs_audit/render_cli.py from click's help text — edit the command docstrings, never this page" - - -def help_texts() -> list[tuple[str, str]]: - """`(command name, help text)` for `ctrlrun` and every subcommand, in registration order.""" - os.environ["COLUMNS"] = COLUMNS - from click.testing import CliRunner - - from ctrlrun.cli.main import main - - # `prog_name` is not cosmetic. Without it click takes the program name from `sys.argv[0]`, - # which under pytest and under this generator is `main` -- so every one of the fourteen - # blocks on a page that promises "the command's own --help, verbatim" opened with - # `Usage: main [OPTIONS] COMMAND [ARGS]...`, a command that does not exist. A reader who - # tried it got command-not-found from the reference page. Found by the launch-readiness - # audit, reading the page as a stranger. - runner = CliRunner() - invoked = runner.invoke(main, ["--help"], env={"COLUMNS": COLUMNS}, prog_name="ctrlrun") - texts = [("ctrlrun", invoked.output)] - for name in main.commands: - # `prog_name` is the *group's* name; click appends the subcommand itself, so passing - # "ctrlrun demo" here produced `Usage: ctrlrun demo demo`. - result = runner.invoke( - main, [name, "--help"], env={"COLUMNS": COLUMNS}, prog_name="ctrlrun" - ) - texts.append((f"ctrlrun {name}", result.output)) - return texts - - -def render() -> str: - lines = [ - "---", - 'title: "CLI reference"', - "description: \"Every ctrlrun command and option, from the command's own help text: " - 'init, demo, approve, deny, receipts, effects, resolve, inspect, stats, scan, verify."', - "---", - "", - "{/* " + MARKER + " */}", - "", - "The `ctrlrun` command reads the policy in the working directory (`ctrlrun.yaml`, or the", - "file `$CTRLRUN_CONFIG` names) and the store beside it, `.ctrlrun/state.db`, unless", - "`--store-url` or `$CTRLRUN_STORE_URL` names another. A command that reads evidence creates", - "nothing and migrates nothing. Each section below is the command's own `--help`, verbatim.", - "", - ] - for name, text in help_texts(): - lines.append(f"## {name}") - lines.append("") - lines.append("```text") - lines.append(text.rstrip("\n")) - lines.append("```") - lines.append("") - lines += [ - "## Next", - "", - "- [Exit codes](/docs/reference/exit-codes): what each command's exit status means.", - "- [Resolve an AMBIGUOUS effect](/docs/guides/resolve-an-ambiguous-effect): `effects`, `resolve` and `inspect` in use.", - "- [Get started](/docs/get-started/quickstart) · [Why](/docs/why).", - "", - ] - return "\n".join(lines) - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("--write", action="store_true") - parser.add_argument("--check", action="store_true") - arguments = parser.parse_args(argv) - text = render() - if arguments.write: - TARGET.parent.mkdir(parents=True, exist_ok=True) - TARGET.write_text(text, encoding="utf-8") - print(f"wrote {relative(TARGET)}") - if arguments.check or not arguments.write: - if not TARGET.exists() or TARGET.read_text(encoding="utf-8") != text: - print(f"DRIFT {relative(TARGET)} differs from click's help text; run --write") - return 1 - print(f"cli reference: {relative(TARGET)} matches") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/render_cookbook.py b/tools/docs_audit/render_cookbook.py deleted file mode 100644 index 46f4e44..0000000 --- a/tools/docs_audit/render_cookbook.py +++ /dev/null @@ -1,109 +0,0 @@ -"""Extract every cookbook recipe's files from its page into `examples/cookbook/<name>/`. - -A recipe page under `docs/docs/cookbook/` is the single source: its `yaml runnable` block is the -recipe's `ctrlrun.yaml` and its `python runnable file=main.py` block is the script. This -script writes those into `examples/cookbook/<name>/`, so the directory a reader clones runs -exactly what the page shows, and `--check` refuses a copy that drifted either way. - - python tools/docs_audit/render_cookbook.py --write - python tools/docs_audit/render_cookbook.py --check - -`tests/test_cookbook.py` runs every extracted directory offline, twice, and asserts exit 0. -""" - -from __future__ import annotations - -import argparse -import sys - -from _files import REPO_ROOT, fences, relative - -PAGES = REPO_ROOT / "docs" / "docs" / "cookbook" -EXAMPLES = REPO_ROOT / "examples" / "cookbook" -HEADER = ( - "# Extracted by tools/docs_audit/render_cookbook.py from\n" - "# docs/docs/cookbook/{name}.mdx — edit the page, never this file.\n" -) - - -def recipes() -> dict[str, dict[str, str]]: - """`{recipe name: {file name: content}}` for every page under `docs/docs/cookbook/`.""" - out: dict[str, dict[str, str]] = {} - for page in sorted(PAGES.glob("*.mdx")): - if page.stem == "index": - continue - files: dict[str, str] = {} - for fence in fences(page.read_text(encoding="utf-8"), page): - if "runnable" not in fence.tokens or fence.language not in {"python", "yaml", "bash"}: - continue - name = next((t[5:] for t in fence.tokens if t.startswith("file=")), None) - if name is None: - if fence.language != "yaml": - continue - name = "ctrlrun.yaml" - header = HEADER.format(name=page.stem) - files[name] = header + fence.body - # A recipe is a directory only where the page carries something to run. The two adapter - # recipes show a framework's own code, which the adapters CI job runs against a real - # install; they extract nothing here rather than a directory that cannot run offline. - if "main.py" in files or "run.sh" in files: - out[page.stem] = files - return out - - -def check(extracted: dict[str, dict[str, str]]) -> list[str]: - drift: list[str] = [] - for name, files in extracted.items(): - for filename, content in files.items(): - target = EXAMPLES / name / filename - if not target.exists(): - drift.append(f"{relative(target)} missing; run --write") - elif target.read_text(encoding="utf-8") != content: - drift.append( - f"{relative(target)} differs from docs/docs/cookbook/{name}.mdx; run --write" - ) - if EXAMPLES.exists(): - for existing in EXAMPLES.iterdir(): - if ( - existing.is_dir() - and existing.name not in extracted - and existing.name != "__pycache__" - ): - drift.append( - f"{relative(existing)} has no page under docs/docs/cookbook/; remove it" - ) - return drift - - -def write(extracted: dict[str, dict[str, str]]) -> int: - count = 0 - for name, files in extracted.items(): - directory = EXAMPLES / name - directory.mkdir(parents=True, exist_ok=True) - for filename, content in files.items(): - (directory / filename).write_text(content, encoding="utf-8") - count += 1 - return count - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("--write", action="store_true") - parser.add_argument("--check", action="store_true") - arguments = parser.parse_args(argv) - extracted = recipes() - if arguments.write: - print( - f"wrote {write(extracted)} files for {len(extracted)} recipes under {relative(EXAMPLES)}" - ) - if arguments.check or not arguments.write: - drift = check(extracted) - for item in drift: - print(f"DRIFT {item}") - print(f"cookbook: {len(extracted)} recipes, {len(drift)} drifted") - return 0 if not drift else 1 - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/render_probe.py b/tools/docs_audit/render_probe.py deleted file mode 100644 index a18edab..0000000 --- a/tools/docs_audit/render_probe.py +++ /dev/null @@ -1,229 +0,0 @@ -"""Render the framework-probe study page from the published results, and refuse a hand edit. - -`docs/docs/study/does-your-framework-double-execute.mdx` is a **render**, never written by hand: -its table comes from `research/framework-probe/results/*.json`, which the maintainer publishes -by committing a run. Until one exists the page says so, in those words, and lists no framework. - - python tools/docs_audit/render_probe.py --write - python tools/docs_audit/render_probe.py --check - -A framework whose adapter was never executed is not in the results file and therefore not on the -page: the one way a row appears is that the harness produced it. - -The page lives under `docs/study/` and not `docs/research/` because two release guards refuse -**any** path segment named `research` in a distribution, which is how the harness at the -repository root is kept out of the wheel. Renaming one page is cheaper than making a -release-critical rule subtler. -""" - -from __future__ import annotations - -import argparse -import json -import sys -from pathlib import Path - -from _files import REPO_ROOT, relative - -RESULTS = REPO_ROOT / "research" / "framework-probe" / "results" -TARGET = REPO_ROOT / "docs" / "docs" / "study" / "does-your-framework-double-execute.mdx" -MARKER = ( - "generated by tools/docs_audit/render_probe.py from " - "research/framework-probe/results/ — publish a run, do not edit this page" -) -NO_RESULTS = "No published results yet." - -#: The scenarios the harness runs, in the order the page reads them. -SCENARIOS: tuple[tuple[str, str], ...] = ( - ("double-refund", "Double execution"), - ("approval-mutation", "Approval mutation"), -) - -#: SPEC-v0.4 §7.3's fairness rules, quoted because the table carries other projects' names. -FAIRNESS: tuple[str, ...] = ( - "The same fake remote for every framework, a fresh instance per run.", - "The same scenario text: prompt, tool name, description and schema byte-identical wherever the framework's API admits it.", - "Framework defaults. No retry setting changed, no timeout tuned, no guard added.", - "At most one configuration change per framework, only where the scenario cannot run without it, and it appears in the table's own column.", - "The version is read at runtime from the installed distribution, never typed by hand.", - "The table reports behaviour, not quality.", -) - - -def latest() -> tuple[Path, dict] | None: - """The most recent published results file, or `None` where none exists.""" - files = sorted(RESULTS.glob("*.json")) - if not files: - return None - newest = files[-1] - return newest, json.loads(newest.read_text(encoding="utf-8")) - - -def unrun(entry: dict) -> bool: - """Was this adapter executed at all? - - An entry whose notes begin `skipped:` is an adapter the harness never ran, because the - framework was not installed. It is **not a measurement** and must never reach the table: - the probe's README says these frameworks "remain unexecuted in every sense", and a row that - read `error` beside a version-less framework would be a finding about it. - """ - return str(entry.get("notes", "")).startswith("skipped:") - - -def _rows(document: dict) -> tuple[list[tuple[str, str, dict[str, dict]]], dict[str, str]]: - """The measured frameworks, and the ones the harness never ran with the reason.""" - by_framework: dict[str, dict[str, dict]] = {} - versions: dict[str, str] = {} - skipped: dict[str, str] = {} - for entry in document["results"]: - if unrun(entry): - skipped[entry["framework"]] = str(entry["notes"]).removeprefix("skipped:").strip() - continue - by_framework.setdefault(entry["framework"], {})[entry["scenario"]] = entry - versions[entry["framework"]] = entry.get("version", "") - measured = [ - (name, versions[name], scenarios) - for name, scenarios in by_framework.items() - if name not in skipped - ] - return measured, skipped - - -def _cell(entry: dict | None) -> str: - if entry is None: - return "not run" - outcome = f"`{entry['outcome']}`" - deviation = entry.get("config_deviation") - return outcome if not deviation else f"{outcome} ({deviation})" - - -def render() -> str: - found = latest() - lines = [ - "---", - 'title: "Does your framework double-execute?"', - 'description: "What agent frameworks do when a remote commits and the reply is lost, ' - 'measured with one harness, the same fake remote and framework defaults."', - "---", - "", - "{/* " + MARKER + " */}", - "", - "When a remote commits a refund and the reply is lost, what does an agent framework do?", - "This page is the measurement, not an argument: one harness, one fake remote, framework", - "defaults, and a table rendered from the run's own JSON.", - "", - "**It reports behaviour, not quality.** None of these projects claims to solve duplicate", - "execution, and none is doing anything its documentation does not describe. The finding is", - "about what an agent stack does *without* an effect-level guard.", - "", - ] - if found is None: - lines += [ - "## " + NO_RESULTS, - "", - "The harness exists and the fairness rules below are in force; nothing has been", - "published. A row appears here only when a run has been committed to", - "`research/framework-probe/results/`, so this page can never describe a framework whose", - "adapter was not executed.", - "", - ] - else: - path, document = found - measured, skipped = _rows(document) - lines += [ - f"## What the run of {document['run_at'][:10]} found", - "", - "| Framework | Version | " + " | ".join(label for _, label in SCENARIOS) + " |", - "|---|---|" + "---|" * len(SCENARIOS), - ] - for name, version, scenarios in measured: - cells = " | ".join(_cell(scenarios.get(key)) for key, _ in SCENARIOS) - lines.append(f"| {name} | {version or '—'} | {cells} |") - lines.append("") - for name, _version, scenarios in measured: - for key, label in SCENARIOS: - entry = scenarios.get(key) - if entry and entry.get("notes"): - lines.append(f"- **{name}, {label.lower()}**: {entry['notes']}") - lines += [ - "", - f"Run on {document['run_at'][:10]} against `{document['remote']}` on Python " - f"{document['python']}. The file is " - f"[`{relative(path)}`](https://github.com/CTRLRun/ctrlrun/blob/main/{relative(path)}).", - "", - "**Read the approval-mutation column carefully.** `executed_once` there does not mean", - "the scenario was handled well: it means the *mutated* action, the refund the human", - "never approved, reached the remote and committed. Every row shows it, the stubs", - "included, because nothing in these stacks binds a human's approval to the exact action", - "that then runs. `outcome` is a closed set with no value for *the mutation landed*,", - "which is why that is said here rather than in a cell.", - "", - "**The double-execution column is the finding.** The two stub rows are the control: a", - "harness that reported `executed_twice` unconditionally would have said the same about", - "both of them.", - "", - ] - if skipped: - lines += [ - "### Not run", - "", - "An adapter exists for each of these and **was never executed**, so this page says", - "nothing about them. They are listed by name rather than left out, because a reader", - "who knows the adapter exists should not have to wonder what happened to it.", - "", - ] - lines += [f"- **{name}**: {reason}." for name, reason in sorted(skipped.items())] - lines.append("") - lines += [ - "## The fairness rules", - "", - "Normative, because the table carries other projects' names.", - "", - ] - lines += [f"{index}. {rule}" for index, rule in enumerate(FAIRNESS, start=1)] - lines += [ - "", - "## Run it yourself", - "", - "The harness is in the repository, outside the package, and is never shipped in a wheel.", - "It needs the network, real API keys and a budget, which is why its results are published", - "by hand rather than by CI.", - "", - "```bash", - "python research/framework-probe/run.py --help", - "```", - "", - "[`research/framework-probe/README.md`](https://github.com/CTRLRun/ctrlrun/blob/main/research/framework-probe/README.md)", - "has the scenarios, the fake remote, each framework's documented defaults with the date", - "read, and what a run does not establish.", - "", - "## Next", - "", - "- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): what a lost reply is, and why a retry is refused.", - "- [Effect keys](/docs/concepts/effect-keys): the guard the frameworks above are running without.", - "- [Get started](/docs/get-started/quickstart) · [Why](/docs/why).", - "", - ] - return "\n".join(lines) - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("--write", action="store_true") - parser.add_argument("--check", action="store_true") - arguments = parser.parse_args(argv) - text = render() - if arguments.write: - TARGET.parent.mkdir(parents=True, exist_ok=True) - TARGET.write_text(text, encoding="utf-8") - print(f"wrote {relative(TARGET)}") - if arguments.check or not arguments.write: - if not TARGET.exists() or TARGET.read_text(encoding="utf-8") != text: - print(f"DRIFT {relative(TARGET)} differs from the published results; run --write") - return 1 - print(f"probe page: {relative(TARGET)} matches the published results") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/render_readiness.py b/tools/docs_audit/render_readiness.py deleted file mode 100644 index 9fa7e43..0000000 --- a/tools/docs_audit/render_readiness.py +++ /dev/null @@ -1,301 +0,0 @@ -"""Render the readiness block, the same in three places, from generated sources only. - -The block is the first thing a stranger reads about whether CTRLRun can be run for real, so -every number in it comes from something that measures itself: - -- the version and the dependency floor from `pyproject.toml`; -- the test count from `pytest --collect-only`, recorded in `docs/generated/readiness.json`; -- the soak's duration, actions and unattributed count from `research/soak/results/*.json`; -- what `ctrlrun verify` checks from the guarantee catalogue itself. - -And it carries a **Not yet** list, inside the block and never below it: no external security -audit, no third-party review of the kernel, no sector packs. The honest half is why the first -half is believed. A line leaves only when the thing it names has become true, in its own pull -request, and `docs/docs/CLAIMS.md` changes in the same one. - - python tools/docs_audit/render_readiness.py --write # refresh, re-counting the suite - python tools/docs_audit/render_readiness.py --check # what CI runs - -**The test count is a floor, not a snapshot.** `--check` fails when the suite has *fewer* tests -than the block claims, and passes when it has more: the suite only grows, and a number that had -to be regenerated by every pull request that added a test would be regenerated without being -read. `--write` records the count of the moment; the badge in the README is live. -""" - -from __future__ import annotations - -import argparse -import json -import re -import subprocess -import sys -import tomllib -from pathlib import Path - -from _files import REPO_ROOT, relative - -STATE = REPO_ROOT / "docs" / "generated" / "readiness.json" -GENERATED = REPO_ROOT / "docs" / "generated" -FILENAMES = {"readme": "readiness.readme.md", "mdx": "readiness.mdx", "full": "readiness.full.mdx"} -FORMATS = tuple(FILENAMES) -SOAK = REPO_ROOT / "research" / "soak" / "results" -_OPEN = re.compile(r"generated from the suite, pyproject and the soak \((?P<format>[a-z]+)\)") -_CLOSE = re.compile(r"end generated") - -#: Stated here rather than counted, because each is a statement about what has **not** been -#: done and nothing in the repository can measure an absence. Removing one is its own pull -#: request, with the CLAIMS.md row that makes the new sentence true. -NOT_YET: tuple[tuple[str, str], ...] = ( - ("No external security audit.", "planned for v0.8 or v0.9"), - ("No third-party review of the kernel.", "every review so far was run inside this project"), - ("No sector packs.", "the policy templates are starting points, not a product"), -) - - -def _version() -> str: - with (REPO_ROOT / "pyproject.toml").open("rb") as handle: - return str(tomllib.load(handle)["project"]["version"]) - - -#: A changelog heading: `## [0.6.0] - unreleased — Durable runtime`, or with a date. The file -#: uses a hyphen and an em dash interchangeably as the separator, so both are accepted. -_HEADING = re.compile(r"^## \[(?P<version>[^\]]+)\]\s*[-—]\s*(?P<when>[^\s—]+)", re.M) - - -def released() -> str | None: - """The newest version the changelog gives a date to, or `None` if it gives none. - - The readiness block used to say *"Version 0.6.0, on PyPI"* off `pyproject.toml` alone, and - on the day it was written 0.6.0 was `unreleased` and PyPI held 0.5.0 — a false sentence on - the README, produced by a generator, which is the failure a generator is supposed to make - impossible. The changelog is the source because it is the file that already has to be - right before a tag, and it flips this line on its own when the release lands. - """ - text = (REPO_ROOT / "CHANGELOG.md").read_text(encoding="utf-8") - for found in _HEADING.finditer(text): - if found.group("when").lower() != "unreleased": - return found.group("version") - return None - - -def collected() -> int: - """How many tests `pytest` collects right now.""" - result = subprocess.run( - [sys.executable, "-m", "pytest", "--collect-only", "-q", "-p", "no:cacheprovider"], - cwd=REPO_ROOT, - capture_output=True, - text=True, - check=False, - ) - found = re.search(r"(\d+)\s+tests? collected", result.stdout) - if found is None: - raise SystemExit(f"could not read a test count from pytest:\n{result.stdout[-2000:]}") - return int(found.group(1)) - - -def soak() -> dict | None: - """The most recent soak run, or `None` where none has been published.""" - files = sorted(SOAK.glob("*.json")) if SOAK.is_dir() else [] - return json.loads(files[-1].read_text(encoding="utf-8")) if files else None - - -def state() -> dict: - return json.loads(STATE.read_text(encoding="utf-8")) if STATE.exists() else {} - - -def measure() -> dict: - """Everything the block says, measured now.""" - run = soak() - return { - "version": _version(), - "released": released(), - "tests": collected(), - "guarantees": _guarantees(), - "soak": None - if run is None - else { - "elapsed": run["elapsed_human"], - "elapsed_seconds": run["elapsed_seconds"], - "backend": run["backend"].split(" ")[0], - "actions": run["actions"], - "unexplained": run["unexplained"], - "positive_control": run["positive_control_fired"], - }, - } - - -def _guarantees() -> int: - from ctrlrun.verify.guarantees import GUARANTEES - - return len(GUARANTEES) - - -def _lines(data: dict, *, full: bool) -> list[str]: - version, tests, guarantees = data["version"], data["tests"], data["guarantees"] - run, published = data["soak"], data.get("released") - link = "https://pypi.org/project/ctrlrun/" - - def where(text: str, page: str) -> str: - """`full` adds a Read-more link; the other formats carry the sentence alone. - - The soak line is the exception and links in every format: on the README and the docs - home it is the one bullet a reader could quote as a stronger claim than it is, so the - route to the page that qualifies it travels with it. - """ - if full: - return f"{text} [Read more](/docs/{page})." - if page == "production/soak": - return f"{text} [What it does not establish](https://ctrlrun.dev/docs/{page})." - return text - - lines = [ - ( - f"- **Version {version}**, on [PyPI]({link}), Python 3.11 and later." - if published == version - else f"- **Version {version} is in development**; [PyPI]({link}) has {published}. " - "Python 3.11 and later." - ), - where( - f"- **{tests:,} tests**, every version specified before it was written and every " - "requirement mutation-tested.", - "how-this-is-built", - ), - where( - f"- **{guarantees} 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.", - "security/verify-guarantees", - ), - where( - "- **One host: a file.** SQLite, no server, no ops. **Many hosts: Postgres**, the same " - "guarantees, graded by the same suite.", - "production/postgres", - ), - ] - if run is not None: - lines.append( - where( - f"- **Soaked for {run['elapsed']} on {run['backend']}**: {run['actions']:,} actions, " - f"{run['unexplained']} unattributed ambiguous outcomes" - + (", positive control fired." if run["positive_control"] else ".") - # The duration travels with the number, in every format. Without it the README - # and the docs home carried "soaked" with no route to the page that says what - # a run of that length cannot show -- the flattering half of a true sentence, - # on the two surfaces most likely to be quoted. SPEC-v0.6 §8.1 took the - # duration out of the *criterion* and not out of this line: the gate went, the - # fact did not, and the link goes to the page that separates them. - + " Nothing here establishes what only accumulates over days.", - "production/soak", - ) - ) - else: - lines.append("- **The soak has not been run for this version yet.**") - lines += [ - where( - "- **Each receipt carries the hash of the one before it**, so an alteration is detected " - "and named.", - "production/receipt-integrity", - ), - "- **Apache-2.0**, and the enforcement kernel stays open source. Releases carry PyPI " - "provenance attestations from GitHub Actions.", - "", - "**Not yet:**", - "", - ] - lines += [f"- {claim} ({why})" for claim, why in NOT_YET] - return lines - - -def render(fmt: str, data: dict) -> str: - body = _lines(data, full=fmt == "full") - comment = f"generated from the suite, pyproject and the soak ({fmt}) — run the generator" - open_marker = f"<!-- {comment} -->" if fmt == "readme" else "{/* " + comment + " */}" - close_marker = "<!-- end generated -->" if fmt == "readme" else "{/* end generated */}" - return "\n".join([open_marker, *body, close_marker]) + "\n" - - -def marker_blocks(text: str) -> list[tuple[int, str, str]]: - lines = text.splitlines() - blocks: list[tuple[int, str, str]] = [] - index = 0 - while index < len(lines): - opened = _OPEN.search(lines[index]) - if opened is None: - index += 1 - continue - start, fmt = index, opened.group("format") - index += 1 - while index < len(lines) and not _CLOSE.search(lines[index]): - index += 1 - if index >= len(lines): - blocks.append((start + 1, fmt, "")) - break - blocks.append((start + 1, fmt, "\n".join(lines[start : index + 1]) + "\n")) - index += 1 - return blocks - - -def check(data: dict, pages: list[Path] | None = None) -> list[str]: - drift: list[str] = [] - recorded = state() - if not recorded: - return [f"{relative(STATE)} is missing; run --write"] - current = data["tests"] - if current < recorded["tests"]: - drift.append( - f"the block claims {recorded['tests']:,} tests and the suite collects {current:,}; " - "run --write" - ) - for key in ("version", "released", "guarantees", "soak"): - if recorded.get(key) != data.get(key): - drift.append(f"{key} changed since the block was generated; run --write") - for fmt in FORMATS: - target = GENERATED / FILENAMES[fmt] - expected = render(fmt, recorded) - if not target.exists() or target.read_text(encoding="utf-8") != expected: - drift.append(f"{relative(target)} differs from the generator; run --write") - if pages is None: - from _files import documents - - pages = documents(patterns=("README.md", "docs/**/*.md", "docs/**/*.mdx")) - for page in pages: - if page.parent == GENERATED: - continue - for line, fmt, embedded in marker_blocks(page.read_text(encoding="utf-8")): - if fmt not in FORMATS: - drift.append(f"{relative(page)}:{line}: unknown readiness format {fmt!r}") - elif embedded != render(fmt, recorded): - drift.append(f"{relative(page)}:{line}: readiness block differs; paste it fresh") - return drift - - -def write(data: dict) -> None: - GENERATED.mkdir(parents=True, exist_ok=True) - STATE.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8") - for fmt in FORMATS: - (GENERATED / FILENAMES[fmt]).write_text(render(fmt, data), encoding="utf-8") - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("format", nargs="?", choices=FORMATS) - parser.add_argument("--write", action="store_true") - parser.add_argument("--check", action="store_true") - arguments = parser.parse_args(argv) - if arguments.format: - sys.stdout.write(render(arguments.format, state() or measure())) - return 0 - data = measure() - if arguments.write: - write(data) - print(f"readiness: {data['tests']:,} tests, version {data['version']}, written") - if arguments.check or not arguments.write: - drift = check(data) - for item in drift: - print(f"DRIFT {item}") - print(f"readiness: {len(drift)} drifted") - return 0 if not drift else 1 - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/render_schemas.py b/tools/docs_audit/render_schemas.py deleted file mode 100644 index 059a8cc..0000000 --- a/tools/docs_audit/render_schemas.py +++ /dev/null @@ -1,231 +0,0 @@ -"""Render the receipt and event schemas and the error hierarchy from the code. - -Three pages, each a marker-headed render that `--check` refuses when it has drifted: - -- `docs/docs/reference/receipt-and-event-schemas.mdx` from the `Receipt` and `Event` dataclasses and - the `EventType` enum; -- `docs/docs/reference/errors.mdx` from `ctrlrun.errors`, every class with its base and the first - line of its docstring. - - python tools/docs_audit/render_schemas.py --write - python tools/docs_audit/render_schemas.py --check -""" - -from __future__ import annotations - -import argparse -import dataclasses -import inspect -import sys -import typing -from pathlib import Path - -from _files import REPO_ROOT, relative - -SCHEMAS = REPO_ROOT / "docs" / "docs" / "reference" / "receipt-and-event-schemas.mdx" -ERRORS = REPO_ROOT / "docs" / "docs" / "reference" / "errors.mdx" -MARKER = "generated by tools/docs_audit/render_schemas.py from the code — edit the dataclasses and docstrings, never this page" - - -def _type_name(annotation: object) -> str: - text = ( - annotation - if isinstance(annotation, str) - else getattr(annotation, "__name__", str(annotation)) - ) - return text.replace("typing.", "") - - -def _fields(cls: type) -> list[tuple[str, str, str]]: - hints = typing.get_type_hints(cls, include_extras=False) - rows: list[tuple[str, str, str]] = [] - for item in dataclasses.fields(cls): - default = "" - if item.default is not dataclasses.MISSING: - default = repr(item.default) - elif item.default_factory is not dataclasses.MISSING: # type: ignore[misc] - default = "(empty)" - rows.append((item.name, _type_name(hints.get(item.name, item.type)), default)) - return rows - - -def _table(rows: list[tuple[str, str, str]]) -> list[str]: - lines = ["| Field | Type | Default |", "|---|---|---|"] - for name, kind, default in rows: - lines.append( - f"| `{name}` | `{kind}` | {('`' + default + '`') if default else 'required'} |" - ) - return lines - - -def render_schemas() -> str: - from ctrlrun import Event, Receipt - from ctrlrun.receipt import EventType, ReceiptResult - - lines = [ - "---", - 'title: "Receipt and event schemas"', - 'description: "Every field of a CTRLRun receipt and of an event, and every event ' - 'type, rendered from the dataclasses that write them."', - "---", - "", - "{/* " + MARKER + " */}", - "", - "A receipt is one executed action; an event is one step on the way. Both are written to the", - "store, appended to `.ctrlrun/receipts.jsonl` and `.ctrlrun/events.jsonl` as one JSON object", - "per line, and exported to any sink installed. Every enum renders by value, so a reader that", - "never imported CTRLRun can read the evidence.", - "", - "## Receipt", - "", - "`ctrlrun.receipt/v3`. `seq` and `prev_hash` are the chain; `policy_hash` and", - "`policy_version` say which policy decided the action; `controls` are the registry ids the", - "action and its matched rule cite.", - "", - "**Two rows are about the object rather than the document**, and the difference matters", - "when you are reading a JSONL line rather than a `Receipt`. Every line begins with", - '`"schema": "ctrlrun.receipt/v3"`, which is written by the serializer and is not a field', - "below. And `hash` **is** a field below and is *not* in the line: a document cannot", - "contain its own hash, so the store keeps it in a column and `chain_hash()` recomputes", - "it. A reader checking a chain compares those two.", - "", - *_table(_fields(Receipt)), - "", - "### Result", - "", - "| Value | Meaning |", - "|---|---|", - ] - for member in ReceiptResult: - lines.append(f"| `{member.value}` | {_result_meaning(member.name)} |") - lines += [ - "", - "## Event", - "", - *_table(_fields(Event)), - "", - "### Event types", - "", - "In the order the specification introduced them. The five authority types appear only in a", - "configuration with an `authority:` section.", - "", - "| Type |", - "|---|", - ] - for member in EventType: - lines.append(f"| `{member.value}` |") - lines += [ - "", - "## Next", - "", - "- [Receipts and evidence](/docs/concepts/receipts-and-evidence): what a receipt is for.", - "- [The receipt chain](/docs/security/receipt-chain): what `seq`, `prev_hash` and `hash` detect.", - "- [Get started](/docs/get-started/quickstart) · [Why](/docs/why).", - "", - ] - return "\n".join(lines) - - -def _result_meaning(name: str) -> str: - return { - "COMMITTED": "the executor returned; the remote did it", - "FAILED": "the executor raised `NotExecuted`; the remote provably did nothing", - "AMBIGUOUS": "the executor raised anything else, timed out, or never returned; nobody knows", - "BLOCKED": "refused before the executor ran: denied, mismatched approval, duplicate or ambiguous effect", - "OBSERVED": "observe mode: executed, with what enforce mode would have done recorded in `would_have`", - "SUSPENDED": "the executor raised `Suspended`; the reservation is held for a continuation", - }.get(name, "") - - -def render_errors() -> str: - from ctrlrun import errors - - classes = [ - obj - for _, obj in inspect.getmembers(errors, inspect.isclass) - if obj.__module__ == errors.__name__ and issubclass(obj, Exception) - ] - order = {name: index for index, name in enumerate(_source_order(errors))} - classes.sort(key=lambda cls: order.get(cls.__name__, len(order))) - lines = [ - "---", - 'title: "Errors"', - 'description: "The closed set of CTRLRun exceptions, each with its base class and ' - 'when it is raised: ActionDenied, ApprovalRequired, DuplicateEffect and the rest."', - "---", - "", - "{/* " + MARKER + " */}", - "", - "Every refusal is an exception of its own, raised as itself before the executor runs, so an", - "agent loop can tell them apart with `except`. All of them derive from `CTRLRunError`; the", - "set is closed by the specification and a new one is a specification amendment first.", - "", - "| Exception | Base | Raised when |", - "|---|---|---|", - ] - for cls in classes: - base = cls.__mro__[1].__name__ - first = (inspect.getdoc(cls) or "").split("\n\n")[0].replace("\n", " ") - lines.append(f"| `{cls.__name__}` | `{base}` | {_prose(first)} |") - lines += ["", "## Each one", ""] - for cls in classes: - lines.append(f"### {cls.__name__}") - lines.append("") - lines.append(_prose(inspect.getdoc(cls) or "")) - lines.append("") - lines += [ - "## Next", - "", - "- [Fail closed](/docs/concepts/fail-closed): the table of what is refused, and where.", - "- [Outcomes and AMBIGUOUS](/docs/concepts/outcomes-and-ambiguous): `NotExecuted` and why it is the dangerous one.", - "- [Get started](/docs/get-started/quickstart) · [Why](/docs/why).", - "", - ] - return "\n".join(lines) - - -def _prose(text: str) -> str: - """Outside inline code, braces and angle brackets would be parsed as JSX.""" - import re - - parts = re.split(r"(`[^`]*`)", text) - for index, part in enumerate(parts): - if not part.startswith("`"): - parts[index] = ( - part.replace("{", "{") - .replace("}", "}") - .replace("<", "<") - .replace(">", ">") - ) - return "".join(parts) - - -def _source_order(module: object) -> list[str]: - import re - - source = Path(inspect.getsourcefile(module) or "").read_text(encoding="utf-8") - return re.findall(r"^class (\w+)", source, re.M) - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("--write", action="store_true") - parser.add_argument("--check", action="store_true") - arguments = parser.parse_args(argv) - status = 0 - for target, text in ((SCHEMAS, render_schemas()), (ERRORS, render_errors())): - if arguments.write: - target.parent.mkdir(parents=True, exist_ok=True) - target.write_text(text, encoding="utf-8") - print(f"wrote {relative(target)}") - if arguments.check or not arguments.write: - if not target.exists() or target.read_text(encoding="utf-8") != text: - print(f"DRIFT {relative(target)} differs from the code; run --write") - status = 1 - else: - print(f"schemas: {relative(target)} matches") - return status - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/render_soak.py b/tools/docs_audit/render_soak.py deleted file mode 100644 index 6ee3ec3..0000000 --- a/tools/docs_audit/render_soak.py +++ /dev/null @@ -1,239 +0,0 @@ -"""Render the soak page from the published results, and refuse a hand edit. - -`docs/docs/production/soak.mdx` is a **render**, never written by hand. Every number on it comes -from `research/soak/results/*.json`, which the maintainer publishes by committing a run, and -until one exists the page says so in those words and shows no table. - - python tools/docs_audit/render_soak.py --write - python tools/docs_audit/render_soak.py --check - -Two sentences on that page are the reason it is generated rather than written. - -**The duration is reported and gates nothing.** `SPEC-v0.6.md` §8.1's criterion is the two -things a harness may decide — no unattributed `AMBIGUOUS`, and a positive control that fired — -and it no longer carries a duration; §8.1 records that amendment and argues it. What did not -change is that a page saying "soaked" with the clock left out is the flattering half of a true -sentence, so the measured duration is printed and **what a run of that length cannot establish -is a section of its own**. Dropping a criterion is not the same as dropping the fact it was -about, and this page is where that distinction is kept. - -**`exit_criterion_met` in the JSON is about the ambiguity count alone.** It is the harness -answering the only question a harness may answer — *did an `AMBIGUOUS` appear that I did not -cause?* — and it is not the release gate. The page names the field and says what it covers, -because a reader who finds `true` in the results file and no explanation will read it as the -gate it is not. -""" - -from __future__ import annotations - -import argparse -import json -import sys -from pathlib import Path - -from _files import REPO_ROOT, relative - -RESULTS = REPO_ROOT / "research" / "soak" / "results" -TARGET = REPO_ROOT / "docs" / "docs" / "production" / "soak.mdx" -MARKER = ( - "generated by tools/docs_audit/render_soak.py from research/soak/results/ — " - "publish a run, do not edit this page" -) -NO_RESULTS = "No published results yet." - - -def criterion(run: dict) -> bool: - """`ROADMAP.md`'s exit criterion for one published run: control fired, nothing unattributed. - - **Recomputed here rather than read from `exit_criterion_met`**, which the harness writes - into the same file. A gate with no duration left in it is a weaker gate, so it gets the - stronger check: two derivations of one criterion from one run, and a test asserts they - agree. A results file edited by hand moves the field and not this. - - Computed rather than written for the reason the whole page is generated -- a hard-coded - verdict keeps being printed after it stops being true, and the failure would be the - flattering one. - """ - return bool(run["positive_control_fired"]) and run["unexplained"] == 0 - - -def latest() -> tuple[Path, dict] | None: - """The most recently published run, or `None` when none has been.""" - files = sorted(RESULTS.glob("*.json")) if RESULTS.is_dir() else [] - if not files: - return None - return files[-1], json.loads(files[-1].read_text(encoding="utf-8")) - - -def _table(run: dict) -> list[str]: - ambiguous = run["ambiguous"] - return [ - "| | |", - "|---|---|", - f"| Ran for | {run['elapsed_human']} ({run['started_at'][:16].replace('T', ' ')}Z → " - f"{run['ended_at'][:16].replace('T', ' ')}Z) |", - f"| Backend | {run['backend']} |", - f"| Actions attempted | {run['actions']:,} |", - f"| Ended `AMBIGUOUS` | {ambiguous:,} |", - f"| Explained by a recorded injection | {run['explained']:,} |", - f"| **Unattributed** | **{run['unexplained']:,}** |", - f"| Positive control fired | {'yes' if run['positive_control_fired'] else 'no'} |", - ] - - -def render() -> str: - found = latest() - lines = [ - "---", - 'title: "The soak, and what it does not establish"', - 'description: "One published run against a real Postgres: how long it lasted, how many ' - 'actions it attempted, and how many ambiguous outcomes it could not attribute."', - "---", - "", - "{/* " + MARKER + " */}", - "", - ] - if found is None: - lines += [ - f"**{NO_RESULTS}** The harness is in the repository and this page renders from what", - "it produces, so there is nothing here until a run is committed. Nothing on this", - "site claims a soak result in the meantime.", - "", - ] - else: - path, run = found - lines += [ - "A soak asks one question, and it is not a performance question: **does an", - "`AMBIGUOUS` outcome ever appear that the harness did not cause?** Everything in the", - "run exists to make an unattributed ambiguity visible rather than rare. Here is the", - "one published run.", - "", - *_table(run), - "", - f"The table is [`{relative(path)}`]" - f"(https://github.com/CTRLRun/ctrlrun/blob/main/{relative(path)}), rendered.", - "", - "## What that is evidence of", - "", - f"Across {run['actions']:,} attempts, every `AMBIGUOUS` the store held at the end had", - "a ledger entry written **before** the failure that produced it. Nothing became", - "ambiguous that the harness did not make ambiguous. The positive control fired, so", - "the run was capable of saying otherwise: a short control phase injects an ambiguity", - "it deliberately does not record, and the classifier has to report it. A run whose", - "control did not fire is not a result, and the table says which happened.", - "", - "**Unexplained is defined before the run starts**, or the question is unfalsifiable.", - "An `AMBIGUOUS` whose attempt has a recorded injection is explained; one with no", - "corresponding injection is unattributed. It is keyed on the attempt and never on the", - "effect key alone, because one key may be attempted more than once and an injection", - "against the first attempt says nothing about the second.", - "", - ] - if criterion(run): - lines += [ - "**`ROADMAP.md`'s exit criterion is met by this run**: nothing unattributed, and", - "a positive control that fired, so the run was capable of reporting otherwise.", - "Those are the two halves and `SPEC-v0.6.md` §8.1 says they are the whole of it.", - "The criterion asks for no duration — §8.1 records when that stopped being true", - "and argues it — so what this run's length does **not** establish is the section", - "below rather than a footnote to a gate.", - "", - ] - elif run["unexplained"]: - lines += [ - "**`ROADMAP.md`'s exit criterion is not met.** The run found", - f"{run['unexplained']:,} ambiguous outcomes it could not attribute. That is a", - "finding, and it is investigated before a release is tagged.", - "", - ] - else: - lines += [ - "**`ROADMAP.md`'s exit criterion is not met.** The positive control did not fire,", - "so this run could report zero without having been able to see one. A table whose", - "control did not fire is not evidence, whatever else is on it.", - "", - ] - lines += [ - "`exit_criterion_met` in the results file is those same two halves, written by the", - "harness. This page **recomputes** them from the counts rather than reading the", - "field, and a test asserts the two agree: one derivation of a criterion is a claim,", - "two that match is a check.", - "", - "## What it is not evidence of", - "", - f"**A long run.** This one lasted {run['elapsed_human']}. Everything a soak finds by", - "*accumulating* is outside what that can see: a connection pool that degrades over", - "hours, table growth against the one-row chain head, a lease that only lapses under", - "load held longer than this, an operator restart in the middle. The duration is on", - "the table above and in every place this run is quoted, because a criterion that", - "stopped asking for one is not the same as a run that no longer has one.", - "", - "## What this does not do", - "", - "- **It is not a load test.** The throughput is a by-product, nothing here is tuned", - " for it, and no number on this page is a performance claim.", - "- **It is not a throughput figure you can plan against.** A policy denial writes a", - " receipt like any other outcome, so nearly every attempt above went through the", - " one-row chain head — but on one host, with four threads, against a database on", - " the same machine. [Postgres](/docs/postgres) describes that ceiling; this run does not", - " size it for your hardware.", - "- **It does not exercise a partition or a second host.** That is the cross-host", - " suite, and [how reservation works](/docs/production/how-reservation-works) says which", - " of those were actually run.", - "- **It says nothing about the receipt chain's integrity.**", - " [Receipt integrity](/docs/production/receipt-integrity) is that.", - "", - "## Run it yourself", - "", - "```bash", - "python research/soak/run.py --minutes " - f"{max(1, round(run['elapsed_seconds'] / 60))}" - ' --postgres "$CTRLRUN_STORE_URL" --out soak.json', - "```", - "", - "Worker threads share one schema, created for the run and dropped after it, and each", - "attempt is drawn from a fixed injection mix — mostly clean, the rest a timeout, an", - "unknown exception, a stated non-execution, or a lease short enough to lapse", - "mid-execution. The mix and the thread count live in the harness rather than here,", - "because a page that restated them would be a second copy nothing compares against:", - "[`research/soak/README.md`]" - "(https://github.com/CTRLRun/ctrlrun/blob/main/research/soak/README.md) has both.", - "", - "**Verified by** the soak harness's own suite: an injected ambiguity is explained,", - "one with no injection is a finding, an injection against another attempt explains", - "nothing, and the control cause never explains anything — four tests, and the fourth", - "is what stops the control from absorbing a real finding. `T160` covers what an", - "expired lease does and does not free.", - "", - ] - lines += [ - "## Next", - "", - "- [Run it in production](/docs/production/index): the section this belongs to.", - "- [Recovery after a crash](/docs/production/recovery): what survives a restart, and what does not.", - "- [Get started](/docs/get-started/quickstart) · [Why](/docs/why).", - "", - ] - return "\n".join(lines) - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("--write", action="store_true") - parser.add_argument("--check", action="store_true") - arguments = parser.parse_args(argv) - text = render() - if arguments.write: - TARGET.parent.mkdir(parents=True, exist_ok=True) - TARGET.write_text(text, encoding="utf-8") - print(f"wrote {relative(TARGET)}") - if arguments.check or not arguments.write: - if not TARGET.exists() or TARGET.read_text(encoding="utf-8") != text: - print(f"DRIFT {relative(TARGET)} differs from the published results; run --write") - return 1 - print(f"soak page: {relative(TARGET)} matches the published results") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/tools/docs_audit/snippets.py b/tools/docs_audit/snippets.py deleted file mode 100644 index 8c1357d..0000000 --- a/tools/docs_audit/snippets.py +++ /dev/null @@ -1,264 +0,0 @@ -"""Run every fenced block marked `runnable`, offline, and fail on the first sentence that lies. - -A code sample a reader pastes and watches fail is the most expensive sentence in the -documentation, so a sample is either runnable and run here, or it carries no marker and makes -no promise. The marker is a word on the fence's info string: - - ```python runnable - ```bash runnable - ```yaml runnable - -Rules, stated once here and in `docs/STYLE.md`: - -- Every runnable block in one document runs in **one temporary directory**, in document order, - so a `yaml runnable` policy written early is the `ctrlrun.yaml` a later block reads. -- A `python runnable` block is its own script. `python runnable continue` is appended to the - previous runnable Python blocks of the same document and the whole is run again, which is - how a page defines a function in one block and calls it in the next without repeating it. -- A `bash runnable` block runs under `bash -euo pipefail`, with this interpreter's `bin/` on - `PATH` so `ctrlrun …` is the checkout's CLI. -- A `yaml runnable` block is loaded with `Policy.from_yaml`, and with `Authority.from_yaml` - when it carries an `authority:` section, and is then written to `ctrlrun.yaml` — or to the - name given by a `file=<name>` token, which any block may carry. -- **No network.** Every subprocess gets a `sitecustomize` that refuses sockets, name resolution - and connections, the same guard `tests/test_examples.py` puts under the examples. A snippet - that reaches for the network fails here rather than in a reader's terminal, where it would - fail differently. - -Exit status is the number of failures, capped at 1. -""" - -from __future__ import annotations - -import argparse -import os -import subprocess -import sys -import tempfile -from collections.abc import Iterable, Mapping -from dataclasses import dataclass -from pathlib import Path - -from _files import DOCUMENT_PATTERNS, Fence, documents, fences, relative - -RUNNABLE = "runnable" -LANGUAGES = frozenset({"python", "bash", "yaml"}) -TIMEOUT_SECONDS = 120 - -#: Installed as `sitecustomize` on the subprocess's `PYTHONPATH`. Replacing the socket *type* -#: with a function breaks anything that subclasses it — `ssl` does — so the refusal goes on -#: the operations, exactly as `tests/test_examples.py` does it. -NO_NETWORK = """\ -import socket - -_real = socket.socket - - -class _Refusing(_real): - def connect(self, *args, **kwargs): - raise RuntimeError("a documentation snippet tried to connect; snippets run offline") - - def connect_ex(self, *args, **kwargs): - raise RuntimeError("a documentation snippet tried to connect; snippets run offline") - - -def _refuse(*args, **kwargs): - raise RuntimeError("a documentation snippet tried to resolve a name; snippets run offline") - - -socket.socket = _Refusing -socket.create_connection = _refuse -socket.getaddrinfo = _refuse -""" - - -@dataclass(frozen=True) -class Failure: - location: str - language: str - message: str - - def __str__(self) -> str: - return f"{self.location} ({self.language}): {self.message}" - - -@dataclass(frozen=True) -class Outcome: - ran: int - failures: tuple[Failure, ...] - - @property - def ok(self) -> bool: - return not self.failures - - -def runnable_fences(path: Path) -> list[Fence]: - text = path.read_text(encoding="utf-8") - return [ - fence - for fence in fences(text, path) - if RUNNABLE in fence.tokens and fence.language in LANGUAGES - ] - - -def run_document(path: Path, *, guard: Path | None = None) -> Outcome: - """Run every runnable block of one document, in order, in one temporary directory.""" - blocks = runnable_fences(path) - if not blocks: - return Outcome(0, ()) - with tempfile.TemporaryDirectory(prefix="docs-snippet-") as scratch: - workdir = Path(scratch) / "work" - workdir.mkdir() - if guard is None: - guard = Path(scratch) / "guard" - guard.mkdir() - (guard / "sitecustomize.py").write_text(NO_NETWORK, encoding="utf-8") - environment = _environment(guard) - failures: list[Failure] = [] - python_so_far: list[str] = [] - for fence in blocks: - if fence.language == "python": - if "continue" in fence.tokens: - source = "\n".join([*python_so_far, fence.body]) - else: - python_so_far = [] - source = fence.body - python_so_far.append(fence.body) - failure = _run_python(fence, source, workdir, environment) - elif fence.language == "bash": - failure = _run_bash(fence, workdir, environment) - else: - failure = _load_yaml(fence, workdir) - if failure is not None: - failures.append(failure) - return Outcome(len(blocks), tuple(failures)) - - -def run_documents(paths: Iterable[Path]) -> Outcome: - ran = 0 - failures: list[Failure] = [] - with tempfile.TemporaryDirectory(prefix="docs-snippet-guard-") as scratch: - guard = Path(scratch) - (guard / "sitecustomize.py").write_text(NO_NETWORK, encoding="utf-8") - for path in paths: - outcome = run_document(path, guard=guard) - ran += outcome.ran - failures.extend(outcome.failures) - return Outcome(ran, tuple(failures)) - - -def _environment(guard: Path) -> dict[str, str]: - environment = dict(os.environ) - environment["PYTHONPATH"] = os.pathsep.join( - part for part in (str(guard), environment.get("PYTHONPATH", "")) if part - ) - environment["PYTHONDONTWRITEBYTECODE"] = "1" - environment["PATH"] = os.pathsep.join( - [str(Path(sys.executable).parent), environment.get("PATH", "")] - ) - # A snippet decides its own policy and store; the operator's must not leak in. - for name in ("CTRLRUN_CONFIG", "CTRLRUN_STATE", "CTRLRUN_STORE_URL"): - environment.pop(name, None) - return environment - - -def _file_token(fence: Fence, default: str) -> str: - for token in fence.tokens: - if token.startswith("file="): - return token[len("file=") :] - return default - - -def _run_python( - fence: Fence, source: str, workdir: Path, environment: Mapping[str, str] -) -> Failure | None: - script = workdir / _file_token(fence, f"snippet_{fence.line}.py") - script.write_text(source, encoding="utf-8") - return _run([sys.executable, str(script)], fence, workdir, environment) - - -def _run_bash(fence: Fence, workdir: Path, environment: Mapping[str, str]) -> Failure | None: - script = workdir / _file_token(fence, f"snippet_{fence.line}.sh") - script.write_text(fence.body, encoding="utf-8") - return _run(["bash", "-euo", "pipefail", str(script)], fence, workdir, environment) - - -def _run( - command: list[str], fence: Fence, workdir: Path, environment: Mapping[str, str] -) -> Failure | None: - try: - completed = subprocess.run( - command, - cwd=workdir, - env=dict(environment), - capture_output=True, - text=True, - timeout=TIMEOUT_SECONDS, - check=False, - ) - except subprocess.TimeoutExpired: - return Failure(fence.location, fence.language, f"did not finish in {TIMEOUT_SECONDS}s") - except OSError as exc: - return Failure(fence.location, fence.language, f"could not start: {exc}") - if completed.returncode != 0: - tail = (completed.stderr or completed.stdout).strip().splitlines()[-8:] - return Failure( - fence.location, - fence.language, - f"exit {completed.returncode}\n " + "\n ".join(tail), - ) - return None - - -def _load_yaml(fence: Fence, workdir: Path) -> Failure | None: - import yaml - - from ctrlrun import Authority, Policy - from ctrlrun.errors import CTRLRunError - - try: - document = yaml.safe_load(fence.body) - except yaml.YAMLError as exc: - return Failure(fence.location, fence.language, f"not valid YAML: {exc}") - if not isinstance(document, Mapping): - return Failure(fence.location, fence.language, "a runnable YAML block is a document") - try: - if "actions" in document: - Policy.from_yaml(fence.body, source=fence.location) - if "authority" in document: - Authority.from_yaml( - fence.body, source=fence.location, standalone="actions" not in document - ) - if "actions" not in document and "authority" not in document: - return Failure( - fence.location, - fence.language, - "neither a policy (`actions:`) nor an authority document (`authority:`)", - ) - except CTRLRunError as exc: - return Failure(fence.location, fence.language, f"{type(exc).__name__}: {exc}") - (workdir / _file_token(fence, "ctrlrun.yaml")).write_text(fence.body, encoding="utf-8") - return None - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) - parser.add_argument("paths", nargs="*", type=Path, help="documents to run; default: all") - parser.add_argument("--list", action="store_true", help="list runnable blocks and exit") - arguments = parser.parse_args(argv) - paths = [p.resolve() for p in arguments.paths] or documents(patterns=DOCUMENT_PATTERNS) - if arguments.list: - for path in paths: - for fence in runnable_fences(path): - print(f"{fence.location} {fence.language} {' '.join(fence.tokens)}") - return 0 - outcome = run_documents(paths) - for failure in outcome.failures: - print(f"FAIL {failure}") - scope = ", ".join(relative(p) for p in paths) if len(paths) <= 3 else f"{len(paths)} documents" - print(f"snippets: {outcome.ran} runnable block(s) in {scope}, {len(outcome.failures)} failed") - return 0 if outcome.ok else 1 - - -if __name__ == "__main__": - sys.exit(main())