@assuredloop/orca-bot-kit 0.18.0 → 0.20.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.
@@ -43,6 +43,9 @@ thanks. Each licence below was read from the file named beside it.
43
43
  - `why/SKILL.md` adds coverage rather than minimalism, documenting the null
44
44
  instead of skipping the search, and the high bar for skipping a source:
45
45
  provably irrelevant rather than probably irrelevant.
46
+ Revision: cursor/plugins@6ed0f7a9504f577d7529064103cecce9be7dfc5e
47
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
48
+ from; the revision actually read was not recorded)
46
49
  - **`addyosmani/agent-skills`, `skills/source-driven-development`**: MIT,
47
50
  `addyosmani_agent-skills/LICENSE`, "Copyright (c) 2025 Addy Osmani". The
48
51
  source hierarchy and what sits outside it: model-written summaries and your
@@ -60,6 +63,9 @@ thanks. Each licence below was read from the file named beside it.
60
63
  could not find documentation. And the rule this skill takes whole, that
61
64
  hedging is the worst of the three options: either verify and cite, or mark it
62
65
  unverified, because a disclaimer in a subordinate clause reads as confidence.
66
+ Revision: addyosmani/agent-skills@dc27a9c2e13721158157632de61b4106c6c2a2a1
67
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
68
+ from; the revision actually read was not recorded)
63
69
  - **`garrytan/gstack`, `ETHOS.md`**: MIT, `garrytan_gstack/LICENSE`,
64
70
  "Copyright (c) 2026 Garry Tan". The three layers of what you find and how
65
71
  much weight each bears: the settled and well-trodden, where the risk is
@@ -71,6 +77,9 @@ thanks. Each licence below was read from the file named beside it.
71
77
  look things up by general category rather than by the private thing you are
72
78
  working on, and strip names, addresses, paths and anything that looks like a
73
79
  secret from a query before it leaves the machine.
80
+ Revision: garrytan/gstack@a6b3a57512ca6d5c6aa5b68f74f736195021f96e
81
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
82
+ from; the revision actually read was not recorded)
74
83
  - **`openai/skills`, `skills/.curated/notion-research-documentation`**: MIT,
75
84
  that skill's own `LICENSE.txt`, "Copyright 2025 Notion Labs, Inc." The search
76
85
  strategy, which is the only material of its kind in the sources: broad to
@@ -83,30 +92,42 @@ thanks. Each licence below was read from the file named beside it.
83
92
  citing every sentence, put the citation beside what it supports, mark a
84
93
  quotation as a quotation, keep a sources section that includes what held
85
94
  nothing, and flag a superseded source where it stands.
95
+ Revision: openai/skills@49f948faa9258a0c61caceaf225e179651397431
96
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
97
+ from; the revision actually read was not recorded)
86
98
  - **`mattpocock/skills`, `skills/engineering/research`**: MIT,
87
99
  `mattpocock_skills/LICENSE`, "Copyright (c) 2026 Matt Pocock". Twelve lines,
88
100
  one of which the research pack singled out and this skill is built around:
89
101
  follow every claim back to the source that owns it, and go to primary
90
102
  material rather than a secondary write-up of it.
103
+ Revision: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7
104
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
105
+ from; the revision actually read was not recorded)
91
106
  - **Cloudflare's security-audit skill**: MIT,
92
107
  `cloudflare_security-audit-skill/LICENSE`, "Copyright (c) 2025-2026
93
108
  Cloudflare, Inc." Coverage honesty: never imply that one pass exhausts the
94
109
  subject, and a scoped piece of work presents itself as partial rather than
95
110
  letting silence read as "the rest is fine".
111
+ Revision:
112
+ cloudflare/security-audit-skill@c1c8a8c1471069fb0e188eeaff69b8e8db6564a8
113
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
114
+ from; the revision actually read was not recorded)
96
115
 
97
116
  Two things come from the research pack rather than from a repository, and are
98
117
  marked here because the difference matters:
99
118
 
