access-engine/examples/informed-decision-sitting/policy.md
tegwick 1aae59feb6
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 49s
Admit review acts for the three T03 version-3 memos (v11).
Assistant: grok
Assistant-Session: 01a106a5-fc07-78c2-b64f-8e04cea25daf
2026-10-04 16:36:26 +02:00

28 KiB

id name namespace version status package allow_ttl actions owner fixtures caring activation
informed-decision.compact-sitting Compact sitting exact-record human review informed-decision:decision-memo v11 ready flexauth.informed_decision.compact_sitting 30s
read
acknowledge
accept
return
discuss
decline
list
flex-auth
fixtures.json
attribute_fixtures.json
profile enforce
caring-0.4.0-rc2 false
mode
local

Compact sitting review mandate

This is a new exact-record package for seven 2026-09-14 sitting memos. v2 (2026-09-21) adds exactly one record, memo:infd-20260921-b01 (the SECRETS-WP-0009-T03 spend envelope), with native pins from informed-decision docs/evidence/2026-09-21-budget-approval-create.json. The seven v1 records and the identity bar are unchanged. It is not an expansion of examples/informed-decision-t03 / FLEX-WP-0027. memo:infd-20260914-c01 is omitted (create-client still undecided).

v3 (2026-09-21, FLEX-WP-0032, FLEX-DEC-2026-017) adds one action, list, for informed-decision's decision overview (INFD-IN-0008). It is a separate rule, not an extra member of the act set, and it changes nothing else:

  • read and the five acts keep the v2 rule unchanged — the same eight records, the same 900-second MFA window. A list allow satisfies no other action.
  • list covers the union of this package's eight records and the three SECRETS-WP-0010-T03-* records from informed-decision.t03-review, each pinned by approval id, binding digest and its own memo version (T03 at 3). Scope stays exact-record: a memo is listable only once someone admitted it. The operator declined resource-type-wide scope because the PDP checks no recipient, and a type-wide rule would have left consumer code — which the consumer itself says is not an entitlement — as the only scope.
  • list carries the same identity bar with a 12-hour MFA window instead of 900 seconds. Looking back at your own outcomes is not binding a new one. The bar is lighter, not absent: the PDP still states a bound.
  • The KeyCape stale-timestamp defect (INFD-IN-0005) is not worked around here. read stays strict; that defect is key-cape's to fix.

v4 (2026-09-27, REINAH-WP-0003-T06) adds exactly one record for the EUR 10 single-attempt tool proof. Native pins come from informed-decision docs/evidence/2026-09-27-tool-budget-approval-create.json. Existing records, actions and identity requirements remain unchanged.

v5 (2026-09-27, REINAH-WP-0003-T06) admits the replacement-window memo memo:infd-20260927-b02 with fresh native pins. The accepted b01 record is preserved; this change does not extend its signed execution window.

v6 (2026-09-27, REINAH-WP-0003-T06) admits six exact native metered credential requests, apply/verify/exec per provider and worker lane. All acts still require the authenticated human and fresh MFA. Ordinary worker approvals retain their native control type and require exact-ID consumer configuration.

v7 (2026-10-03, INFD-WP-ADHOC-2026-10-03-T02) adds the exact memo:infd-20261003-p01 delivery-proof acceptance record. Native pins come from informed-decision docs/evidence/2026-10-03-provisioning-window-approval-create.json. Existing records and identity requirements are preserved.

v8 (2026-10-03, offline attribute admission) adds one branch beside those exact-record rules. It is not the deployed sitting pin. Requests whose resource id is in records or listable still take only the exact-record rules, including when they also carry attribute fields, so an exact-record decision does not change. list stays on the exact-record rule.

The attribute branch may allow read, acknowledge, accept, return, discuss and decline for any other memo id. attribute_eligible is eligibility only. It checks that the carried approval id is a UUID and the carried digest matches sha256: plus 64 lowercase hex digits. It does not read an approval and it does not prove the memo pin. The effect owner still reads the approval live and compares that id and the engine's native digest with the memo. approval_human_control must be boolean true. No presentation hash is read. Context fields are review_group, memo_class, intake_submitter, approval_requester, approval_human_control, memo_version, approval_id and approval_binding_digest.

