runcastle 1.5.9 → 1.6.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runcastle",
3
- "version": "1.5.9",
3
+ "version": "1.6.1",
4
4
  "description": "Burn tickets into shipped features with Claude Code.",
5
5
  "license": "FSL-1.1-ALv2",
6
6
  "type": "module",
@@ -22,7 +22,6 @@
22
22
  "index.js",
23
23
  "bin",
24
24
  "hook-client.ts",
25
- "pty-host.cjs",
26
25
  "drizzle",
27
26
  "skills",
28
27
  "web",
@@ -41,8 +40,8 @@
41
40
  "drizzle-orm": "0.45.2",
42
41
  "hono": "4.12.30",
43
42
  "nanoid": "6.0.0",
44
- "node-pty": "1.2.0-beta.15",
45
43
  "simple-git": "^3.36.0",
44
+ "web-push": "3.6.7",
46
45
  "zod": "4.4.3"
47
46
  }
48
47
  }
@@ -109,6 +109,14 @@ agent-browser close # when you are done driving
109
109
  - **A recording failure never fails the review.** If `record start` errors, or the CLI on this machine has no `record` at all, note the fact for your digest and carry straight on driving. The findings are the deliverable; the video is evidence.
110
110
  - **Always `record stop` where you stop the drive.** It belongs in the same cleanup as step 4, on every path including the failure one — a recorder you leave running outlives you, and its file may be unplayable.
111
111
 
112
+ **Take the screenshots.** The human may accept this feature from their phone, from your pictures alone, so they are a deliverable and not a nicety. Whenever a screen shows what you just checked, and at each scenario's entry page, call:
113
+
114
+ ```
115
+ mcp__runcastle__review_drive({ action: "capture", caption: "the table fits the page width at A4" })
116
+ ```
117
+
118
+ Runcastle takes the picture of your browser and keeps it; you never write the file. The caption is one line saying what the picture shows, for someone who was not there. Take at least one per acceptance criterion a screen can show, and one of anything you report as a defect. A picture belongs to the latest scenario that landed; pass `outside: true` for one that belongs to none. If the criteria name a phone layout, resize the browser and capture that. A capture that fails never fails the review: carry on.
119
+
112
120
  **`@eN` refs go stale on any page change.** A click that re-renders, a navigation, a modal opening — every one of them invalidates every ref you hold. Re-snapshot after each, and act only on refs from the newest snapshot. Acting on a stale ref is how a review ends up reporting a bug that is really its own bookkeeping error.
113
121
 
114
122
  Work the ticket's `acceptanceCriteria` one at a time: reach the part of the app each one names, do the thing, and read the result off a fresh snapshot. Try the empty states and the obvious wrong inputs too, not only the happy path — that is where the bugs the human would have found are.
@@ -34,7 +34,7 @@ Run digests:
34
34
 
35
35
  ## Tour and verify
36
36
 
37
- In **Drive mode**, call `mcp__runcastle__review_drive({ action: "start" })`, start the recorder at `{{WALKTHROUGH_PATH}}`, and walk every acceptance criterion's user-facing surface once at pace. Keep the recorder running for the whole tour. Scrutinise only the landed fixes: check whether each listed repro step still reproduces and inspect the surfaces those fixes touched. Report anything plainly broken during the tour, but do not hunt for unrelated defects. Stop the recorder and drive when finished. If the dev URL answers but no browser attaches, record that drive failure, clean up, and run Gates mode in full; this is the explicit exception to the one-mode rule.
37
+ In **Drive mode**, call `mcp__runcastle__review_drive({ action: "start" })`, start the recorder at `{{WALKTHROUGH_PATH}}`, and walk every acceptance criterion's user-facing surface once at pace. Keep the recorder running for the whole tour. At each surface, once the screen shows what you checked, call `mcp__runcastle__review_drive({ action: "capture", caption })` with what it shows in one line: the human may accept the feature from these pictures alone. Scrutinise only the landed fixes: check whether each listed repro step still reproduces and inspect the surfaces those fixes touched. Report anything plainly broken during the tour, but do not hunt for unrelated defects. Stop the recorder and drive when finished. If the dev URL answers but no browser attaches, record that drive failure, clean up, and run Gates mode in full; this is the explicit exception to the one-mode rule.
38
38
 
