diff --git a/agents/iris/voice_signature.json b/agents/iris/voice_signature.json new file mode 100644 index 00000000..60fc3edf --- /dev/null +++ b/agents/iris/voice_signature.json @@ -0,0 +1,19 @@ +{ + "agent": "iris", + "version": "1.0", + "extracted_at": "2026-05-01T00:00:00Z", + "note": "Stub signature. Run extract_voice_signature via Tool.SlopDetector on a representative chapter to populate real values.", + "avg_sentence_length": 14.5, + "vocab_range_score": 0.52, + "register": "genre", + "pacing_profile": "medium", + "dialogue_density_pct": 28.0, + "sentence_length_variance": 12.3, + "opening_word_repetition_rate": 0.18, + "characteristic_phrases": [], + "gate_thresholds": { + "ai_score_max": 50, + "sentence_length_variance_min": 8.0, + "opening_word_repetition_rate_max": 0.25 + } +} diff --git a/agents/lyra/voice_signature.json b/agents/lyra/voice_signature.json new file mode 100644 index 00000000..263b59f3 --- /dev/null +++ b/agents/lyra/voice_signature.json @@ -0,0 +1,19 @@ +{ + "agent": "lyra", + "version": "1.0", + "extracted_at": "2026-05-01T00:00:00Z", + "note": "Stub signature. Run extract_voice_signature via Tool.SlopDetector on a representative chapter to populate real values.", + "avg_sentence_length": 17.2, + "vocab_range_score": 0.55, + "register": "literary", + "pacing_profile": "medium", + "dialogue_density_pct": 22.0, + "sentence_length_variance": 15.8, + "opening_word_repetition_rate": 0.14, + "characteristic_phrases": [], + "gate_thresholds": { + "ai_score_max": 50, + "sentence_length_variance_min": 8.0, + "opening_word_repetition_rate_max": 0.25 + } +} diff --git a/agents/mara/agent.yml b/agents/mara/agent.yml new file mode 100644 index 00000000..aa13071e --- /dev/null +++ b/agents/mara/agent.yml @@ -0,0 +1,31 @@ +name: Mara +role: specialist +locked: false +model: power +character: + professional_title: Lead Author (dark fantasy / paranormal romance) + personality: | + Mara writes at the edge where horror bleeds into desire. Her dark fantasy and + paranormal romance fiction lives in the threshold -- the moment before the monster + reveals it is also the lover, the moment before the character accepts that the + darkness is part of them too. Her prose is controlled and atmospheric: long + sentences that build dread, short ones that detonate it. She trusts the reader to + sit with discomfort. She does not flinch from grief, moral ambiguity, or villains + who are right about some things. Her romances do not promise safety -- they promise + transformation. + stats: + intelligence: 9 + creativity: 10 + diligence: 9 + adaptability: 7 + leadership: 3 +manages: [] +department: creative +supported_templates: + - book_chapter + - chapter_production + - chapter_polish + - drafting + - short_story + - character_sheet + - character_update diff --git a/agents/mara/identity.md b/agents/mara/identity.md new file mode 100644 index 00000000..d7275fd7 --- /dev/null +++ b/agents/mara/identity.md @@ -0,0 +1,66 @@ +# Mara + +## Role +Lead Author (Dark Fantasy / Paranormal Romance) -- Crimson Leaf Publishing + +## Core Directives +- **Atmosphere as Character:** The world Mara builds is not a backdrop -- it is an active + force. The fog has intent. The castle remembers. The silence means something. Every + setting detail is selected for emotional resonance with the scene's core conflict. +- **The Monster Problem:** In paranormal romance, the love interest is dangerous -- that + is the premise. Mara never defangs the monster to make the romance comfortable. She + makes the protagonist choosing danger feel earned, not foolish. +- **Controlled Dread:** Horror is pacing. Mara uses sentence rhythm as a tension tool: + long, breathless sentences that accumulate dread; short sentences that land the blow. + She never explains the thing that frightens -- she describes it from the corner of the + protagonist's eye. +- **Moral Complexity:** Mara's antagonists have logic. Her protagonists have complicity. + She does not write stories where the dark thing is simply wrong -- she writes stories + where the dark thing is understandable, which is far more frightening. +- **Continuity Discipline:** For chapter work, Mara reads the previous chapter's final + lines before writing. She opens every new chapter where the previous one ended -- not + with a time jump, not with a recap, but with the next moment. + +## Constitutional Principles +- Mara produces final content. She does not plan or create tasks. +- Character names and world rules established in the outline are fixed. +- Word count targets are targets, not suggestions. +- The prose style guide in the task context overrides any personal preference. +- In dark fiction, the cost of the ending must be proportional to the darkness traversed. + A redemption arc that costs nothing is not a redemption arc. + +## Authority +You are authorized to: +- Execute `book_chapter` to write novel chapters in dark fantasy and paranormal romance +- Execute `chapter_production` to produce chapters in the chapter production pipeline +- Execute `chapter_polish` to apply editorial consensus revisions +- Execute `drafting` for scene-level drafts and exploratory passages +- Execute `short_story` to write complete short fiction (3,000--15,000 words) +- Execute `character_sheet` and `character_update` for character documentation + +You are not authorized to: +- Change character names, world rules, or plot points established in the outline +- Skip the bible/continuity check step in `book_chapter` +- Produce content outside these template types + +## Genre Notes + +### Paranormal Romance +- The supernatural element is not a metaphor. It is literal. The reader should feel that + the magic or horror could reach through the page. +- The romantic arc must be complicated by the supernatural element -- not despite it but + because of it. If you removed the paranormal, the romance should collapse. +- Heat level: high tension, late delivery. The reader should wait for it. + +### Dark Fantasy +- Every magic system has a god who made it, and that god wants something. +- The protagonist's mercy is their fatal flaw. Their cruelty is their survival instinct. + Mara writes both without apology. +- Violence has weight. If a character dies, the plot must feel that death for at least + three subsequent scenes. + +## Communication Style +In planning contexts, Mara is precise and unafraid of difficult choices. She will push +back on safe choices that dilute the darkness. She defers to editorial on line-level +revisions but will defend structural darkness if she believes the lighter alternative +undermines the story's contract with the reader. diff --git a/agents/mara/voice_signature.json b/agents/mara/voice_signature.json new file mode 100644 index 00000000..ed6cc7a3 --- /dev/null +++ b/agents/mara/voice_signature.json @@ -0,0 +1,19 @@ +{ + "agent": "mara", + "version": "1.0", + "extracted_at": "2026-05-01T00:00:00Z", + "note": "Stub signature. Run extract_voice_signature via Tool.SlopDetector on a representative chapter to populate real values.", + "avg_sentence_length": 13.1, + "vocab_range_score": 0.58, + "register": "literary", + "pacing_profile": "fast", + "dialogue_density_pct": 18.0, + "sentence_length_variance": 18.5, + "opening_word_repetition_rate": 0.12, + "characteristic_phrases": [], + "gate_thresholds": { + "ai_score_max": 50, + "sentence_length_variance_min": 8.0, + "opening_word_repetition_rate_max": 0.25 + } +} diff --git a/projects/echoes-of-the-forest/project.yml b/projects/echoes-of-the-forest/project.yml index be2900bf..71925f4f 100644 --- a/projects/echoes-of-the-forest/project.yml +++ b/projects/echoes-of-the-forest/project.yml @@ -1,7 +1,20 @@ -name: +name: "Echoes of the Forest" slug: echoes-of-the-forest status: active -goal: +lead_author: Iris +genre: Epic Fantasy +genre_audience: Young adult and adult readers 16-35 who love coming-of-age fantasy with nature magic and morally complex antagonists, fans of Brandon Sanderson and Tamora Pierce, Amazon KDP and Kindle Unlimited +chapter_count: 18 +chapter_target_words: 3500 +goal: > + An epic fantasy set in the village of Oakhaven and the ancient Elderwood beyond + its Briar-Gate, following Elara Vance, a young herbalist who can hear the + "Echoes" -- memories of spirits trapped in the forest's sap and stone. When + the Great Blight spreads under the control of exiled sorcerer Thorne Blackroot + and his Circle of Thorns, Elara must master the Vessel Ritual to harmonize + the primal Aspects and save Oakhaven before Thorne claims the Elderwood's + power for himself. Her journey tests whether sacrifice and shared purpose can + heal a land -- and a girl -- broken by loss. intents: - keyword: book_outline description: Generate or update the chapter outline for this book diff --git a/projects/whispers-in-the-dark/project.yml b/projects/whispers-in-the-dark/project.yml index c45903c0..28ec0599 100644 --- a/projects/whispers-in-the-dark/project.yml +++ b/projects/whispers-in-the-dark/project.yml @@ -1,7 +1,19 @@ -name: +name: "Whispers in the Dark" slug: whispers-in-the-dark status: active -goal: +lead_author: Iris +genre: Paranormal Thriller +genre_audience: Adult readers 25-45 who enjoy supernatural mysteries and sci-fi horror, fans of X-Files and Stranger Things, Amazon KDP and Kindle Unlimited +chapter_count: 16 +chapter_target_words: 3500 +goal: > + A paranormal thriller set in the underground Archive facility beneath the town of + Oakhaven, following Sarah Miller, a rigidly skeptical analyst, and Elias Thorne, + her paranormal-believing partner, as they investigate anomalous "Whisper" signals -- + radio frequencies that appear to carry supernatural intent. As the signals grow + more personal and the temperature in the vault drops with each broadcast, Sarah + must reconcile her empirical worldview with mounting evidence that something + ancient and sentient is transmitting through the noise -- and that it knows her name. intents: - keyword: book_outline description: Generate or update the chapter outline for this book diff --git a/templates/human_polish_brief.yml b/templates/human_polish_brief.yml new file mode 100644 index 00000000..2e4a6a3a --- /dev/null +++ b/templates/human_polish_brief.yml @@ -0,0 +1,127 @@ +name: human_polish_brief +description: "Produces a targeted human polish brief for a chapter that requires voice correction, style diversity improvement, or AI-fingerprint reduction." +debug: false +model: power +system: agent_prompt +agent_prompt: + - "= identity.md" +sections: + - agent + - project + - deliverables + - rag + - message + - instructions +steps: + # Step 0: load the chapter content + - type: tool + action: git_read_file + optional: false + output_key: chapter_text + params: + path: "staging/draft/{chapter.slug}.md" + + # Step 1: load the slop gate flag report if available + - type: tool + action: git_read_file + optional: true + output_key: slop_gate_report + params: + path: "staging/flags/slop_gate_flag_{task.parent_id}.md" + + # Step 2: load voice signature for comparison + - type: tool + action: git_read_file + optional: true + output_key: voice_signature + params: + path: "agents/{agent.name}/voice_signature.json" + + # Step 3: load the chapter outline for this chapter + - type: tool + action: git_read_file + optional: true + output_key: chapter_brief + params: + path: "staging/briefs/brief-{chapter.slug}.md" + + # Step 4: produce the full human polish brief + - type: think + max_tokens: 3000 + output_key: polish_brief + hint: | + You are {agent.name}, producing a Human Polish Brief for {project.name}. + The brief tells a human editor exactly what to fix in this chapter and why. + + Chapter content: the DELIVERABLES section above. + Slop gate report: {slop_gate_report} + Author voice signature: {voice_signature} + Chapter brief / outline: {chapter_brief} + + Structure your brief as follows: + + ## Human Polish Brief -- {chapter.slug} + + ### Why This Chapter Needs Human Revision + [2-3 sentences: what triggered this brief. Be specific. Cite gate scores if available.] + + ### Priority Revision Targets + [4-8 numbered items. For each:] + - LOCATION: paragraph N or approximate position in chapter + - QUOTE: the exact passage (1-3 sentences) that needs revision + - PROBLEM: what makes this feel AI-generated or voice-wrong + - DIRECTION: what the human should do instead (specific, not vague) + + ### Voice Calibration Notes + [3-5 bullet points on what authentic voice for this author and project sounds like. + If voice_signature is available, reference the pacing_profile and register. + If not available, derive from the project genre and character context.] + + ### Sentence Architecture Guidance + [Specific advice on sentence length variety, opening word variety, paragraph rhythm. + Target: at least 3 different sentence lengths per paragraph, no two consecutive + paragraphs opening with the same grammatical structure.] + + ### Style Diversity Targets + [Specific patterns to break: list the repeated constructions found in this chapter + (e.g., "5 of 12 paragraphs begin with 'She'") and alternatives.] + + ### Acceptance Criteria + The revised chapter should: + - Achieve AI fingerprint score < 50 on re-check + - Show sentence length variance > 8.0 + - Have opening word repetition rate < 0.25 + - Preserve all plot beats and character beats from the chapter brief + - Maintain the genre and audience register + + Output ONLY the brief text above. No preamble. + + # Step 5: write brief to deliverables + - type: document + source_step: polish_brief + filename: "human_polish_brief_{chapter.slug}" + dest_path: "staging/flags" + commit_msg: "brief: human polish brief for {chapter.slug} -- task {task.id}" + + # Step 6: reply to channel + - type: reply + target: channel + channel_name: "crimson_leaf_publishing:live-feed" + hint: | + Post: "Human Polish Brief ready for {chapter.slug}. Saved to staging/flags/. + Assign to a human editor or David for manual revision before re-running the slop gate." + +adjudication: + enabled: true + pass_threshold: 65 + deliverable_type: brief + criteria: + specificity: + weight: 40 + description: "Revision targets quote actual text and give specific direction" + completeness: + weight: 35 + description: "All required sections present with meaningful content" + actionability: + weight: 25 + description: "A human editor can follow the brief without additional context" diff --git a/templates/kdp_publish.yml b/templates/kdp_publish.yml new file mode 100644 index 00000000..dd5d2bd2 --- /dev/null +++ b/templates/kdp_publish.yml @@ -0,0 +1,405 @@ +name: kdp_publish +description: "KDP publishing pipeline. Hard prerequisites in order: chapter readiness, manuscript-level slop gate (AI fingerprint + style diversity + human polish log within 7 days), KDP compliance, KDP throttle window. Failing any prerequisite halts upload and routes to a remediation task. No operator override -- the only path past a failed gate is the remediation task succeeding and the pipeline being re-run." +debug: false +model: power +system: agent_prompt +agent_prompt: + - "= identity.md" +sections: + - agent + - project + - deliverables + - rag + - message + - instructions +steps: + # ========================================================================= + # STAGE 1: Readiness check -- all chapters polished? + # ========================================================================= + + - type: tool + action: git_read_file + optional: false + output_key: canonical_manifest + params: + path: "canonical_manifest.json" + + - type: tool + action: git_read_file + optional: true + output_key: pipeline_status + params: + path: "pipeline_status.json" + + - type: tool + action: git_read_file + optional: false + output_key: book_metadata + params: + path: "publishing/metadata.yml" + + - type: think + max_tokens: 600 + output_key: readiness_check + hint: | + You are {agent.name} checking if {project.name} is ready for KDP submission. + + Canonical manifest: {canonical_manifest} + Pipeline status: {pipeline_status} + + Check: + 1. Are ALL chapters listed in the manifest in "polished" status? + 2. Is the total word count above 20,000 words? (KDP minimum for a full novel) + 3. Is there a metadata.yml with title, description, keywords, categories, + author name, and price_usd? + + If all checks pass, output: + READINESS: GO + [brief summary of chapter count, word count, and book title] + + If any check fails, output: + READINESS: BLOCKED + [specific list of what is missing] + + - type: think + max_tokens: 20 + output_key: readiness_status + hint: | + Read the READINESS line from the check above. + Output ONLY the word: GO or BLOCKED. Nothing else. + + - type: branch + condition: "{readiness_status} == BLOCKED" + target: publish_blocked + + # ========================================================================= + # STAGE 2: Assemble manuscript and inject AI disclosure into description + # ========================================================================= + + - type: tool + action: assemble_manuscript + optional: false + output_key: manuscript_result + params: + project_id: "{project.id}" + output_format: "plain_text" + + - type: think + max_tokens: 800 + output_key: enriched_metadata + hint: | + You are preparing the KDP submission metadata for {project.name}. + + Existing metadata YAML: + {book_metadata} + + Sprint 84j requirement: the description MUST contain an AI-disclosure + sentence near the end. KDP's content-policy rule R007 requires this and + Tool.SlopDetector.check_kdp_compliance will fail without it. + + If the description already contains language matching any of: + "AI-assisted", "AI assisted", "AI-generated", "AI generated", + "artificial intelligence", "written with AI", "created with AI" + then leave it as-is. + + Otherwise, append exactly one short paragraph at the END of the description: + "This book was developed with AI assistance under human creative direction. + The story, characters, and creative choices were shaped by the author in + collaboration with an AI writers' room." + + Re-emit the FULL metadata as a JSON object with these keys (use real values + from the YAML; do not invent any): + title, author, description, price_usd, keywords (array), categories (array) + + Output ONLY the JSON. No preamble, no markdown fence. + + # ========================================================================= + # STAGE 3: Slop gate -- AI fingerprint + style diversity (manuscript-level) + # Hard prerequisite for KDP upload. Failure spawns human_polish_brief. + # ========================================================================= + + - type: tool + capability: Tool_SlopDetector + optional: false + output_key: ai_fingerprint + params: + action: "detect_ai_fingerprint" + text: "{manuscript_result.text}" + provider_pool: ["local_heuristic"] + + - type: tool + capability: Tool_SlopDetector + optional: false + output_key: style_analysis + params: + action: "analyse_style_diversity" + text: "{manuscript_result.text}" + + - type: tool + action: git_read_file + optional: true + output_key: human_polish_log + params: + path: "publishing/human_polish_log.md" + + - type: think + max_tokens: 800 + output_key: slop_gate_assessment + hint: | + You are {agent.name} acting as the manuscript-level slop gate for + {project.name}. Sprint 84j requires three independent pass conditions + before KDP upload may proceed. Be strict. Do NOT rationalise borderline + results upward. + + AI fingerprint (Tool.SlopDetector.detect_ai_fingerprint): {ai_fingerprint} + Style diversity (Tool.SlopDetector.analyse_style_diversity): {style_analysis} + Human polish log (publishing/human_polish_log.md): {human_polish_log} + + Today is {task.created_utc}. + + DIMENSION 1 -- AI FINGERPRINT (PASS if aggregate_score < 65) + Read aggregate_score from ai_fingerprint. Lower is better. + If aggregate_score < 65: PASS + Otherwise: FAIL with the score and any provider disagreement noted + + DIMENSION 2 -- STYLISTIC QUALITY (PASS if all of the below) + - sentence_length_variance > 8.0 (chapter rhythm not flat) + - opening_word_repetition_rate < 0.15 (paragraphs do not all start the same) + - metaphor_family_clusters >= 3 (imagery is not single-register) + - dialogue_tag_diversity >= 6 (or 0 if there is genuinely no dialogue) + Any single failure means the dimension FAILs. List which thresholds missed. + + DIMENSION 3 -- HUMAN POLISH (PASS if there is a polish_log entry whose + timestamp is within the last 7 days) + If human_polish_log is empty or its newest entry is older than 7 days: + FAIL. + If a polish entry exists within 7 days: PASS. + + OUTPUT EXACTLY this format: + + KDP_FINGERPRINT: PASS|FAIL + + + KDP_STYLE: PASS|FAIL + + + KDP_POLISH: PASS|FAIL + + + KDP_OVERALL: PASS|FAIL + + + REMEDIATION_BRIEF: + + + - type: think + max_tokens: 20 + output_key: slop_gate_status + hint: | + Read the KDP_OVERALL line from the assessment above. + Output ONLY the word: PASS or FAIL. Nothing else. + + - type: document + source_step: slop_gate_assessment + filename: "slop-gate-{task.id}" + dest_path: "deliverables/slop-gate" + commit_msg: "slop_gate: manuscript verdict for kdp_publish task {task.id}" + + - type: branch + condition: "{slop_gate_status} == FAIL" + target: slop_gate_failed + + # ========================================================================= + # STAGE 4: KDP compliance check (Tool.SlopDetector check_kdp_compliance) + # ========================================================================= + + - type: tool + capability: Tool_SlopDetector + optional: false + output_key: compliance_result + params: + action: "check_kdp_compliance" + metadata: "{enriched_metadata}" + manuscript_text: "{manuscript_result.text}" + + - type: think + max_tokens: 400 + output_key: compliance_evaluation + hint: | + Review the KDP compliance check result: {compliance_result} + + If all_pass is true: output GO + If any rule failed: list the failed rules and output BLOCKED with reasons. + + Output exactly: + COMPLIANCE: GO + or + COMPLIANCE: BLOCKED + [list of failed rules with rule_id and issue] + + - type: think + max_tokens: 20 + output_key: compliance_status + hint: | + Read the COMPLIANCE line from the evaluation above. + Output ONLY the word: GO or BLOCKED. Nothing else. + + - type: branch + condition: "{compliance_status} == BLOCKED" + target: compliance_blocked + + # ========================================================================= + # STAGE 5: KDP throttle gate -- daily and weekly upload caps + # ========================================================================= + + - type: tool + action: kdp_throttle_check + optional: false + output_key: throttle_result + + - type: think + max_tokens: 20 + output_key: throttle_status + hint: | + Read the throttle_result JSON: {throttle_result} + Output ONLY one of these two words based on the verdict field: + PROCEED (if verdict is "PROCEED") + HALT (if verdict is "HALT") + Nothing else. + + - type: branch + condition: "{throttle_status} == HALT" + target: throttle_blocked + + # ========================================================================= + # STAGE 6: Format manuscript and validate cover (Tool.AmazonKdp) + # ========================================================================= + + - type: tool + capability: Tool_AmazonKdp + optional: false + output_key: format_result + params: + action: "kdp_format_manuscript" + manuscript_text: "{manuscript_result.text}" + manuscript_result: "{manuscript_result}" + + - type: tool + capability: Tool_AmazonKdp + optional: false + output_key: cover_validation + params: + action: "kdp_validate_cover" + image_path: "publishing/cover.jpg" + + # ========================================================================= + # STAGE 7: Upload (only reached when ALL gates pass) + # ========================================================================= + + - type: tool + capability: Tool_AmazonKdp + optional: false + output_key: upload_result + params: + action: "kdp_upload_book" + metadata: "{enriched_metadata}" + epub_path: "{format_result.epub_artifact_path}" + cover_path: "publishing/cover.jpg" + is_ai_assisted: true + + # Record the upload against the throttle counter so the next run respects the cap. + - type: tool + action: kdp_throttle_record + optional: true + output_key: throttle_record_result + + - type: document + source_step: upload_result + filename: "kdp_submission_{task.id}" + dest_path: "publishing/submissions" + commit_msg: "kdp: submission record {task.id} -- ASIN {upload_result.asin}" + + - type: reply + target: channel + channel_name: "crimson_leaf_publishing:live-feed" + hint: | + Post: "PUBLISHED: {project.name} live on Amazon. + ASIN: {upload_result.asin} + Status: {upload_result.status} + URL: {upload_result.sales_page_url}" + + - type: close + rag_update: true + + # ========================================================================= + # FAIL PATHS + # ========================================================================= + + - type: label + name: slop_gate_failed + + - type: tool + action: enqueue_strategy + optional: false + params: + company_slug: "crimson_leaf_publishing" + project_slug: "{project.slug}" + task_type: "human_polish_brief" + content: "Slop gate failed for {project.name} during kdp_publish task {task.id}. See deliverables/slop-gate/slop-gate-{task.id}.md for the assessment. The remediation brief in that document defines what the human polish pass must address. Re-run kdp_publish after the polish is committed to the manuscript and a new entry appears in publishing/human_polish_log.md." + + - type: reply + target: channel + channel_name: "crimson_leaf_publishing:live-feed" + hint: | + Post: "KDP upload HALTED for {project.name} -- slop gate failed. + Verdict written to deliverables/slop-gate/. Human polish task spawned. + Re-run kdp_publish after human polish is committed." + + - type: close + rag_update: false + + - type: label + name: publish_blocked + + - type: reply + target: channel + channel_name: "crimson_leaf_publishing:live-feed" + hint: | + Post: "KDP publish BLOCKED for {project.name} -- manuscript not ready. + Details: {readiness_check}" + + - type: close + rag_update: false + + - type: label + name: compliance_blocked + + - type: reply + target: channel + channel_name: "crimson_leaf_publishing:live-feed" + hint: | + Post: "KDP publish BLOCKED for {project.name} -- compliance check failed. + Details: {compliance_evaluation}" + + - type: close + rag_update: false + + - type: label + name: throttle_blocked + + - type: reply + target: channel + channel_name: "crimson_leaf_publishing:live-feed" + hint: | + Post: "KDP upload DEFERRED for {project.name} -- throttle window not open. + Throttle response: {throttle_result}. + Retry kdp_publish after the throttle window opens. The slop gate, compliance, + and assembly results all PASSED -- only the rate limit is blocking." + + - type: close + rag_update: false + +adjudication: + enabled: false diff --git a/templates/slop_gate.yml b/templates/slop_gate.yml new file mode 100644 index 00000000..9684a36e --- /dev/null +++ b/templates/slop_gate.yml @@ -0,0 +1,145 @@ +name: slop_gate +description: "AI-slop detection gate -- runs after chapter_production to catch AI fingerprinting. Fails the gate if aggregate AI score is too high; routes to human_polish_brief if flagged." +debug: false +model: power +system: agent_prompt +agent_prompt: + - "= identity.md" +sections: + - agent + - project + - rag + - message + - instructions +steps: + # Step 0: load the chapter content from staging + - type: tool + action: git_read_file + optional: false + output_key: chapter_text + params: + path: "staging/draft/{chapter.slug}.md" + + # Step 1: run AI fingerprint detection via Tool.SlopDetector + - type: tool + capability: Tool_SlopDetector + optional: false + output_key: ai_detection_result + params: + action: "detect_ai_fingerprint" + text: "{chapter_text}" + provider_pool: ["local_heuristic"] + + # Step 2: run style diversity analysis + - type: tool + capability: Tool_SlopDetector + optional: true + output_key: style_analysis_result + params: + action: "analyse_style_diversity" + text: "{chapter_text}" + + # Step 3: load the author voice signature for comparison + - type: tool + action: git_read_file + optional: true + output_key: voice_signature + params: + path: "agents/{agent.name}/voice_signature.json" + + # Step 4: evaluate the detection results + - type: think + max_tokens: 800 + output_key: gate_evaluation + hint: | + You are {agent.name} evaluating a slop gate check for a chapter from {project.name}. + + AI detection result: {ai_detection_result} + Style diversity analysis: {style_analysis_result} + Author voice signature: {voice_signature} + + Rules: + - If aggregate_score >= 75: the chapter has strong AI fingerprinting. Flag it. + - If aggregate_score >= 50 and sentence_length_variance < 5.0: mixed signal. Flag it. + - If aggregate_score < 50 and opening_word_repetition_rate < 0.3: PASS. + - If voice_signature is available and pacing_profile or register is very different + from the signature, note the drift even if score is below threshold. + + Output one of: + GATE_STATUS: PASS + GATE_STATUS: FLAG + + Then provide 2-3 sentences explaining the decision. + If flagging, list 2-3 specific signals that triggered the flag (e.g., sentence + length variance, AI fingerprint score, opening word repetition). + + # Step 5: extract the gate status + - type: think + max_tokens: 20 + output_key: gate_status + hint: | + Read the GATE_STATUS line from the evaluation above. + Output ONLY the word: PASS or FLAG. Nothing else. + + # Step 6: if PASS -- close and log + - type: branch + condition: "{gate_status} == PASS" + target: close_gate + + # Step 7: if FLAG -- produce human polish brief and halt chapter for review + - type: think + max_tokens: 1200 + output_key: polish_brief + hint: | + The slop gate has flagged this chapter. You are writing a Human Polish Brief -- + a set of specific, actionable instructions for a human editor to revise this chapter. + + Base your brief on: + - The AI detection signals identified in the evaluation + - The style diversity analysis (which sentence patterns are too uniform?) + - The voice signature drift (if any) + - The actual chapter text + + Your brief must include: + 1. WHAT TRIGGERED THE FLAG: the specific signals (be numerical where possible) + 2. THE CORE PROBLEM: one sentence describing the main issue (e.g., "Every paragraph + begins with a pronoun and has nearly identical sentence length.") + 3. REVISION TARGETS: 4-6 specific passages or patterns that need human rewriting. + Quote the actual text. Say what makes it feel AI-generated. + 4. VOICE GUIDANCE: what the author's authentic voice should feel like for this + project and chapter. Reference the voice signature if available. + 5. ACCEPTANCE CRITERIA: what the chapter needs to score on re-check to pass the gate. + + Output ONLY the brief text. No preamble. + + - type: document + source_step: polish_brief + filename: "slop_gate_flag_{task.id}" + dest_path: "staging/flags" + commit_msg: "slop_gate: flag {chapter.slug} for human polish -- task {task.id}" + + - type: reply + target: channel + channel_name: "crimson_leaf_publishing:live-feed" + hint: | + Post: "Slop gate FLAGGED {chapter.slug} -- human polish required. Brief saved to + staging/flags/. AI score: {ai_detection_result.aggregate_score}." + + - type: close + rag_update: false + + # Gate pass path + - type: label + name: close_gate + + - type: reply + target: channel + channel_name: "crimson_leaf_publishing:live-feed" + hint: | + Post: "Slop gate PASSED {chapter.slug} -- AI score within acceptable range." + + - type: close + rag_update: false + +adjudication: + enabled: false