fix(launchd): pin the nightly backup template to the keg interpreter (XS) - #817
fix(launchd): pin the nightly backup template to the keg interpreter (XS)#817EtanHey wants to merge 1 commit into
Conversation
…(XS) Found by the PR #815 pair review. #790 pinned every hook to the keg python; the launchd template for the nightly JSONL backup was missed and still shipped `/usr/bin/env python3`. That matters here for the reason AGENTS.md already documents: bare `python3` fronts the framework python, whose `_brainlayer.pth` injects `~/Gits/brainlayer/src`. So a `git checkout` at the repo root silently re-aims the job -- and the job in question is the one that PREVENTS data loss. The installed plist on this machine happens to be safe: it goes through brainlayer-env-run.sh with BRAINLAYER_PYTHON set to the keg. The template is what a reinstall would render, so the hazard is latent rather than active. That is exactly the shape that put a checkout's install.sh in front of every LaunchAgent on 09-05. The test reuses the gate #790 already built -- hook_python.is_pinned_interpreter -- rather than inventing a second definition of "pinned", so the two cannot drift. It walks every launchd template, judges only direct python invocations (a wrapper script makes no interpreter claim), and fails on anything it cannot vouch for. Verified RED against origin/main's plist and green with the pin. Co-Authored-By: brainlayerClaude running claude-opus-5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_129145ca-5652-4e3f-84a5-44976de6ab69) |
|
@codex review Focus: the test judges only Also worth a look: hardcoding the ARM Homebrew prefix makes the template machine-specific. — brainlayerClaude (lead) · claude-code/claude-opus-5 |
|
Warning Review limit reachedNext included review available in 35 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
BrainLayer ratchetEvery Value below was measured by this run. A row this machine cannot measure says
🟢 GREEN measured, within budget · 🔴 RED measured, out of budget — a finding to clear before merge · ⚪ n/a not measurable on this machine, never guessed. No RED rows. Measured on Linux/x86_64 · measured |
| python, whose _brainlayer.pth injects ~/Gits/brainlayer/src - so a `git checkout` | ||
| at the root would silently re-aim the nightly backup at a working tree. Same | ||
| reasoning as #790 for hooks; the `opt/` symlink outlives any single keg. --> | ||
| <string>/opt/homebrew/opt/brainlayer/libexec/venv/bin/python</string> |
There was a problem hiding this comment.
🟠 High launchd/com.brainlayer.jsonl-backup.plist:17
On Intel Homebrew installations, the scheduled backup cannot start because /opt/homebrew/opt/brainlayer/libexec/venv/bin/python does not point to the installed keg at /usr/local/opt/brainlayer/libexec/venv/bin/python. Render the actual Homebrew prefix/interpreter or invoke a prefix-aware wrapper instead of hard-coding /opt/homebrew.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @launchd/com.brainlayer.jsonl-backup.plist around line 17:
On Intel Homebrew installations, the scheduled backup cannot start because `/opt/homebrew/opt/brainlayer/libexec/venv/bin/python` does not point to the installed keg at `/usr/local/opt/brainlayer/libexec/venv/bin/python`. Render the actual Homebrew prefix/interpreter or invoke a prefix-aware wrapper instead of hard-coding `/opt/homebrew`.
Summary
Found by the PR #815 pair review (finding 5). #790 pinned every hook to the keg python; the launchd template for the nightly JSONL backup was missed and still shipped
/usr/bin/env python3.That matters for the reason
AGENTS.mdalready documents: barepython3fronts the framework python, whose_brainlayer.pthinjects~/Gits/brainlayer/src. Agit checkoutat the repo root therefore silently re-aims the job — and the job here is the one that prevents data loss.Latent, not active — and why it still matters
The installed plist on this machine is safe: it runs through
brainlayer-env-run.shwithBRAINLAYER_PYTHONset to the keg. I measured that directly. The template is what a reinstall renders, so the hazard is latent rather than live.That distinction is the whole point of shipping this separately: it is exactly the shape that put a checkout's
install.shin front of every LaunchAgent on 09-05. The reviewer and I initially disagreed here — we had each measured a different file, and both measurements were correct.The test reuses the existing gate
test_launchd_plist_templates_pin_their_interpretercallshook_python.is_pinned_interpreter— the gate #790 already built — rather than inventing a second definition of "pinned", so the two cannot drift apart. It walks every launchd template, judges only direct python invocations (a wrapper script makes no interpreter claim), and fails on anything it cannot vouch for, per that gate's affirmative stance.Verified RED against
origin/main's plist and green with the pin. 88 passed, 1 skipped.Scope
jsonl-backupwas the only one invoking python via PATH.install.sh, or the wrapper scripts.com.brainlayer.jsonl-backup— that stays unloaded pending fix(backup): never treat a file as covered without a surviving archive object (S) #815 merging and installing.Bot policy
Read
brainlayer/AGENTS.md→ "Do not route mandatory reviews to Bugbot or Greptile" → panel = CodeRabbit + Codex only. Non-core diff (a plist template and a test), so Bugbot is off by tiering as well.— brainlayerClaude (lead) · claude-code/claude-opus-5
Note
Low Risk
Template-only interpreter pin plus a regression test; no runtime auth, data, or install-script changes.
Overview
Fixes a gap left after #790: the launchd template for the nightly JSONL backup still invoked
/usr/bin/env python3, so a reinstall could run the backup through PATH/framework python and silently pick up a checkout via_brainlayer.pth— risky for the job that prevents data loss.The template now calls
/opt/homebrew/opt/brainlayer/libexec/venv/bin/pythondirectly (with an inline comment matching the hooks rationale).Adds
test_launchd_plist_templates_pin_their_interpreter, which walks everylaunchd/*.plist, treats/usr/bin/env …as unpinned, and reuseshook_python.is_pinned_interpreterso launchd and hook policy stay aligned.Reviewed by Cursor Bugbot for commit dee6a59. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Pin nightly backup launchd template to keg interpreter
Replaces
/usr/bin/env python3in the launchd backupProgramArgumentswith the Homebrew keg virtual-environment interpreter at/opt/homebrew/opt/brainlayer/libexec/venv/bin/python, using the stableopt/symlink. Risk: the job now fails if the Brainlayer keg is unlinked or theopt/symlink is removed, since it no longer falls back to PATH-resolvedpython3.📊 Macroscope summarized dee6a59. 1 file reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted
🗂️ Filtered Issues