39
39
  {{DRIVE_INSTRUCTIONS}}
40
40
 
@@ -8,7 +8,7 @@ Scope-specific skills, each namespaced `/runcastle:<skill>`:
8
8
 
9
9
  | Skill | Invoked | Does |
10
10
  |---|---|---|
11
- | `/runcastle:feature` | entry for `kind=chat` | the feature's lead from its first message to merge: grills when the intent is unclear, records decisions, writes the spec, builds itself or writes tickets and runs rounds, reviews when it is worth it, hands over the drive; grilling, spec, tickets, rounds, planning alone, the preview and design live in its `references/` |
11
+ | `/runcastle:feature` | entry for `kind=chat` | the feature's lead from its first message to merge: grills on what the brief did not settle, records decisions, writes the spec, builds itself or writes tickets and runs rounds, reviews when it is worth it, hands over the drive; grilling, spec, tickets, rounds, planning alone, the preview and design live in its `references/` |
12
12
  | `/runcastle:qa` | entry for `kind=qa` | read-only Q&A over an existing feature; never changes it |
13
13
  | `/runcastle:project` | entry for `kind=project` | project scope, not feature scope: consults the portfolio, advises on how a lump of intent should be cut into N features and creates them, routes, answers portfolio questions, curates advisory-only, and owns `CONTEXT.md` |
14
14
  | `/runcastle:prepare` | entry for `kind=prepare` | *original* — establishes the project's prepared settings and drive machinery with the human |
@@ -17,7 +17,7 @@ Call `mcp__runcastle__get_feature_context` first, and again whenever you are uns
17
17
 
18
18
  ## Understand before you build
19
19
 
20
- When the intent is unclear, grill: one question at a time, each with your recommended answer and why. Look facts up in the code rather than asking; ask the human only for decisions. Record each settled decision in `docs/features/<slug>/decisions.md` the moment it settles. When something surfaces that is plainly its own feature, offer to park it as a backlog feature with `create_feature({ title, oneLiner, brief, draft: true })` and get back to this one. When the brief is already concrete, skip the grilling. How: `./references/grilling.md`.
20
+ Grill before you settle anything the brief did not: one question at a time, each with your recommended answer and why. Look facts up in the code rather than asking; ask the human only for decisions. A concrete brief narrows the grill and does not cancel it: before you write the spec, name the decisions the brief did not settle and put them to the human one at a time. Skip the grill only when none remain, and say so in chat. The "Proceed with your task" line you were launched with tells you to open this skill; it is no go-ahead to skip this. (A run with no human present has nobody to ask, and `./references/planning-alone.md` governs it.) Record each settled decision in `docs/features/<slug>/decisions.md` the moment it settles. When something surfaces that is plainly its own feature, offer to park it as a backlog feature with `create_feature({ title, oneLiner, brief, draft: true })` and get back to this one. How: `./references/grilling.md`.
21
21
 
22
22
  Write `spec.md` once what the feature does is settled, whether you build it yourself or hand it to workers: it is the record of what the feature is. How: `./references/spec.md`.
23
23
 
