[object Object]

← back to Crazy News Channel Shadowman

Backfill story_id links for 9 orphaned cartoons + codify link-to-article rule

c130b62dd763f6d527fdca320b4560685d053701 · 2026-09-24 13:00:06 -0700 · Steve Abrams

9 cartoons shipped with story_id: null (no underlying article at all):
commission-turtles, budget-pie-fight, pork-barrel-train, quorum-call-hide-seek,
cloture-oclock, lobbyist-revolving-door, conrad-filibuster-ink,
conrad-filibuster-qwen25, filibuster-marathon.

Added 7 new stories-data.js entries (window.P24_EXTRA_STORIES, matching the
existing schema exactly): 6 distinct stories for the 6 non-filibuster
cartoons, plus one shared story (pw-filibuster-holloway) for the 3
Paul-Conrad/model-contest/plain filibuster variants, since they all depict
the same invented Delegate Holloway event. Re-pointed all 9 cartoons'
story_id fields in cartoons/manifest.js accordingly. Verified via a vm-context
load of both files: all 23 cartoons now resolve to a real story (0 orphans,
0 broken links).

Codified the standing rule (Steve, verbatim: "always link images cartoons to
the real article") as a comment block at the top of cartoons/manifest.js, and
wired the same requirement into scripts/build-cartoon-batch.sh — the
not-yet-installed daily batch pipeline that appends new manifest entries:
updated its claude -p prompt to require writing a companion story + a
non-null story_id, and added a cheap substring-based post-build check that
now fails (not passes) a build whose manifest entry has story_id: null.

Scope: only cartoons/manifest.js, stories-data.js, and
scripts/build-cartoon-batch.sh touched. Left untouched (a sibling agent's
uncommitted CSS-unification work): cartoons/index.html, index.html, and all
cartoons/*.html strip files.

TK-12158

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V29xaoBwcFwJyR4KC43ptn

Files touched

Diff

commit c130b62dd763f6d527fdca320b4560685d053701
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Sep 24 13:00:06 2026 -0700

    Backfill story_id links for 9 orphaned cartoons + codify link-to-article rule
    
    9 cartoons shipped with story_id: null (no underlying article at all):
    commission-turtles, budget-pie-fight, pork-barrel-train, quorum-call-hide-seek,
    cloture-oclock, lobbyist-revolving-door, conrad-filibuster-ink,
    conrad-filibuster-qwen25, filibuster-marathon.
    
    Added 7 new stories-data.js entries (window.P24_EXTRA_STORIES, matching the
    existing schema exactly): 6 distinct stories for the 6 non-filibuster
    cartoons, plus one shared story (pw-filibuster-holloway) for the 3
    Paul-Conrad/model-contest/plain filibuster variants, since they all depict
    the same invented Delegate Holloway event. Re-pointed all 9 cartoons'
    story_id fields in cartoons/manifest.js accordingly. Verified via a vm-context
    load of both files: all 23 cartoons now resolve to a real story (0 orphans,
    0 broken links).
    
    Codified the standing rule (Steve, verbatim: "always link images cartoons to
    the real article") as a comment block at the top of cartoons/manifest.js, and
    wired the same requirement into scripts/build-cartoon-batch.sh — the
    not-yet-installed daily batch pipeline that appends new manifest entries:
    updated its claude -p prompt to require writing a companion story + a
    non-null story_id, and added a cheap substring-based post-build check that
    now fails (not passes) a build whose manifest entry has story_id: null.
    
    Scope: only cartoons/manifest.js, stories-data.js, and
    scripts/build-cartoon-batch.sh touched. Left untouched (a sibling agent's
    uncommitted CSS-unification work): cartoons/index.html, index.html, and all
    cartoons/*.html strip files.
    
    TK-12158
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01V29xaoBwcFwJyR4KC43ptn
---
 cartoons/manifest.js           |  36 +++--
 scripts/build-cartoon-batch.sh |  36 ++++-
 stories-data.js                | 329 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 388 insertions(+), 13 deletions(-)

diff --git a/cartoons/manifest.js b/cartoons/manifest.js
index e9f31da..f036253 100644
--- a/cartoons/manifest.js
+++ b/cartoons/manifest.js
@@ -4,6 +4,24 @@
 // contract is offline-capable file:// use with no server (see ../README.md) — a
 // fetch() of a sibling JSON file is blocked under file:// in Chrome/Safari and
 // silently mis-renders the empty state instead of erroring (TK-12133 finding #2).
+//
+// STANDING RULE (Steve, verbatim: "always link images cartoons to the real
+// article" — codified TK-12158, 2026-09-24): every cartoon entry below MUST
+// carry a non-null story_id that resolves to a real entry in
+// ../stories-data.js (window.P24_EXTRA_STORIES) or ../real-news-data.js
+// (window.P24_REAL_STORIES) — see cartoons/index.html's storyCategoryById()
+// for exactly how story_id is resolved and used. A cartoon with story_id:
+// null is a GAP TO FIX, never a valid end state. If a cartoon's topic has no
+// underlying article yet, write one into stories-data.js (matching the
+// window.P24_EXTRA_STORIES schema: id, category, categoryLabel, location,
+// byline, image, intervalSec, offsetSec, stageIndex, article{dek,
+// photoCaption, paragraphs}, stages[]) BEFORE — or in the same change as —
+// adding the cartoon here. Several cartoons drawn as visual style-contest
+// variants of the same underlying event (e.g. the three "Filibuster
+// Marathon" strips) should share ONE story_id rather than each getting a
+// duplicate story. TK-12158 backfilled 9 cartoons that had shipped with
+// story_id: null (6 new story entries covering them, one shared by 3
+// cartoons) — do not reintroduce that gap.
 window.P24_CARTOONS = [
   {
     "id": "commission-turtles",
@@ -14,7 +32,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "A blue-ribbon commission recommends forming a commission to study its own recommendation. It keeps going.",
     "thumb": null,
-    "story_id": null
+    "story_id": "pw-commission-turtles"
   },
   {
     "id": "meter-that-wouldnt-yield",
@@ -91,7 +109,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "An invented town's budget pie gets re-sliced smaller across three courses while five invented departments hold their forks; drag the slider and watch who ends up with crumbs.",
     "thumb": null,
-    "story_id": null
+    "story_id": "pw-budget-pie-slice"
   },
   {
     "id": "pork-barrel-train",
@@ -102,7 +120,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "An invented infrastructure bill leaves committee as a single train car and picks up wildly unrelated riders — a desert lighthouse, a ferris wheel, a spoon museum — at every stop; click a car for its invented cost.",
     "thumb": null,
-    "story_id": null
+    "story_id": "pw-pork-barrel-express"
   },
   {
     "id": "quorum-call-hide-seek",
@@ -113,7 +131,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "An invented legislative chamber plays hide-and-seek to dodge a quorum call, propping paper cutouts in empty chairs while the Sergeant-at-Arms searches a suspiciously form-shaped closet; each plot twist relocates the hiding spot.",
     "thumb": null,
-    "story_id": null
+    "story_id": "pw-quorum-hide-seek"
   },
   {
     "id": "cloture-oclock",
@@ -124,7 +142,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "An invented chamber's ceremonial floor clock is wound tight by one side and wound right back by the other, ticking forward and backward until it just shrugs; each plot twist changes its face.",
     "thumb": null,
-    "story_id": null
+    "story_id": "pw-cloture-oclock"
   },
   {
     "id": "tollpoints-diamond-status",
@@ -190,7 +208,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "An invented capitol official spins out of the revolving door as a regulator and spins back in seconds later as a lobbyist, carrying a slightly bigger briefcase every revolution.",
     "thumb": null,
-    "story_id": null
+    "story_id": "pw-lobbyist-revolving-door"
   },
   {
     "id": "conrad-filibuster-ink",
@@ -201,7 +219,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "An invented delegate drones on from a phone book the size of a cinder block. The chamber sleeps. The clock gives up and melts down the wall.",
     "thumb": "../images/filibuster-marathon-conrad.jpg",
-    "story_id": null,
+    "story_id": "pw-filibuster-holloway",
     "ai_generated": true,
     "model": "flux-kontext"
   },
@@ -214,7 +232,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "A delegate reads from a massive phone book to stall a vote. The chamber clock melts Dali-style. Congress sleeps standing up. Winner of the Model Arena 3-model Conrad-style showdown (Qwen3 14B vs Qwen2.5 7B, auto-judged by vision-referee).",
     "thumb": null,
-    "story_id": null,
+    "story_id": "pw-filibuster-holloway",
     "ai_generated": true,
     "model": "qwen25-7b",
     "challenge_id": "56406f116d2a"
@@ -228,7 +246,7 @@ window.P24_CARTOONS = [
     "section": "politics",
     "blurb": "Delegate Holloway holds the floor of the invented Assembly by reading anything within arm's reach — a phone book, a cereal box, furniture instructions, his own bill — while a Dali-style clock melts and the chamber falls asleep standing up.",
     "thumb": null,
-    "story_id": null,
+    "story_id": "pw-filibuster-holloway",
     "ai_generated": false
   },
   {
diff --git a/scripts/build-cartoon-batch.sh b/scripts/build-cartoon-batch.sh
index 43f2cb7..e9370ed 100644
--- a/scripts/build-cartoon-batch.sh
+++ b/scripts/build-cartoon-batch.sh
@@ -16,6 +16,13 @@
 #     satire, 390-1440px responsive, keyboard accessible, reduced-motion safe,
 #     zero console errors — same acceptance bar as 20260924-commission-turtles.html),
 #     e2e-test it with Playwright, add it to cartoons/manifest.js, and commit.
+#     HARD RULE (Steve, verbatim: "always link images cartoons to the real
+#     article", codified TK-12158) — the manifest entry's story_id must NOT be
+#     null. Every new cartoon must link to a real article, either an existing
+#     one in stories-data.js/real-news-data.js or a new stories-data.js entry
+#     written for it. See the requirement comment at the top of
+#     cartoons/manifest.js. Step 90-98 below enforces this: a built cartoon
+#     with story_id: null (or missing) is logged FAIL, not PASS.
 #  3. Logs the whole run to yolo/cartoon-batch-log.jsonl.
 #
 # COST: each `claude -p` build is a real paid Anthropic API session. Today's single
@@ -74,7 +81,15 @@ for b in q['briefs']:
         f"launch chromium with channel:'chrome'). Fix any real defects found, then add an entry to "
         f"~/Projects/crazy-news-channel/cartoons/manifest.js (as a new object appended to the window.P24_CARTOONS array: id, title, file, created_at ISO now, "
         f"category 'Political Cartoon', blurb, thumb:null) and commit with author "
-        f"steve@designerwallcoverings.com. Do not deploy, push, or touch anything outside this repo."
+        f"steve@designerwallcoverings.com. HARD RULE — Steve's standing instruction is 'always link "
+        f"images cartoons to the real article': the manifest entry's story_id field must be a real, "
+        f"non-null id. If no existing entry in ~/Projects/crazy-news-channel/stories-data.js or "
+        f"real-news-data.js already covers this brief's topic, write ONE new satirical story object "
+        f"matching the exact schema of an existing window.P24_EXTRA_STORIES entry (id, category, "
+        f"categoryLabel, location, byline, image, intervalSec, offsetSec, stageIndex, article.dek, "
+        f"article.photoCaption, article.paragraphs, stages) and append it to stories-data.js, then set "
+        f"this cartoon's story_id to that new id. Never leave story_id: null. Do not deploy, push, or "
+        f"touch anything outside this repo."
     )
     if dry == "1":
         print(f"[DRY RUN] would build: {b['id']} — {b['title']}")
@@ -91,11 +106,24 @@ for b in q['briefs']:
     out = os.path.join(root, "cartoons", b["slug"] + ".html")
     man = open(os.path.join(root, "cartoons", "manifest.js")).read()
     has_file, in_manifest = os.path.isfile(out), (b["slug"] + ".html") in man
-    ok = rc == 0 and has_file and in_manifest
+    # HARD RULE check (TK-12158): a cartoon with story_id: null is not a valid
+    # end state (Steve, verbatim: "always link images cartoons to the real
+    # article"). Cheap substring check, not a full JSON parse — find this
+    # entry's object body between its "file" key and the object's closing
+    # "  }" line, and require a non-null "story_id" inside it.
+    has_story_id = False
+    marker = f'"file": "{b["slug"]}.html"'
+    mi = man.find(marker)
+    if mi != -1:
+        obj_end = man.find("\n  }", mi)
+        obj_body = man[mi: obj_end if obj_end != -1 else mi + 2000]
+        m = __import__("re").search(r'"story_id"\s*:\s*"([^"]+)"', obj_body)
+        has_story_id = bool(m)
+    ok = rc == 0 and has_file and in_manifest and has_story_id
     with open(log, "a") as f:
         f.write(json.dumps({"ts": ts, "id": b["id"], "title": b["title"], "exit": rc,
-                            "file": has_file, "manifest": in_manifest, "ok": ok,
-                            "verdict": "PASS" if ok else "FAIL"}) + "\n")
+                            "file": has_file, "manifest": in_manifest, "story_id": has_story_id,
+                            "ok": ok, "verdict": "PASS" if ok else "FAIL"}) + "\n")
     b['status'] = 'built' if ok else 'failed'
 json.dump(q, open(qfile, 'w'), indent=2)
 sys.exit(1 if any(b.get('status') == 'failed' for b in q['briefs']) else 0)
diff --git a/stories-data.js b/stories-data.js
index aec5291..b427884 100644
--- a/stories-data.js
+++ b/stories-data.js
@@ -1774,5 +1774,334 @@ window.P24_EXTRA_STORIES = [
     "conclusion": "The spot remains, by all accounts, a completely unremarkable curb."
    }
   ]
+ },
+ {
+  "id": "pw-commission-turtles",
+  "category": "politics",
+  "categoryLabel": "Politics",
+  "location": "Two Egg, FL",
+  "byline": "Municipal Affairs Correspondent Priya Osgood",
+  "image": null,
+  "intervalSec": 45,
+  "offsetSec": 5,
+  "stageIndex": 0,
+  "article": {
+   "dek": "A blue-ribbon commission convened to trim government waste in Two Egg has recommended forming a second commission to verify its own recommendation, with a third already under discussion to review that one.",
+   "photoCaption": "P24 illustration.",
+   "paragraphs": [
+    "TWO EGG, FL—The city's Commission on Governmental Efficiency, formed 14 months ago with a mandate to eliminate redundant bureaucracy, voted unanimously Tuesday night to recommend the creation of a second commission tasked with confirming that the first commission's recommendation was, in fact, efficient.",
+    "\"We wanted to be thorough,\" said commission chair Roland Ashby, reading from a 212-page report that concluded the city could save an estimated $40,000 a year by disbanding the commission that produced the report. \"So naturally, the next step is a second commission to double-check the math.\"",
+    "The proposed Commission on the Efficiency of the Efficiency Commission would meet monthly, retain its own outside consultant, and report its findings to a subcommittee not yet named, according to a memo circulated ahead of the vote.",
+    "City Councilwoman Theresa Okafor, who voted in favor, acknowledged the arrangement 'does raise some questions,' but said she trusted the process. \"If the second commission finds the first commission was inefficient, we'll know we need a commission for that too,\" she said.",
+    "Local resident Gary Vance, who has attended all fourteen of the original commission's public meetings, said he plans to attend the new commission's meetings as well, 'assuming they ever schedule one that isn't about scheduling the next one.'",
+    "A preliminary budget request for the second commission, obtained by this paper, includes a line item for 'commission-on-commission overhead,' which two council members said they did not fully understand but voted to approve anyway.",
+    "As of press time, a resolution had been filed to form a third commission to determine whether the first two commissions still had a quorum."
+   ]
+  },
+  "stages": [
+   {
+    "headline": "City Forms Blue-Ribbon Commission to Trim Government Waste",
+    "detail": "The Commission on Governmental Efficiency will spend a year studying redundant city bureaucracy, chair Roland Ashby said, calling it 'long overdue.'"
+   },
+   {
+    "headline": "Efficiency Commission Recommends Second Commission to Verify Its Own Report",
+    "detail": "The 212-page report concluded the city could save $40,000 by disbanding the commission that wrote it, prompting a call for independent confirmation."
+   },
+   {
+    "headline": "Second Commission Requests Its Own Outside Consultant",
+    "detail": "The Commission on the Efficiency of the Efficiency Commission will meet monthly and report to a subcommittee not yet named, per a city memo."
+   },
+   {
+    "headline": "Third Commission Proposed to Determine Whether the First Two Still Have a Quorum",
+    "detail": "Neither original commission has met since March, city records show, though both remain fully funded."
+   },
+   {
+    "headline": "City Quietly Approves Fourth Commission to Study Whether Any of the Others Still Exist",
+    "detail": "Council members voted 6-1 to fund the new body, whose sole task is confirming attendance records for the previous three.",
+    "conclusion": "The original $40,000 in projected savings has not been mentioned in a public meeting since February."
+   }
+  ]
+ },
+ {
+  "id": "pw-budget-pie-slice",
+  "category": "politics",
+  "categoryLabel": "Politics",
+  "location": "Toad Suck, AR",
+  "byline": "Civic Budget Correspondent Marlene Petrosky",
+  "image": null,
+  "intervalSec": 52,
+  "offsetSec": 10,
+  "stageIndex": 0,
+  "article": {
+   "dek": "Toad Suck's annual budget pie has been re-sliced smaller in each of three public work-sessions this month, as five city departments continue holding out forks.",
+   "photoCaption": "P24 illustration.",
+   "paragraphs": [
+    "TOAD SUCK, AR—City department heads returned for a third consecutive budget work-session Wednesday night to find the municipal pie chart had shrunk again, after finance officials discovered a $60,000 shortfall wedged, they said, 'somewhere between the culvert fund and the copier lease.'",
+    "\"Every session we come back and the pie is smaller,\" said Parks and Recreation Director Wendell Bosley, holding a fork over a slice roughly the width of a dessert spoon. \"At this rate we'll be splitting a single crumb by Arbor Day.\"",
+    "Finance Director Lucille Tran, who has redrawn the chart three times using the same software, said the shrinkage was 'unfortunate but mathematically sound,' and noted the pie could theoretically continue shrinking through a fourth and fifth session if the culvert issue 'gets worse before the vote.'",
+    "Public Works, Library Services, Animal Control, the Fire Auxiliary, and Parks and Recreation have each held a fork at the table since the first session in March, though only Public Works has managed to secure a slice larger than a garnish.",
+    "\"I brought my own fork this year because last year someone took mine,\" said Animal Control supervisor Denny Wray, who described his department's current allotment as 'theoretical.'",
+    "Mayor Carol Dunmire pledged the pie would be 'meaningfully larger' at next year's session, a promise the council has now made in four consecutive budget cycles without, according to city archives, an increase in the pie's actual size.",
+    "As of press time, a fourth work-session had been scheduled for next month, with department heads asked to bring their own napkins."
+   ]
+  },
+  "stages": [
+   {
+    "headline": "City Holds First Budget Work-Session of the Year, Unveils Full-Size Pie Chart",
+    "detail": "Five departments arrived with forks as the council presented its initial budget allocation, finance officials said."
+   },
+   {
+    "headline": "Second Work-Session Reveals Pie Has Shrunk to Accommodate Culvert Shortfall",
+    "detail": "A newly discovered $60,000 gap forced a re-slice, said Finance Director Lucille Tran, who called the reduction 'mathematically sound.'"
+   },
+   {
+    "headline": "Third Session Leaves Parks and Recreation With Slice 'the Width of a Dessert Spoon'",
+    "detail": "Director Wendell Bosley said the department's allocation has shrunk in every session since March."
+   },
+   {
+    "headline": "Animal Control Reports Its Allotment Has Become 'Theoretical'",
+    "detail": "Supervisor Denny Wray said his department now brings its own utensils after last year's fork went missing mid-vote."
+   },
+   {
+    "headline": "Council Schedules Fourth Work-Session, Asks Departments to Bring Napkins",
+    "detail": "Mayor Carol Dunmire again pledged a larger pie next year, a promise made in four consecutive budget cycles.",
+    "conclusion": "City archives show no record of the pie ever actually growing."
+   }
+  ]
+ },
+ {
+  "id": "pw-pork-barrel-express",
+  "category": "politics",
+  "categoryLabel": "Politics",
+  "location": "Pierre, SD",
+  "byline": "Capitol Correspondent Desmond Ruiz",
+  "image": null,
+  "intervalSec": 59,
+  "offsetSec": 15,
+  "stageIndex": 0,
+  "article": {
+   "dek": "A Pierre infrastructure bill meant to repave two miles of county road has left committee as a single funding train carrying a desert lighthouse, a Ferris wheel, and a spoon museum.",
+   "photoCaption": "P24 illustration.",
+   "paragraphs": [
+    "PIERRE, SD—A state infrastructure bill introduced in March to repave 2.3 miles of county road outside Pierre emerged from its fourth and final committee stop this week carrying eleven additional line items, including a desert lighthouse, a 90-foot Ferris wheel, and a museum dedicated entirely to spoons.",
+    "\"It started as a very simple bill,\" said sponsor Sen. Carla Vance, who noted the original text was four paragraphs long and is now 214 pages. \"By the Transportation Committee it had picked up a rest stop. By Appropriations it had a lighthouse. I genuinely don't know when the Ferris wheel got on.\"",
+    "Sen. Dwight Farrow, who voted against the bill in all four committees, said he stopped trying to remove individual items after the third hearing. \"You pull one thing off and by the next stop there are two more,\" he said. \"It's like trying to get gum off a shoe that's also collecting more gum.\"",
+    "Lobbyists for the National Spoon Heritage Foundation, who successfully attached $1.8 million for the museum during a late-night Appropriations session, said the addition 'made sense given the timeline,' though they declined to specify the timeline in question.",
+    "The state Legislative Budget Office confirmed the bill's total cost has risen from an estimated $340,000 to $19.4 million since introduction, and noted the road repaving itself now represents roughly two percent of total spending.",
+    "\"We just wanted our two miles of road fixed,\" said county commissioner Ida Ruskin, who said she has stopped attending the hearings. \"I don't even know if the road's still in there.\"",
+    "As of press time, the bill was headed to a fifth committee, where a Ferris-wheel operators' union had requested a stop of its own."
+   ]
+  },
+  "stages": [
+   {
+    "headline": "Simple Road-Repaving Bill Introduced to Fix 2.3 Miles Outside Pierre",
+    "detail": "Sen. Carla Vance's four-paragraph bill sought funding for a modest stretch of county road, a routine ask, transportation officials said."
+   },
+   {
+    "headline": "Bill Picks Up Funding for Rest Stop and Desert Lighthouse in First Two Committees",
+    "detail": "The lighthouse addition alone added $2.1 million to the bill, which had grown to 60 pages by its second hearing."
+   },
+   {
+    "headline": "Ferris Wheel Attached During Late-Night Appropriations Session",
+    "detail": "Sen. Dwight Farrow said he stopped trying to remove riders after the third hearing, comparing the process to 'gum collecting more gum.'"
+   },
+   {
+    "headline": "Spoon Museum Lobbyists Secure $1.8 Million in Final Committee Stop",
+    "detail": "The National Spoon Heritage Foundation's addition brought the bill to 214 pages and $19.4 million in total cost, budget officials confirmed."
+   },
+   {
+    "headline": "Bill Heads to Fifth Committee as Ferris-Wheel Operators Request Their Own Stop",
+    "detail": "County commissioner Ida Ruskin, the bill's original requester, said she is no longer certain the road repaving is still included.",
+    "conclusion": "The Legislative Budget Office says the road now represents about two percent of the bill's total spending."
+   }
+  ]
+ },
+ {
+  "id": "pw-quorum-hide-seek",
+  "category": "politics",
+  "categoryLabel": "Politics",
+  "location": "Frankfort, KY",
+  "byline": "Legislative Correspondent Renata Voss",
+  "image": null,
+  "intervalSec": 21,
+  "offsetSec": 0,
+  "stageIndex": 0,
+  "article": {
+   "dek": "Minority members of the Kentucky Assembly spent Tuesday hiding behind curtains and inside a supply closet to deny the chamber a quorum, relocating twice as the Sergeant-at-Arms closed in on a suspiciously person-shaped coat rack.",
+   "photoCaption": "P24 illustration.",
+   "paragraphs": [
+    "FRANKFORT, KY—Seven members of the Assembly's minority caucus spent roughly four hours Tuesday evading a mandatory quorum call, relocating twice between the chamber's velvet curtain alcove, a supply closet stocked with legal pads, and a coat rack draped to approximate, from a distance, a standing adult male.",
+    "\"We had the numbers to block the vote, we just didn't have anywhere to be that wasn't the floor,\" said Rep. Odalys Fenn, who spent 40 minutes wedged behind the curtain before relocating to the closet. \"The closet had better legroom, honestly.\"",
+    "Sergeant-at-Arms Milo Prager, tasked with locating the absent members, said he searched the closet twice but was initially convinced by a stack of binders arranged 'in a very deliberate person shape' on the third floor.",
+    "Majority Leader Wendell Krause, who called the quorum vote three separate times, said staff eventually found paper cutouts of two lawmakers propped in their assigned chairs, complete with reading glasses. \"That's a level of commitment I have to respect,\" Krause admitted.",
+    "Fenn's group ultimately relocated a second time after Prager began checking closets systematically, moving instead to a stairwell landing that Fenn described as 'less comfortable but structurally sound.'",
+    "By early evening, the chamber had gone 90 minutes without a working quorum, and House leadership adjourned the session rather than continue the search, according to floor staff.",
+    "As of press time, the coat rack remained in the chamber, and at least one aide had begun referring to it by Fenn's first name."
+   ]
+  },
+  "stages": [
+   {
+    "headline": "Kentucky Assembly Minority Threatens to Deny Quorum Over Contested Vote",
+    "detail": "Seven lawmakers said they would leave the chamber rather than allow a quorum for a floor vote on the bill, setting up a standoff."
+   },
+   {
+    "headline": "Missing Lawmakers Found Hiding Behind Chamber Curtains, Relocate to Supply Closet",
+    "detail": "Sergeant-at-Arms Milo Prager tracked the group to a curtain alcove before they moved to a closet 'with better legroom,' said Rep. Odalys Fenn."
+   },
+   {
+    "headline": "Staff Discover Paper Cutouts Propped in Absent Lawmakers' Chairs, Complete With Reading Glasses",
+    "detail": "Majority Leader Wendell Krause called the props 'a level of commitment I have to respect' after officials confirmed two chairs were occupied by cardboard."
+   },
+   {
+    "headline": "Hiding Caucus Relocates a Second Time to Stairwell Landing as Search Intensifies",
+    "detail": "Prager began checking closets systematically, prompting the group to move to a landing Fenn called 'less comfortable but structurally sound.'"
+   },
+   {
+    "headline": "Chamber Adjourns After 90 Minutes Without Quorum, Coat Rack Left in Place",
+    "detail": "Leadership called off the search rather than continue, floor staff said, ending the session with the disguised coat rack still seated at its desk.",
+    "conclusion": "At least one aide has reportedly begun referring to the coat rack by a lawmaker's first name."
+   }
+  ]
+ },
+ {
+  "id": "pw-cloture-oclock",
+  "category": "politics",
+  "categoryLabel": "Politics",
+  "location": "Dover, DE",
+  "byline": "Statehouse Correspondent Ophelia Grant",
+  "image": null,
+  "intervalSec": 28,
+  "offsetSec": 5,
+  "stageIndex": 0,
+  "article": {
+   "dek": "The Delaware Assembly's ceremonial floor clock has been wound forward by the majority and back by the minority so many times this week that it now simply displays a shrug.",
+   "photoCaption": "P24 illustration.",
+   "paragraphs": [
+    "DOVER, DE—The Assembly's ceremonial floor clock, mounted above the rostrum since 1961 and traditionally wound only on opening day, has been manually adjusted at least nine times this week amid a dispute between the majority and minority over precisely when a procedural cloture vote becomes eligible to proceed.",
+    "\"The rule says cloture can't be called before the hour strikes,\" said Assembly Clerk Fenwick Odom, \"so both sides have taken to just... moving the hour.\"",
+    "Majority Whip Denise Castellano acknowledged winding the clock forward twice Tuesday to 'get us to the vote sooner,' while Minority Leader Arthur Holbein confirmed winding it back three times the same afternoon 'to buy the caucus more time to caucus.'",
+    "By Wednesday, the clock's hour hand had been moved so many times that horologist Ines Prado, called in by legislative staff, said the mechanism was 'not currently telling anyone anything,' and that the hands had settled into a position she described only as 'a shrug.'",
+    "\"I've serviced a lot of antique clocks,\" Prado said. \"This is the first one I've had to advise be taken off the wall for its own protection.\"",
+    "Staff have proposed replacing the mechanism temporarily with a paper clock face that can be moved by hand 'more honestly,' a suggestion both caucuses have so far declined to rule out.",
+    "As of press time, the clock remained mounted above the rostrum, its hands unmoving, its face reportedly still shrugging."
+   ]
+  },
+  "stages": [
+   {
+    "headline": "Delaware Assembly Clock Wound Forward by Majority to Speed Cloture Vote",
+    "detail": "Majority Whip Denise Castellano acknowledged advancing the ceremonial floor clock Tuesday to 'get us to the vote sooner,' per Assembly Clerk Fenwick Odom."
+   },
+   {
+    "headline": "Minority Winds Clock Back Three Times Same Afternoon to 'Buy Time to Caucus'",
+    "detail": "Minority Leader Arthur Holbein confirmed the counter-adjustments, setting off a running dispute over the clock's actual time."
+   },
+   {
+    "headline": "Clock Adjusted Nine Times in One Week, Horologist Called In to Assess Mechanism",
+    "detail": "Ines Prado, a horologist retained by legislative staff, said the clock was 'not currently telling anyone anything' after repeated hand-winding."
+   },
+   {
+    "headline": "Horologist Recommends Clock Be Removed From Wall 'For Its Own Protection'",
+    "detail": "Prado said the hands had settled into a position she could describe only as 'a shrug,' the first such recommendation in her career."
+   },
+   {
+    "headline": "Staff Propose Temporary Paper Clock Face for 'More Honest' Manual Adjustment",
+    "detail": "Neither caucus has ruled out the paper-clock proposal, according to floor staff, as the original mechanism remains stalled.",
+    "conclusion": "The Assembly's opening-day tradition of winding the clock once a year has not been observed since Monday."
+   }
+  ]
+ },
+ {
+  "id": "pw-lobbyist-revolving-door",
+  "category": "politics",
+  "categoryLabel": "Politics",
+  "location": "Jefferson City, MO",
+  "byline": "Government Ethics Correspondent Neil Padgett",
+  "image": null,
+  "intervalSec": 35,
+  "offsetSec": 10,
+  "stageIndex": 0,
+  "article": {
+   "dek": "A Missouri capitol official has spun through the building's revolving door as a state regulator and back out seconds later as a lobbyist so many times this week that security has stopped logging the transitions.",
+   "photoCaption": "P24 illustration.",
+   "paragraphs": [
+    "JEFFERSON CITY, MO—Capitol security confirmed this week that former Utilities Commissioner Grant Pemberton has passed through the building's revolving door in both directions no fewer than six times since Monday, swapping his regulatory badge for a lobbyist credential — and back — each time he completes a rotation.",
+    "\"He goes in as a regulator, comes out three seconds later representing the same utility he used to regulate,\" said security supervisor Dale Ferris, who said the door itself has required servicing twice this week 'from sheer use.'",
+    "Building staff noted that Pemberton's briefcase appears to grow slightly larger with each pass, from a slim folio Monday morning to what one elevator operator described Wednesday as 'genuinely difficult for him to carry.'",
+    "The Capitol Ethics Office confirmed Pemberton's transitions technically comply with the state's one-day 'cooling-off' period, since each rotation through the door is logged, per statute, as a new calendar day.",
+    "\"I'm not doing anything the door isn't already built for,\" Pemberton said, adding that he has begun timing his rotations to avoid a competing lobbyist who 'uses the same door and frankly needs to find his own door.'",
+    "State Rep. Marcus Thibodaux, reached for comment on an unrelated matter, said only, \"Is that door still spinning? I thought we fixed that door.\"",
+    "As of press time, Pemberton had completed a seventh rotation, and his briefcase reportedly required a hand truck."
+   ]
+  },
+  "stages": [
+   {
+    "headline": "Former Utilities Commissioner Registers as Lobbyist One Day After Leaving Post",
+    "detail": "Grant Pemberton filed lobbyist paperwork within 24 hours of leaving the Utilities Commission, capitol records show."
+   },
+   {
+    "headline": "Pemberton Spotted Rotating Through Capitol's Revolving Door as Both Regulator and Lobbyist",
+    "detail": "Security supervisor Dale Ferris said the door required servicing this week 'from sheer use' after six passes in two days."
+   },
+   {
+    "headline": "Ethics Office Confirms Rotations Technically Satisfy One-Day Cooling-Off Rule",
+    "detail": "Each pass through the door is logged as a new calendar day under state statute, the Capitol Ethics Office said."
+   },
+   {
+    "headline": "Pemberton's Briefcase Reportedly Growing Larger With Every Pass",
+    "detail": "An elevator operator described Wednesday's briefcase as 'genuinely difficult for him to carry,' up from a slim folio Monday morning."
+   },
+   {
+    "headline": "Pemberton Completes Seventh Rotation, Briefcase Now Requires Hand Truck",
+    "detail": "Capitol staff say the door has become a minor tourist attraction, with visitors timing their visits to watch a rotation.",
+    "conclusion": "The Ethics Office says it has no rule against watching."
+   }
+  ]
+ },
+ {
+  "id": "pw-filibuster-holloway",
+  "category": "politics",
+  "categoryLabel": "Politics",
+  "location": "Charleston, WV",
+  "byline": "Floor Proceedings Correspondent Hollis Underwood",
+  "image": null,
+  "intervalSec": 42,
+  "offsetSec": 15,
+  "stageIndex": 0,
+  "article": {
+   "dek": "West Virginia Delegate Holloway has held the House floor for over 31 hours by reading from a phone book, a cereal box, and his own bill's furniture-assembly instructions, and shows no sign of stopping.",
+   "photoCaption": "P24 illustration.",
+   "paragraphs": [
+    "CHARLESTON, WV—Delegate Wallace Holloway entered his 31st consecutive hour holding the floor of the House of Delegates on Wednesday, having worked his way through a phone book, a cereal box, and the assembly instructions for a bookshelf before returning, twice, to read aloud from the footnotes of his own bill.",
+    "\"I intend to keep talking for as long as it takes,\" Holloway said, pausing only to accept a cough drop from a page, \"and I have brought reading material for a situation exactly like this.\"",
+    "Majority Leader Denise Castellano — no relation to the Delaware official of the same name, staff confirmed — called the filibuster 'an abuse of the phone book,' though she acknowledged the chamber's rules impose no limit on reading material.",
+    "By hour 19, at least four delegates had fallen visibly asleep at their desks, and a page was dispatched twice for coffee and, once, for a pillow, which the Sergeant-at-Arms declined to authorize.",
+    "The chamber's antique wall clock, which has kept continuous time since 1932, stopped ticking sometime around hour 24, according to maintenance staff, who said the mechanism had 'simply had enough' and would need to be removed for servicing.",
+    "\"There's no rule that says the clock has to keep working during a filibuster,\" said Sergeant-at-Arms Ruth Ostrander, watching the frozen clock face be carried out on a hand truck. \"There's also no rule that says it doesn't.\"",
+    "As of press time, Holloway had moved on to reading the bookshelf assembly instructions a second time, citing 'a step I want to make sure everyone really understood.'"
+   ]
+  },
+  "stages": [
+   {
+    "headline": "Delegate Holloway Begins Filibuster of Assembly Vote With Reading From Phone Book",
+    "detail": "Wallace Holloway took the House floor Monday afternoon and has not yielded it since, beginning with what staff estimate is a 900-page phone book."
+   },
+   {
+    "headline": "Filibuster Reaches Hour 12 as Holloway Moves On to Cereal Box and Furniture Instructions",
+    "detail": "Holloway exhausted the phone book by midday Tuesday and began reading a cereal box ingredient list, followed by bookshelf assembly instructions."
+   },
+   {
+    "headline": "Four Delegates Fall Asleep at Desks as Filibuster Passes Hour 19",
+    "detail": "A page was dispatched for coffee and, once, a pillow, which Sergeant-at-Arms Ruth Ostrander declined to authorize."
+   },
+   {
+    "headline": "Chamber's Antique Wall Clock Stops Ticking Around Hour 24",
+    "detail": "Maintenance staff said the 1932 mechanism had 'simply had enough' and would need to be removed and serviced."
+   },
+   {
+    "headline": "Holloway Passes 31 Hours, Begins Rereading Furniture Instructions 'For a Step Everyone Really Understood'",
+    "detail": "The frozen chamber clock was carried out on a hand truck as the filibuster continued into a second full day, with no vote yet called.",
+    "conclusion": "Holloway's office says he has packed a second phone book in case the first one 'comes up again.'"
+   }
+  ]
  }
 ];

← dff6f9f P24: add Paul Conrad style reference (Masters page + device  ·  back to Crazy News Channel Shadowman  ·  Unify P24 stylesheet: shared external CSS across front page, 6481269 →