theway
Concepts

Changes

Change IDs, series, the change folder and the archive.

A change is one unit of work: a folder with its spec and its tasks.

Change IDs

A change ID is lowercase kebab-case and starts with one of five verbs: add-, update-, refactor-, remove- or fix-. For example add-user-authentication, update-payment-api or fix-login-crash.

A fix- change fixes a bug. /theway:engineering reproduces the bug before it writes anything and writes its spec from the fix-spec-template prompt, which records the symptom, the reproduction, the root cause and the regression test. See /theway:engineering. A small bug with a known cause can go through /theway:engineering --light instead: a short spec with the reproduction, and a regression test that fails before the fix and passes after it.

theway validate-id checks the format, and /theway:engineering runs it on a standalone ID before it writes a change folder. A series' member IDs come from theway next-id, which checks the series ID. A standalone ID must not end in a one- or two-digit number, since -NN is kept for series members.

Series

A series is a set of dependent changes that share a <series-id>. Each member is <series-id>-NN, with a zero-padded two-digit ordinal starting at 01, assigned in dependency order:

add-user-auth-01
add-user-auth-02
add-user-auth-03
  • theway next-id names the members of a new or continued series: it validates the series ID and prints the next free IDs, counting active and archived members. Existing folders are never renamed or renumbered.
  • With --series, validate-id rejects topic suffixes (add-user-auth-login), letter suffixes (-a, -b), unpadded numbers (-1), -00 and double ordinals.
  • A member is known by its folder name; the series' total is its highest ordinal. The scaffold writes every member of a series in one run.

/theway:workflow takes the members in order. After each change, it asks you before merging the PR the run opened, and starts the next change once it is merged; when a run opened no PR, the series stops after that change.

Project key

Every project has a key, and its files live in <home>/projects/<key>/. The CLI derives the key from the current directory, the way Claude Code names its ~/.claude/projects/ folders: the project root's absolute path with every character outside [A-Za-z0-9] replaced by -. /home/you/code/my-api gives -home-you-code-my-api.

  • In a git repository: the root is the main repository's root, from the repository itself, any of its subfolders and every linked worktree, so they all share one key. A bare repository or one with a separate git dir uses its worktree root; a linked worktree of a --separate-git-dir repository and a submodule get their own key.
  • Outside git: the root is the current directory.
  • Physical path: symlinks in the root are resolved first, so a repository reached through a symlink has the key of its real path.
  • Moving or re-cloning a repository changes its path, so it starts a new, empty project. Two clones of the same repository are two projects.
  • --project <key> replaces the derived key on every subcommand that uses a project: letters, digits and -, at most 200 characters. A derived key longer than 200 characters is an error that asks for --project.

theway project prints the key and the folder; the commands run it and never compute the key themselves.

Folder layout

<key> is the project key.

~/.theway/projects/<key>/changes/
├── add-redis-cache/
│   ├── spec.md      # required: why, what, risks and Success Criteria
│   ├── change.yaml  # required: the description and the ordered tasks
│   ├── design.md    # optional: contracts, data models, diagrams
│   └── notes.md     # optional: what was learned while implementing
└── archive/
    └── 2025-10-15-update-auth-middleware/

change.yaml holds the change's one-line description and its tasks, in order; a task's number is its position, counted from 1:

version: theway.change/v1beta
description: Limit requests per API key with a token bucket
tasks:
  - text: Add a token bucket per API key, kept in memory
    done: true
  - text: Answer 429 with a `Retry-After` header when the bucket is empty
  - text: Read the limit and the burst from the settings

The CLI validates it on every read: theway change checks a hand-edited file, and theway task done is how a task becomes done. theway list and theway archive report a missing or invalid change.yaml as invalid. spec.md, design.md and notes.md are prose: no command reads a line of them.

Archive format

An archived change keeps its whole folder and is named YYYY-MM-DD-<change-id>, with the local date of the archive:

~/.theway/projects/<key>/changes/archive/
├── 2025-10-10-add-logging-framework/
└── 2025-10-15-update-auth-middleware/

On this page