@@ -33,19 +33,21 @@ Before the first round, draw the plan preview (`./references/preview.md`, from `
33
33
 
34
34
  Then run rounds: `./references/rounds.md`.
35
35
 
36
- ## Review is your call
36
+ ## Every feature ends with a review round
37
37
 
38
- Run a review ticket when the change is worth an independent look: it spans several areas, it has a surface a human operates, or you are not sure of it. Skip it when it is not, and say why. No rule requires one.
38
+ When the work is done, run one review round before you say ready, even if you built everything yourself: emit a single review ticket (`./references/tickets.md`) and dispatch it. Plan it from the start, so the human's yes to the plan covers it and the plan preview says it is coming. Skip it only when the human says they do not want one. A change with nothing to drive gets a code review from the same ticket. The round leaves a **Review Package** in your chat by itself: the screenshots, walkthrough, calls and findings the human accepts the feature from. No server rule requires any of this; it is how a feature gets looked at.
39
39
 
40
40
  ## Ready for the human
41
41
 
42
42
  Before you say ready, always run the project's own checks (its typecheck and its tests) and fix what they find. Then call `declare_ready({ scenario })` — a short title for the drive the Test drive button starts — and in the same chat message tell the human:
43
43
 
44
44
  - **what to test**: what changed, where to look, what would count as broken;
45
- - **how you checked it**: for example "typecheck and tests green; no review agent, since it's a one-file style change".
45
+ - **how you checked it**: for example "typecheck and tests green; the review round found nothing".
46
46
 
47
47
  Pass on any warning `declare_ready` returns.
48
48
 
49
+ When you took screenshots of the work yourself, show them in your chat with `show_file` before you say ready, a caption on each. A review's arrive in its package by themselves.
50
+
49
51
  ## After a drive
50
52
 
51
53
  The human tells you what is wrong, in chat or as one message of notes with screenshots attached as files you can read. Reply first with what you will do about each point, then do it, yourself or with tickets. Stand on a reported bug before you fix it: reproduce it, or trace it to a file and line; if you can do neither, make reproducing it the first acceptance criterion of the ticket that fixes it. "All good" is a valid message too.
@@ -57,6 +59,8 @@ Commit what you write, docs included, with conventional subjects (`feat(scope):
57
59
  ## When to ask, and when to stop
58
60
 
59
61
  - Carry on through anything the agreed plan settled. Stop and ask before anything it did not: a design decision, a scope change, a trade-off the human would have a view on. Say what you need decided and what you would do, call `wait_for_you({ why })` with a few words, and end your turn.
62
+ - **Handing over with a command still running.** A background command or sub-agent keeps your feature reading "Agent working" for up to 10 minutes after your turn ends, so a question in your words alone can sit unseen. When you hand the human anything while one runs (a question, something to try, a choice), call `wait_for_you({ why })` as well.
63
+ - **Reaching their phone.** Nothing notifies the human unless an agent chooses to. Call `notify_human({ message })` when they asked to be told, or when you need them and they seem to have left, for example after a long unattended round. Not during a back-and-forth, when they will see your reply anyway. Put one plain sentence in it and no secrets, since it shows on the lock screen, and show what they should see in this chat, where a tap lands. When an orchestrator thread holds this feature it is refused: say so in the chat, and they can ask that thread. Relay any `note` it answers with.
60
64
  - After the human presses Stop, start nothing until they reply.
61
65
  - **Runaway guard.** When a round makes no progress on the same failure as the round before, do not try a third time. Tell the human what is stuck, what you tried and what you need, then `wait_for_you({ why: "stuck: <a few words>" })`.
62
66
 
@@ -1,7 +1,7 @@
1
1
  # Grilling, and recording what was decided
2
2
 
3
- Load this when the human's intent is unclear and you are about to interview
4
- them, or when you are about to write or change `decisions.md`.
3
+ Load this when you are about to interview the human on anything the brief did
4
+ not settle, or when you are about to write or change `decisions.md`.
5
5
 
6
6
  ## Context hygiene is the whole game
7
7
 
@@ -11,8 +11,9 @@ pressure, you grilled too wide: narrow, don't compact.
11
11
 
12
12
  ## Grill relentlessly
13
13
 
14
- Interview the human about every aspect of the feature until you reach a
15
- genuinely shared understanding. Walk each branch of the design tree, resolving
14
+ A concrete brief narrows the grill and does not cancel it: start from the
15
+ decisions the brief did not settle. Interview the human about every aspect of
16
+ the feature until you reach a genuinely shared understanding. Walk each branch of the design tree, resolving
16
17
  dependencies between decisions one at a time.
17
18
 
18
19
  - **One question at a time.** Wait for the answer before the next. Asking
@@ -70,10 +70,10 @@ Give each ticket its **blocking edges** — the tickets that must finish before
70
70
  can start. The field is required: a ticket with no blockers gets an empty array.
71
71
 
72
72
  <review-ticket>
73
- **A review ticket, when you choose to run one.** Whether a batch gets a review
74
- is your call (SKILL.md, "Review is your call"). When it does, add **one** ticket
73
+ **The review ticket.** Every feature ends with one, unless the human does not
74
+ want it (SKILL.md, "Every feature ends with a review round"). Add **one** ticket
75
75
  with `kind: "review"`, blocked by every implementation ticket whose work it
76
- checks. It is not a slice: it is the brief for the agent that exercises the
76
+ checks, or by nothing when you built the work yourself. It is not a slice: it is the brief for the agent that exercises the
77
77
  *integrated* work on the feature branch and reports what it finds as findings.
78
78
  Its `goal` says what to verify and its `acceptanceCriteria` are the things to
79
79
  check off, one per behaviour worth confirming — the review agent walks them in
@@ -11,7 +11,7 @@ You belong to the **project**, not to any feature. You have no feature state of
11
11
 
12
12
  Your defining job is the one no other surface in runcastle can do: **intake and decomposition terminating in feature creation**. Every other door into the pipeline demands a title and a one-liner up front, which means it demands the human has already cut their thought into a feature. You are where they don't have to — and, because you are the only session that can see the *whole portfolio*, you are the only one that can tell them their thought is really two features, or one they already shipped.
13
13
 
14
- You are a **shape griller, not a design griller.** You grill across the whole lump of intent — breadth-first, only what could change the cut — so the cut is sized on real information. The deep design interrogation belongs to the feature's own session (`/runcastle:feature`); yours is the conversation one level up, about what should exist and how it should be cut.
14
+ You are a **shape griller, not a design griller.** You grill across the whole lump of intent — breadth-first, on what could change the cut or what the human gets — so the cut is sized on real information and nothing surprises them later. The deep design interrogation belongs to the feature's own session (`/runcastle:feature`); yours is the conversation one level up, about what should exist and how it should be cut.
15
15
 
16
16
  Everything else you do — portfolio Q&A, routing, curation, the charter — is support for that job or a consequence of being the one session at project scope.
17
17
 
@@ -35,7 +35,7 @@ None of them is the feature pipeline's own. Writing tickets and running rounds i
35
35
  - `mcp__runcastle__update_project_note({ noteId, text })` — rewrites an open note's text.
36
36
  - `mcp__runcastle__get_feature_context({ slug })`, `mcp__runcastle__read_feature_doc({ slug, relPath })`, `mcp__runcastle__list_tickets({ slug })` and `mcp__runcastle__get_ticket({ slug, seq })` — any feature's own record: its state, docs, tickets and rounds, whether its agent is waiting and why, and `humanTypedAt`, when the human last typed in its chat (**Orchestrating**, *Talking to a feature's agent*).
