Lab Architect / Ellsworth
Afternoon Brief
Tuesday, October 6, 2026 — Twenty-eighth consecutive night with no nightly-branch build on any app. No commits on any ref in any app repo in the last 36 hours. Codebase health: 0 analyzer issues on all four apps. No morning brief was published today (briefs/ stops at Oct 5). Correction: Closr+'s DashboardPage hasn't been reachable since 0f0b5f5 (Jun 17, "make Closr project-first"). Fourteen dashboard cards are imported only by that page, so they're dead too. That includes the Asset Handover Checklist targeted by yesterday's Recommendation #3, which is withdrawn.
Last Night’s Builds
No nightly-branch build on any app, twenty-eighth night running missed
Ran git fetch origin on all four repos. No feature/nightly-20261006 or feature/nightly2-20261006 branch exists, and there are no October nightly branches of either kind. git log --all --since="36 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 a ninth day. Today's Fountainhead morning report (morning-reports/2026-10-06.md) again shows Hermes UP and the nightly review artifacts MISSING. Its log tail still ends Sept 6, and it doesn't check the 00:15 or 01:15 builder jobs. 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, Sept 18). 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 1,648 changed paths, nearly all deleted-but-tracked node_modules/. Unchanged.
Inspectr+ 7 commits unpushed
Local main is at 8145093 (Sept 21), 7 ahead / 0 behind origin/main (4140149, Sept 8). Unchanged.
DailyReportr+ silent 22 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 | Unimported files | Raw 'Error: $…' text |
Test files | Breakdown | Last 3 Commits (local main) |
|---|---|---|---|---|---|---|
| Buildr+ | 0 | 16 | 60 / 56 files | 86 | "No issues found!" Nothing new. Still open: unguarded onDismissed deletes, impact counts from unloaded data, the "Unlinked Rev. 0" label, the producer-less offline queue, and the 6 owner-retired pages. |
a7a5a03 merge harden-ios-release-gate • a2873c3 merge project-card spacing fix • fac04bd source protected secrets file (unpushed) |
| Closr+ | 0 | 12 (+14 transitive) | 35 / 30 files | 35 | "No issues found!" New today: DashboardPage (1,248 lines) has no importer. 0f0b5f5 (Jun 17) cut the bottom nav to Projects / Map / Settings. The 12-file orphan count missed the 14 widgets imported only by that page: Owner Packet Score, Evidence Matrix (and the Completeness Matrix page it links to), Completion Forecast, Turnover Risk Digest, Asset Handover Checklist, Handoff Risk Score, Owner Callback Queue, Owner Walkthrough Readiness, Retainage Release Radar, Closeout Exposure Snapshot, Exposure Aging, Closeout Aging Digest, Closeout Risk Heatmap, and Subcontractor Chase Plan. PunchListPage is also never constructed. Of the 35 raw-error lines, 7 sit on the reachable Projects → project path (Rec #1). |
0925b0b merge harden-ios-release-gate • d4c8952 gate TestFlight IPA on client IDs • ca33394 bump TestFlight 2.32.75 (unpushed) |
| Inspectr+ | 0 | 18 | 5 / 5 files | 66 | "No issues found!" Nothing new. Still open: DrawingReferenceChips hides on error (Oct 4), the gallery ignores the tapped index, and 29 raw Colors.green. |
8145093 merge Google sign-in client-ID fix • 5e0849b merge harden-ios-release-gate • 744cc12 add iOS artifact gate (unpushed) |
| DailyReportr+ | 0 | 11 | 0 | 75 | "No issues found!" Nothing new. Still open: the admin reports retry loop, the duplicated _buildReportCard, the PDF missed-item check comparing a report with itself (Oct 5), and 40 raw Colors.green. |
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-20261006/. Test-file counts (test/**/*_test.dart) are a new column today. Closr+ has the fewest tests (35) for the most source files (266). Method note: the "unimported files" metric only counts files with zero importers. A page with no entry point can still keep a whole subtree "imported." Future runs should also count widgets reachable only from orphan pages.
Recurring Themes from Morning Briefs
Sources: the Oct 5, Oct 4, and Oct 3 morning briefs in briefs/. No Oct 6 morning brief was published, only the Fountainhead morning report.
- Don't manufacture certainty: six briefs running, and every item is still unbuilt. Recent examples are sync receipts,
_markSynced, queue honesty, "Rev. 0", hidden drawing refs, zero impact from unloaded data, and a missed-item check that compares a report with itself. Today's Rec #1 extends the theme to errors. A rawCloudflareApiException(…)string is neither honest nor useful to a field user. - Reachability keeps catching the morning ideas out: Connected Sources (dead since Apr 25), the producer-less offline queue (Oct 3), and now the Closr+ Dashboard (dead since Jun 17). The Oct 5 morning brief called the handover card "reachable"; it isn't. The morning generator should check for an entry point (a nav tab, route, or
pushcall), not just an import. - Drawings and plan context: three briefs running (revision impact, snapshot revision, sheet reference). These stay queued and aren't repeated here.
- Automation stall: 28 nights. The morning sources still watch only the retired review producer.
Feature Ideas + UI/Code Health Recommendations
There are 3 recommendations: 2 UI/code health items and 1 feature. All three are in Closr+, because today's finding is specific to it. Dedup checks: git log --all -i --grep for "error state", "owner link", "link status", and "owner viewed" found nothing relevant. The only "error state" hit is 229be66, the Digital Closeout Package feature. No shared error widget exists in Closr+ (onRetry: 0 hits). git log -S "DashboardPage()" shows the last construction was removed in 0f0b5f5. Every target below was checked for an actual entry point, not just an importer. The held items from Sept 28 to Oct 5 still rank ahead of these.
1. Errors a Closeout Manager Can Act On Closr+ — UI/Code Health (shared error widget + tests)
When a load fails on the Projects tab (the app's first screen), users see Text('Error: $error'). For a Cloudflare failure, that reads Error: CloudflareApiException(401, …): …, and there's no way to retry. The same pattern sits on every main step into a project: projects_page.dart:89, project_detail_page.dart:138 (the project itself), :2259 (Punch tab, in red), checklist_page.dart:50, documents_page.dart:185, and under More, subcontractors_tab_view.dart:36 and lien_waiver_tab_view.dart:95. Closr+ has no shared error widget. DailyReportr+ already has the pattern to copy: a private _ErrorState(message, onRetry) with a "Try Again" button (project_map_page.dart:473).
Why now: Closr+ has 35 raw-error lines, the second most of any app, and these 7 are the ones users actually reach. Today's dead-dashboard finding means effort should go to the Projects-first path that ships. Closr+ also has the thinnest test suite (35 files).
Sketch: add lib/widgets/app_error_state.dart with AppErrorState({required String title, String? detail, VoidCallback? onRetry}). Add a friendlyErrorMessage(Object e) helper that maps CloudflareApiException status codes as follows: 401/403 → "Your session expired. Sign in again", 404 → "This project is no longer available", 5xx or socket errors → "Couldn't reach Closr+. Check your connection". Replace the 7 sites, with each onRetry calling ref.invalidate on its own provider. Use SliverFillRemaining on the Projects tab. Add widget tests for the helper's mapping and for Projects-tab error → Try Again → data. Analyzer stays at 0, and the raw-error count drops from 35 to 28.
2. Retire or Re-home the Orphaned Dashboard Closr+ — UI/Code Health (dead-code decision)
0f0b5f5 (Jun 17, by the owner) made Closr+ project-first. It replaced the Dashboard tab with Projects / Map / Settings, but left dashboard_page.dart and 14 cards in lib/. Nightly builders kept shipping into that dead code for seven weeks. Examples are the Turnover Risk Digest polish (Aug 3) and the Completeness Matrix, whose only entry is the dead Evidence Matrix card (Aug 4). Briefs kept recommending fixes there too (yesterday's Rec #3). The cards still compile, analyze clean, and some have tests, so nothing flags them.
Why now: this is the third dead-code correction in five days, after Connected Sources (Oct 2) and the offline queue (Oct 3). Until there's a decision, every builder and brief risks targeting it again.
Sketch (owner decides, builder executes): sort the 14 cards into re-home and retire. Re-homed cards go into a project's Overview (per-project cards like Owner Packet Score) or a Projects-tab "Portfolio" header. Retired cards get deleted in one commit along with dashboard_page.dart, PunchListPage, and any providers left with no watchers. Record the decision in docs/ux/, as Buildr+ did in its Aug 8 audit. Add a CI guard test that fails when a lib/pages/**/*_page.dart class is never constructed, with an allowlist. Analyzer stays at 0. The dead subtree is 9,645 lines (dashboard + 14 cards + Completeness Matrix + PunchListPage), minus whatever gets re-homed.
3. Owner Link Status on the Project Overview Closr+ — Feature
Closr+ already tracks whether the owner review link was sent, viewed, expiring, or expired. OwnerPacketScore.reviewLinkStatusLabel and reviewLinkDetail produce labels like "Owner viewed", "Link expiring", and "Expired today. Refresh the link.", and the model has a 156-line test file. Today that status only appears on the dead dashboard card. On the reachable app, the view count and expiry are visible only after opening the Share dialog. Add one row to the project Overview's existing Handover card (_buildHandoverSummaryCard, project_detail_page.dart:459). It should read "Owner review link · Owner viewed (3 views) · expires in 2 days", and tapping it opens ShareProjectDialog.
Why now: it's the smallest re-home from Rec #2. It brings a tested model back into use, needs no backend, and puts closeout's last-mile signal (did the owner open the package?) on the screen users actually see. Bluebeam's web Session Status (shown per person; reported Oct 5) and Procore's Owner Hub milestone variance (below) both point at owner-facing status.
Sketch: compute OwnerPacketScore.fromProject(project) in _buildHandoverSummaryCard, and add a second _buildOverviewNavRow with a link icon, the status label as the title, and reviewLinkDetail as the detail. Use amber when expiring and red when expired, from AppColors rather than raw colors. Tapping it pushes the share dialog (the same call as :2287). Add a widget test for each of the four states: none, not viewed, viewed, and expired. If Rec #2 retires owner_packet_score_card.dart, keep the model.
UI Inconsistencies
- Closr+ project page uses three different error treatments: the project load shows plain
'Error: $error'(:138). The Punch tab shows red'Error loading closeout items: $error'(:2259). Four intelligence cards show a muted "_buildMutedIntelligenceCard" (:768–887), and two sections disappear entirely withSizedBox.shrink()(:185,:1395). On one screen, a failure can be loud, quiet, styled, or invisible. Rec #1 standardizes the full-screen cases. The muted card is the right model for inline ones. - Closr+ Documents tab hides 4 of its 5 failure branches:
documents_page.dart:131, 135, 149, 280all renderSizedBox.shrink()on error, and:185shows raw text. This is the same "failure looks like empty" pattern flagged in Buildr+ and Inspectr+. - No shared error widget in any app: Inspectr+ (
map_page.dart:810) and DailyReportr+ (project_map_page.dart:473) each define a private_ErrorStateinside a map page. Buildr+ and Closr+ have none. Raw-error lines: Buildr+ 60, Closr+ 35, Inspectr+ 5, DailyReportr+ 0. - Carried over, unchanged (no commits): the Buildr+ custom
Icons.arrow_back_iosback button on 9 reachable pages. Inspectr+DrawingReferenceChipspassesisDark28 times. The Inspectr+ gallery ignores the tapped index. The DailyReportr+ "Today" pill looks tappable but isn't. RawColors.green: DailyReportr+ 40, Inspectr+ 29, Buildr+ 0, Closr+ 0. Yesterday's Closr+ "Copy Handoff" vs. "Copy Handoff Brief" note is withdrawn, because the "Copy Handoff" card is unreachable.
Competitive Intel
- Procore Hubs: Track Milestone Dates Across Projects (posted Sept 29, available Oct 13). A new Owner Hub "Project Date Variance" card shows a table of projects with one column per company-defined milestone. Baseline dates are shown, overdue cells are flagged red, and variance is color-coded. It supports filtering by stage and department, plus inline edits. This is the cross-project view the dead Closr+ dashboard used to try to be. If Rec #2 re-homes anything portfolio-level, a closeout-milestone variance strip is the comparable shape. new to these briefs [source]
- Procore My Open Items: grouping, saved views, project-number and due-date filters (posted Sept 29, available Oct 13). already reported Oct 2, Oct 3 [source]
- Bluebeam on mobile iOS v1.32: Image Capture on markups. Take a photo or choose one from the library and attach it to a markup. Markup details now combine history and comments in one timeline. It's relevant to Inspectr+ deficiency markup and photo evidence. Aug 25 release; outside the 7-day window, new to these briefs [source]
- Not used: Procore's Oct 5 "EU Application Zone" launch is infrastructure, not a field feature. The Daily Log filtering/sticky toolbar items (Aug) and Inspections bulk creation are older. The Autodesk results ("Open for Manager", "Download All Attachments", spec linking) are undated, so they're treated as current capability, not news. Fieldwire's newest feature post is Jan 2026 (Tasks in 3D). No PlanGrid ship was found. It's another quiet week for in-scope features.
Tomorrow’s Build Suggestion
This is the twenty-eighth night without builders. The assignments stay held (ninth day). Queue change: the Closr+ "Copy One Owner-Walk Handoff" item is removed because it targets dead code. Today's Rec #1 replaces it as the Closr+ queue item. Rec #2 needs an owner decision first. Owner actions before either 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 (retire or re-home). For Closr+, stage explicit paths rather than using git add -A.
Dominique → Buildr+
Task: Deletes That Wait for the Server (Sept 28 Rec #1), then impact counts that wait for their data (Oct 5 Rec #1). Rationale: Buildr+ hasn't had a nightly feature since Aug 5 and has the most raw error text (60 lines). Both fixes are reachable and verified.
Katey → DailyReportr+
Task: a single reports_page.dart rework (Admin Reports That Admit Failure → shared ReportSummaryCard → lazy SliverList), then the prior-days-only comparison (Oct 5 Rec #2). Rationale: it's the stalest app (22 days on main). Queued next for whichever builder frees up first: Closr+ Errors a Closeout Manager Can Act On (today's #1), then Inspectr+ Drawing References That Admit Failure (Oct 4), then the Inspectr+ tapped-photo fix. Closr+ Owner Link Status (today's #3) is next after the owner's dashboard decision.