You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(brainbar): Backups recovery checks, centred status dots, one Config file row (Etan E1/E4/E5) - #1064
Six checks with human labels, plain states and relative times ("Verified 1 hour ago", "Paused by a safety stop", "A copy is older than 36 hours"), under one verdict ("All 6 checks pass" / "3 of 6 checks need attention"). The checks use the page's card language.
No Drive ID, file name or launchd label in the default view. They sit under Technical details (closed by default), each value selectable, each with Copy.
Light/dark: every capture was rendered under the aqua and darkAqua appearances (light example). The pairs match pixel for pixel except the Drive card's "renews by …" minute digits, which come from the wall clock at render time. BrainBar pins its own dark scheme.
Tests (written failing first)
BrainBarBackupChecksTests (12):
human labels and values, with relative times;
the default view never contains a Drive ID, file name, launchd label or .disabled-retention-P0;
the raw values live in details;
parked, unverified, missing, stale, failed and unknown states;
each check tone equals the status line it replaces;
job alerts and the restored-credential note;
relative time is never in the future;
the badge reason never names the launchd label;
Config file Copy/Reveal go through the model's own store path.
BrainBarStatusDotTests (2) measure in pixels: the dot is within 0.5 pt of the cap centre at all 5 sizes the app uses, and the old bare Circle is shown to fail.
DeepSource closure-naming findings fixed in b4e1812a. Rebased on feat(brainbar): show a job alert once per screen, with Show log, cleared by a clean run #10624f7d1090. Full suite at c4c75fe5 plus that DEBUG-harness rename (×3): 1073 UI + 10 daemon tests, 0 failures. The one CI swift (macos-15) failure was a silent xctest exit in MCPRouterTests (pending-queue area, untouched here); it passed on rerun of the same SHA.
Size L: 815 added lines = 354 product + 301 tests + 104 debug-only render harness + 56 README. The handoff asked for E1/E4/E5 as one PR.
Low Risk
BrainBar presentation and settings UI only, with broad unit tests and no changes to backup execution or auth.
Overview
Addresses Etan feedback (E1/E4/E5) on the Backups and settings UX.
E1 — Recovery checks: The Backups page no longer shows raw ObservabilityStatusRows. It now derives BrainBarBackupChecks (plain-language checks with tones tied to existing status lines) and renders BrainBarBackupChecksCard, including a collapsed Technical details section with selectable values and Copy. The combined backups badge can use the checks’ attentionSentence, and backupsBadgeReason drops reasons already shown on the job-alert, Drive, or recovery cards. Duplicate LAST/NEXT RUN rows are removed from the Backups job group card (Schedule owns timing).
E4 — Status dots:BrainBarStatusDot replaces bare Circle markers on the Drive card, dashboard status strip, attention items, and observability rows so dots align with label cap height.
E5 — Config path: The brainlayer.env path is removed from every page header; Advanced gets a single Config file row with Copy path / Reveal in Finder, and backup schedule local-copy names become selectable.
The DEBUG render harness adds renderEtanRowsE1E4E5, aligns fixture clocks for coherent renders, and requires Vision OCR to miss labels on three passes before failing. New BrainBarBackupChecksTests and BrainBarStatusDotTests cover wording, tone parity, and pixel alignment.
Reviewed by Cursor Bugbot for commit db97e1a. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add Backups recovery-check card, centered status dots, and single Advanced Config file row
Replaces the Backups page status-row list with BrainBarBackupChecksCard, showing six plain-language checks (upload, database copy, scheduling, freshness, retention, archive) with a combined verdict. Raw identifiers such as drive IDs, filenames, and launchd labels move into a collapsible Technical details section with copy actions.
Adds a reusable BrainBarStatusDot component in BrainBarStatusDot.swift that centers dots on the label's text line. It replaces bare circles in the dashboard, Drive auth card, and observability rows.
Moves the config-file path out of page headers into one Config file row on the Advanced page, with Copy path and Reveal in Finder actions.
Suppresses Backups badge reasons already shown by another card, and removes duplicate last-run/next-run rows from the Backups group card. The red Backups health verdict now uses the recovery-check attention sentence.
Risk: BrainBarJobGroupCard takes a caller-supplied Backups reason and drops its direct job-alert hiding case; other job-group cards still show run timings. backupStatus falls back to the old status-row list only when measured observability is unavailable. Check these two paths in BrainBarSettingsView.swift.
Every Value below was measured by this run. A row this machine cannot measure says n/a — <reason> instead of a number; baselines in Notes name their own machine, method and date and were not measured here.
Row
Status
Value (measured by this run)
Method
Notes
commit provenance
🟢 GREEN
measured db97e1a6dc8a == PR head · checkout 4e2f08a9a7a0
commit graph + live PR head · in-process · runner
Which commit this whole table is about. On a pull_request event the checkout is GitHub's synthetic merge ref, whose sha is not on the PR — #759's table printed 13fa724278bf while that PR's head was 4632f979 — so this row names the PR-head parent instead, the sha a reviewer can actually see. The comparison sha is read live from repos/{owner}/{repo}/pulls/{n} when the table is collected, not taken from the event payload, because the payload cannot know the run has been overtaken. Residual window, stated rather than papered over: a push landing between that read and the comment being posted is not caught here — the run for that push refreshes the table.
baseline attestation
🟢 GREEN
baseline f421d1a7c5e6 unchanged from base 9255e12d5082 by git · the attestation is for main e59cf87142c8, not this checkout's base 9255e12d5082
main attestation artifact via Actions API · in-process · runner
What every comparison is measured AGAINST, and who says so. The baseline fields of tests/fixtures/sprint_gate/corpus.json (queries, latency_baseline_ms, thresholds) are compared to the ratchet-attestation artifact of the latest successful push or (no-input) workflow_dispatch run of ratchet-attest.yml on main, fetched through the Actions API — a PR run cannot write to another run's artifacts. A field that differs is RED unless that main run measured the new value. The calibrated socket collector can license p50/p95; every absent measured path stays locked, so missing collection never passes as permission for a hand edit. Boundary: the comparator is this PR's checkout of ci_ratchet_table.py, diff-reviewable, not tamper-proof.
provenance
🟢 GREEN
stamped 4e2f08a9a7a0 == HEAD, tree clean
wheel stamp · in-process · runner
Sha half of #749 keg-mode provenance: a keg built from this wheel can answer __build_sha__. The helper-age and served-process predicates need a running BrainBar and are measured only by scripts/sprint_gate.py on an installed Mac. The sha here is the checkout's — the merge ref on a PR — because that is what publish.yml stamps at release time; the PR-head sha this table describes is the one in commit provenance above.
fallback replay debt
⚪ n/a
n/a — no fallback queue on this machine: the pending memories live in ~/Gits/*/docs.local/decisions, and docs.local/ is gitignored, so a runner checkout has no copy of them to count
docs.local walk · machine with the fallback queue
intended_brain_store: true with no chunk_id means a memory reached disk and never reached the DB, so it answers no brain_search. Budget: 0. Any pending or unparseable file is a finding, never a band -- 122 of these sat from 2026-06-28 to 2026-09-05 because nothing counted them where a reader would look. Measured by walking the tree, so it is only ever measured on a machine that HAS the tree.
mapped bytes
⚪ n/a
n/a — no BrainBar daemon at /tmp/brainbar.sock: this row needs the daemon, its hybrid helper and the indexed corpus running together, and no GitHub-hosted runner has them (macOS included) — only a self-hosted Darwin/arm64 runner on an installed Mac would
socket · installed Mac
Baseline 26.2 GB — installed Mac, socket, 2026-09-03, after R2 drained 15,070 → 0. Up from 16.8 GB because the drain left more vectors mapped under the same cap: the change is the drain, not a leak. Not measured by this run.
search p50/p95
⚪ n/a
n/a — no BrainBar daemon at /tmp/brainbar.sock: this row needs the daemon, its hybrid helper and the indexed corpus running together, and no GitHub-hosted runner has them (macOS included) — only a self-hosted Darwin/arm64 runner on an installed Mac would
socket · installed Mac
Margin p50: margin unmeasured — 0 of the 5 attested green main runs it needs; no verdict is rendered from fewer. Margin p95: margin unmeasured — 0 of the 5 attested green main runs it needs; no verdict is rendered from fewer. Calibrated on MacBook-Pro.local at 2026-09-01T08:42:22Z under active_sprint_load (tests/fixtures/sprint_gate/corpus.json). Not measured by this run.
idle CPU
⚪ n/a
n/a — no BrainBar daemon at /tmp/brainbar.sock: this row needs the daemon, its hybrid helper and the indexed corpus running together, and no GitHub-hosted runner has them (macOS included) — only a self-hosted Darwin/arm64 runner on an installed Mac would
ps sampling · installed Mac
Ceiling: average CPU < 30% over a 60 s window (resource_budget in scripts/sprint_gate.py), ratified and kept as a hard budget. Margin daemon: margin unmeasured — 0 of the 5 attested green main runs it needs; no verdict is rendered from fewer. Margin helper: margin unmeasured — 0 of the 5 attested green main runs it needs; no verdict is rendered from fewer. Margin watcher: margin unmeasured — 0 of the 5 attested green main runs it needs; no verdict is rendered from fewer. Needs the BrainBar daemon, helper and watcher actually running. Not measured by this run.
signature_valid
⚪ n/a
n/a — the macOS signature-parity job is trigger-gated and did not run on this PR: it touches no release or signing path (pyproject.toml, scripts/release-*, scripts/brainlayer-version-check.sh, publish.yml, ratchet.yml) and carries no ratchet:signatures label — a GitHub macOS runner bills at ~10× Linux minutes and rebuilds the keg venv from source
codesign · installed keg
scripts/release-verify-signatures.sh <keg> codesign-verifies every *.so/*.dylib under libexec/venv. The macOS parity job installs the published tap formula (etanhey/layers/brainlayer), so this row measures the release path — formula, published sdist and Homebrew's relocation — and not this PR's tree. Release-time baseline for the same keg on a different machine: 442 valid / 0 invalid — installed Mac (M4 Max), brew --prefix brainlayer 1.5.11, 2026-09-03.
🟢 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 db97e1a6dc8a · PR head db97e1a6dc8a · checkout 4e2f08a9a7a0 · run · updated 2026-10-04 14:14:35 UTC
We reviewed changes in 2f0c2d4...db97e1a on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.
Some issues found as part of this review are outside of the diff in this pull request and aren't shown in the inline review comments due to GitHub's API limitations. You can see those issues on the DeepSource dashboard.
AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.
The reason will be displayed to describe this comment to others. Learn more.
Use named arguments in multiline closures
When using closures in Swift with multiple parameters, it is often necessary to split the closure into multiple lines to improve readability. However, if the arguments are not named explicitly, it can be difficult to determine which argument a particular line refers to. This can lead to bugs and make the code harder to understand and maintain. To improve the readability and maintainability of your code, it is recommended to use named arguments in closures that span multiple lines. This makes it clear which argument each line is referring to, and can make the code much easier to follow.
The reason will be displayed to describe this comment to others. Learn more.
Force unwrapping should be avoided
Force unwrapping should be avoided in Swift as it can lead to runtime errors and crashes. Force unwrapping is when an optional value is forcefully unwrapped using the exclamation mark (!) operator without checking if the value is nil or not. This can result in a fatal error if the optional value is actually nil at runtime.
The reason will be displayed to describe this comment to others. Learn more.
Use named arguments in multiline closures
When using closures in Swift with multiple parameters, it is often necessary to split the closure into multiple lines to improve readability. However, if the arguments are not named explicitly, it can be difficult to determine which argument a particular line refers to. This can lead to bugs and make the code harder to understand and maintain. To improve the readability and maintainability of your code, it is recommended to use named arguments in closures that span multiple lines. This makes it clear which argument each line is referring to, and can make the code much easier to follow.
The reason will be displayed to describe this comment to others. Learn more.
Use named arguments in multiline closures
When using closures in Swift with multiple parameters, it is often necessary to split the closure into multiple lines to improve readability. However, if the arguments are not named explicitly, it can be difficult to determine which argument a particular line refers to. This can lead to bugs and make the code harder to understand and maintain. To improve the readability and maintainability of your code, it is recommended to use named arguments in closures that span multiple lines. This makes it clear which argument each line is referring to, and can make the code much easier to follow.
The reason will be displayed to describe this comment to others. Learn more.
Returning values from Void functions should be avoided
Returning values from a function that is declared to return Void is unnecessary and can lead to confusion and potential bugs in the code. Here are a few reasons why returning values from a Void function should be avoided:
…un source (lead UX r1 on #1064)
- The Backups header keeps only its badge: a reason another card on the page
already states (a recovery check, the Drive card, the job-alert card) is not
repeated; one shown nowhere else still is.
- The Backups page drops the monospace LAST RUN / NEXT RUN rows; the Schedule
section is the single source (the Jobs page keeps them).
- Render fixtures use one clock (no 2023 beside "today"); a parked job reads
"Not scheduled".
- Harness: a Dashboard OCR label must be missing on three Vision passes before
the render fails (review N1).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Round 1 (lead UX) addressed in ae51a1c0 (rebased on #1062695065c4)
Each failure shows once: the Backups header keeps only its badge. A reason that another card already states (a recovery check, the Drive card, the job-alert card) isn't repeated; one shown nowhere else still is. Test: test_the_backups_header_never_repeats_a_reason_the_page_already_shows.
LAST RUN / NEXT RUN rows removed from the Backups page. Schedule is the single source; the Jobs page keeps its rows.
Coherent fixture times: one clock for the Schedule rows, the checks, Technical details, the local-copy names and the Drive renewal. A parked job reads "Not scheduled" with no next run. Light and dark Backups captures are now byte-identical.
N1 (OCR): a label must be missing on three Vision passes before the render fails. The full harness exits 0 on 3 consecutive runs.
E4 re-measured on the new renders: 0.00 pt at all three widths.
Full suite @ ae51a1c0, ×3 sequential: 1070 UI tests, 3 skipped, 0 failures, plus 10 daemon tests, 0 failures, exit 0 each time.
The reason will be displayed to describe this comment to others. Learn more.
Use named arguments in multiline closures
When using closures in Swift with multiple parameters, it is often necessary to split the closure into multiple lines to improve readability. However, if the arguments are not named explicitly, it can be difficult to determine which argument a particular line refers to. This can lead to bugs and make the code harder to understand and maintain. To improve the readability and maintainability of your code, it is recommended to use named arguments in closures that span multiple lines. This makes it clear which argument each line is referring to, and can make the code much easier to follow.
The reason will be displayed to describe this comment to others. Learn more.
Use named arguments in multiline closures
When using closures in Swift with multiple parameters, it is often necessary to split the closure into multiple lines to improve readability. However, if the arguments are not named explicitly, it can be difficult to determine which argument a particular line refers to. This can lead to bugs and make the code harder to understand and maintain. To improve the readability and maintainability of your code, it is recommended to use named arguments in closures that span multiple lines. This makes it clear which argument each line is referring to, and can make the code much easier to follow.
…un source (lead UX r1 on #1064)
- The Backups header keeps only its badge: a reason another card on the page
already states (a recovery check, the Drive card, the job-alert card) is not
repeated; one shown nowhere else still is.
- The Backups page drops the monospace LAST RUN / NEXT RUN rows; the Schedule
section is the single source (the Jobs page keeps them).
- Render fixtures use one clock (no 2023 beside "today"); a parked job reads
"Not scheduled".
- Harness: a Dashboard OCR label must be missing on three Vision passes before
the render fails (review N1).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…fig file row (Etan E1/E4/E5)
E1: the Backups page's ad-hoc status list becomes "Recovery checks": six
checks with human labels, plain states and relative times, one verdict, and
the raw Drive IDs / file names / launchd label behind a Technical details
disclosure where every value is selectable with Copy. The Backups badge's
reason uses the same words; each check keeps its status line's tone (#1029 B1).
E4: BrainBarStatusDot centres a status dot on its label's line (measured
before +1.00 pt low, after 0.00 pt) on the Drive card, the backup status rows
and the Dashboard status strip and attention items.
E5: no config path under any page title; Advanced has one Config file row
(what it is, selectable path, Copy path, Reveal in Finder). Backup local-copy
file names are selectable.
Render proof: brain-bar/docs/ui-renders/2026-10-04-etan-e1-e4-e5/.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…un source (lead UX r1 on #1064)
- The Backups header keeps only its badge: a reason another card on the page
already states (a recovery check, the Drive card, the job-alert card) is not
repeated; one shown nowhere else still is.
- The Backups page drops the monospace LAST RUN / NEXT RUN rows; the Schedule
section is the single source (the Jobs page keeps them).
- Render fixtures use one clock (no 2023 beside "today"); a parked job reads
"Not scheduled".
- Harness: a Dashboard OCR label must be missing on three Vision passes before
the render fails (review N1).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merged. Opus brainlayerClaude-a877a8e3 implemented; Codex brainlayerCodex-59f5acee reviewed in 2 rounds (round 2: #1062 PASS; #1064 PASS on code, with the render-proof finding accepted by the lead as dark-only, since BrainBar pins colorScheme(.dark); the mislabelled light renders are tracked in #1067). Merge order: #1062 → retarget #1064 to main → #1064. Installed-app proof comes with the next BL release. The socket-test flake is pre-existing (#1066).
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
size:LTight-loop PR size: over 400 hand-written lines added; canon 9 needs a one-line why
1 participant
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.
Why
Etan's rows, 2026-10-01 (
etan-feedback-1445.md):brainlayer.envpath under every page title is "repetitive… I don't know what it even means".What changed
E1: Recovery checks (
BrainBarBackupChecks+BrainBarBackupChecksCard)E4:
BrainBarStatusDot.top-aligned and rode high) and attention items.E5: Paths
Render proof
Committed in
brain-bar/docs/ui-renders/2026-10-04-etan-e1-e4-e5/. Before is the same render pass built on this PR's base (6b7aa3bc); after is this branch. Fixtures only.Light/dark: every capture was rendered under the
aquaanddarkAquaappearances (light example). The pairs match pixel for pixel except the Drive card's "renews by …" minute digits, which come from the wall clock at render time. BrainBar pins its own dark scheme.Tests (written failing first)
BrainBarBackupChecksTests(12):.disabled-retention-P0;BrainBarStatusDotTests(2) measure in pixels: the dot is within 0.5 pt of the cap centre at all 5 sizes the app uses, and the old bareCircleis shown to fail.changed-onlygate passed.Not done here
Provenance
Implementer: brainlayerClaude-a877a8e3 (Claude Opus 5.5). UI work, so Claude implements and Codex reviews, routed by the lead (brainClaude).
Review rounds: 1 (bots). Defects: DeepSource raised 5 style findings, all fixed in
3c8c64ea. Rebased onto feat(brainbar): show a job alert once per screen, with Show log, cleared by a clean run #106256ce24a5. Lead UX round 1, fixed inae51a1c0→c4c75fe5:DeepSource closure-naming findings fixed in
b4e1812a. Rebased on feat(brainbar): show a job alert once per screen, with Show log, cleared by a clean run #10624f7d1090. Full suite atc4c75fe5plus that DEBUG-harness rename (×3): 1073 UI + 10 daemon tests, 0 failures. The one CIswift (macos-15)failure was a silent xctest exit inMCPRouterTests(pending-queue area, untouched here); it passed on rerun of the same SHA.Size L: 815 added lines = 354 product + 301 tests + 104 debug-only render harness + 56 README. The handoff asked for E1/E4/E5 as one PR.
🤖 Generated with Claude Code
— brainlayerClaude (worker) · claude-code/opus-5.5
Note
Low Risk
BrainBar presentation and settings UI only, with broad unit tests and no changes to backup execution or auth.
Overview
Addresses Etan feedback (E1/E4/E5) on the Backups and settings UX.
E1 — Recovery checks: The Backups page no longer shows raw
ObservabilityStatusRows. It now derivesBrainBarBackupChecks(plain-language checks with tones tied to existing status lines) and rendersBrainBarBackupChecksCard, including a collapsed Technical details section with selectable values and Copy. The combined backups badge can use the checks’attentionSentence, andbackupsBadgeReasondrops reasons already shown on the job-alert, Drive, or recovery cards. Duplicate LAST/NEXT RUN rows are removed from the Backups job group card (Schedule owns timing).E4 — Status dots:
BrainBarStatusDotreplaces bareCirclemarkers on the Drive card, dashboard status strip, attention items, and observability rows so dots align with label cap height.E5 — Config path: The
brainlayer.envpath is removed from every page header; Advanced gets a single Config file row with Copy path / Reveal in Finder, and backup schedule local-copy names become selectable.The DEBUG render harness adds
renderEtanRowsE1E4E5, aligns fixture clocks for coherent renders, and requires Vision OCR to miss labels on three passes before failing. NewBrainBarBackupChecksTestsandBrainBarStatusDotTestscover wording, tone parity, and pixel alignment.Reviewed by Cursor Bugbot for commit db97e1a. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add Backups recovery-check card, centered status dots, and single Advanced Config file row
BrainBarBackupChecksCard, showing six plain-language checks (upload, database copy, scheduling, freshness, retention, archive) with a combined verdict. Raw identifiers such as drive IDs, filenames, and launchd labels move into a collapsible Technical details section with copy actions.BrainBarStatusDotcomponent in BrainBarStatusDot.swift that centers dots on the label's text line. It replaces bare circles in the dashboard, Drive auth card, and observability rows.BrainBarJobGroupCardtakes a caller-supplied Backups reason and drops its direct job-alert hiding case; other job-group cards still show run timings.backupStatusfalls back to the old status-row list only when measured observability is unavailable. Check these two paths in BrainBarSettingsView.swift.Macroscope summarized db97e1a.