- Git section carries the rules that lived in auto-memory: push and PRs without asking, no --amend or stash pop with parallel sessions, absolute commit-message path, readable PR branches, push unsandboxed - External communication: no notice on automated texts, terse PR replies, local time in chat - Model selection: opus for research and judgement work; rule 0 for the self-hosted backend, fed by agents/backend-hint.sh as a SessionStart hook (prints a context line only when ANTHROPIC_BASE_URL is the vLLM gateway) Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UH8jPP1zXteddiR9pEd4KE
212 lines
12 KiB
Markdown
212 lines
12 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 I phrase; never in chat
|
|
replies to me, and not in automated webhook or alert texts.
|
|
- PR thread replies carry only the decisive argument: no side findings,
|
|
links or follow-up ideas.
|
|
- Times in chat in Europe/Berlin local time; convert server UTC first.
|
|
|
|
## 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.
|
|
- **Push and open PRs (also drafts) without asking**, then report the link.
|
|
Not covered: force-push, pushes to shared or foreign branches, merges, PR
|
|
comments. Exception: in the private l4d2 project Martin pushes himself.
|
|
- **Never `--amend` and never `git stash pop` when other sessions may work in
|
|
the same repo.** An amend rewrote another session's pushed commit once
|
|
(2026-09-25); a pop after "No local changes to save" pops a foreign stash,
|
|
in the ISAC repo one with staged secrets. Fix-ups are new commits; to look
|
|
at an old version use `git show <ref>:<path>`.
|
|
- **Commit messages via `-F` use one absolute path for writing and reading**
|
|
(the Bash tool's cwd changes silently; a relative `.tmp/commitmsg.txt` once
|
|
landed in a task folder and the commit took the old message). Check
|
|
`head -1` before committing; several commits per turn get numbered files.
|
|
- **Own PR branches: readable over historical.** Re-cut commits into one per
|
|
logical step (pure `git mv` first, content second) and push with
|
|
`--force-with-lease`; rebuild from the final tree instead of amending.
|
|
Bitbucket detects renames only by content similarity, so keep a renamed
|
|
file small.
|
|
- `git push` over SSH fails inside the sandbox (no raw TCP; `excludedCommands`
|
|
does not help): push with `dangerouslyDisableSandbox: true`, ISAC via
|
|
`isac git -C <repo>`.
|
|
|
|
## 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 for Seibert repos without a local checkout:** the `sourcebot` skill
|
|
(MCP tools, gotchas such as mirrors and result caps; never `ask_codebase` on
|
|
your own). A local checkout stays first choice.
|
|
- **`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.
|