100
- - The evidence-label pair `(verified: <command>)` and `(inferred: did not
101
- run)`, which `source-book-2.md:139` calls the single best sentence in its
102
- whole survey, is quoted there from **tw93/Waza**'s `rules/anti-patterns.md`
119
+ - **tw93/Waza**, `rules/anti-patterns.md`: the evidence-label pair `(verified:
120
+ <command>)` and `(inferred: did not run)`, which `source-book-2.md:139` calls
121
+ the single best sentence in its whole survey, is quoted there from it
103
122
  (recorded as MIT in the same book's source table). Waza is not among the
104
123
  clones in the research pack, so this is taken from the book's verbatim quote
105
124
  rather than from the repository. The label's checkable form is kept as the
106
125
  source has it, because being able to audit the label is the whole of its
107
- value; the prose around it is ours. The source applies `inferred` to
108
- reasoning from code, so this skill keeps it for an inference and asks for
109
- `not checked` where the claim is somebody else's unchecked account.
126
+ value; the prose around it is ours. The source applies `inferred` to reasoning
127
+ from code, so this skill keeps it for an inference and asks for `not checked`
128
+ where the claim is somebody else's unchecked account.
129
+ Revision: tw93/Waza@59323dee82b04fa8b9ad97a8ee503ca8aee7eb3c (as recorded
130
+ in the research pack's source-book-2.md, read 2026-09-19)
110
131
  - The pack's own reports label each claim by where it came from and whether it
111
132
  was checked, and keep a section of gaps and cautions at the end. That habit,
112
133
  rather than any source, is why this skill treats a claim's support and the
@@ -16,6 +16,9 @@ noted, with thanks:
16
16
  has no caller, premature abstraction, "I would have done it differently",
17
17
  about five items, and showing what was set aside. Its `poteto-mode`
18
18
  bugbot-triage reference gave fix, dismiss or ask, and "when in doubt, ask".
19
+ Revision: cursor/plugins@6ed0f7a9504f577d7529064103cecce9be7dfc5e
20
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
21
+ from; the revision actually read was not recorded)
19
22
  - **obra/superpowers**, `requesting-code-review`, `receiving-code-review` and
20
23
  `subagent-driven-development/task-reviewer-prompt.md` (the last for bounded
21
24
  reading, "declined to judge", the read-only rule and one focused test only
@@ -27,6 +30,9 @@ noted, with thanks:
27
30
  pattern: read, restate, verify, evaluate, respond, implement, with the stop
28
31
  on an unclear item, the check for who calls it, the order of fixes, and
29
32
  correcting your own pushback without a speech.
33
+ Revision: obra/superpowers@5bf4e78011075bcfc0dc295f0724994cd123ee71
34
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
35
+ from; the revision actually read was not recorded)
30
36
  - **mattpocock/skills**, `code-review`: the smell baseline in full, with its
31
37
  own guards: every entry a labelled judgement call, the repo's documented
32
38
  standard overriding it, and anything tooling enforces skipped. Also pinning
@@ -34,17 +40,26 @@ noted, with thanks:
34
40
  missing, unasked-for and misunderstood, quoting the rule for a standards
35
41
  breach, and the two axes staying separate so neither hides the other. The
36
42
  smells are Fowler's, from *Refactoring* chapter 3.
43
+ Revision: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7
44
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
45
+ from; the revision actually read was not recorded)
37
46
  - **Cursor thermos**, with `thermo-nuclear-review`: scope held to what the
38
47
  change touches, not spending the author's time on a breakage the change
39
48
  intends, what over-reporting costs you,
40
49
  reading the change before the discussion, and never presenting a finding with
41
50
  the research unfinished when the answer was there to be read.
51
+ Revision: cursor/plugins@6ed0f7a9504f577d7529064103cecce9be7dfc5e
52
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
53
+ from; the revision actually read was not recorded)
42
54
  - **addyosmani/agent-skills**: passing the artefact and the contract without
43
55
  the conclusion, the one structural problem outranking ten small ones, and,
44
56
  from `doubt-driven-development`, sorting findings into misread, valid,
45
57
  trade-off and noise in that order, with the brief fixed first for a misread.
46
58
  Its `code-review-and-quality`: not softening a real issue, which pstack's
47
59
  `code-quality-review` says too.
60
+ Revision: addyosmani/agent-skills@dc27a9c2e13721158157632de61b4106c6c2a2a1
61
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
62
+ from; the revision actually read was not recorded)
48
63
  - **Anthropic's built-in review**, as behaviour observed rather than text
49
64
  taken: the angles worth separating, naming the behaviour a deleted line held
