dotfiles/agents/AGENTS.md
mwiegand 2163e5e4ef
docs(agents): drop skill pointers that duplicate the skill descriptions
Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
2026-10-09 21:57:06 +02:00

196 lines
11 KiB
Markdown

# Personal preferences
## Workflow
- **Specs, plans, and design docs go into the repo they describe.** When
brainstorming, plan-mode, or any flow produces a persistent document
(design spec, implementation plan, ADR, etc.), the final destination is
always the working tree of the project it belongs to — typically
under `docs/` (or wherever the project conventionally keeps them).
Scratch locations like `~/.claude/plans/<slug>.md` are fine *during*
plan mode, but the moment plan mode exits with an approved artifact,
copy it into the repo and `git commit` it. Don't ship a feature
while its spec or plan still lives only in a scratch file. If a
project's `AGENTS.md` / `CLAUDE.md` specifies a different directory,
that wins.
## Identity
- Email martin.wiegand@seibert.group, Bitbucket username `mwiegand`.
## Write actions: confirm before executing
Before any action that creates, modifies or sends something outside this
machine (Jira comments, ticket transitions, Confluence edits, chat messages,
emails), show exactly what will happen (the text, the target, the transition)
and wait for explicit approval. For bulk operations present the full list
first and change nothing until the plan is confirmed. Local edits, commits,
pushes and memory writes do not need this.
## External communication (messages, emails, comments)
- Neutral and technical: the agent conveys information, it does not imitate
a human. No social emojis, no emotional filler ("Danke dir! 🙂", "Huhu").
- Structure: factual salutation ("Hallo <Name>,"), precise content, concrete
call to action, closing without emotional markers.
- Append "(ai generated)" to every external text; never in chat replies to me.
## Error handling
If a tool call fails or hits a rate limit, pause and tell me. One retry with
the identified cause fixed (e.g. a sandbox denial) is fine; never retry in a
loop or brute-force through API calls.
## Git commits
- Conventional Commits; imperative, intent-focused subjects; body only when
needed; split unrelated changes; ask only for mixed diffs.
- On a Jira issue, prefix the subject with its key (`IT-12345`) in every repo.
The ISAC repo has its own single-line convention (`IT-12345 bw/<bundle>:
<what>`, no Conventional Commits); the `isac` skill has the details.
## Jira
- Search with JQL scoped to issues, never Confluence. Default filter:
`assignee = currentUser() AND status NOT IN (Done, Closed) ORDER BY duedate ASC`
- Asked to work on a ticket: present the ticket, then a numbered action plan.
No vague follow-up questions.
- Write actions (tickets, comments) go through the `jira-write` skill.
Comments are internal by default; public only when they address the
participants, never silently public.
## Code health
Strategic over tactical, with follow-through. Each change should leave the
codebase at least as coherent as it was — don't just *flag* messiness, address it.
- **Default to acting on cleanups, not just mentioning them.** If you notice
duplication, a band-aid, or an inconsistency, fix it as part of the work
rather than leaving it as an observation. "I noticed X but didn't do it"
is the anti-pattern — it leaves the user with both the mess *and* the
homework of cleaning it up.
- **Scope boundary for inline cleanups: on-path AND reversible AND within
files already being touched.** Inline when all three hold. If the cleanup
crosses files, would be hard to undo, or is parallel to the task —
surface it in 2-3 sentences and ask before pursuing.
- **Tolerate duplication until the pattern is real.** Removing existing
duplication is welcome; inventing new abstractions speculatively is not.
Rule of three: don't unify two instances, wait for the third.
- **Treat friction as architectural data.** Awkward expression, edits that
ripple across files, patterns that recur with subtle variations, structure
fighting the task — these are the architecture telling you something, not
just noise to push through. Propose architectural changes when they'd
make the code more sustainable. Frame as proposals with a clear ask
("now, or follow-up?"), not silent rewrites.
## Interpreting requests
Treat vague input and question-back responses critically, not as instructions.
- **Vagueness is not authorization.** "Make it cleaner", "maybe X?",
"looks good but…" are signals to ask one clarifying question, not green
lights to pick an interpretation and run.
- **A tangent is not an answer.** If you ask "A or B?" and get "maybe X?",
that's a new question, not a pick. Surface the mismatch and ask which the
user meant — don't bundle the tangent into the active task as if it were
direction.
## Team memory (cognee)
cognee is a real memory, not an archive: unlike `MEMORY.md` it is **not**
injected automatically, so it only works if you fetch from it and write to it
on your own. Command forms, flags, dataset sharing and failure modes are in the
`cognee` plugin skill; this section only says *when*.
- **Read: `cognee recall <question>` before the first tool call** when the task
touches infrastructure, a server, a service, a ticket or a tool we run
ourselves; when an error "smells familiar"; when choosing between options
where a decision may already exist; or when the task will plausibly take more
than a handful of tool calls. Plain `recall` reads every readable dataset,
team included. Treat what comes back like a colleague's note: useful, possibly
outdated; verify a named file, flag or host still exists before acting on it.
- **Write: `cognee remember` as the insight appears**, not at session end.
Announce it in one line, never ask first: memory writes are exempt from any
project rule that asks to confirm write actions (those rules target external
systems: Jira, chat, Confluence, hosts). Moments: a bug fixed whose cause was
not visible in the code; a decision with a rejected alternative (save the
*why*); a measurement that contradicts an assumption; a correction, yours or
mine; a tool or API that behaves differently than its docs claim.
- **Routing:** `--team` for everything concerning team IT (Seibert IT-Infra,
ISAC/bw, monitoring, INFRA board, shared services, team processes), plain
`remember` for my preferences and personal context. Never secrets,
credentials or customer-personal data; nothing the repo already records;
nothing that only matters inside this conversation.
- **Projects with their own findings convention** (task folders,
`erkenntnisse/`, `decisions/`): write the file there first, then the cognee
note with the conclusion and a link to the file. The file is the detailed
record; cognee is what the next session or a colleague in another repo finds.
- **Hygiene:** on recurring topics `recall` first and extend the existing note
instead of adding a second one. Write notes that answer a question: concrete
numbers, the error message verbatim, the fix, and the external references
(Confluence, Jira, TeamVault, Google Chat thread URLs
`https://chat.google.com/room/<SPACE-ID>/<THREAD-ID>`). No size limit, so
write self-contained.
## Sandbox
- **Always run commands sandboxed first.** Only use `dangerouslyDisableSandbox: true` after a sandbox-related failure — never preemptively. One targeted retry with the identified cause fixed is fine; retrying in a loop is not.
- **On sandbox failure:** analyze the error message for the blocked path, then suggest adding it to `sandbox.filesystem.allowWrite` in `~/.claude/settings.json`. Only fall back to `dangerouslyDisableSandbox: true` if the path can't be determined or the user prefers it.
- **Commands that must run unsandboxed belong in `sandbox.excludedCommands`** (e.g. `git *`, the pinned
`bin/srv`-style wrappers), not behind the flag: the exclusion is the owner's decision, the flag is the
model's. Without a hook, the flag is only a convention: an unsandboxed command that matches an allow
rule (`Bash(git *)`, `Bash(pytest *)` …) runs without a prompt in default mode, and auto mode may wave it
through as well. (The former PreToolUse hook that forced a prompt on the flag was removed 2026-10-04;
its JSON is in this file's git history.)
## Temporary Files
- **Use `$TMPDIR` or `.tmp/` (project-local) for temporary files.** Never use `/tmp` directly or paths like `/Library/Application Support` — those are not in the sandbox allowlist and trigger permission prompts.
- `$TMPDIR` is set by the sandbox to a writable path. `.tmp/` inside the project directory is always writable without prompts.
- Ensure `.tmp/` is listed in `.gitignore` when creating temp files in a tracked repo.
## Shell — literal `!` in Bash commands
- **Never put a literal `!` in an inline Bash command.** Claude Code's Bash tool
escapes every `!` to `\!` at the transport layer before any shell sees it —
even inside single/double quotes and in non-interactive shells
(anthropics/claude-code#61121, a regression of a fix shipped in 2.1.87). The
stray backslash corrupts downstream tools: Python `!=` → SyntaxWarning + broken
string, jq, Jira JQL (`status != Done` → server 400), branch names, etc.
`bash -c '...'` and quoted heredocs do **not** avoid it.
- **One rule covers everything:** if a command needs a `!`, write the command/code
to a file with the Write tool under `.tmp/` and run the file. `.tmp/` is
prompt-free via the `Edit(.tmp/**)` allow rule in `~/.claude/settings.json`. Do
**not** create the file with inline `printf`/`echo >` — that re-escapes the `!`.
- Need a literal `!` inline anyway: ANSI-C hex `$'\x21'` (e.g. `B=$'\x21'; cmd
"${B}=…"`) yields a real `!` with no literal `!` in the command.
## Tooling
- **Sourcebot MCP for org repos without a local checkout.** The
`mcp__sourcebot__*` tools (instance sourcebot.it.seibert.diy) search
the indexed Seibert codebases — Bitbucket DC/Cloud, Forgejo,
seibert-external on GitHub. Reach for them when a question touches a
repo that isn't cloned locally (other teams' code, cross-repo
lookups, PR context): `grep`, `glob`, `read_file`, `list_tree`,
`list_commits`, `get_diff`, `find_symbol_definitions`/`_references`
answer in seconds and return file:line plus web links. A local
checkout stays first choice when it exists. Never call
`ask_codebase` on your own — it spawns a nested server-side agent
(minutes per call, shared vLLM); use it only when explicitly asked.
- **`ccc` before `grep` for concept questions.** In a repo with a
`.cocoindex_code/` directory, a question about a concept ("where is X
handled", "what talks to Y", "which code does Z") starts with
`ccc search '<concept>'` from the project root, then `grep` verifies what it
found. An exact string (UUID, ticket ID, error message, identifier) goes
straight to `grep`/`rg`: ccc is embeddings only and will not find it. Gotchas
in the `ccc` skill.
- **`ccc index` / `ccc init` are read-safe maintenance.** They only write to the
gitignored `.cocoindex_code/` directory, never to source. Run them without
confirmation prompts; treat like `grep` for permission purposes.
- **`md` for long Markdown files instead of `head`/`grep -n '^#'`.**
`md outline <file>` prints the heading tree with line numbers and size per
section; decide from that, then `md section <file> "<heading>"` for exactly
that subtree (`--range` yields `offset limit` for the Read tool, `--depth 0`
cuts subsections). It knows code fences and frontmatter, so a `# comment` in
a bash block is not a heading. Below ~500 lines just `Read` the file.