(module examples.private_deployment_risk
  (capsule "0")
  (profile agentic persistence.surrealdb external.mcp ui.a2ui zk.noir)

  (store operational
    (backend surrealdb)
    (authority runtime-state))

  (port ci
    (protocol mcp)
    (tool deploy))

  (surface private_change_approval
    (title "Private deployment risk approval")
    (route "/changes/private-risk")
    (bind PrivateRiskChangeApproval)
    (event SubmitChange RiskProofSubmitted ManagerApprove Deploy Reject))

  (zk-proof DeploymentRiskProof
    (backend noir)
    (public
      (change_id U64)
      (threshold U32)
      (risk_model_hash Bytes32))
    (private
      (risk_score U32)
      (findings_commitment Bytes32))
    (proves (<= risk_score threshold))
    (summary "Proves that a private deployment risk score is below a public threshold without revealing the risk score or findings."))

  (machine PrivateRiskChangeApproval
    (version "0.1.0")
    (context
      (change_id U64)
      (risk_proof_verified Bool)
      (manager_approved Bool)
      (deployed Bool))
    (event SubmitChange
      (change_id U64))
    (event RiskProofSubmitted
      (proof_ref Bytes32))
    (event ManagerApprove)
    (event Deploy)
    (event Reject)
    (initial idle)
    (persistence
      (store operational)
      (event-log authoritative)
      (snapshot every-transition)
      (replay true))

    (state idle
      (on SubmitChange
        (target awaiting_private_risk_proof)
        (assign
          (change_id event.change_id)
          (risk_proof_verified false)
          (manager_approved false)
          (deployed false))
        (effects
          (db.write operational.change_requests)
          (a2ui.emit private_change_approval))))

    (state awaiting_private_risk_proof
      (on RiskProofSubmitted
        (target awaiting_manager_approval)
        (assign
          (risk_proof_verified true))
        (effects
          (zk.verify DeploymentRiskProof)
          (db.write operational.proof_events)
          (a2ui.emit private_change_approval)))
      (on Reject
        (target rejected)
        (effects
          (db.write operational.approvals)
          (a2ui.emit private_change_approval))))

    (state awaiting_manager_approval
      (on ManagerApprove
        (target ready_to_deploy)
        (guard risk_proof_verified)
        (assign
          (manager_approved true))
        (effects
          (db.write operational.approvals)
          (a2ui.emit private_change_approval)))
      (on Reject
        (target rejected)
        (effects
          (db.write operational.approvals)
          (a2ui.emit private_change_approval))))

    (state ready_to_deploy
      (on Deploy
        (guard (and risk_proof_verified manager_approved))
        (target deployed)
        (assign
          (deployed true))
        (effects
          (db.write operational.deployments)
          (mcp.call ci.deploy)
          (a2ui.emit private_change_approval))))

    (state deployed (type final))
    (state rejected (type final))))
