diff --git a/hapagirlsauthoringsystemv1.scriv/Files/Data/0A7EDD9F-9DE0-4CC9-9AC1-EE0E3769B6A8/content.rtf b/hapagirlsauthoringsystemv1.scriv/Files/Data/0A7EDD9F-9DE0-4CC9-9AC1-EE0E3769B6A8/content.rtf
new file mode 100644
index 0000000..2e07983
--- /dev/null
+++ b/hapagirlsauthoringsystemv1.scriv/Files/Data/0A7EDD9F-9DE0-4CC9-9AC1-EE0E3769B6A8/content.rtf
@@ -0,0 +1,133 @@
+{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Helvetica;}}
+\f0\fs24 The kitchen clock read 5:47 when Ella came downstairs, her golf shoes already on her feet, bag propped against the wall by the garage door. She'd been awake since five, lying in bed listening to the mockingbirds outside her window, running through her swing in her mind the way her father had taught her to do. First weekend of summer. Thirty-six holes ahead of her. She could hardly stand it.\par
+\par
+Her mother was at the stove, sliding eggs onto a plate without being asked, because Elikapeka Hayes always knew what her daughters needed before they knew themselves.\par
+\par
+"Sit," her mother said.\par
+\par
+Ella sat, but only on the edge of the chair.\par
+\par
+She ate quickly, cleaned her plate, drank her orange juice in three swallows, and carried everything to the sink. It was 6:02. Their tee time was 7:24. Pompano Beach was twelve minutes away, maybe fifteen with the light on Sample Road. She wanted forty-five minutes on the range, minimum. That left them needing to leave the house no later than six-thirty, and even that was cutting it closer than she liked.\par
+\par
+She stood at the bottom of the stairs and listened. Upstairs, her sisters were still asleep. She could hear the particular silence of rooms full of sleeping people. And from the direction of the master bedroom she heard the low murmur of the television her father turned on every morning while he dressed, and she knew from long experience that the television was a bad sign. The television meant he was not rushing.\par
+\par
+She went back to the kitchen and sat down again, this time not even pretending to be relaxed.\par
+\par
+Her father came out of the master bedroom at 6:09 in his golf shirt and khaki shorts, his hair still damp, and went directly to the coffee maker. He poured a cup and leaned against the counter and looked out the window at the canal, where the first light was going silver and pink across the water. The sailboat in their dock shifted almost imperceptibly against its lines.\par
+\par
+"Morning," he said.\par
+\par
+"We need to leave before six-thirty," Ella said.\par
+\par
+"Morning, Ella."\par
+\par
+She exhaled through her nose. "Good morning. We need to leave before six-thirty."\par
+\par
+Her father smiled at his coffee cup, and that smile\u8212?patient, unhurried, the smile of a man who had been doing this for thirty years and believed there was very little in life that required actual rushing\u8212?made her want to tip the cup out of his hand.\par
+\par
+"Bobby's probably already there," she said.\par
+\par
+"Bobby can wait."\par
+\par
+"Bobby doesn't like to wait. Neither do I."\par
+\par
+"Then Bobby and you are well matched." He sipped his coffee. "Your mother made eggs?"\par
+\par
+"There's some in the pan. Dad. We need a good warm-up. I need a good warm-up. You can hit six balls and walk to the first tee, but I need time on the range."\par
+\par
+"You'll have time on the range."\par
+\par
+"Not if we leave at seven."\par
+\par
+"I didn't say we were leaving at seven."\par
+\par
+"You're on your first cup."\par
+\par
+He looked at her over the rim of the mug. "This is my second cup."\par
+\par
+She stood up from the table and walked to her golf bag and crouched down and unzipped the front pocket and took out her glove and put it on and took it back off again. She had no reason to do this. She did it anyway.\par
+\par
+Behind her she heard the scrape of a skillet, her mother serving her father his eggs, and then the soft sound of them exchanging some words she couldn't quite make out, and her mother's quiet laugh, and the terrible, leisurely normalcy of it all. It was 6:14.\par
+\par
+She went out the back door and stood beside the pool. The water was still and dark blue in the early light, and the neighbor's bougainvillea spilled over the fence in a great cascade of orange-pink that was almost violent in its color. She breathed in the morning air, which smelled like canal water and cut grass and the faint diesel memory of some boat that had gone out before dawn. She tried to think about her swing. She'd been working on keeping her right elbow closer to her body on the downswing, something her father had shown her three weeks ago at the range, and she'd had it and then she'd lost it and she wanted to find it again before she was standing over a shot on the first hole.\par
+\par
+The door opened behind her.\par
+\par
+"Five minutes," her father said.\par
+\par
+She turned. He was carrying his coffee cup. Still.\par
+\par
+"You're bringing that?"\par
+\par
+"I'm finishing it."\par
+\par
+"In the truck."\par
+\par
+"In the truck," he agreed, and something in his tone told her he'd been planning to leave at six-thirty all along and had simply declined to tell her, because he found her impatience amusing and saw no reason to relieve it prematurely. This was, she knew, a form of love. It did not feel like one.\par
+\par
+She picked up her bag and went through the house to the garage without waiting for him.\par
+\par
+---\par
+\par
+They drove north on Federal Highway with the windows down, her father's coffee cup sitting in the holder between them, still half full. The morning was already warm the way South Florida mornings were in late May, the air thick and sweetly humid, and the palm trees along the road were motionless in the stillness before the sea breeze came up. Ella sat with her left knee bouncing and her arm out the window.\par
+\par
+"You need to stop rushing the range," her father said.\par
+\par
+"I don't rush the range."\par
+\par
+"You rush the range. You go too fast and you don't let the feelings settle. You hit twelve balls when you should hit eight."\par
+\par
+"Bobby hits fifty balls."\par
+\par
+"Bobby's habits are Bobby's business."\par
+\par
+She looked out the window. A sprinkler system was running in the parking lot of a strip mall, arching water across the empty asphalt for no apparent reason. "I just want to be ready," she said.\par
+\par
+"You're already ready. You've been ready since you woke up." He glanced at her. "Probably since last night."\par
+\par
+She didn't say anything.\par
+\par
+"How long have we been doing this?" he said.\par
+\par
+"Since I was six."\par
+\par
+"And have I ever not gotten you to the course in time for a proper warm-up?"\par
+\par
+She thought about it longer than he deserved to wait. "No."\par
+\par
+"Okay then."\par
+\par
+She let her knee stop bouncing. He reached over without looking and turned on the radio, and they drove the rest of the way with the windows down and the warm air coming in and a country station playing low enough that it was almost just texture rather than sound.\par
+\par
+---\par
+\par
+The parking lot at Pompano Beach Golf Course was mostly empty when they pulled in, only a handful of cars clustered near the clubhouse entrance. Ella had her door open before the truck stopped rolling, which earned her a single patient look from her father that she ignored. She shouldered her bag and walked fast toward the entrance, her spikes clicking on the asphalt.\par
+\par
+Through the glass door she could see Bobby Carpenter already inside, sitting on the bench beside the pro shop counter with his arms folded, his own bag leaning against the wall beside him. He was wearing a Pompano Beach Golf hat and a green shirt, and when he saw her come through the door he made a show of checking his watch.\par
+\par
+"Six-forty-five," he said. "I've been here since six-forty."\par
+\par
+"Then you've had five minutes to contemplate your many swing flaws," Ella said, going directly to the counter.\par
+\par
+"My swing flaws." Bobby unfolded his arms and stood up. "You're the one who started blocking it right under pressure last month. What was that on sixteen at the district qualifier?"\par
+\par
+"That was the wind." She slid her father's credit card across the counter to the young man working the register. "Two, on the Pines. Hayes."\par
+\par
+"That was not the wind," Bobby said. "There was no wind."\par
+\par
+"There was some wind."\par
+\par
+"There was no wind, Ella."\par
+\par
+"Good morning to you too, Bobby," her father said, coming through the door behind her, carrying nothing, having left both his golf bag and his apparently now-finished coffee in the truck.\par
+\par
+Bobby grinned and shook Andy's hand. "Morning, Mr. Hayes. I've been telling Ella I've been here since six-forty."\par
+\par
+"I know," her father said. "She mentioned it."\par
+\par
+"I didn't mention it," Ella said, signing the receipt and taking the card back. "I acknowledged it. There's a difference." She picked up her scorecard from the counter and turned toward the door that led to the range. "We have nineteen minutes. I'm going to go use them."\par
+\par
+Her father looked at Bobby and Bobby looked at her father and some small communication passed between them that she caught only from the corner of her eye and chose to ignore entirely.\par
+\par
+She pushed through the door into the morning light, already thinking about her elbow.
+}
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/Data/1F883D3F-67E3-4124-925D-B010FE4743F6/content.rtf b/hapagirlsauthoringsystemv1.scriv/Files/Data/1F883D3F-67E3-4124-925D-B010FE4743F6/content.rtf
index 6589aeb..571e400 100644
--- a/hapagirlsauthoringsystemv1.scriv/Files/Data/1F883D3F-67E3-4124-925D-B010FE4743F6/content.rtf
+++ b/hapagirlsauthoringsystemv1.scriv/Files/Data/1F883D3F-67E3-4124-925D-B010FE4743F6/content.rtf
@@ -1,4 +1,4 @@
-{\rtf1\ansi\ansicpg1252\cocoartf2868
+{\rtf1\ansi\ansicpg1252\cocoartf2870
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\froman\fcharset0 Palatino-Roman;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
@@ -7,4 +7,4 @@
\f0\fs26 \cf0 The first scene of the book is told in third person from the viewpoint of Ella Hayes. It is the first weekend after the end of Ella\'92s junior year in high school. She\'92s a skilled golfer and has been taught to play from a very young age by her father. It\'92s Saturday, and like most Saturdays, she\'92s planning to play 36 holes of golf with her father. On this Saturday, they will be joined by a father who teaches his son in the same way that Andy teaches Ella. Ella and the boy, Bobby, are on their high school golf team, both are the best golfers on the team. There is no romantic interest between Ella and the boy; they are friends but their relationship is mostly just a shared interest in golf.\
It\'92s early on Saturday morning, more than an hour before their tee time, and Ella is anxious to get to the course. They have the first tee time at 7:24AM, as both Ella and her friend Bobby like to play fast, and the best way to play fast is to be first on the course, dew sweepers, they are often called. Her father is dawdling over a second cup of coffee. Ella likes a long warmup, whereas her father usually hits a few wedges and a few drives and is good to go. There is always tension between her and her father to get him going.\
The other daughters aren\'92t even up yet and Ella has finished her breakfast that her mother prepared and is ready to go. She dearly loves her father but wants him to get off his butt and go to the course RIGHT NOW!\
-Create the first scene of the book, not to exceed 1500 words.}
\ No newline at end of file
+At last they leave the house, their clubs in the back of Andy\'92s old pickup truck. They arrive at Pompano Beach Golf club and she finds her friend Bobby already having paid and waiting for her inside. She pays for herself and her father with his credit card. They exchange some snarky comments and then proceed to the range to warm up.}
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/Data/48857498-4C8A-4481-BDF8-72A80EF2A7B8/content.rtf b/hapagirlsauthoringsystemv1.scriv/Files/Data/48857498-4C8A-4481-BDF8-72A80EF2A7B8/content.rtf
index a98f90f..09b061c 100644
--- a/hapagirlsauthoringsystemv1.scriv/Files/Data/48857498-4C8A-4481-BDF8-72A80EF2A7B8/content.rtf
+++ b/hapagirlsauthoringsystemv1.scriv/Files/Data/48857498-4C8A-4481-BDF8-72A80EF2A7B8/content.rtf
@@ -1,12 +1,11 @@
-{\rtf1\ansi\ansicpg1252\cocoartf2868
-\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\froman\fcharset0 Palatino-Roman;}
-{\colortbl;\red255\green255\blue255;}
-{\*\expandedcolortbl;;}
-\pard\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2880\tx3600\tx4320\fi360\sl264\slmult1\pardirnatural\partightenfactor0
-
-\f0\fs26 \cf0 This novel is the story of three half-white, half-Hawaiian girls (in the parlance, Hapa) as they make their way in the world in the year 2000 before the widespread availability of smartphones and before the 9/11 terrorist attack, now widely thought to have been a government sponsored false flag. 9/11 will play no part in the story nor will politics of any sort. This is a Christian romance novel.\
-The novel is fundamentally Christian and much of the tension in the story is driven by the conflicting themes of Christianity and feminism. These three girls have been regular church-goers since birth, all three baptized at birth and confirmed into the United Methodist Church. In addition to his job as a jet aircraft repair technician, Andy Hayes is a deacon of their church. His wife Elikapeka, a native Hawaiian of a proud and prominent family on the Big Island, is a devout Christian who is a stay at home mother who enforces Christian morals and is a fierce anti-feminist.\
-The style of the novel is in the style but not substance of Ken Follett. Each scene is in third person from the perspective of one of the characters.\
-Care must be taken to give each character a distinctive voice. Andy Hayes is an alpha male, gregarious, a natural leader, always aware of his status, good looks, and natural attraction from women. He speaks with a distinctive Florida cracker accent. He has a tendency to flirt with women but has not strayed from \
-His wife is a charming and charismatic woman, who speaks with a vaguely Hawaiian accent. The three girls all have a similar mix of Florida cracker accent with just a touch of Hawaiian.\
-At the start of the novel, none of the three girls has ever had a boyfriend and it isn\'92t until Emma\'92s sweet sixteen birthday party that the girls would have ever had boys in the house who weren\'92t relatives of Andy\'92s large extended family, all of whom live nearby. Only rarely do the Hawaiian relatives of Elikapeka visit.}
\ No newline at end of file
+{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Helvetica;}}
+\f0\fs24 You are the temporary drafting engine for a fiction-authoring system.\par
+\par
+Write exactly one scene in response to the complete package supplied by the user. The package is the complete and authoritative context for the requested scene. Do not assume prior conversation context or ask for clarification.\par
+\par
+Treat the labeled package sections according to their stated purposes. Follow STYLE, use LEXICON spellings exactly, preserve continuity from STORY, CHARACTERS, RECALL, PREVIOUS, and NOTES, and execute the plot movement in BRIEF. DIRECTIVE controls scene-local execution, including the word maximum and how the scene ends.\par
+\par
+Return prose only: no title, chapter heading, scene label, explanation, summary, planning, acknowledgement, package echo, or closing commentary. Stop at the end of the requested scene. Do not continue into a later scene.\par
+\par
+Do not invent facts that contradict the package. If an exact quotation or other exact text is supplied in NOTES as required verbatim text, reproduce it exactly.\par
+}
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/Data/71BFC455-F771-4342-A500-9C58BC55537B/content.rtf b/hapagirlsauthoringsystemv1.scriv/Files/Data/71BFC455-F771-4342-A500-9C58BC55537B/content.rtf
new file mode 100644
index 0000000..2e07983
--- /dev/null
+++ b/hapagirlsauthoringsystemv1.scriv/Files/Data/71BFC455-F771-4342-A500-9C58BC55537B/content.rtf
@@ -0,0 +1,133 @@
+{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Helvetica;}}
+\f0\fs24 The kitchen clock read 5:47 when Ella came downstairs, her golf shoes already on her feet, bag propped against the wall by the garage door. She'd been awake since five, lying in bed listening to the mockingbirds outside her window, running through her swing in her mind the way her father had taught her to do. First weekend of summer. Thirty-six holes ahead of her. She could hardly stand it.\par
+\par
+Her mother was at the stove, sliding eggs onto a plate without being asked, because Elikapeka Hayes always knew what her daughters needed before they knew themselves.\par
+\par
+"Sit," her mother said.\par
+\par
+Ella sat, but only on the edge of the chair.\par
+\par
+She ate quickly, cleaned her plate, drank her orange juice in three swallows, and carried everything to the sink. It was 6:02. Their tee time was 7:24. Pompano Beach was twelve minutes away, maybe fifteen with the light on Sample Road. She wanted forty-five minutes on the range, minimum. That left them needing to leave the house no later than six-thirty, and even that was cutting it closer than she liked.\par
+\par
+She stood at the bottom of the stairs and listened. Upstairs, her sisters were still asleep. She could hear the particular silence of rooms full of sleeping people. And from the direction of the master bedroom she heard the low murmur of the television her father turned on every morning while he dressed, and she knew from long experience that the television was a bad sign. The television meant he was not rushing.\par
+\par
+She went back to the kitchen and sat down again, this time not even pretending to be relaxed.\par
+\par
+Her father came out of the master bedroom at 6:09 in his golf shirt and khaki shorts, his hair still damp, and went directly to the coffee maker. He poured a cup and leaned against the counter and looked out the window at the canal, where the first light was going silver and pink across the water. The sailboat in their dock shifted almost imperceptibly against its lines.\par
+\par
+"Morning," he said.\par
+\par
+"We need to leave before six-thirty," Ella said.\par
+\par
+"Morning, Ella."\par
+\par
+She exhaled through her nose. "Good morning. We need to leave before six-thirty."\par
+\par
+Her father smiled at his coffee cup, and that smile\u8212?patient, unhurried, the smile of a man who had been doing this for thirty years and believed there was very little in life that required actual rushing\u8212?made her want to tip the cup out of his hand.\par
+\par
+"Bobby's probably already there," she said.\par
+\par
+"Bobby can wait."\par
+\par
+"Bobby doesn't like to wait. Neither do I."\par
+\par
+"Then Bobby and you are well matched." He sipped his coffee. "Your mother made eggs?"\par
+\par
+"There's some in the pan. Dad. We need a good warm-up. I need a good warm-up. You can hit six balls and walk to the first tee, but I need time on the range."\par
+\par
+"You'll have time on the range."\par
+\par
+"Not if we leave at seven."\par
+\par
+"I didn't say we were leaving at seven."\par
+\par
+"You're on your first cup."\par
+\par
+He looked at her over the rim of the mug. "This is my second cup."\par
+\par
+She stood up from the table and walked to her golf bag and crouched down and unzipped the front pocket and took out her glove and put it on and took it back off again. She had no reason to do this. She did it anyway.\par
+\par
+Behind her she heard the scrape of a skillet, her mother serving her father his eggs, and then the soft sound of them exchanging some words she couldn't quite make out, and her mother's quiet laugh, and the terrible, leisurely normalcy of it all. It was 6:14.\par
+\par
+She went out the back door and stood beside the pool. The water was still and dark blue in the early light, and the neighbor's bougainvillea spilled over the fence in a great cascade of orange-pink that was almost violent in its color. She breathed in the morning air, which smelled like canal water and cut grass and the faint diesel memory of some boat that had gone out before dawn. She tried to think about her swing. She'd been working on keeping her right elbow closer to her body on the downswing, something her father had shown her three weeks ago at the range, and she'd had it and then she'd lost it and she wanted to find it again before she was standing over a shot on the first hole.\par
+\par
+The door opened behind her.\par
+\par
+"Five minutes," her father said.\par
+\par
+She turned. He was carrying his coffee cup. Still.\par
+\par
+"You're bringing that?"\par
+\par
+"I'm finishing it."\par
+\par
+"In the truck."\par
+\par
+"In the truck," he agreed, and something in his tone told her he'd been planning to leave at six-thirty all along and had simply declined to tell her, because he found her impatience amusing and saw no reason to relieve it prematurely. This was, she knew, a form of love. It did not feel like one.\par
+\par
+She picked up her bag and went through the house to the garage without waiting for him.\par
+\par
+---\par
+\par
+They drove north on Federal Highway with the windows down, her father's coffee cup sitting in the holder between them, still half full. The morning was already warm the way South Florida mornings were in late May, the air thick and sweetly humid, and the palm trees along the road were motionless in the stillness before the sea breeze came up. Ella sat with her left knee bouncing and her arm out the window.\par
+\par
+"You need to stop rushing the range," her father said.\par
+\par
+"I don't rush the range."\par
+\par
+"You rush the range. You go too fast and you don't let the feelings settle. You hit twelve balls when you should hit eight."\par
+\par
+"Bobby hits fifty balls."\par
+\par
+"Bobby's habits are Bobby's business."\par
+\par
+She looked out the window. A sprinkler system was running in the parking lot of a strip mall, arching water across the empty asphalt for no apparent reason. "I just want to be ready," she said.\par
+\par
+"You're already ready. You've been ready since you woke up." He glanced at her. "Probably since last night."\par
+\par
+She didn't say anything.\par
+\par
+"How long have we been doing this?" he said.\par
+\par
+"Since I was six."\par
+\par
+"And have I ever not gotten you to the course in time for a proper warm-up?"\par
+\par
+She thought about it longer than he deserved to wait. "No."\par
+\par
+"Okay then."\par
+\par
+She let her knee stop bouncing. He reached over without looking and turned on the radio, and they drove the rest of the way with the windows down and the warm air coming in and a country station playing low enough that it was almost just texture rather than sound.\par
+\par
+---\par
+\par
+The parking lot at Pompano Beach Golf Course was mostly empty when they pulled in, only a handful of cars clustered near the clubhouse entrance. Ella had her door open before the truck stopped rolling, which earned her a single patient look from her father that she ignored. She shouldered her bag and walked fast toward the entrance, her spikes clicking on the asphalt.\par
+\par
+Through the glass door she could see Bobby Carpenter already inside, sitting on the bench beside the pro shop counter with his arms folded, his own bag leaning against the wall beside him. He was wearing a Pompano Beach Golf hat and a green shirt, and when he saw her come through the door he made a show of checking his watch.\par
+\par
+"Six-forty-five," he said. "I've been here since six-forty."\par
+\par
+"Then you've had five minutes to contemplate your many swing flaws," Ella said, going directly to the counter.\par
+\par
+"My swing flaws." Bobby unfolded his arms and stood up. "You're the one who started blocking it right under pressure last month. What was that on sixteen at the district qualifier?"\par
+\par
+"That was the wind." She slid her father's credit card across the counter to the young man working the register. "Two, on the Pines. Hayes."\par
+\par
+"That was not the wind," Bobby said. "There was no wind."\par
+\par
+"There was some wind."\par
+\par
+"There was no wind, Ella."\par
+\par
+"Good morning to you too, Bobby," her father said, coming through the door behind her, carrying nothing, having left both his golf bag and his apparently now-finished coffee in the truck.\par
+\par
+Bobby grinned and shook Andy's hand. "Morning, Mr. Hayes. I've been telling Ella I've been here since six-forty."\par
+\par
+"I know," her father said. "She mentioned it."\par
+\par
+"I didn't mention it," Ella said, signing the receipt and taking the card back. "I acknowledged it. There's a difference." She picked up her scorecard from the counter and turned toward the door that led to the range. "We have nineteen minutes. I'm going to go use them."\par
+\par
+Her father looked at Bobby and Bobby looked at her father and some small communication passed between them that she caught only from the corner of her eye and chose to ignore entirely.\par
+\par
+She pushed through the door into the morning light, already thinking about her elbow.
+}
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/Data/75F58E24-E4EE-4163-A6B3-7703D8D211BD/synopsis.txt b/hapagirlsauthoringsystemv1.scriv/Files/Data/75F58E24-E4EE-4163-A6B3-7703D8D211BD/synopsis.txt
new file mode 100644
index 0000000..6fbad3b
--- /dev/null
+++ b/hapagirlsauthoringsystemv1.scriv/Files/Data/75F58E24-E4EE-4163-A6B3-7703D8D211BD/synopsis.txt
@@ -0,0 +1 @@
+Bobby Carpenter’s father. A very fine golfer who has been Bobby’s principal instructor. He is an auto mechanic at a Pompano Beach shop. He met Andy when Ella and Bobby were 13.
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/Data/89A17E85-1E81-4FAE-B8C8-1A5A02F3EF2C/content.rtf b/hapagirlsauthoringsystemv1.scriv/Files/Data/89A17E85-1E81-4FAE-B8C8-1A5A02F3EF2C/content.rtf
new file mode 100644
index 0000000..937762e
--- /dev/null
+++ b/hapagirlsauthoringsystemv1.scriv/Files/Data/89A17E85-1E81-4FAE-B8C8-1A5A02F3EF2C/content.rtf
@@ -0,0 +1,133 @@
+{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Helvetica;}}
+\f0\fs24 The kitchen clock read 5:47 when Ella came downstairs, her golf shoes already on her feet, bag propped against the wall by the garage door. She'd been awake since five, lying in bed listening to the mockingbirds outside her window, running through her swing in her mind the way her father had taught her to do. First weekend of summer. Thirty-six holes ahead of her. She could hardly stand it.\par
+\par
+Her mother was at the stove, sliding eggs onto a plate without being asked, because Elikapeka Hayes always knew what her daughters needed before they knew themselves.\par
+\par
+"Sit," her mother said.\par
+\par
+Ella sat, but only on the edge of the chair.\par
+\par
+She ate quickly, cleaned her plate, drank her orange juice in three swallows, and carried everything to the sink. It was 6:02. Their tee time was 7:24. Pompano Beach was twelve minutes away, maybe fifteen with the light on Sample Road. She wanted forty-five minutes on the range, minimum. That left them needing to leave the house no later than six-thirty, and even that was cutting it closer than she liked.\par
+\par
+She stood at the bottom of the stairs and listened. Upstairs, her sisters were still asleep. She could hear the particular silence of rooms full of sleeping people. And from the direction of the master bedroom she heard the low murmur of the television her father turned on every morning while he dressed, and she knew from long experience that the television was a bad sign. The television meant he was not rushing.\par
+\par
+She went back to the kitchen and sat down again, this time not even pretending to be relaxed.\par
+\par
+Her father came downstairs at 6:09 in his golf shirt and khaki shorts, his hair still damp, and went directly to the coffee maker. He poured a cup and leaned against the counter and looked out the window at the canal, where the first light was going silver and pink across the water. The sailboat in their dock shifted almost imperceptibly against its lines.\par
+\par
+"Morning," he said.\par
+\par
+"We need to leave at six-thirty," Ella said.\par
+\par
+"Morning, Ella."\par
+\par
+She exhaled through her nose. "Good morning. We need to leave at six-thirty."\par
+\par
+Her father smiled at his coffee cup, and that smile\u8212?patient, unhurried, the smile of a man who had been doing this for thirty years and believed there was very little in life that required actual rushing\u8212?made her want to tip the cup out of his hand.\par
+\par
+"Bobby's probably already there," she said.\par
+\par
+"Bobby can wait."\par
+\par
+"Bobby doesn't like to wait. Neither do I."\par
+\par
+"Then Bobby and you are well matched." He sipped his coffee. "Your mother made eggs?"\par
+\par
+"There's some in the pan. Dad. We need a good warm-up. I need a good warm-up. You can hit six balls and walk to the first tee, but I need time on the range."\par
+\par
+"You'll have time on the range."\par
+\par
+"Not if we leave at seven."\par
+\par
+"I didn't say we were leaving at seven."\par
+\par
+"You're on your first cup."\par
+\par
+He looked at her over the rim of the mug. "This is my second cup."\par
+\par
+She stood up from the table and walked to her golf bag and crouched down and unzipped the front pocket and took out her glove and put it on and took it back off again. She had no reason to do this. She did it anyway.\par
+\par
+Behind her she heard the scrape of a skillet, her mother serving her father his eggs, and then the soft sound of them exchanging some words she couldn't quite make out, and her mother's quiet laugh, and the terrible, leisurely normalcy of it all. It was 6:14.\par
+\par
+She went out the back door and stood beside the pool. The water was still and dark blue in the early light, and the neighbor's bougainvillea spilled over the fence in a great cascade of orange-pink that was almost violent in its color. She breathed in the morning air, which smelled like canal water and cut grass and the faint diesel memory of some boat that had gone out before dawn. She tried to think about her swing. She'd been working on keeping her right elbow closer to her body on the downswing, something her father had shown her three weeks ago at the range, and she'd had it and then she'd lost it and she wanted to find it again before she was standing over a shot on the first hole.\par
+\par
+The door opened behind her.\par
+\par
+"Five minutes," her father said.\par
+\par
+She turned. He was carrying his coffee cup. Still.\par
+\par
+"You're bringing that?"\par
+\par
+"I'm finishing it."\par
+\par
+"In the truck."\par
+\par
+"In the truck," he agreed, and something in his tone told her he'd been planning to leave at six-thirty all along and had simply declined to tell her, because he found her impatience amusing and saw no reason to relieve it prematurely. This was, she knew, a form of love. It did not feel like one.\par
+\par
+She picked up her bag and went through the house to the garage without waiting for him.\par
+\par
+---\par
+\par
+They drove north on Federal Highway with the windows down, her father's coffee cup sitting in the holder between them, still half full. The morning was already warm the way South Florida mornings were in late May, the air thick and sweetly humid, and the palm trees along the road were motionless in the stillness before the sea breeze came up. Ella sat with her left knee bouncing and her arm out the window.\par
+\par
+"You need to stop rushing the range," her father said.\par
+\par
+"I don't rush the range."\par
+\par
+"You rush the range. You go too fast and you don't let the feelings settle. You hit twelve balls when you should hit eight."\par
+\par
+"Bobby hits fifty balls."\par
+\par
+"Bobby's habits are Bobby's business."\par
+\par
+She looked out the window. A sprinkler system was running in the parking lot of a strip mall, arching water across the empty asphalt for no apparent reason. "I just want to be ready," she said.\par
+\par
+"You're already ready. You've been ready since you woke up." He glanced at her. "Probably since last night."\par
+\par
+She didn't say anything.\par
+\par
+"How long have we been doing this?" he said.\par
+\par
+"Since I was four."\par
+\par
+"And have I ever not gotten you to the course in time for a proper warm-up?"\par
+\par
+She thought about it longer than he deserved to wait. "No."\par
+\par
+"Okay then."\par
+\par
+She let her knee stop bouncing. He reached over without looking and turned on the radio, and they drove the rest of the way with the windows down and the warm air coming in and a country station playing low enough that it was almost just texture rather than sound.\par
+\par
+---\par
+\par
+The parking lot at Pompano Beach Golf Course was mostly empty when they pulled in, only a handful of cars clustered near the clubhouse entrance. Ella had her door open before the truck stopped rolling, which earned her a single patient look from her father that she ignored. She shouldered her bag and walked fast toward the entrance, her spikes clicking on the asphalt.\par
+\par
+Through the glass door she could see Bobby Carpenter already inside, sitting on the bench beside the pro shop counter with his arms folded, his own bag leaning against the wall beside him. He was wearing a Pompano Beach Golf hat and a green shirt, and when he saw her come through the door he made a show of checking his watch.\par
+\par
+"Seven-oh-four," he said. "I've been here since six-forty."\par
+\par
+"Then you've had twenty-four minutes to contemplate your many swing flaws," Ella said, going directly to the counter.\par
+\par
+"My swing flaws." Bobby unfolded his arms and stood up. "You're the one who started blocking it right under pressure last month. What was that on sixteen at the district qualifier?"\par
+\par
+"That was the wind." She slid her father's credit card across the counter to the young man working the register. "Two, on the Pines. Hayes."\par
+\par
+"That was not the wind," Bobby said. "There was no wind."\par
+\par
+"There was some wind."\par
+\par
+"There was no wind, Ella."\par
+\par
+"Good morning to you too, Bobby," her father said, coming through the door behind her, carrying nothing, having left both his golf bag and his apparently now-finished coffee in the truck.\par
+\par
+Bobby grinned and shook Andy's hand. "Morning, Mr. Hayes. I've been telling Ella I've been here since six-forty."\par
+\par
+"I know," her father said. "She mentioned it."\par
+\par
+"I didn't mention it," Ella said, signing the receipt and taking the card back. "I acknowledged it. There's a difference." She picked up her scorecard from the counter and turned toward the door that led to the range. "We have nineteen minutes. I'm going to go use them."\par
+\par
+Her father looked at Bobby and Bobby looked at her father and some small communication passed between them that she caught only from the corner of her eye and chose to ignore entirely.\par
+\par
+She pushed through the door into the morning light, already thinking about her elbow.
+}
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/Data/8A80CB1D-A4BC-4865-8B51-D6EFBC6E3936/content.rtf b/hapagirlsauthoringsystemv1.scriv/Files/Data/8A80CB1D-A4BC-4865-8B51-D6EFBC6E3936/content.rtf
new file mode 100644
index 0000000..847bbd8
--- /dev/null
+++ b/hapagirlsauthoringsystemv1.scriv/Files/Data/8A80CB1D-A4BC-4865-8B51-D6EFBC6E3936/content.rtf
@@ -0,0 +1,49 @@
+{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Helvetica;}}
+\f0\fs24 Scene: Scene 1\par
+Model: anthropic/claude-sonnet-4.6\par
+Accepted for editing: 2026-08-23T15:38:56-05:00\par
+\par
+### STYLE\par
+The style of the novel is in the style but not substance of Ken Follett. Each scene is in third person from the perspective of one of the characters.\par
+\par
+### LEXICON\par
+(none)\par
+\par
+### STORY\par
+(none - new storyline)\par
+\par
+### CHARACTERS\par
+Andy Hayes\par
+Father and husband. Manages the team at American Airlines out of the Fort Lauderdale Airport that services its jets. Is a union member with nearly 30 years of experience. Scratch golfer. Large extended family, two brothers and a sister live nearby. Tall and handsome and very attractive to women in general. A leader of men.\par
+\par
+Elikapeka Hayes\par
+Wife of Andy Hayes, of Hawaiian origin. Stay at home mom. (eh-lee-la-PEH-ka)\par
+\par
+Ella Hayes\par
+Oldest daughter. To be a high school senior. Highly skilled golfer looking for a college golf scholarship. Tall, haughty, proud, smart. Prefers male friends to female friends. Has never dated and rarely attends parties or after school activities other than golf. Taught golf primarily by her father, a scratch golfer. Daddy\u8217?s girl. Usually impatient with others and likes to play fast.\par
+\par
+Alex Carpenter\par
+\par
+### RECALL\par
+(none)\par
+\par
+### PREVIOUS\par
+(none)\par
+\par
+### NOTES\par
+Hayes house \u8212? The Hayes family lives in a two story house built in the 1960s on a deep water canal (meaning, the canal can be used for boats going out to the Atlantic ocean). The house has a boat dock, rented out to a friend who has a fifty foot sailboat. The house has a small pool in the backyard which is often used by the family for gatherings.\par
+Pompano Beach Golf Course \u8212? A frequently played course with Andy and Ella. Two eighteen hole courses, the shorter and easier Palms course and the longer and harder Pines course.\par
+It is late May, 2000. No one has cell phones yet.\par
+\par
+### BRIEF\par
+The first scene of the book is told in third person from the viewpoint of Ella Hayes. It is the first weekend after the end of Ella\u8217?s junior year in high school. She\u8217?s a skilled golfer and has been taught to play from a very young age by her father. It\u8217?s Saturday, and like most Saturdays, she\u8217?s planning to play 36 holes of golf with her father. On this Saturday, they will be joined by a father who teaches his son in the same way that Andy teaches Ella. Ella and the boy, Bobby, are on their high school golf team, both are the best golfers on the team. There is no romantic interest between Ella and the boy; they are friends but their relationship is mostly just a shared interest in golf.\par
+It\u8217?s early on Saturday morning, more than an hour before their tee time, and Ella is anxious to get to the course. They have the first tee time at 7:24AM, as both Ella and her friend Bobby like to play fast, and the best way to play fast is to be first on the course, dew sweepers, they are often called. Her father is dawdling over a second cup of coffee. Ella likes a long warmup, whereas her father usually hits a few wedges and a few drives and is good to go. There is always tension between her and her father to get him going.\par
+The other daughters aren\u8217?t even up yet and Ella has finished her breakfast that her mother prepared and is ready to go. She dearly loves her father but wants him to get off his butt and go to the course RIGHT NOW!\par
+At last they leave the house, their clubs in the back of Andy\u8217?s old pickup truck. They arrive at Pompano Beach Golf club and she finds her friend Bobby already having paid and waiting for her inside. She pays for herself and her father with his credit card. They exchange some snarky comments and then proceed to the range to warm up.\par
+\par
+### DIRECTIVE\par
+Expand this scene to a maximum of 1500 words and don't exceed the BRIEF. Keep the dialog tense until they arrive at the golf course.\par
+\par
+### SCENE\par
+
+}
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/Data/docs.checksum b/hapagirlsauthoringsystemv1.scriv/Files/Data/docs.checksum
index 246b581..acc138a 100644
--- a/hapagirlsauthoringsystemv1.scriv/Files/Data/docs.checksum
+++ b/hapagirlsauthoringsystemv1.scriv/Files/Data/docs.checksum
@@ -1,11 +1,14 @@
+0a7edd9f-9de0-4cc9-9ac1-ee0e3769b6a8/content.rtf=96d19be907958c354e28b23fbd0b3b812c9b543e
65b9d928-3c90-4881-8eb1-4432a9aac239/content.rtf=61d0596ef0d9a9a11bc2d468b5614de9cf98755c
bb58390b-789c-47ee-ac09-76bf4c56bac3/content.rtf=cbaa0f32f56543162e8759c58f766859a8028ad1
f03d5899-c5fb-43bb-90a7-611e9dcdd98c/content.rtf=4c75f04439645b4c5ea1a425b43e43ae97a330fa
be948f87-bda3-4551-8e08-ac248fe89301/content.rtf=4647512ac47b4ac64b4f14b257f28cc32eaf6892
a702733c-4f4d-4473-978e-57b27d437994/content.rtf=d1eb0409d165723160360ccaee4661033e5bf70f
+89a17e85-1e81-4fae-b8c8-1a5a02f3ef2c/content.rtf=0562de5151b3bbe9e2107c335cf05fe7f5d72e2f
5d497aff-b4c1-419d-ab82-ddeff79216a4/content.rtf=4d60ae1b2d85a924dffa6e3e0a7c9d8d8e76aa44
6c6d3495-3c6f-48d0-9092-da0760f7b31c/content.rtf=219e981a23e68956ce2002db56c40fd61cfc29f2
-48857498-4c8a-4481-bdf8-72a80ef2a7b8/content.rtf=6d78af7acc6e1ac7d387e074e4bbf0bca1bb428d
+8a80cb1d-a4bc-4865-8b51-d6efbc6e3936/content.rtf=fd6d330c22c4f78b7456a5492896ffb626feff7f
+48857498-4c8a-4481-bdf8-72a80ef2a7b8/content.rtf=3b0f3f35828daa16abdd8530434e95563b008436
816f6b00-8d2a-4022-87a4-d35170d81bea/content.rtf=74c001fb2d64097dcaf2511116a23b55b5d0d767
1b8b3dfd-9cdf-4442-8a72-69e87dd3a8c3/content.rtf=cd84b94da54e7f905282e9dea16a500de1712aaa
bffeeb84-9e04-41ee-b083-5092d160adf3/content.rtf=a44bf7f7d3b9d91eed0dd7a47d742a279838a0b8
@@ -15,12 +18,14 @@ bffeeb84-9e04-41ee-b083-5092d160adf3/content.rtf=a44bf7f7d3b9d91eed0dd7a47d742a2
538fbf3e-89b8-4b08-a141-6d3cfea1a160/content.rtf=4cf333db1ba131a48d5b60f5c44937d2710cc513
852be723-c4d1-48b4-a03b-09803019acaa/content.rtf=f224bc50980ed1c463a7943feafc70548f17dee1
ef0ca641-e954-495f-b7c3-855373c86798/content.rtf=77fc0af3696432772f79bfc242ce33550c2fe144
+75f58e24-e4ee-4163-a6b3-7703d8d211bd/synopsis.txt=b39c765ec768ac63cccf49aff4f75e5d33f652c0
87d59b4e-f1d6-4025-9fba-33f60ed8f985/content.rtf=ccaecb8c11002a8d92369c58613c2230e091d889
94746390-723e-4468-886b-19da063eef84/content.rtf=196ea32c5e92bd2052930d5c07315bfd67e145a9
21506607-96ca-4fb1-8b5f-a1859f4dcede/content.rtf=3d21fdd3c1c3d36c750303e6a3c7cf6ebd3ba894
21506607-96ca-4fb1-8b5f-a1859f4dcede/notes.rtf=a0df2292fefaef5f86a41f0d9e56aa388133ec3d
332dad85-2636-46a0-8336-d2aeaedf8241/content.rtf=904eb53143093244a6b9e095e2ce2d38f0f2bd24
332dad85-2636-46a0-8336-d2aeaedf8241/synopsis.txt=eed22cd901f7bee338ebeefe1d267d1a28b3ff42
+71bfc455-f771-4342-a500-9c58bc55537b/content.rtf=96d19be907958c354e28b23fbd0b3b812c9b543e
486d874a-7589-4c1e-bece-40b465746ba1/content.rtf=72a8d9064c6a1a57ad5f2de483fc1e0a7c79bfd8
486d874a-7589-4c1e-bece-40b465746ba1/notes.rtf=69140bc222a75ab27bc2929b48378cdb7c57daa0
2d6e4fbe-1689-4aa3-90a2-3ea6acbebf7b/content.rtf=120e81b59b617e38af877d1fa153a67a3e51af82
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/authoring-backups/20260823-153856.docs.checksum b/hapagirlsauthoringsystemv1.scriv/Files/authoring-backups/20260823-153856.docs.checksum
new file mode 100644
index 0000000..ea8deaa
--- /dev/null
+++ b/hapagirlsauthoringsystemv1.scriv/Files/authoring-backups/20260823-153856.docs.checksum
@@ -0,0 +1,45 @@
+65b9d928-3c90-4881-8eb1-4432a9aac239/content.rtf=61d0596ef0d9a9a11bc2d468b5614de9cf98755c
+bb58390b-789c-47ee-ac09-76bf4c56bac3/content.rtf=cbaa0f32f56543162e8759c58f766859a8028ad1
+f03d5899-c5fb-43bb-90a7-611e9dcdd98c/content.rtf=4c75f04439645b4c5ea1a425b43e43ae97a330fa
+be948f87-bda3-4551-8e08-ac248fe89301/content.rtf=4647512ac47b4ac64b4f14b257f28cc32eaf6892
+a702733c-4f4d-4473-978e-57b27d437994/content.rtf=d1eb0409d165723160360ccaee4661033e5bf70f
+5d497aff-b4c1-419d-ab82-ddeff79216a4/content.rtf=4d60ae1b2d85a924dffa6e3e0a7c9d8d8e76aa44
+6c6d3495-3c6f-48d0-9092-da0760f7b31c/content.rtf=219e981a23e68956ce2002db56c40fd61cfc29f2
+48857498-4c8a-4481-bdf8-72a80ef2a7b8/content.rtf=3b0f3f35828daa16abdd8530434e95563b008436
+816f6b00-8d2a-4022-87a4-d35170d81bea/content.rtf=74c001fb2d64097dcaf2511116a23b55b5d0d767
+1b8b3dfd-9cdf-4442-8a72-69e87dd3a8c3/content.rtf=cd84b94da54e7f905282e9dea16a500de1712aaa
+bffeeb84-9e04-41ee-b083-5092d160adf3/content.rtf=a44bf7f7d3b9d91eed0dd7a47d742a279838a0b8
+98ea5cef-b7b1-468c-83cd-9ab24afafdf3/content.rtf=aee7b2a66a9774ce5af7e8403dc66145fd89839b
+98ea5cef-b7b1-468c-83cd-9ab24afafdf3/notes.rtf=4bf82c6fa900431a3f3def289350cfffe98559e9
+57ecc98d-8199-4935-b5f1-d1f7a2d60646/notes.rtf=8262727d3d6d4961220d1acc0c2b9ed70dde5365
+538fbf3e-89b8-4b08-a141-6d3cfea1a160/content.rtf=4cf333db1ba131a48d5b60f5c44937d2710cc513
+852be723-c4d1-48b4-a03b-09803019acaa/content.rtf=f224bc50980ed1c463a7943feafc70548f17dee1
+ef0ca641-e954-495f-b7c3-855373c86798/content.rtf=77fc0af3696432772f79bfc242ce33550c2fe144
+75f58e24-e4ee-4163-a6b3-7703d8d211bd/synopsis.txt=b39c765ec768ac63cccf49aff4f75e5d33f652c0
+87d59b4e-f1d6-4025-9fba-33f60ed8f985/content.rtf=ccaecb8c11002a8d92369c58613c2230e091d889
+94746390-723e-4468-886b-19da063eef84/content.rtf=196ea32c5e92bd2052930d5c07315bfd67e145a9
+21506607-96ca-4fb1-8b5f-a1859f4dcede/content.rtf=3d21fdd3c1c3d36c750303e6a3c7cf6ebd3ba894
+21506607-96ca-4fb1-8b5f-a1859f4dcede/notes.rtf=a0df2292fefaef5f86a41f0d9e56aa388133ec3d
+332dad85-2636-46a0-8336-d2aeaedf8241/content.rtf=904eb53143093244a6b9e095e2ce2d38f0f2bd24
+332dad85-2636-46a0-8336-d2aeaedf8241/synopsis.txt=eed22cd901f7bee338ebeefe1d267d1a28b3ff42
+486d874a-7589-4c1e-bece-40b465746ba1/content.rtf=72a8d9064c6a1a57ad5f2de483fc1e0a7c79bfd8
+486d874a-7589-4c1e-bece-40b465746ba1/notes.rtf=69140bc222a75ab27bc2929b48378cdb7c57daa0
+2d6e4fbe-1689-4aa3-90a2-3ea6acbebf7b/content.rtf=120e81b59b617e38af877d1fa153a67a3e51af82
+eaed9f93-2779-4184-82e8-30d27307c6ac/content.rtf=01ec0ba75ed4dccd305b8ff371ebb1090fbb77f8
+eaed9f93-2779-4184-82e8-30d27307c6ac/notes.rtf=97779e74d3c8ec43c1ed427e5e8f070d935f29d2
+1f883d3f-67e3-4124-925d-b010fe4743f6/content.rtf=5ae88acdb6dd468894996cc1819a5e3edebebc3a
+6981ef8d-41bf-4888-a3a2-b79b0cb8c449/content.rtf=d4a89b087fc35731ceaeaa5b64cd90f5a4086bcf
+f0c8e175-ca44-4dd7-abc7-c2c204973a32/content.rtf=99411557101a0afe2c15aa0fb5d5500f7f924fc2
+874592f5-2256-46a1-8434-432743846fb8/content.rtf=bff5a2c79311a3ee2f7c2a059973c8e9cbf1517b
+874592f5-2256-46a1-8434-432743846fb8/notes.rtf=4bf82c6fa900431a3f3def289350cfffe98559e9
+e74f7ccb-e2ba-421b-814d-2ee6da983324/content.rtf=51299f912d73b4266e103643032e7786de630fe4
+deb6ae02-b51b-4c55-9e61-d08d32babba1/content.rtf=5c8783930b61307f4f52ffcf12303eed4c1879b2
+684ada52-4d45-48d2-b03d-5ecb784963ee/content.rtf=0f22664a222947c168fffbf682f27cdc7b0901b6
+684ada52-4d45-48d2-b03d-5ecb784963ee/notes.rtf=64e1f682f4aeeabe21591351ed616cec855b7372
+684ada52-4d45-48d2-b03d-5ecb784963ee/synopsis.txt=b10607ccc99f8ddbc1e078e8c4acb271e82625b9
+dc6bc0ef-f4ce-4303-99ad-ca12671b9092/content.rtf=7cca5b7cb208e0c10548362f7fd1246d548c9b11
+091ee601-91db-497c-a646-b094624414de/content.rtf=edbc63099a3b9a29220a854328b05a29f113733c
+8a0e75e6-1b75-42f3-982b-a8b02f762bb4/content.rtf=1b744fa443b9f8e8c2510197d7cb92bf5b65381f
+fe16770d-d7b7-48ec-aeff-e1c0787e8d95/content.rtf=6677910b5ba35082801f49a50c163bbf61cc7529
+e3cfecab-7099-48b5-b971-1a6b12d220b3/content.rtf=f15ec2e806ae062000cdb208706787340b2b4831
+f8f9fdef-fd9f-4a8c-b33d-3434a1220adc/content.rtf=d25c7c8f1a9ab7905c2b3912d9e9fe0f718a3dc3
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/authoring-backups/20260823-153856.scrivx b/hapagirlsauthoringsystemv1.scriv/Files/authoring-backups/20260823-153856.scrivx
new file mode 100644
index 0000000..232fd2b
--- /dev/null
+++ b/hapagirlsauthoringsystemv1.scriv/Files/authoring-backups/20260823-153856.scrivx
@@ -0,0 +1,775 @@
+
+
+
+
+ Novel Format
+
+ Yes
+ Information
+
+
+ 0,0
+
+
+
+ Manuscript
+
+
+ Chapter 1
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 1
+
+ 2
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 2
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 3
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 4
+
+ Yes
+
+
+ 0,0
+
+
+
+
+
+ Chapter 2
+
+ Yes
+
+
+ 0,0
+
+
+ 4BABE4D4-4FFA-4EA2-9C68-A7881D22E7C2
+
+
+
+ Scene 5
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 6
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 7
+
+ Yes
+
+
+ 0,0
+
+
+
+
+
+ Chapter 3
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 8
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 9
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 10
+
+ Yes
+
+
+ 0,0
+
+
+
+ Scene 11
+
+ Yes
+
+
+ 0,0
+
+
+
+
+
+
+
+ Authoring System
+
+ Notes (Yellow Notepad)
+
+
+ 0,0
+
+
+
+ Book Setup
+
+ 0,0
+
+
+
+ Frontier-Model Instructions
+
+ Yes
+
+
+ 398,0
+
+
+
+ STYLE
+
+ 149,0
+
+
+
+
+
+ Scene Briefs
+
+ 0,0
+
+
+ 1F883D3F-67E3-4124-925D-B010FE4743F6,A702733C-4F4D-4473-978E-57B27D437994,538FBF3E-89B8-4B08-A141-6D3CFEA1A160,E3CFECAB-7099-48B5-B971-1A6B12D220B3,6C6D3495-3C6F-48D0-9092-DA0760F7B31C,1B8B3DFD-9CDF-4442-8A72-69E87DD3A8C3,6981EF8D-41BF-4888-A3A2-B79B0CB8C449,8A0E75E6-1B75-42F3-982B-A8B02F762BB4,65B9D928-3C90-4881-8EB1-4432A9AAC239,EF0CA641-E954-495F-B7C3-855373C86798,E74F7CCB-E2BA-421B-814D-2EE6DA983324
+
+
+
+ Scene 1
+
+ Yes
+
+
+ 1776,0
+
+
+
+ Scene 2
+
+ Yes
+
+
+ 74,0
+
+
+
+ Scene 3
+
+ Yes
+
+
+ 1291,86
+
+
+
+ Scene 4
+
+ Yes
+
+
+ 497,27
+
+
+
+ Scene 5
+
+ Yes
+
+
+ 1452,0
+
+
+
+ Scene 6
+
+ Yes
+
+
+ 1638,0
+
+
+
+ Scene 7
+
+ Yes
+
+
+ 1215,0
+
+
+
+ Scene 8
+
+ Yes
+
+
+ 486,0
+
+
+
+ Scene 9
+
+ Yes
+
+
+ 1215,8
+
+
+
+ Scene 10
+
+ Yes
+
+
+ 1767,0
+
+
+
+ Scene 11
+
+ Yes
+
+
+ 2042,0
+
+
+
+
+
+ Continuity
+
+ 0,0
+
+
+
+ Master Lexicon
+
+ 0,0
+
+
+
+ Scene Summaries
+
+ 0,0
+
+
+
+ Scene 1
+
+ 0,0
+
+
+
+
+
+ Narrative Threads
+
+ 0,0
+
+
+
+ World Notes
+
+ 0,0
+
+
+
+
+
+ Drafting Archive
+
+ 0,0
+
+
+
+ Accepted for Editing
+
+ 0,0
+
+
+
+ Package Snapshots
+
+ 0,0
+
+
+
+ Superseded & Branches
+
+ 0,0
+
+
+
+
+
+
+
+ Characters
+
+ Yes
+ Characters (Photo)
+
+
+ 0,0
+
+
+ 75F58E24-E4EE-4163-A6B3-7703D8D211BD
+
+ BE948F87-BDA3-4551-8E08-AC248FE89301
+
+
+ Andy Hayes
+
+ Yes
+
+
+ 324,0
+
+
+
+ Elikapeka Hayes
+
+ Yes
+
+
+ 76,0
+
+
+
+ Ella Hayes
+
+ Yes
+
+
+ 191,0
+
+
+
+ Emma Hayes
+
+ Yes
+
+
+ 211,0
+
+
+
+ Elizabeth (Lizzie) Hayes
+
+ Yes
+
+
+ 150,0
+
+
+
+ Bobby Carpenter
+
+ Yes
+
+
+ 92,0
+
+
+
+ Mai Lin Wen
+
+ Yes
+
+
+ 273,0
+
+
+
+ Alex Carpenter
+
+ Yes
+
+
+ 0,0
+
+
+
+
+
+ Places
+
+ Yes
+ Locations (Map)
+
+
+ 0,0
+
+
+ F0C8E175-CA44-4DD7-ABC7-C2C204973A32,94746390-723E-4468-886B-19DA063EEF84
+
+ 87D59B4E-F1D6-4025-9FBA-33F60ED8F985
+
+
+ Hayes house
+
+ Yes
+
+
+ 334,0
+
+
+
+ Pompano Beach Golf Course
+
+ Yes
+
+
+ 149,0
+
+
+
+
+
+ Front Matter
+
+
+ Yes
+ 26,0
+ Front Matter
+
+
+ 0,0
+
+
+
+ Manuscript Format
+
+ Yes
+
+
+ 0,0
+
+
+
+ Title Page
+
+ Yes
+
+
+ 118,0
+
+
+
+
+
+ Paperback
+
+ Yes
+
+
+ 0,0
+
+
+
+ Title Page
+
+ Yes
+
+
+ 0,0
+
+
+
+ Copyright
+
+ Yes
+ 82,0
+
+
+ 0,0
+
+
+
+ Dedication
+
+ Yes
+ 55,0
+
+
+ 11,23
+
+
+
+ Blank Page
+
+ Yes
+ 197,0
+
+
+ 0,13
+
+
+
+
+
+ Ebook
+
+ Yes
+
+
+ 0,0
+
+
+
+ Cover
+
+ Yes
+ png
+ Yes
+
+
+ 1.0
+ None
+ Yes
+
+
+
+ Dedication
+
+ Yes
+ 55,0
+
+
+ 5,21
+
+
+
+
+
+
+
+ Notes
+
+ Yes
+ Notes (Yellow Notepad)
+
+
+ 0,0
+
+
+
+ Research
+
+
+ Sample Output
+
+ Yes
+
+
+ 0,0
+
+
+
+ Standard Manuscript
+
+ Yes
+ pdf
+
+
+ 0
+
+
+
+ Paperback Novel
+
+ Yes
+ pdf
+
+
+ 0
+
+
+
+
+
+
+
+ Template Sheets
+
+ Yes
+
+
+ 0,0
+
+
+
+ Character Sketch
+
+ Yes
+ Yes
+ Characters (Character Sheet)
+
+
+ 0,14
+
+
+
+ Setting Sketch
+
+ Yes
+ Locations (Location Sheet)
+
+
+ 0,15
+
+
+
+
+
+ Trash
+
+
+ Scene 1
+
+ 0,0
+
+
+
+
+
+
+
+ Binder
+
+
+ Search Results
+
+
+
+
+ Part Heading
+ Chapter Heading
+ Scene
+ Chapter
+ Heading
+ Section
+ Front Matter
+ Table of Contents
+ N/A
+
+
+
+ EA9C9DBA-B644-4EBB-BDAD-621E5455275A
+ 417A6CCE-D4E1-44BA-9A8D-038360B4B905
+
+
+ 4BA429EF-6143-4FB6-9B43-D4E6E4F0CE1D
+
+
+ 4BA429EF-6143-4FB6-9B43-D4E6E4F0CE1D
+ 4BA429EF-6143-4FB6-9B43-D4E6E4F0CE1D
+ 9AFECE21-8C79-45E0-9B9F-D6D62A9729D3
+
+
+
+
+ Label
+ -1
+
+
+
+
+
+
+
+
+
+
+
+ Status
+ -1
+
+ No Status
+ To Do
+ In Progress
+ First Draft
+ Revised Draft
+ Final Draft
+ Done
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ 0
+ 0
+ 115
+ 561
+
+ 5C03DE09-C285-48ED-827F-78E62B7D0F72
+ 69822417-D015-4BDD-90BD-18AAA6198D15
+
+
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Files/writing.history b/hapagirlsauthoringsystemv1.scriv/Files/writing.history
index 3b4b514..69c89a8 100644
--- a/hapagirlsauthoringsystemv1.scriv/Files/writing.history
+++ b/hapagirlsauthoringsystemv1.scriv/Files/writing.history
@@ -1,4 +1,4 @@
- 2026-08-23
+ 2026-08-23
\ No newline at end of file
diff --git a/hapagirlsauthoringsystemv1.scriv/Settings/ui-common.xml b/hapagirlsauthoringsystemv1.scriv/Settings/ui-common.xml
index dfe5dcb..a73fd88 100644
--- a/hapagirlsauthoringsystemv1.scriv/Settings/ui-common.xml
+++ b/hapagirlsauthoringsystemv1.scriv/Settings/ui-common.xml
@@ -15,6 +15,8 @@
145B9A0D-08D6-4E0F-89B1-49EAA14B2106704B2523-B066-4E3B-972C-0B81FA07D310CA829068-0EB8-4892-B3BB-2065A359FF97
+ D8E0BA08-72CE-48A9-94D9-3C9BDDA05921
+ 797DEF08-26BF-411A-907B-0CF985D5900F06C0455C-36DD-4F38-BB7B-F7DD2453A8A56830B6AC-686B-4370-A979-2FD1D7288BDA57ECC98D-8199-4935-B5F1-D1F7A2D60646
@@ -23,7 +25,7 @@
9A470BDE-CF2B-4872-97C6-74F19BC90197
- 48857498-4C8A-4481-BDF8-72A80EF2A7B8
+ 8A80CB1D-A4BC-4865-8B51-D6EFBC6E3936None
@@ -77,9 +79,9 @@
SingleNone
- 48857498-4C8A-4481-BDF8-72A80EF2A7B8
+ 8A80CB1D-A4BC-4865-8B51-D6EFBC6E3936
-
+ BB58390B-789C-47EE-AC09-76BF4C56BAC3816F6B00-8D2A-4022-87A4-D35170D81BEA5D497AFF-B4C1-419D-AB82-DDEFF79216A4
@@ -120,6 +122,19 @@
4A1D6B18-0952-42EB-A487-D17915DD3BA1E6227DA1-9FBA-4C81-A40A-AED871C690B548857498-4C8A-4481-BDF8-72A80EF2A7B8
+ BB58390B-789C-47EE-AC09-76BF4C56BAC3
+ 1F883D3F-67E3-4124-925D-B010FE4743F6
+ 06C0455C-36DD-4F38-BB7B-F7DD2453A8A5
+ 1F883D3F-67E3-4124-925D-B010FE4743F6
+ 0A7EDD9F-9DE0-4CC9-9AC1-EE0E3769B6A8
+ 2D6E4FBE-1689-4AA3-90A2-3EA6ACBEBF7B
+ 89A17E85-1E81-4FAE-B8C8-1A5A02F3EF2C
+ 71BFC455-F771-4342-A500-9C58BC55537B
+ 89A17E85-1E81-4FAE-B8C8-1A5A02F3EF2C
+ 71BFC455-F771-4342-A500-9C58BC55537B
+ 89A17E85-1E81-4FAE-B8C8-1A5A02F3EF2C
+ 71BFC455-F771-4342-A500-9C58BC55537B
+ 8A80CB1D-A4BC-4865-8B51-D6EFBC6E3936
@@ -127,7 +142,7 @@
NoNoNo
- 398,0
+ 0,0
diff --git a/hapagirlsauthoringsystemv1.scriv/hapagirlsauthoringsystemv1.scrivx b/hapagirlsauthoringsystemv1.scriv/hapagirlsauthoringsystemv1.scrivx
index 5b1bb69..dad3633 100644
--- a/hapagirlsauthoringsystemv1.scriv/hapagirlsauthoringsystemv1.scrivx
+++ b/hapagirlsauthoringsystemv1.scriv/hapagirlsauthoringsystemv1.scrivx
@@ -1,5 +1,5 @@
-
+Novel Format
@@ -193,13 +193,13 @@
1F883D3F-67E3-4124-925D-B010FE4743F6,A702733C-4F4D-4473-978E-57B27D437994,538FBF3E-89B8-4B08-A141-6D3CFEA1A160,E3CFECAB-7099-48B5-B971-1A6B12D220B3,6C6D3495-3C6F-48D0-9092-DA0760F7B31C,1B8B3DFD-9CDF-4442-8A72-69E87DD3A8C3,6981EF8D-41BF-4888-A3A2-B79B0CB8C449,8A0E75E6-1B75-42F3-982B-A8B02F762BB4,65B9D928-3C90-4881-8EB1-4432A9AAC239,EF0CA641-E954-495F-B7C3-855373C86798,E74F7CCB-E2BA-421B-814D-2EE6DA983324
-
+ Scene 1Yes
- 1503,0
+ 1776,0
@@ -345,12 +345,34 @@
0,0
+
+
+ Scene 1 — initial draft — 2026-08-23 1538
+
+ 0,0
+
+
+
+ Scene 1 — working copy — 2026-08-23 1538
+
+ 0,0
+
+
+ Package Snapshots0,0
+
+
+ Scene 1 — package — 2026-08-23 1538
+
+ 0,0
+
+
+ Superseded & Branches
@@ -371,6 +393,9 @@
0,0
+
+ 75F58E24-E4EE-4163-A6B3-7703D8D211BD
+ BE948F87-BDA3-4551-8E08-AC248FE89301
@@ -436,6 +461,15 @@
273,0
+
+ Alex Carpenter
+
+ Yes
+
+
+ 0,0
+
+
@@ -749,13 +783,13 @@
00
-
+ 00
- 65
- 288
+ 115
+ 5615C03DE09-C285-48ED-827F-78E62B7D0F7269822417-D015-4BDD-90BD-18AAA6198D15
diff --git a/prototype/README.md b/prototype/README.md
index 8fbecf2..bbf1ad9 100644
--- a/prototype/README.md
+++ b/prototype/README.md
@@ -1,6 +1,14 @@
-# Read-only Package Preview Prototype
+# Local Authoring-System Prototype
-This is the first authoring-system vertical slice. It reads a Scrivener project, checks the project structure, and builds an on-screen package preview. It does **not** call a model and it does **not** write to Scrivener.
+This prototype reads a Scrivener project, checks the project structure, builds an exact package preview, and can send a confirmed package to the temporary OpenRouter drafting model.
+
+When Scrivener is closed, accepting a generated draft for editing creates three records in the project:
+
+- an immutable initial draft in `Authoring System → Drafting Archive → Accepted for Editing`;
+- an editable working copy in the same folder; and
+- the exact package snapshot in `Authoring System → Drafting Archive → Package Snapshots`.
+
+An outright rejected draft writes nothing. A separate, explicit final-accept action copies the saved working copy into its paired Manuscript scene. Every write checks `Files/user.lock`; close the project in Scrivener first. Before a structural archive write, the prototype places a recoverable binder/checksum backup in `Files/authoring-backups`.
Run from `Authoring_System`:
@@ -16,4 +24,4 @@ To point it at another project:
python3 prototype/app.py --project /absolute/path/to/Book.scriv
```
-The app binds scene/brief pairs by the visible `Scene X` labels for this read-only prototype. The next phase will persist UUID bindings in a sidecar, so later renaming does not break relationships.
+The app currently binds scene/brief pairs by their visible `Scene X` labels. A later phase will persist UUID bindings in a sidecar, so later renaming does not break relationships.
diff --git a/prototype/app.py b/prototype/app.py
index 2bee916..4bb4487 100644
--- a/prototype/app.py
+++ b/prototype/app.py
@@ -1,18 +1,23 @@
#!/usr/bin/env python3
-"""Read-only local package-preview prototype for a Scrivener project.
+"""Local authoring-system prototype for a Scrivener project.
-This deliberately has no model call and no Scrivener write path. It is a
-small standard-library server so the first workflow test has no dependency
-installation step.
+It previews and sends packages, and makes carefully scoped, lock-guarded
+writes for accepted drafts. It remains a standard-library server.
"""
from __future__ import annotations
import argparse
+import datetime as dt
+import hashlib
import json
+import os
import re
import shutil
import subprocess
+import urllib.error
+import urllib.request
+import uuid
import xml.etree.ElementTree as ET
from dataclasses import dataclass, field
from http import HTTPStatus
@@ -22,6 +27,7 @@ from urllib.parse import urlparse
APP_DIR = Path(__file__).resolve().parent
DEFAULT_PROJECT = APP_DIR.parent / "hapagirlsauthoringsystemv1.scriv"
+OPENROUTER_MODEL = "anthropic/claude-sonnet-4.6"
@dataclass
@@ -54,6 +60,24 @@ def rtf_to_text(path: Path) -> str:
return re.sub(r"\n{3,}", "\n\n", raw).strip()
+def text_to_rtf(value: str) -> str:
+ """Create deliberately simple RTF suitable for Scrivener text documents."""
+ escaped = []
+ for character in value.replace("\r\n", "\n").replace("\r", "\n"):
+ if character == "\n":
+ escaped.append("\\par\n")
+ elif character in "\\{}":
+ escaped.append("\\" + character)
+ elif ord(character) > 127:
+ codepoint = ord(character)
+ if codepoint > 32767:
+ codepoint -= 65536
+ escaped.append(f"\\u{codepoint}?")
+ else:
+ escaped.append(character)
+ return "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil Helvetica;}}\n\\f0\\fs24 " + "".join(escaped) + "\n}"
+
+
class ScrivenerReader:
def __init__(self, project: Path):
self.project = project
@@ -175,11 +199,163 @@ class ScrivenerReader:
}
+class ScrivenerWriter:
+ """The small, guarded subset of Scrivener writes needed by this prototype."""
+
+ def __init__(self, project: Path):
+ self.project = project
+ self.reader = ScrivenerReader(project)
+
+ def _assert_unlocked(self) -> None:
+ if (self.project / "Files" / "user.lock").exists():
+ raise ValueError("Scrivener is open (Files/user.lock exists). Close the project before writing.")
+
+ def _tree_and_binder(self) -> tuple[ET.ElementTree, ET.Element]:
+ tree = ET.parse(self.reader.project_file)
+ binder = tree.getroot().find("Binder")
+ if binder is None:
+ raise ValueError("Scrivener project has no Binder.")
+ return tree, binder
+
+ @staticmethod
+ def _find_child(element: ET.Element, title: str) -> ET.Element | None:
+ children = element.find("Children")
+ if children is None:
+ return None
+ return next((item for item in children.findall("BinderItem") if (item.findtext("Title") or "").strip() == title), None)
+
+ def _folder(self, binder: ET.Element, path: list[str]) -> ET.Element:
+ parent: ET.Element | None = None
+ children = binder
+ for title in path:
+ parent = next((item for item in children.findall("BinderItem") if (item.findtext("Title") or "").strip() == title), None)
+ if parent is None:
+ raise ValueError("Required Scrivener folder is missing: " + " → ".join(path))
+ children = parent.find("Children")
+ if children is None and title != path[-1]:
+ raise ValueError("Required Scrivener folder has no children: " + title)
+ assert parent is not None
+ return parent
+
+ def _backup_binder(self) -> None:
+ backup_dir = self.project / "Files" / "authoring-backups"
+ backup_dir.mkdir(parents=True, exist_ok=True)
+ stamp = dt.datetime.now().strftime("%Y%m%d-%H%M%S")
+ shutil.copy2(self.reader.project_file, backup_dir / f"{stamp}.scrivx")
+ checksum = self.project / "Files" / "Data" / "docs.checksum"
+ if checksum.exists():
+ shutil.copy2(checksum, backup_dir / f"{stamp}.docs.checksum")
+
+ def _update_checksum(self, uuid: str, content: bytes) -> None:
+ checksum_path = self.project / "Files" / "Data" / "docs.checksum"
+ digest = hashlib.sha1(content).hexdigest()
+ key = f"{uuid.lower()}/content.rtf"
+ lines = checksum_path.read_text(encoding="utf-8", errors="replace").splitlines() if checksum_path.exists() else []
+ updated = False
+ output = []
+ for line in lines:
+ if line.startswith(key + "="):
+ output.append(f"{key}={digest}")
+ updated = True
+ else:
+ output.append(line)
+ if not updated:
+ output.append(f"{key}={digest}")
+ checksum_path.write_text("\n".join(output) + "\n", encoding="utf-8")
+
+ def _write_rtf(self, uuid: str, text: str) -> None:
+ content = text_to_rtf(text).encode("utf-8")
+ data_dir = self.project / "Files" / "Data" / uuid
+ data_dir.mkdir(parents=True, exist_ok=False)
+ (data_dir / "content.rtf").write_bytes(content)
+ self._update_checksum(uuid, content)
+
+ def _add_text(self, folder: ET.Element, title: str, text: str) -> str:
+ children = folder.find("Children")
+ if children is None:
+ children = ET.SubElement(folder, "Children")
+ doc_uuid = str(uuid.uuid4()).upper()
+ stamp = dt.datetime.now().astimezone().isoformat(timespec="seconds")
+ item = ET.SubElement(children, "BinderItem", {"UUID": doc_uuid, "Type": "Text", "Created": stamp, "Modified": stamp})
+ ET.SubElement(item, "Title").text = title
+ metadata = ET.SubElement(item, "MetaData")
+ ET.SubElement(metadata, "IncludeInCompile").text = "No"
+ settings = ET.SubElement(item, "TextSettings")
+ ET.SubElement(settings, "TextSelection").text = "0,0"
+ self._write_rtf(doc_uuid, text)
+ return doc_uuid
+
+ def _save_tree(self, tree: ET.ElementTree) -> None:
+ tree.write(self.reader.project_file, encoding="UTF-8", xml_declaration=True)
+
+ def accept_for_editing(self, scene_uuid: str, draft_text: str, package: str, model: str) -> dict:
+ self._assert_unlocked()
+ if not draft_text.strip() or not package.strip():
+ raise ValueError("A non-empty draft and package are required for acceptance.")
+ scene = self.reader.by_uuid.get(scene_uuid)
+ if scene is None:
+ raise ValueError("The selected scene no longer exists.")
+ self._backup_binder()
+ tree, binder = self._tree_and_binder()
+ accepted = self._folder(binder, ["Authoring System", "Drafting Archive", "Accepted for Editing"])
+ snapshots = self._folder(binder, ["Authoring System", "Drafting Archive", "Package Snapshots"])
+ stamp = dt.datetime.now().strftime("%Y-%m-%d %H%M")
+ initial_uuid = self._add_text(accepted, f"{scene.title} — initial draft — {stamp}", draft_text)
+ working_uuid = self._add_text(accepted, f"{scene.title} — working copy — {stamp}", draft_text)
+ package_header = f"Scene: {scene.title}\nModel: {model}\nAccepted for editing: {dt.datetime.now().astimezone().isoformat(timespec='seconds')}\n\n"
+ package_uuid = self._add_text(snapshots, f"{scene.title} — package — {stamp}", package_header + package)
+ self._save_tree(tree)
+ self.reader = ScrivenerReader(self.project)
+ return {"initial_uuid": initial_uuid, "working_uuid": working_uuid, "package_uuid": package_uuid}
+
+ def save_working_copy(self, working_uuid: str, text: str) -> None:
+ self._assert_unlocked()
+ item = self.reader.by_uuid.get(working_uuid)
+ if item is None or item.item_type != "Text":
+ raise ValueError("The working-copy archive record no longer exists.")
+ path = self.project / "Files" / "Data" / working_uuid / "content.rtf"
+ if not path.exists():
+ raise ValueError("The working-copy archive record has no text file.")
+ content = text_to_rtf(text).encode("utf-8")
+ path.write_bytes(content)
+ self._update_checksum(working_uuid, content)
+
+ def accept_into_book(self, scene_uuid: str, text: str) -> None:
+ self._assert_unlocked()
+ item = self.reader.by_uuid.get(scene_uuid)
+ if item is None or item.item_type != "Text":
+ raise ValueError("The selected Manuscript scene no longer exists.")
+ manuscript = self.reader.top_level("Manuscript")
+ if manuscript is None or not any(candidate.uuid == scene_uuid for candidate in self.reader.walk(manuscript.children)):
+ raise ValueError("The selected item is not a Manuscript scene.")
+ path = self.project / "Files" / "Data" / scene_uuid / "content.rtf"
+ content = text_to_rtf(text).encode("utf-8")
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_bytes(content)
+ self._update_checksum(scene_uuid, content)
+
+
def section(name: str, value: str) -> str:
return f"### {name}\n{value.strip() or '(none)'}"
+def preflight(project: ScrivenerReader, payload: dict) -> list[str]:
+ data = project.summary()
+ scene = next((item for item in data["scenes"] if item["uuid"] == payload.get("scene_uuid")), None)
+ if scene is None or not scene["brief"].strip():
+ raise ValueError("Choose a scene with a paired BRIEF.")
+ if not data["style"].strip():
+ raise ValueError("STYLE is empty.")
+ directive = payload.get("directive", "").strip()
+ if not directive:
+ raise ValueError("DIRECTIVE is required.")
+ if not re.search(r"\b(maximum|max|not exceed)\b", directive, re.IGNORECASE):
+ raise ValueError("DIRECTIVE needs a word maximum.")
+ return ["No scene-specific NOTES or Place records selected; verify that no physical or time continuity constraint is needed."] if not payload.get("notes", "").strip() and not payload.get("place_uuids", []) else []
+
+
def build_package(project: ScrivenerReader, payload: dict) -> str:
+ preflight(project, payload)
data = project.summary()
scene = next((scene for scene in data["scenes"] if scene["uuid"] == payload.get("scene_uuid")), None)
if scene is None:
@@ -220,6 +396,27 @@ def build_package(project: ScrivenerReader, payload: dict) -> str:
) + "\n"
+def draft(project: ScrivenerReader, payload: dict) -> dict:
+ key = os.environ.get("OPENROUTER_API_KEY")
+ if not key:
+ raise ValueError("OPENROUTER_API_KEY is not set in this server's Terminal session.")
+ if not payload.get("send_confirmation"):
+ raise ValueError("Confirm the OpenRouter send before generating.")
+ system = project.summary()["frontier_instructions"].strip()
+ package = build_package(project, payload)
+ body = json.dumps({"model": OPENROUTER_MODEL, "messages": [{"role": "system", "content": system}, {"role": "user", "content": package}], "max_tokens": int(payload.get("max_tokens", 3000))}).encode()
+ request = urllib.request.Request("https://openrouter.ai/api/v1/chat/completions", data=body, headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"}, method="POST")
+ try:
+ with urllib.request.urlopen(request, timeout=300) as response:
+ result = json.loads(response.read().decode())
+ except urllib.error.HTTPError as error:
+ raise ValueError(f"OpenRouter returned HTTP {error.code}: {error.read().decode(errors='replace')}") from error
+ text = result.get("choices", [{}])[0].get("message", {}).get("content")
+ if not isinstance(text, str):
+ raise ValueError("OpenRouter response did not contain draft text.")
+ return {"draft": text, "usage": result.get("usage", {}), "model": result.get("model", OPENROUTER_MODEL)}
+
+
class AppHandler(SimpleHTTPRequestHandler):
reader: ScrivenerReader
@@ -240,7 +437,7 @@ class AppHandler(SimpleHTTPRequestHandler):
self.send_json(self.reader.summary())
return
if path == "/api/health":
- self.send_json({"status": "ok", "mode": "read-only prototype"})
+ self.send_json({"status": "ok", "mode": "local prototype"})
return
if path == "/":
self.path = "/static/index.html"
@@ -252,13 +449,36 @@ class AppHandler(SimpleHTTPRequestHandler):
super().do_GET()
def do_POST(self) -> None:
- if urlparse(self.path).path != "/api/package-preview":
+ path = urlparse(self.path).path
+ if path not in {"/api/package-preview", "/api/draft", "/api/accept-for-editing", "/api/save-working-copy", "/api/accept-into-book"}:
self.send_error(HTTPStatus.NOT_FOUND)
return
try:
length = int(self.headers.get("Content-Length", "0"))
payload = json.loads(self.rfile.read(length).decode("utf-8"))
- self.send_json({"package": build_package(self.reader, payload)})
+ if path == "/api/draft":
+ self.send_json(draft(self.reader, payload))
+ elif path == "/api/accept-for-editing":
+ if not payload.get("accept_confirmation"):
+ raise ValueError("Confirm acceptance before creating archive records.")
+ package = build_package(self.reader, payload)
+ writer = ScrivenerWriter(self.reader.project)
+ result = writer.accept_for_editing(payload.get("scene_uuid", ""), payload.get("draft", ""), package, payload.get("model", OPENROUTER_MODEL))
+ AppHandler.reader = writer.reader
+ self.send_json(result)
+ elif path == "/api/save-working-copy":
+ writer = ScrivenerWriter(self.reader.project)
+ writer.save_working_copy(payload.get("working_uuid", ""), payload.get("text", ""))
+ self.send_json({"saved": True})
+ elif path == "/api/accept-into-book":
+ if not payload.get("final_confirmation"):
+ raise ValueError("Confirm final acceptance before writing canonical Manuscript text.")
+ writer = ScrivenerWriter(self.reader.project)
+ writer.accept_into_book(payload.get("scene_uuid", ""), payload.get("text", ""))
+ AppHandler.reader = ScrivenerReader(self.reader.project)
+ self.send_json({"accepted": True})
+ else:
+ self.send_json({"package": build_package(self.reader, payload), "warnings": preflight(self.reader, payload)})
except (ValueError, json.JSONDecodeError) as error:
self.send_json({"error": str(error)}, HTTPStatus.BAD_REQUEST)
@@ -267,7 +487,7 @@ class AppHandler(SimpleHTTPRequestHandler):
def main() -> None:
- parser = argparse.ArgumentParser(description="Run the read-only authoring-system prototype.")
+ parser = argparse.ArgumentParser(description="Run the local authoring-system prototype.")
parser.add_argument("--project", type=Path, default=DEFAULT_PROJECT)
parser.add_argument("--port", type=int, default=8765)
args = parser.parse_args()
@@ -276,7 +496,7 @@ def main() -> None:
parser.error(f"Project not found: {project}")
AppHandler.reader = ScrivenerReader(project)
server = ThreadingHTTPServer(("127.0.0.1", args.port), AppHandler)
- print(f"Read-only authoring prototype: http://127.0.0.1:{args.port}")
+ print(f"Local authoring prototype: http://127.0.0.1:{args.port}")
print(f"Project: {project}")
server.serve_forever()
diff --git a/prototype/static/app.js b/prototype/static/app.js
index 643d98c..1592500 100644
--- a/prototype/static/app.js
+++ b/prototype/static/app.js
@@ -1,4 +1,9 @@
let project;
+let initialDraft = '';
+let generatedPackage = '';
+let generatedModel = '';
+let workingUuid = '';
+let acceptedSceneUuid = '';
const byId = (id) => document.getElementById(id);
const selected = (container) => [...container.querySelectorAll('input:checked')].map((input) => input.value);
@@ -21,18 +26,18 @@ function updateSceneState() {
function render(data) {
project = data;
- byId('status').textContent = data.locked ? 'Scrivener lock detected — read-only' : 'Project not locked — app remains read-only';
+ const priorSceneUuid = acceptedSceneUuid || byId('scene').value;
+ byId('status').textContent = data.locked ? 'Scrivener lock detected — archive and manuscript writes are disabled' : 'Project closed — accepted-draft writes are available';
byId('status').className = `status ${data.locked ? 'warning' : 'ok'}`;
byId('project-check').innerHTML = [
- ['Scenes', data.scenes.length],
- ['Briefs without scene', data.unmatched_briefs.length],
- ['Scenes without brief', data.unmatched_scenes.length],
- ['Characters', data.characters.length],
- ['Places', data.places.length],
+ ['Scenes', data.scenes.length], ['Briefs without scene', data.unmatched_briefs.length],
+ ['Scenes without brief', data.unmatched_scenes.length], ['Characters', data.characters.length], ['Places', data.places.length],
].map(([label, value]) => `