runcastle 1.0.15 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/bin/runcastle.js +231 -74
  2. package/drizzle/0008_panoramic_molecule_man.sql +1 -0
  3. package/drizzle/meta/0008_snapshot.json +603 -0
  4. package/drizzle/meta/_journal.json +7 -0
  5. package/index.js +231 -74
  6. package/package.json +1 -1
  7. package/skills/packs/README.md +1 -1
  8. package/skills/packs/runcastle/skills/converge/SKILL.md +5 -9
  9. package/skills/packs/runcastle/skills/ideate/SKILL.md +6 -6
  10. package/skills/packs/runcastle/skills/revisit/SKILL.md +9 -0
  11. package/skills/packs/runcastle/skills/spec/SKILL.md +1 -1
  12. package/skills/packs/runcastle/skills/tickets/SKILL.md +2 -2
  13. package/web/assets/index-CgbdxRlZ.js +110 -0
  14. package/web/assets/index-jQSjMQ_c.css +1 -0
  15. package/web/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  16. package/web/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  17. package/web/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  18. package/web/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  19. package/web/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  20. package/web/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  21. package/web/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  22. package/web/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  23. package/web/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  24. package/web/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  25. package/web/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  26. package/web/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  27. package/web/favicon.svg +8 -0
  28. package/web/index.html +3 -2
  29. package/web/assets/index-BEeyZA5j.js +0 -109
  30. package/web/assets/index-CI8-AEi9.css +0 -1
@@ -15,7 +15,7 @@ Everything happens in this one window. **Never compact. Never `/clear`. Never su
15
15
 
16
16
  ## 0. Orient
17
17
 
18
- 1. Call `mcp__runcastle__get_feature_context`. It returns the feature (`slug`, `title`, `oneLiner`, `size`), current `phase`, the docs already on disk (`brief.md`, and any `decisions.md` — **this may be a resumed session; read what is already locked and do not re-ask it**), and any tickets.
18
+ 1. Call `mcp__runcastle__get_feature_context`. It returns the feature (`slug`, `title`, `oneLiner`), current `phase`, the docs already on disk (`brief.md`, and any `decisions.md` — **this may be a resumed session; read what is already locked and do not re-ask it**), and any tickets.
19
19
  2. Decisions live at `docs/features/<slug>/decisions.md` in this worktree. The injected system prompt carries the slug and paths; trust `get_feature_context` for the live state.
20
20
  3. `mcp__runcastle__record_event({ type: "ideation.started", message: "<feature title>" })`.
21
21
 
@@ -27,6 +27,7 @@ Interview the human about every aspect of the feature until you reach a genuinel
27
27
  - **Always recommend an answer.** Never ask a bare question — put your recommended answer to it and say why. The human corrects or confirms.
28
28
  - **Look up facts; ask only for decisions.** If a fact is discoverable in the codebase — how something currently works, what a type looks like, whether a pattern already exists — read/grep the repo and find it. Never make the human be your grep. *Decisions* are theirs: put each one to them and wait.
29
29
  - **Model the domain as you go** (forked from domain-modeling): challenge terms that conflict with existing usage, sharpen fuzzy words to one canonical meaning ("you said 'account' — Customer or User?"), invent concrete edge-case scenarios that force precision, and cross-check claims against the actual code ("your code cancels whole Orders, but you just said partial — which is right?").
30
+ - **Probe the size early.** Within your first few questions, ask enough about scope to judge whether this is one-session-sized or map-sized — how many independent areas it touches, what has to be researched or prototyped before decisions can lock, how wide the design tree looks. Make that call up front, not thirty questions deep into one corner. If it smells map-sized, go to §3 *now* rather than rabbit-holing first.
30
31
 
31
32
  Do not move on until the human confirms you have reached shared understanding.
32
33
 
