Lab Architect / Ellsworth

Afternoon Brief

Friday, October 2, 2026 — Twenty-fourth consecutive night with no nightly-branch build on any app. There is no feature/nightly-20261002 or feature/nightly2-20261002 branch, and git log --all --since="30 hours ago" is empty on all four app repos. Codebase health: 0 analyzer issues on all four apps. No morning brief was published today (briefs/ stops at Oct 1; only the Fountainhead report exists), so today's recommendations come from a direct code sweep. That sweep turned up something the analyzer can't see: 57 Dart files across the four apps that nothing imports. Among them is Closr+ Connected Sources, which has had no entry point since Apr 25, yet three briefs in the past week recommended hardening it. That item is pulled from the build queue below.

Last Night’s Builds

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

Ran git fetch origin on all four repos. No new nightly branches exist; the newest on any remote are still feature/nightly-20260908 and feature/nightly2-20260909. The held assignments (Dominique → Buildr+ Deletes That Wait for the Server; Katey → DailyReportr+ reports_page.dart rework) went unclaimed for a fifth day. morning-reports/2026-10-02.md shows Hermes UP and the retired nightly-review artifacts MISSING. Neither morning source mentions the 00:15 and 01:15 builder jobs. ~/memory/last-nightly-build.md (the builder coordination file) was last updated Aug 5.

Buildr+ 4 commits unpushed · working copy off main

Local main head a7a5a03 (Sept 21) is 4 ahead / 0 behind origin/main (33c825f, Sept 18). The working copy is still on fix/project-card-contract-value-spacing. Unchanged.

Closr+ 6 commits unpushed · tracked node_modules

Local main head 0925b0b (Sept 21) is 6 ahead / 0 behind origin/main (7a3ca21). git status still lists the deleted-but-tracked node_modules/ files. Unchanged.

Inspectr+ 7 commits unpushed

Local main head 8145093 (Sept 21) is 7 ahead / 0 behind origin/main (4140149, Sept 8). origin/main has had no new commits for 24 days.

DailyReportr+ silent 18 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 Breakdown Last 3 Commits (local main)
Buildr+ 0 16 "No issues found!" New: six pages the owner approved for retirement on 2026-08-08 (docs/ux/buildrplus-feature-effectiveness-audit.md) lost their routes in 85364d3, but their files stayed in lib/: 4,527 lines. ActivityLogTimeline and LinkedDocumentsSection are also never mounted, and nothing calls ActivityLogService.log. Still open: the 10 unguarded onDismissed deletes and ProjectCard semantics. a7a5a03 merge harden-ios-release-gate • a2873c3 merge project-card spacing fix • fac04bd source protected secrets file (unpushed)
Closr+ 0 12 "No issues found!" New: connected_sources_page.dart (1,592 lines) has had no importer since 492ce70 (Apr 25, "remove redundant … Connected Sources cards"). Its provider and service (539 lines) are reachable only through that page. Also unimported: punch_list_page, punch_item_form_page, client_portal_page, import_from_procore_page, dashboard_page, and closeout_readiness_card. Still open: the isExpiringSoon boundary gap, the silent portfolio catch (_), and tracked node_modules/. 0925b0b merge harden-ios-release-gate • d4c8952 gate TestFlight IPA on client IDs • ca33394 bump TestFlight 2.32.75 (unpushed)
Inspectr+ 0 18 "No issues found!" Unimported files include auth_page_fixed.dart, paywall_timer_debug_widget.dart, debug_platform_widget.dart, glass_container/glass_dialog, and sync_history_page.dart. The last one was deliberately unlinked in f447ac2 (Jun 16), so it should be deleted, not revived. Still open: the tapped-photo bug (2 entry points). Raw Colors.green: 29. 8145093 merge Google sign-in client-ID fix • 5e0849b merge harden-ios-release-gate • 744cc12 add iOS artifact gate (unpushed)
DailyReportr+ 0 11 "No issues found!" Unimported files: whole equipment, tasks, materials, checklists, gallery, and notes pages, plus daily_report_edit_view.dart. Still open: the admin reports retry loop, the duplicated _buildReportCard with its fake "1 activity" badge, the eager Reports list, 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, from dart analyze lib on git archive main snapshots (after flutter pub get --offline). Unimported files is a new, conservative metric: a lib/ file whose basename appears in no import/export in lib/ or test/ (excluding main.dart and *.g.dart). The total is 57. It undercounts dead code, because files used only by a dead file (such as the Closr+ link provider and service) aren't included. The analyzer doesn't report unused public classes, which is why "0 issues" has hidden this.

Recurring Themes from Morning Briefs

Sources: the Oct 1, Sept 30, and Sept 29 morning briefs (briefs/). There is no Oct 2 morning brief, only morning-reports/2026-10-02.md.

Feature Ideas + UI/Code Health Recommendations

There are 3 recommendations: 2 UI/code health items and 1 feature. With no morning brief today, all three come from a code sweep of main snapshots. Each was checked with grep and git log -S/--all: no commit has wired the activity log, and no orphan guard exists in any repo. The held Sept 28 items (Buildr+ server-confirmed deletes, DailyReportr+ admin failure state) still outrank these.

1. Decide Connected Sources Before Anyone Hardens It Closr+ — UI/Code Health (dead feature / correction)

ConnectedSourcesPage (lib/pages/projects/connected_sources_page.dart, 1,592 lines) has zero references anywhere in lib/ or test/. On Apr 25, 492ce70 ("remove redundant Import Data and Connected Sources cards from Overview tab") deleted _buildConnectedSourcesCard, the only MaterialPageRoute to it, from project_detail_page.dart. project_link_provider.dart and project_link_service.dart (539 lines) are imported only by that page. import_from_procore_page.dart (719 lines), the other half of that card pair, is also unimported. So the _markSynced-on-failure bug (Sept 29), the unlink race, and the missing try/catch (Oct 1) can't affect users today. Yesterday's afternoon brief queued all of them for a builder anyway.

