296 lines
10 KiB
Markdown
296 lines
10 KiB
Markdown
# AGENTS.md — Timmy Time Development Standards for AI Agents
|
|
|
|
Read [`CLAUDE.md`](CLAUDE.md) for architecture patterns and conventions.
|
|
|
|
---
|
|
|
|
## Communication Protocol
|
|
|
|
**Before making changes, always:**
|
|
1. Read CLAUDE.md and AGENTS.md fully
|
|
2. Explore the relevant src/ modules to understand existing patterns
|
|
3. Explain what you're changing and **why** in plain English
|
|
4. Provide decision rationale - don't just make changes, explain the reasoning
|
|
|
|
**For Timmy's growth goals:**
|
|
- Improve reasoning in complex/uncertain situations: think step-by-step, consider alternatives
|
|
- When uncertain, state uncertainty explicitly rather than guessing
|
|
- Document major decisions in DECISIONS.md
|
|
|
|
---
|
|
|
|
## Non-Negotiable Rules
|
|
|
|
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.
|
|
|
|
---
|
|
|
|
## One-Agent-Per-Issue Convention
|
|
|
|
**An issue must only be worked by one agent at a time.** Duplicate branches from
|
|
multiple agents on the same issue cause merge conflicts, redundant code, and wasted compute.
|
|
|
|
### Labels
|
|
|
|
When an agent picks up an issue, add the corresponding label:
|
|
|
|
| Label | Meaning |
|
|
|-------|---------|
|
|
| `assigned-claude` | Claude is actively working this issue |
|
|
| `assigned-gemini` | Gemini is actively working this issue |
|
|
| `assigned-kimi` | Kimi is actively working this issue |
|
|
| `assigned-manus` | Manus is actively working this issue |
|
|
|
|
### Rules
|
|
|
|
1. **Before starting an issue**, check that none of the `assigned-*` labels are present.
|
|
If one is, skip the issue — another agent owns it.
|
|
2. **When you start**, add the label matching your agent (e.g. `assigned-claude`).
|
|
3. **When your PR is merged or closed**, remove the label (or it auto-clears when
|
|
the branch is deleted — see Auto-Delete below).
|
|
4. **Never assign the same issue to two agents simultaneously.**
|
|
|
|
### Auto-Delete Merged Branches
|
|
|
|
`default_delete_branch_after_merge` is **enabled** on this repo. Branches are
|
|
automatically deleted after a PR merges — no manual cleanup needed and no stale
|
|
`claude/*`, `gemini/*`, or `kimi/*` branches accumulate.
|
|
|
|
If you discover stale merged branches, they can be pruned with:
|
|
```bash
|
|
git fetch --prune
|
|
```
|
|
|
|
---
|
|
|
|
## 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.
|
|
|
|
### Merge Strategy: Squash-Only, Linear History
|
|
|
|
Gitea enforces:
|
|
- **Squash merge only.** No merge commits, no rebase merge. Every commit on
|
|
main is a single squashed commit from a PR. Clean, linear, auditable.
|
|
- **Branch must be up-to-date.** If a PR is behind main, it cannot merge.
|
|
Rebase onto main, re-run tests, force-push the branch, then merge.
|
|
- **Auto-delete branches** after merge. No stale branches.
|
|
|
|
### The Workflow
|
|
```
|
|
1. Create a feature branch: git checkout -b fix/my-thing
|
|
2. Make changes, commit locally
|
|
3. Run tests: tox -e unit
|
|
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: {"Do": "squash"}
|
|
```
|
|
|
|
If behind main before merge:
|
|
```
|
|
1. git fetch origin main
|
|
2. git rebase origin/main
|
|
3. tox -e unit
|
|
4. git push --force-with-lease --no-verify origin fix/my-thing
|
|
5. Then merge the PR
|
|
```
|
|
|
|
### 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 `tox -e unit` in each worktree BEFORE committing
|
|
- Never push to main directly — always push a feature branch + PR
|
|
- Always use `{"Do": "squash"}` when merging PRs via API
|
|
- If a PR is behind main, rebase and re-test before merging
|
|
- Verify test results before merging any PR
|
|
- If tests fail, fix or reject — never merge red
|
|
|
|
---
|
|
|
|
## QA Philosophy — File Issues, Don't Stay Quiet
|
|
|
|
Every agent is a quality engineer. When you see something wrong, broken,
|
|
slow, or missing — **file a Gitea issue**. Don't fix it silently. Don't
|
|
ignore it. Don't wait for someone to notice.
|
|
|
|
**Escalate bugs:**
|
|
- Test failures → file with traceback, tag `[bug]`
|
|
- Flaky tests → file with reproduction details
|
|
- Runtime errors → file with steps to reproduce
|
|
- Broken behavior on main → file IMMEDIATELY
|
|
|
|
**Propose improvements — don't be shy:**
|
|
- Slow function? File `[optimization]`
|
|
- Missing capability? File `[feature]`
|
|
- Dead code / tech debt? File `[refactor]`
|
|
- Idea to make Timmy smarter? File `[timmy-capability]`
|
|
- Gap between SOUL.md and reality? File `[soul-gap]`
|
|
|
|
Bad ideas get closed. Good ideas get built. File them all.
|
|
|
|
When the issue queue runs low, that's a signal to **look harder**, not relax.
|
|
|
|
## Dogfooding — Timmy Is Our Product, Use Him
|
|
|
|
Timmy is not just the thing we're building. He's our teammate and our
|
|
test subject. Every feature we give him should be **used by the agents
|
|
building him**.
|
|
|
|
- When Timmy gets a new tool, start using it immediately.
|
|
- When Timmy gets a new capability, integrate it into the workflow.
|
|
- When Timmy fails at something, file a `[timmy-capability]` issue.
|
|
- His failures are our roadmap.
|
|
|
|
The goal: Timmy should be so woven into the development process that
|
|
removing him would hurt. Triage, review, architecture discussion,
|
|
self-testing, reflection — use every tool he has.
|
|
|
|
---
|
|
|
|
## Agent Roster
|
|
|
|
### Gitea Permissions
|
|
|
|
All agents that push branches and create PRs require **write** permission on the
|
|
repository. Set via the Gitea admin API or UI under Repository → Settings → Collaborators.
|
|
|
|
| Agent user | Required permission | Gitea login |
|
|
|------------|--------------------|----|
|
|
| kimi | write | `kimi` |
|
|
| claude | write | `claude` |
|
|
| gemini | write | `gemini` |
|
|
| antigravity | write | `antigravity` |
|
|
| hermes | write | `hermes` |
|
|
| manus | write | `manus` |
|
|
|
|
To grant write access (requires Gitea admin or repo admin token):
|
|
```bash
|
|
curl -s -X PUT "http://143.198.27.163:3000/api/v1/repos/rockachopa/Timmy-time-dashboard/collaborators/<username>" \
|
|
-H "Authorization: token <admin-token>" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"permission": "write"}'
|
|
```
|
|
|
|
### Build Tier
|
|
|
|
**Local (Ollama)** — Primary workhorse. Free. Unrestricted.
|
|
Best for: everything, iterative dev, Docker swarm workers.
|
|
|
|
**Kimi (Moonshot)** — Paid. Large-context feature drops, new subsystems, persona agents.
|
|
Avoid: touching CI/pyproject.toml, adding cloud calls, removing tests.
|
|
|
|
**DeepSeek** — Near-free. Second-opinion generation, large refactors (R1 for hard problems).
|
|
Avoid: bypassing review tier for security modules.
|
|
|
|
### Review Tier
|
|
|
|
**Claude (Anthropic)** — Architecture, tests, docs, CI/CD, PR review.
|
|
Avoid: large one-shot feature dumps.
|
|
|
|
**Gemini (Google)** — Docs, frontend polish, boilerplate, diff summaries.
|
|
Avoid: security modules, Python business logic without Claude review.
|
|
|
|
**Manus AI** — Security audits, coverage gaps, L402 validation.
|
|
Avoid: large refactors, new features, prompt changes.
|
|
|
|
---
|
|
|
|
## Docker Agents
|
|
|
|
Container agents poll the coordinator's HTTP API (not in-memory `SwarmComms`):
|
|
|
|
```
|
|
GET /internal/tasks → list tasks open for bidding
|
|
POST /internal/bids → submit a bid
|
|
```
|
|
|
|
`COORDINATOR_URL=http://dashboard:8000` is set by docker-compose.
|
|
|
|
```bash
|
|
make docker-build # build image
|
|
make docker-up # start dashboard
|
|
make docker-agent # add a worker
|
|
```
|
|
|
|
---
|
|
|
|
## File Conventions
|
|
|
|
| Pattern | Convention |
|
|
|---------|-----------|
|
|
| New route | `src/dashboard/routes/<name>.py` + register in `app.py` |
|
|
| New template | `src/dashboard/templates/<name>.html` extends `base.html` |
|
|
| New subsystem | Add to existing `src/<package>/` — see module map in CLAUDE.md |
|
|
| New test | `tests/<module>/test_<feature>.py` (mirror source structure) |
|
|
| Secrets | Via `config.settings` + startup warning if default |
|
|
| DB files | Project root or `data/` — never in `src/` |
|
|
|
|
---
|
|
|
|
## Search Capability (SearXNG + Crawl4AI)
|
|
|
|
Timmy has a self-hosted search backend requiring **no paid API key**.
|
|
|
|
### Tools
|
|
|
|
| Tool | Module | Description |
|
|
|------|--------|-------------|
|
|
| `web_search(query)` | `timmy/tools/search.py` | Meta-search via SearXNG — returns ranked results |
|
|
| `scrape_url(url)` | `timmy/tools/search.py` | Full-page scrape via Crawl4AI → clean markdown |
|
|
|
|
Both tools are registered in the **orchestrator** (full) and **echo** (research) toolkits.
|
|
|
|
### Configuration
|
|
|
|
| Env Var | Default | Description |
|
|
|---------|---------|-------------|
|
|
| `TIMMY_SEARCH_BACKEND` | `searxng` | `searxng` or `none` (disable) |
|
|
| `TIMMY_SEARCH_URL` | `http://localhost:8888` | SearXNG base URL |
|
|
| `TIMMY_CRAWL_URL` | `http://localhost:11235` | Crawl4AI base URL |
|
|
|
|
Inside Docker Compose (when `--profile search` is active), the dashboard
|
|
uses `http://searxng:8080` and `http://crawl4ai:11235` by default.
|
|
|
|
### Starting the services
|
|
|
|
```bash
|
|
# Start SearXNG + Crawl4AI alongside the dashboard:
|
|
docker compose --profile search up
|
|
|
|
# Or start only the search services:
|
|
docker compose --profile search up searxng crawl4ai
|
|
```
|
|
|
|
### Graceful degradation
|
|
|
|
- If `TIMMY_SEARCH_BACKEND=none`: tools return a "disabled" message.
|
|
- If SearXNG or Crawl4AI is unreachable: tools log a WARNING and return an
|
|
error string — the app never crashes.
|
|
|
|
---
|
|
|
|
## Roadmap
|
|
|
|
**v2.0 Exodus (in progress):** Voice + Marketplace + Integrations
|
|
**v3.0 Revelation (planned):** Lightning treasury + `.app` bundle + federation
|