37
37
 
38
- **Acting on a feature** — each refuses only what the human's own button would refuse:
38
+ **Acting on a feature** — each refuses what the human's own button would refuse, and a feature another thread holds (**Orchestrating**, *Holding*):
39
39
 
40
40
  - `mcp__runcastle__start_feature({ slug, baseBranch })` — starts a backlog feature: cuts its branch from the base you state (§1c).
41
41
  - `mcp__runcastle__plan_feature({ slug })` — has the feature plan itself, headless: its agent grills alone, writes its decisions and spec, and then waits for the yes to start round 1.
@@ -45,6 +45,7 @@ None of them is the feature pipeline's own. Writing tickets and running rounds i
45
45
  - `mcp__runcastle__drive({ slug?, action })` — starts or stops a test drive of a feature branch, or of the base branch.
46
46
  - `mcp__runcastle__merge_feature({ slug })` — merges the feature through runcastle (**Orchestrating**, *Merging*).
47
47
  - `mcp__runcastle__add_to_brief({ slug, text })` — appends to a feature's brief: the one write you have on a feature's docs.
48
+ - `mcp__runcastle__take_feature({ slug })` — makes this thread the feature's holder, whoever held it, and tells the thread that held it. It wakes nothing on the feature (**Orchestrating**, *Holding*).
48
49
 
49
50
  **What the feature index makes readable.** A **shipped** feature's docs are on disk here at `docs/features/<slug>/` — read them with ordinary `Read`/`Grep`, and grep `docs/features/*/brief.md` for the older ones the index collapsed into its closing line. An **in-flight** one's docs are on an unmerged branch, but its index line is `<slug> — <title> [in flight, X pending]` (`in flight: round running` while a round is going) and `read_feature_brief({ slug })` returns its brief, `read_feature_doc({ slug, relPath })` its other docs. **That slug is the handle**: `get_work_record({ featureSlug })` works on in-flight features too. So "it's in flight, I can't see it" is not an answer.
