agent-bios 0.9.8 → 0.10.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 +19 -19
- package/README.md +43 -12
- package/claude/CLAUDE.md +5 -41
- package/claude/guides/claude-prompting.md +1 -1
- package/claude/guides/cli-multi-model-workflow.md +22 -4
- package/claude/guides/coding-staged-workflow.md +49 -15
- package/claude/guides/concept-economy.md +187 -0
- package/claude/guides/documentation-hygiene.md +112 -0
- package/claude/guides/gpt-prompting.md +1 -1
- package/claude/guides/learning-flow.md +5 -5
- package/claude/guides/llm-capability-boundary.md +6 -1
- package/claude/guides/review-request.md +9 -7
- package/claude/guides/session-distill-workflow.md +19 -9
- package/claude/guides/tooling-gotchas.md +26 -0
- package/claude/guides/verification-discipline.md +166 -0
- package/claude/hooks/tooling-gotchas-hook.py +329 -12
- package/codex/AGENTS.md +5 -41
- package/codex/guides/claude-prompting.md +1 -1
- package/codex/guides/cli-multi-model-workflow.md +22 -4
- package/codex/guides/coding-staged-workflow.md +49 -15
- package/codex/guides/concept-economy.md +187 -0
- package/codex/guides/documentation-hygiene.md +112 -0
- package/codex/guides/gpt-prompting.md +1 -1
- package/codex/guides/learning-flow.md +5 -5
- package/codex/guides/llm-capability-boundary.md +6 -1
- package/codex/guides/review-request.md +9 -7
- package/codex/guides/session-distill-workflow.md +19 -9
- package/codex/guides/tooling-gotchas.md +26 -0
- package/codex/guides/verification-discipline.md +166 -0
- package/{scripts → compose}/assemble.py +194 -17
- package/{scripts → compose}/canary.sh +14 -5
- package/compose/check-domains.py +1178 -0
- package/{config → compose}/domains.json +11 -44
- package/{scripts → compose}/pkgid.py +8 -1
- package/compose/prune-backups.py +204 -0
- package/{scripts → compose}/register-hooks.py +3 -3
- package/install.sh +1233 -0
- package/launch/agent-launch.py +5294 -0
- package/launch/agent-launch.toml +376 -0
- package/{scripts → launch}/check-prompting-targets.sh +1 -1
- package/{scripts → launch}/provision-venv.sh +1 -1
- package/{scripts → learn}/check-learning.py +7 -7
- package/{scripts → learn}/collect-learning.py +10 -10
- package/{config → learn}/learning.schema.json +3 -3
- package/{scripts → learn}/migrate-learnings.py +95 -54
- package/{scripts → learn}/redact.py +4 -4
- package/package.json +32 -27
- package/provenance.json +1 -0
- package/wrappers/claude-run.sh +162 -0
- package/{scripts → wrappers}/codex-run.sh +62 -6
- package/config/agent-launch.toml +0 -143
- package/scripts/agent-launch.py +0 -2350
- package/scripts/check-domains.py +0 -296
- package/scripts/check-parity.sh +0 -2003
- package/scripts/install.sh +0 -819
- /package/{shell → launch}/agent-launch.zsh +0 -0
- /package/{config → learn}/promotions.json +0 -0
- /package/{scripts/session-cost.py → session-cost.py} +0 -0
- /package/{scripts → wrappers}/codex-helm.sh +0 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
guide_id: concept-economy
|
|
3
|
+
language: en
|
|
4
|
+
status: active
|
|
5
|
+
use_when:
|
|
6
|
+
- naming anything lasting or shared — a feature, entity, type, field, flag, enum value, failure kind, artifact, or documentation term
|
|
7
|
+
- a review finding or test failure tempts you to add a name to make it go away
|
|
8
|
+
- deciding whether a value is its own concept or a property of an existing one
|
|
9
|
+
- deciding what a public surface exposes versus where the truth actually lives
|
|
10
|
+
- laying out a repository, or judging whether its shape still matches its concept graph
|
|
11
|
+
core_rules:
|
|
12
|
+
- name the nearest existing concept before adding one, then choose reuse / extend / rename / split out loud
|
|
13
|
+
- every fix has a concept-surface sign — reducing, preserving, or increasing; say which before making it
|
|
14
|
+
- one value has one owner, and every other surface is generated from it rather than restated
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Concept Economy
|
|
18
|
+
|
|
19
|
+
A scoped extension of the global Concept Economy section. Use it when you are about to introduce
|
|
20
|
+
or change a name that will outlive the change that created it.
|
|
21
|
+
|
|
22
|
+
The cost this guide manages is not disk or tokens. It is the reader's working set: every distinct
|
|
23
|
+
name in a system is something a person or a model must hold, disambiguate, and keep aligned with
|
|
24
|
+
its siblings. Two names for one behavior is not redundancy — it is a standing invitation to edit
|
|
25
|
+
one and not the other, and that divergence is silent until something breaks in production.
|
|
26
|
+
|
|
27
|
+
## What Counts As A Concept
|
|
28
|
+
|
|
29
|
+
Anything **lasting or shared**. The list is deliberately long because the expensive additions are
|
|
30
|
+
rarely the ones that feel like architecture:
|
|
31
|
+
|
|
32
|
+
features, entities, variables, types, helper modules, artifacts, config keys, CLI flags, MCP/tool
|
|
33
|
+
fields, public response fields, artifact fields, enum values, failure kinds, retry/recovery
|
|
34
|
+
tokens, process names, documentation terms.
|
|
35
|
+
|
|
36
|
+
What is *not* a concept: transient locals, generic containers (`items`, `result`, `tmp`), and
|
|
37
|
+
layout a framework or tool imposes on you. The binding test is whether a second person has to
|
|
38
|
+
learn the name to work here. A loop variable never crosses that line; a new failure kind always
|
|
39
|
+
does, even when it is one string in one enum.
|
|
40
|
+
|
|
41
|
+
The trap is scale-blindness. A field added to a response is one line of diff and a permanent
|
|
42
|
+
addition to every consumer's mental model — including consumers you have not met.
|
|
43
|
+
|
|
44
|
+
## The Four Paths
|
|
45
|
+
|
|
46
|
+
Before adding or changing a concept, find the nearest existing one and choose a path **explicitly**.
|
|
47
|
+
Choosing silently is how near-duplicates arrive: nobody decided to add a second name, they just
|
|
48
|
+
did not look for the first.
|
|
49
|
+
|
|
50
|
+
| Path | Choose it when | What you owe |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| **Reuse** | an existing concept already covers this behavior | nothing — this is the default and needs no justification |
|
|
53
|
+
| **Extend** | the existing concept covers it once you add a property | the property, and a check that existing readers tolerate its absence |
|
|
54
|
+
| **Rename** | the behavior is right and the name has drifted from it | every site, in one change — a half-rename is strictly worse than either name |
|
|
55
|
+
| **Split** | one of the split triggers below actually fired | the parent named, the reason stated, aliases mapped back |
|
|
56
|
+
|
|
57
|
+
Prefer broad, stable concepts with precise properties over narrow near-duplicates. `Job` with a
|
|
58
|
+
`kind` property beats `ImportJob` / `ExportJob` / `CleanupJob` as long as they share a lifecycle;
|
|
59
|
+
the moment they stop sharing one, that is a split trigger, not a naming preference.
|
|
60
|
+
|
|
61
|
+
### Finding the nearest concept
|
|
62
|
+
|
|
63
|
+
The instruction to "find the nearest existing concept" fails when you search for the name you
|
|
64
|
+
already have in mind — the name you invented will not be there, and its absence reads as
|
|
65
|
+
permission. Search for the **behavior** instead:
|
|
66
|
+
|
|
67
|
+
- Grep the vocabulary the concept would produce, not the concept: the enum values, the failure
|
|
68
|
+
strings, the field names, the log messages.
|
|
69
|
+
- Read the nearest sibling's full definition, not its name. Names understate coverage; a type
|
|
70
|
+
called `Session` often already carries the lifecycle you were about to name separately.
|
|
71
|
+
- Ask what would have to be true for the existing concept to be wrong here. If you cannot state
|
|
72
|
+
it as a behavioral difference, you are adding a synonym.
|
|
73
|
+
- Check the terminology surface the repo already operates — a lexicon, a glossary, a domain
|
|
74
|
+
manifest — before the code. It is shorter and it is where the deliberate decisions live.
|
|
75
|
+
|
|
76
|
+
If that search returns nothing, the addition is probably real. Record what you searched, because
|
|
77
|
+
the next person will otherwise repeat it.
|
|
78
|
+
|
|
79
|
+
## When To Split
|
|
80
|
+
|
|
81
|
+
A split is warranted when the two things differ in something a caller can observe or must handle.
|
|
82
|
+
These are the triggers; anything else is a preference:
|
|
83
|
+
|
|
84
|
+
runtime behavior · ownership · lifecycle · validation · failure mode · user-visible behavior ·
|
|
85
|
+
audit/replay requirements · authority · persistence · user control · failure handling
|
|
86
|
+
|
|
87
|
+
Not triggers: a different call site, a different caller, a longer function, or a reviewer's
|
|
88
|
+
discomfort. Those are reasons to add a property, a parameter, or a comment.
|
|
89
|
+
|
|
90
|
+
When a split is necessary, three things ship with it or the split leaves debt:
|
|
91
|
+
|
|
92
|
+
1. **Name the parent.** The concept being split from, explicitly, in the change.
|
|
93
|
+
2. **State the reason.** Which trigger fired, in one sentence, where a maintainer will find it.
|
|
94
|
+
3. **Map the variants back.** Aliases, deprecated spellings, and old values resolve to the
|
|
95
|
+
canonical concept — otherwise the old name lives on as a second concept nobody declared.
|
|
96
|
+
|
|
97
|
+
## Derived Values Stay Derived
|
|
98
|
+
|
|
99
|
+
A value that tools or code can compute from its source is a **property or projection** of that
|
|
100
|
+
source, not a concept of its own. Persisting it creates a second authority that can disagree with
|
|
101
|
+
the first, and it will: the source moves and the copy does not.
|
|
102
|
+
|
|
103
|
+
The test is whether anything reads the stored value that could not have derived it. If the answer
|
|
104
|
+
is no, the value is a cache at best and a contradiction at worst.
|
|
105
|
+
|
|
106
|
+
**Authority is not visibility.** These are separate questions and conflating them produces both
|
|
107
|
+
failure modes at once:
|
|
108
|
+
|
|
109
|
+
| | Question | Wrong answer looks like |
|
|
110
|
+
| --- | --- | --- |
|
|
111
|
+
| Authority | where does the truth live, and who may change it | two writers, or a derived copy that outranks its source |
|
|
112
|
+
| Visibility | what may a given surface see | an internal projection leaked into a public contract, now unchangeable |
|
|
113
|
+
|
|
114
|
+
A public response may expose a bounded view — fewer fields, coarser precision, a rendered form —
|
|
115
|
+
while the source concept or artifact remains the one truth location. That is a projection, and it
|
|
116
|
+
is correct. What is not correct is treating the projection as the place to fix a wrong value.
|
|
117
|
+
|
|
118
|
+
Keep internal projections and helper outputs internal unless public exposure is genuinely required
|
|
119
|
+
by user behavior, a product contract, or artifact truth. An exposed field cannot be withdrawn on
|
|
120
|
+
your schedule.
|
|
121
|
+
|
|
122
|
+
## Reuse The Vocabulary Before Adding To It
|
|
123
|
+
|
|
124
|
+
Enum values, failure kinds, retry/recovery tokens, and result/failure surfaces are concepts with
|
|
125
|
+
unusually high blast radius: every consumer's branch coverage depends on the set being stable.
|
|
126
|
+
Adding a value obliges every exhaustive reader to handle it; adding a near-synonym obliges them to
|
|
127
|
+
handle it *and* to guess which one they will actually receive.
|
|
128
|
+
|
|
129
|
+
Check the existing set first, and prefer an existing value whose meaning genuinely covers the case
|
|
130
|
+
over a new one that describes it more precisely. Precision that fragments the set costs more than
|
|
131
|
+
it buys.
|
|
132
|
+
|
|
133
|
+
## Classifying A Fix
|
|
134
|
+
|
|
135
|
+
Before fixing a review finding or a test failure, say which way the fix moves the active concept
|
|
136
|
+
surface:
|
|
137
|
+
|
|
138
|
+
- **Reducing** — the fix removes a name, merges a duplicate, or deletes a branch. Cheapest, and
|
|
139
|
+
usually available when the finding is "these two do the same thing".
|
|
140
|
+
- **Preserving** — the fix changes behavior inside existing names. The normal case.
|
|
141
|
+
- **Increasing** — the fix adds a name. Legitimate, but it must survive the four-paths question,
|
|
142
|
+
and a review finding is not by itself a reason to add a concept.
|
|
143
|
+
|
|
144
|
+
This matters because review findings create pressure toward the increasing path: adding a flag, a
|
|
145
|
+
kind, or a special case makes a finding disappear locally while widening the surface everyone else
|
|
146
|
+
carries. Naming the direction before making the change is what keeps that trade deliberate.
|
|
147
|
+
|
|
148
|
+
## Migration Compatibility
|
|
149
|
+
|
|
150
|
+
**Use** fallback paths, compatibility shims, and deprecated alias normalization **when explicit
|
|
151
|
+
migration compatibility is required** — the obligation runs both ways: required compatibility gets
|
|
152
|
+
a shim, and nothing gets one as a default hedge. Each one is a second
|
|
153
|
+
concept surface that must be maintained and eventually removed.
|
|
154
|
+
|
|
155
|
+
When you add one, the removal condition ships with it: what has to be true for the shim to go, and
|
|
156
|
+
where that is recorded. A compatibility path with no stated end becomes permanent architecture by
|
|
157
|
+
attrition.
|
|
158
|
+
|
|
159
|
+
## Keeping The Shape Navigable
|
|
160
|
+
|
|
161
|
+
Let the repository's shape mirror its concept graph. A shared, lasting concept's canonical name
|
|
162
|
+
should be traceable across every layer it appears in — path, module, type/interface, field, public
|
|
163
|
+
API — so the structure is guessable from the concept name instead of from a translation table you
|
|
164
|
+
have to already know.
|
|
165
|
+
|
|
166
|
+
The working test: someone who knows the concept's name but not this repo should be able to guess
|
|
167
|
+
the path, or find it with one grep. If finding it requires knowing that the concept is called one
|
|
168
|
+
thing in the schema, another in the module, and a third in the URL, the layout has stopped being
|
|
169
|
+
navigable and the names are doing damage rather than work.
|
|
170
|
+
|
|
171
|
+
This binds shared concepts only. Transient locals, generic containers, and framework- or
|
|
172
|
+
tooling-imposed layout may diverge, and forcing them to conform is its own kind of waste.
|
|
173
|
+
|
|
174
|
+
## Domain Notes
|
|
175
|
+
|
|
176
|
+
- **Ontology work.** Check existing entities and relations first — before adding, modifying,
|
|
177
|
+
removing, or relinking either; the graph is the
|
|
178
|
+
artifact whose value degrades fastest under duplication, because every added node multiplies the
|
|
179
|
+
edges a reader must consider.
|
|
180
|
+
- **Code work.** Follow the naming patterns the repository already uses — the file first, then
|
|
181
|
+
its neighbors — and consolidate the variations
|
|
182
|
+
your own change introduced before calling it done. A change that leaves three spellings of one
|
|
183
|
+
idea has added two concepts regardless of intent.
|
|
184
|
+
- **Comments and active docs.** Keep them aligned with current runtime behavior, failure
|
|
185
|
+
semantics, retry policy, ownership, and authority. A comment describing a superseded contract is
|
|
186
|
+
not stale documentation — it is a second, false authority, and it reads as current to anyone who
|
|
187
|
+
finds it first.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
guide_id: documentation-hygiene
|
|
3
|
+
language: en
|
|
4
|
+
status: active
|
|
5
|
+
use_when:
|
|
6
|
+
- writing a comment, and deciding whether it earns its place
|
|
7
|
+
- recording why something changed, an alternative that was rejected, or a migration's rationale
|
|
8
|
+
- deciding whether an active document should link to a historical note
|
|
9
|
+
- authoring a rule, guideline, or instruction others will follow
|
|
10
|
+
- choosing where change history and implementation context belong
|
|
11
|
+
core_rules:
|
|
12
|
+
- prose about the past and prose about the present need different addresses, not different tenses
|
|
13
|
+
- a comment earns its place by carrying what the code cannot say about itself
|
|
14
|
+
- phrase a rule as the behavior you want, because a prohibition describes everything except what to do
|
|
15
|
+
- a continuously overwritten "current state" file claims to be now and is no particular time
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Documentation Hygiene
|
|
19
|
+
|
|
20
|
+
A scoped extension of the global Documentation Hygiene section. The subject is placement: **prose
|
|
21
|
+
about the past and prose about the present need different addresses.**
|
|
22
|
+
|
|
23
|
+
The cost this manages is misreading, not tidiness. A sentence describing how something used to
|
|
24
|
+
work, sitting beside code that works differently now, reads as a present fact — to a person
|
|
25
|
+
skimming and to a model retrieving. Nothing marks it as history except a tense, and a tense is not
|
|
26
|
+
a signal anyone checks. Moving it is cheaper than maintaining the reader's suspicion.
|
|
27
|
+
|
|
28
|
+
## The two addresses
|
|
29
|
+
|
|
30
|
+
**Active surfaces** — runtime code, comments, the docs someone reads to operate the thing — carry
|
|
31
|
+
current behavior, current decisions, current contracts, current authority, current failure
|
|
32
|
+
handling. Nothing else.
|
|
33
|
+
|
|
34
|
+
**Isolated paths** — `docs/`, `design/`, `archive/`, `deprecated/` or whatever the repository uses
|
|
35
|
+
— carry backward-compatibility notes, deprecated behavior, migration rationale, historical
|
|
36
|
+
alternatives, change narratives, and handoff logs.
|
|
37
|
+
|
|
38
|
+
The test for any sentence: *if this stopped being true, would anyone notice?* Active surfaces are
|
|
39
|
+
where the answer must be yes, because something breaks. History is where the answer is no, which
|
|
40
|
+
is exactly why it must not sit in the first place.
|
|
41
|
+
|
|
42
|
+
## Comments carry what the code cannot
|
|
43
|
+
|
|
44
|
+
A comment earns its place by saying something the code cannot say about itself:
|
|
45
|
+
|
|
46
|
+
- Non-obvious current behavior — why this looks wrong and is right.
|
|
47
|
+
- An invariant a reader could break without noticing they broke it.
|
|
48
|
+
- A constraint that comes from outside the file: a protocol, a rate limit, an ordering another
|
|
49
|
+
system depends on.
|
|
50
|
+
- A risk that still applies. Not one that used to.
|
|
51
|
+
|
|
52
|
+
What does not earn its place: restating the line below it, narrating the change that introduced it
|
|
53
|
+
("changed this to fix the bug"), or describing a contract that has since moved. That last one is
|
|
54
|
+
not stale documentation — it is a **second, false authority**, and to whoever reads it first it is
|
|
55
|
+
simply the answer.
|
|
56
|
+
|
|
57
|
+
Comments describing superseded behavior are the highest-yield deletion in most files. They are
|
|
58
|
+
also the hardest to find, because nothing fails when they are wrong.
|
|
59
|
+
|
|
60
|
+
## History has its own address
|
|
61
|
+
|
|
62
|
+
When you have something worth recording that is not current behavior — why an alternative was
|
|
63
|
+
rejected, what a migration was compensating for, what a session handed off — write it in an
|
|
64
|
+
isolated path rather than beside the code.
|
|
65
|
+
|
|
66
|
+
Two properties make such a record useful:
|
|
67
|
+
|
|
68
|
+
- **It is written once.** A record that is edited whenever things change stops describing any
|
|
69
|
+
particular moment. If it must be updated, the honest move is a new record that supersedes the
|
|
70
|
+
old one, not an overwrite.
|
|
71
|
+
- **It carries its own point in time.** A timestamp in the filename cannot rot, because the age is
|
|
72
|
+
on the label. A file called "current state" makes a claim it cannot keep.
|
|
73
|
+
|
|
74
|
+
That second point generalizes past records. Any continuously overwritten "the state of things"
|
|
75
|
+
document claims to be now and is, in practice, no particular time — the last person to touch it
|
|
76
|
+
decided how current it is, and nobody else can tell. Where the underlying facts are derivable,
|
|
77
|
+
give the reader the command that re-derives them instead of a number someone typed.
|
|
78
|
+
|
|
79
|
+
## Linking back
|
|
80
|
+
|
|
81
|
+
Link from active material to a historical note only when the current task needs that history, or
|
|
82
|
+
when the reference genuinely helps a future maintainer — usually because the present design looks
|
|
83
|
+
arbitrary without it.
|
|
84
|
+
|
|
85
|
+
A link is a small permanent cost: it invites the reader to leave, and it must stay resolvable. An
|
|
86
|
+
active document that links to five historical notes has partly become one.
|
|
87
|
+
|
|
88
|
+
## Writing rules people follow
|
|
89
|
+
|
|
90
|
+
Phrase a rule as the behavior you want, not as the thing you are afraid of. A prohibition
|
|
91
|
+
describes everything except what to do, and leaves the reader to invent the positive form —
|
|
92
|
+
usually at the moment they have the least attention to spare.
|
|
93
|
+
|
|
94
|
+
- "Pin the interpreter when a bash-specific feature is needed" beats "don't rely on the default
|
|
95
|
+
shell".
|
|
96
|
+
- "State the assumption you are proceeding under" beats "don't guess".
|
|
97
|
+
|
|
98
|
+
Two more properties of a rule that survives contact:
|
|
99
|
+
|
|
100
|
+
- **It says when it fires.** A rule with no trigger is advice, and advice is followed when
|
|
101
|
+
convenient.
|
|
102
|
+
- **It says what it costs.** A rule whose expense is hidden gets quietly dropped the first time
|
|
103
|
+
someone is in a hurry, and nobody records that it was dropped.
|
|
104
|
+
|
|
105
|
+
## Where change history belongs
|
|
106
|
+
|
|
107
|
+
Prefer the established homes over inventing one per change: a changelog for released behavior, a
|
|
108
|
+
current-state dashboard for architecture and risk, handoff notes for what a session left unfinished.
|
|
109
|
+
|
|
110
|
+
Keep their jobs distinct. A changelog that accumulates design rationale becomes unreadable as a
|
|
111
|
+
changelog; a dashboard that accumulates history stops being current. When a document starts
|
|
112
|
+
answering a question it was not built for, that is a signal to split it, not to add a section.
|
|
@@ -114,5 +114,5 @@ Derived from the vendor's published prompting guidance for the `targets` models
|
|
|
114
114
|
above. When a `targets` model changes, re-derive this guide from current vendor
|
|
115
115
|
guidance rather than editing around the old rules — prompting guidance is
|
|
116
116
|
version-bound, and the previous generation's advice inverted on this one.
|
|
117
|
-
`
|
|
117
|
+
`launch/check-prompting-targets.sh` fails when the launch config binds a model
|
|
118
118
|
this guide does not list.
|
|
@@ -18,9 +18,9 @@ The **light**, per-user, single-session capture flow: turn a lesson from the
|
|
|
18
18
|
current session into a **learning** (prose + a JSON record) that (a) applies to
|
|
19
19
|
the user's own next session and (b) reaches the org for curation. This is the
|
|
20
20
|
counterpart of the **heavy** session-distill pipeline (`distill!`), which mines
|
|
21
|
-
many sessions and is curator/power-user only.
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
many sessions and is curator/power-user only. Terminology and the full routing
|
|
22
|
+
framework are maintained in the agent-bios repo; the criteria this flow applies
|
|
23
|
+
are stated below.
|
|
24
24
|
|
|
25
25
|
Defer to the preset mission: if this session runs the **Session distill** preset
|
|
26
26
|
(trigger `distill!`), that mission owns capture — do not also run this flow.
|
|
@@ -62,7 +62,7 @@ still-valid candidates are surfaced for the user's approval.
|
|
|
62
62
|
|
|
63
63
|
## Domain tagging (the curation join key)
|
|
64
64
|
|
|
65
|
-
Suggest a `domain` from the registered vocabulary in `
|
|
65
|
+
Suggest a `domain` from the registered vocabulary in `compose/domains.json`
|
|
66
66
|
(domain keys for domain-specific lessons, or a tier name like `core`/`infra`
|
|
67
67
|
for a genuinely cross-cutting lesson); the user **confirms**. If unsure, use
|
|
68
68
|
`unclassified` (never blocks capture — the curator assigns later). If no
|
|
@@ -86,7 +86,7 @@ match your host):
|
|
|
86
86
|
| agent-bios learn --host <claude|codex>
|
|
87
87
|
|
|
88
88
|
The script (capability boundary) owns `learning_id` / `created` / `schema_version`,
|
|
89
|
-
validates against `
|
|
89
|
+
validates against `learn/learning.schema.json`, logs the JSON record, and writes
|
|
90
90
|
the lesson prose where THIS host loads it next session:
|
|
91
91
|
- **Claude**: appended to the automation-owned personal learnings file, pulled in
|
|
92
92
|
by the entry file's `@personal/learnings.md` import.
|
|
@@ -204,7 +204,12 @@ Use it per field or operation, not as a blanket replacement for LLM judgment.
|
|
|
204
204
|
Use this procedure when designing a new LLM-assisted artifact or revising an
|
|
205
205
|
existing one.
|
|
206
206
|
|
|
207
|
-
1. Identify the canonical artifact and downstream consumers.
|
|
207
|
+
1. Identify the canonical artifact and downstream consumers. When the consumer already
|
|
208
|
+
exists, read its **acceptance predicate**, not only its schema: the schema says which
|
|
209
|
+
fields may appear, and the predicate says which combinations are credited. A producer
|
|
210
|
+
designed against the schema alone can emit records that are valid and never
|
|
211
|
+
accepted — one record per event where the consumer judges one record per subject is
|
|
212
|
+
the common shape of this, and it survives every field-level check.
|
|
208
213
|
2. Split fields into semantic fields, deterministic fields, provenance fields,
|
|
209
214
|
and side-effect operations.
|
|
210
215
|
3. Assign each field or operation one primary authority.
|
|
@@ -26,10 +26,11 @@ verification_focus:
|
|
|
26
26
|
This guide is a scoped extension of the global Coding Guidelines. Use it when
|
|
27
27
|
composing what you ask a reviewer for — the request, the evidence bar, the
|
|
28
28
|
verdict shape. It does not cover when to review, how deep, or what counts as
|
|
29
|
-
material (the
|
|
30
|
-
which reviewer kind to route to
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
material (the severity ladder and review loop in `${CLAUDE_CONFIG_DIR:-$HOME/.claude}/guides/coding-staged-workflow.md` own that),
|
|
30
|
+
which reviewer kind to route to — the convergence heuristic in
|
|
31
|
+
`${CLAUDE_CONFIG_DIR:-$HOME/.claude}/guides/verification-discipline.md` owns that. Phrasing a prompt for a specific model
|
|
32
|
+
family is out of scope here; where that guidance ships, the rule that needs it
|
|
33
|
+
points at it.
|
|
33
34
|
|
|
34
35
|
The rules below are derived from ~330 real multi-lens review sessions run in
|
|
35
36
|
this environment. That corpus is one model family in practice, so nothing here
|
|
@@ -80,8 +81,9 @@ So state the floor in the request: **do not report a finding you would rate low.
|
|
|
80
81
|
It will be discarded; spend the effort on a medium-or-above finding instead.**
|
|
81
82
|
This is not a quality bar on the reviewer, it is a cost decision — the corpus
|
|
82
83
|
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
|
|
84
|
-
|
|
84
|
+
generate it first. (What counts as each severity is the ladder in
|
|
85
|
+
`${CLAUDE_CONFIG_DIR:-$HOME/.claude}/guides/coding-staged-workflow.md`, not
|
|
86
|
+
this guide's.)
|
|
85
87
|
|
|
86
88
|
## Forbid carry-forward findings
|
|
87
89
|
|
|
@@ -128,7 +130,7 @@ nicely: the submit schema refuses output without them. The result is a corpus
|
|
|
128
130
|
where reviewers are right about existence (0.3% of issues end unresolved after
|
|
129
131
|
argument) and where "found nothing" is a verified statement rather than silence.
|
|
130
132
|
|
|
131
|
-
This is the general
|
|
133
|
+
This is the general capability-boundary rule applied to review:
|
|
132
134
|
when output must have a property, make it unavailable without it. If your review
|
|
133
135
|
route has a schema, put the anchor there. If it does not, the demand belongs in
|
|
134
136
|
the request — but expect the weaker result that a request-only rule gives you.
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
guide_id: session-distill-workflow
|
|
3
3
|
language: en
|
|
4
4
|
status: active
|
|
5
|
+
audience: author
|
|
5
6
|
use_when:
|
|
6
7
|
- a session was launched with the Session distill preset (mission-injected)
|
|
7
8
|
- the launcher nudge says enough sessions accumulated for a mining window
|
|
8
9
|
- mining local Claude/Codex sessions for learnings absent from the corpus
|
|
9
10
|
- promoting, incubating, or retiring items in the session-distill ledger
|
|
10
11
|
core_rules:
|
|
11
|
-
- the ledger
|
|
12
|
+
- the ledger is the SSOT for state; read it before touching the pipeline
|
|
12
13
|
- placement follows PLACEMENT-FRAMEWORK.md, never ad-hoc judgment
|
|
13
14
|
- every promotion passes an explicit user-approval gate
|
|
14
15
|
- global growth per round is hard-capped (~500 tokens) by a measured gate
|
|
@@ -17,19 +18,28 @@ core_rules:
|
|
|
17
18
|
|
|
18
19
|
# Session-Distill Workflow
|
|
19
20
|
|
|
21
|
+
**Requires an agent-bios checkout.** This runbook edits the corpus itself, so it
|
|
22
|
+
names repo paths and runs repo scripts. On a packaged install those do not exist:
|
|
23
|
+
say so and stop rather than following steps you cannot execute.
|
|
24
|
+
|
|
20
25
|
Runbook for a session-distill run: mine recent main-context sessions,
|
|
21
26
|
verify candidates, place them through the framework, and apply with the user.
|
|
22
27
|
Everything durable lives in the agent-bios repo.
|
|
23
28
|
|
|
24
29
|
## Read first (SSOT)
|
|
25
30
|
|
|
26
|
-
1. `design/session-distill/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
1. `design/session-distill/ledger.json` — the initiative's state. Every item
|
|
32
|
+
carries its status (placed / incubating / incubating-G / absorbed /
|
|
33
|
+
adopted-no-text), strength, and provenance, so what is open, what was
|
|
34
|
+
promoted, and what is still incubating are all queries against this file.
|
|
35
|
+
Read state here and nowhere else: a count or a status written into prose is
|
|
36
|
+
correct on the day it is written and silently wrong afterwards.
|
|
37
|
+
2. `design/session-distill/versions.json` — which closed mining window maps to
|
|
38
|
+
which commit, and therefore what a rollback restores.
|
|
39
|
+
3. `design/session-distill/PLACEMENT-FRAMEWORK.md` — the placement authority
|
|
40
|
+
(typology A–G, layers, admission bars, lifecycle).
|
|
31
41
|
|
|
32
|
-
## Stage 1 — Mine (pipeline in `
|
|
42
|
+
## Stage 1 — Mine (pipeline in `session-distill/`)
|
|
33
43
|
|
|
34
44
|
Run in order; each stage reads the previous stage's `out/`:
|
|
35
45
|
|
|
@@ -73,7 +83,7 @@ Run in order; each stage reads the previous stage's `out/`:
|
|
|
73
83
|
stdout/stderr channel contracts) → codex/ + ko/ mirrors.
|
|
74
84
|
- Verify per layer, not just by diff: enforcement/gate fixture tests
|
|
75
85
|
(non-vacuous — known-bad must fire), hook trigger positive/negative sets,
|
|
76
|
-
`
|
|
86
|
+
`gates/check-parity.sh` exit 0 unpiped, prompting-target gate, then
|
|
77
87
|
`agent-bios install` to activate and re-verify.
|
|
78
88
|
|
|
79
89
|
## Stage 4 — G-pass (principles, not directives)
|
|
@@ -95,6 +105,6 @@ Run in order; each stage reads the previous stage's `out/`:
|
|
|
95
105
|
3. Register the corpus version: append {version = window end, commit = the
|
|
96
106
|
corpus-close commit} to `design/session-distill/versions.json` — this is
|
|
97
107
|
what the launcher's Versions & rollback screen offers — then run
|
|
98
|
-
`python3
|
|
108
|
+
`python3 session-distill/update-state.py --window-end <date>`
|
|
99
109
|
(nudge baseline) and `corpus-state.py project` (launcher status panel).
|
|
100
110
|
4. Merge the branch, push, and confirm deployed state (`agent-bios verify`).
|
|
@@ -62,6 +62,15 @@ depends on it, pin it explicitly instead of trusting the environment.
|
|
|
62
62
|
early-exit consumers (`cmd | head -1` → SIGPIPE 141), so it is a per-command
|
|
63
63
|
choice, not a global default. Does not apply when the final stage IS the
|
|
64
64
|
assertion (`cmd | grep -q pattern`).
|
|
65
|
+
- **Passthrough arguments in a CLI you author**: an option meant to carry
|
|
66
|
+
another command's own flags cannot use a greedy-but-dash-stopping arity —
|
|
67
|
+
Python's `nargs="+"` ends at the first token starting with `-`, so the
|
|
68
|
+
wrapped command's `--model x` lands on the next positional and the error
|
|
69
|
+
names a parameter the caller never mentioned. Use the parser's
|
|
70
|
+
everything-after form (`argparse.REMAINDER`). A bare `--` separator is a
|
|
71
|
+
second, separate trap: argparse consumes it as its own positional marker
|
|
72
|
+
before the remainder sees it, so the form every caller reaches for first is
|
|
73
|
+
the one that breaks — normalize it out of `argv` before parsing.
|
|
65
74
|
- **Reserved parameter names**: assigning to reserved shell names (`UID`,
|
|
66
75
|
`EUID`, `GID`, `PPID`) can invoke the bound system behavior instead of
|
|
67
76
|
storing a value — silently changing process credentials mid-script. Use
|
|
@@ -99,12 +108,29 @@ depends on it, pin it explicitly instead of trusting the environment.
|
|
|
99
108
|
|
|
100
109
|
## Git operations
|
|
101
110
|
|
|
111
|
+
- **A stale local base inflates the range**: before reasoning about what a branch
|
|
112
|
+
contains or opening a PR, `git fetch`, then ask against the remote rather than the
|
|
113
|
+
local tracking ref — `git log origin/<base>..HEAD` for which commits are yours, and
|
|
114
|
+
the merge-base form below for the diff. On a shared repo the local base lags until
|
|
115
|
+
you pull, so `<base>..HEAD` quietly folds in work that already merged. When a range
|
|
116
|
+
looks surprisingly large, suspect the base before the branch.
|
|
117
|
+
- **"Mergeable" is measured against the base, not against siblings**: the platform
|
|
118
|
+
flag says each PR merges into the base, and two PRs can both be clean while
|
|
119
|
+
conflicting with each other. Before choosing a merge order, diff their changed-file
|
|
120
|
+
sets and simulate the sequence.
|
|
102
121
|
- **Two-dot diff semantics**: `git diff A..B` is a direct snapshot
|
|
103
122
|
comparison — unlike `git log A..B` it excludes nothing, so a lagging
|
|
104
123
|
merge-base injects unrelated upstream changes into the diff. For PR/review
|
|
105
124
|
diffs use `git diff origin/base...HEAD` (merge-base form); suspect this
|
|
106
125
|
mechanism first when a diff looks too large or shows deletions in untouched
|
|
107
126
|
files.
|
|
127
|
+
- **Reverting a path is not undoing your edit**: `git checkout <path>` and
|
|
128
|
+
`git restore <path>` discard *every* uncommitted change in that file. Used
|
|
129
|
+
to remove a planted probe it also removes whatever else was in flight there,
|
|
130
|
+
and the loss is silent. Check `git diff <path>` first, or plant in a copy and
|
|
131
|
+
restore from that. The same asymmetry makes the restore step fragile: if the
|
|
132
|
+
probe can time out or abort, the restore must not be the next command in the
|
|
133
|
+
same invocation — put it where a failure cannot skip it.
|
|
108
134
|
- **Dirty-worktree pulls**: before pulling into a worktree with
|
|
109
135
|
staged/unstaged/untracked changes, fetch first and compare incoming paths
|
|
110
136
|
against every dirty path; on overlap or a non-fast-forward, stop and clear
|