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 ¶
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.
type Probe ¶
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 ¶
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" )