Skip to content

bug(launcher): auto-provision setup fails on CodeGraph "path escapes allowed roots" — infinite first-run loop #1388

Description

@clezappdev-alt

Bug description

Running gentle-shell on a fresh or un-provisioned home enters an infinite first-run loop. The auto-provisioning setup (introduced in #1351) installs all companion packages successfully but then fails at the CodeGraph capture step with:

Error: execute install pipeline: capture Pi CodeGraph child "/home/cleceta/.pi/agent/agents/gentle-ai-verify.md": Pi CodeGraph path "/home/cleceta/.pi/agent/agents/gentle-ai-verify.md" escapes allowed roots

Because the setup exits non-zero, the provisioning marker in ~/.gentle-shell/config.json is never written, so every subsequent gentle-shell launch retries the same failing setup.

Steps to reproduce

  1. Have no ~/.gentle-shell/config.json (or delete it).
  2. Run gentle-shell (or gentle-shell setup).
  3. Observe the full package install succeeds, then the CodeGraph capture step fails.
  4. Run gentle-shell again — same output, same failure.

Expected behavior

Setup completes, writes the provisioning marker to ~/.gentle-shell/config.json, and subsequent launches skip the auto-provision step.

Actual behavior

Setup fails at CodeGraph capture because --scope global writes agents into ~/.pi/agent/agents/ (Pi's own default agent dir) while CodeGraph's allowed roots are scoped to ~/.gentle-shell/agent/ (the PI_CODING_AGENT_DIR the launcher sets). The path mismatch triggers the "escapes allowed roots" guard.

Root cause analysis

The auto-provision flow in runSetupFlow spawns:

gentle-ai install --agent pi --scope global

with PI_CODING_AGENT_DIR=~/.gentle-shell/agent. The --scope global flag causes gentle-ai to write managed agents into the user's real ~/.pi/agent/agents/ directory instead of the PI_CODING_AGENT_DIR target. The subsequent CodeGraph capture step then tries to index those files but rejects them because ~/.pi/agent/ is outside the allowed root (~/.gentle-shell/agent/).

PR #587 fixed a similar PI_CODING_AGENT_DIR alignment for subagent asset installation and model routing, but the CodeGraph capture pipeline step was not covered by that fix.

Environment

Component Version
gentle-pi 3.7.0
gentle-ai (pinned) v3.7.0
Pi 0.87.1
Node v24.19.0
OS WSL2 (Linux 6.6.87.2, x86_64)

Workaround

Until this is fixed, either:

  1. Create the provisioning marker manually — write ~/.gentle-shell/config.json with:

    {
      "provisioned": {
        "/home/<user>/.gentle-shell/agent": {
          "gentleAi": "3.7.0",
          "gentlePi": "3.7.0",
          "at": "2026-09-24T00:00:00.000Z"
        }
      }
    }

    (Replace paths/versions with your actual values.)

  2. Disable auto-setup — set GENTLE_SHELL_NO_AUTO_SETUP=1 in your shell environment.

Related

Activity

  1. memotux commented on Sep 24, 2026

    @memotux

    I have installed gentle-shell standalone today. Every time I run it is a first run setup. This is the output:

    gentle-shell: first run in /Users/<user>/.gentle-shell/agent: installing the Gentle AI companion packages (one time; set GENTLE_SHELL_NO_AUTO_SETUP=1 to skip)
    gentle-shell: provisioning /Users/<user>/.gentle-shell/agent with the gentle-ai companion packages
    WARNING: installing with --scope=global (default). Agent config files (system prompts, skills/, agents/, etc.)
    will be written to each selected agent's global config directory and will affect ALL workspaces for those agents on this machine.
    To install only into the current workspace, rerun with --scope=workspace.
    
    [pi-web-access] Dynamic tool activation requires Pi 0.86.1 or newer; web tools remain eagerly available.
    Installing npm:gentle-pi...
    
    up to date, audited 305 packages in 562ms
    
    159 packages are looking for funding
      run `npm fund` for details
    
    found 0 vulnerabilities
    Installed npm:gentle-pi
    [pi-web-access] Dynamic tool activation requires Pi 0.86.1 or newer; web tools remain eagerly available.
    Installing npm:gentle-engram...
    
    up to date, audited 305 packages in 507ms
    
    159 packages are looking for funding
      run `npm fund` for details
    
    found 0 vulnerabilities
    Installed npm:gentle-engram
    [pi-web-access] Dynamic tool activation requires Pi 0.86.1 or newer; web tools remain eagerly available.
    Installing npm:pi-mcp-adapter...
    
    up to date, audited 305 packages in 528ms
    
    159 packages are looking for funding
      run `npm fund` for details
    
    found 0 vulnerabilities
    Installed npm:pi-mcp-adapter
    npm notice run npx
    npm notice run 'pi-engram' init
    Pi agent dir: /Users/<user>/.gentle-shell/agent
    Kept npm:pi-mcp-adapter in settings.json
    Kept npm:gentle-engram@0.1.15 in settings.json
    Wrote Engram MCP server in mcp.json
    Set ENGRAM_URL for an existing engram serve instance, or ENGRAM_BIN for a custom engram binary path.
    [pi-web-access] Dynamic tool activation requires Pi 0.86.1 or newer; web tools remain eagerly available.
    Installing npm:pi-web-access...
    
    up to date, audited 305 packages in 510ms
    
    159 packages are looking for funding
      run `npm fund` for details
    
    found 0 vulnerabilities
    Installed npm:pi-web-access
    [pi-web-access] Dynamic tool activation requires Pi 0.86.1 or newer; web tools remain eagerly available.
    Installing npm:pi-btw...
    
    up to date, audited 305 packages in 507ms
    
    159 packages are looking for funding
      run `npm fund` for details
    
    found 0 vulnerabilities
    Installed npm:pi-btw
    Error: execute install pipeline: capture Pi CodeGraph child "/Users/<user>/.pi/agent/agents/sdd-proposal.md": Pi CodeGraph path "/Users/<user>/.pi/agent/agents/sdd-proposal.md" escapes allowed roots
    gentle-shell: automatic setup failed (exit 1); starting anyway and retrying next run. Run `gentle-shell setup` to see the full output.
    [pi-web-access] Dynamic tool activation requires Pi 0.86.1 or newer; web tools remain eagerly available.
    

    It is non blocking. Gentle Shell start with all tools. But, it happen every time and every project directory that I run it.

    gentle-shell setup give same output.

    No ~/.gentle-shell/config.json exist.

    Environment

    Component Version
    gentle-pi 3.6.0
    gentle-ai v3.7.0
    Pi 0.87.1
    Node v24.20.0
    OS macOS 27
  2. memotux commented on Sep 24, 2026

    @memotux

    From workaround only Disable auto-setup — set GENTLE_SHELL_NO_AUTO_SETUP=1 in your shell environment. work.

  3. carlosmoradev commented on Sep 24, 2026

    @carlosmoradev
    Contributor

    Confirmed, this diagnosis is spot on.

    What is happening

    During runSetupFlow in bin/gentle-shell.mjs, the launcher spawns:

    gentle-ai install --agent pi --scope global

    with PI_CODING_AGENT_DIR pointing to the resolved home (e.g. ~/.gentle-shell/agent).

    1. All companion packages (gentle-pi, gentle-engram, pi-web-access, etc.) install cleanly into ~/.gentle-shell/agent.
    2. However, the gentle-ai installer pipeline resolves global agent files against the default ~/.pi/agent/agents/ path, while CodeGraph's allowed root is bounded by PI_CODING_AGENT_DIR (~/.gentle-shell/agent).
    3. CodeGraph's path confinement guard detects that ~/.pi/agent/ is outside ~/.gentle-shell/agent/ and aborts with escapes allowed roots (exit code 1).
    4. Because the installer exited non-zero, runSetupFlow never executes recordProvisioned(), leaving ~/.gentle-shell/config.json unwritten. This triggers the setup flow again on every subsequent launch.

    Immediate Workaround

    Since the companion packages are already installed, setting GENTLE_SHELL_NO_AUTO_SETUP=1 in your environment skips the loop while keeping all tools functional.

    Fix Direction

    The upstream fix belongs in gentle-ai's installer pipeline: when PI_CODING_AGENT_DIR is set in the environment, the CodeGraph capture step for global agents must resolve against PI_CODING_AGENT_DIR instead of hardcoding ~/.pi/agent/.

  4. decode2 commented on Sep 25, 2026

    @decode2
    Member

    Adding to @carlosmoradev's diagnosis with the exact root cause in gentle-ai:

    There are two coupled issues in internal/agents/pi/adapter.go:

    1. Shared CodeGraph Manifest: CodeGraphPaths() hardcodes Manifest to ~/.gentle-ai/pi-codegraph.json. If Pi was previously run without PI_CODING_AGENT_DIR, the manifest already holds children under ~/.pi/agent/agents/.... When gentle-shell runs with PI_CODING_AGENT_DIR=~/.gentle-shell/agent, piCodeGraphAllowedRoots() restricts allowed roots to ~/.gentle-shell/agent and ~/.gentle-ai. During reconciliation, journal.validate() encounters the old ~/.pi/agent child path from the shared manifest, sees it outside the allowed roots, and aborts with escapes allowed roots.

    2. Split-brain in AgentConfigPath: AgentConfigPath(homeDir) returns ~/.pi/agent directly and ignores PI_CODING_AGENT_DIR. Only CodeGraphPaths() was checking the environment variable.

    We are preparing the fix in gentle-ai to isolate the manifest and align AgentConfigPath with PI_CODING_AGENT_DIR.

  5. added theissue type on Sep 25, 2026
  6. added
    bugSomething isn't working
    status:approvedIssue approved by maintainer; PR may be opened
    on Sep 25, 2026
  7. decode2 commented on Sep 25, 2026

    @decode2
    Member

    Upstream PR opened with the isolation fix and regression test: Gentleman-Programming/gentle-ai#4985

  8. aeizaguerri commented on Sep 25, 2026

    @aeizaguerri

    Hit this on Linux too (Fedora, brew; gentle-shell 3.7.0 / gentle-ai 3.7.0 / pi 0.87.1). Sharing some diagnostics that slightly contradict the root-cause analysis in the issue description — worth checking before the fix lands:

    Evidence

    1. The agent files were correctly written to ~/.gentle-shell/agent/agents/ (verified byte-identical to the gentle-pi package assets). Only the CodeGraph capture step failed.
    2. Running PI_CODING_AGENT_DIR=~/.gentle-shell/agent gentle-ai install --agent pi --scope global directly did not fix it, nor did upgrading gentle-ai 2.9.1 → 3.7.0.
    3. The failing child path changes on every run (sdd-apply.md, then sdd-onboard.md, then sdd-spec.md…). Go map iteration is randomized, so this means every recorded child fails the roots check, not a specific one — the reported path is just whichever comes first.

    Actual root cause (in my case)

    A stale journal manifest at ~/.gentle-ai/pi-codegraph.json, written by a previous gentle-ai install against the default Pi home (~/.pi/agent). It records children under both /home/<user>/.pi/agent/agents/… and /home/<user>/.pi/agents/…. When the install pipeline later runs with the isolated home, the journal's allowed roots are scoped to ~/.gentle-shell/agent, and the capture step rejects every path recorded in that legacy manifest (piJournal.capture() over manifest.Children in internal/components/communitytool/pi_codegraph.go). The recorded targets didn't even exist anymore.

    Workaround that fully fixed it

    mv ~/.gentle-ai/pi-codegraph.json ~/.gentle-ai/pi-codegraph.json.legacy-bak
    gentle-shell setup   # → Verification checks: 4 passed, 0 failed

    Suggestion for the fix

    The pipeline should skip (or quarantine) manifest entries whose paths fall outside the current allowed roots instead of failing the whole install — the per-agent-dir hashed manifest naming (pi-codegraph-<hash>.json in CodeGraphPaths) already prevents new cross-contamination, but legacy default-home journals still break the flow.

  9. memotux commented on Sep 28, 2026

    @memotux

    Confirm workaround in #1388 (comment), fix: rename pi-codegraph.json.

    gentle-setup successful. config.json created. No more 'first-round setup' loop in next gentle-shell launch. No need of GENTLE_SHELL_NO_AUTO_SETUP flag.

  10. itrejomx commented on Sep 28, 2026

    @itrejomx

    Another occurrence on macOS, with the legacy manifest confirmed as the trigger.

    Environment

    Component Version
    gentle-pi / gentle-shell 3.7.0 (npm global, stable)
    gentle-ai (pinned, package-local) v3.7.0
    Pi 0.85.1
    Node v26.10.0
    OS macOS 27.0, arm64

    What I ran

    1. npm i -g gentle-pi
    2. gentle-shell setup --dry-run (clean, exit 0)
    3. gentle-shell setup (one attempt, isolated home, default flags)

    Observed

    All companion packages installed, then the run exited 1:

    Error: execute install pipeline: capture Pi CodeGraph child "<default pi home>/agents/jd-judge-a.md": Pi CodeGraph path "<default pi home>/agents/jd-judge-a.md" escapes allowed roots
    

    State left behind in the isolated home:

    • No provisioned marker in the launcher config.json.
    • No mcp.json, even though the log printed Wrote Engram MCP server in mcp.json.
    • No agents/ or skills/ directories, only npm/ and settings.json.
    • npm:gentle-pi still declared and npm:gentle-engram declared twice (unpinned and @0.1.16), since the post-install cleanup never ran.

    The default Pi home was not modified (its settings.json checksum is identical before and after).

    Matches the legacy manifest diagnosis

    A pi-codegraph.json written on 2026-09-18 by an earlier default-home install exists in the shared gentle-ai directory, and the rejected child is one of the agent files from that default home.

    Expected

    Setup skips or quarantines manifest entries outside the current allowed roots and finishes provisioning.

    The fix in gentle-ai#4985 is merged but not in a published release yet, so 3.7.0 stable still reproduces.

  11. josepiera commented on Sep 29, 2026

    @josepiera

    Another confirmation on Linux (WSL2), same legacy-manifest trigger, plus one detail on what the successful rerun leaves behind.

    Environment

    Component Version
    gentle-pi / gentle-shell 3.7.0 (npm global)
    gentle-ai (pinned, package-local) v3.7.0
    Pi 0.87.1
    OS WSL2, Linux 6.18, x86_64

    Observed

    gentle-shell setup (manual) installed every companion package and then failed with:

    Error: execute install pipeline: capture Pi CodeGraph child "<home>/.pi/agent/agents/gentle-ai-worker.md": Pi CodeGraph path "<home>/.pi/agent/agents/gentle-ai-worker.md" escapes allowed roots
    

    <home>/.gentle-ai/pi-codegraph.json had been written on 2026-09-10 by a default-home gentle-ai install, with mcpPath under <home>/.pi/agent/mcp.json and 23 children under <home>/.pi/agent/agents/. The isolated home was left without mcp.json despite the Wrote Engram MCP server in mcp.json line, and with npm:gentle-pi still declared, matching the state described above.

    Workaround confirmed

    Moving the legacy manifest aside and rerunning gentle-shell setup completes with Verification checks: 4 passed, 0 failed, writes mcp.json and runs the post-install cleanup that removes npm:gentle-pi.

    One extra data point: after the successful rerun, no new pi-codegraph.json was written for the isolated home, so restoring the legacy manifest afterwards keeps the default Pi home's journal intact without conflicting with anything. The isolated home's mcp.json only gets the engram server, not codegraph.

  12. edwinsaavedran commented on Sep 30, 2026

    @edwinsaavedran

    Confirmed — reproduces on macOS with the current 3.7.0 stack. Adding environment evidence since the original report is WSL2/x86_64.

    Environment

    Component Version
    gentle-pi (npm package, installed by launcher) 3.7.0
    gentle-ai (package-local binary) v3.7.0
    Pi 0.99.2
    Node v22.15.1
    OS macOS 26.6.2 (arm64)

    Observed

    Fresh machine, no ~/.gentle-shell/ present. Ran the gentle-shell launcher from the git checkout at gentle-shell@ d5bedca9 (v3.7.0-311). The auto-setup installed the companion npm packages successfully, then failed at the CodeGraph capture step:

    Error: execute install pipeline: capture Pi CodeGraph child "/Users/<user>/.pi/agent/agents/sdd-design.md": Pi CodeGraph path "/Users/<user>/.pi/agent/agents/sdd-design.md" escapes allowed roots
    gentle-shell: automatic setup failed (exit 1); starting anyway and retrying next run.
    

    Details consistent with this report:

    • The rejected child is a different file (agents/sdd-design.md vs agents/gentle-ai-verify.md in the original report), which supports the analysis that the guard fires for any child under Pi's real global agents dir while the capture's allowed roots are scoped to the launcher home.
    • The infinite first-run loop reproduces: three consecutive launches each re-ran the full setup ("first run ... provisioning") and failed at the same step, because the provisioning marker is only written on success.
    • Pi 0.99.2 was in place before the failure (the new Pi >= 0.99.1 gate is not a factor here).

    Workaround from this issue (manually writing the provisioned entry in ~/.gentle-shell/config.json) was not applied at the time of writing; the loop is the currently observed state.

  13. osantis commented on Oct 1, 2026

    @osantis

    Another reproduction, plus one consequence that is not described in this thread yet: after the failed automatic setup, a source checkout of gentle-shell silently runs the published npm gentle-pi instead of its own package.

    Environment: gentle-shell launcher from a git checkout of main @ cc36bd8 (same launcher code at 1162ce9), package-local gentle-ai v3.7.0, Pi 0.99.1, Linux (WSL2). Fresh custom home inside $HOME, launcher config isolated with GENTLE_SHELL_CONFIG.

    Run 1 (auto-setup) fails as reported here:

    gentle-shell: first run in <home>/.gs-test/agent: installing the Gentle AI companion packages (one time; set GENTLE_SHELL_NO_AUTO_SETUP=1 to skip)
    Error: execute install pipeline: capture Pi CodeGraph child "<home>/.pi/agent/agents/sdd-archive.md": Pi CodeGraph path "<home>/.pi/agent/agents/sdd-archive.md" escapes allowed roots
    gentle-shell: automatic setup failed (exit 1); starting anyway and retrying next run. Run `gentle-shell setup` to see the full output.
    

    No provisioning marker is written, and the test home's settings.json is left with:

    ["npm:gentle-pi", "npm:gentle-engram", "npm:gentle-engram@0.1.16", "npm:pi-web-access", "npm:pi-btw", "npm:pi-mcp-adapter"]
    

    Run 2 (GENTLE_SHELL_NO_AUTO_SETUP=1, same home): Pi loads the extension from <home>/.gs-test/agent/npm/node_modules/gentle-pi (version 3.7.0 from npm) instead of the checkout the launcher runs from. The only output is the generic setup-failed line on run 1 and Pi's peerDependencies warnings for the installed packages; nothing says that the launcher's own package is being skipped.

    Why: on failure the post-install removal of npm:gentle-pi never runs (bin/gentle-shell.mjs:862-864), and a home whose settings.json declares gentle-pi makes the launcher defer to the declared package instead of injecting its own (runtime/gentle-shell-launcher.mjs:637 and :938-940).

    User-visible effect (observed in an earlier run of the same setup): /gentle:yolo is unknown, the model answers as the bare provider identity instead of "el Gentleman" (the harness-append fix from #1497 is not in 3.7.0), and on exit only pi --session <id> is printed without the gentle-shell resume line. Anyone evaluating main with a fresh home can therefore be testing 3.7.0 without noticing. After removing npm:gentle-pi from the home's settings.json and starting with GENTLE_SHELL_NO_AUTO_SETUP=1, the checkout's own package loads and those features work.

    Suggestion: when automatic setup fails, still run the npm:gentle-pi removal, or print a warning when the home's declared gentle-pi differs from the launcher's own package and is about to be used instead.

  14. danielgap commented on Oct 1, 2026

    @danielgap
    Contributor

    Verified on a current main checkout (1f35ab1e) with a controlled reproduction, both sides of the fix line:

    • Control, pinned gentle-ai 3.7.0 (via the documented GENTLE_SHELL_GENTLE_AI_BIN/GENTLE_SHELL_GENTLE_AI_PIN overrides): planted a legacy shared manifest at <tmp-home>/.gentle-ai/pi-codegraph.json whose child targets <tmp-home>/.pi/agent/agents/legacy-agent.md (schema taken from the reconcile journal). Auto-setup fails with the exact reported error (capture Pi CodeGraph child ... escapes allowed roots), exit 1, no provisioning marker, and the home is left declaring npm:gentle-pi with the published copy in node_modules. Infinite retry confirmed.
    • Fix, pinned gentle-ai 4.0.0 (same fixture, no overrides): manual setup exits 0 and removes npm:gentle-pi; the automatic first run exits 0, writes the marker (gentleAi 4.0.0 / gentlePi 4.0.0), and the second launch skips provisioning entirely (no first-run lines). The legacy manifest is never read; with a custom agent dir the isolated pi-codegraph-<hash>.json path applies.

    So the first published gentle-ai release carrying #4985 is 4.0.0 (answering @itrejomx's note that the fix was merged but unreleased): the loop is closed for every home once gentle-pi 4.0.0 with that pin reaches users, and pre-existing legacy manifests are harmless because the custom-dir manifest path is isolated.

    One failure-path consequence first reported by @osantis is now filed separately as #1647: when setup does fail, the npm:gentle-pi removal never runs and the home silently ends up running the published package instead of the launcher's own copy. That residue is independent of the 4.0.0 fix (it needs any install failure, not this one).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions