Ctx progress
The agent context layer — converge messy multi-session AI-agent work into one lean, LIVING, spec-centered source of truth that doesn't rot. Organize docs by lifetime, keep the spec generative, and let an agent (or a human three months later) build from it.
npx -y skills add motiful/ctx --skill ctx-progressAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Tracks the WORK truth of a project — where we are, what's next, and what to read first — in a living progress file a fresh session can resume from, including cross-session handoff. Use when updating work or project state in a ctx knowledge base, recording what's done or what's next, opening a progress subtree as it grows past a flat file, handing off to a new session, or auditing a project for progress drift.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
16.3 KB, as published. Nobody here has run it
ctx-progress — the LIVING work-truth doc
The lifetime model and shared conventions live in
../ctx; this is the how-to for the LIVINGprogress/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>.mdchildren (zero-padded, creation-ordered per consistency.md numbering). A child that itself grows gets a siblingNN-<slug>/dir with its ownREADME.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):
---
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)
- Commit the code/doc change.
- Update
progress/in the same commit: bumpupdated, move the active leaf, ripple the parent's status/pointer line. - 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 toprogress/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.mdand apply on top. Applies to every file in aprogress/tree, a flatprogress.md, or a<project>-ctx/progress/; NOT to skillreferences/,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>-ctxstore), 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); updateupdatedon every substantive edit. - MUST use absolute ISO dates (
YYYY-MM-DD). NEVER relative phrasing (yesterday,Thursday), NEVER filesystemmtimeas 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
statustransitions. Nesting ≤ 2 levels below the root. - NEVER apply an
NN-prefix to skillreferences//scripts//design/(functional modules, not timelines). NEVER rename files to reflect priority — usestatus+ 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.