Skip to content

fix(deploy): one agent-runtime install, the deployed one - #2236

Open
abretonc7s wants to merge 1 commit into
mainfrom
fix/one-agent-runtime-install
Open

abretonc7s wants to merge 1 commit into
mainfrom
fix/one-agent-runtime-install

Conversation

@abretonc7s

Copy link
Copy Markdown
Owner

Why

The engine tells a worker to run farmslot-agent: the escape hatch in a refused mark, the mark help, the farmslot-farm recipe fixture. A deploy only ever linked farmslot, so that bin resolved to whatever npm had installed globally. On mini that was @farmslot/agent-runtime 0.4.0, predating every worker-side fix in this revision, which is how a worker reached mark behaviour the current wrapper refuses.

Audit before the change (mini, macwork; macpro excluded, ssh down):

  • ~/.npm-global/lib/node_modules/@farmslot/agent-runtime 0.4.0 on mini, first on PATH for farmslot-agent
  • no caller in farmslot, the pack templates or the skills needs a PATH-global copy; every legitimate caller wants the deployed revision

What

  • farmslot-agent is linked from the same snapshot as farmslot, by the same rules, in all three layouts (unmigrated, layout 2, legacy), with a farmslot-agent-shim mirroring farmslot-shim for instance resolution.
  • Any global @farmslot/* package is uninstalled first. npm's uninstall removes the bins it owns, so doing this after linking would delete ours. A failed uninstall stops the deploy with the package name rather than falling back to rm -rf.
  • Then it verifies, and fails the deploy rather than leaving a worker on a stale engine: no global @farmslot package may remain, and both bins must resolve inside the install.

Notes for review

Two defects of mine during this change were both in the verification, not the linking, and both invisible to the check I had run:

  1. The guard used case. bash 3.2, which these nodes run, parses this heredoc body as code inside the surrounding $( ), where ;; is a syntax error that stopped the whole script from loading. bash -n had passed because it ran under bash 5.3 and on the outer file only. Replaced with prefix tests; /bin/bash -n now verified on the outer file and on both extracted heredoc bodies.
  2. The guard compared a resolved link against unresolved prefixes. /var is a symlink to /private/var on macOS, so every good link was rejected. Prefixes are resolved too, and the unresolved comparison is kept so either form matches.

Please attack the guard rather than the linking — that is where I have now been wrong twice.

Proof

scripts/deploy-node.test.mjs: 73/73, matching the pre-change baseline (fail 0).

The redeploy idempotence test needed a fixture change, not an assertion change: an installed revision now means both bins point at the snapshot, so the fixture seeds both, and seedSnapshot writes the agent-runtime bin a real snapshot always carries. The "moves nothing on redeploy" assertion is unchanged.

Live proof after merge: a deploy to mini and macwork showing both bins resolving into the snapshot and no global @farmslot package. macpro once its ssh is restored.

The engine tells a worker to run `farmslot-agent` — the escape hatch in a
refusal message, the mark help, the farmslot-farm recipe fixture — but a
deploy only ever linked `farmslot`. That bin kept resolving to whatever npm
had installed globally, on mini an agent-runtime 0.4.0 that predates every
worker-side fix in this revision, so a worker calling it directly bypassed the
wrapper's refusals.

A deploy now links `farmslot-agent` from the same snapshot as `farmslot`, by
the same rules and in all three layouts, uninstalls any global `@farmslot/*`
package first (npm's uninstall removes the bins it owns, so doing it after
linking would delete ours), and then verifies: no global `@farmslot` package
may remain, and both bins must resolve inside the install.

The verification resolves its allowed prefixes as well as the link, since
/var is a symlink to /private/var on macOS and comparing a resolved path
against an unresolved prefix rejects a good link. It uses prefix tests rather
than `case`, because bash 3.2 — what these nodes run — parses this heredoc
body as code inside the surrounding command substitution, where a `;;` is a
syntax error that stops the whole script from loading.

An installed revision now means both bins point at the snapshot, so the
redeploy fixture seeds both; `seedSnapshot` also writes the agent-runtime bin
that a real snapshot always carries.
@abretonc7s
abretonc7s requested a review from deeeed as a code owner November 15, 2026 20:08

This branch has not been deployed

No deployments
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