Skip to main content

Module learn

Module learn 

Source
Expand description

The conscience’s live learning loop.

Capture (hooks, deterministic, 0 tokens): an engineer correction is a prompt that pushes back on what the drone just proposed (“no…”, “double check…”, “why do you…”), or a rejected tool call / plan whose rejection carries the engineer’s words. Each becomes a raw episode: the task, the drone’s proposal, the correction.

Generalise (borg learn, at session end, one model call per episode): the episode becomes a lesson (question + situations → consequence) or is merged into an existing lesson that expresses the same concern — the old wording is kept in history and support grows, so the library consolidates instead of piling up near-duplicates. Each lesson lists the engineers (git user.email) whose corrections it was learned from, its area (the kind of concern, for trust per engineer × area, trust.rs) and, when the correction contradicts a lesson it was shown, which lessons it supersedes; all from the same model call.

Outcomes (borg learn, 0 tokens): a merge into a lesson the conscience asked earlier in the same session, or a new lesson superseding one it asked, means asking did not prevent the correction; a correction siding with one side of a rendered disagreement corrects the other sides instead; see outcome.rs.

Vetoes (borg no, veto.rs): an engineer’s “no” is an episode of kind veto, asked with its own prompt (veto::OPENING), whose answer may also name an invariant. It is learned at the end of any session, not only its own (a terminal veto may name an ended session). A veto merged into a lesson an earlier veto made counts as veto_repeat; an invariant of a lesson placed in this store becomes a proposed constraint in the queen’s queue (veto::propose), never a constraint.

Modules§

regret
A regret: an earlier session’s decision whose lines a later session fixed (notes/regress.rs). borg learn asks about it as about a correction, one model call, with its own opening and sections: the lesson is a question to ask at the decision point (“Before in , has been considered?”). Reach, merging and superseding follow the correction prompt’s rules unchanged.

Structs§

AskFailed
The model call failed (quota, rate limit, not logged in, network, malformed answer): unlike a verdict of “not a lesson”, the episode stays waiting and a later borg learn retries it.
Episode
HeldRepo
The waiting episodes of one repo that borg learn holds in a store because the repo routes elsewhere now (held).
Known
What a store already holds, so an episode read again (the transcript sweep, session end, borg assimilate) is never appended twice. Read once, then grown with what is appended.
Lesson
A lesson as stored: the conscience’s Challenge plus provenance and consolidation state. Append-only: a merge writes a new version with the same id; readers keep the latest.
Step
One model verdict during a learn run, for a progress line: the episode’s place among those this run asks about (done of total), and what came of it.

Constants§

ANSWER
Episode::via of an answer to the agent’s own question, and its why in the usage statistics.
CORRECT
Episode::via of a correction the engineer recorded in a collective by name (borg correct --collective): placed there explicitly, so borg learn never holds it for its repo’s route (held).
EXCERPT_CHARS
The longest excerpt an episode keeps of a correction, a rejected tool call, and the task as the learn prompt shows it. Guard: bounds what one episode adds to the store and to its prompt (a pasted log would otherwise go in whole); a regret’s excerpts share it (regret.rs CAP).
PROPOSAL_CHARS
The end of the drone’s last proposal an episode keeps (hook.rs proposal). Guard: bounds one episode’s agent text.
SAME_MS
Two prompt episodes of one session this close together are the same correction. Method: a dedupe window; the live hook’s capture time and the transcript’s message time of one prompt differ by a second or two, two corrections of a session by far more. Episodes of a tool call are matched by their id and words instead (Known::holds).
TASK_CHARS
The session’s task an episode keeps (hook.rs capture_prompt): the prompt it started from. Guard: bounds the .task state file and each episode’s task (a pasted spec would otherwise go in whole); the learn prompt shows its first EXCERPT_CHARS.

Functions§

