Files
kyleandClaude Opus 5.5 cfde35397a P5a plan: PDF documents — seven Ornith tasks with acceptance tests first
docs/plans/p5a: 01 kind+fetch limits, 02 pdftext child + runner, 03 dcache PDF tables,
04 pdfpool, 05 pdfdoc render (map/pages/grep), 06 api, 07 digest citations, metrics, CLI,
skill, unit, README. Given tests compile against a panic-only skeleton and fail there for the
intended reasons; PDFs for tests are built by internal/pdftest (given), plus two qpdf-encrypted
fixtures.

Owner changes for the run: vendor go-pdfkit/extract v0.3.0 + reader v0.6.0 (pinned via
tools.go until task 02); AGENTS.md, tools/run-plan.sh (enforces a Co-Authored-By trailer for
the model), docs/implementer-log.md, `make gate`; gofmt (whitespace) on clean.go and guard;
TestUnsupportedType uses a zip now that PDFs are supported; requestDeadline 90→210 s and
writeTimeout 120→240 s for the PDF path's worst case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:47:38 -07:00

99 lines
5.2 KiB
Markdown

# AGENTS.md
sift is the fleet's fetch and search service for LLM agents: it fetches a URL through an SSRF
guard, cleans the result (HTML → Markdown, JSON, text, and from P5a PDF), optionally digests it
with a small model, and serves Hermes agents through a Firecrawl-compatible API. It is written in
Go and runs on orion under a hardened systemd unit. You are implementing it one task at a time.
## How you work
1. The owner gives you one task file, `docs/plans/<plan>/NN-name.md`. Read it fully. Do that task
and nothing else. Do not start the next task.
2. Do the steps in order. Where a step shows a command and its expected output, run it and compare.
3. Do not read other task files, `docs/PLAN.md` or other phase docs unless the task tells you to.
The task file quotes what you need.
4. If something in the task is impossible, contradictory, or fails twice in the same way, **stop**.
Do not improvise, do not change a test, do not weaken a check. Add your row to
`docs/implementer-log.md` with status `stopped`, say what you tried and what happened, commit
only that file, and tell the owner.
5. Work only from files inside this repository. Never read another checkout, and never search the
file system for code. If you are stuck, stop as in point 4.
## Files you must never edit
- `docs/plans/`, `docs/PLAN.md`, `docs/P*.md`, `AGENTS.md`, `tools/run-plan.sh`
- `internal/guard/` and `internal/auth/` — the SSRF guard and the key store are the security
boundary; no task changes them.
- `go.mod`, `go.sum`, `vendor/` — every dependency is already vendored. Never add a module and
never run `go get` or `go mod tidy`/`vendor`; the build is offline.
- `nix/` and `flake.nix`, unless the task names the exact change.
- Anything a task told you to copy from `docs/plans/**/_files/` — tests, fixtures,
`internal/pdftest` — in this plan **or any earlier one**. If a copied test fails, your code is
wrong. If a copied test can no longer be right because the task changes what it tested, that
is the owner's error: stop and report it.
## Code rules
- Go 1.26 (`go.mod`). Standard library plus what is already in `vendor/`.
- No **new** source file over 400 lines. Do not grow `internal/api/api.go`: new API code goes in
the new file the task names.
- Library code (`internal/...`) never panics on input: no `panic`, no indexing that can go out of
range on data from a file, a request, a PDF or a peer. Check lengths. `main` may exit with a
message.
- Errors are values: return them, wrap with `fmt.Errorf("...: %w", err)`. A check that cannot do
its job fails; it does not return "ok".
- **Never log, print or store a request or response body, a document's text or its title.** Log
lines carry caller, host, sizes, counts, durations and outcomes. For a restricted caller
(`PermitRestricted`) use the existing helpers (`logHost`, `restrictedLog`, `logErr`): they
already blank what must not be written.
- Anything read from the network, a child process or a file is bounded (`io.LimitReader`,
deadlines).
- Exported names, field names and JSON tags are exactly as the task gives them; the tests compile
against them.
- Comments say why, not what. `gofmt` decides layout.
## Lessons from earlier work (crossbar, same owner, same process)
- A type assertion on a value from outside your package uses the two-value form and handles
`false`.
- When a rule says "every" or "everywhere", finish by listing each place it applies and checking
them one by one.
- Never end a turn by describing what you are about to do. Do it, then report.
- Work only inside this repository. Scratch programs under `/tmp` or anywhere else are refused by
the sandbox, and **a refused tool call is not a reason to end the turn**: write the experiment
as a `_test.go` file inside the repository (delete it before committing), or reason it out.
- Never change when production code releases, flushes or records something just to make a given
test's timing pass. If a given test seems to check a value before the code could settle it,
that is the owner's bug: stop and report it.
## The gate
`make gate` must pass before a task is done:
```
make gate # gofmt check, go vet, go test -race ./..., staticcheck if installed
```
It runs offline against `vendor/`. Run `gofmt -w` on the files you touched first. `go test
./internal/<pkg>/` runs one package.
## Git
- Work on the branch the task names. One task is one commit.
- Stage only the paths the task lists: `git add <path> ...`. Never `git add -A` or `git add .`.
- Never push, amend, rebase, reset, or switch to another branch.
- Commit message: the subject line the task gives, a blank line, a short body if useful, then the
`Co-Authored-By:` trailer line the owner's prompt gives you, exactly, as the last line.
- A message with more than one line goes in `.state/commit-msg.txt` (inside the repository and
ignored by git; `/tmp` is refused) and is committed with `git commit -F .state/commit-msg.txt`.
## The implementer log
Before you commit, add one row to the table in `docs/implementer-log.md` and include the file in
the commit:
`| <plan>/<task> | <date> | done or stopped | <sessions> | gate pass/fail | deviations | what you did |`
Be honest: the log is how the owner judges the process. A deviation you log is a finding; one
you hide is a defect.