Repository navigation
v0.2.1
v0.2.1: hardened plugin launch and link-safe workspace
Released on 2026-09-12 from commit
abb39a6b46a74c6538556a90d6ba95e8fb06eea4.
Install or upgrade
Semctx 0.2.1 requires Bun >=1.4.0. Pin the release when reproducibility matters:
bunx semctx@0.2.1 installPlugin installation does not reload an active agent session. Open a new Codex task, or run
/reload-plugins in Claude Code and restart if reload fails. The plugin launch fix below only
applies to sessions started after the plugin is reinstalled.
What changed
This is a security patch release. It closes the three P0 findings of the 2026-09-09 quality audit
and changes no public CLI, MCP, schema or plugin contract.
Plugin MCP servers now pin Bun's working directory to the installed plugin. Claude Code launches
bun --cwd ${CLAUDE_PLUGIN_ROOT} and Oh My Pi bun --cwd ${PLUGIN_ROOT} before the bundle path;
Codex already resolved its launch against the installed plugin. A host that started the server
inside the analysed checkout previously let that checkout's bunfig.toml preload scripts run,
and its .env load, before the server existed.
The GitHub Action runs every bun step from the action's own checkout and passes the analysed
repository as an absolute --root. The verify step previously ran Bun inside the pull-request
checkout, so a pull request's bunfig.toml could execute code on the runner before semctx
started. working-directory, config-path and report-path keep their documented meaning.
Nothing semctx opens under .semctx may be a symlink or junction, dangling ones included: the
directory itself, config.json, the SQLite index and its sidecars, context packs, verification
state, the semantic, change, target and working trees, the anchor-migration transaction and the
feedback store with its writer lock are checked before every read, write, scaffold and init.
Every file written under .semctx goes through a writer that refuses a link at the destination
or below the root and stages through an unguessable temporary name, so a planted <file>.tmp
link is never followed; the verify --output report uses the same protocol. Reads and rewrites
could previously land outside the repository through a planted link. Refusals surface as
CONFIG_INVALID, CONTROL_INPUTS_UNSAFE or STORE_ERROR depending on the surface;
.semctx/guard.json, read by the cooperative guard hook, stays outside this guarantee.
Quality tooling moves to ruff 0.16.6 and zizmor 1.30.0, and the ESLint development dependencies
to typescript-eslint 8.70.0 and globals 17.12.0. No runtime dependency changes.
The evidence position of v0.2.0 is unchanged. All current labels are UNKNOWN: accuracy, benefit,
adoption, retention and human contribution time remain unmeasured, and those human outcomes stay
explicitly NOT_MEASURED in the public evidence. The packaged first-use demo was replayed against
the published 0.2.1 npm artifact (same runtime digest as the candidate bundle) with the same three
fixed cases and the same WARN verdict. Oh My Pi
support remains experimental and is not part of the Codex/Claude stable-delivery attestation.
Evidence and further reading
- Interactive public demo
- npm package
- Complete changelog
- Security policy
- Release workflow evidence
- GitHub release
Release publication follows the existing annotated-tag pipeline: verification, exact npm
gitHead, stable promotion, GitHub Release, then isolated delivery checks for both supported hosts.
The release workflow is the source
for publication status. A built candidate, replay result or green local test is not publication.
For rollback, pin the preceding CLI/plugin release, v0.2.0, and accept that it carries the three
findings above. Do not force the shared stable branch. Feedback state is optional local data;
inspect and export it before explicitly removing records.