Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ impl/

**CLAUDE.md
**AGENT.md
# …except the repo's canonical agent guide at the root.
# …except the repo's canonical agent guide at the root, and the
# CLAUDE.md that loads it into Claude Code.
!/AGENT.md
!/CLAUDE.md
# Local planning workspace (Nimbalyst) — not product source
nimbalyst-local/

Expand Down
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@AGENTS.md
@docs/agent/ops.md
@docs/agent/dev.md
18 changes: 18 additions & 0 deletions docs/adr/adr-011-vault-brain-projection.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,21 @@ Consequences of the rule:
trailer on brain commits), and a rebase of the prototype branch onto
the todo work. Implementation is tracked in
`docs/todos/brain-projection-plan.md`.

## Update 2026-09-19: search reads the brain

`stack memory search` reads the brain, not the vault. The rule above
("search and todos read memory") left search blind to generated pages.
The diary is compiled from the diary room, so its text exists only in
the brain, and a diary question could not be answered by search. The
agent fell back to grep on its `vault/` mount, which is the brain.

| Reader | Tree | Reason |
|---|---|---|
| `stack memory search` | brain (vault before the first curator run) | brain holds every vault page plus the compiled pages |
| todos, writes | vault | read-your-writes stays a vault promise |

Cost: a page filed seconds ago is findable after the next mirror tick,
not at once. Read-your-writes is tested for todos only
(`tests/integration/test_demo_rig_e2e.py`), so no stated invariant changes.

13 changes: 13 additions & 0 deletions docs/adr/adr-012-nanobot-fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,16 @@ diff keeps growing.
* Where the fork lives. Arthur refers to reactivating an existing one; it is
not visible under `famstack-dev` or `arthware-dev` from this machine.
* Whether the vault tools move in or stay on the discovery seam.

## Update 2026-09-19

Two shims removed; history size is left to nanobot's own settings.

| Shim | Change | Reason |
|---|---|---|
| `lean_state` | removed; `state_log` keeps the debug log, opt-in (`AGENT_STATE_LOG=1`) | duplicated nanobot's microcompact, broke the prefix cache, and its "re-run" placeholders made the model repeat tool calls |
| `grep_tool` | removed; grep is literal again | ran a regex as a semantic query (lesson 7); the model retried the same grep |
| `compact_tools` | added; patches `agent.runner._COMPACTABLE_TOOLS` | nanobot's microcompact now also shortens old vault tool results |

`config.json` sets the primary preset's `context_window_tokens` to 32768, so nanobot's token
consolidation and history snip act at a size that keeps prefill short.
37 changes: 37 additions & 0 deletions docs/design/agent/agent-improvement-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -1276,3 +1276,40 @@ list_edit(op=add, items=["butter","eggs","flour"]) -> "added 3" in one
commit (was 3 calls, 3 commits). Full lifecycle correct: every item
kept, [x] preserved, clean commit trail. Rig now runs the production
transform, so this exercised the real store code.

## 2026-09-19 - Answer decay removed from lean_state

Failure: in a room with a long history, a vault question ran 11
iterations, sent the same grep 4 times, then replied with the placeholder
text `[earlier answer from grep({...}); re-run for the current value]`
instead of an answer.

Cause: commit 6b80a08 replaced each prior answer of a tool-using turn
with that placeholder. In a long room most assistant turns in the
context were placeholders, and the model copied the format.

| Rewrite | Role | Result |
|---|---|---|
| prior tool result -> `[prior result of ...]` | tool | kept, not copied |
| prior tool-turn answer -> `[earlier answer from ...]` | assistant | removed, copied into replies |

Trade-off: a prior answer that recites a list is in the context again.
The tool result behind it is still a pointer. Regression test:
`test_no_assistant_message_holds_a_placeholder`.

## 2026-09-19 - Context size left to nanobot

The shims that rewrote context worked against nanobot's own mechanisms.

| Item | Before | After |
|---|---|---|
| Prior tool results | `lean_state` placeholder, all of them, every turn | nanobot microcompact: 10 newest kept, older >= 500 chars omitted |
| Vault tool results | not compactable (names missing from `_COMPACTABLE_TOOLS`) | compactable (`compact_tools.py`) |
| Vault grep | semantic query via `grep_tool` | literal grep |
| `context_window_tokens` | 200000 (default; consolidation never ran) | 32768 (budget 23.5k, consolidation target 11.7k) |
| `llm-state.log` | every `build_messages` call | only with `AGENT_STATE_LOG=1` |

Why autocompact did not shrink the room: it keeps the last 8 messages,
extended back to the start of that turn. A turn with 11 tool calls has
24 messages, so the whole turn stayed.

Loading
Loading