50
65
  up, following a change out to its callers, confirmed against plausible
@@ -53,6 +68,10 @@ noted, with thanks:
53
68
  bug states its trigger, not collapsing finding into judging,
54
69
  correctness outranking cleanup, and saying when a review was less than it was
55
70
  meant to be.
71
+ Revision: none (Claude Code's built-in review, its behaviour observed rather
72
+ than a text read)
56
73
  - **ECC's reviewer prompt**, through the research pack: the four questions
57
74
  before a finding, a defensible severity, zero findings being expected,
58
75
  consolidating repeats, and the list of findings that are usually wrong.
76
+ Revision: affaan-m/ECC@07756cee15788a54506031462794ad645719b028 (as recorded
77
+ in the research pack's source-book-2.md, read 2026-09-19)
@@ -14,6 +14,9 @@ thanks:
14
14
  `to-spec`: the existing seam preferred, the highest one, and the fewer the
15
15
  better. Its `diagnosing-bugs`: the correct seam for a bug test, and no
16
16
  correct seam being the finding.
17
+ Revision: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7
18
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
19
+ from; the revision actually read was not recorded)
17
20
  - **obra/superpowers**, `test-driven-development` and its `writing-good-tests`:
18
21
  naming the break a test catches, deriving the expected value by hand, change
19
22
  detectors, behaviour rather than text, your contract rather than the
@@ -21,16 +24,25 @@ thanks:
21
24
  the mutation classes. Its `verification-before-completion`: the
22
25
  revert-the-fix proof. Its `writing-plans`: a requirement's silence not being
23
26
  permission, and the few uncovered input classes most likely to bite.
27
+ Revision: obra/superpowers@5bf4e78011075bcfc0dc295f0724994cd123ee71
28
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
29
+ from; the revision actually read was not recorded)
24
30
  - **Cursor pstack**, `tdd` and `principle-test-behavior-not-implementation`:
25
31
  the five shapes that observe no behaviour and the fix for each (asserting
26
32
  what a stand-in received rather than that it was called, and the relation
27
33
  across rows of data that is kept), "prefer no
28
34
  new test over a bad test", the honest exit when a test is impractical, and
29
35
  the report that names the failing-before and passing-after runs.
36
+ Revision: cursor/plugins@6ed0f7a9504f577d7529064103cecce9be7dfc5e
37
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
38
+ from; the revision actually read was not recorded)
30
39
  - **addyosmani/agent-skills**, `test-driven-development` and
31
40
  `constraint-driven-development`: finding out how the project tests before
32
41
  writing anything, repetition being no fault in a test, a subagent for the
33
42
  reproduction test, and the cheap roads to green.
43
+ Revision: addyosmani/agent-skills@dc27a9c2e13721158157632de61b4106c6c2a2a1
44
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
45
+ from; the revision actually read was not recorded)
34
46
  - **citypaul/.dotfiles**, `tdd` and `mutation-testing` with its
35
47
  `mutator-rules`: the mutation loop, survivor triage into killed, equivalent
36
48
  or named and deferred, the equivalence question, the high-value logic worth
@@ -38,15 +50,34 @@ thanks:
38
50
  mixed true and false, no identity values), the tool-run mechanics in
39
51
  `mutation-tools.md`, keeping the harness out of the inner loop, triangulating
40
52
  after a fake, and refusing to manufacture a red.
53
+ Revision: citypaul/.dotfiles@a109f9972bb46671c624fc05752031523e1cf6fc
54
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
55
+ from; the revision actually read was not recorded)
41
56
  - **Kent Beck's own rules file**: one test at a time, the smallest code that
42
57
  passes, structure and behaviour kept apart, and the two-level test for a
43
58
  defect.
59
+ Revision: KentBeck/BPlusTree3@ca80e4d85a99cd0af2effe717f709d43e80403bc
60
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
61
+ from; the revision actually read was not recorded)
44
62
  - **nizos/tdd-guard**: the ladder to a clean red.
