Releases: IngTian/witness
Release list
v0.5.1
Metadata-only patch release. No functional change from v0.5.0.
Why: the MCP Registry (schema 2025-12-11) verifies package ownership by requiring the referenced npm package to declare an mcpName field matching the server name. v0.5.0's @witness-ai/opencode lacked it, so mcp-publisher publish rejected it. npm versions are immutable, so the field ships via this patch.
Changes:
npm/opencode/package.json: add"mcpName": "io.github.IngTian/witness".- Version bump
0.5.0→0.5.1across npm packages, Claude plugin manifests, andserver.json.
Binaries below; npm packages published automatically via OIDC.
🤖 Generated with Claude Code
v0.5.0 — witness ingest (records-in engine) + install/wire split
witness becomes a generic records-in distillation engine — it now ingests your own records (notes, articles, any text stream), not just Claude Code / OpenCode chats — and the install surface is split so witness can be set up as a standalone library without wiring an editor.
Highlights
witness ingest— feed witness a documented NDJSON record contract (one JSON object per line, via stdin or--file) and it distills those records exactly like a coding session: observations → bi-temporal facets → a narrative profile, per lens, served over MCP. witness owns the format + protocol; you bring clean records (it parses no files itself).Dedup keys on your{"text": "...", "id": "stable-dedup-key", "session": "optional-group", "ts": "2026-07-26", "role": "document"}id(same id + unchanged → skip; same id + changed → update; new id → append), so re-ingesting is idempotent and never deletes records you didn't mention.tsis the temporal axis;sessionoptionally groups records mined together.fileplatform adapter — an ingested source distills through the unchanged engine;file:-namespaced sessions never collide with editor sessions.- install ≠ wire (breaking rename):
witness install [--path <dir>]now provisions an archive (no editor, no person-growth default lens — a blank engine you fill with your own lens);witness wire <claude|opencode>connects an editor (wasinstall <target>);witness unwire(wasuninstall). Run severalinstall --pathfor isolated archives (one per data source). - Contract documented + versioned in
prompts/SCHEMA.md— the public API a downstream tool builds against.
Breaking changes
witness install <claude|opencode>→witness wire <claude|opencode>;witness uninstall <target>→witness unwire <target>.witness installwith no target now provisions an archive.- Already-wired editors keep working — the installed hook contract (
capture/session-start/session-end) is unchanged; only the human-facing command names moved. Re-runwitness wire <target>(ormake install) if you want to re-wire.
Verification
Built via a fresh-subagent-per-task workflow with a final whole-branch review that caught + fixed a Critical incremental-append data-loss bug before release (dedup now uses true merge/append semantics). make fmt vet test + -race green; hook ABI byte-unchanged; zero distillation-engine changes; live end-to-end verified (a file: session mines observations under a domain lens on an isolated archive).
v0.4.0 — CLI surface diet: a ~6-verb front door, unified config, readable help
A CLI surface overhaul — witness's command surface is now organized around what a user actually does, with the engine's internal vocabulary moved off the front door. Breaking for anyone scripting the old commands (see below); the distillation engine and data are unchanged.
The new front door (~6 verbs, grouped)
READ profile · status
LENSES lens
CONFIG config
SETUP install · uninstall · doctor
MAINT export · cleanup
Highlights
witness status— one read for "is it working / what's captured / is it fresh" (replacesdistill status).- Unified
config— one scoped tree:witness config set <key> <value> [--lens <name>], canonical keysrunner/mine_model/review_modelat both scopes, andconfig listshows an origin view ((lens override)vsinherited from default, never blank) so per-lens overrides are legible.witness lens setis gone — it'sconfig set --lensnow. installis host-wiring only — it wires the editor integration + MCP; the runner default moves towitness config set runner <claude|opencode>.- Scannable
lens show— a compact card by default (dimensions, models, prompt excerpts);witness lens show <name> --promptsfor the full prompt text. - De-jargoned, grouped help — the L0/L1/L2 pipeline vocabulary no longer leaks into user-facing help/output;
witness --helpis sectioned. - The worker moved off the front door —
distill/revieware now the hiddenwitness worker run|stop|reviewoperator group (a normal user never needs them; the worker runs off editor hooks).importis hidden plumbing.
Breaking changes
witness distill status→witness status;witness distill start/--all/stop→witness worker run [--detach]/witness worker stop;witness review→witness worker review.witness lens set <name> …→witness config set <key> <value> --lens <name>.witness version→witness --version.- Installed editor hooks are unaffected — the hook contract (
capture/session-start/session-end) is unchanged, so existing installs keep capturing. Only the human-facing command names moved.
Verification
Built and reviewed via a fresh-subagent-per-task workflow with a final whole-branch review (which caught + fixed a command-name collision before release); make fmt vet test + -race green; hook ABI verified byte-unchanged; --json outputs undecorated; live smoke on an isolated archive. Zero engine changes.
v0.3.1 — install=mechanism · deletable auto-seeded default · unified backfill
CLI-surface cleanup (#102 / #103): the install and lens commands now follow a clean separation of concerns, and the built-in "default" lens is an ordinary, deletable lens rather than a special built-in.
Highlights
installis a pure mechanism. It wires the Claude Code hooks / OpenCode plugin + MCP server and binds the runner — and never prompts or seeds content. Safe to run as a hook subprocess and in CI.- The built-in "default" person-growth lens is auto-seeded once on the first time an archive is opened (a fresh personal install, or a pre-1a migration), and is fully deletable:
witness lens disable/deregister defaultsticks forever — it will not silently come back. Restore it any time withwitness lens load-default, or opt a fresh archive out entirely withWITNESS_NO_DEFAULT_LENS=1. installnow prints the enabled-lens set so you can see what will run (and cost an LLM call) on every session.lens rebuildis unified intolens backfill <name> [--fresh]. Backfill now always refreshes the lens's facets after re-mining (fixing a drift where facets could lag the re-mined observations).--fresh(the oldrebuild) drops the lens's observations + facets first, and is now guarded: it fails fast if a worker is running, asks for confirmation with exact counts (--yesto skip), and warns that in-session (hand-recorded) observations are not reproducible by a re-mine.- Docs/messages corrected for the "default is an ordinary lens" world (
profile/facetshelp + empty states).
Verification
make fmt vet test + -race green; npm checks 26/26; a full live end-to-end run (real LLM: capture → mine → observations → review → facets → profile) on an isolated archive; and an adversarial merge-gate review (correctness / best-practices / long-term-plan / UX) that came back GREEN with no blockers.
Upgrade is transparent for existing archives (the pre-1a default is migrated in automatically on first open).
v0.3.0 — per-lens tuning, cross-runtime distillation, architecture hardening
witness v0.3.0 — per-lens tuning, cross-runtime distillation, and a big architecture-hardening pass.
Highlights
Per-lens runner + model (#75)
A lens can now declare its own runtime and models in lens.json (runner, extract_model, review_model). So one drain can span both Claude and OpenCode — the always-on default lens rides your default runner while a rare heavy lens runs a stronger (or free) model on the other runtime, without paying for it on every session. A per-runtime circuit breaker isolates an outage on one runtime from the lenses on the other.
witness lens try (#72)
A read-only preview of a lens's prompts against your real sessions before you register or backfill it — previews both the EXTRACT (mining) and, with --review, the REVIEW (facet synthesis) pass. Writes nothing. This is the fast prompt-tuning loop.
Distillation quality + observability
- prose-drift detection (#68): a below-floor model that returns no observations no longer masquerades as a "quiet session" —
doctorand backfill surface it so you know to raise the model. - per-lens watermark (#66): a newly-enabled lens backfills over history independently, without re-mining every other lens.
- profile dirty-tracking (#84): an unchanged review regenerates 0 profiles instead of N+1 — reviews are cheaper.
Architecture hardening (#73)
Worker-liveness via a single flock authority (#76); runner resolution collapsed to one source of truth (#71/#83); hot-path progress indexes (#80); RenderTranscript moved to the platform leaf so runtimes don't depend on each other (#81); the "global"→"default" naming cleanup (#79).
Notable fix
- Review no longer inherits a heavy ambient model (#87): when
distill_modelis empty, the review/profile stage now falls back totriage_modelinstead of whatever model your interactiveclaudeis configured with. Previously, running the worker inside a Claude-Code-on-Bedrock shell could make the batched review stall on a frontier model even though you'd set a lighttriage_model. Set onetriage_modeland the whole pipeline stays light.
Known issue
- #16 — L2 review input is unbounded. The reviewer feeds all observations for a lens into one call, so on a large archive (~1,700+ observations for a single lens) the review can exceed the model's context window and fail. Bounded/generational review is planned. If you hit this, keep per-lens archives smaller or use a large-context model for review until it lands.
Install
- OpenCode:
@witness-ai/opencodeon npm (auto-publishes with this release). - Claude Code / standalone: grab the binary for your platform below (or the self-contained Windows zip), then
witness install <claude|opencode>.
Full changelog: v0.2.3...v0.3.0 (21 commits).
v0.2.4 — audit fixes: worker livelock, watermark CAS, hardening
Audit-hardening patch release. A comprehensive adversarial audit of v0.2.3 (#49) surfaced two latent-race CRITICALs and several hardening items; this release fixes all of the CRITICALs plus the cheap IMPORTANTs. All fixes were live-tested end-to-end on both runtimes (real claude -p + real opencode serve) and are test-locked.
Fixes
Critical
- Worker review-only livelock (#50) — a review-only worker that had new work land during the review would spin at 100% CPU holding the global worker lock forever, silently halting all distillation until a manual
distill stop. The drain loop now re-checks pending work on a fresh read each pass. Refs #49 (C1). - Watermark resurrection on a raw replace/delete mid-mine (#51) — when an OpenCode history rewrite (or
witness cleanup) deleted a session's raw rows while the worker was mining it, a blind watermark write could mark never-mined turns as done, silently leaving stale L1. The watermark write is now a compare-and-set keyed on the raw generation actually mined (MarkDistilledIfCurrent); it advances only if that generation still exists, else the session re-mines cleanly. Runtime-agnostic — free insurance on the append-only Claude path. Refs #49 (C2).
Hardening (#52)
review_every <= 0now clamps to the default instead of firing the reviewer on every session-end (I1).- Install hook-strip match is basename-exact + token instead of a loose substring that could strip an unrelated foreign hook merely containing "witness.sh" (I3).
/dist/added to.gitignoreso release-staging binaries can't be accidentally committed (I6).
Compatibility
No schema changes, no config-format changes. A drop-in upgrade from v0.2.3. Existing archives are used in place.
Artifacts
6 raw binaries (darwin/linux × amd64/arm64, .exe for Windows inside the zips), 2 self-contained Windows zips (exe + prompts + embedding model, ~295MB each), and SHA256SUMS.txt. The npm package @witness-ai/opencode@0.2.4 (+ the two platform packages) publishes automatically from this release via OIDC trusted publishing.
v0.2.3 — parallel mining · opencode idle-reconcile · discovery
Highlights
- Parallel mining + self-draining worker (#22). Distillation now mines many sessions at once (bounded map-reduce pool,
mine_concurrencydefault 4, capped at min(16, GOMAXPROCS)); a full-history backfill drops from ~28h → ~7h (Haiku, conc=4). Newwitness distill start --allforeground backfill. Removed the old 1 Hz wakeup cascade + respawn/debounce machinery — the worker now re-checks its own queue under the lock. OpenCode distillation is parallel too (narrowed the serve mutex). Adversarially reviewed twice (internal 3-lens audit + a maintainer PR review that caught 3 more real issues, all fixed). - OpenCode reconcile on
session.status=idle(#41, closes #33). Retires the dead event-driven capture path (the SQLite store is the only complete source of truth), makesCaptureran optional platform capability, adds targeted--sessionreconcile that doesn't advance the global watermark, single-flights imports in both plugins with graceful dispose, and resolves the DB viaXDG_DATA_HOME. Thanks @ChangeHow. - Agent discoverability + metadata fixes (#46). Corrected stale/wrong plugin & marketplace metadata (version, "pure tool" framing, global lenses), the MCP handshake now reports the real build version, and descriptions/keywords/README/
llms.txtseed the vocabulary an agent uses to find the tool.
Install
- Claude Code:
witness install claude· OpenCode:witness install opencode - npm (OpenCode):
@witness-ai/opencode@0.2.3 - Binaries below (darwin/linux amd64+arm64, Windows self-contained zips), verify with
SHA256SUMS.txt.
Single pure-Go binary, CGO_ENABLED=0. Windows Claude Code support is smoke-tested; OpenCode-on-Windows is not yet at parity.
v0.2.1 — module rename, export, npm auto-publish
Since v0.2.0. Small, non-breaking release; also the first to auto-publish the OpenCode npm plugin.
Changes
- feat(export):
witness export <path>— consistent single-file DB snapshot viaVACUUM INTO(#15). - feat(opencode): publishable
@witness-ai/opencodenpm package +witness.jsplugin rename with self-healing legacy cleanup (fixes the double-capture bug, #7 / #13). - chore: Go module + display strings
claude-witness→witness(repo/command name alignment; runtime-neutral) (#14). - ci: auto-publish
@witness-ai/opencodeto npm on release via OIDC trusted publishing — no stored token, provenance attested (#17).
Notes
- Binaries below are attached from
make build-all; the@witness-ai/opencodenpm package (which bundles them) publishes automatically from this release. - Data-dir adoption unchanged: existing archives under
claude-witness/are used in place; fresh installs usewitness/. - OpenCode-on-Windows remains unsupported (#10).
🤖 Generated with Claude Code
v0.2.0 — Windows (Claude Code) + hardening
Windows support (Claude Code) + OpenCode on macOS/Linux + reliability hardening.
Highlights since v0.1.0
- Windows — Claude Code (new).
witnessnow cross-compiles and runs on Windows (amd64 + arm64), andwitness install claudewires Claude Code natively: exec-form hooks pointing atwitness.exe(no shell/Git Bash needed), install into%LOCALAPPDATA%\witness, and user-PATH registration. Verified end-to-end on real Intel Windows. (#6, #9) - OpenCode (macOS/Linux). Full OpenCode runtime support — plugin + MCP + long-session distillation stability. (#3, #5)
- Self-healing data dir. The archive directory now adopts an existing install in place and only creates the new preferred name (
witness) on a fresh machine — the rename never orphans an existing archive. (#12)
Install
macOS / Linux — from a checkout:
./install.sh claude # or: opencodeWindows (Claude Code) — download witness-v0.2.0-windows-amd64.zip (Intel/AMD) or -arm64.zip, unzip to a witness\ folder, then from inside it:
.\witness.exe install claudeThe zip is self-contained (exe + prompt templates + the ~448 MB embedding model). Install copies everything into %LOCALAPPDATA%\witness and adds it to your PATH, so you can delete the download afterward.
Not yet supported
- OpenCode on Windows — the OpenCode plugin still relies on a shell shim; the native Windows path is designed but not built (tracked in #10). OpenCode works on macOS/Linux.
- Windows uninstall leaves the copied
%LOCALAPPDATA%\witnessfiles + PATH entry in place.
Notes
- Existing installs keep using
~/.local/share/claude-witness; fresh installs use~/.local/share/witness. Both are adopted automatically — no migration, no data loss. - Windows binaries are unsigned; SmartScreen may warn on first run ("More info → Run anyway").
Artifacts
- macOS/Linux: raw
witness-v0.2.0-<os>-<arch>binaries. - Windows: self-contained
witness-v0.2.0-windows-<arch>.zip(exe + prompts + model). SHA256SUMS.txtfor all of the above.
🤖 Generated with Claude Code
v0.1.0 — Claude Code
First tagged release of claude-witness — a Claude Code plugin that keeps a person-centric archive of how you think, work, and grow across sessions. This is a stable, end-to-end-verified cut of the Claude Code integration.
What's in this release
- Capture (L0) — every turn recorded verbatim from stable Claude Code hook fields (
UserPromptSubmit.prompt,Stop.last_assistant_message); no fragile transcript parsing. Append-only, never LLM-touched. - Distillation (L1/L2/L4) — a detached worker mines per-session observations, a periodic reviewer synthesizes them into bi-temporal facets, and profiles are regenerated on top. Runs on your existing Claude Code auth via
claude -p. - Local & self-contained — one pure-Go static binary (
CGO_ENABLED=0), local multilingual (EN + ZH) embeddings via GoMLX. No Python, no external services, no vector DB, no cloud key. - MCP server — agents read the profile on demand via
get_profile/get_facets/search_observations/record_observation/delete_observation. - Lenses — pluggable observation dimensions; ships with a
defaultlens and a lens-authoring guide. - Commands —
witness <doctor | profile | lens | cleanup | install | uninstall>.
Verified
gofmt, go vet, go test ./..., and make build-all (darwin/linux × amd64/arm64) all green at this commit.
Install
./install.sh # builds, fetches the embedding model (~448MB, once), wires hooks + MCPOr download a prebuilt binary below and run witness install. The embedding model is fetched separately on first run (not bundled in the binary).
Scope note
This release is the Claude Code integration. OpenCode support is in progress on a separate branch and is not part of v0.1.0.
Assets
Prebuilt binaries for darwin/linux × amd64/arm64, plus SHA256SUMS.txt. Verify with shasum -a 256 -c SHA256SUMS.txt.