Skip to content

chore(brainbar): release deploy + never-again deploy-check rule#250

Closed
EtanHey wants to merge 1 commit intomainfrom
chore/brainbar-release-deploy-check
Closed

chore(brainbar): release deploy + never-again deploy-check rule#250
EtanHey wants to merge 1 commit intomainfrom
chore/brainbar-release-deploy-check

Conversation

@EtanHey
Copy link
Copy Markdown
Owner

@EtanHey EtanHey commented Apr 18, 2026

Summary

  • add a mandatory post-merge BrainBar deploy checklist to CLAUDE.md
  • document the exact release-build and launchd plist verification steps
  • capture the 2026-04-18 failure mode so future BrainBar merges do not stop at PR merge

Runtime verification

  • rebuilt BrainBar in release mode from ~/Gits/brainlayer/brain-bar
  • relaunched com.brainlayer.brainbar from /Users/etanheyman/Gits/brainlayer/brain-bar/.build/release/BrainBar
  • verified /tmp/brainbar.sock returned and CPU settled near idle after relaunch

Note

Low Risk
Documentation-only change that adds an operational checklist; no runtime code or configuration is modified.

Overview
Adds a mandatory post-merge deploy checklist to CLAUDE.md for any PR touching brain-bar/, requiring a release rebuild and verification that the launchd plist points to the canonical .build/release/BrainBar path (not a debug/worktree binary).

Documents the specific launchctl commands for reload/kickstart, plus verification steps (PID path, /tmp/brainbar.sock, CPU sanity) and an emergency stop procedure to prevent repeats of the prior “merged but not deployed” incident.

Reviewed by Cursor Bugbot for commit 2cf4214. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add post-merge BrainBar deploy check documentation to CLAUDE.md

Adds a mandatory Post-Merge BrainBar Deploy Check section to CLAUDE.md with step-by-step instructions for building a release binary and verifying the launchd service after merging. Covers correcting plist paths from debug/worktree to release builds, restart procedures, runtime verification (PID, socket, CPU), and an emergency stop command.

Macroscope summarized 2cf4214.

Summary by CodeRabbit

  • Documentation
    • Added post-merge deployment verification procedures for BrainBar, including build configuration checks, configuration validation, and runtime verification steps.

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 18, 2026

📝 Walkthrough

Walkthrough

Added a "Post-Merge BrainBar Deploy Check" section to CLAUDE.md documenting a release-build and verification procedure for brain-bar/ changes, including steps to validate the LaunchAgent plist, update runtime paths, restart the launchd job, and confirm proper execution.

Changes

Cohort / File(s) Summary
Documentation
CLAUDE.md
Added mandatory post-merge deployment verification guide for BrainBar, including build configuration, LaunchAgent plist validation, binary path updates, job restart procedures, and PID/socket/CPU behavior checks.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

Poem

