agentafk
Guides

Record architecture decisions in SPINE.md

Keep project invariants, rejected patterns, and deliberate design choices in a reviewable repository file.

SPINE.md is an architecture manifest intended to live in Git alongside your code. Use it to keep future sessions aware of constraints that are easy to lose in conversation history, and review automated changes like any other repository edit.

Bootstrap and review

Generate an initial manifest

In your project's REPL:

/spine init

AFK gathers invariant, contract, and history comments, project AFK.md, Git revert history, a short CHANGELOG.md excerpt, and the location of an ADR directory if present. A classifier proposes entries from that material.

Inspect the result

/spine show

Read SPINE.md directly and correct any overgeneralizations. The classifier is an aid, not an authority. If authentication or classification fails, initialization can still produce an empty skeleton.

Include it in your normal review

Review the diff and commit the file with your project's usual workflow. Ask the agent to read it before implementation, or use /ground-state, whose reconnaissance includes a spine survey.

/spine init refuses to overwrite an existing file. /spine init --force regenerates it, so inspect or preserve any hand-written decisions first. Regeneration is useful after a major architecture change, not a requirement for every session.

Entry format

SectionPrefixMeaning
InvariantsINVContracts that must remain true
Explicitly Rejected PatternsREJApproaches deliberately ruled out
Taste Calls MadeTSTDesign choices where valid alternatives exist
## Invariants

- **INV-001** (2026-10-17, spine-init): Database writes must finish before success is rendered.

## Explicitly Rejected Patterns

- **REJ-001** (2026-10-17, spine-init): Do not keep a second mutable cache of account balances.

## Taste Calls Made

- **TST-001** (2026-10-17, spine-init): Prefer explicit parameters for extracted helpers.

IDs remain stable when descriptions change. Manual entries should use the same zero-padded INV-NNN, REJ-NNN, or TST-NNN shape, followed by date, session attribution, and a one-line description. Unrecognized text is preserved as trailer content when the document is serialized.

Automatic maintenance

The top-level SessionEnd hook examines the session checkout's tracked diff against HEAD, excluding SPINE.md itself. It skips empty or spine-only diffs, subagent sessions, and an unchanged diff fingerprint already handled for that checkout.

The classifier makes a single Haiku call using Anthropic credentials. It sends up to 20,000 characters of the diff plus the current manifest, so this is model processing with potential provider cost, not a purely local parser.

ClassificationAction
new-additionAdd a new entry
strengthensAnnotate the entry as reinforced and log the finding
weakensAnnotate the entry as partially weakened and log it for review
contradictsPreserve the existing entry and queue the conflict for human review

When automatic changes are made, AFK writes the manifest atomically and attempts to stage SPINE.md with Git. If no manifest exists yet, a classifiable addition can create it. Failures are handled on a best-effort basis and logged rather than breaking session teardown.

For linked worktrees, the classified diff comes from the session's own checkout, but the manifest is read and written in the repository's main common-root checkout. Concurrent sessions can overwrite one another's manifest updates. Review staged changes before committing, especially during parallel work.

Review queued findings

/spine pending

The queue is spine-pending.jsonl in the shared state directory. It can include reinforcements, weakened entries, unresolved IDs, contradictions, and hook errors, not just conflicts. It is not a separate queue per repository.

For a contradiction, inspect the relevant project and edit SPINE.md if the new design should replace the old constraint. Then dismiss the notification:

/spine dismiss 2

Use /spine dismiss-all only when you intend to clear the whole displayed queue. Dismissing a notification does not apply its proposed change. Contradictions also trigger a best-effort Telegram notification when Telegram is configured.

Disable automatic updates

Set AFK_DISABLE_SPINE_UPDATE=1 to skip the session-end classifier:

AFK_DISABLE_SPINE_UPDATE=1 afk chat "Review the current diff without changing files"

You can also store that variable in afk.env. It disables automatic updates, not the explicit /spine init command. Use manual edits if you want architecture documentation without a classifier call.

On this page