template-jj/AGENTS.md

9.9 KiB

AGENTS.md

Canonical agent instructions for this repository. This file is the source of truth for how AI coding agents — Claude Code, GitHub Copilot CLI, OpenAI Codex CLI, Google Gemini CLI, Kiro CLI, Cursor, etc. — should work here. Tool-specific files like CLAUDE.md should point to this file and add only tool-specific items on top.

When this template is copied into a new project, AGENTS.md travels with it as the portable convention doc. Replace the <PLACEHOLDER> tokens below with your project's values.


Working style — read before you write

Default to more reading, less guessing. The cost of reading one more file upstream or downstream of a change is almost always paid back by the constraint you'd have missed. Fast, confident-looking code that turns out to be wrong is a net loss here.

  • Read the relevant plan first. If a change lands under dev/plans/<YYWWD>-<feature-slug>/, skim the plan's PRD / design / tasks before editing. The plan exists precisely because the obvious fix is often wrong.
  • Verify assumptions with tools, not memory. Before claiming "function X does Y" or "field Z exists," run Grep/Read. File paths, line numbers, and type signatures drift — check the current state. Memory entries can be stale; treat them as hints, not facts.
  • Prefer a small Read over a big Edit. If a change feels obvious after 30 seconds, that's usually a sign you haven't read enough yet. One more file's context almost always surfaces a constraint you'd have missed.
  • Trace lifetimes, threads, and invariants explicitly. Bugs about where data lives and which thread touches it pass code review and crash in the wild. State the ownership / threading / invariant assumption (in your head or a comment) before editing.
  • Say what you don't know. If the user asks for a fix and the right approach depends on a fact you haven't verified (protocol quirk, library behavior, tool version), call it out and verify before implementing. Don't paper over uncertainty with plausible-looking code.

Thoroughness and speed aren't at odds — agents can parallelize research (see CLAUDE.md for Claude-specific sub-agent guidance) to do more reading per wall-clock second.

Layout

The following directory conventions are load-bearing. Generic names (<PROJECT_NAME>, <TEST_COMMAND>) are placeholder tokens you should replace with your project's actual values when using this template.

  • ./ — working tree of <PROJECT_NAME>. Primary language: <PRIMARY_LANGUAGE>. Test command: <TEST_COMMAND>.
  • ./dev/ — agentic / developer working artifacts. Tracked (not excluded). See dev/README.md. Subdirs: dev/plans/<YYWWD>-<feature-slug>/, dev/plans/archive/, dev/notes/, dev/research/, dev/tools/.
  • ./.claude/ — Claude Code harness directory.
    • .claude/skills/ — skill packs (codex, copilot, gemini, kiro + spec-driven workflow skills). See "Skills index" below.
    • .claude/commands/ — Claude Code slash commands (e.g. /repo-cleanup).
    • .claude/settings.json — team-shared hook configuration.
    • .claude/settings.local.json — personal overrides (gitignored by default).
  • ./AGENTS.md (this file) — canonical agent instructions.
  • ./CLAUDE.md — Claude Code entrypoint; points here and adds Claude-specific items.

Skills index

Skills under .claude/skills/ are self-contained instruction packs. Claude Code loads them as /skill-name slash commands. Other tools can reference them as documentation.

