Back to skills
SkillHub ClubShip Full StackFull Stack

ralph-specum

Use only when the user explicitly invokes `$ralph-specum`, requests Ralph Specum in Codex, asks Ralph Specum to handle a named phase, or explicitly requests autonomous or quick mode or continuation without pauses.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
256
Hot score
98
Updated
March 20, 2026
Overall rating
C3.2
Composite score
3.2
Best-practice grade
C62.8

Install command

npx @skill-hub/cli install tzachbon-smart-ralph-ralph-specum

Repository

tzachbon/smart-ralph

Skill path: platforms/codex/skills/ralph-specum

Use only when the user explicitly invokes `$ralph-specum`, requests Ralph Specum in Codex, asks Ralph Specum to handle a named phase, or explicitly requests autonomous or quick mode or continuation without pauses.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: tzachbon.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install ralph-specum into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/tzachbon/smart-ralph before adding ralph-specum to shared team environments
  • Use ralph-specum for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: ralph-specum
description: Use only when the user explicitly invokes `$ralph-specum`, requests Ralph Specum in Codex, asks Ralph Specum to handle a named phase, or explicitly requests autonomous or quick mode or continuation without pauses.
metadata:
  surface: primary
---

# Ralph Specum

Use this as the primary Codex surface for Ralph Specum. It carries the full reusable workflow and can handle the entire command surface directly when helper skills are not installed.

## Read These References

- `references/workflow.md` for the phase flow, branch and worktree behavior, quick mode, and command routing
- `references/state-contract.md` for `.ralph-state.json`, `.progress.md`, commit rules, and resume semantics
- `references/path-resolution.md` for `specs_dirs`, `.current-spec`, ambiguity handling, and default directory behavior
- `references/parity-matrix.md` for Claude-to-Codex feature translation and command mapping

## Use These Helpers

- `scripts/resolve_spec_paths.py` for spec roots, current spec, and unique or ambiguous name resolution
- `scripts/merge_state.py` for safe top-level state merges
- `scripts/count_tasks.py` for task counts and next incomplete task
- `assets/templates/` for the canonical Ralph markdown file shapes
- `assets/bootstrap/` when the user wants optional project-local Codex guidance

## Primary Routing

Handle these intents directly:

| Intent | Action |
|--------|--------|
| Start, new, resume, quick mode | Follow the start flow in `references/workflow.md` |
| Triage | Decompose a large goal into an epic and dependency-aware specs |
| Research | Write `research.md` using the research template shape |
| Requirements | Write `requirements.md` using the requirements template shape |
| Design | Write `design.md` using the design template shape |
| Tasks | Write `tasks.md` using the tasks template shape |
| Implement | Run remaining tasks until completion or a blocker stops progress |
| Status | Show active spec, backlog state, and per-root listing |
| Switch | Update `.current-spec` only |
| Cancel | Stop execution and clean up state, confirm before destructive delete |
| Index | Generate `specs/.index/` component and external specs |
| Refactor | Update existing spec files after implementation learnings |
| Feedback | Open or draft GitHub feedback |
| Help | Summarize the surface and next commands |

If the corresponding helper skill is installed and the user invoked it explicitly, keep behavior aligned with that helper. If not, perform the action here.

## Core Rules

1. Keep the Ralph disk contract stable.
2. Treat `.claude/ralph-specum.local.md` as the settings source when present.
3. Default to `./specs` when no valid config exists.
4. Keep `.current-spec` in the default specs root.
5. Merge state fields. Do not replace the whole state object.
6. Preserve `source`, `name`, `basePath`, `phase`, `taskIndex`, `totalTasks`, `taskIteration`, `maxTaskIterations`, `globalIteration`, `maxGlobalIterations`, `commitSpec`, and `relatedSpecs`.
7. Also preserve newer state fields when present, especially `awaitingApproval`, `quickMode`, `granularity`, `epicName`, `discoveredSkills`, and native task sync metadata.
8. Write `.progress.md` after every phase and after every implementation attempt.
9. Honor approval checkpoints between phases unless quick mode is active.
10. Honor the `Commit` line in tasks during implementation unless the user explicitly disables task commits.
11. Use branch creation or worktree creation when the user asks for branch isolation or the repo policy requires it.
12. Enter quick mode only when the user explicitly asks Ralph to be autonomous, do it quickly, or continue without pauses.
13. In quick mode, generate missing artifacts, default task granularity to `fine` when unset, and continue into implementation in the same session.

## Response Handoff

- After writing `research.md`, `requirements.md`, `design.md`, `tasks.md`, or refactored spec files outside quick mode:
  - name the file or files that changed
  - give a short summary
  - end with exactly one explicit choice prompt:
    - `approve current artifact`
    - `request changes`
    - `continue to <named next step>`
- Treat `continue to <named next step>` as approval of the current artifact and permission to proceed.
- After `start` or `new`, summarize the resolved spec and stop unless the user explicitly asked for quick or autonomous flow. The next choice should point to `continue to research`.

## Current Workflow Expectations

- Use brainstorming-style interviews for research, requirements, design, and tasks when quick mode is not active.
- Route obviously large or cross-cutting efforts to triage before normal spec generation.
- Support active epic state via `specs/.current-epic` and per-epic state in `specs/_epics/<epic-name>/`.
- Treat task planning as POC-first with `[P]` markers for safe parallel work and `[VERIFY]` checkpoints for explicit quality validation.
- Support VE tasks when the plan needs autonomous end-to-end verification.
- During implementation, recompute task counts from disk, resume from the first incomplete task, and prefer task file truth over stale state.
- Native task sync is part of the current Ralph execution model. Keep Codex wording aligned with that behavior without promising Claude-only hook mechanics.

## Bootstrap

Bootstrap project-local files only when the user wants them.

