Expand description
The directory context the harness supplies (HP-19): the working directory a command
runs in, and the project root. It exists to make relative-path classification honest —
cd /etc && echo > ./x must be seen as writing /etc/x, not a worktree file.
The context is ambient for one command evaluation: a single cwd/root pair threads
logically through the whole recursive verdict tree (script → pipeline → cmd → redirect →
leaf). Rather than add a pass-through parameter to ~15 recursive functions across cst,
handlers, and engine, it lives in a scoped thread-local, installed by
enter at the top of an evaluation and read at exactly two leaves: legacy
is_safe_write_target and engine classify_locus, both via resolve.
Everything is fail-open to today’s behavior: with no cwd/root (or an unresolvable
path) resolve returns the path unchanged, so the classifiers behave exactly as before
— the signal tightens when present, never a regression when absent.
Structs§
- Guard
- Restores the previous
PathCtxwhen dropped. - Loop
Guard - Pops the loop binding when dropped.
- PathCtx
- The working directory and project root for the command under evaluation. Both optional: a harness may supply neither (e.g. opencode), and classification falls back to the relative-is-worktree assumption.
- Stdin
Repr Guard - VarGuard
Functions§
- cwd
- The ambient working directory, if known.
- enter
- Install
ctxas the ambient context for the duration of the returned guard; the previous context is restored on drop (panic-safe, so a failing test can’t leak into the next). - enter_
cwd - Run
fwith the ambientcwdtemporarily replaced (root unchanged) — used by intra-linecdtracking as it walks a chain’s statements. Restored on drop. - enter_
loop_ var - Bind loop variable
nameto its list’s representative items for the duration of the guard (the loop body’s classification). Nested loops stack; the innermost binding of a name wins. - enter_
stdin_ repr - Bind the representative PATH of the items arriving on stdin, for the duration of the guard —
set by the pipeline walker to the previous stage’s output-path locus. An operand-injecting
consumer (
xargs) reads it sofind / | xargs catgates the injected operand at/, whilefind ./src | xargs catgates it at the workspace (mirrorsfind -exec’s{}binding). - enter_
var - Bind
nameto a CERTAIN literalvalue(aVAR=/pathassignment, or$1at a function call) for the duration of the guard; consulted byexpand_varsAFTER loop vars, so the innermost/latest binding wins. The caller binds only values it is certain of — an uncertain value (VAR=$(cmd),VAR=$UNBOUND) is bound to the unpinnable sentinel so$VARstill fail-closes rather than resolving to a stale or dropped value. - expand_
vars - Expand any bound loop variable (
$name/${name}) inpathto its representative list item — the read representative whenwant_writeis false, the write representative when true. Unbound$…is left untouched (so it still fail-closes to machine). Returnspathunchanged when nothing is bound. - join_
cwd - Resolve a
cdtarget to a new absolute working directory, orNoneif it can’t be pinned statically (cd,cd -,cd ~…,cd $VAR) — the caller then leaves the running cwd unchanged.curis the current cwd, needed to resolve a relative target. Used by intra-linecdtracking (HP-19 #2). - resolve
- Resolve a path argument for classification against the ambient
cwd/root. Returns a path the existing classifiers (classify_locus,is_safe_write_target) can score unchanged. Whencwdandrootare both known and absolute, a relative path is lexically joined ontocwd(no filesystem access) and an absolute path is normalized in place; then either way, if the result is insiderootit comes back as a root-relative path (so the classifiers see “worktree”), and if it escapedroot(e.g.cwdis/etc, or an absolute/etc/hosts) it comes back absolute (so they seemachine/etc.). This makes the absolute and relative spellings of the SAME in-root file classify identically — safety on the OPERATION, not the SYNTAX. A~(home) or$-unpinnable path, or no context, is returned as-is. - root
- The workspace ROOT (project dir), if known — falling back to
cwd(the hook defaults root to cwd). Used by the adjacent-sibling classifier to find the workspace’s parent. - stdin_
item_ repr - The current stdin-item representative, or
Nonewhen the source is unknown (no pipe / an unmodeled producer) — in which case the consumer worst-cases the injected operand.