Spec-driven workflow (chains through a feature's lifecycle):

  • /create-prd — draft a Product Requirements Document with EARS-syntax acceptance criteria, peer-reviewed by codex.
  • /create-design — optional technical blueprint translating the PRD (architecture, data flow, interfaces, security, tests).
  • /generate-tasks — two-phase decomposition (parent tasks → sub-tasks on "Go") with traceability tags.
  • /process-task-list — execute the task list one sub-task at a time; codex review at parent-task completion and pre-PR.

All four use a fresh codex session per stage (see codex skill's "Cross-stage continuation" section for the rationale).

Peer-reviewer CLIs (driven by the spec-driven skills or invoked ad-hoc):

  • codex — OpenAI Codex CLI. codex exec --sandbox read-only + resume --last for iterative review. Session UUIDs logged in dev/plans/<YYWWD>-<feature-slug>/codex-sessions.md.
  • copilot — GitHub Copilot CLI (agentic, not the older gh copilot suggest). Sessions in copilot-sessions.md.
  • gemini — Google Gemini CLI. Index-based session resume (not UUID). Sessions in gemini-sessions.md.
  • kiro — Kiro CLI (AWS, rebranded Amazon Q Developer lineage). Sessions in kiro-sessions.md.

Separate per-tool session-log files keep lineage unambiguous when mixing reviewers on one feature.

dev/ workflow

  • Plan directories use a YYWWD- chronological prefix. YY = two-digit ISO year, WW = ISO week, D = ISO day-of-week (1=Mon … 7=Sun). Compute with date +%y%V%u at creation time — don't backdate. Example: dev/plans/26167-pane-focus-sync/.
  • Plan directory contents (produced by the spec-driven skills): prd.md, optional design.md, tasks.md, and per-tool *-sessions.md logs.
  • Feature branches mirror the plan slug: feature/<YYWWD>-<feature-slug>. jj bookmark list stays in the same chronological order as ls dev/plans/.
  • Archive completed plans by moving them under dev/plans/archive/ so the active list stays scannable.
  • In-code traceability tags: // spec:<feature-slug>/<ref> where <ref> is R<n.m> (PRD requirement), D§<n> (design section), or T<n.m> (task). Use the bare slug (no YYWWD prefix) — shorter for rg 'spec:<slug>'.
  • Lint a plan directory with planctl lint before spawning a codex review or opening a PR. It catches tag-syntax errors, orphan / uncovered references, missing close-out files, and EARS-keyword deviations — all classes codex historically flagged — in single-digit milliseconds per plan. Run from inside the plan dir or pass the path explicitly; classification codes (orphan-requirement, tag-unclosed, ears-violation, etc.) are listed in planctl --help. Install once with go install forgejo.zerova.net/sid/template-jj/cmd/planctl@latest — spec lives at dev/plans/26172-planctl/.

See dev/README.md for the full workflow.

Version control

This template uses jj colocated with git. Prefer jj for authoring and rewriting local history; use git only for remote operations and the occasional git status sanity check.

jj new main -m "scratch"              # start a change on top of main
jj describe / jj squash / etc.        # normal jj workflow
jj git push                           # pushes to origin

Commit rules:

  • Never include Co-Authored-By lines in commit messages. Agent-generated commits go under the user's identity unchanged.
  • Conventional commit prefixes: feat:, fix:, refactor:, test:, docs:, chore:, dev: (for dev/-only changes).
  • Lowercase imperative subject, keep under ~70 chars. Body explains the why — the diff shows the what.
  • Never skip hooks (--no-verify) unless the user explicitly requests it.
  • Never push to upstream trees containing dev/ content. If <UPSTREAM_BLOCKED_PATTERN> is set in your environment, the pre-push guard at dev/tools/pre-push-guard.sh will refuse pushes of dev/ paths to a matching remote. Install via ./dev/tools/install-hooks.sh.

Multi-agent coordination

When multiple agents are active on the same repository simultaneously (the default when using this template's jj-commitd session-commit daemon):

  • Use jj workspace add for true parallel isolation. Each workspace gets its own @ pointer; a branch switch in one session never flips the working tree underneath another. Setup: jj workspace add --name <role> ../<project>-<role>. See dev/README.md → "Primary isolation: jj workspaces".
  • Each session commits its own tracked files under a per-session commit message (wip(claude:<session_id>): <files>) and bookmark (wip/claude-<session_id> set at session end). History stays attributable even when agents interleave.
  • Use the session inventory on start. The daemon's session-start response lists every other active session and its tracked files. Log it and check for overlap with files your session plans to edit — if another session holds them, coordinate with the user before writing. See docs/jj-commitd.md → "Session inventory consumption".
  • JJ_AGENT_FEATURE labels your work (planned). Exporting JJ_AGENT_FEATURE=<feature-name> before starting will label commits as wip(<feature>:<session_id>) and set a feat/<feature> bookmark at session end — human-readable names instead of bare UUIDs. Not yet implemented; see dev/README.md → "Planned: JJ_AGENT_FEATURE".
  • Cross-session file conflicts are logged. Grep /tmp/jj-commitd-<repo_id>.log for conflict if edits seem to disappear.
  • Don't assume the working copy is yours. Before writing, jj status and confirm @ is the change you expect. If a pre-flight step is relevant to your skill, run it every invocation — don't rely on session state.

Placeholder tokens (for template users)

When adopting this template, replace:

  • <PROJECT_NAME> — your project's short name.
  • <PRIMARY_LANGUAGE> — Zig, Rust, Python, Go, TypeScript, etc.
  • <TEST_COMMAND> — the canonical test command (zig build test, pytest, npm test, go test ./..., etc.).
  • <SOURCE_ROOT> — the main source directory (src/, lib/, pkg/, etc.).
  • <UPSTREAM_BLOCKED_PATTERN> — if you're maintaining a fork, the substring the pre-push guard matches against the upstream's remote URL (e.g. upstream-org/repo). Leave unset if your repo has no upstream to protect against.

rg -n '<[A-Z_]+>' AGENTS.md CLAUDE.md dev/ .claude/skills/ finds every placeholder token in one pass.