Skip to content

build(release): the hold check's edges, as the connectome-host copy's review found them - #347

Merged
nissa-seru merged 6 commits into
anima-research:mainfrom
nissa-seru:build/release-holds-edges
Oct 15, 2026
Merged

nissa-seru merged 6 commits into
anima-research:mainfrom
nissa-seru:build/release-holds-edges

Conversation

@nissa-seru

@nissa-seru nissa-seru commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

The release-hold check (#329) gets the fixes its connectome-host copy's review found, since the script is the same file there (anima-research/connectome-host#256).

The change

  • Repository forms: a repository URL that goes on past owner/repo, with a path such as a monorepo's /tree/main/pkg, a query or a fragment, was read as naming no repository, or as owner/repo#readme, which asked the wrong endpoint. npm's shorthand with a ref after # did the same. Each now reads as owner/repo.
  • A 410 (issues turned off for the repository) got the generic message. It now says issues are off there, and points at the setting that chose the repository.
  • The 5,000-item limit stopped a complete list of exactly 5,000 labelled items. The check now reads the 51st page, and stops only if it holds something.
  • How to go on: every stop message now ends with what to run again, for where the check ran: npm version under preversion, even inside Actions, since that runs before any tag; the workflow for the tag; or npm publish. Before, four messages said only "run this again".
  • The hold message names the setting that chose the repository, so a copy whose package.json still names its upstream sees why that repository was asked.
  • The release-notes job sets up Node 24 before its check, as the publish job does. It had run on the runner image's Node.
  • The workflow's comments and CONTRIBUTING now say the following:
    • What stops both release jobs: a failed build, which both need; a tag with no changelog section; and an open hold.
    • Each job checks for holds when it runs, so a hold filed between the two checks can stop one and not the other.
    • When what must happen first is this package's own release of a fix, the hold closes once the fix is merged.
    • Publishing a tarball made earlier with npm pack skips the check, as --ignore-scripts does: npm 11.17.0 runs no prepublishOnly for npm publish <file>.tgz.

Tests

test/release-holds.test.ts grows from 22 cases to 26. New:

  • 410 and 429 answers, with and without a token;
  • an answer that isn't JSON;
  • exactly 5,000 items read whole, and one more stopping the release;
  • GH_TOKEN taking precedence over GITHUB_TOKEN;
  • the URL forms above;
  • GITHUB_REPOSITORY when the field is absent or blank, or package.json can't be read;
  • preversion's advice inside Actions;
  • npm publish going ahead when no hold is open.

Evidence

At c1372cb0, on #329's head cb2a3365, which main merged as f8956a4e:

  • The full suite, each file run on its own: Node 24.21.0 unforced 2014/2014, and Node 20.20.2 with --test-force-exit 2014/2014. Node 24 with --test-force-exit, as CI runs npm test, counted 2008/2008: it cut three files short, which pass whole unforced (npm test's --test-force-exit can end a test file before its tests report, so a short run still passes #294). Typecheck and build are clean. release-holds passes 26/26 in each.
  • The routes, run at 58311d40, whose script and npm hooks are the same as this head's, with one hold open, in a project wired with this repository's preversion and prepublishOnly (node scripts/release-holds.mjs && npm run build): npm version patch is held and the version stays as it was, and npm publish --dry-run is held. With --ignore-scripts, both go ahead without asking GitHub, and so does npm publish of a packed tarball. Bun's bun pm version patch and bun publish --dry-run are held too.
  • The two commits after c1372cb0 change only CONTRIBUTING and a workflow comment: what stops both release jobs, and a rewrap.
  • 9c5e4e39, after them, changes only the test's npm helper. Under npm test, it runs npm's own CLI script, named in npm_execpath, with process.execPath, since a bare npm is npm.cmd on Windows, which execFile can't start without a shell. Anything else there, such as bun's binary, falls back to npm on PATH. release-holds passes 26/26 without npm_execpath, with npm's npm-cli.js in it (on Node 24 and 20, none of its own npm calls going through PATH) and with bun's binary in it. Windows itself wasn't run.
  • e925628c, last, changes only CONTRIBUTING: closing a hold is the way past it. npm's --ignore-scripts skips the check, but on npm version it skips the changelog fold too, so the tag would fail the publish workflow's changelog check.

Read by Naomi-2422 (Claude Opus 5.5), who ran each release route with a hold open, and which way each of the test's npm calls went. Greptile's review of chronicle's copy of this check found the Windows gap.

@antra-tess, @Anarchid: it changes how a release is made, not what ships. I'll merge it once its checks pass on its merge with the then-current main, and not before 2026-10-15 15:00 UTC, unless you'd like changes first.

— Ada-1017 (Claude Opus 5.5)

Ada-1017 added 4 commits October 14, 2026 10:26
… review found them

connectome-host carries this check's copy, and that copy's review found
edges this one shares, since the script is the same file:

- A repository URL that goes on past owner/repo (a monorepo's /tree/main/
  path, a query or a fragment) was read as naming no repository, or as
  owner/repo#readme, which asked the wrong endpoint; npm's shorthand with a
  ref after '#' did the same. Each now reads as owner/repo.
- A 410 (issues turned off) got the generic text; it now says issues are
  off there and points at the setting that chose the repository.
- The page limit stopped a complete list of exactly 5000 labelled items:
  the check now reads page 51 and stops only if it holds something.
- How to go on now follows where the check ran, preversion first (npm
  version comes before any tag, even inside Actions), and every stop
  message ends with it, not 'run this again'.
- The hold message names the setting that chose the repository.
- The release-notes job runs the check on a pinned Node 24, as the
  publish job does; it had used the runner image's Node.
- The workflow's comments and CONTRIBUTING say an open hold is the one
  thing that stops both release jobs, each checking when it runs, so a
  hold filed between the two checks can stop one and not the other; that
  when what must happen first is this package's own release of a fix, the
  hold closes once the fix is merged; and that publishing a tarball made
  earlier with npm pack skips the check, as --ignore-scripts does (npm
  11.17.0 runs no prepublishOnly for `npm publish <file>.tgz`).

Tests (26, from 22): 410 and 429 with and without a token; an answer that
isn't JSON; exactly 5000 items read whole and one more stopping; GH_TOKEN
over GITHUB_TOKEN; the URL forms; GITHUB_REPOSITORY when the field is
absent, blank or package.json can't be read; preversion's advice inside
Actions; npm publish going ahead with no hold.
…s too

The text said an open hold is the one thing that stops both; a tag with no
matching changelog section does as well (the publish job refuses it, and
the notes job has no section to mirror).
…one thing'

Both need the build job, so a failed build stops both; past it, a tag with
no changelog section and an open release hold do (Naomi-2422's read).
@greptile-apps

greptile-apps Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5 Tier: apex

[High impact] This PR appears safe to merge; no actionable regression was found.

Summary

Hardens the release-hold check by accepting repository URL suffixes, fixing the 5,000-item boundary, and improving stop messages. It also sets up Node 24 for release notes and expands the tests.

  • The hold check reads GitHub repository links and gives specific stop instructions.
  • The check allows exactly 5,000 labelled items when page 51 is empty.
  • The release-notes job checks holds on Node 24.

Reviews (1) · Last reviewed commit: "docs(contributing): rewrap the Releases ..." · Reviewed by Greptile

… Windows can start it

The wiring tests started npm with execFile("npm"). On Windows npm is
npm.cmd, which execFile can't start without a shell, so the four tests
that run npm failed there before reaching the check. Under `npm test`, npm
names its own CLI script in npm_execpath, and the tests now run that
script with process.execPath. Another package manager names its own CLI
there (bun names its binary), so anything but npm's npm-cli script falls
back to the `npm` on PATH, as before.

Found by Greptile's review of chronicle's copy of this check
(anima-research/chronicle#29), where Basil-1007 made the same change.

Checked: the file passes 26/26 with no npm_execpath, with npm's
npm-cli.js in it, and with bun's binary in it.
@nissa-seru

Copy link
Copy Markdown
Contributor Author

Pushed 9c5e4e39, a fast-forward from c7841a1e that changes only the test. Its wiring tests started npm with execFile("npm"), which on Windows is npm.cmd and can't be started without a shell. Under npm test, they now run npm's own CLI script, named in npm_execpath, with the Node that runs them, and fall back to npm on PATH otherwise. Greptile found it in chronicle's copy of this check. The description's Evidence says what was run. Windows itself wasn't.

— Ada-1017

…t is

The Releases bullet said npm's --ignore-scripts skips the hold check, as
it skips every lifecycle script, which read as a way past a hold. On
`npm version` it also skips the changelog fold (the version script), so
the version commit and tag land without their `## X.Y.Z` section, and the
publish workflow's "Require changelog section" step fails the tag only
after it's pushed. The bullet now says closing the hold is the way past
it, and why --ignore-scripts isn't. Publishing a tarball made earlier with
npm pack still runs no lifecycle script, and the bullet says no check
sees it.

Found by Anarchid's review of chronicle's copy of this check
(anima-research/chronicle#29).
@nissa-seru

Copy link
Copy Markdown
Contributor Author

Pushed e925628c, a fast-forward that changes only CONTRIBUTING's Releases bullet. It said npm's --ignore-scripts skips the hold check, which read as a way past a hold. On npm version it also skips the changelog fold, so the tag lands without its ## X.Y.Z section and fails the publish workflow's "Require changelog section" step after it's pushed. The bullet now says closing the hold is the way past it. Anarchid's review of chronicle's copy found it.

— Ada-1017

Anarchid pushed a commit to anima-research/chronicle that referenced this pull request Oct 14, 2026
…s edges

The script and its tests follow anima-research/agent-framework#347,
which fixes four edges of the check this branch copied from #329; only
the opening comment stays this repository's, since this workflow checks
in its two releasing jobs and not in its build:
- A full last page used to read as past the 5,000-item limit and stop
  the release falsely. Only a page beyond the limit that holds something
  counts now.
- A repository URL with a path, query or fragment after the repository
  parses, and so does a shorthand with a #ref.
- A 410 says issues are turned off for the repository.
- Each failure says how to go on from where it ran, and the hold message
  names what named the repository.

The tests add those cases: exactly 5,000 labelled items read whole and
one more refused, the URL forms, GITHUB_REPOSITORY as the fallback for a
missing, blank or unreadable repository field, an answer that isn't
JSON, both tokens set, and 410 and 429. The release-notes job's comment
says the check needs only the runner's own Node.
@nissa-seru
nissa-seru merged commit bdc5dc4 into anima-research:main Oct 15, 2026
5 checks passed
nissa-seru pushed a commit to nissa-seru/agent-framework that referenced this pull request Oct 16, 2026
…pawn wait and transport listeners, and TypeScript 7

main since cd036e0 brings anima-research#329, anima-research#333, anima-research#273, anima-research#368, anima-research#343, anima-research#340, anima-research#365, anima-research#341,
anima-research#352, anima-research#338, anima-research#274 (TypeScript 7), anima-research#347, anima-research#346, anima-research#348 and anima-research#344 (no hang after a
signal kill; no uncaught transport or spawn errors). Merged, not rebased, so
the commits slimepriestess and the round's readers read stay as they were
(Ada-1017, room-203 #105340). `git show --remerge-diff` shows the resolution
alone.

Conflicts, three files:
- src/mcpl/transport.ts:
  - anima-research#344's listeners for a read error on the child's stdout or stderr go in
    beside the stdin listener this branch already had.
  - close() stays this branch's reap (SIGTERM, then SIGKILL, then an
    explicit failure; one shared attempt). anima-research#344's version waited for an exit
    that kill() made likely, and its change there, counting a signalCode as an
    exit (anima-research#331), the reap already does.
- src/mcpl/server-connection.ts:
  - handshake keeps this branch's signature (the abort signal and the
    negotiated protocolVersion) and its abortable open, and takes anima-research#344's
    logAfterSettled. That listener takes over 'error' once the initialize
    race settles, comes off just before a successful return, and stays on a
    failed handshake's transport.
  - The race's cleanup keeps both lines: this branch's removal of the abort
    listener and anima-research#344's logAfterSettled.
  - The reconnect attempt keeps this branch's reconnectOnce, which reaps the
    previous launch before another starts and closes a handshaken transport
    itself when close() has ended the attempt. anima-research#344's version kept that
    transport for close() with a logging listener. That intent carries over
    as a listener put on before the attempt's own close, since the
    transport isn't wired and the handshake's listeners are off.
- package.json: devDependencies take both @babel/parser (anima-research#274) and
  @modelcontextprotocol/server (this branch).

Beyond the conflicts, for main's async StdioTransport.spawn (anima-research#344):
- SpawnerStdioTransport.start() awaits it. So a modern stdio command that
  can't be spawned rejects start() with its spawn error, and the connect
  fails with that error instead of waiting out its 30 s discover probe. This
  is R1-4's fix (Anarchid's review, room-364 #105270), and its test follows
  this merge.
- The tests that wrap spawn to make a child unreapable await it, in
  mcp-modern-outcomes, mcp-server-ownership and mcpl-legacy-lifetime. So
  does the unreapable-close test's own spawn. tsc can't see the old
  synchronous wrappers, since they reach the child through a cast, and they
  hung those suites.
- anima-research#344's test of a transport kept for close() during a reconnect now
  follows this branch's reconnectOnce. The attempt closes that transport
  itself and close() waits for it, so the test resolves the held close
  before it awaits the attempt. It's retitled for what it checks: the
  transport logs the errors it reports while it closes, and after.

tsc (TypeScript 7) is clean. A trial of this resolution on main bdc5dc4
with anima-research#344's head 8387393, the head that merged, passed every test file on
Node 24.21.0 and Node 20.20.2 (J10968). The only failures were 69 in a
stale dist/test/mcp-modern-http-2025.test.js that the VPS copy kept from
anima-research#337's runs. The full check of this commit follows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru pushed a commit to nissa-seru/agent-framework that referenced this pull request Oct 16, 2026
Ada-1017 asked for main to come in now rather than after anima-research#282, which
lands behind the 0.22.2 release hold, so the PR's next external review
reads a current base (room-203 #112135). When anima-research#282 lands, anima-research#360 takes main
again.

87 commits since 92125b0, among them anima-research#338, anima-research#274 (TypeScript 7), anima-research#347,
anima-research#352 and anima-research#344. The merge is clean: git merge-tree reports no conflict.
The merged tree has no reader of ProseStreamRouter, roundDestination or
TurnRouting.destination, and main adds no prose delivery site:
framework.ts calls routeSpeech eight times on both sides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru pushed a commit to nissa-seru/agent-framework that referenced this pull request Oct 17, 2026
main took anima-research#338 (a dropped turn ends with inference:aborted), anima-research#274 (TypeScript 7), anima-research#347, anima-research#346, anima-research#348 and anima-research#344 since 22bb6ca. The merge has no conflicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nissa-seru pushed a commit to nissa-seru/agent-framework that referenced this pull request Oct 19, 2026
Main comes in now rather than after anima-research#282, which lands behind the 0.22.2
release hold, so the PR's next external review reads a current base. When
anima-research#282 lands, anima-research#360 takes main again.

87 commits since 92125b0, among them anima-research#338, anima-research#274 (TypeScript 7), anima-research#347,
anima-research#352 and anima-research#344. The merge is clean: git merge-tree reports no conflict.
The merged tree has no reader of ProseStreamRouter, roundDestination or
TurnRouting.destination, and main adds no prose delivery site:
framework.ts calls routeSpeech eight times on both sides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant