fix(governance): validate reviewed split completions exactly

A reviewed notification correction and its required contracts and API proof were accepted as separate immutable commits, leaving the protected per-commit governance check unable to pass without rewriting reviewed history. Add a fail-closed exact-pair validator that reconstructs the completion commit in a detached worktree and runs the normal guard over the combined file set; all unregistered commits continue through the unchanged per-commit path.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-09-07 20:13:34 +01:00
parent 238c9762ba
commit 092405e33c
5 changed files with 207 additions and 5 deletions
+24 -5
View File
@@ -104,15 +104,31 @@ jobs:
fi
reason=$(git log -1 --format='%(trailers:key=Contract-Neutral,valueonly,separator=; )' "${commit}" | tr '\n' ' ')
echo "::group::canonical completion guard @ ${commit}"
set +e
python3 scripts/release_control/canonical_completion_history.py \
--commit "${commit}" --head "${head_sha}"
completion_status=$?
set -e
if [ "${completion_status}" -eq 0 ]; then
completion_history=true
elif [ "${completion_status}" -eq 3 ]; then
completion_history=false
else
echo "Canonical completion history failed for commit ${commit}."
status=1
completion_history=true
fi
# Pass the parent as the diff base so the guard compares
# contract texts parent-vs-commit; the CI index equals HEAD,
# so the default index comparison would misreport contract
# updates in earlier commits as insubstantial.
if ! git diff-tree --no-commit-id --name-only -r "${commit}" \
| PULSE_ALLOW_CONTRACT_NEUTRAL_COMMIT="${reason}" python3 scripts/release_control/canonical_completion_guard.py \
--files-from-stdin --diff-base "${commit}^" --commit "${commit}"; then
echo "Canonical completion guard failed for commit ${commit}."
status=1
if [ "${completion_history}" != true ]; then
if ! git diff-tree --no-commit-id --name-only -r "${commit}" \
| PULSE_ALLOW_CONTRACT_NEUTRAL_COMMIT="${reason}" python3 scripts/release_control/canonical_completion_guard.py \
--files-from-stdin --diff-base "${commit}^" --commit "${commit}"; then
echo "Canonical completion guard failed for commit ${commit}."
status=1
fi
fi
if ! git diff-tree --no-commit-id --name-only -r "${commit}" \
| python3 scripts/release_control/browser_verification_guard.py \
@@ -146,6 +162,9 @@ jobs:
- name: Run canonical completion guard unit tests
run: python3 scripts/release_control/canonical_completion_guard_test.py
- name: Run canonical completion history unit tests
run: python3 scripts/release_control/canonical_completion_history_test.py
- name: Run browser verification guard unit tests
run: python3 scripts/release_control/browser_verification_guard_test.py
+3
View File
@@ -224,6 +224,9 @@ scripts/release_control/
scripts/release_control/*
!scripts/release_control/canonical_completion_guard.py
!scripts/release_control/canonical_completion_guard_test.py
!scripts/release_control/canonical_completion_history.json
!scripts/release_control/canonical_completion_history.py
!scripts/release_control/canonical_completion_history_test.py
!scripts/release_control/commercial_cancellation_reactivation_proof.py
!scripts/release_control/commercial_cancellation_reactivation_rehearsal.py
!scripts/release_control/contract_audit.py
@@ -0,0 +1,10 @@
{
"version": 1,
"completions": [
{
"incomplete_commit": "a2dbb27a68463adb02b614e9927174543f5b7799",
"completion_commit": "5f99f5c13fcc547e5e34286dfe873415a4876cfa",
"reason": "Preserve the reviewed diagnostic-redaction commit while evaluating its separately reviewed contracts and API proof as one historical completion unit."
}
]
}
@@ -0,0 +1,138 @@
#!/usr/bin/env python3
"""Validate exact, reviewed canonical-completion pairs without rewriting history."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
import re
import subprocess
import sys
import tempfile
REPO_ROOT = Path(__file__).resolve().parents[2]
REGISTRY = Path(__file__).with_name("canonical_completion_history.json")
SHA_PATTERN = re.compile(r"[0-9a-f]{40}")
def git(*args: str, cwd: Path = REPO_ROOT) -> str:
return subprocess.run(
["git", *args],
cwd=cwd,
check=True,
capture_output=True,
text=True,
).stdout.rstrip("\n")
def load_completions(path: Path = REGISTRY) -> dict[str, dict[str, str]]:
document = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(document, dict) or set(document) != {"version", "completions"}:
raise ValueError("completion registry must contain only version and completions")
if document["version"] != 1 or isinstance(document["version"], bool):
raise ValueError("unsupported completion registry version")
if not isinstance(document["completions"], list):
raise ValueError("completion registry entries must be a list")
result: dict[str, dict[str, str]] = {}
required = {"incomplete_commit", "completion_commit", "reason"}
for entry in document["completions"]:
if not isinstance(entry, dict) or set(entry) != required:
raise ValueError("completion entry has unexpected fields")
if not all(isinstance(entry[field], str) and entry[field].strip() for field in required):
raise ValueError("completion entry fields must be non-empty strings")
incomplete = entry["incomplete_commit"]
completion = entry["completion_commit"]
if not SHA_PATTERN.fullmatch(incomplete) or not SHA_PATTERN.fullmatch(completion):
raise ValueError("completion entry revisions must be full lowercase commit IDs")
if incomplete == completion or incomplete in result:
raise ValueError("completion entries must identify distinct, unique commits")
result[incomplete] = entry
return result
def changed_files(commit: str) -> list[str]:
return [
line
for line in git("diff-tree", "--no-commit-id", "--name-only", "-r", commit).splitlines()
if line
]
def validate_completion(incomplete: str, head: str) -> bool:
"""Return False for an ordinary commit; validate and return True for a registered pair."""
entry = load_completions().get(incomplete)
if entry is None:
return False
if not SHA_PATTERN.fullmatch(head):
raise ValueError("head must be a full lowercase commit ID")
completion = entry["completion_commit"]
git("cat-file", "-e", f"{incomplete}^{{commit}}")
git("cat-file", "-e", f"{completion}^{{commit}}")
git("cat-file", "-e", f"{head}^{{commit}}")
subprocess.run(
["git", "merge-base", "--is-ancestor", incomplete, completion],
cwd=REPO_ROOT,
check=True,
)
subprocess.run(
["git", "merge-base", "--is-ancestor", completion, head],
cwd=REPO_ROOT,
check=True,
)
files = sorted(set(changed_files(incomplete) + changed_files(completion)))
with tempfile.TemporaryDirectory(prefix="pulse-canonical-completion-") as temp:
worktree = Path(temp) / "pulse"
git("worktree", "add", "--detach", str(worktree), completion)
try:
guard = worktree / "scripts/release_control/canonical_completion_guard.py"
result = subprocess.run(
[
sys.executable,
str(guard),
"--files-from-stdin",
"--diff-base",
f"{incomplete}^",
"--commit",
completion,
],
cwd=worktree,
input="".join(f"{path}\n" for path in files),
text=True,
)
if result.returncode != 0:
raise ValueError(
f"registered completion {completion} does not complete {incomplete}"
)
finally:
git("worktree", "remove", "--force", str(worktree))
print(
"Canonical completion history passed "
f"({incomplete} completed by {completion}: {entry['reason']})"
)
return True
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--commit", required=True)
parser.add_argument("--head", required=True)
return parser.parse_args()
def main() -> int:
args = parse_args()
try:
return 0 if validate_completion(args.commit, args.head) else 3
except (OSError, ValueError, subprocess.CalledProcessError, json.JSONDecodeError) as error:
print(f"Canonical completion history failed: {error}", file=sys.stderr)
return 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,32 @@
import json
import tempfile
import unittest
from pathlib import Path
from canonical_completion_history import load_completions, validate_completion
class CanonicalCompletionHistoryTest(unittest.TestCase):
def test_registry_names_the_exact_reviewed_completion_pair(self):
entries = load_completions()
self.assertEqual(
entries["a2dbb27a68463adb02b614e9927174543f5b7799"]["completion_commit"],
"5f99f5c13fcc547e5e34286dfe873415a4876cfa",
)
def test_registry_rejects_unknown_fields(self):
with tempfile.TemporaryDirectory() as temp:
path = Path(temp) / "history.json"
path.write_text(
json.dumps({"version": 1, "completions": [], "unexpected": True}),
encoding="utf-8",
)
with self.assertRaisesRegex(ValueError, "only version and completions"):
load_completions(path)
def test_unregistered_commit_uses_the_normal_guard(self):
self.assertFalse(validate_completion("0" * 40, "1" * 40))
if __name__ == "__main__":
unittest.main()