gate-worktree-git-safety
SkillDev toolsUse when changing recursive gate containment, run worktree placement, bare-gate Git calls, GitHub PR targeting, or post-receive hooks.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the gate-worktree-git-safety skill
What this skill tells your AI
The instructions your AI receives, as published by kunchenguid/no-mistakes in .agents/skills/gate-worktree-git-safety/SKILL.md and read by ahel’s review.
Recursive Gate-Execution Containment
internal/gatecontextis the single classifier for recursive pipeline control. It combines canonical registered gate common-directory identity with OS-authenticated IPC peer ancestry;NO_MISTAKES_GATEis diagnostic only. CLI preflight, daemon mutation ingress, gate init/eject, branch-sync mutation, and the managed pre-receive hook must all keep using that owner so marker removal, cwd changes, and direct pushes cannot bypass refusal. Read-only AXI status/logs, help, and doctor remain available. Regressions:internal/gatecontext,TestGateStepCannotStartRecursivePipeline.- Every pipeline agent prompt receives the phase boundary from
internal/gateguidance, and the generated user-level skill reuses the same owner. Step agents return only their assigned phase; the outer executor alone controls other validation, push, PR, and CI phases. Editinternal/skill/skill.go, then runmake skill; never edit the generated skill directly.
Filesystem and Paths
- Use
filepath.Join; respectNM_HOMEfor app state; directories are0o755and files0o644by convention. - On macOS, path comparisons may need symlink resolution (
/varvs/private/var); useworktrees.Canonical/worktrees.Containswherever run worktree paths are compared, so one spelling matches everywhere. - Run worktree placement (
worktree_roots) is owned byinternal/worktrees. Configuration decides it exactly once, at run creation (Layout.DirinRunManager.startRunWithIntentSource), and the result is persisted inruns.worktree_dir; every later consumer - resume, step diff, startup cleanup,procreap, eject, gatecontext attribution - must read it back throughworktrees.RecordedDirand never re-derive it from config, so a mid-flight edit can neither strand a parked run nor point a removal at a directory the run never used. An empty column means the default<NM_HOME>/worktrees/<repoID>/<runID>. worktrees.CheckPlacementis the single policy for an unusable root (insideNM_HOME, inside any registered checkout);config.ValidateWorktreeRootsowns what the config can judge alone. The daemon refuses to start on an unusable placement, soinit --worktree-rootmust refuse exactly the same set or it prints a paste that takes the operator's CLI down, and EVERYinitrefuses to register a checkout that contains a configured root - the same state reached from the other direction. User-facing semantics live indocs/src/content/docs/reference/global-config.md. Regressions:internal/worktrees,internal/config/config_worktree_roots_test.go,internal/daemon/worktree_roots_test.go,internal/gate/eject_sweep_test.go,internal/cli/init_test.go.
Git on Bare Gate Repos (safe.bareRepository)
- Agent harnesses and hardened CI inject
safe.bareRepository=explicit, which forbids cwd-based discovery of bare repositories. Route every gate git call throughgit.Run, which detects a bare git dir and prepends--git-dir=<dir>; never shell out to git in a bare gate repo relying oncmd.Diror-Cdiscovery (issue #362). - Startup gate migration is DB-authoritative with a strict validated
<id>.gitlegacy fallback; it must reject non-gates before hook or Git mutation and usegit.RunBareso a malformed directory cannot discover an ancestor worktree. Completed migrations carry the content-versioned gate-config stamp and normal restarts must stay filesystem-only for current gates. Regressions:TestMigrateGateConfigsRejectsInvalidDirectoriesAndSkipsCurrentGates,TestColdDetachedStartupProductionGateCardinality. - Regressions:
TestRunOnBareRepoUnderSafeBareRepositoryExplicit,TestWorktreeAddRemoveOnBareRepoUnderSafeBareRepositoryExplicit,TestInitUnderSafeBareRepositoryExplicit.
gh PR-Targeting From the Bare Gate Repo (internal/scm/github)
- The daemon runs
ghfrom the detached bare gate repo whose HEAD is the default branch, so every PR-targeting command must name the exact PR explicitly: an empty positional makesgh pr <verb>infer the cwd branch (main) and returnno pull requests found for branch maineven when the feature PR's checks are green.GetChecks,GetPRState,GetMergeableState, andUpdatePRroute through the sharedprSelector(number, else URL, else fail closed) - never append a barepr.Number/pr.URLthat can be empty. This is theghanalogue of the git bare-gate-repo trap above. - Regressions:
TestGetChecksTargetsKnownPRByURLWhenNumberMissing,TestPRTargetingReadsFailClosedWithoutIdentity,TestPRStateAndMergeableTargetKnownPRByURL,TestUpdatePRTargetsKnownPRByURLWhenNumberMissing,TestUpdatePRFailsClosedWithoutIdentity.
Post-Receive Hook Gate Path Resolution (internal/git/hook.go)
- The hook's
--gatevalue must never come from a bare$(pwd): Git can invokepost-receivefrom a cwd that collapses to.(issue #269), which the daemon rejects and the pipeline silently never starts. The hook script resolves an absolute gate dir (git first, hook location fallback), andnormalizeNotifyGatePathininternal/cli/daemon_cmd.gois an independent second layer that absolutizes whatever an already-installed older hook sends. - Regressions:
TestPostReceiveHook_ResolvesAbsoluteGateDir,TestPostReceiveHook_FallsBackToHookLocationForGateDir,TestNormalizeNotifyGatePathResolvesLegacyDotGate.
Signals
- GitHub stars
- 8k
- Forks
- 855
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
gate-worktree-git-safety- Source
- github.com/kunchenguid/no-mistakes