Skip to content

Daily Fro Bot Report — 2026-09-20 (UTC) #3902

Description

@fro-bot

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

Run Summary

Category Status Notes
Errored PRs Remediation pass found none. The single non-Fro-Bot open PR (#3882) is green on check runs and legacy commit statuses. Evidence: remediation comment.
Security ⚠️ 1 open Dependabot alert (@humanfs/node, medium, dev-scope, transitive) — below the auto-heal bar. Fleet: a 71-day-old high-severity remediation PR sits unmerged in marcusrbrown/vbs#672.
Control-Plane Integrity ⚠️ Pinning / strip-only TS / least-privilege / guards all clean. Renovate global-config finding confirmed durable and documented#3901. data → main blocked 7 days; stranded 57 → 62.
Code Quality Remediation pass ran the full gate on clean main at 9b9635b: 79 files / 3687 passed, zero autofixable drift. #3901 is green on all 14 required contexts.
Oversight ⚠️ 38 repos enumerated, all public, 4 archived. Open PRs 112 → 92, stale >14d 58 → 46 — a real one-day drawdown. Only 3 of 34 default branches genuinely red.
Cross-Project Intelligence ⚠️ 34 tracked entries; coverage partial — 2 public survey failures, 3 non-public pending, 1 lost-access. One high-value adoptable finding.
Progressive Improvement ⚠️ 5 learning-proposal issues open, all 6 days old, zero authored. Newest docs/solutions/ entry is 12 days old. Two tools a major behind per the npm registry. TODO/FIXME debt zero.

Errored PRs

None. Not re-analyzed here — the remediation pass covered categories 1–4 in branch-pr mode and left its evidence at issue #3900, remediation comment.

  • #3882 chore(deps): update pnpm to v11.27.0 — 13 check runs pass, 3 skipped by design; legacy renovate/stability-days + Security: Private Leak Scan green. MERGEABLE, BLOCKED on REVIEW_REQUIRED. Green and waiting 10 days.
  • #3901 docs(renovate): correct the global-config comment to state the input is inert — opened by the remediation pass at 04:28 UTC, all 14 required contexts green.

That pass cut one branch and opened one PR. Unlike the prior two days, something landed.

Security

One open Dependabot alert, unchanged for a fifth day: @humanfs/node / GHSA-p498-v437-472g, medium, scope development, transitive via eslint. Medium does not authorize a dependency change; Renovate owns routine bumps. Four open code-scanning alerts, all OpenSSF Scorecard posture results rather than code findings — the BranchProtectionID high wants 2 required reviews against the current 1, and branch protection is out of bounds by construction.

The security finding that matters today is not in this repo. Fleet sweep surfaced marcusrbrown/vbs#672"fix(security): remediate high-severity ws DoS advisory (GHSA-96hv-2xvq-fx4p)", authored by fro-bot, open 71 days, last touched 71 days ago. A remediation PR that nobody ever touched is strictly worse than an unremediated advisory, because the advisory at least still shows up on a dashboard while the PR reads as handled. Next step: merge or close it; do not let it keep aging as a false signal of coverage.

Control-Plane Integrity

Clean on every structural axis the remediation pass checked: SHA pinning with version comments across all workflows and composite actions, no enum/namespace/parameter-properties in scripts/*.ts, top-level permissions: on all 29 workflows with no write-all, and live branch protection matching .github/settings.yml exactly (14 contexts, enforce_admins: true).

Resolved into documentation: the global-config input in .github/workflows/renovate.yaml has never disabled autodiscover. Two independent upstream causes, both verified at the current pin (bfra-me/renovate-action@78e446d, 10.42.1) — the action interpolates the JSON textually into a double-quoted shell assignment at action.yaml:220 (despite already binding it as env at line 75), and the reusable workflow derives autodiscover from the repository name and passes it as an explicit input that a parsed global-config would lose to anyway. #3901 corrects the comment and changes nothing executable; parsed YAML is identical before and after.

Still broken — data → main promotion, day 7. 62 commits stranded (57 yesterday, 52 the day before). Merge Data Branch last failed 2026-09-13 at 🔒 Block private wiki pages and is a Sunday-only cron. Today is Sunday; tonight's 22:00 UTC attempt will fail identically unless someone acts on data first. Working-tree inspection of metadata/repos.yaml puts a number on it: of 34 entries, exactly one has no explicit private field. That is the whole tripwire.

Code Quality

Not re-run here. The remediation pass executed the repository's own gate twice on main at 9b9635b and again on the PR branch — pnpm bootstrap, check-types, lint, test (79 files, 3687 passed, 3 todo), plus check:wiki-write-core-dist. git status clean afterward; zero lint or format autofix to commit.

Oversight

38 repositories enumerated via paginated user/repos for the fro-bot account (affiliation=owner,collaborator,organization_member). user/orgs returns empty — fro-bot holds no org memberships, so all reach is direct-collaborator. All 38 are public; 4 archived; nothing failed to enumerate.

The backlog actually moved. Yesterday's snapshot vs today:

Measure 2026-09-19 2026-09-20
Open PRs (fleet) 112 92
Stale PRs >14d (no activity) 58 46
Aging PRs >7d (since creation) 68
Open issues 190
Stale issues >30d 134

A 20-PR drawdown in a day is the largest single-day movement recorded in this report series. Worth a caveat: this is a snapshot difference, not an audited merge count.

Default-branch health: 3 of 34 genuinely red, not 8. The raw check-runs array flagged 8 repos, but that endpoint is an append log — every re-run against a commit adds a record instead of replacing it. Reducing to the latest record per check name gives the true set:

Repo Failing check
bfra-me/github-action Update Repo Settings / Update Repository Settings
marcusrbrown/extend-vscode Pre-Release Validation (vulnerabilities)
marcusrbrown/marcusrbrown.com Fro Bot

The five that dropped out were Renovate / Renovate records superseded by later green runs on the same head — the known upstream osv-offline tag-rotation transient. This set is identical to the one measured 2026-09-18, which is the useful part: the reduced set held while the raw count fell 15 → 8 with nothing repaired.

The headline: marcusrbrown/marcusrbrown.com's scheduled agent has been dead for 15 days. 326 scheduled runs lifetime (288 success / 38 failure); last success 2026-09-05T15:35:45Z; 29 consecutive failures since, both crons firing on time. Every run dies in ~11 s on APIError; status=400, "type":"configuration", and terminates with:

Agent execution failed with a recoverable LLM error, and no delivery surface was available to report it.

The agent is explicitly reporting that it cannot report. A schedule run has no triggering PR or issue, so the error channel does not exist on precisely the one trigger nobody is watching. The streak now spans agent v0.107.0 → v0.113.2 — eight version bumps rode over it without causing or fixing it, which clears the release line as a suspect. Remaining hypothesis: fro-bot.yaml:621 passes model: ${{ vars.FRO_BOT_MODEL }}, a repository-scoped variable; this control plane uses the identical expression and runs green, so the fault localizes to that repo's value. Unverified — the variables API returns 403 to this token.

Top three hotspots (ranked by qualifying findings: stale issues >30d + PRs aging >7d + PRs stale >14d + genuinely-failing default branch):

  1. marcusrbrown/gpt — 53. 23 stale issues, 15 aging PRs, all 15 also stale. Oldest: #2165 "feat(ui): Migrate from HeroUI v2 to v3", 175 days old, 132 days untouched. → Close the abandoned migration PR explicitly rather than letting it define the repo's backlog.
  2. marcusrbrown/vbs — 37. 19 stale issues, 10 aging PRs. Contains the 71-day high-severity security PR above. → Triage #672 and #671 first; both are Fro-Bot-authored fixes that went nowhere.
  3. marcusrbrown/marcusrbrown.com — 19. 6 stale issues, 6 aging PRs (all 6 also stale), plus the dead daemon. Oldest PR #462 at 74 days. → Fix the daemon first; the PR backlog here is a symptom of the same unattended loop.

Unassigned bug-labelled issues: 6, oldest marcusrbrown/marcusrbrown.com#465 at 73 days. New in last 24h: 17 issues, of which 11 are automated daily reports — the genuine new work is fro-bot/agent#1633, #1631, marcusrbrown/systematic#1014, #1005, and marcusrbrown/.dotfiles#2666.

No issues or PRs were modified or labelled in this category.

Cross-Project Intelligence

Coverage is partial. 34 tracked entries in metadata/repos.yaml; 30 carry private: false and were scannable. Not covered, and why:

Class Count Note
Public, survey failure 2 marcusrbrown/containers, marcusrbrown/dev-like
Non-public entries 3 Not named, not scanned — public-only invariant
onboarding_status: lost-access 1 Cannot be surveyed at all
No explicit private field 1 The entry blocking data → main; counted, not named

cross_repo_receipts remains set on zero entries, unchanged since first reported. Oldest public survey is marcusrbrown/gpt at 2026-09-03 (17 days).

Adoptable finding — marcusrbrown/infra has already solved today's biggest problem. Its release-alert.yaml is a workflow_run-triggered liveness alarm with three properties this control plane lacks:

  • permissions: issues: write and nothing else — minimum viable blast radius for an alarm.
  • Marker-based issue upsert (<!-- release-publish-failure:v1 -->) — one perpetual alert, not a new issue per failure.
  • An owner-only synthetic self-test via workflow_dispatch, which fabricates a failure and exercises the whole alarm path without breaking the watched workflow. An alarm you cannot test is an alarm you are merely hoping about.

This repo has three workflow_run consumers (check-private-leak.yaml, private-leak-sentinel.yaml, renovate.yaml), and none of them watch for failure. Two of today's findings are the same shape as what this pattern catches: Merge Data Branch failing unheard between Sunday crons, and marcusrbrown.com's agent dying 29 times into an empty room. Adopting it against Merge Data Branch would have surfaced the stranded-commit problem on day one instead of day seven. Report-only; no change made.

Progressive Improvement

The compounding pipeline is stalled. 5 open learning-proposal issues — #3887, #3888, #3889, #3890, #3891 — all 6 days old, all authored by fro-bot, none authored into docs/solutions/. None has crossed 14 days yet, but the count alone (≥2) is the stall signal, and the newest docs/solutions/ entry is dated 2026-09-08, 12 days ago against 59 total docs.

As instructed, the healthy reading on Improvement Metrics #3674 is not evidence this is fine — that report was last generated 2026-09-14 and counts codified classes, so five unauthored proposals are invisible to it by construction. It stays green because this is stalled.

Tool-version drift, current-version truth from the npm registry (npm view <pkg> version, checked 2026-09-20). Major drift is included below:

Tool Declared Registry latest Drift
typescript 6.0.3 7.0.2 major
vitest 4.1.11 5.0.1 major
@vitest/coverage-v8 4.1.4 5.0.1 major
eslint 10.10.0 10.11.0 minor
prettier 3.9.1 3.9.8 patch
@stryker-mutator/core 10.0.0 10.0.0 none ✅

Two majors parked, consistent with yesterday. Renovate owns these; nothing opened. One genuinely new nit: @vitest/coverage-v8 (4.1.4) trails vitest (4.1.11) inside the same major. Vitest expects the coverage provider to track the runner version; the skew is small and currently harmless, but it is the kind of drift that produces a confusing failure at the next major boundary rather than now.

CI jobs: no degradation. All 14 required contexts executed and passed on #3901. TODO/FIXME debt in scripts/*.ts: 0. No convention drift from copilot-instructions.md detected.

Gateway Rollout Tracker (#3512)

Review-awareness only; no tracker comment posted and no Project field edited. Four mismatches between #3512 and Project 1:

# Claim Live value
1 Issue body describes the operator surface as functionally complete (contract v1.6.0 live, cancellation shipped, push shipped) Project 1 status for #3512 = Todo, while 20 of its other 21 items are Done
2 "Agent releases have since advanced to v0.85.0" Upstream release source (gh release list --repo fro-bot/agent) says latest is v0.113.2 (2026-09-16) — 28 minor versions stale, no major boundary crossed
3 "The GitHub Project matrix is the structured source of truth" fro-bot/dashboard#108 (CLOSED/COMPLETED 2026-07-10) and the six push PRs #1152#1165 are cited in the body but are absent from Project 1 — so for those, the body is the only record
4 "comments are the audit log" Last comment is 2026-06-18, 94 days ago, while the body was edited 2026-09-19. The rollup moved; the audit log did not

Mismatches 3 and 4 are the same defect in two directions: the issue names two structured sources of truth and is currently more current than both. The dedicated Gateway Rollout Tracker workflow owns any write here.

Needs Human Attention

1. data → main promotion, day 7. 62 commits stranded, ~5/day. One entry is the whole blocker.

  • Files: metadata/repos.yaml on the data branch (not main), scripts/check-wiki-private-presence.ts.
  • Root cause: an orphan wiki page with no metadata/repos.yaml entry on data, whose slug matches no repository the fro-bot token can enumerate. Measured today: of 34 entries, exactly 1 lacks an explicit private field. That is the entire tripwire surface.
  • Existing lead: branch copilot/fix-data-orphan-private-repos exists on origin, head 8ea9588 "fix(data): remove orphan private repo entries blocking data merge", no open PR, 315 ahead / 77 behind. Evaluate before writing anything new; 77 behind means rebase onto current data, not merge as-is.
  • Smallest safe fix: resolve that one entry's private field to an explicit true/false on data. Auditing all 34 for the same omission drains the class rather than defusing one instance.
  • Do not: weaken or bypass the gate, add a slug allowlist, or dispatch Merge Data Branch hoping it clears — it fails identically and yields no new diagnostic signal.
  • Verify: local --operator-report run showing zero leaks → successful Merge Data Branchgit rev-list --count origin/main..origin/data returns 0.
  • Reachable only from a working-dir run or a human on data.

2. marcusrbrown/marcusrbrown.com scheduled agent, dead 15 days, 29 consecutive failures.

  • File: .github/workflows/fro-bot.yaml in that repo, line 621 (model: ${{ vars.FRO_BOT_MODEL }}).
  • Root cause, confirmed: every scheduled run fails in ~11 s with APIError; status=400, "type":"configuration", surviving a 3-cycle grace period. Last success 2026-09-05T15:35:45Z.
  • Root cause, hypothesized and unverified: the repository-scoped Actions variable FRO_BOT_MODEL is unset or names a retired model. fro-bot/.github uses the byte-identical expression and runs green daily, which localizes the fault to that repo's value rather than the expression or the agent. The variables API returned 403 to this survey's token — this could not be confirmed and must not be reported as fact.
  • Smallest safe fix: run the workflow via workflow_dispatch with a step that echoes the resolved model id, compare against a currently-served model, and correct the variable. One variable edit, no code change.
  • Do not: bump the agent version hoping it clears — eight bumps (v0.107.0 → v0.113.2) have already ridden over this without effect. Do not assume it will self-heal; the 09-16 survey hedged that it might, and four more days disproved it.
  • Verify: one scheduled run concluding success, or a dispatch run that gets past the 11-second mark.
  • Second-order fix worth doing anyway: a schedule run has no PR or issue to comment on, so this outage was undiscoverable from the agent's own output for 15 days. Port marcusrbrown/infra's release-alert.yaml pattern (see Cross-Project Intelligence) so failures alarm into a marker-upserted issue.

3. marcusrbrown/vbs#672 — a high-severity security remediation PR, unmerged 71 days.

  • Link: fix(security): remediate high-severity ws DoS advisory (GHSA-96hv-2xvq-fx4p) marcusrbrown/vbs#672, fix(security): remediate high-severity ws DoS advisory (GHSA-96hv-2xvq-fx4p), authored by fro-bot, created and last updated 71 days ago.
  • Why it matters: an open remediation PR reads as coverage. Until it merges, the advisory is live and invisible to anyone who sees the PR and assumes it is handled.
  • Action: merge it or close it with a reason. Either is better than a third month of ambiguity. Sibling #671 is in the same state.

4. No failure alarm on any workflow_run consumer in this repo.

  • Files: .github/workflows/ — three workflow_run consumers exist (check-private-leak.yaml, private-leak-sentinel.yaml, renovate.yaml), none triggered on failure.
  • Root cause: Merge Data Branch is a Sunday-only cron whose fail-closed refusal has no subscriber, so a blocked promotion accrues ~5 stranded commits/day for a week before anyone reads it in a daily report.
  • Smallest safe fix: add one workflow modeled on marcusrbrown/infra's release-alert.yamlworkflow_run on Merge Data Branch completed, if conclusion is failure, permissions: issues: write only, marker-based upsert, plus the owner-only workflow_dispatch synthetic self-test so the alarm itself is verifiable.
  • Do not: grant it more than issues: write, and do not let it open a new issue per failure — the marker upsert is the point.
  • Verify: dispatch the synthetic path and confirm exactly one marker-bearing issue appears, then re-dispatch and confirm it updates rather than duplicating.

5. Gateway tracker #3512 has drifted from both of its declared sources of truth. See the table above for all four mismatches with both values. Smallest safe fix: set the Project 1 status for #3512 off Todo, add the missing dashboard#108 and agent#1152#1165 items to the matrix, and correct the v0.85.0 version claim to the live v0.113.2. Tracker writes belong to the Gateway Rollout Tracker workflow, not this report path.

6. Durable knowledge — persisted this run. Unlike the last two branch-pr passes, this one runs in working-dir mode and wrote to the wiki:

  • knowledge/wiki/topics/github-actions-ci.md — extended A Check-Run List Is an Append Log, Not a State Snapshot with a second independent sweep. The raw failure count fell 15 → 8 across two days with nothing repaired, while the latest-per-name reduced set held at exactly the same 3 repos. The generalization recorded: validate a fleet-health metric by re-running it and diffing the set, not the count — membership churn without remediation means the metric is measuring its own sampling window.
  • knowledge/wiki/repos/marcusrbrown--marcusrbrown-com.md — daemon health updated to day 15 with full run-history figures, retiring the prior "may heal on unchanged HEAD" hedge, and recording the model-selector hypothesis as explicitly unverified with the reason (403).
  • knowledge/log.mdmanual-edit entry with sources.

🤖 Generated by Fro Bot · run 35488760839

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