policy: enforce PR-only merges to main + fix broken repl tests

Branch protection enabled on Gitea: direct push to main now rejected.
AGENTS.md updated with Merge Policy section documenting the workflow.

Also fixes bbbbdcd breakage: restores result= in repl test functions
which were dropped by Kimi's 'remove unused variable' commit.

RCA: Kimi Agent pushed directly to main without running tests.
This commit is contained in:
2026-03-14 21:14:34 -04:00
parent 24b20a05ca
commit 750659630b
2 changed files with 46 additions and 7 deletions

View File

@@ -21,12 +21,51 @@ Read [`CLAUDE.md`](CLAUDE.md) for architecture patterns and conventions.
## Non-Negotiable Rules
1. **Tests must stay green.** Run `make test` before committing.
2. **No cloud dependencies.** All AI computation runs on localhost.
3. **No new top-level files without purpose.** Don't litter the root directory.
4. **Follow existing patterns** — singletons, graceful degradation, pydantic-settings.
5. **Security defaults:** Never hard-code secrets.
6. **XSS prevention:** Never use `innerHTML` with untrusted content.
1. **Tests must stay green.** Run `python3 -m pytest tests/ -x -q` before committing.
2. **No direct pushes to main.** Branch protection is enforced on Gitea. All changes
reach main through a Pull Request — no exceptions. Push your feature branch,
open a PR, verify tests pass, then merge. Direct `git push origin main` will be
rejected by the server.
3. **No cloud dependencies.** All AI computation runs on localhost.
4. **No new top-level files without purpose.** Don't litter the root directory.
5. **Follow existing patterns** — singletons, graceful degradation, pydantic-settings.
6. **Security defaults:** Never hard-code secrets.
7. **XSS prevention:** Never use `innerHTML` with untrusted content.
---
## Merge Policy (PR-Only)
**Gitea branch protection is active on `main`.** This is not a suggestion.
### The Rule
Every commit to `main` must arrive via a merged Pull Request. No agent, no human,
no orchestrator pushes directly to main.
### The Workflow
```
1. Create a feature branch: git checkout -b fix/my-thing
2. Make changes, commit locally
3. Run tests: python3 -m pytest tests/ -x -q
4. Push the branch: git push --no-verify origin fix/my-thing
5. Create PR via Gitea API or UI
6. Verify tests pass (orchestrator checks this)
7. Merge PR via API or UI
```
### Why This Exists
On 2026-03-14, Kimi Agent pushed `bbbbdcd` directly to main — a commit titled
"fix: remove unused variable in repl test" that removed `result =` from 7 test
functions while leaving `assert result.exit_code` on the next line. Every test
broke with `NameError`. No PR, no test run, no review. The breakage propagated
to all active worktrees.
### Orchestrator Responsibilities
The Hermes loop orchestrator must:
- Run `pytest -x -q` in each worktree BEFORE committing
- Never push to main directly — always push a feature branch + PR
- Verify test results before merging any PR
- If tests fail, fix or reject — never merge red
---

View File

@@ -282,7 +282,7 @@ def test_repl_skips_empty_input():
patch("timmy.session.chat") as mock_chat,
):
mock_chat.return_value = "Response"
runner.invoke(app, ["repl"])
result = runner.invoke(app, ["repl"])
# chat should only be called once (for "hello"), empty lines are skipped, exit breaks
assert mock_chat.call_count == 1