🐰 A checklist hops into the docs so fine,
Release builds and plists, all in line,
LaunchAgents wake with verified delight,
BrainBar bounces left and right!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: adding mandatory post-merge BrainBar deploy checks and release deployment procedures to CLAUDE.md.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/brainbar-release-deploy-check

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CLAUDE.md`:
- Around line 40-41: The plist doc currently shows using '~' in the
ProgramArguments and WorkingDirectory values which launchd will not expand;
update the lines that mention ProgramArguments and WorkingDirectory to use
absolute paths (e.g.,
/Users/<user>/Gits/brainlayer/brain-bar/.build/release/BrainBar and
/Users/<user>/Gits/brainlayer/brain-bar) instead of '~/...' and include a clear
example showing the full absolute path so readers replace <user> with their
username.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 47d59960-123d-4e9e-9f11-3a1f8e75b5b5

📥 Commits

Reviewing files that changed from the base of the PR and between 05b2eaf and 2cf4214.

📒 Files selected for processing (1)
  • CLAUDE.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: test (3.12)
  • GitHub Check: test (3.11)
  • GitHub Check: test (3.13)
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: EtanHey/brainlayer

Timestamp: 2026-04-18T16:19:46.390Z
Learning: BrainLayer project must resolve database path via `paths.py:get_db_path()` which supports environment variable override (`BRAINLAYER_DB_PATH`) or canonical path `~/.local/share/brainlayer/brainlayer.db`
Learnt from: CR
Repo: EtanHey/brainlayer

Timestamp: 2026-04-18T16:19:46.390Z
Learning: Always use `brain_search` before answering questions about project history, architecture, or past decisions; use `brain_store` after making decisions, hitting bugs, or receiving corrections
Learnt from: CR
Repo: EtanHey/brainlayer

Timestamp: 2026-04-18T16:19:46.390Z
Learning: Extract and enrich sessions using entity extraction rules: capitalized names, PascalCase identifiers, URLs, and code paths via the `brain_digest` tool
Learnt from: CR
Repo: EtanHey/brainlayer

Timestamp: 2026-04-18T16:19:46.390Z
Learning: Post-merge deploy check for brain-bar PRs is mandatory: verify release build, update launchd plist if needed, kickstart daemon, verify PID and CPU usage
📚 Learning: 2026-03-17T01:04:22.497Z
Learnt from: EtanHey
Repo: EtanHey/brainlayer PR: 0
File: :0-0
Timestamp: 2026-03-17T01:04:22.497Z
Learning: Applies to src/brainlayer/mcp/**/*.py and brain-bar/Sources/BrainBar/MCPRouter.swift: The 8 required MCP tools are `brain_search`, `brain_store`, `brain_recall`, `brain_entity`, `brain_expand`, `brain_update`, `brain_digest`, `brain_tags`. `brain_tags` is the 8th tool, replacing `brain_get_person`, as defined in the Phase B spec merged in PR `#72`. The Python MCP server already implements `brain_tags`. Legacy `brainlayer_*` aliases must be maintained for backward compatibility.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-17T01:04:11.749Z
Learnt from: EtanHey
Repo: EtanHey/brainlayer PR: 0
File: :0-0
Timestamp: 2026-03-17T01:04:11.749Z
Learning: The socket path `/tmp/brainbar.sock` is intentional for the BrainBar Swift daemon (brain-bar/) and must NOT be changed to `/tmp/brainlayer.sock`. BrainBar is a new daemon that coexists with the existing Python `brainlayer-mcp` (which uses `/tmp/brainlayer.sock`) during the migration period. The different paths avoid conflicts and allow A/B testing. Once BrainBar is proven stable, the Python server will be retired and `.mcp.json` will point to `/tmp/brainbar.sock` via socat.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-17T01:04:22.497Z
Learnt from: EtanHey
Repo: EtanHey/brainlayer PR: 0
File: :0-0
Timestamp: 2026-03-17T01:04:22.497Z
Learning: In BrainLayer, the BrainBar daemon uses the socket path `/tmp/brainbar.sock` (NOT `/tmp/brainlayer.sock`). BrainBar is a new native Swift daemon designed to coexist with the existing Python `brainlayer-mcp` server during the migration period. Different socket paths avoid conflicts and enable A/B testing. Once BrainBar is proven stable, the Python server will be retired.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-18T00:12:15.607Z
Learnt from: EtanHey
Repo: EtanHey/brainlayer PR: 87
File: brain-bar/Sources/BrainBar/BrainBarServer.swift:118-129
Timestamp: 2026-03-18T00:12:15.607Z
Learning: In `brain-bar/Sources/BrainBar/MCPRouter.swift` (Swift, BrainBar daemon), the socket-before-DB startup pattern means the Unix socket binds immediately (~1ms) while the database may take several seconds to open on cold start (8GB file). Any tool handler that accesses `database` MUST throw an explicit error (e.g., `ToolError.noDatabase`) when `database` is nil — never return empty or default results (e.g., `guard let db else { return "[]" }` is forbidden). The false-success pattern hides startup timing issues from MCP clients. Flag any `guard let db = database else { return ... }` patterns that silently return defaults instead of throwing.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-04-13T14:12:32.868Z
Learnt from: EtanHey
Repo: EtanHey/brainlayer PR: 239
File: scripts/launchd/com.brainlayer.decay.plist:8-24
Timestamp: 2026-04-13T14:12:32.868Z
Learning: In `src/brainlayer/decay_job.py`, `run_decay_job()` is intentionally platform-neutral and must NOT contain any macOS launchd-specific logic (e.g., `launchctl unload/load`). It is used by the CLI and tests. Any enrichment-agent coordination around decay should be handled in a launchd wrapper or a dedicated follow-up command, not inside the shared decay function.

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-14T02:20:54.656Z
Learnt from: CR
Repo: EtanHey/brainlayer PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-14T02:20:54.656Z
Learning: Treat retrieval correctness, write safety, and MCP stability as critical-path concerns in BrainLayer reviews

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-04-06T11:15:05.940Z
Learnt from: CR
Repo: EtanHey/brainlayer PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-06T11:15:05.940Z
Learning: Applies to src/brainlayer/watcher*.py : Real-time watcher via LaunchAgent (`com.brainlayer.watch.plist`) uses 4-layer content filters: entry type whitelist → classify → chunk min-length → system-reminder strip

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-03-14T02:20:54.656Z
Learnt from: CR
Repo: EtanHey/brainlayer PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-14T02:20:54.656Z
Learning: Request codex review, cursor review, and bugbot review for BrainLayer PRs

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-04-01T22:38:15.693Z
Learnt from: CR
Repo: EtanHey/brainlayer PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T22:38:15.693Z
Learning: Applies to src/brainlayer/mcp/brain_supersede.py : `brain_supersede` tool must include safety gate for personal data (journals, notes, health/finance)