63
+ Revision: nizos/tdd-guard@2579ec1823fac5f4afb73be678d9c500b19885ac (as
64
+ recorded in the research pack's source-book-2.md, read 2026-09-19)
45
65
 
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.
66
+ Ideas paraphrased, with no text taken:
67
+
68
+ - **Trail of Bits' mutation-testing skill**, in `trailofbits/skills` (CC BY-SA
69
+ 4.0), on equivalent mutants.
70
+ Revision: trailofbits/skills@123037ec8aed26f0d86327cc39137ee5043e5deb (as
71
+ recorded in the research pack's source-book-2.md, read 2026-09-19)
72
+ - **Anthropic's Claude Code documentation**, "Claude Code: Best practices", on
73
+ separate test authorship.
74
+ Read: 2026-09-19 (read for the research pack's source-book-1.md, of that date)
75
+ - **alexop.dev**, "A Claude Code TDD Skill: Forcing Red-Green-Refactor", on why
76
+ one context cannot hold both halves.
77
+ Read: 2026-09-19 (read for the research pack's source-book-1.md, of that date)
78
+ - **The published work on mutation testing at scale**, Petrović and others,
79
+ "Practical Mutation Testing at Scale" (arXiv 2102.11378).
80
+ Read: 2026-09-19 (read for the research pack's source-book-1.md, of that date)
50
81
 
51
82
  Our own, with no source behind them: the order to break things in, the red
52
83
  from an archived baseline for behaviour that already existed, checking that an
@@ -45,6 +45,9 @@ thanks:
45
45
  print, and the reply being the explanation itself rather than a report about
46
46
  it). Its worked density example is not carried; the rules it illustrates
47
47
  are.
48
+ Revision: cursor/plugins@6ed0f7a9504f577d7529064103cecce9be7dfc5e
49
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
50
+ from; the revision actually read was not recorded)
48
51
 
49
52
  Made generic, which is what the owner asked for. The original is built on top
50
53
  of two other skills it invokes by name, and a kit skill carries what it needs
@@ -37,6 +37,9 @@ The skill `obk-why` was consolidated for this kit from this, MIT, with thanks:
37
37
  including one line per source consulted covering the empty and skipped ones;
38
38
  and turning the findings into a preserve, change, avoid and risk constraint
39
39
  set when the question precedes a change.
40
+ Revision: cursor/plugins@6ed0f7a9504f577d7529064103cecce9be7dfc5e
41
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
42
+ from; the revision actually read was not recorded)
40
43
  - The same skill's `references/sources/code-archaeology.md`. Its pitfalls: the
41
44
  squash merge that flattens a branch's steps, the commit message that calls a
42
45
  behaviour change a small refactor so the diff has to be read instead, the
@@ -30,6 +30,9 @@ Each licence below was read from the file named beside it.
30
30
  read machine-written when every sentence is clipped to the same length; its
31
31
  heading rule, that a heading carries the point rather than the topic; its
32
32
  list rules; and the instruction to call each thing by one name everywhere.
33
+ Revision: cursor/plugins@6ed0f7a9504f577d7529064103cecce9be7dfc5e
34
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
35
+ from; the revision actually read was not recorded)
33
36
  - **Cursor `plugins`, `pstack/skills/unslop`**: same licence. Two of its rules
34
37
  are load-bearing here. Say what it does rather than how it feels, with its
35
38
  test: ask what the sentence tells the reader to do or know, restate it as a
@@ -44,6 +47,9 @@ Each licence below was read from the file named beside it.
44
47
  named above are kept in their positive form, not every rule in the catalogue,
45
48
  and the word list is left where it is, as something to review against rather
46
49
  than to load.
50
+ Revision: cursor/plugins@6ed0f7a9504f577d7529064103cecce9be7dfc5e
51
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
52
+ from; the revision actually read was not recorded)
47
53
  - **`citypaul/.dotfiles`, `claude/.claude/skills/technical-writing`**: MIT,
48
54
  that skill's own nested `LICENSE`, "Copyright (c) 2025 Adam Bulmer", which
49
55
  governs its directory rather than the repository root's MIT licence in
@@ -63,6 +69,9 @@ Each licence below was read from the file named beside it.
63
69
  leads with the decision requested. And from `resources/formatting.md`, bold
64
70
  for the one phrase a skimmer must not miss, and a numbered list claiming that
65
71
  order matters.
72
+ Revision: citypaul/.dotfiles@a109f9972bb46671c624fc05752031523e1cf6fc
73
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
74
+ from; the revision actually read was not recorded)
66
75
  - **`mattpocock/skills`, `skills/in-progress/writing-shape`**: MIT,
