Skip to content

Assync Human Decision Queue

Purpose

The only place an elevated authorization may be minted, and the only place a mission's blocked path is resolved — never automatically.

Model (decisions/models.py)

A Decision has: id, mission_id, question, decision_type, a fixed set of options (id/label pairs), recommendations (role_id → option, for display only — never binding), evidence_ids, blocking_finding_ids, required_authority, state, created_at, and an optional resolution.

States (decisions/queue.py)

PENDING → APPROVED | REJECTED | CHANGES_REQUESTED | ABORTED

PENDING is the only non-terminal state — every resolution is final. A decision is never re-resolved (require_pending() raises StateTransitionError on a second attempt, tested in test_decisions.py::test_invalid_state_transition_rejected). Decisions are never auto-resolved — every resolution requires a non-empty human_actor (decisions/service.py::resolve_decision).

Resolution (decisions/service.py::resolve_decision)

Records: selected option, human actor, timestamp, optional rationale, referenced evidence, and an optional authorization_granted_id. An authorization grant is only ever created when the resolution is APPROVED — attempting it alongside a REJECTED/CHANGES_REQUESTED resolution raises ValidationError (test_authorization_grant_rejected_for_non_approval). The minted Authorization's evidence_or_decision_reference is always set to the decision's own ID, giving every elevated grant a traceable human-decision provenance.

Finding Risk Acceptance (findings/service.py::accept_finding_risk)

The only path that turns a blocking finding non-blocking. Requires both a decision_reference and a justification — never deletes the finding, only marks it accepted with the acceptance recorded (see role-pool.md's and synthesis-engine.md's references to this).

CLI (commands/decision.py)

assync decision list|show|approve|reject|request-changes. Each resolution command requires an explicit --actor; there is no "resolve as system" path.

MVP Limitations

  • There is no mission-side automatic re-evaluation after a decision resolves — see mission-orchestrator.md's note on why a rejected risk-acceptance decision requires a separate, explicit assync mission abort call in this state model, rather than an automatic mission-state transition.
  • required_authority is currently a free-text field (default "governance_authority"), not yet cross-checked against the role registry's non-executable Human Governance Authority entry.