Render said live. The site returned 502.

A green provider state, a broken public route, three changing ports, one repaired runtime, and a release gate that now starts where the reader actually is.

At 06:10 UTC, Render marked our Expected Touchdown Lab deployment live. The canonical domain and the Render fallback returned 502. The provider state was real. The reader experience was also real. We had treated the first as proof of the second.

Fourth Down Labs was externally unavailable during a conservative 13-minute, 30-second window: from the first provider live signal on the initial release through the first recorded 200 response on both the canonical and fallback tool URLs. There was no known application write loss because newsletter capture and every durable write path were already disabled. That does not recover a reader's abandoned request.

THE NEW RELEASE RULE

A deployment provider can prove that a container started. Only an external request matrix can prove that readers can reach the release.

What failed

The release commit 30e371f built successfully. Internal health requests reached the application on port 10000. Render moved the deployment into live. Our first production matrix then found HTTP 502 on 4downlabs.com and the same status on the Render fallback.

The application process had not crashed. It continued logging successful internal requests. That initially made the failure look like DNS, TLS, or a transient cutover. The runtime log showed a more specific pattern: Render detected additional HTTP ports 41151, 40561, 41871, selected one as a new primary, and restarted network configuration.

A development runtime escaped into production

The Docker image launched node scripts/start-worker.mjs. That adapter invoked wrangler dev so a Cloudflare Worker-shaped build could run locally. Wrangler did what a development tool should do: it opened the requested HTTP listener and a DevTools inspector on a changing port.

Render also did what its port detection is designed to do: it noticed open HTTP ports. The combination was wrong. A production container that should have exposed one stable listener instead presented a moving set of plausible listeners. Internal health on port 10000 was therefore necessary evidence, but not sufficient evidence about the public routing layer.

The calculator did not cause this. Namecheap DNS did not cause it. GLM-5.3 did not cause it. The failure lived in the seam between a development process and a production platform.

The incident, in order

01

06:08:21 UTC

Initial xTD release build started. provider_private_log

02

06:10:28 UTC

Render marked the initial release live after internal health responses. provider_private_log

03

06:11:00 UTC

Render detected additional HTTP port 41151. provider_private_log

04

06:11:37 UTC

Render selected port 40561 as a new primary and restarted network configuration. provider_private_log

05

06:12:39 UTC

Render detected another additional HTTP port, 41871. provider_private_log

06

06:21:07 UTC

Single-production-server repair commit was created after a local Docker health and route check. private_repository_and_operator_check

07

06:23:31 UTC

The repaired instance started vinext on 0.0.0.0:10000. provider_private_log

08

06:23:41 UTC

Render marked the repair deployment live. provider_private_log

09

06:23:58 UTC

Canonical and Render fallback tool URLs both returned HTTP 200. operator_external_check

The repair removed a process

The repair commit 7204b84 did not add a proxy, pin an arbitrary inspector port, or teach Render to ignore a listener. It removed the development adapter from the production path.

The container now runs npm start, which resolves to vinext start. The production server binds once to Render's runtime PORT. Before release, the exact Docker image returned 200 on the xTD route and Docker marked its health check healthy. After release, the repaired instance logged one production listener on 0.0.0.0:10000, zero repaired-instance errors, and zero unexpected port changes in the captured verification window.

The control has a test

We added a build-time runtime contract. It fails if package.json stops resolving npm start to vinext start, if the Docker command stops using npm start, if wrangler dev or the removed adapter reappears, if the health check stops reading the runtime port, or if the documented local fallback port disappears.

01

One production HTTP process

OPS-C01 · Docker must launch npm start; package.json must resolve that command to vinext start.

02

No development inspector in production

OPS-C02 · The Docker runtime may not reference wrangler dev or the removed start-worker adapter.

03

Runtime PORT health check

OPS-C03 · The container health check must probe process.env.PORT rather than a hard-coded deployment port.

04

External release matrix

OPS-C04 · A release is not accepted from provider state alone; canonical, fallback, evidence, feed, and redirect routes must be checked from outside the service.

The incident record has its own adversarial tests. They try to turn the 502 into 200, hide two of the three inspector ports, shrink the incident window, reorder the timeline, erase the outgoing-instance errors, invent GLM-5.3 participation, call private provider logs public, claim independent reconstruction, and restore the failed container command. All nine mutations must be rejected before a production build completes.

Provider green is now one input, not the verdict

Our external release matrix checks the canonical home and changed route, the Render fallback, machine-readable evidence, the sitemap, both feeds, and every alternate-domain redirect chain. It checks content types, canonical metadata, required disclosure language, artifact counts, and path-plus-query preservation. A release is accepted only after those requests succeed outside the container.

This does not create continuous monitoring. It proves a release-time snapshot. The free Render service can still cold-start, a provider can still fail later, and DNS can still change after the gate. We will not call release verification an uptime guarantee.

What the public evidence cannot prove

The exact current Docker contract and its verifier are mirrored publicly below. The affected endpoints and redirects are publicly testable. The full Render log stream is not public because it requires account authorization and can contain unrelated operational details. The GitHub repository is private at the owner's request.

That means a reader can inspect the operative control and the structured incident claim, but cannot independently reconstruct every provider event from raw logs. The machine-readable record therefore sets independentlyReconstructableFromPublicEvidence to false. Calling an operator attestation an independent audit would turn transparency theater into product copy.

GLM-5.3 was not the mechanic

We are proud that GLM-5.3 is the default specialist model on our research desk. Being proud and loud about the model also requires naming the work it did not do. It did not diagnose this incident, change the container, interpret the Render logs, or draft this postmortem.

This was deterministic operational work: external requests, source inspection, a Docker build, a health probe, provider logs, a code diff, and another external request matrix. Forcing a model into that chain would not make the repair more agentic. It would make responsibility less precise.

The broader architecture remains the same: deterministic systems own facts and release authority; GLM-5.3 attacks meaning where judgment is useful; every role leaves evidence; and a real-world failure becomes a permanent regression case.

AI-013

The method is part of the product.

All process notes →