Files
management/AGENTS.md
T
Thore CimbalandClaude Opus 5 9ca5ec3b6d feat: the twelve findings move to pages with a proven harvest state
Slice 4.3. Every finding is now a stolpersteine page carrying its state,
and the mapping is discharged mechanically: twelve findings in the
register's last hand-maintained revision, twelve pages naming their origin,
zero unassigned.

The states were verified against the rule text of the tags, not derived
from issue status - and that turned up two errors in my own Gate-2 mapping.
FB-06 was listed as open; the framework had actually split the combined
item and closed that half as issue 0028 in v0.1.3, whose WORKFLOW.md
carries "Name what this work made false" verbatim. FB-09 and FB-11 were
listed as open too; v0.3.0 covers them partly through the ledger and the
ladder's trace duty, so they are `partly` with the version named.

Two are `declined`: the framework considered them and will not cover them,
so they remain ours. That state exists because writing `open` for a decided
matter is the failure class this undertaking exists to clear.

The texts are not edited. They came out of git at the register's last
revision and moved unchanged; only repo-relative links were rewritten,
because inline links resolve against the file.

Also done: the duplicated half of the ADR rule is gone from the project
section - permanent exceptions have been upstream since v0.1.2 - and three
descriptions that still called the register an inbox now describe the
pages, the generated overview and the signpost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F2Q4Ri8NGwyTZzScvKnWFM
2026-08-21 12:00:00 +00:00

