Skip to content

Daily Fro Bot Report — 2026-09-11 (UTC) #3883

Description

@fro-bot

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

Run Summary

Category Status Notes
Errored PRs ✅ Remediation pass found 5 open PRs, all green on check runs and legacy statuses. Four BLOCKED on required review, not CI.
Security ⚠️ This repo: 1 open medium (dev-scope transitive), below autoheal bar. Org-wide: alert data denied on 17 of 22 repos probed — see Security.
Control-Plane Integrity ✅ 20 action refs all full-SHA + version comment; strip-only TS clean; 29/29 workflows declare permissions; settings.yml matches live protection.
Code Quality ✅ bootstrap / check-types / lint / test green on main at 36894f6 — 79 files, 3672 tests.
Oversight ⚠️ 38 repos enumerated. 3 default branches red; 8 repos carrying stale bot PRs; 6 open PRs against one finding in the top hotspot.
Cross-Project Intelligence ⚠️ 34 tracked entries scanned, coverage partial (3 private withheld, 3 never surveyed, 2 survey failures, 1 lost-access). One durable pattern persisted to the wiki.
Progressive Improvement ⚠️ Compounding pipeline healthy (0 open learning-proposal, 5 authored+closed 09-08). Two majors behind on TypeScript and Vitest.

Categories 1–4 were executed by the separate remediation pass in branch-pr mode; the rows above are read from what it produced, not re-analyzed. Its report comment is here.

Errored PRs

None. The remediation pass inspected both check runs and legacy commit statuses across #3877, #3878, #3879, #3880, #3882 and found zero failures from either source. BLOCKED on four of them is branch protection's one-approving-review requirement with require_last_push_approval: true, not a red check — #3878 is CLEAN because it has the review.

The one genuinely broken thing in this repo, Manage Issues → Lock, is covered by #3880 (pin verified against upstream: annotated tag v6.0.2 → 89ae32b). Eleven consecutive failed scheduled runs, one line of repair, waiting on a signature.

Security

This repo: one open Dependabot alert, @humanfs/node < 0.16.8 (GHSA-p498-v437-472g), medium, development scope, transitive through the ESLint stack. Below the critical/high autoheal threshold; Renovate owns it.

