# How gsd-build Maintains State Across Sessions Using STATE.md

> Discover how gsd-build maintains state across sessions using STATE.md. Learn how this plain-text file ensures project continuity and acts as a single source of truth in your workflows.

- Repository: [GSD/get-shit-done](https://github.com/gsd-build/get-shit-done)
- Tags: internals
- Published: 2026-02-16

---

**gsd-build persists project continuity through a plain-text markdown file located at [`.planning/STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/.planning/STATE.md) that serves as a single source of truth, read at the start of every workflow and atomically updated after each meaningful change.**

The `gsd-build/get-shit-done` repository implements a novel approach to project state management by treating a markdown file as a living database. Unlike traditional databases or hidden binary files, gsd-build maintains state across sessions using [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md)—a human-readable file that tracks current position, performance metrics, and session continuity while remaining under version control.

## The STATE.md File Structure and Template

Located at [`.planning/STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/.planning/STATE.md), this file follows a strict template-driven structure defined in [`templates/state.md`](https://github.com/gsd-build/get-shit-done/blob/main/templates/state.md). The layout is intentionally constrained to approximately 100 lines, making it inexpensive to read and write while maintaining clarity.

The file contains five core sections:

- **Project Reference**: Links to [`PROJECT.md`](https://github.com/gsd-build/get-shit-done/blob/main/PROJECT.md) and [`ROADMAP.md`](https://github.com/gsd-build/get-shit-done/blob/main/ROADMAP.md)
- **Current Position**: Active phase, plan, and status indicators
- **Performance Metrics**: Counters for plans executed, todos completed, and blockers encountered
- **Accumulated Context**: Decisions made and blockers resolved during the session
- **Session Continuity**: Last session timestamp, completed work summary, and path to a "continue-here" markdown file

## Reading State at the Start of Every Workflow

gsd-build implements a **read-first rule** that guarantees every session begins with the latest project context. Every workflow file—including [`transition.md`](https://github.com/gsd-build/get-shit-done/blob/main/transition.md), [`execute-phase.md`](https://github.com/gsd-build/get-shit-done/blob/main/execute-phase.md), [`execute-plan.md`](https://github.com/gsd-build/get-shit-done/blob/main/execute-plan.md), and [`quick.md`](https://github.com/gsd-build/get-shit-done/blob/main/quick.md)—starts with a `<required_reading>` block that lists [`.planning/STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/.planning/STATE.md) as the first file to read.

For example, in [`workflows/transition.md`](https://github.com/gsd-build/get-shit-done/blob/main/workflows/transition.md), the initial step executes:

```bash
cat .planning/STATE.md 2>/dev/null
cat .planning/PROJECT.md 2>/dev/null

```

This pattern ensures that the current position, pending todos, and accumulated context are always loaded before any planning logic executes.

## Atomic State Updates via gsd-tools

When workflows complete meaningful work, they delegate state persistence to `bin/gsd-tools.cjs`. This CLI tool handles atomic updates to [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md) alongside other project artifacts, ensuring consistency across the planning database.

The tool exposes a `commit` subcommand that accepts a `--files` argument. For example, when completing a plan in [`workflows/execute-plan.md`](https://github.com/gsd-build/get-shit-done/blob/main/workflows/execute-plan.md), the system invokes:

```bash
node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit \
  "docs({phase}-{plan}): complete [plan-name] plan" \
  --files .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md \
           .planning/STATE.md .planning/ROADMAP.md

```

This command atomically writes:
- Phase completion checkboxes with timestamps
- Updated progress bars
- Current phase transitions
- Accumulated context including decisions and blockers

The `gsd-tools.cjs` script also provides a `state_exists` flag that sub-commands like `add-todo` check before attempting to read or modify state, preventing operations outside of an initialized project context.

## Session Continuity and State Recovery

The **Session Continuity** section within [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md) enables precise resumption of interrupted work. It records:
- The timestamp of the last session
- What was last completed
- A path to a "continue-here" markdown file containing context for the next session

When a user resumes a project, [`workflows/resume-project.md`](https://github.com/gsd-build/get-shit-done/blob/main/workflows/resume-project.md) reads this section to restore the exact point of interruption.

Additionally, gsd-build implements defensive state reconstruction. If [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md) is deleted or corrupted, [`resume-project.md`](https://github.com/gsd-build/get-shit-done/blob/main/resume-project.md) detects `state_exists === false` and reconstructs the file by parsing [`PROJECT.md`](https://github.com/gsd-build/get-shit-done/blob/main/PROJECT.md) and [`ROADMAP.md`](https://github.com/gsd-build/get-shit-done/blob/main/ROADMAP.md):

```bash
if (!state_exists && (roadmap_exists || project_exists)) {
  echo "STATE.md missing. Reconstructing from artifacts..."
  # Parse PROJECT.md & ROADMAP.md, write a fresh STATE.md

}

```

This guarantees that users can always resume work even after losing the state file.

## Practical Implementation Examples

### Initializing STATE.md

When creating a new project, `gsd:new-project` copies the template and initializes the file:

```bash
cp get-shit-done/templates/state.md .planning/STATE.md

# Later, gsd-tools fills in placeholders during the first commit

```

### Reading State at Workflow Start

Every workflow begins by reading the current position:

```bash

# From workflows/transition.md

cat .planning/STATE.md 2>/dev/null
cat .planning/PROJECT.md 2>/dev/null

```

### Updating State After Phase Completion

When transitioning between phases, the system delegates to `gsd-tools`:

```bash
TRANSITION=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs phase complete "${current_phase}")

# gsd-tools writes:

# - Phase checkbox → [x] with date

# - Progress bar line

# - Current Phase → Next phase

# - Status → Ready to plan

# - Accumulated Context (decisions, blockers)

```

### Recovering from Missing State

The resume workflow handles missing state files gracefully:

```bash

# From workflows/resume-project.md

if (!state_exists && (roadmap_exists || project_exists)) {
  echo "STATE.md missing. Reconstructing from artifacts..."
  # Parse PROJECT.md & ROADMAP.md, write a fresh STATE.md

}

```

## Summary

- **gsd-build** treats [`.planning/STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/.planning/STATE.md) as a plain-text database that maintains project continuity across sessions.
- The **read-first rule** ensures every workflow starts by loading the current position, metrics, and context from [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md).
- **Atomic updates** occur via `gsd-tools.cjs`, which writes to [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md) alongside other artifacts like [`ROADMAP.md`](https://github.com/gsd-build/get-shit-done/blob/main/ROADMAP.md) to maintain consistency.
- **Session Continuity** tracking allows precise resumption of interrupted work, while defensive reconstruction logic in [`resume-project.md`](https://github.com/gsd-build/get-shit-done/blob/main/resume-project.md) can rebuild the state file from [`PROJECT.md`](https://github.com/gsd-build/get-shit-done/blob/main/PROJECT.md) and [`ROADMAP.md`](https://github.com/gsd-build/get-shit-done/blob/main/ROADMAP.md) if it goes missing.

## Frequently Asked Questions

### What happens if STATE.md is deleted or corrupted?

If [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md) is missing, the [`resume-project.md`](https://github.com/gsd-build/get-shit-done/blob/main/resume-project.md) workflow detects `state_exists === false` and automatically reconstructs the file by parsing [`PROJECT.md`](https://github.com/gsd-build/get-shit-done/blob/main/PROJECT.md) and [`ROADMAP.md`](https://github.com/gsd-build/get-shit-done/blob/main/ROADMAP.md). This ensures that even if the state file is accidentally deleted or corrupted, the project context can be restored without data loss.

### How does gsd-build ensure atomic updates to STATE.md?

State updates are delegated to `bin/gsd-tools.cjs`, which provides a `commit` subcommand accepting a `--files` argument. When completing work, the tool writes to [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md) simultaneously with other modified files like [`ROADMAP.md`](https://github.com/gsd-build/get-shit-done/blob/main/ROADMAP.md) and phase summaries. This atomic commit pattern ensures that all planning artifacts remain synchronized and prevents partial state updates that could corrupt the project context.

### What information is stored in the Session Continuity section?

The **Session Continuity** section tracks the timestamp of the last session, a summary of what was last completed, and the path to a "continue-here" markdown file. This structure enables [`resume-project.md`](https://github.com/gsd-build/get-shit-done/blob/main/resume-project.md) to restore the exact point of interruption when a user returns to the project, including any pending context, decisions, or blockers from the previous session that need immediate attention.

### Can multiple users work on the same project simultaneously using STATE.md?

While [`STATE.md`](https://github.com/gsd-build/get-shit-done/blob/main/STATE.md) is designed for single-user sessions with Claude Code, its plain-text markdown format and atomic commit mechanism via `gsd-tools.cjs` make it compatible with version control systems like Git. Multiple users can theoretically share a project repository, though simultaneous editing would require standard Git merge conflict resolution, as the system does not implement real-time collaborative locking mechanisms.