Skip to content

governance: require reviewed-content binding for direct proposal approval #1979

Closed

Description

@mashkovd

Parent: mctlhq/.github#181
Source: mctlhq/.github#182 decision-assurance audit (G3 / P2).

Problem

The standalone/direct GitOps proposal approval path can call mctl_trigger_approve without expected_content_digest. In that mode the approval operation hashes the current proposal bytes at flip time. This proves only that the proposal does not change after approval; it does not prove that the human reviewed and approved those exact bytes.

This is distinct from the canonical Temporal DevLoop aar_ path, where the reviewed artifact digest is bound before the human decision.

Required invariant

A governed direct approval must bind the exact content reviewed by the human before the decision is recorded:

reviewed_hash=A + approve + current_hash=B (A != B) -> hard fail

No empty/unbound digest mode may silently create an approval binding from bytes first observed at execution time.

Scope

  • Determine whether any legitimate caller still requires unbound/empty-digest direct approval.
  • Prefer removing the unbound mode. If compatibility requires retaining it temporarily, make it explicitly non-governed and impossible to confuse with a reviewed approval.
  • Preserve the existing DevLoop aar_ path and chore(argo): count distinct attachments in the janitor's kept total #681 guarantees.
  • Record typed audit evidence for digest mismatch/unbound refusal.

Acceptance criteria

  • Direct governed approval requires a caller-supplied digest representing the reviewed proposal content.
  • Mutation between review and approval is rejected before state changes.
  • Empty/missing digest cannot be interpreted as a governed human approval.
  • Happy-path direct approval records the same reviewed digest in approval evidence/status.
  • Regression tests fail if execution-time self-binding is restored.

Refs mctlhq/.github#181, mctlhq/.github#182, mctlhq/mctl-agents#681.

Activity

  1. mctl-agents commented on Oct 19, 2026

    @mctl-agents
    Contributor

    mctl-agents issue-investigator has analyzed this issue and created a proposal:

    https://github.com/mctlhq/mctl-gitops/tree/main/platform-gitops/agents-state/mctl-gitops/proposals/issue-1979-governance-require-reviewed-content-bind/

    Status: proposed — pending human approval. Review requirements.md, design.md and tasks.md, then approve: signal this issue's DevLoopWorkflow (mctl-api POST /api/v1/agents/dev-loop/dev-loop-mctlhq-mctl-gitops-1979/approve, or python -m orchestrator.temporal.cli approve dev-loop-mctlhq-mctl-gitops-1979 --approver <your-identity>) — the workflow flips .status.yaml to accepted via the mctl-agents-approve operation and runs the Tier 2 implementer. If no DevLoopWorkflow is running for this issue (pre-Temporal proposal), run the mctl-agents-approve operation directly with service=mctl-gitops slug=issue-1979-governance-require-reviewed-content-bind.

    The approver is recorded in .status.yaml and in the gitops commit, and the implementer refuses a proposal whose control.requires_human_approval carries no named approver — so prefer the mctl-api endpoint, which takes the approver from the authenticated caller rather than from what the caller types.

  2. added 2 commits that reference this issue on Oct 19, 2026
  3. mctl-agents commented on Oct 19, 2026

    @mctl-agents
    Contributor

    Approval grant aar_1a5cfa4595f34586b97c299d442b371e was superseded because the proposal was rewritten. It was bound to digest sha256:dec0e821aad9aac5b437a425069fa2920b8c133249391414f799baecea993bc8; the current digest is sha256:fa2623cc9fb2bead5e3a91b812cd0ddcd59ff0fccb6640b70a1f36fdbd115e9a. Please decide the fresh grant aar_39e2134706b7423fbb51029f050b8a8c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions