fix(agent-team): post-build denied-path check writes scratch outside the checkout
Live smoke exposed a self-pollution bug (pre-existing from PR #17): the post-build denied-path check wrote its own _build_diff_z.bin / _build_status_z.bin into the working tree, then its own `git status --untracked-files=all` flagged them as out-of-scope writes — failing any run with a narrow declared_scope (the smoke's docs/**). Write them to $RUNNER_TEMP instead (read via $_DIFF_Z/$_STATUS_Z), so the check no longer sees its own temp files. The agent-team pytest artifacts were already correctly gitignored; only the check's own files tripped it. Test harness updated to pass the env paths. 1044 tests, ruff clean.
This commit is contained in:
parent
5756178d62
commit
2dce5c6b76
2 changed files with 23 additions and 7 deletions
15
.github/workflows/agent-team-apply-verify.yml
vendored
15
.github/workflows/agent-team-apply-verify.yml
vendored
|
|
@ -742,8 +742,15 @@ jobs:
|
|||
# mangling is done anywhere. A path that cannot be cleanly decoded is
|
||||
# treated as a VIOLATION (fail closed).
|
||||
git config core.quotepath false
|
||||
git diff -z --name-only HEAD > ./_build_diff_z.bin || true
|
||||
git status --porcelain=v1 -z --untracked-files=all > ./_build_status_z.bin || true
|
||||
# Write the scratch capture files OUTSIDE the checkout ($RUNNER_TEMP) so
|
||||
# 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'
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -885,7 +892,7 @@ jobs:
|
|||
"""`git diff -z --name-only` records: each NUL field is one path."""
|
||||
ok: list[str] = []
|
||||
bad: list[bytes] = []
|
||||
for rec in _read_z("./_build_diff_z.bin"):
|
||||
for rec in _read_z(os.environ["_DIFF_Z"]):
|
||||
dec = _decode(rec)
|
||||
(ok if dec is not None else bad).append(dec if dec is not None else rec)
|
||||
return ok, bad
|
||||
|
|
@ -901,7 +908,7 @@ jobs:
|
|||
"""
|
||||
ok: list[str] = []
|
||||
bad: list[bytes] = []
|
||||
recs = _read_z("./_build_status_z.bin")
|
||||
recs = _read_z(os.environ["_STATUS_Z"])
|
||||
i = 0
|
||||
while i < len(recs):
|
||||
rec = recs[i]
|
||||
|
|
|
|||
|
|
@ -390,9 +390,18 @@ def _run_post_build(
|
|||
|
||||
script = tmp_path / "post_build.py"
|
||||
script.write_text(_extract_post_build_script(), encoding="utf-8")
|
||||
(tmp_path / "_build_diff_z.bin").write_bytes(diff_z)
|
||||
(tmp_path / "_build_status_z.bin").write_bytes(status_z)
|
||||
env = dict(os.environ, DECLARED_SCOPE=scope)
|
||||
diff_z_path = tmp_path / "_build_diff_z.bin"
|
||||
status_z_path = tmp_path / "_build_status_z.bin"
|
||||
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(
|
||||
[sys.executable, str(script)],
|
||||
env=env,
|
||||
|
|
|
|||
Reference in a new issue