Why now: it stops a builder from spending a night hardening code no one can open. It also removes about 2,850 lines of unreachable Closr+ code if retired. The pattern repeats on the Buildr+ side (Recommendation #2).

Sketch: Owner decision (one line): retire or restore. Retire (default, matching the Apr 25 "redundant" message): delete the page, provider, service, and import_from_procore_page.dart in one commit, and keep the D1 tables and Worker routes until a separate backend cleanup. Restore: re-add one entry point in Project Detail and land the Sept 29 + Oct 1 fixes together with the first service and widget tests. Either way, the change should leave the unimported-file count for Closr+ lower.

2. Finish the Approved Retirements, Then Guard Against New Orphans Buildr+ (pilot) → all apps — UI/Code Health (dead code + test)

The Aug 8 simplification (85364d3, "simplify Buildr project workspaces") removed routes to six pages: RFI Impact Tracker, RFI Field Verification, RFI Action Checklist, RFI Location Assist, Submittal Commitment Tracker, and Submittal Review Radar. The owner approved all six for retirement on 2026-08-08 in docs/ux/buildrplus-feature-effectiveness-audit.md, which calls Commitment Tracker "fabricated" and Field Verification/Action Checklist "in-memory only". Their page files (4,527 lines) are still in lib/, along with providers and services only they use. Submittal Review Radar got a nightly polish on Aug 5, three days before it was retired. The same thing is happening across all four apps: 16/12/18/11 files that nothing imports. Some are obviously stale, like Inspectr+ auth_page_fixed.dart and paywall_timer_debug_widget.dart. Because the analyzer stays at 0, none of this shows up in health checks, and builders and briefs keep finding "bugs" in code that never runs.

Why now: under the "leave it cleaner" standard, this is the largest code-health gain available, and it's mostly deletion that was already approved. Buildr+ already has test/simplification_route_inventory_test.dart, so a reachability test fits right next to it.

Sketch: (a) In Buildr+, delete the six retired pages plus their now-unused providers and services. Re-run dart analyze until it reports 0 again, and keep the inventory test green. (b) Add test/no_orphan_files_test.dart: walk the import/export graph from lib/main.dart, then fail with a list of unreachable lib/**.dart files, minus a small commented allowlist. (c) Port the test to the other three apps once each one has been triaged; start with the Inspectr+ debug and auth leftovers. Only delete what has an owner retirement or is clearly a debug/duplicate file. List anything ambiguous, such as the DailyReportr+ equipment/tasks/materials pages, for the owner instead.

3. Submittal Status History (Who Changed It, From What, When) Buildr+ — Feature

Buildr+ already has a complete activity log stack, but it's never been connected. ActivityLogService.log(documentId, documentType, action, oldValue, newValue, performedBy) writes to the activity_logs support record. ActivityAction.statusChanged exists. ActivityLogTimeline renders a collapsible timeline. However, nothing in lib/ calls log() and nothing mounts the timeline. Today, saving a submittal in submittal_detail_page.dart:251 (updateSubmittal(copyWith(status: _status, …))) overwrites the status with no trace, and so does the Bulk Edit sheet. When an architect asks "who marked this Approved?", the app can't answer.

Why now: Procore shipped Workflows Step Override on Sept 29, which lets users advance a stalled approval with required documentation and attribution history (intel below). An honest status trail is the small, in-scope version of that for Buildr+ submittals. It also turns three dead files into used code instead of adding new ones.

Sketch: In _save(), when editing and widget.submittal!.status != _status, call ActivityLogService().log(action: statusChanged, oldValue: old.name, newValue: _status.name, documentType: 'submittal') only after updateSubmittal succeeds. Do the same per item in the bulk path. Mount ActivityLogTimeline(documentId: submittal.id) on the existing-submittal detail view. Before mounting, fix the timeline's catch (_) {} so a failed load shows "Couldn't load history · Retry" instead of disappearing, and give getLogsForDocument a projectId so it stops listing every activity_logs row client-side. Tests: a status change writes one entry, an unchanged save writes none, a failed update writes none, and a timeline load error shows the retry state.

UI Inconsistencies

Competitive Intel

Tomorrow’s Build Suggestion

This is the twenty-fourth night without builders. The assignments stay held (fifth day). Queue change: the Closr+ Connected Sources hardening pass is removed until the owner decides to retire or restore it (Recommendation #1). 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), and give the one-line Connected Sources decision. For Closr+, stage explicit paths rather than using git add -A.

Dominique → Buildr+

Task: Deletes That Wait for the Server (Sept 28 Recommendation #1). If time remains, delete the six owner-retired pages (Recommendation #2a), which is pure deletion with the inventory test as a safety net. Rationale: Buildr+ hasn't had a nightly feature since Aug 5. A delete that can hide a live project is still the top honesty bug, and the retirement cleanup removes about 4.5k lines no one can reach.

Katey → DailyReportr+

Task: a single reports_page.dart rework: Admin Reports That Admit Failure, then the shared ReportSummaryCard without the fake "1 activity" badge, then a lazy SliverList. Rationale: it's the stalest app (18 days on main), and all three fixes target the same file, which is reachable (unlike the 11 unimported DailyReportr+ files). Queued next for whichever builder frees up first: the Inspectr+ tapped-photo fix, then Buildr+ Submittal Status History (Recommendation #3).