SuperAPI AI Directory

ctx-progress

General & other

View repository

Updated 10-16 01:20

About this skill

ctx-progress — the LIVING work-truth doc

The lifetime model and shared conventions live in ../ctx; this is the how-to for the LIVING progress/ folder.

Execution Procedure

progress/ is the supervisor's clipboard, not a second spec: it holds the WORK truth (where we are / next / read-first) and POINTS at spec/ + decisions/, never restating a product fact. The durable "what/why" lives in spec/decisions; progress tracks doing it against them. The ordered T### task list lives here (not in the spec — ctx-spec §14 was retired); each T### points back to the REQ-### in spec/ that it implements.

track_work_truth(project) → one LIVING current-position a fresh session resumes from

# EP1 — Locate / create the progress root
root = ctx/progress/                      # fixed, exactly ONE (see Hard constraints)
doc  = flat progress.md UNTIL ~150 lines, then graduate to a tree
EP2 — Update work state (the common case)

on any decided work-state change (active leaf moved · next settled · user lock · subagent report): write_into_progress(change) # sink SAME-TURN; never leave decided state only in chat reference(spec, decisions, by="pointer") # never restate a product fact # the ordered T### task list + each task's status live HERE (not in spec); every T### → a spec REQ-### # row format: T### <task title> — status: done | active | blocked → REQ-### (one line per task; # this status vocabulary is per-TASK, distinct from the frontmatter status field above, which # describes the whole progress doc, not an individual task)

EP3 — Open a subtree (a node passes ~150 lines)

open_child(); parent = one-line summary + link; never duplicate child content into parent

EP4 — Pre-reset checkpoint (before /compact, a context reset, or dispatching an independent session)

sink_decided_state() # anything decided this session → progress/ (+ spec/decisions if product truth) verify(active_leaf_current ∧ next_step_written ∧ nothing_decided_only_in_chat) # progress IS the handoff; no separate prompt artifact

EP5 — Incoming session (resume)

read(CLAUDE.md → progress root → active node → its linked spec/decisions); summarize; WAIT for confirmation before work

EP6 — Audit for drift

assert one_active_leaf_per_live_subtree ∧ frontmatter_valid ∧ pointers_not_restated ∧ thresholds_respected → fix before handoff

Before committing — apply the cross-cutting constraints

apply("../ctx/references/consistency.md") # single-source · same-change · verify-canonical · gate + conventions

DoD per work chunk: commit → update progress → archive-when-long (see Hard constraints)

## Where it lives (no location matrix)

In this collection the location is **fixed**: the knowledge root's `ctx/progress/`. For a shippable artifact whose docs must not ship, it is `<name>-ctx/progress/` (that external `<name>-ctx/` folder IS the knowledge root — no nested `ctx/`). There is no per-archetype location matrix to consult — ctx already fixed `ctx/` as the root, so `progress/` is unambiguous.

`progress/` is a LIVING doc: current focus + next + "read first". It is the WORK truth; `spec/` + `decisions/` are the PRODUCT truth. Two living docs, different domains, no SSOT clash — **guarded by the pointer rule below**.

## Single file, or a tree (JBGE)

Start with **one file** `ctx/progress/progress.md`. Graduate to a **tree** only when the flat file would exceed **~150 lines** — never pre-open a tree. (JBGE: a single file is enough until it demonstrably is not; a premature tree is empty ceremony.)

**There are exactly TWO size thresholds** (this is their single canonical statement — companions reference these numbers, they do not restate divergent ones):

| Threshold | Trigger | Action |
|---|---|---|
| **~150 lines** | a flat `progress.md` grows past it | **graduate flat → tree** = open the first child. ("graduate to a tree" and "open a child" are the SAME event, not two thresholds — this is the point that removes the three-numbers illusion.) |
| **~200 lines** | any single node (flat file OR a tree node) grows past it | **archive** the completed portion per the LIVING archive mechanic (see DoD below). |

- **Flat**: `ctx/progress/progress.md` (frontmatter + current position + next + pointers).
- **Tree**: `ctx/progress/README.md` (entry) + `NN-<slug>.md` children (zero-padded, creation-ordered per consistency.md numbering). A child that itself grows gets a sibling `NN-<slug>/` dir with its own `README.md`. Recommended nesting ceiling: **2 levels** below the root; a 3rd level usually means the work should be factored out as its own project.

**Frontmatter on every progress doc** (this is the canonical field set):

```yaml
---
title: <human-readable, one line, no markdown>
created: YYYY-MM-DD        # absolute ISO date, never relative ("yesterday")
updated: YYYY-MM-DD        # bump on every substantive edit
status: draft | active | stale | archived
---

Optional when useful: parent: ../README.md, owner, supersedes. Status is one-way in practice: draft → active → stale → archived.

Exactly one active leaf — per live session

[LOAD-BEARING — hard constraint, see § Hard constraints below] A well-formed progress tree (or flat file) has exactly one active leaf per live session — the current position that session resumes from. In the ordinary single-session case that is one active leaf for the whole tree.

When work legitimately runs in parallel across sessions — each session on its own child subtree (opened per the "subtask complex enough to spawn its own session" rule below) — the tree holds one active leaf per live-session subtree, so several at once is normal, not a propagation failure. The invariant is within a subtree: each live-session subtree has exactly one active leaf, and the root surfaces them side by side through the existing parent-pointer mechanism. Two active leaves inside the same subtree still mean propagation failed — repair before handing off. This is what lets any given session find its "where we are" in one hop.

Parent → child by POINTER, never copy

The parent carries a one-line summary + a link into the child subtree; the detail lives only in the child. Never duplicate child content into the parent — copy-style references always drift; pointer-style cannot. The parent surfaces the child's status (that's the one piece of child-derived state an index must carry), not its body.

## 02 · Stripe integration — status: active

See [`./02-stripe-integration/`](./02-stripe-integration/README.md) for the subtree.
Current position: webhook signature validation (2/4 e2e tests passing). Next: Stripe Tax for EU.

Pointer, don't restate (the SSOT guard)

[LOAD-BEARING — hard constraint, see § Hard constraints below] Progress references spec and decisions by pointer; it never restates a product fact. "Where we are on the auth flow" belongs in progress; "the auth flow requires PKCE" belongs in spec/, and progress links to it. Restating the spec fact in progress creates a second copy that goes stale — the exact rot ctx exists to prevent.

The same discipline extends to ctx/services.md when ctx-serve is in use: a topology change (new service, moved port) gets a one-line pointer from the active leaf, never a restated topology detail (see ctx-serve § serve ⟂ progress).

Session continuity — progress IS the handoff

There is no separate handoff artifact. A well-maintained progress/ already carries everything a fresh session needs, so continuity is just two moments — a pre-reset checkpoint out, and a guided read in.

Pre-reset checkpoint (outgoing) — before a /compact, a context reset, or dispatching an independent session, run one gate: sink any state decided this session into progress/ (and settled product truth into spec//decisions/), then verify progress reflects the current position — active leaf current, next step written, nothing decided sitting only in chat. That is all "handoff" is now: because state hits disk continuously (sink same-turn below), progress is always current, so a reset is safe at any moment. Do not generate a standalone handoff-prompt file — if a fact isn't in progress, fix progress, don't paper over it in a prompt. (The compaction mechanism itself — how a tool summarizes history — is the tool's concern, not this skill's; ctx owns only that the state is externalized. Optional Claude-Code convenience: a /ctx-compact command can trigger this checkpoint before you run /compact — the checkpoint is tool-agnostic, the command is just a shortcut.)

Incoming (resume) — read in this order, then stop and confirm:

1. CLAUDE.md (+ CLAUDE.local.md if present)   → project instructions
2. ctx/progress/README.md (or progress.md)    → the current active node
3. the active-node file                        → the concrete next step
4. files the active node links to (cap ~3)     → upstream spec/decision context
→ summarize goal / current position / next step to the user, WAIT for confirmation. Do NOT start work first.

Do not read the whole tree — it preserves history verbatim on purpose; reading all of it burns the context the session needs to work.

Sink same-turn (decided state hits disk before the turn ends)

Work-state that got decided this turn — the active leaf moved, a next step settled, a user verbal lock ("OK do X" / "lock X"), a subagent's status report — must be written into progress/ in the same assistant turn it happens. Never end a turn, dispatch a subagent, or approach compaction with decided state sitting only in chat. The failure mode this prevents: chat remembers, files don't; compaction comes, the decision is gone. A quick end-of-turn self-check — "did the active position, a next step, or a user lock change this turn? then the file changed too" — is cheaper than reconstructing lost state next session.

Two gates, two granularities — the tracking gate must not govern the SOT. Sink-same-turn is the tracking gate: it keeps progress/ current-to-the-turn, at the leanness the rest of this skill already requires — pointer, don't restate; the minimal current position + next + read-first shape (see the worked example); reasoning, options, and detail live in reports/ and git, never in progress. It does NOT govern the SOT gate (spec/ + decisions/). A durable product truth or an ADR crosses that gate only once the conclusion has been surfaced in a report and survived the owner's review — the ctx-report keep/drop distillation, where the owner's silence on a reviewed point is assent, but an un-surfaced design the agent synthesized this turn is not (the owner never saw it). So: sink tracking every turn; sink to the SOT only what has passed review.

Definition of Done (per unit of work)

  1. Commit the code/doc change.
  2. Update progress/ in the same commit: bump updated, move the active leaf, ripple the parent's status/pointer line.
  3. Archive when long — when a progress file/subtree is complete or a node reaches the ~200-line archive threshold (distinct from the ~150-line graduate-flat→tree threshold), retire it per the LIVING lifetime-class mechanic in ../ctx/references/consistency.md § Archive mechanics: localized staleness → edit in place (git keeps the old text); a foundational shift → move the whole old doc/subtree to progress/archive/ under the canonical archive filename and write one clean new doc reusing the canonical name. Do not restate that mechanic or the filename format here — both are defined once there.

Worked example — a minimal progress.md

---
title: Acme Auth — Progress
created: 2026-06-20
updated: 2026-07-03
status: active
---

# Auth — where we are

Current position: PKCE token exchange wired; refresh-token rotation is the open piece.
Next: implement rotation + its EARS acceptance test.

Spec: [`../spec/auth.md`](../spec/auth.md) · Why PKCE: [`../decisions/0007-pkce.md`](../decisions/0007-pkce.md)

That is the whole shape at flat scale: frontmatter · current position · next · pointers to the SOT (no restated product facts). Grow it into a tree only when it crosses ~150 lines.

The three lifetime classes

Not restated here — see ../ctx/SKILL.md § The model. progress/ is LIVING: edited in place, always current, never carrying a stale section inline.

Stop condition (JBGE)

The smallest progress surface that lets a fresh session continue correctly. One flat file is the default; a tree is earned, not scaffolded ahead of need. If handoff needs 10+ files or private chat history to continue, the progress doc has failed — reshape it, don't pad the prompt.

Hard constraints (progress hygiene)

The MUST/NEVER lines below are the domain constraints for progress — binding, load-before-act; they fire when a progress/ file is touched. The cross-cutting rules (single-source, same-change, verify-canonical, the gate) live in ../ctx/references/consistency.md and apply on top. Applies to every file in a progress/ tree, a flat progress.md, or a <project>-ctx/progress/; NOT to skill references/, scripts/, design docs, or code.

Location & single root

  • MUST maintain exactly one progress root per project (the knowledge root's progress/). Two roots cause drift.
  • NEVER place progress files under any .claude/, .agents/, or agent-workspace directory — those are for config, not project state.
  • NEVER maintain two progress files in one project with mutual cross-references. When a project legitimately spans repos (a shippable artifact + its <name>-ctx store), MUST declare "Source of Truth" at the top of the authoritative root; other repos edit the SoT only.

Frontmatter & the pointer rule

  • MUST give every progress / research / tree-entry doc YAML frontmatter with title, created, updated, status; status ∈ {draft,active,stale,archived} (no synonyms); update updated on every substantive edit.
  • MUST use absolute ISO dates (YYYY-MM-DD). NEVER relative phrasing (yesterday, Thursday), NEVER filesystem mtime as a substitute (clobbered by clone / auto-save / indexers).
  • MUST have progress reference spec/decisions by pointer (summary line + link). NEVER restate a product fact in progress — a restated fact drifts from spec/. (This is the LOAD-BEARING SSOT guard above.)

Tree graduation & archive DoD

The two size thresholds — ~150 lines (flat → open a child) and ~200 lines (archive a completed node) — are defined once in § Single file, or a tree above. These MUST lines enforce those two numbers; they do not introduce a third.

  • MUST open a child subtree before a progress file exceeds ~150 lines (or when a subtask is complex enough to spawn its own session). Reference children by pointer; NEVER duplicate child content into the parent. Use relative paths in parent/child/archive links. Update the parent summary line in the same commit a child's status transitions. Nesting ≤ 2 levels below the root.
  • NEVER apply an NN- prefix to skill references//scripts//design/ (functional modules, not timelines). NEVER rename files to reflect priority — use status + the parent summary line.
  • Definition of Done for a work chunk = commit → update progress → archive-when-long. MUST archive completed phases when a file exceeds ~200 lines, preserving archived text verbatim (move, not delete; canonical archive filename per ../ctx/references/consistency.md § Archive mechanics). Archive a section only when all its sub-tasks are complete. NEVER summarize/paraphrase/rewrite when archiving; NEVER delete completed history.