Repository navigation
go-live 8/9: post-swap docs, labels, boards, and integration hygiene #1821
Description
Activity
- changed the title
[-]go-live 7/9: restrict PRs to collaborators; CONTRIBUTORS.md + SECURITY.md[/-][+]go-live 8/9: post-swap docs, labels, boards, and integration hygiene[/+]on Jul 27, 2026 Two items for this phase, found during phases 1–4
1. Branch protection requires a reviewer the project does not have
Both default-branch rulesets (
2749948,3187937, each targeting~DEFAULT_BRANCH) require:required_approving_review_count: 1 require_code_owner_review: trueand there is no CODEOWNERS file anywhere in the repo (
CODEOWNERS,.github/CODEOWNERS,docs/CODEOWNERSall absent). The same shape was cloned ontov1/mainin phase 1 (19858989).The consequence is that every merge goes through
--adminbypass: #1827, #1828, #1829 onv1/mainand #1830, #1831, #1832 onmainall did. A required check that nothing can satisfy is worse than no check — it reads as protection while making bypass the routine path.⚠️ Note the fix is not a CODEOWNERS file. GitHub forbids approving your own PR, so for a single maintainerrequired_approving_review_count: 1is unsatisfiable regardless of who the code owner is — naming yourself in CODEOWNERS changes nothing, and droppingrequire_code_owner_reviewalone still leaves the count. The options are:- A second reviewer with write access — the only path that satisfies the rule as written. Organizational, not technical.
- Align the rulesets with reality — drop the approval requirement on the default branch and rely on the required
buildcheck plus admin discipline. Honest, but weaker. - Leave it and accept routine bypass — the current de facto state, which should at least be a decision rather than an accident.
Deliberately not changed during phases 1–4: editing rulesets immediately before an irreversible npm publish adds risk without removing the need to bypass. Recording it here so it is resolved as a considered choice.
2. Dependabot backlog — deferred, with reasoning
72 open alerts as of 2026-07-28:
Scope Count Severities runtime (ships to users) 38 14 high, 21 medium, 3 low development (never ships) 34 3 critical, 22 high, 5 medium, 4 low Why they do not block the 2.0.0 release (#1818): 2.0.0 ships the same dependency tree
v2/mainhas carried all along. The swap changed nothing about it —mainsimply began reporting alerts it had never scanned before. Nothing regressed; visibility changed.On the three criticals: all are
@vitest/browser, development scope. The publishedfilesallowlist isclients/*/build+clients/web/dist+scripts/install-clients.mjs, so dev dependencies are never in the tarball. They are not user-facing.One was investigated properly rather than triaged by severity — GHSA-frvp-7c67-39w9 (
@hono/node-server, path traversal inserve-static), because the Inspector calls that exact function in its prod web server. Result: the advisory blocks..escapes, so it only reaches files inside the static root by bypassing prefix-mounted middleware; here that root is the public SPA bundle and the only prefix middleware (/api/*) is a separate route, not a subdirectory. No auth bypass, no arbitrary read, Windows-only. Upgraded anyway in #1832 since it proved free.The plan:
- Ship 2.0.0 (go-live 5/9: publish 2.0.0 (rc under next first; rollback plan written first) #1818) on the current tree — no dependency changes in the release PR, so the publish diff stays minimal and reviewable.
- After the release, let Dependabot open its own PRs and land the transitive bumps in batches. Most of these are lockfile-only and resolve together.
- Re-audit the runtime-scope set specifically once the noise clears — those are the ones that reach users via
npm install. Current runtime offenders:fast-uri(12),hono(15),@hono/node-server(fixed),qs,ip-address,yaml,body-parser,postcss. - Treat dev-scope alerts as low priority by policy, and consider documenting that so future criticals in test tooling do not trigger a fire drill.
The general lesson worth keeping: severity alone was a poor triage signal here. The three criticals were unshippable dev tooling; the one alert genuinely worth reading in full was a medium.
- linked a pull request that will close this issuedocs: post-swap branch model, PR policy, milestone rule, and Copilot review instructions #1866
on Jul 31, 2026 Task 1 — "Merges from v2/main into main enabled for milestone release workflow"
Worked up against the real SHAs. Correction first: no graft/stitch commit is needed. The two branches already share history — I earlier concluded they didn't, but that was an artifact of a shallow local clone (
git rev-parse --is-shallow-repository→true), which truncates history sogit merge-basefinds nothing. Aftergit fetch --unshallowit resolves.Actual state
Merge base 4d30d1cd— "docs: restore the missing docs/ targets and split the catalog-seeding wording (#1811) (#1812)"Established by 25106dcc— "Merge pull request #1830 from modelcontextprotocol/chore/v2-golive", which mergedv2/mainintomain(the tree swapec5d8e13was part of that branch)maintipfb1b0cb4— "docs: restore SECURITY.md, lost in the v2 tree swap (#1843)"v2/maintip5d91d4ac— "fix(core): mirror SEP-2243 x-mcp-header args to Mcp-Param-* on tools/call (#1847)"Divergence mainahead by 223 (all v1 history + the 2.0.0 release commits), behind by 1The v1 history is reachable from
mainbut not fromv2/main, which is why the compare shows 223 — it is not 223 commits of pending work, and it does not affect the merge, because the 3-way merge compares trees against the base at4d30d1cd.Verified by dry run
Merging
origin/v2/mainintoorigin/mainin a scratch worktree:- Succeeds as an ordinary merge — no
--allow-unrelated-histories, no graft. - One conflict:
README.md(the "Serving the modern protocol era" section —maincarries a restructured version from go-live,v2/mainextended the original prose). Every other file auto-merges: 13 files, +719/−33. SECURITY.mdsurvives the merge (added onmainafter the base, untouched onv2/main, so 3-way keeps it).
The milestone merge sequence
git fetch origin # 1. Merge the milestone's work into the release branch. git checkout -B main origin/main git merge --no-ff origin/v2/main -m "chore: merge v2/main for <version> milestone release" # → resolve conflicts (today: README.md only), then `git add` + `git commit` # 2. Gate before it becomes the release. npm install && npm run ci # 3. Publish the branch, then cut the release from it. git push origin main npm version <major|minor|patch> # on main — bumps root package.json + tags git push --follow-tags # → draft & publish the GitHub Release for that tag; the `publish` job # runs pack:verify and publishes the `latest` dist-tag # 4. Back-merge so the branches don't drift. git checkout -B v2/main origin/v2/main git merge --no-ff origin/main -m "chore: back-merge release commits from main into v2/main" git push origin v2/main
Why step 4 matters
v2/mainis missingSECURITY.mdtoday, and the version bump commits land onmainonly. Without the back-merge each milestone leavesv2/maina little further behind on release-only files, and thepackage.jsonversion diverges — which is the one file most likely to conflict on every subsequent merge. The back-merge keeps the trees converged so each milestone merge stays as small as this one.Remaining checks before the first real run
- Branch protection on
main— confirm the ruleset permits a merge commit from a maintainer (or that the merge goes through a PR, ifmainrequires one). This is the only thing that can block the sequence above; everything else is verified. - Decide whether step 1 goes through a PR (
v2/main→main, reviewable, matches the "no direct pushes" posture) or a direct maintainer merge. A PR is the better default; note the PR body'sCloses #Nwill not auto-close sincemainis the default branch — closing keywords work there, so it actually will. Worth confirming which issue such a release PR should reference. - Resolve the
README.mdconflict once by bringingmain's restructured section ontov2/mainahead of the merge, so the first milestone merge is conflict-free.
- Succeeds as an ordinary merge — no
Folded the task-1 analysis from my earlier comment into the issue description, along with the full ordered sequence, so the plan lives in one place rather than scattered across comments. That comment is now superseded — the description supersedes it wherever they differ (notably: it recommended a back-merge, which was built as #1868 and rejected).
- added sub-issues
on Aug 1, 2026 - added 2 commits that reference this issue
on Aug 1, 2026
Phase 8 of 9 in the v2 go-live runbook — see #1804 (§10). Depends on phase 4. Reversible.
Everything that silently inverts when
mainbecomes v2.Current state of the branch model
Established and now documented in
AGENTS.md/README.md/CONTRIBUTORS.md(#1866):v2/mainmain)mainv2/mainonlylatestv1/mainv1-latest, straight from the branchVerified on npm:
v1-latest: 1.0.1,latest: 2.0.0.Merged
All eight PRs are merged to
v2/main, in this order, each squash-merged after a Copilot review loop reached a clean round:3ac34e402c24b82eCONTRIBUTORS.md→CONTRIBUTING.md379a8a0a7cc3c127SECURITY.mdff995473claude.yml+.mcp.jsonee707db5.gitattributes, CoC13e981e9@hono/node-server2.x, vite 8.1.5)694d013fTheir issues (#1873, #1877, #1874, #1883, #1813, #1864, #1850, #1870, #1875) are closed and their cards are Done.
One conflict actually materialized, on #1884: GitHub flagged
CONFLICTINGfor the rename/modify pair once #1866 landed (it renamesCONTRIBUTORS.mdwhile #1866 edited that file's contents), even though local git resolved it cleanly via rename detection. Resolved by mergingv2/maininto the branch — #1866's edits applied to the renamed file,CONTRIBUTORS.mdgone,CONTRIBUTING.mdcarrying the new content. Worth remembering: GitHub's mergeability check is more conservative thangit mergefor rename/modify.This phase is complete — all nine sub-issues are closed and their PRs merged.
The
v2/main→mainmilestone merge is not part of this phase. It is tracked separately in #1876 as the last issue of the v2.1.0 milestone, because it ships everything in that milestone rather than only this phase's work. The merges above unblock it, and because #1880 landed it should now be conflict-free rather than needing the one-hunk README fallback.