Skills · Maintainer

dev-loop

/dev-loop

Run an autonomous, issue-driven development loop over Ralphy itself — the same cadence as a focused maintainer session: pick the open `notes/issues/`, order them by dependency,…

Maintainermaintainer
SKILL.md

dev-loop — autonomous issue-driven dev cycle

A maintainer skill. It executes the open work in notes/issues/ (the inbox /dev-issues fills), one issue at a time, committing after each. It does not touch .ralphy/workspaces/<ws>/projects/ or call media models except where an issue explicitly requires it (and then only behind the paid-generation gate below).

Scope + limit

  • Default scope: every open issue at the flat top level of notes/issues/. The notes/issues/done/ and notes/issues/deprecated/ subfolders are the closed archive — never in scope (status is encoded by folder; see Issues folder layout).
  • Default limit: 25 issues per loop run. If the user's prompt names more (or "no limit", or a specific subset / range), honor that.
  • The user can narrow scope in their prompt ("just the landing ones", "only #052-#055", "everything tagged cli").

Workflow (per run)

  1. Read the rules first. docs/developing-ralphy.md (English-only, the lint suite, append-only contract, auto-generated files), AGENTS.md (the hard invariants — especially "wait for user 'go' before any paid generation"), and notes/README.md (including the Issues folder layout — active work is the flat top level only). Skim every candidate issue.

  2. Build the execution order. Sort issues by dependency, not by number:

    • Foundational / schema / data-model changes FIRST (everything keys off them).
    • Cross-cutting renames or moves NEXT, as a single coordinated step (never parallelize these).
    • Independent, low-collision, and plan-only/docs issues can go any time.
    • Read each issue's ## Notes for explicit "sequence after #NNN" hints. State the planned order up front and track it with TaskCreate / TaskUpdate (one task per issue; mark in_progress on start, completed on land).
  3. For each issue, in order: a. Dispatch ONE sub-agent (the Agent tool, usually general-purpose) with a tight, self-contained mandate: the mandatory reads, the exact scope, the gates it must pass, "do NOT git commit or push — leave changes in the working tree", and a required structured report-back. Give it the rename maps / file lists / schema decisions up front so it does not improvise on settled questions. Run agents sequentially — wait for one to finish and land before starting the next — to avoid collisions on shared files (AGENTS.md, skills, the landing app, the template schema). b. Review the diff yourself. Read the changed files / diffstat. Trust but verify the agent's report — re-run the real gates manually: the relevant lint:* scripts, the affected bun test files, cd landing && bunx next build for landing changes, the regenerated cli:surface:build / docs:cli for CLI-surface changes, and rg '\p{Cyrillic}' --pcre2 over changed files (text only; .webp/.png are binary false positives). c. Close gaps. Fix small issues inline; for a substantive miss, dispatch a focused follow-up agent (you cannot resume a finished agent — SendMessage is not available — so either edit directly or spawn a fresh scoped agent). d. Commit + push to main, then move on. One commit per issue with a Conventional-Commits message referencing the issue number. As part of that same commit, git mv the issue into notes/issues/done/ and update its > **Status:** line to done — <YYYY-MM-DD> (the folder is the live signal, the line carries the date/why — keep them in sync). If the issue turns out to be obsolete or superseded rather than implemented, git mv it into notes/issues/deprecated/ and set the line to SUPERSEDED by #NNN / dropped (<reason>) instead. Never delete the note — moving preserves the record. Push to origin (this repo commits to main; never gitlab).

  4. Repeat until the scope is exhausted or the limit is hit. Report a final summary: issues landed (with commit SHAs), issues skipped/deferred and why, and any new issues discovered mid-run (file them via the /dev-issues shape).

Gates the loop must respect

  • Paid-generation gate. If an issue requires paid model generation (image/video/voice/icon gen via ralphy generate or OpenRouter/ElevenLabs), STOP and ask the user for explicit go-ahead with a cost estimate before spending. This is an AGENTS.md hard invariant.
  • Irreversible / outward-facing gate. Pause and confirm before repo-split-class operations, force-pushes, deletions of user artifacts, publishing releases, or anything that leaves the repo.
  • Decision forks. Where an issue leaves a genuine choice that is the user's (scope, naming convention, product direction), use AskUserQuestion rather than guessing.

The flaky pre-commit/pre-push hook

The husky hooks run the full bun test suite, which contains a load-dependent flaky integration timeout (tests/integration/cli-dryrun*.test.ts; see issue #061) that passes in isolation but intermittently fails under full-suite parallel load. When it blocks a commit/push but every REAL gate you ran manually is green, --no-verify is acceptable — but only after you have manually verified the lints + relevant tests + cli:surface:check yourself. Never --no-verify to skip a gate that legitimately fails.

HARD INVARIANTS

  • Sequential, not parallel. One issue, one agent, one commit at a time. Parallel agents collide on shared files.
  • Commit + push after each issue before starting the next — keeps the working tree clean and each change reviewable in isolation.
  • Never rewrite a published commit. If you need to add to something already pushed, append a NEW commit; never force-push main.
  • Review every agent diff. The agent's report is a claim; the gates are the proof. Re-run them.
  • English-only on disk. Run the Cyrillic gate before every commit.
  • Respect the paid-generation and irreversible-action gates above — the loop is autonomous, not unsupervised.
  • Resolve = move, never delete. A landed issue is git mv'd into notes/issues/done/ (obsolete → deprecated/) with its > **Status:** line synced — never rm'd. The archive is the record of what was already tried. Only the flat top level is ever in scope.
  • Append-only on .ralphy/workspaces/<ws>/projects/ and the JSONL logs (AGENTS.md #14).