@assuredloop/orca-bot-kit 0.1.0 → 0.2.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/LICENSE +21 -0
- package/README.md +545 -3
- package/SETUP.md +270 -0
- package/package.json +32 -13
- package/rules/evidence.md +15 -0
- package/rules/finishing.md +20 -0
- package/rules/limits.md +18 -0
- package/rules/mail.md +17 -0
- package/rules/profiles.md +9 -0
- package/rules/review.md +14 -0
- package/rules/scope.md +20 -0
- package/rules/simple.md +14 -0
- package/rules/talk.md +13 -0
- package/rules/tests-first.md +15 -0
- package/rules/the-ask.md +19 -0
- package/skills/obk-arch/LICENSES.md +45 -0
- package/skills/obk-arch/NOTICE.md +134 -0
- package/skills/obk-arch/SKILL.md +387 -0
- package/skills/obk-bot-building/LICENSES.md +21 -0
- package/skills/obk-bot-building/NOTICE.md +113 -0
- package/skills/obk-bot-building/SKILL.md +235 -0
- package/skills/obk-debugging/LICENSES.md +67 -0
- package/skills/obk-debugging/NOTICE.md +115 -0
- package/skills/obk-debugging/SKILL.md +419 -0
- package/skills/obk-decision-memo/LICENSES.md +49 -0
- package/skills/obk-decision-memo/NOTICE.md +181 -0
- package/skills/obk-decision-memo/SKILL.md +241 -0
- package/skills/obk-finops/LICENSES.md +19 -0
- package/skills/obk-finops/NOTICE.md +77 -0
- package/skills/obk-finops/SKILL.md +146 -0
- package/skills/obk-fleet-review/LICENSES.md +52 -0
- package/skills/obk-fleet-review/NOTICE.md +104 -0
- package/skills/obk-fleet-review/SKILL.md +219 -0
- package/skills/obk-grilling/LICENSES.md +42 -0
- package/skills/obk-grilling/NOTICE.md +103 -0
- package/skills/obk-grilling/SKILL.md +217 -0
- package/skills/obk-grooming/LICENSES.md +52 -0
- package/skills/obk-grooming/NOTICE.md +111 -0
- package/skills/obk-grooming/SKILL.md +219 -0
- package/skills/obk-handoff/LICENSES.md +45 -0
- package/skills/obk-handoff/NOTICE.md +51 -0
- package/skills/obk-handoff/SKILL.md +119 -0
- package/skills/obk-personal-facilitation/LICENSES.md +53 -0
- package/skills/obk-personal-facilitation/NOTICE.md +62 -0
- package/skills/obk-personal-facilitation/SKILL.md +86 -0
- package/skills/obk-recall/LICENSES.md +42 -0
- package/skills/obk-recall/NOTICE.md +53 -0
- package/skills/obk-recall/SKILL.md +129 -0
- package/skills/obk-researching/LICENSES.md +67 -0
- package/skills/obk-researching/NOTICE.md +170 -0
- package/skills/obk-researching/SKILL.md +259 -0
- package/skills/obk-reviewing/LICENSES.md +66 -0
- package/skills/obk-reviewing/NOTICE.md +58 -0
- package/skills/obk-reviewing/SKILL.md +408 -0
- package/skills/obk-tdd/LICENSES.md +68 -0
- package/skills/obk-tdd/NOTICE.md +54 -0
- package/skills/obk-tdd/SKILL.md +516 -0
- package/skills/obk-tdd/mutation-tools.md +80 -0
- package/skills/obk-teach/LICENSES.md +42 -0
- package/skills/obk-teach/NOTICE.md +65 -0
- package/skills/obk-teach/SKILL.md +106 -0
- package/skills/obk-why/LICENSES.md +42 -0
- package/skills/obk-why/NOTICE.md +74 -0
- package/skills/obk-why/SKILL.md +169 -0
- package/skills/obk-writing/LICENSES.md +272 -0
- package/skills/obk-writing/NOTICE.md +161 -0
- package/skills/obk-writing/SKILL.md +254 -0
- package/src/book.js +268 -0
- package/src/bot.js +451 -0
- package/src/cli.js +1130 -0
- package/src/conversations.js +150 -0
- package/src/groom.js +157 -0
- package/src/health.js +309 -0
- package/src/hooks.js +202 -0
- package/src/init.js +314 -0
- package/src/launch.js +276 -0
- package/src/message.js +380 -0
- package/src/orca.js +291 -0
- package/src/pause.js +58 -0
- package/src/record.js +209 -0
- package/src/restart.js +192 -0
- package/src/retire.js +92 -0
- package/src/roster.js +71 -0
- package/src/rules.js +408 -0
- package/src/skills.js +629 -0
- package/src/sources.js +370 -0
- package/src/up.js +475 -0
- package/src/usage.js +401 -0
- package/bin/okb.js +0 -4
- package/src/index.js +0 -11
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
<!-- Attribution for the sources this skill was built from. Kept out of
|
|
2
|
+
SKILL.md so it is not read into context on every use; it travels with
|
|
3
|
+
the skill directory, which is what the licences require. -->
|
|
4
|
+
|
|
5
|
+
# Sources and licences
|
|
6
|
+
|
|
7
|
+
The skill `obk-arch` was consolidated for this kit from these, all MIT, with
|
|
8
|
+
thanks:
|
|
9
|
+
|
|
10
|
+
- **Cursor pstack**, `architect` with its `runner-prompt`, `design-red-flags`
|
|
11
|
+
and `rationale-template` references. Writing the caller's usage and two or
|
|
12
|
+
three real call sites before the types, with the usage as the specification
|
|
13
|
+
and the sketch reconciled to it; data structures first with every dominant
|
|
14
|
+
access pattern traced through the proposed shape, and "we'll add an index
|
|
15
|
+
later" meaning the shape is wrong now; designing it twice with at least two
|
|
16
|
+
structurally distinct whole-shape candidates before synthesis; comparing on
|
|
17
|
+
interface depth; the red flags (callers coordinating several methods for one
|
|
18
|
+
operation, options exposing internal stages, learning the interface not
|
|
19
|
+
saving you from learning the implementation, information leakage, temporal
|
|
20
|
+
decomposition, pass-through methods); the rationale in the form "we accept X
|
|
21
|
+
in exchange for Y" with at least one alternative and why it lost, or "the
|
|
22
|
+
only viable shape, because..." where the constraints forced it (from its
|
|
23
|
+
`rationale-template`); keeping candidates genuinely apart rather than
|
|
24
|
+
converging on a safe middle (from `runner-prompt`); naming
|
|
25
|
+
anything a later reader might take for an oversight; and the scrap tells (the
|
|
26
|
+
repeated workaround, unrelated edge cases each needing a branch, escape
|
|
27
|
+
hatches in the types, the lock reflex where nothing was meant to be shared,
|
|
28
|
+
callers needing the internal rules), with deviations treated as signal and a
|
|
29
|
+
few edge cases not condemning a design.
|
|
30
|
+
- **Cursor pstack**, `architect`'s `runner-prompt` further to the above.
|
|
31
|
+
Grounding the design in what the code actually touches before sketching, and
|
|
32
|
+
what a sketch is (types and signatures with unimplemented bodies, a reader
|
|
33
|
+
able to trace input to output from the signatures alone); encoding invariants
|
|
34
|
+
in types ahead of runtime checks ahead of comments; validating at boundaries
|
|
35
|
+
and trusting types inside; one source of truth per invariant, derived rather
|
|
36
|
+
than kept in step; and asking what happens if an operation runs twice or
|
|
37
|
+
crashes halfway.
|
|
38
|
+
- **Cursor pstack**, `figure-it-out` further to the above. Capturing the
|
|
39
|
+
baseline before the change so the check reads as the old value against the
|
|
40
|
+
new; verdicts of verified, not verified or inconclusive with inconclusive not
|
|
41
|
+
being a pass; inspecting the artefact rather than a report of it; and
|
|
42
|
+
suspecting the observation method when something passes too easily.
|
|
43
|
+
- **Cursor pstack**, `blast-radius` further to the above. Looking where a
|
|
44
|
+
symbol search stops: the library's own source and its pinned version, when
|
|
45
|
+
things run, the shape of what an interface returns, a column, a wire format,
|
|
46
|
+
another language reading the same bytes, a feature flag; giving each risk a
|
|
47
|
+
real likelihood and a real cost; and listing separately what was checked and
|
|
48
|
+
cleared, since a search that finds nothing is still a result.
|
|
49
|
+
- **Cursor pstack**, `create-verification-skill`. The whole of making a thing
|
|
50
|
+
runnable and drivable, which the owner asked to live inside this skill rather
|
|
51
|
+
than have one of its own: interviewing the repository rather than the user
|
|
52
|
+
about surface, how it starts and how you know it is ready, how to drive it
|
|
53
|
+
without a person, what evidence can be captured, and whether two can run side
|
|
54
|
+
by side; the read-only check that says whether an instance is worth driving;
|
|
55
|
+
the proof standards (the real user path rather than an internal setter or a
|
|
56
|
+
test-only endpoint, the action and the resulting state rather than the final
|
|
57
|
+
screen, side effects verified alongside what is visible, stand-ins only where
|
|
58
|
+
a production boundary already isolates the thing); finding out what a dry run
|
|
59
|
+
actually skips by observing rather than trusting its name; cleanup that
|
|
60
|
+
removes what the run started and never the evidence, killing what you started
|
|
61
|
+
rather than by name; and running the instructions once end to end, because
|
|
62
|
+
something never executed is a draft rather than a deliverable. Also fixing,
|
|
63
|
+
or saying precisely what stopped, a checkout that does not build or start
|
|
64
|
+
before writing the recipe against it,
|
|
65
|
+
preferring stable handles over positions and coordinates, and the feature map
|
|
66
|
+
(a short list of what the thing does for someone, one entry per feature),
|
|
67
|
+
which that skill's own users praised most because an agent stops searching
|
|
68
|
+
the codebase for where things are. Kept here in that reduced form rather than
|
|
69
|
+
as its own generated directory.
|
|
70
|
+
- **Cursor pstack**, `principle-sequence-verifiable-units`, `figure-it-out`,
|
|
71
|
+
`blast-radius`, `principle-foundational-thinking`, `principle-model-the-domain`,
|
|
72
|
+
`principle-exhaust-the-design-space` and the `poteto-mode` planning playbooks.
|
|
73
|
+
Ordering work as small units each ending in a state you can check and not
|
|
74
|
+
advancing until it is green, with the reason (a break caught at the unit that
|
|
75
|
+
caused it is cheap, one caught after a batch is buried); done as a falsifiable
|
|
76
|
+
predicate stated before the run and never relaxed to declare victory (the
|
|
77
|
+
last from the `autonomous-run` playbook);
|
|
78
|
+
sequencing the riskiest unknown first; every box naming the evidence that
|
|
79
|
+
checks it, ticked only when that evidence exists; skipping the plan when the
|
|
80
|
+
change is one or two files with an obvious approach; settling an open
|
|
81
|
+
question by prototype before writing; data structures first with types and
|
|
82
|
+
data converging; a structure that carries the domain (a state machine, a
|
|
83
|
+
lookup table, a typed object) making invalid states impossible and deleting
|
|
84
|
+
branches, and the other side, not forcing an abstraction that removes no
|
|
85
|
+
branch, no duplicated rule and no invalid state, with the tell that the
|
|
86
|
+
modelling was skipped; the cases where exploring the design space is not worth it; and the
|
|
87
|
+
blast-radius ladder (said so, pointed at the line, showed the bad case
|
|
88
|
+
cannot happen, ran it, reproduced it) with "listing the callers is not the
|
|
89
|
+
job", the one fact a change is safe because of, and anything short of
|
|
90
|
+
running it said rather than written up as settled.
|
|
91
|
+
- **mattpocock/skills**, `codebase-design` with `DEEPENING` and
|
|
92
|
+
`DESIGN-IT-TWICE`, `domain-modeling` with its `ADR-FORMAT`, `prototype` and
|
|
93
|
+
`to-tickets`. The three questions to put to an interface (fewer ways in,
|
|
94
|
+
simpler arguments, more hidden behind it) and the interface as everything a
|
|
95
|
+
caller must know; the three conditions that must all hold before a decision
|
|
96
|
+
earns a lasting record of its own
|
|
97
|
+
(hard to reverse, surprising without the context, and the result of a real
|
|
98
|
+
trade-off) with what each one rules out; from `domain-modeling`, sharpening
|
|
99
|
+
a term that is doing too much work, forcing a boundary open with a concrete
|
|
100
|
+
scenario, and checking a claim about the domain against the code; from
|
|
101
|
+
`prototype`, being trivial to start, keeping nothing between runs, showing
|
|
102
|
+
the state after every action, and keeping only the decision it produced;
|
|
103
|
+
from `DESIGN-IT-TWICE`, combining the best of the candidates; the deletion
|
|
104
|
+
test,
|
|
105
|
+
the interface being the test surface, and one adapter meaning a hypothetical
|
|
106
|
+
seam against two meaning a real one; designing for testability by accepting
|
|
107
|
+
dependencies rather than creating them, returning results rather than causing
|
|
108
|
+
effects, and keeping the surface small; the four constraints that make
|
|
109
|
+
candidates genuinely different; how the dependency decides the way you test
|
|
110
|
+
across a seam, and "replace, don't layer" with the old shallow tests deleted
|
|
111
|
+
once tests exist at the deeper interface; vertical slices that cut a narrow
|
|
112
|
+
but complete path through every layer, each demoable on its own and sized to
|
|
113
|
+
one fresh context, with prefactoring first; expand, migrate and contract as
|
|
114
|
+
the exception for a change that has to happen everywhere; and a prototype
|
|
115
|
+
being throwaway code that answers a question, with the polish skipped on
|
|
116
|
+
purpose.
|
|
117
|
+
|
|
118
|
+
Left behind on purpose: the multi-model arena and its runners, fixed model
|
|
119
|
+
choices, the phase todolist and its ceremony, tracker and pull-request
|
|
120
|
+
machinery, the generated report formats, and the trigger that fires a design
|
|
121
|
+
review on any change crossing a function boundary. This skill is reached for
|
|
122
|
+
when there is a shape to get wrong, not on every change.
|
|
123
|
+
|
|
124
|
+
What the owner said, and how it shaped this: he asked for a very light part on
|
|
125
|
+
what is wanted and on dividing the work, leaving the details and the tracking
|
|
126
|
+
to the user (research-pack dialogue, 2026-09-19 19:09). The five items of the
|
|
127
|
+
note are the proposal he was given then; three further items that had been
|
|
128
|
+
added since, with no source behind them, are gone. He wanted the design to
|
|
129
|
+
include a clear effort on the big test step so the app is runnable and
|
|
130
|
+
testable (2026-09-19 18:54, and 2026-09-20 02:21), which is why that part stays in full. He agreed
|
|
131
|
+
that the source's strict vocabulary be dropped for plain words (18:50), so the
|
|
132
|
+
list of defined terms is gone and the ideas stay. He did not want a
|
|
133
|
+
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.
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: obk-arch
|
|
3
|
+
description: >-
|
|
4
|
+
Shaping a piece of work before building it: a short note of what is wanted
|
|
5
|
+
and what done means, deciding the shape from the usage and the data with
|
|
6
|
+
more than one candidate, making the thing runnable and testable so anyone
|
|
7
|
+
can find out whether it works, and cutting the work into pieces that each
|
|
8
|
+
end in a check. Use when starting something new, planning a feature, adding
|
|
9
|
+
a public interface or a new data shape, making a choice that is hard to
|
|
10
|
+
undo, or when a change is big enough that jumping into the code would settle
|
|
11
|
+
the shape by accident.
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Shaping work before you build it
|
|
15
|
+
|
|
16
|
+
Four things: say what is wanted, decide the shape, make sure the thing can be
|
|
17
|
+
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.
|
|
19
|
+
|
|
20
|
+
None of this needs a particular document, tracker or format. Where a project
|
|
21
|
+
has one, use it; where it does not, a few lines in the right place do the job.
|
|
22
|
+
|
|
23
|
+
Reach for this when there is a shape to get wrong: something new, a public
|
|
24
|
+
interface, a new data shape, a choice that will be expensive to undo. Not for
|
|
25
|
+
work where the pattern is already set, a bug fix with a clear target, or a
|
|
26
|
+
change the constraints leave only one way to make. When it is one or two files
|
|
27
|
+
and the approach is obvious, say so and go and do it. A plan longer than the
|
|
28
|
+
work it plans is a cost with no return.
|
|
29
|
+
|
|
30
|
+
These are defaults for work where nothing says otherwise. A user who asks for
|
|
31
|
+
something else gets what they asked for; say which of these you left and why.
|
|
32
|
+
|
|
33
|
+
## Say what is wanted
|
|
34
|
+
|
|
35
|
+
A very light note: short enough to be read, long enough that someone else could
|
|
36
|
+
act on it. It says:
|
|
37
|
+
|
|
38
|
+
- **The problem.** What is wrong or missing now, not the solution wearing a
|
|
39
|
+
problem's clothes.
|
|
40
|
+
- **Who it is for.** The person who has that problem, which is often not the
|
|
41
|
+
person asking.
|
|
42
|
+
- **What they can do once it is finished**, as behaviour someone could observe
|
|
43
|
+
from outside.
|
|
44
|
+
- **How we will know it works**, written as checkable statements. These are the
|
|
45
|
+
ones that matter most: they become the acceptance tests when the work starts
|
|
46
|
+
and the "what was asked" a reviewer reads it against, so write them as
|
|
47
|
+
something you could be wrong about, and never loosen one to declare victory.
|
|
48
|
+
- **What we are not doing.** The things nobody said aloud are the things that
|
|
49
|
+
get built by accident.
|
|
50
|
+
|
|
51
|
+
No format and no home: an issue, a file, a message, a page in whatever the
|
|
52
|
+
project already uses. And if a proper note already exists, use that one rather
|
|
53
|
+
than writing a second.
|
|
54
|
+
|
|
55
|
+
## Decide the shape
|
|
56
|
+
|
|
57
|
+
### Sharpen the words while you are at it
|
|
58
|
+
|
|
59
|
+
When a term keeps doing heavy lifting ("account", "active", "ready"), say what
|
|
60
|
+
it means here and what it does not; where that stays vague, a concrete scenario
|
|
61
|
+
forces the boundary open. Check a claim about how things work against the code
|
|
62
|
+
rather than accepting it.
|
|
63
|
+
|
|
64
|
+
### Ground it first
|
|
65
|
+
|
|
66
|
+
Before sketching anything, build a real model of what the new code touches: the
|
|
67
|
+
modules it will sit between, how data reaches them now, what already owns the
|
|
68
|
+
rules you are about to write. Naming a file is not grounding. Trace it.
|
|
69
|
+
Skipping this is what produces a design that is elegant and does not fit.
|
|
70
|
+
|
|
71
|
+
Where the design redefines who owns what, find out why the current shape is
|
|
72
|
+
the way it is first, so the reason becomes a constraint you are choosing to
|
|
73
|
+
overrule rather than one you never saw. Greenfield with nothing around it is
|
|
74
|
+
the one case to skip.
|
|
75
|
+
|
|
76
|
+
### What a sketch is
|
|
77
|
+
|
|
78
|
+
Types, signatures and module boundaries with nothing implemented: bodies that
|
|
79
|
+
say "not implemented", a comment where the tricky logic will go, and a line on
|
|
80
|
+
each saying what it is for and what it must keep true. The test of a good one
|
|
81
|
+
is that a reader can follow the data from input to output by reading the
|
|
82
|
+
signatures alone.
|
|
83
|
+
|
|
84
|
+
That is what you compare, argue about and throw away, cheaply, which is the
|
|
85
|
+
point of doing it before the code.
|
|
86
|
+
|
|
87
|
+
### Usage first, then the data, then the types
|
|
88
|
+
|
|
89
|
+
Write the calls before the types: two or three real call sites, and how
|
|
90
|
+
someone would use it if they were reading about it for the first time. The
|
|
91
|
+
usage is the specification. When the sketch and the usage disagree, change the
|
|
92
|
+
sketch.
|
|
93
|
+
|
|
94
|
+
Then the data. Get the shape of it right before the logic, and trace every way
|
|
95
|
+
it will be read and written through the shape you are proposing. If the answer
|
|
96
|
+
to one of those is "we can add an index or a cache for that later", the shape
|
|
97
|
+
is wrong now, not later.
|
|
98
|
+
|
|
99
|
+
Types and data converge. Three similar lines still beat an abstraction
|
|
100
|
+
invented before there was anything to abstract.
|
|
101
|
+
|
|
102
|
+
Five things worth deciding while the shape is still cheap to change:
|
|
103
|
+
|
|
104
|
+
- **Let a structure carry the domain.** A state machine rather than scattered
|
|
105
|
+
flags, a lookup table rather than branches spread across files, a typed
|
|
106
|
+
object rather than loose parameters: the right structure makes invalid
|
|
107
|
+
states impossible to write and deletes branches.
|
|
108
|
+
|
|
109
|
+
- **Put the rules in the types where you can.** A type that cannot be misused
|
|
110
|
+
beats a check at runtime, which beats a comment asking people to be careful.
|
|
111
|
+
- **Check at the edges and trust inside.** Validate where data enters, then let
|
|
112
|
+
the inside assume it is good. Scattering the same check through the middle
|
|
113
|
+
means no one place is responsible for it.
|
|
114
|
+
- **One home per rule.** Derive the rest rather than keeping two copies in
|
|
115
|
+
step; two copies of one fact is a bug with a delay on it.
|
|
116
|
+
- **Ask what happens if it runs twice, or stops halfway.** If the answer
|
|
117
|
+
depends on what the last attempt left behind, something is missing that puts
|
|
118
|
+
it back in order, and that is a design question, not an operational one.
|
|
119
|
+
|
|
120
|
+
### Design it twice
|
|
121
|
+
|
|
122
|
+
Produce at least two structurally different candidates before you choose, even
|
|
123
|
+
when the first looks sufficient. Whole shapes, not variations inside one shape.
|
|
124
|
+
Two ways to arrange the same idea teach you nothing.
|
|
125
|
+
|
|
126
|
+
A cheap way to get real difference is to give each candidate a constraint of
|
|
127
|
+
its own and see what it forces:
|
|
128
|
+
|
|
129
|
+
- the smallest possible interface, one to three ways in, as much behind each as
|
|
130
|
+
will fit;
|
|
131
|
+
- the one that bends to the widest range of uses;
|
|
132
|
+
- the one that makes the most common case trivial and lets the rest be awkward;
|
|
133
|
+
- the one that puts whatever varies behind a port with adapters either side.
|
|
134
|
+
|
|
135
|
+
Keep them genuinely apart while you make them; a safe middle drafted early
|
|
136
|
+
defeats the point. Then compare on how much each hides, prefer the shape that
|
|
137
|
+
puts more behaviour behind a smaller surface (that is what a caller is buying),
|
|
138
|
+
and take the best parts of the others into it where they combine.
|
|
139
|
+
|
|
140
|
+
### Judging an interface
|
|
141
|
+
|
|
142
|
+
The interface is everything a caller has to know to use a piece correctly: not
|
|
143
|
+
only the signature, but the order things must happen in, what errors come out,
|
|
144
|
+
what it needs and what it costs. A good one gives a caller a lot of behaviour
|
|
145
|
+
for a little of that. Three questions do most of the work: can it have fewer
|
|
146
|
+
ways in, can the arguments be simpler, and can more be hidden behind it?
|
|
147
|
+
|
|
148
|
+
### Three tests that settle most of it
|
|
149
|
+
|
|
150
|
+
- **The deletion test.** Imagine the module gone. If the complexity goes with
|
|
151
|
+
it, it was a pass-through. If the complexity reappears in every caller, it
|
|
152
|
+
was earning its place.
|
|
153
|
+
- **The interface is the test surface.** Callers and tests cross at the same
|
|
154
|
+
place. If you find yourself wanting to test past the interface, the shape is
|
|
155
|
+
probably wrong.
|
|
156
|
+
- **One adapter is a hypothetical port; two is a real one.** This one is about
|
|
157
|
+
pluggability, not about whether a module should exist. Before putting an
|
|
158
|
+
interchangeable boundary in (a port with adapters either side), ask what the
|
|
159
|
+
second adapter is; production plus a test double is the usual honest pair. If
|
|
160
|
+
there is only ever one, you have added a layer to swap something that never
|
|
161
|
+
gets swapped. Pure computation needs no adapter at all: merge it and test it
|
|
162
|
+
through its interface.
|
|
163
|
+
|
|
164
|
+
Whether a module earns its place is a different question, answered by the
|
|
165
|
+
deletion test and by how much it hides. A module with one caller can be
|
|
166
|
+
entirely right, hiding an invariant, a rule or a state machine that would
|
|
167
|
+
otherwise sit in the middle of something else. One caller is not one adapter,
|
|
168
|
+
and counting callers is not this test.
|
|
169
|
+
|
|
170
|
+
### Signs the shape is wrong
|
|
171
|
+
|
|
172
|
+
- A caller has to call several things in the right order to do one thing.
|
|
173
|
+
- The options expose the stages inside rather than what the caller wants.
|
|
174
|
+
- Learning the interface does not save you from learning the implementation.
|
|
175
|
+
- Several modules depend on the same decision made inside one of them.
|
|
176
|
+
- Modules named after the order things happen rather than what they know. The
|
|
177
|
+
same rule then gets repeated in each step.
|
|
178
|
+
- A function that passes the same arguments on to something with the same
|
|
179
|
+
shape, adding a layer and hiding nothing.
|
|
180
|
+
|
|
181
|
+
And the other way: do not force it. Boring, local and clear is right where the
|
|
182
|
+
thing is unlikely to grow, and an abstraction that removes no branch, no
|
|
183
|
+
repeated rule and no impossible state is just indirection. The tell that this
|
|
184
|
+
step got skipped is the next feature adding one more branch to an if-else
|
|
185
|
+
chain, or a second flag that has to be kept in step with the first.
|
|
186
|
+
|
|
187
|
+
### Write down what you chose
|
|
188
|
+
|
|
189
|
+
One short paragraph, where the next person will find it: the problem, how it
|
|
190
|
+
is used, the shape, the trade-offs accepted (in the form *we accept X in
|
|
191
|
+
exchange for Y*), at least one other shape you considered with a line on why
|
|
192
|
+
it lost, and anything still open.
|
|
193
|
+
|
|
194
|
+
Where the constraints left only one shape, say that instead: "the only viable
|
|
195
|
+
shape, because...". Name anything a later reader might mistake for an
|
|
196
|
+
oversight.
|
|
197
|
+
|
|
198
|
+
A lasting record of its own, kept beyond the change, earns its place when all
|
|
199
|
+
three are true: it is hard to reverse, it is surprising without the context,
|
|
200
|
+
and it came out of a genuine trade-off. Miss one and the paragraph is enough.
|
|
201
|
+
|
|
202
|
+
### When to build a throwaway instead of arguing
|
|
203
|
+
|
|
204
|
+
A prototype answers one question and is then deleted. No question, no
|
|
205
|
+
prototype: "let's try something" is not a question.
|
|
206
|
+
|
|
207
|
+
Skip the polish deliberately: no tests, no error handling beyond what makes it
|
|
208
|
+
run, no abstractions. Say out loud that it is throwaway, so nobody tries to
|
|
209
|
+
harden it or ship it.
|
|
210
|
+
|
|
211
|
+
Three things make one actually useful. It has to be trivial to start: one
|
|
212
|
+
command, or a file someone double-clicks; anything that needs explaining will
|
|
213
|
+
not get run by the person whose opinion you wanted. It should keep nothing
|
|
214
|
+
between runs, because persistence is usually the thing being questioned rather
|
|
215
|
+
than something to lean on. And it should show its state after every action, so
|
|
216
|
+
what changed is visible rather than inferred.
|
|
217
|
+
|
|
218
|
+
The observation is the result, not the code. Keep the decision it produced,
|
|
219
|
+
throw the prototype away or park it somewhere clearly marked, and write the
|
|
220
|
+
real thing from the beginning, test first.
|
|
221
|
+
|
|
222
|
+
## Make it runnable and testable
|
|
223
|
+
|
|
224
|
+
This is the part that makes an agent able to check its own work at any size
|
|
225
|
+
above a single function, and it belongs in the design rather than after it.
|
|
226
|
+
When a whole application is designed, or a feature is planned, the end-to-end
|
|
227
|
+
test work is planned at the same time and with the same care, and written, like
|
|
228
|
+
any other test, by someone other than the implementer.
|
|
229
|
+
|
|
230
|
+
Answer these about the thing you are shaping, from the code where you can
|
|
231
|
+
rather than by asking:
|
|
232
|
+
|
|
233
|
+
- **Surface**. What does a person actually touch? A screen, a command, an
|
|
234
|
+
endpoint, a library. If there are several, pick the main one and name the
|
|
235
|
+
rest.
|
|
236
|
+
- **Start**. How does it come up, and how do you know it is ready? A log line,
|
|
237
|
+
a port answering, a prompt appearing. Guessing with a pause is not knowing.
|
|
238
|
+
- **Drive**. How can something interact with it with nobody watching?
|
|
239
|
+
Whatever the project already has first; a general harness only after that.
|
|
240
|
+
- **Observe**. What evidence can be captured? Output, an exit status, a file,
|
|
241
|
+
a stored row, a message sent, a picture of the screen.
|
|
242
|
+
- **Isolate**. Can two of these run side by side, with their own ports and
|
|
243
|
+
data? If not, say so plainly, because refusing to drive a shared instance is
|
|
244
|
+
better than corrupting the one someone is using.
|
|
245
|
+
|
|
246
|
+
If the thing does not build or start as it stands, either fix that first or say
|
|
247
|
+
precisely what stopped it: which command, which failure, what was missing.
|
|
248
|
+
A recipe written against a broken checkout and presented as working teaches the
|
|
249
|
+
next reader the wrong steps, confidently. A recipe written against one and
|
|
250
|
+
marked as not yet run is still worth having: it says what the proof will be
|
|
251
|
+
once someone can get the thing up, which is most of the value. What it must not
|
|
252
|
+
do is claim to have been proven. And repairing whatever is broken is its own
|
|
253
|
+
piece of work, not something to absorb quietly into this one.
|
|
254
|
+
|
|
255
|
+
Prefer handles that survive: the name of a thing, a label, a route, a prompt
|
|
256
|
+
the program prints. Positions, orders and coordinates all drift, and a recipe
|
|
257
|
+
pinned to them fails for reasons that have nothing to do with the code.
|
|
258
|
+
|
|
259
|
+
Worth writing beside the recipe: a short list of what the thing actually does
|
|
260
|
+
for someone, one entry per feature (how to reach it, how to drive it, and what
|
|
261
|
+
state proves it worked). It is the part people find most useful later, because a
|
|
262
|
+
proof that exercises whichever entry point was convenient is incomplete when
|
|
263
|
+
the list names others. Start with the few that matter and let it grow.
|
|
264
|
+
|
|
265
|
+
Worth having beside that: one read-only check that answers "is this instance
|
|
266
|
+
worth driving at all" (is it up, is it the build I think, is that port ours).
|
|
267
|
+
Run it first whenever something looks strange, before debugging the thing
|
|
268
|
+
underneath.
|
|
269
|
+
|
|
270
|
+
What a proof has to do, which is where most of them fail:
|
|
271
|
+
|
|
272
|
+
- drive the path a person would actually take, not an internal setter or a
|
|
273
|
+
door that exists only for tests;
|
|
274
|
+
- capture the action and the state it produced, not only the final screen;
|
|
275
|
+
- check the effects as well as what is visible: what was written, sent,
|
|
276
|
+
recorded;
|
|
277
|
+
- stand in for something only where a real boundary already separates it.
|
|
278
|
+
|
|
279
|
+
Where the safe path is a dry run, find out what it genuinely skips by watching
|
|
280
|
+
what happens (files, network, state) rather than trusting its name.
|
|
281
|
+
|
|
282
|
+
Clean up what a run started, and never by name: stop what you started. Cleanup
|
|
283
|
+
takes the instance away and leaves the evidence where it said it would be.
|
|
284
|
+
|
|
285
|
+
Whatever you write down so that the next agent can do this, run it once, end to
|
|
286
|
+
end, before you hand it over. Instructions nobody has executed are a draft.
|
|
287
|
+
|
|
288
|
+
Where the work is about changing a number rather than adding a behaviour, take
|
|
289
|
+
the measurement before you start, so the check reads as the old value against
|
|
290
|
+
the new one rather than as a number with nothing to compare it to.
|
|
291
|
+
|
|
292
|
+
And be strict about what counts. A check comes back verified, not verified, or
|
|
293
|
+
inconclusive. And inconclusive is not a pass. Read the artefact rather than a
|
|
294
|
+
report about it. When something passes more easily than you expected, suspect
|
|
295
|
+
the way you are observing before you believe the result: that is the shape of a
|
|
296
|
+
check that is not actually looking.
|
|
297
|
+
|
|
298
|
+
### Designing so this is possible
|
|
299
|
+
|
|
300
|
+
Accept what you depend on rather than building it inside. Return results
|
|
301
|
+
instead of reaching out and changing things. Keep the surface small: fewer ways
|
|
302
|
+
in means less to set up.
|
|
303
|
+
|
|
304
|
+
How you test across a boundary follows what is behind it. Pure computation:
|
|
305
|
+
no boundary needed, test through the interface. Something with a good local
|
|
306
|
+
stand-in: use the stand-in and keep the boundary inside. Your own service
|
|
307
|
+
across a network: a port at the boundary, a real adapter for production and an
|
|
308
|
+
in-memory one for tests. Something you do not own at all: a port, and a
|
|
309
|
+
stand-in for it.
|
|
310
|
+
|
|
311
|
+
Once behaviour is covered through the interface above, tests against the pieces
|
|
312
|
+
inside it prove the same thing twice; retiring them, like any change to
|
|
313
|
+
tests, is for whoever wrote them.
|
|
314
|
+
|
|
315
|
+
## Cut the work into pieces
|
|
316
|
+
|
|
317
|
+
Each piece ends in a state you can check, and a piece that depends on it does
|
|
318
|
+
not start until it is green. A break found at the step that caused it is cheap; the
|
|
319
|
+
same break found five steps later is buried under everything built on top of
|
|
320
|
+
it.
|
|
321
|
+
|
|
322
|
+
- **Each piece is a narrow but complete path** through every layer it touches,
|
|
323
|
+
not one layer done across the whole feature. A finished piece can be shown
|
|
324
|
+
or checked on its own.
|
|
325
|
+
- **Sized to what one fresh context can hold**, because a piece that does not
|
|
326
|
+
fit gets done half-remembered.
|
|
327
|
+
- **Ordered by what you will learn.** The riskiest unknown first, so that
|
|
328
|
+
being wrong about it is cheap.
|
|
329
|
+
- **Prefactor where it helps.** Make the change easy, then make the easy
|
|
330
|
+
change. A small reshaping is part of the change; a large one is a piece of
|
|
331
|
+
its own, before the feature.
|
|
332
|
+
- **The first piece gets the thing running and testable as a whole**, even if
|
|
333
|
+
it does almost nothing yet. That is where the end-to-end test work lands, and
|
|
334
|
+
everything after it is checked through what it puts in place.
|
|
335
|
+
- **Each piece names the evidence** that says it is done: a test run, a file, a
|
|
336
|
+
line of output, a command. It is done when the evidence exists, not when it
|
|
337
|
+
feels done.
|
|
338
|
+
- **Say which pieces depend on which, and which can run side by side.** Two
|
|
339
|
+
people, or two sessions, can take independent pieces at once; a dependency
|
|
340
|
+
nobody wrote down turns into two people editing the same thing.
|
|
341
|
+
|
|
342
|
+
The exception is a change that has to happen everywhere at once. Sequence it as
|
|
343
|
+
expand, migrate, contract: add the new form beside the old so nothing breaks,
|
|
344
|
+
move the callers over in batches sized by what each batch touches, then delete
|
|
345
|
+
the old form once nothing calls it. If a piece deliberately leaves something
|
|
346
|
+
broken in between, say which piece and for how long.
|
|
347
|
+
|
|
348
|
+
## Before you build on it
|
|
349
|
+
|
|
350
|
+
Find out what the shape breaks elsewhere. Listing the callers is not the job;
|
|
351
|
+
the breakage a search does not show is (a changed order, a new precondition, an
|
|
352
|
+
assumption two things shared). Most plans that look risky are safe because of
|
|
353
|
+
one fact: find it, since if it holds most of the risky cases clear at once.
|
|
354
|
+
|
|
355
|
+
Look where a symbol search stops, because that is where the surprises are: the
|
|
356
|
+
library you call, at the version actually pinned; when things run, not only
|
|
357
|
+
what calls what; and what two things agree on without naming each other (the
|
|
358
|
+
shape of what an interface returns, a stored column, a wire format, something
|
|
359
|
+
in another language reading the same bytes, a setting that turns a path on).
|
|
360
|
+
Give each risk you keep a real likelihood and a real cost.
|
|
361
|
+
|
|
362
|
+
Then say how far you proved it: you said so, you pointed at the line, you
|
|
363
|
+
walked the bad case through, you ran something that would have failed if you
|
|
364
|
+
were wrong, or you saw it in the running thing. Short of running it, say so
|
|
365
|
+
rather than writing it up as settled, and list what you checked and cleared as
|
|
366
|
+
well as what you kept.
|
|
367
|
+
|
|
368
|
+
## When the shape turns out to be wrong
|
|
369
|
+
|
|
370
|
+
Deviations from the sketch are signal, not friction to absorb quietly. A
|
|
371
|
+
function that needs a parameter the sketch did not anticipate is asking a
|
|
372
|
+
question: was the sketch wrong, was the requirement missed, or is the
|
|
373
|
+
implementation reaching for something that is not its business?
|
|
374
|
+
|
|
375
|
+
The signal is a pattern rather than a single instance:
|
|
376
|
+
|
|
377
|
+
- the same shape of workaround appearing in unrelated places;
|
|
378
|
+
- several unrelated edge cases that each need their own special branch;
|
|
379
|
+
- types needing escape hatches to compile at all;
|
|
380
|
+
- reaching for a lock where the sketch said nothing was shared;
|
|
381
|
+
- callers having to know the rules inside to use it correctly.
|
|
382
|
+
|
|
383
|
+
A few edge cases do not condemn a design; some problems really are knotty, and
|
|
384
|
+
complexity in the problem is not complexity in the design. But when the pattern
|
|
385
|
+
is there, say so and redesign, rather than paying it off one branch at a time.
|
|
386
|
+
|
|
387
|
+
Sources and licences: [NOTICE.md](NOTICE.md).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!-- The licences of the sources this skill was consolidated from. They travel
|
|
2
|
+
with the skill directory because the licences require it of anyone who
|
|
3
|
+
distributes the material. NOTICE.md says what was taken from each source;
|
|
4
|
+
this file carries the permission notices themselves. -->
|
|
5
|
+
|
|
6
|
+
# Licences of the sources
|
|
7
|
+
|
|
8
|
+
`obk-bot-building` names its sources in [NOTICE.md](NOTICE.md).
|
|
9
|
+
|
|
10
|
+
## Sources that need no third-party notice
|
|
11
|
+
|
|
12
|
+
This skill reproduces no third-party text. It was written from this kit's own
|
|
13
|
+
PRD and ADRs, from the owner's own words in the research pack, and from ideas
|
|
14
|
+
restated in our own words.
|
|
15
|
+
|
|
16
|
+
Those ideas came from material that carries no licence: a knowledge base and a
|
|
17
|
+
hosted bot product's own marketplace and documentation pages, gathered in the
|
|
18
|
+
research pack's `grok-bot-lessons.md`. Because no licence is attached to them,
|
|
19
|
+
nothing of theirs is copied here, and there is accordingly no permission notice
|
|
20
|
+
to reproduce. Credit for the ideas is given in NOTICE.md instead, which is
|
|
21
|
+
where it belongs.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!-- Attribution for the sources this skill was built from. Kept out of
|
|
2
|
+
SKILL.md so it is not read into context on every use; it travels with
|
|
3
|
+
the skill directory, which is what the licences require. -->
|
|
4
|
+
|
|
5
|
+
# Sources and licences
|
|
6
|
+
|
|
7
|
+
`obk-bot-building` reproduces no third-party text. What it took from outside
|
|
8
|
+
this kit, it took as an idea and wrote again in its own words, for the reason
|
|
9
|
+
given under "Ideas taken from material with no licence" below.
|
|
10
|
+
|
|
11
|
+
## The owner's own words
|
|
12
|
+
|
|
13
|
+
The charter is three questions because he settled it at three. His word on the
|
|
14
|
+
proposal that the interview happens once at a bot's creation and asks what the
|
|
15
|
+
bot owns, what good work looks like, and what it must ask about first, in the
|
|
16
|
+
research pack's session dialogue: "looks good for charter interview."
|
|
17
|
+
|
|
18
|
+
Two other lines of his shape this skill. On what a bot is allowed to do: he is
|
|
19
|
+
"building bot to allow agency by itself but in the boundary and contract we are
|
|
20
|
+
creating, not freely", which is why the limits section here reads as a boundary
|
|
21
|
+
to act inside rather than as a leash. His one-liner remark ("I expect to have
|
|
22
|
+
one liner the user can send to LLM, and then the rest is done by AI") was about
|
|
23
|
+
setup, not the interview, and is no longer used for it; the interview follows
|
|
24
|
+
his own grilling instruction instead (below).
|
|
25
|
+
|
|
26
|
+
On bringing in a session they already run: "yes the session history shall be
|
|
27
|
+
able to resume, i.e., resume an external session, the rest is best effort
|
|
28
|
+
migrated with llm capability", and, correcting a restatement of it, "as the
|
|
29
|
+
setup is done via llm, including future setup via the bot manager, the llm does
|
|
30
|
+
best effort to help user migrate". That is where "best effort, and say so
|
|
31
|
+
plainly" comes from.
|
|
32
|
+
|
|
33
|
+
## This kit's own design
|
|
34
|
+
|
|
35
|
+
The PRD and the ADRs carry the rest: the line-up suggestions and the
|
|
36
|
+
role-to-skills guidance (PRD 6.8, ADR 0009, which puts that table in the
|
|
37
|
+
management skill), a session's settings and the rule that the kit never
|
|
38
|
+
hardcodes a model id, the approval levels and that the widest one is used only
|
|
39
|
+
when the user asks for it in plain words, the two plain defaults that no
|
|
40
|
+
silent fallback happens and that a role limit such as "read-only, does not
|
|
41
|
+
modify" is a normal part of a charter (PRD 6.4 and 6.6), and pinning an online
|
|
42
|
+
skill source to a version with a word about what a source carrying scripts or
|
|
43
|
+
hooks means (PRD 6.7).
|
|
44
|
+
|
|
45
|
+
## Ideas taken from material with no licence
|
|
46
|
+
|
|
47
|
+
The research pack's `grok-bot-lessons.md` gathers how one hosted bot product is
|
|
48
|
+
run. Its material comes from a knowledge base and from that product's own
|
|
49
|
+
marketplace and documentation pages. No licence is attached to those pages, and
|
|
50
|
+
the pack's own caution records that the marketplace entries were summarised by
|
|
51
|
+
a fetch tool rather than read verbatim. So no text of theirs is reproduced
|
|
52
|
+
here, and none of it was read as text worth copying. What was taken is the
|
|
53
|
+
idea, restated:
|
|
54
|
+
|
|
55
|
+
- that a bot is a job somebody holds rather than a prompt that came out well,
|
|
56
|
+
and is named after a job a person could hold;
|
|
57
|
+
- that the thing worth writing down is what it owns, what good looks like, and
|
|
58
|
+
what it must not do without asking;
|
|
59
|
+
- that an interview at creation is what writes that down;
|
|
60
|
+
- that a bot an existing one could own the work of should not be created;
|
|
61
|
+
- that a role needing several unrelated verbs is more than one role, that the
|
|
62
|
+
split goes by domain rather than by how much work there is, and that a
|
|
63
|
+
specialist is worth adding only when a real bottleneck has shown up: a noisy
|
|
64
|
+
shared context, a bot that cannot review its own work, or permissions that
|
|
65
|
+
have diverged;
|
|
66
|
+
- that instructions have three lifetimes, the durable role, the one assignment
|
|
67
|
+
and the reusable procedure, and that a one-off correction must not quietly
|
|
68
|
+
become a rule.
|
|
69
|
+
|
|
70
|
+
## What was deliberately not taken
|
|
71
|
+
|
|
72
|
+
That source's creation interview fills a fixed list of about ten fields. This
|
|
73
|
+
skill asks three questions and stops. The owner settled the charter at three,
|
|
74
|
+
and the rest of what a bot needs is settings, which are not an interview.
|
|
75
|
+
|
|
76
|
+
Its bot-classification vocabulary is not here either; reviewing a fleet that
|
|
77
|
+
already exists is a different job and lives in `obk-fleet-review`.
|
|
78
|
+
|
|
79
|
+
## Sources that need no third-party notice
|
|
80
|
+
|
|
81
|
+
Everything above is either this kit's own design, the owner's own words, or an
|
|
82
|
+
idea restated in our own words from material that carries no licence. Nothing
|
|
83
|
+
in this skill reproduces a third party's text, so there is no permission notice
|
|
84
|
+
to pass on. See [LICENSES.md](LICENSES.md).
|
|
85
|
+
|
|
86
|
+
## What the re-validation changed (#156)
|
|
87
|
+
|
|
88
|
+
- The charter questions are asked together, each with a drafted answer, not
|
|
89
|
+
one at a time: the owner asked to be asked three questions at a time with a
|
|
90
|
+
recommended answer (research-pack dialogue, 2026-09-19 13:24, with matt's
|
|
91
|
+
grilling loaded), and
|
|
92
|
+
his usage review complains of one question per turn.
|
|
93
|
+
- The answer handed back is the roster card PRD 6.8 decides (name, harness,
|
|
94
|
+
model and effort, a two-line charter, one hard limit).
|
|
95
|
+
- The skills for each role are named, since ADR 0009 puts that choice in the
|
|
96
|
+
management skill.
|
|
97
|
+
- What the command line does and does not do, checked against `obk --help`:
|
|
98
|
+
`obk skills fetch` was missing; a charter, settings or list change is an
|
|
99
|
+
edit plus `obk rules build` or `obk skills build`; pausing or retiring has
|
|
100
|
+
no command. Each management action is committed (PRD 6.10). Issue #158 later
|
|
101
|
+
gave changing, pausing and retiring their commands, and the hand edit is
|
|
102
|
+
left for the special case, said so.
|
|
103
|
+
- A change of model, effort or approval reaches a session only by `obk
|
|
104
|
+
restart`, on the user's word, and a whole-fleet restart is done from the ops
|
|
105
|
+
tab (PRD 6.5).
|
|
106
|
+
- Bringing in a session: the outside id goes into the book by hand, and a
|
|
107
|
+
resume across folders is to be tried before it is promised.
|
|
108
|
+
- Cut: a paragraph restating the opening, and two sentences of framing.
|
|
109
|
+
- Memory per bot is the owner's decision of 2026-09-23 (issue #211): a bot may
|
|
110
|
+
turn on its harness's memory for itself, since the owner's global setting is
|
|
111
|
+
off. The three Claude Code keys, and that without `autoMemoryDirectory` every
|
|
112
|
+
bot in the repo shares one memory, were measured live and are in the tech
|
|
113
|
+
notes; Codex's memories are the user's and cannot be one bot's.
|