Inventoried the 24 git.lab PATs by metadata only — last_used_at separates 'needed' from 'lying around': four are in active use, five are active but never used at all (one with manage_runner and k8s scope), and several names exist twice because a replacement was created without revoking the old one. All six push mirrors are healthy, but GitLab masks both parts of the mirror URL, so the credential remains unidentifiable — and it is a Gitea token, which the PAT list cannot answer for. Hence the ordering: set a dedicated mirror credential first, revoke second. The revocations themselves are sorb's; from here a never-used token is indistinguishable from a staged one. W5 resolved: the secrets rule now has a bootstrap exception, since on a headless host it was only satisfiable by violating it. W4 splits — point 5 is #0015 (plus the WG key, which no token inventory covers), point 4 is demonstrably undone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
10 KiB
AGENTS.md — Canonical Agent Instructions
Canonical instruction set for any coding agent working in this repository
(Claude Code, GPT-OSS harnesses, others). CLAUDE.md points here.
This file is loaded into every session — keep it short. Process details
live in WORKFLOW.md; read that when a task begins, not preemptively.
Tradeoff: these rules bias toward caution over speed. For trivial tasks, use judgment — but say so.
1. Operating Rules
Think before coding
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them — don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.
Simplicity first
- Minimum code that solves the problem. Nothing speculative.
- No features beyond what was asked. No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.
- Test: "Would a senior engineer call this overcomplicated?" If yes, simplify.
- Before writing new code, stop at the first rung that holds: needed at all? → codebase already has it? → stdlib? → platform-native? → installed dependency? → one line? → only then: the minimum that works. (Ladder after ponytail, MIT.)
- Never cut, at any rung: trust-boundary validation, data-loss handling, security, accessibility.
- Lazy about the solution, never about reading the code first.
Surgical changes
- Touch only what you must. Match existing style, even if you'd differ.
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- If you notice unrelated dead code, mention it — don't delete it.
- Remove imports/variables/functions that YOUR changes made unused; leave pre-existing dead code alone unless asked.
- Every changed line must trace directly to the request.
Goal-driven execution
- Transform tasks into verifiable goals: "fix the bug" → "write a test that reproduces it, then make it pass".
- For multi-step work, state a brief plan: step → verify, step → verify.
- A task is well-defined only if it names all four: files, action, verify, done. Missing one? The task is too vague — say so.
Verification before completion
- Never claim something works without evidence: a test run, command output, a rendered result. "Should work" is not a status.
- Report every task/slice with exactly one status:
DONE|DONE_WITH_CONCERNS|NEEDS_CONTEXT|BLOCKED. - Uncertainty is reported, never swallowed. Flag your shakiest calls.
2. Project Initialization (Gate 0)
At session start, read PROJECT.md. If it does not exist, initialization
is your first task: before anything else, ask the Gate 0 questions defined
in WORKFLOW.md — response language, size-S gate exception (yes/no),
one-line project purpose, audience — write the answers to PROJECT.md,
and have validate.py accept it. Never guess these answers; ask.
3. Workflow
For anything beyond a trivial change, read WORKFLOW.md and follow its
gates. At task start, propose a size class (S/M/L); the human confirms
(possibly batched later). Never advance past a gate without explicit
human approval — sole exception: size-S tasks, and only if PROJECT.md
explicitly grants that exception.
4. Repository Map
| Path | Purpose |
|---|---|
WORKFLOW.md |
Gate 0 (init) + Gates 1–5, size classes, debugging path, session handoff, refinement ritual |
PROJECT.md |
Per-project answers from Gate 0: language, size-S exception, purpose, audience |
STATUS.md |
Generated overview: open issues, active designs, recent ADRs — do not edit by hand |
schema.yaml |
Frontmatter schema — single source of truth for artifact structure |
docs/adr/ |
Architecture Decision Records — binding; never edited, only superseded |
docs/design/ |
One design doc per undertaking; completed ones move to done/ |
docs/aar/ |
Standalone After Action Reviews (incidents, major deviations only) |
docs/issues/ |
In-repo issues, one file each; status lives in frontmatter |
docs/wiki/ |
Wiki areas as folders, created on demand — rules in docs/wiki/index.md |
docs/sources/ |
Immutable original sources; wiki pages cite them — read-only for agents |
scripts/ |
Deterministic tooling: validate.py, gen_status.py |
Before proposing options (Gate 2), read the relevant ADRs and AARs first — past decisions and learnings are input, not trivia.
5. Artifact Rules
- All artifacts are standard Markdown with YAML frontmatter conforming to
schema.yaml. Standard links only ([text](path.md)), no wikilinks. Diagrams as Mermaid. This keeps every artifact portable across LLMs, GitLab, and Obsidian. - Never invent frontmatter fields or status values.
validate.pyis authoritative; if it rejects your artifact, fix the artifact, not the validator. - Deterministic jobs (status generation, validation, link checks) are done by scripts, not by you. If a deterministic job lacks a script, propose one instead of doing it by inference.
6. Gruppenregeln (Projekt axion1337.chat)
Dieses Repo steuert die Gruppe axion1337.chat. Die Abschnitte 1–5
oben sind neckbeard v0.1.1 und bleiben byte-treu (Baseline:
docs/sources/upstream/neckbeard-v0.1.1/, Prüfung:
scripts/pruefe_upstream_drift.py); §1 ist destilliert aus den
wortgleich archivierten
Karpathy-Guidelines.
Änderungen an dieser Datei nur mit sorb abgestimmt. Dieser
Abschnitt gilt für jede Session in allen Repos der Gruppe;
Komponenten-Repos tragen nur Projektspezifika plus einen Pointer
hierher (ADR-0013).
Ohne Lab-Zugang: dieses Repo ist als Push-Mirror unter
https://rohana.axion1337.de/sorb/management lesbar — pushen dorthin ist tabu.
Quelle der Wahrheit & Mirror-Topologie
git.lab/axion1337.chat/*ist kanonisch; Gitea/rohana wird per Push-Mirror beliefert und bleibt Flux-Quelle, Registry und Release-Download (ADR-0001, ADR-0004). Die Flux-Quelle nicht auf git.lab „geradeziehen" — die Produktion darf nicht an der Lab-Verfügbarkeit hängen.- Nie direkt zu Gitea pushen (der Mirror überschreibt per Force). Landet doch ein Commit dort: Kanonisierungs-Verfahren in verfahren/deploy-uebergabe.md.
- Einzige bewusste Ausnahme: der TURN-Rotations-CronJob schreibt nach
Gitea; der tägliche CI-Job
canonize_rotationholt es zurück. Seine rote Pipeline ist der Alarm — es gibt bewusst keinen zweiten Meldeweg.
Issues & Board
docs/issues/ist kanonisch für den Management-Scope (ADR-0012); GitLab ist bespiegelte Ansicht. Jedes Issue trägt genau einen Meilenstein (M1–M5) und genau eine Priorität — das Schema erzwingt beides. Zeitkritisches trägt eindue-Datum, nicht „bald".- WIP-Limit 2 (Validator-Regel). Die Zusage-Status
nextundin-progressvergibt nur sorb; Sessions bilden ab (waitingmitwartegrund, Erledigtesdonemit Begründung im Issue-Commit), sagen aber nichts zu. - ADR-Pflicht bei Architektur-/Prozessentscheidungen und jeder dauerhaften Ausnahme von einer Regel — eine Ausnahme nur zu dokumentieren statt sie zu entscheiden, ist ein Fehler.
Secrets & Credentials
- Token-/Secret-Werte niemals anzeigen, loggen oder in Dateien
echoen — anzeigen = Exposure = Rotation. Referenz nur über
Dateipfade (z. B.
~/.config/gitlab-lab/token) oder maskierte CI-Variablen. Die Trennung ist „Credential vs. Config": nicht-geheime Konfiguration wird normal committet. - Bootstrap-Ausnahme (aus #0027/W5): Auf einem Host, auf dem sorb die Datei nicht selbst anlegen kann und kein anderer Übergabekanal existiert, darf eine Session ein Credential schreiben — sonst ist die Inbetriebnahme unmöglich, und die Regel wäre nur durch Verstoß erfüllbar. Es gilt dann zwingend: (a) der Wert ist damit exponiert, also rotationspflichtig, sobald der reguläre Weg steht; (b) im AAR oder Issue wird festgehalten welches Credential wohin geschrieben wurde (nur Pfad und Zweck, nie der Wert); (c) die Rotation bekommt ein Issue mit Fälligkeit — „später mal" zählt nicht. Die Ausnahme deckt das Ablegen, nicht das Anzeigen: auch im Bootstrap wird der Wert nicht in Logs, Chat oder Commits sichtbar.
Commit-Konventionen
- Nachrichten auf Englisch, Conventional-Stil; der Betreff sagt was, der Rumpf warum.
- Autor- und Committer-Datum auf 12:00:00 UTC des laufenden Tages.
- Kanonische Identität (gilt für alle Repos der Gruppe): Autor
Thore Cimbal <cfx@riot.8shield.net>, dazu ein TrailerCo-Authored-By: <Modell> <noreply@anthropic.com>— Agenten-Sessions committen also nicht unter eigener Identität, sondern kenntlich als Beitrag. Ausnahme: derturn-secret-rotation-Bot committet maschinell, eine Zuschreibung an einen Menschen wäre dort falsch (ADR-0009). - Historien-Rewrites nur mit alt→neu-Zuordnung (ADR-0009, Tabelle: shared/commit-zuordnung-2026-08-07.md).
- ⚠️ Das schützt nur die Git-Historie; Plattform-Zeitstempel (Push, Issues, Pipelines, Pakete) tragen die echte Uhrzeit (ADR-0009).
Redlichkeit
- Verifiziert (Messung/Konsole) klar von Vermutung trennen; Korrelation ≠ Kausalität — ein plausibler Verdacht ist kein Befund.
- Config-Dateien chirurgisch editieren, nie re-dumpen; vor dem Push
validieren (
docker compose config, YAML-Parse). - Fehlschläge und übersprungene Schritte benennen, nicht glätten — „fertig" heißt verifiziert (deckungsgleich mit §1).