Skip to content

Changelog

The team's shared record of executed changes. Every contributor, human or AI agent, logs the changes they make so others can query what happened, why, and how to verify it. The decision log records intent (rulings by the owner); this log records execution (what was actually done).

Convention

  • One file per entry, under changelog/YYYY-MM/, named <UTC stamp>-<slug>.md (e.g. 20260901T1726Z-prd-operational-requirements.md). One file per entry means parallel contributors never conflict.
  • The entry travels with the change. Code changes: same PR. Doc, spec, and design changes: same commit. Infra changes with no commit of their own: commit the entry by itself, citing the infra resource ids.
  • Refs cite what exists at write time: PR URL, decision id, doc path and section, infra resource id, external run id. The commit hash of a code change comes free because the entry is in that commit; git log --follow on the entry file recovers it.

Filing bar

Log a change iff it alters what another contributor would build, decide, or verify: merged code, a ratified spec or design change, an executed infra change. Do not log progress notes, failed attempts, formatting, or reasoning that produced no change (that belongs in a research doc or nowhere).

Categories

Category Covers
code Implementation. Subtype in kind: feature, bugfix, refactor, test, chore
design How a module is planned to be implemented: architecture, interfaces, module plans
infra Hosting, deploy, CI, database operations, external services
spec PRD-level changes: goals, non-goals, requirements, milestones
docs Documentation changes that are not spec or design: research docs, conventions, README

Entry template

---
id: <UTC stamp>-<slug>            # matches the filename
date: YYYY-MM-DD
actor: agus | claude (session <first 8 of session id>)
category: code | design | infra | spec | docs
kind: feature | bugfix | refactor | test | chore   # code only, omit otherwise
module: ingestion | extraction | matching | store | bootstrap | cross   # omit if none
refs:
  - <PR url | commit | docs/decisions.md#dN | infra id | doc path>
---

**What.** The change itself, one to three lines.

**Why.** The reasoning. Link the decision, finding, or failure that drove it.

**Verify.** How a reviewer checks it: a command, a link, a query.

Querying

rg -l "^category: spec" changelog/          # all spec changes
rg -l "module: extraction" changelog/2026-09/
rg "^\*\*Why\.\*\*" changelog/ -A 2         # reasoning across all entries

Storage

Entries stay in git. They are 1-2KB each; even 20 entries a day is roughly 15MB a year, and the same-commit rule is what makes review free and linkage intrinsic. Monthly directories keep listings small. If querying ever outgrows rg, the frontmatter makes a migration to a database mechanical; do not build one before that pain exists.