harborclerk
AGENTS.md3 starsChanged 31 days agoMITView on GitHub
Operating rules for any agent or human working in this repository. Rules here are binding. Reference material — architecture, API surface, schema — lives elsewhere; see Map. On matters of fact, the code is authoritative and this file may be stale: trust the source and fix this file. On matters of rule, this file is authoritative. Harbor Clerk is a single-tenant, local-first document intelligence system: local extraction, OCR (eng/fra), hybrid retrieval with reranking, cited local-AI answers, and Research. It runs…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository9 other files it gives its agents.
- alembic/AGENTS.mdAGENTS.md
- frontend/AGENTS.mdAGENTS.md
- macos/AGENTS.mdAGENTS.md
- acceptanceSkill
- benchmarkSkill
- build-macosSkill
- model-refreshSkill
- verifySkill
- harbor-clerkSkill
The file
We split this AGENTS.md into the rules it gives an agent
11 rules. About 0 are common, 7 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 28
All results carry citations: Every retrieval surface returns sources.
- Distinctive: line 38
Branch first: Create a feature branch before any change, including docs.
- Distinctive: line 39
Never commit to main. Do this from the start, not retroactively.
- Distinctive: line 40
PR always: Every change lands via PR, even docs-only.
- Distinctive: line 44
Verify before claiming done: Run the checks and read the output before saying anything passes.
- Very specific: line 48
Regenerate docs: after changing tools, routes, models, stages, or compose services: uv run python -m scripts.gen_docs.
- Very specific: line 66
Signing is human: No agent runs make sign or handles the app-specific password.
- Distinctive: line 89
Before requesting review, the author runs two mechanical checks:
- Distinctive: line 113
A project rule never goes in personal memory: Test: could someone with a fresh clone and no memory work on this repo safely?
- Very specific: line 138
Read those rather than any transcription, and regenerate with uv run python -m scripts.gen_docs after changing them.
- Very specific: line 156
Every job added this week (embedder, macos, eval-harness) needed a separate gh api -X PATCH …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
Operating rules for any agent or human working in this repository. Rules here are binding. Reference material — architecture, API surface, schema — lives elsewhere; see Map. On matters of fact, the code is authoritative and this file may be stale: trust the source and fix this file. On matters of rule, this file is authoritative.
What this is
Harbor Clerk is a single-tenant, local-first document intelligence system: local extraction, OCR (eng/fra), hybrid retrieval with reranking, cited local-AI answers, and Research. It runs as a Mac-native app or via Docker Compose, and exposes the corpus to external agents through an MCP server and a mirrored CLI.
Non-negotiables
- Single-tenant. No
tenant_idin schema, API, or code. Ever. - Read-only external access. API keys are read-only and stored hashed.
- Snippets, not corpus. MCP/CLI callers receive retrieved passages and citations — never a bulk corpus export.
- Never modify a source. Watched-folder files are never altered, copied, or
moved. Mailboxes are read-only (IMAP
EXAMINE; read-only OAuth scopes when OAuth lands) — never marked read, never deleted. - Copy only where the source requires it. Watched-folder documents are read
in place from
source_path. IMAP is the deliberate exception: messages and attachments must be fetched and stored, because there is no file to reference. - All results carry citations. Every retrieval surface returns sources.
- Tika is required for PDF/Office/eBook/HTML/email extraction.
- Never commit credentials. Passwords, API keys, JWTs, or tokens supplied in conversation never enter a file, regardless of stated intent.
- Strategy stays private. Positioning, competitive analysis, claim posture,
and candid assessment live in
docs/strategy/(a separate private repo), never here.
Working agreement
- Branch first. Create a feature branch before any change, including docs.
Never commit to
main. Do this from the start, not retroactively. - PR always. Every change lands via PR, even docs-only. Branch protection is enforced.
- Never bypass the gate. No
gh pr merge --admin, no direct push to main, without explicit human permission in the current conversation. - Verify before claiming done. Run the checks and read the output before saying anything passes. Evidence, then assertion.
- Don't stack PRs. Land the base on
mainand branch again. A stacked branch once lost ~3,000 lines to a squash-merge of its base. - Regenerate docs after changing tools, routes, models, stages, or compose
services:
uv run python -m scripts.gen_docs. CI fails otherwise. dependency-auditcan fail on an unrelated PR. It audits the whole environment against live advisory databases, so a newly-published CVE turns it red on a change that touched nothing relevant.
Identities
- The machine user is
John-Doebot(write, never admin). Agent-produced PRs are opened as the bot from any session, so the owner approves agent work; the owner's own PRs are approved by the bot after an unprimed agent review. Its token is read from Keychain at the point of use (security find-generic-password -a harborclerk-bot -s github-token -w), never pasted; only unattended launchers export it for a whole session. Seedocs/adr/0001-agent-native-sdlc.md..github/CODEOWNERSlists both, so GitHub requests the right reviewer on every PR without anyone assigning. - No agent merges its own PR. Branch protection requires one approving review.
- Signing is human. No agent runs
make signor handles the app-specific password.
Review policy
A PR requires a fresh-eyes review before merge if it touches more than three
files, changes behavior, modifies public API or tool contracts, adjusts
auth/security, affects ingest/retrieval/LLM flows, adds a new subsystem,
client surface, or storage location, or changes .claude/settings.json (its
hooks run on every clone). Trivial doc edits and one-line mechanical fixes do
not.
That last trigger exists because a new subsystem is exactly when a stated non-negotiable quietly stops being true — "originals are never copied" was correct until IMAP ingest shipped.
The reviewer must be unprimed: hand it the diff and nothing else. No focus areas, no "don't flag X", no restatement of the design. A primed reviewer confirms the author's mental model instead of finding defects. Self-review "as if someone else wrote it" is not a substitute — it is the failure mode.
Review output leads with bugs, regressions, missing tests, and contract risk.
Before requesting review, the author runs two mechanical checks:
- Sweep for sibling call sites. A change that fixes a pattern, migrates a contract, or adds a cleanup path is not done until the old idiom has been grepped for and every hit accounted for in the PR. Three migrations each shipped N−1 of N sites; the missed site was always the one outside the module being edited — exactly the site self-review never visits.
- Mutation-verify tests guarding error handling, resource cleanup, or a
finally. Commit first, then revert the guarded line and confirm a test fails; restore, and state the result in the PR. A green suite on a change you just made is not evidence — five consecutive review rounds found vacuous tests, concentrated in exactly these three places, and revert-the-line caught every one.
Where knowledge goes
- Project-wide rule or constraint → this file
- Subsystem gotcha → the nearest scoped
AGENTS.md - Decision + rationale + rejected alternatives →
docs/adr/ - Loop output, eval and field reports →
docs/reports/ - Deferred work → a GitHub issue
- Strategy, positioning, claims →
docs/strategy/(private repo) - Personal workflow preference → user memory
A project rule never goes in personal memory. Test: could someone with a fresh clone and no memory work on this repo safely? If not, a rule is in the wrong place.
Map
| What | Where |
| Architecture, data model, deployment | docs/architecture.md |
| Generated reference (tools, routes, tables, stages, services) | docs/architecture.md#generated-reference |
| Design specs and implementation plans | docs/superpowers/{specs,plans}/ |
| Decisions, with rejected alternatives | docs/adr/ |
| Dated reports: evals, acceptance, field work | docs/reports/ |
Skills: verify, build-macos, acceptance, model-refresh, benchmark | .claude/skills/*/SKILL.md — tracked, no machine-specific paths |
| Eval harness and methodology | scripts/test_corpora/, docs/evaluation.md |
| Integration setup (MCP, CLI, connectors) | docs/integrations.md |
| Release procedure: tag first, version stamps, signing by hand | docs/releasing.md |
Pipeline stages, queues, mark_stage_done, extraction paths, storage, retrieval, async traps | src/harbor_clerk/AGENTS.md |
| Tailwind v4 (no config file), ESLint hooks rules, React Router state loss, npm peer deps, WKWebView dialogs | frontend/AGENTS.md |
Swift process management, waitUntilExit, pipe deadlocks, ports 8100/8443, worker presets, bundle IDs | macos/AGENTS.md |
| Migrations, enum casing, embedding dimension sentinel, log-table conventions | alembic/AGENTS.md |
Console scripts, MCP tools, REST routes, database tables, pipeline stages and
Compose services are all generated into
docs/architecture.md from source.
Read those rather than any transcription, and regenerate with
uv run python -m scripts.gen_docs after changing them.
Linting & formatting
- Python:
uv run ruff check ./uv run ruff format .(line length 120) - Frontend:
npm run lint/format:check/type-checkinfrontend/ - Everything at once: the
verifyskill
CI
Required checks on PRs to main: python, embedder, macos,
eval-harness, frontend, codeql, dependency-audit, container-scan. The
python job also verifies generated docs are current. Counted in prose once — "six required checks" — and
it was wrong by the next PR, so it isn't counted here.
A new job is not enforced until branch protection requires it. Adding one to
ci.yml makes it run and go green; it does not make it able to block a merge.
Every job added this week (embedder, macos, eval-harness) needed a separate
gh api -X PATCH repos/:owner/:repo/branches/main/protection/required_status_checks
call, and until that lands the guard is advisory.
Add the job to main before requiring it. A required context that never
reports blocks the merge, so requiring macos and eval-harness while their own
PRs were still open would have deadlocked all four open PRs — including the two
that added those jobs, which then could not merge to supply them. Land the job,
then require it, then rebase everything else.
Instruction files and your harness
AGENTS.md is the real file; CLAUDE.md beside it is a symlink to the same
content, because Claude Code reads only CLAUDE.md while Codex and most other
harnesses read AGENTS.md. One source of truth, two names — never edit them as
if they were separate files.
.claude/ is tracked — hooks, skills, commands, launch configs — and must stay
portable: no machine-specific paths. Only .claude/settings.local.json,
worktree checkouts and lock files are ignored. The protected-file hook covers
the Edit and Write tools only; a shell redirect is not covered. It is a guard,
not a gate.
Scoped files are NOT auto-loaded — read them yourself
Verified empirically (2026-07-21, Claude Code, /context): launching from the
repo root loads this file only. Scoped AGENTS.md files did not appear in
context even after explicitly reading a file in that directory. Do not rely on
on-demand loading; it did not happen.
Before working in a directory below, read its AGENTS.md first. It contains
rules that will not otherwise be in your context.
The Map above is the discovery mechanism — an agent finds a scoped file because the Map names its subject. That works when the topic matches obviously and fails when it does not, which is the second reason to read the file rather than wait to be reminded.
This is also why anything catastrophic-if-violated lives in this file rather than a scoped one: severity decides placement, not topic.
If your harness does not support hierarchical instruction files, read the
scoped AGENTS.md files manually before working in those directories.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