v9 (2026-10-04, EMERGENT-WP-0002 profile adoption) adds exactly one record, memo:emergent-profile-adoption-0-2-6. Native pins come from informed-decision docs/evidence/2026-10-04-emergent-profile-approval-create.json, approval 05751e09-3a5b-4a41-a4e8-b79e96de6484. Existing exact records stay. The v8 attribute branch remains beside them and still admits nobody, because the shipped submitter and class sets are empty.

v10 (2026-10-04, STATE-WP-0094 production-steps sitting) adds exactly four records: memo:state-hub-edge-receiving-rollout-c287ed8, memo:owner-return-pickup-plan-b6222af, memo:freshness-runner-deploy-trial-e77f8b4 and memo:freshness-schedule-enable-retire-sweep. Native pins come from informed-decision docs/evidence/2026-10-04-state-hub-wp0094-approval-create.json, approvals 974eae4d-782d-41ed-93be-e34433b5fe59, 77993081-1db2-4bba-99f2-74ca1f8652b1, 4ae04c8e-d604-4d8b-b166-693eef855da8 and b75752d1-bab6-4cf3-9308-5368c1d5aa91. Existing exact records, including v9's, stay. The v8 attribute branch still admits nobody.

v11 (2026-10-04, IR-WP-0005-T02) lets the three list_only_records be reviewed. read, acknowledge, accept, return, discuss and decline allow when the memo id, memo version 3, approval id and binding digest match those records, with the same 900-second KeyCape bar as the version-1 act rule. list is unchanged. A version other than 3, a foreign approval id, or a different digest is refused. The version-1 records set is unchanged, and these three ids stay out of it.

admitted_submitters and admitted_classes are generated from informed-decision deploy/intake-submitters.json. The shipped registry is empty, so both sets are empty and this branch admits nobody. Regenerate with python3 tools/gen_informed_decision_admission.py; --check reports drift.

The identity bar matches T03: authenticated informed-decision caller, net-kingdom-admins, fresh KeyCape AAL2 MFA. No permission follows from memo content or presentation state. TokenReview must admit system:serviceaccount:informed-decision:review before this package is served. Membership tenant provenance may follow the accepted registration route; it does not assert directory membership in tenant:platform. Only a real human uses accept. This package neither issues nor consumes approval. Native pins: docs/evidence/2026-09-15-sitting-approval-creates.json.

import rego.v1

