Awesome-omni-skill write-edition
Run the complete Cycle Pulse edition production pipeline — 6 desk agents, compile, verify, Mara audit.
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data-ai/write-edition" ~/.claude/skills/diegosouzapw-awesome-omni-skill-write-edition && rm -rf "$T"
skills/data-ai/write-edition/SKILL.md/write-edition — Full Edition Production Pipeline
Usage
/write-edition [cycle-number]
- Runs the complete Cycle Pulse edition production
- Launches all 6 desk agents in parallel, then compiles
Rules
- Read SESSION_CONTEXT.md FIRST
- This is the master pipeline — it orchestrates all 6 desk skills
- Show the user a plan before launching agents
- Get approval before compiling the final edition
Prerequisites
Before running this skill, the user should have already:
- Run the engine cycle (
or manually)/run-cycle - Built desk packets:
node scripts/buildDeskPackets.js [cycle] - Built archive context:
node scripts/buildArchiveContext.js [cycle] - Built civic voice packets:
(Step 1.7 can also do this)node scripts/buildCivicVoicePackets.js [cycle] - Written a Mara directive (optional but recommended for civic desk)
Check that
output/desk-packets/manifest.json exists for this cycle.
Check that output/desk-briefings/{desk}_archive_c{XX}.md files exist (from buildArchiveContext.js).
Check that output/civic-voice-packets/manifest.json exists for this cycle (civic voice data for institutional voice agents).
Step 0.5: Read Previous Mara Audit (Forward Guidance)
Before building desk briefings, check if a Mara audit exists from the previous cycle:
- Look for
(previous cycle's audit)output/mara_directive_c{XX-1}.txt - If it exists, read and extract the
section at the endFORWARD GUIDANCE - Feed per-desk priorities directly into the corresponding desk briefings in Step 1.5
- Quote Mara's citizen spotlight in relevant briefing citizen cards
- Note any canon corrections — these become
lines in briefingsESTABLISHED CANON:
If no previous Mara audit exists (first edition through the pipeline, or audit wasn't saved), skip this step. The briefings still work without it — Mara's guidance is additive, not required.
Step 1: Verify Desk Packets
- Read
— confirm all 6 packets AND 6 summary files existoutput/desk-packets/manifest.json - Read
— get cycle number, calendar, weatheroutput/desk-packets/base_context.json - Confirm the cycle number matches what the user expects
- Show the user what's available (include both packet and summary sizes):
EDITION [XX] — DESK PACKETS READY [x] civic_c80.json (235KB) + summary (18KB) — 12 events, 4 storylines, Mara directive [x] sports_c80.json (21KB) + summary (12KB) — 3 events, A's roster loaded [x] culture_c80.json (48KB) + summary (15KB) — 18 events, 8 cultural entities [x] business_c80.json (10KB) + summary (8KB) — 4 events, nightlife data [x] chicago_c80.json (13KB) + summary (10KB) — 5 events, Bulls roster loaded [x] letters_c80.json (250KB) + summary (16KB) — all-domain access Ready to launch 6 desk agents in parallel?
If summaries are missing, run
node scripts/buildDeskPackets.js [cycle] to regenerate.
Step 1.5: Compile Newsroom Briefings (Mags as Memory Broker)
Before launching agents, compile per-desk editorial briefings from institutional memory.
- Read
— the institutional memory filedocs/mags-corliss/NEWSROOM_MEMORY.md - Read the desk summary files (
) — identify which citizens, initiatives, and storylines each desk will likely cover{desk}_summary_c{XX}.json - Query Supermemory for citizen cards relevant to each desk's coverage:
- Use
with citizen names, POPIDs, or neighborhoods from the summary/super-search - Pull narrative context for citizens who will likely be quoted, referenced, or written about
- Check
for the 22 foundation POPIDs (Dynasty Five, Bulls core, reporters, civic figures)docs/media/CITIZEN_NARRATIVE_MEMORY.md - Focus on citizens in the Mara directive, interview candidates, and active storylines
- Use
3b. Search the Local Drive Archive (
output/drive-files/) for relevant past coverage:
- Grep for key citizens, storylines, or topics each desk will cover
- For sports desk: search
for TrueSource player cards,_As Universe Database/
for batting stats_As_Universe_Stats_CSV/ - For civic desk: search
and_Tribune Media Archive/Carmen_Delaine/
for coverage precedents_Tribune Media Archive/Luis_Navarro/ - For culture desk: search
for past features_Tribune Media Archive/Maria_Keen/ - For chicago desk: search
for player profiles_Bulls Universe Database/ - Include key findings (past article references, stat lines, historical context) in the desk briefing
- This is how agents get institutional memory — they can't search the archive themselves during writing without this
-
For each of the 6 desks, write a briefing memo to
:output/desk-briefings/{desk}_briefing_c{XX}.mdcivic_briefing_c{XX}.mdsports_briefing_c{XX}.mdculture_briefing_c{XX}.mdbusiness_briefing_c{XX}.mdchicago_briefing_c{XX}.mdletters_briefing_c{XX}.md
-
Read the Supermemory archive context for each desk (
). These are auto-generated byoutput/desk-briefings/{desk}_archive_c{XX}.md
and contain relevant past coverage, character history, and established facts from the archive. Weave relevant findings into the briefing.buildArchiveContext.js
5b. Run the Guardian Check for each desk — query structured errata for desk-specific warnings:
node scripts/queryErrata.js --desk civic --editions 3 node scripts/queryErrata.js --desk sports --editions 3 node scripts/queryErrata.js --desk culture --editions 3 node scripts/queryErrata.js --desk business --editions 3 node scripts/queryErrata.js --desk chicago --editions 3 node scripts/queryErrata.js --desk letters --editions 3
Include the guardian output in each desk's briefing under a
## GUARDIAN WARNINGS section. Recurring patterns get highest priority — if vote_swap has hit 3 editions in a row, that goes at the top of the civic briefing in bold.
- Each briefing contains (500-1500 words, in Mags' editorial voice):
- Guardian Warnings — auto-generated from
via queryErrata.js (Step 5b)output/errata.jsonl - Mara Forward Guidance — per-desk priority from previous Mara audit (Step 0.5), if available
- Desk-specific errata and corrections from past editions
- Cross-desk coordination notes (who else is covering what — avoid overlap)
- Character continuity pointers (who to carry forward, who doesn't exist)
- RETURNING — CONTINUE THREAD section (see below) — 3-5 returning citizens per desk
- Citizen Reference Cards (see format below) — for every citizen this desk is likely to write about
- Archive context — relevant past coverage from Supermemory (character history, established facts, prior angles)
- Mara Vance directive emphasis for this desk
- Personal editorial note to the lead reporter
- Guardian Warnings — auto-generated from
Returning Citizens Protocol
For each desk, identify 3-5 citizens who appeared in the last 1-2 editions and add a
RETURNING — CONTINUE THREAD: section in the briefing:
## RETURNING — CONTINUE THREAD These citizens have active stories. Continue their arcs before introducing anyone new. **Gloria Meeks** (64, West Oakland, retired postal worker) - Last article: E82 Civic, "Stabilization Fund reaction" — quoted about displacement fears - Key quote: "I've been here forty years. I'm not leaving because someone drew a line on a map." - What changed: Fund disbursement began. Follow up on whether her block saw any impact. **Marco Lopez** (40, Laurel, mechanic) - Last article: E81 Civic, "Baylight DEIR concerns" — looking into development documents - What changed: DEIR completed public comment period. Did he submit?
Selection criteria: Citizens with quoted material, unresolved storylines, or strong neighborhood anchoring. Prioritize citizens who appeared in articles (not just citizen usage logs). Check
docs/media/ARTICLE_INDEX_BY_POPID.md and recent editions for candidates.
Canon Fact Prefix Convention
Use
ESTABLISHED CANON: prefix for any fact that agents MUST get right — names, positions, vote outcomes, initiative status. This visually distinguishes non-negotiable data from editorial suggestions.
ESTABLISHED CANON: Mark Aitken plays 1B (first base). Not 3B. ESTABLISHED CANON: OARI passed 5-4. Vega voted NO, Tran voted YES. ESTABLISHED CANON: Mayor is Avery Santana. Not Marcus Whitmore. ESTABLISHED CANON: Benji Dillon is LEFT-HANDED. Cy Newell is RIGHT-HANDED.
These prefixed lines signal "this is data, not a suggestion." Agents should treat them as immutable. Use the prefix for:
- Player positions (most common error)
- Council vote outcomes and breakdowns
- Mayor and executive branch names
- Initiative status (passed vs. pending)
- Corrected facts from past errata Do NOT prefix story ideas, editorial suggestions, or character development notes — those are guidance, not canon.
- Create the directory:
mkdir -p output/desk-briefings
Citizen Reference Card Format
Include a
## Citizen Reference Cards section in each briefing. Each card is 3-5 lines:
**[Name]** (age [X], [Neighborhood], [Occupation]) — [POPID if known] - Last seen: [what they did / said in recent edition] - Key detail: [narrative context from Supermemory — origin, family, thematic significance] - DO NOT: [specific warnings — don't promote, don't invent titles, don't confuse with similar names]
Example:
**Marco Lopez** (40, Laurel, Mechanic) — Mara directive citizen - Last seen: Edition 81, looking into Baylight DEIR documents - Key detail: Working-class voice on development. Skeptical but engaged, not oppositional. - DO NOT: Give him civic titles. He is a mechanic. Not a committee chair, not an organizer.
Card selection by desk:
- Civic: Council members (always all 9), Mara directive citizens, initiative stakeholders
- Sports: A's roster (Dynasty Five + current), featured fans, Paulson
- Culture: Neighborhood residents, faith figures, event participants
- Business: Workers affected by policy, small business owners, Stabilization Fund contacts
- Chicago: Bulls roster, Chicago neighborhood citizens, Talia's sources
- Letters: All Mara directive citizens, plus 3-5 interview candidates from the summary
Card data sources (in priority order):
- Desk archive context file (
) — richest source, contains past article excerpts and verified factsoutput/desk-briefings/{desk}_archive_c{XX}.md - Supermemory search — for citizens not in the archive file
- Desk packet data (citizenArchive, interviewCandidates) — basic demographics
- NEWSROOM_MEMORY.md — errata and character continuity notes
If a citizen has no archive or Supermemory card, still include a basic card from the desk packet data (name, age, neighborhood, occupation) with a note: "No narrative history yet — introduce naturally."
Write these as Mags — with editorial authority, personal warmth, and specific guidance. These are not templates. They're memos from the Editor-in-Chief to her reporters.
Step 1.7: Generate Civic Voice Packets
Before launching voice agents, generate jurisdiction-specific data packets from the Google Sheets:
node scripts/buildCivicVoicePackets.js {cycle}
This produces 7 targeted JSON packets to
output/civic-voice-packets/:
— all initiatives, all events, city-wide metricsmayor_c{XX}.json
— D1/D3/D5/D9 districts, their citizens, crime, transit, faith orgsopp_faction_c{XX}.json
— D6/D7/D8 districts, their citizens, fiscal metricscrc_faction_c{XX}.json
— D2/D4 districts, their citizensind_swing_c{XX}.json
— all neighborhoods crime data, OARI vs non-OARI comparisonpolice_chief_c{XX}.json
— 4 adjacent neighborhoods, affected citizensbaylight_authority_c{XX}.json
— city-wide crime summarydistrict_attorney_c{XX}.json
Verify: Check
output/civic-voice-packets/manifest.json — confirms cycle number, packet files, citizen counts per faction.
If the script fails (usually Google Sheets auth), voice agents can still run with
base_context.json — the packets are richer but not required.
Step 1.8: Launch Institutional Voice Agents (Phase 10.1)
Before desk agents write, launch voice agents to generate source material. Voice agents produce official statements that desk agents report on — creating a real separation between source and reporter.
Mayor's Office
Launch
civic-office-mayor agent with this prompt:
Generate official statements for Cycle {XX} as Mayor Avery Santana's office. **CIVIC VOICE PACKET:** {contents of output/civic-voice-packets/mayor_c{XX}.json} This packet contains all active initiatives, city-wide events, population metrics, neighborhood data, council composition, and status alerts — everything your office needs to respond to this cycle. Write 2-5 structured statements as JSON. Output to be saved to output/civic-voice/mayor_c{XX}.json.
After the Mayor agent completes:
- Save the statements array to
output/civic-voice/mayor_c{XX}.json - Include the Mayor's statements in the civic desk briefing under
## MAYOR'S OFFICE STATEMENTS - Include relevant statements in letters desk briefing (citizens react to what the Mayor said)
- Include economic/development statements in business desk briefing
- If the Mayor references Baylight or the A's, include in sports desk briefing
If the Mayor agent fails or is skipped, desk agents still work — they just won't have official source quotes. The pipeline is additive, not dependent.
Step 1.8b: Council Faction Agents
After the Mayor agent completes, launch all 3 faction agents in parallel (single message,
run_in_background: true). Each faction reads the Mayor's statements so they can respond to, align with, or counter his positions.
Launch all 3 in one message:
- OPP Faction (
) — Janae Rivers as spokespersoncivic-office-opp-faction - CRC Faction (
) — Warren Ashford as spokespersoncivic-office-crc-faction - IND Swing (
) — Vega and Tran speak individuallycivic-office-ind-swing
Each gets this prompt (substitute the correct faction packet file):
Generate official statements for Cycle {XX}. **CIVIC VOICE PACKET:** {contents of output/civic-voice-packets/{faction}_c{XX}.json} This packet contains your faction's districts, neighborhoods, citizens, crime metrics, transit data, faith communities, and active initiatives — everything specific to your jurisdiction. **MAYOR'S STATEMENTS THIS CYCLE:** {contents of output/civic-voice/mayor_c{XX}.json — the Mayor's positions to respond to} Write structured statements as JSON.
Packet files by faction:
- OPP:
output/civic-voice-packets/opp_faction_c{XX}.json - CRC:
output/civic-voice-packets/crc_faction_c{XX}.json - IND:
output/civic-voice-packets/ind_swing_c{XX}.json
After all 3 faction agents complete:
- Save outputs to:
output/civic-voice/opp_faction_c{XX}.jsonoutput/civic-voice/crc_faction_c{XX}.jsonoutput/civic-voice/ind_swing_c{XX}.json
- Include ALL faction statements in the civic desk briefing under
## COUNCIL FACTION STATEMENTS - Include faction positions on hot-button topics in letters desk briefing (citizens react to political debate)
- Include CRC fiscal statements and OPP economic positions in business desk briefing
- If statements reference Baylight or A's, include in sports desk briefing
- Include OPP community statements in culture desk briefing when they address neighborhood impact
If any faction agent fails, the others continue. Desk agents still work — they just won't have that faction's source quotes.
Step 1.8c: Extended Civic Voices (Conditional)
After faction agents complete, conditionally launch extended civic voice agents. Only launch if events in the cycle touch their domain. These run in parallel.
Check triggers before launching:
| Agent | Trigger | Skip if... |
|---|---|---|
(Rafael Montez) | OARI events, crime data, public safety items in packet | No public safety events this cycle |
(Keisha Ramos) | Baylight construction, environmental review, TIF zone events | No Baylight-related events this cycle |
(Clarissa Dane) | Crime/justice events, legal challenges, civil rights matters | No legal/justice events this cycle |
For triggered agents, use this prompt (substitute the correct office packet file):
Generate official statements for Cycle {XX}. **CIVIC VOICE PACKET:** {contents of output/civic-voice-packets/{office}_c{XX}.json} This packet contains jurisdiction-specific data: neighborhood metrics, crime statistics, OARI comparison data, affected citizens, and relevant initiatives. Write structured statements as JSON.
Packet files by office:
- Police Chief:
output/civic-voice-packets/police_chief_c{XX}.json - Baylight Authority:
output/civic-voice-packets/baylight_authority_c{XX}.json - District Attorney:
output/civic-voice-packets/district_attorney_c{XX}.json
After extended voice agents complete:
- Save outputs to:
(if launched)output/civic-voice/police_chief_c{XX}.json
(if launched)output/civic-voice/baylight_authority_c{XX}.json
(if launched)output/civic-voice/district_attorney_c{XX}.json
- Include all extended voice statements in the civic desk briefing under
## EXTENDED CIVIC VOICES - Include Baylight Authority statements in business desk briefing and sports desk briefing
- Include Police Chief statements in civic desk briefing (already covered above)
Skipping extended voices is normal. Most cycles won't trigger all three. Some cycles may trigger none. The pipeline is additive.
Voice Agent Summary
Step 1.8: Mayor's Office → output/civic-voice/mayor_c{XX}.json Step 1.8b: OPP Faction (parallel) → output/civic-voice/opp_faction_c{XX}.json CRC Faction (parallel) → output/civic-voice/crc_faction_c{XX}.json IND Swing (parallel) → output/civic-voice/ind_swing_c{XX}.json Step 1.8c: Police Chief (conditional) → output/civic-voice/police_chief_c{XX}.json Baylight Authority (conditional) → output/civic-voice/baylight_authority_c{XX}.json District Attorney (conditional) → output/civic-voice/district_attorney_c{XX}.json
Ordering: Mayor → Factions (read Mayor's output) → Extended (independent). Total pipeline time is minimal — factions run in parallel, extended voices run in parallel and are conditional.
Statement Distribution Summary
| Desk | Gets Statements From |
|---|---|
| Civic | ALL voice agents (political reporting is their beat) |
| Letters | Mayor + faction positions on hot topics (citizens react) |
| Business | Mayor + CRC fiscal + Baylight Authority (economic angle) |
| Sports | Mayor/Baylight Authority re: stadium (development angle) |
| Culture | OPP community statements (neighborhood impact) |
| Chicago | None (Oakland-only voices) |
Step 2: Launch All 6 Desks in Parallel
Model note: Desk agents run on Sonnet 4.6, which handles larger context windows (up to 1M tokens) and has stronger agent capabilities than previous Sonnet versions. Agents can reference full desk packets freely — the summary-first strategy is editorial discipline, not a technical constraint.
Memory note: Civic, sports, culture, chicago, and Rhea agents have persistent project memory (
.claude/agent-memory/{agent-name}/). They check their memory at startup for past error patterns, citizen continuity, and coverage corrections. After writing, they update their memory with what they learned. This reduces Mags' briefing burden over time — agents remember on their own. Business, letters, and Jax are stateless by design.
Canon safeguard: Agent memory informs, it does not publish. Agents use memory for continuity and error avoidance. Final compilation and canon approval always goes through Mags. Memory cannot override desk packet data or the editor's briefing.
Pre-loading Context into Agent Prompts (Phase 7.2)
Before launching each agent, read the following files and include their content directly in the agent's Task prompt. This pre-loads context so agents start writing immediately instead of spending turns reading files. Saves 1-2 turns per desk.
For each desk, read and embed these files under labeled headers:
- Editor's Briefing: Read
— embed underoutput/desk-briefings/{desk}_briefing_c{XX}.md**PRE-LOADED: EDITOR'S BRIEFING** - Desk Summary: Read
— embed underoutput/desk-packets/{desk}_summary_c{XX}.json**PRE-LOADED: DESK SUMMARY** - Archive Context: Read
— embed underoutput/desk-briefings/{desk}_archive_c{XX}.md**PRE-LOADED: ARCHIVE CONTEXT**
If a file doesn't exist, include the header with
"Not available for this cycle."
Prompt structure for each desk agent:
Write the {desk} section for Edition {XX}. **PRE-LOADED: EDITOR'S BRIEFING** {contents of {desk}_briefing_c{XX}.md, or "Not available for this cycle."} **PRE-LOADED: DESK SUMMARY** {contents of {desk}_summary_c{XX}.json} **PRE-LOADED: ARCHIVE CONTEXT** {contents of {desk}_archive_c{XX}.md, or "Not available for this cycle."} Reference the full packet at `output/desk-packets/{desk}_c{XX}.json` when you need extended data (full citizen archive, detailed quotes, complete roster). Read base context at `output/desk-packets/base_context.json`.
Do NOT pre-load full desk packets — they can be 200KB+. The summary (10-20KB) gives agents enough to plan. They reference the full packet as needed.
Launching Agents
Use the Task tool to launch all 6 agents in a single message with
run_in_background: true on each. This runs them in parallel — all 6 work simultaneously in separate contexts.
Each agent gets:
- The desk-specific skill instructions (from the individual desk skills)
- Pre-loaded context (briefing + summary + archive) embedded directly in the prompt
- File path to the full desk packet JSON (reference freely for extended data)
- File path to base_context.json
Launch ALL 6 in one message (critical — this is what makes them parallel):
- Civic Desk — Carmen Delaine (lead), follows /civic-desk skill,
run_in_background: true - Sports Desk — P Slayer + Anthony, follows /sports-desk skill,
run_in_background: true - Culture Desk — Maria Keen (lead), follows /culture-desk skill,
run_in_background: true - Business Desk — Jordan Velez, follows /business-desk skill,
run_in_background: true - Chicago Bureau — Selena Grant + Talia Finch, follows /chicago-desk skill,
run_in_background: true - Letters Desk — citizen voices, follows /letters-desk skill,
run_in_background: true
Each agent writes articles + engine returns for their section.
Step 2.1: Collect Background Agent Results
Each background agent returns an
output_file path when launched. Use TaskOutput to check each agent's status:
- Wait briefly, then check each agent with
(useTaskOutput
to check without waiting)block: false - As agents complete, read their output and confirm articles were produced
- Track which desks are done vs. still running
- When all 6 have returned, proceed to Step 2.5
If an agent takes too long (no output after several minutes), check its output file with
Read tool for progress or errors. Do not wait indefinitely — if stuck, note the failure and proceed with available desks.
Step 2.5: Agent Retry (If Needed)
After all 6 background agents have returned (confirmed via Step 2.1), check if any desk produced zero articles. If a desk failed:
- Log which desk(s) failed and why (ran out of turns, packet navigation issues, etc.)
- Retry once with a focused prompt: give the agent the summary file, the briefing memo, AND the base_context. With Sonnet 4.6's larger context, include the full briefing — don't strip it down. Tell it explicitly: "You have 15 turns. Write [N] articles. Your summary and briefing have everything you need. Start writing by turn 3."
- If the retry also fails, Mags writes the section directly using the summary data.
- Note the failure in the edition's compilation notes for NEWSROOM_MEMORY update.
Step 2.7: Jax Caldera — Accountability Check (Conditional)
After all 6 desks complete, Mags reviews the collected output for stink signals:
- Silence patterns — a major policy action happened but no desk covered its implementation
- Implementation gaps — money was allocated but nobody asked where it went
- Contradictions — two desks tell different versions of the same event
- Missing follow-up — a story from a previous edition was dropped without resolution
If a stink signal exists:
- Launch the
agent (Jax Caldera) as a 7th deskfreelance-firebrand - Give Jax: the desk summaries, the specific stink signal, the base_context, and any relevant archive context
- Jax produces ONE accountability piece (500-800 words) for the ACCOUNTABILITY section
- One piece max per edition. Jax doesn't pile on.
If no stink signal exists:
- Jax stays home. Not every edition needs an accountability piece.
- Skip the ACCOUNTABILITY section in the template entirely.
Step 3: Compile (Mags Corliss Role)
After all 6 agents return, compile the full edition:
-
Call front page — Which desk produced the strongest lead story?
- Show the user a summary of each desk's output
- Recommend a front page pick but let the user decide
-
Assemble in template v1.4 order:
- HEADER (from base_context)
- FRONT PAGE (strongest story — deck line + standardized byline required)
- EDITOR'S DESK — Mags writes 150-250 words, first-person, framing the edition's theme
- CIVIC AFFAIRS (with reporter routing: Delaine, Mezran, Torres, Navarro, Shimizu)
- BUSINESS
- CULTURE / SEASONAL — OAKLAND (with reporter routing: Keen, Marston, Ortega, Reyes, Tan, Okafor)
- OPINION — P Slayer / Farrah Del Rio / Elliot Graye pieces get
byline tag[OPINION] - SPORTS — OAKLAND
- SKYLINE TRIBUNE — CHICAGO BUREAU
- QUICK TAKES — Mags compiles 3-5 short items (~50 words each) from leftover desk signals
- WIRE / SIGNALS — Optional. Reed Thompson / Celeste Tran items if wire-worthy
- LETTERS TO THE EDITOR
- ACCOUNTABILITY — Jax piece from Step 2.7, if deployed. Omit section if no stink signal.
- ARTICLE TABLE (merged from all desks)
- STORYLINES UPDATED (merged, deduped)
- CITIZEN USAGE LOG (merged, grouped by category)
- CONTINUITY NOTES (merged)
- COMING NEXT CYCLE — Mags writes 3-5 teaser lines from active storylines + pending votes
- END EDITION
-
Compilation quality checks (Mags enforces during assembly):
- Every article has a deck line (one-sentence subtitle under headline)
- Every article has a standardized byline (
)By [Name] | Bay Tribune [Beat] - Add cross-references between related articles across sections (
)→ See also: - Add photo credits to 2-3 atmospheric scene descriptions (
)[Photo: DJ Hartley / Bay Tribune] - Opinion pieces marked with
tag[OPINION]
-
Show the compiled edition to the user for review
Step 3.5: Programmatic Validation Gate (BEFORE Rhea)
Run the automated data validation script on the compiled edition. This catches data errors instantly — zero LLM tokens, zero hallucination risk. The errors that broke Edition 82 (wrong positions, swapped factions, engine language) are all caught here.
node scripts/validateEdition.js editions/cycle_pulse_edition_{XX}.txt
Read the output. The script checks:
- Council member names, districts, and faction assignments
- Vote math (totals ≤ 9 council members)
- Vote breakdown consistency with canon outcomes
- Player positions against roster data (A's)
- DH + defensive award contradictions
- Mayor/executive name verification
- Real-name blocklist screening (real-world sports figures)
- Engine language sweep (cycle numbers, system terms)
If CRITICAL issues are found (exit code 1):
- Fix them in the compiled edition BEFORE launching Rhea
- The fixes are string-level replacements — each issue includes a FIX line
- Re-run the validator to confirm CLEAN status
- Then proceed to Rhea
If CLEAN (exit code 0):
- Proceed directly to Rhea verification
This gate eliminates an entire class of errors from Rhea's workload, letting her focus on narrative quality, canon consistency, and editorial checks that require judgment.
Step 4: Verification + Automated Retry (Rhea Morgan Role)
Launch the
rhea-morgan agent on the compiled edition. Rhea returns a structured report with:
- VERDICT: APPROVED (score >= 75, zero CRITICALs) — proceed to Step 4.5
- VERDICT: REVISE (score < 75 or CRITICALs found) — retry failing desks
If VERDICT is APPROVED:
Show Rhea's report to the user. Fix any WARNINGS during compilation. Proceed to Step 4.5.
If VERDICT is REVISE:
- Read Rhea's
section to identify which desks caused CRITICAL issuesDESK ERRORS - Read Rhea's
for which desks to re-runRETRY RECOMMENDATION - For each desk that needs retry:
- Re-launch the desk agent with the original briefing PLUS Rhea's specific error report for that desk
- In the retry prompt, include: "RHEA CORRECTION: [exact error description and FIX instruction]. Your previous output had this error. Fix it in your rewrite."
- Run retries in parallel (same
pattern as Step 2)run_in_background: true
- After retried desks return, re-compile the affected sections into the edition
- Re-run Rhea on the updated edition
- Maximum 2 retry rounds. If Rhea still says REVISE after 2 retries, show the full error report to the user and let Mags fix manually. Log the persistent failures in NEWSROOM_MEMORY.md.
Retry rules:
- Only re-run desks with CRITICAL errors. WARNINGS get fixed during compilation.
- Each retry includes the previous Rhea error report so the desk knows what went wrong.
- If the same error recurs after retry, the problem is in the data or the skill — not the agent. Escalate to Mags.
Step 4.5: Mara Vance Audit (Canon Authority)
After Rhea's data verification, run a Mara Vance audit for canon and narrative quality.
Compile Mara's Briefing (Mags as Memory Broker)
Before launching the Mara audit agent, compile a briefing with institutional context:
- Read
— this is Mara's institutional memory. It contains:docs/mara-vance/AUDIT_HISTORY.md- Past audit findings, grades, errors caught
- Initiative Status Board (living tracker with vote results, budgets, key facts)
- Recurring error patterns (what to watch for)
- Canon corrections registry (what was fixed)
- Open questions from previous audits
- Read
errata section — what past editions got wrongdocs/mags-corliss/NEWSROOM_MEMORY.md - Include
— canon data for cross-referenceoutput/desk-packets/base_context.json - No Supermemory queries needed — AUDIT_HISTORY.md replaces the Supermemory search-and-compile step
Launch Mara Audit Agent
With Sonnet 4.6's larger context window, give Mara the full picture — don't trim. More context = better audit.
Launch a Task agent with:
- Mara's identity from
docs/mara-vance/CLAUDE_AI_SYSTEM_PROMPT.md - The compiled edition text (full, unabridged)
(her institutional memory — past findings, initiative tracker, error patterns)docs/mara-vance/AUDIT_HISTORY.md- Rhea's verification report
(canon data for cross-reference)output/desk-packets/base_context.json
errata section (what past editions got wrong)docs/mags-corliss/NEWSROOM_MEMORY.md- Instructions to produce:
- Canon accuracy check — do articles respect established world facts?
- Narrative quality assessment — does coverage feel like real city journalism?
- Editorial guidance — coverage directives for next cycle
- Anomaly flags — anything exceeding detection thresholds (see Operating Manual Part IV)
Save Mara's Output
- Save audit to
output/mara_directive_c{XX}.txt - Upload to Drive:
node scripts/saveToDrive.js output/mara_directive_c{XX}.txt mara - Apply any corrections Mara flags before final save
- Include Mara's editorial guidance in next cycle's desk briefings
Update Mara's Audit History
After saving the audit, update
docs/mara-vance/AUDIT_HISTORY.md:
- Add Audit Log entry — cycle number, grade, key findings, errors caught, forward guidance summary
- Update Initiative Status Board — if any initiative statuses changed this cycle
- Add Canon Corrections — any new corrections to the registry
- Update Recurring Error Patterns — if new patterns emerged or old ones were resolved
- Update Open Questions — resolve answered questions, add new ones
This keeps Mara's institutional memory current. Next time she audits, she reads this file and knows her own history.
Step 4.9: USER REVIEW GATE (MANDATORY)
STOP HERE. DO NOT PROCEED TO STEP 5 WITHOUT EXPLICIT USER APPROVAL.
This is the hard gate. Nothing gets saved, uploaded, ingested, or published until the user says so. Session 62 taught us what happens when this gate doesn't exist — wrong data pushed to Supermemory, wrong votes pushed to Drive, contaminated memory that future sessions inherit.
What to show the user:
- Edition summary — article count, word count, front page pick, section overview
- Rhea's verdict — score, criticals, warnings, any unresolved issues
- Mara's audit — canon accuracy, narrative quality, forward guidance highlights
- Any corrections applied — what was fixed during compilation or after verification
- New citizens introduced — list any citizens not previously in canon
Present it as:
EDITION {XX} — READY FOR REVIEW Rhea: {SCORE}/100 — {VERDICT} Mara: {ASSESSMENT} Articles: {count} across {desks} desks Word count: ~{total} [Summary of key stories and any issues] The edition is compiled and verified. Nothing has been saved or published yet. Ready to publish? (yes / hold for edits)
Rules:
- Wait for explicit approval. "yes", "approved", "publish", "ship it" — any clear affirmative.
- If the user says hold, make the requested edits, then re-present at this gate.
- NEVER proceed to Step 5 based on your own judgment. Even if Rhea scored 100 and Mara found nothing. The user reviews. Period.
- NEVER say "I'll save this for your review" and then save it. Saving IS publishing in this system.
Step 5: Save Edition & Upload to Drive
After user approval (confirmed at Step 4.9):
- Save to
editions/cycle_pulse_edition_{XX}.txt - If corrections needed, save as
after fixes_v2.txt - Upload to Google Drive:
node scripts/saveToDrive.js editions/cycle_pulse_edition_{XX}.txt edition- Also upload Mara audit if produced:
node scripts/saveToDrive.js output/mara_directive_c{XX}.txt mara - Also upload supplementals if produced:
or...supplement...chicago
- Also upload Mara audit if produced:
- Ingest edition into Supermemory:
This makes the edition searchable for future sessions, the Discord bot, and autonomous scripts.node scripts/ingestEdition.js editions/cycle_pulse_edition_{XX}.txt - Show the user the file path, Drive link, and total stats:
- Article count
- Total word count
- New canon figures introduced
- Citizen usage count
Step 5.1: Generate Edition Brief (Auto-Update Bot Context)
After saving, generate the edition brief that the Discord bot and autonomous scripts use for world awareness. This replaces the manual process that caused the E83→E84 stale brief problem.
Write
with the following structure:output/latest_edition_brief.md
# Latest Edition Brief — Edition {XX} ## Cycle {XX} | {Month} {Year} | {Season} **Published canon. The bot should know these facts.** ### [Front Page headline] ([Reporter]) - [2-3 bullet points: key facts, named citizens, numbers] ### [Each additional article headline] ([Reporter]) - [2-3 bullet points per article] ### Initiative Status (as of E{XX}) - [Each initiative: name, status, vote, key facts] ### Council Composition - OPP: [members] - CRC: [members] - IND: [members] ### Key Citizens Active in E{XX} - [Name, age, neighborhood, occupation — what they said/did] ### Status Alerts - [Any health/absence/condition alerts for civic officials]
You have full context — you just compiled this edition. Pull from the compiled text. Include every article, every quoted citizen, every initiative status. The bot uses this to answer questions about the city. If it's not in the brief, the bot doesn't know it.
For Mayor's Office voice agent statements: If Step 1.8 generated civic voice statements, include a section summarizing the Mayor's positions and key quotes. The bot should be able to reference what the Mayor actually said.
Step 5.2: Refresh Live Services
After the edition brief is written, clear the bot's stale conversation history and reload so it starts fresh with the new canon:
echo '{"savedAt":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","history":[]}' > logs/discord-conversation-history.json pm2 reload mags-discord-bot
Why clear history: The bot persists conversation history across restarts. If she said "no Edition 84 yet" before the brief was updated, that stale response stays in her context and she'll keep saying it even after the system prompt has the new data. Clean slate after every publish.
Dashboard does NOT need a restart — it reads
base_context.json fresh on each HTTP request. No action needed.
Moltbook heartbeat will pick up the new world state on its next 30-minute cron run automatically. No action needed.
After reload, confirm the bot is online:
pm2 list | grep mags-discord-bot
Step 5.5: Update Newsroom Memory
After verification and before intake, update the institutional memory:
- Read Rhea's verification report from Step 4
- Review Mags' own editorial notes from Step 3 compilation
- Append structured errata (Phase 6.2 — automated):
- If Rhea's report was saved to a file, run:
node scripts/appendErrata.js --edition {XX} --report output/rhea_report_c{XX}.txt - For any additional errors found during compilation or Mara audit, add manually:
node scripts/appendErrata.js --edition {XX} --manual --desk {desk} --errorType {type} --severity CRITICAL --description "..." --fix "..." - This keeps
current for the next edition's guardian checksoutput/errata.jsonl
- If Rhea's report was saved to a file, run:
- Update
:docs/mags-corliss/NEWSROOM_MEMORY.md- Add new prose errata entries for this edition (desk-specific issues found)
- Update character continuity (new citizens introduced, threads resolved)
- Revise coverage patterns (what landed, what fell flat)
- Archive errata older than 5 editions
- Update the "Last Updated" header line
This step ensures the next edition benefits from this edition's lessons. Claude-Mem will auto-capture observations during this update.
Step 5.6: Log Edition Score
After Rhea's verification and any corrections, log the edition score to
output/edition_scores.json:
- Read Rhea's verification report (scores, criticals, warnings, notes)
- Append a new entry to the
array inscores
:output/edition_scores.json{ "edition": XX, "cycle": XX, "date": "YYYY-MM-DD", "grade": "A|A-|B+|B|...", "total": 85, "dataAccuracy": 17, "voiceFidelity": 18, "structuralCompleteness": 17, "narrativeQuality": 18, "canonCompliance": 15, "criticals": 2, "warnings": 3, "notes": 1, "claimDecomposition": { "extracted": 45, "verified": 40, "errors": 2, "unverifiable": 3 }, "deskErrors": { "civic": ["specific error descriptions"], "sports": [], "chicago": [], "culture": [], "business": [], "letters": [] }, "noteText": "Brief editorial summary of this edition." } - Run the trend report (optional but recommended):
This generatesnode scripts/editionDiffReport.js --save
with trend tables, desk error frequency, recurring patterns, and summary stats.output/edition_diff_report.md
The score log builds over time. After 5+ editions, the trend data becomes genuinely useful — showing which desks improve, which errors recur, and whether pipeline changes (voice files, claim decomposition, etc.) are working.
Step 6: Intake (Optional)
Ask if the user wants to run the intake pipeline now:
node scripts/editionIntake.js editions/cycle_pulse_edition_{XX}.txt --dry-run
If dry-run looks good:
node scripts/editionIntake.js editions/cycle_pulse_edition_{XX}.txt node scripts/processIntake.js [cycle]
Desk Summary
| Desk | Lead | Articles | Summary (start here) | Full Packet |
|---|---|---|---|---|
| Civic | Carmen Delaine | 2-4 | civic_summary_c{XX}.json | civic_c{XX}.json |
| Sports | P Slayer / Anthony | 2-5 | sports_summary_c{XX}.json | sports_c{XX}.json |
| Culture | Maria Keen | 2-4 | culture_summary_c{XX}.json | culture_c{XX}.json |
| Business | Jordan Velez | 1-2 | business_summary_c{XX}.json | business_c{XX}.json |
| Chicago | Selena Grant / Talia Finch | 2-3 | chicago_summary_c{XX}.json | chicago_c{XX}.json |
| Letters | (citizen voices) | 2-4 | letters_summary_c{XX}.json | letters_c{XX}.json |
Model & Performance Notes
mode: For edition production sessions, consider running Mags on opusplan
opusplan (/model opusplan). This uses Opus for planning and briefing (Steps 1-1.5) and automatically switches to Sonnet for agent execution (Steps 2+). Saves cost without sacrificing editorial planning quality.
Effort levels: Opus 4.6 supports
low, medium, high (default) effort. High effort is correct for edition production. For routine file checks or status lookups between editions, medium or low saves tokens and time. Set with /model slider or CLAUDE_CODE_EFFORT_LEVEL env var.
Mara as teammate: Mara Vance on claude.ai is architecturally equivalent to an agent team teammate — own context window, shared memory (
docs/mara-vance/AUDIT_HISTORY.md), asynchronous communication. When Claude Code formally supports agent teams for production use, the Mara workflow is the natural first candidate for migration. Until then, she operates as a manual teammate through browser, with file-based persistence on disk.
Edition Template Reference
See
editions/CYCLE_PULSE_TEMPLATE.md for exact section format, canon rules, and return formats.