Org-wide coverage is where this row earns its ⚠️. I probed Dependabot alerts on 22 repositories:

  • Readable (5): fro-bot/.github (1 medium), fro-bot/agent, fro-bot/dashboard, fro-bot/space-bus, fro-bot/systematic (0 open each).
  • Denied (17): every marcusrbrown/* and bfra-me/* repo probed returns 403 Resource not accessible by personal access token.

So org-wide security posture is not verified clean — it is unverified. I will not infer a clean bill from a denied read. The only cross-org security signal I can see is indirect and unflattering: eleven fix(security): PRs authored by Fro Bot sit unmerged across four repos, the oldest 87 days.

Control-Plane Integrity

Verified clean by the remediation pass: 20 distinct third-party action references across 29 workflow files and .github/actions/**, every one a full 40-hex SHA with a # vX.Y.Z comment; no enum / namespace / parameter properties / TS import aliases in scripts/*.ts with erasableSyntaxOnly still live at eslint.config.ts:28; all 29 workflows declaring top-level permissions, the only contents: write grants being the two data-branch writers; .github/settings.yml matching live branch protection at 14 contexts with strict: true.

No guard was weakened. Check Wiki Authority, the privacy gates, and the mutation guard are all still required and all still passing.

Code Quality

Green. pnpm bootstrap, check-types, lint, test all pass on main at 36894f6 — 79 test files, 3672 tests, 3 todo. No mechanical fixes were available to apply.

Oversight

Enumeration. 38 repositories returned with at least read access via paginated user/repos (affiliation=owner,collaborator,organization_member). One gap to name: GET /user/orgs returns an empty list — the token lacks read:org, so organization membership could not be enumerated directly. Org-owned repos still surfaced through the organization_member affiliation, so coverage is believed complete but was reached by inference rather than by listing. Private repositories are excluded from everything below by policy; nothing about them is reported here.

Failing default branches (3).

Repo Check Shape
fro-bot/.github Lock 11 consecutive failures. Fix open at #3880.
marcusrbrown/marcusrbrown.com Fro Bot 11 consecutive failures, twice daily since 2026-09-06. Untracked.
marcusrbrown/containers Renovate / Renovate Single failure 00:59Z, succeeded again at 01:00Z. Transient.

The middle row is the one that matters. The agent hits a recoverable LLM error (APIError; status=400) on a scheduled run, then:

##[warning] Cannot post error comment: missing target context
##[error]  Agent execution failed with a recoverable LLM error, and no delivery surface was available to report it.

A transient upstream 400 becomes a hard red job because a scheduled run has no issue or PR to report into. It has failed this way 11 times and generated exactly zero notifications, because the thing that broke is the notifier. Next step: file this against fro-bot/agent — a scheduled run needs a fallback delivery surface (a rolling issue, or a run-summary annotation) so a recoverable error is reported rather than merely red. No matching open issue exists there today.

Stale and aging PRs. Measured from creation (aging, >7d) and last activity (stale, >14d idle), public repos only:

Repo Stale bot PRs Oldest
marcusrbrown/gpt 15 #2165, 123d idle
marcusrbrown/vbs 8 #671, 62d idle
marcusrbrown/tokentoilet 7 #1298, 52d idle
marcusrbrown/marcusrbrown.com 6 #462, 65d idle
marcusrbrown/containers 4 #723, 36d idle
marcusrbrown/opencode-copilot-delegate 4 #135, 30d idle
bfra-me/github-app 3 #840, 86d idle
bfra-me/github-action 3 #1463, 86d idle

Top three hotspots, ranked by qualifying findings in this snapshot:

  1. marcusrbrown/gpt (~33) — 15 stale PRs + ~18 stale issues. Six PRs against one finding; see Cross-Project Intelligence. Next step: pick one of #2672, #2673, #2692 (the three still mergeable), merge it, close the other five and #2519.
  2. marcusrbrown/vbs (~13) — 8 stale PRs incl. five fix(security): aged 33–62d, plus four open convention-drift issues. Next step: drain the security four (#672, #688, #697, #701, #717) before they conflict.
  3. marcusrbrown/tokentoilet (~12) — 7 stale PRs, six of them fix(security): aged 31–52d, plus three AGENTS.md/docs-drift issues. Next step: same — the advisory remediations are one-line override edits that only get harder with age.

Stale issues (>30d). Concentrated in the same three repos. marcusrbrown/gpt alone carries the entire HeroUI v2→v3 migration tree (#2175 + 8 children) untouched for 166 days. Next step: close the tree as superseded or re-baseline it; nine issues frozen at the same timestamp are a plan, not a backlog.

Unassigned bugs. marcusrbrown/infra#1234 (bug,deployment, stuck deploy), #1258, #1277, #1278, #1292; bfra-me/ha-addon-repository#569 (settings-sync 500, 8d idle); marcusrbrown/marcusrbrown.com#465 and #517.

No issues or PRs were modified and no labels applied in this category.

Cross-Project Intelligence

Coverage: partial. metadata/repos.yaml holds 34 tracked entries. Scanned: 30 public. Not scanned or incomplete:

  • 3 private — excluded by policy, identities withheld.
  • 3 never surveyed (onboarding_status: pending, last_survey_status: null) — all three private, so they are simultaneously the pending set and the withheld set.
  • 2 survey failures — marcusrbrown/renovate-config (last attempt 2026-08-26) and bfra-me/renovate-action (2026-09-02). Both have gone ≥9 days without a successful ingest.
  • 1 lost-access — marcusrbrown/copiloting, retained in the ledger with status recorded.

Two bfra-me repos carrying findings in this report (github-action, github-app) have no wiki page at all — they are not in repos.yaml, so the ingest loop has never looked at them. That absence is why the finding below went uncounted for three months.

The adoptable finding — autoheal re-derivation has become self-blocking.

The duplicate-authoring behavior was previously recorded as a single pair in one repo. It now measures fleet-wide, and it has crossed a severity line. marcusrbrown/gpt#2519 has six open Fro-Bot PRs all editing the same one file, src/components/settings/ollama-settings.tsx:

PR Opened Mergeable
#2664 fix(a11y): improve ollama status contrast 2026-07-08 CONFLICTING
#2665 fix(a11y): improve ollama settings contrast 2026-07-09 CONFLICTING
#2672 fix(ui): restore ollama chip contrast 2026-07-12 MERGEABLE
#2673 fix(accessibility): improve ollama status chip contrast 2026-07-13 MERGEABLE
#2674 fix(accessibility): keep ollama status legible 2026-07-18 CONFLICTING
#2692 fix(a11y): improve ollama settings contrast 2026-07-28 MERGEABLE

#2665 and #2692 share a byte-identical title 19 days apart. The same signature appears as exact-title, day-apart pairs in bfra-me/github-action (#1463/#1467) and bfra-me/github-app (#840/#843), both touching only pnpm-lock.yaml + pnpm-workspace.yaml.

Three of gpt's six conflict — with each other, not with upstream drift. The loop has manufactured work that can no longer be merged without a human picking a winner. What this repo should adopt: deduplication has to be a pre-authoring gate, not a post-hoc report note. Caps, null-verdict clauses, and strict-order ladders all bound volume per run without preventing the same fix being authored on the next one. Detection is cheap and needs no prose comparison — group open bot-authored PRs by (repo, changed file set) and flag any group of size > 1; all eight PRs above are one- or two-file changes, so the key is exact.

Persisted to the wiki this run: knowledge/wiki/topics/github-actions-ci.md (additive subsection under the existing 2026-08-30 null-verdict section, where the marcusrbrown/dev-like control case already lives), plus knowledge/index.md and knowledge/log.md. No prior content replaced.

No changes were made in any scanned repository.

Progressive Improvement

Compounding pipeline: healthy. Zero open learning-proposal issues. The last cohort (#3849–#3853) was authored into docs/solutions/ and closed on 2026-09-08 — three days ago, five proposals, five docs. docs/solutions/ now holds 59 entries. Neither stall condition (any proposal >14d, or ≥2 open at once) is met, and this reading comes from the proposal queue directly rather than from #3674, per the caveat in the brief.

Tool-version drift. Declared versions in package.json versus latest on the npm registry (registry.npmjs.org, queried live this run); major drift is included in this comparison:

Tool Declared Latest Drift
eslint 10.10.0 10.10.0 current
prettier 3.9.1 3.9.6 5 patches — within tolerance
typescript 6.0.3 7.0.2 one major
vitest 4.1.11 5.0.0 one major
pnpm (packageManager) 11.25.0 12.3.4 one major (#3882 moves it to 11.26.0, in-lane)

Both majors are parked deliberately — Renovate owns them and they carry real migration cost. Reporting them as visibility, not as a request. One genuine inconsistency worth a cheap fix: @vitest/coverage-v8 is pinned at 4.1.4 while vitest is at 4.1.11. Vitest requires its coverage provider to match the core version; a seven-patch gap inside the same minor is a latent instrumentation mismatch, not a policy decision.

CI jobs. No missing or degraded jobs. All 14 required contexts present and passing; 29 workflow files, 26 with runs in the last 30 days.

Convention drift from copilot-instructions.md. One item, documentation-only: README.md:153 claims "25 GitHub Actions workflows"; there are 29 files. The Automation tables also omit Cross-Repo Dispatch (cross-repo-dispatch.yaml) and Unpublish Wiki (emergency takedown) (unpublish-wiki.yaml). The second omission has operational weight — docs/wiki-site-runbook.md documents the emergency takedown procedure, and the workflow that performs it is absent from the inventory a reader would consult under pressure.

Stale TODO/FIXME. None. The single match in the tree is a string literal inside a test fixture at scripts/check-private-leak.test.ts:219.

Gateway Operator Control-Surface Rollout (#3512)

Review awareness only. No tracker comment posted and no Project field edited from this path — the dedicated Gateway Rollout Tracker workflow owns those writes. Two drifts, both values given:

1. Issue body contradicts its own audit log. The body of #3512 still states that operator push is "Not yet deployed (the deployed pin is v0.83.0)". The tracker's 2026-09-10 comment establishes the pin moved v0.83.0 → v0.86.0 (2026-07-11, marcusrbrown/infra#817, first deployed pin carrying the v0.85.0 push surface) → v0.88.0 → v0.93.1 (current), with packages/gateway/src/web/operator-push/** confirmed present at tag v0.93.1.

  • Body claims: not deployed, pin v0.83.0.
  • Evidence claims: deployed since v0.86.0, pin now v0.93.1.

The body is two months and three pins stale. The rollup and the audit log disagree, and the rollup is the half humans read first.

2. Project 1 item status contradicts every sibling. The fro-bot/.github#3512 item on Project 1 carries Status = Todo while all 20 other tracked items read Done.

  • Board value: Status = Todo, Readiness = tracking.
  • Tracker's owed value: Status = In Progress, Readiness = ready now.

The tracker could not write it. Its comment records updateProjectV2ItemFieldValue returning Resource not accessible by personal access token on both fields. The read path authenticates fine and the write path does not — which, per docs/solutions/workflow-issues/required-github-token-for-agent-steps-2026-06-22.md, is the exact signature that sends people debugging the agent instead of the credential. Capability here is bounded by token scope, not token presence. This will fail identically on every scheduled run until the token carries Projects write scope.

Not drift, but worth surfacing: activation of operator push is blocked on a policy precondition, not a technical one — fro-bot/dashboard#238 (publish the public operator push privacy policy) has been open and untouched for 51 days. The VAPID deploy contract is wired and fail-closed; no keys are seeded. Wired, unpowered.

Needs Human Attention

1. marcusrbrown/marcusrbrown.com — the Fro Bot job fails silently-loudly, 11 runs deep.
Root cause: a scheduled run has no issue or PR context, so when the agent hits a recoverable APIError; status=400, the error-comment path finds no delivery surface and the job exits red with the report undelivered. File against fro-bot/agent; no matching open issue exists. Smallest safe fix is in the agent's error-delivery path, not in the consuming repo: on a schedule/dispatch trigger with no target context, fall back to a rolling issue or $GITHUB_STEP_SUMMARY before failing. Do not "fix" this by making the recoverable error non-fatal — that converts a visible red into an invisible no-op, which is strictly worse. Verify by forcing a 400 on a scheduled run and confirming the report lands somewhere durable.

2. marcusrbrown/gpt#2519 — six competing PRs, three mutually conflicting.
Exact paths: all six touch only src/components/settings/ollama-settings.tsx. Merge exactly one of #2672 / #2673 / #2692 (the three still MERGEABLE), then close #2664, #2665, #2674 and the remaining two of the mergeable trio, then close #2519. Do not attempt to rebase the three CONFLICTING PRs — they conflict with each other, so rebasing produces a fourth variant of the same fix rather than resolving anything. Verify by re-running axe against the settings panel after the merge.

3. Projects write scope is missing from the tracker token.
updateProjectV2ItemFieldValue returns Resource not accessible by personal access token for Project 1 items. The owed edit is recorded in #3512's 2026-09-10 comment (Status: Todo → In Progress, Readiness: tracking → ready now). Grant the tracker credential Projects write scope, or accept that the board is human-maintained and remove the tracker's write attempt so it stops reporting an owed edit it structurally cannot make. A tracker that narrates state it cannot record is a very articulate log line. Verify by dispatching the Gateway Rollout Tracker and confirming the field moves.

4. #3512's body rollup is two months stale.
Edit the "Shipped / closed" bullet for operator push: it says v0.85.0 is "Not yet deployed (the deployed pin is v0.83.0)"; the deployed pin is v0.93.1 and the push surface has been deployed since v0.86.0 (2026-07-11). The evidence is already in the issue's own 2026-09-10 comment, so this is a transcription, not an investigation.

5. @vitest/coverage-v8 is seven patches behind vitest.
package.json declares vitest@4.1.11 and @vitest/coverage-v8@4.1.4. Vitest expects the coverage provider to track the core version; the gap opened when the vitest security bump (#3873) advanced core without the provider. Smallest safe fix is aligning @vitest/coverage-v8 to 4.1.11. This is a same-minor alignment, not a version bump in the Renovate-owned sense. Verify with pnpm coverage.

6. README workflow inventory drift.
README.md:153 says "25 GitHub Actions workflows"; there are 29. The Automation tables omit cross-repo-dispatch.yaml (Cross-Repo Dispatch) and unpublish-wiki.yaml (Unpublish Wiki (emergency takedown)). The second matters operationally — docs/wiki-site-runbook.md depends on that workflow existing and the inventory doesn't list it. Fix is a count correction plus two table rows. Verify with pnpm lint, which runs check-md-links (link validity only — the count is not machine-checked, which is why it drifted).

7. Two tracked repos have not ingested successfully in ≥9 days.
marcusrbrown/renovate-config (last_survey_status: failure, 2026-08-26) and bfra-me/renovate-action (failure, 2026-09-02). Re-dispatch via gh workflow run survey-repo.yaml -f node_id=<node_id>, reading node_id from metadata/repos.yaml on the data branch. If they fail again, the failure reason is the finding — capture it rather than retrying a third time.

8. Org-wide security alert visibility is denied.
17 of 22 probed repositories return 403 Resource not accessible by personal access token on GET /repos/{owner}/{repo}/dependabot/alerts — every marcusrbrown/* and bfra-me/* repo. Only the five fro-bot/* repos are readable. Until that scope exists, org-wide security in this report is ❔, never ✅. Either grant the credential security_events read across those orgs, or record the limitation as permanent so future runs stop re-probing 17 endpoints for a guaranteed 403.

9. GET /user/orgs returns empty.
The token lacks read:org, so organization membership cannot be enumerated directly. Org repos surfaced anyway through the organization_member affiliation on user/repos, so today's coverage is believed complete — but it was reached by inference. If an org is ever added whose repos the token cannot see through affiliation, this sweep will silently under-report it with no error to notice.

🤖 Generated by Fro Bot · run 34560259464

Activity

  1. fro-bot commented on Sep 13, 2026

    @fro-bot
    OwnerAuthor

    Superseded by the 2026-09-13 report: #3885

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