67
76
  `mattpocock_skills/LICENSE`, "Copyright (c) 2026 Matt Pocock". The grounding
68
77
  idea, which nothing else in the sources has: every concept a block leans on
@@ -73,6 +82,9 @@ Each licence below was read from the file named beside it.
73
82
  drowns the opening. Its format arguments are also taken: prose carries an
74
83
  argument and lists carry parallel items, a table where the same shape repeats
75
84
  three times or more, and quoting where the original wording is the point.
85
+ Revision: mattpocock/skills@c55ee46073ed923f86ce59a5eb3b6d895095d1b7
86
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
87
+ from; the revision actually read was not recorded)
76
88
  - **`anthropics/skills`, `skills/internal-comms`**: Apache 2.0, that skill's
77
89
  own `LICENSE.txt`, "Copyright 2026 Anthropic, PBC." The only source here that
78
90
  is explicitly about audience, platform and register for non-engineering
@@ -83,11 +95,17 @@ Each licence below was read from the file named beside it.
83
95
  read is a constraint on the writing rather than a detail: something meant to
84
96
  be read in under a minute by people with some but not much context is a
85
97
  different piece from the same facts written to be landed on.
98
+ Revision: anthropics/skills@34040c9c568585f6929bedeaad110ad08f079624
99
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
100
+ from; the revision actually read was not recorded)
86
101
  - **`garrytan/gstack`, `document-generate/SKILL.md`**: MIT,
87
102
  `garrytan_gstack/LICENSE`, "Copyright (c) 2026 Garry Tan". Its voice section:
88
103
  lead with the point, be concrete, name the real thing and the real number.
89
104
  Its rule to gloss a piece of jargon on first use even where the user
90
105
  introduced the term.
106
+ Revision: garrytan/gstack@a6b3a57512ca6d5c6aa5b68f74f736195021f96e
107
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
108
+ from; the revision actually read was not recorded)
91
109
  - **`addyosmani/agent-skills`, `skills/doubt-driven-development`** and
92
110
  **`citypaul/.dotfiles`, `claude/.claude/skills/double-check`**: MIT,
93
111
  `addyosmani_agent-skills/LICENSE` ("Copyright (c) 2025 Addy Osmani") and
@@ -99,6 +117,12 @@ Each licence below was read from the file named beside it.
99
117
  than deferring, since a fresh reader can be wrong for want of context; and
100
118
  stop when a pass finds only small or known things, bounded at about three
101
119
  passes, with a piece still failing then reported as not ready.
120
+ Revision: addyosmani/agent-skills@dc27a9c2e13721158157632de61b4106c6c2a2a1
121
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
122
+ from; the revision actually read was not recorded)
123
+ Revision: citypaul/.dotfiles@a109f9972bb46671c624fc05752031523e1cf6fc
124
+ (reconstructed: the research pack's 2026-09-20 clone the skills were built
125
+ from; the revision actually read was not recorded)
102
126
 
103
127
  **Left out on a licence.** `anthropics/skills`' `doc-coauthoring` has the best
104
128
  statement of reader testing in the corpus, but its directory holds no licence
package/src/cli.js CHANGED
@@ -28,7 +28,7 @@ import { readRoster } from './roster.js';
28
28
  import { buildAgents, buildRules, CODEX_CAP } from './rules.js';
29
29
  import { addSkill, buildSkills, linkSkills, removeSkill } from './skills.js';
30
30
  import { addSource, fetchSources } from './sources.js';
31
- import { makeTemp, retireTemp } from './temp.js';
31
+ import { makeTemp, retireTemp, trustHooks } from './temp.js';
32
32
  import { readUsage } from './usage.js';
33
33
  import { BOT_FATHER, bringUp, ownMailbox } from './up.js';
34
34
 
@@ -99,18 +99,25 @@ Usage:
99
99
  obk temp make --bots <path> --name <session>
100
100
  (--prompt <text> | --prompt-file <path>) [--harness claude|codex]
101
101
  [--model <m>] [--effort <e>] [--context <c>]
102
- [--approval ${APPROVALS.join('|')}]
102
+ [--approval ${APPROVALS.join('|')}] [--extra-arg=<arg>]...
103
103
  Run in a long-lived session's own tab: make a
104
104
  temporary session of that session's bot for a piece
