--- id: informed-decision.lifecycle name: Decision lifecycle authoring and collaboration namespace: informed-decision:decision-memo version: v1 status: ready package: flexauth.informed_decision.lifecycle allow_ttl: 30s actions: [lifecycle.register, lifecycle.read, lifecycle.search, lifecycle.revise, lifecycle.source, lifecycle.evaluation, lifecycle.comment, lifecycle.events, lifecycle.packet, lifecycle.publish, lifecycle.request_review, lifecycle.outcomes] owner: flex-auth fixtures: [fixtures.json] caring: profile: caring-0.4.0-rc2 enforce: false activation: mode: local --- # Initial lifecycle audience Founder direction, 2026-10-04, INFD-WP-0007: net-kingdom-admins humans and system:serviceaccount:state-hub:state-hub. This package is evaluated by Access Engine; the consumer supplies authenticated identity and immutable record facts. The evaluator's workload caller remains informed-decision/review, audience flex-auth. The State Hub subject is authenticated separately for audience informed-decision-lifecycle using CA-verified TokenReview, never a browser token. Humans require KeyCape AAL2 MFA within 12 hours for authoring. Actual human binding retains the separate review policy's 900-second MFA requirement. This package has no accept action. An initial caller can register and search; record access requires original authorship or an explicit publication audience. Published collaborators may research, discuss and refine. Publication and requesting review require original authorship or an admitted human collaborator. Publication may name only the initial human group; explicit subjects still require admitted identity. Review routing is fixed to State Hub, decision-record class and net-kingdom-admins. Every operation is fresh; neither content nor evaluation assertions confer permission. Command digests correlate commands, not signatures. No presentation/view hash enters this policy. The sibling registry declares identity contract profiles, following the existing review packages. These are not real human or workload identifiers and mint no identity. Authentication-derived values still come from the enforced consumer boundary (KeyCape sessions or CA-verified TokenReview). This remains a consumer claim trust boundary; a registry declaration is not independent verification. ```rego import rego.v1 common if { input.tenant == "tenant:platform" input.subject.tenant == input.tenant input.resource.tenant == input.tenant input.resource.system == "informed-decision" input.context.contract == "informed-decision.lifecycle.v1" regex.match("^sha256:[0-9a-f]{64}$", input.context.command_digest) input.subject.attributes.principal_type_source == "authentication-derived" input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"} } human if { input.subject.type == "human" "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) age := time.now_ns()/1000000000 - assurance.at age >= -30 age <= 43200 } workload if { input.subject.type == "service" input.subject.id == "system:serviceaccount:state-hub:state-hub" input.subject.attributes.authentication_audience == "informed-decision-lifecycle" is_string(input.subject.attributes.workload_uid) input.subject.attributes.workload_uid != "" } identity if human identity if workload memo_resource if { input.resource.type == "decision-memo" regex.match("^memo:[A-Za-z0-9._:-]{1,256}$", input.resource.id) } owner if { input.context.record.registered == true some author in [input.context.record.registered_by, input.context.record.revision_by] author.sub == input.subject.id author.kind == "person" human } owner if { input.context.record.registered == true some author in [input.context.record.registered_by, input.context.record.revision_by] author.sub == input.subject.id author.kind == "service" workload } readable if owner readable if { input.context.record.registered == true input.subject.id in input.context.record.published_audience.subjects } readable if { human "net-kingdom-admins" in input.context.record.published_audience.groups } may_publish if owner may_publish if { human readable } audience_ok if { a := input.context.publication_audience is_array(a.subjects) is_array(a.groups) count(a.subjects) <= 32 count(a.groups) <= 32 count(a.subjects)+count(a.groups) > 0 every group in a.groups { group == "net-kingdom-admins" } every subject in a.subjects { is_string(subject); subject != ""; subject != "*" } } operation if { input.action == "lifecycle.register" memo_resource not input.context.record.registered input.context.memo_version == 1 } operation if { input.action == "lifecycle.register" memo_resource owner input.context.memo_version == 1 } operation if { input.action == "lifecycle.search" input.resource.type == "decision-collection" input.resource.id == "decisions" } operation if { input.action in {"lifecycle.read", "lifecycle.events", "lifecycle.packet", "lifecycle.outcomes", "lifecycle.revise", "lifecycle.source", "lifecycle.evaluation", "lifecycle.comment"} memo_resource readable } operation if { input.action == "lifecycle.publish" memo_resource may_publish audience_ok } operation if { input.action == "lifecycle.request_review" memo_resource may_publish routing := input.context.review_routing routing.submitter == "state-hub" routing.memo_class == "decision-record" routing.review_group == "net-kingdom-admins" } decision := {"effect":"allow", "reason":"lifecycle_collaboration"} if { common identity operation } else := {"effect":"deny", "reason":"lifecycle_scope_or_identity_refused"} ``` ```rego test package flexauth.informed_decision.lifecycle_test import rego.v1 import data.flexauth.informed_decision.lifecycle test_empty_denied if { lifecycle.decision.effect == "deny" with input as {} } ```