Skip to content

fix(janitor): dual-org support for the wyre-technology/WYRE-AI fleet split - #66

Merged
asachs01 merged 1 commit into
mainfrom
fix/dependabot-janitor-dual-org
Aug 28, 2026
Merged

fix(janitor): dual-org support for the wyre-technology/WYRE-AI fleet split#66
asachs01 merged 1 commit into
mainfrom
fix/dependabot-janitor-dual-org

Conversation

@asachs01

@asachs01 asachs01 commented Aug 25, 2026

Copy link
Copy Markdown
Member

Problem

The -mcp/node- fleet moved from being entirely under wyre-technology to being split across wyre-technology (13 repos) and WYRE-AI (50 repos, conduit included) sometime around 2026-08-24 evening/night — confirmed via org repo listings and org IDs, not inferred. dependabot-janitor.sh's repo enumeration was a single-org API call (ORG, defaulting to wyre-technology, and the workflow explicitly pinned it there), so it silently kept scanning only the 13 repos still under wyre-technology — no error, just 50 of 63 repos never looked at.

This is almost certainly the real explanation for a persistent ~80-108-PR "chronic dependabot backlog" that multiple scan-mcp-repos cycles reported today as steady-state review-gating — it wasn't; the janitor simply never reached most of those repos.

Fix

  • ORGORGS (space-separated org list, default "wyre-technology WYRE-AI"; ORG kept as a back-compat single-org override).
  • REPOS entries are now "org/name" pairs, not bare names — every downstream gh ... -R call now targets the repo's actual org directly, rather than assuming one global org.
  • EXCLUDE_REPOS still matches on the bare repo name (unchanged behavior), now via an awk filter that's org-agnostic.
  • Workflow: removed the ORG: ${{ github.repository_owner }} env line, which was silently overriding the script's own ORGS default back down to a single org — without this the script fix would have done nothing in production.

