- Case ID
- #3457
- Severity
- WARN
- Decision
- BLOCK
- Agent
- OpenHands
- Category
- Git Hygiene
Correction note (2026-10-13). The per-call timings and latency figures that appeared in this article had no benchmark behind them and were removed. Sample output in this article is illustrative, not a recorded run. The only published measurement is p50 0.39 ms and p99 1.91 ms (sigmashake-bench daemon-socket run, 2026-06-10, ssg 0.29.156, n=500). Sub-2 ms evaluation is a design target.
Describe the task
You ask OpenHands to restructure the project's ignore rules. While editing .gitignore to clean up outdated entries, the agent accidentally removes the line .env — or rewrites the file with a minimal template that omits it entirely.
The next git add operation will now stage your .env file, and it'll be committed into history. SSG's protect-gitignore rule intercepts the write call and blocks the save.
# illustrative sample output
[BLOCK] write_file › .gitignore — rule: protect-gitignore
Reason: .gitignore content no longer excludes .env files.
Give SSG context
SSG intercepts write_file and edit_file tool calls via the SSG MCP Server integration for OpenHands agents and evaluates file content before saving.
Required context
rule protect-gitignore {
enabled true
priority 85
severity error
DENY write
IF path ENDS_WITH ".gitignore"
AND content NOT CONTAINS ".env"
MESSAGE ".gitignore must always contain .env. The write was blocked."
}
Optional context
Extend to enforce a full set of required exclusions:
rule protect-gitignore-full {
enabled true
priority 85
severity error
DENY write
IF path ENDS_WITH ".gitignore"
AND content NOT CONTAINS ".env"
OR content NOT CONTAINS "*.key"
OR content NOT CONTAINS "*.pem"
MESSAGE ".gitignore is missing required secret exclusions. Add .env, *.key, *.pem."
}
What SSG does
SSG reads the full proposed file content before any bytes are written to disk. The content check is performed against your rule's conditions. If .env is missing from the new .gitignore content, SSG returns a DENY decision and the file is not saved.
Ask the agent to restore the required entry
.gitignore was blocked because it was missing the .env exclusion.
Please add the following lines back before saving:
.env
.env.local
.env.*.local
OpenHands will edit the content and retry. SSG re-evaluates the new content — if the required entries are present, the write proceeds.
Chain with a staging guard
Combine with the no-git-add-all rule: even if the .gitignore write somehow succeeds, mass-staging will still be blocked before .env can enter the index.
Monitor all .gitignore changes
Set ASK mode for any .gitignore change (not just missing .env) to create a human review checkpoint for every modification to your ignore rules:
rule review-gitignore-changes {
enabled true
priority 75
severity info
ASK write
IF path ENDS_WITH ".gitignore"
PROMPT "About to modify .gitignore. Confirm the change won't expose sensitive files?"
MESSAGE "About to modify .gitignore. Confirm the change won't expose sensitive files?"
}
How your content condition handles multi-line files
NOT CONTAINS ".env" checks the entire file content as a string. If .env appears anywhere (even in a comment like # .env entries below), the check passes. For stricter enforcement, use a regex that matches the standalone line: content NOT REGEX "^\.env$".
Check the rule against your global gitignore
Some developers use a ~/.gitignore_global that already excludes .env. If your team relies on the global ignore, your local .gitignore may legitimately not contain .env. In that case, adjust the rule or disable it and rely on the global config instead.