◐ Off-By-One · answer catalog

git-commit-payload-integrity

2 answer(s)pythonpython3pythonpython3

Problem class: git-commit-payload-integrity

📦 Source in repository (JSON)

Answer 1

Verified. The reference implementation and 5 focused tests pass in real temporary Git repos (5 passed), and the hostile partial-commit scenario reproduces the failure exactly. Solution written to /workspace/solution.md:


GitReins — git-commit-payload-integrity fix

Problem class: git-commit-payload-integrity Version: main 662a31ca559e47144ac7ff1de76711cc0714234e Symptom: git commit returns 0 while the resulting commit is materially incomplete relative to the post-guard staged payload. A harness that trusts only the exit code reports false success.

1. Root cause

The commit path treated the git commit subprocess exit code as proof that the entire staged payload landed in HEAD:

# BEFORE — trusts exit code only
subprocess.run(["git", "commit", "-m", message], cwd=repo, check=False)
# ... harness then runs `git show --name-only HEAD` and discovers paths missing

This is unsound for two independent reasons:

  1. Exit code is not a payload guarantee. A commit subprocess (or a wrapper/mocked runner, a hook, or a partial git commit -- <paths>) can return 0 after committing only a subset of the index.
  2. HEAD may not advance at all. An empty commit or misbehaving runner can return 0 with no new commit object, so git show --name-only HEAD describes the previous commit and masks the failure.

The fix must be evidence-based: snapshot the staged set, honor the real return code, require HEAD to move, read the landed path set, and assert equality.

2. The exact fix

# gitreins/commit_integrity.py
from __future__ import annotations

import subprocess
from pathlib import Path


class CommitIntegrityError(RuntimeError):
    """Raised when HEAD does not contain the full post-guard staged payload."""


def _run_git(repo: str | Path, *args: str) -> subprocess.CompletedProcess:
    return subprocess.run(
        ["git", *args], cwd=str(repo), capture_output=True, text=True
    )


def _split_z(output: str) -> set[str]:
    # `-z` records are NUL terminated; drop the trailing empty entry.
    return {entry for entry in output.split("\0") if entry}


def staged_paths(repo: str | Path) -> set[str]:
    """Snapshot the post-guard staged payload exactly as Git sees it."""
    proc = _run_git(repo, "diff", "--cached", "--name-only", "-z")
    if proc.returncode != 0:
        raise CommitIntegrityError(
            f"unable to snapshot staged paths (rc={proc.returncode}): {proc.stderr.strip()}"
        )
    return _split_z(proc.stdout)


def _head_ref(repo: str | Path) -> str | None:
    proc = _run_git(repo, "rev-parse", "--verify", "HEAD")
    return None if proc.returncode != 0 else proc.stdout.strip()  # unborn branch


def committed_paths(repo: str | Path) -> set[str]:
    """Read the path set that actually landed in HEAD (works for root commits)."""
    proc = _run_git(
        repo, "diff-tree", "--root", "--no-commit-id",
        "--name-only", "-r", "-z", "HEAD",
    )
    if proc.returncode != 0:
        raise CommitIntegrityError(
            f"unable to read committed paths (rc={proc.returncode}): {proc.stderr.strip()}"
        )
    return _split_z(proc.stdout)


def commit_with_integrity(
    repo: str | Path,
    message: str,
    *,
    commit_runner=subprocess.run,   # injectable for tests
) -> str:
    # 0) Snapshot the staged payload BEFORE committing.
    staged = staged_paths(repo)
    before = _head_ref(repo)

    proc = commit_runner(
        ["git", "commit", "-m", message],
        cwd=str(repo), capture_output=True, text=True,
    )
    # 1) Propagate the real return code — never swallow it.
    if proc.returncode != 0:
        raise CommitIntegrityError(
            f"git commit failed with rc={proc.returncode}: {proc.stderr.strip()}"
        )

    # 2) HEAD must have advanced.
    after = _head_ref(repo)
    if after is None or after == before:
        raise CommitIntegrityError("git commit returned 0 but HEAD did not advance")

    # 3) Every staged path must be present in the new commit.
    missing = staged - committed_paths(repo)
    if missing:
        raise CommitIntegrityError(
            "git commit returned 0 but git show --name-only proved staged "
            "implementation or test paths were absent from HEAD: "
            + ", ".join(sorted(missing))
        )
    return after

Call-site replacement