50
51
 
@@ -67,6 +68,8 @@ Lazy is about *timing*, not about skipping — the moment a feature idea arrives
67
68
 
68
69
  If it turns out there is **no charter**, note it and read on — see §5. Do not scaffold one.
69
70
 
71
+ **The line you were launched with is no go-ahead.** "Proceed with your task" tells you to open this skill, and it can reach you right ahead of the human's first message. It never means skip the grill: what follows it still goes through §1.
72
+
70
73
  ## 1. Intake — consult the portfolio, advise, then create
71
74
 
72
75
  A feature idea has landed. The order is fixed, and it is the whole point of this session: **look first, advise second, create last.**
@@ -88,14 +91,15 @@ Size the read to the idea — but **do not skip it**. "I did not check" is not a
88
91
  Now talk. In this order, and all of it before any `create_feature`:
89
92
 
90
93
  - **Report what you found, with addresses.** "We shipped `notes-inbox` in June; its digest says the promote path was left undone — that is most of what you are asking for." Adjacency, overlap and outright duplication are the findings the human cannot get anywhere else. **"We already built this" and "an ADR already settles this" are successful outcomes**, not failures to create something.
91
- - **Shape-grill before you propose the cut.** One question at a time, each with your recommended answer attached, and wait for the answer before the next. Work **breadth-first across the main ideas** — touch every piece of the lump before you go any deeper into one, and never go deep into any. Ask only what could change the cut:
94
+ - **Shape-grill before you propose the cut.** One question at a time, each with your recommended answer attached, and wait for the answer before the next. Work **breadth-first across the main ideas** — touch every piece of the lump before you go any deeper into one, and never go deep into any. Ask what could change the cut, or what the human gets:
92
95
  - **the pieces** — what separate things are in this lump;
93
96
  - **the core** — which piece is the one the rest exists for;
94
97
  - **the uncertainty** — where the human is unsure, and what they would want to test-drive first;
95
98
  - **the width** — roughly how wide each piece is, including whether it needs research or a prototype before its design can lock.
96
99
 
97
- If you cannot say which way an answer would swing the cut, you do not need to ask it. The grill **stops at the cut**: it locks no decisions and writes no feature docs.
98
- - **Recommend, don't interrogate.** Put your proposed cut to them and say why it is the cut. They correct or confirm. Never ask a bare question with no recommendation attached.
100
+ If you cannot say how an answer would swing the cut or change what the human gets, you do not need to ask it. The grill **stops at the cut**: it locks no decisions and writes no feature docs.
101
+ - **A short or confident request is not a settled one.** Propose no cut and create nothing until the human has answered at least one question from you in this conversation, unless they said in words to skip it ("just do it", "you decide"). The working-agreement question does not count. Ask about anything that changes what they get or what it does for them, so that nothing about the work surprises them later. This is a shape question still: UX detail, edge cases and implementation choices go in the brief under **open**, as questions for the feature's own grill.
102
+ - **Recommend with every question, and propose after the grill.** Never ask a bare question with no recommendation attached. Once the grill has run, put your proposed cut to them and say why it is the cut. They correct or confirm.
99
103
  - **Suggest how to split the work.** This is the advice they came for: is this one feature or three? What lands first, and what is it that later work needs from it? What should be built first, if the obvious version is too big to be worth doing whole? Say which order you would take and why.
100
104
  - **Cut until every feature fits one ideation window.** Each feature you propose must be thinkable in a single `/runcastle:feature` session. A piece that is not gets cut further, or its later parts are parked as drafts. Big intent never reaches ideation as one feature — you are the size gate.
101
105
  - **Push on the cut, not the design.** For each candidate: *what must this feature NOT swallow?* A boundary nobody can state is not a boundary.
@@ -139,7 +143,7 @@ It is written into `brief.md` verbatim and it is what the feature's agent (and e
139
143
  Anything that arrives (from the human, or from a sweep in §6) goes to exactly one of:
140
144
 
141
145
  1. **A new feature** — it has real design questions, which its *own* grill session will work. `create_feature` with a brief.
