Your agent's next step up. Every session picks up where you left off. Every turn goes higher.
One-line pitch. ascent-research is an incremental research workflow CLI for AI agents: point it at a topic / source tree / Obsidian vault, and it will keep researching across sessions — fetching, citing, diagramming, and accreting a durable wiki you can come back to tomorrow and pick up exactly where you stopped.
ascent-research new "tokio internals 2026" --slug tokio --preset tech
ascent-research add-local ~/tokio/tokio/src/runtime --glob '**/*.rs'
ascent-research loop tokio --provider claude --iterations 12
ascent-research finish tokio --open # coverage -> HTML -> audit
# (next day)
ascent-research resume tokio && ascent-research loop tokio --iterations 8Bookmark-ready: every session lives as plain files under
~/.actionbook/ascent-research/<slug>/, so Obsidian, VS Code, grep
and git all work.
A Claude Code or Codex conversation ends. The agent forgets everything. Next week you ask the same question — same search, same fetches, same half-formed understanding.
I built ascent-research because I want my AI agents to get smarter
over time, not reset every session. The on-disk session (session.md,
session.jsonl, wiki/, SCHEMA.md) is the agent's external long-term
memory — survives process death, carries across tool switches, inspectable
and editable by the human. Every loop run isn't "research this topic
from scratch"; it's "continue the research we were doing, check what's
unused from last time, append to the pages you've already written."
The agent-facing surface (actions like write_wiki_page,
append_wiki_page, digest_source) exists specifically so the agent can
accrete rather than overwrite. The infra-enforced rules
(smell test, preserve_diagram_refs, figure-rich contract) exist so this
long-term memory stays clean without human QA every turn.
Whether you use it standalone or as a skill inside a coding-agent instance, the pitch is the same: stop throwing away your agent's research work at the end of every conversation. Keep it on disk. Let the next turn stand on the last one's shoulders.
ascent-research is a CLI that calls an LLM provider (Claude via
cc-sdk, Codex via codex app-server, or fake for tests). Which
process hosts the agent decides the usage shape:
Run the CLI directly; it spawns the provider itself and drives the research loop end-to-end, no outer agent needed. Good for batch / CI / "I just want a report."
ascent-research new "tokio internals" --slug tokio
ascent-research add-local ~/tokio/tokio/src
ascent-research loop tokio --provider claude --iterations 12
ascent-research finish tokio --openDrop the bundled skill into your Claude Code / Codex config and the outer agent invokes the CLI per-turn as a tool. Good for interactive sessions where you want to mix research with coding / writing work in the same conversation, or want the outer agent to plan the workflow (decide what to ingest, when to query, when to synthesize).
ln -s "$PWD/skills/ascent-research" ~/.claude/skills/ascent-research
# Then in a Claude Code session: /skill:ascent-research
# Or just describe the task — "research tokio's scheduler via source" —
# the skill triggers automatically.Both modes share the same on-disk session format, so you can start a session in standalone mode and later resume it from inside a Claude Code / Codex instance, or vice versa.
- Third LLM provider: OpenCode Go ($10/mo subscription, OpenAI-
and Anthropic-compatible HTTP endpoints to DeepSeek / Kimi / GLM /
Qwen / MiniMax). Build with
--features provider-opencode-go, setOPENCODE_API_KEY+ASR_OPENCODE_MODEL, thenascent-research loop <slug> --provider opencode-go. - Useful when Claude Code Pro / ChatGPT Plus subscriptions are out of
reach (cost or payment-region constraints). All knobs are env-driven
(
ASR_OPENCODE_PROTOCOL,ASR_OPENCODE_TEMPERATURE,ASR_OPENCODE_MAX_TOKENS,ASR_OPENCODE_TIMEOUT_MS). - Also works as
ASR_BILINGUAL_PROVIDER=opencode-goforsynthesize --bilingualChinese translation. - CLI defaults unchanged —
--providerstill defaults tofake; opt in toopencode-goexplicitly. - Thanks to @Paul-Yuchao-Dong for raising the use case and contributing the initial design (PR #19).
See CHANGELOG.md for the full design rationale incl. what was
deliberately not adopted from the PR.
- x.com / twitter.com tweet capture works end-to-end through the V2
browser backend. v0.4.0's generic runcode JS returned ~160 bytes of
X's left-nav chrome only; 0.4.1 adds an
XTweetruncode flavor that waits forarticle[data-testid="tweet"](notnetworkidle), scrolls with snapshot-collect across virtualized DOM so the main tweet isn't unmounted out of the result, and reads up to 25 thread articles with image / video poster URLs inlined as markdown. - 3 new tech preset rules:
x-tweet-status,x-profile,x-search-live— explicit kinds forroutedebugging. - Bugfix in
md_parser::extract_http_links: markdown image syntaxis now correctly excluded from the cited-sources scan, so embedding pictures of cited tweets no longer tripssources_hallucinated.
Live impact (same URLs, before vs after):
| URL | 0.4.0 | 0.4.1 |
|---|---|---|
x.com/<user>/status/<id> (any) |
162 B chrome | 2-3 KB main tweet + thread + media |
See CHANGELOG.md for full notes and specs/x-com-tweet-runcode-flavor.spec.md
for the design (33 BDD scenarios, lint 100%).
- V2 Actionbook MCP backend is now the default for browser-rendered
fetches (Cloud Worker at
edge.actionbook.dev/mcp+ Chrome extension over WSS). SetACTIONBOOK_BACKEND=v1-clito keep the old local-CLI path — it's a permanent fallback, not slated for removal. - Catalog seed pre-fetch: every
add/batchfirst probes the V2 catalog and seeds matching actions into the session wiki, so the agent knows what's known about a site before navigating. - Composite source fetch: one rule can fan out into N parts
(e.g. postagent metadata + browser rendered) merged under
composite-v1; short-circuits on first part failure with a labelledcomposite_failed_partevent. - 3 new autoresearch actions for the loop:
actionbook_search,actionbook_manual,actionbook_run_code. - New flags on
add/batch:--frame-id,--run-code-args,--reseed,--actionbook-backend. - Default per-source timeout raised from 30 s → 90 s (V2 server's inner run-code budget is 60 s; extra 30 s covers edge overhead).
- Fixes: smell
www.↔ apex equivalence; CJK / UTF-8 docs now pass theadd-localtext detector; user--timeout > 60sis no longer silently truncated by the V2 server's hard cap.
See CHANGELOG.md for the full list and docs/rfc/v2-session-export-to-postagent.md
for the cross-tool RFC that didn't ship in this release.
Five properties — each validated end-to-end across four live research sessions (tokio internals, an Obsidian agent-SE series, a mixed online-plus-local AI coding agents comparison, and self-research on this repo):
Inherits the core loop architecture from
karpathy/autoresearch
and pi-autoresearch:
a fresh agent can resume any session from two files —
session.md (human-readable living doc) + session.jsonl
(append-only event log) — even after process death, context reset,
or a week of inactivity. Where the original autoresearch optimizes a
single scalar (training loss, bundle size, test speed) via
edit → benchmark → keep-or-revert, ascent-research generalizes
the same loop grammar to research:
plan → fetch → digest → write_section / write_wiki_page / write_diagram
producing a figure-rich report plus a durable cross-session wiki
instead of a single optimized number.
ascent-research resume <slug> picks up exactly where a prior turn
stopped. Wiki pages accrue via append_wiki_page — new findings
grow existing entity pages instead of overwriting them. Coverage
signals (sources_unused, diagrams_referenced, wiki_pages,
wiki_total_bytes) let each loop run know what's still open from
the previous turn, so it continues rather than restarts. One-shot
DR tools can't do this — when they finish, they're done.
add (HTTP via postagent) + add-local (file trees) + browser
fallback (via actionbook browser for JS-heavy pages) all flow
through the same smell-test → event-log → wiki → report path. A
single session can cite GitHub READMEs, arXiv papers, blog posts,
and your private Obsidian notes side-by-side in one wiki page's
sources list — the renderer doesn't care about URL scheme.
Narrative-only output is considered incomplete. The loop's system
prompt carries a non-negotiable FIGURE-RICH CONTRACT: target ≥ 1
hand-drawn SVG per numbered section, bidirectional rule that every
 markdown reference must have a matching
write_diagram action and vice versa, infra-level guarantee that
section overwrites never drop figures. Every SVG is inline
(no external assets, no screenshots) and the HTML report has a
clickable wiki TOC + EN/ZH bilingual toggle.
Agents can't "just summarize this for me." Every fetch runs through
a smell test at the CLI layer before the LLM sees it; rejections
become typed events. Overwrites preserve figures. Wiki writes are
append-safe. Coverage computes sources_hallucinated (URLs cited
but never fetched) as a report_ready blocker. Every error returns
a machine-readable code (NO_ACTIVE_SESSION, SMELL_REJECTED,
DIAGRAM_OUT_OF_BOUNDS, WIKI_EMPTY, …) so agents route recovery
deterministically without parsing prose.
git clone https://github.com/actionbook/ascent-research
cd ascent-research
# Full build (loop + Claude provider) — what live sessions need
cargo build -p ascent-research --release --features "autoresearch provider-claude provider-codex"
export PATH="$PWD/target/release:$PATH"
ascent-research --helpAlternative feature sets:
# Minimal — no autonomous loop, no LLM
cargo build -p ascent-research --release
# Loop with fake provider only (for scripted tests)
cargo build -p ascent-research --release --features autoresearch
# Loop with Codex instead of Claude
cargo build -p ascent-research --release --features "autoresearch provider-codex"Prereqs for online ingest: Rust stable (edition 2024),
postagent for HTTP API fetches,
and (for JS-heavy pages) the Actionbook Chrome extension — see below.
Neither is required if you only use add-local.
ascent-research picks between two actionbook backends based on
ACTIONBOOK_BACKEND (default v2-mcp):
| Env value | Path | What's needed |
|---|---|---|
v2-mcp (default) |
Cloud MCP at edge.actionbook.dev/mcp + Actionbook Chrome extension over WSS |
ACTIONBOOK_API_KEY (an ak_* token), Chrome extension installed & signed in |
v1-cli |
Local actionbook CLI subprocess (offline-capable fallback, permanently supported) |
The actionbook binary on PATH, and your Chrome profile reachable by it |
V2 setup:
- Install the Actionbook Cloud (v2) Chrome extension (v0.2.0-alpha.4
or later). Unpacked-load it from
chrome://extensions→ Load unpacked. - Sign in via the extension popup.
- Get an
ak_*token from actionbook.dev/dashboard/api-keys and export it:export ACTIONBOOK_API_KEY=ak_xxxxxxxxxxxxxxxx⚠️ Do not commit this token to git. Prefer.envrc+ direnv or a secret manager.ascent-researchnever echoes the token in error messages or logs.
Recommended: dedicated Chrome profile. V2 drives the page through
chrome.debugger, which Chromium will refuse to attach when other
extensions inject chrome-extension:// content frames into the target
page (most password managers, AI sidebars, translation extensions, and
DevTools extensions do this). Symptom: every browser fetch fails with
DEBUGGER_ATTACH_CONFLICT.
The cleanest fix is a dedicated Chrome profile that only has the Actionbook extension installed:
# macOS — launch a specific profile directly:
open -na "Google Chrome" --args --profile-directory="Profile 2"(Replace Profile 2 with the directory name shown at chrome://version
in your dedicated profile.)
Other V2 env vars:
| Env | Default | Purpose |
|---|---|---|
ACTIONBOOK_BACKEND |
v2-mcp |
v1-cli to revert to subprocess; unknown values are fatal |
ACTIONBOOK_MCP_ENDPOINT |
https://edge.actionbook.dev/mcp |
Point at staging or a local worker |
ACTIONBOOK_API_KEY |
— | ak_* token (required for v2-mcp) |
ACTIONBOOK_BIN |
actionbook |
V1 path only; ignored under v2-mcp |
ACTIONBOOK_BROWSER_SESSION |
— | V1: shared session name. V2: tab-handle prefix (lets multiple ascent instances share one Chrome without colliding) |
ACTIONBOOK_STDOUT_CAP |
16 MB | Cap on per-call response body (both backends) |
ascent-research new "state-space models 2026" --slug ssm --preset tech
ascent-research batch \
https://arxiv.org/abs/2111.00396 \
https://arxiv.org/abs/2312.00752 \
https://github.com/HazyResearch/state-spaces \
--concurrency 4
ascent-research loop ssm --provider claude --iterations 10
ascent-research finish ssm --bilingual --openPDF export is opt-in. The default backend is local and free: it uses an isolated headless Chromium when available, so the HTML stays on your machine and no paid API is required:
ascent-research synthesize ssm --bilingual --pdfThe local backend discovers Playwright Chromium first. If it is not installed,
run npx playwright install chromium or set ASR_PDF_CHROME_BIN to a known
safe browser binary. Desktop Google Chrome is not auto-launched by default; set
ASR_PDF_ALLOW_SYSTEM_CHROME=1 only if you explicitly want that fallback.
ascent-research new "axum internals" --slug axum --preset tech
ascent-research schema edit # set your "what to emphasize"
ascent-research add-local ~/axum/axum/src --glob '**/*.rs'
ascent-research loop axum --provider claude --iterations 12
ascent-research finish axum --openascent-research new "my agent-SE notes" --slug notes --preset tech
ascent-research add-local ~/vault/agent-notes --glob '**/*.md'
ascent-research loop notes --provider claude --iterations 10
ascent-research wiki query "what's my stance on code review for AI?" \
--save-as my-code-review-stancegithub-audit creates a deterministic evidence artifact first; the LLM only
interprets that artifact and any follow-up public context. It reports a
human-facing trust score, machine-facing risk score/band, confidence, reasons,
and evidence, not a hard “fake/real” verdict.
ascent-research github-audit dagster-io/dagster \
--depth timeline --sample 500 --out audit.json --html audit.html
ascent-research new "dagster-io/dagster GitHub trust audit" \
--slug dagster-trust --preset github-trust --tag fact-check
ascent-research add-local audit.json --slug dagster-trust
ascent-research loop dagster-trust --provider claude --iterations 8
ascent-research finish dagster-trust --openUse audit.html when the user needs the trust decision surface directly:
trust score, risk score, confidence, metric dashboard, reasons, and evidence
gaps. Use the research session only for contextual follow-up around that
deterministic score.
Full command reference, error-code triage, loop contracts, and scenario
playbooks: see skills/ascent-research/SKILL.md.
Each project is one directory under ~/.actionbook/ascent-research/<slug>/.
Everything is plain files — markdown, JSON lines, SVG, TOML — so your
editor / grep / git / Obsidian all work without a custom client.
| File | Purpose |
|---|---|
session.md |
Narrative — numbered sections, overview, aside. Report spine. |
session.jsonl |
Append-only event log. Sources, attempts, loop steps. Authoritative. |
SCHEMA.md |
User-editable session guidance. Loop re-reads each turn. |
wiki/*.md |
Persistent entity / concept / analysis pages with cross-links. |
diagrams/*.svg |
Hand-drawn figures inlined into the HTML report. |
raw/ |
Raw fetched content, one file per accepted source. |
report.html |
Rendered editorial output — wiki TOC, inline SVGs, optional bilingual toggle. |
report.pdf |
Optional local PDF export of report.html, created only by synthesize --pdf or --pdf-output. Defaults to isolated local Chromium. |
Override the root via ACTIONBOOK_RESEARCH_HOME=/some/path. Legacy
~/.actionbook/research/ is read as a fallback so sessions from
v0.2 keep working.
skills/ascent-research/SKILL.md is a bundled Claude Code / Codex skill
describing the full workflow with nine scenario playbooks, error-code
triage, and build-target matrix. Expose it on your global skill path:
ln -s "$PWD/skills/ascent-research" ~/.claude/skills/ascent-researchcargo test -p ascent-research # core suite
cargo test -p ascent-research --features autoresearch # + loop suite (fake provider)All integration tests use a FakeProvider replaying scripted JSON
turns, so the full suite never hits a real LLM and needs no network.
- Core 2-file resume loop inherited from karpathy/autoresearch
- Per-session wiki layer inspired by karpathy's LLM Wiki gist
- Widget / dashboard pattern borrowed from pi-autoresearch
- Previously named
research-rs(v0.1 / v0.2); renamed toascent-researchin v0.3 to foreground the incremental-research story
Apache-2.0.