Skip to content

Daily Fro Bot Report — 2026-09-01 (UTC) #3812

Description

@fro-bot

Daily Fro Bot Report — 2026-09-01 (UTC)

Run Summary

Category Status Notes
Errored PRs One open PR (#3811), all 15 checks green. Check-runs and legacy commit statuses both inspected on the head SHA.
Security ⚠️ 0 open Dependabot alerts across fro-bot/*. 4 open code-scanning alerts, all Scorecard-sourced, 2 rated high. Branch protection read directly and verified intact.
Control-Plane Integrity 29 workflows, 20 third-party action refs — all SHA-pinned with version comments. Strip-only clean. Every workflow declares top-level permissions. Guards intact.
Code Quality bootstrap, check-types, lint, test all pass (2845 passed / 3 todo, 71 files). No mechanical fixes needed.
Oversight Dependabot alert data denied to this token for all marcusrbrown/* and bfra-me/* repos (HTTP 403). Everything else enumerated.
Cross-Project Intelligence ⚠️ 30/34 tracked entries scanned. 3 survey failures, 1 lost-access. Coverage partial.
Progressive Improvement Compounding pipeline recovered: the 5-proposal backlog flagged yesterday was authored and closed via #3809. Zero open proposals.

Gateway rollout tracker (#3512) drift is reported under Oversight per the task's routing; no tracker comments or Project edits were made from this path.

Errored PRs

None.

fro-bot/.github has exactly one open PR — #3811 (docs: correct the editable wiki plan to the dashboard-backed architecture, author marcusrbrown, trusted). Both required sources were inspected against head SHA e77dd35:

  • Check runs (gh pr checks + /commits/{sha}/check-runs): 15 contexts, zero failure / timed_out. The lone pending is this run's own in-flight Fro Bot context, not a regression.
  • Legacy commit statuses (/commits/{sha}/status): aggregate success, one record (Security: Private Leak Scan), zero failure / error.

Worth naming the distinction because it keeps biting: those are two different record stores. gh pr checks renders both in one table, but the REST endpoints do not — /check-runs will happily return all-green while a legacy status sits red beside it. Both were read.

Security

  • Dependabot alerts (fro-bot/.github): 0 open. No critical/high advisory is unaddressed, so no remediation PR was warranted. Renovate retains ownership of routine bumps.
  • Code scanning: 4 open alerts, all OpenSSF Scorecard probes, none tied to a source file (no file associated with this alert):
    • Branch-Protection (high) — contradicted by direct observation. Reading /branches/main/protection returns enforce_admins: true, allow_force_pushes: false, allow_deletions: false, required_approving_review_count: 1, require_code_owner_reviews: true, require_last_push_approval: true, strict: true, and 13 required contexts. This is a Scorecard token-visibility artifact, not a real gap. Do not "fix" it by touching protection.
    • Vulnerabilities (high), Fuzzing (medium), CII-Best-Practices (low) — standing posture signals, not incidents.
  • No security PR is failing or conflicted in this repo. Six aging Fro-Bot-authored security PRs exist in bfra-me/* and are listed under Oversight; they are outside this repo's write scope.

Control-Plane Integrity

a. SHA pinning — clean. 29 workflow files and the composite actions were scanned. 20 distinct third-party uses: refs, every one a full 40-hex commit SHA with a trailing version comment. Zero floating tags; zero bare-SHA-without-comment. The two ./-relative refs (./.github/actions/setup, ./.github/workflows/fro-bot.yaml) are local and correctly unpinned.

b. Strip-only TypeScript — clean. No enum, namespace, TS import = alias, or constructor parameter property across scripts/*.ts and packages/**. The only match for the parameter-property pattern is a comment in scripts/repos-metadata.ts:476 explaining why the syntax is avoided. Test Scripts Load and the erasable-syntax-only ESLint rule both pass.

c. Least privilege — clean. All 29 workflows declare top-level permissions. Five declare permissions: {} (private-leak-sentinel, publish-wiki, unpublish-wiki, update-repo-settings) — zero ambient authority, elevation pushed to the job. scorecard.yaml uses read-all, which is the upstream-recommended shape for that action. No workflow that runs pnpm or node scripts/ bypasses ./.github/actions/setup.

d. Guard integrity — intact, nothing relaxed. Check Wiki Authority, Security: Private Leak Scan, and Sentinel all pass on #3811. main protection verified above. No guard was weakened, and none was touched.

Code Quality

All four gates green on a clean tree:

Gate Result
pnpm bootstrap pass
pnpm check-types pass
pnpm lint (check:md-links + eslint) pass
pnpm test pass — 71 files, 2845 passed / 3 todo, 11.7s

No mechanical fixes were available and none were invented. The improvement-metrics-report: digest file has invalid shape and wiki-ingest:warning: corrections-read-failed lines in test output are asserted negative-path fixtures, not real failures — the suites that emit them pass.

Delivery mode for this run was working-dir, so no branch, commit, push, or PR was created by me. Nothing needed one.

Oversight

Scope: 34 public repositories across bfra-me, fro-bot, and marcusrbrown, enumerated via paginated /user/repos with affiliation=owner,collaborator,organization_member. Non-public repositories are out of scope for this surface. No repository failed to enumerate.

Security alerts — could not check. /repos/{owner}/{repo}/dependabot/alerts returns HTTP 403 Resource not accessible by personal access token for every bfra-me/* and marcusrbrown/* repo tested. Only fro-bot/* is readable (0 open there). This is a token-scope gap, not a clean bill of health; see Needs Human Attention.

Failing default-branch checks — 4. All read from both /check-runs and /status:

Repo Failing context Read
bfra-me/github-action Update Repo Settings / Update Repository Settings intermittent
bfra-me/github-app Renovate / Renovate needs a log read
marcusrbrown/dev-like check-links tracked at dev-like#100
marcusrbrown/extend-vscode Pre-Release Validation (vulnerabilities) advisory-driven

The Update Repo Settings failure is worth pulling apart, because the obvious read is wrong. bfra-me/ha-addon-repository#569 files it as a job that "fails with 500," which reads like a config bug. The run history says otherwise: bfra-me/ha-addon-repository ran that workflow six times in the last two hours — 03:58 success, 03:29 failure, 03:22 success, 03:00 success, 02:28 success, 02:15 success. bfra-me/github-action interleaves the same way. fro-bot/.github, consuming the same reusable workflow at the same pin, is 8-for-8 green. A deterministic config fault does not alternate. This is an upstream settings-API 500 with no retry, and the fix is backoff-and-retry in the reusable workflow, not a settings change in any consumer. Recommended next step: read one failed job's log to confirm the 500 origin, then add a bounded retry in bfra-me/.github's update-repo-settings.yaml.

Open PRs — 108 across the fleet. Aging (created >7d ago) and staleness (no commit/review/comment/state change in >14d) measured separately, as specified:

  • Stale PRs: 63. Concentrated, not diffuse — see hotspots.
  • Longest-stale: renovate-config#1383 (untouched since 2026-03-25, 160 days), gpt#2165 (HeroUI v2→v3 migration, 114 days).
  • Six Fro-Bot security PRs stalled since mid-June in bfra-me/github-app (#843, #842, #840) and bfra-me/github-action (#1467, #1466, #1463). Each pair contains a superseding duplicate. Recommended next step: close the superseded halves, then merge or explicitly reject the survivors — a security PR that sits for 78 days is a decision nobody made.

Stale issues (>30d without activity): 41. Largest single cluster is the nine-issue HeroUI v3 migration tree in marcusrbrown/gpt (#2162 and children), untouched since 2026-03-28, plus six techdebt:/todo: issues from 2026-03-25. Recommended next step: decide whether the HeroUI migration is alive; if not, close the tree and its PR together rather than leaving nine orphans pointing at a dead branch.

Unassigned bugs — 7: ha-addon-repository#569, infra#1234, infra#1227, sparkle#1940, systematic#740, marcusrbrown.com#517, marcusrbrown.com#465. The two infra deployment bugs are the load-bearing ones — #1227 reports the deploy router failing at startup, and #1234 reports a manual deploy stuck in waiting. Those two are almost certainly the same fault seen from two ends, and they explain the gateway pin drift below.

New issues in the last 24h (excluding daily-report boilerplate) — 5: ha-addon-repository#569, agent#1517, agent#1514, infra#1234, dev-like#100.

Top three hotspots (ranked by qualifying findings in this snapshot — stale PRs + stale issues + failing default-branch checks):

  1. marcusrbrown/gpt — 32. 15 stale PRs, 17 stale issues, main green. Almost entirely the frozen HeroUI v3 migration (#2162, PR #2165) plus a repeating a11y-contrast PR series (#2664, #2665, #2672, #2673, #2674, #2688, #2692) — seven PRs re-fixing the same Ollama contrast defect on seven different days. That is not seven fixes; that is one unmerged fix and six ghosts of it. Next step: merge or close one, delete the rest.
  2. marcusrbrown/sparkle — 15. 13 stale PRs, 2 stale issues, main green. Same shape: five chore(lint): apply auto-fixes from autohealing run PRs (#1787, #1816, #1886, #1891, #1914) stacked since July. Next step: merge the newest, close the four it subsumes, and consider whether that autoheal should update an existing PR instead of opening a new one.
  3. marcusrbrown/vbs — 13. 8 stale PRs, 5 stale issues, main green. Four are security remediations (#688, #697, #701, #717). Next step: triage those four first; the rest can wait.

The through-line across all three: an autoheal that opens rather than updates accumulates duplicates faster than a human merges them. The remediation is upstream in the autoheal path, not in the queues.

Gateway operator control-surface rollout — #3512, review-only. Three concrete mismatches between the tracker's claims, Project 1, and live evidence:

Claim in #3512 Observed Source
"the deployed gateway is pinned to v0.83.0" (asserted 5×) pin is v0.93.1 marcusrbrown/infra apps/gateway/upstream.json
"Not yet advanced to v0.85.0 (operator push)" already 8 minors past it; latest agent release is v0.107.0 (2026-08-31) fro-bot/agent releases
Dependency matrix: fro-bot/dashboard#179Open CLOSED dashboard issue state

Plus two Project-side gaps: the Project item for #3512 reads Todo while the body describes a rollout with most gates satisfied, and no board item is In Progress; and Project 1's 21 items stop at fro-bot/agent#944 / fro-bot/dashboard#81. Everything the body calls Released or Deployed — agent#1033, #1109, #1111, the six-PR push set (#1152, #1157, #1160, #1162, #1163, #1165), dashboard#108, #122, #179 — has no board representation at all.

The tracker declares "The GitHub Project matrix is the structured source of truth." Right now the board is a fossil layer and the issue body is a stale rollup, so there is no source of truth — only two disagreeing records, both citing the other. The version drift is the sharper signal: an evidence gate that was verified once and then never re-read is indistinguishable from an evidence gate that was never there. Writes belong to the Gateway Rollout Tracker workflow; this path only observes.

Cross-Project Intelligence

metadata/repos.yaml carries 34 tracked entries. Coverage this pass is partial — 30 scanned, 4 not:

  • 3 never surveyed (onboarding_status: pending, no last_survey_at). Not named here: all three are non-public.
  • 1 lost-access, last surveyed 2026-04-23. Also non-public; the entry should be reconciled or retired rather than left indefinitely stale.
  • 3 with last_survey_status: failuremarcusrbrown/renovate-config (2026-08-26), marcusrbrown/systematic (2026-08-15), fro-bot/agent (2026-08-21). These were scanned but their wiki pages are running on data up to 17 days old. fro-bot/agent failing is the costly one — it is the most-changed repo in the fleet and the one this control plane pins.

Adoptable findings (report-only, nothing changed):

  1. Out-of-band health probe. marcusrbrown/infra runs cliproxy-auth-monitor.yaml — a 15-minute scheduled probe with a synthetic self-test that verifies the monitor still detects failure, not just that the target responds. The gateway pin drift above is exactly what that shape catches: #3512 asserts a deployed version from a one-time manual probe, and nothing re-reads it. A scheduled probe comparing dashboard.fro.bot/operator/health contractVersion against apps/gateway/upstream.json would have surfaced the v0.83.0v0.93.1 drift the day it happened. Applicable to this repo's gateway-rollout-tracker.yaml.
  2. Deterministic finding issues over prose reports. This repo's own wiki-lint.yaml emits fingerprinted, idempotent issues (<!-- wiki-lint:subject:fingerprint=… -->). The duplicate-PR sprawl in gpt and sparkle is the same problem in a different medium — a producer that creates instead of reconciling. The fingerprint-and-update pattern is the transferable half.
  3. Link checking as a first-class job. marcusrbrown/dev-like runs link-check.yaml against external URLs and files rot as issues (#100). This repo's check:md-links resolves relative links under root and docs/ only. That gap is precisely why #3798 had to be caught by a separate linter — see below.

Progressive Improvement

Compounding pipeline: recovered. Yesterday's report flagged five open learning-proposal issues with 45-day authoring latency. All five (#3801#3805) are now closed and authored into docs/solutions/ via #3809 — six files across best-practices/, workflow-issues/, and documentation-gaps/. Zero open proposals; zero older than 14 days. The stall condition described in the task is not present today.

Stating the obvious guard anyway: the Improvement Metrics report reading healthy was not the evidence used. It cannot be — unauthored proposals never become classes there, so it stays green exactly when the pipeline is stuck. The evidence is the closed-issue count and the merged authoring commit.

Tool-version drift. Current versions from the npm registry (authoritative for these packages), read this run. Major drift was included in the comparison and is called out:

Package Pinned Latest Drift
eslint 10.9.0 10.9.1 patch
prettier 3.9.1 3.9.6 patch
vitest 4.1.4 4.1.11 patch
pnpm 11.24.0 11.25.0 patch
typescript 6.0.3 7.0.2 major
@types/node 24.13.2 26.4.0 major

Nothing is more than a minor behind. The two majors are Renovate's to schedule, and @types/node is deliberately held at 24 to match the Node 24 strip-only runtime this control plane executes scripts/*.ts under — bumping it to 26 would decouple the type surface from the runtime that actually runs the code. No action taken; no version-bump PR opened.

CI job coverage. No degraded or missing jobs. 29 workflows; 13 required contexts on main. Two known gaps are already filed and remain open: #3793 (no renovate-config-validator gate on a preset that ships org-wide) and #3792 (reusable-workflow deps fall outside the Actions group rule). Both are pre-existing; neither regressed.

Convention drift. None found against .github/copilot-instructions.md. No any, no @ts-ignore, pnpm-only, setup action used consistently.

Stale TODO/FIXME. Two matches repo-wide, both intentional: a test fixture string in scripts/check-private-leak.test.ts:196 and prompt text in .github/workflows/fro-bot.yaml:281. Zero real annotations.

Needs Human Attention

1. Dependabot alert data is unreadable outside fro-bot/* — Oversight security coverage is unverified, not clean.

  • Root cause: the token used by this run lacks the security_events (or equivalent fine-grained Dependabot alerts: read) scope for the bfra-me and marcusrbrown owners. GET /repos/{owner}/{repo}/dependabot/alerts returns HTTP 403 Resource not accessible by personal access token for all of them; fro-bot/* succeeds.
  • Smallest safe fix: grant Dependabot-alerts read on the bfra-me and marcusrbrown installations for the credential referenced as FRO_BOT_PAT in .github/workflows/fro-bot.yaml. No code change.
  • Do not: widen the token to write tiers, or infer "no alerts" from a 403. This run reports ❔ for that sub-signal rather than ✅ precisely because absence of data is not absence of alerts.
  • Verify: gh api repos/marcusrbrown/gpt/dependabot/alerts --jq 'length' returns a number instead of a 403.

2. #3512 gateway rollout tracker asserts a deployed version that is 10 minors stale.

  • Files: fro-bot/.github issue Track cross-repo Gateway operator control-surface rollout #3512 body (dependency matrix + "Remaining rollout tasks" §1); Project 1 item statuses; evidence source marcusrbrown/infra apps/gateway/upstream.json.
  • Root cause: every deployed-version claim in Track cross-repo Gateway operator control-surface rollout #3512 was written from a manual probe on 2026-07-11 and never re-read. upstream.json now pins v0.93.1; the tracker says v0.83.0 five times and says v0.85.0 is "not yet deployed." fro-bot/dashboard#179 is listed Open but is CLOSED. Project 1 has no items for any workstream after agent#944 / dashboard#81.
  • Smallest safe fix: refresh Track cross-repo Gateway operator control-surface rollout #3512's version claims from upstream.json + dashboard.fro.bot/operator/health, flip the #179 row to Done, add board items for agent#1033/#1109/#1111, the six push PRs, and dashboard#108/#122/#179, and move Track cross-repo Gateway operator control-surface rollout #3512's Project status off Todo.
  • Do not: write any of this from the daily-report path. .github/workflows/gateway-rollout-tracker.yaml owns tracker comments and Project field writes, and it maintains a settled snapshot hash (c112ff27…) that an out-of-band edit would desynchronize.
  • Verify: after the tracker workflow runs, gh issue view 3512 --repo fro-bot/.github cites the same ref as gh api repos/marcusrbrown/infra/contents/apps/gateway/upstream.json.
  • Durable lesson worth compounding: a verification gate that is satisfied once and never re-read decays into an assertion. Candidate for docs/solutions/best-practices/. Not authored here — docs/solutions/ is the compounding pipeline's output and this run should not write into it out-of-band.

3. Wiki lint #3798: dangling esphome target in knowledge/wiki/topics/home-assistant.md.

  • Root cause: the file references an esphome topic page twice — a markdown link [ESPHome](esphome) at line 73 and a wikilink [[esphome]] at line 59 — but knowledge/wiki/topics/esphome.md does not exist. Only the markdown-link form trips the linter, so the wikilink at line 59 is a second, currently-silent instance of the same defect. Fixing only line 73 leaves the real gap.
  • Smallest safe fix: either create knowledge/wiki/topics/esphome.md per knowledge/schema.md (preferred — marcusrbrown--esphome-life.md already exists in knowledge/wiki/repos/ and the topic is referenced from three places), or replace both references with the external https://esphome.io URL.
  • Do not hand-edit knowledge/** from an autoheal run. That tree is written by the data branch through the wiki scripts; a direct edit races the survey writer. Route it through the established wiki write path.
  • Verify: re-run wiki-lint.yaml; fingerprint 27b6b7f49461bcb9 should not reappear, and the line-59 wikilink should resolve.

4. Update Repo Settings failures in bfra-me/* are transient upstream 500s, not consumer misconfiguration.

  • Files: bfra-me/.github/.github/workflows/update-repo-settings.yaml (the reusable workflow); consumers bfra-me/github-action, bfra-me/ha-addon-repository, fro-bot/.github.
  • Root cause: the GitHub settings API intermittently returns 500 and the job has no retry. Evidence that it is not deterministic: bfra-me/ha-addon-repository ran 03:58 success, 03:29 failure, 03:22 success, 03:00 success within one hour, and fro-bot/.github is 8-for-8 green on the identical pin.
  • Smallest safe fix: bounded retry with backoff around the settings API call in the reusable workflow.
  • Do not change repository settings, common-settings.yaml, or any consumer's .github/settings.yml in response to this — the config is not what is failing, and ha-addon-repository#569 frames it in a way that invites exactly that wrong fix.
  • Verify: ten consecutive green runs of the workflow across two consumer repos.

5. Duplicate-PR sprawl is a producer defect, not a queue-hygiene problem.

  • Root cause: the autoheal path in marcusrbrown/gpt and marcusrbrown/sparkle opens a new PR each run instead of updating the existing open PR for the same root cause. Result: seven PRs for one Ollama contrast fix in gpt, five for one lint-autofix in sparkle.
  • Smallest safe fix (in the producer): before opening, search for an open same-author PR whose head branch matches the deterministic branch name for that root cause, and push to it instead. This repo's wiki-lint.yaml fingerprint-and-update pattern is the working reference implementation.
  • Do not mass-close the existing duplicates before the producer is fixed — they will regenerate within a day, and the closures will bury the one PR that actually carries the fix.
  • Verify: two consecutive autoheal runs against an unfixed defect produce one PR with two commits, not two PRs.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions