Repository navigation
fix(session): make the remote-session bootstrap reachable and honest - #341
Merged
Merged
Conversation
A session holding several organs clones them side by side under the session's project directory. Claude Code registers project hooks from that directory — which is then their parent: not a repo, no `.claude/`, no hook registered. So in exactly the sessions holding the most repos, no repo's SessionStart hook ran, and the session came up on the container's Python 3.11: one minor below the floor this organism set for itself and below every CI leg, with mypy and flake8 reading the interpreter and judging code against 3.11 rules. Nothing announced it; it surfaced as local-green/CI-red. - `policy/session_start_hook.sh` derives its repo from the hook's own location instead of `$CLAUDE_PROJECT_DIR`, so `session-python.txt` is read from the repo that owns it rather than from a parent that has none. - When it detects the multi-repo layout it installs a workspace-root `settings.json` plus a fan-out that runs each sibling repo's hook, so the next session in the container starts correctly. - It unshallows the session's clones. A shallow clone makes `git merge-base --is-ancestor` report "not an ancestor" for a commit whose ancestry is merely absent, and the ship and close-out procedures act on that answer (already logged once in `complete/2026/08/status-sh-repos-missing-source.md`). Here that was 249 of 4398 commits. - Git history and hook reachability now run before, and independently of, the interpreter legs: a container that cannot build the venv still wants honest ancestry and a hook that fires next time. `PYAUTO_SESSION_SKIP_PYTHON=1` is the seam the tests use. - The env file now also exports `PYAUTO_ROOT`. `scripts/session_bootstrap.sh` is the other half — the door anything can knock on to fix the session it is already in, which `bin/pyauto-brain` now calls before dispatch. `--check` reports each tool's real interpreter (resolved via its shebang; a tool's own `--version` says nothing about what it runs on). `repos_sync.py`: seven tenant-firewall allowlist entries dropped or narrowed. Each named the owner only because it hardcoded a workspace root under `$HOME`; those consumers now delegate to the Brain's resolvers, which name no absolute path at all. Tests: 8 new, covering the layout that used to defeat the hook entirely, the fan-out's reach, and the shallow-clone lie (asserted against git itself, before and after). All four of the behavioural ones fail against the previous hook. 224 PyAutoMind tests pass; `lifecycle.py check` and `repos_sync.py --check` OK. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012PDoeCuecjutdnwkxsTqg7
…ot read The Brain board is the morning door and on mobile it is mostly blind: eleven of its legs read GitHub through `gh api`, and a Claude Code remote session has no `gh` at all. The 2026-08-26 work made that blindness visible rather than green-and-wrong; this prompt is for closing it. Carries the measurements so the next session does not re-derive them: gh absent, MCP tools working but agent-only (a subprocess cannot call them), the injected $GH_TOKEN refused at the proxy with an org-level message, git and api.github.com otherwise fine. That combination is why "port the board to MCP" is a design question rather than a substitution, so phase 0 is a probe and a decision between three named options, not code. Filed separately from brain_board_follow_ups.md, which is the small-nit catch-all for the same board; cross-linked both ways. Sized `large` on the sizing faculty's own read (score 9) rather than the medium first guessed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012PDoeCuecjutdnwkxsTqg7
This was referenced Aug 26, 2026
Merged
…ance-review-5qwv8r # Conflicts: # dashboard.html # dashboard.md
Jammy2211
added a commit
that referenced
this pull request
Sep 3, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VsKeuX83FNGjLqs2axLHeR
Jammy2211
pushed a commit
that referenced
this pull request
Sep 3, 2026
mind: dashboard refresh on batches/**; dev batch stays collected-once, reviewed-once (#341)
Jammy2211
pushed a commit
that referenced
this pull request
Sep 27, 2026
…profiling#342) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MwuV47ESjoLFM8MuFZjw2s
Jammy2211
pushed a commit
that referenced
this pull request
Sep 27, 2026
…); dashboard regen Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MwuV47ESjoLFM8MuFZjw2s
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Mind half of a mobile-performance review. Companion to PyAutoLabs/PyAutoBrain#289, which is already merged — this PR's firewall change depends on it (see Merge order).
The hook that never fired
Claude Code registers project hooks from the session's project directory. A session holding several organs clones them side by side under that directory, so the project directory is their parent: not a repo, no
.claude/, no hook registered.So in exactly the sessions holding the most repos, no repo's SessionStart hook ran at all, and the session came up on the container's Python 3.11 — one minor below the floor this organism set for itself and below every CI leg, with mypy and flake8 reading the interpreter and judging code against 3.11 rules. Nothing announced it; it surfaced as local-green/CI-red.
Measured, not inferred: running the hook by hand ~40s into a live session printed
building /root/.pyauto/session-py312and rebuilt all seven uv tools. Nothing had built it.What changed
policy/session_start_hook.shderives its repo from the hook's own location, not$CLAUDE_PROJECT_DIR, sosession-python.txtis read from the repo that owns it rather than from a parent that has none.settings.jsonplus a fan-out that runs each sibling repo's hook, so the next session in the container starts correctly.git merge-base --is-ancestorreport "not an ancestor" for a commit whose ancestry is merely absent, and the ship/close-out procedures act on that answer — already logged once incomplete/2026/08/status-sh-repos-missing-source.mdas an environment note. Observed here: PyAutoMind had 249 of 4398 commits.PYAUTO_SESSION_SKIP_PYTHON=1is the documented seam the tests use.PYAUTO_ROOT.scripts/session_bootstrap.shis the other half — the door anything can knock on to fix the session it is already in.bin/pyauto-braincalls it before dispatch, so no/verbruns unbootstrapped. Its--checkresolves each tool's shebang to report the interpreter it actually runs on, because a tool's own--versionsays nothing about that — and a 3.11 mypy is the whole problem.Tenant firewall: seven entries dropped or narrowed
FIREWALL_ALLOWLISTshrinks. Each of those entries named the owner only because it hardcoded a workspace root under$HOME; PyAutoBrain#289 makes those consumers delegate to resolvers that name no absolute path.Worth recording: the firewall check caught the first draft of that fix naming
~/Code/PyAutoLabsas a fallback — correctly, since an instance fact in organ code is precisely what caused the bug. The fallback proved redundant as well as wrong, so the list shrank instead of growing.Merge order
Mind's
firewall_gate.ymlchecks PyAutoBrain out pinned tomain, and this PR touchesscripts/repos_sync.py, so it triggers. Reproduced locally: 7 mismatches against the old Brain main, 0 against the merged one. PyAutoBrain#289 is merged, so this PR's first CI run lands against a main that satisfies it.Also in this PR
draft/feature/pyautobrain/board_without_gh.md— the follow-up prompt for the eleven board legs that read GitHub throughgh apiand stay dark in a remote session, carrying the measurements so the next session need not re-derive them. Cross-linked with the board's small-nit catch-all; dashboard regenerated in the same commit.Validation
lifecycle.py checkandrepos_sync.py --checkboth clean.tests/**KEEP-copy rule.ruffclean on every file touched.🤖 Generated with Claude Code
https://claude.ai/code/session_012PDoeCuecjutdnwkxsTqg7
Generated by Claude Code