records := {
  "memo:state-hub-edge-receiving-rollout-c287ed8": {
    "approval_id": "974eae4d-782d-41ed-93be-e34433b5fe59",
    "binding_digest": "sha256:84735b88b2db20d9445af369e28a8d40bd495dd20c0303ff3a764666ec976dde"
  },
  "memo:owner-return-pickup-plan-b6222af": {
    "approval_id": "77993081-1db2-4bba-99f2-74ca1f8652b1",
    "binding_digest": "sha256:e745ef64658e77e41b2a5ef569ec0f6986e120d338656d75749425f5f29b7ca0"
  },
  "memo:freshness-runner-deploy-trial-e77f8b4": {
    "approval_id": "4ae04c8e-d604-4d8b-b166-693eef855da8",
    "binding_digest": "sha256:f8ff89dd353c1d2006622c45996c0f05f050865f8c203373dc74da1ba3f05e24"
  },
  "memo:freshness-schedule-enable-retire-sweep": {
    "approval_id": "b75752d1-bab6-4cf3-9308-5368c1d5aa91",
    "binding_digest": "sha256:cc3e8fe6ace5438f19d647d3de226407c8b009985c82ad9a993e81226e6f316f"
  },
  "memo:infd-20261003-p01": {
    "approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
    "binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
  },
  "memo:emergent-profile-adoption-0-2-6": {
    "approval_id": "05751e09-3a5b-4a41-a4e8-b79e96de6484",
    "binding_digest": "sha256:7843e660694dcd7c806dc02ee0cca05dd3a96488f614b1946291496259a02001"
  },
  "memo:infd-20260914-c02": {
    "approval_id": "ccfd8007-2061-48fd-9356-99b16279dac1",
    "binding_digest": "sha256:942cf7d5e6805987df2077a0cc6cde75b148e1729a96dd0692153287820b6a0a"
  },
  "memo:infd-20260914-c03": {
    "approval_id": "a0611d0d-b9ef-4b9a-aa79-e94a9e3fcd5f",
    "binding_digest": "sha256:95cae135b994acea6dad9da978dd3df1aa3354de900a1f43c2e5a03a20e8e844"
  },
  "memo:infd-20260914-c04": {
    "approval_id": "22ac6df3-e6a9-472b-a68e-c8caca4289a7",
    "binding_digest": "sha256:dec960b30efaf654abbdcd8a2cdd20d4ff6bf52e170744f817dc55845d9cb192"
  },
  "memo:infd-20260914-d01": {
    "approval_id": "9f7c3506-68de-4826-86ff-e301f428408d",
    "binding_digest": "sha256:8cb7cc93f38db9d19b49e201e0554b50af1891fec853fef333a06ea078541d15"
  },
  "memo:infd-20260914-d02": {
    "approval_id": "b3ce2c01-0a3b-401e-b4ed-c1954af169c9",
    "binding_digest": "sha256:be0c7de123216740d2c2eeaed80384e03e6b6d1668104f94bb8f9cbae7dfe30f"
  },
  "memo:infd-20260914-d03": {
    "approval_id": "3b483e6b-0b92-45ff-83b6-bc5057c0a496",
    "binding_digest": "sha256:3c562278e86bb5e7f747452cf2e99d3a136853ab748676e8359262b835cd1425"
  },
  "memo:infd-20260914-d04": {
    "approval_id": "356e67a3-5539-46a1-922a-f5591fd38ee5",
    "binding_digest": "sha256:3c2d7759679d871cb7c5cac8999542a365e64c918d59d0c4ce864ffb837453e4"
  },
  "memo:infd-20260921-b01": {
    "approval_id": "ba5ce2d8-8b6d-40be-af89-2e8c147029a3",
    "binding_digest": "sha256:e9eaf454e94871ec2060855fcfbd327bcaec873d2c61cae031bec9f95a34bcae"
  },
  "memo:infd-20260927-b01": {
    "approval_id": "e9521804-8fce-4fbc-bfdf-8a1aa959fd61",
    "binding_digest": "sha256:7aefcee9b79eb3285997066b323ae1772e13d58f875aacc6eb5e9407bd1c1185"
  },
  "memo:infd-20260927-b02": {
    "approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
    "binding_digest": "sha256:3e5951847e1909abe1561f561b4591228848a2e1a939b9bf5acab61e2db42773"
  },
  "memo:metered-20260927-provider-apply": {
    "approval_id": "0c05bd0a-f81f-451d-840c-5565628e2edc",
    "binding_digest": "sha256:a36b88244c26b1ffcd765cbadc201ff79260c7bcbd71d20d1584c3c0a3b1c3de"
  },
  "memo:metered-20260927-provider-verify": {
    "approval_id": "47f118a3-a86c-43ad-969d-42e09a0f45bb",
    "binding_digest": "sha256:98636335ccd36286c02fe018f296fd7d4dfd091ee89d27fe1b629e3db00cf121"
  },
  "memo:metered-20260927-provider-exec": {
    "approval_id": "7b32443a-a817-400c-a130-01b9ef04c8ee",
    "binding_digest": "sha256:8b31dd5911552b901b1f807a8cd6348d09547f3dbb2a52e3b42ad9fd948a2b01"
  },
  "memo:metered-20260927-worker-apply": {
    "approval_id": "2ce76d7f-01c3-4b63-8476-8d1230679769",
    "binding_digest": "sha256:412b79fb537d4444e52e3358820b6ea204fa17173a4420ab6372c52d010ee018"
  },
  "memo:metered-20260927-worker-verify": {
    "approval_id": "c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
    "binding_digest": "sha256:bce6e2091ed076ec0040804d24c822078ac1eda18cd62703801fc9da77898303"
  },
  "memo:metered-20260927-worker-exec": {
    "approval_id": "dc22666a-d5d7-46bc-9490-ebe9fe09dc38",
    "binding_digest": "sha256:ae261c9271a21b626be354646054f493d0951f69aecdbde3cfce3ac0c5667e8f"
  }
}

list_only_records := {
  "memo:SECRETS-WP-0010-T03-apply": {
    "approval_id": "b5fcbfcc-ad56-456f-bc36-c823052e9917",
    "binding_digest": "sha256:03cc5b37437f14e86b686ce4054f976556334eff3fa260b03e8014ed3d9217e5",
    "memo_version": 3
  },
  "memo:SECRETS-WP-0010-T03-verify": {
    "approval_id": "4e9ff881-d59f-4143-9155-929afbe8dd43",
    "binding_digest": "sha256:72d9267d038c17107c880ffc9009793ce9c70defbddfe2219628854b811a04b2",
    "memo_version": 3
  },
  "memo:SECRETS-WP-0010-T03-exec": {
    "approval_id": "a24e0898-b3c5-4e50-85a8-18a2c2aa229e",
    "binding_digest": "sha256:f2cf0fb53b740900756ccde5587c3578fcff44beef2f1edab17b9a198a4033d8",
    "memo_version": 3
  }
}

