ci: run otel-tagged api tests; pin strict for identical-tree evidence (#1465)

The tag-gated step ran -tags otel only for ./telemetry/..., so
api/recoverer_otel_test.go — B3-9's OC-0346 panic-log test — executed
nowhere in CI. Widen the scope to ./api/... and correct the comment that
lists the tagged files. Both packages pass locally under the tag.

G-03 as amended: integration evidence for a dev squash commit is the full
required matrix on its PR head plus tree identity between the two, which
required_status_checks.strict guarantees by construction. Make that
checkable: verify-gate-evidence.mjs --selftest now fails if the protection
script ever loses "strict": true, and scripts/verify-integration-tree.sh
asserts squash-tree == PR-head-tree for any squash SHA (the three newest
dev commits PASS), for phase-exit and hold-point evidence blocks.


Claude-Session: https://claude.ai/code/session_01B8dwVLEihnGZYtH9X631F4

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
J3vb
2026-08-31 04:58:39 +00:00
committed by GitHub
co-authored by Claude
parent 7abdd941fd
commit 59518c4767
3 changed files with 90 additions and 6 deletions
+8 -6
View File
@@ -84,16 +84,18 @@ jobs:
# Tag-gated tests (DC-06 / T-2026-07-25-16). The build-tag matrix above
# only COMPILES the otel/wazero variants; the tests behind those tags
# (plugin/sandbox_wazero_test.go, telemetry/telemetry_otel_test.go) ran
# nowhere until this step. Scoped to the two packages that carry tagged
# files — every other package is tag-invariant and already covered by the
# race run above. One leg is enough; no -race (the runtime under the tag
# is the concern, not new concurrency).
# (plugin/sandbox_wazero_test.go, telemetry/telemetry_otel_test.go,
# api/recoverer_otel_test.go — the OC-0346 panic-log test, which this
# step never executed until ./api/... was added) ran nowhere until this
# step. Scoped to the packages that carry tagged files — every other
# package is tag-invariant and already covered by the race run above.
# One leg is enough; no -race (the runtime under the tag is the concern,
# not new concurrency).
- name: Run tag-gated tests (-tags wazero, -tags otel)
if: matrix.os == 'ubuntu-latest'
run: |
go test -tags wazero -count=1 ./plugin/...
go test -tags otel -count=1 ./telemetry/...
go test -tags otel -count=1 ./telemetry/... ./api/...
# Coverage ratchet (B3-6 item 1). Reads the profile the race step wrote,
# but placed after the other test steps so a floor miss does not hide
+31
View File
@@ -36,6 +36,25 @@ export function requiredContexts(scriptSrc) {
return [...block[1].matchAll(/"([^"]+)"/g)].map((m) => m[1]);
}
// The identical-tree evidence model (G-03 as amended 2026-08-31) leans on
// required_status_checks.strict: with strict off, a PR that is behind dev can
// be squash-merged into a tree no CI run ever saw, and the PR-head evidence
// this gate trusts stops describing what actually landed. strict: true is what
// makes "the required matrix ran on the merged tree" a construction rather
// than a habit — scripts/verify-integration-tree.sh spot-proves it per squash
// SHA — so losing the flag must fail on a pull request, not in a later audit.
export function strictUpToDate(scriptSrc) {
const block = scriptSrc.match(/"required_status_checks"\s*:\s*\{([\s\S]*?)\}/);
if (!block) {
throw new Error(`no "required_status_checks" object found in ${PROTECTION_SCRIPT}`);
}
const strict = block[1].match(/"strict"\s*:\s*(true|false)/);
if (!strict) {
throw new Error(`no "strict" key found under required_status_checks in ${PROTECTION_SCRIPT}`);
}
return strict[1] === "true";
}
// checkRuns is the API's check_runs array, already collected across pages.
// Returns the reasons this commit is not releasable; empty means it is.
export function evaluate(required, checkRuns) {
@@ -138,6 +157,18 @@ function selftest() {
real.includes("Server Build & Test (ubuntu-latest)"),
"an ampersand name survives parsing",
);
assert(
strictUpToDate(readFileSync(join(ROOT, PROTECTION_SCRIPT), "utf8")),
"strict: true is pinned — identical-tree integration evidence relies on it",
);
assert(
strictUpToDate('"required_status_checks": { "strict": true, "contexts": ["A"] }'),
"strict true parses",
);
assert(
!strictUpToDate('"required_status_checks": { "strict": false, "contexts": ["A"] }'),
"strict false is detected, not glossed as true",
);
const req = ["A", "B"];
const ok = (name, extra = {}) => ({
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# Integration evidence for a dev squash commit (G-03 as amended 2026-08-31).
#
# dev is squash-merge-only and its pushes deliberately run no ci.yml matrix
# (the pull_request trigger already ran it on the PR head), so the squash
# commit itself carries only CodeQL runs. What makes the PR-head evidence
# transfer to the squash commit is required_status_checks.strict: an
# up-to-date PR's head names the same tree the squash commit lands. This
# script turns that construction into a per-commit statement a phase-exit or
# hold-point evidence block can cite as a command with output, instead of an
# assumption:
#
# bash scripts/verify-integration-tree.sh <squash-sha> [<squash-sha>...]
#
# For each squash commit: parse the pull-request number from the "(#N)"
# subject suffix every squash merge carries, fetch refs/pull/N/head from
# origin, and assert both commits name the same git tree. Exits non-zero if
# any commit fails. Needs network access to origin; verify-gate-evidence.mjs
# --selftest is what keeps the strict flag itself pinned.
set -euo pipefail
if [ "$#" -lt 1 ]; then
echo "usage: bash scripts/verify-integration-tree.sh <squash-sha> [<squash-sha>...]" >&2
exit 2
fi
fail=0
for sha in "$@"; do
if ! subject=$(git log -1 --format=%s "$sha" 2>/dev/null); then
echo "FAIL ${sha}: unknown commit (fetch the branch that carries it first)" >&2
fail=1
continue
fi
if [[ "$subject" =~ \(#([0-9]+)\)$ ]]; then
pr="${BASH_REMATCH[1]}"
else
echo "FAIL ${sha}: subject does not end in (#N), so it is not the squash of a PR: ${subject}" >&2
fail=1
continue
fi
git fetch -q --no-tags origin "refs/pull/${pr}/head"
head_tree=$(git rev-parse "FETCH_HEAD^{tree}")
squash_tree=$(git rev-parse "${sha}^{tree}")
if [ "$head_tree" = "$squash_tree" ]; then
echo "PASS ${sha} (PR #${pr}): squash tree == PR head tree ${head_tree}"
else
echo "FAIL ${sha} (PR #${pr}): squash tree ${squash_tree} != PR head tree ${head_tree} — the merged tree was never CI-tested as-is" >&2
fail=1
fi
done
exit "$fail"