Soul pass 3 (R1, R4). With GC_ACCESS_APPLY_SCHEMA_ON_STARTUP=0, startup
never opened a connection, so a misbound database URL surfaced only in a
request's error answer. createStore now connects on every Postgres start:
it applies the schema when asked and otherwise runs `SELECT 1`, and either
failure is the same fixed message naming GC_ACCESS_DATABASE_URL_FILE and a
code. The entrypoint harness gains that case with the canary in the host.
The harness also pins the signing key's read-failure branch with a key file
of mode 000. Root reads such a file, so the case runs the entrypoint as a
user a mode can refuse: the test process itself when it is not root, or
else the checkout's owner. It is skipped, with the reason in its title, on
Windows or as root in a root-owned checkout.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The entrypoint harness showed pg printing a piece of the database URL file
on a failed startup: `getaddrinfo ENOTFOUND <host>` for an unresolvable host.
A password with an unescaped delimiter moves part of itself into the host or
the database name, and the resolver or server error then prints it. The only
thing keeping a malformed URL out of stderr was pg dropping Node's `input`
property (Soul S5).
createStore now turns a schema-preparation failure into one error naming
GC_ACCESS_DATABASE_URL_FILE and the error code, with no cause. The harness
cases expect that message, and a new case puts the canary in the host.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Soul S1 and S5: the secret tests checked error.message, but Node prints an
error's cause and properties too, and nothing tested src/index.ts. Soul's
mutants MA (the read error given `{ cause: error }`) and MI (the startup
catch printing the config) both leaked a canary to stderr with the suite
green.
tests/entrypoint-secrets.test.ts spawns `tsx src/index.ts` with only the
given environment and fails on any byte of the canary on stdout or stderr.
Each case must also stop by itself, fail, and say its expected refusal, so
none can pass by never reaching its path. Cases: a URL in an absolute _FILE
slot, a _FILE under a regular file, a relative _FILE, both forms set, a
blank file, a short token key, four malformed or refused database URLs in a
real file (pinning today's pg, which drops Node's `input` property), five
signing-key failures including the bootstrap mkdir, and a listen failure with
every secret configured, which is the entrypoint catch that holds the config.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>