# listable is the union list may range over. Sitting records are memo version 1.
# T03 records carry memo version 3 and are acted on only through list_only_records.
listable := object.union(
  {id: object.union(r, {"memo_version": 1}) | some id, r in records},
  list_only_records,
)

# BEGIN GENERATED admitted_sets (tools/gen_informed_decision_admission.py; do not edit by hand)
admitted_submitters := set()

admitted_classes := set()
# END GENERATED admitted_sets

exact_id if {
  id := object.get(object.get(input, "resource", {}), "id", "")
  listable[id]
}

attribute_attempt if {
  not exact_id
  input.action in {"read", "acknowledge", "accept", "return", "discuss", "decline"}
  ctx := object.get(input, "context", {})
  some key in {"review_group", "memo_class", "intake_submitter", "approval_requester", "approval_human_control"}
  object.get(ctx, key, null) != null
}

identity_core if {
  input.tenant == "tenant:platform"
  input.subject.tenant == "tenant:platform"
  input.subject.type == "human"
  is_string(input.subject.id)
  input.subject.id != ""
  input.subject.attributes.principal_type_source == "authentication-derived"
  input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
  assurance := input.subject.attributes.assurance
  assurance.level == "aal2"
  assurance.mfa == true
  assurance.source == "key-cape"
  assurance.methods == ["pwd", "otp"]
  is_number(assurance.at)
  assurance.at > 0
}

mfa_fresh if {
  identity_core
  age := time.now_ns() / 1000000000 - input.subject.attributes.assurance.at
  age >= -30
  age <= 900
}

stale_mfa if {
  identity_core
  age := time.now_ns() / 1000000000 - input.subject.attributes.assurance.at
  age > 900
}

resource_ok if {
  input.resource.tenant == "tenant:platform"
  input.resource.system == "informed-decision"
  input.resource.type == "decision-memo"
  is_string(input.resource.id)
  regex.match(`^memo:[a-z0-9][a-z0-9-]{2,62}$`, input.resource.id)
}

review_group_ok if {
  group := input.context.review_group
  is_string(group)
  group != ""
  group in input.subject.attributes.groups
}

class_ok if {
  is_string(input.context.memo_class)
  input.context.memo_class in admitted_classes
}

submitter_ok if {
  is_string(input.context.intake_submitter)
  input.context.intake_submitter in admitted_submitters
}

requester_ok if {
  input.context.approval_requester == "informed-decision"
}

human_control_ok if {
  input.context.approval_human_control == true
}

