Lab Architect / Ellsworth
Afternoon Brief
Thursday, October 8, 2026 — Thirtieth consecutive night with no nightly-branch build on any app. No commits on any ref in any app repo in the last 30 hours. Codebase health: 0 analyzer issues on all four apps. No morning brief was published again (briefs/ still stops at Oct 5). New today: an accessibility sweep of icon-only buttons in reachable code (files imported from main.dart). 105 of 215 IconButtons have no tooltip, so screen readers announce them as just "button". Closr+ is worst at 27 of 33, including the Back and Edit buttons on its main project screen. None of the four apps labels its show/hide-password toggle, and Buildr+ and DailyReportr+ each use opposite eye-icon meanings on their sign-in and change-password screens.
Last Night’s Builds
No nightly-branch build on any app, thirtieth night running missed
Ran git fetch origin on all four repos. No feature/nightly-20261008 or feature/nightly2-20261008 branch exists. The newest nightly branches are still from early September (Buildr+ nightly2-20260909, DailyReportr+ nightly-20260909, Closr+ nightly2-20260907, Inspectr+ nightly-20260823). git log --all --since="30 hours ago" is empty on all four. The held assignments (Dominique → Buildr+ Deletes That Wait for the Server; Katey → DailyReportr+ reports_page.dart rework) went unclaimed for an eleventh day. Today's Fountainhead morning report (morning-reports/2026-10-08.md, untracked in the dashboard repo) again shows Hermes UP and the nightly review artifacts MISSING. Its log tail still ends in early September. The builder coordination file ~/memory/last-nightly-build.md was last updated Aug 5.
Buildr+ 4 commits unpushed · working copy off main
Local main is at a7a5a03 (Sept 21), 4 ahead / 0 behind origin/main (33c825f). The working copy is on fix/project-card-contract-value-spacing. Unchanged.
Closr+ 6 commits unpushed · tracked node_modules
Local main is at 0925b0b (Sept 21), 6 ahead / 0 behind origin/main (7a3ca21). git status still lists deleted-but-tracked node_modules/ paths. Unchanged.
Inspectr+ 7 commits unpushed
Local main is at 8145093 (Sept 21), 7 ahead / 0 behind origin/main (4140149). Unchanged.
DailyReportr+ silent 24 days · working copy off main
main = origin/main = 0433f44 (Sept 14, 3.8.1 TestFlight prep). The working copy is still on the Aug 11 fix/owner-report-media-web branch, with modified tracked files.
Codebase Health
| App | Analyzer Issues | Unlabeled IconButtons (reachable) |
Raw 'Error: $…' text |
Deletes in onDismissed |
Breakdown | Last 3 Commits (local main) |
|---|---|---|---|---|---|---|
| Buildr+ | 0 | 23 / 67 | 60 | 10 | "No issues found!" Unlabeled buttons cluster in security_page.dart (4: back + 3 password toggles) and rfi_drawing_snapshot_page.dart (2). sign_in_page.dart:445 password toggle has no label. |
a7a5a03 merge harden-ios-release-gate • a2873c3 merge project-card spacing fix • fac04bd source protected secrets file (unpushed) |
| Closr+ | 0 | 27 / 33 | 35 | 0 | "No issues found!" Worst ratio (82%). The project screen AppBar (project_detail_page.dart:159 back, :189 edit) reads "button, button" to VoiceOver. Also auth_page.dart (3 password toggles) and security_page.dart (4). The 9,645-line dead dashboard subtree is excluded from this count. |
0925b0b merge harden-ios-release-gate • d4c8952 gate TestFlight IPA on client IDs • ca33394 bump TestFlight 2.32.75 (unpushed) |
| Inspectr+ | 0 | 27 / 61 | 5 | 1 | "No issues found!" Spread thin: security_page.dart (3), auth_page.dart (2), both wizards (2 each), photo_gallery_viewer.dart (2), responsive_navigation.dart (2). Most Semantics usage of the four (37 call sites). |
8145093 merge Google sign-in client-ID fix • 5e0849b merge harden-ios-release-gate • 744cc12 add iOS artifact gate (unpushed) |
| DailyReportr+ | 0 | 28 / 54 | 0 | 2 | "No issues found!" security_page.dart (4), auth_page.dart (3), workforce_trend_detail_page.dart (2). A naive count says 52, but the top offenders (notes_page, gallery_page, materials_page, checklists_page) are dead: ProjectToolsPage routes to the *_manager_enhanced_view.dart versions instead. |
0433f44 prepare 3.8.1 TestFlight • 2495d04 merge keyboard-recovery fix • 7253e65 stop keyboard recovery stranding text field (pushed) |
Analyzer counts: Buildr+ 0 · Closr+ 0 · Inspectr+ 0 · DailyReportr+ 0. They come from dart analyze lib on fresh git archive main snapshots, after flutter pub get --offline, in /private/tmp/afternoon-brief-20261008/. New column: "Unlabeled IconButtons" counts IconButton( calls with no tooltip: argument, restricted to files reachable from lib/main.dart through imports, exports and parts (unreachable files: Buildr+ 46, Closr+ 57, Inspectr+ 38, DailyReportr+ 25, counting transitive orphans). It replaces the "Unimported files" column, which is unchanged at 16 / 12 / 18 / 11. Raw-error and onDismissed counts carry over from Oct 7 (no commits since Sept 21). Without a tooltip, an icon-only button also gets no long-press hint on mobile and no hover label on web.
Recurring Themes from Morning Briefs
Sources: the Oct 5, Oct 4, and Oct 3 morning briefs in briefs/. There was no morning brief for Oct 6, 7, or 8, only the Fountainhead morning reports, which repeat "artifacts MISSING".
- Don't show success before it happens: sync receipts,
_markSynced, "Rev. 0", zero impact counts from unloaded data, and the swipe-deletes. Still the dominant theme, and still unbuilt. Today's Rec #2 is a small version of it: Inspectr+ "Reopen" erases a completion with one tap and no confirmation. - Reachability: Connected Sources, the offline queue, the Closr+ Dashboard. Today's tooltip metric is reachable-only for this reason. The DailyReportr+ naive count would have pointed a builder at four dead pages.
- Accessibility came up Sept 10 (Closr+ header) and Sept 27–30 (Buildr+
arrow_back_iosback buttons, ProjectCard with no Semantics), but always as one-off items. Today's Rec #1 makes it a counted, ratcheted metric. - Automation stall: 30 nights. The morning sources still watch only the retired review producer.
Feature Ideas + UI/Code Health Recommendations
There are 2 recommendations: 1 UI/code health item (Closr+ first, then all four apps) and 1 feature (Inspectr+). Dedup checks: git log --all -i --grep for "tooltip", "accessib", "semantic label" and "reopen" found nothing relevant in any repo. The only Inspectr+ reinspection work is the Reinspection Route planner (9a85861), which groups visits and doesn't touch the Reopen action. grep -rn "Show password" returns 0 hits in all four lib/ trees. Both targets were checked for an entry point: Closr+ ProjectDetailPage is the project-first home, and the Inspectr+ Reopen button is on inspection_item_page.dart, reached from every project's item list. The held items from Sept 28 to Oct 7 still rank ahead of these.
1. Every Button Says What It Does Closr+ first, then all apps — UI/Code Health (accessibility + test)
105 of 215 reachable icon-only buttons across the four apps have no tooltip, so VoiceOver and TalkBack read them as "button" with no name. Closr+ is the worst case: 27 of 33. That includes the Back (CupertinoIcons.back, project_detail_page.dart:159) and Edit (CupertinoIcons.pencil, :189) buttons on the project screen every user lands on. The custom back button also drops the "Back" label that Flutter's default BackButton provides. The password show/hide toggles are unlabeled in every app (0 hits for "Show password"), and on a password field that toggle is the one control a screen-reader user most needs to identify.
Why now: analyzer is at 0 everywhere, so dart analyze can't catch new debt here. The tooltip count is the next health signal that can actually move. Accessibility has been raised piecemeal since Sept 10 without a metric behind it. App Store review and public-sector construction owners increasingly expect basic screen-reader support.
Sketch: (1) Closr+: add tooltip: to all 27 reachable sites. Use MaterialLocalizations.of(context).backButtonTooltip on the custom back buttons (or replace them with BackButton/CupertinoNavigationBarBackButton). Use "Edit project", and on password toggles use obscure ? 'Show password' : 'Hide password'. (2) Add test/guards/icon_button_tooltip_test.dart: walk lib/ from main.dart, count IconButton( calls without tooltip:, and fail if the count is above a checked-in baseline (0 for Closr+ after this pass). That ratchet keeps the count from growing back. (3) Roll the same guard into the other three apps with their current baselines (23 / 27 / 28), and fix the shared security_page.dart + auth toggles in each as a follow-up. Analyzer stays at 0, and Closr+ unlabeled buttons go from 27 to 0.
2. Reopen With a Reason Inspectr+ — Feature
On a completed inspection item, the primary action is a one-tap orange "Reopen" button (inspection_item_page.dart:2493). It sets the status straight back to Pending with no confirmation and no reason (_updateStatus, :2630). The only record is an auto-comment, "Status changed from Completed to Pending". A mis-tap undoes a close-out, and a real failed reinspection looks identical to a correction. Nothing on the item or in the project tools shows that an item has been reopened, or how many times. Proposal: tapping Reopen opens a short sheet with a reason (Failed reinspection / Work damaged after close / Closed in error / Other) and an optional note. The item goes to In Progress for failed reinspection, or Pending otherwise. The comment reads "Reopened — Failed reinspection: <note>", and the item header shows a "Reopened ×N" chip.
Why now: Procore's Inspections tool now lets you reinspect a closed inspection, carrying over the original responses and linking the new inspection to the old one (release notes, below). Repeat failures are exactly what Inspectr+'s Repeat Defect Radar and Contractor Closure Rate Scorecard try to measure, but today they can't tell a reopen from a fresh item. This is also the "don't erase state silently" theme from the morning briefs, at the item level.
Sketch: (1) Add _showReopenSheet(item), which returns a ReopenReason enum plus a note, or null to cancel. Route both Reopen buttons (:2493 and the enhanced variant at :2578) and the _primaryActionLabel path through it. (2) Write the structured comment with a stable prefix ("Reopened — "). Derive reopenCount from the item's comments client-side, so no schema change is needed for v1. (3) Show the chip in the item header and in the project item list. Add "Reopened" as a filter in the triage queue. (4) Feed the count into Repeat Defect Radar's scoring. (5) Tests: a widget test (cancel leaves the status Completed; confirming with "Failed reinspection" sets In Progress and writes the comment) and a unit test for reopenCount parsing. This also gives Inspectr+ its first coverage of the status transitions.
UI Inconsistencies
- The password eye icon means opposite things on two screens of the same app. Buildr+ sign-in (
sign_in_page.dart:451) showsvisibility_offwhile the password is hidden (icon = current state). Buildr+ Change Password (security_page.dart:369/402/440) showsvisibilitywhile hidden (icon = action). DailyReportr+ splits the same way:auth_page.dart:861andsign_up_wizard.dart:914showeye_slash_fillwhen hidden, whilesecurity_page.dart:577/661/748showsvisibility. Closr+ and Inspectr+ are internally consistent (eye = "tap to show"), but Closr+ mixesCupertinoIcons.eyeon auth with MaterialIcons.visibilityin Security. Rec #1's tooltip makes the meaning explicit either way. Pick "icon = action" (the majority) when touching these. - Back buttons: on the main project screen, Closr+ uses
CupertinoIcons.back, and in Settings › Security it usesIcons.arrow_back_ios(security_page.dart:272). Neither has a label. The samearrow_back_iospattern is in Buildr+ (9 reachable pages, Sept 27) and in thesecurity_page.dartof all four apps. - Dead controls in dead code: the DailyReportr+
gallery_page.dart:110/125search and filter buttons areonPressed: () {}, but the page is unreachable (the gallery is served bygallery_manager_enhanced_view.dart). No user impact today, but it's another argument for the pending dead-file cleanup. - Carried over, unchanged (no commits): Inspectr+ Projects vs Reports delete behavior and SnackBar styles (Oct 7). Swipe-delete semantics differ across apps (Oct 7). Closr+ has three error treatments on the project page (Oct 6). The Inspectr+ gallery ignores the tapped index. The DailyReportr+ "Today" pill looks tappable but isn't. Raw
Colors.green: DailyReportr+ 40, Inspectr+ 29, Buildr+ 0, Closr+ 0.
Competitive Intel
- Procore Project Inspections: reinspect closed inspections. You can reinspect a closed inspection, carrying over the original responses and linking the new inspection for reporting. This is the basis for Rec #2. date not shown on the release-notes summary · new to these briefs [source]
- Procore Daily Log: filters drive the totals, plus bulk delete. Filtered views now recalculate totals and hide log types with no matches. There's also a bulk delete for teams with 50–100+ entries a day. The bulk delete is relevant to the swipe-delete theme: DailyReportr+ has only one-at-a-time swipe deletes, and they don't wait for the server. date not shown · new to these briefs [source]
- Procore Resource Forecast (Oct 13). Labor and equipment forecasts in one view, to spot over-capacity periods. It's adjacent to the DailyReportr+ crew and equipment data, but it's a planning feature, so it's out of scope for now. upcoming · new to these briefs [source]
- Not used: Hubs milestone dates (already reported Oct 6), the Permissions redesign (Oct 2), the Explore feed and October General Enhancements (Oct 4 and Oct 5), iOS 2026.0923 and Project Map status pins (Oct 3 and 4), the EU zone (infrastructure), and Groundbreak Oct 21–22 (Oct 7). The Autodesk Assistant / Handover / Drawing Extraction announcement is still undated and was already reported. Bluebeam Max (early 2026) is not news this week. Fieldwire's public changelog shows nothing after July 2026, and no PlanGrid ship was found.
Tomorrow’s Build Suggestion
This is the thirtieth night without builders. The assignments stay held (eleventh day). Queue change: Closr+ Every Button Says What It Does (today's #1) joins the shared queue after Inspectr+ Report Deletes, and Inspectr+ Reopen With a Reason goes at the end. Owner actions before any build: check the 00:15 and 01:15 builder launch jobs. Push the unpushed main commits (Buildr+ 4, Closr+ 6, Inspectr+ 7). Decide on the Closr+ Dashboard and Connected Sources.
Dominique → Buildr+
Task: Deletes That Wait for the Server (Sept 28 Rec #1), using the Inspectr+ projects_page.dart:288 confirmDismiss pattern for all 10 sites. While in the files, give any touched IconButton a tooltip. Rationale: Buildr+ hasn't had a nightly feature since Aug 5 and has the most onDismissed deletes (10) and raw error text (60).
Katey → DailyReportr+
Task: the single reports_page.dart rework (Admin Reports That Admit Failure → shared ReportSummaryCard → lazy SliverList), including moving the two swipe-deletes (:224, :408) into confirmDismiss. Rationale: it's the stalest app (24 days on main), and every open DailyReportr+ issue is in this one file. Queued next for whichever builder frees up first: Inspectr+ Report Deletes That Wait for the Server (Oct 7), Closr+ Every Button Says What It Does (today's #1), Closr+ Errors a Closeout Manager Can Act On (Oct 6), Inspectr+ Drawing References That Admit Failure (Oct 4), Inspectr+ Recently Deleted Reports (Oct 7), then Inspectr+ Reopen With a Reason (today's #2).