105
105
  of work, and bring it up. It takes your harness,
106
106
  model, effort, context and approval unless you say
107
- otherwise, works in work/<session>, and has the task
108
- as its start prompt. The book records it as
109
- temporary, made by you.
107
+ otherwise; on another harness than yours it takes
108
+ only your approval. It works in work/<session>, and
109
+ has the task as its start prompt. The book records
110
+ it as temporary, made by you.
110
111
  obk temp retire --bots <path> --name <session>
111
112
  Run in the maker's own tab: retire a temporary
112
113
  session it made, as obk retire does. It refuses a
113
114
  long-lived session, or one another session made.
115
+ obk temp trust-hooks --bots <path> --name <session>
116
+ Run in the maker's own tab: answer the hooks review
117
+ of a Codex temporary session it made with "Trust
118
+ all and continue", and check the review went. It
119
+ refuses anything else on that screen, and types
120
+ nothing then.
114
121
  obk rules build --bots <path> [--bot <bot>]
115
122
  Build every bot's AGENTS.md from its charter and
116
123
  the rule units it carries, or just the one you
@@ -190,7 +197,8 @@ Usage:
190
197
  with its settings, its tab and the conversation it
191
198
  is in. It reads your files and reports them as they
192
199
  stand; what to make of them is yours.
193
- obk groom --bots <path> [--on [--at <HH:MM>] | --at <HH:MM> | --off | --now | --compact]
200
+ obk groom --bots <path> [--on [--at <HH:MM>] [--run-on codex [--model <m>] [--effort <e>] [--extra-arg=<arg>]...]
201
+ | --at <HH:MM> | --off | --now | --compact]
194
202
  Say what the daily grooming is: Bot Father's session
195
203
  grooming, and the job scheduled in it on Claude
196
204
  Code's own scheduler. Add that session like any
@@ -201,19 +209,23 @@ Usage:
201
209
  day, so run it by hand once and read it first. --at
202
210
  moves it, --off unschedules it, and --compact
203
211
  compacts its conversation between runs. It fires
204
- only while its tab is up in Orca.
212
+ only while its tab is up in Orca. --run-on codex
213
+ makes each run a temporary Codex session of the
214
+ grooming session's, launched with --model, --effort
215
+ and --extra-arg, which reports back by the kit's
216
+ mail and is retired.
205
217
  obk usage --bots <path> [--bot <bot>] [--session <name>] [--since <time>] [--until <time>]
206
218
  Say what your sessions have used: the conversations
207
219
  each one had, their calls and tokens (their
208
- subagents' included, and how many were theirs), the
209
- models and efforts they ran at, and how often they
210
- were compacted. --since counts the calls made from
211
- that moment on, and --until the calls made before
212
- that one: a daily run asks from the last run's end
213
- up to its own, and the next starts where it stopped,
214
- so no call is counted twice. It counts tokens and
215
- never money: what a token costs is looked up live by
216
- whoever is asking.
220
+ subagents' and Codex's auto-reviews included, and
221
+ how many were whose), the models and efforts they
222
+ ran at, and how often they were compacted. --since
223
+ counts the calls made from that moment on, and
224
+ --until the calls made before that one: a daily run
225
+ asks from the last run's end up to its own, and the
226
+ next starts where it stopped, so no call is counted
227
+ twice. It counts tokens and never money: what a
228
+ token costs is looked up live by whoever is asking.
217
229
  obk session record --bots <path> --bot <bot>
218
230
  For the kit's own hook, not for typing: it reads
219
231
  what the harness says about a session starting on
@@ -260,6 +272,7 @@ const COMMANDS = {
260
272
  'session mailbox': ['bots', 'bot', 'session'],
261
273
  'temp make': ['bots', 'name'],
262
274
  'temp retire': ['bots', 'name'],
275
+ 'temp trust-hooks': ['bots', 'name'],
263
276
  };
264
277
 
265
278
  /** What each flag is for, in the sentence a caller reads when it is missing. */
