What's New for Soma
Agent-facing changelog: 'what NEW capabilities can I use, with just enough detail to use them.' Distinct from the technical CHANGELOG.md — this is action-oriented, dense, version-tagged, and tells YOU (the agent) which tools just landed and how to invoke them.
Read this when you wake up in a session that just ran soma update, or when starting fresh after a release. Each section is a version’s agent-actionable surface: NEW caps you can call, behavior changes you should know, bugs you can stop stepping around. Not the technical commit log — that’s CHANGELOG.md. This is the answer to “what can I do now that I couldn’t yesterday?”.
How to read this
Each version section follows the same shape:
- 🆕 New caps — agent-callable surfaces with one-line invocation hints. Format:
cap_name(args) → outcome. - 🔄 Behavior changes — defaults flipped, conventions shifted. What you did yesterday may now be wrong.
- 🐛 Bugs you can stop stepping around — known issues that are now closed.
- 📁 New files / locations — useful paths the runtime now writes/reads.
- 🧰 Workflows — new patterns worth muscle memory.
A [dev] tag = dev install only (build-excluded from soma-beta end-user tarball).
v0.42.1 — July 2026
🐛 Bugs you can stop stepping around
soma:browser.renderwithformat:'markdown'and noselectornow actually converts. It was silently readingdocument.body.innerText(plain rendered text, no HTML) instead ofouterHTML, so the converter had nothing to clean — every real-world call reportedformat:"markdown"while returning near-0% “reduction” and full page chrome. Fixed; verified live (89050 → 13215 chars, −85.2%, real content preserved, nav/footer gone). A page’s own in-content<header>/<nav>(an article’s title + breadcrumbs) also survives now instead of being stripped identically to global site chrome.- A
claude-cli/*role’smax-cost-usdbudget is now actually enforced. It read the wrong frontmatter key and had two separate falsy-zero bugs that silently turned an explicit0into “no cap.” If your role declares a real number, it’s held to it now — including a genuine0hard cap (never draw billed overage). Only applies todefault-model: claude-cli/*; every other backend (mistral/groq/cohere) still has no dollar-cost enforcement, onlymax-tool-calls.
📁 New files / locations
_boot.mdshows a last-session/last-reflection breadcrumb ({{last_session_ref}}/{{last_mlx_ref}}) on a fresh boot with no preload loaded — a pointer to what’s still on disk, not a summary. Zero-cost on a brand-new project with nomemory/history yet.
v0.42.0 — July 2026
🆕 New caps
soma:agent.claude — delegate through a FILE contract, no ARG_MAX ceiling
soma:agent.claude({task:'...', role?:'general', model?:'sonnet', maxBudgetUsd?:3})
→ runId + tmux session + contract/report/log paths
soma:agent.claude_harvest({runDir}) → the child's report, or not-finished
delegate passes the compiled prompt as a claude -p ARGUMENT, so a large role + task can exceed
ARG_MAX and fail. This writes the contract to a file and hands the child a tiny instruction to read it.
Always background (tmux). Use delegate normally; reach for this when the prompt is large, or when
delegate already failed on argument length. Poll claude_harvest rather than attaching to tmux.
🔄 Behavior changes
- Role frontmatter is parsed by real YAML now (Pi’s
parseFrontmatter). It is STRICT: an unquoted value containing": "becomes a mapping, and one containing" #"truncates at the comment. If a role errors or a value arrives half-length, quote it — 7 bundled roles needed exactly that. The previous hand-rolled parser accepted both and was silently masking them. context:in a role’s frontmatter actually stacks now. It shipped inert: the parser’s promotion allowlist omitted the key, so declared files rendered as"(none)". Declared muscles/docs now arrive as<context_file path=...>blocks. A child spawned from a session older than this change still gets the old compiler — reload for it to take effect.- The shipped harness asks you to cite only from files you have OPEN. Naming a doc as support asserts you read it this session; a routing table says which file owns a fact, never what the fact is.
🐛 Bugs you can stop stepping around
soma-dev sync dev/sync mainnow actually write STATE.md’s activity log (all writers were broken; on a default install none had ever appended a row) — and they assert the row arrived, not just exit 0.dist/.dev-syncedcarries provenance (branch@sha, version, piVersion, timestamp) instead of being a zero-byte flag;soma-dev switch statusprints it and states that the git ref describes the CHECKOUT, not the dist.
v0.41.2 — July 2026
Maintenance release. Nothing to try.
No user-facing change shipped in this one, and it is listed here only so the trail has no gap. The single code addition was an internal delegation backend whose capability was never registered — unreachable, so there was nothing a user could call. It became reachable in a later release and is documented there.
These notes were written retroactively: the release originally shipped with no narrative at all, because the changelog-promotion step matched on a heading format that had since changed, found nothing, and exited reporting success. Both the match and the silent success are fixed.
v0.41.1 — July 2026
🐛 Fixes
- Leanstral models no longer error when reasoning is on.
labs-leanstral-*were sending a reasoning flag the Mistral API rejects outright (400 code 3051); they now send the field the API actually expects. - The runtime no longer breaks after a Pi version bump. Syncing a bump that changed
package.jsonskipped reinstalling dependencies, so a newly-built runtime could run against the previous version’s modules and crash at boot. The sync now reinstalls before rebuilding.
v0.41.0 — July 2026
🆕 Delegation goes multi-model
Child roles are no longer pinned to a single Claude model. A role can declare a chain — an ordered list of models with a cost class — and delegation walks it, falling through to the next entry when one is unavailable. In practice that means a cheap model does the routine pass and a capable one is reached for only when the work needs it.
default-model: claude-cli/haiku
model-chain:
- id: claude-cli/haiku
class: cheap
- id: claude-cli/sonnet
class: coding
🔄 Behavior changes
- Child defaults moved to the free tier. New child templates no longer default to a paid model.
Existing roles that name their own
default-modelare unaffected. - Pi runtime 0.80.6 → 0.80.10.
🐛 Fixes
/bodystopped crying wolf. Unreferenced body files used to emit one warning each; they now collapse into a single line.- Large delegate prompts no longer fail on argument length. The compiled role prompt is written to a file instead of passed as a command-line argument, so prompt size no longer has a ceiling.
v0.40.0 — July 2026
🆕 You can see, and scope, which models are available
soma:agent.models → live catalog, honouring settings.json scoping
soma:extensions.search → search pi.dev packages
soma:extensions.show → inspect one before installing
soma install npm:<pkg> → install through Pi's own package manager
The delegate model catalog is now built at call time from the live registry rather than a hardcoded
list, so a provider you have configured shows up without a code change. {{enabled_models}} and
{{active_extensions}} are available as template variables, so a prompt can state what this install
actually has rather than what it assumed.
🔄 Behavior changes
- A budget guardrail on the system prompt —
systemPrompt.maxTokens. Compiling a prompt over the configured budget warns rather than failing, so a body grows lean by decision rather than by accident. Check yours withsoma:body.slots.
v0.39.0 — July 2026
🆕 New caps
soma:refdocs.* — external platform docs (BUNDLED)
soma:refdocs.find({query:'cloudflare'}) → {baseUrl, method, pageCount, pages}
soma:refdocs.tree({query:'react'}) → {pageCount, tree} (section-organized)
soma:refdocs.fetch({query:'cloudflare', topic:'durable objects'}) → {matches, pages: [{content}]}
soma:refdocs.download({query:'cloudflare', topic:'workers', depth:5}) → writes to .soma/refdocs/<name>/
Flags: output:'/path' (custom dir), output:false (inline JSON), all:true (full download)
Discovers docs via llms.txt convention (Cloudflare, Vercel, React, Mintlify, 25+ known domains).
Falls back to HTML scraping. Fetches pages as clean markdown via Accept: text/markdown.
Use BEFORE researching any third-party platform docs.
soma:cf-docs.* — Cloudflare docs (HUB, soma install soma-cf-docs)
soma:cf-docs.index({product:'workers'}) → {product, pages, count}
soma:cf-docs.read({url:'/containers/'}) → {title, url, content}
soma:cf-docs.query({product:'containers', topic:'outbound traffic'}) → {matches, pages}
CF-specific, no API key needed.
🔄 Behavior changes
- Pi runtime bumped to 0.80.6 —
maxthinking level available.showCacheMissNoticestoggle (complementary to our predictive cache TTL in the statusline). New extension hooks:agent_settled,before_provider_headers.pi config -lfor project-local config. - Freebuff harness uses JSON extraction — reads
chat-messages.jsoninstead of scrapingtmux capture-pane. Multi-paragraph + table responses now reliable. TUI parsing is fallback.
📁 New files / locations
.soma/refdocs/<name>/— auto-created byrefdocs.download, organized by section withindex.md~/.soma/agent/scripts/dev-only/soma-freebuff.{sh,py}— $0 AI model harness (6 free models)
🧰 Workflows
- $0 delegation: write spec → hand to freebuff (
~/.soma/agent/scripts/dev-only/soma-freebuff.sh ask) → gate → commit. Six free models. Same pattern assoma:agent.delegatebut costs nothing. - Pi bump TUI smoke: after bumping Pi, boot with a free model in tmux to catch import errors
and duplicate declarations that build+tests+sandbox miss.
soma --model opencode/deepseek-v4-flash-free
v0.38.0 — June 2026
🆕 New caps
soma:caselaw.* — Caselaw Researcher cap family.
🐛 Bugs you can stop stepping around
- Script subcommands get clean
userArgs, not injected argv. A subcommand no longer inherits arguments meant for the wrapper — if you passed flags and the script saw extra ones, that was this. - Browser-driving caps are serialized. Two browser caps in flight at once raced each other; they now queue. Symptom was an operation returning another call’s page.
v0.37.1 — June 2026
🐛 Bugs you can stop stepping around
- Exiting a session no longer garbles your shell. Two soma-driven exits left the
terminal in a bad state. If you were reflexively running
resetafter quitting — stop, it’s fixed.
v0.37.0 — June 2026
🔄 Behavior changes
- The system prompt split along a scaffold-vs-behavior line.
prompts/system-core.mdholds what is always true of Soma; your body files hold what is true of you. Why you care: editing your body no longer risks clobbering framework scaffolding, and core updates arrive without touching your files. - template-migration plumbing for
core_rules.mdand_protocol-template.md.
🆕 New caps
soma:browser.render — render a JS-heavy / SPA page in an ephemeral tab and return its text. Use when fetch returns an empty shell because the content is client-rendered.
v0.36.0 — June 2026
🔄 Behavior changes
- The always-loaded core was restructured and sharpened — shorter, and generally useful to every install rather than shaped by one workspace’s habits.
- The prompt now states the
.soma/layout rule and that.soma/commits itself. Two recurring confusions — “where does this file go?” and “do Igit add .soma?” — are answered in the prompt instead of being re-derived per session. You do not commit.soma/; it checkpoints itself. - Prompt refined from corpus mining of the two most-recurring anti-patterns across real sessions.
v0.35.0 — June 2026
🐛 Bugs you can stop stepping around
- Opus
Editmis-shape is coerced, not rejected. A crammed secondoldText2/newText2pair used to fail the whole edit; it is now folded into a normal edit. /inhaleno longer crashes the TUI. The error-sanitizer import is prepended and fails loud rather than silently producing a broken module.
🔄 Behavior changes
- Body templates lead with “ground before think.”
soul.mdandcore_rules.mdnow open with the discipline of checking an artifact before reasoning about it. headlessis documented as the reliable delegation mode. If background children were behaving unpredictably, this is the mode to use.
v0.34.0 — June 2026
🆕 New caps
soma:inbox.list({status?})→ list markdown-inbox letters (default unread;'all'for every status). Each entry shows the filename to act on.soma:inbox.read({file})→ mark a letterreadonce you’ve read it, so it stops surfacing at boot.soma:inbox.actioned({file})→ mark a letteractioned(read AND acted on — e.g. shipped the fix it reported).soma:inbox.archive({file})→ move a processed letter toinbox/_archive/.file= filename, slug, or unique partial; ambiguous refs list their candidates. Resolves the.soma/chain, so a parent-inbox letter is clearable from a child project.
🧰 Workflows
- Close the inbox loop. The
inbox-handlingmuscle always required marking letters read — now there’s a tool instead of hand-editing frontmatter. Read a letter →soma:inbox.read/.actioned/.archive. The boot summary now shows what’s actually pending instead of piling up.
🐛 Bugs you can stop stepping around
- Exhale no longer crashes in an uninitialized directory. Ending a session where the local
.soma/didn’t exist threwENOENTfromsaveProtocolStateand aborted the whole save — it now creates the directory first.
v0.27.2 — May 2026
The soma:seam.* family lands — archaeology caps for tracing concepts through your own writings.
🆕 New — shared preload lifecycle (cycle 29)
Preload state tracking across /exhale, /breathe, auto-rotation, and keepalive auto-exhale is now unified into a single shared state machine (extensions/_shared/preload-lifecycle.ts). Four states: UNREQUESTED → REQUESTED → SAVED → STALE. Three route caps for read/write/reset.
What changed:
/exhaleat high context (85%+) no longer causes the safety net to override and rotate immediately. The exhale handler signalsREQUESTED→ safety net defers.- Keepalive exhaustion no longer double-requests a preload if one is already in flight.
- Statusline’s
📝saved/📝staleindicator now reads from the same state as the breathe extension — no drift. - 7 local
letflags removed fromsoma-breathe.ts.
Route caps: preload:lifecycle, preload:transition, preload:reset, preload:noteToolCall.
Detail: .soma/cycles/audit-improve/29-preload-lifecycle/cycle.md
🆕 New caps
soma:seam.trace— walk a concept across docs + code + sessions + blog + kanban + soul-space. Use BEFORE raw grep for any “where did X come from?” question. args:{term, limit?:200}. Free tier.soma:seam.ancestors— trace a concept through vault agents + Pi sessions + Claude sessions, with agent attribution. Returns who-said-what-and-when across the lineage. Closure test:seam.ancestors "breathe"returnsZenith (openclaw-dev) — soma's daddy. args:{term, limit?:200}. PRO feature (wraps_pro/soma-seam.sh).soma:seam.timeline— chronological evolution of a concept. Optionaltagfilter. args:{tag?, limit?:300}. PRO.soma:seam.sessions— search.soma/memory/sessions/+ preloads +~/.pi/agent/sessions/JSONLs. args:{query, limit?:200}. Dev tree only.soma:seam.seeds— forward pointers (frontmatterseeds:field).{unplanted: true}for ones not yet referenced. args:{unplanted?:bool}. PRO.soma:seam.gaps— orphan documents (no inbound refs). Hygiene scan. No args. PRO.soma:seam.web— PERSISTENT — writes markdown trace to.soma/memory/webs/web-<term>-<date>.md. Becomes a memory artifact next-self can read without re-running. args:{term, output?:path}. PRO.soma:seam.stats— Pi JSONL session analytics: tool usage, errors, interrupts. args:{mode?, limit?:200}. Dev tree only.soma:docs.related— frontmatter graph walk from a file (forward + back refs viarelated:,seams:,seeds:). args:{file}. Dev tree only.soma:docs.impact— what docs/protocols/muscles reference this file? Run BEFORE renaming or deleting a doc. args:{file}. Dev tree only.
🧰 New workflow: reach for seam before grep
When the question shape is “where did X come from?” / “who said X?” / “when did X evolve?” — the seam family beats raw grep + find every time. PRO caps fail gracefully on free tier with a “PRO feature” message; dev-tree caps fail gracefully on user installs. Caps live in the route registry — zero cache cost at register-time.
Tier breakdown:
- Free tier (everyone):
seam.trace(wrapsamps/scripts/soma-trace.sh). - PRO tier (soma-beta tarball):
seam.ancestors,seam.timeline,seam.seeds,seam.gaps,seam.web. - Dev tree only (internal):
seam.sessions,seam.stats,docs.related,docs.impact.
📁 New files / locations
extensions/_shared/script-resolver.ts— shared helper for addons that wrap shell scripts. Path resolution + subprocess + graceful fallback messages.extensions/soma-addons/seam.ts— the new family..soma/memory/webs/— whereseam.webpersists trace artifacts.
Detail: .soma/releases/v0.27.x/plans/seam-addon-family.md.
v0.27.1 — May 2026
The “first end-to-end autonomous PR ship” patch. Cycles 16 + 17 land together: Sonnet’s long-context wall now triggers warn/exhale BEFORE the wall hits, /inhale no longer double-injects preload, and release-please becomes the canonical ship pipeline.
🆕 New caps & workflows
soma-dev delegate cycle <brief>— full implementation pipeline for any markdown brief (cycle.md, inbox/.md, plans/.md). Pipeline:intern(investigate, 80-call) →intern(build, 80-call) →verifier(25-call) →pr_author(30-call). Total ~215 tool calls / ~$2.50 per cycle. Outputs/tmp/soma-cycle-investigation.md,/tmp/soma-cycle-impl-summary.md,/tmp/soma-pr-description.md. Flags:--no-pr,--no-verify. Use this whenbuilder’s 25-call default is too small for a multi-step cycle./auto-breathe model-aware— NEW subcommand. The auto-breathe enum is now tri-state:off/global/model-aware.model-awarereadsctx.model.idand selects per-glob thresholds frombreathe.thresholdsmap. Default install shipsmodel-aware. Backward-compat: boolean still parses (true → “global”, false → “off”) via migrationbreathe-tri-state-v0.27.0.tokens_inputnow includes cache_read inrunDelegation()results. Previously reported only the uncached delta (showingtokens_input: 3for repeated calls with stable prefix). New fields:tokens_input_uncached+tokens_input_cachedfor transparency. Was NOT a delegation-degraded bug — was a metric-display bug. The model received the full prompt all along.route.provide("preload:wasInjected", ...)— new route cap exposing whethersession_start’s “new”/“resume” branch already injected the preload./inhalepost-await queries this and skips its own send if true. Available cycle-17+.
🔄 Behavior changes
- Sonnet thresholds: model-aware default for
*sonnet*iswarnRange [28,33] / exhaleRange [34,50]— fires BEFORE the empirical ~48% “extra usage required for long context” wall. Opus:[60,74] / [75,90]. Default fallback:[50,64] / [65,85]. If you’re on Sonnet and were used to 50/70 thresholds, you’ll see notifications much earlier now — by design. /inhaleno longer produces double preload in rotated sessions. Previously, every/inhaletriggered TWO preload-injection user messages ([Soma Boot — rotated session]fromsession_start+[Soma Inhale — Loading Preload]from/inhalepost-await). ~8K tokens duplicated per rotation, verified across 10 sessions. Now: single inject fromsession_start,/inhaleskips whenwasInjected=true. Print-mode safety preserved (whenctx.hasUI=false,/inhalefalls back to direct send).- Auto-breathe notify text changed:
🪵 Auto-breathe: rotating at N%→🪵 Preload requested at N% — rotating after agent writes it. Honest about the request-vs-rotation distinction. Other branch (preload-already-written, immediate.rotate-signal) keepsRotating — preload already written. soma-release-ship.shnow bumps.github/.release-please-manifest.jsonin lockstep withpackage.json. Without this, release-please’s view of “current version” stays stuck and the next push to dev files a confused PR (caught when v0.27.0 ship left manifest at 0.26.2 → release-please filed PR #18 “release 0.26.3” with conflicts everywhere).- Catch-block fallback in
/inhaleis race-safe: the previouscatch (err)block always sent the fallback preload regardless of state. Now checksroute.get("preload:wasInjected")— ifsession_startalready injected (rare race wherenewSession()throws AFTER emitting), catch suppresses its send.
🤖 Release flow now PR-driven (canonical)
PRIMARY (cycle-17, v0.27.1+): Push commits to dev with conventional-commit messages (feat:, fix:, chore:, etc.) → release-please GHA auto-files release PR with versioned CHANGELOG → review + amend the PR (move rich [Unreleased] narratives into [X.Y.Z] if release-please’s auto-bullets are too thin) → merge → build dist + publish draft GH release + npm publish + force-push main + rsync.
FALLBACK (high-stakes): soma-release-prepare.sh (10 checklog gates) → soma-release-ship.sh. Use for major bumps, breaking changes, or mid-flight rescues. Both flows now bump the manifest in lockstep.
🐛 Bugs you can stop stepping around
pr-check.ymlsilent test-failure — GHA’sbash -e {0}shell exited the test loop on the first failing test BEFORE logging which one. Now usesset +einside the loop + captures failed names + logs them at the end.- In-flight detection robustness — 4 tests had brittle
chore(release): vX.Y.Zregex that broke on release-please’schore(dev): release X.Y.Zformat AND on amendment commits. Switched to NO-TAG-YET detection (if package.json bumped to vX.Y.Z but no git tag v$PKG_VERSION exists, we're in-flight). Robust against ALL release-commit shapes. test-preload-notify-state-machineruntime-mirror gate failed on CI runners (no~/.soma/agentinstall dir). Now skips onCI=trueOR when install dir absent.- Release-please
Summarizestep bash-escape — the PR JSON output contains parens (v0.27.0...v0.27.1) which brokeecho "... ${{ steps.release.outputs.pr }}"interpolation. Moved interpolation to env block.
📁 New files / locations
.soma/cycles/audit-improve/16-model-aware-breathe-collapse/cycle.md— full plan for tri-state + per-model thresholds..soma/cycles/audit-improve/17-rotation-mechanism-repair/cycle.md— 5-bug rotation-mechanism audit + fixes.migrations/phases/v0.26.2-to-v0.27.0.md— the breathe-tri-state migration journal.- 5 new test files:
test-breathe-tri-state.sh,test-breathe-migration.sh,test-breathe-model-thresholds.sh,test-breathe-warn-range.sh,test-breathe-exhale-once.sh. 81 new test cases covering the tri-state + per-model paths.
🧠 Architecture notes worth knowing
{{skills_block}}is a transplant, not a duplicate.core/body.ts:775extracts<available_skills>...</available_skills>from Pi’s compiled prompt, then re-injects it into soma’s templated prompt via the{{skills_block}}slot. Soma’s compiled output FULLY REPLACES Pi’s prompt (when Pi’s is the default-shape — the normal case), so the slot is the ONLY copy of the skills XML in the final prompt. Removing the slot from_mind.mdwould lose skills entirely. (The earliermuscle_digestsremoval was different: muscle_digests was rendered by soma + ALSO injected by Pi compiler-prepend — a true double. Skills are not.)- Auto-rotation Path A (
.rotate-signal+ process re-exec) is canonical. Per Pi types (pi-coding-agent/dist/core/extensions/types.d.ts),newSessionlives onExtensionCommandContext, not on the baseExtensionContextevent handlers receive. The route cap"session:new"is therefore only registered when a user explicitly invokes/breathe//inhale//auto-breathe(provideCommandCapabilitiesruns from those handlers). Auto-breathe’sperformRotationfalling back to.rotate-signal(Path A) is correct by design — Pi treats process re-exec as the safer auto-path. In-process Path B is a happy-path optimization available only after a command was invoked.
v0.27.0 — May 2026
The “autonomous CI/PR pipeline” minor. Three layers ship together: nightly tests + auto-issue-filing + delegate-driven fix orchestration.
🆕 New caps & workflows
soma-dev delegate <workflow>— multi-agent orchestrator. Workflows:pr(full PR pipeline),pr-brief(brief only),ci-fix <url>(issue → fix → verify),changelog(rich CHANGELOG),doc-update,audit [tickets...]. Composeschangelog_curator + pr_author + doc_writer + verifier(orissue_investigator + builder + verifierfor ci-fix).dev:issue.{create,list}— GitHub issues from inside soma sessions.createfiles structured nightly-failure issues with dedupe gate (skip if open issue exists for same failure).soma-dev check-phases— 30-second pre-release gate (upstream sync + tests + tsc) before the full 5-minsoma-release-prepare.sh.soma-pr-brief.sh— generates structured PR brief (git-cliff CHANGELOG diff, affected files, semver bump type, docs to update, roadmap suggestion). Used as input to delegate workflows.{{pi_gap}}body var — readsPI_UPSTREAM.mdat session start, injects live Pi version-gap into the system prompt. Updated by 6h GitHub Actions monitor.- 3 new child role bodies —
pr_author(rich PR descriptions),issue_investigator(root-cause tracer for nightly failures),changelog_curator(rich[Unreleased]narratives, replaces auto-bullet noise).
🔄 Behavior changes
- Pi 0.72.1 → 0.73.1 lockstep bump. All 4 pi-* packages move together (
pi-coding-agent,pi-ai,pi-agent-core,pi-tui). Bumping only one causes silent API mismatches. MODEL_ALIASESreverted to 4-5 (NOT bumped to 4-6) — default-tier safety. Bumping aliases would silently force users onto 1M-context variants.- Nightly test failures auto-file GitHub issues with
nightly-failurelabel. Dedupe gate prevents floods. Issue body includes failing tests, error excerpts, Pi version, last 5 commits, and a fix brief for the next agent. - 18 tests gained
CI=trueskip guards — workspace/dist-dependent tests self-skip on CI runners.
🧰 Release flow consolidation
- Archived stale
soma-ship.sh. Wiredsoma-dev ship/release/betasubcommands. pr-check.ymlhardened: tsc typecheck job + changelog blocking + conventional-commit format validation.cliff.tomladded — git-cliff configured for Keep-A-Changelog format from conventional commits (feat→Added, fix→Fixed, ci/chore/test filtered).release-pleaseauto-trigger enabled on push to dev (proposes; release-please takes over as canonical in v0.27.1).
📁 New files / locations
PI_UPSTREAM.md(auto-updated by 6h GHA) — live Pi version gap + flagged commits relevant to Soma (33 Pi API usages tracked).tests/test-children-roles-exist.sh— drift-prevention regression test: every_run_rolereference indelegate.shmust have a matchingbody/children/<role>.md.
v0.26.x — May 2026
Maintenance arc: cache-invalidation hardening, Pi runtime bump rehearsals, soma-github local-mode runtime ship gap fix, body audit + state slimming, anti-accretion discipline. Two reverted patches (long-context, briefly enabled) that were rolled back when they broke a client’s Anthropic billing wall — documented in docs/anthropic-long-context.md with the anthropic.enableLongContext opt-in setting as the durable replacement.
v0.25.x — May 2026
The /inhale stale-ctx fix family + preflight update prompt + sentinel migrations made unconditional + body-template migration mind-prepend-cleanup-v0.25.0 with backup safety + Pi-cruft startup warnings removed. Cycle 12 (preload notify state machine) shipped — transitions only fire once per state change (none→saved, saved→stale, stale→saved). breathe:detail cap added.
v0.24.1 — May 2026
The “releases verify they actually completed” patch arc: protect the release pipeline from silently incomplete ships, and lock the cap-bus surface against accidental drift.
🛠 New tests you can run
tests/test-release-completeness.sh— asserts CHANGELOG ↔ git tag parity,dev↔mainff-merge reachability,dist/manifest.json↔package.json,npm/package.json↔package.json(collapsed-train case). Auto-runs in orchestrator Phase 1 (tests gate). If a previous release was incomplete, the next prepare fails CONFLICT-HARD before any new bump.tests/test-namespaced-caps.sh— static-analysis floor for the ~92-cap soma:/dev:/somaverse: bus surface. Per-family minimums, named-cap presence (18 specific from CHANGELOG), duplicate-registration detection, namespace hygiene. Catches accidental cap deletion or rename.
Both run as part of npm test; both fail loud if real drift exists.
🔄 Behavior changes
soma-release-ship.shStep 7 now verifies post-pull (was silent on failure). Reads~/.soma/agent/package.jsonaftergit pull --ff-onlyand asserts version matchesNEW_VERSION; on mismatch prints diagnostic + manual fix path + exits 1. Fixes the case where v0.24.0 silently shipped to npm with the runtime worktree stuck at v0.23.0 because pull failure was being swallowed).tests/test-doctor.sh,test-release-completeness.sh,test-release-surfaces.sh, andtest-version-truth.share now in-flight aware: detect HEAD subjectchore(release): vX.Y.Zand skip transient assertions during the ship window. Without this,npm testfails mid-ship becausedist/manifest.jsonlags the bumpedpackage.json. Re-run post-ship to confirm the assertion holds.
🧰 Workflows
- Anti-accretion sweep (governed by
amps/protocols/atlas.mdv1.1.0): whenbody/STATE.mdexceeds 6KB, run an anti-accretion sweep — session-history paragraphs (“sNN-XXXXXX shipped…”) belong inmemory/sessions/andmemory/journal/, not in STATE. STATE holds current state + pointers; history references the actual session log. Fired live s01-f1230f: cutbody/STATE.md18,148 → 5,513 bytes (-70%) without losing any current state. - Phase 6 (Reflect) step 4 expanded (
releases/cycles/soma-dev/phases/6-reflect.md): post-release body+state audit now mechanical. Runsoma:body.audit(catches duplicate slot interpolations, lazy-frontmatter lies) +soma:body.slots(token budget per slot) + the size gate on STATE.md. Plus stale-state scan: pulse.md, _recent-lessons.md, ecosystem.md, journal.md “Latest”. - In-flight test detection pattern (for any future test asserting build artifacts or release-pipeline state): detect
chore(release): vX.Y.ZHEAD subject; if matches, skip the transient assertion with a SKIP not FAIL. Re-run post-ship for verification. Pattern lives inbody/_recent-lessons.md § In-flight test detection.
📁 New files / locations
body/STATE.mdfrontmattergoverned-by: amps/protocols/atlas.mdfield — makes the protocol discoverable from the file.releases/v0.24.x/plans/cycle-cross-check-audit.md— audit doc surfacing five Curtis-decision items from the cycle MAP cross-check (e.g., should5-release.mdSteps 4-13 be split into orchestrator-internal vs human-action sections?).
🐛 Bugs you can stop stepping around
soma-scrape.shlost fetched docs silently when_website/dest dir didn’t exist. Nowmkdir -pbefore write. (scripts/_pro/*is gitignored from soma-beta release — dev/main only.)tsconfig.jsonwas type-checkingextensions/_archive/**— cleared 15 TS7006 errors from_archive/sx594-flat-wrappers/.npm run checknow exit 0.
v0.24.0 — May 2026
The “audit + scan + remember” patch arc: tooling for auditing your own kanban, scanning third-party repos as if they were local, and protecting your input from auto-rotation.
🆕 New caps
Kanban audit [dev] — close the “is SX-N actually still open?” question
dev:kanban.audit({ticket: 'SX-N'})→ JSON verdict + evidence (verdicts:SHIPPED/STALE/STALE-CROSS-PROJECT/STILL-VALID/NEEDS-REPRO/UNCLEAR)dev:kanban.audit_batch({tickets: [...]} | {all_open: true} | {all: true}, mode?: 'default'|'md'|'json'})→ grouped table or markdown for cycle docsdev:kanban.audit_open()→ every non-✅ row in workspace kanban (one-shot)- Backbone triangulates: kanban row + git log +
soma:code.*+ sessions/preloads + cross-project trees (somaverse/somadian/website) - For high-stakes verdicts, follow with
soma:agent.delegate({role: 'verifier', background: true})— independent second-opinion catches what heuristics miss - Read first:
dev(op='help', cap='dev:kanban.audit')ordocs/_dev/kanban-audit.md
GitHub scanner v2 — treat any repo as local without cloning
soma:github.local_path({repo: 'owner/name'})→ fetch tarball + return extract path. Cache by SHA at~/.soma/cache/gh/. ~1–5s cold, instant warm.soma:github.local_map({repo, file})→ function/struct/class map of any file (12 langs: rs / ts-tsx / js-jsx / py / go / java / c-cpp / rb / sh / md / json / toml). API-modesoma:github.maponly knew rs/ts/py — local mode is the upgrade.soma:github.local_find({repo, pattern, path?, ext?})→ full ripgrep regex (API search is literal-only). Auto-scopes to repo’s primary language via meta.jsonlanguagehint.soma:github.local_refs({repo, symbol, path?})→ DEF/IMP/USE classification across the cached reposoma:github.local_blast({repo, symbol, path?})→ blast radius (files × risk) for a symbolsoma:github.local_structure({repo, path?})→ faster + richer than API once cachedsoma:github.cache_list()/soma:github.cache_clean({days?: N | all?: true})→ cache management- Plus 5 API-mode caps that were missing from the addon but already in the script:
audit,releases,diff,compare,file_diff
Soma docs got smarter
soma:docs.whats_new({version?, limit?: 3})→ THIS doc, version-scoped if askedsoma:docs.guide({name})→ resolves fromguides/first,_dev/second. Convenience over.show.soma:docs.listnow recursive (catchesguides/and_dev/) and shows TL;DR per entry, grouped by section
🔄 Behavior changes
breathe.autois now opt-in by default (was on by default). Auto-rotation at 70% context was wiping user input mid-compose. If you want it back: setbreathe.auto: truein.soma/settings.json. Existing installs are migrated once viabreathe-auto-off-v0.23.1(recorded in newsettings.migrations[]array; respects re-enable).soma initnow writes the correct version to.soma/settings.json. Pre-fix it stamped 0.10.0 because the package.json walk-up only walked one level. Fresh inits + repaired existing installs.soma updateauto-detects your remote name (was hardcoded toorigin; broke on dogfood worktrees withmeetsomaremote).soma doctorpersists version bump even whenfixes==0(was printing “version bumped” without writing settings.json).
🐛 Bugs you can stop stepping around
/inhalestale-after-reload — extension code that capturedpi.sendUserMessagewent stale after session rotation. Now consumesroute.get("message:send")for fresh closure. Pattern: anypi.Xconsumed across rotation should go through soma-route’s capability bus. Seeamps/muscles/internal/route-plumbing-first.md.soma:code.findreturned 0 results silently whenextwas passed withoutpath(positional CLI shifted ext into path slot). Cap now defaultspathto.when ext is set.- GitHub script silently 404’d on master-default repos —
BRANCH=mainwas hardcoded. v2 auto-detects viadefault_branchAPI field, falls back tomainonly on API failure. - GitHub script
--helpranstructureon a repo named--help— now short-circuits to usage block.
📁 New files / locations
~/.soma/cache/gh/<owner>--<repo>--<sha>/→ GitHub tarball cache..soma-meta.jsonper entry with{owner, repo, sha, ref, language, fetched_at, size_bytes}..soma/settings.jsonnow hasmigrations: []array — list of one-time semantic migration IDs that have been applied. The runtime appends to this; you don’t typically write to it.docs/_dev/[dev]— dev-only docs subdir, surfaced bysoma:docs.listwhen present.
🧰 Workflows
- End-of-arc kanban sweep:
dev:kanban.audit_open()before cutting a release. Closes 3–4 wrongly-marked tickets in seconds; spawns verifier delegations for the high-stakes ones. - Survey a third-party repo without cloning:
soma:github.local_path({repo: 'owner/name'})→ returns cache dir → run anything against it. Map / find / blast / refs all work locally with full toolchain. ~5s one-time cost, then instant. - Soma-code env override:
SOMA_CODE_DEFAULT_EXT="go,md"(or any ext list) overrides cwd-marker auto-detect. Use when working in monorepo subdirs or pre-modules language repos that lack manifest files.
🛠 New scripts
scripts/_pro/soma-github-cache.sh— tarball fetch + extract + cache management.soma/amps/scripts/soma-audit-ticket.py[dev]— single-ticket audit (Python; the heuristics engine).soma/amps/scripts/soma-audit-tickets.sh[dev]— parallel batch wrapper (xargs -P 8)
📜 Plans referenced this arc
releases/v0.23.x/plans/github-tool-10x.md— the soma-github v1 → v2 architectural pivotreleases/v0.23.x/plans/discovered-tools-body-injection.md— the seed for self-discovering tool surface (Phase 0 done, Phase 1+ queued)
v0.23.0 — April 2026
The “release orchestrator + tree-hygiene” arc.
🆕 New caps
soma:agent.list({role: 'X'})→ filter children by role string. Stacks with existingactive_only/all/cleanup. Useful when a parent has spawned multiple roles and wants to inspect just one cohort.
🔄 Behavior changes
- Release orchestrator is now 10 gates (was 8). New: tree-hygiene (Phase 0.5) — halts on uncommitted state in
repos/agent/other thanM CHANGELOG.md. Prevents agent-spawned files leaking into ship. website-readiness (Phase 5.5) — callstests/test-release-surfaces.shfor CHANGELOG ↔ roadmap.json drift. - Phase 4-ship.md and 4.5-audit.md are archived. Their work is now inside
soma-release-prepare.sh+soma-release-ship.sh.
📜 Plans referenced this arc
releases/RELEASE-FLOW.md— current head (10 gates documented)- Old phase docs:
releases/cycles/soma-dev/phases/_archive/
v0.22.x and earlier
For the technical commit-by-commit history, see CHANGELOG.md at the repo root or https://soma.gravicity.ai/changelog. This whats-new.md only goes back to v0.23.0 — versions older than that didn’t have an agent-facing digest layer.
Conventions for whoever maintains this
- One section per release. Latest at top. Version + month + a one-line tagline.
- Density first. Skip the “why” if a one-liner won’t shrink the gain. Ship the “how to use it” — that’s what an agent reads to pick up the new surface.
- Tag dev-only.
[dev]after the cap name when it’s only on dev installs. - Always include invocation hint.
cap_name(args) → outcome. The agent reads this and can call it on the next turn. - No commits. Commits go in CHANGELOG.md. This file isn’t generated from git; it’s hand-curated for the agent’s benefit. Treat it like a muscle: dense, action-oriented.
- TL;DR up top so
soma:docs.listextracts a useful preview.