| name | ai-agents-docs-of-record |
| version | 1.0.0 |
| license | MIT |
| description | Runbook for this repo's documents of record. Session logs, ADRs, retrospectives, Serena memories, per-issue handoffs, plus the templates, validators, naming rules, and house prose style that bind them. Use when you say `write the session log`, `create an ADR`, `fill the retro`, `save this to memory`, `which document of record`. Do NOT use for authoring skills (use `SkillForge`) or research write-ups (use `ai-agents-research-methodology`). |
ai-agents-docs-of-record
This repo runs on verification-based governance: work that is not recorded in a
document of record did not happen (SESSION-PROTOCOL.md, "Trust-Based vs
Verification-Based"). This skill is the operating manual for the five record
systems, the house style they share, and the decision table for which record a
given fact belongs in. Jargon: a "document of record" is an artifact a later
session or CI gate treats as authoritative evidence, as opposed to chat output,
which evaporates.
Triggers
write the session log
create an ADR
fill the retro
save this to memory
which document of record does this go in
The Record System Map
| Record | Location | Create with | Validated by |
|---|
| Session log | .agents/sessions/YYYY-MM-DD-session-NN[-slug].json | session-init skill | scripts/validate_session_json.py; CI ai-session-protocol.yml |
| Per-issue handoff | .agents/sessions/handoffs/{YYYY-MM-DD}-{ISSUE}-handoff.md | copy .agents/templates/HANDOFF.md | resume-verification checklist at next session start |
| ADR | .agents/architecture/ADR-NNN-slug.md | adr-generator skill | scripts/validation/check_adr_uniqueness.py; adr-review debate gate |
| Retrospective | .agents/retrospective/ | auto-retro skeleton + /retro fill, or retrospective skill | INDEX.md row (auto-appended, incomplete; see Phase 4) |
| Serena memory | .serena/memories/[domain]-[name].md | memory skill write conventions | curating-memories skill; memory-index routing |
| Project dashboard | .agents/HANDOFF.md | nobody. READ-ONLY per ADR-014, 5K hard cap | push guard; protocol MUST NOT |
Process
Phase 1: Pick the right record
| Situation | Record | Why |
|---|
| Any session doing real work | Session log, always | Protocol MUST; CI validates |
| Issue spans multiple sessions | Per-issue handoff | Cold-start continuity (Issue #1725: 95.8% protocol failure without file-based gates) |
| Architectural or irreversible decision | ADR | Fires adr-review multi-agent debate |
| Incident, failure, or "what went wrong" | Retrospective | Feeds the failure canon; see ai-agents-failure-archaeology |
| Reusable pattern, correction, gotcha | Serena memory | Only memories are read by future sessions at start |
| User corrected you mid-session | reflect skill, then memory | Corrections not persisted are lost |
| A doc you touched is stale | Fix on contact (Phase 7) | Broken-windows rule |
One fact can need two records: an incident gets a retrospective AND a memory
distilling the rule. The retro is the evidence; the memory is the searchable
lesson.
Phase 2: Session logs
Session logs are JSON, schema at .agents/schemas/session-log.schema.json
(top-level required: session, protocolCompliance with sessionStart and
sessionEnd subsections).
Create early. SESSION-PROTOCOL.md Phase 5: the log SHOULD exist within the
first 5 tool calls and MUST NOT be deferred to session end.
uv run python "${COPILOT_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-.claude}}/skills/session-init/scripts/new_session_log.py" \
--session-number 2601 --objective "Fix issue 2785"
uv run python3 scripts/validate_session_json.py .agents/sessions/<file>.json
Hard requirements enforced by scripts/validate_session_json.py:
- Required
session fields: number, date, branch, startingCommit, objective.
- Branch must match
^(feat|fix|docs|chore|refactor|test|ci)/.
startingCommit must be a 7-40 char lowercase hex SHA.
Naming in current practice (as of 2026-07-03) appends a slug:
2026-06-30-session-2600-skill-tooling-hygiene-taste-lints-naming.json. Let
the session-init script produce the name; do not hand-roll it. If the CI
session-protocol gate goes red, use session-log-fixer. Session end duties
(complete the log, write handoff if an issue stays open, update Serena) belong
to session-end. Never resolve a session-log merge conflict with
git checkout --ours; the settled rule from the session 1187 incident is take
--theirs and rename your own log to the next free number (see
ai-agents-failure-archaeology).
Phase 3: ADRs
Numbering collides here; treat numbers as claims, not identity. History:
concurrent ADR PRs each picked the same "next" number (Issue #2253), and
ADR-058/062/063 each existed twice until the duplicates were renumbered to
069/070/071 (Issue #2228, per the docstring of
scripts/validation/check_adr_uniqueness.py). ADR-055 and ADR-024 share the
slug github-actions-runner-selection (055 supersedes 024). Rule: when citing
an ADR, verify the file content says what you claim, not just the number.
python3 scripts/validation/check_adr_uniqueness.py --print-next
Workflow:
- Search first:
memory-search for prior decisions, then read neighbors in
.agents/architecture/ (ADR-007 memory-first: retrieval precedes reasoning).
- Generate with
adr-generator against .agents/architecture/ADR-TEMPLATE.md.
- Claim the number from
--print-next at the last moment before commit.
- Expect the gate: any
ADR-*.md or SESSION-PROTOCOL.md create or edit
fires the adr-review multi-agent debate (AGENTS.md, "ADR Review").
Governance-level changes additionally need human approval (AGENTS.md
Boundaries: "Ask First: Architecture|New ADRs|Breaking|Security").
- Lifecycle frontmatter per ADR-073 (accepted 2026-06-19): optional,
unenforced Phase-1 fields
id, status, date, decision-makers,
supersedes, superseded-by, explainer, implemented. Use them on new
ADRs; do not backfill mechanically.
Phase 4: Retrospectives
Two skills, different jobs. reflect captures corrections and praise
mid-conversation while context is hot. retrospective produces the full
artifact (timeline, Five Whys, learning matrix) in .agents/retrospective/.
Retrospectives are written on demand: /retro here, plus the Post-PR
Retrospective workflow in CI. Until #3349 a Stop hook also wrote a skeleton
at session end stamped <!-- RETRO-STATE: skeleton-pending-fill --> (Issue #2079); that hook is deleted, but skeletons it already wrote are still
placeholders rather than records, so fill them with /retro fill YYYY-MM-DD.
INDEX.md was auto-appended by that hook (Issue #1703) and is incomplete: 5
rows against 95 retro files as of 2026-07-03. Nothing appends to it now.
Never treat INDEX.md as the catalog; list the directory. Also note retro-cited short SHAs do not resolve
locally even with full history present (~1471 commits as of 2026-07-03), so
retros and memories, not git archaeology, are the durable history (depth in
ai-agents-failure-archaeology).
Retro learnings MUST be persisted to Serena in the same session, not left as
prose in the artifact (.serena/memories/retrospective-accuracy.md: "learnings
were proposed in the retrospective but then not persisted to Serena, so they
will be lost").
Phase 5: Serena memories
Write conventions (canonical text: .claude/skills/memory/SKILL.md, "Serena
Write Conventions"):
- File name:
[domain]-[descriptive-name].md, lowercase, hyphens. Example:
pr-review-security.md.
- Entity ID inside the file:
{domain}-{description}, kebab-case, no prefix.
File name and entity ID are separate things; do not conflate them.
- Domain index files (
skills-*-index.md) are a two-column table ONLY. Insert
new rows AFTER the last existing data row, never after the header or
delimiter row.
- Register new memories where
memory-index (the keyword-to-memory routing
map read at session start) will find them.
Curation (marking obsolete, dedupe, bidirectional links) is the
curating-memories skill. Search is memory-search (Tier 1); the four-tier
model is ADR-063.
Separate-PR rule: .claude/rules/claude-agents.md MUST NOT item 2: "MUST NOT
bundle skill code changes with memory changes in the same PR (separate
concerns)." Memory edits ride their own PR. The cautionary tale is PR #908,
where 53 memory files changed in a PR that started as one CI fix
(.agents/retrospective/2026-01-15-pr-908-comprehensive-retrospective.md).
Phase 6: Handoffs
Tier model per ADR-014 and .agents/sessions/handoffs/README.md:
| Tier | Location | Scope |
|---|
| Session log | .agents/sessions/*.json | Single session, canonical record |
| Per-issue handoff | .agents/sessions/handoffs/{date}-{issue}-handoff.md | One issue across sessions; rewritten each session |
| Per-branch handoff | .agents/handoffs/{branch}/{session}.md | Multi-session branch coordination |
| Dashboard | .agents/HANDOFF.md | Project-wide, READ-ONLY, 5K hard cap |
Start from the template .agents/templates/HANDOFF.md. A handoff must carry a
"Verification on Resume" checklist; the next session executes it before any
Edit or Write (SESSION-PROTOCOL.md Phase 2.5, a blocking gate). Never edit
.agents/HANDOFF.md itself: it had grown to 122KB with an 80%+ per-PR merge
conflict rate before ADR-014 froze it
(.agents/architecture/ADR-014-distributed-handoff-architecture.md:13-16;
AGENTS.md "Never" list).
Phase 7: House style and stale docs
Prose rules (canonical: .claude/rules/voice.md, .claude/rules/universal.md):
- Lead with the point. Name file, line, command, number, or say you do not know.
- No em-dashes or en-dashes anywhere in authored text (universal.md MUST NOT
item 5; only
tests/hooks/fixtures/ is exempt). Every dash costs a bot
review thread.
- No banned vocabulary (voice.md "Banned Vocabulary" section).
- No auto-generated headers or timestamps-as-headers in any authored or
generated file (universal.md MUST NOT item 6; rejected by the user three
times as of 2025-12-17).
- Block-style YAML arrays only in frontmatter
(
.agents/governance/PROJECT-CONSTRAINTS.md, Frontmatter constraints table;
ADR-040 Amendment). Inline ['a', 'b'] breaks Copilot CLI parsing.
- Run
prose-self-check before emitting any session-log narrative, ADR
context section, retro, or PR description.
Markdown lint is SCOPED to files you changed. The PR #908 Five Whys traced 53
unrelated memory-file changes to markdownlint --fix **/*.md run repo-wide
(retro, Q1-Q4). Lefthook filters staged Markdown and runs the named validator
declared in lefthook.yml. Config is .markdownlint-cli2.yaml. Never widen
the glob.
Mirror claims (FM-9): any statement that a file "matches", "mirrors", or
"aligns with" another source MUST cite the canonical path and quote the
load-bearing fragment character-for-character; intentional divergence gets a
named divergence section (.agents/governance/FAILURE-MODES.md, failure mode
9; rule text in .claude/rules/canonical-source-mirror.md; heuristic gate
scripts/validation/check_canonical_citations.py, warn-only unless
STRICT_CANONICAL_CHECK=1). Cost of ignoring it: PR #1887 took 7 fix commits
on confident-incorrectness claims.
Fix stale docs on contact. Worked example from before PR #2871:
CONTRIBUTING.md line 155 said build/Generate-Agents.ps1 PowerShell invocation until PR #2871
repointed it to build/generate_agents.py. Zero .ps1 build scripts
exist (ADR-042 Python migration). When you touch a stale doc: fix the lines on
your path, quote the canonical source per FM-9, and flag (do not silently expand
into) the rest. Behavioral claims in docs are verified with doc-accuracy.
Anti-Patterns
| Anti-pattern | Why it burns you | Evidence |
|---|
Editing .agents/HANDOFF.md | Read-only per ADR-014; push guards and reviewers reject it | AGENTS.md "Never" list |
| Deferring the session log to session end | Incomplete records when sessions die; protocol MUST NOT | SESSION-PROTOCOL.md Phase 5 |
| Trusting an ADR number without reading the file | Numbers collided (058/062/063 dupes; 024 vs 055 same slug) | check_adr_uniqueness.py docstring |
Repo-wide markdownlint --fix | Reformatted 53 unrelated memory files in PR #908 | PR #908 retro Five Whys |
| Bundling memory changes with skill code in one PR | Violates claude-agents.md MUST NOT 2; scope explosion | PR #908 retro |
| "Matches X" without a verbatim quote | FM-9 confident-incorrectness; 7 fix commits on PR #1887 | FAILURE-MODES.md section 9 |
| Leaving learnings only in the retro artifact | Never read by future sessions | retrospective-accuracy memory |
Treating INDEX.md or git log as complete history | 5 index rows vs 95 retro files; retro-cited SHAs do not resolve locally | Phase 4 |
git checkout --ours on session-log conflicts | Corrupted the main session log once | session 1187 incident |
| Em/en dashes, banned vocab, generated headers | One bot thread per dash, every PR | universal.md MUST NOT 5 and 6 |
Verification
Before ending any session that produced records:
Provenance and Maintenance
Verified 2026-07-03 against the working tree. Re-verify volatile facts before
relying on them:
| Fact | Source | Re-verify |
|---|
| Session log MUSTs, blocking phases | .agents/SESSION-PROTOCOL.md (Phases 0-5, 2.5) | grep -n "MUST NOT defer" .agents/SESSION-PROTOCOL.md |
| Branch naming pattern | scripts/validate_session_json.py (BRANCH_PATTERN) | grep -n "^BRANCH_PATTERN = re.compile" scripts/validate_session_json.py |
| Schema required keys, top level and nested session | .agents/schemas/session-log.schema.json | python3 -c "import json;s=json.load(open('.agents/schemas/session-log.schema.json'));print(s['required'], s['properties']['session']['required'])" |
| ADR collision history, next-number helper | scripts/validation/check_adr_uniqueness.py docstring | python3 scripts/validation/check_adr_uniqueness.py --print-next |
| ADR-073 lifecycle fields | .agents/architecture/ADR-073-adr-lifecycle-frontmatter.md:1-9 | head -10 .agents/architecture/ADR-073-adr-lifecycle-frontmatter.md |
| adr-review fires on ADR/protocol edits | AGENTS.md "ADR Review" | grep -n "adr-review" AGENTS.md |
| Auto-retro skeleton + marker + /retro fill | .claude/commands/retro.md:1-15 | grep -n "RETRO-STATE" .claude/commands/retro.md |
| Retro corpus size vs INDEX.md coverage | .agents/retrospective/ | python3 -c "import pathlib;d=pathlib.Path('.agents/retrospective');f={p.name for p in d.glob('*.md')}-{'INDEX.md'};t=(d/'INDEX.md').read_text();print(len(f),'retro files,',sum(n in t for n in f),'indexed')" |
| Memory naming + index-row hazard | .claude/skills/memory/SKILL.md "Serena Write Conventions" | grep -n "Serena Write Conventions" .claude/skills/memory/SKILL.md |
| Memory/skill separate-PR rule | .claude/rules/claude-agents.md MUST NOT item 2 | grep -n "same PR" .claude/rules/claude-agents.md |
| Handoff tiers, HANDOFF.md 5K cap |
Maintenance: when a validator, template path, or protocol phase changes, update
the matching row here in the same PR. This file is itself a document of record;
it obeys everything it prescribes.