fix(agent-team): post-build check writes scratch outside the checkout (smoke fix) #38

Merged
amoussa1229 merged 1 commit from fix/post-build-scratch-outside-checkout into main 2026-06-22 23:20:05 +00:00
2 changed files with 23 additions and 7 deletions

View file

@ -742,8 +742,15 @@ jobs:
# mangling is done anywhere. A path that cannot be cleanly decoded is # mangling is done anywhere. A path that cannot be cleanly decoded is
# treated as a VIOLATION (fail closed). # treated as a VIOLATION (fail closed).
git config core.quotepath false git config core.quotepath false
git diff -z --name-only HEAD > ./_build_diff_z.bin || true # Write the scratch capture files OUTSIDE the checkout ($RUNNER_TEMP) so
git status --porcelain=v1 -z --untracked-files=all > ./_build_status_z.bin || true # the `git status --untracked-files=all` below does not see — and flag —
# the check's OWN temp files as out-of-scope writes (they would otherwise
# appear as untracked and fail a narrow declared_scope).
_DIFF_Z="${RUNNER_TEMP:-/tmp}/_build_diff_z.bin"
_STATUS_Z="${RUNNER_TEMP:-/tmp}/_build_status_z.bin"
export _DIFF_Z _STATUS_Z
git diff -z --name-only HEAD > "$_DIFF_Z" || true
git status --porcelain=v1 -z --untracked-files=all > "$_STATUS_Z" || true
python3 - <<'PY' python3 - <<'PY'
from __future__ import annotations from __future__ import annotations
@ -885,7 +892,7 @@ jobs:
"""`git diff -z --name-only` records: each NUL field is one path.""" """`git diff -z --name-only` records: each NUL field is one path."""
ok: list[str] = [] ok: list[str] = []
bad: list[bytes] = [] bad: list[bytes] = []
for rec in _read_z("./_build_diff_z.bin"): for rec in _read_z(os.environ["_DIFF_Z"]):
dec = _decode(rec) dec = _decode(rec)
(ok if dec is not None else bad).append(dec if dec is not None else rec) (ok if dec is not None else bad).append(dec if dec is not None else rec)
return ok, bad return ok, bad
@ -901,7 +908,7 @@ jobs:
""" """
ok: list[str] = [] ok: list[str] = []
bad: list[bytes] = [] bad: list[bytes] = []
recs = _read_z("./_build_status_z.bin") recs = _read_z(os.environ["_STATUS_Z"])
i = 0 i = 0
while i < len(recs): while i < len(recs):
rec = recs[i] rec = recs[i]

View file

@ -390,9 +390,18 @@ def _run_post_build(
script = tmp_path / "post_build.py" script = tmp_path / "post_build.py"
script.write_text(_extract_post_build_script(), encoding="utf-8") script.write_text(_extract_post_build_script(), encoding="utf-8")
(tmp_path / "_build_diff_z.bin").write_bytes(diff_z) diff_z_path = tmp_path / "_build_diff_z.bin"
(tmp_path / "_build_status_z.bin").write_bytes(status_z) status_z_path = tmp_path / "_build_status_z.bin"
env = dict(os.environ, DECLARED_SCOPE=scope) diff_z_path.write_bytes(diff_z)
status_z_path.write_bytes(status_z)
# The script now reads its capture files from $_DIFF_Z / $_STATUS_Z (written
# outside the checkout in CI so the check's own temp files are not flagged).
env = dict(
os.environ,
DECLARED_SCOPE=scope,
_DIFF_Z=str(diff_z_path),
_STATUS_Z=str(status_z_path),
)
result = subprocess.run( result = subprocess.run(
[sys.executable, str(script)], [sys.executable, str(script)],
env=env, env=env,