@assuredloop/orca-bot-kit 0.1.0 → 0.3.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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +548 -3
  3. package/SETUP.md +275 -0
  4. package/package.json +32 -13
  5. package/rules/evidence.md +15 -0
  6. package/rules/finishing.md +23 -0
  7. package/rules/limits.md +18 -0
  8. package/rules/mail.md +17 -0
  9. package/rules/profiles.md +9 -0
  10. package/rules/review.md +14 -0
  11. package/rules/scope.md +22 -0
  12. package/rules/simple.md +14 -0
  13. package/rules/talk.md +13 -0
  14. package/rules/tests-first.md +17 -0
  15. package/rules/the-ask.md +19 -0
  16. package/skills/obk-arch/LICENSES.md +52 -0
  17. package/skills/obk-arch/NOTICE.md +242 -0
  18. package/skills/obk-arch/SKILL.md +598 -0
  19. package/skills/obk-bot-building/LICENSES.md +21 -0
  20. package/skills/obk-bot-building/NOTICE.md +113 -0
  21. package/skills/obk-bot-building/SKILL.md +312 -0
  22. package/skills/obk-debugging/LICENSES.md +67 -0
  23. package/skills/obk-debugging/NOTICE.md +115 -0
  24. package/skills/obk-debugging/SKILL.md +434 -0
  25. package/skills/obk-decision-memo/LICENSES.md +49 -0
  26. package/skills/obk-decision-memo/NOTICE.md +181 -0
  27. package/skills/obk-decision-memo/SKILL.md +241 -0
  28. package/skills/obk-finops/LICENSES.md +19 -0
  29. package/skills/obk-finops/NOTICE.md +77 -0
  30. package/skills/obk-finops/SKILL.md +148 -0
  31. package/skills/obk-fleet-review/LICENSES.md +52 -0
  32. package/skills/obk-fleet-review/NOTICE.md +104 -0
  33. package/skills/obk-fleet-review/SKILL.md +256 -0
  34. package/skills/obk-grilling/LICENSES.md +42 -0
  35. package/skills/obk-grilling/NOTICE.md +111 -0
  36. package/skills/obk-grilling/SKILL.md +221 -0
  37. package/skills/obk-grooming/LICENSES.md +52 -0
  38. package/skills/obk-grooming/NOTICE.md +111 -0
  39. package/skills/obk-grooming/SKILL.md +222 -0
  40. package/skills/obk-handoff/LICENSES.md +45 -0
  41. package/skills/obk-handoff/NOTICE.md +51 -0
  42. package/skills/obk-handoff/SKILL.md +119 -0
  43. package/skills/obk-personal-facilitation/LICENSES.md +53 -0
  44. package/skills/obk-personal-facilitation/NOTICE.md +62 -0
  45. package/skills/obk-personal-facilitation/SKILL.md +86 -0
  46. package/skills/obk-recall/LICENSES.md +42 -0
  47. package/skills/obk-recall/NOTICE.md +53 -0
  48. package/skills/obk-recall/SKILL.md +129 -0
  49. package/skills/obk-researching/LICENSES.md +67 -0
  50. package/skills/obk-researching/NOTICE.md +170 -0
  51. package/skills/obk-researching/SKILL.md +269 -0
  52. package/skills/obk-reviewing/LICENSES.md +66 -0
  53. package/skills/obk-reviewing/NOTICE.md +58 -0
  54. package/skills/obk-reviewing/SKILL.md +411 -0
  55. package/skills/obk-tdd/LICENSES.md +68 -0
  56. package/skills/obk-tdd/NOTICE.md +54 -0
  57. package/skills/obk-tdd/SKILL.md +547 -0
  58. package/skills/obk-tdd/mutation-tools.md +80 -0
  59. package/skills/obk-teach/LICENSES.md +42 -0
  60. package/skills/obk-teach/NOTICE.md +65 -0
  61. package/skills/obk-teach/SKILL.md +106 -0
  62. package/skills/obk-why/LICENSES.md +42 -0
  63. package/skills/obk-why/NOTICE.md +74 -0
  64. package/skills/obk-why/SKILL.md +180 -0
  65. package/skills/obk-writing/LICENSES.md +272 -0
  66. package/skills/obk-writing/NOTICE.md +161 -0
  67. package/skills/obk-writing/SKILL.md +254 -0
  68. package/src/book.js +268 -0
  69. package/src/bot.js +451 -0
  70. package/src/cli.js +1169 -0
  71. package/src/conversations.js +150 -0
  72. package/src/groom.js +159 -0
  73. package/src/health.js +309 -0
  74. package/src/hooks.js +257 -0
  75. package/src/init.js +314 -0
  76. package/src/launch.js +299 -0
  77. package/src/message.js +402 -0
  78. package/src/orca.js +362 -0
  79. package/src/pause.js +63 -0
  80. package/src/record.js +209 -0
  81. package/src/restart.js +193 -0
  82. package/src/retire.js +92 -0
  83. package/src/roster.js +71 -0
  84. package/src/rules.js +408 -0
  85. package/src/skills.js +630 -0
  86. package/src/sources.js +371 -0
  87. package/src/up.js +500 -0
  88. package/src/usage.js +401 -0
  89. package/bin/okb.js +0 -4
  90. package/src/index.js +0 -11