@@ -333,6 +346,7 @@ async function run(argv) {
333
346
  disallow: { type: 'string', multiple: true },
334
347
  ...Object.fromEntries(SETTINGS.map(([flag]) => [flag, { type: 'string' }])),
335
348
  'extra-arg': { type: 'string', multiple: true },
349
+ 'run-on': { type: 'string' },
336
350
  json: { type: 'boolean' },
337
351
  help: { type: 'boolean', short: 'h' },
338
352
  version: { type: 'boolean' },
@@ -601,6 +615,7 @@ const commands = {
601
615
  if (values[flag] !== undefined) given[key] = values[flag];
602
616
  }
603
617
  if (values.context !== undefined) given.context = asNumberOrText(values.context);
618
+ if (values['extra-arg'] !== undefined) given.extra_args = values['extra-arg'];
604
619
  const made = await makeTemp(bots, { tab, ...given });
605
620
  const { tabs, rules, skills, permissions, paused, projects } = made.up;
606
621
  const answer = { bots, bot: made.bot, session: made.session, maker: made.maker, settings: made.settings, created: [], completed: [], rules, skills, permissions, tabs, paused, projects };
@@ -625,6 +640,16 @@ const commands = {
625
640
  };
626
641
  },
627
642
 
643
+ async 'temp trust-hooks'(bots, values) {
644
+ const tab = callerTab(bots, true);
645
+ refuseWhenOrcaIsDown();
646
+ const trusted = await trustHooks(bots, { tab, name: values.name });
647
+ return {
648
+ answer: { bots, ...trusted },
649
+ lines: [`trusted ${trusted.bot} ${trusted.session}'s hooks, a temporary session of ${trusted.maker}'s: chose "Trust all and continue" on its hooks review, and the review has gone`],
650
+ };
651
+ },
652
+
628
653
  'bot create'(bots, values) {
629
654
  const made = createBot(bots, { name: values.name, harness: values.harness, charter: values.charter });
630
655
  // The bot's AGENTS.md is the rules build's, here as everywhere else, so
@@ -821,7 +846,16 @@ const commands = {
821
846
  }
822
847
  // --at on its own moves grooming that is on to another time.
823
848
  const ask = asks[0] ?? (values.at === undefined ? undefined : 'move');
824
- const groom = grooming(bots, { at: values.at, ask });
849
+ // What each run is launched with when it runs on Codex (#238): given only
850
+ // with --run-on, and refused by grooming() when it is not.
851
+ const given = ['run-on', 'model', 'effort', 'extra-arg'].some((flag) => values[flag] !== undefined);
852
+ const run = !given ? undefined : {
853
+ harness: values['run-on'],
854
+ ...(values.model === undefined ? {} : { model: values.model }),
855
+ ...(values.effort === undefined ? {} : { effort: values.effort }),
856
+ ...(values['extra-arg'] === undefined ? {} : { extra_args: values['extra-arg'] }),
857
+ };
858
+ const groom = grooming(bots, { at: values.at, ask, run });
825
859
  return { answer: { bots, groom }, lines: groomLines(groom, bots) };
826
860
  },
827
861
 
