kb_write
Persist coding insights as file, flow, or absence notes after real tasks; correct or retract notes that prove wrong. A reuse gate merges matches into existing notes to prevent duplicates.
Instructions
Save or correct NOTEBOOK notes after finishing real work here — you have the files in context, so no future agent is better placed to record what you learned. Write a file note (what a file is for), a flow note (how a task spans files), or an absence lesson (a confirmed "there is no X"). Pass specs (an ARRAY of specs) to write ALL your notes in ONE call — malformed notes are reported together instead of one hiding the rest, and the result ends with a coverage line naming any worked files still without a note; pass spec (a single object) for a one-off. Also the tool to FIX or RETRACT a note you used that proved wrong: op: "put" replaces; op: "retract" with target: {kind: "note"} removes the whole note (or target: {kind: "anchor"|"alias"|"facet"|"invariant"|"behavior"|"feature", key: "<value>"} removes one part).
TWO-PHASE reuse gate: a flow/lesson spec sent WITHOUT an id first searches the notebook for the same concept. If plausible matches exist, kb_write returns {status:"candidates", candidates:[...]} INSTEAD of writing — re-call with into: "<id>" to merge into an existing note, or is_new: true to declare a genuinely new one. This makes note identity reliable (matching, not guessing an exact title). File notes skip the gate (id derives from the path).
The spec shape: type ("file"|"flow"|"lesson", or sugar "file-hub"/"file-single"), title, summary, anchors ([{path, symbols?}] — the addresses the note is about, which drive freshness), plus type-specific fields (file: facets/character; flow: steps/verified; lesson: kind:"absence"/scope/body). Call with NO arguments to get the full spec guide.
REQUIRED for the note to be findable at all — file-single: identityAliases + anchors[].symbols; file-hub: identityAliases + facets[].symbol; flow: identityAliases + steps + verified; lesson: scope.terms. A note missing these is written but unreachable: identityAliases are the only STABLE search surface besides the exact title (incidentAliases are optional — symptom words for a write that describes one, replaced by the next such write, never required), and anchor symbols are the only channel that answers a query typed as an identifier.
This tool WRITES to the repo notebook; it never commits to git — publishing notes is a human-only step (coldstart kb commit).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| into | No | Phase-2 answer: merge this write into the existing note with this id (from a prior `candidates` response). | |
| spec | No | A single note spec (JSON object). Fields: type, title, summary, identityAliases (stable — unions forever), incidentAliases (this write's symptom words — replaced by the next write that changes summary/body, omit if this write isn't about an incident), anchors:[{path,symbols?}], and type-specific fields (facets/character for file; steps/verified for flow; kind/scope/body for lesson). REQUIRED for the note to be findable at all — file-single: identityAliases + anchors[].symbols; file-hub: identityAliases + facets[].symbol; flow: identityAliases + steps + verified; lesson: scope.terms. A note missing these is written but unreachable: identityAliases are the only STABLE search surface besides the exact title (incidentAliases are optional — symptom words for a write that describes one, replaced by the next such write, never required), and anchor symbols are the only channel that answers a query typed as an identifier. Omit `id` on a new flow/lesson to trigger the reuse gate. Use `specs` instead to write several notes at once. | |
| agent | No | Optional agent id (given in a capture prompt, alongside session). Selects THIS agent stream's durable worklist for the coverage line so a subagent does not clear the main agent's list. Defaults to "main". | |
| specs | No | The capture path: an ARRAY of note specs (each the same shape as `spec`), written in ONE call. Order flows before the file notes that reference them. Well-formed notes are written; malformed ones are reported together (not atomic — a bad note never silences a good one); the result ends with a coverage line naming any worked file still without a note. Prefer this over many single-`spec` calls. | |
| is_new | No | Phase-2 answer: declare this a genuinely new concept, bypassing the candidate matches from a prior `candidates` response. | |
| session | No | Optional session id (given in a capture prompt). Enables the flow-evidence check: a flow whose step files this session never actually read gets a warning. |