pathguard

package
v0.150.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package pathguard declares the paths a WB command needs to write to and turns a denial into an actionable diagnostic.

A sandboxed harness grants write access to a workspace root and nothing else. WB keeps private state at <root>/.wb and, in the default central store mode, checkouts at <root>/.worktrees — both outside a workspace that was widened only to a canonical clone. Without this package the operator sees a bare "operation not permitted" from whichever syscall happened to fail first, with no path, no role and no remedy.

The contract this package implements is projects-root-layout#req:declared-writable-paths and projects-root-layout#req:actionable-permission-error.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Check

func Check(root string, requirements []Requirement, probe Probe) error

Check probes every declared requirement and returns nil when all of them are writable. It returns a *Error naming each unwritable path, its role and the remedies, so a caller can fail before its first mutation instead of reporting whichever syscall lost the race to fail.

A nil probe falls back to OSProbe. Root is only used to word the remedies.

func OSProbe

func OSProbe(path string) error

OSProbe is the production probe. It walks up to the nearest existing directory — a declared path such as <root>/.wb usually does not exist yet — and creates and removes one uniquely named entry there, which is exactly the permission a later create needs. The entry is transient and dot-named, but it is a real write: probing a directory inside a canonical clone briefly adds and removes a `.wb-writable-probe-*` entry in it, because creating the checkout root is the permission being tested and no read-only check answers it.

Types

type Denial

type Denial struct {
	Path string
	Role Role
	// Err is the underlying probe failure. It is carried for the operator's
	// logs but is deliberately not the whole diagnostic.
	Err error
}

Denial is one declared path the probe refused.

type Error

type Error struct {
	// Root is the projects root the command resolves every path from.
	Root string
	// Denials is non-empty and ordered as the requirements were declared.
	Denials []Denial
}

Error is the actionable diagnostic: it names every unwritable path, the role each plays, and the remedies. It never consists solely of an errno string, because the errno is what the operator already had.

func (*Error) Error

func (err *Error) Error() string

type Probe

type Probe func(path string) error

Probe reports whether WB can create an entry at or under path. A nil result means the path is writable. Production callers use OSProbe; a test that must reproduce a sandbox denial without being sandboxed injects its own.

type Requirement

type Requirement struct {
	Path string
	Role Role
}

Requirement is one path WB must be able to write to, together with the role that path plays in the command about to run.

func CanonicalRequirement

func CanonicalRequirement(canonicalPath string) Requirement

CanonicalRequirement declares the canonical clone Git registration for one repository. WB needs the clone's .git directory writable to register, repair or remove a linked checkout.

func Requirements

func Requirements(stateDir, centralStore string) []Requirement

Requirements builds the declared writable set for a command: the private state directory, the platform temporary area, and — only when the selected store mode has one — the central checkout store. Repository-local mode keeps checkouts inside their canonical clone, so it declares no store root; the canonical clone is declared per repository by CanonicalRequirement.

type Role

type Role string

Role names why WB needs to write to a declared path. The role is what makes the diagnostic actionable: an operator who is told the path is the checkout store can move it, while an operator told only the path can only guess.

const (
	// RoleState is the private coordination state directory <root>/.wb.
	RoleState Role = "state"
	// RoleStore is the central checkout store <root>/.worktrees, where
	// central-mode task checkouts physically land.
	RoleStore Role = "store"
	// RoleLocalStore is <canonical>/.worktrees, where a repository-local
	// checkout physically lands. It is a distinct role from RoleStore because
	// the two select different layouts: telling an operator already in
	// repository-local mode to select repository-local mode is not a remedy.
	RoleLocalStore Role = "local-store"
	// RoleCanonicalGit is <canonical>/.git. Git writes gitdir, commondir,
	// HEAD, index, logs, refs, ORIG_HEAD and COMMIT_EDITMSG there on worktree
	// create, repair and remove — so it is part of the declared writable set
	// even though it sits inside a directory WB otherwise only reads.
	RoleCanonicalGit Role = "canonical-git"
	// RoleTemp is the platform temporary area.
	RoleTemp Role = "temp"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL