Skip to content

Daily Fro Bot Report — 2026-09-21 (UTC) #3910

Description

@fro-bot

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

Run Summary

Category Status Notes
Errored PRs ✅ Remediation pass verified 3 open PRs green on both check-runs and legacy statuses. Zero repairs needed. #3882 green and waiting 11 days on REVIEW_REQUIRED.
Security ⚠️ One open Dependabot alert here (medium, transitive) — below the remediation bar, Renovate's lane. Fleet security coverage is partial: all marcusrbrown/* alert endpoints return 403. Five conflicted security PRs in vbs.
Control-Plane Integrity ⚠️ Pinning / strip-only TS / least-privilege / guards all clean and independently verified (17/17 SHA pins resolved against tag refs; mutation guards 100%, zero survivors). data → main blocked, day 15, 67 commits stranded, two consecutive Sunday failures.
Code Quality ✅ bootstrap → check-types → lint → test all exit 0. 3687 tests pass. pnpm fix would be an empty diff.
Oversight ⚠️ 38/38 repos enumerated, none denied. Two repos with failing main. Large aged-PR backlog concentrated in three hotspots; oldest open PR is 177 days.
Cross-Project Intelligence ⚠️ Coverage partial: 30 of 34 tracked entries scannable. 7 public tracked repos still carry no Fro Bot workflow; 2 tracked repos have last_survey_status: failure.
Progressive Improvement ❌ Compounding pipeline regressed: learning-proposal issues doubled 5 → 10 in one day while docs/solutions/ stayed flat at 59, newest 13 days old. Two major tool-version drifts.

Errored PRs

Handled by the remediation pass (run 35560232912, comment). Zero fixes applied, zero PRs opened — nothing was broken.

PR Author Check runs Legacy statuses State
#3904 app/fro-bot 15 pass, 3 skipped by design ✅ MERGEABLE
#3901 fro-bot 13 pass, 4 skipped ✅ MERGEABLE
#3882 app/fro-bot 15 pass, 3 skipped ✅ (incl. renovate/stability-days) MERGEABLE

Both check sources were inspected separately, per the append-log caveat recorded in the wiki — gh pr checks enumerates check runs only, and the legacy /status records here are real (Security: Private Leak Scan, renovate/stability-days), not empty.

#3882 is the only actionable item and it needs a human: fully green, 11 days, blocked solely on REVIEW_REQUIRED.

Security

This repo: one open Dependabot alert — @humanfs/node, medium, transitive via pnpm-lock.yaml. Below the critical/high remediation bar, so Renovate owns it. No direct dependency or Action carries an open advisory.

Scorecard code-scanning reports BranchProtectionID at high. Assessed as a probable false read: live main protection is enforce_admins: true, force-push off, deletions off, 14 required contexts, code-owner review required, require_last_push_approval: true. Scorecard most likely scores the intentionally-unprotected data branch, which is load-bearing by design.