Suggested bootstrap files:

- `assets/bootstrap/AGENTS.md` to give a consumer repo local Ralph guidance
- `assets/bootstrap/ralph-specum.local.md` to seed local settings

Do not bootstrap by default. Installation into `$CODEX_HOME/skills` is enough.


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/workflow.md

```markdown
# Ralph Specum Workflow

## Entry Surface

| Claude surface | Codex surface |
|----------------|---------------|
| `/ralph-specum:start` | `$ralph-specum` or `$ralph-specum-start` |
| `/ralph-specum:new` | `$ralph-specum` or `$ralph-specum-start` |
| `/ralph-specum:research` | `$ralph-specum` or `$ralph-specum-research` |
| `/ralph-specum:requirements` | `$ralph-specum` or `$ralph-specum-requirements` |
| `/ralph-specum:design` | `$ralph-specum` or `$ralph-specum-design` |
| `/ralph-specum:tasks` | `$ralph-specum` or `$ralph-specum-tasks` |
| `/ralph-specum:implement` | `$ralph-specum` or `$ralph-specum-implement` |
| `/ralph-specum:status` | `$ralph-specum` or `$ralph-specum-status` |
| `/ralph-specum:switch` | `$ralph-specum` or `$ralph-specum-switch` |
| `/ralph-specum:cancel` | `$ralph-specum` or `$ralph-specum-cancel` |
| `/ralph-specum:index` | `$ralph-specum` or `$ralph-specum-index` |
| `/ralph-specum:refactor` | `$ralph-specum` or `$ralph-specum-refactor` |
| `/ralph-specum:feedback` | `$ralph-specum` or `$ralph-specum-feedback` |
| `/ralph-specum:help` | `$ralph-specum` or `$ralph-specum-help` |

## Normal Flow

1. Resolve current repo state, branch, and spec roots.
2. Start or resume a spec.
3. Wait for explicit direction to continue to research unless the user explicitly asked for quick or autonomous flow.
4. Create `research.md` and request approval, changes, or continuation to requirements.
5. Draft `requirements.md` and request approval, changes, or continuation to design.
6. Prepare `design.md` and request approval, changes, or continuation to tasks.
7. Compile `tasks.md` and request approval, changes, or continuation to implementation.
8. Implement tasks until complete or blocked.
9. Use `status`, `switch`, `cancel`, `index`, `refactor`, `feedback`, and `help` as needed.

## Start And New

- `new` is an alias within the start flow.
- Resolve the target spec by explicit path, exact name, or current spec.
- If the current branch is the default branch and the user wants isolation, offer:
  - feature branch in place
  - worktree with a feature branch
- If the user wants a worktree, stop after creating it and ask them to continue from the worktree.

## Quick Mode

Quick mode does not rely on Claude hooks. In Codex it means:

1. Create or resolve the spec.
2. Generate missing phase artifacts in order.
3. Count tasks.
4. Continue directly into implementation in the same run.
5. Persist `.ralph-state.json` after every task so a later run can resume.

Only use quick mode when the user explicitly asks Ralph to be autonomous, do it quickly, or continue without pauses.

## Implement

- Read `tasks.md`, `.progress.md`, and `.ralph-state.json`.
- Recompute task counts before execution.
- Process tasks in order.
- `[P]` tasks may be batched only when file sets do not overlap and verification is independent.
- `[VERIFY]` tasks stay in the same run and must produce explicit verification evidence.
- After each task:
  - mark checkbox
  - update state
  - update progress
  - commit using the task commit line unless task commits were explicitly disabled
- Remove `.ralph-state.json` only when all tasks are complete and verified.

## Cancel

Claude `cancel` deletes the spec directory. In Codex:

- confirm before deleting a spec directory
- allow a safer "stop but keep files" interpretation when the user asks to keep the spec
- always clear execution state when the user asks to stop execution

## Index

Index creates or updates:

- `specs/.index/index.md`
- `specs/.index/components/*.md`
- `specs/.index/external/*.md`

Use the canonical templates from `assets/templates/`.

## Refactor

Refactor updates existing spec artifacts after implementation learnings. Review files in order:

1. `requirements.md`
2. `design.md`
3. `tasks.md`

Cascade downstream updates when upstream requirements or design changes.

## Approval Prompt Shape

When a phase writes `research.md`, `requirements.md`, `design.md`, `tasks.md`, or refactored spec files outside quick mode:

- name the file or files that changed
- give a short summary
- end with exactly one explicit choice prompt:
  - `approve current artifact`
  - `request changes`
  - `continue to <named next step>`

Treat `continue to <named next step>` as approval of the current artifact.

```

### references/state-contract.md

```markdown
# Ralph State Contract

## Core Files

Each spec directory uses:

- `.ralph-state.json`
- `.progress.md`
- `research.md`
- `requirements.md`
- `design.md`
- `tasks.md`

## Required State Fields

Preserve these fields across all phases:

- `source`
- `name`
- `basePath`
- `phase`
- `taskIndex`
- `totalTasks`
- `taskIteration`
- `maxTaskIterations`
- `globalIteration`
- `maxGlobalIterations`
- `commitSpec`
- `relatedSpecs`

Optional but common:

- `awaitingApproval`
- `recoveryMode`
- `fixTaskMap`

## New Spec Defaults

Use these defaults when a new spec starts:

```json
{
  "source": "spec",
  "name": "<spec-name>",
  "basePath": "<resolved-spec-path>",
  "phase": "research",
  "taskIndex": 0,
  "totalTasks": 0,
  "taskIteration": 1,
  "maxTaskIterations": 5,
  "globalIteration": 1,
  "maxGlobalIterations": 100,
  "commitSpec": true,
  "relatedSpecs": [],
  "awaitingApproval": false
}
```

Read `default_max_iterations` and `auto_commit_spec` from `.claude/ralph-specum.local.md` when present.

## Merge Rule

Never rebuild state from scratch once the file exists. Merge only the fields needed for the current phase.

Use `scripts/merge_state.py` for deterministic top-level merges.

## Approval Contract

`awaitingApproval: true` is not enough on its own.

This mirrors `Approval Prompt Shape` in `references/workflow.md` and should stay in sync with that section. Current enforcement is via Codex platform review plus the repo-local metadata and content checks.

When a phase sets `awaitingApproval: true`, the visible assistant response must also:

- name the file or files that changed
- give a short summary
- end with exactly one explicit choice prompt:
  - `approve current artifact`
  - `request changes`
  - `continue to <named next step>`

Treat `continue to <named next step>` as approval of the current artifact and permission to move forward.

## Progress File

`.progress.md` is persistent. Keep:

- original goal
- current phase
- current task summary
- completed task notes
- learnings
- blockers
- next step

## Commit Rules

- Spec artifacts may be auto-committed when `commitSpec` is true.
- Implementation tasks should use the task's `Commit` line by default.
- If the user disables commits, keep the disk state and progress updates but skip git commits.

```

### references/path-resolution.md

```markdown
# Ralph Path Resolution

## Settings Source

Read `.claude/ralph-specum.local.md` when it exists.

Relevant frontmatter keys:

- `specs_dirs`
- `default_max_iterations`
- `auto_commit_spec`

## Default Behavior

- default specs root: `./specs`
- current spec marker: `<default-specs-root>/.current-spec`
- ignore unknown or deprecated settings keys, including `quick_mode_default`

## `.current-spec` Rules

- bare name means `<default-root>/<name>`
- path starting with `./` or `/` means full path

## Ambiguity Rules

When a spec name exists in multiple roots:

- do not guess
- show the matching full paths
- require the user to pick the full path

## Script Usage

Use `scripts/resolve_spec_paths.py`.

Examples for this source repo, run them from the repo root:

```bash
python3 ./platforms/codex/skills/ralph-specum/scripts/resolve_spec_paths.py --cwd "$PWD"
python3 ./platforms/codex/skills/ralph-specum/scripts/resolve_spec_paths.py --cwd "$PWD" --current
python3 ./platforms/codex/skills/ralph-specum/scripts/resolve_spec_paths.py --cwd "$PWD" --name api-auth
python3 ./platforms/codex/skills/ralph-specum/scripts/resolve_spec_paths.py --cwd "$PWD" --list
```

Exit behavior:

- `--name` returns `0` for a unique match
- `--name` returns `1` when no spec matches
- `--name` returns `2` when multiple specs match

## Listing Rules

- Only existing spec directories count in `--list`
- Hidden directories are ignored
- Missing configured roots do not stop resolution

```

### references/parity-matrix.md

```markdown
# Ralph Parity Matrix

## Command Mapping

| Claude feature | Codex equivalent | Translation note |
|----------------|------------------|------------------|
| Plugin manifest | Installable skill folder | Codex installs skill folders, not plugins |
| Slash commands | Primary and helper skills | Public surface moves from `/command` to `$skill` |
| Hook-driven loop | State-driven resume | `.ralph-state.json` replaces hook continuation |
| `start --quick` | Quick-mode intent in start or primary skill | Generate artifacts and continue in one session |
| `new` | Alias inside start | No separate install unit needed |
| `implement` | Same skill surface | Implementation continues until complete or blocked |
| `switch` | Same skill surface | Updates `.current-spec` |
| `cancel` | Same skill surface | Confirm before destructive spec delete |
| `index` | Same skill surface | Generate `specs/.index/` directly |
| `refactor` | Same skill surface | Update requirements, design, and tasks after learnings |
| `feedback` | Same skill surface | Use `gh` when available or fall back to issue URL |
| `help` | Same skill surface | Summarize flow and entrypoints |

## Behavior Translation

### Hooks

Claude:

- `SessionStart` loads context
- `Stop` continues execution

Codex:

- read repo state at skill start
- persist state after each phase or task
- resume on the next invocation

### Subagents

Claude uses subagents like `research-analyst` and `spec-executor`.

Codex skills should preserve the same responsibilities, but the skill itself may execute the work in one session instead of requiring Claude plugin subagent dispatch.

### Worktrees

Claude start has explicit worktree prompts. Codex should still support that behavior when the user wants isolation, but it stays conversational.

### Parallel Tasks

Claude can batch `[P]` tasks in one delegated message. Codex can do the same only when file overlap and verification risk are low. Otherwise fall back to sequential execution and say why.

```

### scripts/resolve_spec_paths.py

```python
#!/usr/bin/env python3
"""Resolve Ralph Specum roots, current spec, and named specs."""

from __future__ import annotations

import argparse
import json
import re
from pathlib import Path

DEFAULT_SPECS_DIR = "./specs"
TRUE_VALUES = {"true", "yes", "1"}
FALSE_VALUES = {"false", "no", "0"}


def parse_scalar(value: str):
    stripped = value.strip()
    lowered = stripped.lower()
    if lowered == "true":
        return True
    if lowered == "false":
        return False
    if lowered == "null":
        return None
    if re.fullmatch(r"-?\d+", stripped):
        return int(stripped)
    if (stripped.startswith('"') and stripped.endswith('"')) or (
        stripped.startswith("'") and stripped.endswith("'")
    ):
        return stripped[1:-1]
    if stripped.startswith("[") and stripped.endswith("]"):
        body = stripped[1:-1].strip()
        if not body:
            return []
        return [part.strip().strip('"').strip("'") for part in body.split(",") if part.strip()]
    return stripped


def parse_frontmatter(path: Path) -> dict[str, object]:
    if not path.exists():
        return {}
    text = path.read_text(encoding="utf-8")
    match = re.match(r"^---\r?\n(.*?)\r?\n---(?:\r?\n|$)", text, re.DOTALL)
    if not match:
        return {}
    lines = match.group(1).splitlines()
    data: dict[str, object] = {}
    i = 0
    while i < len(lines):
        line = lines[i]
        if not line.strip():
            i += 1
            continue
        if ":" not in line:
            i += 1
            continue
        key, raw_value = line.split(":", 1)
        key = key.strip()
        raw_value = raw_value.strip()
        if raw_value:
            data[key] = parse_scalar(raw_value)
            i += 1
            continue
        i += 1
        items: list[str] = []
        while i < len(lines):
            item = lines[i]
            stripped = item.strip()
            if stripped.startswith("- "):
                items.append(stripped[2:].strip().strip('"').strip("'"))
                i += 1
                continue
            if stripped:
                break
            i += 1
        data[key] = items
    return data


def coerce_int(value: object, default: int) -> int:
    if isinstance(value, bool):
        return default
    if isinstance(value, int):
        return value
    if isinstance(value, str) and re.fullmatch(r"-?\d+", value.strip()):
        return int(value.strip())
    return default


def coerce_bool(value: object, default: bool) -> bool:
    if isinstance(value, bool):
        return value
    if isinstance(value, int):
        if value == 1:
            return True
        if value == 0:
            return False
        return default
    if isinstance(value, str):
        lowered = value.strip().lower()
        if lowered in TRUE_VALUES:
            return True
        if lowered in FALSE_VALUES:
            return False
    return default


def default_specs_dir(cwd: Path, specs_dirs: list[str]) -> str:
    for root in specs_dirs:
        root_path = cwd / root
        if root_path.exists() and root_path.is_dir():
            return root
    return DEFAULT_SPECS_DIR


def resolve_config(cwd: Path) -> dict[str, object]:
    settings = parse_frontmatter(cwd / ".claude" / "ralph-specum.local.md")
    raw_dirs = settings.get("specs_dirs")
    if isinstance(raw_dirs, list):
        specs_dirs = [str(item) for item in raw_dirs if str(item).strip()]
    else:
        specs_dirs = [DEFAULT_SPECS_DIR]
    if not specs_dirs:
        specs_dirs = [DEFAULT_SPECS_DIR]
    return {
        "specs_dirs": specs_dirs,
        "default_dir": default_specs_dir(cwd, specs_dirs),
        "default_max_iterations": coerce_int(settings.get("default_max_iterations", 5), 5),
        "auto_commit_spec": coerce_bool(settings.get("auto_commit_spec", True), True),
    }


def normalize_relative(value: str) -> str:
    if value.startswith("/"):
        return value
    norm = str(Path(value))
    return norm if norm.startswith(".") else f"./{norm.lstrip('./')}"


def resolve_current(cwd: Path, default_dir: str) -> str | None:
    marker = cwd / default_dir / ".current-spec"
    if not marker.exists():
        return None
    content = marker.read_text().strip()
    if not content:
        return None
    if content.startswith("./") or content.startswith("/"):
        return content
    return f"{default_dir.rstrip('/')}/{content}"


def list_specs(cwd: Path, specs_dirs: list[str]) -> list[dict[str, str]]:
    specs = []
    for root in specs_dirs:
        root_path = cwd / root
        if not root_path.exists() or not root_path.is_dir():
            continue
        for child in sorted(root_path.iterdir()):
            if not child.is_dir() or child.name.startswith("."):
                continue
            specs.append(
                {
                    "name": child.name,
                    "path": normalize_relative(str(Path(root) / child.name)),
                    "root": normalize_relative(root),
                }
            )
    return specs


def main() -> int:
    parser = argparse.ArgumentParser(description="Resolve Ralph Specum spec paths.")
    parser.add_argument("--cwd", default=".", help="Repository root")
    parser.add_argument("--current", action="store_true", help="Print current spec path")
    parser.add_argument("--list", action="store_true", help="Print all specs as JSON")
    parser.add_argument("--name", help="Find a spec by name")
    args = parser.parse_args()

    cwd = Path(args.cwd).resolve()
    config = resolve_config(cwd)
    specs = list_specs(cwd, config["specs_dirs"])
    current = resolve_current(cwd, config["default_dir"])

    if args.list:
        print(json.dumps(specs, indent=2, sort_keys=True))
        return 0

    if args.current:
        if not current:
            return 1
        print(current)
        return 0

    if args.name:
        matches = [spec["path"] for spec in specs if spec["name"] == args.name]
        if not matches:
            return 1
        if len(matches) > 1:
            print(json.dumps(matches, indent=2), end="")
            return 2
        print(matches[0])
        return 0

    payload = dict(config)
    payload["current_spec"] = current
    print(json.dumps(payload, indent=2, sort_keys=True))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

```

### scripts/merge_state.py

```python
#!/usr/bin/env python3
"""Merge top-level Ralph state fields into a JSON file."""

from __future__ import annotations

import argparse
import json
import os
from pathlib import Path


def parse_scalar(raw: str):
    lowered = raw.lower()
    if lowered == "true":
        return True
    if lowered == "false":
        return False
    if lowered == "null":
        return None
    try:
        return int(raw)
    except ValueError:
        return raw


def parse_pairs(items: list[str], as_json: bool) -> dict[str, object]:
    merged: dict[str, object] = {}
    for item in items:
        if "=" not in item:
            raise SystemExit(f"Invalid assignment: {item}")
        key, value = item.split("=", 1)
        key = key.strip()
        value = value.strip()
        if not key:
            raise SystemExit(f"Invalid assignment: {item}")
        if as_json:
            try:
                merged[key] = json.loads(value)
            except json.JSONDecodeError as exc:
                raise SystemExit(f"Invalid JSON for '{key}': {exc.msg}") from exc
        else:
            merged[key] = parse_scalar(value)
    return merged


def main() -> int:
    parser = argparse.ArgumentParser(description="Merge Ralph state fields into a JSON file.")
    parser.add_argument("state_file", help="Path to .ralph-state.json")
    parser.add_argument("--set", action="append", default=[], help="key=value assignment")
    parser.add_argument("--json", action="append", default=[], help="key=<json> assignment")
    parser.add_argument("--stdout", action="store_true", help="Print merged JSON to stdout")
    args = parser.parse_args()

    state_path = Path(args.state_file)
    state = {}
    if state_path.exists():
        try:
            state = json.loads(state_path.read_text(encoding="utf-8"))
        except json.JSONDecodeError as exc:
            raise SystemExit(f"State file is not valid JSON: {state_path} ({exc.msg})") from exc
        if not isinstance(state, dict):
            raise SystemExit("State file must contain a JSON object.")

    state.update(parse_pairs(args.set, as_json=False))
    state.update(parse_pairs(args.json, as_json=True))

    encoded = json.dumps(state, indent=2, sort_keys=True) + "\n"
    if args.stdout:
        print(encoded, end="")
        return 0

    state_path.parent.mkdir(parents=True, exist_ok=True)
    tmp_path = state_path.with_suffix(state_path.suffix + ".tmp")
    try:
        with tmp_path.open("w", encoding="utf-8") as handle:
            handle.write(encoded)
            handle.flush()
            os.fsync(handle.fileno())
        os.replace(tmp_path, state_path)
    except Exception:
        if tmp_path.exists():
            tmp_path.unlink()
        raise
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

```

### scripts/count_tasks.py

```python
#!/usr/bin/env python3
"""Count Ralph markdown tasks and find the next incomplete task."""

from __future__ import annotations

import argparse
import json
import re
from pathlib import Path

TASK_RE = re.compile(r"^- \[(?P<mark>[ xX])\] ")


def main() -> int:
    parser = argparse.ArgumentParser(description="Count Ralph task checkboxes.")
    parser.add_argument("tasks_file", help="Path to tasks.md")
    args = parser.parse_args()

    task_path = Path(args.tasks_file)
    if not task_path.exists():
        raise SystemExit(f"Tasks file not found: {task_path}")

    total = 0
    completed = 0
    next_index = None

    for line in task_path.read_text().splitlines():
        match = TASK_RE.match(line)
        if not match:
            continue
        if next_index is None and match.group("mark") == " ":
            next_index = total
        if match.group("mark").lower() == "x":
            completed += 1
        total += 1

    payload = {
        "total": total,
        "completed": completed,
        "incomplete": total - completed,
        "next_index": total if next_index is None else next_index,
    }
    print(json.dumps(payload, indent=2, sort_keys=True))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

```

### assets/bootstrap/AGENTS.md

```markdown
# Ralph Specum Project Guidance

Use Ralph Specum as the spec workflow for this repo.

## Preferred Entry Surface

- `$ralph-specum` for the general flow
- `$ralph-specum-start` to create, resume, or run in quick mode, then stop unless quick or autonomous flow was explicit
- `$ralph-specum-research`
- `$ralph-specum-requirements`
- `$ralph-specum-design`
- `$ralph-specum-tasks`
- `$ralph-specum-implement`
- `$ralph-specum-status`

## Project Contract

- Specs live in `./specs` unless `.claude/ralph-specum.local.md` defines `specs_dirs`
- `.current-spec` lives in the default specs root
- `.ralph-state.json` is transient execution state
- `.progress.md` persists learnings and blockers

## Flow

1. Start or resume a spec
2. Stop and ask whether to continue to research
3. Research
4. Approve the artifact, request changes, or continue to requirements
5. Requirements
6. Approve the artifact, request changes, or continue to design
7. Design
8. Approve the artifact, request changes, or continue to tasks
9. Tasks
10. Approve the artifact, request changes, or continue to implementation
11. Implement

Quick mode may generate missing artifacts and continue straight into implementation in one run only when the user explicitly asks for quick or autonomous flow.

```

### assets/bootstrap/ralph-specum.local.md

```markdown
---
enabled: true
default_max_iterations: 5
auto_commit_spec: true
specs_dirs:
  - "./specs"
---

# Ralph Specum Configuration

Use this file to configure Codex or Claude Ralph Specum flows for this project.

## Notes

- Add more entries to `specs_dirs` for monorepos
- Set `auto_commit_spec` to `false` if spec artifact commits should stay manual
- `quick_mode_default` is removed and ignored in this version
- Quick or autonomous flow must come from explicit user wording

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### assets/templates/component-spec.md

```markdown
---
type: component-spec
generated: true
source: {{SOURCE_PATH}}
hash: {{CONTENT_HASH}}
category: {{CATEGORY}}
indexed: {{TIMESTAMP}}
---

# {{COMPONENT_NAME}}

## Purpose
{{AUTO_GENERATED_SUMMARY}}

## Location
`{{SOURCE_PATH}}`

## Public Interface

### Exports
{{#each EXPORTS}}
- `{{this}}`
{{/each}}

### Methods

| Method | Parameters | Description |
|--------|------------|-------------|
<!-- markdownlint-disable MD055 MD056 -->
{{#each METHODS}}
| {{name}} | {{params}} | {{description}} |
{{/each}}
<!-- markdownlint-enable MD055 MD056 -->

## Dependencies
{{#each DEPENDENCIES}}
- `{{this}}`
{{/each}}

## AI Context
**Keywords**: {{KEYWORDS}}
**Related files**: {{RELATED_FILES}}

```

### assets/templates/design.md

```markdown
# Design: {{FEATURE_NAME}}

## Overview

{{Technical approach summary in 2-3 sentences}}

## Architecture

### Component Diagram

```mermaid
graph TB
    subgraph System["{{System Name}}"]
        A[Component A] --> B[Component B]
        B --> C[Component C]
    end
    External[External Service] --> A
```

### Components

#### Component A
**Purpose**: {{What this component does}}
**Responsibilities**:
- {{Responsibility 1}}
- {{Responsibility 2}}

#### Component B
**Purpose**: {{What this component does}}
**Responsibilities**:
- {{Responsibility 1}}
- {{Responsibility 2}}

### Data Flow

```mermaid
sequenceDiagram
    participant User
    participant System
    participant External
    User->>System: Action
    System->>External: Request
    External->>System: Response
    System->>User: Result
```

1. {{Step one of data flow}}
2. {{Step two}}
3. {{Step three}}

## Technical Decisions

| Decision | Options Considered | Choice | Rationale |
|----------|-------------------|--------|-----------|
| {{Decision 1}} | A, B, C | B | {{Why B was chosen}} |
| {{Decision 2}} | X, Y | X | {{Why X was chosen}} |

## File Structure

| File | Action | Purpose |
|------|--------|---------|
| {{src/path/file.ts}} | Create | {{Purpose}} |
| {{src/path/existing.ts}} | Modify | {{What changes}} |

## Interfaces

```typescript
interface {{ComponentInput}} {
  {{param}}: {{type}};
}

interface {{ComponentOutput}} {
  success: boolean;
  result?: {{type}};
  error?: string;
}
```

## Error Handling

| Error Scenario | Handling Strategy | User Impact |
|----------------|-------------------|-------------|
| {{Scenario 1}} | {{How handled}} | {{What user sees}} |
| {{Scenario 2}} | {{How handled}} | {{What user sees}} |

## Edge Cases

- **{{Edge case 1}}**: {{How handled}}
- **{{Edge case 2}}**: {{How handled}}

## Dependencies

| Package | Version | Purpose |
|---------|---------|---------|
| {{package}} | {{version}} | {{purpose}} |

## Security Considerations

- {{Security requirement or approach}}

## Performance Considerations

- {{Performance approach or constraint}}

## Test Strategy

### Unit Tests
- {{Component/function to test}}
- Mock requirements: {{what to mock}}

### Integration Tests
- {{Integration point to test}}

### E2E Tests (if UI)
- {{User flow to test}}

## Existing Patterns to Follow

Based on codebase analysis:
- {{Pattern 1 found in codebase}}
- {{Pattern 2 to maintain consistency}}

```

### assets/templates/external-spec.md

```markdown
---
type: external-spec
generated: true
source-type: {{SOURCE_TYPE}}
source-id: {{SOURCE_ID}}
fetched: {{FETCH_TIMESTAMP}}
---

# {{RESOURCE_NAME}}

## Source
- **Type**: {{SOURCE_TYPE}}
- **URL/ID**: {{SOURCE_ID}}
- **Fetched**: {{FETCH_TIMESTAMP}}

## Summary
{{CONTENT_SUMMARY}}

## Key Sections
{{#each SECTIONS}}
### {{title}}
{{content}}
{{/each}}

## AI Context
**Keywords**: {{KEYWORDS}}
**Related components**: {{RELATED_COMPONENTS}}

```

### assets/templates/index-summary.md

```markdown
---
type: index-summary
generated: true
indexed: {{TIMESTAMP}}
---

# Codebase Index

## Overview

| Category | Count | Last Updated |
|----------|-------|--------------|
{{#each CATEGORIES}}
| {{name}} | {{count}} | {{lastUpdated}} |
{{/each}}
| **Total** | **{{TOTAL}}** | {{TIMESTAMP}} |

## Components

### Controllers
{{#each CONTROLLERS}}
- [{{name}}](components/{{file}}) - {{purpose}}
{{/each}}

### Services
{{#each SERVICES}}
- [{{name}}](components/{{file}}) - {{purpose}}
{{/each}}

### Models
{{#each MODELS}}
- [{{name}}](components/{{file}}) - {{purpose}}
{{/each}}

### Helpers
{{#each HELPERS}}
- [{{name}}](components/{{file}}) - {{purpose}}
{{/each}}

### Migrations
{{#each MIGRATIONS}}
- [{{name}}](components/{{file}}) - {{purpose}}
{{/each}}

## External Resources

| Resource | Type | Fetched |
|----------|------|---------|
{{#each EXTERNAL}}
| [{{name}}](external/{{file}}) | {{type}} | {{fetched}} |
{{/each}}

## Index Settings

- **Excluded patterns**: {{EXCLUDES}}
- **Indexed paths**: {{PATHS}}

```

### assets/templates/progress.md

```markdown
# Ralph Progress

## Current Goal

**Phase**: requirements
**Task**: 0/0 - Initializing
**Objective**: Generate requirements from goal description

## Original Goal

{{USER_GOAL_DESCRIPTION}}

## Completed

_No tasks completed yet_

## Learnings

_Discoveries and insights will be captured here_

## Blockers

- None currently

## Next Steps

1. Read the goal description
2. Generate requirements.md
3. Update this progress file

```

### assets/templates/requirements.md

```markdown
# Requirements: {{FEATURE_NAME}}

## Goal

{{1-2 sentence description of what this feature accomplishes and why it matters}}

## User Stories

### US-1: {{Story Title}}

**As a** {{user type}}
**I want to** {{action/capability}}
**So that** {{benefit/value}}

**Acceptance Criteria:**
- AC-1.1: {{Specific, testable criterion}}
- AC-1.2: {{Specific, testable criterion}}

### US-2: {{Story Title}}

**As a** {{user type}}
**I want to** {{action/capability}}
**So that** {{benefit/value}}

**Acceptance Criteria:**
- AC-2.1: {{Specific, testable criterion}}
- AC-2.2: {{Specific, testable criterion}}

## Functional Requirements

| ID | Requirement | Priority | Acceptance Criteria |
|----|-------------|----------|---------------------|
| FR-1 | {{description}} | High | {{how to verify}} |
| FR-2 | {{description}} | Medium | {{how to verify}} |
| FR-3 | {{description}} | Low | {{how to verify}} |

## Non-Functional Requirements

| ID | Requirement | Metric | Target |
|----|-------------|--------|--------|
| NFR-1 | Performance | {{metric}} | {{target value}} |
| NFR-2 | Reliability | {{metric}} | {{target value}} |
| NFR-3 | Security | {{standard}} | {{compliance level}} |

## Glossary

- **{{Term 1}}**: {{Definition relevant to this feature}}
- **{{Term 2}}**: {{Another domain-specific term}}

## Out of Scope

- {{Item explicitly not included in this implementation}}
- {{Another exclusion to prevent scope creep}}

## Dependencies

- {{External dependency or prerequisite}}
- {{Another dependency}}

## Success Criteria

- {{Measurable outcome that defines success}}
- {{Another measurable outcome}}

## Risks

| Risk | Impact | Mitigation |
|------|--------|------------|
| {{Risk 1}} | High/Medium/Low | {{How to mitigate}} |
| {{Risk 2}} | High/Medium/Low | {{How to mitigate}} |

```

### assets/templates/research.md

```markdown
---
spec: "{{SPEC_NAME}}"
phase: research
created: "{{TIMESTAMP}}"
---

# Research: {{SPEC_NAME}}

## Executive Summary

{{2-3 sentence overview of research findings and feasibility assessment}}

## External Research

### Best Practices
- {{Finding with source URL}}
- {{Additional finding}}

### Prior Art
- {{Similar solutions or implementations found}}
- {{Relevant patterns from other projects}}

### Pitfalls to Avoid
- {{Common mistakes from community research}}
- {{Known issues or gotchas}}

## Codebase Analysis

### Existing Patterns
- {{Pattern found in codebase with file path}}
- {{Related implementation details}}

### Dependencies
- {{Existing dependencies that can be leveraged}}
- {{Required new dependencies}}

### Constraints
- {{Technical limitations discovered}}
- {{Architectural constraints}}

## Related Specs

| Spec | Relevance | Relationship | May Need Update |
|------|-----------|--------------|-----------------|
| {{spec-name}} | High/Medium/Low | {{why related}} | Yes/No |

### Coordination Notes
{{How this spec relates to existing specs, conflicts, coordination needed}}

## Feasibility Assessment

| Aspect | Assessment | Notes |
|--------|------------|-------|
| Technical Viability | High/Medium/Low | {{reasoning}} |
| Effort Estimate | S/M/L/XL | {{basis for estimate}} |
| Risk Level | High/Medium/Low | {{key risks identified}} |

## Recommendations for Requirements

1. {{Actionable recommendation based on research}}
2. {{Another recommendation}}
3. {{Additional consideration}}

## Open Questions

- {{Question needing clarification before requirements}}
- {{Unresolved technical question}}

## Sources

- {{URL with description}}
- {{File path with context}}

```

### assets/templates/settings-template.md

```markdown
---
enabled: true
default_max_iterations: 5
auto_commit_spec: true
specs_dirs: ["./specs"]
---

# Ralph Specum Configuration

This file configures Ralph Specum behavior for this project.

## Settings

### enabled
Enable or disable the workflow.

### default_max_iterations
Default maximum retries per failed task before blocking.

### auto_commit_spec
Whether to automatically commit spec files after generation.

### specs_dirs
Array of directories where specs can be stored.

```

### assets/templates/tasks.md

```markdown
# Tasks: {{FEATURE_NAME}}

## Overview

Total tasks: {{N}}
POC-first workflow with 5 phases:
1. Phase 1: Make It Work (POC) - Validate idea end-to-end
2. Phase 2: Refactoring - Clean up code structure
3. Phase 3: Testing - Add unit/integration/e2e tests
4. Phase 4: Quality Gates - Local quality checks and PR creation
5. Phase 5: PR Lifecycle - Autonomous CI monitoring, review resolution, final validation

## Completion Criteria (Autonomous Execution Standard)

This spec is not complete until ALL criteria are met:

✅ **Zero Regressions**: All existing tests pass (no broken functionality)
✅ **Modular & Reusable**: Code follows project patterns, properly abstracted
✅ **Real-World Validation**: Feature tested in actual environment (not just unit tests)
✅ **All Tests Pass**: Unit, integration, E2E all green
✅ **CI Green**: All CI checks passing
✅ **PR Ready**: Pull request created, reviewed, approved
✅ **Review Comments Resolved**: All code review feedback addressed

**Note**: The executor will continue working until all criteria are met. Do not stop at Phase 4 if CI fails or review comments exist.

> **Quality Checkpoints**: Intermediate quality gate checks are inserted every 2-3 tasks to catch issues early. For small tasks, insert after 3 tasks. For medium or large tasks, insert after 2 tasks.

## Phase 1: Make It Work (POC)

Focus: Validate the idea works end-to-end. Skip tests, accept hardcoded values.

- [ ] 1.1 {{Specific task name}}
  - **Do**: {{Exact steps to implement}}
  - **Files**: {{Exact file paths to create or modify}}
  - **Done when**: {{Explicit success criteria}}
  - **Verify**: {{Command to verify}}
  - **Commit**: `feat(scope): {{task description}}`
  - _Requirements: FR-1, AC-1.1_
  - _Design: Component A_

- [ ] 1.2 {{Another task}}
  - **Do**: {{Steps}}
  - **Files**: {{Paths}}
  - **Done when**: {{Criteria}}
  - **Verify**: {{Command}}
  - **Commit**: `feat(scope): {{description}}`
  - _Requirements: FR-2_
  - _Design: Component B_

- [ ] 1.3 Quality Checkpoint
  - **Do**: Run all quality checks to verify recent changes do not break the build
  - **Verify**: All commands must pass:
    - Type check: `pnpm check-types` or equivalent
    - Lint: `pnpm lint` or equivalent
    - E2E: `pnpm test:e2e` or equivalent if it exists
  - **Done when**: All quality checks pass with no errors
  - **Commit**: `chore(scope): pass quality checkpoint` only if fixes were needed

- [ ] 1.4 {{Continue with more tasks}}
  - **Do**: {{Steps}}
  - **Files**: {{Paths}}
  - **Done when**: {{Criteria}}
  - **Verify**: {{Command}}
  - **Commit**: `feat(scope): {{description}}`

- [ ] 1.5 POC Checkpoint
  - **Do**: Verify feature works end-to-end
  - **Done when**: Feature can be demonstrated working
  - **Verify**: Manual test of core flow
  - **Commit**: `feat(scope): complete POC`

## Phase 2: Refactoring

After POC is validated, clean up code.

- [ ] 2.1 Extract and modularize
  - **Do**: {{Specific refactoring steps}}
  - **Files**: {{Files to modify}}
  - **Done when**: Code follows project patterns
  - **Verify**: Type check passes
  - **Commit**: `refactor(scope): extract {{component}}`
  - _Design: Architecture section_

- [ ] 2.2 Add error handling
  - **Do**: Add try/catch and proper error messages
  - **Done when**: All error paths handled
  - **Verify**: Type check passes
  - **Commit**: `refactor(scope): add error handling`
  - _Design: Error Handling_

- [ ] 2.3 Quality Checkpoint
  - **Do**: Run all quality checks to verify refactoring does not break the build
  - **Verify**: All commands must pass:
    - Type check: `pnpm check-types` or equivalent
    - Lint: `pnpm lint` or equivalent
    - Tests: `pnpm test` if it exists
    - E2E: `pnpm test:e2e` or equivalent if it exists
  - **Done when**: All quality checks pass with no errors
  - **Commit**: `chore(scope): pass quality checkpoint` only if fixes were needed

- [ ] 2.4 Code cleanup
  - **Do**: Remove hardcoded values and add proper types
  - **Done when**: No TODOs or hardcoded values remain
  - **Verify**: Code review checklist passes
  - **Commit**: `refactor(scope): cleanup and finalize`

## Phase 3: Testing

- [ ] 3.1 Unit tests for {{component}}
  - **Do**: Create test file at {{path}}
  - **Files**: {{test file path}}
  - **Done when**: Tests cover main functionality
  - **Verify**: `pnpm test` or equivalent passes
  - **Commit**: `test(scope): add unit tests for {{component}}`
  - _Requirements: AC-1.1, AC-1.2_
  - _Design: Test Strategy_

- [ ] 3.2 Integration tests
  - **Do**: Create integration test at {{path}}
  - **Files**: {{test file path}}
  - **Done when**: Integration points tested
  - **Verify**: Test command passes
  - **Commit**: `test(scope): add integration tests`
  - _Design: Test Strategy_

- [ ] 3.3 Quality Checkpoint
  - **Do**: Run all quality checks to verify tests do not introduce issues
  - **Verify**: All commands must pass:
    - Type check: `pnpm check-types` or equivalent
    - Lint: `pnpm lint` or equivalent
    - Tests: `pnpm test`
    - E2E: `pnpm test:e2e` or equivalent if it exists
  - **Done when**: All quality checks pass with no errors
  - **Commit**: `chore(scope): pass quality checkpoint` only if fixes were needed

- [ ] 3.4 E2E tests if UI exists
  - **Do**: Create E2E test at {{path}}
  - **Files**: {{test file path}}
  - **Done when**: User flow tested
  - **Verify**: E2E test command passes
  - **Commit**: `test(scope): add e2e tests`
  - _Requirements: US-1_

## Phase 4: Quality Gates

- [ ] 4.1 Local quality check
  - **Do**: Run all local quality checks before PR creation
  - **Verify**: Types, lint, tests, and E2E pass where available
  - **Done when**: All commands pass with no errors
  - **Commit**: `fix(scope): address quality issues` only if fixes were needed

- [ ] 4.2 Create PR and verify CI
  - **Do**:
    1. Verify current branch is a feature branch
    2. Push the branch
    3. Create a PR with `gh` if available
    4. Watch CI and fix failures
  - **Done when**: PR exists and CI is green

- [ ] 4.3 Merge after approval if explicitly requested
  - **Do**: Merge only when the user explicitly asks
  - **Done when**: Requested merge is complete

## Phase 5: PR Lifecycle

- [ ] 5.1 Create pull request
  - **Do**: Push the branch and open a PR
  - **Done when**: PR URL exists

- [ ] 5.2 Monitor CI and fix failures
  - **Do**: Repeat fix, commit, push, and recheck until CI is green
  - **Done when**: All checks pass

- [ ] 5.3 Address code review comments
  - **Do**: Resolve outstanding review comments and push fixes
  - **Done when**: No unresolved review feedback remains

- [ ] 5.4 Final validation
  - **Do**: Re-run the full validation set and confirm all completion criteria
  - **Done when**: The feature is ready

## Notes

- **POC shortcuts taken**: {{list hardcoded values and skipped validations}}
- **Production TODOs**: {{what still needs proper implementation}}

## Dependencies

```text
Phase 1 (POC) -> Phase 2 (Refactor) -> Phase 3 (Testing) -> Phase 4 (Quality) -> Phase 5 (PR Lifecycle)
```

```