Skip to content

fix(pi-permission-system): fold a home-prefixed cd target - #1084

Open
Susensio wants to merge 3 commits into
gotgenes:mainfrom
Susensio:issue-1083-cd-home-target
Open

Susensio wants to merge 3 commits into
gotgenes:mainfrom
Susensio:issue-1083-cd-home-target

Conversation

@Susensio

Copy link
Copy Markdown

Closes #1083.

A cd ~/… target used to render the effective directory unknown, so every relative token after it was resolved against the session cwd — a path the shell never reaches and no rule can match — and a ./-prefixed token was not projected at all.
~/ is static: bash expands it from HOME before cd runs.

This folds an unquoted ~ / ~/… target to os.homedir() plus the rest of the word verbatim, under the ShellVariables rule the token projection already applies.
The rest is spelled verbatim rather than through expandHomePath, whose join would drop the separator a following concatenation part relies on (cd ~/"work").

What keeps the unknown base, and why:

  • a program that rebinds HOME (HOME=/tmp cd ~/x), the existing spellsReboundHome rule;
  • ~user, which reads the password database rather than HOME;
  • ~"work", because bash ends the tilde-prefix only at an unquoted slash, so that word is the literal ~work;
  • ~\/work, because the backslash quotes the slash and bash expands nothing;
  • a quoted ~ (cd "~/x", cd '~/x'), which is not a tilde-prefix at all and stays the relative literal it is;
  • bare cd and cd -.

Seven cases cover the fold in test/access-intent/bash/program-external-accesses.test.ts; ~/work && cat ../notes.txt projects <cwd>/../notes.txt without the src change.
The existing unknown-base case now uses cd "$DIR" so it keeps testing what its name says.

Checks, from the repo root:

pnpm --filter @gotgenes/pi-permission-system run test    # 6420 passed
pnpm --filter @gotgenes/pi-permission-system run check   # clean
pnpm --filter @gotgenes/pi-permission-system run lint    # clean

Docs: ADR 0009 amendment (2026-10-24), the completeness contract, docs/configuration.md, and the bash-path-resolver.ts architecture entry.

Out of scope, and still unknown: $HOME/x as a cd target, bare cd, and cd -.

A `cd ~/x` target made the effective directory unknown, so the external
gate resolved every relative token after it against the session cwd — a
path the shell never reaches — and a `./`-prefixed token was not projected
at all. `~/` is static: bash expands it from HOME before `cd` runs, so the
target now folds to `os.homedir()` plus its rest, with the separator kept
verbatim for a quoted remainder. A rebound HOME, `~user`, a tilde running
into a quoted part (`~"x"`), a slash the shell escapes (`~\/x`), and bare
`cd` keep the unknown base.

Refs gotgenes#1083
ADR 0009 gains the 2026-10-24 amendment, the completeness contract names
the fold, the configuration guide stops calling `cd ~` a non-literal
target, and the resolver's architecture entry says how the target folds.

Refs gotgenes#1083
…d-tilde cd

The `~\/work` token is reported as `$HOME/work` when that directory exists, as it does on GitHub runners, so asserting the whole list failed there. Assert the unknown base instead: the cwd-relative path is present and nothing is spelled from home.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cd ~/… leaves the effective directory unknown and resolves later tokens against the cwd

1 participant