Fleet — coverage is partial and that is the headline. Dependabot alerts were readable for fro-bot/* only (.github 1 medium; agent, dashboard, space-bus, systematic all 0). Every marcusrbrown/* repository returned 403 Resource not accessible by personal access token — 10 repos unqueryable. Fleet-wide security posture cannot be asserted from this run; see Needs Human Attention.

Five conflicted security PRs in marcusrbrown/vbs:

PR Age Mergeability
#717 js-yaml omap DoS 44d CONFLICTING/DIRTY
#701 PostCSS source-map disclosure 58d CONFLICTING/DIRTY
#697 fast-uri host confusion 60d CONFLICTING/DIRTY
#688 brace-expansion DoS 62d CONFLICTING/DIRTY
#672 ws DoS (GHSA-96hv-2xvq-fx4p) 73d CONFLICTING/DIRTY

Yesterday's report flagged #672 alone. Widening the query shows it is a cohort, not an outlier — and not one of the five can merge without rework. An open remediation PR reads as coverage; these are the opposite. Persisted to the wiki as a durable pattern.

Control-Plane Integrity

Verified clean, and verified harder than a regex audit:

  • SHA pinning — all 20 third-party uses: across 29 workflows and the composite actions are full-SHA pinned with # vX.Y.Z comments. All 17 distinct repo@tag pairs were resolved against the GitHub refs API (dereferencing annotated tags) and compared to the pinned SHA: 17/17 match, zero comment drift.
  • Strip-only TypeScript — no enum, namespace, parameter properties, or TS path aliases in scripts/*.ts.
  • Least privilege — all 29 workflows declare top-level permissions; zero write-all; the only blanket grant is scorecard.yaml's read-all.
  • Guards — wiki-authority, privacy gates, and branch protection intact and untouched. check:mutation-guards at 100% across all 11 guarded modules, zero survivors.

Still broken: data → main promotion, day 15, second consecutive Sunday failure.

2026-09-20 Today
Stranded commits 62 67
Consecutive Sunday failures 1 2
Days since last success 7 15

Last green promotion was run 34066893138 (2026-09-06). Run 35545734311 failed identically at 🔒 Block private wiki pages. Next cron is 2026-09-27 — failure number three at roughly 100 stranded commits unless someone acts on data first.

The root cause is now measured, and it corrects both prior readings. Derived from data at 3b81d32 without operator credentials: 33 wiki repo pages against 34 tracked entries, producing two blocking subclasses at once —

  • 2 pages with no metadata/repos.yaml entry at all (the orphan class the 09-17 analysis found), and
  • 1 page whose entry exists, carries onboarding_status: lost-access, and has no private key — a third subclass neither prior reading recorded.

The decisive new fact: that lost-access repo is currently enumerable by the fro-bot token. Access came back (or was never lost as the April snapshot recorded) and nothing re-resolves a terminal-looking status. So the fix for that row is writing private: false — not deleting the entry, which is what the standing lead branch copilot/fix-data-orphan-private-repos does. For this subclass, deletion would remove the row that makes the page attributable and manufacture a fresh orphan. Full analysis persisted to the wiki.

Code Quality

pnpm bootstrap → check-types → lint → test all exit 0. 79 test files, 3687 tests passing, 3 todo. check:wiki-write-core-dist reports dist up to date. One TODO/FIXME annotation across all of scripts/*.ts — no annotation debt.

Oversight

Enumeration complete: 38 repositories via paginated user/repos (affiliation=owner,collaborator,organization_member), all returning at least read access, all public, 4 archived. Nothing failed to enumerate.

Failing main (2 repos of 22 sampled, last 12 runs each):

Repo Workflow Failures Detail
marcusrbrown/extend-vscode Publish 2 of 12 (09-20, 09-21) Dies at Pre-Release Validation (vulnerabilities) → Scan vulnerabilities; all 8 sibling validation shards cancelled, Semantic Release skipped. Releases are blocked by a security scan. Next step: read the audit output and decide patch-vs-waiver — this is a real gate holding a real release, not flake.
fro-bot/agent Prepare Release PR 1 of 12 (09-20) Failed at Wait for release PR mergeability. Self-resolved — release PR #1626 (v0.114.0) is now MERGEABLE/CLEAN with zero failing checks. Next step: merge #1626; no code fix needed.

Aged and stale PRs (aging from creation, staleness from last activity). The backlog is real and concentrated:

Repo Open PRs Worst case
marcusrbrown/gpt 15 #2165 HeroUI v2→v3 — 177d aged, 134d stale, CONFLICTING
marcusrbrown/vbs 10 5 conflicted security PRs, 44–73d (see Security)
fro-bot/agent 7 all ≤6d and actively updated — healthy
marcusrbrown/containers 5 #723 52d
fro-bot/space-bus 5 #72 72d aged / 2d stale
marcusrbrown/marcusrbrown.com 6 #462 76d aged and 76d stale — all 6 untouched since creation

Stale issues (>30d): zero in fro-bot/.github. Not swept fleet-wide this run.

Top three hotspots (ranked by qualifying findings in this snapshot, each with linked evidence):

  1. marcusrbrown/gpt — 15 open PRs / 23 open issues. Six PRs (#2664, #2665, #2672, #2673, #2674, #2692) touch the identical single file src/components/settings/ollama-settings.tsx — the same defect proposed six times. Re-checked today: no new member since 2026-07-28, so the daemon that produced them has stopped; the wreckage remains. Next step: keep the best one, close five, then confirm the dedup predicate keys on changed-file-set rather than title.
  2. marcusrbrown/vbs — 10 open PRs / 19 issues, five of them unmergeable security remediations aged 44–73d. Next step: rebase or re-file the five; treat each as live exposure, not as mitigation in flight.
  3. fro-bot/.github — 22 open items. data → main blocked 15 days / 67 commits, plus 10 unauthored learning-proposal issues. Next step: the one-field data repair below, then drain the proposal queue.

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

Cross-Project Intelligence

Coverage is partial. 34 tracked entries in metadata/repos.yaml; 30 scanned.

Not scanned Count Why
private: true 3 Correctly excluded — public-only invariant
onboarding_status: lost-access, no private key 1 The data → main blocker; counted, never named

Survey health: 2 tracked repos carry last_survey_status: failure — marcusrbrown/containers and marcusrbrown/dev-like. Both are otherwise healthy (clean main, active queues), so this is ingest-side, not repo-side.

Adoption gaps across tracked public repos:

  • No Fro Bot workflow (7): marcusrbrown/ha-config, marcusrbrown/.github, marcusrbrown/esphome.life, marcusrbrown/extend-vscode, fro-bot/fro-bot.github.io, fro-bot/systematic, marcusrbrown/Presentations. extend-vscode is the notable one — it has a failing release pipeline and no agent to notice.
  • No Renovate (3): fro-bot/fro-bot.github.io, fro-bot/systematic, marcusrbrown/cortexkit_anthropic-auth.

Adoptable finding. marcusrbrown/infra runs release-alert.yaml — a workflow_run failure alarm with a marker-based issue upsert and an owner-only synthetic self-test. This repo has three workflow_run consumers (check-private-leak.yaml, private-leak-sentinel.yaml, renovate.yaml) and none watches for failure. Adopting that pattern against Merge Data Branch is now the structural mitigation, not a nice-to-have — see Needs Human Attention item 2 for why the pull path is closed by construction. Report-only; no change made.

Progressive Improvement

The compounding pipeline regressed sharply. This is the worst category today.

2026-09-20 Today
Open learning-proposal issues 5 10
docs/solutions/ entries 59 59
Age of newest solution doc 12d 13d (2026-09-08)

Five new proposals opened today (#3905, #3906, #3907, #3908, #3909); the 2026-09-14 batch (#3887–#3891) is now 7 days old. The expected action for each is authoring into docs/solutions/, and zero have been authored. The queue doubled in 24 hours while output stayed at zero. Monthly codification: Jun 16, Jul 12, Aug 8, Sep 7 — none since the 8th.

As instructed, the healthy reading on Improvement Metrics #3674 is not evidence this is fine. Unauthored proposals never become codified classes, so that report stays green precisely because this is stalled. Ten open proposals is the signal; the green metric is an artifact of the same blockage.

Tool-version drift (authoritative source: npm registry latest; major drift included and called out):

Tool Pinned Registry latest Drift
typescript 6.0.3 7.0.2 ⚠️ major
vitest 4.1.11 5.0.1 ⚠️ major
eslint 10.10.0 10.11.0 one minor — within tolerance
prettier 3.9.1 3.9.8 patch only

Both majors are Renovate's to schedule; flagged here as durable drift, not actioned. @vitest/coverage-v8 sits at 4.1.4 against vitest 4.1.11 — a small internal skew worth aligning whenever vitest next moves.

CI jobs: no missing or degraded jobs detected. Convention drift from copilot-instructions.md: none found. Stale annotations: 1 TODO/FIXME total across scripts/*.ts.

Gateway Rollout Tracker (#3512) — review awareness

Issue updated_at is 2026-09-21T02:39Z. It is still drifted — and worse than the 09-17 reading, because the deploy pin moved 30 minors while the body stood still.

Claim in #3512 Live value Source
"releases have since advanced to v0.85.0" v0.113.2 (2026-09-16) fro-bot/agent GitHub Releases (latest)
"deployed gateway is pinned to v0.83.0" v0.113.2 marcusrbrown/infra:apps/gateway/upstream.json
"push … not yet deployed (deployed pin is v0.83.0)" deployed pin exceeds v0.85.0, so the push build is deployed (inert without VAPID) same file
matrix row fro-bot/dashboard#179 — Open CLOSED issue state
fro-bot/dashboard#125 — "one low-severity nit filed" CLOSED issue state

GitHub Project 1 holds 21 items: 20 Done, 1 Todo — and the Todo is #3512 itself, while the body narrates roughly fifteen later items that have no Project entry. The issue's own first acceptance criterion is that the Project matrix reflects all shipped items; it does not.

No tracker comment posted and no Project field edited from this path — the Gateway Rollout Tracker workflow owns those writes.


Needs Human Attention

1. data → main promotion — day 15, 67 stranded commits, and the remediation guidance has changed.

  • Files: metadata/repos.yaml on the data branch (not main); scripts/check-wiki-private-presence.ts for gate logic.
  • Root cause, measured today: 33 wiki repo pages vs 34 tracked entries on data@3b81d32 — 2 pages with no tracked entry, plus 1 page whose entry has onboarding_status: lost-access and no private key. Two subclasses, not one.
  • Smallest safe fix: for the lost-access row, write an explicit private: false — its repo is currently enumerable by the fro-bot token, so visibility is provable without special credentials. The 2 true orphans need a separate bookkeeping decision (add entries, or remove the pages).
  • ⚠️ Do not reuse the lead branch as-is. copilot/fix-data-orphan-private-repos (head 8ea9588) deletes two repos.yaml entries. For the lost-access subclass that is the wrong direction — deletion removes the row that makes the page attributable and creates a fresh orphan. It is also stale (forked at eaf767c; repos.yaml has since moved 195 insertions / 66 deletions).
  • Do not: weaken or bypass the gate, add a slug allowlist, wire --operator-report into any workflow, or re-dispatch Merge Data Branch hoping it clears — two Sundays of identical failure say it will not.
  • Verify without operator credentials: diff git ls-tree --name-only origin/data knowledge/wiki/repos/ against slugs derived from metadata/repos.yaml via computeRepoSlug, and cross-check any private-less entry against the authenticated account's repo listing. Then: Merge Data Branch green → git rev-list --count origin/main..origin/data returns 0.

2. No failure alarm on any workflow_run consumer — and the pull path is closed by construction.

  • Files: .github/workflows/ — check-private-leak.yaml, private-leak-sentinel.yaml, renovate.yaml are the three consumers; none triggers on failure.
  • Why this is now structural, not cosmetic: the gate's only diagnostic, check-wiki-private-presence.ts --operator-report, hard-refuses to run when GITHUB_ACTIONS or CI=true is set — correctly, since its output is the private data. Composed with a weekly fail-closed cron, that means no CI-resident agent can ever investigate this class of failure. A push notification is the only channel that reaches a human before the next Sunday.
  • Smallest safe fix: one workflow modeled on marcusrbrown/infra's release-alert.yaml — workflow_run on Merge Data Branch completed, gated on conclusion != 'success' (not == 'failure'; a cancelled run is also a non-delivery), permissions: issues: write only, marker-based upsert, plus an owner-only workflow_dispatch synthetic self-test.
  • Do not: grant more than issues: write, and do not open one issue per failure — the marker upsert is the point.
  • Verify: dispatch the synthetic path, confirm exactly one marker-bearing issue; re-dispatch and confirm it updates rather than duplicating.

3. Fleet security visibility is a hole, not a clean bill.

  • Symptom: GET /repos/marcusrbrown/*/dependabot/alerts returns 403 Resource not accessible by personal access token for all 10 sampled repos. fro-bot/* reads fine.
  • Consequence: the Security row can never be honestly ✅ fleet-wide. Roughly two-thirds of tracked repos are unaudited by this pass, including vbs, which demonstrably carries high-severity advisories.
  • Smallest safe fix: grant the credential used by this workflow security_events: read (or Dependabot alerts: read) on the marcusrbrown repos, or accept the gap and change the report to state scope explicitly. Either is fine; silently reporting ✅ is not.
  • Verify: re-run the alert query across the fleet and confirm zero 403s.

4. marcusrbrown/extend-vscode release pipeline blocked by its own vulnerability gate.

  • Files: the Publish workflow, job Pre-Release Validation (vulnerabilities), step Scan vulnerabilities.
  • Root cause: not extracted — the failed-log view for runs 35549879149 and 35511059280 returned only runner setup and post-job cleanup, with the scanner's own output absent from the failed-step slice. Stated as unresolved rather than guessed.
  • Smallest safe fix: open the run in the UI, read the scanner output, then patch the flagged dependency. Do not relax the audit level or add a blanket ignore to unblock publishing — that trades a visible release block for an invisible advisory.
  • Constraint: this repo has no Fro Bot workflow, so nothing there will surface this on its own. It has now failed twice; without a subscriber it will keep failing quietly.

5. Five unmergeable security PRs in marcusrbrown/vbs (#672, #688, #697, #701, #717).

  • Root cause: all five target lockfiles/manifests — the highest-churn files in the repo — so ordinary dependency traffic rewrote them into conflict while the PRs waited 44–73 days.
  • Smallest safe fix: rebase each onto current main, or close and re-file from current state. Re-filing is usually cheaper than resolving a 73-day lockfile conflict.
  • Why it can't just be left: a dedup check keyed on root cause will find the dead PR and decline to open a live one, so each conflicted PR actively suppresses its own replacement. Treat them as exposure, not as work in progress.

6. Six duplicate PRs in marcusrbrown/gpt for one defect.

  • Files: all six (#2664, #2665, #2672, #2673, #2674, #2692) modify only src/components/settings/ollama-settings.tsx.
  • Root cause: a dedup predicate that compared titles, not changed-file sets — six differently-worded titles for one fix.
  • Status: no new member since 2026-07-28, so the producing loop has already stopped. This is cleanup, not an active leak — keep the best PR, close the other five.
  • Verify: confirm no seventh PR touching that file appears after cleanup.

7. Housekeeping: metadata/repos.yaml is staged in this job's working tree, and it is not mine.

  • A prior step in this job restored the data snapshot and left metadata/repos.yaml staged (58 insertions / 58 deletions — it reads as a re-serialization, not a semantic change). This run wrote nothing outside knowledge/wiki/topics/github-actions-ci.md and knowledge/log.md.
  • Why it's flagged: the downstream capture step discovers its payload via git status --porcelain, so it may sweep this staged file into the wiki commit. That would be an unintended metadata/** write from a path that does not own it.
  • Do not: have an agent git restore it mid-run — cleanup against the working tree is explicitly forbidden here and would also discard the wiki diff. The fix belongs in the capture step's path filter, not in the agent.
  • Verify: confirm the resulting data commit touches only knowledge/**.

8. Durable knowledge — persisted this run. This pass runs in working-dir mode, so unlike yesterday's branch-pr half it could write:

  • knowledge/wiki/topics/github-actions-ci.md — Revoked Access Leaves an Unclassifiable Page Behind, and the Gate Blocks Forever. Corrects the 2026-09-17 subclass claim with measured counts, records lost-access as a one-way latch (the condition that sets it prevents clearing it), names de-provisioning as the missing half of ingest, and prices the redaction/triage tension as a concrete ask: emit counts by reason code, which leak a class but never a slug.
  • Same page — A Security Remediation PR Has a Shelf Life, and Past It, It Inflates Coverage. The vbs cohort generalized, plus the re-checked gpt cluster distinguishing a daemon still duplicating from a daemon that stopped and left duplicates.
  • knowledge/log.md — manual-edit entry with sources. No pages created or removed, so index.md is unchanged. No unenumerable repository is named anywhere.

🤖 Generated by Fro Bot · run 35560232912

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