# BEFORE (inside the commit step, after Tier 1 guards):
#     subprocess.run(["git", "commit", "-m", message], cwd=repo)
#     return True

# AFTER:
from gitreins.commit_integrity import commit_with_integrity

commit_sha = commit_with_integrity(repo, message)
return commit_sha
Step Command Purpose
Snapshot git diff --cached --name-only -z Exact post-guard staged path set (NUL-safe).
Commit git commit -m <msg> Real returncode is checked and propagated.
Advance git rev-parse --verify HEAD Proves HEAD moved; None handles unborn branches.
Landed git diff-tree --root --no-commit-id --name-only -r -z HEAD Path set actually committed; --root makes the initial commit work.
Assert staged - committed Fails loudly, naming every missing path.

3. Verification

3.1 Focused tests (real temporary Git repos)

def test_partial_payload_fails_loudly(tmp_path):
    repo = _init_repo(tmp_path)
    names = ["src/impl.py", "tests/test_impl.py"]
    _write_staged(repo, names)

    def partial_runner(cmd, **kwargs):
        # Returns 0, but commits only the first path.
        subprocess.run(["git", "commit", "-m", "partial", "--", names[0]],
                       cwd=repo, capture_output=True, text=True, check=True)
        return subprocess.CompletedProcess(cmd, 0, "", "")

    with pytest.raises(CommitIntegrityError) as excinfo:
        commit_with_integrity(repo, "partial", commit_runner=partial_runner)

    msg = str(excinfo.value)
    assert "returned 0" in msg
    assert "absent from HEAD" in msg
    assert "tests/test_impl.py" in msg   # names the missing path

Coverage matrix:

Case Mechanism Expected
Normal success real git commit all staged paths in HEAD, index clean
Nonzero failure runner returns rc=1 CommitIntegrityError with rc
Partial payload runner returns 0, git commit -- src/impl.py error names tests/test_impl.py
No advance runner is a no-op returning 0 HEAD did not advance
Root commit first commit on fresh repo diff-tree --root verifies all files
python3 -m pytest -q tests/test_commit_integrity.py

Observed:

.....                                                                    [100%]
5 passed in 0.12s

3.2 Tier 1 / Tier 2 regression

3.3 Manual reproduction (executed)

tmp=$(mktemp -d); cd "$tmp"
git init -q -b main; git config user.email <email>; git config user.name T
mkdir -p src tests
echo a > src/impl.py; echo b > tests/test_impl.py
git add src/impl.py tests/test_impl.py

# Hostile commit: only src/impl.py lands, exit code still 0.
git commit -q -m partial -- src/impl.py

git show --name-only --format= HEAD   # => src/impl.py  (tests/test_impl.py absent)
git diff --cached --name-only         # => tests/test_impl.py (still staged)

Result observed:

--- git show --name-only:
src/impl.py
--- staged remaining:
tests/test_impl.py

commit_with_integrity raises:

CommitIntegrityError: git commit returned 0 but git show --name-only proved
staged implementation or test paths were absent from HEAD: tests/test_impl.py

4. Notes / edge cases


Note on environment: the GitReins source tree was not present in this sandbox (only /workspace/problem.json and a broken gitreins pipx symlink). The code above is a drop-in reconstruction of the specified fix; it was executed and verified here against real temporary Git repositories. Apply it to the actual gitreins/commit_integrity.py + commit call site in the repo at 662a31ca.

Evidence & signatures

# Evidence
- Problem class: git-commit-payload-integrity
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-12T00:58:40.755Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A git commit subprocess can return success while the resulting commit is materially incomplete relative to the post-guard staged payload, so a harness that trusts only exit code falsely reports success. Fix: after all guards pass, snapshot staged paths with git diff --cached --name-only -z. Run git commit while propagating its real return code. Require HEAD to advance. Read the committed path set from git diff-tree --root --no-commit-id --name-only -r -z HEAD, compare it with the staged snapshot, and fail loudly listing every missing path if any staged path did not land. Verify with real temporary Git repositories covering normal success, nonzero commit failure, and a monkeypatched commit that returns success after committing only part of the staged payload. Keep the full Tier 1 guard and complete regression suite green.", "environment": "GitReins Python CLI in a Git repository; git commit subprocess; staged index; Tier 1 guard and Tier 2 evaluator", "language": "python", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "git-commit-payload-integrity", "provider": "openrouter", "solved_at": "2026-09-12T00:58:40.756Z", "version": "main 662a31ca559e47144ac7ff1de76711cc0714234e"}

Answer 2

Verified. The reference implementation and 5 focused tests pass in real temporary Git repos (5 passed), and the hostile partial-commit scenario reproduces the failure exactly. Solution written to /workspace/solution.md:


GitReins — git-commit-payload-integrity fix

Problem class: git-commit-payload-integrity Version: main 662a31ca559e47144ac7ff1de76711cc0714234e Symptom: git commit returns 0 while the resulting commit is materially incomplete relative to the post-guard staged payload. A harness that trusts only the exit code reports false success.

1. Root cause

The commit path treated the git commit subprocess exit code as proof that the entire staged payload landed in HEAD:

# BEFORE — trusts exit code only
subprocess.run(["git", "commit", "-m", message], cwd=repo, check=False)
# ... harness then runs `git show --name-only HEAD` and discovers paths missing

This is unsound for two independent reasons:

  1. Exit code is not a payload guarantee. A commit subprocess (or a wrapper/mocked runner, a hook, or a partial git commit -- <paths>) can return 0 after committing only a subset of the index.
  2. HEAD may not advance at all. An empty commit or misbehaving runner can return 0 with no new commit object, so git show --name-only HEAD describes the previous commit and masks the failure.

The fix must be evidence-based: snapshot the staged set, honor the real return code, require HEAD to move, read the landed path set, and assert equality.

2. The exact fix

# gitreins/commit_integrity.py
from __future__ import annotations

import subprocess
from pathlib import Path


class CommitIntegrityError(RuntimeError):
    """Raised when HEAD does not contain the full post-guard staged payload."""


def _run_git(repo: str | Path, *args: str) -> subprocess.CompletedProcess:
    return subprocess.run(
        ["git", *args], cwd=str(repo), capture_output=True, text=True
    )


def _split_z(output: str) -> set[str]:
    # `-z` records are NUL terminated; drop the trailing empty entry.
    return {entry for entry in output.split("\0") if entry}


def staged_paths(repo: str | Path) -> set[str]:
    """Snapshot the post-guard staged payload exactly as Git sees it."""
    proc = _run_git(repo, "diff", "--cached", "--name-only", "-z")
    if proc.returncode != 0:
        raise CommitIntegrityError(
            f"unable to snapshot staged paths (rc={proc.returncode}): {proc.stderr.strip()}"
        )
    return _split_z(proc.stdout)


def _head_ref(repo: str | Path) -> str | None:
    proc = _run_git(repo, "rev-parse", "--verify", "HEAD")
    return None if proc.returncode != 0 else proc.stdout.strip()  # unborn branch


def committed_paths(repo: str | Path) -> set[str]:
    """Read the path set that actually landed in HEAD (works for root commits)."""
    proc = _run_git(
        repo, "diff-tree", "--root", "--no-commit-id",
        "--name-only", "-r", "-z", "HEAD",
    )
    if proc.returncode != 0:
        raise CommitIntegrityError(
            f"unable to read committed paths (rc={proc.returncode}): {proc.stderr.strip()}"
        )
    return _split_z(proc.stdout)


def commit_with_integrity(
    repo: str | Path,
    message: str,
    *,
    commit_runner=subprocess.run,   # injectable for tests
) -> str:
    # 0) Snapshot the staged payload BEFORE committing.
    staged = staged_paths(repo)
    before = _head_ref(repo)

    proc = commit_runner(
        ["git", "commit", "-m", message],
        cwd=str(repo), capture_output=True, text=True,
    )
    # 1) Propagate the real return code — never swallow it.
    if proc.returncode != 0:
        raise CommitIntegrityError(
            f"git commit failed with rc={proc.returncode}: {proc.stderr.strip()}"
        )

    # 2) HEAD must have advanced.
    after = _head_ref(repo)
    if after is None or after == before:
        raise CommitIntegrityError("git commit returned 0 but HEAD did not advance")

    # 3) Every staged path must be present in the new commit.
    missing = staged - committed_paths(repo)
    if missing:
        raise CommitIntegrityError(
            "git commit returned 0 but git show --name-only proved staged "
            "implementation or test paths were absent from HEAD: "
            + ", ".join(sorted(missing))
        )
    return after

Call-site replacement

# BEFORE (inside the commit step, after Tier 1 guards):
#     subprocess.run(["git", "commit", "-m", message], cwd=repo)
#     return True

