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).
- The nightly build-review producer ("Ellsworth Nightly Build Review") has reported MISSING in all three most recent morning briefs — no reviewed before/after diff, test run, or shipping artifact exists for any commit this week, owner-driven or otherwise.
- Sync reliability / false-success defects keep resurfacing: Sept 20's morning brief flagged Inspectr+'s Walk Mode marking every captured item "synced" on reconnect even when individual retries fail (connectivity ≠ Cloudflare acceptance), echoing Sept 19's Closr+ finding that unrecognized
SyncSourcevalues silently fall back to Procore instead of failing closed. Neither is built yet. - Accessibility gaps in dense field-facing views: Sept 20 raised DailyReportr+'s 1,666-line
DailyReportViewhaving noSemantics(header: true)structure for VoiceOver/TalkBack — still true today (0Semanticsmatches), and forms the basis of Recommendation #3 below. - Widget-test coverage lags behind layout fixes: Sept 20 flagged that Buildr+'s new project-card spacing commit fixed a real collision but shipped with no focused widget test to protect it. That commit landed Sept 21 (
a2873c3) exactly as described, still with no test file attest/— the gap Recommendation #1 below closes. - Destructive-action recoverability is a newly surfaced thread: Sept 21's competitive intel on Fieldwire's 30-day web Trash for plans/files/tasks/forms prompted the observation that Closr+'s document actions should stay recoverable rather than becoming silent permanent loss — direct code read today confirms
deleteDocument()has no such recovery path, the basis of Recommendation #2. - Closr+'s hardcoded Procore client secret and Inspectr+'s missing backoff logic are both fourteenth-consecutive misses, unchanged at the same file:line locations as every prior check.
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
primaryBluenames a green color in Closr+, not blue, re-verified today:lib/theme/app_colors.dart:10definesprimaryBlue = Color(0xFF267B4A)in Closr+ — RGB(38,123,74), a distinctly green hue — while the same constant name is genuinely blue in Buildr+ (primaryBlue = Color(0xFF234B74),app_colors.dart:8) and DailyReportr+ (primaryBlue = Color.fromRGBO(37, 99, 235, 1.0)/ #2563EB,app_colors.dart:8). A developer reusingAppColors.primaryBluefor a "blue" element in Closr+ ships green. Cross-app design-token drift, unchanged since first flagged.- Raw Material colors vs. app design-system tokens (
grep -rn "Colors.green" lib/), re-verified today: Buildr+ 0, Closr+ 0, Inspectr+ 154, DailyReportr+ 40. Inspectr+ and DailyReportr+ remain the two worst offenders, unchanged. - DailyReportr+'s report view has zero semantic structure for assistive tech while the rest of the app uses standard Flutter widgets that inherit default semantics — the single largest, most information-dense screen in the app (1,666 lines, 7 sections) is also the one screen with no explicit accessibility scaffolding (see Recommendation #3).
- Buildr+'s project-card fix is a truncation patch, not a layout fix: the new 12px gap plus
maxLines: 1ellipsis (project_card.dart:129–138) stops the immediate text collision but still silently truncates the contract value display under the same conditions that caused the original bug, rather than reflowing to a stacked layout (see Recommendation #1).
Competitive Intel
- Procore's Inspections tool on iOS shipped a consolidated sync header with an "estimated time remaining" indicator and a new configuration menu to download specific subsets of inspection data by status or timeframe. Directly relevant to Inspectr+'s Walk Mode sync UX (see Recurring Themes above) — Procore's own bar for "clear sync status, not just connectivity state" is exactly the signal the receipt-bound sync idea from Sept 20 should be measured against. [source]
- Procore Connect now supports "Submittals: Sync Distributed Items," letting collaborating companies automatically sync and retain a permanent, read-only copy of completed submittals in their own accounts. Relevant to Buildr+'s existing RFI/submittal handoff, which today only copies text to a clipboard — a permanent, retained cross-company record is a materially stronger handoff guarantee than a one-time clipboard copy. [source]
- Autodesk Build's "As Built Export" lets teams filter, find, and export all relevant as-built information — Sheets, RFIs, and Submittals together — for handover, and a new Data Transition tool preserves access to Tasks/RFIs/Submittals/Field Reports during closeout. Directly relevant to Closr+'s closeout/handover surface and this brief's Recoverable Document Delete recommendation — the industry bar for closeout is shifting toward "nothing gets silently lost during handover," which applies to both export completeness and delete recoverability. [source]
- Autodesk Construction Cloud submittals gained a "Download All Attachments" button and mobile-side reference linking, improving traceability of related submittal data. A concrete, shipped bar for Buildr+'s submittal/RFI surface to track as its own handoff feature (Recommendation from the Sept 19 morning brief, still unbuilt) matures beyond clipboard text. [source]
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.