Phase 1 implementation: script ingestion + AI extraction pipeline

Complete working pipeline from Fountain script to validated scene JSON:
- Schemas (Pydantic): all 7 layers defined upfront
- Fountain parser + normalizer (Layer 1)
- AI scene extractor with prompt contracts (Layer 2)
- Schema validator + scene-specific semantic validator
- Structured JSON logging per layer/scene execution
- Versioned output writer (never overwrites)
- Retry engine with 4-level failure escalation
- Stop condition evaluator (per-unit + global halts)
- Diff/drift detector for re-run comparison
- CLI entry point with --dry-run, --scene, --test, --force
- 3 test scripts (dialogue-heavy, action-heavy, nonstandard)
- Expected output files for regression testing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 15:49:43 -07:00
co-authored by Claude Opus 4.6
parent 2218e47c1f
commit 87d0af0748
42 changed files with 2418 additions and 0 deletions
+238
View File
@@ -0,0 +1,238 @@
Title: The Extraction
Credit: written by
Author: Test Script
Draft date: 2026-04-06
====
EXT. ROOFTOP - MEXICO CITY - NIGHT
A sprawling cityscape glitters below. JACK REEVES (40s, ex-military, scar across his jaw) crouches behind an air conditioning unit, binoculars pressed to his eyes.
Through the binoculars: a fortified compound three blocks away. Armed guards patrol the perimeter.
Jack touches his earpiece.
JACK
I count twelve on the outside. How many inside?
DISPATCH (V.O.)
Thermal says another eight. Plus the package.
JACK
Twenty hostiles. One extraction target. Lovely.
He slings a tactical bag over his shoulder and moves to the roof's edge.
EXT. ALLEY - MEXICO CITY - NIGHT
Jack drops from a fire escape, landing silently. He presses against the wall as a patrol vehicle passes.
He checks his watch: 11:47 PM.
He moves through the shadows toward the compound.
EXT. COMPOUND PERIMETER - NIGHT
Jack reaches a drainage grate at the compound's east wall. He pulls a small cutting tool from his bag and works the bolts.
A guard's flashlight sweeps nearby. Jack freezes. The light passes.
He removes the grate and slides into the drain.
INT. DRAINAGE TUNNEL - NIGHT
Cramped, wet, dark. Jack crawls through the tunnel using a red-filtered headlamp. Rats scatter ahead of him.
He reaches a junction and checks a hand-drawn map.
JACK
(whispering)
Left fork, thirty meters, then up.
He crawls left.
INT. COMPOUND - BASEMENT - NIGHT
Jack pushes up through a floor grate into a dimly lit basement. Stacked crates everywhere. He draws his suppressed pistol and listens.
Footsteps above. Two sets, moving away.
He crosses the basement to a steel door. Locked. He pulls a bypass kit from his bag and works the lock. It clicks open in twelve seconds.
INT. COMPOUND - GROUND FLOOR CORRIDOR - NIGHT
Jack moves down a concrete corridor, back to the wall. Security camera ahead — he pulls a small device from his pocket and aims it. The camera's red light blinks off.
He rounds a corner and comes face to face with GUARD #1.
A brutal, silent fight. Jack disarms the guard, puts him in a chokehold. The guard goes limp. Jack drags him into a side room.
INT. COMPOUND - STAIRWELL - NIGHT
Jack climbs the stairs, pistol leading. He pauses at the second floor landing — voices in Spanish behind the door.
He waits. The voices move away. He opens the door slowly.
INT. COMPOUND - SECOND FLOOR - NIGHT
A hallway lined with doors. At the far end, GUARD #2 and GUARD #3 stand outside a reinforced door.
Jack checks his options. A ventilation shaft above him. He holsters the pistol, jumps, grabs the edge, and pulls himself up.
INT. VENTILATION SHAFT - NIGHT
Jack crawls above the hallway. Through a vent below, he can see the two guards.
He pulls two smoke canisters from his bag. Drops them through the vent.
The hallway fills with white smoke. Shouts from the guards. Jack drops through the vent, lands between them.
Two precise strikes. Both guards are down in four seconds.
INT. COMPOUND - HOLDING ROOM - NIGHT
Jack kicks through the reinforced door. Inside: a bare room with a single chair. DR. SOFIA NAVARRO (30s, bruised, defiant) is handcuffed to it.
SOFIA
About time.
Jack cuts the cuffs with bolt cutters.
JACK
Can you run?
SOFIA
Can you get us out of here?
An alarm blares. Red lights flood the corridor outside.
JACK
That answers that. Move.
He hands her a spare earpiece and they exit into the hallway.
INT. COMPOUND - SECOND FLOOR - NIGHT
They run. Jack fires twice behind them as guards pour from a doorway. Both shots hit.
JACK
Stairs — go left!
They hit the stairwell. Gunfire chases them, sparking off the metal railing.
EXT. COMPOUND - COURTYARD - NIGHT
They burst through a ground floor exit into an open courtyard. Floodlights snap on. Guards converge from two sides.
Jack pulls a flashbang from his vest. Throws it. BANG — blinding white light.
In the chaos, Jack grabs Sofia and they sprint for the east wall.
JACK
Over the wall. I'll boost you.
He cups his hands. Sofia steps up and scrambles over. Jack follows, bullets pocking the concrete around him.
EXT. STREET - MEXICO CITY - NIGHT
They drop onto a narrow street. A black SUV screeches around the corner — RAMOS (30s, driver, cool under fire) behind the wheel.
RAMOS
Get in!
They dive into the back. Ramos floors it.
INT. SUV - MOVING - NIGHT
Jack reloads. Sofia catches her breath.
SOFIA
Who sent you?
JACK
People who want you alive.
SOFIA
That narrows it down to almost nobody.
Rear window SHATTERS — pursuit vehicle behind them.
RAMOS
Hang on!
Ramos cuts hard left through a market street. Stalls explode as the SUV plows through. The pursuit vehicle follows.
Jack leans out the window and fires at the pursuit vehicle's tires. Third shot connects — the vehicle swerves and crashes into a storefront.
EXT. HIGHWAY - NIGHT
The SUV merges onto a highway. City lights fall behind them.
Silence in the car. Ramos checks the mirror — no pursuit.
RAMOS
Airstrip is forty minutes out.
Jack nods. He looks at Sofia.
JACK
You're going to have to tell them everything. The lab, the formula, all of it.
SOFIA
I know.
JACK
They won't be happy about what you found.
SOFIA
That's why they tried to kill me.
EXT. DESERT AIRSTRIP - NIGHT
A small prop plane waits on a dirt runway, engines running. The SUV skids to a stop beside it.
Jack, Sofia, and Ramos exit. PILOT waves them toward the plane.
JACK
(to Ramos)
Burn the car.
RAMOS
Already planned on it.
Jack and Sofia board the plane.
INT. PROP PLANE - NIGHT
They settle into seats. The plane taxis and lifts off. Through the window, they watch the SUV ignite below — Ramos standing clear, lighter in hand.
SOFIA
Where are we going?
JACK
Somewhere they can't reach you.
SOFIA
Does that place exist?
Jack doesn't answer. The plane climbs into darkness.
EXT. COMPOUND - NIGHT
The compound is in chaos. Guards shout, lights sweep the surrounding blocks. COLONEL VEGA (50s, cold, scarred) stands in the holding room, staring at the empty chair and cut handcuffs.
An AIDE approaches.
AIDE
They escaped east. Vehicle lost them on the highway.
VEGA
Find the pilot's name. Find the airstrip. Find the plane.
He picks up the cut handcuffs.
VEGA
And find whoever sent the soldier.
FADE OUT.
+267
View File
@@ -0,0 +1,267 @@
Title: The Weight of Words
Credit: written by
Author: Test Script
Draft date: 2026-04-06
====
INT. THERAPIST'S OFFICE - DAY
A small, warm room. Bookshelves line the walls. DR. ELENA VOSS (50s, calm, measured) sits across from MARCUS CHEN (30s, restless, avoiding eye contact).
DR. VOSS
How have you been sleeping?
MARCUS
(shifting in his seat)
Fine. Same as always.
DR. VOSS
Marcus, we've talked about this. "Fine" isn't —
MARCUS
It's not a feeling, I know. You've said that.
A long beat. Elena writes something in her notebook.
DR. VOSS
Your sister called me.
MARCUS
She had no right to do that.
DR. VOSS
She's worried about you. She said you haven't left the apartment in two weeks.
MARCUS
That's an exaggeration.
DR. VOSS
Is it?
Marcus finally looks at her. His eyes are red-rimmed.
INT. MARCUS'S APARTMENT - NIGHT
A cluttered studio apartment. Takeout containers on every surface. Marcus sits on the floor against the wall, phone in hand. He stares at a text from LILY CHEN: "Please call me back."
He sets the phone face-down.
INT. COFFEE SHOP - MORNING
Bright, busy. LILY CHEN (late 20s, sharp, put-together but tired) waits at a corner table. Marcus enters, looking like he hasn't slept.
LILY
You look terrible.
MARCUS
Thanks. Love you too.
He sits. An awkward silence.
LILY
Mom's been asking about you.
MARCUS
Tell her I'm fine.
LILY
I'm not going to lie to her, Marcus.
MARCUS
Then don't tell her anything.
LILY
That's the same thing and you know it.
MARCUS
(quiet)
How is she?
LILY
She's scared. Dad's getting worse and you won't even visit.
Marcus stares at his coffee.
INT. HOSPITAL ROOM - AFTERNOON
HENRY CHEN (60s) lies in a hospital bed, frail but alert. Marcus stands in the doorway, unable to step inside.
HENRY
Are you going to stand there all day or come in?
Marcus enters slowly. He sits in the chair beside the bed.
HENRY
Your sister tells me you've been hiding.
MARCUS
I haven't been hiding.
HENRY
(smiling weakly)
You're a terrible liar. Always were.
MARCUS
Dad —
HENRY
I'm dying, Marcus. Not dead yet. You can still talk to me.
Marcus's composure cracks. He puts his head in his hands.
INT. THERAPIST'S OFFICE - DAY
Back with Dr. Voss. Marcus is more open now, leaning forward.
MARCUS
He just said it. Like it was nothing. "I'm dying."
DR. VOSS
How did that make you feel?
MARCUS
Like I've been wasting time. Like every day I spent not going to see him was —
He stops.
DR. VOSS
Was what?
MARCUS
Selfish. It was selfish.
DR. VOSS
You were protecting yourself. That's not the same as selfishness.
MARCUS
Isn't it?
INT. MARCUS'S APARTMENT - NIGHT
Marcus packs a small bag. He picks up a framed photo from the shelf — a young Marcus and Henry at a baseball game, both laughing.
He puts the photo in the bag.
INT. HOSPITAL ROOM - NIGHT
Marcus enters with the bag. Henry is asleep. NURSE PATRICIA (40s, gentle) is checking his IV.
NURSE PATRICIA
He's been asking for you.
MARCUS
I'm here now.
He sits in the chair and takes his father's hand. Henry stirs.
HENRY
(half asleep)
Marcus?
MARCUS
I'm here, Dad. I'm not going anywhere.
Henry squeezes his hand weakly and drifts back to sleep. Marcus settles in, pulling his jacket around himself like a blanket.
INT. HOSPITAL CAFETERIA - MORNING
Marcus and Lily sit across from each other, both holding bad coffee.
LILY
You stayed all night?
MARCUS
Yeah.
LILY
(softening)
Thank you.
MARCUS
Don't thank me. I should have been here weeks ago.
LILY
You're here now. That's what matters.
A beat.
MARCUS
I'm going to take a leave from work. Stay until... however long.
LILY
(eyes welling up)
Okay.
MARCUS
I called Dr. Voss. She's going to do phone sessions.
LILY
That's good. That's really good, Marcus.
They sit in silence, something unspoken settling between them.
INT. HOSPITAL ROOM - AFTERNOON
Marcus reads aloud from a book. Henry listens, eyes closed but smiling.
HENRY
You always did have a good voice for reading.
MARCUS
Mom used to say I should have been an actor.
HENRY
Your mother was right about most things.
MARCUS
She was right about you too.
HENRY
(opening his eyes)
What did she say?
MARCUS
That you were the most stubborn man alive.
HENRY
(laughing, then coughing)
Was. Was the most stubborn.
They share a look — sad, warm, real.
INT. HOSPITAL HALLWAY - EVENING
Marcus leans against the wall outside Henry's room, on the phone.
MARCUS
(into phone)
I know I missed the deadline. I understand... No, I'm not asking for sympathy. I'm asking for two weeks... Thank you. I appreciate it.
He hangs up. Takes a breath. Goes back inside.
INT. THERAPIST'S OFFICE - DAY (PHONE SESSION)
Marcus sits in the hospital cafeteria, phone to his ear.
DR. VOSS (V.O.)
How does it feel to be there?
MARCUS
Terrifying. And also... right. Like I'm finally where I'm supposed to be.
DR. VOSS (V.O.)
That's a significant shift, Marcus.
MARCUS
I know. I just wish it hadn't taken this long.
DR. VOSS (V.O.)
The important thing isn't when you arrived. It's that you stayed.
Marcus looks through the cafeteria window toward the hallway leading to his father's room.
MARCUS
Yeah. I'm staying.
FADE OUT.
@@ -0,0 +1,7 @@
{
"expected_scene_count": 18,
"expected_characters": ["JACK", "SOFIA", "RAMOS", "VEGA"],
"expected_locations": ["ROOFTOP", "ALLEY", "COMPOUND", "DRAINAGE TUNNEL", "STAIRWELL", "SUV", "HIGHWAY", "AIRSTRIP", "PROP PLANE"],
"must_not_contain_characters": [],
"must_not_contain_locations": []
}
@@ -0,0 +1,7 @@
{
"expected_scene_count": 13,
"expected_characters": ["MARCUS", "DR. VOSS", "LILY", "HENRY", "NURSE PATRICIA"],
"expected_locations": ["THERAPIST'S OFFICE", "APARTMENT", "COFFEE SHOP", "HOSPITAL ROOM", "HOSPITAL CAFETERIA", "HOSPITAL HALLWAY"],
"must_not_contain_characters": [],
"must_not_contain_locations": []
}
@@ -0,0 +1,7 @@
{
"expected_scene_count": 11,
"expected_characters": ["NADIA", "DEREK", "TOMMY", "MRS. PETROV", "MOTHER"],
"expected_locations": ["APARTMENT", "GROCERY STORE", "PARKING LOT", "BUS STOP", "BUS", "GAS STATION", "FAMILY HOUSE", "MOTEL ROOM"],
"must_not_contain_characters": [],
"must_not_contain_locations": []
}
+186
View File
@@ -0,0 +1,186 @@
Title: Loose Threads
Author: Test Script
====
apartment - morning
NADIA wakes up on the couch. Still in yesterday's clothes. Her phone buzzes on the coffee table — 14 missed calls.
She ignores it and walks to the kitchen.
NADIA
(to herself)
Not today.
She opens the fridge. Empty except for a bottle of hot sauce.
INT GROCERY STORE DAY
Nadia pushes a cart through fluorescent aisles. She looks half-asleep. Her phone rings again. She silences it.
at the checkout, TOMMY (20s, works here, knows everybody) scans her items.
TOMMY
You look rough.
NADIA
Didn't sleep.
TOMMY
Your brother was in here earlier looking for you.
Nadia freezes.
NADIA
What did you tell him?
TOMMY
Nothing. I don't get involved.
EXT. PARKING LOT - DAY
Nadia loads groceries into her car. A beat-up sedan is parked three spaces away. DEREK (30s, her brother, intense) leans against it.
DEREK
We need to talk.
NADIA
No we don't.
DEREK
It's about the house.
NADIA
I said no.
She gets in her car and drives away. Derek watches her go.
nadia's apartment - night
Nadia sits at her kitchen table eating cereal. A KNOCK at the door. She doesn't move. Another KNOCK.
MRS. PETROV (O.S.)
Nadia, I know you're in there. I can hear the television.
Nadia mutes the TV and stays quiet.
MRS. PETROV (O.S.)
Your rent is late again, dear.
NADIA
(calling out)
I'll have it Friday!
MRS. PETROV (O.S.)
That's what you said last Friday.
Silence. Footsteps recede.
EXT. BUS STOP - EARLY MORNING
Nadia waits at a bus stop, duffel bag at her feet. The sun is barely up. Nobody else around.
Her phone rings. She looks at the screen — "DEREK." She answers.
NADIA
What.
DEREK (V.O.)
The lawyer says we have to both sign or we lose everything.
NADIA
Maybe we should lose everything.
DEREK (V.O.)
You don't mean that.
NADIA
Don't tell me what I mean.
She hangs up. The bus arrives. She boards.
INT - BUS - MORNING
Nadia sits in the back. PASSENGER (elderly woman) across the aisle knits something blue.
PASSENGER
Going far?
NADIA
Hopefully.
The bus pulls away.
EXT GAS STATION - AFTERNOON
The bus has stopped. Passengers mill around. Nadia buys a sandwich from a vending machine and sits on the curb.
Her phone has 3 new texts from Derek. She reads them:
"Please just call me"
"This isn't about us this is about mom's house"
"Nadia"
She types: "I need a few days." Sends it.
.FLASHBACK - INT. FAMILY HOUSE - KITCHEN - YEARS AGO
Young NADIA (12) and young DEREK (16) sit at the kitchen table. Their MOTHER sets plates in front of them.
MOTHER
Eat your dinner before it gets cold.
YOUNG DEREK
Mom, can I go to Tyler's after?
MOTHER
After you clean your room.
YOUNG NADIA
His room is disgusting.
YOUNG DEREK
Shut up.
MOTHER
Both of you. Eat.
A normal evening. Nothing special. Everything special.
INT. MOTEL ROOM - NIGHT
Cheap. Clean enough. Nadia drops her duffel on the bed and lies down without undressing.
She stares at the ceiling for a long time.
Then she calls Derek.
DEREK (V.O.)
Nadia?
NADIA
Tell the lawyer I'll sign.
DEREK (V.O.)
Really?
NADIA
But I want to go through the house first. Before they clear it.
DEREK (V.O.)
...okay. Yeah. We can do that.
NADIA
I'll be back Thursday.
DEREK (V.O.)
Okay. Drive safe. Or... bus safe. Whatever.
NADIA
(almost smiling)
Goodnight, Derek.
She hangs up. Closes her eyes.
> FADE OUT.