mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-02 15:04:37 +01:00
v1.91.59.0 fix(autoplan): bind init through symlinked plan directories and superseded failed inits (#3083)
* fix(autoplan): bind init through symlinked plan directories and superseded failed inits The publication guard compared snapshot init's JSON against the literal argv spelling, but init reports canonical destinations, so a plan under macOS /tmp or /var (realpath /private/...) always denied init_mismatch. The guard also hard-failed on the first errored init, so a corrected re-run never bound. - bin/gstack-autoplan-snapshot.ts: export canonicalDestination (the inner destination() path math); initializePlan output is unchanged. - autoplan/bin/phase-publication-hook.ts: compare activePlan/restorePath against the canonicalized argv; a mistyped tool path is unbindable, not a crash; skip errored inits and deny init_failed only when the most recent init errored; Write/Edit to the active plan match by canonical path. - autoplan/bin/guard-reasons.ts: init_mismatch never says re-run; init_failed does. - tests: PAX-3638 Fix A/A2/B/C cases (bun test -t "Fix B" runs one fix); the three autoplan-init assertions that failed on macOS now compare canonical paths. 9 of the 11 new guard cases fail against the previous hook. - docs: init_mismatch, init_failed, Symlinked plan directories. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(autoplan): canonicalRequested comment matches realpath behavior realpathSync resolves a leaf link as well as directory links; only a missing target or dangling link keeps the literal spelling. Note why resolving a leaf link cannot bind an aliased active plan, and drop Read from the callers list (only Write/Edit use it). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * v1.91.59.0 fix(autoplan): bind init through symlinked plan directories and superseded failed inits Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: Wyatt Barrett <wyatt@Wyatts-MacBook-Pro.local> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
10 files changed
+232
-33
No files matched your search
@@ -177,8 +177,14 @@ previous report.
|
||||
|
||||
<a id="init-mismatch"></a>
|
||||
### `init_mismatch`
|
||||
The snapshot init result or its artifacts (restore point, active plan header)
|
||||
do not match this invocation.
|
||||
Snapshot init returned paths that do not match the canonical form of its own
|
||||
command arguments, or its artifacts (restore point, active plan header) do not
|
||||
match this invocation. The guard canonicalizes the `<active>` and `<restore>`
|
||||
arguments the way `init` does (see
|
||||
[Symlinked plan directories](#symlinked-plan-directories)) before comparing, so
|
||||
a retargeted or forged init result is denied here. Zero results or duplicate
|
||||
results for one init use also deny as `init_mismatch`. Do not re-run the same
|
||||
call: run init with the paths the guard expects.
|
||||
|
||||
<a id="snapshot"></a>
|
||||
### `snapshot`
|
||||
@@ -241,7 +247,10 @@ A new `/autoplan` turn needs its own init (it may answer `reused: true`).
|
||||
|
||||
<a id="init-failed"></a>
|
||||
### `init_failed`
|
||||
The init step failed. Complete it first.
|
||||
The most recent snapshot init call failed; re-run the same init command with
|
||||
the same three paths. An errored init is skipped, so a later successful init
|
||||
still binds. This denial applies when no init ever succeeded, or when an
|
||||
errored init follows a good one.
|
||||
|
||||
<a id="init-unbindable"></a>
|
||||
### `init_unbindable`
|
||||
@@ -335,3 +344,18 @@ write it never changes a decision.
|
||||
Claude Code and Git Bash can spell one path as `C:\x`, `c:\x`, `C:/x` or `/c/x`.
|
||||
The guard treats these as the same path. It does not resolve `.` or `..`, so a
|
||||
path containing them is still rejected.
|
||||
|
||||
<a id="symlinked-plan-directories"></a>
|
||||
## Symlinked plan directories (macOS /tmp, /var)
|
||||
|
||||
The guard compares plan paths canonically, not by argv spelling. On macOS
|
||||
`/tmp` and `/var` are symlinks to `/private/tmp` and `/private/var`, so a plan
|
||||
under `/tmp` or `/var/folders` is expected to appear as `/private/...` in the
|
||||
init JSON. That is by design: `init` reports canonical paths (the deepest
|
||||
existing ancestor is resolved with `realpath` and the missing segments are
|
||||
re-joined, `canonicalDestination` in `bin/gstack-autoplan-snapshot.ts`), and
|
||||
the guard canonicalizes the init command's `<active>` and `<restore>` the same
|
||||
way. Writes and Edits to the active plan are matched by canonical path too, so
|
||||
editing the plan through an alias spelling is recognized. Symlinked plan
|
||||
directories are allowed; only a result that differs from the canonical form of
|
||||
its own arguments is denied (`init_mismatch`).
|
||||
Reference in new issue
Block a user