Lab Architect / Ellsworth

Afternoon Brief

Tuesday, September 22, 2026 — Fourteenth consecutive night with no nightly-branch build on any app. No feature/nightly-20260922 (Dominique) or feature/nightly2-20260922 (Katey/Howard-3) branch exists on Buildr+, Closr+, Inspectr+, or DailyReportr+, confirmed via fresh git fetch origin + git branch -r on all four repos. Unlike the last two quiet nights, three of the four repos did move on main yesterday (Sept 21) — all owner-driven (Howard Roark), not nightly-builder work: Buildr+, Closr+, and Inspectr+ each merged a build/harden-ios-release-gate commit, Inspectr+ also merged a Google sign-in client-ID fix, and Buildr+ separately merged a project-card spacing fix. DailyReportr+ remains unchanged since Sept 14 — now 8 days silent, the fleet's longest gap. Codebase health: 0 analyzer issues across all four apps. Both re-issued nightly tasks — Closr+'s hardcoded Procore secret and Inspectr+'s missing backoff logic — are a fourteenth consecutive miss. Source note: /Volumes/Media/App Dev/ remains missing (outage since ~Sept 2), but the ~/Documents/Applications/<App> fallback checkouts are readable again today (the Sept 20 readdir "Interrupted system call" issue did not recur) — this brief runs from those local working copies after a stash/pull/pop to reconcile uncommitted morning-pipeline WIP already sitting in the Howard Dashboard checkout.

Last Night’s Builds

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

No feature/nightly-20260922 or feature/nightly2-20260922 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 fourteenth straight miss for both Dominique and Katey/Howard-3.

Buildr+ owner commits Sept 21

