As written, ADR 0020 gave PORT ownership of cmake/platform*.cmake while also making PORT wait for Phase 0 — but Phase 0's seams are exactly what needs velox_platform_sources() to select platform/linux/*.cpp. PORT cannot start until Phase 0 lands, and Phase 0 cannot land without the file PORT owns. PKG/QA caught the circularity before writing anything, which was the right call. Central OS detection is root build infrastructure, so it stays with PKG/QA and lands during Phase 0. PORT keeps the per-OS backend directories and the macOS and Windows packaging, and owns no part of cmake/. Also drops a hardcoded test count from the PORT definition of done; the suite number moves every round and the gate is that it stays green. Co-Authored-By: Claude Opus 5 <[email protected]>
3.6 KiB
Rules of engagement — agents working in this repo
Read this before touching anything. Then read your lane brief in docs/agents/.
1. Stay in your lane
| Lane | Owns | Never writes |
|---|---|---|
| PROTO | contracts/, tools/mockd/, tests/conformance/ |
everything else |
| CORE | core/, tools/bench/, tools/fuzz/ |
daemon/, gui/, extension/, contracts/ |
| DAEMON | daemon/, cli/, nmhost/, packaging/nativehost/ |
core/, gui/, extension/, contracts/ |
| GUI | gui/ |
everything else |
| EXT | extension/ |
everything else |
| PKG/QA | packaging/, .github/, tools/testserver/, tests/integration/, tests/e2e/, root build files |
any lane's feature code |
| PORT | **/platform/<os>/**, packaging/macos/, packaging/windows/ |
all logic, and cmake/ — see ADR 0020 |
If your task seems to require editing another lane's files, that is a signal the interface is wrong. File the request; don't reach across.
2. contracts/ is sacred
- Only PROTO commits there.
- Generated code (
core/generated/,extension/src/shared/protocol/) is committed and must never be hand-edited. Fix the schema, regenerate. - Need a new field? Open a
contracts/-only PR: schema + fixtures + regenerated code +VERSIONbump. Optional field or new method = minor; rename/remove/retype = major + ADR. - Working around a wrong contract locally is the single failure mode most likely to sink this project. Don't.
3. Layering
core → no JSON, no SQL, no Qt, no RPC. Ever.
daemon → depends on core. No Qt.
gui / ext → zero download logic. They render state and forward user intent.
nmhost → a dumb pipe. Under 300 lines. No logic.
A grep for curl|pwrite|sqlite in gui/ must come back empty. Same for download logic in
extension/.
4. Non-negotiable behaviours
- Capture fails open. Daemon down, slow, or erroring → Firefox downloads normally.
Never swallow a user's download.
capture.offeranswers within 750 ms or the extension gives up. - Resume is validated.
If-Rangewith ETag/Last-Modified; a200where206was expected means the file changed — ask the user, never silently corrupt. - Never bind beyond
127.0.0.1. The WS transport is token-authenticated, origin-checked, and rate-limited. - Secrets go to the Secret Service, never SQLite, never logs.
- Paths are canonicalized and checked against allowed roots before any write.
- No allocation in the transfer hot path.
5. Definition of done, everywhere
Code + tests + docs updated in the same change. A feature with no test does not exist. If
you change observable behaviour, update the doc in docs/ that describes it in the same PR.
6. Style
- C++23,
-Wall -Wextra -Werror, clang-format (config at root), clang-tidy clean. - TypeScript strict mode, ESLint, no
anyon protocol boundaries. - Commit messages:
lane: imperative summary(e.g.core: add dynamic segment stealing). - One logical change per commit. Rebase onto
main; no merge commits.
7. When you're unsure
Ask in the PR rather than guessing at the interface. A day of clarification is cheaper than
an M2 integration rewrite. And record real decisions as an ADR in docs/adr/ — the next
agent to touch this will have none of your context.
ADR numbers: there is no allocator. Take the next free number in main's
docs/adr/ (gaps from reserved-but-unwritten entries are fine to fill). Lanes draft in
parallel, so collisions happen: whoever merges second renumbers, updates any
cross-references, and keeps going — it is not worth a round trip.