Skip to content

symfonic.memory.protocols_human_review

protocols_human_review

Optional human re-review CAS capability, separate from the draft review port.

ProcedureHumanReviewBackend

Bases: Protocol

A preparatory persistence seam; no service or route composes it yet.

It is not activation: the human approval door still writes through generic update_node, which is unconditional and can still erase any review. That door has no verified human actor and no audit sink, so wiring it here would either drop attribution or invent it. Both remain open CORE-72 blockers.

compare_and_set_procedure_human_review async

compare_and_set_procedure_human_review(scope: StorageScope, node_id: NodeId, expected_properties: dict[str, Any], properties: dict[str, Any]) -> Any | None

Human-review a draft or replace a policy decision, conditionally.

expected_properties is a detached snapshot of get_node.properties and must be a published draft without review authority or actor keys, or approved/rejected with policy authority and a nonblank policy actor; anything else, including a human-reviewed row, raises ValueError. The proposal must approve (active) or reject (inactive) with human authority and no procedure_review_actor key, so the stale policy actor is removed and none is minted. Artifact, binding, ownership and revision rules match compare_and_set_procedure_review; revision advances once. Every committed property is compared under the backend write lock. Return None when the committed row changed or is no longer eligible; raise KeyError for a missing or not-exactly-owned row.

Source code in src/symfonic/memory/protocols_human_review.py
async def compare_and_set_procedure_human_review(
    self, scope: StorageScope, node_id: NodeId,
    expected_properties: dict[str, Any], properties: dict[str, Any],
) -> Any | None:
    """Human-review a draft or replace a policy decision, conditionally.

    ``expected_properties`` is a detached snapshot of get_node.properties
    and must be a published draft without review authority or actor
    keys, or approved/rejected with ``policy``
    authority and a nonblank policy actor; anything else, including a
    human-reviewed row, raises ValueError. The proposal must approve
    (active) or reject (inactive) with ``human`` authority and no
    ``procedure_review_actor`` key, so the stale policy actor is removed
    and none is minted. Artifact, binding, ownership and revision rules
    match ``compare_and_set_procedure_review``; revision advances once.
    Every committed property is compared under the backend write lock.
    Return None when the committed row changed or is no longer eligible;
    raise KeyError for a missing or not-exactly-owned row.
    """
    ...