main head is a7a5a03 (Sept 21, 8:07am PT) — merge of build/harden-ios-release-gate. Also merged Sept 21 8:05am: a2873c3, the project-card name/contract-value spacing fix (12px gap, see Recommendation #1 below). Both owner-driven, not nightly-branch work.

Closr+ owner commits Sept 21

main head is 0925b0b (Sept 21, 8:07am PT) — merge of build/harden-ios-release-gate, gating the TestFlight IPA on compiled client IDs. Owner-driven, not nightly-branch work.

Inspectr+ owner commits Sept 21, ends 13-day main silence

main head is 8145093 (Sept 21, 8:22am PT) — merge of fix/android-google-signin-client-id, on top of the same build/harden-ios-release-gate merge the other two apps received. This ends the fleet's longest main-silence streak (previously 12+ days), but the underlying nightly-assigned Backoff-Aware Outbox Retry task is still unbuilt: grep -n "nextAttemptAt\|backoff" lib/services/sync_outbox_service.dart returns nothing.

DailyReportr+ silent 8 days, fleet's longest gap

main head is still 0433f44 (Sept 14, 10:45am PT, preparing 3.8.1 TestFlight). No new activity in 8 days — now the fleet's stalest app on both nightly and daytime fronts.

Codebase Health

App Analyzer Issues Breakdown Last 3 Commits (main)
Buildr+ 0 dart analyze: "No issues found!" Genuinely clean, no suppression block in analysis_options.yaml. The Sept 21 spacing fix at lib/widgets/project_card.dart:133 patches the immediate overflow with a fixed 12px gap and maxLines: 1 ellipsis, but the row still has no LayoutBuilder-based stacking and no widget test — see Recommendation #1. a7a5a03 merge harden-ios-release-gate • a2873c3 merge project-card spacing fix • fac04bd source protected secrets file
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 (14th night). deleteDocument() in document_service.dart:179–191 is a hard, unrecoverable delete with no trash window — see Recommendation #2. 0925b0b merge harden-ios-release-gate • d4c8952 gate TestFlight IPA on client IDs • ca33394 bump TestFlight version 2.32.75
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 (14th ask) remains unbuilt. 8145093 merge Google sign-in client-ID fix • 5e0849b merge harden-ios-release-gate • 744cc12 add iOS artifact gate
DailyReportr+ 0 dart analyze: "No issues found!" from the local working checkout (no clone-artifact warning today). 40 raw Colors.green occurrences remain, unchanged. The 1,666-line daily_report_view.dart has zero Semantics widgets — see Recommendation #3. 0433f44 prepare 3.8.1 TestFlight • 2495d04 merge keyboard-recovery fix • 7253e65 stop keyboard recovery stranding text field

All four apps analyze clean today. No build shipped worse code health — yesterday's owner commits were iOS release-gate hardening and a real bug fix (project-card spacing), not feature work, and none introduced new analyzer issues. The more meaningful signal remains what the clean analyzer counts don't show: Inspectr+'s 154 raw Colors.green uses, DailyReportr+'s zero-Semantics 1,666-line report view, and Closr+'s hard-delete-with-no-recovery path, all addressed in this brief's recommendations.

Recurring Themes from Morning Briefs

Based on the Sept 19, 20, and 21 morning briefs (the most recent three available in this repo).

Feature Ideas + UI/Code Health Recommendations

3 recommendations (2 UI/code health, 1 feature), each verified fresh today against code and git history before inclusion. Weighted toward code health today because the two strongest health signals — an untested layout patch that just shipped, and a zero-Semantics report view — surfaced from direct code reads this run, not from repeating older asks. 50/50 standard satisfied (exceeded on the health side).

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

Verified today: yesterday's a2873c3 merge fixed a real 411dp-width collision between a long project name and its contract value by adding a fixed SizedBox(width: 12) gap and maxLines: 1 ellipsis at lib/widgets/project_card.dart:129–138. The name column stays Expanded with no LayoutBuilder-based stacking fallback, and find test -iname "*project_card*" returns nothing — the fix is unprotected against the next layout change, large text scale, or an even longer name.

Why now: Raised in the Sept 20 morning brief before the fix even shipped; the fix landed exactly as predicted on Sept 21 with no accompanying test, so the gap the morning brief warned about is now live in production rather than hypothetical.

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. Recoverable Document Delete Closr+ — Feature

Verified today: deleteDocument() at lib/services/document_service.dart:179–191 calls the Cloudflare API client's delete endpoint directly with no soft-delete flag, staging period, or restore path — distinct from the existing restoreVersion()/version-history feature (document_service.dart:290–359), 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" returns nothing, confirming this hasn't been built or attempted before.

Why now: Directly prompted by Sept 21's competitive intel: Fieldwire's web Trash gives a 30-day recovery window for deleted plans, files, tasks, and forms. 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.

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

Verified today: lib/widgets/daily_report_view.dart is 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 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 (8 days silent on main), so a scoped, self-contained accessibility pass is a low-risk way to make real progress on this 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.

UI Inconsistencies

Competitive Intel

Tomorrow’s Build Suggestion

Same two assignments, re-issued a fourteenth time: neither task has been completed in fourteen nights, and both underlying gaps are unchanged. Buildr+ and Closr+ did get owner-driven iOS release-gate commits yesterday, but that's infrastructure hardening, not a discharged nightly assignment — DailyReportr+ is deliberately skipped again despite being the most stale app on main (8 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.

Dominique → Inspectr+

Task: Backoff-Aware Outbox Retry (open since Sept 9, 14th ask) — persist nextAttemptAt in lib/services/sync_outbox_service.dart, classify retryable vs. terminal failures, add exponential backoff with jitter. Rationale: Fourteenth consecutive night this exact task has gone unbuilt; yesterday's owner commits touched iOS release gating and Google sign-in on this app but didn't address sync reliability, and Sept 20's morning brief independently flagged a related false-success defect in Walk Mode's sync-status reporting — both point at the same underlying outbox service needing real attention.

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 fourteen nights running; remains the single highest-severity known issue in the fleet and is fully scoped and ready to build.