Verified live (read-only, before writing any code): the new enumeration logic finds 105 repos in scope (85 WYRE-AI + 20 wyre-technology, using the script's actual -mcp$|^mcp|^node- pattern, which is broader than just the *-mcp fleet) vs. the ~20 the old single-org call would find.

Known gap, left visible rather than silently forced

Not fully live yet — one line still gates it. Checked live via gh api orgs/WYRE-AI/installations: the wyre-projects-bot App (the one APP_ID/APP_PRIVATE_KEY mint tokens for) is not installed on WYRE-AI — only digitalocean, blacksmith-sh, vanta-with-task-management, and two infisical apps are.

Adding WYRE-AI to the token-minting step's owner: before that install exists risks failing token minting outright rather than degrading gracefully to a partial-org token — untested behavior of actions/create-github-app-token, and not worth risking the currently-working wyre-technology half of the janitor to find out. So owner: is left single-org for now, with the exact one-line change (add WYRE-AI to a newline-separated owner: list) documented inline in the workflow for whoever does the App install.

In the interim, ORGS already includes WYRE-AI, so every WYRE-AI repo will show up in each run's Errors section (pr list failed, an auth failure) until the install lands. This is expected and isolated per-repo — no crash, no effect on wyre-technology repos' processing — and turns a previously-invisible gap (silently scanning 13/63 with no error) into a visible, diagnosable one in the workflow's own summary output.

Ripples worth noting (per boss)

  1. A prior Gate-7 sweep's enumeration recipe is now stale for reruns. analyst's 2026-08-24 ~14:2xZ Gate-7 verification enumerated all 63 *-mcp repos under wyre-technology — correct at the time, and its conclusions still hold, but a straight rerun of that same wyre-technology-only recipe today would only find 13. Anyone rerunning that verification needs the dual-org enumeration too.
  2. Every org-level enumeration in fleet tooling needs the same dual-org treatment — this janitor, scan-mcp-repos cron prompts, any stale-PR sweep, anything that does a full-org repo listing. Per-repo gh calls (PR view, run list, etc.) already survive the split via GitHub's transfer redirect; only enumeration is affected. Flagging so this isn't treated as a one-off fix specific to the janitor.

Verification

  • bash -n on the script: syntax OK.
  • python3 -c "import yaml; yaml.safe_load(...)" on the workflow: valid.
  • Live-tested the new REPOS enumeration end-to-end against real org data (read-only gh api calls, no merges/mutations): 105 repos found, correctly split 85/20 across the two orgs, WYRE-AI/timezest-mcp present, EXCLUDE_REPOS filtering verified correct on a synthetic multi-org test case.
  • Did not run the full janitor (merge/review logic) — that needs the App-token auth this PR doesn't yet have for WYRE-AI, and running it for real against wyre-technology wasn't necessary to verify this specific fix.

View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.

…split

The *-mcp/node-* fleet moved from entirely under wyre-technology to split
across wyre-technology (13 repos) and WYRE-AI (50 repos, conduit included)
around 2026-08-24 evening/night. The janitor's repo enumeration was a
single-org API call, so it silently kept scanning only the 13 repos still
under wyre-technology -- likely the real explanation for a persistent
~80-108-PR "chronic dependabot backlog" multiple scan-mcp-repos cycles
reported as steady-state review-gating rather than the janitor simply
never reaching those repos.

ORG -> ORGS (space-separated, default "wyre-technology WYRE-AI", ORG kept
as a back-compat single-org override). REPOS entries are now "org/name"
pairs so every downstream gh -R call targets the repo's real org. Verified
live: 105 repos in scope (85 WYRE-AI + 20 wyre-technology, the script's
actual -mcp$|^mcp|^node- pattern) vs ~20 under the old single-org call.

Not fully live yet: the wyre-projects-bot App used for token minting is
confirmed NOT installed on WYRE-AI (verified via the installations API).
Left the token-minting owner: single-org rather than risk a hard failure
on an untested assumption -- documented the exact one-line change needed
once the install lands. WYRE-AI repos will show up in the run's Errors
section (isolated per-repo auth failures, no crash) until then, which
turns a previously-invisible gap into a visible, diagnosable one.
@asachs01
asachs01 force-pushed the fix/dependabot-janitor-dual-org branch from aa6204a to 404f71e Compare August 27, 2026 15:56
@asachs01

Copy link
Copy Markdown
Member Author

Disclosure: this is my own PR from 2026-08-25 (forge) — flagging that rather than presenting a fresh review of unfamiliar work. Native approve is blocked by shared identity regardless, so this is a currency re-check instead of an independent review:

  • Branch is still up to date with main (baseRefOid matches current main HEAD exactly, mergeStateStatus: CLEAN) — no drift in 2 days.
  • Re-verified the documented gap is still accurate: gh api orgs/WYRE-AI/installations still shows wyre-projects-bot NOT installed (only digitalocean/blacksmith-sh/vanta/2x infisical) — the single-org owner: limitation this PR documents inline is still the correct interim state, not stale.
  • No code changes needed. Still awaiting the App-install (separate [HUMAN]/ops item) before the WYRE-AI half goes fully live, and the usual Aaron override bundle for merge.

@asachs01
asachs01 merged commit 902bc76 into main Aug 28, 2026
3 checks passed
@asachs01
asachs01 deleted the fix/dependabot-janitor-dual-org branch August 28, 2026 12:06
@github-project-automation github-project-automation Bot moved this from Todo to Done in MSP Claude Plugins Aug 28, 2026
asachs01 added a commit that referenced this pull request Aug 31, 2026
…ent overlap (#69)

Three open PRs (#26, #50, #54) all showed mergeable=CONFLICTING against
current main. None of their real changes overlap line-for-line — the
conflicts are purely stale-diff artifacts of main having moved on since
each PR's fork point (#66's dual-org repo-enumeration restructure in
particular). This reapplies all three fixes' actual intent by hand onto
current main, in dependency order (both #50 and #54 touch
dependabot-janitor.sh).

#54 (classify() group-PR hardening, supersedes #23): a Dependabot "group"
PR title no longer proves minor/patch. classify() now fetches the PR body
via REST and requires every per-dependency "from A to B" marker to be
same-major, failing closed otherwise. Reapplied verbatim except the body
fetch now calls `repos/$repo/pulls/$num` directly (since $repo is already
"org/name" post-#66) instead of #54's original `repos/$ORG/$repo/...`.
Adds dependabot-janitor.test.sh (14 assertions, real fixtures) — verified
byte-identical to #54's original test file aside from that same $ORG->
$repo adaptation; all 14 assertions pass unmodified.

#50 (cortextos/conduit scope carve-out): reapplied by hand onto the
current multi-org enumeration loop (#66) rather than #50's own stale
single-org grep pipeline — added `|^cortextos$|^conduit$` to the
still-present grep -E inside the `for _org in $ORGS` loop.

#26 (mcp-server-release.yml always() gating): the release job's "Detect
released version" step now runs with `if: always()`, and the docker job's
gate is `if: always() && needs.release.outputs.released == 'true'`, so a
non-fatal failure after semantic-release cuts a release (e.g. a flaky
git-notes push) can't silently skip artifact publishing. Investigated the
apparent second `id: detect` in the current file: it is an unrelated step
in the (post-#26) mcpb job that checks for a pack:mcpb script, not a
duplicate release-detection block — #26's fix applies to exactly the one
occurrence it always targeted. Flagged in the CHANGELOG that mcpb's own
released=='true' gate has an analogous latent exposure, left out of scope
here since it predates neither #26 nor this reconciliation.

Verified: shellcheck clean on dependabot-janitor.sh (baseline was already
clean); dependabot-janitor.test.sh carries only pre-existing info-level
notices inherited from #54's original file (one pre-existing SC2034
warning was fixed by dropping the now-unused $ORG var); all 14 tests
pass; mcp-server-release.yml parses as valid YAML.

Refs: #26, #50, #54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant