Files
Bo 7e06834615 fix(ci): make the validate.yml backstop green — fix all four pre-existing red check classes (#908)
## Why

Every PR since #906 has run red on the same 5 checks (correctness
ubuntu+windows, go-gate-shadow, security, summary) — #906 and #907 both
merged with identical red sets. A permanently-red backstop is worse than
none: a real regression is invisible in the noise. This PR fixes every
class and makes green the expected state again.

## What (three commits)

**Wave 1 — the four red check classes** (each verified by running the CI
job's own command):
- **correctness/bats (138 CI-only failures, ~6 env mismatches)**: pawl
verdict-edge fail-closed fires without a trusted `ao` on PATH →
`PAWL_EDGE_FAIL_OPEN=1` on the bats step (the 3 fail-closed regression
suites opt back out); gtimeout probe crashing setup() on Linux; gawk \\"
bracket-expression warning corrupting jq assertions; ripgrep missing on
runners; teardown/skip-path exit codes; taxonomy fixture missing the
now-required observations field.
- **go-gate-shadow (8 full-gate failures → 0)**: #906 landed without a
heal/regen pass — pre/post-mortem pointer skills missing
`hexagonal_role`; codex twins/hashes drift; shrink-only grandfather
lists; evolve SKILL.md referencing 3 deleted scripts;
@covered-by/allowlist conflicts; 3 go.lint findings.
- **security (BLOCKED_HIGH → PASS)**: 3 false positives suppressed
per-finding with justification (gosec G122 on the dev-time arch checker;
2 semgrep mis-traces).
- **correctness/windows**: tests set HOME but Go os.UserHomeDir() reads
USERPROFILE on Windows → cross-platform setHome helper.

**Wave 2 — 18 residual bats failures across 13 files**, each first
proven identical on pristine origin/main (differential run) before
fixing. Content drift (README golden-path literal, discovery references,
bootstrap↔install-bd wiring, pawl-review reachability via council, rpi
helper-rung tokens), validator regressions (validate-codex-rpi-contract
resolver routing, em-loop labels, goal-design fixture), and stale tests
updated only where provably behind a deliberate change (catalog
schema_version pin 1→2, SHA-pinned action regex, retired perf scenario,
drained dangler pin 2→0, tagged-ao test build).

**Commit 3**: the `ao skills unlink` train that landed on main mid-work
re-reddened security with the same semgrep value-struct FP — suppressed
like its skills_link sibling.

## Verification (rebased onto current main tip)

- `ao gate check --full`: **92/93 pass, 0 fail** (1 expected AP7 skip)
- `security-gate.sh --mode quick`: **PASS**
- `go vet` clean; **11,878 Go tests green** (149 packages)
- All 13 wave-2 bats suites **0 not-ok**; CI-sim (no-ao PATH) bats clean
on wave-1 suites
- Windows fix verified via GOOS=windows build+vet (needs the
windows-latest job for final confirmation)

**Acceptance: this PR's own validate.yml run going green.**

Bead: age-htrqp

---------

Co-authored-by: boshu <241868352+boshu2@users.noreply.github.com>
2026-07-14 02:06:44 -04:00

58 lines
2.1 KiB
Bash

#!/usr/bin/env bats
setup() {
REPO_ROOT="$(cd "$BATS_TEST_DIRNAME/../.." && pwd)"
WORKFLOW="$REPO_ROOT/.github/workflows/release.yml"
}
line_of() {
local pattern="$1"
grep -n "$pattern" "$WORKFLOW" | head -1 | cut -d: -f1
}
@test "release workflow gates publish on pre-publish evidence" {
run grep -Fq 'pre-publish-evidence:' "$WORKFLOW"
[ "$status" -eq 0 ]
run grep -Fq 'needs: [doc-release-gate, pre-publish-evidence]' "$WORKFLOW"
[ "$status" -eq 0 ]
run grep -Fq "needs.pre-publish-evidence.result == 'success'" "$WORKFLOW"
[ "$status" -eq 0 ]
}
@test "release workflow has no soft security publish bypass" {
run grep -Fq 'continue-on-error: true' "$WORKFLOW"
[ "$status" -eq 1 ]
run grep -Fq "needs.doc-release-gate.result == 'success' && needs.pre-publish-evidence.result == 'success'" "$WORKFLOW"
[ "$status" -eq 0 ]
}
@test "security and readiness evidence run before GoReleaser publish" {
local security_line
local readiness_line
local publish_line
security_line="$(line_of 'security-gate.sh --mode full --json')"
readiness_line="$(line_of 'check-release-readiness.sh')"
publish_line="$(line_of 'Publish with GoReleaser')"
[ -n "$security_line" ]
[ -n "$readiness_line" ]
[ -n "$publish_line" ]
[ "$security_line" -lt "$publish_line" ]
[ "$readiness_line" -lt "$publish_line" ]
}
@test "release evidence is uploaded after publish from pre-publish artifact" {
# Version- and pin-style-agnostic. The fleet is SHA-pinned (sec/age-9838),
# so refs read `@<sha> # vN`; match either a SHA pin or a bare vN tag so the
# assertion survives both dependabot major bumps and the SHA-pin convention.
run grep -Eq 'actions/upload-artifact@([0-9a-f]{7,}|v[0-9]+)' "$WORKFLOW"
[ "$status" -eq 0 ]
run grep -Eq 'actions/download-artifact@([0-9a-f]{7,}|v[0-9]+)' "$WORKFLOW"
[ "$status" -eq 0 ]
run grep -Fq 'pre-publish-release-evidence' "$WORKFLOW"
[ "$status" -eq 0 ]
run grep -Fq 'gh release upload "$VERSION" release-artifacts/security-gate-summary.json --clobber' "$WORKFLOW"
[ "$status" -eq 0 ]
}