🤖 Generated by the Agentic Engineer
Evidence
#3836 added moved-entry diagnostics to the authorization gate: on an unapproved
aggregate, run() calls surfaceMismatchReport, which renders the approval base and
names the surface entries that differ. describeSurfaceDelta is covered by
surface_delta_test.go and works.
It has never run on a real mismatch. The CI step invokes two commands in order:
run: |
set -euo pipefail
go test ./scripts/validate-eks-ci-role-policy
base_root="$RUNNER_TEMP/approval-base-tree"
if git worktree add --detach "$base_root" HEAD^1; then
go run ./scripts/validate-eks-ci-role-policy . "$base_root"
TestValidateAuthorizationAcceptsCommittedPolicy (main_test.go:1609) calls
validateAuthorization() and t.Fatalfs with the bare error. It fails on exactly the
condition the diagnostics exist to explain, and under set -e that aborts the step — so
go run, the only caller of surfaceMismatchReport, never executes. The
cd.yaml copy of the step has the same ordering.
Measured live on #3878, CI run 35257229458, job 105324573289:
| observation |
value |
| approval base checkout |
succeeded (EKS CI role authorization approval base passed, 18:13:32Z) |
go test verdict |
FAIL, 18:13:44Z |
| aggregate reported |
a4781e58… |
| moved-entry lines emitted |
0 |
The entry that moved was a single HelmRelease, and identifying it took a
purpose-written conservation render — precisely the cost #3836 set out to remove.
Affected audience and impact
Whoever next moves the aggregate. Every such PR pays a manual conservation render to
learn what the gate already knows, and the re-approval is reviewed without the one fact
that makes it checkable. That is the desensitisation risk #2803 names: re-approval
becomes a rubber stamp when nothing states what actually moved.
Four re-approvals on 2026-09-17 alone (#3873, #3874, #3875, #3876) each paid this cost.
Expected behaviour
A run that fails the aggregate check emits the moved-entry diagnostics, and still fails.
Smallest useful change
Run both commands and fail if either failed, rather than short-circuiting on the first:
the go test verdict and the diagnostics are independent outputs, and the step needs
both. Apply to ci.yaml and cd.yaml.
Acceptance criteria
Size
Small.
Follow-up to #3836. Unblocks #2803's third acceptance criterion.
Evidence
#3836 added moved-entry diagnostics to the authorization gate: on an unapproved
aggregate,
run()callssurfaceMismatchReport, which renders the approval base andnames the surface entries that differ.
describeSurfaceDeltais covered bysurface_delta_test.goand works.It has never run on a real mismatch. The CI step invokes two commands in order:
TestValidateAuthorizationAcceptsCommittedPolicy(main_test.go:1609) callsvalidateAuthorization()andt.Fatalfs with the bare error. It fails on exactly thecondition the diagnostics exist to explain, and under
set -ethat aborts the step — sogo run, the only caller ofsurfaceMismatchReport, never executes. Thecd.yamlcopy of the step has the same ordering.Measured live on #3878, CI run 35257229458, job 105324573289:
EKS CI role authorization approval base passed, 18:13:32Z)go testverdicta4781e58…The entry that moved was a single HelmRelease, and identifying it took a
purpose-written conservation render — precisely the cost #3836 set out to remove.
Affected audience and impact
Whoever next moves the aggregate. Every such PR pays a manual conservation render to
learn what the gate already knows, and the re-approval is reviewed without the one fact
that makes it checkable. That is the desensitisation risk #2803 names: re-approval
becomes a rubber stamp when nothing states what actually moved.
Four re-approvals on 2026-09-17 alone (#3873, #3874, #3875, #3876) each paid this cost.
Expected behaviour
A run that fails the aggregate check emits the moved-entry diagnostics, and still fails.
Smallest useful change
Run both commands and fail if either failed, rather than short-circuiting on the first:
the
go testverdict and the diagnostics are independent outputs, and the step needsboth. Apply to
ci.yamlandcd.yaml.Acceptance criteria
go testfails for a reasonunrelated to the aggregate.
cd.yamlcopy of the step gets the same treatment.Size
Small.
Follow-up to #3836. Unblocks #2803's third acceptance criterion.