GV18 is satisfied when candidate validation permits semantic authority to be one commit ahead of versioned materializations without granting the candidate a write capability. The Test workflow must materialize only in its ephemeral workspace before checking the resulting state, while the post-authorization Materialize workflow retains the canonical derived-commit identity and parent provenance marker.
GitHub Actions Test run 35996248284 is the preserved
counterexample: commit 5770bc3 was semantically valid, but
the old Test workflow rejected it solely because
CHANGELOG.md still reflected its semantic parent. The fix
must keep that case valid without requiring candidate authors or agents
to create the derived commit themselves.
{-# OPTIONS --safe #-}
module Govenv.Assurance.GV18 where
open import Agda.Builtin.Equality using (_≡_; refl)
open import Agda.Builtin.List using ([]; _∷_)
open import Agda.Builtin.Maybe using (just; nothing)
open import Govenv.Github.Authorization using
( WorkflowSecurityProfile; candidateSource; ungatedCandidate
; readOnlyToken; testJob )
open import Govenv.Administration using (authorizedBranch)
open import Govenv.Kernel.Assurance using (StaticEvidence; staticEvidence)
open import Govenv.Materialization.Github.Workflows.Materialize using
(materializerCommitSubject; derivedFromParentMarker)
open import Govenv.Materialization.Github.Workflows.Test using
( candidateValidationSteps; materializeCommand; previewCommand
; candidateLearningCommand; checkCommand; testCommand )
open import Govenv.Materialization.Github.Workflows.Workflow using
(binding; expression; literal; runStep)
record Proposition : Set where
constructor satisfied
field
candidateMaterializesBeforeValidation :
candidateValidationSteps ≡
( runStep "Materialize candidate transiently" nothing nothing
materializeCommand []
∷ runStep "Record candidate materialization preview" nothing nothing
previewCommand []
∷ runStep "Check candidate learning gate" nothing
(just "github.event_name == 'pull_request'")
candidateLearningCommand
( binding "GOVENV_CANDIDATE_COMPARISON_BASE_SHA"
(expression "github.event.pull_request.base.sha")
∷ binding "GOVENV_CANDIDATE_TARGET_BRANCH"
(expression "github.event.pull_request.base.ref")
∷ binding "GOVENV_AUTHORIZED_BRANCH"
(literal authorizedBranch)
∷ [])
∷ runStep "Check materialized candidate" nothing nothing
checkCommand []
∷ runStep "Run tests" nothing nothing testCommand []
∷ [] )
candidateSourceRemainsUnprivileged :
WorkflowSecurityProfile.sourceAuthority testJob ≡ candidateSource
candidateHasNoPrivilegedEnvironment :
WorkflowSecurityProfile.environmentGate testJob ≡ ungatedCandidate
candidateTokenRemainsReadOnly :
WorkflowSecurityProfile.githubToken testJob ≡ readOnlyToken
postAuthorizationCommitIdentity :
materializerCommitSubject ≡
"chore(materialize): update governed materializations"
postAuthorizationCommitRetainsParentProvenance :
derivedFromParentMarker ≡ "Derived-From-Parent: true"
proof : Proposition
proof = satisfied refl refl refl refl refl refl
evidence : StaticEvidence 18
evidence = staticEvidence Proposition proof