Applied to files:

  • CLAUDE.md
📚 Learning: 2026-04-01T01:24:44.281Z
Learnt from: CR
Repo: EtanHey/brainlayer PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-01T01:24:44.281Z
Learning: Applies to src/brainlayer/mcp/*.py : MCP tools include: brain_search, brain_store, brain_recall, brain_entity, brain_expand, brain_update, brain_digest, brain_get_person, brain_tags, brain_supersede, brain_archive (legacy brainlayer_* aliases still supported)

Applied to files:

  • CLAUDE.md
🔇 Additional comments (1)
CLAUDE.md (1)

26-60: Strong operational checklist; this directly addresses the prior non-deployed-merge failure mode.

The release-build + plist-target + kickstart + PID/socket/CPU verification sequence is concrete and actionable. The /tmp/brainbar.sock validation is also aligned with BrainBar’s intended socket separation.

Based on learnings: “Post-merge deploy check for brain-bar PRs is mandatory: verify release build, update launchd plist if needed, kickstart daemon, verify PID and CPU usage” and “The socket path /tmp/brainbar.sock is intentional for the BrainBar Swift daemon.”

Comment thread CLAUDE.md
Comment on lines +40 to +41
- Update plist `ProgramArguments` to point at `~/Gits/brainlayer/brain-bar/.build/release/BrainBar` (canonical release path)
- Update `WorkingDirectory` to `~/Gits/brainlayer/brain-bar`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether plist currently contains non-absolute paths for launchd keys.
PLIST="$HOME/Library/LaunchAgents/com.brainlayer.brainbar.plist"

plutil -p "$PLIST" | sed -n '1,220p'
echo "---- Potentially unsafe tilde usage ----"
plutil -p "$PLIST" | rg -n '"~/' || true

echo "---- ProgramArguments + WorkingDirectory ----"
plutil -extract ProgramArguments json -o - "$PLIST" 2>/dev/null || true
plutil -extract WorkingDirectory raw -o - "$PLIST" 2>/dev/null || true

Repository: EtanHey/brainlayer

Length of output: 255


🏁 Script executed:

# Locate and read CLAUDE.md around lines 40-41
git ls-files | grep -i claude

Repository: EtanHey/brainlayer

Length of output: 344


🏁 Script executed:

# If CLAUDE.md exists, read the relevant section
if [ -f CLAUDE.md ]; then
  echo "=== CLAUDE.md lines 30-55 (context around 40-41) ==="
  sed -n '30,55p' CLAUDE.md
fi

Repository: EtanHey/brainlayer

Length of output: 2343


🏁 Script executed:

# Search for plist files in the repo
find . -name "*.plist" -type f 2>/dev/null | head -20

Repository: EtanHey/brainlayer

Length of output: 371


🏁 Script executed:

# Search for references to launchd, plist, ProgramArguments, or WorkingDirectory
rg -i "(launchd|plist|programarguments|workingdirectory)" --type md --type json -A 2 -B 2 | head -100

Repository: EtanHey/brainlayer

Length of output: 7242


🏁 Script executed:

# Read the actual plist file to see current path format
cat ./brain-bar/bundle/com.brainlayer.brainbar.plist

Repository: EtanHey/brainlayer

Length of output: 796


🏁 Script executed:

# Check other plist files in repo for path patterns
for plist in $(find . -name "*.plist" -type f 2>/dev/null); do
  echo "=== $plist ==="
  grep -E "(ProgramArguments|WorkingDirectory|<string>.*/" "$plist" 2>/dev/null | head -20
