Skip to content

feat(sessions): a weights checkpoint links the session that edited a model to the experiments that ran it - #36

Merged
jackulau merged 12 commits into
mainfrom
feat/weights-checkpoint
Nov 13, 2026
Merged

jackulau merged 12 commits into
mainfrom
feat/weights-checkpoint

Conversation

@jackulau

Copy link
Copy Markdown
Owner

What this does

A weights file's SHA-256 now joins the session that saved it with the experiments that ran it, and every surface shows the join the same way.

  • Record it. coding_sh.weights_checkpoint() (Python), weightsCheckpoint() (TypeScript) or an OpenTelemetry span or log named weights.checkpoint records the file a script saved its edited weights to. Both SDKs' tests check one shared fixture.
  • Find it. The session lists the hashes in stats.weightEdits.checkpoints, gets the weights:checkpoint tag, and --where 'weights.checkpoint:<hash or prefix*>' finds it on SQLite, Postgres and ClickHouse.
  • From the experiment. exp show and exp compare print an edits line under the weights line: the session that saved the file and what it changed. --json, MCP experiments_list and experiment_compare, and the viewer's /api/compare and /api/experiments/{id} carry the ids as weights.sessions.
  • From the session. coding.sh show prints an Experiments row per checkpoint an experiment ran. show --json, MCP session_get and /api/sessions/{id} carry checkpointExperiments.
  • Viewer. The weights stamp on the experiment and compare pages links the session; the session's header links each experiment as ran in <name>.
  • OTel out. The otlp sink and [serve.forward] send one weights.checkpoint span per event.
  • All weights hashes print at 12 hex characters (edit lines printed 8; that was never released).
  • Docs: a new "Compare an edited model with its base" section on the site's experiments page, the API reference, concepts, the evals guide and the changelog.

SESSION_FOLD_VERSION is 21 and the viewer's MODEL_VERSION is 3, so stored sessions are folded again.

Checked

On the final tree, locally:

  • packages/coding.sh: npm run check printed 6380 tests, 6371 pass, 0 fail, 9 skipped. npm run build passed.
  • packages/sdk: 120 of 120. store-postgres: 16 pass, 2 skipped (no live database). store-clickhouse: 16 pass, 1 skipped.
  • Python SDK with CODING_SH_SDK_REQUIRE_ALL=1: 136 tests OK. mypy --strict src: no issues.
  • npm run lint: clean. Site: build, 135 of 135 with a built dist, perf-budget: ok.

By hand on a throwaway store: the Python SDK, the TypeScript SDK and an OTLP span each recorded a checkpoint; sessions --where found each; exp compare, exp show, show, the MCP tools and the built coding.sh ui server returned the same ids as each other.

Tests only, not run by hand: OTLP out, live Postgres and ClickHouse filters, a real torch model.

Limits

  • A project-scoped read key gets a session without checkpointExperiments: experiments belong to no project.
  • show and session_get read the newest 200 experiments. One lookup took 18 ms on SQLite with 200 experiments of 100 runs each.
  • /api/experiments (the list) carries the stamp in metadata.weights and not the session ids; the list page does not show the stamp.
  • No weights.tensor: filter: tensor names are stored as a count only.

…ere finds it by its hash

A notification with payload.kind weights.checkpoint carries the SHA-256 of the saved
weights file (the value exp run --weights takes), and optionally the base file's and a note.

- stats.weightEdits.checkpoints lists the distinct hashes in arrival order, at most 16, and
  the session gets the weights:checkpoint tag. A session with a checkpoint and nothing else
  is still listed. SESSION_FOLD_VERSION is 21, so stored sessions are folded again.
- --where 'weights.checkpoint:<hash or prefix*>' in the SQLite index, the scan, and the
  Postgres and ClickHouse stores.
- show, the viewer and MCP session_get print 'checkpoint 58899f90572c ← 0496e5111097' from
  one formatter, and the Weight edits row names the checkpoints.
- Metadata capture keeps both hashes and drops the note.
…heckpoint span

- In: a span or a log record named weights.checkpoint with coding_sh.weights.sha256 (and
  .base_sha256, .note) is stored as the checkpoint event. Without a 64-hex sha256 it is not
  read as a checkpoint.
- Out: the otlp sink and [serve.forward] send one weights.checkpoint span per event. A
  session with a checkpoint and no edit carries no coding_sh.stats weight attributes.
- Metadata mode keeps the two file hashes, which join a session to an experiment, and drops
  the note. The forwarder passes the base hash only on a weights.checkpoint span.
…ights file a script saved

Both send one notification with payload.kind weights.checkpoint: the SHA-256 of the saved
file (the value exp run --weights takes), and optionally the base file's and a note.

- Same conventions as weights_edit() and weightsEdit(): true only when the event was
  queued, an invalid hash drops the event with one warning, a note that is not a string is
  dropped and the checkpoint still recorded, and nothing raises into the app.
- Hashes are sent in lowercase. In Python, base_sha256 and note are keyword-only.
- One fixture, checked by both SDKs' tests, holds the payload both must send. Each suite
  also sends an edit and a checkpoint to a real coding.sh serve and finds the session by
  the checkpoint's hash.
- The SDK reference generator leaves a bare * out of a Python function's heading and table.
…oduced a checkpoint

An experiment's --weights stamp and a session's weights.checkpoint event carry the same
SHA-256, so each side can now name the other.

- exp show and both sides of exp compare print one line per session that recorded the
  stamp, with that session's edits:
    edits    <session id>  2 edits, 2 tensors, 66,560 weights changed
  At most 5 sessions per hash, newest first.
- --json carries the ids as weights.sessions (exp compare, exp list, and a top-level
  weights object in exp show), and so do MCP experiments_list and experiment_compare.
- coding.sh show <session> adds an Experiments row for each checkpoint an experiment ran,
  and checkpointExperiments with --json.
- A stamp no session recorded prints as before. So does a store that cannot answer the
  lookup: nothing is added and nothing fails.
- A list with more stamps than one --where query holds (2,000 characters, about 30 hashes)
  is looked up 25 hashes at a time.
… and the viewer's Saved weights row is checked in a browser
…and the session links the experiments that ran it
… with where the session and experiment links appear
@jackulau
jackulau merged commit 94a9ccb into main Nov 13, 2026
29 checks passed
@jackulau
jackulau deleted the feat/weights-checkpoint branch November 13, 2026 02:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant