agent-bios 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.
- package/DEPENDENCIES.md +5 -4
- package/README.md +2 -2
- package/claude/CLAUDE.md +14 -5
- package/claude/agents/frontier.md +9 -0
- package/claude/agents/sweep.md +9 -0
- package/claude/agents/workhorse.md +8 -0
- package/claude/guides/claude-prompting.md +123 -0
- package/claude/guides/cli-multi-model-workflow.md +11 -4
- package/claude/guides/coding-staged-workflow.md +8 -0
- package/claude/guides/gpt-prompting.md +118 -0
- package/claude/guides/llm-capability-boundary-patterns.md +5 -0
- package/claude/guides/mock-realization-boundary.md +9 -0
- package/claude/guides/review-request.md +274 -0
- package/claude/guides/session-learning-workflow.md +100 -0
- package/claude/guides/tooling-gotchas.md +155 -0
- package/claude/hooks/tooling-gotchas-hook.py +79 -0
- package/codex/AGENTS.md +14 -5
- package/codex/config-additions.toml +22 -0
- package/codex/guides/claude-prompting.md +123 -0
- package/codex/guides/cli-multi-model-workflow.md +11 -4
- package/codex/guides/coding-staged-workflow.md +8 -0
- package/codex/guides/gpt-prompting.md +118 -0
- package/codex/guides/llm-capability-boundary-patterns.md +5 -0
- package/codex/guides/mock-realization-boundary.md +9 -0
- package/codex/guides/review-request.md +274 -0
- package/codex/guides/session-learning-workflow.md +100 -0
- package/codex/guides/tooling-gotchas.md +155 -0
- package/config/agent-launch.toml +23 -0
- package/package.json +6 -2
- package/scripts/agent-launch.py +504 -29
- package/scripts/check-parity.sh +73 -6
- package/scripts/check-prompting-targets.sh +62 -0
- package/scripts/codex-helm.sh +19 -1
- package/scripts/codex-run.sh +19 -0
- package/scripts/install.sh +298 -6
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
---
|
|
2
|
+
guide_id: review-request
|
|
3
|
+
language: en
|
|
4
|
+
status: active
|
|
5
|
+
use_when:
|
|
6
|
+
- writing a review request, packet, or reviewer role for any model
|
|
7
|
+
- deciding what evidence bar and verdict shape to demand from a reviewer
|
|
8
|
+
- triaging why a review returned noise, nothing, or a clean bill of health
|
|
9
|
+
- choosing which perspectives to run and whether to pay for deliberation
|
|
10
|
+
core_rules:
|
|
11
|
+
- demand a failure path, not a gap — "X is unverified" dies, "X breaks when Y" survives
|
|
12
|
+
- require every finding to anchor to file:line, and every empty result to cite what was checked
|
|
13
|
+
- say what the target is and is not — stage, boundary, and what absence means
|
|
14
|
+
- bundle the consumer the target depends on, or its most load-bearing claim is unreviewable
|
|
15
|
+
- forbid carry-forward findings — anything phrased "watch" or "document later" is not a finding
|
|
16
|
+
- read participation before believing a verdict; a crashed harness reports zero findings
|
|
17
|
+
- treat a finding's causal attribution as the reviewer's weakest claim, not its severity
|
|
18
|
+
verification_focus:
|
|
19
|
+
- a zero-findings verdict is confirmed against participation, not accepted at face value
|
|
20
|
+
- findings are checked for a stated failure path before they are acted on
|
|
21
|
+
- an empty result is trusted only when it cites the evidence it checked
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
# Review Request Guide
|
|
25
|
+
|
|
26
|
+
This guide is a scoped extension of the global Coding Guidelines. Use it when
|
|
27
|
+
composing what you ask a reviewer for — the request, the evidence bar, the
|
|
28
|
+
verdict shape. It does not cover when to review, how deep, or what counts as
|
|
29
|
+
material (the staged-workflow guide's severity ladder and review loop own that),
|
|
30
|
+
which reviewer kind to route to (the multi-model guide's convergence heuristic),
|
|
31
|
+
or how to phrase a prompt for a given model family (the per-family prompting
|
|
32
|
+
guides).
|
|
33
|
+
|
|
34
|
+
The rules below are derived from ~330 real multi-lens review sessions run in
|
|
35
|
+
this environment. That corpus is one model family in practice, so nothing here
|
|
36
|
+
is a per-model claim; these are the failures that persist regardless of who
|
|
37
|
+
reviews. Every rule names the evidence behind it, because a review guide that
|
|
38
|
+
asserts without evidence would fail its own bar.
|
|
39
|
+
|
|
40
|
+
## Demand a failure path, not a gap
|
|
41
|
+
|
|
42
|
+
The dominant reviewer failure is not hallucination. Across 372 rejected
|
|
43
|
+
findings, "asserted a gap without demonstrating a failure" accounts for the
|
|
44
|
+
largest share (~34%), while misreading correct code accounts for **one** case
|
|
45
|
+
and speculation for seven. Reviewers do not invent defects — they report
|
|
46
|
+
unverified things and call them findings.
|
|
47
|
+
|
|
48
|
+
The corpus separates these cleanly by how the finding is framed:
|
|
49
|
+
|
|
50
|
+
| Framed as | Dropped |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `evidence_gap` — "not covered / not verified" | 94% (n=143) |
|
|
53
|
+
| `needs_evidence` | 93% (n=118) |
|
|
54
|
+
| `document_only` | 92% (n=144) |
|
|
55
|
+
| `root_cause` — a defect with a cause | 3% (n=878) |
|
|
56
|
+
| `fix_now` | 3% (n=1026) |
|
|
57
|
+
|
|
58
|
+
So say it in the request: **state the input, the branch, and the observable
|
|
59
|
+
wrong behavior. "X is not verified" is not a finding; "X breaks when Y" is.**
|
|
60
|
+
A reviewer that cannot show the failure should say so as a boundary note, not
|
|
61
|
+
file it against the target.
|
|
62
|
+
|
|
63
|
+
## Set a severity floor, because low never survives
|
|
64
|
+
|
|
65
|
+
Severity is the single most decisive predictor in the corpus, and it is close to
|
|
66
|
+
deterministic:
|
|
67
|
+
|
|
68
|
+
| Severity | Reaches the deliverable |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `blocker` (n=16) | 100% |
|
|
71
|
+
| `high` (n=366) | 96% |
|
|
72
|
+
| `medium` (n=1338) | 92% |
|
|
73
|
+
| `info` (n=44) | 5% |
|
|
74
|
+
| `low` (n=226) | **0%** |
|
|
75
|
+
|
|
76
|
+
Not one low-severity finding out of 226 survived. The tokens that produced them
|
|
77
|
+
were spent for nothing, twice — once writing, once reading.
|
|
78
|
+
|
|
79
|
+
So state the floor in the request: **do not report a finding you would rate low.
|
|
80
|
+
It will be discarded; spend the effort on a medium-or-above finding instead.**
|
|
81
|
+
This is not a quality bar on the reviewer, it is a cost decision — the corpus
|
|
82
|
+
shows the discard happens regardless, so the only question is whether you pay to
|
|
83
|
+
generate it first. (What counts as each severity is the staged-workflow guide's
|
|
84
|
+
ladder, not this guide's.)
|
|
85
|
+
|
|
86
|
+
## Forbid carry-forward findings
|
|
87
|
+
|
|
88
|
+
Every finding the corpus classified as deferrable died: `planned_later` 100%
|
|
89
|
+
(n=104), `watch` 100% (n=36), `defer_watch` 97% (n=71), `out_of_scope` 92%
|
|
90
|
+
(n=26). Not one survived to the deliverable.
|
|
91
|
+
|
|
92
|
+
Ask only for what must change in this target now. Anything the reviewer would
|
|
93
|
+
phrase as "carry forward", "watch", or "document later" costs tokens to produce,
|
|
94
|
+
tokens to read, and is discarded — say that up front so it is never written.
|
|
95
|
+
|
|
96
|
+
## Say what the target is, and what absence means
|
|
97
|
+
|
|
98
|
+
The most common thing reviewers report they lacked is the stage context: they
|
|
99
|
+
review a design and cannot see the implementation, then hedge every finding into
|
|
100
|
+
a design-contract claim. Their own words, recurring across sessions: *"The packet
|
|
101
|
+
reviews a design, not an implemented patch, so the exact future API is not
|
|
102
|
+
visible."*
|
|
103
|
+
|
|
104
|
+
Name the stage and say what absence means — "this is a pre-implementation
|
|
105
|
+
design; do not treat missing implementation as a defect." A session given exactly
|
|
106
|
+
that instruction returned zero findings and proved it had looked, anchored on
|
|
107
|
+
both sides of the comparison. A session not given it filed unimplemented code as
|
|
108
|
+
blockers, and the user caught it manually.
|
|
109
|
+
|
|
110
|
+
## Bundle the consumer, not just the artifact
|
|
111
|
+
|
|
112
|
+
When a target says "see X", X is part of the target. The corpus's sharpest
|
|
113
|
+
example: a reviewer identified the most load-bearing connection in a design and
|
|
114
|
+
then could not review it — *"§6.4 is outside the review boundary, so
|
|
115
|
+
axis-consumption completeness cannot be verified within the artifact."* The
|
|
116
|
+
request bundled the child and not the parent it depended on.
|
|
117
|
+
|
|
118
|
+
What reviewers needed, almost every time, was the consumer: the code that reads
|
|
119
|
+
the field, the parent doc defining the weights, the log proving the behavior. If
|
|
120
|
+
a claim's evidence lives outside the boundary, either widen the boundary or
|
|
121
|
+
accept that the claim is unreviewable — do not expect a finding about it.
|
|
122
|
+
|
|
123
|
+
## Make evidence structural, not requested
|
|
124
|
+
|
|
125
|
+
In this corpus every finding carries a `file:line` anchor and every empty result
|
|
126
|
+
carries a rationale — 2,466/2,466 and 981/981. Not because the prompts asked
|
|
127
|
+
nicely: the submit schema refuses output without them. The result is a corpus
|
|
128
|
+
where reviewers are right about existence (0.3% of issues end unresolved after
|
|
129
|
+
argument) and where "found nothing" is a verified statement rather than silence.
|
|
130
|
+
|
|
131
|
+
This is the general rule from the capability-boundary guide applied to review:
|
|
132
|
+
when output must have a property, make it unavailable without it. If your review
|
|
133
|
+
route has a schema, put the anchor there. If it does not, the demand belongs in
|
|
134
|
+
the request — but expect the weaker result that a request-only rule gives you.
|
|
135
|
+
|
|
136
|
+
The same applies to the target: a document that cites its own facts as
|
|
137
|
+
`file:line` gives the reviewer a falsifiable surface, and the corpus's best
|
|
138
|
+
findings are refutations of exactly those cited facts. Prose gives nothing to
|
|
139
|
+
check.
|
|
140
|
+
|
|
141
|
+
## Claim only what the evidence proves, and attribute it to one root
|
|
142
|
+
|
|
143
|
+
Reviewers are calibrated on whether a defect exists and miscalibrated on why.
|
|
144
|
+
When a finding is narrowed, the defect itself almost always survives (97%,
|
|
145
|
+
n=212). What gets cut is the causal attribution (45%) or the surface the claim
|
|
146
|
+
covered (34%) — not the proposed fix (10%), and not the defect. Lenses register
|
|
147
|
+
this as a first-class stance: `narrow` appears 1,320 times against 101 for
|
|
148
|
+
`oppose`. They rarely disagree that something is broken; they routinely disagree
|
|
149
|
+
about what broke it, and about how much of the system it touches.
|
|
150
|
+
|
|
151
|
+
"Narrowed" is a misleading name for what happens. Narrowed claims get **longer**
|
|
152
|
+
— 94% of them, by a median of ~118 characters — because narrowing adds
|
|
153
|
+
qualification and re-attribution rather than deleting text. The final root cause
|
|
154
|
+
is a near-rewrite (median text similarity 0.21 against the original). What looks
|
|
155
|
+
like trimming is the reviewer being made to say what its evidence actually
|
|
156
|
+
supports.
|
|
157
|
+
|
|
158
|
+
That makes narrowing and rejection the same force at different granularity:
|
|
159
|
+
overclaim beyond your evidence and the finding is narrowed if a proven core
|
|
160
|
+
exists, dropped if it does not. The corpus language is identical in both — the
|
|
161
|
+
survivors are "narrowed to the directly evidenced command-wiring gap", "to files
|
|
162
|
+
proven in capsule authority_refs", "to the demonstrated side-effect path".
|
|
163
|
+
|
|
164
|
+
So ask for the observable failure and the evidence that proves it, scoped to the
|
|
165
|
+
surface that evidence covers. Treat the reviewer's causal story as its weakest
|
|
166
|
+
claim — a hypothesis to verify, not a conclusion — and do not let a proposed fix
|
|
167
|
+
become the design by default.
|
|
168
|
+
|
|
169
|
+
One axis is easy to miss: in ~17% of narrowings every lens accepts the defect,
|
|
170
|
+
the root, and the fix, and the only live disagreement is **how bad it is**. That
|
|
171
|
+
matters more than its share suggests, because severity decides survival — a
|
|
172
|
+
finding rated low never reaches the deliverable. If severity is contested, it is
|
|
173
|
+
the thing to adjudicate, not a detail to average out.
|
|
174
|
+
|
|
175
|
+
## Read participation before believing a verdict
|
|
176
|
+
|
|
177
|
+
Seven sessions reported `Finding count: 0` — a clean bill of health — with
|
|
178
|
+
`Participating lenses: 0/N`. Nothing was reviewed. And when the harness dies, two
|
|
179
|
+
separate channels lie about why. Twenty-two sessions recorded
|
|
180
|
+
`failure_kind: output_contract`; in the ones whose nested stderr is readable the
|
|
181
|
+
cause is a provider usage-limit rejection — *"You've hit your usage limit"*,
|
|
182
|
+
`exit=1`, no model output produced at all — so the label blames the model's
|
|
183
|
+
output format for a pre-dispatch billing refusal, when no output ever existed to
|
|
184
|
+
violate a contract. Triage by that label and you debug the prompt when you needed
|
|
185
|
+
to buy credits.
|
|
186
|
+
|
|
187
|
+
Two consequences for anyone consuming a review:
|
|
188
|
+
|
|
189
|
+
- The tell is the participation count and execution status, never the severity
|
|
190
|
+
counts. A crashed harness renders as a perfect score.
|
|
191
|
+
- Artifacts named for failure may not carry it, and the two failures compound. In
|
|
192
|
+
those same quota-killed sessions the file named `environment-warnings.yaml`
|
|
193
|
+
recorded only `non_fatal` dispatch traces with `outputTrustImpact: unknown` and
|
|
194
|
+
never once mentioned the quota; corpus-wide it holds ~9,800 warnings and has
|
|
195
|
+
never fired on a real failure. So the channel named for failures never fires,
|
|
196
|
+
the channel that fires uses the wrong name, and the truth is only in the nested
|
|
197
|
+
stderr. Read the channel the mechanism actually writes, confirmed against the
|
|
198
|
+
low-level log, not the one named for the thing you want.
|
|
199
|
+
- Participation tells you the lenses ran, not that they saw the whole subject.
|
|
200
|
+
Git-diff-based review tools silently omit staged-but-uncommitted changes from
|
|
201
|
+
a HEAD-range diff, and untracked files from any diff. Before dispatch, list
|
|
202
|
+
the subject with `git status --porcelain` and expose untracked files
|
|
203
|
+
(`git add -N` or a WIP commit); after the run, compare the reviewed-file list
|
|
204
|
+
against that listing — an unexplained gap demotes the verdict to incomplete.
|
|
205
|
+
(Our own dispatch wrapper does this check itself; apply this manually on
|
|
206
|
+
review routes we do not own.)
|
|
207
|
+
- A review deliverable names the findings it *rejected* as well as the ones it
|
|
208
|
+
kept, so a finding's presence in the document is not its survival. Deriving
|
|
209
|
+
survival from presence returns 100% by construction — it did here, until the
|
|
210
|
+
count was scoped to the material section, at which point 16% of the same
|
|
211
|
+
findings turned out to have reached the reader explicitly flagged
|
|
212
|
+
non-material. Read the verdict field, not the mention.
|
|
213
|
+
|
|
214
|
+
## Trust an empty result only when it cites what it checked
|
|
215
|
+
|
|
216
|
+
Empty is common and usually correct: 42% of lens invocations produce nothing,
|
|
217
|
+
and those runs have *larger* inputs and sit *later* in a repo's review sequence
|
|
218
|
+
than productive ones — they are re-reviews of targets already fixed. The waste
|
|
219
|
+
worth naming is not the empty result; it is paying full pipeline cost to
|
|
220
|
+
re-review something you already repaired.
|
|
221
|
+
|
|
222
|
+
An empty result earns trust from its rationale. A reasoned null names the
|
|
223
|
+
evidence it checked on both sides of the comparison. A rationale-free empty
|
|
224
|
+
result is a failed run wearing a clean verdict — gate on the rationale, not on
|
|
225
|
+
the emptiness.
|
|
226
|
+
|
|
227
|
+
## Spend deliberation where it adjudicates, not where it agrees
|
|
228
|
+
|
|
229
|
+
Two-thirds of issues (66%, n=1153) never need deliberation, and the largest
|
|
230
|
+
single cause of halted sessions is the user cancelling. But they do not cancel
|
|
231
|
+
early: of 27 cancelled sessions all 27 reached the raw first pass, 22 reached the
|
|
232
|
+
consolidated finding ledger, and only 2 reached deliberation. Users wait for the
|
|
233
|
+
deduplicated, severity-tagged ledger, act on it, and abandon the deliberation and
|
|
234
|
+
synthesis that would have run next. Meanwhile the issues that *are* deliberated
|
|
235
|
+
and survive are the most reliable in the corpus (94% material vs 74% for
|
|
236
|
+
undeliberated).
|
|
237
|
+
|
|
238
|
+
So deliberation is worth its cost when it adjudicates a contested claim, and is
|
|
239
|
+
ceremony when every perspective already agrees — one of the largest deliberation
|
|
240
|
+
artifacts in the corpus resolved 22 of 22 issues as "no deliberation needed".
|
|
241
|
+
Front-load the actionable findings, because that is the part that gets used.
|
|
242
|
+
|
|
243
|
+
## Choose perspectives that can bite
|
|
244
|
+
|
|
245
|
+
Adding a perspective is not free. In this corpus the concept-surface lens
|
|
246
|
+
produces the fewest findings, is silent most often, and half of what it does
|
|
247
|
+
produce is discarded — because 43% of its candidates are rated low, and low
|
|
248
|
+
never survives. Naming, redundancy, and abstraction concerns count only when
|
|
249
|
+
they change runtime behavior or enforced semantics; ask for them on that
|
|
250
|
+
condition or not at all.
|
|
251
|
+
|
|
252
|
+
The inverse failure is worth watching for: when no perspective owns the real
|
|
253
|
+
risk, a reviewer files a governance gap instead of a defect — *"this is a
|
|
254
|
+
review-governance gap, not a design defect in the target."* That is the review
|
|
255
|
+
telling you its own lens set was wrong for the target.
|
|
256
|
+
|
|
257
|
+
## Evidence base
|
|
258
|
+
|
|
259
|
+
Derived 2026-07-16 from ~330 onto review sessions across 15 repositories in this
|
|
260
|
+
environment (1,738 classified issues; 2,466 anchored findings; 278 deliberations;
|
|
261
|
+
14,370 lens stances). Every count here was reproduced independently before being
|
|
262
|
+
written down, and several first attempts were wrong: survival measured by
|
|
263
|
+
document presence returns 100% by construction, and hand-rolled verb-object
|
|
264
|
+
counting undercounted the narrowing axes about fivefold. Where a share is given
|
|
265
|
+
for how narrowing splits, read it as a floor — ~19% of cases resist
|
|
266
|
+
classification — and trust the ordering (root > scope > severity > remedy) rather
|
|
267
|
+
than the magnitudes.
|
|
268
|
+
|
|
269
|
+
Two limits bound what this guide may claim. The corpus is ~95% a single model
|
|
270
|
+
family, so nothing here is a per-model claim. And it contains no under-specified
|
|
271
|
+
requests — the shortest still names its axes and its evidence bar — so these are
|
|
272
|
+
the failures that survive a *good* request, not an argument that requests need
|
|
273
|
+
specifying. Re-derive from a fresh corpus when the review route or the bound
|
|
274
|
+
models change.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
guide_id: session-learning-workflow
|
|
3
|
+
language: en
|
|
4
|
+
status: active
|
|
5
|
+
use_when:
|
|
6
|
+
- a session was launched with the Session learning preset (mission-injected)
|
|
7
|
+
- the launcher nudge says enough sessions accumulated for a mining window
|
|
8
|
+
- mining local Claude/Codex sessions for learnings absent from the corpus
|
|
9
|
+
- promoting, incubating, or retiring items in the session-learning ledger
|
|
10
|
+
core_rules:
|
|
11
|
+
- the ledger and HANDOFF are the SSOT; read them before touching the pipeline
|
|
12
|
+
- placement follows PLACEMENT-FRAMEWORK.md, never ad-hoc judgment
|
|
13
|
+
- every promotion passes an explicit user-approval gate
|
|
14
|
+
- global growth per round is hard-capped (~500 tokens) by a measured gate
|
|
15
|
+
- close the window by updating mirrors, parity, deployment, and the nudge baseline
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Session-Learning Workflow
|
|
19
|
+
|
|
20
|
+
Runbook for a learning-refinement session: mine recent main-context sessions,
|
|
21
|
+
verify candidates, place them through the framework, and apply with the user.
|
|
22
|
+
Everything durable lives in the agent-bios repo.
|
|
23
|
+
|
|
24
|
+
## Read first (SSOT)
|
|
25
|
+
|
|
26
|
+
1. `design/session-learning/HANDOFF.md` — initiative state, prior decisions,
|
|
27
|
+
open threads. 2. `design/session-learning/PLACEMENT-FRAMEWORK.md` — the
|
|
28
|
+
placement authority (typology A–G, layers, admission bars, lifecycle).
|
|
29
|
+
3. `design/session-learning/ledger.json` — cumulative item states
|
|
30
|
+
(placed / incubating / absorbed / retired) with provenance.
|
|
31
|
+
|
|
32
|
+
## Stage 1 — Mine (pipeline in `scripts/session-learning/`)
|
|
33
|
+
|
|
34
|
+
Run in order; each stage reads the previous stage's `out/`:
|
|
35
|
+
|
|
36
|
+
1. `census.py --end YYYY-MM-DD` — enumerate from both providers'
|
|
37
|
+
history.jsonl; keep only directly-handled main-context sessions by
|
|
38
|
+
transcript-side provenance (dispatched = Codex source=exec /
|
|
39
|
+
Claude sidechain/sdk-cli/agentId).
|
|
40
|
+
2. `digest.py` — one secret-redacted digest per session with deterministic
|
|
41
|
+
6-criteria signals. Screen ALL digests; triage orders, never drops.
|
|
42
|
+
3. Provider-affine screening against the concatenated live baseline
|
|
43
|
+
(CLAUDE.md + guides): `screen-claude.js` (Workflow) and
|
|
44
|
+
`screen-codex.js` (ultracode). Novelty is judged against real baseline
|
|
45
|
+
text, not memory.
|
|
46
|
+
4. `consolidate.js` — dedup + independent novelty verification. Rank by
|
|
47
|
+
strength (recurrence × materiality), never by self-reported confidence.
|
|
48
|
+
5. `bundle_final.py` — tiered bundle. Merge new candidates into
|
|
49
|
+
`ledger.json` by cluster identity so recurrence accumulates across
|
|
50
|
+
windows (incubated items promote when they re-occur).
|
|
51
|
+
|
|
52
|
+
## Stage 2 — Review with the user
|
|
53
|
+
|
|
54
|
+
- Produce a Korean review edition as a local repo file (this user cannot
|
|
55
|
+
access web artifact renders): per item, principle, why it was selected,
|
|
56
|
+
verdict, and placement recommendation, with stable IDs.
|
|
57
|
+
- Decisions, in order: ① selection against the promotion bar (recurrence ≥2
|
|
58
|
+
or single-event high materiality — irreversible / verification-corrupting /
|
|
59
|
+
security); ② PROPOSED resolutions (never silently resolved); ③ G-candidate
|
|
60
|
+
adoption. Record every decision in the ledger.
|
|
61
|
+
|
|
62
|
+
## Stage 3 — Classify and apply (§P8)
|
|
63
|
+
|
|
64
|
+
- Walk each accepted item through the framework pipeline: type (A–G) →
|
|
65
|
+
leftward reformulation (fact→principle, knowledge→structure) → layer →
|
|
66
|
+
consumer check (hermetic dispatch and scripts read no prose) → admission
|
|
67
|
+
bar → token estimate. Ambiguity stays PROPOSED for the user.
|
|
68
|
+
- Apply canonical-first, on a branch, stepwise commits: canonical guide text
|
|
69
|
+
→ global edits under the measured budget gate (net growth ≤ ~500 tokens/
|
|
70
|
+
round; overflow re-routes to guides, not silent deferral) → other guides →
|
|
71
|
+
hooks (derive injected text from the canonical guide; read-only, never
|
|
72
|
+
blocking) → enforcement in owned wrappers (loud failures; keep
|
|
73
|
+
stdout/stderr channel contracts) → codex/ + ko/ mirrors.
|
|
74
|
+
- Verify per layer, not just by diff: enforcement/gate fixture tests
|
|
75
|
+
(non-vacuous — known-bad must fire), hook trigger positive/negative sets,
|
|
76
|
+
`scripts/check-parity.sh` exit 0 unpiped, prompting-target gate, then
|
|
77
|
+
`agent-bios install` to activate and re-verify.
|
|
78
|
+
|
|
79
|
+
## Stage 4 — G-pass (principles, not directives)
|
|
80
|
+
|
|
81
|
+
- Mine user-correction turns (deterministic marker extraction over digests)
|
|
82
|
+
and initiative-arc retrospectives; add upward distillation over newly
|
|
83
|
+
placed directives (≥3 sharing one value → parent-principle candidate).
|
|
84
|
+
- G evidence bar is higher: ≥3 independent consistent resolutions, or one
|
|
85
|
+
user-confirmed arc retrospective. A principle must name the tension, the
|
|
86
|
+
ordering, and what it forbids. For an under-applied gap (rule exists but
|
|
87
|
+
behavior does not follow), prose repetition is invalid — list it for the
|
|
88
|
+
behavior battery and change the surface instead.
|
|
89
|
+
|
|
90
|
+
## Stage 5 — Close the window
|
|
91
|
+
|
|
92
|
+
1. Ledger: statuses to placed (with implementation paths) / incubating;
|
|
93
|
+
dated corrections for anything refuted.
|
|
94
|
+
2. HANDOFF: completion record, incidental finds as next-window candidates.
|
|
95
|
+
3. Register the learning version: append {version = window end, commit = the
|
|
96
|
+
corpus-close commit} to `design/session-learning/versions.json` — this is
|
|
97
|
+
what the launcher's Versions & rollback screen offers — then run
|
|
98
|
+
`python3 scripts/session-learning/update-state.py --window-end <date>`
|
|
99
|
+
(nudge baseline) and `learning-state.py project` (launcher status panel).
|
|
100
|
+
4. Merge the branch, push, and confirm deployed state (`agent-bios verify`).
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
guide_id: tooling-gotchas
|
|
3
|
+
language: en
|
|
4
|
+
status: active
|
|
5
|
+
use_when:
|
|
6
|
+
- a shell command's exit code or output will gate a pass/fail or verification decision
|
|
7
|
+
- a tool returns empty / no-match / not-found output that contradicts other evidence
|
|
8
|
+
- running git diff over ranges, or pulling into a worktree with local changes
|
|
9
|
+
- passing dynamic or untrusted strings through a shell command line
|
|
10
|
+
- operating cloud/managed-service CLIs, update APIs, or secrets-bearing config
|
|
11
|
+
- spawning subprocesses or long-lived handles
|
|
12
|
+
core_rules:
|
|
13
|
+
- pin ambient state (interpreter, CLI context, command resolution) where an outcome depends on it
|
|
14
|
+
- a piped command's exit code reflects only the last stage — capture the stage under test
|
|
15
|
+
- treat surprising empty output as a tool artifact hypothesis before a world fact
|
|
16
|
+
- git two-dot diff is a snapshot comparison, not a range exclusion; protect dirty worktrees before pulling
|
|
17
|
+
- own the full lifecycle of anything you spawn
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Tooling Gotchas
|
|
21
|
+
|
|
22
|
+
Concrete, tool-level traps behind the global principles. Claude-side hook
|
|
23
|
+
injections derive their text from this file — edit here, never in the hook
|
|
24
|
+
data (single source of truth).
|
|
25
|
+
|
|
26
|
+
## Ambient state drifts — pin it
|
|
27
|
+
|
|
28
|
+
Instances of the global rule: ambient state silently drifts; where an outcome
|
|
29
|
+
depends on it, pin it explicitly instead of trusting the environment.
|
|
30
|
+
|
|
31
|
+
- **Interpreter**: the default shell differs across machines (zsh/bash/dash)
|
|
32
|
+
and bash-only idioms misbehave silently elsewhere (unquoted-variable word
|
|
33
|
+
splitting, `read -r -d ''` hangs). Don't probe the shell per command — make
|
|
34
|
+
shell identity irrelevant: keep inline one-liners POSIX-portable; when a
|
|
35
|
+
bash-specific feature (arrays, `read -d`, `PIPESTATUS`) is needed, pin the
|
|
36
|
+
interpreter with a `#!/bin/bash` script file or `bash -c '…'`. The session
|
|
37
|
+
environment block already declares the shell — read it for free; probe only
|
|
38
|
+
when diagnosing a misbehavior.
|
|
39
|
+
- **Command resolution**: a command name is not a fixed binary — interactive
|
|
40
|
+
shells resolve functions/aliases first, programmatic spawns resolve raw
|
|
41
|
+
PATH, and a same-named package can shadow a system tool with silent empty
|
|
42
|
+
output. Before trusting a result across execution contexts, confirm the
|
|
43
|
+
resolved target (`type -a`, absolute path).
|
|
44
|
+
- **Cloud CLI context**: gcloud/aws/kubectl/terraform carry mutable ambient
|
|
45
|
+
context (active project, profile, cluster) that drifts between sessions.
|
|
46
|
+
Before the first environment-affecting command — or right after a resume —
|
|
47
|
+
verify it against intent, then pin the target explicitly on every command
|
|
48
|
+
(`--project`, `--profile`, `--context`) rather than fixing the global
|
|
49
|
+
default once.
|
|
50
|
+
- **Installed is not running**: a live process keeps its old code until
|
|
51
|
+
restarted or reloaded. When confirming an update, config change, or
|
|
52
|
+
dependency bump took effect, don't stop at the on-disk artifact — confirm
|
|
53
|
+
the running process's actual version/behavior or force a restart.
|
|
54
|
+
|
|
55
|
+
## Shell execution traps
|
|
56
|
+
|
|
57
|
+
- **Pipe exit masking**: `$?` after a pipeline reflects only the last stage;
|
|
58
|
+
a real failure in the command under test is masked by a successful
|
|
59
|
+
`tail`/`grep`/`jq` and reads as a false green. Capture the tested stage's
|
|
60
|
+
own status: run it unpiped, store `$?` immediately, or use
|
|
61
|
+
`set -o pipefail`/`PIPESTATUS` — noting pipefail breaks legitimate
|
|
62
|
+
early-exit consumers (`cmd | head -1` → SIGPIPE 141), so it is a per-command
|
|
63
|
+
choice, not a global default. Does not apply when the final stage IS the
|
|
64
|
+
assertion (`cmd | grep -q pattern`).
|
|
65
|
+
- **Reserved parameter names**: assigning to reserved shell names (`UID`,
|
|
66
|
+
`EUID`, `GID`, `PPID`) can invoke the bound system behavior instead of
|
|
67
|
+
storing a value — silently changing process credentials mid-script. Use
|
|
68
|
+
unreserved names; if such an assignment already ran alongside a
|
|
69
|
+
side-effecting command, verify the resulting system state directly instead
|
|
70
|
+
of assuming the mistake inhibited the command.
|
|
71
|
+
- **Metacharacter-bearing values**: prompts, filenames, or content strings
|
|
72
|
+
that may contain `$`, backticks, quotes, or globs must not be inlined as
|
|
73
|
+
raw CLI arguments — the shell expands or mangles them before the target
|
|
74
|
+
process sees them. Pass via stdin, heredoc, or a temp file. (Our dispatch
|
|
75
|
+
scripts codex-run/codex-helm already accept stdin — use that path.)
|
|
76
|
+
- **Multi-line pasted commands**: a command pasted across lines without
|
|
77
|
+
continuation markers can be re-wrapped into two invocations, silently
|
|
78
|
+
dropping trailing flags (a real incident: `--scopes` lost during an auth
|
|
79
|
+
flow → wrong-scope credential). After running one, verify the target's
|
|
80
|
+
actual state (granted scopes, applied settings); on re-run, join to one
|
|
81
|
+
line or use explicit continuations.
|
|
82
|
+
|
|
83
|
+
## Tool output is a rendering, not the bytes
|
|
84
|
+
|
|
85
|
+
- **grep binary heuristic**: grep silently treats heavy non-ASCII or
|
|
86
|
+
NUL-containing text files as binary and returns a false no-match without
|
|
87
|
+
error. When a no-match contradicts other evidence (git diff, an earlier
|
|
88
|
+
read), re-check with the harness Grep tool (ripgrep) or `grep -a`, or read
|
|
89
|
+
the file directly.
|
|
90
|
+
- **Viewer normalization**: file-read tools can render non-printable bytes
|
|
91
|
+
(NUL) as visually indistinguishable blanks. When correctness rides on
|
|
92
|
+
byte-exact content (delimiters, encodings), verify with `hexdump`/`od` or a
|
|
93
|
+
byte-comparing script, not the rendered view.
|
|
94
|
+
- **Stale caches in rapid loops**: mtime/size-keyed compile or rewrite caches
|
|
95
|
+
can re-serve a previous file's result when mutate→test cycles run within
|
|
96
|
+
timestamp resolution (mutation testing). Clear the cache or run no-cache
|
|
97
|
+
per iteration, and re-confirm the unmutated baseline still passes after a
|
|
98
|
+
cache clear.
|
|
99
|
+
|
|
100
|
+
## Git operations
|
|
101
|
+
|
|
102
|
+
- **Two-dot diff semantics**: `git diff A..B` is a direct snapshot
|
|
103
|
+
comparison — unlike `git log A..B` it excludes nothing, so a lagging
|
|
104
|
+
merge-base injects unrelated upstream changes into the diff. For PR/review
|
|
105
|
+
diffs use `git diff origin/base...HEAD` (merge-base form); suspect this
|
|
106
|
+
mechanism first when a diff looks too large or shows deletions in untouched
|
|
107
|
+
files.
|
|
108
|
+
- **Dirty-worktree pulls**: before pulling into a worktree with
|
|
109
|
+
staged/unstaged/untracked changes, fetch first and compare incoming paths
|
|
110
|
+
against every dirty path; on overlap or a non-fast-forward, stop and clear
|
|
111
|
+
the conflict risk (stash, commit, ask). Otherwise pull `--ff-only`, confirm
|
|
112
|
+
dirty changes survived, and regenerate any local derived artifacts whose
|
|
113
|
+
inputs were updated.
|
|
114
|
+
|
|
115
|
+
## Config, secrets, and managed services
|
|
116
|
+
|
|
117
|
+
- **Verbatim slicing over parse-reserialize**: when provisioning part of a
|
|
118
|
+
user's structured config (TOML/YAML/INI) that may carry secrets and
|
|
119
|
+
comments, extract the section's raw text instead of parsing and
|
|
120
|
+
re-serializing — rewrites silently drop comments, formatting, or secret
|
|
121
|
+
values. Use a parser only for real structural change, and test the slicer
|
|
122
|
+
against actual shapes first.
|
|
123
|
+
- **Merge-not-replace update APIs**: managed-service update calls (secret
|
|
124
|
+
rotation, mount changes) often merge new definitions into the existing set,
|
|
125
|
+
leaving stale, unreferenced definitions live. After updating, re-read the
|
|
126
|
+
resource, check definitions and active references separately, and remove
|
|
127
|
+
the orphans explicitly.
|
|
128
|
+
- **Perimeter controls need the enforcement point's own logs**: an agent-side
|
|
129
|
+
fetch is not an independent external observer — its egress IP and caching
|
|
130
|
+
path are opaque, and it may share the protected network or serve a stale
|
|
131
|
+
cached response. Verify allow AND deny directions from the load balancer /
|
|
132
|
+
firewall's own logs, and check for a front-side cache/CDN separately.
|
|
133
|
+
- **Smoke limits outlive the smoke test**: item caps, sample sizes, and row
|
|
134
|
+
limits left in env vars/flags/config make a later "full-scale" run silently
|
|
135
|
+
succeed on a slice. Clearing or explicitly verifying their absence is a
|
|
136
|
+
precondition of declaring a full run.
|
|
137
|
+
- **Shared live config has concurrent writers**: before concluding your edit
|
|
138
|
+
to a shared state/config file was lost or corrupting, rule out concurrent
|
|
139
|
+
writers with a short live observation (mtime plus the fields you changed),
|
|
140
|
+
and scope merge/union operations to the intended fields only.
|
|
141
|
+
- **Production probes expose data**: default diagnostic queries against
|
|
142
|
+
production stores to read-only server-side aggregation (counts, types,
|
|
143
|
+
presence, hashes) — never pull raw payloads into logs, prompts, or
|
|
144
|
+
transcripts — and delete scratch probe resources after the decision.
|
|
145
|
+
|
|
146
|
+
## Own what you spawn
|
|
147
|
+
|
|
148
|
+
Instance of the global rule: own the full lifecycle of what you create.
|
|
149
|
+
|
|
150
|
+
- **Subprocess/handle lifecycle**: creating a subprocess means owning spawn
|
|
151
|
+
(set up a process group), result acquisition, and teardown — close owned
|
|
152
|
+
stdio handles, kill exactly that group (not just a wrapper PID, which
|
|
153
|
+
orphans the real child), and await exit. An unref'd child handle or open
|
|
154
|
+
stdin pipe keeps the parent's event loop alive and hangs otherwise-complete
|
|
155
|
+
commands.
|
package/config/agent-launch.toml
CHANGED
|
@@ -8,11 +8,17 @@ passthrough_args = []
|
|
|
8
8
|
command = "claude"
|
|
9
9
|
passthrough_args = ["--dangerously-skip-permissions"]
|
|
10
10
|
|
|
11
|
+
# Optional dependencies. `command` gates the route: unresolvable means the route
|
|
12
|
+
# is unavailable and the review setup degrades without it. `install` is the single
|
|
13
|
+
# source for both the one-line hint shown when it is missing and what
|
|
14
|
+
# `agent-bios install --with <name>` runs.
|
|
11
15
|
[capabilities.onto]
|
|
12
16
|
command = "onto"
|
|
17
|
+
install = "npm i -g onto-mcp"
|
|
13
18
|
|
|
14
19
|
[capabilities.ultracode]
|
|
15
20
|
command = "ultracode-for-codex"
|
|
21
|
+
install = "npm i -g ultracode-for-codex"
|
|
16
22
|
|
|
17
23
|
[hosts.codex]
|
|
18
24
|
models = ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"]
|
|
@@ -92,3 +98,20 @@ review_setup = "native-panel"
|
|
|
92
98
|
delegation = true
|
|
93
99
|
codex_execution_policy = "bypass"
|
|
94
100
|
claude_permission_mode = "bypassPermissions"
|
|
101
|
+
|
|
102
|
+
[presets.session-learning]
|
|
103
|
+
label = "Session learning"
|
|
104
|
+
description = "Dedicated learning-refinement session: mine recent sessions, verify, place, and apply per the session-learning workflow."
|
|
105
|
+
main_tier = "helm"
|
|
106
|
+
frontier_effort = "max"
|
|
107
|
+
review_setup = "hybrid"
|
|
108
|
+
delegation = true
|
|
109
|
+
codex_execution_policy = "bypass"
|
|
110
|
+
claude_permission_mode = "bypassPermissions"
|
|
111
|
+
mission = "This is a session-learning initiative session, gated on a trigger. When the user enters the trigger command '{trigger}': read the session-learning-workflow guide in your installed guides directory, then the initiative SSOT design/session-learning/HANDOFF.md in the agent-bios repo, and run the next mining window per that guide. Until the trigger arrives, respond normally and do not start the workflow. Every promotion passes through explicit user approval; nothing is applied to the corpus without it."
|
|
112
|
+
trigger = "learn!"
|
|
113
|
+
|
|
114
|
+
# Nudge baseline lives in ~/.local/share/agent-bios/session-learning-state.json,
|
|
115
|
+
# written by scripts/session-learning/update-state.py at window close.
|
|
116
|
+
[session_learning]
|
|
117
|
+
nudge_after = 250
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-bios",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A thin, low-level instruction layer for LLM CLI agents: one set of principles and behavior whichever model you run. Deploys into $HOME by copy via an explicit `agent-bios install`.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"agent-bios": "scripts/install.sh"
|
|
@@ -8,13 +8,17 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"claude/CLAUDE.md",
|
|
10
10
|
"claude/guides/",
|
|
11
|
+
"claude/hooks/",
|
|
12
|
+
"claude/agents/",
|
|
11
13
|
"codex/AGENTS.md",
|
|
12
14
|
"codex/guides/",
|
|
13
15
|
"codex/agents/",
|
|
16
|
+
"codex/config-additions.toml",
|
|
14
17
|
"config/agent-launch.toml",
|
|
15
18
|
"shell/agent-launch.zsh",
|
|
16
19
|
"scripts/agent-launch.py",
|
|
17
20
|
"scripts/check-parity.sh",
|
|
21
|
+
"scripts/check-prompting-targets.sh",
|
|
18
22
|
"scripts/codex-run.sh",
|
|
19
23
|
"scripts/codex-helm.sh",
|
|
20
24
|
"scripts/install.sh",
|
|
@@ -48,7 +52,7 @@
|
|
|
48
52
|
],
|
|
49
53
|
"repository": {
|
|
50
54
|
"type": "git",
|
|
51
|
-
"url": "git+https://github.com/kangminlee-maker/agent-
|
|
55
|
+
"url": "git+https://github.com/kangminlee-maker/agent-bios.git"
|
|
52
56
|
},
|
|
53
57
|
"license": "MIT"
|
|
54
58
|
}
|