Lab Architect / Ellsworth

Afternoon Brief

Wednesday, September 23, 2026 — Fifteenth consecutive night with no nightly-branch build on any app. No feature/nightly-20260923 (Dominique) or feature/nightly2-20260923 (Katey/Howard-3) branch exists on Buildr+, Closr+, Inspectr+, or DailyReportr+, confirmed via fresh git fetch origin + git branch -r on all four repos. Nothing new landed on any app since Sept 21's owner-driven merges either — git log --since="18 hours ago" and --since="2026-09-20" against origin/main return empty on all four repos. Codebase health: 0 analyzer issues across all four apps, unchanged. New finding today: local main on Buildr+, Closr+, and Inspectr+ is 4, 6, and 7 commits ahead of origin/main respectively — Sept 21's release-gate and sign-in merges were made locally but never pushed to GitHub, so yesterday's brief linked to commit hashes (a7a5a03, 0925b0b, 8145093, etc.) that do not actually resolve on github.com. DailyReportr+ remains the exception, in sync with origin and unchanged since Sept 14 (now 9 days silent, the fleet's longest true gap). Both re-issued nightly tasks — Closr+'s hardcoded Procore secret and Inspectr+'s missing backoff logic — are a fifteenth consecutive miss. Source note: /Volumes/Media/App Dev/ remains missing (outage since ~Sept 2); this brief runs from the ~/Documents/Applications/<App> local working copies, which were reachable and listable today with no repeat of the Sept 20 readdir issue.

Last Night’s Builds

No nightly-branch build on any app, fifteenth night running missed

No feature/nightly-20260923 or feature/nightly2-20260923 branch exists on any of the 4 repos, confirmed via git branch -r | grep nightly on Buildr+, Closr+, Inspectr+, and DailyReportr+ after a fresh git fetch origin on each. The streak that began Sept 9–10 now extends to a fifteenth straight miss for both Dominique and Katey/Howard-3.

Buildr+ 4 commits unpushed since Sept 21

Local main head is a7a5a03 (merge of build/harden-ios-release-gate) on top of a2873c3 (merge of the project-card spacing fix, see Recommendation #1). Both are real, dated Sept 21 8:07am PT, but neither reached origin/main — git rev-list --left-right --count main...origin/main reports 4 ahead, 0 behind. origin/main's actual top commit is still 33c825f (Sept 18).

Closr+ 6 commits unpushed since Sept 21

Local main head is 0925b0b (merge of build/harden-ios-release-gate), 6 commits ahead of origin/main, 0 behind. The chain includes the TestFlight client-ID gate (d4c8952) and the checklist progress-header wrap fix (b7f0b9b/acba191/3776b2d) — all real work, none of it on GitHub yet.

Inspectr+ 7 commits unpushed since Sept 21

Local main head is 8145093 (merge of the Google sign-in client-ID fix on top of the iOS release-gate merge), 7 commits ahead of origin/main, 0 behind. The underlying nightly-assigned Backoff-Aware Outbox Retry task is still unbuilt regardless: grep -n "nextAttemptAt\|backoff" lib/services/sync_outbox_service.dart returns nothing.

DailyReportr+ silent 9 days, in sync with origin

main head is still 0433f44 (Sept 14, 10:45am PT, preparing 3.8.1 TestFlight), and local main matches origin/main exactly (0 ahead, 0 behind) — the one app with nothing at risk of being lost unpushed, but also the one with no activity at all in 9 days.

Codebase Health

App Analyzer Issues Breakdown Last 3 Commits (local main)
Buildr+ 0 dart analyze: "No issues found!" Genuinely clean. The Sept 21 spacing fix at lib/widgets/project_card.dart:129–138 still has no widget test protecting it (find test -iname "*project_card*" empty) — see Recommendation #1. Separately, 4 commits including that fix sit unpushed on local main. a7a5a03 merge harden-ios-release-gate • a2873c3 merge project-card spacing fix • fac04bd source protected secrets file (unpushed)
Closr+ 0 dart analyze: "No issues found!" Genuinely clean. Procore client secret still hardcoded at procore_service.dart:56,168,222, unchanged since Sept 9 (15th night). deleteDocument() in document_service.dart:179–191 remains a hard, unrecoverable delete with no trash window — see Recommendation #3. 6 commits sit unpushed on local main. 0925b0b merge harden-ios-release-gate • d4c8952 gate TestFlight IPA on client IDs • ca33394 bump TestFlight version 2.32.75 (unpushed)
Inspectr+ 0 dart analyze: "No issues found!" Still the fleet's worst offender for raw Colors.green: 154 occurrences, unchanged. Backoff-Aware Outbox Retry task (15th ask) remains unbuilt. 7 commits sit unpushed on local main. 8145093 merge Google sign-in client-ID fix • 5e0849b merge harden-ios-release-gate • 744cc12 add iOS artifact gate (unpushed)
DailyReportr+ 0 dart analyze: "No issues found!" 40 raw Colors.green occurrences remain, unchanged. lib/widgets/daily_report_view.dart is 1,666 lines with zero Semantics widgets, unchanged — see Recommendation #2. In sync with origin/main. 0433f44 prepare 3.8.1 TestFlight • 2495d04 merge keyboard-recovery fix • 7253e65 stop keyboard recovery stranding text field (pushed)

All four apps analyze clean today, and no new commit shipped worse code health — there simply were no new commits anywhere since Sept 21. The standing gaps (Inspectr+'s 154 raw Colors.green uses, DailyReportr+'s zero-Semantics report view, Closr+'s hard-delete-with-no-recovery path, Buildr+'s untested layout fix) are all unchanged and addressed in this brief's recommendations. Today's one new signal isn't an analyzer count — it's that three of the four apps have real, dated work sitting on local main that never reached GitHub, which is a code-health risk of its own (unpushed work is unreviewable, undeployable, and one disk failure from gone).

Recurring Themes from Morning Briefs

Based on the Sept 19, 20, and 21 morning briefs (the most recent three available in this repo) plus today's Sept 23 Fountainhead morning report.

Feature Ideas + UI/Code Health Recommendations

3 recommendations (2 UI/code health, 1 feature), each re-verified fresh today against current code and git history rather than carried over blind. All three were also true yesterday because nothing shipped overnight to close them — re-issuing a correct, unbuilt recommendation is preferable to inventing a new one just for novelty. 50/50 standard satisfied (exceeded on the health side).

1. Responsive Project-Card Regression Gate Buildr+ — UI/Code Health

Re-verified today: lib/widgets/project_card.dart:129–138 still fixes the 411dp-width name/contract-value collision with a fixed SizedBox(width: 12) gap and maxLines: 1 ellipsis, with no LayoutBuilder-based stacking fallback. find test -iname "*project_card*" still returns nothing. The commit containing this fix (a2873c3) is also one of the 4 commits sitting unpushed on Buildr+'s local main — it isn't just untested, it isn't on GitHub either.

Why now: Raised in the Sept 20 morning brief before the fix even shipped, and still open two days after the fix landed locally. Every day this ships without a test is a day the next unrelated layout change can silently reopen the same 411dp collision.

Sketch: Extract the name/value header Row into a LayoutBuilder that stacks the contract value below the name when the measured row can't fit both at the current text scale, rather than relying on ellipsis truncation alone. Add a widget test with Cloudflare-shaped Project fixtures at 320, 411, and 430 logical-pixel widths and 1.0×/2.0× text scale, asserting no overflow, a real visible gap in row mode, and unchanged tap targets/imagery.

2. Screen-Reader Report Outline DailyReportr+ — UI/Code Health

Re-verified today: lib/widgets/daily_report_view.dart is still 1,666 lines and visually separates project, weather, work, safety, quality, photos, and signature sections, but grep -c "Semantics" lib/widgets/daily_report_view.dart still returns 0 — no explicit semantics structure exists for VoiceOver/TalkBack users, who currently hear one undifferentiated stream.

Why now: Raised in the Sept 20 morning brief and still fully unbuilt. DailyReportr+ is also the fleet's most stalled app right now (9 days silent on main, and the only one of the four with no unpushed local work either), so a scoped, self-contained accessibility pass is a low-risk way to make real progress on this specific app without waiting on the nightly-branch pipeline to resume.

Sketch: Wrap each existing section title with Semantics(header: true) and stable OrdinalSortKey values so VoiceOver/TalkBack can jump between sections, merge label/value pairs into single semantic nodes, label photos by activity and position, and exclude purely decorative marks from the accessibility tree. Preserve the existing visual layout and PDF export untouched, then add SemanticsTester coverage, a 200% text-scale check, and a VoiceOver/TalkBack manual-pass note before shipping.

3. Recoverable Document Delete Closr+ — Feature

Re-verified today: deleteDocument() at lib/services/document_service.dart:179–191 still calls the Cloudflare API client's delete endpoint directly with no soft-delete flag, staging period, or restore path — distinct from the existing restoreVersion() (document_service.dart:346), which only restores prior *versions* of a document that still exists, not a deleted one. git log --all --oneline | grep -i "trash\|undo.delete\|recoverable.delete\|soft.delete" still returns nothing.

Why now: Directly prompted by Sept 21's competitive intel on Fieldwire's 30-day web Trash, and reinforced by today's competitive intel below on Autodesk Build's Data Transition tooling for closeout handover. Closeout documents are exactly the kind of evidence where an accidental owner-scoped delete during a fast-moving handover is costly and currently unrecoverable.

Sketch: Add a deletedAt timestamp column in D1 instead of an immediate R2/DB delete; filter deleted rows out of normal document queries but keep them queryable in a new project-scoped "Recently Deleted" view for 30 days. Add a restoreDocument() call that clears deletedAt, and a scheduled Worker cron (or lazy check on read) that performs the real R2 delete once the window expires. Test owner-scope isolation, restore-after-partial-expiry, and that version history for a soft-deleted document stays intact until hard-delete.

UI Inconsistencies

Competitive Intel

Tomorrow’s Build Suggestion

Same two assignments, re-issued a fifteenth time: neither task has been completed in fifteen nights, and both underlying gaps are unchanged. DailyReportr+ is deliberately skipped again despite being the most stale app on main (9 days), since neither Dominique nor Katey currently holds an open task for it and re-assigning cold without a scoped ask would waste a night better spent clearing the two known, fully-scoped, highest-severity gaps below. Whoever touches Buildr+, Closr+, or Inspectr+ next should also run git push origin main first — all three currently have real, unpushed local work (4/6/7 commits) that a nightly build based on a fresh clone would not even see.

Dominique → Inspectr+

Task: Backoff-Aware Outbox Retry (open since Sept 9, 15th ask) — persist nextAttemptAt in lib/services/sync_outbox_service.dart, classify retryable vs. terminal failures, add exponential backoff with jitter. Rationale: Fifteenth consecutive night this exact task has gone unbuilt; Sept 20's morning brief independently flagged a related false-success defect in Walk Mode's sync-status reporting, both pointing at the same underlying outbox service needing real attention. First step: git push origin main to land the 7 pending commits before starting new work on top of them.

Katey → Closr+

Task: Move Procore OAuth Authority Out of the App — route token exchange through the existing Cloudflare Worker and remove the hardcoded client secret from lib/services/procore_service.dart:56,168,222. Rationale: Same task assigned Sept 9, missed fifteen nights running; remains the single highest-severity known issue in the fleet and is fully scoped and ready to build. First step: git push origin main to land the 6 pending commits before starting new work on top of them.