forked from Rockachopa/Timmy-time-dashboard
Merge pull request 'policy: enforce PR-only merges to main + fix broken repl tests' (#116) from policy/pr-only-main into main
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
|
||||
|
||||
16
tox.ini
16
tox.ini
@@ -52,14 +52,14 @@ commands =
|
||||
pytest tests/ -q --tb=short \
|
||||
--ignore=tests/e2e \
|
||||
--ignore=tests/functional \
|
||||
-m "not ollama and not docker and not selenium and not external_api and not skip_ci" \
|
||||
-m "not ollama and not docker and not selenium and not external_api and not skip_ci and not slow" \
|
||||
-n auto --dist worksteal
|
||||
|
||||
[testenv:integration]
|
||||
description = Integration tests (marked with @pytest.mark.integration)
|
||||
commands =
|
||||
pytest tests/ -q --tb=short \
|
||||
-m "integration and not ollama and not docker and not selenium and not external_api" \
|
||||
-m "integration and not ollama and not docker and not selenium and not external_api and not slow" \
|
||||
-n auto --dist worksteal
|
||||
|
||||
[testenv:functional]
|
||||
@@ -79,7 +79,7 @@ commands =
|
||||
pytest tests/ -q --tb=short \
|
||||
--ignore=tests/e2e \
|
||||
--ignore=tests/functional \
|
||||
-m "not ollama and not docker and not selenium and not external_api" \
|
||||
-m "not ollama and not docker and not selenium and not external_api and not slow" \
|
||||
-n auto --dist worksteal
|
||||
|
||||
[testenv:ollama]
|
||||
@@ -100,7 +100,7 @@ commands =
|
||||
--cov-fail-under=73 \
|
||||
--junitxml=reports/junit.xml \
|
||||
-p no:xdist \
|
||||
-m "not ollama and not docker and not selenium and not external_api and not skip_ci"
|
||||
-m "not ollama and not docker and not selenium and not external_api and not skip_ci and not slow"
|
||||
|
||||
[testenv:coverage]
|
||||
description = Full coverage report (terminal + XML)
|
||||
@@ -111,7 +111,7 @@ commands =
|
||||
--cov-report=xml \
|
||||
--cov-fail-under=73 \
|
||||
-p no:xdist \
|
||||
-m "not ollama and not docker and not selenium and not external_api"
|
||||
-m "not ollama and not docker and not selenium and not external_api and not slow"
|
||||
|
||||
[testenv:coverage-html]
|
||||
description = Coverage with HTML report
|
||||
@@ -122,7 +122,7 @@ commands =
|
||||
--cov-report=html \
|
||||
--cov-fail-under=73 \
|
||||
-p no:xdist \
|
||||
-m "not ollama and not docker and not selenium and not external_api"
|
||||
-m "not ollama and not docker and not selenium and not external_api and not slow"
|
||||
|
||||
# ── Pre-push (mirrors CI exactly) ────────────────────────────────────────────
|
||||
|
||||
@@ -142,7 +142,7 @@ commands =
|
||||
--cov-fail-under=73 \
|
||||
--junitxml=reports/junit.xml \
|
||||
-p no:xdist \
|
||||
-m "not ollama and not docker and not selenium and not external_api and not skip_ci"
|
||||
-m "not ollama and not docker and not selenium and not external_api and not skip_ci and not slow"
|
||||
|
||||
# ── Pre-commit (fast local gate) ────────────────────────────────────────────
|
||||
|
||||
@@ -156,7 +156,7 @@ commands =
|
||||
pytest tests/ -q --tb=short \
|
||||
--ignore=tests/e2e \
|
||||
--ignore=tests/functional \
|
||||
-m "not ollama and not docker and not selenium and not external_api and not skip_ci" \
|
||||
-m "not ollama and not docker and not selenium and not external_api and not skip_ci and not slow" \
|
||||
-n auto --dist worksteal
|
||||
|
||||
# ── Dev Server ───────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user