approval_id_ok if {
  is_string(input.context.approval_id)
  regex.match(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`, input.context.approval_id)
}

digest_ok if {
  is_string(input.context.approval_binding_digest)
  regex.match(`^sha256:[0-9a-f]{64}$`, input.context.approval_binding_digest)
}

version_ok if {
  is_number(input.context.memo_version)
  input.context.memo_version >= 1
}

decision := {"effect": "allow", "reason": "operator_admitted_compact_sitting"} if {
  input.tenant == "tenant:platform"
  input.subject.tenant == "tenant:platform"
  input.subject.type == "human"
  is_string(input.subject.id)
  input.subject.id != ""
  input.subject.attributes.principal_type_source == "authentication-derived"
  input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
  "net-kingdom-admins" in input.subject.attributes.groups
  assurance := input.subject.attributes.assurance
  assurance.level == "aal2"
  assurance.mfa == true
  assurance.source == "key-cape"
  assurance.methods == ["pwd", "otp"]
  is_number(assurance.at)
  assurance.at > 0
  age := time.now_ns() / 1000000000 - assurance.at
  age >= -30
  age <= 900
  input.resource.tenant == "tenant:platform"
  input.resource.system == "informed-decision"
  input.resource.type == "decision-memo"
  record := records[input.resource.id]
  input.context.memo_version == 1
  input.context.approval_id == record.approval_id
  input.context.approval_binding_digest == record.binding_digest
  input.action in {"read", "acknowledge", "accept", "return", "discuss", "decline"}
} else := {"effect": "allow", "reason": "operator_admitted_t03_review_act"} if {
  input.action in {"read", "acknowledge", "accept", "return", "discuss", "decline"}
  input.tenant == "tenant:platform"
  input.subject.tenant == "tenant:platform"
  input.subject.type == "human"
  is_string(input.subject.id)
  input.subject.id != ""
  input.subject.attributes.principal_type_source == "authentication-derived"
  input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
  "net-kingdom-admins" in input.subject.attributes.groups
  assurance := input.subject.attributes.assurance
  assurance.level == "aal2"
  assurance.mfa == true
  assurance.source == "key-cape"
  assurance.methods == ["pwd", "otp"]
  is_number(assurance.at)
  assurance.at > 0
  age := time.now_ns() / 1000000000 - assurance.at
  age >= -30
  age <= 900
  input.resource.tenant == "tenant:platform"
  input.resource.system == "informed-decision"
  input.resource.type == "decision-memo"
  record := list_only_records[input.resource.id]
  input.context.memo_version == record.memo_version
  input.context.approval_id == record.approval_id
  input.context.approval_binding_digest == record.binding_digest
} else := {"effect": "allow", "reason": "operator_admitted_overview_list"} if {
  input.action == "list"
  input.tenant == "tenant:platform"
  input.subject.tenant == "tenant:platform"
  input.subject.type == "human"
  is_string(input.subject.id)
  input.subject.id != ""
  input.subject.attributes.principal_type_source == "authentication-derived"
  input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"}
  "net-kingdom-admins" in input.subject.attributes.groups
  assurance := input.subject.attributes.assurance
  assurance.level == "aal2"
  assurance.mfa == true
  assurance.source == "key-cape"
  assurance.methods == ["pwd", "otp"]
  is_number(assurance.at)
  assurance.at > 0
  age := time.now_ns() / 1000000000 - assurance.at
  age >= -30
  age <= 43200
  input.resource.tenant == "tenant:platform"
  input.resource.system == "informed-decision"
  input.resource.type == "decision-memo"
  record := listable[input.resource.id]
  input.context.memo_version == record.memo_version
  input.context.approval_id == record.approval_id
  input.context.approval_binding_digest == record.binding_digest
} else := {"effect": "allow", "reason": "attribute_eligible"} if {
  attribute_attempt
  mfa_fresh
  resource_ok
  review_group_ok
  class_ok
  submitter_ok
  requester_ok
  human_control_ok
  approval_id_ok
  digest_ok
  version_ok
} else := {"effect": "deny", "reason": "identity_refused"} if {
  attribute_attempt
  not identity_core
} else := {"effect": "deny", "reason": "stale_mfa"} if {
  attribute_attempt
  stale_mfa
} else := {"effect": "deny", "reason": "identity_refused"} if {
  attribute_attempt
  not mfa_fresh
} else := {"effect": "deny", "reason": "resource_refused"} if {
  attribute_attempt
  not resource_ok
} else := {"effect": "deny", "reason": "review_group_not_verified"} if {
  attribute_attempt
  not review_group_ok
} else := {"effect": "deny", "reason": "unknown_class"} if {
  attribute_attempt
  not class_ok
} else := {"effect": "deny", "reason": "unknown_submitter"} if {
  attribute_attempt
  not submitter_ok
} else := {"effect": "deny", "reason": "requester_mismatch"} if {
  attribute_attempt
  not requester_ok
} else := {"effect": "deny", "reason": "human_control_false"} if {
  attribute_attempt
  not human_control_ok
} else := {"effect": "deny", "reason": "approval_id_malformed"} if {
  attribute_attempt
  not approval_id_ok
} else := {"effect": "deny", "reason": "digest_mismatch"} if {
  attribute_attempt
  not digest_ok
} else := {"effect": "deny", "reason": "memo_version_refused"} if {
  attribute_attempt
  not version_ok
} else := {"effect": "deny", "reason": "compact_sitting_scope_or_identity_refused"} if {
  true
}
package flexauth.informed_decision.compact_sitting_test
import rego.v1
import data.flexauth.informed_decision.compact_sitting

test_unknown_request_denied if {
  compact_sitting.decision.effect == "deny" with input as {}
}

test_listable_is_exact_union if {
  count(compact_sitting.listable) == count(compact_sitting.records) + count(compact_sitting.list_only_records)
}

test_t03_records_not_in_act_scope if {
  every id, _ in compact_sitting.list_only_records {
    not compact_sitting.records[id]
  }
}

tool_proof_input := {
  "tenant": "tenant:platform",
  "subject": {"id": "test-human", "type": "human", "tenant": "tenant:platform",
    "attributes": {"principal_type_source": "authentication-derived",
      "tenant_source": "registration-supplied", "groups": ["net-kingdom-admins"],
      "assurance": {"level": "aal2", "mfa": true, "source": "key-cape",
        "methods": ["pwd", "otp"], "at": time.now_ns() / 1000000000}}},
  "resource": {"tenant": "tenant:platform", "system": "informed-decision",
    "type": "decision-memo", "id": "memo:infd-20260927-b02"},
  "action": "accept",
  "context": {"memo_version": 1,
    "approval_id": "1e73e514-ef74-4bff-83e7-fa88a3eaba0c",
    "approval_binding_digest": "sha256:3e5951847e1909abe1561f561b4591228848a2e1a939b9bf5acab61e2db42773"},
}

test_tool_proof_exact_record_allowed if {
  compact_sitting.decision.effect == "allow" with input as tool_proof_input
}

test_tool_proof_wrong_native_id_denied if {
  compact_sitting.decision.effect == "deny" with input as tool_proof_input
    with input.context.approval_id as "another-approval"
}

test_tool_proof_wrong_digest_denied if {
  compact_sitting.decision.effect == "deny" with input as tool_proof_input
    with input.context.approval_binding_digest as "sha256:wrong"
}

test_tool_proof_without_mfa_denied if {
  compact_sitting.decision.effect == "deny" with input as tool_proof_input
    with input.subject.attributes.assurance.mfa as false
}


test_six_exact_metered_memos_allow_human_review if {
  every id in ["memo:metered-20260927-provider-apply", "memo:metered-20260927-provider-verify", "memo:metered-20260927-provider-exec", "memo:metered-20260927-worker-apply", "memo:metered-20260927-worker-verify", "memo:metered-20260927-worker-exec"] {
    record := compact_sitting.records[id]
    request := object.union(tool_proof_input, {
      "resource": object.union(tool_proof_input.resource, {"id": id}),
      "context": {"memo_version": 1, "approval_id": record.approval_id,
        "approval_binding_digest": record.binding_digest},
    })
    compact_sitting.decision.effect == "allow" with input as request
  }
}

attribute_input := {
  "tenant": "tenant:platform",
  "subject": {"id": "test-human", "type": "human", "tenant": "tenant:platform",
    "attributes": {"principal_type_source": "authentication-derived",
      "tenant_source": "registration-supplied", "groups": ["net-kingdom-admins"],
      "assurance": {"level": "aal2", "mfa": true, "source": "key-cape",
        "methods": ["pwd", "otp"], "at": time.now_ns() / 1000000000}}},
  "resource": {"tenant": "tenant:platform", "system": "informed-decision",
    "type": "decision-memo", "id": "memo:intake-new-memo"},
  "action": "accept",
  "context": {
    "review_group": "net-kingdom-admins",
    "memo_class": "credential-lane",
    "intake_submitter": "state-hub",
    "approval_requester": "informed-decision",
    "approval_human_control": true,
    "memo_version": 1,
    "approval_id": "706f4205-aaa7-44f6-be30-d0f57664d69c",
    "approval_binding_digest": "sha256:c8a1a9c8fb22616e3aacfb877ba7974feb5eedaed491f856a6c90719c502ebe4"
  },
}

patched_context(req, patch) := object.union(req, {"context": object.union(req.context, patch)})

with_at(req, at) := object.union(req, {"subject": object.union(req.subject, {"attributes": object.union(req.subject.attributes, {"assurance": object.union(req.subject.attributes.assurance, {"at": at})})})})

eligible(req) := result if {
  result := compact_sitting.decision with input as req
    with data.flexauth.informed_decision.compact_sitting.admitted_classes as {"credential-lane"}
    with data.flexauth.informed_decision.compact_sitting.admitted_submitters as {"state-hub"}
}

classes_only(req) := result if {
  result := compact_sitting.decision with input as req
    with data.flexauth.informed_decision.compact_sitting.admitted_classes as {"credential-lane"}
}

test_shipped_sets_admit_nobody if {
  count(compact_sitting.admitted_classes) == 0
  count(compact_sitting.admitted_submitters) == 0
  compact_sitting.decision.reason == "unknown_class" with input as attribute_input
}

test_attribute_acts_are_eligible_only_when_sets_admit if {
  every action in ["read", "acknowledge", "accept", "return", "discuss", "decline"] {
    eligible(object.union(attribute_input, {"action": action})).reason == "attribute_eligible"
  }
}

test_allow_does_not_prove_the_pin if {
  other := "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
  attribute_input.context.approval_binding_digest != other
  eligible(attribute_input).reason == "attribute_eligible"
  eligible(patched_context(attribute_input, {"approval_binding_digest": other})).reason == "attribute_eligible"
}

test_unknown_class if {
  eligible(patched_context(attribute_input, {"memo_class": "not-a-class"})).reason == "unknown_class"
}

test_unknown_submitter if {
  classes_only(attribute_input).reason == "unknown_submitter"
}

test_requester_mismatch if {
  eligible(patched_context(attribute_input, {"approval_requester": "other-service"})).reason == "requester_mismatch"
}

test_human_control_false if {
  eligible(patched_context(attribute_input, {"approval_human_control": false})).reason == "human_control_false"
  eligible(patched_context(attribute_input, {"approval_human_control": "true"})).reason == "human_control_false"
}

test_digest_mismatch if {
  eligible(patched_context(attribute_input, {"approval_binding_digest": "sha256:wrong"})).reason == "digest_mismatch"
  eligible(patched_context(attribute_input, {"approval_binding_digest": "sha256:C8A1A9C8FB22616E3AACFB877BA7974FEB5EEDAED491F856A6C90719C502EBE4"})).reason == "digest_mismatch"
}

test_approval_id_malformed if {
  eligible(patched_context(attribute_input, {"approval_id": "not-a-uuid"})).reason == "approval_id_malformed"
}

test_memo_version_refused if {
  eligible(patched_context(attribute_input, {"memo_version": 0})).reason == "memo_version_refused"
}

test_stale_mfa_on_attribute_branch if {
  eligible(with_at(attribute_input, time.now_ns() / 1000000000 - 901)).reason == "stale_mfa"
}

test_future_mfa_is_identity_refused if {
  eligible(with_at(attribute_input, time.now_ns() / 1000000000 + 300)).reason == "identity_refused"
}

test_service_subject_is_identity_refused if {
  eligible(object.union(attribute_input, {"subject": object.union(attribute_input.subject, {"type": "service"})})).reason == "identity_refused"
}

test_review_group_must_be_verified if {
  req := object.union(attribute_input, {"subject": object.union(attribute_input.subject, {"attributes": object.union(attribute_input.subject.attributes, {"groups": ["other-group"]})})})
  eligible(req).reason == "review_group_not_verified"
}

test_memo_review_group_is_not_hardcoded if {
  req := object.union(attribute_input, {
    "subject": object.union(attribute_input.subject, {"attributes": object.union(attribute_input.subject.attributes, {"groups": ["cabinet-reviewers"]})}),
    "context": object.union(attribute_input.context, {"review_group": "cabinet-reviewers"}),
  })
  eligible(req).reason == "attribute_eligible"
}

test_bad_memo_id_refused if {
  eligible(object.union(attribute_input, {"resource": object.union(attribute_input.resource, {"id": "memo:NO"})})).reason == "resource_refused"
}

test_list_does_not_use_attribute_admission if {
  got := eligible(object.union(attribute_input, {"action": "list"}))
  got.effect == "deny"
  got.reason == "compact_sitting_scope_or_identity_refused"
}

test_exact_record_ignores_attribute_context if {
  req := object.union(tool_proof_input, {"context": object.union(tool_proof_input.context, {
    "review_group": "net-kingdom-admins",
    "memo_class": "credential-lane",
    "intake_submitter": "state-hub",
    "approval_requester": "informed-decision",
    "approval_human_control": true,
    "view_hash": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
  })})
  got := compact_sitting.decision with input as req
  got.effect == "allow"
  got.reason == "operator_admitted_compact_sitting"
}

test_exact_pin_mismatch_is_not_rescued if {
  req := object.union(tool_proof_input, {"context": object.union(tool_proof_input.context, {
    "review_group": "net-kingdom-admins",
    "memo_class": "credential-lane",
    "intake_submitter": "state-hub",
    "approval_requester": "informed-decision",
    "approval_human_control": true,
    "approval_binding_digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  })})
  got := eligible(req)
  got.effect == "deny"
  got.reason == "compact_sitting_scope_or_identity_refused"
}