Skip to content

Latest commit

 

History

History
368 lines (243 loc) · 20 KB

File metadata and controls

368 lines (243 loc) · 20 KB
name devlog
description Maintain a structured development changelog (DEVLOG.md) that captures architectural decisions, progress milestones, key conversation takeaways, and strategic/business decisions for any project. Use this skill whenever the user says "log this", "devlog", "update the devlog", "push devlog", or references logging a decision, milestone, or takeaway. Also trigger proactively at the end of conversations that involve significant architectural choices, design changes, strategic pivots, or completed milestones — suggest a devlog entry even if the user doesn't ask. Trigger whenever the user mentions changelog, development log, decision log, or progress tracking for their project. Works across any project — not tied to a specific repo or product.

Development Changelog (Devlog) Skill

This skill maintains a living development log (DEVLOG.md) in the root of a project's Git repository. It captures the important decisions, progress, and insights from development conversations so that future sessions have full context on what was done and why.

This skill is project-agnostic — it works with any repository. On first use in a session, it identifies the active project and adapts accordingly.

Why This Matters

Development conversations contain critical context — the reasoning behind decisions, alternatives that were considered and rejected, and strategic pivots that shaped the project. Without a structured log, this context evaporates between sessions. The devlog serves as institutional memory for the project, making every future conversation more informed.

Project Context (First Use Per Session)

The first time this skill triggers in a session, establish the project context by checking for clues in this order:

  1. Memory/conversation context — Does Claude already know what project the user is working on? If so, confirm: "I'll log this to the devlog for [Project Name] — correct?"
  2. Project knowledge — Are there project files or documents that identify the project name and repo?
  3. Ask the user — If neither source provides clarity, ask: "Which project should I log this to? I'll need the project name and Git repo URL."

