2026-10-11 17:14 UTC

Backpass maintainer kunchenguid claims the released CLI converts coding-agent transcripts into token-budgeted memory and skill edits backed by session evidence and gated by human approval, potentially replacing manual instruction maintenance with a repeatable feedback loop.

state: seedheat: mediumuncertainty: mediumconvergesscott: mediumagent-memory agent-harnesses coding-agents memory-optimizationkunchenguid

What is this?

Backpass is an MIT-licensed CLI by Kun Chen (GitHub: kunchenguid), offered via `npx -y backpass`; the supplied repository metadata lists version 0.1.18. Its repository and author’s announcement describe reading local transcripts from seven coding-agent harnesses and proposing token-budgeted edits to instruction files such as AGENTS.md / CLAUDE.md and project skills, with verbatim evidence from at least two distinct sessions for each add, rewrite, or removal and human approval before writing. The author frames this as “gradient descent” for agent memory, but the snippets establish a proposed transcript-driven instruction-maintenance loop, not measured improvements or demonstrated replacement of manual maintenance.

Why it matters to Scott

Backpass’s released CLI operationalizes Scott’s Second-Order Learning and CLAUDE.md Pattern: mining recurring session evidence into concise, human-reviewed instructions, offering a concrete candidate to test alongside his Search Conversations archive and dev-wiki rather than merely another memory thesis. Its cross-session evidence requirement and token-bounded edits extend that workflow, but neither improved agent outcomes nor replacement of manual maintenance is established; the radar tracks adjacent Braindump and Memctl developments, not Backpass itself.
ip:concept.second-order-learningip:concept.claude-md-patternip:concept.fat-agents-md-anti-patterndev:project.search-conversationsdev:project.dev-wikiradar:braindump-pr-review-agent-rulesradar:memctl-versioned-agent-memoryradar:driftproof-skill-regression-testingradar:concept.agent-memory
queries asked of Scott's wikis
  • agent memory maintenance from session transcripts
  • AGENTS.md CLAUDE.md instruction optimization token budgets
  • coding harness feedback loops failure evidence
  • agent-maintained wikis provenance human approval
  • reusable skills extraction cross-session learning

Measured heat

now 0 pts/hpeak 0 pts/hcomments 0/hpeers p14momentum: steady2 platformsage 643h
points/hour across evidence · reading as of 2026-10-12 02:59:37.977291+11:00 · deterministic, not a model opinion

How the heat travelled

09-14 21:28 (minted)⭐ origin echo-reconstructedBackpass reads transcript stores from seven agent harnesses and proposes bounded edits to memory files and project skills; add, rewrite, and
kunchenguid on github (echo) · attributed from hn.story.49703919 · published time unknown
—
09-14 20:59first on hacker news · published · lag ?Backpass: Gradient descent for your agent memory
nkko
—
09-14 20:59amplified on hacker news 👑hn.story.49703919
nkko
peak 2 · 0 comments · 98% of case engagement
09-14 21:21our radar first saw it · lag ?discovery anchor: hn.story.49703919—
pace: p23 vs 1032 stories at the 336h mark (now 643h old) — ahead of aafp-commons-signed-agent-notebook (2.0x), behind agentgate-signed-agent-receipts (0.7x)

Evidence (2) — ⭐ canonical anchor

sourceobjectauthorscorecomments
🟧 hnBackpass: Gradient descent for your agent memory
Retrieved article excerpt

Open article · Retrieved 2026-09-14T21:22:05.401421+00:00

# backpass

[CI](https://github.com/kunchenguid/backpass/actions/workflows/ci.yml)
[Release](https://github.com/kunchenguid/backpass/actions/workflows/release-please.yml)
[npm](https://www.npmjs.com/package/backpass)
[Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-blue?style=flat-square)
[X](https://x.com/kunchenguid)
[Discord](https://discord.gg/Wsy2NpnZDu)

### Gradient descent for your agent memory.

Your `AGENTS.md` is a set of weights. Every agent session is a forward pass. The
transcript that session leaves on disk is the loss signal - and today nothing reads it.
The loop only closes when a human happens to remember a failure and edits the file by hand.

`backpass` closes it. It finds the agent sessions that actually ran in your repo, reads
what happened in them, and proposes evidence-backed edits to your memory surface - the
memory file and project skills - under a token budget, gated by you.

- **Local-first** - Reads the transcript stores of seven agent harnesses directly from disk,
  locally or over SSH to your own machines. No API, no upload; transcripts never leave your
  machines except into an agent you already authenticated, and obvious secrets are redacted
  before they do.
- **Evidence-gated** - Every proposed edit carries verbatim quotes from real sessions,
  and every `add`, `rewrite`, or `remove` edit needs evidence from at least two distinct
  sessions. Small, noisy, bounded steps - not a rewrite.
- **Human in the loop** - Analysis never writes. `backpass apply` is the only writing
  command, and it shows each edit with its evidence for you to accept or reject.

```
AGENTS.md / CLAUDE.md + skills (the weights)
  → agent session               (forward pass)
  → transcript on disk          (loss signal)
  → backpass: collect samples, distill, calculate loss, aggregate gradients
  → backpass: gradient descent  (diffs + skill extractions)
  → you accept or reject        (the human gate)
  → back to the weights
```

One run is one bounded gradient step.

## Quick Start

```
npm install -g backpass
# or run it without installing
npx backpass
```

Requires **Node >= 22.5** and [`acpx`](https://github.com/openclaw/acpx) on your PATH.

backpass has **no API keys of its own**. Every model call goes through acpx to a harness
you have already authenticated.

```
cd your-repo
backpass init      # write .backpassrc.json, exclude .backpass/ via .git/info/exclude
backpass           # collect samples → calculate loss → aggregate gradients → gradient descent (never writes)
backpass apply     # review each edit, accept or reject, then write
```

### User-level memory

A run is one scope. The default is the checkout you are in. `backpass --scope user`
trains the always-loaded user file and user-level skills from Claude Code and Codex
sessions across projects, and writes only those files. A project-scoped run never
writes a user-level file.

Canonical user memory is the first existing file in this order: `~/.agents/AGENTS.md`,
`$CLAUDE_CONFIG_DIR/CLAUDE.md` (default `~/.claude/CLAUDE.md`), and
`$CODEX_HOME/AGENTS.md` (default `~/.codex/AGENTS.md`). User-level skill extractions
default to `~/.agents/skills`, with a warning if Claude's active `skills` path is a
real directory rather than the usual symlink. See [Configuration](https://github.com/kunchenguid/backpass#configuration) for
using an existing harness-loaded directory instead.

In user scope every `add`, `rewrite`, or `remove` edit also clears `minGapProjects`
(default `1`): the distinct projects behind its own quotes, counted from the gap
clusters it cites and from the session-to-project map behind the instruction evidence
rows. `extract` and `move` edits remain exempt.

State lives in `$XDG_CONFIG_HOME/backpass/user/` (default
`~/.config/backpass/user/`) with mode 0700, isolated from every project's
`.backpass/`. User-scope evidence, ledgers, proposals, and apply surfaces stay in
that one directory.

Harness load paths, verified for v1:

- **Claude Code** loads `CLAUDE.md` from `CLAUDE_CONFIG_DIR` (default `~/.claude`)
  and inlines `@` imports, including `~/` and absolute paths. A CLAUDE.md containing
  only an import that resolves to the canonical user memory is a valid pointer, such
  as `@~/.agents/AGENTS.md` with the default paths.
- **Codex** loads `AGENTS.md` from `CODEX_HOME` (default `~/.codex`). It follows the
  AGENTS.md convention; `@` import is not assumed.

A target that resolves into a read-only store (nix, home-manager) is refused by name
rather than written. The whole path is resolved, so the link may be the file itself
(`<path> is a symlink to <real>, which is not writable; edit the source that generates it`) or a directory on the way to it (`<path> resolves to <real>, which is not writable; ...`). The test is whether the directory holding the resolved location can be
written; both messages name that resolved location, so you know which source to edit.

```
backpass init --scope user
backpass --scope user
backpass apply --scope user
```

### Your other machines

Sessions you ran on your own other machines can join the same corpus over SSH. Name the
hosts once in your personal config:

```
{
  "discovery": {
    "hosts": [
      "mac-home",
      {
        "host": "kunchen@nixos-home",
        "node": "/run/current-system/sw/bin/node",
        "env": { "CLAUDE_CONFIG_DIR": "~/.claude-work" },
        "harnesses": ["claude", "codex"]
      }
    ]
  }
}
```

`--host <dest>` adds one for a single run (repeatable), and `--host none` collects
locally only. Hosts are **personal configuration**: a `discovery.hosts` in a repo's
`.backpassrc.json` is refused by name, so a checked-in file can never point someone
else's backpass at a machine. The personal file is
`$XDG_CONFIG_HOME/backpass/config.json` (default `~/.config/backpass/config.json`).

An object entry may set an absolute remote `node` path, an optional `harnesses` subset,
a positive integer `connectTimeoutSeconds` (default `10`), and store relocation variables
under `env`. The allowed variables are `CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `HERMES_HOME`,
`PI_CODING_AGENT_DIR`, `PI_CODING_AGENT_SESSION_DIR`, `BB_DATA_DIR`, and
`BB_PI_BRIDGE_SESSION_DIR`.

backpass installs nothing on the remote. It runs your own `ssh` (with `BatchMode=yes`,
so a password prompt fails the host instead of hanging the run) and pipes a one-shot Node
program holding its own adapters into `node -` over there. That program lists the
sessions in the window, computes the filesystem and git facts about each session's cwd -
which is the only place those paths are real - and exits, removing its temp directory.
Association then runs here, with the same tiers, against those facts. Only the sessions
that are associated, sampled, and not already analyzed are fetched: the raw transcript
file for file-backed stores, so the analysis agent's raw-transcript escape hatch still
opens a real file, and the adapter's normalized events for SQLite stores. Fetched copies
are cached under the run's state directory (mode 0700) and pruned after 30 days unused;
`backpass status` lists them per host.

Remote tiers are the local ones with a lower ceiling. Nothing on another machine is
tier 1 ("this clone"); a live remote checkout sharing a git remote with this repo is
tier 1.5, a recorded remote is tier 2, and a dead path is tier 3. A session that exists
on two machines is kept once, local copy first. Evidence labels carry the host, so
cross-machine corroboration is visible in the apply surface.

Every host is fail-soft and named: an unreachable machine, a key that needs a prompt, an
unknown or changed host key, no Node, a Node below 22.5 (file-backed harnesses still
work, the SQLite ones are named as skipped), or a missing git each produce one row in
`backpass scan` and leave the rest of the run alone. Host keys are never auto-accepted
and `StrictHostKeyChecking=no` is never suggested. Windows remotes are out of scope.
`BACKPASS_SSH_BIN` overrides the ssh binary.

### One file instead of the whole surface

`--target` narrows a run to one configured memory file or one skill, named exactly: a
`memoryFiles` entry, or a skill's `name:`. Nothing else resolves - not a basename, a
directory, a path to a SKILL.md, or an existing file the config does not name - and an
unknown name fails, listing the valid ones, instead of falling back to the whole surface. A
configured file that contains only an `@` import is rejected rather than rewritten or silently
mapped to its import; the error names the imported memory file, which must itself be configured
to be targeted. A correctly named skill whose file backpass cannot write - one resolving into a
location nothing may write, or in project scope one resolving outside the repository - is refused
by name too: backpass loads and bills that skill, but a targeted run against it could only end in
a refused write.

```
backpass --target AGENTS.md          # this memory file; existing skills are read-only
backpass --target db                 # this skill only; the memory file and other skills are read-only
backpass --scope user --target db    # the same, against the user-level surface
```

A memory-file target may still extract a **new** skill (that is how the file shrinks). A
skill target writes only that `SKILL.md`, and its budget is still the whole always-loaded
surface: the memory file plus every description line, moved by the description-line delta
of the edit. Analysis, evidence, and state are those of the whole surface; only staging and
the proposal gate narrow. `--target` applies to the default run, `analyze`, `propose`, and
`apply`; on `apply` it is optional, but when supplied it must match the saved proposal's target.
It cannot be combined with
`--memory-file`, and a targeted run never bootstraps a missing memory file.

## How It Works

### 1. Collect samples - which sessions belong to this repo

backpass reads the local transcript stores of seven harnesses directly. No API, no upload.

| Harness | Store | Repo tie |
| --- | --- | --- |
| **claude** | `~/.claude/projects/<munged-cwd>/<uuid>.jsonl` | per-line `cwd` |
| **codex** | `~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl` | `cwd` + recorded `git.repository_url` |
| **pi** | standalone and BB-managed Pi JSONL stores | session-header `cwd` |
| **opencode** | `~/.local/share/opencode/opencode.db` (sqlite) | `session.directory` |
| **grok** | `~/.grok/sessions/<encoded-cwd>/<uuid>/` | `summary.json` `cwd` + `git_remotes` |
| **cursor CLI** | `~/.cursor/chats/<md5(cwd)>/<uuid>/` | `meta.json` `cwd` |
| **hermes** | `~/.hermes/state.db` (sqlite) | session cwd, with CLI prompt / ACP config fallbacks |

Claude collection covers `$CLAUDE_CONFIG_DIR/projects` alongside the default store, so a
relocated config dir does not hide its sessions. The variable is read from backpass's own
environment: if you reach that profile through an alias that only prefixes `claude`, set it
for the backpass run too (`CLAUDE_CONFIG_DIR=~/.claude-work backpass`, or export it).

Pi collection covers standalone sessions under `~/.pi/agent/sessions/` and BB-managed Pi
sessions under `~/.bb/pi-bridge-sessions/`. It also honors `PI_CODING_AGENT_DIR`,
`PI_CODING_AGENT_SESSION_DIR`, `BB_DATA_DIR`, and `BB_PI_BRIDGE_SESSION_DIR` when they are
set in backpass's environment. When roots overlap, backpass scans every applicable layout
and reads each JSONL file once.

Hermes collection includes CLI and ACP sessions only. Gateway, cron, and WhatsApp sessions
are excluded because their recorded cwd belongs to the shared gateway process, not a project.

Association runs in four tiers:

1. **Tier 1 - deterministic.** The session's cwd is (or sits inside) one of this repo's
   worktrees.
2. **Tier 1.5 - deterministic, sibling clone.** The cwd is a live local clone (or one of
   its worktrees) that shares a git remote with this repo. `git worktree list` only sees
   worktrees from one clone, and Claude records no remote, so without this tier a
nkko20
🟧 echo.github ⭐Backpass reads transcript stores from seven agent harnesses and proposes bounded edits to memory files and project skills; add, rewrite, andkunchenguid——

Interpretation history

Decision trace