forked from Rockachopa/Timmy-time-dashboard
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:
51
AGENTS.md
51
AGENTS.md
@@ -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
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user