You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
governance: require reviewed-content binding for direct proposal approval #1979
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.
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.
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.
Activity
mctl-agents commentedon Oct 19, 2026
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. Reviewrequirements.md,design.mdandtasks.md, then approve: signal this issue's DevLoopWorkflow (mctl-apiPOST /api/v1/agents/dev-loop/dev-loop-mctlhq-mctl-gitops-1979/approve, orpython -m orchestrator.temporal.cli approve dev-loop-mctlhq-mctl-gitops-1979 --approver <your-identity>) — the workflow flips.status.yamltoacceptedvia themctl-agents-approveoperation and runs the Tier 2 implementer. If no DevLoopWorkflow is running for this issue (pre-Temporal proposal), run themctl-agents-approveoperation directly withservice=mctl-gitops slug=issue-1979-governance-require-reviewed-content-bind.The approver is recorded in
.status.yamland in the gitops commit, and the implementer refuses a proposal whosecontrol.requires_human_approvalcarries no named approver — so prefer the mctl-api endpoint, which takes the approver from the authenticated caller rather than from what the caller types.chore(agents): investigate #1979 2026-10-19
Merge pull request #2010 from mctlhq/docs/review-notes-1979-1980
mctl-agents commentedon Oct 19, 2026
Approval grant
aar_1a5cfa4595f34586b97c299d442b371ewas superseded because the proposal was rewritten. It was bound to digestsha256:dec0e821aad9aac5b437a425069fa2920b8c133249391414f799baecea993bc8; the current digest issha256:fa2623cc9fb2bead5e3a91b812cd0ddcd59ff0fccb6640b70a1f36fdbd115e9a. Please decide the fresh grantaar_39e2134706b7423fbb51029f050b8a8c.