406 lines
13 KiB
YAML
406 lines
13 KiB
YAML
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
|
|
<one-sentence justification with score>
|
|
|
|
KDP_STYLE: PASS|FAIL
|
|
<one-sentence justification with the specific style metrics that crossed/missed>
|
|
|
|
KDP_POLISH: PASS|FAIL
|
|
<one-sentence justification citing the most recent polish_log timestamp or its absence>
|
|
|
|
KDP_OVERALL: PASS|FAIL
|
|
<PASS only if all three dimensions are PASS; otherwise FAIL>
|
|
|
|
REMEDIATION_BRIEF:
|
|
<if KDP_OVERALL is FAIL: 3-6 sentences describing what the human polish task should
|
|
target -- specific chapters, specific style metrics, specific opening passages.
|
|
If KDP_OVERALL is PASS: write the literal string "n/a">
|
|
|
|
- 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
|