@@ -1213,6 +1247,7 @@ function conversationLine(one) {
1213
1247
  .join(' ');
1214
1248
  return ` ${one.id} ${one.calls} call${one.calls === 1 ? '' : 's'}`
1215
1249
  + `${one.subagent_calls > 0 ? ` of which subagents: ${one.subagent_calls} call${one.subagent_calls === 1 ? '' : 's'}` : ''}`
1250
+ + `${one.review_calls > 0 ? ` of which Codex's auto-review: ${one.review_calls} call${one.review_calls === 1 ? '' : 's'}` : ''}`
1216
1251
  + `${ran === '' ? '' : ` ${ran}`}`
1217
1252
  + `${used === '' ? '' : ` ${used}`}`
1218
1253
  + `${one.compactions > 0 ? ` compacted ${one.compactions}` : ''}`;
@@ -1275,6 +1310,7 @@ function jobLines(jobs, bots, head) {
1275
1310
  const [job] = jobs;
1276
1311
  return [
1277
1312
  `${head} on, daily at ${job.at ?? job.cron} job ${job.id}`,
1313
+ ...(job.run === undefined ? [] : [`${more}Each run is a temporary ${job.run.harness} session: model ${job.run.model ?? `${job.run.harness}'s own`}, effort ${job.run.effort ?? `${job.run.harness}'s own`}.`]),
1278
1314
  `${more}Each run renews it; with no run, Claude Code ends it at ${job.expires}.`,
1279
1315
  `Turn it off: ${groomCommand(bots)} --off`,
1280
1316
  ];
@@ -115,7 +115,8 @@ export function claudeSubagentTranscripts(file) {
115
115
  /**
116
116
  * The same conversations, each with the file the harness keeps it in, for a
117
117
  * caller that has to read what is inside one rather than only know it is there,
118
- * and whether the harness marks it as a subagent's.
118
+ * whether the harness marks it as a subagent's, and, for a Codex subagent, the
119
+ * conversation it was started for and whether it is Codex's auto-review.
119
120
  */
120
121
  export function transcriptsIn(harness, home, since) {
121
122
  const from = since === undefined ? 0 : Date.parse(since);
@@ -123,7 +124,13 @@ export function transcriptsIn(harness, home, since) {
123
124
  return found
124
125
  .filter((one) => Number.isNaN(from) || one.at >= from)
125
126
  .sort((left, right) => left.at - right.at)
126
- .map((one) => ({ id: one.id, at: new Date(one.at).toISOString(), file: one.file, subagent: one.subagent === true }));
127
+ .map((one) => ({
128
+ id: one.id,
129
+ at: new Date(one.at).toISOString(),
130
+ file: one.file,
131
+ subagent: one.subagent === true,
132
+ ...(one.parent === undefined ? {} : { parent: one.parent, review: one.review }),
133
+ }));
127
134
  }
128
135
 
129
136
  /**
@@ -209,11 +216,29 @@ function codexConversations(home, from) {
209
216
  .flatMap((file) => {
210
217
  const meta = sessionMeta(file);
211
218
  return meta?.cwd === home && typeof meta.id === 'string'
212
- ? [{ id: meta.id, at: Date.parse(meta.timestamp ?? '') || startedAt(file) || 0, file, subagent: isSubagent(meta) }]
219
+ ? [{ id: meta.id, at: Date.parse(meta.timestamp ?? '') || startedAt(file) || 0, file, subagent: isSubagent(meta), ...codexParent(meta) }]
213
220
  : [];
214
221
  });
215
222
  }
216
223
 
224
+ /**
225
+ * Every Codex subagent on record, wherever it ran, with the conversation it was
226
+ * started for: `{ id, file, parent, review }` (#449). Found by the link in its
227
+ * own record, not by folder: a session's worker can run in a folder of its own.
228
+ * Read once per process, since every bot asks the same question of the same
229
+ * files.
230
+ */
231
+ let subagents;
232
+ export function codexSubagents() {
233
+ subagents ??= rollouts(codexDir()).flatMap((file) => {
234
+ const meta = sessionMeta(file);
235
+ if (meta === undefined || typeof meta.id !== 'string') return [];
236
+ const link = codexParent(meta);
237
+ return link.parent === undefined ? [] : [{ id: meta.id, file, ...link }];
238
+ });
239
+ return subagents;
240
+ }
241
+
217
242
  /** Every rollout file under Codex's sessions folder, however deep it files them. */
218
243
  function rollouts(dir, depth = 0) {
219
244
  if (depth > 4) return [];
@@ -243,6 +268,21 @@ function sessionMeta(file) {
243
268
  const isSubagent = (meta) =>
244
269
  meta.source !== null && typeof meta.source === 'object' && 'subagent' in meta.source;
245
270
 
271
+ /**
272
+ * The conversation a Codex subagent was started for, as its own record names
273
+ * it, and whether it is Codex's auto-review: `{ parent, review }`, or nothing
274
+ * for a session's own (#449). A session's spawned subagent names it under
275
+ * `source.subagent.thread_spawn.parent_thread_id`; Codex's auto-review, which
276
+ * is `{ subagent: { other: 'guardian' } }`, names the conversation it reviewed
277
+ * as a top-level `parent_thread_id` (tech notes, section 3).
278
+ */
279
+ function codexParent(meta) {
280
+ if (!isSubagent(meta)) return {};
281
+ const parent = meta.source.subagent?.thread_spawn?.parent_thread_id ?? meta.parent_thread_id;
282
+ if (typeof parent !== 'string' || parent === '') return {};
283
+ return { parent, review: meta.source.subagent?.other === 'guardian' };
284
+ }
285
+
246
286
  /** When a file was last written, for leaving out what is plainly too old. */
247
287
  function lastTouched(file) {
248
288
  try {