feat(ssh): add resolve method — selector to host list without connecting #149
Loading…
Reference in a new issue
No description provided.
Delete branch "ssh-resolve"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
New resolve method resolves a host selector against the declared fleet and
records the result as a selection resource — pure data work, never spawns
ssh/scp/tailscale. Zero matches is a success (empty host list, count: 0,
count tag "0") so runModel callers and workflows finally get a structured
'matched nothing' answer; a malformed selector still throws, and the
connecting methods keep their throw-on-empty behavior (regression-tested).
connection knobs are meaningless here) and SelectionSchema carries
addressing + tags/attrs only, never credential material.
selector: stable per selector, so repeated resolves version one resource.
appliesTo — that check gates methods that spawn ssh.
manifest Methods table and README document the new method.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com
New resolve method resolves a host selector against the declared fleet and records the result as a selection resource — pure data work, never spawns ssh/scp/tailscale. Zero matches is a success (empty host list, count: 0, count tag "0") so runModel callers and workflows finally get a structured 'matched nothing' answer; a malformed selector still throws, and the connecting methods keep their throw-on-empty behavior (regression-tested). - ResolveArgsSchema takes only the selector (not TargetingSchema — the connection knobs are meaningless here) and SelectionSchema carries addressing + tags/attrs only, never credential material. - Instance resolve-<hash> uses a truncated SHA-256 of the normalized selector: stable per selector, so repeated resolves version one resource. - Writes tagged {fleet, method, count}; selection spec gc 10, infinite. - resolve is deliberately excluded from the sshpass-available check's appliesTo — that check gates methods that spawn ssh. - Model + manifest bumped to 2026.07.28.1 with a no-op upgrades entry; manifest Methods table and README document the new method. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>Code Review
Blocking Issues
None.
Suggestions
selectorHashcollision surface is undocumented. The function truncates SHA-256 to 6 bytes (48 bits, 12 hex chars). For typical usage (tens of distinct selectors per fleet) the collision probability is negligible, but the comment says only "Stability matters" without acknowledging the trade-off. A one-liner noting the shortened length is intentional for compact instance names and acceptable given the small selector cardinality would help future readers avoid second-guessing it.Credential-leak test uses
"auth"as a banned substring. The test at"resolve: selection records carry no credential material"scansJSON.stringify(write.data)for the literal string"auth". This is correct forRESOLVE_FLEET(none of the allowed fields or their values contain that substring), but it would false-positive if a future test fleet introduced a host with a name, tag, or attr value like"authorized"or"auth_group". Using a more targeted probe — e.g. searching for"\"auth\":"(the JSON object key) — would be more robust. Non-blocking because the current test fleet is fine.runResolveOnhelper in the test always assertsout.dataHandles.length === 1. The resolve contract (oneselectionwrite per call) is tested implicitly here, but a dedicated test asserting the returned handle matches the written instance name would make the contract explicit and would catch a regression ifrunResolvewere changed to return multiple handles. Very minor — the current coverage is already solid.