@@ -0,0 +1,411 @@
1
+ ---
2
+ name: obk-reviewing
3
+ description: >-
4
+ Reviewing a change, and receiving a review of your own: what a reviewer is
5
+ given and what it is not, the angles worth taking on a diff, the test to put
6
+ a finding through before writing it, the findings that are usually wrong,
7
+ what a report says, and how to answer one without performing agreement. Use
8
+ whenever you are reading someone else's change (a diff, a branch, a pull
9
+ request, a patch) or have been asked to look at, check over or give an
10
+ opinion on work you did not write, and equally whenever findings come back
11
+ on your own work and you have to decide what to do about each one.
12
+ ---
13
+
14
+ # Reviewing
15
+
16
+ Two jobs, and they are different: reading someone else's change, and answering
17
+ a reading of your own. A review is worth having only when the reader did not
18
+ write the code, and it is worth acting on only when each finding survives being
19
+ checked.
20
+
21
+ The reviewer comments and does not edit. Whoever wrote the code makes the
22
+ change, and the check is run again afterwards.
23
+
24
+ Scale the reading to the change. A review is not skipped because the work is
25
+ small, but a small change gets a small review: the questions that could matter
26
+ here, not the whole list every time. Formality repeated on every change costs
27
+ trust as surely as missing a defect does.
28
+
29
+ Question the approach before the edge cases. If the change solves the problem
30
+ in the wrong place, or solves the wrong problem, the boundary conditions inside
31
+ it are beside the point; settle the shape first and look at the details after.
32
+
33
+ These are defaults for work where nothing says otherwise. A user who asks for
34
+ something else gets what they asked for; say which of these you left and why.
35
+
36
+ ## Giving a review
37
+
38
+ ### What you are given, and what you are not
39
+
40
+ The requirement, the change, and the criteria it has to meet. Not the author's
41
+ session, not its reasoning, and not its conclusion: handed a conclusion, a
42
+ reader tends to come back agreeing with it. If you are the one asking for the
43
+ review, pass the artefact and the contract, and keep your verdict to yourself.
44
+
45
+ State the intent in one paragraph before you read the diff, taken from the
46
+ requirement rather than from the author's summary. You are judging whether the
47
+ change achieves that intent, not whether the intent was right. Solving the
48
+ wrong problem is still a finding. That is the change failing the requirement,
49
+ not you re-arguing it. A breakage the change sets out to make (an interface
50
+ retired on purpose, a behaviour deliberately dropped) is not a defect; do not
51
+ spend the author's time on it.
52
+
53
+ Pin what you are reading: the range, and that it resolves and is not empty.
54
+ Work that out before you start rather than half way through.
55
+
56
+ Read the change before you read what anyone else said about it. Other people's
57
+ comments, and any automated review, come after your own pass, so your eyes are
58
+ your own.
59
+
60
+ ### The author's report is a claim
61
+
62
+ Treat it as a claim about the code, not as evidence. It may be incomplete,
63
+ optimistic, or simply wrong. Check what it says against the change itself. A
64
+ rationale in the report ("left out deliberately", "kept simple on purpose")
65
+ is the author grading its own work and never lowers the severity of anything
66
+ you find.
67
+
68
+ The other way round holds too: evidence you cannot see is not evidence that
69
+ does not exist. When you cannot check something, say that you could not, and
70
+ say what would settle it.
71
+
72
+ ### Two questions, kept apart
73
+
74
+ Does the change do what was asked, and is it well made? A change can pass one
75
+ and fail the other: correct in every detail and solving the wrong problem, or
76
+ exactly what was wanted and a mess in the codebase. Answer them separately and
77
+ report them separately. Merged into one ranked list, the loud one hides the
78
+ other.
79
+
80
+ For the first, go through the requirement and sort what you find into three:
81
+
82
+ - **Missing.** Asked for and not there, or claimed and not implemented.
83
+ - **Not asked for.** Behaviour, options or generality nobody wanted.
84
+ - **Misunderstood.** The right thing built the wrong way, or the wrong
85
+ problem solved.
86
+
87
+ Quote the line of the requirement for each. Where settling one means reading
88
+ code the change does not touch (the function it delegates to, the contract it
89
+ relies on), read it: that is evidence about this change, not a review of
90
+ something else. And the requirement is not a list of everything that matters:
91
+ what a reasonable person would expect is part of it, and silence about an input
92
+ is not permission for that input to break things.
93
+
94
+ ### Where to look
95
+
96
+ The second question. What you report is the change: what it adds or alters, and
97
+ a defect in an untouched line of a function it touched. Not a survey of
98
+ everything around it.
99
+
100
+ What you read to get there is a different matter. Follow a question you can
101
+ name (where does this value come from, what did the old contract promise, who
102
+ calls this) until it is settled or you are genuinely stuck, and say in the
103
+ report what you followed and what you found. Do not report a half-answer you
104
+ could have finished: "this breaks unless the caller handles it" is not a
105
+ finding when the caller is there to be read. What you must not do is wander:
106
+ reading with no question in hand turns a review of this change into a review of
107
+ the codebase, and that is the thing to stay out of.
108
+
109
+ These are questions, not a list to complete. A one-line fix does not need
110
+ paragraphs about the architecture.
111
+
112
+ - **Every line.** What input, state, timing or platform makes this line wrong?
113
+ Empty input, a boundary, a value that is absent, two of these at once, the
114
+ second time it runs.
115
+ - **The second run, and the half-finished one.** What happens if this runs
116
+ twice, or if the last attempt died partway through? If the answer depends on
117
+ what was left behind, something is missing that puts it back in order.
118
+ - **Two at once.** Where more than one actor can touch the same file, branch or
119
+ shared value, is the access made safe by the structure (a lock, a sequence,
120
+ one owner) or by a convention that will not hold?
121
+ - **Checked against the real thing.** Does the code establish what it claims,
122
+ or does it read a stand-in for it: a timestamp instead of the value, a cached
123
+ flag instead of the state, a helper's summary instead of what the helper
124
+ produced?
125
+ - **What the change took away.** For each line deleted or replaced, name the
126
+ behaviour it was holding up, then find where that behaviour is held up now.
127
+ This is the one most reviews miss.
128
+ - **The callers.** A changed function reaches its call sites: a new
129
+ precondition, a different return shape, an error that did not use to come
130
+ out, a new dependency on ordering or timing.
131
+ - **The cause, not the symptom.** A guard that hides a broken invariant, a
132
+ retry that covers a broken contract, a cast that silences a modelling
133
+ mistake. A special case layered onto shared machinery usually means the fix
134
+ went in at the wrong depth. If the fix is a comment telling the next person
135
+ not to do something, ask what would make the wrong thing impossible instead.
136
+ - **The shape.** Does the change read as though the design always allowed for
137
+ it, or as though it was pushed in from outside? Does the data match how it is
138
+ actually used? Is a second path being kept alive for callers that do not
139
+ exist?
140
+ - **What could be less.** An abstraction with one caller, an option for a case
141
+ nobody has, a parameter nothing passes, a compatibility path whose migration
142
+ is over, a helper the codebase already has written out again by hand. Do
143
+ not mark simple code down for not being abstract: a few lines repeated beat
144
+ an abstraction invented too early.
145
+ - **The tests.** Is there a test for what changed, and would it fail if the
146
+ code were wrong? Where a separate author wrote them, is every test the
147
+ hand-over names in the revision being handed on, as the author wrote it?
148
+ Look at the revision, not only the diff, since the tests may have landed in
149
+ an earlier change this one builds on. A named test that is not there, or is
150
+ there with its assertions softened, is a finding. For a bug, is there a test that
151
+ reproduces it? Was there a failing run before the code, or only a green one
152
+ after? Do the tests observe behaviour or repeat the implementation? And look
153
+ for green that was bought: a threshold moved, a test skipped or deleted,
154
+ assertions taken out of a test that stayed, a check switched off by a
155
+ comment, a value hard-coded to match one test's input. Tightening the bar is
156
+ quiet; loosening it should not be.
157
+ - **The repo's own rules.** Flag a breach only when you can quote the rule and
158
+ the line that breaks it. Not a style you prefer, and not the spirit of a
159
+ document. Skip anything the project's own tooling already enforces.
160
+ - **Security**, only where you can follow it: an input, the path it takes, and
161
+ the place it lands. "This could be an injection" without that path is not a
162
+ finding. Worth following: a new way in with no check on who may use it; a
163
+ secret that reaches a log, an error or a message; a check made at one moment
164
+ and relied on at a later one, when the answer can change in between; and
165
+ whether a value is checked once where it enters and trusted after, or checked
166
+ again and again in the middle and never at the edge.
167
+ - **What it breaks for the people working on it.** A change to where a secret
168
+ is read from, the name of a setting, a port, or a step that now has to be run
169
+ before anything works, will stop other people's machines. So will a feature
170
+ reaching someone it was meant to be hidden from, which is usually a quiet
171
+ change to a condition rather than a loud one.
172
+
173
+ ### A baseline when the repo documents nothing
174
+
175
+ What the project writes down about how code should be written is the standard,
176
+ and it wins. On top of it, this set carries where nothing is written down. Each
177
+ one reads as what it is, then what to do about it, and each is a label you
178
+ apply with judgement: "possible feature envy", never a violation. A documented
179
+ repo standard that endorses something here suppresses it, and anything the
180
+ project's tooling already enforces is not a finding.
181
+
182
+ - **Mysterious name.** A function, variable or type whose name does not say
183
+ what it does or holds. → Rename it; if no honest name comes, the design is
184
+ the murky part.
185
+ - **Duplicated code.** The same shape of logic in more than one place in the
186
+ change. → Pull the shape out and call it from both.
187
+ - **Feature envy.** A function that reaches into another object's data more
188
+ than its own. → Move it onto the data it envies.
189
+ - **Data clumps.** The same few fields or parameters keep travelling together,
190
+ a type waiting to be born. → Bundle them and pass the one thing.
191
+ - **Primitive obsession.** A string or a number standing in for a domain idea
192
+ that deserves its own type. → Give the idea its own small type.
193
+ - **Repeated switches.** The same branch on the same kind of thing recurring
194
+ across the change. → One map both sites share, or let the type decide.
195
+ - **Shotgun surgery.** One logical change forcing scattered edits across many
196
+ files. → Gather what changes together into one place.
197
+ - **Divergent change.** One file edited for several unrelated reasons. → Split
198
+ it, so each part changes for one reason.
199
+ - **Speculative generality.** Abstraction, parameters or hooks for needs the
200
+ requirement does not have. → Delete it; inline it back until a real need
201
+ turns up.
202
+ - **Message chains.** Long `a.b().c().d()` navigation the caller should not
203
+ have to know about. → Hide the walk behind one method on the first object.
204
+ - **Middle man.** A class or function that mostly passes calls onward. → Cut
205
+ it out and call the real target.
206
+ - **Refused bequest.** Something that inherits and then ignores or overrides
207
+ most of what it got. → Drop the inheritance and compose instead.
208
+
209
+ ### Before you write a finding
210
+
211
+ Four questions. If any answer is no or unsure, the finding drops or its
212
+ severity does.
213
+
214
+ 1. Can you name the file and the line? "Somewhere in the parsing" is not
215
+ something anyone can act on.
216
+ 2. Can you state the failure concretely: this input, in this state, gives that
217
+ wrong outcome? If you cannot name the trigger, you are matching a pattern,
218
+ not reviewing. A cleanup finding (a smell, a breached rule, something that
219
+ could be less) has no trigger; it names its concrete cost instead: what is
220
+ duplicated, wasted or harder to change, or which rule it breaks.
221
+ 3. Have you read what is around it: the callers, the types, the tests? Much of
222
+ what looks wrong is already handled one frame up.
223
+ 4. Is the severity one you could defend? A missing comment is never urgent.
224
+ Inflated severity costs you the next review as well as this one.
225
+
226
+ Trace it before you flag it. "This could be nil" becomes a finding when you can
227
+ show the call that makes it nil. Where a type or a validated boundary already
228
+ rules it out, it is not one.
229
+
230
+ Put each candidate in one of three states and say which:
231
+
232
+ - **Confirmed.** You can name the input and the wrong result, and quote the
233
+ line.
234
+ - **Plausible.** The mechanism is real but you cannot reach the trigger from
235
+ here. Say what would settle it. A realistic state is not a reason to refute:
236
+ two things running at once, an absent value on a rare path that can still be
237
+ reached (an error handler, a cold cache, an optional field), zero read as
238
+ missing, a boundary the code does not exclude, a retry after a partial
239
+ failure, a pattern that lost its anchor.
240
+ - **Refuted.** Drop it, and only call it that when the code proves it: the
241
+ line says otherwise, a type or constant makes it impossible, or a guard in
242
+ the change already handles it.
243
+
244
+ Finding and judging are two steps, and collapsing them is how real defects get
245
+ lost. While you are looking, keep anything you can name a failure for. Judge
246
+ afterwards. What reaches the report is what survived.
247
+
248
+ ### What a report says
249
+
250
+ Every line is a verdict, a finding, or a check you ran. Start with the answer.
251
+ No preamble, no narration of your process, no closing summary.
252
+
253
+ A finding gives its location, what is wrong, and the evidence for it: why you
254
+ believe it, not just that you do. A concrete alternative if you have one, and
255
+ nothing if you do not. Fold repeats together: "five handlers swallow the error"
256
+ is one finding, not five.
257
+
258
+ - No findings is a real result. A clean review is a valid review, and
259
+ manufacturing findings to justify having looked is the failure that makes
260
+ reviewers worth ignoring.
261
+ - Do not restate what the code does, suggest rewriting working code because you
262
+ would have written it differently, raise a case you cannot reach, or pad with
263
+ small points to look thorough. Do not praise it either; that is not what the
264
+ reader needs.
265
+ - Say what severity means where you are writing, and keep to it. A useful
266
+ line: it matters when the work cannot be trusted until it is fixed (wrong
267
+ or fragile behaviour, a requirement missed, the same block of logic copied
268
+ verbatim, an error swallowed, a test that asserts nothing). "The coverage
269
+ could be broader" and polish are the other kind.
270
+ - Severity never exceeds what you showed, and it does not fall below it
271
+ either: a real defect written up as a suggestion is lost as surely as one
272
+ left out. If you demonstrated a way to read a
273
+ value that should not be read, that is what it is worth; it does not become
274
+ urgent because of what someone might do next with it.
275
+ - One structural problem and ten small ones: the structural problem is the
276
+ review. Correctness outranks cleanup when something has to be cut.
277
+ - If the list of things to act on runs past about five, you have probably not
278
+ finished filtering.
279
+ - List what you considered and set aside, one line each with the reason, so
280
+ nothing is dropped silently. An empty list is fine and means you set nothing
281
+ aside.
282
+ - Say what you did not check. If you looked less thoroughly than you were asked
283
+ to (one pass where more was wanted, a part of the change you could not read),
284
+ say that plainly, so nobody takes the review for more than it is.
285
+ - A review reads the change. Whether the whole of it runs is a separate check;
286
+ where one focused test would settle a doubt and changes nothing, run it and
287
+ say so.
288
+
289
+ ### Findings that are usually wrong
290
+
291
+ Before writing one of these, do the thing in brackets.
292
+
293
+ - "Add error handling here" [check whether the caller or the framework already
294
+ does].
295
+ - "This input is not validated" on something internal [follow one caller and
296
+ see what reaches it].
297
+ - "Magic number" for a number everyone knows [ask whether naming it helps a
298
+ reader who already knows it].
299
+ - "This function is too long" for a table, a switch or a list of cases [length
300
+ is not the same as complexity].
301
+ - "Possible null" where a guard or a type is in scope [read the scope].
302
+ - "This is N+1" over a fixed, small set [count it].
303
+ - "Missing await" where not waiting is the point [check whether the result is
304
+ wanted].
305
+ - "Hard-coded value" in a test [a test is supposed to hard-code what it
306
+ expects].
307
+
308
+ The question that settles most of them: would someone who knows this codebase
309
+ actually change the code because of this comment?
310
+
311
+ ### One reviewer
312
+
313
+ Do the review yourself rather than handing parts of it on. If the change really
314
+ is too large to hold in one reading, that is itself worth saying.
315
+
316
+ Reviewing is read-only. Do not change the working tree, the index, or which
317
+ branch or commit is checked out. Look with the commands that only read. If you
318
+ need another revision to compare, take a separate copy of it somewhere else.
319
+
320
+ ## Receiving a review
321
+
322
+ Read all of it before you react. Then take the items one at a time.
323
+
324
+ **Restate each in your own words.** Go through the whole review first and ask
325
+ about every item you are unsure of, in one go, before you start changing
326
+ anything. Never guess at an unclear item and never act on a half-understood
327
+ one: that produces the wrong change, and then a second wrong change when the
328
+ answer arrives.
329
+
330
+ Items are related more often than they look, so assume the answer to one bears
331
+ on the others until you have checked. Where you have checked and an item plainly
332
+ stands alone (a crash with a reproduction, while the unclear item is a vague
333
+ note about tidying something up), that one can go ahead. Anything the answer
334
+ could change waits for it.
335
+
336
+ **Check it against the code before you act on it.** Is it right for this
337
+ codebase? Does it break something that works? Is there a reason the code is the
338
+ way it is? A fresh reader has less context, not more. That is the point of it,
339
+ and it is also its weakness. Do not defer to a finding because it is fresh, and
340
+ do not dismiss one because it is uncomfortable.
341
+
342
+ **Sort each item**, in this order. Misread: the reader flagged it because what
343
+ you gave them was unclear or incomplete, so fix the brief first and look at the
344
+ item again. Valid: it stands, and gets a change. A trade-off: real, but fixing
345
+ it costs more than living with it, so write it down where the user will see
346
+ it. Or noise: correct under context the reader did not have, and the useful
347
+ question is whether the brief should have said something that would have
348
+ prevented it.
349
+
350
+ Some findings carry a sign that the reader was working without something you
351
+ have: a change asked for in code you did not touch, a pattern flagged that the
352
+ rest of the codebase already uses, an approach recommended that a constraint
353
+ you know about rules out. Treat that as a reason to look, not as an answer. It
354
+ is often an honest mistake from someone with less context, and it is just as
355
+ often the finding that matters most: a caller you did not touch is exactly
356
+ where a changed return shape breaks, and the same unsafe pattern elsewhere says
357
+ nothing about whether this use of it is safe.
358
+
359
+ So check it out, and dismiss it only on what the code, the contract or a
360
+ decision you can point to actually shows. "The reviewer did not know about X"
361
+ dismisses the finding once you have said what X is and why it settles this
362
+ case; on its own it is not a reason. Say that much, and move on without making
363
+ a point of it.
364
+
365
+ A plausible finding about correctness, security, privacy, lost data, who is
366
+ allowed to do what, money, a data migration, or whether something can safely
367
+ run twice is fixed; it needs nobody's leave. Ask rather than decide when such a
368
+ finding is one you would dismiss and it is novel, or when you cannot tell.
369
+ Passing over a noisy remark about style costs little; passing over one of
370
+ those costs a great deal. When in doubt about dismissing one, ask.
371
+
372
+ Where someone suggests building something out "properly", look first for who
373
+ calls it. If nothing does, say so and ask whether it should exist at all.
374
+
375
+ Where you cannot check a point, say so: "I cannot settle this without X" is an
376
+ answer, with what you would do next.
377
+
378
+ **Push back with evidence.** Name what you checked and what it showed. Where a
379
+ finding conflicts with a decision the user already made, raise it rather than
380
+ quietly following one or the other.
381
+
382
+ A finding that asks for a new test, or for an existing one to assert more, is
383
+ not yours to satisfy. It goes to the author, with the finding attached, for the
384
+ same reason the first tests did: a test written by the person whose code was
385
+ just criticised tends to be a test that passes. Answering the reviewer with a
386
+ test you wrote yourself closes the thread and loses the check.
387
+
388
+ **Then fix, in this order:** what is broken or unsafe, then the small certain
389
+ things, then the structural ones. One at a time, running the check after each,
390
+ so you know which change did what. Fixes that touch only wording can go
391
+ together, and so can changes whose shared check still shows which one failed; a
392
+ behaviour change still gets the check that covers it. Say how you grouped them
393
+ and which checks you ran.
394
+
395
+ **Answer plainly.** No performative agreement, no thanks, no apology: state the
396
+ fix or state the pushback. If you pushed back and turned out to be wrong, say
397
+ what you checked, what it showed, and carry on. The correction is one line,
398
+ not a paragraph about how it happened.
399
+
400
+ When the changes are in, the check is run again and the result reported. The
401
+ review is answered when every point has a fix, a reason it does not hold, or a
402
+ question back, not when the list has been read.
403
+
404
+ ## Reviewing something that is not code
405
+
406
+ The same shape holds for a document, a configuration, a prompt or a plan: what
407
+ was asked for, what the thing does, and the difference between them. The
408
+ questions change, the discipline does not: cite the place, name the concrete
409
+ consequence, and say plainly when there is nothing to report.
410
+
411
+ Sources and licences: [NOTICE.md](NOTICE.md).
@@ -0,0 +1,68 @@
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-tdd` consolidates material from the sources named in
9
+ [NOTICE.md](NOTICE.md). Their licences are reproduced below in full.
10
+
11
+ ## MIT
12
+
13
+ The MIT permission notice below applies to the work of each of these copyright
14
+ holders, and is reproduced with each of their notices. The path after each one
15
+ is the licence file it was read from, in the research pack's source clones.
16
+
17
+ - **`mattpocock/skills`**, Copyright (c) 2026 Matt Pocock
18
+ (`mattpocock_skills/LICENSE`)
19
+ - **`obra/superpowers`**, Copyright (c) 2025 Jesse Vincent
20
+ (`obra_superpowers/LICENSE`)
21
+ - **Cursor `plugins`, the pstack plugin**, Copyright (c) 2026 Lauren Tan
22
+ (`cursor_plugins/pstack/LICENSE`)
23
+ - **`addyosmani/agent-skills`**, Copyright (c) 2025 Addy Osmani
24
+ (`addyosmani_agent-skills/LICENSE`)
25
+ - **`citypaul/.dotfiles`; the `tdd` and `mutation-testing` skills carry no
26
+ nested notice, so the repository licence governs them**, Copyright (c) 2024 Paul Hammond
27
+ (`citypaul_.dotfiles/LICENSE`)
28
+ - **`KentBeck/BPlusTree3`, for his own rules file**, Copyright (c) 2025 Kent Beck
29
+ (`KentBeck_BPlusTree3/LICENSE`)
30
+
31
+ ```
32
+ MIT License
33
+
34
+ Copyright (c) 2026 Matt Pocock
35
+ Copyright (c) 2025 Jesse Vincent
36
+ Copyright (c) 2026 Lauren Tan
37
+ Copyright (c) 2025 Addy Osmani
38
+ Copyright (c) 2024 Paul Hammond
39
+ Copyright (c) 2025 Kent Beck
40
+
41
+ Permission is hereby granted, free of charge, to any person obtaining a copy
42
+ of this software and associated documentation files (the "Software"), to deal
43
+ in the Software without restriction, including without limitation the rights
44
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45
+ copies of the Software, and to permit persons to whom the Software is
46
+ furnished to do so, subject to the following conditions:
47
+
48
+ The above copyright notice and this permission notice shall be included in all
49
+ copies or substantial portions of the Software.
50
+
51
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
56
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
57
+ SOFTWARE.
58
+ ```
59
+
60
+ ## Sources that could not be read
61
+
62
+ - **`nizos/tdd-guard`** is not among the clones in the research pack. What this
63
+ skill takes from it is the idea of a check that refuses work which skipped
64
+ the failing test, described in our own words.
65
+
66
+ These are named in NOTICE.md for honesty about where the material came from.
67
+ No text of theirs is reproduced in this skill, and their licence files were not
68
+ available here to reproduce.
@@ -0,0 +1,54 @@
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-tdd` was consolidated for this kit from these, all MIT, with
8
+ thanks:
9
+
10
+ - **mattpocock/skills**, `engineering/tdd`: seams and where tests go, vertical
11
+ slices against bulk testing, the tautological and implementation-coupled
12
+ shapes, refactoring outside the loop, standing in only at system boundaries,
13
+ and not testing everything so the effort lands on the paths that matter. Its
14
+ `to-spec`: the existing seam preferred, the highest one, and the fewer the
15
+ better. Its `diagnosing-bugs`: the correct seam for a bug test, and no
16
+ correct seam being the finding.
17
+ - **obra/superpowers**, `test-driven-development` and its `writing-good-tests`:
18
+ naming the break a test catches, deriving the expected value by hand, change
19
+ detectors, behaviour rather than text, your contract rather than the
20
+ framework's, the four rules about a stand-in, the list of warning signs, and
21
+ the mutation classes. Its `verification-before-completion`: the
22
+ revert-the-fix proof. Its `writing-plans`: a requirement's silence not being
23
+ permission, and the few uncovered input classes most likely to bite.
24
+ - **Cursor pstack**, `tdd` and `principle-test-behavior-not-implementation`:
25
+ the five shapes that observe no behaviour and the fix for each (asserting
26
+ what a stand-in received rather than that it was called, and the relation
27
+ across rows of data that is kept), "prefer no
28
+ new test over a bad test", the honest exit when a test is impractical, and
29
+ the report that names the failing-before and passing-after runs.
30
+ - **addyosmani/agent-skills**, `test-driven-development` and
31
+ `constraint-driven-development`: finding out how the project tests before
32
+ writing anything, repetition being no fault in a test, a subagent for the
33
+ reproduction test, and the cheap roads to green.
34
+ - **citypaul/.dotfiles**, `tdd` and `mutation-testing` with its
35
+ `mutator-rules`: the mutation loop, survivor triage into killed, equivalent
36
+ or named and deferred, the equivalence question, the high-value logic worth
37
+ breaking, the inputs that tell a break apart (either side of a boundary,
38
+ mixed true and false, no identity values), the tool-run mechanics in
39
+ `mutation-tools.md`, keeping the harness out of the inner loop, triangulating
40
+ after a fake, and refusing to manufacture a red.
41
+ - **Kent Beck's own rules file**: one test at a time, the smallest code that
42
+ passes, structure and behaviour kept apart, and the two-level test for a
43
+ defect.
44
+ - **nizos/tdd-guard**: the ladder to a clean red.
45
+
46
+ Ideas paraphrased, with no text taken: Trail of Bits' mutation-testing skill
47
+ (CC BY-SA 4.0) on equivalent mutants, Anthropic's Claude Code documentation on
48
+ separate test authorship, alexop.dev on why one context cannot hold both
49
+ halves, and the published work on mutation testing at scale.
50
+
51
+ Our own, with no source behind them: the order to break things in, the red
52
+ from an archived baseline for behaviour that already existed, checking that an
53
+ author's hand-back is in the change (from this repo's issues #115 and #119),
54
+ and the part on work away from code.