ask_claude
One structured call to the drone’s model (runner.rs picks claude, omp or opencode).
ask_model
The model call behind ask_claude, for any JSON schema: the structured answer and its cost in USD (None when the CLI reported none). BORG_LEARN_MODEL picks the model, runner::choose the CLI.
count_correction
A correction in the usage statistics: a rejected tool call, a pushback, an answer to the agent’s question (why ANSWER, rolled up apart from the corrections, stats.rs fold) or a regret, with a short excerpt.
denied
A refusal that carries no words (see DENIAL): the engineer’s reason is their next prompt.
engineer
The engineer working in cwd: their git user.email, empty when unknown.
generalise
Generalise one episode against the existing library (the merge targets: team and personal lessons, no tombstone): Ok(Some) a new lesson or a merged version of an existing one, Ok(None) not a lesson, Err no verdict. ask performs the model call (injectable for tests). A regret (regret.rs) gets its own prompt, the same verdict.
generalise_with
generalise, with the invariant a veto’s answer named (empty otherwise).
held
The episodes of the store home that borg learn holds under cfg, per repo: not learned, not skipped, not recorded here by name (CORRECT), of a repo that routes to another store (or off) now. They wait, never learned here, until they are moved where they belong (borg move <repo>). Reads this store and the config only.
home
is_correction
A prompt that pushes back on the drone’s last proposal (same heuristic as the offline miner).
learn_in
learn_pending on the store in home. With track, outcomes of asked lessons are recorded (outcome.rs): a merge into a lesson asked earlier in the episode’s session, and a lesson asked earlier that the new one supersedes, are asked_then_corrected (outcome::contradicted); at the end of session, and in every session idle for outcome::IDLE_MS at now, the other asked lessons are asked_not_corrected. So any run settles, not only the end hook’s; a session it skipped episodes of is not settled as idle. Only a “not a lesson” verdict is recorded as skipped: an episode whose model call failed stays waiting (and its session unsettled) for the next run, and after MAX_FAILURES failures in a row the run stops asking. Returns (new lessons, merges, episodes still waiting for a verdict).
learn_in_config
learn_in_reporting under an explicit collectives config: an episode whose repo routes to another store under cfg is held, never learned here (held).
learn_in_reporting
learn_in, calling report after every model call (the CLI prints it; the hooks pass a no-op).
learn_pending
borg learn [--session ID]: generalise every episode not yet folded into a lesson. --session is given when that session ended: its asked lessons and the placebos the judge never reached are then settled. Any run also settles sessions idle for a day, so a missing end hook does not bias the outcomes. Returns (new lessons, merges, episodes still waiting because the model gave no verdict).
learned_episodes
The episodes the store home has folded into a lesson, team or personal (tombstones included: they keep their episodes).
learning
False when BORG_LEARN=off (eval drones): nothing is captured or recorded.
lessons
The latest version of every lesson.
now_ms
print_step
A progress line on stderr: [12/104 · 18 s · ~28 min left] new lesson L…: <question>.
record_episode
Records the hook’s episode e in this session’s store (record_episode_locked).
record_episode_in
record_episode into store (the end-of-session job writes to the route’s store).
record_episode_locked
record_episode_in under the store’s episodes.jsonl lock (live.rs locked): a borg move of a repo’s evidence rewrites that file under the lock, and an append landing between its read and its rename would be lost. Contended only by those moves and the captures that also lock it; uncontended, one lock taken on a path that writes anyway.
record_new_in
Appends to store each of eps it does not hold yet (Known), each counted as record_episode_in counts it, and returns those appended, in order. ready completes an episode (its repo, its engineer) just before it is appended, so one already held costs nothing. The one entry for transcript capture (the transcript sweep, borg assimilate --apply).
regret_credit
False when BORG_REGRET_CREDIT=off: a regret no longer counts against the lessons asked before the decision (credit_regrets).
rejection
The engineer’s words from a rejected tool call or plan, if any.
schema_for
The answer schema for prompt: a veto’s prompt (it starts with veto::OPENING) gets the invariant field; correction and regret calls stay as they were.
store_lessons
The lessons of the store home as this engineer has them: lessons.jsonl with the store’s personal lessons (reach.rs PERSONAL_FILE) over it, a personal version winning over the team one of its id (the tombstone that withdrew it). For counts and “learned” (learned_episodes); borg status.
test_credit
Crediting a session’s own green test runs on (outcome::tested): learning is, and BORG_TEST_CREDIT is not off (an eval’s frozen arm).
transcript_id
The id of an episode read from a transcript: <session8>-T<call> for one about a tool call (the harness’s own id for it: Claude’s tool_use_id, omp’s toolCallId, opencode’s part id, Codex’s call_id), else <session8>-<ms> as the hook names a prompt’s. Content, never a position: a transcript still being written cannot shift it.