Spec Mint Core
Turn ephemeral plans into structured, persistent specs built through deep
research and iterative interviews. Specs have phases, tasks, acceptance
criteria, a registry, resume context, a decision log, and a deviations
log. They live in .specs/ at the project root and work with any AI
coding tool that can read markdown.
Whether .specs/ is committed is repository policy. Respect .gitignore
and the user's preference for tracked vs local-only spec state.
Critical Invariants
- Single-file policy: Keep this workflow in one
SKILL.mdfile. - Canonical paths:
- Registry:
.specs/registry.md - Per-spec files:
.specs/<id>/SPEC.md,.specs/<id>/research-*.md,.specs/<id>/interview-*.md
- Registry:
- Authority rule:
SPEC.mdfrontmatter is authoritative. Registry is a denormalized index for quick lookup. - Active-spec rule: Target exactly one active spec at a time.
- Parser policy: Use best-effort parsing with clear warnings and repair guidance instead of hard failure on malformed rows.
- Progress tracking is sacred: After completing any task, immediately
update SPEC.md (checkbox,
← currentmarker, phase marker) AND registry.md (progress count, date). Then re-read both files to verify the edits landed correctly. Never move to the next task without updating both files. Never end a session with the registry out of sync with SPEC.md. This is non-negotiable — if you do nothing else, do this.
Claude Code Plugin
If running as a Claude Code plugin, slash commands like /specmint-core:forge,
/specmint-core:resume, /specmint-core:pause etc. are available. See the
plugin's commands/ directory for the full set. The /forge command
replaces plan mode with deep research, iterative interviews, and spec
writing.
Session Start
If active-spec context was injected by host tooling, use it directly instead of reading files. Otherwise, fall back to reading files manually:
- Read
.specs/registry.mdto check for a spec withactivestatus - If one exists, briefly mention it: "You have an active spec: User Auth System (5/12 tasks, Phase 2). Say 'resume' to pick up where you left off."
- Don't force it — the user might want to do something else first
Deterministic Edge Cases (Best-Effort)
| Situation | Required behavior |
|---|---|
.specs/registry.md missing | If .specs/ exists, report "No registry yet" and offer to initialize it. If .specs/ is missing, report "No specs yet" and continue normally. |
| Malformed registry row | Skip malformed row, emit warning with row text, continue parsing remaining rows. |
Multiple active rows | Warn user. Pick the row with the newest Updated date (or first active row if dates are unavailable) for this run. On next write, normalize to a single active spec. |
Registry row exists but .specs/<id>/SPEC.md missing | Warn and continue. Keep row visible in list/status with (SPEC.md missing). |
| Registry and SPEC conflict | Trust SPEC.md, then repair registry values on next write. |
| No active spec | List available specs and ask which to activate or resume. |
Working on a Spec
Resuming
When the user says "resume", "what was I working on", or similar:
-
Read
.specs/registry.md— find the spec withactivestatus. If none, list specs and ask which to resume -
Load
.specs/<id>/SPEC.md -
Parse progress:
- Count completed
[x]vs total tasks per phase - Find current phase (first
[in-progress]phase) - Find current task (
← currentmarker, or first unchecked in current phase)
- Count completed
-
Read the Resume Context section
-
Present a compact summary:
Resuming: User Auth System Progress: 5/12 tasks (Phase 2: OAuth Integration) Current: Implement Google OAuth callback handler Context: Token exchange is working. Need to handle the callback URL parsing and store refresh tokens in the user model. Next file: src/auth/oauth/google.ts -
Begin working on the current task — don't wait for permission
Implementing
After completing each task, immediately edit the SPEC.md file to record progress. Do not wait until the end of a session or until asked — update the spec as you go. This is sacred (see Critical Invariant #6).
- Check off the completed task:
- [ ]->- [x] - Move
← currentto the next unchecked task - When all tasks in a phase are done:
- Phase status:
[in-progress]->[completed] - Next phase:
[pending]->[in-progress] - Review Acceptance Criteria — check off any that are now satisfied
- Phase status:
- Update the
updateddate in YAML frontmatter - Update progress (
X/Y) andupdateddate in.specs/registry.md
Update transaction (required order — never skip steps):
- Edit
SPEC.md(checkbox, current marker, phase marker, resume context). - Recompute progress directly from
SPEC.mdcheckboxes. - Edit the matching registry row (status, progress, updated date).
- Verify: Re-read both
SPEC.mdandregistry.mdto confirm the edits are correct. If the registry progress doesn't match the SPEC.md checkbox count, fix it now. - If registry update fails, keep
SPEC.mdas source of truth and emit a warning with exact repair action for.specs/registry.md.
If you notice you forgot to update after a previous task, stop what you're doing and update now before continuing. Stale tracking is the single most common failure mode — it makes resume unreliable and the registry useless.
Also:
- If a task is more complex than expected, split it into subtasks
- Update resume context at natural pauses
- Log non-obvious technical decisions to the Decision Log
- If implementation diverges from the spec (errors found, better approach discovered, assumptions proved wrong), log it in the Deviations section
Pausing
When the user says "pause", switches specs, or a session is ending:
- If there is no active spec, report that there is nothing to pause and stop.
- Capture what was happening:
- Which task was in progress
- What files were being modified (paths, function names)
- Key decisions made this session
- Any blockers or open questions
- Write this to the Resume Context section in SPEC.md
- Update checkboxes to reflect actual progress
- Move
← currentmarker to the right task - Add any session decisions to the Decision Log
- Update
status: pausedin frontmatter - Update the
updateddate
Resume Context is the most important part of pausing. Write it as if
briefing a colleague who will pick up tomorrow. Include specific file paths,
function names, and the exact next step. Vague context like "was working on
auth" is useless — write "implementing verifyRefreshToken() in
src/auth/tokens.ts, the JWT verification works but refresh rotation isn't
hooked up to the /auth/refresh endpoint yet."
Switching Between Specs
- Validate the target spec ID first. If missing, list available specs.
- Confirm
.specs/<target-id>/SPEC.mdexists. If not, stop with an error. - If target is already active, report and stop.
- Pause the current active spec if one exists (full pause workflow).
- Set target status to
activein frontmatter and in.specs/registry.md. - Resume the target spec (full resume workflow).
Command Ownership Map
SKILL.md: global invariants, lifecycle rules, state authority, and conflict handling, plus cross-tool OpenAPI behavior.commands/*.md: command-specific entrypoints, prompts, and output shapes.- If there is a conflict, preserve
Critical Invariantsfrom this file and apply command-specific behavior only where it does not violate invariants.
Spec Format
Frontmatter
YAML frontmatter with: id, title, status, created, updated,
optional priority and tags.
Status values: active, paused, completed, archived
Phase Markers
[pending], [in-progress], [completed], [blocked]