Repository navigation
fix: single-writer plugin guard — never overwrite host-managed copies (#991) - #995
Conversation
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)npm install -g billion-context@pr-995Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pr995.tgz
npm install -g packageInstall instructions are refreshed on each push. |
[bot] 🏷 Received. This is a [PR] mirror of #995 (
Note: 开始审查 PR #995:拉取分支核对 diff、本地重跑 typecheck/test/build、查 CI 状态,结论稍后回帖。 |
[bot] 🏷 Review complete for PR #995 (Fixes #991) — verified on branch Verification (local re-run on head
Code review
Fixed directly on the PR branch (commit
Minor observation (report-only, nothing changed): on a machine where bili exists only as dsh profile bundles (no npm-global install), no process runs the periodic update loop, so those profiles won't refresh automatically — the user must run Bottom line: single-writer principle implemented cleanly, both enforcement points covered, docs accurate. Mergeable once the fresh CI on 中文摘要:审查了 #995 单写者插件守卫——本地复跑 typecheck/test/build 全绿、CI 8 项全过,代码与文档核对无误;已在 PR 分支直接修掉两处小问题( |
…, add bili plugin update - src/update.ts: hostManagedInstall() classifies install dirs (pnpm .pnpm virtual store, pi/opencode/dsh/kimi/omp host homes); checkForUpdate skips them, installViaTarball refuses them structurally (#991) - dsh bundles: self-update re-runs dsh's plugin channel per profile instead of copying over a pnpm store - bili plugin update [client]: drives each lane through its own owner, prints per-lane update path; bili plugin list shows the same channel info - tests: update-host-guard (classification + refusal), plugin-update lanes - docs: single-writer principle in README + AGENTS.md Key Design Decisions Fixes #991
dabb2a9 to
8c706c3
Compare
|
Rebased onto post-v0.1.123 master (clean, only Ship gate (per release plan): merge is held until the local validation hop succeeds — a machine running THIS guard build auto-updates 0.1.123 → 0.1.124 (no-op #1000) through the new updater code. |
…S.md decision-list numbering (#995)
[bot] 🏷 Rebase verified — with one catch: the squash dropped my two review-nit fixes, so I re-applied them. New head: Rebase check
Catch — fixes lost in the squash Verification on final head
Ship gate — agreed, and it's the right shape: this PR modifies 中文摘要:复核了 rebase 后的 #995(基线干净、与 master 无冲突、PR 未动 version),发现 squash 丢掉了上一轮两处小修复(行尾空白、AGENTS.md 重复编号),已按原样补回为新提交 |
Fixes #991
Problem
The global self-updater located any
billion-contextinstall dir viafindInstallDir()and copied the new tarball over it in place. That is correct only for the copy npm itself installed. WhenfindInstallDirresolved to a host-managed copy — a dsh profile bundle inside pnpm's.pnpmvirtual store, pi's npm entry, opencode's plugin dir — the copy-over breaks the owning package manager's integrity (pnpm store corruption / hardlink damage, #953's breeding ground) and violates the principle: the thing that installed a copy is the thing that updates it.Change
1.
hostManagedInstall()classification (src/update.ts) — detects install dirs under a pnpm virtual store (<dir>/.pnpm/...) or a host agent tree (pi / opencode / dsh / kimi / omp homes, honoring their env relocations). Returns{ owner, channel, hint }:dsh plugin --profile <name> add billion-context@latest(ordsh plugin add) — the channel dsh itself drivespi update/ opencode's plugin manager /kimi plugin update2. Guard enforcement —
checkForUpdateskips host-managed dirs (logs the owner's channel instead);installViaTarballrefuses them structurally (single-writerrefusal), so direct callers cannot corrupt a store either. bili-owned dirs (npm global layout, scratch) stay updatable.3. dsh bundles refresh through dsh's channel — self-update no longer copies over a pnpm store; it re-runs
dsh plugin --profile <name> add billion-contextper profile (the same commandbili plugin install dshdrives), falling back to plain tarball install only when dsh is absent.4.
bili plugin update [client]— one command that brings every lane's bili presence up to date, each through its own owner: reference lanes (omp/claude/codex/kimi) follow the global install; host-managed copies report their owner's updater with a #991 note; dsh lanes refresh through dsh's plugin channel.bili plugin listshows the same per-lane channel info.Principle (documented)
Every bili presence has exactly one writer. Mixing user commands is fine (
dsh plugin add≡bili plugin install dsh— same channel, same records); mixing writers is what the guard forbids. Documented in README (Single-writer: who owns which copy) and AGENTS.md Key Design Decisions #6.Tests
tests/update-host-guard.test.ts— classification (pnpm store, all five host homes, bili-owned stays updatable) +installViaTarballrefusal leaves the store copy untouchedtests/plugin-update.test.ts—pluginUpdatelanes: reference lanes point at global install, pi lane reports owner by entry form, dsh lane short-circuits offlinePre-flight
npm run typecheck✅npm test— 1959 pass / 0 fail (2 skipped = e2e gates) ✅npm run build✅cc @ranxianglei — merged cleanly with the native-channels README section from the ework PRs; single-writer table now sits right after it.