# Six Git Checks After an AI-Assisted Change — And What They Cannot Guarantee

> Source: <https://dev.to/mars70s/six-git-checks-after-an-ai-assisted-change-and-what-they-cannot-guarantee-260g>
> Published: 2026-10-08 14:15:41+00:00

A coding assistant changes the two files you asked it to edit. The diff looks reasonable. Is the next Git operation safe to proceed?

Not necessarily. You might be in the wrong repository. An extra file might already be staged. The branch or configured push destination might have changed. Or the secret scanner might have failed to run at all.

These are not necessarily mistakes in the generated code. They are mismatches between **the workflow you authorized** and **the Git state that actually exists**.

I built a small, [public reference Git Safety Harness](https://github.com/mars70s/ai-workflow-safety-harness) to check selected mismatches before a later operation. It is a PowerShell-based, fail-closed workflow control—not a sandbox, not an independent enforcement boundary, and not a guarantee of safe AI-generated code.

Suppose the authorized work is:

`docs/article.md` and `public/article.html` in a particular repository.`main`.` origin` against an explicitly approved URL.
The harness does not invent these expectations. A human or an authorized workflow must define them first. The harness then compares selected observed Git state against them.

| Check | Question before proceeding | Example of a reason to stop | 
|---|---|---|
| **Repository Root** | Is this the intended Git repository? | The command is running in another valid checkout. | 
| **Write Set** | Are observed tracked changes and non-ignored untracked paths within the allowed set? | `README.md` changed even though it was not authorized. | 
| **Stage Set** | Does the actual Git index contain only explicitly allowed staged paths? | An unrelated file was staged earlier. | 
| **Branch** | Is the current symbolic branch the expected branch? | HEAD is detached or the branch differs. | 
| **Push URL** | Does the selected remote have exactly one configured push URL, matching the approved URL? | `origin` points somewhere else, or has multiple push URLs. | 
| **Secret Scan** | Can Gitleaks run and accept the staged diff? | Gitleaks is missing, cannot execute, or exits nonzero. | 

Each question has a different failure mode. A PASS from one check does not substitute for the others.

The Write Set asks which paths are allowed to change. The Stage Set asks a different question: which paths are allowed in the Git index for the next operation?

The reference implementation reads the actual index with `git diff --cached --no-renames --name-only` and compares staged paths with a separate allow-list. That is a separate comparison from the Write Set, which covers staged and unstaged tracked changes as well as non-ignored untracked paths, using its own allow-list.

The approved **Write Set** contains both `docs/article.md` and `public/article.html`. The approved **Stage Set** contains only `docs/article.md`. Now imagine the following *hypothetical* output, not a captured test transcript:

``` bash
$ git diff --cached --no-renames --name-only
docs/article.md
public/article.html
```

Both paths are allowed to **change**, so their presence alone does not violate the Write Set. But `public/article.html` is **not** allowed in the index for this operation. The reference implementation treats this as a Stage Set mismatch and reports `GSH_STOP_STAGE_SET` instead of accepting that staged state.

**What would happen next?** Consider two *hypothetical* paths from this same Git state:

`git commit` without changing the index, `GSH_STOP_STAGE_SET` and a nonzero result. The calling workflow stops This illustrates a workflow boundary, not a measured incident or a new test result. It also does **not** mean that the harness itself blocks direct Git commands: if an actor bypasses the checked path, the local Layer-2 harness cannot enforce that stop.

Likewise, checking a remote's *fetch* address is not enough to establish its *push* destination. The harness inspects push URLs and requires one exact match.

If a required state cannot be confirmed, the normal harness path stops rather than treating missing evidence as success.

That includes a repository root that cannot be resolved, an unexpected branch, an unavailable Gitleaks executable, and a scanner execution failure. The validated PowerShell wrapper also treats invocation errors, a missing child exit status, and nonzero exits as failures.

**STOP is not an instruction for the assistant to silently repair the situation and continue.** It is a point for inspecting the observed state and obtaining any necessary human decision.

The [commit-pinned Validation Record](https://github.com/mars70s/ai-workflow-safety-harness/blob/605f95cc2499120db8557f454312580fab2279a3/harnesses/git/docs/validation.md) reports results for the identified implementation in documented Windows reference environments:

The tests used synthetic local remotes and recorded bounded results for the identified implementation and environments. They did **not** establish universal compatibility, unbypassability, or the safety of a later real-world push or deployment.

The [Evidence Pack from that later revalidation](https://github.com/mars70s/ai-workflow-safety-harness/tree/605f95cc2499120db8557f454312580fab2279a3/harnesses/git/docs/evidence/validation-20260919) preserves execution output, case results, exit codes, and a SHA-256 manifest. These are records of the later run, not the original run’s raw logs.

Three limits matter especially in AI-assisted workflows:

`git push`. Its Gitleaks check covers the staged diff examined by the scanner, not every file or every secret.
Those limitations are reasons to keep human approval separate from independent enforcement, such as repository-side controls. Human approval is a workflow decision, not independent enforcement; the local harness replaces neither.

The goal is not to prove that an AI assistant is safe. It is narrower: **before a selected Git workflow continues, make certain mismatches observable and stop when required checks cannot be accepted.**

The full [English design article on OSIIX](https://osiix.com/en/library/ai-git-safety-harness.html) explains the checks in detail. For the current implementation—including its separate `AllowedStagedFiles` parameter—use the [commit-pinned source](https://github.com/mars70s/ai-workflow-safety-harness/tree/605f95cc2499120db8557f454312580fab2279a3/harnesses/git), [Getting Started guide](https://github.com/mars70s/ai-workflow-safety-harness/blob/605f95cc2499120db8557f454312580fab2279a3/harnesses/git/docs/getting-started.md), and [limitations](https://github.com/mars70s/ai-workflow-safety-harness/blob/605f95cc2499120db8557f454312580fab2279a3/harnesses/git/docs/limitations.md), rather than treating every illustrative snippet in the earlier article as the latest tested code.

If you use AI-assisted Git automation, which of these checks is enforced *outside* the agent-controlled execution path, and which is only a convention the agent is expected to follow?
