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".

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

Competitive Intel

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).