Augments LabsCrucible Code

Network

What crucible connects to, and how it gets there: the proxy it takes from your environment, the certificates it trusts and how long it waits.

What crucible connects to

crucible makes requests of its own for three things, and nothing else:

  • The provider's endpoint, for every request a turn makes and for web_search and web_fetch, which are asked of the same vendor. That is its built-in address, or the baseUrl you set. The vendor opens the page a fetch names; crucible never does.
  • The account hosts, when you sign in to a ChatGPT or Kimi Code plan with /login and when its token is renewed (account login). A MiniMax or Qwen plan is a key, sent to the provider's endpoint like any other, and signs in to no host.
  • api.github.com, to learn whether there is a newer release. It is asked once crucible has started, at most once a day, and is given ten seconds for the whole exchange; what it says is shown on the next run. A check that fails keeps the last answer and still counts as that day's check. { "updates": { "check": "never" } } turns it off (updates).

MCP servers and extensions are programs crucible starts and talks to over their standard input and output. crucible opens no connection for them, and any they open are their own. A command's connections are its own too, except that with confinement on, crucible's per-command proxy makes them on its behalf, through your proxy when you set one (see commands connect on their own).

Through a proxy

crucible takes its proxy from the first of these variables that holds an address it can read:

ALL_PROXY, all_proxy, HTTPS_PROXY, https_proxy, HTTP_PROXY, http_proxy

That one proxy carries every request, whatever the address's scheme, so a proxy named in HTTP_PROXY is used for https addresses as well. An address with no scheme is read as http://. A value that is not an address with a host, or whose scheme is not http, https or one of the SOCKS schemes below, is passed over for the next variable. A SOCKS address is not passed over: it is the one taken, and the variables after it are not read, so ALL_PROXY naming a SOCKS proxy hides an HTTPS_PROXY you also set.

These are read from the environment crucible was started in, so set them in your shell. One set in the env block never reaches crucible's own requests. It reaches the commands crucible runs, unless confinement's per-command proxy replaces it (see commands connect on their own). Proxy settings made in the operating system's own network settings are not read.

What happens next depends on the scheme:

ProxyWhat crucible doesWhat a confined command's allowed connections do
http://Asks it for a tunnel with CONNECT and speaks TLS to the provider through it, unless the provider's address is http. The request to the proxy is plain text.Go through it the same way, in a tunnel to the address crucible checked.
https://The same, over TLS to the proxy, checked against the same certificates as any other host.Fail with 502: they cannot be sent through it and are not sent around it.
socks://, socks4://, socks5://Ignores it and connects straight to the host.Go straight to the host, as crucible's requests do.
socks4a://, socks5h://Refuses to connect: every request fails unless its host skips the proxy.Fail with 502, as crucible's requests fail.

A user name and password in the address, as in http://name:secret@proxy.example:3128, are sent to the proxy as Basic credentials and to nowhere else. They are sent exactly as written: a %40 in the password stays those three characters and is not read as @. An address that is no longer valid once the name and password are taken out of it is refused, like the SOCKS kinds in the last row.

Hosts that skip the proxy

NO_PROXY lists hosts that are connected to directly; no_proxy is read only when NO_PROXY is not set at all, so NO_PROXY= with nothing after it hides no_proxy. Entries are separated by commas, and spaces are kept as part of an entry, so write the list without them. Each entry is compared with the host, ignoring case and the host's port:

EntryMatches
*every host
.example.comhosts ending in .example.com, not example.com itself
*example.comhosts ending in example.com, badexample.com included
10.hosts beginning with 10.
internal*hosts beginning with internal
example.comexample.com alone

There is no address-range matching: 10.0.0.0/8 matches nothing, and neither does an entry that carries a port. Nothing is skipped unless the list names it, localhost and 127.0.0.1 included, so a provider on your own machine is reached through the proxy until you add it.

Certificates