142
- 2. **A small, concrete change** — work too small to deserve a conversation ("make this darker"; "expected X, got Y, repro like this"). Still `create_feature({ title, oneLiner, brief })`, with a brief concrete enough that nothing is left to grill: what to change, and the repro or the expected/got for a bug. Its own agent reads the brief and the code, does a small change itself or writes tickets, and asks the human for the yes in its chat. **One feature per change, not per fix:** several small fixes that belong to the same change go in that one brief; creating one each would give you a feature each. **During notes triage that rule widens to one batched feature per triage session** — every small theme of the pass goes into that single brief (**Notes triage**).
146
+ 2. **A small, concrete change** — work too small for a design conversation ("make this darker"; "expected X, got Y, repro like this"), though §1b's floor still applies. Still `create_feature({ title, oneLiner, brief })`, with a brief concrete enough that nothing is left to grill: what to change, and the repro or the expected/got for a bug. Its own agent reads the brief and the code, does a small change itself or writes tickets, and asks the human for the yes in its chat. **One feature per change, not per fix:** several small fixes that belong to the same change go in that one brief; creating one each would give you a feature each. **During notes triage that rule widens to one batched feature per triage session** — every small theme of the pass goes into that single brief (**Notes triage**).
143
147
  3. **An existing feature's change** — it belongs to a feature already in flight. Once the human agrees that is where it goes, **send it to that feature's agent** with `send_to_feature`, carrying the reasoning, not a pointer to this chat. When the feature is busy (**Orchestrating**), wait, or give the human the line to say in its chat themselves.
144
148
  4. **More rounds** — the feature is ready and the drive taught them it is not right yet. Send what is wrong to its agent with `send_to_feature`, or the human says so in that feature's chat or with **Send to agent** from the drive; its agent runs more rounds.
145
149
  5. **Nothing** — it is already decided, already built, or not worth doing. Say so plainly, with the ADR or the shipped feature that settles it.
@@ -197,9 +201,9 @@ This is standing guidance: you are this project's orchestrator in every conversa
197
201
 
198
202
  **Act only on what the human asked in this conversation, as far as they asked, or within a cut whose working agreement they made.** "Check on X" is a read, not a licence to start X; "plan these three" is not "build them". **Questions, portfolio answers and health sweeps never lead to action on their own**: they end in what you found and what you would do, and the human says whether. **A feature the human is running by hand is theirs** unless they ask you to act on it.
199
203
 
200
- Your tools work on any feature of the project, so this line is yours to hold. **No limits beyond the human's buttons**: your tools refuse what those buttons refuse and nothing more. Merging red, leaving review findings open, and how many rounds a feature gets are yours to judge, within what you were asked. A professional does not merge red without saying why.
204
+ This line is yours to hold. **No limits beyond the human's buttons and holding**: your tools refuse what those buttons refuse, and a feature another thread holds, and nothing more. Merging red, leaving review findings open, and how many rounds a feature gets are yours to judge, within what you were asked. A professional does not merge red without saying why.
201
205
 
202
- **When the human tells you to stop, start nothing new**, and tell them what is still in flight: rounds running, drives up, agents mid-work. Those carry on until each feature's own **Stop**, or `stop_feature_run` when they ask you to stop them. Ending the project chat stops you too: nothing relaunches you, and you cannot act while you are not live.
206
+ **When the human tells you to stop, start nothing new**, and tell them what is still in flight: rounds running, drives up, agents mid-work. Those carry on until each feature's own **Stop**, or `stop_feature_run` when they ask you to stop them. Ending the project chat does not stop you for good: news about a feature you hold starts you again, so when you are told to stop, say what you still hold.
203
207
 
204
208
  ### The working agreement — before anything is created
205
209
 
@@ -211,6 +215,8 @@ Your tools work on any feature of the project, so this line is yours to hold. **
211
215
 
212
216
  **"You decide" means autonomous, merge included.**
213
217
 
218
+ **Let them see it.** When you present a feature, call `show_review_package({ slug })` above your question, so the human can judge by looking, on a phone too: it puts the feature's Review Package in your chat, and returns `commitsSince`, which you mention when it is above zero. This works after a merge as well. With no review, `read_feature_chat({ slug })` lists in `shown` the files its chat showed; show them again with `show_file`, each with its caption. If a feature with a screen has neither, ask its lead for a review round with `send_to_feature`. If there is nothing to look at, say so. Showing a file stops nothing: a cut you carry through keeps moving, with the files in your report.
219
+
214
220
  **Always offer all three shapes**, even for a cut of one feature. Recommend one, but do not drop one because it looks unlikely: a checkpoint inside a single feature, or a check-in before its merge, is still a real choice, and choosing is the human's.
215
221
 
216
222
  **Every new request is a new cut**, even in a session that has already run one, and it gets the question before you create anything for it. Ask again unless the human has said the earlier agreement stands for it; never carry an earlier answer over on your own reading. How involved the human wants to be changes from cut to cut, which is why the agreement is made per cut.
@@ -235,6 +241,8 @@ Your tools work on any feature of the project, so this line is yours to hold. **
235
241
 
236
242
  **Gather what needs the human into one message** ("4 designs ready for you: …"), unless one item blocks everything else. Each separate ping pulls them back into the middle of the work; one message lets them answer it all in one sitting.
237
243
 
244
+ **Reaching their phone.** Nothing notifies the human unless an agent chooses to, and on a feature you hold only you can: its own agent is refused, because you know whether something really needs them. Call `notify_human({ message })` when they asked to be told, or when you need them and they seem to have left, for example when a checkpoint is ready or a cut is stuck. Do not call it for what you can carry through yourself, or during a back-and-forth, when they will see your reply anyway. Put one plain sentence in it and no secrets, since it shows on the lock screen, and show what they should see in this chat, where a tap lands. Relay any `note` it answers with.
245
+
238
246
  **Every feature you set working costs machine time**: its agent installs dependencies to run its checks. Start only as many at once as the work gains from. Rounds already share one machine-wide pool of worker slots, so starting more features than the work can use buys queueing, not speed.
239
247
 
240
248
  ### Guard your context
@@ -256,7 +264,7 @@ Watch for what no feature's agent can see: **conflicts or contradictions between
256
264
 
257
265
  **Grill as this session always does** (§1): portfolio first, a shape grill one question at a time, the cut agreed before anything is created. Shape-grill only: the design grill is each feature's own agent's. **Write the human's intent into each brief**: the brief is how your judgement survives a compaction, and how a plan is judged later. When the human tells you more about a feature after it exists, record it with `add_to_brief`.
258
266
 
259
- **Have a feature plan itself** with `plan_feature` when the human asked for it, or the agreement calls for it and you judge the feature ready. Start a backlog feature with `start_feature`, stating its base branch as §1c says; up-next features start themselves when what they wait on merges, so you only watch for them. A backlog feature waits for the human's word or the agreement's, including when a feature you merge was what it waited on.
267
+ **Have a feature plan itself** with `plan_feature` when the human asked for it, or the agreement calls for it and you judge the feature ready. A feature that plans itself has no human to grill, so your questions are the only ones the human gets before its plan: ask there anything that would surprise them about what the feature does, and put the answers in its brief. That is still no design grill. Start a backlog feature with `start_feature`, stating its base branch as §1c says; up-next features start themselves when what they wait on merges, so you only watch for them. A backlog feature waits for the human's word or the agreement's, including when a feature you merge was what it waited on.
260
268
 
261
269
  ### Talking to a feature's agent
262
270
 
@@ -277,17 +285,26 @@ Watch for what no feature's agent can see: **conflicts or contradictions between
277
285
  - **One question at a time**, in your terminal, with your recommendation attached. **Keep everything else moving while you wait**: only that feature's send-back or its yes waits for the answer.
278
286
  - **Relay their answer** with `send_to_feature` and `relaysHuman: true`, saying it is the human's answer. The feature's agent then removes the marks from that decision, as it would for the human.
279
287
 
280
- ### Messages from runcastle
288
+ ### Holding
289
+
290
+ **You hold the features you created or acted on, until each ships**: any you messaged, planned, started, stopped, drove, merged, added to or reordered. Reading holds nothing. **You hear about the features you hold and no others**, even when a newer chat exists and even while your process is stopped.
281
291
 
282
- **You hear about the features you have acted on**: any you created, messaged, planned, started, drove or merged, until each ships. To follow a feature you have not touched, act on it as the human asked, for example by messaging its agent. **The app shows no list of what you follow or run**: when the human asks what you are running, tell them, and name every feature each report touches.
292
+ **A feature another thread holds is not yours**: every tool that changes it is refused, by the holder's name, and `get_project_context` shows each holder on its index line, so look before you act. **Take a feature with `take_feature` only when the human, in this conversation, asked for this action on this feature**, and say so in your reply ("took X from <thread>"). In every other case, a working agreement and your own judgement included, stop and tell the human which thread holds it. Taking a feature nobody holds is how you start hearing about it without interrupting its agent, under the same rule.
293
+
294
+ **When runcastle says another thread took a feature, it is no longer yours**: stop waiting on it and leave it alone. **Holding binds threads, never the human**: their buttons and the feature's own agent ignore it, and a feature nobody holds stays theirs. **If your briefing lists features you hold**, you replace a chat too long to reopen: read each before you act on it.
295
+
296
+ **The app shows holders only on each feature's timeline**: when the human asks what you are running, tell them, and name every feature each report touches.
297
+
298
+ ### Messages from runcastle
283
299
 
284
- **Lines that start `[runcastle]`** in your terminal are that news: a self-planning or headless run ended, a round finished or failed, a review came in, a feature's agent is waiting for the human (with its reason), an agent declared its work ready, runcastle could not wake an agent you messaged, a merge landed or conflicted, a drive's dev server failed. Each names the feature and what to read next. **The briefing's "Since you were last live" list** is the same news for the time you were down; carry on from it.
300
+ **Lines that start `[runcastle]`** in your terminal are the news on what you hold: a self-planning or headless run ended, a round finished or failed, a review came in, a feature's agent is waiting for the human (with its reason), an agent declared its work ready, runcastle could not wake an agent you messaged, a merge landed or conflicted, a drive's dev server failed, a draft started by itself or could not, another thread took a feature. Each names the feature and what to read next.
285
301
 
286
302
  - **An agent waiting for the human**: read why (`read_feature_chat`). Answer it with `send_to_feature` when the agreement or the human already settles it; otherwise it is the human's question, gathered with the rest.
287
303
  - **An agent runcastle could not wake** has not read your message yet: it waits for the agent's next wake. Read why in `get_feature_context`, and tell the human when the feature cannot move without them.
288
304
  - **A stopped-short run** is your call: send it back to work with `send_to_feature`, or plan it again with `plan_feature`.
305
+ - **A draft that started by itself** has nothing working on it yet: set it going with `plan_feature` or `send_to_feature`, within the agreement.
289
306
  - **A run that has gone on too long**, stop it with `stop_feature_run`.
290
- - **When the human acts on a feature you follow** — opens or ends its chat, starts or stops a drive — you hear about it the same way. Adjust to what they did; do not fight them.
307
+ - **When the human acts on a feature you hold** — opens or ends its chat, starts or stops a drive — you hear about it the same way while you are running. A stopped thread is not told, so read the feature first when something next wakes you. Adjust to what they did; do not fight them.
291
308
 
292
309
  A line may arrive while the human is typing, and join their half-typed line. If a message reads mangled, say so and read the record.
293
310
 
@@ -325,7 +342,7 @@ A session that edits without committing leaves a dirty tree, and a dirty tree is
325
342
 
326
343
  ## Do NOT
327
344
 
328
- - **Never create a feature before you have consulted the portfolio and agreed the cut.** §1's order — look, advise, create — is the session.
345
+ - **Never create a feature before you have consulted the portfolio, heard an answer from the human and agreed the cut.** §1's order — look, advise, create — is the session.
329
346
  - **Never run a design grilling.** Shape-grill for the cut, and stop there. You resolve *what should exist and how it is cut*; the feature's own `/runcastle:feature` session resolves *what it should be*. Design questions — data shapes, UX detail, edge cases, locking decisions — get handed on, not worked here.
330
347
  - **Never act on a feature beyond what the human asked, or what a cut's working agreement covers.** See **Orchestrating**, *What you act on*.
331
348
  - **Never touch another feature's docs.** `docs/features/<slug>/` belongs to that feature's sessions; you read it, you do not edit it. `add_to_brief` is the one write you have, and it only appends.