Repository navigation
fix: harden destructive ops — root-level prune/sync guards, ancestry session check, durable branch prefix - #26
Merged
Merged
Conversation
…session check, durable branch prefix prune: run from project root only; skip workspaces the session is rooted in (process-ancestry check, not CWD); skip dirty/foreign-repo/unmerged-jot candidates without --force; refusal messages name no bypass; removed from the skill's action surface (enforcement replaces documentation). Branch cleanup now names squash/rebase-merged branches in the skip line (content equivalence via git merge-tree, git cherry fallback) with the exact native-git cleanup command for the human operator. sync: --force/--branch are root-level only; --branch retires only the replaced branch's fetch refspec and rolls back on failure. branch prefix: moved from ORBIT_BRANCH_PREFIX env to project config (branch.prefix) — validated on write, immovable while branches carry it. repo names validated as pool basenames across sync/add/info/memo/clone (path-traversal fix); clone basename outside the contract points at --name. jot queue stored as [jot "<repo>"] subsections — names plain git-config keys can't hold (my_repo, 2048) now round-trip. auto-approve hooks match destructive flags on normalized tokens (quotes/ backslashes stripped); sync --branch joins the prompt tier. workspace/repo inference compares physical paths (symlinked cwd); session guard announces its blind spot when ancestry is unreadable; doctor reports the ancestry facility. CHANGELOG rewritten CNCF-style (Urgent Upgrade Notes + Changes by Kind, PR-attributed) covering v0.1.0..HEAD, release-ready for 0.2.0. Signed-off-by: zheng-weihao <zheng-weihao@outlook.com>
zheng-weihao
force-pushed
the
prune-protection
branch
from
July 31, 2026 12:45
0b1b13f to
528e810
Compare
…te the cleanup command git cherry failing (unresolvable upstream, or any error) left an empty '+' set that the negated grep inverted into 'content upstream' — handing out branch -D for content that was never verified. Capture cherry's output and fail closed; match via here-string (no producer pipe under pipefail). Also quote the path and branch in the printed cleanup command so it survives copy-paste from paths with spaces; message contract and registry updated, plus a test pinning the unresolvable-upstream case. Signed-off-by: zheng-weihao <zheng-weihao@outlook.com>
…ndent ancestry refusal, structural workspace detection, blind walk withholds cd replay Signed-off-by: zheng-weihao <zheng-weihao@outlook.com>
…ng exit defeats Linux exec-collapse that made assertions platform-dependent Signed-off-by: zheng-weihao <zheng-weihao@outlook.com>
…ame exec-collapse fix as prune Signed-off-by: zheng-weihao <zheng-weihao@outlook.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
An agent ran
orbit prunefrom inside a workspace: it deleted a sibling workspace, read the self-protection skip message (you are currently in this workspace) as instructions,cd'd out, and pruned the workspace it was working in. The protection checked state the agent controls (shell CWD) and its refusal message doubled as a bypass guide.git worktree remove --forcealso destroyed uncommitted changes with no check at all.What
Prune — four guards, all on state an agent cannot change by
cd-ing (spec: docs/spec-lifecycle.md → Prune Safety Guards)/procon Linux,lsofon macOS; physical-path normalization so symlinked roots still match) — best-effort, announces its blind spot,orbit doctorreports the facility--forceoverrides data guards only, never the scope guardssync —
--force/--branchare root-level only (they destroy/re-point shared pool state);--branchretires only the replaced branch's fetch refspec and rolls back on failure. Baresyncunaffected.branch prefix — moved from
ORBIT_BRANCH_PREFIXenv toorbit config branch.prefix(defaultws): the value names every branch orbit creates and selects which branches prune deletes, so it must be durable. Validated on write; refused while branches still carry the current prefix. BREAKING.Repo names validated as pool basenames across
sync/add/info/memo/clone --name— a traversing name (sync ../<ws>/<repo> --force) previously aimedgit reset --hardat a worktree's checked-out branch. Clone basename outside the contract points at--name.jot queue stored as
[jot "<repo>"]subsections — names plain git-config keys can't hold (my_repo,2048) now round-trip.auto-approve hooks match destructive flags on normalized tokens —
'--force',--force'',\-\-forceno longer slip past (both hooks/auto-approve.sh and the OpenCode plugin);sync --branchjoins the prompt tier.inference — workspace/repo inference compares physical paths (commands work through symlinked cwds, e.g.
/tmp→/private/tmp).CHANGELOG rewritten CNCF-style (Urgent Upgrade Notes + Changes by Kind, PR-attributed), complete for v0.1.0..HEAD — release-ready: flipping
Unreleased→0.2.0(+ORBIT_VERSIONbump + filling this PR's number in the Security entries) is all the release needs.Test plan
node --test .opencode-plugin/plugin.test.ts— 16/16 locally)