roadmap
SkillDocs & knowledgeRead the feature roadmap, find the next unplanned phase, brainstorm it, and update the roadmap with the resulting document name
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the roadmap skill
What this skill tells your AI
The instructions your AI receives, as published by ovid/paad in .claude/skills/roadmap/SKILL.md and read by ahel’s review.
Start
Announce: "Checking for in-progress runs and roadmap layout…"
Read @CLAUDE.md.
Per-Phase Checklist File
One checklist per /roadmap run, created right after step 2a (branch checkout succeeded), updated at the end of every subsequent step. The checklist lives at docs/roadmap/plans/YYYY-MM-DD-<topic>-checklist.md — alongside the design and plan files for the same run.
Filename
YYYY-MM-DD-<phase-slug>-checklist.md, where <phase-slug> is the phase filename slug (defined immediately below), and YYYY-MM-DD is the day step 0 → step 1 fires (start date) — so the design / plan / checklist for one run sit alphabetically adjacent in plans/.
Phase filename slug
A single rule, used by checklist filenames here and referenced from §2a and §Appendix:
- Take the phase title text (everything after the
Phase N:orPhase Na:prefix in the roadmap heading). - Lowercase.
- Drop apostrophes (
',',') without inserting a separator (soEditor'sbecomeseditors, noteditor-s). - Replace any run of non-
[a-z0-9]characters with a single hyphen. - Strip leading and trailing hyphens.
- If the result is empty (e.g. the title was only Unicode/CJK characters that collapsed to nothing), fall back to
phase-Nusing the phase number — including any sub-letter — from the heading.Phase 3a: 漢字→phase-3a.
Examples:
| Phase heading | Phase filename slug |
|---|---|
Phase 1: Backend Foundation | backend-foundation |
Phase 3a: Movie Data Cleaning | movie-data-cleaning |
Phase 7: User Authentication implementation | user-authentication-implementation |
Phase 9: Editor's Polish | editors-polish |
Phase 12: Implementation | implementation |
This rule does NOT drop the trailing implementation/impl/feature word. The §2a branch slug is this same rule with one extra step (drop that trailing word) — branch names benefit from terseness; filenames benefit from accuracy. The decision-log filename slug (§Appendix) is also separate (heading-based with phase-N prefix for year-at-a-glance browsability); see §Appendix Slug rule.
The phase_slug frontmatter field on the checklist is the phase filename slug verbatim — it is the linkable name future tooling can use to correlate the checklist with its sibling design / plan files in plans/.
Schema
The example below shows a mid-run state (steps 1-4 complete, design_file populated, step 5 next). The §2a "Create the run checklist" sub-section creates the file with steps 1, 2, 2a pre-checked and design_file: null; subsequent steps fill in path fields and tick boxes as their work lands. Treat the §2a creation block — not this example — as the canonical write-template.
---
phase: 'Phase 2: agentic-architecture references conversion'
phase_slug: agentic-architecture-references
branch: ovid/agentic-architecture-refs
roadmap: docs/roadmap/roadmap.md
started: 2026-05-02
last_updated: 2026-05-02
design_file: docs/roadmap/plans/2026-05-02-agentic-architecture-references-design.md
plan_file: null
decision_log: null
---
# Phase 2: agentic-architecture references conversion — Run Checklist
## Steps
- [x] 1. Read roadmap
- [x] 2. Identified next unplanned phase
- [x] 2a. Working branch created: `ovid/agentic-architecture-refs`
- [x] 3. Extract phase context
- [x] 4. Brainstorm → design saved
- [ ] 5. Record plan filename in roadmap
- [ ] 6. Pushback review
- [ ] 6a. Pushback returned all findings
- [ ] 7. CLAUDE.md review
- [ ] 8. Write implementation plan
- [ ] 9. Alignment check
- [ ] 9a. Alignment returned all findings
- [ ] 10. Write decision log entry
- [ ] 11. Announce completion
## Pushback Findings
(populated during step 6, transcribed by step 10)
### [1] Lens 3 spec contradicts §Key Architecture Decisions
- **Severity:** Critical
- **Category:** Contradiction
- **Summary:** The Lens 3 spec requires X, but §Key Architecture Decisions in CLAUDE.md mandates Y for cross-cutting consistency. The two cannot both hold; one must yield.
- **Status:** open
- **Resolution:** _(pending)_
### [2] Phase scope bundles refactor + new feature
- **Severity:** Important
- **Category:** Scope
- **Summary:** This phase combines the references-package extraction (refactor) with new lens content (feature), violating the one-refactor-OR-one-feature PR rule from CLAUDE.md.
- **Status:** closed
- **Resolution:** fixed-in-design — split into 2a (refactor) + 2b (feature)
## Alignment Findings
(populated during step 9, transcribed by step 10)
Field rules
branchis the working branch name from §2a; resume verifies it matches the current branch.design_file,plan_file,decision_loggo fromnullto a path the moment each artifact is written.last_updatedis bumped on every write (lets stale-checklist detection work without filesystem mtime).- Summary is a one-paragraph description of the finding, written by pushback (or alignment) at the moment the issue is first raised — while the context is still in head. It is not generated at transcription time. This is the only field step 10 carries forward as written prose, so writing it now (not later) is what eliminates the "mentally tracked" failure mode the design exists to fix.
- Status vocabulary (closed set):
open | closed. Whileopen, the finding is still being discussed. Whenclosed, theResolution:line uses one of the values from the §Appendix Resolution vocabulary verbatim. Status itself has no decision-log analog (every entry there is closed by definition); step 10's transcription drops theStatus:line and is otherwise a literal copy. - Severity / Category vocabularies are defined authoritatively in §Appendix Vocabularies (Severity, Pushback Category, Alignment Category). When the values listed there change, they change here — do not duplicate the lists.
- Sub-checkboxes for steps 6 and 9. Each has a
Nasub-checkbox (6a. Pushback returned all findings,9a. Alignment returned all findings) flipped only when the corresponding subagent returns cleanly. The top-level- [x] Nis checked when both Na is checked AND noStatus: openentries remain in the corresponding findings section. The "no open findings" half is a derived condition computed from the file, not a separate checkbox. - Provenance of findings appended after the Na tick. Once
6a(or9a) is ticked, the subagent has already returned. Any subsequent finding the user raises during the resolution discussion ("what about X?") is user-authored, not subagent-authored. Append it to the same## Pushback Findings(or## Alignment Findings) section using the same template, and prefix the issue title with(user-added)so the decision-log transcription preserves the provenance distinction without a separate schema field. Example:### [4] (user-added) Phase split misses a downstream consumer. Step 10's literal-copy rule carries the prefix forward to the decision log unchanged. phasefield YAML escaping. Use single-quoted YAML scalars:phase: '<heading>'. Embedded apostrophes are doubled (Editor's→Editor''s). Reject literal newlines — if the H2 heading wraps to multiple lines (it shouldn't), take the first line only. No other escaping is required. Why single-quoted: a phase title is contributor-controlled and can contain"or\; double-quoted YAML would treat both specially, and a crafted title (e.g., one ending with"followed by a newline anddesign_file: /etc/passwd) could inject a sibling frontmatter key. Single-quoted scalars require only the''doubling, which is harder to weaponize and trivial to apply correctly.
Update obligations
Every step ends with "update the checklist (frontmatter last_updated + the relevant box + any frontmatter path field) before announcing or moving on." No exceptions.
Shell-command hardening
Whenever this skill invokes git mv, always include the -- separator: git mv -- <src> <dst>. Without it, a path that begins with - (-foo.md, -checklist.md written by an unusual brainstorming output) is parsed as a flag and either errors or, worse, causes git to act on something else. The -- separator is a one-character hardening cost; document it as the project convention so no git mv invocation in this skill silently omits it.
Rationalization table
| Excuse | Reality |
|---|---|
| "This step is obvious, I'll skip the box" | Resume detection scans boxes, not artifacts. The box is the source of truth. |
| "I'll batch the checklist updates at the end" | A /clear between now and the end loses the run. Update before moving on. |
| "I'll keep the open pushback issues in my head" | The next session won't have a head. The checklist is the memory. |
| "The artifact exists on disk, the checkbox is redundant" | Both must agree; mismatch means the run is in an unknown state. |
| "Branch mismatch is fine, I know what I'm doing" | The recorded branch is the safety net. Update or override explicitly — never ignore. |
| "There are partial findings on disk — let me merge yesterday's into today's pushback output instead of wiping." | Pushback is partly stochastic — yesterday's findings are not a guaranteed subset of today's. Merging silently corrupts the evidence trail. §0's wipe-and-re-invoke is the only safe recovery when 6a is unchecked. |
Verification before ticking
Marking step 4 done requires design_file to exist at the recorded path and be non-empty. Step 5 requires that 5a's plan comment is present exactly once in roadmap.md at the expected position, and that 5b's Phase Structure table status flips actually landed. Step 8 requires plan_file. Step 10 requires decision_log. This is verification-before-completion applied to checklist updates.
"Non-empty" file check
Steps 4, 8, and 10 each verify that an artifact file exists and is non-empty before ticking. Use this check (not bare test -s):
test -s "<path>" && grep -q '[^[:space:]]' -- "<path>"
test -s accepts any file with size > 0 — including a one-byte \n or a stray-whitespace-only file. The whole point of the verification gate is to catch silent writer failures, and a truncated or whitespace-only artifact passes test -s while being functionally missing. The combined check requires at least one non-whitespace byte, which is what "non-empty Markdown document" really means in this context. Surface and stop on either failure.
Brainstorming non-resumability
If interrupted mid-step-4, re-run brainstorming. Step 4's box flips only when the design file is written.
0. Resume Detection
A new step that runs before everything else. Before reading the roadmap or doing any phase work, the skill checks for an in-progress run that needs to be resumed and verifies the project is on the current directory layout.
digraph step0 {
"start" [shape=doublecircle];
"old layout?" [shape=diamond];
"prompt to migrate" [shape=box];
"abort run" [shape=doublecircle];
"scan active plans/*-checklist.md with unchecked steps" [shape=box];
"candidates" [shape=diamond];
"fresh run" [shape=box];
"ask which" [shape=box];
"verify branch" [shape=diamond];
"branch matches" [shape=box];
"branch differs" [shape=box];
"recorded branch missing" [shape=box];
"stale check" [shape=diamond];
"prompt resume vs archive" [shape=box];
"archive stale checklist" [shape=box];
"jump to first unchecked step" [shape=doublecircle];
"current step 1" [shape=doublecircle];
"start" -> "old layout?";
"old layout?" -> "abort run" [label="no roadmap anywhere\n(prompt: create docs/roadmap/roadmap.md)"];
"old layout?" -> "abort run" [label="both layouts coexist\n(prompt: reconcile manually)"];
"old layout?" -> "prompt to migrate" [label="legacy only:\ndocs/roadmap.md exists\n+ docs/roadmap/ doesn't"];
"old layout?" -> "scan active plans/*-checklist.md with unchecked steps" [label="already migrated"];
"prompt to migrate" -> "scan active plans/*-checklist.md with unchecked steps" [label="yes (clean tree → run git mv)"];
"prompt to migrate" -> "abort run" [label="no/cancel\nor dirty tree without confirmation"];
"scan active plans/*-checklist.md with unchecked steps" -> "candidates";
"candidates" -> "fresh run" [label="0"];
"candidates" -> "verify branch" [label="1"];
"candidates" -> "ask which" [label="2+"];
"ask which" -> "verify branch" [label="picked one"];
"ask which" -> "fresh run" [label="none — start fresh"];
"verify branch" -> "branch matches" [label="match"];
"verify branch" -> "branch differs" [label="mismatch"];
"verify branch" -> "recorded branch missing" [label="gone"];
"branch matches" -> "stale check";
"branch differs" -> "stale check" [label="continue/switch"];
"branch differs" -> "abort run" [label="cancel"];
"recorded branch missing" -> "stale check" [label="recreate"];
"recorded branch missing" -> "archive stale checklist" [label="archive"];
"recorded branch missing" -> "abort run" [label="cancel"];
"stale check" -> "prompt resume vs archive" [label="last_updated > 30d"];
"stale check" -> "jump to first unchecked step" [label="recent"];
"prompt resume vs archive" -> "jump to first unchecked step" [label="resume"];
"prompt resume vs archive" -> "archive stale checklist" [label="archive"];
"prompt resume vs archive" -> "abort run" [label="cancel"];
"archive stale checklist" -> "fresh run";
"fresh run" -> "current step 1";
}
Layout migration
Step 0's first action is a layout sanity check across three locations: docs/roadmap.md (legacy roadmap), docs/roadmap/roadmap.md (new roadmap), docs/plans/ (legacy plans dir), docs/roadmap/plans/ (new plans dir), and docs/roadmap-decisions/ (legacy decisions dir, named by earlier versions of this skill).
There are four cases:
-
No roadmap anywhere — neither
docs/roadmap.mdnordocs/roadmap/roadmap.mdexists. Stop and prompt:No roadmap found. /roadmap operates on
docs/roadmap/roadmap.md. Create that file first (a minimal H1 + Phase Structure table is enough), then re-run.Do not silently fall through to step 1 — step 1 reads
docs/roadmap/roadmap.md, and a missing-file error there is less actionable than this prompt. -
Both layouts coexist — both
docs/roadmap.mdANDdocs/roadmap/roadmap.mdexist (or bothdocs/plans/ANDdocs/roadmap/plans/exist, or bothdocs/roadmap-decisions/ANDdocs/roadmap/decisions/exist). A half-migrated state, an accidental hand-creation, or independent files. Stop and prompt:Roadmap layout looks half-migrated:
- both
docs/roadmap.mdanddocs/roadmap/roadmap.mdexist (one will be canonical, the other should be removed/merged)
Reconcile manually (which is canonical?) and re-run /roadmap.
Do not pick one silently — the user's actual roadmap content can be in either file, and silent abandonment of the other is the I4 footgun this guard exists to prevent.
- both
-
Legacy layout only —
docs/roadmap.mdexists,docs/roadmap/roadmap.mddoes not, and (any ofdocs/plans/ordocs/roadmap-decisions/exists OR neither does). Run the migration prompt:Old roadmap layout detected:
docs/roadmap.md(will move todocs/roadmap/roadmap.md)docs/plans/(will move todocs/roadmap/plans/) [if present]docs/roadmap-decisions/(will move todocs/roadmap/decisions/) [if present]
Run the migration now?
yes/no/cancelBefore running any
git mv, rungit status --porcelain. If output is non-empty, the working tree is dirty — surface the paths and ask the user to commit, stash, or explicitly confirm the carry-over before continuing. Layout migration is a one-time, irrevocable structural change that should land in a clean, intentional commit; running it over WIP entrains unrelated changes into the staged moves. Do not silentlygit mvover a dirty tree.On
yes(after the dirty-tree gate passes), rungit mv -- <src> <dst>for each pair that is present. Onnoorcancel, abort the run and tell the user the new skill cannot operate on the legacy layout. Oncedocs/roadmap/roadmap.mdexists, this prompt never fires again for the project (case 4 takes over). Detection is by presence — no marker file needed. -
New layout only (or already migrated) —
docs/roadmap/roadmap.mdexists,docs/roadmap.mddoes not, and no legacydocs/plans/ordocs/roadmap-decisions/linger. Skip the migration prompt and continue to the scan.
Once layout migration succeeds and resume detection finds no in-progress checklist, fall through to step 1 → step 2; the archive prompt fires from step 2 if applicable.
Scan scope
The scan reads docs/roadmap/plans/*-checklist.md exclusively. It never recurses into docs/roadmap/archive/ — once a roadmap is archived, its in-progress runs are intentionally abandoned and should not surface as resume candidates.
Branch verification
Recorded branch vs git branch --show-current | Action |
|---|---|
| Match | Silently proceed; announce "Resuming Phase X at step N" |
| Mismatch | Prompt: switch to recorded, continue here (updates branch field), or cancel |
| Recorded branch no longer exists locally | Prompt: archive the stale checklist, recreate on current branch, or cancel |
Multiple candidates
If scan returns two or more checklists with unchecked steps, list them and ask which to resume; offer "none — start fresh" as a fourth option.
Stale-checklist threshold
Stale threshold: 30 days (single labeled constant — change here, nowhere else).
If last_updated is more than the stale threshold ago, prompt before resuming:
Checklist
<filename>was last updated days ago. Resume the run, archive this checklist (rename out of the scan glob and treat the §0 flow as fresh), or cancel?
Acceptable answers (case-insensitive, exact-match): resume, archive, cancel. Anything else → re-prompt.
resume— proceed to "jump to first unchecked step".archive— see §Archiving a stale checklist below; the file is renamed out of scan scope, then §0 falls through to "fresh run" → step 1.cancel— stop the /roadmap run.
Archiving a stale checklist
When the user picks "archive" — for a stale checklist (this section) or for a checklist whose recorded branch no longer exists locally (per the branch-verification table above) — rename the single checklist file out of the *-checklist.md scan glob without moving directories:
git mv -- docs/roadmap/plans/<original>-checklist.md \
docs/roadmap/plans/<original>-checklist.stale-<YYYY-MM-DD>.md
The .stale-<YYYY-MM-DD> infix breaks the *-checklist.md scan match (the glob is anchored — files ending in .stale-…md no longer surface), so the file no longer appears as a resume candidate but stays alongside the run's design / plan / decision-log artifacts as historical evidence. Use today's date.
After the rename succeeds, treat the §0 flow as a fresh run: fall through to step 1. Do not re-scan within the same /roadmap invocation — one archived checklist per /roadmap run keeps the flow predictable.
Jumping to the right step
The first unchecked - [ ] in ## Steps (treating a top-level step as unchecked if either it or any of its sub-checkboxes is unchecked) is the target. The label after the number identifies which step's prose to load.
For steps 6 and 9, the sub-checkbox Na distinguishes two recovery modes:
Naunchecked → the subagent never returned a complete findings list (never invoked, errored, or timed out). Wipe the corresponding## Pushback Findings(or## Alignment Findings) section, re-invoke the subagent from scratch, and start over for that step.Nachecked, top-levelNunchecked → findings list is complete; at least one entry hasStatus: open. Resume the discussion from those open findings; do not re-invoke the subagent.
Re-validate recorded artifact paths on resume
Before announcing "Resuming Phase X at step N" and handing control back to the per-step prose, re-check each path-bearing frontmatter field whose corresponding step is ticked: design_file (step 4), plan_file (step 8), decision_log (step 10). For each ticked-with-recorded-path tuple, run the §"Non-empty" file check (test -s + non-whitespace grep) against the recorded path.
On any mismatch — file missing, file zero-size, or file whitespace-only — stop and surface to the user. Do not auto-recover by clearing the path field or re-running the writing step: the recorded path is part of the run's evidence trail, and silently overwriting it would mask the original loss.
Why this is here: a checklist with - [x] 4. Brainstorm → design saved and design_file: foo.md ticked means the agent reported step 4 done at some point. If foo.md was deleted, moved, or truncated between sessions, downstream steps key off a path that no longer points to the artifact they expect — step 5's plan-comment insertion would point at a non-existent file; step 8 would build on a missing design; step 10's decision log would record a broken design_file. Catching this at §0 is cheaper than letting any of those downstream failures land first.
1. Read the Roadmap
Read docs/roadmap/roadmap.md in full. Each phase heading (## Phase N: …) may have a <!-- plan: filename.md --> comment on the line immediately after the --- separator that follows that phase's section. This comment marks the phase as already brainstormed.
Example of a completed phase:
---
## Phase 2: Goals & Velocity
<!-- plan: 2026-04-01-goals-velocity-design.md -->
Example of an incomplete phase (no comment, or no <!-- plan: … --> line):
---
## Phase 3: Export
On a fresh run, the checklist file does not exist yet — it is created at step 2a after the working branch is established, and steps 1, 2, 2a are written pre-checked there (the work to reach step 2a has been done by then). Do not invent a checklist before step 2a. On a resume, the checklist already exists; tick - [x] 1. Read roadmap in place and bump last_updated.
2. Identify the Next Unplanned Phase
Scan phases in order (Phase 1, 2, 3, … 7). The first phase whose section does not have a <!-- plan: … --> comment is the target.
If all phases have plan comments, the roadmap is fully planned. Surface the archive prompt:
All phases of this roadmap have been planned. Archive to
docs/roadmap/archive/<slug>/and start fresh?yes/no/later
Parse the response (case-insensitive, leniently as the §2a accept-grammar):
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 112
- Forks
- 10
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
roadmap-ovid- Source
- github.com/ovid/paad