Capture and remember for the session:

  • Project name — Used in the DEVLOG.md header and commit messages (e.g., "The Chronicle", "My Portfolio Site")
  • Git repo URL — Where to push (e.g., https://github.com/user/repo.git or https://gitlab.com/user/repo.git)
  • Authentication — If git is configured with a credential helper (e.g., macOS Keychain), no token is needed — git handles it transparently. Only ask for a Personal Access Token if a push fails with an auth error.
  • Default branch — Usually main, but confirm if unsure

Lint Check

When establishing project context for the first time in a session, verify that the project has a linter configured. Check for stack-appropriate lint configuration files:

  • Python: ruff.toml, pyproject.toml with [tool.ruff], .flake8
  • JavaScript/TypeScript: .eslintrc*, eslint.config.*, biome.json, or a lint script in package.json
  • Swift/iOS: .swiftlint.yml
  • Go: .golangci.yml
  • Rust: clippy configuration in Cargo.toml
  • General: .pre-commit-config.yaml

If no linter is configured, flag it to the user before proceeding. Recommend: Ruff for Python, ESLint or Biome for JS/TS, SwiftLint for Swift, golangci-lint for Go, clippy for Rust. Frame it as a prerequisite, not an afterthought.

Entry Format

Each entry follows this structure:

## [YYYY-MM-DD] Brief descriptive title
<!-- If superseded, a SUPERSEDED marker goes here (see Entry Deprecation) -->

**Category:** `feature` | `bugfix` | `refactor` | `infrastructure` | `security` | `milestone` | `strategy`
**Tags:** `relevant`, `topic`, `tags`
**Risk Level:** `low` | `med` | `high`
**Breaking Change:** `yes` | `no`

### Summary
A 1-2 sentence overview of what happened or was decided.

### Detail
Full context including:
- What was decided or accomplished
- Why this approach was chosen
- Dependencies or implications for future work
- Any open questions or follow-ups

### Decisions Made
Explicit trade-off decisions recorded here — what options were evaluated, what was chosen, and why alternatives were rejected.

### Related
- Links to related entries, documents, or resources when applicable

Categories Explained

Choose the category that best fits each entry:

  • feature — New capability or user-facing functionality added to the project.

  • bugfix — A defect was identified and resolved.

  • refactor — Internal restructuring with no behavior change (code quality, naming, structure). Use this for what was previously called architecture.

  • infrastructure — Build system, CI/CD, deployment, tooling, or dependency changes.

  • security — Security hardening, vulnerability fixes, auth changes, secrets management, access control.

  • milestone — Completed phase, release, or significant deliverable. The "what we shipped" entries.

  • strategy — Business decisions, market positioning, pricing changes, go-to-market pivots, competitive analysis conclusions. The "why we're doing it this way" entries. Use for purely non-technical context.

Fields Explained

Risk Level

Describes the blast radius and reversibility of the change:

  • low — Isolated change, easy to revert, no shared state affected
  • med — Touches shared code, multiple files, or has integration dependencies
  • high — Affects shared infrastructure, auth, data models, or production systems

Breaking Change

Whether this update changes a public contract, API, CLI behavior, or file format:

  • yes — Existing consumers must update to remain compatible
  • no — Backwards compatible, no consumer changes required

Decisions Made

A dedicated section for recording explicit trade-off decisions: what options were evaluated, what was chosen, and why alternatives were rejected. Acts as a lightweight ADR (Architecture Decision Record) inline with the log entry. Populate this whenever an alternative approach was considered — even briefly — to prevent re-litigating settled decisions in future sessions.

Entry Deprecation

As a project evolves, earlier devlog entries may contain decisions that were later reversed, superseded, or implemented differently. Without an explicit signal, Claude (and humans) may act on stale decisions buried deep in a growing DEVLOG.md. The deprecation mechanism solves this by marking outdated entries in-place.

Supersession Marker

When an entry's decisions are no longer current, add a blockquote marker immediately after the entry heading, before the **Category:** line:

## [2026-03-22] Original decision title
> **SUPERSEDED [2026-03-26]:** Replaced by [2026-03-26] d20Mob ruleset adopted. Reason: custom ruleset replaces SRD 5e as mechanical foundation.

**Category:** `strategy`
...

Marker Rules

  • Format: > **SUPERSEDED [YYYY-MM-DD]:** Replaced by [date] replacement-entry-title. Reason: one-phrase explanation.
  • Placement: Immediately after the ## [date] title heading, before **Category:**.
  • One marker per entry. If an entry is superseded multiple times, update the existing marker to point to the latest replacement.
  • Partial supersession: When only some decisions in an entry are stale, use: > **PARTIALLY SUPERSEDED [YYYY-MM-DD]:** [which decisions are stale and why]. [which decisions remain current].
  • Preserve the entry body. The marker annotates; it does not rewrite history. The full original entry remains below the marker for historical reference.
  • User approval required. Never add a SUPERSEDED marker without showing it to the user first. Supersession is a judgment call, not an automation.

When Deprecation Happens

Deprecation review is part of the entry-creation workflow (see Step 2 below). Every time a new entry is written, Claude scans existing entries for conflicts and proposes SUPERSEDED markers alongside the new entry. This is not a separate manual step.

When to Create Entries

Proactive Suggestions (Claude-initiated)

At natural pause points or the end of substantive conversations, review what was discussed and suggest devlog entries for any of the following:

  • A technical architecture decision was made or changed
  • A meaningful piece of work was completed
  • A strategic or business direction was established or shifted
  • An important insight emerged that should persist across sessions
  • A design trade-off was evaluated and a direction was chosen

Frame the suggestion naturally: "This feels like something worth capturing in the devlog — we decided X because of Y. Want me to log it?"

Do NOT suggest entries for:

  • Routine Q&A or simple lookups
  • Work that's still in-progress with no decision point
  • Minor clarifications that don't change direction

Ad-hoc Entries (User-initiated)

The user may say things like:

  • "Log this"
  • "Add this to the devlog"
  • "This should go in the changelog"
  • "Devlog: [description]"

When this happens, capture what the user is referring to — which may be the immediately preceding discussion, a specific decision, or something they describe explicitly.

Workflow: Creating and Pushing an Entry

Step 1: Draft the Entry

Write the entry following the format above. Include rich detail — the goal is that someone reading this months from now (including a future Claude session) can fully understand what happened and why.

Step 2: Review for Superseded Entries

After drafting the new entry, scan the existing DEVLOG.md for decisions that the new entry conflicts with or replaces. This review is lightweight:

  1. Scan entry headings (## [date] title), Summary sections, and Decisions Made sections only. Skip Detail bodies unless a heading or summary suggests a conflict.
  2. For each conflict found, draft a SUPERSEDED or PARTIALLY SUPERSEDED marker (see Entry Deprecation above).
  3. If no conflicts are found, proceed to Step 3 with no deprecations.

This scan is proportional to the number of entries, not the total line count. For a 15-entry DEVLOG, scanning headings + summaries + decisions is approximately 30-40 lines of reading.

Step 3: Show the User

Present the drafted entry in the conversation. If Step 2 identified superseded entries, also present the proposed SUPERSEDED markers:

"New entry ready. I also noticed that [2026-03-22] Original decision is superseded by this new entry — I'd like to add a SUPERSEDED marker to it. Here's the new entry and the proposed deprecation:"

Ask for confirmation or edits before committing. Never push without the user seeing the entry and any proposed deprecations first.

Step 4: Update DEVLOG.md

IMPORTANT: DEVLOG.md always lives inside the project repo root — never in a parent directory.

Determine the correct path:

  • Local Claude Code session (most common): The primary working directory IS the repo root. Use {cwd}/DEVLOG.md directly — e.g., if cwd is /Users/alice/projects/my-app, write to /Users/alice/projects/my-app/DEVLOG.md.
  • Remote/cloned session: Use the cloned repo path (e.g., /home/claude/[repo-name]/DEVLOG.md).

Read the existing DEVLOG.md from that path (or create it if it doesn't exist). Insert the new entry at the top of the file, below the header. Entries are reverse-chronological (newest first). If the user approved any SUPERSEDED markers in Step 3, insert those markers into the affected entries as well.

If creating DEVLOG.md for the first time, use this header:

# [Project Name] — Development Log

A living record of architectural decisions, milestones, key insights, and strategic direction.
Auto-maintained via [claude-devlog-skill](https://github.com/code-katz/claude-devlog-skill). Entries are reverse-chronological.

---

Replace [Project Name] with the actual project name established during session setup (e.g., "The Chronicle", "My API Service").

Step 5: Archive if Needed

After updating DEVLOG.md, check whether archiving is warranted. Archiving moves superseded entries to a separate file to keep the active DEVLOG focused and within a manageable context window. See the Archiving section below for trigger conditions, file format, and rules.

Step 6: Commit and Push

After the user approves:

cd /path/to/repo
git add DEVLOG.md
# If archiving occurred, also add DEVLOG-ARCHIVE.md
git add DEVLOG-ARCHIVE.md 2>/dev/null
git commit -m "devlog: [brief title from entry]"
git push origin main

Use a commit message prefixed with devlog: followed by a short version of the entry title. If archiving occurred in Step 5, use: devlog: [brief title] + archive N superseded entries.

Error Handling

  • Git not configured: Prompt the user to provide their repo URL and set up authentication. Walk them through creating a Personal Access Token if needed.
  • Push fails: Show the error, suggest common fixes (auth issues, branch protection, network). Offer to save the entry locally so it's not lost.
  • DEVLOG.md has merge conflicts: Show the conflict, help resolve it, then retry.
  • No repo cloned locally: Clone the repo first, then proceed.

Archiving

As a project matures, superseded entries accumulate in DEVLOG.md. Archiving moves them to a separate file so the active devlog stays focused on current decisions and fits comfortably within Claude's context window.

When to Archive

Archiving triggers during Step 5 of the workflow when both conditions are true:

  1. DEVLOG.md exceeds approximately 50 entries or 1,500 lines (whichever comes first)
  2. There are entries with SUPERSEDED markers available to archive

If either condition is not met, skip archiving. Small devlogs and devlogs with no superseded entries are never archived.

What Gets Archived

Only entries with a SUPERSEDED or PARTIALLY SUPERSEDED marker. Current entries are never archived regardless of age. A 3-month-old architectural decision that is still in effect is more valuable in the active devlog than a 1-week-old decision that was reversed.

For PARTIALLY SUPERSEDED entries: do not archive. These entries still contain current decisions alongside stale ones. They remain in DEVLOG.md with their partial marker intact.

Archive File Format

The archive file is DEVLOG-ARCHIVE.md in the same repo root as DEVLOG.md.

# [Project Name] — Development Log Archive

Superseded entries moved from DEVLOG.md. Each entry's SUPERSEDED marker points to its replacement in the active devlog.
Auto-maintained via [claude-devlog-skill](https://github.com/code-katz/claude-devlog-skill). Entries are reverse-chronological.

---

## [2026-03-22] Original decision title
> **SUPERSEDED [2026-03-26]:** Replaced by [2026-03-26] d20Mob ruleset adopted. Reason: custom ruleset replaces SRD 5e.

**Category:** `strategy`
...full original entry preserved...

---

No Tombstones

When an entry is moved to the archive, it is removed entirely from DEVLOG.md. No stub or placeholder is left behind. The superseding entry already exists in DEVLOG.md and provides the current context. If someone needs the historical record, DEVLOG-ARCHIVE.md is in the same directory.

Archive Commit

If archiving occurs, stage both files and use the commit message format: devlog: archive N superseded entries.

Git Setup (First-Time Per Session)

Local Claude Code Session (Most Common)

If Claude Code's primary working directory is already inside the project repo, no setup is needed — the repo is already available locally. Verify with:

git -C /path/to/cwd rev-parse --show-toplevel

The output is the repo root. DEVLOG.md belongs there.

Remote/Sandboxed Session

If the repo isn't available locally, check whether it's been cloned and git is configured:

# Check if repo exists locally (use project-specific directory name)
ls /home/claude/[repo-name] 2>/dev/null

# If not, clone it (user needs to provide URL + token)
# GitHub:  https://[token]@github.com/[user]/[repo].git
# GitLab:  https://oauth2:[token]@gitlab.com/[user]/[repo].git
git clone https://[token]@[host]/[user]/[repo].git /home/claude/[repo-name]

# Configure git identity
git config --global user.name "[Project Name] Devlog"
git config --global user.email "devlog@[repo-name].dev"

Replace [repo-name], [user], [token], and [Project Name] with the actual values from the project context established during session setup.

Only ask the user for a personal access token if a push fails with an authentication error. If git is using a credential helper (e.g., macOS Keychain), auth is handled transparently and no token is needed.

Multi-Project Support

If the user works on multiple projects, keep each repo cloned in its own directory under /home/claude/. When the user switches context (mentions a different project or repo), confirm the switch: "Switching devlog context to [Other Project] — correct?"

The devlog for each project lives in its own repo's DEVLOG.md and is managed independently.

Reading the Devlog

At session start (proactive)

When a session begins on a known project that has a DEVLOG.md, read it before doing any work — do not wait to be asked. The devlog contains architectural context, past decisions, and rejected alternatives that are invisible from the code alone. Reading it first prevents re-litigating settled decisions and surfaces the "why" behind things that might otherwise look arbitrary.

To locate the devlog:

  1. Check if DEVLOG.md exists in the repo root ({cwd}/DEVLOG.md)
  2. If the project is listed in MEMORY.md with a devlog path, use that path
  3. If no DEVLOG.md exists yet, proceed normally — nothing to read

Handling superseded entries: When encountering a SUPERSEDED marker while reading, note the supersession and skip the entry body. Do not act on decisions from superseded entries. Follow the pointer to the replacement entry instead. Superseded entries exist in the file only until the next archiving pass moves them to DEVLOG-ARCHIVE.md.

Do NOT read DEVLOG-ARCHIVE.md at session start. It contains only historical entries that have been explicitly replaced. Loading it wastes context budget on stale decisions.

You do not need to summarize the devlog to the user unless they ask. Just read it silently and let it inform your work.

On demand (reactive)

When the user asks about past decisions, progress, or project history:

  1. Read DEVLOG.md from the repo
  2. Search entries by category, tags, or keywords
  3. Summarize relevant entries in the conversation

This makes the devlog a two-way resource — not just for writing, but for recalling context.

Historical research

When the user asks about the evolution of a decision ("why did we change X?", "what was the original approach?", "how did we get here?"):

  1. Read DEVLOG-ARCHIVE.md from the repo root (if it exists)
  2. Find the superseded entry and its replacement in the active DEVLOG.md
  3. Present the evolution: original decision -> supersession reason -> current decision

The archive is a research tool for understanding how the project arrived at its current state. It is not loaded proactively.

Multiple Entries Per Session

If a conversation covers several loggable topics, batch them:

  • Draft all entries at once
  • Present them together for review
  • Commit them in a single push with a summary commit message like devlog: session updates - [topic1], [topic2]

Style Guidelines

  • Write in past tense for decisions and completed work ("Chose SQLAlchemy over raw SQL")
  • Write in present tense for ongoing context ("The data model supports 14 tables")
  • Be specific — include version numbers, file names, and concrete details
  • Include the "why" for every "what" — rationale is the most valuable part
  • Reference related devlog entries by date when they exist
  • Keep tags lowercase, hyphenated, and specific enough to be useful for searching
  • Set Risk Level: high any time the change touches authentication, secrets, data models, CI/CD pipelines, or production infrastructure
  • Populate Decisions Made whenever an alternative approach was considered and rejected — even briefly. The goal is to prevent re-litigating settled decisions in future sessions.