From e800eaf4dc78f19e8b4f6916ee6108d8d3bd822a Mon Sep 17 00:00:00 2001 From: abhiram Date: Sun, 26 Jul 2026 21:36:01 +0530 Subject: [PATCH] docs: add bounded review scenario fixture Fixes #18 --- examples/bounded_review_scenario/README.md | 70 +++++++++++ .../bounded_review_scenario/akta_record.json | 24 ++++ .../review_trigger.json | 17 +++ .../scope_decision.json | 110 ++++++++++++++++++ .../bounded_review_scenario/scope_grant.json | 24 ++++ .../bounded_review_scenario/scope_packet.json | 49 ++++++++ 6 files changed, 294 insertions(+) create mode 100644 examples/bounded_review_scenario/README.md create mode 100644 examples/bounded_review_scenario/akta_record.json create mode 100644 examples/bounded_review_scenario/review_trigger.json create mode 100644 examples/bounded_review_scenario/scope_decision.json create mode 100644 examples/bounded_review_scenario/scope_grant.json create mode 100644 examples/bounded_review_scenario/scope_packet.json diff --git a/examples/bounded_review_scenario/README.md b/examples/bounded_review_scenario/README.md new file mode 100644 index 0000000..65dfc76 --- /dev/null +++ b/examples/bounded_review_scenario/README.md @@ -0,0 +1,70 @@ +\# Bounded Review Scenario: Narrower Scope Grant + + + +Demonstrates a reviewer approving a narrower scope than originally requested. + + + +\## Scenario + + + +\*\*Original Request:\*\* + +\- Tool requested: `protocol\_editor.update\_active\_protocol` + +\- Scope: `protocol\_update` (broader) + +\- Operation: `update\_active` + + + +\*\*Reviewer Decision (narrower):\*\* + +\- Approved scope: `protocol\_draft` + +\- Family: `protocol` + +\- Operation: `draft` + +\- Allowed tool: `protocol\_editor.draft\_change` + +\- Blocked tool: `protocol\_editor.update\_active\_protocol` + + + +\## Files + + + +| File | Description | + +|------|-------------| + +| `review\_trigger.json` | Original request trigger | + +| `akta\_record.json` | AKTA admissibility record | + +| `scope\_packet.json` | Packet with original requested envelope | + +| `scope\_decision.json` | Signed decision approving narrower scope | + +| `scope\_grant.json` | Issued grant with bounded permissions | + + + +\## What the Fixture Shows + + + +1\. \*\*Packet\*\*: Original request for `protocol\_editor.update\_active\_protocol` + +2\. \*\*Signed Decision\*\*: Reviewer approves narrower `protocol\_draft` scope + +3\. \*\*Issued Grant\*\*: Contains only `protocol\_editor.draft\_change`, blocks `protocol\_editor.update\_active\_protocol` + +4\. \*\*Allowed Action\*\*: `protocol\_editor.draft\_change` - permitted by grant + +5\. \*\*Blocked Action\*\*: `protocol\_editor.update\_active\_protocol` - rejected by reviewer + diff --git a/examples/bounded_review_scenario/akta_record.json b/examples/bounded_review_scenario/akta_record.json new file mode 100644 index 0000000..1dc361f --- /dev/null +++ b/examples/bounded_review_scenario/akta_record.json @@ -0,0 +1,24 @@ +{ + "record_id": "AKTA-SAR-BOUNDED-001", + "requested_transition": { + "requested_action": "update_active_protocol", + "requested_tool": "protocol_editor.update_active_protocol" + }, + "classification": { + "scientific_action_type": "A5_protocol_modification", + "responsibility_level": "R4_methodological_modification", + "evidence_state": "E2_preliminary_signal", + "validation_status": "V1_literature_supported", + "verification_status": "Q0_unchecked" + }, + "decision": { + "admissibility": "review_required", + "blocked_tools": [ + "robot_queue.submit" + ], + "next_admissible_steps": [ + "approve protocol draft for validation review" + ] + }, + "akta_record_hash": "sha256:b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1" +} \ No newline at end of file diff --git a/examples/bounded_review_scenario/review_trigger.json b/examples/bounded_review_scenario/review_trigger.json new file mode 100644 index 0000000..615624a --- /dev/null +++ b/examples/bounded_review_scenario/review_trigger.json @@ -0,0 +1,17 @@ +{ + "trigger_id": "AKTA-REVTRIG-BOUNDED-001", + "akta_record_id": "AKTA-SAR-BOUNDED-001", + "requested_action": "update_active_protocol", + "requested_tool": "protocol_editor.update_active_protocol", + "scientific_action_type": "A5_protocol_modification", + "akta_admissibility": "review_required", + "requested_scope": "protocol_update", + "scientific_context": { + "domain": "materials", + "protocol_version": "protocol_v3", + "evidence_state": "E2_preliminary_signal", + "project_id": "bounded_demo" + }, + "review_trigger_hash": "sha256:c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1", + "akta_record_hash": "sha256:b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1" +} \ No newline at end of file diff --git a/examples/bounded_review_scenario/scope_decision.json b/examples/bounded_review_scenario/scope_decision.json new file mode 100644 index 0000000..7d32ded --- /dev/null +++ b/examples/bounded_review_scenario/scope_decision.json @@ -0,0 +1,110 @@ +{ + "decision_id": "SCOPE-DEC-BOUNDED001", + "packet_id": "SCOPE-PKT-BOUNDED001", + "action_chain_id": "action-chain-bounded-001", + "decided_at": "2026-07-26T12:30:00Z", + "review_mode": "bounded_execution_grant", + "decision": { + "type": "approve_narrower_scope", + "requested_scope": "protocol_update", + "approved_scope": "protocol_draft", + "rationale": "Reviewer approves only draft-level changes. Active protocol updates require additional validation evidence.", + "rejected_scope": [ + "protocol:update_active", + "tool:protocol_editor.update_active_protocol" + ], + "envelope_difference": { + "result": "wider", + "same_family": true, + "family_left": "protocol", + "family_right": "protocol", + "operation_left": "update_active", + "operation_right": "draft", + "tools_only_in_left": [ + "protocol_editor.update_active_protocol" + ], + "tools_only_in_right": [], + "contains_left_in_right": false, + "contains_right_in_left": true + }, + "approved_authorization_envelope": { + "envelope_version": "scientific-authorization-envelope-v2", + "capability_id": "CAP-BOUNDED001-NARROW", + "family": "protocol", + "operation": "draft", + "target": { + "type": "protocol", + "protocol_id": "protocol-v3", + "protocol_version": "protocol_v3" + }, + "environment": { + "domain_overlay": "materials_v0.1", + "project_id": "bounded_demo", + "tenant_id": "lab-a", + "institution_id": "demo-institution" + }, + "allowed_tools": [ + "protocol_editor.draft_change" + ], + "blocked_tools": [ + "protocol_editor.update_active_protocol", + "robot_queue.submit" + ], + "cardinality": { + "mode": "single", + "maximum_uses": 1, + "maximum_items": 1 + }, + "expiration": { + "absolute_expiration": "2099-01-01T00:00:00Z", + "expires_after": [ + "policy_version_change", + "protocol_version_change" + ] + }, + "constraints": {}, + "responsibility_ceiling": "R4_methodological_modification" + }, + "requested_authorization_envelope": { + "envelope_version": "scientific-authorization-envelope-v2", + "family": "protocol", + "operation": "update_active", + "allowed_tools": [ + "protocol_editor.draft_change", + "protocol_editor.update_active_protocol" + ], + "blocked_tools": [ + "robot_queue.submit" + ] + } + }, + "confidence": { + "reviewer_confidence": 0.85, + "requires_second_review": false + }, + "reviewer": { + "reviewer_id": "r1", + "role": "protocol_owner", + "declared_expertise": ["materials_science", "protocol_design"], + "independence": { + "independence_schema_version": "scope-reviewer-independence-v1", + "role": "protocol_owner", + "relationship_to_action_owner": "unknown", + "relationship_to_evidence_producer": "none", + "saw_model_recommendations": false, + "blinding_condition": "not_applicable" + }, + "conflict_declared": false + }, + "reviewer_public_key_ref": "sha256:feea3a0b74927afa9286237e5da1e13e3538f9eb8f9515790e81555a0ec3d6f3", + "signature_algorithm": "ed25519", + "decision_signature": "sig_decision_bounded_001", + "signed_payload_hash": "sha256:decision_payload_hash_xyz789", + "decision_hash": "sha256:decision_hash_abc123", + "source": { + "packet_id": "SCOPE-PKT-BOUNDED001", + "packet_hash": "sha256:abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123", + "akta_record_id": "AKTA-SAR-BOUNDED-001", + "review_trigger_id": "AKTA-REVTRIG-BOUNDED-001" + } +} \ No newline at end of file diff --git a/examples/bounded_review_scenario/scope_grant.json b/examples/bounded_review_scenario/scope_grant.json new file mode 100644 index 0000000..f061902 --- /dev/null +++ b/examples/bounded_review_scenario/scope_grant.json @@ -0,0 +1,24 @@ +{ + "grant_id": "SCOPE-GRANT-BOUNDED001", + "grant_version": "2.2.0", + "created_at": "2026-07-26T12:35:00Z", + "source": { + "packet_id": "SCOPE-PKT-BOUNDED001", + "decision_id": "SCOPE-DEC-BOUNDED001", + "akta_record_id": "AKTA-SAR-BOUNDED-001" + }, + "authorization": { + "approved_scope": "protocol_draft", + "approved_actions": ["A5_protocol_modification"], + "authorization_envelope": { + "envelope_version": "scientific-authorization-envelope-v2", + "family": "protocol", + "operation": "draft", + "allowed_tools": ["protocol_editor.draft_change"], + "blocked_tools": ["protocol_editor.update_active_protocol", "robot_queue.submit"], + "cardinality": {"mode": "single", "maximum_uses": 1, "maximum_items": 1} + } + }, + "signature_algorithm": "Ed25519", + "grant_signature": "sig_grant_bounded_001" +} \ No newline at end of file diff --git a/examples/bounded_review_scenario/scope_packet.json b/examples/bounded_review_scenario/scope_packet.json new file mode 100644 index 0000000..406a2a2 --- /dev/null +++ b/examples/bounded_review_scenario/scope_packet.json @@ -0,0 +1,49 @@ +{ + "packet_id": "SCOPE-PKT-BOUNDED001", + "packet_type": "akta_review_packet", + "review_mode": "bounded_execution_grant", + "created_at": "2026-07-26T12:00:00Z", + "source": { + "akta_record_id": "AKTA-SAR-BOUNDED-001", + "review_trigger_id": "AKTA-REVTRIG-BOUNDED-001", + "action_chain_id": "action-chain-bounded-001" + }, + "requested_authorization_envelope": { + "envelope_version": "scientific-authorization-envelope-v2", + "capability_id": "CAP-BOUNDED001", + "family": "protocol", + "operation": "update_active", + "target": { + "type": "protocol", + "protocol_id": "protocol-v3", + "protocol_version": "protocol_v3" + }, + "environment": { + "domain_overlay": "materials_v0.1", + "project_id": "bounded_demo", + "tenant_id": "lab-a", + "institution_id": "demo-institution" + }, + "allowed_tools": [ + "protocol_editor.draft_change", + "protocol_editor.update_active_protocol" + ], + "blocked_tools": [ + "robot_queue.submit" + ], + "cardinality": { + "mode": "unbounded", + "maximum_uses": null, + "maximum_items": null + }, + "expiration": { + "absolute_expiration": null, + "expires_after": [] + }, + "constraints": {}, + "responsibility_ceiling": "R4_methodological_modification" + }, + "requested_scope": "protocol_update", + "packet_hash": "sha256:abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc123", + "packet_signature": "sig_bound_001" +} \ No newline at end of file