runcastle 1.6.2 → 1.6.4
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/README.md +4 -4
- package/bin/runcastle.js +13202 -61413
- package/drizzle/0057_jazzy_lila_cheney.sql +1 -0
- package/drizzle/0058_test_note_open_only.sql +9 -0
- package/drizzle/0059_milky_black_knight.sql +17 -0
- package/drizzle/0060_drop_prepare_sessions.sql +6 -0
- package/drizzle/0061_events_type_index.sql +4 -0
- package/drizzle/0062_workers.sql +30 -0
- package/drizzle/0063_worker_dev_server.sql +1 -0
- package/drizzle/0064_worker_tokens.sql +1 -0
- package/drizzle/0065_review_workers.sql +28 -0
- package/drizzle/0066_drive_workers.sql +39 -0
- package/drizzle/meta/0057_snapshot.json +1351 -0
- package/drizzle/meta/0059_snapshot.json +1461 -0
- package/drizzle/meta/0062_snapshot.json +1654 -0
- package/drizzle/meta/0063_snapshot.json +1662 -0
- package/drizzle/meta/0064_snapshot.json +1669 -0
- package/drizzle/meta/0065_snapshot.json +1690 -0
- package/drizzle/meta/0066_snapshot.json +1704 -0
- package/drizzle/meta/_journal.json +70 -0
- package/index.js +12480 -60694
- package/package.json +2 -3
- package/skills/packs/README.md +11 -15
- package/skills/packs/runcastle/.claude-plugin/plugin.json +1 -1
- package/skills/packs/runcastle/skills/code-review/SKILL.md +3 -3
- package/skills/packs/runcastle/skills/feature/SKILL.md +37 -18
- package/skills/packs/runcastle/skills/feature/references/design.md +102 -127
- package/skills/packs/runcastle/skills/feature/references/grilling.md +9 -3
- package/skills/packs/runcastle/skills/feature/references/planning-alone.md +69 -38
- package/skills/packs/runcastle/skills/feature/references/preview-starter.html +22 -20
- package/skills/packs/runcastle/skills/feature/references/preview.md +45 -27
- package/skills/packs/runcastle/skills/feature/references/spec.md +1 -1
- package/skills/packs/runcastle/skills/feature/references/workers.md +144 -0
- package/skills/packs/runcastle/skills/project/SKILL.md +64 -201
- package/skills/packs/runcastle/skills/project/references/charter.md +3 -3
- package/skills/packs/runcastle/skills/project/references/health-sweeps.md +3 -3
- package/skills/packs/runcastle/skills/project/references/intake.md +139 -0
- package/skills/packs/runcastle/skills/{prepare/references/recipes.md → project/references/preparation-recipes.md} +2 -2
- package/skills/packs/runcastle/skills/project/references/preparation.md +176 -0
- package/skills/packs/runcastle/skills/project/references/routing.md +39 -0
- package/skills/packs/runcastle/skills/project/references/triage.md +3 -3
- package/skills/packs/runcastle/skills/qa/SKILL.md +5 -7
- package/skills/review/review-drive.md +33 -0
- package/skills/review/review-gates.md +22 -0
- package/skills/review/review.md +61 -0
- package/skills/review/verify.md +31 -0
- package/web/assets/index-C0TYj0Ka.css +1 -0
- package/web/assets/index-C6JVtDiw.js +193 -0
- package/web/index.html +3 -3
- package/web/manifest.webmanifest +2 -2
- package/web/sw.js +4 -4
- package/skills/burner/implement-ticket.md +0 -118
- package/skills/burner/resolve-conflict.md +0 -78
- package/skills/burner/review-ticket.md +0 -268
- package/skills/burner/verify-fixes.md +0 -59
- package/skills/packs/runcastle/skills/feature/references/rounds.md +0 -97
- package/skills/packs/runcastle/skills/feature/references/tickets.md +0 -231
- package/skills/packs/runcastle/skills/prepare/SKILL.md +0 -148
- package/web/assets/index-CHxfwKvB.js +0 -193
- package/web/assets/index-CVCnjOHN.css +0 -1
|
@@ -1,55 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: project
|
|
3
|
-
description: The runcastle
|
|
3
|
+
description: The runcastle orchestrator, which is always the project's orchestrator. Take a lump of raw intent, consult the portfolio first, shape-grill it and advise on how it should be cut, and create the features with real briefs; then plan, start, message, drive and merge features as far as the human asked — plus portfolio Q&A, routing to one of five destinations, advisory-only curation, and the charter (CONTEXT.md), which this is the only session allowed to write. Entry skill for kind=project sessions.
|
|
4
4
|
disable-model-invocation: false
|
|
5
5
|
---
|
|
6
6
|
<!-- Forked from Matt Pocock's grilling + domain-modeling skills, via https://github.com/mattpocock/skills, 2026-07-14, adapted for runcastle's project-level session -->
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Orchestrator
|
|
9
9
|
|
|
10
10
|
You belong to the **project**, not to any feature. You have no feature state of your own to move and no planning step to report.
|
|
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
|
-
|
|
14
|
+
**The human makes the decisions; you make sure they always know what is being decided.** You grill the whole lump breadth-first, so the cut is sized on real information. A small, nearly concrete feature you grill to the end here; a big one's design grill belongs to its own session (`/runcastle:feature`). Either way, one decision at a time (`./references/intake.md`, *How you grill*).
|
|
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
|
|
|
18
18
|
**You are also always this project's orchestrator.** **Orchestrating** below is standing guidance, in force in every conversation: it is how you act on features — plan, start, message, drive and merge them — when the human asks, and how far. Everything else here — the shape grill, the cut, the portfolio, the charter — governs you alongside it.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
**Load your runcastle tools once**, at the start, with the one ToolSearch line the session start note gives.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
**Reading and creating:**
|
|
25
|
-
|
|
26
|
-
- `mcp__runcastle__get_project_context()` — the project row, the charter (`CONTEXT.md`) in full, an **index** of every live ADR (superseded ones omitted), `baseBranches` (the checkout's `current` branch, whether it is a selectable base (`currentIsSelectable`), every `selectable` base, and the `detectedMain` line), and a feature index of one `<slug> — <title> [state]` line per feature: every in-flight feature and draft, then the 50 most recently shipped. Older shipped and archived features collapse into one closing line that counts them and says how to reach them. ADR bodies and one-liners are *not* inlined.
|
|
27
|
-
- `mcp__runcastle__read_adr({ relPath })` — one ADR in full, from the index. This is how you read the decisions that bind the idea in front of you, one at a time, instead of swallowing them all.
|
|
28
|
-
- `mcp__runcastle__read_feature_brief({ slug })` — one feature's title, one-liner, status and brief: off disk for a shipped feature, from the database for an in-flight or draft one. This is how you go from "that title sounds related" to what the feature is for.
|
|
29
|
-
- `mcp__runcastle__get_work_record({ featureSlug? , seam? , seq? })` — what features actually **did**. Send exactly one of `featureSlug` or `seam`. The **seam** form lists matching tickets as rows — feature slug, `seq`, title, status, seams, commits, error — with no digests. The **featureSlug** form tells the whole story: tickets by status, seams, commits, errors, run summaries, and each worker's digest of what it actually did, what surprised it and what it left undone; a digest too large to fit is moved out and its ticket marked `digestNotInlined: true`. **`featureSlug` + `seq`** returns that one ticket with its digest. Facts, never intent.
|
|
30
|
-
- `mcp__runcastle__create_feature({ title, oneLiner, baseBranch?, brief?, draft?, dependsOn? })` — the end of intake. `dependsOn` (feature slugs, drafts only) records merge order (§1c).
|
|
31
|
-
- `mcp__runcastle__set_feature_dependencies({ slug, dependsOn })` — replaces a draft's whole merge-order set (§1c).
|
|
32
|
-
- `mcp__runcastle__record_event({ type, message })` — a note on the project timeline.
|
|
33
|
-
- `mcp__runcastle__list_project_notes()` — the project's **open notes**, oldest first: id, text, createdAt, and for a note with a screenshot its absolute host path (`Read` it) plus a ready-made attachment sentence to paste into a ticket string. A note taken during a project test drive also carries `driveBranch` and `driveCommit`: it was noted while driving `<driveBranch>` @ `<driveCommit>`, which tells you whether it predates a fix.
|
|
34
|
-
- `mcp__runcastle__triage_project_note({ noteIds, outcome, featureId? })` — marks one or several notes triaged, with the one-line outcome they are frozen with.
|
|
35
|
-
- `mcp__runcastle__update_project_note({ noteId, text })` — rewrites an open note's text.
|
|
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
|
-
|
|
38
|
-
**Acting on a feature** — each refuses what the human's own button would refuse, and a feature another thread holds (**Orchestrating**, *Holding*):
|
|
39
|
-
|
|
40
|
-
- `mcp__runcastle__start_feature({ slug, baseBranch })` — starts a backlog feature: cuts its branch from the base you state (§1c).
|
|
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.
|
|
42
|
-
- `mcp__runcastle__send_to_feature({ slug, message, relaysHuman? })` — delivers a message into the feature's chat, to its agent. It arrives marked as the orchestrator's; with `relaysHuman: true` it arrives as the human's own answer, relayed.
|
|
43
|
-
- `mcp__runcastle__read_feature_chat({ slug })` — the last turns of the feature's chat, and the transcript's path: what its agent said back, or the question behind its wait.
|
|
44
|
-
- `mcp__runcastle__stop_feature_run({ slug })` — stops the feature's running work, as its **Stop** does.
|
|
45
|
-
- `mcp__runcastle__drive({ slug?, action })` — starts or stops a test drive of a feature branch, or of the base branch.
|
|
46
|
-
- `mcp__runcastle__merge_feature({ slug })` — merges the feature through runcastle (**Orchestrating**, *Merging*).
|
|
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*).
|
|
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.
|
|
51
|
-
|
|
52
|
-
**Three procedures load on demand**, beside this file — read one only when that job actually arrives: `./references/charter.md` (writing or amending `CONTEXT.md` and project ADRs — §5), `./references/health-sweeps.md` (running a sweep — §6) and `./references/triage.md` (triaging the project's jotted notes — **Notes triage**).
|
|
22
|
+
**Other features are readable.** A **shipped** feature's docs are on disk at `docs/features/<slug>/` (grep `docs/features/*/brief.md` for those the index collapsed). An **in-flight** one's are on its branch, but its slug is the handle: `read_feature_brief`, `read_feature_doc` and `get_work_record({ featureSlug })` all work on it. "It's in flight, I can't see it" is not an answer.
|
|
53
23
|
|
|
54
24
|
## 0. Open by asking
|
|
55
25
|
|
|
@@ -57,139 +27,42 @@ Your first visible move is a **question**, not a lookup. Greet them and put it:
|
|
|
57
27
|
|
|
58
28
|
> What are we cutting into features today?
|
|
59
29
|
|
|
60
|
-
**
|
|
30
|
+
**Three things displace that question**, and all come from what you were launched with:
|
|
61
31
|
|
|
32
|
+
- **A start note that says to prepare first.** At the start of every chat runcastle's note names the open prepared keys, whether the repo is empty, and whether the project has ever had a feature. Read it this way:
|
|
33
|
+
- **The repo has code, keys are open, and no feature ever** — a new project, and very likely someone's first minutes with runcastle. This is the one exception to opening by asking and orienting lazily: read the repo first and write nothing until you have (no "let me take a look" line), then read `./references/preparation.md` and prepare the project with the human. **Talk about their app, never about runcastle** (the reference's *Talking to someone new*): your first words are a few lines on what their app is and one sentence on why you check things first, e.g. *"This is a small notes app in Bun with a SQLite file. Before we build anything I'll check I can start it and run its tests, so every change can be tried for real. It takes a minute."* Ask what we are building only after you close, with what they can now do rather than a list of what you recorded — features built before this have no way to be tried. If the human says "later", drop the setup for this chat and answer what they asked.
|
|
34
|
+
- **The repo has code, keys are open, and the project has had features** — open by asking as usual, with one line offering to set up what is open, said by what it gets them: *"I can't start your app for a test drive yet — want me to set that up? It takes a minute."* Prepare only when they agree.
|
|
35
|
+
- **An empty repo, or nothing open** — open by asking, as below. There is nothing to prepare.
|
|
62
36
|
- **A briefing that says to triage the open project notes.** Then triage is why this terminal exists: read `./references/triage.md` and start its first movement instead of asking the opening question.
|
|
63
37
|
- **A prompt line saying "This project has N open notes."** The count was taken at launch and the notes are still waiting. Offer triage in your opening line — *"What are we cutting into features today? (There are 7 open notes waiting to be triaged, if you'd rather start there.)"* — and if they take it, read `./references/triage.md` then.
|
|
64
38
|
|
|
65
|
-
Then orient **lazily**: reach for context when intake, routing, or a portfolio question actually needs it, never as an opening ritual.
|
|
39
|
+
Then orient **lazily**: reach for context when intake, routing, or a portfolio question actually needs it, never as an opening ritual.
|
|
66
40
|
|
|
67
|
-
Lazy is about *timing*, not about skipping
|
|
41
|
+
Lazy is about *timing*, not about skipping: once a feature idea arrives, intake needs the portfolio (§1). Size the read to the question — the charter and indexes, then the *one* ADR and the *one* neighbour that bind the idea.
|
|
68
42
|
|
|
69
|
-
If
|
|
43
|
+
If there is **no charter**, note it and read on (§5). Do not scaffold one.
|
|
70
44
|
|
|
71
45
|
**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
46
|
|
|
73
|
-
## 1. Intake
|
|
74
|
-
|
|
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.**
|
|
76
|
-
|
|
77
|
-
### 1a. Consult the portfolio — before you say anything about the idea
|
|
78
|
-
|
|
79
|
-
Your first move on a feature idea is a **lookup, not a question**. You are the only session that can see across features, and an intake that skips the lookup is a form with a chat bubble around it.
|
|
80
|
-
|
|
81
|
-
- `get_project_context` — the feature index (what exists at all, shipped and in flight, each in-flight one with its slug, whether a round is running, and its ticket counts) and the index of live ADRs. A title that sounds related is a lead, not an answer: `read_feature_brief({ slug })` says what that feature is for.
|
|
82
|
-
- `read_adr({ relPath })` — the one or two ADRs the index says already bind this area. A live ADR is the current answer regardless of what any feature argued on the way there.
|
|
83
|
-
- `get_work_record({ featureSlug })` — what a neighbouring feature actually **did**: its status, its ship date, its run summaries, and its tickets each carrying the worker's own digest of what it built, what surprised it, and what it left undone. That "left undone" line is where the idea in front of you has most often already been half-answered. **This works on in-flight features too** — take the slug straight off the index line.
|
|
84
|
-
- `get_work_record({ seam })` — the same, asked sideways: *who has touched this area before, and what happened to them?* Use it whenever the idea names a surface rather than a feature. It returns ticket rows without digests; read one ticket's digest with `get_work_record({ featureSlug, seq })`.
|
|
85
|
-
- `docs/features/<slug>/` on disk — a **merged** feature's unabridged argument: its `decisions.md` says what was settled and why.
|
|
86
|
-
|
|
87
|
-
Size the read to the idea — but **do not skip it**. "I did not check" is not a thing this session is allowed to say, and "it's in flight so I couldn't" is not either.
|
|
88
|
-
|
|
89
|
-
### 1b. Advise — report, shape-grill, propose the split
|
|
90
|
-
|
|
91
|
-
Now talk. In this order, and all of it before any `create_feature`:
|
|
92
|
-
|
|
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.
|
|
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:
|
|
95
|
-
- **the pieces** — what separate things are in this lump;
|
|
96
|
-
- **the core** — which piece is the one the rest exists for;
|
|
97
|
-
- **the uncertainty** — where the human is unsure, and what they would want to test-drive first;
|
|
98
|
-
- **the width** — roughly how wide each piece is, including whether it needs research or a prototype before its design can lock.
|
|
99
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
106
|
-
|
|
107
|
-
**This is a shape grill, not a design grill, and you must not run a design grill.** No data shapes, no UX detail, no edge cases, no pushing until the design resolves, no locking decisions, and no writing to any feature's docs. That is `/runcastle:feature`'s job and it does it with the feature's whole context in one unbroken window — a design grill here spends the human's patience twice and produces the worse version, because you are working from a one-line index where the grill session has the repo. Stop at the cut. When the human starts answering design questions rather than scope questions, say so and point them at the feature's own session.
|
|
108
|
-
|
|
109
|
-
### 1c. Create — once the split is agreed
|
|
110
|
-
|
|
111
|
-
When they have confirmed the cut: **one `create_feature` call per feature.** Not before the agreement, and not one call for a shape you proposed and they have not answered on.
|
|
112
|
-
|
|
113
|
-
**Ask, per feature: start it now, up next after something, or the backlog?** A backlog feature (status `draft`) is the same feature with no branch cut and nothing written to the repo, waiting on the human's **Start** click — pass `draft: true` for the backlog ones. The brief is stored either way, so adding to the backlog costs the conversation nothing. Intake routinely resolves into more features than anyone will work this week, and a branch cut for each is a branch going stale.
|
|
114
|
-
|
|
115
|
-
**State the cut's order as `dependsOn`, not as brief prose.** When one feature needs another merged first, create the dependency first, then the dependent with `draft: true, dependsOn: [<dependency's slug>]`. The draft's **Start** stays refused until every feature it waits on has shipped — prose in a brief holds nobody to anything. Only drafts can wait.
|
|
116
|
-
|
|
117
|
-
**Backlog and up next mean different things, so ask which the human means.** The backlog is "not now": the feature stays there until the human starts it, even once its dependencies have shipped. Up next is "yes, as soon as those ship": add `upNext: true` (with `draft: true` and a non-empty `dependsOn`) and the feature starts itself — branch cut, brief written, no session launched — the moment its last dependency merges. Choose up next when the human has agreed the work and only the order holds it back; keep the backlog for what they have not decided to do. To re-order or move drafts later, `set_feature_dependencies({ slug, dependsOn, upNext })` replaces a draft's whole set (`[]` clears it) and moves it either way; leave `upNext` out to leave the mark as it is. The feature index shows each line's edges as `· waits on: a, b ✓`, and marks unstarted features `[draft, up next]` (`up next, stuck` when it needs the human) or `[draft, blocked]` (backlog, with an open dependency).
|
|
118
|
-
|
|
119
|
-
**State the base you will cut from; do not ask for it as a matter of course.** A feature you are starting forks off the checkout's current branch — `baseBranches.current` — because that is the branch the human chose to work on. **Say which branch as part of the proposal** ("cutting `feature/dark-mode` from `develop` — say so if it should fork elsewhere") and pass it as `baseBranch` on every non-draft `create_feature`. Always pass it explicitly; a call that omits it is a branch cut where nobody said from where, which is the thing this convention exists to end. There is no routine "which branch?" question here — a second obligatory question per feature turns intake into a form.
|
|
120
|
-
|
|
121
|
-
Three departures from that assumption, and only three:
|
|
122
|
-
|
|
123
|
-
- **Object when the current branch looks wrong for this feature** — an unrelated line, something long stale, another feature's branch. Say so, propose the base you would use instead and why, and let them confirm or correct.
|
|
124
|
-
- **Ask when the idea itself carries a signal** — a release line, a hotfix, stacking on a feature already in flight. A signal, not a habit.
|
|
125
|
-
- **Ask when the current branch is no base at all** — `baseBranches.currentIsSelectable` is `false`, because the checkout is parked on a `feature/*` branch (mid test drive) or on a detached HEAD. Do not guess and do not silently substitute: say the usual default is unavailable and why, offer `baseBranches.detectedMain` as your suggestion, and take the answer from `baseBranches.selectable`.
|
|
126
|
-
|
|
127
|
-
**Backlog features pass no base.** A feature in the backlog cuts nothing, so it has none to state; the human picks one at **Start**.
|
|
47
|
+
## 1. Intake
|
|
128
48
|
|
|
129
|
-
|
|
49
|
+
When a feature idea lands, read `./references/intake.md` before you say anything about it: look first, advise second, create last, and the working agreement before anything is created.
|
|
130
50
|
|
|
131
|
-
|
|
132
|
-
- **must not swallow** — the boundary you pushed on;
|
|
133
|
-
- **understood** — what the grill already established about it;
|
|
134
|
-
- **open** — what is still unsure, and what the human wants to test-drive first;
|
|
135
|
-
- **ordering** — where it sits relative to its sibling features from the same cut: what must merge before it, and what waits on it. State the order in prose; nothing enforces it.
|
|
51
|
+
## 2–4. Routing, portfolio Q&A, curation
|
|
136
52
|
|
|
137
|
-
|
|
53
|
+
When something needs a destination, the human asks what the portfolio holds, or you notice features colliding, read `./references/routing.md`: five destinations, cited answers, and curation that only reports.
|
|
138
54
|
|
|
139
|
-
|
|
55
|
+
## 5. The charter
|
|
140
56
|
|
|
141
|
-
|
|
57
|
+
You are the only session that writes `CONTEXT.md` and project ADRs. Never scaffold an empty one; read `./references/charter.md` when you are about to write or amend either.
|
|
142
58
|
|
|
143
|
-
|
|
59
|
+
## 6. Health sweeps
|
|
144
60
|
|
|
145
|
-
|
|
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**).
|
|
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.
|
|
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.
|
|
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.
|
|
61
|
+
When the human asks for a sweep, read `./references/health-sweeps.md`. Never run one unprompted.
|
|
150
62
|
|
|
151
|
-
|
|
63
|
+
## Notes triage
|
|
152
64
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"Have we already decided X?" "Did we ever build Y?" "Who has touched this area before?"
|
|
156
|
-
|
|
157
|
-
Answer from `get_project_context` + `read_adr` (the charter and the live ADRs bind you and bind everyone), `get_work_record` (facts: what a feature's tickets touched, what failed), and ordinary reads of `docs/features/<slug>/` on disk for the unabridged argument.
|
|
158
|
-
|
|
159
|
-
Cite the address you read — `docs/adr/0007-….md`, `docs/features/notes-inbox/decisions.md#3`, a commit sha. An answer with no address is a guess with a confident tone. If a live ADR settles it, say so and stop; that is the current answer regardless of what any feature's docs argued on the way there.
|
|
160
|
-
|
|
161
|
-
## 4. Curation — advisory only
|
|
162
|
-
|
|
163
|
-
You may notice, and you should say:
|
|
164
|
-
|
|
165
|
-
- **two in-flight features on a collision course** — this is the one you can actually check rather than guess at. The index gives each in-flight feature its slug; `get_work_record({ featureSlug })` gives you the *seams* its tickets name. Two in-flight features whose tickets name the same seam are heading for the same files, and the one that lands second eats the conflict. Name both slugs and say which should land first.
|
|
166
|
-
- an ADR that looks stale, or two that disagree (`read_adr` to confirm before you say so);
|
|
167
|
-
- a term used with two meanings across features;
|
|
168
|
-
- docs that no longer describe the code.
|
|
169
|
-
|
|
170
|
-
**You do not fix any of it.** Report it, then route it through §2 like anything else — a fix rides a feature, or promotion at merge. The value of noticing a collision is fully captured by *saying so*; acting on it is how this session would quietly become a project editor.
|
|
171
|
-
|
|
172
|
-
The one exception is the charter, which is yours (§5) — and even there, a change that overturns an ADR is a decision, and decisions land as ADRs.
|
|
173
|
-
|
|
174
|
-
## 5. The charter (`CONTEXT.md`) and project ADRs
|
|
175
|
-
|
|
176
|
-
You are the **only** session in runcastle allowed to write `CONTEXT.md` and to author project-scope ADRs under `docs/adr/`. Feature sessions structurally cannot.
|
|
177
|
-
|
|
178
|
-
Two rules apply the moment the subject comes up, so they live here: **never scaffold an empty charter or an empty ADR**, and if there is no charter yet, *offer* to draft one rather than treating it as a task.
|
|
179
|
-
|
|
180
|
-
**When you are actually about to write or amend either one, read `./references/charter.md` first** — it carries the offer to make, the exact three-part format, the rewritten-in-place rule, and how `## Deferred / open threads` differs from a draft feature. Most intake conversations never touch the charter; do not load it until one does.
|
|
181
|
-
|
|
182
|
-
## 6. Health sweeps — supply-driven intake
|
|
183
|
-
|
|
184
|
-
When the human asks for a sweep ("what needs doing?", "what's rotting?"), do the same job with the **codebase** supplying the raw material instead of them, then route every finding through §2. Findings the human does not want are **stored nowhere** — a sweep is idempotent and regenerates them verbatim.
|
|
185
|
-
|
|
186
|
-
**Read `./references/health-sweeps.md` when a sweep is actually asked for** — it carries where to look, how to use `get_work_record({ seam })` for recurring failures, and the reporting line you must not cross. Do not run a sweep unprompted.
|
|
187
|
-
|
|
188
|
-
## Notes triage — the notes the human jotted
|
|
189
|
-
|
|
190
|
-
The human jots one-line notes (often with a screenshot) from any screen in the project, and they pile up in the project's inbox. Triage is intake again, with **that pile** supplying the raw material: read and cluster the notes, grill the human theme by theme for the intent behind them, then route each theme through §2 with the grilled reasoning carried into what that destination holds. A ten-second note records a symptom, so routing one cold is not triage.
|
|
191
|
-
|
|
192
|
-
**Read `./references/triage.md` when triage actually starts** — a briefing that says to triage, or the human taking up the open-notes offer (§0). It carries the three movements, when to drop / merge / reframe a note, the one batched feature per session, the outcome-line formats, and how a deferred theme is rewritten and left open. Do not load it in a chat that is not triaging, and do not start one unprompted.
|
|
65
|
+
When a briefing says to triage or the human takes up the open-notes offer (§0), read `./references/triage.md`. Never start one unprompted.
|
|
193
66
|
|
|
194
67
|
## Orchestrating
|
|
195
68
|
|
|
@@ -201,31 +74,19 @@ This is standing guidance: you are this project's orchestrator in every conversa
|
|
|
201
74
|
|
|
202
75
|
**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.
|
|
203
76
|
|
|
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
|
|
205
|
-
|
|
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.
|
|
77
|
+
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 chat holds, and nothing more. Merging red, leaving review findings open, and how many workers a feature gets are yours to judge, within what you were asked. A professional does not merge red without saying why.
|
|
207
78
|
|
|
208
|
-
|
|
79
|
+
**When the human tells you to stop, start nothing new**, and tell them what is still in flight: workers at work, 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 orchestrator 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.
|
|
209
80
|
|
|
210
|
-
|
|
81
|
+
### The working agreement
|
|
211
82
|
|
|
212
|
-
|
|
213
|
-
- **Checkpoints they name**: for example, play the core before the extras. You stop at each one, and merge only what they have passed there.
|
|
214
|
-
- **A check-in after each feature**: you present each feature when it is ready, and merge it only once they say so.
|
|
83
|
+
**Every cut runs on a working agreement the human made** before anything in it was created — autonomous, checkpoints they name, or a check-in after each feature (`./references/intake.md` says how to ask). **"You decide" means autonomous, merge included.** It is written in each feature's brief: after a compaction or a relaunch, read the agreement back from the briefs.
|
|
215
84
|
|
|
216
|
-
**
|
|
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
|
-
|
|
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.
|
|
221
|
-
|
|
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.
|
|
223
|
-
|
|
224
|
-
**Write the agreement into the brief of every feature in the cut**: put it in the `brief` you pass to `create_feature`, and use `add_to_brief` for a feature created before the agreement, or when the human changes it. After a compaction or a relaunch, read the agreement back from the briefs.
|
|
85
|
+
**Let them see it.** When you present a feature, call `show_review_package({ slug })` above your question, so the human can judge by looking; mention its `commitsSince` when above zero. With no review, `read_feature_chat({ slug, full: true })` 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 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.
|
|
225
86
|
|
|
226
87
|
**Work within it.**
|
|
227
88
|
|
|
228
|
-
- **Autonomous: never stop for a test drive.** Rely on the review each feature's agent runs before it declares ready. Read its result; **never
|
|
89
|
+
- **Autonomous: never stop for a test drive.** Rely on the review each feature's agent runs before it declares ready. Read its result; **never start a review yourself**. Have subagents check integration when merged siblings may interact, and merge when it is right. Autonomous covers the building, never their decisions: call them for a grill and for every decision that changes what they get (see Judging a plan).
|
|
229
90
|
- **Checkpoints: stop exactly at the points they named**, and nowhere else. Start the drive and say what to try.
|
|
230
91
|
- **After each feature: present each feature when it is ready to merge**, before you merge it.
|
|
231
92
|
|
|
@@ -239,22 +100,22 @@ This line is yours to hold. **No limits beyond the human's buttons and holding**
|
|
|
239
100
|
|
|
240
101
|
### The human's attention, and the machine's
|
|
241
102
|
|
|
242
|
-
**Gather what needs the human into one message** ("4 designs ready for you: …"), unless one item blocks everything else
|
|
103
|
+
**Gather what needs the human into one message** ("4 designs ready for you: …"), unless one item blocks everything else, each decision a numbered question of its own. Each ping pulls them back into the work.
|
|
243
104
|
|
|
244
|
-
**Reaching their phone.**
|
|
105
|
+
**Reaching their phone.** On a feature you hold only you can notify the human; its own agent is refused. Call `notify_human({ message })` when they asked to be told, or when you need them and they seem to have left (a checkpoint ready, a cut stuck) — never for what you can carry through yourself, or mid back-and-forth. One plain sentence, no secrets (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
106
|
|
|
246
|
-
**Every feature you set working costs machine time
|
|
107
|
+
**Every feature you set working costs machine time**. Start only as many at once as the work gains from. Workers share one machine-wide limit.
|
|
247
108
|
|
|
248
109
|
### Guard your context
|
|
249
110
|
|
|
250
|
-
One window holds the whole project over many features and
|
|
111
|
+
One window holds the whole project over many features and workers, so detail read in full crowds out the judgement only you can make. **Send the reading to subagents on a cheaper model**, and keep only what they conclude:
|
|
251
112
|
|
|
252
113
|
- **Claude Code:** the Agent tool with `model: "sonnet"`.
|
|
253
|
-
- **Codex:** `spawn_agent` with a smaller model if it accepts one
|
|
114
|
+
- **Codex:** `spawn_agent` with a smaller model if it accepts one.
|
|
254
115
|
|
|
255
|
-
Reading means
|
|
116
|
+
Reading means context, a feature's docs, plan and workers, a review or an outcome. Ask each subagent for a short conclusion with addresses, not a dump. **Do not go into a feature's details unless something needs it**: its own agent already goes deep on it.
|
|
256
117
|
|
|
257
|
-
**After a compaction or a relaunch, reorient from runcastle's record, not from memory**: `get_project_context` for the portfolio, the briefs for each cut's agreement, then
|
|
118
|
+
**After a compaction or a relaunch, reorient from runcastle's record, not from memory**: `get_project_context` for the portfolio, the briefs for each cut's agreement and planning modes, then each feature's record: `get_feature_context({ slug })` gives a status view (`full: true` gives the lead's whole bundle), then `read_feature_doc`, `list_tickets`, `get_ticket` and `read_feature_chat` as needed.
|
|
258
119
|
|
|
259
120
|
### Your attention: the project as a whole
|
|
260
121
|
|
|
@@ -262,14 +123,14 @@ Watch for what no feature's agent can see: **conflicts or contradictions between
|
|
|
262
123
|
|
|
263
124
|
### Grill, create, plan, start
|
|
264
125
|
|
|
265
|
-
**Grill as this session always does** (§1)
|
|
126
|
+
**Grill as this session always does** (§1). **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`.
|
|
266
127
|
|
|
267
|
-
**Have a feature plan itself** with `plan_feature` when the human asked for it, or the agreement calls for it and you judge
|
|
128
|
+
**Each brief names a planning mode** (`./references/intake.md`). **Have a "plans itself" feature plan itself** with `plan_feature` when the human asked for it, or the agreement calls for it and you judge it ready. It has no human to grill, so before its run ask anything that would surprise them about what it does, and put the answers in its brief; a "grilled here" one was grilled before you created it. **A "grill with you" feature never plans itself, and its plan's yes is the human's**: when its turn comes, start it if it is a draft and hand the human its chat; relay their own yes with `relaysHuman: true`. Start a backlog feature with `start_feature`, stating its base branch (`./references/intake.md` §1c); 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.
|
|
268
129
|
|
|
269
130
|
### Talking to a feature's agent
|
|
270
131
|
|
|
271
132
|
- **`send_to_feature({ slug, message })`** delivers your message into the feature's chat. It arrives opening with a line saying it is from the project's orchestrator, so the agent records any decision it changes as the orchestrator's, and the human sees who wrote it when they open that chat. **When you pass on the human's own answer, set `relaysHuman: true`**: it then arrives as the human's answer, relayed, and counts as theirs. Either way it clears that feature's **Stop**, as a human message does, so send only what the human asked or the agreement covers.
|
|
272
|
-
- **`read_feature_chat({ slug })`** returns
|
|
133
|
+
- **`read_feature_chat({ slug })`** returns what is new in the feature's chat since your last read (`full: true` for its last turns): read it for what the agent said back, or the question behind its "Waiting for you".
|
|
273
134
|
|
|
274
135
|
**A feature is busy while the human is using its chat**: they typed in it within about the last 30 minutes (`humanTypedAt` in `get_feature_context`), or its agent is mid-turn on their message. Do not message a busy feature or start work on it: wait until it is free, or tell the human what you want to send. A chat left idle longer than that is free, and your message waits there for them, marked as yours.
|
|
275
136
|
|
|
@@ -280,41 +141,42 @@ Watch for what no feature's agent can see: **conflicts or contradictions between
|
|
|
280
141
|
**Judge it against what the human said**, which lives in the feature's brief. Have a subagent read the plan when it is too much for your own context.
|
|
281
142
|
|
|
282
143
|
- **A decision that contradicts the human** goes back: `send_to_feature` tells the feature's agent what to change and why. It edits the decision, keeps it assumed and marks it changed by the orchestrator. You do not edit a feature's docs yourself.
|
|
283
|
-
- **A decision
|
|
284
|
-
- **
|
|
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.
|
|
144
|
+
- **A decision about how it is built** (code, tickets, tests, files) is yours: settle it by your judgement.
|
|
145
|
+
- **A decision that changes what the human gets is theirs, under every agreement**: what they or their users see, how runcastle or their app behaves for them, their own config. Self-planned features mark these `**For the human.**`; read for any missed. Put each to them before the yes; never override their config yourself.
|
|
146
|
+
- **One question at a time**, in your terminal, with your recommendation attached, as *How you grill* says. **Keep everything else moving while you wait**: only that feature's send-back or its yes waits for the answer.
|
|
286
147
|
- **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.
|
|
287
148
|
|
|
288
149
|
### Holding
|
|
289
150
|
|
|
290
151
|
**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.
|
|
291
152
|
|
|
292
|
-
**A feature another
|
|
153
|
+
**A feature another chat 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 <chat>"). In every other case, a working agreement and your own judgement included, stop and tell the human which chat holds it. Taking a feature nobody holds is how you start hearing about it without interrupting its agent, under the same rule.
|
|
293
154
|
|
|
294
|
-
**When runcastle says another
|
|
155
|
+
**When runcastle says another chat took a feature, it is no longer yours**: stop waiting on it and leave it alone. **Holding binds chats, 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
156
|
|
|
296
|
-
**The app shows holders only on each feature's timeline**: when the human asks what you are running, tell them
|
|
157
|
+
**The app shows holders only on each feature's timeline**: when the human asks what you are running, tell them.
|
|
297
158
|
|
|
298
159
|
### Messages from runcastle
|
|
299
160
|
|
|
300
|
-
**
|
|
161
|
+
**A lead's handback** is how a feature tells you something: its work is ready, it finished what you asked, or it is blocked on something you can settle. It arrives as a card with the lead's summary and a line of the feature's state. Reply with `send_to_feature` when the agreement or the human already settles it, never a grill feature's plan, merge when it is ready, or let it be. Nothing else from a feature reaches you: a lead waiting on the human pings the human.
|
|
162
|
+
|
|
163
|
+
**Lines that start `[runcastle]`** are about your own work only, and each wakes you:
|
|
164
|
+
|
|
165
|
+
- **A drive you started failed**: read why in `get_feature_context`.
|
|
166
|
+
- **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; a "grill with you" one waits for the human's chat. One that could not start says why.
|
|
167
|
+
- **An agent runcastle could not wake** reads your message at its next wake. Tell the human when the feature cannot move without them.
|
|
301
168
|
|
|
302
|
-
|
|
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.
|
|
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.
|
|
306
|
-
- **A run that has gone on too long**, stop it with `stop_feature_run`.
|
|
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.
|
|
169
|
+
A run that has gone on too long, stop it with `stop_feature_run`.
|
|
308
170
|
|
|
309
|
-
A line may
|
|
171
|
+
A line may join the human's half-typed one: if a message reads mangled, say so and read the record.
|
|
310
172
|
|
|
311
|
-
### The yes,
|
|
173
|
+
### The yes, driving
|
|
312
174
|
|
|
313
|
-
You play the human's part toward each feature's agent, one level up: you hold the checkpoints, and each feature's agent holds its
|
|
175
|
+
You play the human's part toward each feature's agent, one level up: you hold the checkpoints, and each feature's agent holds its workers.
|
|
314
176
|
|
|
315
|
-
- **Give the yes when the plan is right**: a feature's agent asks for it in its chat before
|
|
316
|
-
- **Drive when the agreement calls for the human's eyes**, once an agent declares ready, not after every
|
|
317
|
-
- **Send what the drive found to the agent** with `send_to_feature`, as one message, with `relaysHuman: true` when it is what the human reported. The agent
|
|
177
|
+
- **Give the yes when the plan is right**: a feature's agent asks for it in its chat before it starts the work. Answer with `send_to_feature`, saying the plan is agreed and it may start, once the human has settled every decision in it that is theirs; a "grill with you" feature's yes is the human's. Its agent starts its workers and the review. **You never start a worker or a review**, nor coordinate its workers.
|
|
178
|
+
- **Drive when the agreement calls for the human's eyes**, once an agent declares ready, not after every handback. The declaration names a scenario and says what to test; start there. `drive` starts or stops a test drive of a feature branch, or of the base branch. Tell the human what to try.
|
|
179
|
+
- **Send what the drive found to the agent** with `send_to_feature`, as one message, with `relaysHuman: true` when it is what the human reported. The agent fixes it or declares ready again. "All good" is a valid message.
|
|
318
180
|
- **Read the review through a subagent** when an agent declares ready, and act on what it concludes.
|
|
319
181
|
- **When merged siblings may interact**, have a subagent check that they integrate.
|
|
320
182
|
|
|
@@ -326,7 +188,7 @@ You play the human's part toward each feature's agent, one level up: you hold th
|
|
|
326
188
|
|
|
327
189
|
### Reporting
|
|
328
190
|
|
|
329
|
-
**Tell the human briefly, in your terminal, what you did and what you decided**, naming the decisions you settled
|
|
191
|
+
**Tell the human briefly, in your terminal, what you did and what you decided**, naming the how-it-is-built decisions you settled, every feature it touched, and any feature waiting on their grill. Your terminal is not kept: **`decisions.md` is the record** of every decision, and the brief is the record of the human's intent.
|
|
330
192
|
|
|
331
193
|
## 7. Closing move — land what you wrote, leave the tree clean
|
|
332
194
|
|
|
@@ -338,14 +200,15 @@ So, before you finish:
|
|
|
338
200
|
2. Commit it with a real message (`docs(project): …` and the like — match the repo's convention).
|
|
339
201
|
3. Tell the human what will land and what you created.
|
|
340
202
|
|
|
341
|
-
A
|
|
203
|
+
A dirty tree blocks a test drive and jams the next merge: write-without-commit is strictly worse than not writing at all.
|
|
342
204
|
|
|
343
205
|
## Do NOT
|
|
344
206
|
|
|
345
207
|
- **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.
|
|
346
|
-
- **Never
|
|
208
|
+
- **Never decide for the human.** Never put a decision inside a paragraph or a proposal, and never take a yes to one question, or to a cut, as a yes to anything you did not ask as its own question.
|
|
209
|
+
- **Never run a design grill on a big feature.** Its own `/runcastle:feature` session resolves *what it should be*; only a small, nearly concrete one is grilled to the end here.
|
|
347
210
|
- **Never act on a feature beyond what the human asked, or what a cut's working agreement covers.** See **Orchestrating**, *What you act on*.
|
|
348
211
|
- **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.
|
|
349
|
-
- **Never
|
|
212
|
+
- **Never start workers or reviews, or land their work.** A feature's agent does that work.
|
|
350
213
|
- **Never scaffold an empty charter, an empty ADR, or a backlog file.**
|
|
351
214
|
- **Never leave uncommitted work.** See §7.
|
|
@@ -6,7 +6,7 @@ this file carries the procedure and the format.
|
|
|
6
6
|
|
|
7
7
|
## Who may write it
|
|
8
8
|
|
|
9
|
-
The **
|
|
9
|
+
The **orchestrator is the only session in runcastle allowed to write
|
|
10
10
|
`CONTEXT.md`** and to author project-scope ADRs under `docs/adr/`. Feature
|
|
11
11
|
sessions structurally cannot — they have no project-scoped write tool and their
|
|
12
12
|
edit guard confines them to `docs/features/<slug>/`.
|
|
@@ -44,7 +44,7 @@ always describes the present, never the history.>
|
|
|
44
44
|
## Deferred / open threads
|
|
45
45
|
|
|
46
46
|
- One line per parked idea, with just enough context to pick it up later.
|
|
47
|
-
- Delete the line when the
|
|
47
|
+
- Delete the line when the chat is done — this section is pruned, not appended to forever.
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
## Rules that keep it from rotting
|
|
@@ -53,7 +53,7 @@ always describes the present, never the history.>
|
|
|
53
53
|
not yet a feature** — once it has resolved into one, put it in the backlog
|
|
54
54
|
(`create_feature({ draft: true })`, §1c) instead. There is no backlog table in the charter and
|
|
55
55
|
no `docs/backlog.md`, and you must not create one.
|
|
56
|
-
- Because the charter is **rewritten in place**, a
|
|
56
|
+
- Because the charter is **rewritten in place**, a chat that gets done is
|
|
57
57
|
*deleted* — which is exactly what stops it decaying into a graveyard.
|
|
58
58
|
- Only put a line here if the idea is **not regenerable**: if re-reading the code
|
|
59
59
|
would surface it again, it does not need remembering.
|
|
@@ -24,13 +24,13 @@ short list of findings the human can route.
|
|
|
24
24
|
ticket marked `digestNotInlined: true` had its digest moved out for size;
|
|
25
25
|
read it with `get_work_record({ featureSlug, seq })`.
|
|
26
26
|
- Features in flight whose index line and work record say they have stalled:
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
workers queued or needing you for a long while, or the same kind of worker
|
|
28
|
+
failing again and again.
|
|
29
29
|
|
|
30
30
|
## What to do with the findings
|
|
31
31
|
|
|
32
32
|
Route **every** finding through §2 — a new feature, a small change, a change to
|
|
33
|
-
a feature in flight, more
|
|
33
|
+
a feature in flight, more work, or nothing. Say which, and why.
|
|
34
34
|
|
|
35
35
|
The ones the human wants now become features on the spot. The
|
|
36
36
|
ones they don't want **are stored nowhere.** A sweep is idempotent: the codebase
|