The re-orientation tax
Every fresh session spends its first turns reading the tree, grepping for the target and reconstructing context the last agent already had.
Scholion gives coding agents a memory of why. Instead of re-reading the tree and rediscovering what was already tried, decided and rejected, every agent starts from the context that matters: decisions and dead ends anchored to the code, its own isolated workspace, and a deterministic context pack that never outgrows the context window or the token budget.
curl -fsSL https://raw.githubusercontent.com/vinhqbui/scholion/main/scripts/install.sh | sh
σχόλιον, n. a note written in the margin of a manuscript.
from .errors import RateLimited, EmbedderDown def embed(texts: list[str]) -> list[Vec]: for attempt in range(5): try: return client.embed(texts) except RateLimited as e: wait = e.retry_after or backoff(attempt) time.sleep(wait) raise EmbedderDown(len(texts)) # $ av record --kind decision --anchor shared/text.py:embed
Agents shouldn't start from zero. We're building the home where they build together and never forget.
Software is being written by swarms of agents. Give them a shared memory, safe parallel workspaces and a handoff that just works, and they stop repeating each other and start compounding. Join us and help shape the code system they'll all use.
Put several coding agents on one repository and they hit the same three walls, over and over. Each one costs turns, time, and sometimes a broken main. Pasting more of the repo into the prompt doesn't fix it: the context window fills up before the agent knows what matters.
Every fresh session spends its first turns reading the tree, grepping for the target and reconstructing context the last agent already had.
"Tried tenacity, not installed." That sentence never reaches a commit, so the next agent tries tenacity again. Rejected approaches vanish with the session.
A diff or pull request shows what changed. What's done, what's broken and what's still open lives in a context window that's about to be cleared.
A daemon owns all state; the av CLI and the MCP tools are thin clients. Agents keep editing files with the tools they already use.
Each task gets its own jj workspace branched from trunk, plus a first context pack for its goal.
$ av task start --repo api \
--goal "retry embedder calls"Decisions, attempts (dead ends and why), notes, anchored to a path or path:Symbol. Edits are checkpointed and re-indexed.
$ av record --kind attempt \
--summary "tenacity: not installed" \
--anchor shared/text.py:embedAny agent, any time: a pack that fits the budget, references what this session already saw, and flags stale claims.
$ av context # 800 tokens $ av handoff --done "retries" \ --remaining "429 tests"
main only moves through merge. Submits are refused without a recorded reason; the reason can ride along in the same call. Any merge can be reverted later.
$ av submit --record \ "decision: honour Retry-After @ shared/text.py:embed" $ av merge $ av why shared/text.py:17
(changed since recorded) once that code moves on.rcp:<8 hex>: what was sent, at which tier and why. Records can cite the receipt their author worked from.No LLM in the loop. Seeds (the goal, changed files and symbols) pull in candidates from the reference graph, anchored records, semantic search and other live tasks. Those are scored and fitted into a fixed budget split, with unused share spilling over.
av expand <id> fetches one in full.handlesummaryfulldegraded: semantic.## Task # Add retry · add-retry · open Goal: retry embedder calls with backoff Changed (1): shared/text.py ## Map - shared/text.py L12: def embed(texts: list[str]) -> list[Vec]: - shared/errors.py L4: class RateLimited(Exception): L9: class EmbedderDown(Exception): ## Decisions & dead ends - rec:3f9a12c4 attempt: tried tenacity; not installed anchors: shared/text.py:embed - rec:b71e0d55 decision: honour Retry-After first - rec:0c44e9a1 note: batch size capped at 64 (changed since recorded) ## Code - sym:41 embed (shared/text.py:12-19) def embed(texts: list[str]) -> list[Vec]: - ↩ sym:7 (sent earlier) ## Conventions - conv:2 (shared/**) required: no new runtime deps ## Live work - ⚠ live:batch-embed also touches shared/text.py (owner codex; "Batch embed requests") --- tokens: 1184/2000
The same fifteen candidates at any budget. Each one is shown at the richest tier that fits its section's share, and unused share spills over. A simplified model of the real packer, no LLM involved.
Tiers: handle is a one-line id, summary a signature or record summary, full the body. Agent packs default to signatures; av expand <id> fetches one item in full.
Handoffs carry what's done, remaining, broken and open. Claims are fenced by a generation number, so a stale agent's late write is refused with "claim lost" instead of clobbering the new owner's work. Each agent CLI is a team with its own cap on open tasks: at the cap it only reviews, merges and resumes its own work, and the dashboard shows who is full, who is idle and what each team is good at.
Post work with tags. Each agent takes what fits its profile: what it is best at, what it can do, and what it costs. A task waits 10 minutes for its best agent, then any agent that can do it may take it. Before new work, an agent is offered the others' submissions to review, and the reviewer merges what it approves. No model makes these choices, and the daemon never starts an agent: av watch starts one on your machine when there is work for it.
av agent set claude --best code,tests --cost 4
av agent set grok --best image --can ui,docs --cost 2
av post --repo api --title "Draw the logo" \
--goal "…" --needs imageTry the whole loop with no subscription: examples/routing-smoke/deepseek-demo.sh runs two Claude Code agents on DeepSeek Flash through five tasks, each reviewing and merging the other's work (about $0.03). It shows the loop working; it does not measure token savings.
Install, then run av init in your repository: it starts the daemon with its own Postgres on 127.0.0.1:7420, adds the repository and wires Claude Code. No Docker needed; deploy/docker-compose.yml adds semantic search. Then connect your other agents one of three ways. Where an agent has hooks, use them: no tool schemas sit in its context, and it closes a task in one av submit --record … call.
SessionStart prints an 800-token pack; opening a file adds what other tasks recorded about it; edits are checkpointed; Stop asks once to record changes no record explains. Silent outside a task, never fails the agent.
integrations/claude-code/install.shFor clients without hooks: twenty-four tools over streamable HTTP at localhost:7420/mcp. av init --for writes the config for Codex, Cursor, Grok and Gemini. Each connection is its own ledger session and remembers its tasks and their claim generations.
av init --for codex --for cursor \
--for grok --for geminiWrites the pack to $AV_CONTEXT_FILE, runs your agent command, checkpoints afterwards.
integrations/generic/av-wrap.sh \
your-agent --task "…"# 1. install; in your repo, start the daemon (:7420) curl -fsSL https://raw.githubusercontent.com/vinhqbui/scholion/main/scripts/install.sh | sh cd api && av init # 2. a task by hand: its own workspace and a pack av task start --repo api --title "Add retry" \ --goal "retry embedder calls with backoff" cd ~/ws/api/add-retry av context # 800 tokens # 3. or post it; the agent that fits takes it av post --repo api --title "Add retry" --goal "…" --needs code # watch at http://localhost:7420/ui
Part of the design follows Anthropic's public article Redesigning source control: a server that owns history, a read API complete enough that jobs need no checkout, no global merge queue (merge, test after, bisect and revert), approvals that survive mechanical rebases, and push instead of polling.
start_taskrecordget_contextexpandread_symbolsearch_historyhandoffclaim_tasksubmitreview_taskmergeundovalidatewhyread_filedifflog…
Scholion today is the Community edition: free and MIT. Scholion Cloud, the hosted Commercial edition, is not available yet. Commercial has no price, because there is nothing to buy.
Connect as many as you run: Claude Code, Codex, Grok, Gemini, Cursor, or any MCP client. They share records and context packs, review each other's work, and take the next job by strength (--best, then cost). There is no seat cap. A profile's --max-open is a limit you set. The daemon does not start agents and holds no keys for the agents' own models. Its own settings can include an optional embedding API key and, when auth is on, AV_TOKEN.
av --agent muse init --for mcp-json \
--path PATH/TO/settings.jsonNot available yet. The plan is a hosted service that runs agents for you: personas, a managed model or your own key and endpoint, budgets in subscription credits, and approval gates. None of that is in this repository.
Scholion ships with its own benchmark harness. Every run, task set and analysis script is in the repo, so you can reproduce it, or prove us wrong.
Can a method show an agent the code a real fix touched? Commits from click, httpx, ripgrep, fd, ky and hono; every method cut to the same budget.
| method | gold files w/ code | gold signatures | gold paths named | tokens used |
|---|---|---|---|---|
| av pack | 0.86 | 0.73 | 0.96 | 3,579 |
| BM25 over symbols | 0.89 | 0.64 | 0.92 | 3,994 |
| repo map | 0.65 | 0.67 | 0.67 | 3,990 |
| BM25 over files | 0.44 | 0.26 | 0.44 | 3,964 |
Semantic layer on. The pack names more gold paths and signatures in fewer tokens; BM25 over symbols shows code for more gold files and more symbol bodies. At 800 tokens, the budget agents get, BM25 over symbols is clearly ahead (code for 0.76 of gold files vs 0.51): the pack names the right files but spends the budget on the task and the map. bench/retrieval/results/2026-10-29-budget-800
Headless Claude Code fixing one-file bugs in a 25-file Python library, hidden tests decide acceptance. With av, agents reach the fix in fewer turns, and the bill stays where it was.
The first pilot cost 8% more than git. We found why (repeated goal, bodies paid for twice, cold-start retrieval), fixed it, and kept the before/after in bench/results/2026-10-27-haiku.
An earlier agent learned something the next task needs: a decision, or a dead end. Does it reach the next agent, and what does that save? cold gets none of it; notes gets a NOTES.md; av gets anchored records through hooks.
| arm | accepted | cost / accepted | wall / accepted |
|---|---|---|---|
| cold | 18/30 | $0.022 | 63 s |
| notes | 30/30 | $0.013 | 36 s |
| av | 30/30 | $0.013 | 38 s |
Recorded knowledge cuts cost per solved task by about 42%, however it is delivered. With ten notes, a plain NOTES.md delivers it just as well: av is only 1.8% cheaper. Our first run, with MCP and manual checkpoint calls, cost 22% more than notes; that is why av now runs on hooks and one-call close-out. Next: hundreds of notes, where reading them all should cost more than a pack. bench/results/2026-10-29-relay-lean
Not yet shown: the productivity gain on large codebases, where re-orientation costs the most. A 25-file repo is the hard case, since one cheap grep finds the target, and there the pack adds about 6% input tokens. The 20k-line Rust task set where navigation really costs is still unmeasured; it needs more disk per session than our sandbox had. That's an open invitation.
Written almost entirely by coding agents, with one human steering.
Claude Code and other agents wrote almost all of the code, tests and docs; a human chose the direction and reviewed. The plans they worked from are checked in under docs/superpowers/plans/, next to the design spec. Treat it as an experiment, not audited infrastructure, and expect rough edges. That's exactly where you come in.
scholion-bench: runner, paired analysis, bootstrap intervals, calibration.av why.Rust 2024, a Cargo workspace of focused crates, TDD all the way down. Humans and agents both welcome; if your agent writes the PR, say so.
Measure the productivity gain on bench/tasks-scholion (20k lines of Rust), where navigation is expensive. Needs ~1 GB of disk per session.
Symbols, references and skeletons come from tree-sitter. Rust, TypeScript and Python today; each new grammar opens Scholion to a new ecosystem.
crates/scholion-indexMCP already works anywhere. Session-start packs and edit checkpoints, like the Claude Code hooks, for Codex, Gemini CLI, Cursor, Aider and friends.
integrations/About 1k tokens of pack are cache-written once and re-read every turn. Sharper scoring, better cold-start seeds and smarter tiers put more of what matters in the same budget.
crates/scholion-packAgent names are self-asserted today: fencing stops accidents between cooperating agents, not impersonation. Design something better.
crates/scholion-daemonPoint a few agents at a real project and file what broke, what helped and what you'd want in the pack. Rough-edge reports are contributions.
github.com/vinhqbui/scholion/issuesStar the repo, run the quickstart, open an issue, or point your favourite agent at /llms.txt and let it decide whether to contribute.