crucible trusts the Mozilla root certificates built into it, over TLS 1.2 or 1.3, and no others. It does not read the operating system's certificate store, a file named by SSL_CERT_FILE or any certificate you add, and there is no setting for one. On a network that inspects TLS by re-signing it with its own authority, as some corporate proxies do, every request fails. A turn or a web tool reports TLS setup failed, /login says account login could not reach the authorization service, and the release check finds nothing. A proxy that passes the tunnel through untouched works. crucible presents no client certificate.

Redirects

A redirect is never followed. The 3xx comes back as the provider's answer and the turn reports it, because a redirect chooses a new recipient for the key the request carries.

How long it waits

Making a connection has 15 seconds, for the lookup, the proxy's tunnel and TLS together. Sending the request has a minute, and the start of the answer a minute more. crucible sets up at most four connections at a time for turns and web requests; a request that needs a fifth waits until one of those is made or fails. A request from a turn or a web tool is given three minutes in all, from being sent to the start of the answer, whatever it spent waiting; the three minutes end when the answer starts, not when it finishes. A web tool's answer then has two minutes to arrive in full. Each request made while you sign in, or while an account's token is renewed, has 30 seconds from start to finish. When the provider refuses a turn's request, its reply is read for at most ten seconds (keys says more).

Connecting directly, a provider's hostname is given five seconds to resolve. The operating system's lookup cannot be cancelled, so once one has taken longer, every later lookup for a turn or a web tool fails at once, and a request that needs a new connection fails with it until crucible is restarted. Behind a proxy crucible looks up only the proxy's hostname, within the 15 seconds for the connection, and the proxy looks up the provider's.

When a request fails

A turn names the provider and what went wrong, as in anthropic: TLS setup failed:

MessageMeans
host was not foundThe proxy's hostname did not resolve, or, connecting directly, the provider's.
hostname resolution stalled; restart crucible before trying another provider requestA lookup took longer than five seconds, or an earlier one did.
connection failedNo connection could be made to the host or the proxy, the proxy refused the tunnel (for a wrong or missing password, or a provider hostname it could not resolve, say), or the proxy is one crucible refuses.
TLS setup failedThe host's or the https:// proxy's certificate was not trusted, or TLS with it failed.
request timed outOne of the waits above ran out.
HTTP protocol failedThe answer's head passed 64 KiB or 128 fields, or the request could not be built.
HTTP request failedThe exchange broke some other way, such as a connection closed before the answer.
request URL was invalidThe address is not http or https with a host.

A turn asks again twice before it reports any of these.

Commands connect on their own

A command the bash tool runs is not a crucible request, and nothing above applies to it except where this section says so. Its environment is built for it rather than copied from yours (environment and credentials). With confinement on under Linux or macOS and network domains allowed, its proxy variables name crucible's own per-command proxy, which checks each connection against the domains you allowed (sandbox). A proxy the env block names is replaced and never used.

An allowed connection then leaves the way crucible's own request to that host would: straight to the host when no proxy is set, NO_PROXY names the host, or the proxy is a SOCKS kind crucible connects past, and otherwise through the proxy crucible took from your environment. crucible looks the host up itself and checks the address it finds before the proxy hears of the connection. It then asks the proxy for a CONNECT tunnel to that address and the port the command asked for, with the name and password from the proxy's address. A plain http request travels inside such a tunnel too. So the machine crucible runs on must be able to resolve the host, and the proxy must accept a tunnel to an address and to that port. A host that is not allowed gets 403 Forbidden and never reaches the proxy. An allowed one this machine cannot resolve, or one reached straight that answers at none of its allowed addresses, gets 502 Bad Gateway saying which, so a command does not take a host that is down for a denial. The command never sees the proxy's address or password.

Only an http:// proxy can carry a command's connections. Under an https:// proxy they fail rather than go around it, though crucible's own requests go through it. Under a SOCKS proxy they do what crucible's own requests do: a socks://, socks4:// or socks5:// one is passed by, and a socks4a:// or socks5h:// one fails them. NO_PROXY sends a host straight there under any of these. A connection also fails when the proxy cannot be reached, refuses the tunnel, or has not opened it within five seconds of the command connecting. Each failure gets 502 Bad Gateway, with one line saying which. A proxy that answers 407 Proxy Authentication Required is not asked again for the host's other addresses.