@assuredloop/orca-bot-kit 0.2.0 → 0.4.0
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 +31 -15
- package/SETUP.md +10 -4
- package/package.json +1 -1
- package/rules/finishing.md +3 -0
- package/rules/mail.md +3 -3
- package/rules/scope.md +4 -2
- package/rules/tests-first.md +6 -4
- package/skills/obk-arch/LICENSES.md +7 -0
- package/skills/obk-arch/NOTICE.md +113 -5
- package/skills/obk-arch/SKILL.md +221 -10
- package/skills/obk-bot-building/NOTICE.md +2 -2
- package/skills/obk-bot-building/SKILL.md +108 -19
- package/skills/obk-debugging/SKILL.md +30 -15
- package/skills/obk-decision-memo/NOTICE.md +1 -1
- package/skills/obk-finops/NOTICE.md +1 -1
- package/skills/obk-finops/SKILL.md +6 -4
- package/skills/obk-fleet-review/SKILL.md +42 -5
- package/skills/obk-grilling/NOTICE.md +11 -3
- package/skills/obk-grilling/SKILL.md +11 -7
- package/skills/obk-grooming/SKILL.md +5 -2
- package/skills/obk-handoff/NOTICE.md +1 -1
- package/skills/obk-recall/NOTICE.md +1 -1
- package/skills/obk-researching/NOTICE.md +1 -1
- package/skills/obk-researching/SKILL.md +19 -9
- package/skills/obk-reviewing/SKILL.md +4 -1
- package/skills/obk-tdd/SKILL.md +54 -23
- package/skills/obk-teach/NOTICE.md +2 -2
- package/skills/obk-why/NOTICE.md +1 -1
- package/skills/obk-why/SKILL.md +21 -10
- package/src/book.js +2 -2
- package/src/bot.js +1 -1
- package/src/cli.js +117 -33
- package/src/groom.js +5 -3
- package/src/health.js +2 -2
- package/src/hooks.js +73 -18
- package/src/init.js +3 -3
- package/src/launch.js +28 -5
- package/src/message.js +38 -19
- package/src/orca-window.cjs +21 -0
- package/src/orca.js +191 -28
- package/src/pause.js +11 -6
- package/src/record.js +1 -1
- package/src/restart.js +6 -5
- package/src/retire.js +41 -6
- package/src/roster.js +1 -1
- package/src/rules.js +2 -2
- package/src/skills.js +113 -21
- package/src/sources.js +4 -3
- package/src/up.js +57 -23
- package/src/usage.js +2 -2
package/README.md
CHANGED
|
@@ -71,8 +71,10 @@ obk --version
|
|
|
71
71
|
The command is `obk`. If `obk --version` does not answer after that, npm has no
|
|
72
72
|
working release yet (an early placeholder has no `obk` in it): run
|
|
73
73
|
`npm uninstall -g @assuredloop/orca-bot-kit`, then install from a clone of this
|
|
74
|
-
repository with `npm install` and `npm link`.
|
|
75
|
-
|
|
74
|
+
repository with `npm install` and `npm link`. To work on the kit itself, run
|
|
75
|
+
your clone's `src/cli.js` by its full path instead of linking it: the `obk` on
|
|
76
|
+
PATH stays the published one, and the kit calls itself back by the path of the
|
|
77
|
+
CLI that started it, so what your clone brings up calls back into your clone.
|
|
76
78
|
|
|
77
79
|
Releases go out from CI: publishing a GitHub Release tagged `v<version>` runs
|
|
78
80
|
`.github/workflows/publish.yml`, which runs the suite and publishes that version
|
|
@@ -99,7 +101,7 @@ my-bots/
|
|
|
99
101
|
|
|
100
102
|
The folder is yours. It holds your configuration and none of the kit's code —
|
|
101
103
|
kit skills are linked from the installed package, never copied
|
|
102
|
-
([ADR
|
|
104
|
+
([ADR 0014](docs/adr/0014-skills-are-linked-never-copied.md)). Run `init` again
|
|
103
105
|
whenever you like: it adds what is missing and leaves everything else, including
|
|
104
106
|
your edits, exactly as it is. It does not commit for you.
|
|
105
107
|
|
|
@@ -136,7 +138,7 @@ note about it. Anything you leave out is the
|
|
|
136
138
|
harness's own default; the kit names no model of its own. The approval level is
|
|
137
139
|
`auto` — the harness's real auto mode — unless you ask for `ask` or, in those
|
|
138
140
|
words, `dangerously-skip`
|
|
139
|
-
([ADR
|
|
141
|
+
([ADR 0015](docs/adr/0015-three-approval-levels-auto-by-default.md)).
|
|
140
142
|
|
|
141
143
|
Neither command touches Orca. `obk up` is what makes it all real there: an Orca
|
|
142
144
|
project per bot, a tab per session, each started at the bot home with its own
|
|
@@ -148,7 +150,7 @@ so run it after a restart, or whenever something is missing. `--bot` and
|
|
|
148
150
|
|
|
149
151
|
Each bot has one `AGENTS.md`, shared by all its sessions: its charter, then the
|
|
150
152
|
rule units it uses
|
|
151
|
-
([ADR
|
|
153
|
+
([ADR 0013](docs/adr/0013-agents-md-is-compiled-from-rule-units.md)). A rule
|
|
152
154
|
unit is one short block of always-on working rules. The kit's own units live in
|
|
153
155
|
[`rules/`](rules/) in this package; yours go in `rules/` inside your bots
|
|
154
156
|
folder. What is always on stays short, because every session reads it on every
|
|
@@ -216,7 +218,7 @@ size the always-on set may reach.
|
|
|
216
218
|
|
|
217
219
|
The kit ships its own skills in [`skills/`](skills/), one directory per skill,
|
|
218
220
|
named `obk-<technique>`
|
|
219
|
-
([ADR
|
|
221
|
+
([ADR 0019](docs/adr/0019-skills-by-technique-with-a-prefix.md)). They are
|
|
220
222
|
organised by technique rather than by role: a role is a charter plus a choice
|
|
221
223
|
of skills. Each one gives techniques and defaults, never a process or
|
|
222
224
|
a way of working you have to adopt, and carries what it needs itself rather
|
|
@@ -261,12 +263,22 @@ name for a directory in `skills/` inside your bots folder, or anything with a
|
|
|
261
263
|
`/` in it for a skill directory anywhere on disk. `obk up` links them before it
|
|
262
264
|
opens a tab, and `bot create` gives a new bot what the lists already name.
|
|
263
265
|
|
|
266
|
+
A bot whose sessions are running gets a changed list without a restart.
|
|
267
|
+
When `skills build` links or takes away a skill, it tells each running
|
|
268
|
+
session of that bot. A Claude Code session gets `/reload-skills` typed into
|
|
269
|
+
its tab: Claude Code's own reload, which a busy session runs when its turn
|
|
270
|
+
ends. Codex has no reload command and takes the change at the start of its
|
|
271
|
+
next turn, so nothing is typed there. The kit prints the new skills'
|
|
272
|
+
`SKILL.md` paths, and says that a restart would make a skill appear if it is
|
|
273
|
+
still missing after that turn. A session the kit could not tell is named,
|
|
274
|
+
with the reason.
|
|
275
|
+
|
|
264
276
|
What lands in the bot is a symlink, never a copy
|
|
265
|
-
([ADR
|
|
277
|
+
([ADR 0014](docs/adr/0014-skills-are-linked-never-copied.md)) — into
|
|
266
278
|
`.claude/skills` and `.agents/skills` in the bot home, which is where each
|
|
267
279
|
harness reads a project's skills from. So a kit skill is read where npm
|
|
268
|
-
installed it,
|
|
269
|
-
|
|
280
|
+
installed it, a running session reads an edited skill the next time it loads
|
|
281
|
+
it, and updating the kit updates every bot at once.
|
|
270
282
|
|
|
271
283
|
The kit takes away only what it can prove it put there. It writes down every
|
|
272
284
|
link it makes, in `.obk-skills.yaml` in the bot folder, and when no list names
|
|
@@ -307,7 +319,7 @@ with no rebuild, because the link points at the clone.
|
|
|
307
319
|
|
|
308
320
|
The kit says one line when a source carries scripts or hooks. It does not read
|
|
309
321
|
them and does not stand in your way — a third-party skill is your risk to take
|
|
310
|
-
([ADR
|
|
322
|
+
([ADR 0014](docs/adr/0014-skills-are-linked-never-copied.md)).
|
|
311
323
|
|
|
312
324
|
A skill is a directory holding `SKILL.md` — frontmatter carrying `name` (the
|
|
313
325
|
directory's own name) and `description`, then the body — plus any reference
|
|
@@ -324,11 +336,11 @@ own directory, because a bot gets the directory alone.
|
|
|
324
336
|
Each bot keeps a book, `sessions.yaml` in its folder: which Orca tab each session
|
|
325
337
|
lives in, which harness session it is running as, and every id it ran as before,
|
|
326
338
|
with why that one ended and when
|
|
327
|
-
([ADR
|
|
339
|
+
([ADR 0012](docs/adr/0012-the-book-is-the-authority-for-session-ids.md)).
|
|
328
340
|
|
|
329
341
|
The book stays true to the harness through a hook `obk up` puts in the bot's own
|
|
330
342
|
folder — `.claude/settings.json` or `.codex/hooks.json`, never your user-level
|
|
331
|
-
settings ([ADR
|
|
343
|
+
settings ([ADR 0020](docs/adr/0020-kit-hooks-live-in-the-bot-folder.md)). Your own
|
|
332
344
|
settings in those files are kept. Codex asks you to trust a hooks file the first
|
|
333
345
|
time it sees one; answer its question in the tab.
|
|
334
346
|
|
|
@@ -402,8 +414,12 @@ same refusals, and `obk up` leaves what is paused closed until `obk unpause`
|
|
|
402
414
|
brings it back with its conversations. Retiring a session takes it off the bot
|
|
403
415
|
and keeps its conversations in the book under `retired`. Retiring a bot closes
|
|
404
416
|
its tabs, removes its Orca project and moves its folder to `retired/`; it will
|
|
405
|
-
not touch a bot whose Orca project holds a tab your book does not name.
|
|
406
|
-
|
|
417
|
+
not touch a bot whose Orca project holds a tab your book does not name. The
|
|
418
|
+
folder moves only once Orca no longer lists the project; if Orca still lists it,
|
|
419
|
+
or its list cannot be read, retire says so and leaves the bot where it is, and
|
|
420
|
+
retiring it again finishes the job. Bot
|
|
421
|
+
Father itself, and its management session `daily`, are never paused or
|
|
422
|
+
retired; its other sessions are like any bot's.
|
|
407
423
|
|
|
408
424
|
## When something is wrong
|
|
409
425
|
|
|
@@ -443,7 +459,7 @@ verdict: which of these matter, and in what order, is for you or for Bot Father.
|
|
|
443
459
|
## Sessions and bots that talk
|
|
444
460
|
|
|
445
461
|
Ask the kit how to reach a session, and it answers with the road and the
|
|
446
|
-
address ([ADR
|
|
462
|
+
address ([ADR 0018](docs/adr/0018-messaging-transport.md)):
|
|
447
463
|
|
|
448
464
|
```sh
|
|
449
465
|
obk message to --bots /path/to/my-bots --to api-bot/daily
|
package/SETUP.md
CHANGED
|
@@ -145,8 +145,9 @@ different answers.
|
|
|
145
145
|
|
|
146
146
|
`obk init` tells you which, for every tab it opened:
|
|
147
147
|
|
|
148
|
-
- *the harness was typed in and
|
|
149
|
-
|
|
148
|
+
- *the harness was typed in and is running. The kit cannot see whether a screen
|
|
149
|
+
in it is waiting for an answer* — look at it: Orca does not flag every first-run
|
|
150
|
+
screen, so it may still be asking something of its own. That is the table below.
|
|
150
151
|
- *the harness was typed in and came up, waiting on: …* — running and blocked on
|
|
151
152
|
a question. The table below.
|
|
152
153
|
- *the harness was typed in, and no session came up in the tab* — **the line did
|
|
@@ -183,8 +184,9 @@ waiting for:
|
|
|
183
184
|
| On screen | Send | Which is |
|
|
184
185
|
|---|---|---|
|
|
185
186
|
| Claude Code's folder trust list | `\x1b[B\r` | down, then return: its selection starts on **No, exit** |
|
|
186
|
-
| Codex's directory trust, `1. Yes, continue` | `1\r` | yes |
|
|
187
|
+
| Codex's directory trust, `1. Trust and continue` (older: `1. Yes, continue`) | `1\r` | yes |
|
|
187
188
|
| Codex's `Hooks need review` | `2\r` | trust all and continue |
|
|
189
|
+
| Codex's `/new`: `Where should the new conversation run?` | `1\r` | current checkout (bot home) |
|
|
188
190
|
| Codex's update offer, `1. Update now` | `1\r` | accept it |
|
|
189
191
|
| `[oh-my-zsh] Would you like to update?` | `n` | they update their own shell |
|
|
190
192
|
| Claude Code's `Teach auto mode about your environment?` | `2\r` | **Not now**: it would write settings of theirs |
|
|
@@ -193,7 +195,7 @@ The numbers there are what these menus showed when this was written. Read them
|
|
|
193
195
|
off the screen in front of you rather than trusting the table: a harness that has
|
|
194
196
|
added an option since has moved them all down one.
|
|
195
197
|
|
|
196
|
-
|
|
198
|
+
Three things to know rather than guess at.
|
|
197
199
|
|
|
198
200
|
Codex's hooks question is not cosmetic. The kit's hook is how the book learns
|
|
199
201
|
which conversation a session is running as, and while that screen is up the
|
|
@@ -203,6 +205,10 @@ empty book and nothing says why.
|
|
|
203
205
|
Codex's trust question applies to the **repository root**, which for a bot means
|
|
204
206
|
the whole bots folder rather than the one bot. That is what they are agreeing to.
|
|
205
207
|
|
|
208
|
+
Codex's `/new` question (0.156.1 on) is always answered with the current
|
|
209
|
+
checkout, which is the bot home. The kit never makes a git worktree, so
|
|
210
|
+
`2. New worktree` is never the answer.
|
|
211
|
+
|
|
206
212
|
**Anything you do not recognise: type nothing.** Tell them what is on the
|
|
207
213
|
screen and which tab it is in, and wait. A keypress into a menu you have not read
|
|
208
214
|
is how a harness quits back to the shell.
|
package/package.json
CHANGED
package/rules/finishing.md
CHANGED
|
@@ -9,6 +9,9 @@ Turn the work into a check you can run. Run it. Read the output.
|
|
|
9
9
|
Check the thing itself, not a stand-in for it: the file that changed, the
|
|
10
10
|
output the reader will get, the real command against the real tool.
|
|
11
11
|
|
|
12
|
+
What does not run is checked against the ask: it answers the question, can be
|
|
13
|
+
followed, and its claims hold. Say what stood in, and what it could not show.
|
|
14
|
+
|
|
12
15
|
Do not say it is done from a plausible diff. Say what the check actually gave,
|
|
13
16
|
failures and empty results included, and what you did not check.
|
|
14
17
|
|
package/rules/mail.md
CHANGED
|
@@ -5,9 +5,9 @@ applies: all
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
To reach another session, ask the kit for the road rather than guessing an
|
|
8
|
-
address: `obk message to --bots <bots> --to <bot>/<session>`. It
|
|
9
|
-
the address and the command that carries it. Your bots folder is
|
|
10
|
-
above the folder you start in.
|
|
8
|
+
address: `"${OBK_CLI:-obk}" message to --bots <bots> --to <bot>/<session>`. It
|
|
9
|
+
answers with the address and the command that carries it. Your bots folder is
|
|
10
|
+
two levels above the folder you start in.
|
|
11
11
|
|
|
12
12
|
Mail is queued, not an interruption. Read it when you finish what you are on.
|
|
13
13
|
|
package/rules/scope.md
CHANGED
|
@@ -16,5 +16,7 @@ When you notice something else worth doing, say so at the end. Doing it is the
|
|
|
16
16
|
user's call.
|
|
17
17
|
|
|
18
18
|
Work inside a project of its own (a repo you cloned into your work dir, a
|
|
19
|
-
folder with its own rules) follows that project's rules as well as yours
|
|
20
|
-
Where the two disagree,
|
|
19
|
+
folder with its own rules) follows that project's rules as well as yours, so
|
|
20
|
+
read its AGENTS.md or CLAUDE.md before you start. Where the two disagree, do not
|
|
21
|
+
pick one: tell whoever gave you the work, quote both, and hold that part until
|
|
22
|
+
it is settled.
|
package/rules/tests-first.md
CHANGED
|
@@ -5,11 +5,13 @@ applies: code
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
A change in behaviour starts with a test that fails for the reason you expect.
|
|
8
|
-
Run it, read the failure, then write the code.
|
|
8
|
+
Run it, read the failure, then write the code. When a failing test really is
|
|
9
|
+
impractical, say why and name the check you ran instead; naming one you will run
|
|
10
|
+
later is not having run it.
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
working from the requirement and the public
|
|
12
|
-
start one nor reach one, say so and ask.
|
|
12
|
+
Wherever a real test is warranted, it is written by someone who is not you: a
|
|
13
|
+
subagent or another session, working from the requirement and the public
|
|
14
|
+
interface. When you can neither start one nor reach one, say so and ask.
|
|
13
15
|
|
|
14
16
|
A test that stands in your way goes back to its author with what you think is
|
|
15
17
|
wrong with it. It does not get weakened, skipped or deleted to reach green.
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
`obk-arch` consolidates material from the sources named in
|
|
9
9
|
[NOTICE.md](NOTICE.md). Their licences are reproduced below in full.
|
|
10
10
|
|
|
11
|
+
The part on decision records copies words only from Michael Nygard's
|
|
12
|
+
"Documenting Architecture Decisions" (CC0 1.0) and MADR 4.0.0 (taken under
|
|
13
|
+
CC0-1.0, one of its two licences). CC0 waives all rights and asks for no
|
|
14
|
+
notice, so there is nothing to reproduce for them: see
|
|
15
|
+
https://creativecommons.org/publicdomain/zero/1.0/. The other decision-record
|
|
16
|
+
sources in NOTICE.md gave ideas only, and none of their text is used.
|
|
17
|
+
|
|
11
18
|
## MIT
|
|
12
19
|
|
|
13
20
|
The MIT permission notice below applies to the work of each of these copyright
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
# Sources and licences
|
|
6
6
|
|
|
7
|
-
The skill `obk-arch` was consolidated for this kit from these,
|
|
8
|
-
|
|
7
|
+
The skill `obk-arch` was consolidated for this kit from these, with thanks.
|
|
8
|
+
The Cursor pstack and mattpocock/skills material is MIT; for the decision
|
|
9
|
+
record sources, see the note on licences under "Keep a record of a decision"
|
|
10
|
+
below.
|
|
9
11
|
|
|
10
12
|
- **Cursor pstack**, `architect` with its `runner-prompt`, `design-red-flags`
|
|
11
13
|
and `rationale-template` references. Writing the caller's usage and two or
|
|
@@ -114,12 +116,30 @@ thanks:
|
|
|
114
116
|
the exception for a change that has to happen everywhere; and a prototype
|
|
115
117
|
being throwaway code that answers a question, with the polish skipped on
|
|
116
118
|
purpose.
|
|
119
|
+
- **mattpocock/skills**, `triage` with its `AGENT-BRIEF`, and `to-tickets`
|
|
120
|
+
further to the above. Handing work over behavioural rather than procedural,
|
|
121
|
+
what the system should do and not how, the builder exploring fresh and
|
|
122
|
+
making their own decisions; durable rather than precise, naming types,
|
|
123
|
+
contracts and behaviours and never file paths or line numbers, because the
|
|
124
|
+
code moves while the work waits; acceptance criteria that can each be
|
|
125
|
+
checked on their own; saying what is out of scope so the builder does not
|
|
126
|
+
gold-plate; the one exception of a prototype's snippet that encodes a
|
|
127
|
+
decision more precisely than prose (from `to-tickets`); and, before handing
|
|
128
|
+
a report on, verifying the claim (reproducing it from the reporter's steps
|
|
129
|
+
and saying whether it was confirmed, failed or lacked detail, a confirmed one
|
|
130
|
+
making a much stronger brief), searching for it by the concept rather than
|
|
131
|
+
the reporter's wording to see whether it already exists, checking whether
|
|
132
|
+
it was turned down before, asking the reporter specific questions rather
|
|
133
|
+
than for more information, and noting when a piece needs a person's
|
|
134
|
+
judgement rather than being delegated.
|
|
117
135
|
|
|
118
136
|
Left behind on purpose: the multi-model arena and its runners, fixed model
|
|
119
137
|
choices, the phase todolist and its ceremony, tracker and pull-request
|
|
120
138
|
machinery, the generated report formats, and the trigger that fires a design
|
|
121
|
-
review on any change crossing a function boundary
|
|
122
|
-
|
|
139
|
+
review on any change crossing a function boundary; from `triage`, the labels,
|
|
140
|
+
the state machine, the brief template, the out-of-scope folder, the grilling
|
|
141
|
+
step and the AI disclaimer. This skill is reached for when there is a shape
|
|
142
|
+
to get wrong, not on every change.
|
|
123
143
|
|
|
124
144
|
What the owner said, and how it shaped this: he asked for a very light part on
|
|
125
145
|
what is wanted and on dividing the work, leaving the details and the tracking
|
|
@@ -131,4 +151,92 @@ testable (2026-09-19 18:54, and 2026-09-20 02:21), which is why that part stays
|
|
|
131
151
|
that the source's strict vocabulary be dropped for plain words (18:50), so the
|
|
132
152
|
list of defined terms is gone and the ideas stay. He did not want a
|
|
133
153
|
blast-radius skill of its own (18:08), so what is kept of it is a short part.
|
|
134
|
-
A small reshaping being part of the change follows PRD 7.3.
|
|
154
|
+
A small reshaping being part of the change follows PRD 7.3. He asked that work
|
|
155
|
+
be handed over by intention, without micro-management or baby steps, with
|
|
156
|
+
only brief research: enough to validate an issue, above all one reported from
|
|
157
|
+
outside, and to triage it (issue #263, 2026-09-24). That is the part on
|
|
158
|
+
handing a piece over, and why its research stops there.
|
|
159
|
+
|
|
160
|
+
## Keep a record of a decision
|
|
161
|
+
|
|
162
|
+
Words were copied only from the two sources whose licences waive all rights:
|
|
163
|
+
|
|
164
|
+
- **Michael Nygard, "Documenting Architecture Decisions"** (Cognitect blog,
|
|
165
|
+
2011-11-15; CC0 1.0, as stated on the page). The reader who can only
|
|
166
|
+
blindly accept or blindly change a decision whose reasons are lost; one
|
|
167
|
+
decision per record, the kinds of decision that earn one (structure,
|
|
168
|
+
non-functional characteristics, dependencies, interfaces, construction
|
|
169
|
+
techniques); context as the forces at play, technological, political, social
|
|
170
|
+
and project local, in tension and described value-neutrally; the decision in
|
|
171
|
+
full sentences and the active voice, "We will…"; all consequences, not just
|
|
172
|
+
the positive ones; bullets only for layout, never an excuse for fragments;
|
|
173
|
+
one or two pages, since nobody reads large documents; records numbered in
|
|
174
|
+
sequence with numbers never reused; and a superseded record kept, because it
|
|
175
|
+
is still worth knowing that it was the decision.
|
|
176
|
+
- **MADR 4.0.0** (adr.github.io/madr; MIT or CC0-1.0 at the reader's choice,
|
|
177
|
+
taken here under CC0). The people who decided and the people consulted as
|
|
178
|
+
fields of the record, "rejected" among the statuses, consequences written as
|
|
179
|
+
good and bad, and a way to confirm the decision is kept (MADR's
|
|
180
|
+
Confirmation, here "Checked by").
|
|
181
|
+
|
|
182
|
+
Taken as ideas only, in this skill's own words, because their licences do not
|
|
183
|
+
allow the text to be reused (all rights reserved unless noted):
|
|
184
|
+
|
|
185
|
+
- **Olaf Zimmermann**, ozimmer.ch: "How to create Architectural Decision
|
|
186
|
+
Records (ADRs) — and how not to", "How to review…", "A Definition of Done for
|
|
187
|
+
Architectural Decision Making" and "Ten Common Mistakes in Architectural
|
|
188
|
+
Decision Records". The ways a record goes wrong (only upsides, a straw-man
|
|
189
|
+
alternative, hidden costs, a sales tone, one option and one time frame, a
|
|
190
|
+
record carrying a whole architecture or a design, criteria reverse-engineered
|
|
191
|
+
from the preferred option, a decision section that repeats the title,
|
|
192
|
+
consequences only for the code); a record for each stage of a staged
|
|
193
|
+
decision; the confidence level; and the definition of done (evidence, at
|
|
194
|
+
least two options compared on criteria, challenged and agreed, written and
|
|
195
|
+
shared, a plan to check and revisit it).
|
|
196
|
+
- **Martin Fowler**, bliki "Architecture Decision Record". Writing the record
|
|
197
|
+
as a way to bring disagreement into the open; most important first; the
|
|
198
|
+
confidence and what should trigger a re-evaluation; an accepted record never
|
|
199
|
+
reopened, only superseded.
|
|
200
|
+
- **AWS Prescriptive Guidance**, "Using architectural decision records…". A
|
|
201
|
+
rejected record kept with its reason so the topic is not argued again; an
|
|
202
|
+
accepted record not changed, a change being a new record noted in the
|
|
203
|
+
record's change history.
|
|
204
|
+
- **Microsoft Azure Well-Architected Framework**, "Maintain an architecture
|
|
205
|
+
decision record" (Microsoft Learn terms of use). Not editing accepted records
|
|
206
|
+
but superseding them and linking the two; a record not being a design guide,
|
|
207
|
+
standing on its own with detail linked; consequences never hidden.
|
|
208
|
+
- **Joel Parker Henderson**, `architecture-decision-record` (CC BY-NC-SA 4.0,
|
|
209
|
+
which does not fit this use). Dating a fact that will change.
|
|
210
|
+
- **adr-tools** (Nat Pryce; the tool is GPL-3.0, the content it adds to a
|
|
211
|
+
project CC BY 4.0). Superseding changes only the old record's status, to a
|
|
212
|
+
link to the new one.
|
|
213
|
+
- **The GDS Way**, "Documenting architecture decisions", and **GOV.UK**,
|
|
214
|
+
"Architectural Decision Record Framework" (both Open Government Licence
|
|
215
|
+
v3.0), and **Google Cloud Architecture Center**, "Architecture decision
|
|
216
|
+
records overview" (CC BY 4.0). Their licences would allow reuse with
|
|
217
|
+
attribution, but no text of theirs is used. The ideas taken: a title that
|
|
218
|
+
names the decision rather than the problem, a superseded status with a link
|
|
219
|
+
to the new record, records kept findable (GDS Way); and a change carrying the
|
|
220
|
+
previous decision and why it changed (Google).
|
|
221
|
+
|
|
222
|
+
What the owner said, and how it shaped this part (issue #264, 2026-09-24): a
|
|
223
|
+
record that partly replaces an older one replaces it with a new one, and he
|
|
224
|
+
wanted one good format; then, on the proposed format, "I need full history of
|
|
225
|
+
change history and the context. For the decision made I also need alternative
|
|
226
|
+
listed and why they are not." So a change to any part of an accepted record is
|
|
227
|
+
a new record that replaces the old one whole and restates what still holds,
|
|
228
|
+
the old record changing only its status; the context is given in full; every
|
|
229
|
+
alternative is listed with why it was not chosen; and each record carries the
|
|
230
|
+
dated history of every record it replaces. No source asks for what still holds
|
|
231
|
+
to be restated; that is his rule. Most sources back superseding over amending
|
|
232
|
+
in place; Joel Parker Henderson and Google prefer adjusting the record with
|
|
233
|
+
the history kept, and the GDS Way allows clarifications in place until the
|
|
234
|
+
decision is acted on, which is where the note on drafts and on spelling fixes
|
|
235
|
+
comes from. The format is the default, and a project's own format wins, since
|
|
236
|
+
PRD 7.1 leaves the user free in how they keep documents. Left behind: review
|
|
237
|
+
boards, decision levels and approval steps (the GOV.UK framework, AWS's review
|
|
238
|
+
meetings), which are process; ADR tooling; and the Y-statement and other
|
|
239
|
+
templates.
|
|
240
|
+
|
|
241
|
+
The three conditions for a lasting record, from mattpocock/skills above, moved
|
|
242
|
+
here from "Write down what you chose" so they are kept in one place.
|
package/skills/obk-arch/SKILL.md
CHANGED
|
@@ -3,19 +3,25 @@ name: obk-arch
|
|
|
3
3
|
description: >-
|
|
4
4
|
Shaping a piece of work before building it: a short note of what is wanted
|
|
5
5
|
and what done means, deciding the shape from the usage and the data with
|
|
6
|
-
more than one candidate,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
a
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
more than one candidate, keeping a decision record (ADR) and replacing it
|
|
7
|
+
whole when the decision changes, making the thing runnable and testable so
|
|
8
|
+
anyone can find out whether it works, and cutting the work into pieces that
|
|
9
|
+
each end in a check, and handing a piece to someone else by what is wanted
|
|
10
|
+
and its boundary, with only the research that confirms and triages it. Use
|
|
11
|
+
when starting something new, planning a feature, adding a public interface
|
|
12
|
+
or a new data shape, making a choice that is hard to undo, writing or
|
|
13
|
+
changing a decision record, handing work to someone else to build, or when a
|
|
14
|
+
change is big enough that jumping into the code would settle the shape by
|
|
15
|
+
accident.
|
|
12
16
|
---
|
|
13
17
|
|
|
14
18
|
# Shaping work before you build it
|
|
15
19
|
|
|
16
20
|
Four things: say what is wanted, decide the shape, make sure the thing can be
|
|
17
21
|
started and driven so anyone can tell whether it works, and cut the work into
|
|
18
|
-
pieces that each end in a check. The third is what makes the rest real.
|
|
22
|
+
pieces that each end in a check. The third is what makes the rest real. A
|
|
23
|
+
decision that will outlast the change gets a record of its own. When a piece
|
|
24
|
+
goes to someone else, it goes by its intention; the how is theirs.
|
|
19
25
|
|
|
20
26
|
None of this needs a particular document, tracker or format. Where a project
|
|
21
27
|
has one, use it; where it does not, a few lines in the right place do the job.
|
|
@@ -195,9 +201,8 @@ Where the constraints left only one shape, say that instead: "the only viable
|
|
|
195
201
|
shape, because...". Name anything a later reader might mistake for an
|
|
196
202
|
oversight.
|
|
197
203
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
and it came out of a genuine trade-off. Miss one and the paragraph is enough.
|
|
204
|
+
Some decisions need more than the paragraph: a record of their own, kept after
|
|
205
|
+
the change. "Keep a record of a decision" below says which ones and how.
|
|
201
206
|
|
|
202
207
|
### When to build a throwaway instead of arguing
|
|
203
208
|
|
|
@@ -219,6 +224,167 @@ The observation is the result, not the code. Keep the decision it produced,
|
|
|
219
224
|
throw the prototype away or park it somewhere clearly marked, and write the
|
|
220
225
|
real thing from the beginning, test first.
|
|
221
226
|
|
|
227
|
+
## Keep a record of a decision
|
|
228
|
+
|
|
229
|
+
A decision record (an architecture decision record, ADR) is for someone months
|
|
230
|
+
or years later who meets the decision without its reasons. Without them they
|
|
231
|
+
have two choices: blindly accept it or blindly change it. The record lets them
|
|
232
|
+
do neither. Writing it has a second use: it forces the reasoning into the
|
|
233
|
+
open, where the people involved find out whether they actually agree.
|
|
234
|
+
|
|
235
|
+
### When one earns its place
|
|
236
|
+
|
|
237
|
+
All three are true: it is hard to reverse, so changing your mind later costs
|
|
238
|
+
something real; it is surprising without the context, so a reader will wonder
|
|
239
|
+
why it was done this way; and it came out of a genuine trade-off, with
|
|
240
|
+
alternatives that could have been chosen. Miss one and the paragraph from
|
|
241
|
+
"Write down what you chose" is enough. The ones that usually pass are about
|
|
242
|
+
structure, the qualities the thing must have (speed, security, cost to run),
|
|
243
|
+
dependencies, interfaces and how it is built. A proposal that met all three
|
|
244
|
+
and was turned down is kept too, as rejected, with the reason, so it is not
|
|
245
|
+
argued again.
|
|
246
|
+
|
|
247
|
+
One decision per record. A decision that comes in stages (a stopgap now, the
|
|
248
|
+
real answer later) gets a record for each stage. A record is not a design
|
|
249
|
+
document: component detail, diagrams and code go elsewhere, linked, and the
|
|
250
|
+
record still makes sense without them.
|
|
251
|
+
|
|
252
|
+
### The default format
|
|
253
|
+
|
|
254
|
+
Where the project already has a format for its records, use that one. Where
|
|
255
|
+
it does not, this is the default:
|
|
256
|
+
|
|
257
|
+
```markdown
|
|
258
|
+
# ADR NNNN: <the decision, as a short phrase>
|
|
259
|
+
|
|
260
|
+
Date: YYYY-MM-DD.
|
|
261
|
+
Status: proposed | accepted | rejected | deprecated | superseded by [ADR MMMM](MMMM-slug.md).
|
|
262
|
+
Decided by: <who>. Consulted: <who, if anyone>. A sentence marked (proposed) is not decided yet.
|
|
263
|
+
Supersedes: [ADR KKKK](KKKK-slug.md). <only when it does>
|
|
264
|
+
|
|
265
|
+
## Context
|
|
266
|
+
<The full context: the forces at play and the problem. Date any fact that will change.>
|
|
267
|
+
|
|
268
|
+
## Decision
|
|
269
|
+
<Full sentences: "We will…". All of what holds, including what is carried over
|
|
270
|
+
from a superseded record.>
|
|
271
|
+
|
|
272
|
+
## Alternatives considered
|
|
273
|
+
- <Alternative>: <what it is; why it was not chosen.>
|
|
274
|
+
|
|
275
|
+
## Consequences
|
|
276
|
+
- Good: …
|
|
277
|
+
- Bad: … <the cost accepted>
|
|
278
|
+
- Revisit if: … Confidence: <high or low, and why>.
|
|
279
|
+
- Checked by: <a test, a review point, a command; optional>
|
|
280
|
+
|
|
281
|
+
## History
|
|
282
|
+
- YYYY-MM-DD, [ADR KKKK](KKKK-slug.md): <what it decided or changed, and why>.
|
|
283
|
+
<one line per earlier record, oldest first; "none" for a first decision>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
What each part is for:
|
|
287
|
+
|
|
288
|
+
- **The title** names the decision, not the problem.
|
|
289
|
+
- **Status.** Proposed while it is being discussed; accepted once the people
|
|
290
|
+
who decide agree; rejected when it was turned down, kept with the reason so
|
|
291
|
+
the question is not reopened; deprecated when it no longer applies and
|
|
292
|
+
nothing replaces it; superseded by the record that replaced it. **Decided
|
|
293
|
+
by** names who made the call, so a reader knows whom to ask and whose call it
|
|
294
|
+
was; **Consulted**, whose views were sought.
|
|
295
|
+
- **Context** describes the forces at play: technical, political, social and
|
|
296
|
+
local to the project, usually in tension with each other, and says so. It is
|
|
297
|
+
value-neutral: facts, not a case for any option. It is the full context, as
|
|
298
|
+
a reader of this record alone would need it, not only what changed since the
|
|
299
|
+
last one. Date a fact that will change (a price, a limit, a version, who is
|
|
300
|
+
on the team).
|
|
301
|
+
- **Decision** is the response to those forces, in full sentences and the
|
|
302
|
+
active voice: "We will…". It says all of what now holds, not a repeat of the
|
|
303
|
+
title.
|
|
304
|
+
- **Alternatives considered** lists every alternative that was on the table,
|
|
305
|
+
each with what it is and why it was not chosen. The reasons weigh the
|
|
306
|
+
alternatives against the same forces the chosen one answers. Where the
|
|
307
|
+
constraints left only one, say "the only viable option, because…"; without
|
|
308
|
+
the reason that line is not allowed.
|
|
309
|
+
- **Consequences** lists all of them, not just the good ones: what gets
|
|
310
|
+
easier, what gets harder, the cost accepted, and for everyone the decision
|
|
311
|
+
touches (whoever runs it, tests it, calls it or pays for it), not only the
|
|
312
|
+
code. Revisit if names the change in circumstances that should reopen it.
|
|
313
|
+
The confidence tells a later reader how hard to push. Checked by, where
|
|
314
|
+
there is one, is how anyone can tell the decision is being kept: a test, a
|
|
315
|
+
point a reviewer looks for, a command.
|
|
316
|
+
- **History** is the whole story of the decision: one dated line for every
|
|
317
|
+
earlier record this one replaces, directly or down the chain, oldest first,
|
|
318
|
+
each with what it decided or changed and why. With the context, it lets the
|
|
319
|
+
newest record alone tell the full story.
|
|
320
|
+
|
|
321
|
+
The headings are there to be answered, not filled in. Write in full sentences;
|
|
322
|
+
bullets are for layout, not an excuse for fragments. Keep it short, with what
|
|
323
|
+
matters most first, since a long record goes unread; but short never costs the
|
|
324
|
+
full context, an alternative or a line of the history. What usually makes a
|
|
325
|
+
record long is design detail, and that goes elsewhere, linked.
|
|
326
|
+
|
|
327
|
+
### Changing a decision
|
|
328
|
+
|
|
329
|
+
A change to any part of an accepted record is a new record, and the new record
|
|
330
|
+
replaces the old one whole. It carries everything that still holds from the
|
|
331
|
+
old one, restated rather than pointed at, alongside what changed; the full
|
|
332
|
+
context as it now stands; the alternatives, old and new, with why each lost;
|
|
333
|
+
and the history, with a line for the record it replaces. Where it replaces
|
|
334
|
+
more than one, it names each.
|
|
335
|
+
|
|
336
|
+
The old record keeps its text. Its status alone changes, to superseded by the
|
|
337
|
+
new record, with a link. It stays true to what it says: that this was the
|
|
338
|
+
decision, for that stretch of time, for those reasons.
|
|
339
|
+
|
|
340
|
+
So a reader never has to put a decision together from several records. The
|
|
341
|
+
newest says all of what holds and how it got there; the older ones say what
|
|
342
|
+
governed the work before.
|
|
343
|
+
|
|
344
|
+
Not a change: until a record is accepted it is a draft, and a draft is edited.
|
|
345
|
+
A spelling or a broken link fixed without changing what the record says is not
|
|
346
|
+
a change either.
|
|
347
|
+
|
|
348
|
+
### Where records live
|
|
349
|
+
|
|
350
|
+
Beside what they are about, in version control, in plain text: one file per
|
|
351
|
+
record, named after the decision, numbered in sequence, and never renumbered.
|
|
352
|
+
A number once used is not used again, even for a rejected record. Where the
|
|
353
|
+
project keeps its records somewhere else, use that. Either way, someone who
|
|
354
|
+
needs a record can find it.
|
|
355
|
+
|
|
356
|
+
### Before it is accepted
|
|
357
|
+
|
|
358
|
+
A record is ready to be accepted when:
|
|
359
|
+
|
|
360
|
+
- there is some evidence the choice will work: a spike, a measurement, the
|
|
361
|
+
same thing done before, someone who has run it;
|
|
362
|
+
- the alternatives were compared on the forces named in the context: at least
|
|
363
|
+
two real ones, or the reason there was only one;
|
|
364
|
+
- someone who did not write it has challenged it, and the people who decide
|
|
365
|
+
agree with the outcome and the reasons;
|
|
366
|
+
- it is written and shared with the people it affects;
|
|
367
|
+
- it is known how to tell it is being kept and when to look at it again.
|
|
368
|
+
|
|
369
|
+
### Where records go wrong
|
|
370
|
+
|
|
371
|
+
- **Only upsides.** A reason that only restates the choice ("a queue, because
|
|
372
|
+
queues are reliable"), and the costs left out or played down.
|
|
373
|
+
- **The straw man.** An alternative that could never have worked, listed to
|
|
374
|
+
make the chosen one look good.
|
|
375
|
+
- **The sales tone.** Adjectives nobody could back with evidence. Take each
|
|
376
|
+
one out and see whether the record loses anything.
|
|
377
|
+
- **One option and one time frame.** No real alternative looked for, and only
|
|
378
|
+
the next few weeks' effects considered.
|
|
379
|
+
- **Criteria after the fact.** The forces chosen to fit the answer, or a
|
|
380
|
+
record written afterwards to justify a decision already made.
|
|
381
|
+
- **Everything in one.** A record carrying a whole architecture, or a detailed
|
|
382
|
+
design, instead of one decision.
|
|
383
|
+
- **Only the code's view.** The consequences for the people who run it, test
|
|
384
|
+
it, call it or pay for it missing.
|
|
385
|
+
- **Edited in place.** An accepted record quietly changed, so nobody can tell
|
|
386
|
+
what governed the work before, or when it changed.
|
|
387
|
+
|
|
222
388
|
## Make it runnable and testable
|
|
223
389
|
|
|
224
390
|
This is the part that makes an agent able to check its own work at any size
|
|
@@ -345,6 +511,51 @@ move the callers over in batches sized by what each batch touches, then delete
|
|
|
345
511
|
the old form once nothing calls it. If a piece deliberately leaves something
|
|
346
512
|
broken in between, say which piece and for how long.
|
|
347
513
|
|
|
514
|
+
## Hand a piece over
|
|
515
|
+
|
|
516
|
+
When someone else will build a piece (a person, another session, a
|
|
517
|
+
subagent), hand it over by its intention and leave the how to them. What goes
|
|
518
|
+
with it:
|
|
519
|
+
|
|
520
|
+
- **What is wanted, and why.** The note from "Say what is wanted", or where to
|
|
521
|
+
find it. The why is what lets the builder make the calls you did not
|
|
522
|
+
foresee.
|
|
523
|
+
- **The boundary.** What is in, what is out, and what it must stay compatible
|
|
524
|
+
with. Saying what is out keeps the builder from gold-plating the next thing
|
|
525
|
+
along. A constraint you know of and they could not find belongs here too:
|
|
526
|
+
that is part of the intent, not a step.
|
|
527
|
+
- **What done means**, as checks that can each be confirmed on their own.
|
|
528
|
+
|
|
529
|
+
Describe what the thing should do, not how to make it: behaviour, and the
|
|
530
|
+
names, types and contracts it touches, rather than file paths, line numbers or
|
|
531
|
+
a list of steps. The code moves while a piece waits, so paths go stale. A step
|
|
532
|
+
list settles the design before the builder has looked, carries your guesses as
|
|
533
|
+
if they were decisions, and takes away the judgement you handed the piece over
|
|
534
|
+
for. The design, the deeper research and the how are theirs, and so is
|
|
535
|
+
everything in this skill about deciding the shape. One exception: a snippet
|
|
536
|
+
from a prototype that pins a decision more exactly than words can (a state
|
|
537
|
+
machine, a schema, a type), trimmed to the decision and marked as coming from
|
|
538
|
+
a prototype.
|
|
539
|
+
|
|
540
|
+
Research before handing over goes as far as validating and triaging the
|
|
541
|
+
piece:
|
|
542
|
+
|
|
543
|
+
- **Is it real?** Above all when someone outside reported it. Reproduce a bug
|
|
544
|
+
from their steps, or find the behaviour in the running thing or the code,
|
|
545
|
+
and say what came of it: confirmed and where, not reproduced, or not enough
|
|
546
|
+
to tell. In the last case, ask the reporter for the specific thing that is
|
|
547
|
+
missing rather than passing a guess on. A confirmed problem makes a much
|
|
548
|
+
stronger hand-over than a suspected one.
|
|
549
|
+
- **Is it already there, or already turned down?** Look by what it does, not
|
|
550
|
+
by the reporter's words, and say where you looked.
|
|
551
|
+
- **Enough to place it**: how much it matters, roughly how big it is, what it
|
|
552
|
+
touches, and whether it can be handed over at all or needs a person's
|
|
553
|
+
judgement.
|
|
554
|
+
|
|
555
|
+
Then stop. Findings by file and line, a proposed fix, or a summary of all that
|
|
556
|
+
in the hand-off message is the builder's work done early, without the
|
|
557
|
+
builder's context.
|
|
558
|
+
|
|
348
559
|
## Before you build on it
|
|
349
560
|
|
|
350
561
|
Find out what the shape breaks elsewhere. Listing the callers is not the job;
|