@@ -48,6 +49,8 @@ Every few locked decisions, `mcp__runcastle__record_event({ type: "decision.lock
48
49
 
49
50
  Some features are too big for one unbroken context. The tells: you are rabbit-holing into one corner while whole branches sit untouched; decisions keep hanging on material nobody has read yet (a prototype to build, a dependency to research, an area to grill on its own); the design tree has grown wider than you can hold and converge in this session. When that happens, **do not compact and do not grind on** — chart a map instead:
50
51
 
52
+ **Ask before you chart.** Escalation is a one-way door — there is no un-map path once charted. So the instant you judge a feature map-sized, put it to the human and *wait for a yes*: "This looks bigger than one session — I'd like to chart it into a waypoint map instead of grinding on here. Chart it?" **Never call `escalate_to_map` without that explicit confirmation.** If they say no, keep grilling. Only on a yes do the steps below run:
53
+
51
54
  1. `mcp__runcastle__escalate_to_map({ destination: "<the one-line north star>", notes: "<what's locked / constraints so far>" })`. This flips the feature to *mapped* and scaffolds `docs/features/<slug>/map.md`. If it warns that the feature is already mapped, that is fine — the map already exists; just proceed to chart the first batch.
52
55
  2. `mcp__runcastle__emit_waypoints({ waypoints: [...] })` for the **first batch** — the questions worth branching now. Each waypoint: `title`, `type` (`grilling` | `research` | `prototype` | `task`), `question` (what that session must answer), and `blockedBy` (1-based positions within this batch, and/or ids of already-stored waypoints) for ordering. Charting the first frontier is enough; later sessions branch the map further (any mapped session may `emit_waypoints`).
53
56
  3. `mcp__runcastle__record_event({ type: "map.charted", message: "<n> waypoints charted" })`.
@@ -63,12 +66,9 @@ When the human confirms shared understanding and the open questions are answered
63
66
 
64
67
  `mcp__runcastle__complete_phase({ phase: "ideation" })` → returns `{ ok, nextPhase }`. If `ok: false`, it names what the gate wants (e.g. `decisions.md` missing) — fix it and retry. Then `record_event({ type: "phase.completed", message: "ideation" })`.
65
68
 
66
- ## 5. Size branch — stay in this window
67
-
68
- Read `feature.size` from step 0:
69
+ ## 5. Spec → tickets — stay in this window
69
70
 
70
- - **`full`** → invoke `/runcastle:spec` (it writes `spec.md` and completes the `spec` phase); when it returns, invoke `/runcastle:tickets`.
71
- - **`collapsed`** → skip spec entirely; invoke `/runcastle:tickets` directly (it works from `decisions.md`).
71
+ Invoke `/runcastle:spec` (it writes `spec.md` and completes the `spec` phase); when it returns, invoke `/runcastle:tickets`.
72
72
 
73
73
  Do not open a new session for these. They run here, on top of everything you just learned.
74
74
 
@@ -23,6 +23,15 @@ The human came back: they remembered a constraint, changed their mind, or learne
23
23
  - `done` work now wrong → emit a NEW ticket that corrects it. Never touch done/burning tickets.
24
24
  5. **Close.** `mcp__runcastle__record_event({ type: "feature.revisited", message: "<one-line gist of what changed>" })`, then tell the human what state you left things in — especially whether a re-Burn is needed (pending tickets exist and the feature is at `implementation`).
25
25
 
26
+ ## Review iteration ("Iterate")
27
+
28
+ At the **review** phase this same session is surfaced as **Iterate**: the tickets were burned, the human test-drove the branch, and now they want to fix what they found. The moves are the same — docs, then ticket surgery — with a review flavour:
29
+
30
+ 1. **Read the outcome first.** `get_feature_context` carries the latest run outcome and every ticket's final state (done / failed / cancelled). Skim it before the interview so you know what already shipped and what failed.
31
+ 2. **Interview about the test drive.** Ask what they hit — bugs, rough edges, missing polish, follow-on tweaks. One concrete change per fix ticket.
32
+ 3. **Emit fix tickets.** New work → `emit_tickets`. If a just-burned ticket was wrong, emit a NEW fix ticket (never reopen `done` work). Reconcile stale pending tickets with `update_ticket` / `cancel_ticket`.
33
+ 4. **Hand back to Burn.** Do NOT advance the phase. When the cards are ready, tell the human to review them and click **Burn** — burning from review loops the feature back through implementation, and the run returns it to review when it finishes. The loop repeats until they click Merge & ship.
34
+
26
35
  ## Do NOT
27
36
 
28
37
  - **Never call `complete_phase`.** A revisit has no gates to cross; the human drives the pipeline from the UI.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spec
3
- description: Synthesize the ideation conversation and decisions.md into docs/features/<slug>/spec.md, then complete the spec phase. No interview — pure synthesis. Invoked by /runcastle:ideate for size=full features.
3
+ description: Synthesize the ideation conversation and decisions.md into docs/features/<slug>/spec.md, then complete the spec phase. No interview — pure synthesis. Invoked by /runcastle:ideate.
4
4
  disable-model-invocation: false
5
5
  ---
6
6
  <!-- Forked from Matt Pocock's to-spec skill, via https://github.com/mattpocock/skills, 2026-07-14, adapted for runcastle -->
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: tickets
3
- description: Break the spec (or decisions.md when collapsed) into tracer-bullet vertical slices, each self-sufficient for one fresh sandboxed agent, and emit them via MCP. Then complete the tickets phase. Invoked by /runcastle:ideate.
3
+ description: Break the spec into tracer-bullet vertical slices, each self-sufficient for one fresh sandboxed agent, and emit them via MCP. Then complete the tickets phase. Invoked by /runcastle:ideate.
4
4
  disable-model-invocation: false
5
5
  ---
6
6
  <!-- Forked from Matt Pocock's to-tickets skill, via https://github.com/mattpocock/skills, 2026-07-14, adapted for runcastle -->
7
7
 
8
8
  # Tickets
9
9
 
10
- Break the work into **tickets** — tracer-bullet vertical slices — and emit them to the runcastle store via `mcp__runcastle__emit_tickets`. You are still in the unbroken ideation window: synthesize from the spec (`docs/features/<slug>/spec.md`) or, for collapsed features, straight from `decisions.md`. Do not compact or clear.
10
+ Break the work into **tickets** — tracer-bullet vertical slices — and emit them to the runcastle store via `mcp__runcastle__emit_tickets`. You are still in the unbroken ideation window: synthesize from the spec (`docs/features/<slug>/spec.md`). Do not compact or clear.
11
11
 
12
12
  ## The one thing that makes a runcastle ticket different
13
13