Skip to content

perf(sdk): probe and hash the authored Node once per CLI process - #681

Merged
miyaontherelay merged 2 commits into
mainfrom
perf/memoize-authored-node-authority
Oct 22, 2026
Merged

miyaontherelay merged 2 commits into
mainfrom
perf/memoize-authored-node-authority

Conversation

@miyaontherelay

@miyaontherelay miyaontherelay commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

What

An authored run resolved the Node authority twice on its startup path: once in assertAuthoredRuntimeAvailable (before root admission) and again in runAuthoredInNode (before spawning the body). Each call spawned a node probe and read and SHA-256 hashed the whole node executable (about 110 MB).

This PR keeps the previous authority for the same FLOWS_AUTHORED_NODE/PATH selection while a stat fingerprint of the resolved executable (dev, ino, size, mtimeNs, ctimeNs) is unchanged. The integrity check is unchanged: the child still hashes the executable it actually runs, and the parent still compares that report with the authority. A binary swapped after the probe is refused, never trusted.

Why

This is part of the hosted Relayflows v2 startup work. In production, the time from CLI spawn to the first step is 2.7–3.2 s (runs 87945dd1, 58982337, aa813b41, 3f646c0f). An instrumented darwin-arm64 standalone build (temporary trace points, not in this PR) put the second authority call at 64–76 ms locally. With the memo it is 0 ms; the whole CLI spawn → first step went from about 780 ms to about 720 ms on the same machine. E2B boxes are slower per operation (the same path takes about 4x longer there), so the expected hosted saving is about 0.2–0.3 s. That figure is an estimate and has not been measured on E2B.

Verification

Commands were run in packages/sdk with Node 22.22.2 and Bun 1.4.2.

Head b8dcf19 (first commit):

  • npm run typecheck and npm run typecheck:tests pass.
  • npx vitest run tests/authored-node-authority.test.ts: 3/3 pass.
  • Mutation checks (each reverted byte-for-byte afterwards):
    • Disabling the reuse branch makes 1 test fail.
    • Dropping the fingerprint revalidation makes 1 test fail.
  • RELAYFLOWD_BIN=<released 2.0.54 darwin relayflowd> npx vitest run tests/authored-node-runtime.test.ts tests/authored-node-admission.test.ts tests/authored-node-result.test.ts tests/authored-node-authority.test.ts (after npm run build): 81/81 pass.

Review fix baf849f (keys the memo on the selected executable's path plus its realpath):

  • npx vitest run tests/authored-node-authority.test.ts: 5/5 pass.
  • npm run typecheck passes.
  • Mutation checks (each restored afterwards):
    • Keying on the selected path without its realpath makes the two retarget tests fail.
    • Disabling reuse makes 3 tests fail.
    • Dropping the fingerprint check makes 1 test fail.
  • The combined authored-node integration suites could not be re-run cleanly:
    • One attempt ran with the machine's load average at 40–200. Runtime tests failed with process-timeout statuses, and the same test fails identically on the previous head under that load.
    • The other attempt ran out of space on the internal disk.
    • The external volume holding the worktree then returned EPERM, and npm run typecheck:tests failed with missing TypeScript lib errors for that reason.
    • These suites need a re-run on an idle machine (or in CI) before merge.
  • The fix was re-applied with the same edit scripts in a sparse clone in order to push; that tree was not re-tested.

Release and pin

This saving reaches hosted runs only through a flows release followed by a Cloud pin bump of the hosted runtime artifact and Surface authority.

🤖 Generated with Claude Code


Note

Medium Risk
Touches security-sensitive Node executable trust on the authored startup path; caching is guarded by fingerprint revalidation and unchanged child-side hash verification, but a wrong invalidation rule could trust a stale authority.

Overview
Memoizes the authored Node authority so a single CLI process no longer runs the expensive probe (spawn Node + SHA-256 of the full executable) twice on startup—once before root admission and again before spawning the body.

Reuse is keyed on FLOWS_AUTHORED_NODE and PATH, and is invalidated when a stat fingerprint (dev, ino, size, mtimeNs, ctimeNs) of the resolved executable changes or the candidate vanishes. The child still reports and hashes the binary it runs; parent comparison is unchanged, and a rewrite during hashing is not cached.

Adds authoredNodeAuthorityForTest() and Vitest coverage for single-probe reuse, re-probe on executable change, and re-probe when PATH changes.

Reviewed by Cursor Bugbot for commit b8dcf19. Bugbot is set up for automated code reviews on this repo. Configure here.


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


Agent Relay sessions

  • claude session a9c94cac · opened via gh pr create · last active 2026-10-21

An authored run resolved the Node authority twice on the startup path:
assertAuthoredRuntimeAvailable before root admission and runAuthoredInNode
before spawning the body. Each call spawned a node probe and read and
SHA-256 hashed the whole node executable (~110 MB).

Reuse the previous authority for the same FLOWS_AUTHORED_NODE/PATH while a
stat fingerprint (dev, ino, size, mtime, ctime) of the resolved executable is
unchanged. The child still hashes the executable it runs and the parent
still compares that report, so a binary swapped after the probe is refused.

Measured with an instrumented darwin-arm64 standalone build: the second
authority call drops from 64-76 ms to 0 ms per run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: dcbfa53f-99f1-4caf-b68a-522b0e226a6d
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; the stale symlink selection is fixed and no new actionable issue was found.

Summary

Caches the authored Node probe and executable hash while the selected executable and its file fingerprint stay unchanged.

  • Authored startup reuses the Node authority when its executable stays the same.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Resolve selected path and realpath] --> B{Same selection and fingerprint?}
  B -->|Yes| C[Reuse cached authority]
  B -->|No or unknown| D[Probe Node and hash executable]
  D --> E[Cache identifiable selection if fingerprint stays unchanged]
  C --> F[Spawn authority.path]
  E --> F
  F --> G[Compare child runtime report before sending workflow]
Loading

Reviews (2) · Last reviewed commit: "fix(sdk): key the Node authority memo on..." · Reviewed by Greptile

Comment thread packages/sdk/src/authored-node-runner.ts Outdated
Review (#681): the memo keyed on FLOWS_AUTHORED_NODE/PATH and fingerprinted
the previously resolved file, so a selection symlink retargeted while the
old binary remained kept returning the old authority.

Key reuse on the candidate spawnSync would run now (the override, or the
first node on an all-absolute PATH) by both its path and its realpath. Any
change re-probes; a PATH with a relative entry is never reused. Tests cover
an override symlink retarget and a PATH node symlink retarget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@miyaontherelay
miyaontherelay merged commit 2cd9561 into main Oct 22, 2026
9 of 10 checks passed
@miyaontherelay
miyaontherelay deleted the perf/memoize-authored-node-authority branch October 22, 2026 04:38
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