done

Repository: EtanHey/brainlayer

Length of output: 427


🌐 Web query:

launchd plist tilde expansion ProgramArguments WorkingDirectory

💡 Result:

In launchd plist files, tilde () expansion behaves as follows: ProgramArguments: Tilde () is not expanded by default. Strings are treated literally, like shell single-quoted arguments—no shell expansion, variables, or tilde. With EnableGlobbing true (pre-macOS 10.10), glob(3) expands wildcards (*) and tildes (~) in ProgramArguments. EnableGlobbing deprecated since macOS 10.10; ignored with warning. Workaround: invoke shell (/bin/sh -c 'command arg') for expansion. WorkingDirectory: Tilde () not expanded; literal string causes chdir failure ("no such file"). Default if absent: /. Use absolute path (e.g., $HOME from script or full /Users/user). Relative paths resolve from default /. Examples: ProgramArguments /bin/sh -c exec /path/to/program ~/"arg with space" WorkingDirectory /Users/$(whoami)/path # But $ not expanded; use script or absolute. For user agents (~Library/LaunchAgents), default cwd /, not ~. Use shell scripts for complex paths. Status as of 2026: No native tilde in plist keys except possibly WatchPaths/QueueDirectories; confirm via man launchd.plist(5).

Citations:


Use absolute paths in plist values, not ~.

The documentation at lines 40-41 instructs updating ProgramArguments and WorkingDirectory to use ~, but launchd does not expand tilde in plist string values—it treats them literally. Users following this guidance will write literal ~ into the plist, causing the daemon to fail to start when it cannot resolve the path. Update the documentation to specify absolute paths (e.g., /Users/<user>/Gits/brainlayer/brain-bar/) instead.

Suggested doc fix
-   - Update plist `ProgramArguments` to point at `~/Gits/brainlayer/brain-bar/.build/release/BrainBar` (canonical release path)
-   - Update `WorkingDirectory` to `~/Gits/brainlayer/brain-bar`
+   - Update plist `ProgramArguments` to point at `/Users/<your-username>/Gits/brainlayer/brain-bar/.build/release/BrainBar` (canonical release path; use absolute path, not `~`)
+   - Update `WorkingDirectory` to `/Users/<your-username>/Gits/brainlayer/brain-bar` (absolute path; launchd does not expand `~`)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Update plist `ProgramArguments` to point at `~/Gits/brainlayer/brain-bar/.build/release/BrainBar` (canonical release path)
- Update `WorkingDirectory` to `~/Gits/brainlayer/brain-bar`
- Update plist `ProgramArguments` to point at `/Users/<your-username>/Gits/brainlayer/brain-bar/.build/release/BrainBar` (canonical release path; use absolute path, not `~`)
- Update `WorkingDirectory` to `/Users/<your-username>/Gits/brainlayer/brain-bar` (absolute path; launchd does not expand `~`)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` around lines 40 - 41, The plist doc currently shows using '~' in
the ProgramArguments and WorkingDirectory values which launchd will not expand;
update the lines that mention ProgramArguments and WorkingDirectory to use
absolute paths (e.g.,
/Users/<user>/Gits/brainlayer/brain-bar/.build/release/BrainBar and
/Users/<user>/Gits/brainlayer/brain-bar) instead of '~/...' and include a clear
example showing the full absolute path so readers replace <user> with their
username.

@EtanHey
Copy link
Copy Markdown
Owner Author

EtanHey commented May 2, 2026

Closing: superseded by Phase B preventive infra shipped 2026-05-01 (orc#60 + brainlayer#264/#265). The deploy-check rule + canonical-deploy-registry are now live on main. (Triage 2026-05-02 reliability sprint Phase 4.)

@EtanHey EtanHey closed this May 2, 2026
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.

1 participant