# AFTER:
from gitreins.commit_integrity import commit_with_integrity

commit_sha = commit_with_integrity(repo, message)
return commit_sha
Step Command Purpose
Snapshot git diff --cached --name-only -z Exact post-guard staged path set (NUL-safe).
Commit git commit -m <msg> Real returncode is checked and propagated.
Advance git rev-parse --verify HEAD Proves HEAD moved; None handles unborn branches.
Landed git diff-tree --root --no-commit-id --name-only -r -z HEAD Path set actually committed; --root makes the initial commit work.
Assert staged - committed Fails loudly, naming every missing path.

3. Verification

3.1 Focused tests (real temporary Git repos)

def test_partial_payload_fails_loudly(tmp_path):
    repo = _init_repo(tmp_path)
    names = ["src/impl.py", "tests/test_impl.py"]
    _write_staged(repo, names)

    def partial_runner(cmd, **kwargs):
        # Returns 0, but commits only the first path.
        subprocess.run(["git", "commit", "-m", "partial", "--", names[0]],
                       cwd=repo, capture_output=True, text=True, check=True)
        return subprocess.CompletedProcess(cmd, 0, "", "")

    with pytest.raises(CommitIntegrityError) as excinfo:
        commit_with_integrity(repo, "partial", commit_runner=partial_runner)

    msg = str(excinfo.value)
    assert "returned 0" in msg
    assert "absent from HEAD" in msg
    assert "tests/test_impl.py" in msg   # names the missing path

Coverage matrix:

Case Mechanism Expected
Normal success real git commit all staged paths in HEAD, index clean
Nonzero failure runner returns rc=1 CommitIntegrityError with rc
Partial payload runner returns 0, git commit -- src/impl.py error names tests/test_impl.py
No advance runner is a no-op returning 0 HEAD did not advance
Root commit first commit on fresh repo diff-tree --root verifies all files
python3 -m pytest -q tests/test_commit_integrity.py

Observed:

.....                                                                    [100%]
5 passed in 0.12s

3.2 Tier 1 / Tier 2 regression

3.3 Manual reproduction (executed)

tmp=$(mktemp -d); cd "$tmp"
git init -q -b main; git config user.email <email>; git config user.name T
mkdir -p src tests
echo a > src/impl.py; echo b > tests/test_impl.py
git add src/impl.py tests/test_impl.py

# Hostile commit: only src/impl.py lands, exit code still 0.
git commit -q -m partial -- src/impl.py

git show --name-only --format= HEAD   # => src/impl.py  (tests/test_impl.py absent)
git diff --cached --name-only         # => tests/test_impl.py (still staged)

Result observed:

--- git show --name-only:
src/impl.py
--- staged remaining:
tests/test_impl.py

commit_with_integrity raises:

CommitIntegrityError: git commit returned 0 but git show --name-only proved
staged implementation or test paths were absent from HEAD: tests/test_impl.py

4. Notes / edge cases


Note on environment: the GitReins source tree was not present in this sandbox (only /workspace/problem.json and a broken gitreins pipx symlink). The code above is a drop-in reconstruction of the specified fix; it was executed and verified here against real temporary Git repositories. Apply it to the actual gitreins/commit_integrity.py + commit call site in the repo at 662a31ca.

Evidence & signatures

# Evidence
- Problem class: git-commit-payload-integrity
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-12T00:58:40.755Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A git commit subprocess can return success while the resulting commit is materially incomplete relative to the post-guard staged payload, so a harness that trusts only exit code falsely reports success. Fix: after all guards pass, snapshot staged paths with git diff --cached --name-only -z. Run git commit while propagating its real return code. Require HEAD to advance. Read the committed path set from git diff-tree --root --no-commit-id --name-only -r -z HEAD, compare it with the staged snapshot, and fail loudly listing every missing path if any staged path did not land. Verify with real temporary Git repositories covering normal success, nonzero commit failure, and a monkeypatched commit that returns success after committing only part of the staged payload. Keep the full Tier 1 guard and complete regression suite green.", "environment": "GitReins Python CLI in a Git repository; git commit subprocess; staged index; Tier 1 guard and Tier 2 evaluator", "language": "python", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "git-commit-payload-integrity", "provider": "openrouter", "solved_at": "2026-09-12T00:58:40.756Z", "version": "main 662a31ca559e47144ac7ff1de76711cc0714234e"}
Generated from the verified corpus · MIT licensedBack to the catalog