246 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.) **Name the rung that holds, and record the
walk in the run's ledger** — searched, found, outcome. A rung that held
and a rung never tried leave the same diff, so without the record this
rule cannot be followed observably. See `WORKFLOW.md`, The Run Ledger.
- 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.
### Exceptions need decisions
- Every **permanent exception** to a rule requires an ADR. An exception
that is documented but never decided is an error.
(Field-proven rule from the first adoption; see docs/issues/0006.)
### 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 15, 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 |
| `docs/ledger/` | One trace per session: a row per gate, plus the ladder walk |
| `docs/verdict/` | Judged runs; findings split into model failure vs framework gap |
| `scripts/` | Deterministic tooling: `validate.py`, `gen_status.py`, the check family |
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.
**Link targets are files, never directories**`validate.py` rejects
`[x](dir/)` even where a forge would render it; point at the
directory's README or a concrete file instead.
Diagrams as Mermaid. This keeps every artifact portable across LLMs,
GitLab, and Obsidian.
- Never invent frontmatter fields or status values. `validate.py` is
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.
- **Adopting projects:** project-specific rules live in a marked section
*appended below* the upstream content of this file (marker line, e.g.
`<!-- project-section -->`) — never woven into it. Vendor the pristine
upstream originals under `docs/sources/upstream/<version>/` and check
the upstream part byte-for-byte against them in CI: a silent rewrite
of the framework files becomes a red pipeline, a framework upgrade
becomes a deliberate baseline-plus-copy commit.
<!-- projektabschnitt -->
## 6. Gruppenregeln (Projekt axion1337.chat)
Dieses Repo steuert die Gruppe `axion1337.chat`. Die Abschnitte 15
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](docs/sources/regelwerk/karpathy-guidelines.md).
**Ä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](docs/adr/0013-gruppenregeln-kanonisch-mit-pruefung.md)).
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](docs/adr/0001-gitlab-kanonisch-push-mirror.md),
[ADR-0004](docs/adr/0004-site-to-site-vpn-hetzner-lab.md)). 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](docs/wiki/deployment/deploy-uebergabe.md).
- Einzige bewusste Ausnahme: der TURN-Rotations-CronJob schreibt nach
Gitea; der tägliche CI-Job `canonize_rotation` holt es zurück. Seine
rote Pipeline **ist** der Alarm — es gibt bewusst keinen zweiten Meldeweg.
Das trägt nur, solange **Grün der Normalzustand** ist: Am 2026-08-18 stand
dieser Job neun Tage rot, und genau deshalb fiel es niemandem auf. Siehe
Prüfungen unten.
- **Wiki:** Das frühere Test-Wiki (Docusaurus-Lesefläche auf `wiki.lab`) wurde als
ungenügend bewertet und auf Basis von **Wiki.js in den Stack integriert**
([ADR-0014](docs/adr/0014-wikijs-loest-docusaurus-ab.md), `wiki.axion1337.chat`).
`wiki.lab` existiert nicht mehr — nicht danach suchen.
### Issues & Board
- `docs/issues/` ist kanonisch für den Management-Scope
([ADR-0012](docs/adr/0012-issues-im-repo-gitlab-als-spiegel.md));
GitLab ist bespiegelte Ansicht. Jedes Issue trägt genau einen
Meilenstein (M1M5) und genau eine Priorität — das Schema erzwingt
beides. Zeitkritisches trägt ein `due`-Datum, nicht „bald".
- **WIP-Limit 2** (Validator-Regel). Die Zusage-Status `next` und
`in-progress` vergibt **nur sorb**; Sessions bilden ab (`waiting` mit
`wartegrund`, Erledigtes `done` mit Begründung im Issue-Commit),
sagen aber nichts zu.
- **ADR-Pflicht** bei Architektur- und Prozessentscheidungen. Die zweite
Hälfte dieser Regel — dauerhafte Ausnahmen brauchen eine Entscheidung,
nicht nur eine Notiz — steht seit v0.1.2 im Upstream-Teil oben
(§1, *Exceptions need decisions*) und wird hier nicht wiederholt.
### Prüfungen
Die Repo-Map oben nennt nur `validate.py` und `gen_status.py` — sie ist
neckbeard-Baseline und bleibt byte-treu. Tatsächlich stehen in `scripts/`:
| Skript | Wann | Wofür |
|---|---|---|
| `validate.py`, `gen_status.py` | jeder Push | Artefakte gegen `schema.yaml`, STATUS aktuell |
| `pruefe_prosa.py`, `pruefe_upstream_drift.py` | jeder Push | tote Verweise/SHA-Zitate; Baseline unverändert |
| `gruppenpruefung.py`, `stillstandspruefung.py` | täglich (Zeitplan) | Verbund- und Stillstandsbefunde über die Gruppe |
| `spiegel_issues.py` | manuell (sorb) | `docs/issues/` → GitLab, Standard Dry-Run |
| `quittungen.py` | von beiden Prüfungen genutzt | Bekanntes quittieren |
| `pruefe_sperrliste.py` | jeder Push | angenommene ADRs und `docs/sources/` sind unveränderlich |
**Bekanntes wird quittiert, nicht toleriert** (`scripts/befund_quittungen.tsv`,
[ADR-0020](docs/adr/0020-bekannte-befunde-quittieren.md)): Jede Zeile trägt eine
Frist, „dauerhaft" geht nur als ADR-Verweis, und wirkungslose Zeilen melden sich.
Quittiertes bleibt in der Ausgabe sichtbar. Eine Prüfung, die dauerhaft rot steht,
meldet nichts mehr — deshalb ist Rot-Stehenlassen kein neutraler Zustand, sondern
ein Befund für sich.
### Nach Deploys und Vorfällen
**Ein AAR ist Pflicht** nach jedem Deploy mit Übergabe und nach jedem Incident
(`roadmap.md`, Kadenz; Vorlage `docs/aar/template.md`). Offene Punkte daraus werden im
selben Zug zu Issues. Die Regel stand bisher nur in der Roadmap — am 2026-08-20 fehlten
dadurch **sechs** AARs auf einmal, alle nachträglich geschrieben.
⚠️ Kein Werkzeug erzwingt sie. Sie hängt an der Aufmerksamkeit dessen, der ausrollt.
**Wiederkehrende Fehlerklassen und Abweichungen vom Verfahren** bekommen je eine
Seite unter `docs/wiki/stolpersteine/` mit `status` und, wo zutreffend, `harvested_in`
(ADR-0009 des Rahmenwerks) — dort steht, was aus mehreren Issues und AARs als **Muster**
hervorgeht, damit die nächste neckbeard-Iteration es abdecken kann. ⚠️ `harvested` nur,
wenn eine **veröffentlichte** Version es abdeckt; übergeben ist nicht geerntet. Die
geclusterte Übersicht erzeugt `gen_status.py` nach [STATUS.md](STATUS.md);
[FRAMEWORK-BEFUNDE.md](FRAMEWORK-BEFUNDE.md) ist nur noch der Wegweiser dorthin. Vor dem Vorschlagen von Optionen gehört sie zu den
Dokumenten, die man gelesen hat (§4).
### 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.
### 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 Autor-Identität. Historien-Rewrites nur mit
alt→neu-Zuordnung
([ADR-0009](docs/adr/0009-commit-konventionen-und-historien-anonymisierung.md),
Tabelle: [shared/commit-zuordnung-2026-08-07.md](docs/sources/migration/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).