███████╗ ██████╗ ██████╗ ██████╗ ███████╗ ██╔════╝██╔═══██╗██╔═══██╗██╔══██╗██╔════╝ ███████╗██║ ██║██║ ██║██████╔╝█████╗ ╚════██║██║ ██║██║ ██║██╔═══╝ ██╔══╝ ███████║╚██████╔╝╚██████╔╝██║ ███████╗ ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
Scoped authorization for AI-shaped scientific work
When an AI system proposes a scientific action — updating a protocol, submitting to a robot queue, or publishing a claim — someone with the right expertise should review it before tools run. Most systems treat that as a checkbox. SCOPE treats it as a structured workflow: who reviewed, what they saw, what scope they approved, when it expires, and what happened at runtime.
SCOPE does not certify that an action is safe or correct. It produces auditable artifacts and enforces the scope a qualified reviewer actually approved.
- Builds a review packet from upstream signals (what changed, what evidence exists, who should review)
- Captures a typed reviewer decision with rationale, role, and provenance
- Issues a bounded grant — allowed tools, scope, and expiration — tied to that decision
- Enforces grants at runtime and records violations, revocations, and expirations
- Maintains a hash-chained ledger for accountability and quality metrics
- Exports obligations and packaging artifacts for downstream runtimes (PF-Core, PCS)
flowchart LR
A[Upstream signal] --> B[Review packet]
B --> C[Reviewer decision]
C --> D[Scoped grant]
D --> E[Runtime enforcement]
E --> F[Ledger and exports]
Review is not a checkbox. Review is a role, an artifact, a scope, an expiration, and an accountability trail.
Under two minutes from clone to a working review:
git clone https://github.com/fraware/SCOPE.git
cd SCOPE
pip install -e "./scientific-authorization-contracts"
pip install -e ".[dev]"
pytestSCOPE 2.1 pins scientific-authorization-contracts==2.1.0 as the sole authorization algebra package. Install contracts before SCOPE (CI does the same).
Run the bundled evaluation scenarios (8 core; add --extended for 14 more, 22 total):
python evals/run_review_cases.py
python evals/run_review_cases.py --extendedProduction grants require an authorization envelope, not an unsigned scalar scope string alone. Reviewer decisions approve a typed envelope (family, operation, targets, constraints, …). Grant issuance finalizes and issuer-signs that envelope in one step (finalize_and_sign_grant).
- Reviewer signs the decision with their registered key (
policy/reviewer_key_registry.yaml/SCOPE_REVIEWER_SIGNING_KEY_MAP). Never use the SCOPE issuer key as a reviewer key. - Issuer signs the grant with
SCOPE_ISSUER_SIGNING_KEYduringissue_grant/ session grant issuance. - Optional: the REST server may attach a separate institutional attestation on a decision without replacing the reviewer signature.
Runtime enforcement loads the grant from the tenant-bound ledger:
engine.preflight_authorize(grant_id, action) # no consume
engine.authorize_and_consume(grant_id, action, key) # atomic consumeREST: POST /v0/grants/check with {grant_id, action} (RuntimeActionContext). Raw external-grant dict verification is admin-only (POST /v0/admin/grants/verify).
| Profile | When |
|---|---|
scope-grant-development-v2 |
Local/dev (unsigned escape hatch allowed only outside production) |
scope-grant-institutional-v2 |
Production — requires envelope, issuer identity, hashes, signatures, IAL/SAL, manifest binding |
SCOPE_PRODUCTION_MODE always requires a signed authorization manifest; the unsigned-manifest escape hatch is disabled in production.
The primary integration path when AKTA flags an action for review: one command produces the packet, decision, grant, and summary.
scope akta review \
--akta-trigger examples/protocol_drift/review_trigger.json \
--akta-record examples/protocol_drift/akta_record.json \
--grant-scope protocol_draft \
--reviewer examples/protocol_drift/reviewer_protocol_owner.json \
--decision-rationale "Narrow protocol draft approval only." \
--signing-key ./keys/reviewer.pem \
--out-dir ./out/akta_reviewProduction paths require a reviewer signing key. Unsigned scalar decisions cannot issue production grants.
Outputs in ./out/akta_review/:
| File | Purpose |
|---|---|
scope_review_packet.json |
Artifacts and context for the reviewer |
scope_decision.json |
Structured approval with rationale |
scope_grant.json |
Runtime authorization bound to the decision |
summary.json |
One-line status for automation |
Full contract: docs/akta_review_contract.md. End-to-end demo: docs/akta_scope_demo.md.
For multi-role actions (for example A6 experimental planning), pass --session to create a review session instead of issuing a grant immediately. The command writes summary.json with status: session_required and a session_id for the vote workflow.
Institutional pilot scenarios with regenerated artifacts: examples/pilot/.
Build and validate a packet from AKTA inputs, optionally enriched with a VSA scientific report:
scope packet create \
--akta-record examples/protocol_change_review/akta_record.json \
--akta-trigger examples/protocol_change_review/review_trigger.json \
--out ./out/packet.json
scope packet validate ./out/packet.json
scope packet render ./out/packet.json --format markdown --out ./out/packet.mdFor multi-reviewer cases, use review sessions (scope review session …) or the review queue (scope review queue …). See docs/reviewer_guide.md.
Submit a reviewer decision with an approved authorization envelope, sign with the reviewer's key, then issue an issuer-signed grant:
scope decision submit \
--packet ./out/packet.json \
--reviewer examples/protocol_change_review/reviewer_protocol_owner.json \
--decision examples/protocol_change_review/decision.json \
--out ./out/decision.json
scope decision sign \
--decision ./out/decision.json \
--key ./keys/reviewer.pem \
--out ./out/decision.signed.json
scope grant issue \
--packet ./out/packet.json \
--decision ./out/decision.signed.json \
--out ./out/grant.jsonIn production, decisions must be cryptographically signed by the reviewer before grant issue, and grants are finalized/issuer-signed in one step. See docs/trusted_boundary.md and docs/key_management.md.
Before a tool executes, verify the grant still allows the requested action (prefer grant ID + ledger):
scope grant check \
--grant ./out/grant.json \
--requested-tool robot_queue.submit \
--context examples/protocol_change_review/current_context.json \
--ledger ./out/scope_events.jsonlPython API (SCOPE 2.1):
engine.authorize_and_consume(grant_id, action_context, idempotency_key)Returns ALLOWED or BLOCKED. Revoke or inspect status via scope grant revoke and scope grant status.
For the complete CLI surface (export, quality, identity, policy overlays), run
scope --helpor see docs/scoped_scientific_authorization.md.
| Component | Role |
|---|---|
| AKTA | Classifies whether a scientific action needs review or authorization |
| SCOPE | Runs the review workflow and issues scoped grants |
| PF-Core | Runtime obligation verification from grant exports |
| PCS | Release packaging from packet, decision, and grant artifacts |
| VSA | Optional scientific report enrichment for review packets |
Integration field mappings: docs/external_integration_contracts.md. Optional REST API: install with pip install -e ".[rest]" and run uvicorn adapters.generic_rest.server:app.
Institutional pilots: start with docs/institutional_pilot_guide.md. Workshop fixtures: examples/institutional_pilot/. v0.8 pilot pack: examples/pilot/.
| Document | Description |
|---|---|
| scoped_scientific_authorization.md | Protocol overview and doc index |
| akta_review_contract.md | Frozen scope akta review output contract |
| akta_integration.md | AKTA adapter and trigger mapping |
| akta_scope_demo.md | Full AKTA → SCOPE → PF → PCS walkthrough |
| reviewer_guide.md | Reviewer role guidance |
| review_doctrine.md | Review principles and accountability |
| production_deployment.md | Production IdP / manifest / ledger wiring |
| institutional_pilot_guide.md | Pilot workshop and lab checklist |
| institutional_guide.md | Institutional deployment overview |
| trusted_boundary.md | Trust assumptions and production mode |
| limitations.md | In-repo vs external boundaries |
| identity_assurance.md | Reviewer identity provenance |
| signing_assurance.md | Decision and grant signing provenance |
| rbac_scope_authority.md | Org RBAC and scope policy checks |
| key_management.md | Key registry and signing providers |
| quality_metrics.md | Ledger-backed review quality metrics |
| threat_model.md | Threats addressed and residual risk |
| external_integration_contracts.md | Cross-repo field mappings |
| pf_core_bridge.md | PF-Core obligation export |
| pcs_export.md | PCS bundle export |
| evidence_vocab_mapping.md | Evidence vocabulary alignment |
| field_thesis.md | Design rationale |
| CHANGELOG.md | Release history |
Contributions are welcome — bug reports, docs improvements, adapters, and test coverage all help.
- Open an issue to discuss larger changes: GitHub Issues
- Fork, branch, and open a PR: GitHub Pull Requests
- Run the same checks as CI before submitting:
# Linux / macOS — local gates
bash scripts/ci.sh
# Institutional profile (requires live Postgres DSN)
export SCOPE_LEDGER_DATABASE_URL=postgresql://scope:scope@127.0.0.1:5432/scope
bash scripts/ci.sh --institutional
# Windows
.\scripts\ci.ps1
.\scripts\ci.ps1 -InstitutionalCI runs on Python 3.10–3.12 (test job) plus an institutional job with a Postgres 16 service. Local gates: ruff, mypy, pytest (excluding live_contract / live_postgres), and evaluation scenarios with --extended. Env template: docs/env.institutional.example. Sibling clones: scripts/clone_sibling_contracts.sh. See docs/institutional_guide.md and docs/production_deployment.md.
Individual commands:
pip install -e "./scientific-authorization-contracts"
pip install -e ".[dev]"
ruff check scope tests evals adapters
mypy scope
pytest
python evals/run_review_cases.py --extended| Path | Contents |
|---|---|
scope/ |
Core protocol engine and CLI |
schemas/ |
JSON schemas for artifacts |
policy/ |
YAML policy bundles and domain overlays |
adapters/ |
AKTA, VSA, PF-Core, PCS, and REST integrations |
examples/ |
Scenario fixtures for docs and evals |
evals/ |
8 core + 14 extended evaluation scenarios |
tests/ |
Pytest suite |
docs/ |
Protocol and integration documentation |
from scope import ScopeEngine
from scope.scopes import envelope_for_scope
from scope.signing import Ed25519Signer
engine = ScopeEngine.from_policy_dir("policy/", ledger_path="logs/scope_events.jsonl")
packet = engine.create_packet(
"examples/protocol_change_review/akta_record.json",
"examples/protocol_change_review/review_trigger.json",
)
envelope = envelope_for_scope("protocol_draft", engine.policy).to_dict()
decision = engine.submit_decision(
packet,
{"reviewer_id": "r1", "role": "protocol_owner"},
{
"type": "approve_narrower_scope",
"approved_scope": "protocol_draft",
"approved_authorization_envelope": envelope,
"rationale": "Evidence supports validation draft only.",
},
)
decision = engine.sign_decision(decision, Ed25519Signer("keys/reviewer.pem"))
grant = engine.issue_grant(packet, decision, issuer_signer=Ed25519Signer("keys/issuer.pem"))
result = engine.authorize_and_consume(
grant["grant_id"],
{
"requested_tool": "protocol_editor.draft_change",
"family": "protocol",
"operation": "draft",
"protocol_version": "protocol_v3",
},
"idem-1",
)Technical reference for assurance models, production mode, and cross-repo contracts:
| Topic | Document |
|---|---|
| Identity assurance levels (IAL0–IAL4) | identity_assurance.md |
| Signing assurance levels (SAL0–SAL4) | signing_assurance.md |
| Two-stage authority checks | rbac_scope_authority.md |
| Production mode and signing | trusted_boundary.md |
REST API (POST /v0/akta/review, grant check, queue) |
external_integration_contracts.md |
| PF obligation and PCS manifest formats | pf_core_bridge.md, pcs_export.md |
Environment variables for production (OIDC identity, signed manifest, Postgres ledger, signing keys) are listed in docs/env.institutional.example and explained in docs/production_deployment.md, docs/trusted_boundary.md, and docs/institutional_guide.md. Dev-only key helper: python scripts/generate_dev_institutional_keys.py --exports (not for production).
MIT — see LICENSE.