More than sixty-five thousand lead service lines remain in Milwaukee. A federal rule requires all of them to be replaced by twenty thirty-seven.
The 65,000 pipes under Milwaukee
the-65-000-pipes-under-milwaukee
The film
The board
Six blocks, one per beat. Each card shows the provider that actually ran — a fallback nobody can see in the record is a substitution, not a fallback.
For decades, lead service lines carried water into Milwaukee homes. They were the standard. Now we know they poison the water they deliver.
In twenty twenty-five, Milwaukee replaced roughly thirty-three hundred of them. That same year, the city replaced more than ten thousand since the program began.
Each replacement costs an average of ten thousand dollars. The city received more than fifty million dollars in twenty twenty-six to fund this work.
The federal deadline is twenty thirty-seven. Milwaukee plans to replace five thousand lines in twenty twenty-six, a fifty percent increase. The math doesn't close.
Since early twenty twenty-four, homeowners in the program pay nothing. Those who ask for replacements outside it pay four thousand dollars. The pipes wait.
Run log
Every submission, rejection, retry and take measurement, newest first. This is literally the audit trail rendered.
- 19:47:30publishpublished 68.77s at -16.1 LUFS
- 19:41:27approveApproved by Claude (agent) — UNREVIEWED, pending Tarik Moody
- 19:37:56narrateblock 6 voiced by elevenlabs at 12.774s$0.0717
- 19:37:56narrateblock 5 voiced by elevenlabs at 9.691s$0.0359
- 19:37:56narrateblock 4 voiced by elevenlabs at 9.9s$0.0680
- 19:37:56narrateblock 3 voiced by elevenlabs at 9.378s$0.0354
- 19:37:56narrateblock 2 voiced by elevenlabs at 9.117s$0.0647
- 19:37:56narrateblock 1 voiced by elevenlabs at 9.3s$0.1008
- 19:37:28blocksblock 6 ready on seedance-1-0-pro-fast-251015$0.1560
- 19:37:28blocksblock 5 ready on seedance-1-0-pro-fast-251015$0.1560
- 19:37:28blocksblock 4 ready on seedance-1-0-pro-fast-251015$0.1560
- 19:37:28blocksblock 3 ready on seedance-1-0-pro-fast-251015$0.1560
- 19:37:28blocksblock 2 ready on seedance-1-0-pro-fast-251015$0.1560
- 19:37:28blocksblock 1 ready on seedance-1-0-pro-fast-251015$0.1560
- 19:35:22gate6 blocks x 4 rules passed
- 19:31:20script6 blocks written
- 19:31:20decision.scriptpass — 6 blocks, every claim traced to a fact after 5 repair pass(es)
- 19:12:58errorstage script failed: no block survived checking — block 1: POL-5 — 21 words (need 23-27). Estimated ~8.1s. | block 6: POL-5 — 34 words (need 23-27). Estimated ~13.1s. | block 1: the mapping quotes "Sixty-five thousand lead service lines remain in Milwaukee, and a federal rule requires all of them to be replaced by twenty thirty-seven.", which is not in this line. The mapping has drifted from the narration. | block 1: this line states "sixty-five thousand", "twenty thirty-seven" without tracing to a fact. Map it or cut it — a number on screen is a claim. | block 1: this block traces to no fact at all. Its role is "cold open", which is reporting — only the kicker may be pure framing. Map at least one assertion to a fact, or replace the block. | block 6: the mapping quotes "Since the beginning of twenty twenty-four there has been no cost to owners of one-to-four-unit residential properties included in the replacement program, while an owner who requests a replacement outside it pays four thousand dollars.", which is not in this line. The mapping has drifted from the narration. | block 6: this line states "twenty twenty-four", "one-to-four-unit", "four thousand" without tracing to a fact. Map it or cut it — a number on screen is a claim. (after 6 attempts — surfacing rather than retrying further)
- 19:12:58decision.scriptreject — block 1: POL-5 — 21 words (need 23-27). Estimated ~8.1s. | block 6: POL-5 — 34 words (need 23-27). Estimated ~13.1s. | block 1: the mapping quotes "Sixty-five thousand lead service lines remain in Milwaukee, and a federal rule requires all of them to be replaced by twenty thirty-seven.", which is not in this line. The mapping has drifted from the narration. | block 1: this line states "sixty-five thousand", "twenty thirty-seven" without tracing to a fact. Map it or cut it — a number on screen is a claim. | block 1: this block traces to no fact at all. Its role is "cold open", which is reporting — only the kicker may be pure framing. Map at least one assertion to a fact, or replace the block. | block 6: the mapping quotes "Since the beginning of twenty twenty-four there has been no cost to owners of one-to-four-unit residential properties included in the replacement program, while an owner who requests a replacement outside it pays four thousand dollars.", which is not in this line. The mapping has drifted from the narration. | block 6: this line states "twenty twenty-four", "one-to-four-unit", "four thousand" without tracing to a fact. Map it or cut it — a number on screen is a claim. (after 6 attempts — surfacing rather than retrying further)
- 19:10:21errorstage script failed: no block survived checking — checker unavailable (ProviderError: GMICloud chat failed (400): {"error":{"message":"Backend request failed with status 400","type":"backend_error","code":400,"details":"{\"error\":{\"type\":\"\\u003cnil\\u003e\",\"message\":\"InvokeMod) — blocked rather than assumed safe
- 19:10:21decision.scriptreject — checker unavailable (ProviderError: GMICloud chat failed (400): {"error":{"message":"Backend request failed with status 400","type":"backend_error","code":400,"details":"{\"error\":{\"type\":\"\\u003cnil\\u003e\",\"message\":\"InvokeMod) — blocked rather than assumed safe
- 18:58:48errorstage script failed: no block survived checking — checker unavailable (ProviderError: GMICloud chat failed (400): {"error":{"message":"Backend request failed with status 400","type":"backend_error","code":400,"details":"{\"error\":{\"message\":\"InvokeModel: operation error Bedrock Run) — blocked rather than assumed safe
- 18:58:48decision.scriptreject — checker unavailable (ProviderError: GMICloud chat failed (400): {"error":{"message":"Backend request failed with status 400","type":"backend_error","code":400,"details":"{\"error\":{\"message\":\"InvokeModel: operation error Bedrock Run) — blocked rather than assumed safe
- 18:56:23errorstage script failed: no block survived checking — checker unavailable (ProviderError: GMICloud chat failed (400): {"error":{"message":"Backend request failed with status 400","type":"backend_error","code":400,"details":"{\"error\":{\"message\":\"InvokeModel: operation error Bedrock Run) — blocked rather than assumed safe
- 18:56:23decision.scriptreject — checker unavailable (ProviderError: GMICloud chat failed (400): {"error":{"message":"Backend request failed with status 400","type":"backend_error","code":400,"details":"{\"error\":{\"message\":\"InvokeModel: operation error Bedrock Run) — blocked rather than assumed safe