[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CAXASNKYPQ0249SW7NQT2D":3,"skill-same:01M6CAXASNKYPQ0249SW7NQT2D":91},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":27,"publishedAt":55,"linkOnly":56,"markdownContent":57,"markdownBody":58,"frontMatter":59,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":6,"ownerHtmlUrl":65,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":66,"install":67,"resources":80},"01M6CAXASNKYPQ0249SW7NQT2D","worldai-campaign-to-google-doc",null,"Consolidate all artifacts for a your-project.com campaign module — the world_reference\u002F markdown files (V1 campaign bible + V1\u002FV2 god-mechanics specs + Faerûn pantheon docs), its live GitHub PR, the Gemini share-link source, and any $PROJECT_ROOT\u002F code references — into a single shareable Google Doc. Use when the user says \"put everything for [campaign] in a Google Doc\", \"update the existing one — don't miss anything\", \"consolidate the [campaign] doc\", or asks for a single shareable artifact. Also fires for **edit-existing-campaign-doc** when the user wants to strip historical\u002Faudit content, fix a canonical fact, or apply LLM-input hygiene to an existing campaign doc (\"remove historical stuff\", \"fix the king\", \"no scar on her nose\"). Not for designing a new campaign (campaign-bible-design), not for exporting a prod Firestore campaign (download-campaign), not for reading an existing Google Doc (google-credentials-fallback).","jleechanorg\u002Fjleechan-skills","jleechanorg","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F221404966?v=4","01M6C1VJ99XG950X1DWPEBCBGX","01M6C1VJDK5YVDNT3362RT5WSB",6,"MIT","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fworldarchitect\u002Fworldai-campaign-to-google-doc\u002FSKILL.md",[17,22],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000019","营销推广","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":25,"taxonomyTypeDesc":26},"01JBSEEDCAT000000000000035","市场营销","PROFESSION","适用职业",[28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54],"google","doc","worldai campaign to google doc","campaign","for","design","reading","input","module","live","project","artifact","fallback","files","use","remove","fix","edit","markdown","credentials","audit","share","artifacts","code","update","pr","gemini","2026-11-10 10:12:30",false,"---\nname: worldai-campaign-to-google-doc\ndescription: Consolidate all artifacts for a your-project.com campaign module — the world_reference\u002F markdown files (V1 campaign bible + V1\u002FV2 god-mechanics specs + Faerûn pantheon docs), its live GitHub PR, the Gemini share-link source, and any $PROJECT_ROOT\u002F code references — into a single shareable Google Doc. Use when the user says \"put everything for [campaign] in a Google Doc\", \"update the existing one — don't miss anything\", \"consolidate the [campaign] doc\", or asks for a single shareable artifact. Also fires for **edit-existing-campaign-doc** when the user wants to strip historical\u002Faudit content, fix a canonical fact, or apply LLM-input hygiene to an existing campaign doc (\"remove historical stuff\", \"fix the king\", \"no scar on her nose\"). Not for designing a new campaign (campaign-bible-design), not for exporting a prod Firestore campaign (download-campaign), not for reading an existing Google Doc (google-credentials-fallback).\n---\n\n# worldai-campaign-to-google-doc\n\nConsolidate every artifact attached to a your-project.com campaign into one Google Doc. Verified 2026-07-21 on the God of Murder \u002F Sanguine Architecture case: produced a 104 KB \u002F 1,479-line \u002F ~16,000-word doc covering 4 stitched source files + PR link + Gemini source attribution, in a single `gog docs write --replace --markdown -f` call.\n\n## When to fire\n\n- User asks to \"put everything for [campaign] in a Google Doc\"\n- User asks to \"update the existing one — don't miss anything\"\n- After iterative V1→V2 design work on a world_reference\u002F module where the user now wants ONE shareable artifact\n- After a multi-PR campaign (e.g. PR #8483 V1 module + PR #8488 V2 overlay) where the diff is hard to follow across branches\n- When the user names a specific campaign that has accumulated sibling docs (`*_v1.md`, `*_v2.md`, `*_pantheon.md`, `*_spec.md`)\n- **Edit-existing campaign doc:** user says \"remove historical stuff\", \"strip the audit \u002F provenance \u002F PR references\", \"fix the king \u002F date \u002F name\", \"no scar \u002F no facial mark\", \"make it LLM-input only\", \"drop the v1-v8 references\", \"this is just campaign content not a design audit\". The campaign doc is being treated as LLM input (the source that the gameplay prompt layer reads), not as a design audit trail. Hygiene edits apply.\n- **Rebuild from canonical source:** user says \"rebuild the Doc from the canonical bible source\", \"rebuild from the canonical source, removing orphan duplicate content\", \"the prior subagent left orphan content in the Doc, fix it\", or otherwise asks for a single-source overwrite. See Step 4d.\n\n## Anti-triggers (do NOT fire this skill)\n\n- **Designing a NEW campaign** → `campaign-bible-design` (runs brainstorming → writes design doc)\n- **Exporting a prod Firestore campaign** → `download-campaign` (downloads FROM Firestore TO disk)\n- **Analyzing existing campaigns** → `wa-campaign-content-analysis` (per-scene content classification)\n- **Reading an existing Google Doc the user shared** → `google-credentials-fallback` (use `gog docs info` + `gog docs export --format txt`)\n- **Iterating on campaign design** → `campaign-design-iteration` (next-version design loop)\n- **Pure prompt \u002F $PROJECT_ROOT\u002F fixes** for a campaign (e.g. fixing a prompt file that already references the campaign) → use the relevant prompt-engineering skill, not this one\n\n## Class-level scope\n\nThis skill handles the recurring pattern: your-project.com campaign modules grow across multiple PRs (V1 module + V1 general spec + V2 overlay + setting-specific specialization). The user wants the stitched artifact in a Google Doc for sharing \u002F cross-platform review \u002F provenance. The skill covers any campaign in `$GITHUB_REPOSITORY\u002Fworld_reference\u002F` — God of Murder, Visenya, Alexiel, Inheritor, Steel Jedi, Year of Four, Heat Detective, Dragon Knight, Luke, Daenerys, Merchant Queen, Shattered Rose, etc.\n\n## Workflow (8 steps)\n\n### Step 1 — Identify the campaign + its artifact inventory\n\nRun parallel:\n- `gh pr list --repo $GITHUB_REPOSITORY --state all --search \"\u003Ccampaign keyword>\" --json number,title,state,url,headRefName,createdAt,mergedAt`\n- `gh pr view \u003Cnumber> --json title,state,headRefName,additions,deletions,changedFiles,files` (one per matching PR)\n- `git -C \u003Cworktree> diff origin\u002Fmain..HEAD --name-only` (for the live branch state)\n- `ls -la \u003Cworktree>\u002Fworld_reference\u002F` (for the canonical source files)\n\n**Output:** a numbered list of every file that belongs to the campaign. Group into:\n- Campaign bible (`world_reference\u002Fcampaign_module_*.md`)\n- V1 mechanic specs (`*_general.md`, `*_v1.md`)\n- V2 mechanic specs (`*-v2-*.md`)\n- Setting-specific specializations (`*_faerun*.md`, `*_nocturne*.md`)\n- Sibling $PROJECT_ROOT\u002F code references (`campaign_divine.py`, `god_mode_level_up.py`, `constants.py`, `tests\u002Ftest_*.py`)\n- Gemini share link source (e.g. `https:\u002F\u002Fshare.gemini.google\u002FTd7fA4pzuvMs`)\n\n### Step 2 — Find the worktree with the live files\n\n```\ngit worktree list | grep -i \"\u003Ccampaign keyword>\"\n```\n\nIf multiple matches, pick the most recent by HEAD SHA. If none, check `~\u002Fprojects\u002Fwt-\u003Ccampaign-keyword>` and `$HOME\u002F.worktrees\u002F\u003Ccampaign-keyword>`. Per `dark-factory-canonical-locations` COMMIT, scan ALL canonical locations (~\u002Fprojects\u002F, $HOME\u002F.worktrees\u002F, \u002Fprivate\u002Ftmp\u002F) before declaring \"no worktree.\"\n\n### Step 3 — Read every artifact end-to-end\n\nRead each file via `read_file` to offset+limit until truncated = false. Critical: don't skip files just because they look like \"more spec.\" Each one carries unique state that the user asked for (\"don't miss anything\").\n\n### Step 4 — Check for an EXISTING Google Doc\n\n```\ngog drive ls -j | python3 -c \"...\"\n```\n\nSearch the response for the campaign name (case-insensitive, partial match). If a doc exists, get its ID via `gog drive ls -j | jq '.files[] | select(.name | test(\"\u003Ccampaign>\"; \"i\")) | {id, name}'`.\n\n**Decision branch — DO NOT default to overwrite.** Before proceeding, classify the existing doc against the canonical campaign module:\n\n- **Doc exists, content matches the campaign bible, smaller than the merged PR module** → safe to `--replace --markdown -f \u003Cstitched>` overwrite.\n- **Doc exists, content is structurally richer than the merged PR** (more sections; includes Personality \u002F Family \u002F Open-PRs; sourced from a brainstorm session rather than the PR) → **DO NOT overwrite.** This is the design-spec artifact from before the PR was drafted. Overwriting would *lose* content. Report the diff to the user and offer three options: (a) leave as-is, (b) refresh from the PR (lose sections), (c) stitch-and-replace (PART 1 = merged PR module + PART 2 = existing doc design spec + provenance footer).\n- **Doc exists, content is a stale prior version of the same artifact** (e.g. merged PR has new sections the doc lacks) → `--replace --markdown -f \u003Cstitched>` is correct.\n- **No doc found** → continue to Step 5.\n\n**How to classify:** `gog docs cat \u003CdocId> | wc -lc` (size), `gog docs cat \u003CdocId> | grep -cE \"^Section |^PART \"` (section count). Compare against `wc -l \u003Cworktree>\u002Fworld_reference\u002Fcampaign_module_*.md` and `grep -cE \"^## |^### \" \u003Csame file>`. If the doc has more sections than the PR file, suspect \"design-spec artifact\" — read the first 60 lines to confirm a brainstorm-session header (look for `source_session:`, `authors:`, `date:` in YAML-style frontmatter).\n\nVerified 2026-07-23 on Visenya v9: existing doc was 924 lines \u002F 15 sections from a Slack brainstorm session, while the merged PR #8486 module was 307 lines \u002F 28 headings — both valid artifacts of the same design at different lifecycle stages. Overwriting would have erased Character Personality, Family dynamics, and the Open PRs audit.\n\n### Step 4b — Edit-existing-campaign-doc branch (LLM-input hygiene + canonical-fact fix)\n\nIf the user wants to **edit** an existing doc (not consolidate or refresh), the workflow is different from Steps 5-7. Skip Step 5 (don't create new doc) and Step 6 (don't restitch from files). Instead:\n\n1. `gog docs cat \u003CdocId> > \u002Ftmp\u002F\u003Ccampaign>_edit.md` — pull the current doc content as the edit source.\n2. Apply the edits the user asked for, in this order:\n   - **Canonical-fact fixes** (e.g. \"the king at this time is Daeron not Viserys\"). Verify against an authoritative source before editing — search `jleechanorg\u002Fllm-wiki` wiki\u002Fconcepts\u002F, the campaign's own `world_reference\u002F` module file, or canonical GRRM lore. If you can't verify, surface the ambiguity to the user instead of guessing. Verified 2026-07-23: Visenya v9 doc said \"King Jaehaerys II \u002F Viserys sits the Iron Throne\" in 209 AC, but `The Hedge Knight` opens with Daeron I alive (he dies at the Ashford tourney that year). Always cross-check 209 AC → Daeron, 298 AC → Aerys II or Robert Baratheon (depends on year), etc.\n   - **LLM-input hygiene strip** — drop any block that is *audit trail*, not campaign content. Use `execute_code` with a single Python pass. Block types to strip (with regex):\n     - YAML frontmatter (`^title:`, `^type:`, `^date:`, `^status:`, `^authors:`, `^related:`, `^references:`, `^source_session:`)\n     - \"Exit Criteria\" \u002F \"Done when\" \u002F \"Spec Self-Review\" \u002F \"Placeholder scan\" \u002F \"Source accuracy check\" \u002F \"Internal consistency\" blocks\n     - \"Open PRs In Flight\" tables (PR #XXXX, Issue #XXXX columns)\n     - Provenance \u002F SHA \u002F wiki-link footer blocks\n     - \"End of \u003CX> Spec. Awaiting user review at...\" trailing lines\n     - Section prefaces that link the spec back to WA issues\u002FPRs (e.g. \"This section describes what the prompt layer \u002F agent layer must NEVER do — the durable invariants v9 requires from the WA harness\")\n     - Guardrails tables that have a `WA Reference` column (PR #XXXX link) → convert to bullet list, drop the audit column\n   - **Cross-version hygiene** — drop any \"V1-V8\" \u002F \"replaces v6's X\" \u002F \"pivot from social geometry to physical geometry\" \u002F \"v1-v8 made Visenya a godling puppeteer\" framing. Even in-universe names like \"V6-Visenya\" are version labels; rename to \"the First Song\" \u002F \"her older self\" \u002F \"an older world\" \u002F \"by her calendar\" if the in-universe elder self is referenced. Keep references to the campaign's own version name (e.g. \"v9 homebrew\" stays — it's the current campaign name).\n   - **PC-appearance hygiene** — never add facial scars, missing limbs, disfigurement, or \"ugly\" descriptors to a player character unless the user explicitly asks. The user has stated: Visenya is \"extremely beautiful\". Replace any scar\u002Fdisfigurement on a PC with an emphasizer of beauty. PC visual defects only land if the user types them explicitly (e.g. \"give her a scar\" \u002F \"she's missing an eye\").\n3. **Apply the same edits to the merged PR module file** (`world_reference\u002Fcampaign_module_\u003Ccampaign>.md`) so the doc and the canonical source stay in sync. Doc is downstream; module is upstream.\n4. Run a final pass: `grep -in -E \"Viserys|Jaehaerys|scar|v1-v8|V6-Visenya|replaces v6|End of .* Spec|Exit Criteria|self_review|Self-Review\" \u002Ftmp\u002F\u003Ccampaign>_edit.md` should return only matches the user explicitly wants to keep.\n5. Write back: `gog docs write \u003CdocId> --replace --markdown -f \u002Ftmp\u002F\u003Ccampaign>_edit.md`.\n6. Stage the merged module file edit on a fresh `git stash` so it doesn't pollute the active worktree. Do NOT push to the current branch — it's mid-flight on a different PR.\n\n### Step 4c — Out-of-band corrections during edit (also applies to rebuild)\n\nWhen the user sends an `[OUT-OF-BAND USER MESSAGE]` mid-edit (a refinement they didn't pre-declare, e.g. \"don't talk about older versions\" or \"remove the scar\"), treat it as an additional edit pass in the same `gog docs write --replace --markdown` cycle. Do NOT split into multiple writes — one replace keeps the doc atomic. Apply the new edit to the in-memory markdown string, then re-verify against your grep checklist before the final write.\n\nVerified 2026-07-23: two OOB refinements arrived in succession on the Visenya v9 edit (version hygiene + scar removal). Both were applied to the same `\u002Ftmp\u002Fv9_doc_cleaned_v4.md` buffer before the single `gog docs write --replace --markdown -f` call.\n\n### Step 4d — Rebuild-from-canonical-source branch (single-file overwrite)\n\nWhen the task is to **rebuild the Doc from a single canonical source** (e.g. \"rebuild from the canonical bible source, removing orphan duplicate content\"), the workflow is even simpler than Step 4b. Skip Step 4b (no edit list to apply) and skip Step 5 (the Doc already exists):\n\n1. **Verify the orphan content exists** — `gog docs cat \u003CdocId>` and search for the specific orphan patterns the user described. If none found, note this in the final reply (see Pitfall #22) but continue with the rebuild.\n2. **Identify the canonical source** — typically `world_reference\u002Fcampaign_module_\u003Ccampaign>.md`. Verify with `find . -name 'campaign_module_\u003Ccampaign>*.md'` and confirm the SHA256 matches the latest commit on `origin\u002Fmain`. Never modify the source.\n3. **Backup the current Doc** — `gog docs cat \u003CdocId> > \u002Ftmp\u002F\u003Ccampaign>_doc_before.txt` so the pre-fix state is recoverable.\n4. **Stage the source as input** — `cp \u003Csource> \u002Ftmp\u002F\u003Ccampaign>_doc_input.md`. No transformations; the source goes in as-is.\n5. **Write the rebuild in one call** — `gog docs write \u003CdocId> --replace --markdown -f \u002Ftmp\u002F\u003Ccampaign>_doc_input.md`. The `--markdown` flag renders headings\u002Flists\u002Ftables in Google Docs native formatting. The `--replace` flag overwrites (NOT append — see Pitfall #1).\n6. **Verify post-fix** — `gog docs cat \u003CdocId>` then `grep -nE '^(Section \\d+:|Notes Appendix|DM Notes|Provenance)'` to confirm all expected section headings are present and in correct order. Cross-reference heading count against the source's `grep -cE '^## (Section \\d+:|Notes Appendix|DM Notes|Provenance)' \u003Csource>`.\n\nVerified 2026-08-01 on Nocturne Ravencrest: doc was rebuilt from `world_reference\u002Fcampaign_module_nocturne_deceiver.md` (188,642 bytes) in a single `--replace --markdown -f` call. Pre-fix doc was 169,302 bytes \u002F 1,249 lines (already faithful); post-fix doc is 180,385 bytes \u002F 1,755 lines (canonical with proper Google Docs headings\u002Flists\u002Ftables rendered).\n\n### Step 5 — Create the new Google Doc\n\n```\ngog docs create \"\u003CCampaign> — \u003CSubtitle> + God Mechanics V1+V2\" 2>&1\n```\n\nNote the new doc ID from the response. The `--replace` flag in Step 7 will overwrite any prior content, so you can safely use the same title for updates.\n\n**Title conventions:**\n- God of Murder → \"God of Murder — Sanguine Architecture + God Mechanics V1+V2\"\n- Visenya → \"Visenya Campaign Bible — V\u003Cn> + Mechanics Spec\"\n- For any campaign: \"\u003CCampaign Name> — \u003COne-Line Pitch> + All Mechanics Versions\"\n\n### Step 6 — Stitch the master markdown\n\nUse `execute_code` (Python) to:\n1. Read each source file into memory.\n2. Replace the leading `# Title` line of each with `# PART N — \u003CSubtitle>\\n\\n*\u003COne-line description of which part this is>.*` — preserves the original content, just adds a part header.\n3. Concatenate: header (with TOC) + Part 1 + separator + Part 2 + separator + ... + footer (provenance + recommended next iterations).\n\n**Verified size ceiling:** 104,339 bytes \u002F 1,479 lines \u002F ~16,000 words in a SINGLE `gog docs write` call worked. Above ~120 KB or ~2,000 lines, expect to chunk via multiple `gog docs insert` calls (rare; only if the campaign is enormous).\n\n**Section structure (4-PART template):**\n```\n# \u003CCampaign Name> (with subtitle)\n*Last updated: \u003Cdate>. Compiled from \u003Cworktree-path>.*\n\n[Purpose paragraph]\n[Source conversation link if Gemini share]\n[GitHub PR link if there's a live PR]\n\n# TABLE OF CONTENTS\n1. PART 1: \u003Ccampaign bible>\n2. PART 2: \u003CV1 mechanic spec>\n3. PART 3: \u003CV2 mechanic spec \u002F overlay>\n4. PART 4: \u003Csetting-specific specialization>\n\n---\n# PART 1 — The Campaign Bible (\u003Csetting> specific)\n\u003Cfile contents, with leading # replaced>\n\n---\n# PART 2 — \u003CV1 spec title>\n\u003Cfile contents, with leading # replaced>\n\n[...]\n\n---\n# PROVENANCE & NEXT STEPS\n- SHA for each source file\n- PR links\n- Companion $PROJECT_ROOT\u002F files\n- Wiki source mirror\n- Recommended next iterations\n```\n\n### Step 7 — Write to Google Doc in ONE call\n\n```\ngog docs write \u003CdocId> -f \u002Ftmp\u002F\u003Ccampaign>_master_doc.md --replace --markdown\n```\n\nUse `--replace` to overwrite (append is the default — wrong here). Use `--markdown` to convert headings\u002Flists\u002Ftables to Google Docs formatting (requires `--replace`). Use `-f` to stream from disk rather than passing content as argv (avoids shell escaping issues with backticks\u002Fquotes in the markdown).\n\n**Verify the write succeeded:**\n```\ngog docs info \u003CdocId> | head -20\ngog docs cat \u003CdocId> | wc -l\ngog docs cat \u003CdocId> | grep -c \"PART \"\n```\n\nThe grep should return the count of PART headers you added (typically 4).\n\n### Step 8 — Post back to Slack\n\nUse `mcp_slack_conversations_add_message` to the originating thread (channel ID + thread_ts from the user's message). Reply must include:\n- **PR link** — full markdown hyperlink (not bare `#8488`), per `pr-hyperlink` rule\n- **Doc link** — full URL\n- **Doc stats** — KB \u002F lines \u002F words \u002F PART count\n- **Artifact table** — every source file mapped to its section in the doc, with SHA\n- **Verification status** — `gog docs cat` confirms content landed\n- **`? Memories used:` line** — per `response guardrail` (always-on)\n\nThen create a 20-minute status cron via `cronjob(action='create', deliver='slack:\u003Cchannel>', schedule='20m', ...)` per `one-time-status-cron-after-every-task`. Cron job ID goes in the reply.\n\n## Pitfalls (verified, do not skip)\n\n### Pitfall #1 — `--replace` is required, not the default\n\n`gog docs write` defaults to APPEND. If you skip `--replace`, the second call adds to the first call's content. The 4-PART doc will end up doubled or tripled. Always use `--replace --markdown -f`.\n\n### Pitfall #2 — `gog docs write` needs `-f \u003Cpath>`, not argv content\n\nPassing the full 104 KB markdown as the `\u003Ccontent>` arg causes shell escaping failures on backticks (`HP×5.4 → DR`) and quotes (`\"calculations which don't mean much\"`). Use `-f \u002Ftmp\u002F\u003Cfile>` and let gog stream from disk.\n\n### Pitfall #3 — `gog docs write --markdown` REQUIRES `--replace`\n\nThe `--markdown` flag (which converts `# headings`, tables, lists, etc. to Google Docs formatting) only works with `--replace`. Without `--replace`, the markdown stays as literal text. Both flags together is the magic combo.\n\n### Pitfall #4 — `gog drive ls` returns 20 items per page\n\nFirst call shows the 20 most recent files. If the campaign doc was created >20 files ago, you won't find it on page 1. Check `nextPageToken` in the response, fetch more pages, OR create a new doc with a known-good title (safe because of `--replace` overwrite).\n\n### Pitfall #5 — DRIVE `ls` only shows top-level files (no folder recursion)\n\nIf the doc lives in a subfolder (e.g. `$USER@gmail.com Drive > Campaigns > 2026\u002F`), `gog drive ls` won't find it. Use `gog drive ls --folder \u003CfolderId>` recursively, OR just create a new top-level doc.\n\n### Pitfall #6 — \"Don't miss anything\" means EVERY file in the worktree\n\nThe user said \"don't miss anything\" — they meant EVERY artifact, not just the headline campaign bible. Read each `*_general.md`, `*_v2-*.md`, `*_faerun*.md` separately and add a PART for each. Skipping files = the user will find the gap and be frustrated.\n\n### Pitfall #7 — Gemini source link must be in the header, not buried\n\nThe Gemini share URL is the upstream design source. Put it in the header block under \"Source conversation:\" so future readers can trace the design history without grepping the doc body.\n\n### Pitfall #8 — Include SHA + PR link in provenance footer\n\nThe user will eventually want to verify the doc matches `origin\u002Fmain`. Embed SHA + PR link + branch name + merge commit in the footer. Verified pattern:\n\n```\n- **Campaign module SHA:** `world_reference\u002Fcampaign_module_god_of_murder.md` @ HEAD `48472d7ed7` (PR #8488)\n- **V1 general spec SHA:** `world_reference\u002Fgod_mechanics_general.md` @ HEAD `48472d7ed7` (PR #8488)\n```\n\n### Pitfall #9 — Don't fabricate content for missing files\n\nIf a referenced file doesn't exist (e.g. user says \"update the Nocturne V2 doc\" but the file is only at `world_reference\u002Fnocturne-v2-god-mechanics-design.md`, not at the path the user named), say so in the reply. Don't invent placeholder text labeled \"TBD\" — that's fabrication. Verify with `ls` first.\n\n### Pitfall #10 — The `dark-factory-canonical-locations` COMMIT applies\n\nThe campaign module's source-of-truth lives in a specific worktree, NOT in your checkout dir. Use `git worktree list` to find it. If you read from the wrong dir, you'll get stale content from the previous PR.\n\n### Pitfall #11 — `gog docs info` returns revision ID but not content size\n\nThe `revision` field in `gog docs info` is a Google-side revision ID (not your content size). To verify content size, use `gog docs cat \u003CdocId> | wc -lc` instead.\n\n### Pitfall #12 — Markdown tables with `|` separators work via `--markdown`\n\nTables in the markdown survive the `--markdown` conversion. The 4-doc God of Murder master had ~20 tables (stat blocks, faction dissonance, ascension tiers) and they all rendered correctly. Don't bother pre-converting tables to plain text.\n\n### Pitfall #13 — Don't use `gws docs` for personal shared docs\n\nPer `google-credentials-fallback` skill, `gws docs` 403s on personal shared docs (service-account auth scope). Use `gog` exclusively — `gog` uses $USER@gmail.com personal OAuth and works for both creating AND reading personal docs.\n\n### Pitfall #14 — Slack reply must use full markdown hyperlinks (not bare `#N`)\n\nPer `pr-hyperlink` rule: every PR number must be `[#N](https:\u002F\u002Fgithub.com\u002FOWNER\u002FREPO\u002Fpull\u002FN)`, never bare `#N`. Same for the Doc URL — paste the full `https:\u002F\u002Fdocs.google.com\u002Fdocument\u002Fd\u002F\u003Cid>\u002Fedit` link.\n\n### Pitfall #15 — Cron `deliver` target must be `slack:C0XXXXXXXXX` (channel ID)\n\nPer `one-time-status-cron-after-every-task`: `--deliver 'slack:C0AH3RY3DK6'` (channel ID), not `slack:#worldai` (channel name). The cron resolver expects the ID format.\n\n### Pitfall #16 — An existing Google Doc may be richer than the merged PR module; don't blindly overwrite\n\nThe skill assumes \"doc exists → overwrite with stitched campaign bible.\" But campaign docs are often written *before* the PR — the brainstorm session produces a 900-line design spec (Personality, Family, Open PRs audit, etc.), then the PR condenses it to a 300-line campaign bible for `world_reference\u002F`. Both artifacts coexist, and the doc is typically the **richer** one.\n\nDetection: `wc -l` both files. If `gog docs cat \u003CdocId> | wc -l` >> `wc -l \u003Cworktree>\u002Fworld_reference\u002Fcampaign_module_*.md`, suspect the doc is a pre-PR brainstorm artifact, not a post-PR mirror. Read the doc's first 60 lines for `source_session:` \u002F `authors:` \u002F `date:` frontmatter to confirm.\n\nMitigation: report the diff and offer three options to the user — leave as-is, refresh from PR (lose sections), or stitch-and-replace (PART 1 = PR module + PART 2 = existing doc design spec). Do NOT auto-overwrite. Verified 2026-07-23 on Visenya v9: doc was 924 lines \u002F 15 sections from Slack `C0AH3RY3DK6\u002Fp1784584425.185909`; PR #8486 module was 307 lines \u002F 28 headings. Auto-overwrite would have erased 600+ lines of design rationale.\n\n### Pitfall #17 — \"It's just LLM input only\" means strip every audit\u002Fprovenance block\n\nJeffrey's explicit stance (verified 2026-07-23): campaign docs are read by the gameplay prompt layer as raw narrative input. The doc is NOT a design audit. Strip:\n\n- YAML frontmatter (title\u002Ftype\u002Fdate\u002Fstatus\u002Fauthors\u002Frelated\u002Fwiki\u002Freferences\u002Fsource_session)\n- \"Exit Criteria\" \u002F \"Done when\" \u002F \"Spec Self-Review\" \u002F \"Source accuracy check\" blocks\n- \"Open PRs In Flight\" tables (PR #XXXX columns)\n- Provenance \u002F SHA \u002F wiki-link footer blocks\n- \"End of \u003CX> Spec. Awaiting user review at...\" trailing lines\n- Section prefaces that link the spec back to WA issues\u002FPRs\n\nDetection: search the doc for `^title:`, `^date:`, `Exit Criteria`, `Spec Self-Review`, `Open PRs`, `$GITHUB_REPOSITORY`, `wiki\u002Fsources\u002F`, `wiki\u002Fconcepts\u002F`, `SHA`, `Provenance`. Each match is a strip candidate.\n\nDon't strip: campaign content (campaign concept, personality, family, mechanics, guardrails, endings, starting scenes). The guardrail *definitions* stay; only the audit columns (Status, WA Reference) drop. Verified 2026-07-23 on Visenya v9: doc dropped from 924 → 387 lines after hygiene pass; 0 Viserys\u002FJaehaerys, 0 V6 \u002F 0 v1-v8, 0 scar on PC, all 14 content sections intact.\n\n### Pitfall #18 — Canonical-fact errors in the doc must also be fixed in the merged PR module file\n\nThe campaign doc and the `world_reference\u002Fcampaign_module_\u003Ccampaign>.md` file should be in sync — both are read by the LLM as campaign input. If you fix a wrong king \u002F wrong date \u002F wrong name in the doc but leave the merged module file unchanged, the LLM gets contradictory inputs depending on which artifact the prompt layer samples.\n\nVerified 2026-07-23 on Visenya v9: doc said \"King Jaehaerys II \u002F Viserys\" in 209 AC; merged module file said the same. Both wrong — Daeron I is on the throne in 209 AC until the Ashford tourney. Fixed both with the same `patch` calls (line 3 + line 13 in the module file; lines 33 + 421 in the doc).\n\nAlways cross-check before editing:\n- 209 AC (year of *The Hedge Knight*) → **Daeron I** (dies at Ashford)\n- 282 AC → Maekar I on throne\n- 298 AC (Rhaegar-wins timeline) → depends on the divergence point\n- 129 AC → Viserys I (Dance of the Dragons) or Aegon II \u002F Rhaenyra\n- Slaver's Bay dates → Daenerys (≈298-300 AC)\n\nIf unsure, surface the ambiguity to the user — don't guess.\n\n### Pitfall #19 — Don't add scars, disfigurement, or \"ugly\" details to a player character\n\nPlayer characters in world_reference\u002F are aspirational figures — Visenya, Alexiel, Daenerys, Luke, etc. are *iconic*. The user has stated explicit preferences:\n\n- Visenya is \"extremely beautiful\". Never put a facial scar \u002F missing eye \u002F burn mark on her without explicit instruction.\n- Same for any PC: PC visual defects land only if the user types them in.\n\nIf the existing doc \u002F module has a scar \u002F mark \u002F disfigurement on a PC, treat it as an *artifact of a prior author* and strip on edit. Replace with an emphasizer of beauty \u002F presence \u002F power. Retainer \u002F NPC scars are fine (Ser Tommard Heddle's scar stayed in the Visenya v9 doc — he's a secondary character, not a PC).\n\nVerified 2026-07-23: \"A thin, white scar across the bridge of her nose\" on Visenya → \"A face that has never once been touched — angular, severe, the kind of beauty that makes a room go quiet when she walks in\".\n\n### Pitfall #20 — Don't leak cross-version framing into in-universe content\n\nThe user has stated: \"Don't talk about older versions of the campaign.\" That means:\n\n- Strip V1-V8 \u002F v1-v8 \u002F \"replaces v6's X\" \u002F \"v6 mirror mechanic\" \u002F \"pivot from social to physical geometry\" framing in narrative prose.\n- Drop \"(V6-Visenya, ~298 AC in her world)\" parenthetical labels — even when V6-Visenya is the in-universe elder self. Rename to \"the First Song\" \u002F \"her older self\" \u002F \"by her own calendar\" \u002F \"an older world\". The version label is a design-history artifact; the narrative doesn't need it.\n- KEEP: the campaign's own version name (e.g. \"v9 homebrew\" stays — it's identifying the current campaign). Stripping \"v9\" from a header would be wrong; it just becomes unlabeled.\n- KEEP: in-universe elder-self references that don't carry a version label (\"the First Song\", \"the elder Visenya\", \"her older self\").\n\nVerified 2026-07-23: doc went from 9 v1-v8 references + 10 V6 references → 0 v1-v8 + 0 V6 in narrative prose. Module file: 0 v1-v8 + 0 V6. The 4 remaining \"v9\" mentions in the doc are the campaign's own name (e.g. \"Visenya v9 — Hard Guardrails\").\n\n### Pitfall #21 — Module file edits don't auto-push; stash on the active branch\n\nWhen the active worktree is mid-flight on a different PR (e.g. `pr8399-w2verify` with 110 files \u002F +2178\u002F-14156 already changed), committing the v9 doc-only edit to that branch pollutes it. The v9 module file edit is on a *separate topic*.\n\nMitigation: `git stash push world_reference\u002Fcampaign_module_\u003Ccampaign>.md -m \"\u003Ccampaign> \u003Ctopic> edits (staged for fresh PR)\"`. The edit is preserved in the stash; the working tree returns to the active PR's state. When the user approves pushing as a fresh PR:\n\n```bash\ngit checkout -B docs\u002F\u003Ccampaign>-\u003Ctopic>-cleanup origin\u002Fmain\ngit stash pop  # if only this file is in the stash\n# OR: git stash show -p stash@{0} | git apply\ngit add world_reference\u002Fcampaign_module_\u003Ccampaign>.md\ngit commit -m \"docs(world_reference): strip audit trail + fix canonical fact (\u003Ccampaign> \u003Ctopic>)\"\ngit push origin HEAD:refs\u002Fheads\u002Fdocs\u002F\u003Ccampaign>-\u003Ctopic>-cleanup\n~\u002F.hermes\u002Fscripts\u002Fgh-safe-publish pr create --base main --title \"...\"\n```\n\nVerified 2026-07-23 on Visenya v9: stash landed on `pr8399-w2verify` cleanly without polluting the active PR's diff stat.\n\n### Pitfall #22 — A pre-existing bug in the source-of-truth file must be preserved in the Doc\n\nSome `world_reference\u002Fcampaign_module_*.md` files have pre-existing bugs (duplicate letter labels in appended lists, broken numbering, etc.) that the canonical author has not yet fixed. Per \"Do NOT modify the source bible file. It is the truth\" — when rebuilding the Doc from source, preserve these bugs verbatim. Do NOT silently fix them in the rebuild (the LLM-input layer reads both Doc and source; a divergence will trigger contradiction checks).\n\nVerified 2026-08-01 on Nocturne Ravencrest: source bible's Notes Appendix labeled its last bullet `(g)` even though the prior `(g)` was Sovereign Decoupling (it should have been `(l)`). The Doc was rebuilt with the duplicate `(g)` preserved. The canonical fix lives with the source author, not the doc-builder.\n\nDetection: after rebuilding, `grep -nE '^\\* ?\\([a-z]\\)' \u003Cdoc>` and visually scan for duplicates. Report any pre-existing source bugs to the user in the final reply so they're aware — but do NOT auto-fix.\n\n### Pitfall #23 — \"Rebuild from canonical source\" can be the right pattern even when the Doc looks clean\n\nThe parent task may describe orphan content (stray headings, partial sentence fragments) that no longer matches the current Doc state. Don't refuse the rebuild on those grounds — the orphan content may have been cleaned up between task-creation and execution, OR the description may be stale. Always verify with `gog docs cat` first, then if no orphan content is found AND the user explicitly said \"rebuild from canonical source,\" still do a full overwrite (`gog docs write --replace --markdown -f \u003Csource>`) to guarantee canonical state. The cost is one overwrite; the value is removing ambiguity about which Doc state is canonical.\n\nVerified 2026-08-01 on Nocturne Ravencrest: the pre-fix Doc was 1,249 lines \u002F 169 KB and structurally matched the source bible (13 sections, no orphan duplicate headings, no orphan sentence fragments). Despite the lack of orphan content, the user asked for a rebuild — and the rebuild landed cleanly at 1,755 lines \u002F 180 KB via a single `--markdown --replace -f` call.\n\n### Pitfall #24 — Single-source rebuild ≠ multi-PART stitch\n\nThe 4-PART stitch template (Step 6) is for consolidating MULTIPLE artifacts (V1 module + V1 spec + V2 overlay + setting specialization). A single-source rebuild (one `world_reference\u002Fcampaign_module_*.md` → one Google Doc) does NOT need PART headers, a stitched TOC, or a provenance footer block beyond what the source already carries. Just `cp` the source to `\u002Ftmp\u002F\u003Ccampaign>_doc_input.md` and `gog docs write --replace --markdown -f \u002Ftmp\u002F\u003Ccampaign>_doc_input.md`. Adding PART 1 \u002F PART 2 scaffolding to a single-source rebuild is over-engineering and changes the canonical structure.\n\n## Verification checklist\n\nBefore posting completion to Slack, verify ALL of:\n\n- [ ] `gog docs info \u003CdocId>` returns the doc + revision ID\n- [ ] `gog docs cat \u003CdocId> | wc -l` shows the expected line count (~1,400-1,500 for a 4-doc stitch)\n- [ ] `gog docs cat \u003CdocId> | grep -c \"PART \"` returns the expected PART count (typically 4)\n- [ ] `gog docs cat \u003CdocId> | head -20` shows the header + TOC\n- [ ] `gog docs cat \u003CdocId> | tail -20` shows the provenance footer\n- [ ] Slack thread reply includes PR link + Doc link + artifact table + memory citation\n- [ ] Cron job ID (`934cf6bee234` style) is in the reply + posted to correct channel\n- [ ] `gog docs export \u003CdocId> --format txt` round-trips cleanly (optional sanity check)\n\n**Pre-overwrite check (Step 4):** if a doc already exists for this campaign, confirm its size + section count against `wc -l \u003Cworktree>\u002Fworld_reference\u002Fcampaign_module_*.md` BEFORE running `gog docs write --replace`. If the doc is larger \u002F has more sections than the PR module, surface the diff to the user — don't auto-overwrite (Pitfall #16).\n\n## Cross-references\n\n- **Loaded skill `google-credentials-fallback`** — covers `gog docs info` + `gog docs export --format txt` for READING personal shared docs. This skill covers WRITING large consolidated docs.\n- **Loaded skill `campaign-bible-design`** — runs superpowers brainstorming to DESIGN a new campaign. This skill stitches EXISTING artifacts into a shareable doc.\n- **Loaded skill `download-campaign`** — exports a prod Firestore campaign to disk. This skill inverts: takes DISK campaigns and pushes them to a Google Doc.\n- **Loaded skill `campaign-design-iteration`** — designs next-version of a recurring campaign. This skill is the cross-platform-share step AFTER iteration work completes.\n- **SOUL.md `pr-hyperlink` rule** — every PR number must be a full markdown hyperlink.\n- **SOUL.md `dark-factory-canonical-locations`** — find the right worktree before reading source files.\n- **SOUL.md `one-time-status-cron-after-every-task`** — arm a 20m follow-up cron for every Slack-posted task.\n\n## Reference files\n\n- **`references\u002Fgog-docs-write-recipe.md`** — verified gog CLI flags + size limits + `--markdown` table rendering behavior (created this skill version)\n- **`references\u002Ffour-part-stitch-template.md`** — copy-paste-ready markdown template for the 4-PART header + TOC + provenance footer (created this skill version)\n","# worldai-campaign-to-google-doc\n\nConsolidate every artifact attached to a your-project.com campaign into one Google Doc. Verified 2026-07-21 on the God of Murder \u002F Sanguine Architecture case: produced a 104 KB \u002F 1,479-line \u002F ~16,000-word doc covering 4 stitched source files + PR link + Gemini source attribution, in a single `gog docs write --replace --markdown -f` call.\n\n## When to fire\n\n- User asks to \"put everything for [campaign] in a Google Doc\"\n- User asks to \"update the existing one — don't miss anything\"\n- After iterative V1→V2 design work on a world_reference\u002F module where the user now wants ONE shareable artifact\n- After a multi-PR campaign (e.g. PR #8483 V1 module + PR #8488 V2 overlay) where the diff is hard to follow across branches\n- When the user names a specific campaign that has accumulated sibling docs (`*_v1.md`, `*_v2.md`, `*_pantheon.md`, `*_spec.md`)\n- **Edit-existing campaign doc:** user says \"remove historical stuff\", \"strip the audit \u002F provenance \u002F PR references\", \"fix the king \u002F date \u002F name\", \"no scar \u002F no facial mark\", \"make it LLM-input only\", \"drop the v1-v8 references\", \"this is just campaign content not a design audit\". The campaign doc is being treated as LLM input (the source that the gameplay prompt layer reads), not as a design audit trail. Hygiene edits apply.\n- **Rebuild from canonical source:** user says \"rebuild the Doc from the canonical bible source\", \"rebuild from the canonical source, removing orphan duplicate content\", \"the prior subagent left orphan content in the Doc, fix it\", or otherwise asks for a single-source overwrite. See Step 4d.\n\n## Anti-triggers (do NOT fire this skill)\n\n- **Designing a NEW campaign** → `campaign-bible-design` (runs brainstorming → writes design doc)\n- **Exporting a prod Firestore campaign** → `download-campaign` (downloads FROM Firestore TO disk)\n- **Analyzing existing campaigns** → `wa-campaign-content-analysis` (per-scene content classification)\n- **Reading an existing Google Doc the user shared** → `google-credentials-fallback` (use `gog docs info` + `gog docs export --format txt`)\n- **Iterating on campaign design** → `campaign-design-iteration` (next-version design loop)\n- **Pure prompt \u002F $PROJECT_ROOT\u002F fixes** for a campaign (e.g. fixing a prompt file that already references the campaign) → use the relevant prompt-engineering skill, not this one\n\n## Class-level scope\n\nThis skill handles the recurring pattern: your-project.com campaign modules grow across multiple PRs (V1 module + V1 general spec + V2 overlay + setting-specific specialization). The user wants the stitched artifact in a Google Doc for sharing \u002F cross-platform review \u002F provenance. The skill covers any campaign in `$GITHUB_REPOSITORY\u002Fworld_reference\u002F` — God of Murder, Visenya, Alexiel, Inheritor, Steel Jedi, Year of Four, Heat Detective, Dragon Knight, Luke, Daenerys, Merchant Queen, Shattered Rose, etc.\n\n## Workflow (8 steps)\n\n### Step 1 — Identify the campaign + its artifact inventory\n\nRun parallel:\n- `gh pr list --repo $GITHUB_REPOSITORY --state all --search \"\u003Ccampaign keyword>\" --json number,title,state,url,headRefName,createdAt,mergedAt`\n- `gh pr view \u003Cnumber> --json title,state,headRefName,additions,deletions,changedFiles,files` (one per matching PR)\n- `git -C \u003Cworktree> diff origin\u002Fmain..HEAD --name-only` (for the live branch state)\n- `ls -la \u003Cworktree>\u002Fworld_reference\u002F` (for the canonical source files)\n\n**Output:** a numbered list of every file that belongs to the campaign. Group into:\n- Campaign bible (`world_reference\u002Fcampaign_module_*.md`)\n- V1 mechanic specs (`*_general.md`, `*_v1.md`)\n- V2 mechanic specs (`*-v2-*.md`)\n- Setting-specific specializations (`*_faerun*.md`, `*_nocturne*.md`)\n- Sibling $PROJECT_ROOT\u002F code references (`campaign_divine.py`, `god_mode_level_up.py`, `constants.py`, `tests\u002Ftest_*.py`)\n- Gemini share link source (e.g. `https:\u002F\u002Fshare.gemini.google\u002FTd7fA4pzuvMs`)\n\n### Step 2 — Find the worktree with the live files\n\n```\ngit worktree list | grep -i \"\u003Ccampaign keyword>\"\n```\n\nIf multiple matches, pick the most recent by HEAD SHA. If none, check `~\u002Fprojects\u002Fwt-\u003Ccampaign-keyword>` and `$HOME\u002F.worktrees\u002F\u003Ccampaign-keyword>`. Per `dark-factory-canonical-locations` COMMIT, scan ALL canonical locations (~\u002Fprojects\u002F, $HOME\u002F.worktrees\u002F, \u002Fprivate\u002Ftmp\u002F) before declaring \"no worktree.\"\n\n### Step 3 — Read every artifact end-to-end\n\nRead each file via `read_file` to offset+limit until truncated = false. Critical: don't skip files just because they look like \"more spec.\" Each one carries unique state that the user asked for (\"don't miss anything\").\n\n### Step 4 — Check for an EXISTING Google Doc\n\n```\ngog drive ls -j | python3 -c \"...\"\n```\n\nSearch the response for the campaign name (case-insensitive, partial match). If a doc exists, get its ID via `gog drive ls -j | jq '.files[] | select(.name | test(\"\u003Ccampaign>\"; \"i\")) | {id, name}'`.\n\n**Decision branch — DO NOT default to overwrite.** Before proceeding, classify the existing doc against the canonical campaign module:\n\n- **Doc exists, content matches the campaign bible, smaller than the merged PR module** → safe to `--replace --markdown -f \u003Cstitched>` overwrite.\n- **Doc exists, content is structurally richer than the merged PR** (more sections; includes Personality \u002F Family \u002F Open-PRs; sourced from a brainstorm session rather than the PR) → **DO NOT overwrite.** This is the design-spec artifact from before the PR was drafted. Overwriting would *lose* content. Report the diff to the user and offer three options: (a) leave as-is, (b) refresh from the PR (lose sections), (c) stitch-and-replace (PART 1 = merged PR module + PART 2 = existing doc design spec + provenance footer).\n- **Doc exists, content is a stale prior version of the same artifact** (e.g. merged PR has new sections the doc lacks) → `--replace --markdown -f \u003Cstitched>` is correct.\n- **No doc found** → continue to Step 5.\n\n**How to classify:** `gog docs cat \u003CdocId> | wc -lc` (size), `gog docs cat \u003CdocId> | grep -cE \"^Section |^PART \"` (section count). Compare against `wc -l \u003Cworktree>\u002Fworld_reference\u002Fcampaign_module_*.md` and `grep -cE \"^## |^### \" \u003Csame file>`. If the doc has more sections than the PR file, suspect \"design-spec artifact\" — read the first 60 lines to confirm a brainstorm-session header (look for `source_session:`, `authors:`, `date:` in YAML-style frontmatter).\n\nVerified 2026-07-23 on Visenya v9: existing doc was 924 lines \u002F 15 sections from a Slack brainstorm session, while the merged PR #8486 module was 307 lines \u002F 28 headings — both valid artifacts of the same design at different lifecycle stages. Overwriting would have erased Character Personality, Family dynamics, and the Open PRs audit.\n\n### Step 4b — Edit-existing-campaign-doc branch (LLM-input hygiene + canonical-fact fix)\n\nIf the user wants to **edit** an existing doc (not consolidate or refresh), the workflow is different from Steps 5-7. Skip Step 5 (don't create new doc) and Step 6 (don't restitch from files). Instead:\n\n1. `gog docs cat \u003CdocId> > \u002Ftmp\u002F\u003Ccampaign>_edit.md` — pull the current doc content as the edit source.\n2. Apply the edits the user asked for, in this order:\n   - **Canonical-fact fixes** (e.g. \"the king at this time is Daeron not Viserys\"). Verify against an authoritative source before editing — search `jleechanorg\u002Fllm-wiki` wiki\u002Fconcepts\u002F, the campaign's own `world_reference\u002F` module file, or canonical GRRM lore. If you can't verify, surface the ambiguity to the user instead of guessing. Verified 2026-07-23: Visenya v9 doc said \"King Jaehaerys II \u002F Viserys sits the Iron Throne\" in 209 AC, but `The Hedge Knight` opens with Daeron I alive (he dies at the Ashford tourney that year). Always cross-check 209 AC → Daeron, 298 AC → Aerys II or Robert Baratheon (depends on year), etc.\n   - **LLM-input hygiene strip** — drop any block that is *audit trail*, not campaign content. Use `execute_code` with a single Python pass. Block types to strip (with regex):\n     - YAML frontmatter (`^title:`, `^type:`, `^date:`, `^status:`, `^authors:`, `^related:`, `^references:`, `^source_session:`)\n     - \"Exit Criteria\" \u002F \"Done when\" \u002F \"Spec Self-Review\" \u002F \"Placeholder scan\" \u002F \"Source accuracy check\" \u002F \"Internal consistency\" blocks\n     - \"Open PRs In Flight\" tables (PR #XXXX, Issue #XXXX columns)\n     - Provenance \u002F SHA \u002F wiki-link footer blocks\n     - \"End of \u003CX> Spec. Awaiting user review at...\" trailing lines\n     - Section prefaces that link the spec back to WA issues\u002FPRs (e.g. \"This section describes what the prompt layer \u002F agent layer must NEVER do — the durable invariants v9 requires from the WA harness\")\n     - Guardrails tables that have a `WA Reference` column (PR #XXXX link) → convert to bullet list, drop the audit column\n   - **Cross-version hygiene** — drop any \"V1-V8\" \u002F \"replaces v6's X\" \u002F \"pivot from social geometry to physical geometry\" \u002F \"v1-v8 made Visenya a godling puppeteer\" framing. Even in-universe names like \"V6-Visenya\" are version labels; rename to \"the First Song\" \u002F \"her older self\" \u002F \"an older world\" \u002F \"by her calendar\" if the in-universe elder self is referenced. Keep references to the campaign's own version name (e.g. \"v9 homebrew\" stays — it's the current campaign name).\n   - **PC-appearance hygiene** — never add facial scars, missing limbs, disfigurement, or \"ugly\" descriptors to a player character unless the user explicitly asks. The user has stated: Visenya is \"extremely beautiful\". Replace any scar\u002Fdisfigurement on a PC with an emphasizer of beauty. PC visual defects only land if the user types them explicitly (e.g. \"give her a scar\" \u002F \"she's missing an eye\").\n3. **Apply the same edits to the merged PR module file** (`world_reference\u002Fcampaign_module_\u003Ccampaign>.md`) so the doc and the canonical source stay in sync. Doc is downstream; module is upstream.\n4. Run a final pass: `grep -in -E \"Viserys|Jaehaerys|scar|v1-v8|V6-Visenya|replaces v6|End of .* Spec|Exit Criteria|self_review|Self-Review\" \u002Ftmp\u002F\u003Ccampaign>_edit.md` should return only matches the user explicitly wants to keep.\n5. Write back: `gog docs write \u003CdocId> --replace --markdown -f \u002Ftmp\u002F\u003Ccampaign>_edit.md`.\n6. Stage the merged module file edit on a fresh `git stash` so it doesn't pollute the active worktree. Do NOT push to the current branch — it's mid-flight on a different PR.\n\n### Step 4c — Out-of-band corrections during edit (also applies to rebuild)\n\nWhen the user sends an `[OUT-OF-BAND USER MESSAGE]` mid-edit (a refinement they didn't pre-declare, e.g. \"don't talk about older versions\" or \"remove the scar\"), treat it as an additional edit pass in the same `gog docs write --replace --markdown` cycle. Do NOT split into multiple writes — one replace keeps the doc atomic. Apply the new edit to the in-memory markdown string, then re-verify against your grep checklist before the final write.\n\nVerified 2026-07-23: two OOB refinements arrived in succession on the Visenya v9 edit (version hygiene + scar removal). Both were applied to the same `\u002Ftmp\u002Fv9_doc_cleaned_v4.md` buffer before the single `gog docs write --replace --markdown -f` call.\n\n### Step 4d — Rebuild-from-canonical-source branch (single-file overwrite)\n\nWhen the task is to **rebuild the Doc from a single canonical source** (e.g. \"rebuild from the canonical bible source, removing orphan duplicate content\"), the workflow is even simpler than Step 4b. Skip Step 4b (no edit list to apply) and skip Step 5 (the Doc already exists):\n\n1. **Verify the orphan content exists** — `gog docs cat \u003CdocId>` and search for the specific orphan patterns the user described. If none found, note this in the final reply (see Pitfall #22) but continue with the rebuild.\n2. **Identify the canonical source** — typically `world_reference\u002Fcampaign_module_\u003Ccampaign>.md`. Verify with `find . -name 'campaign_module_\u003Ccampaign>*.md'` and confirm the SHA256 matches the latest commit on `origin\u002Fmain`. Never modify the source.\n3. **Backup the current Doc** — `gog docs cat \u003CdocId> > \u002Ftmp\u002F\u003Ccampaign>_doc_before.txt` so the pre-fix state is recoverable.\n4. **Stage the source as input** — `cp \u003Csource> \u002Ftmp\u002F\u003Ccampaign>_doc_input.md`. No transformations; the source goes in as-is.\n5. **Write the rebuild in one call** — `gog docs write \u003CdocId> --replace --markdown -f \u002Ftmp\u002F\u003Ccampaign>_doc_input.md`. The `--markdown` flag renders headings\u002Flists\u002Ftables in Google Docs native formatting. The `--replace` flag overwrites (NOT append — see Pitfall #1).\n6. **Verify post-fix** — `gog docs cat \u003CdocId>` then `grep -nE '^(Section \\d+:|Notes Appendix|DM Notes|Provenance)'` to confirm all expected section headings are present and in correct order. Cross-reference heading count against the source's `grep -cE '^## (Section \\d+:|Notes Appendix|DM Notes|Provenance)' \u003Csource>`.\n\nVerified 2026-08-01 on Nocturne Ravencrest: doc was rebuilt from `world_reference\u002Fcampaign_module_nocturne_deceiver.md` (188,642 bytes) in a single `--replace --markdown -f` call. Pre-fix doc was 169,302 bytes \u002F 1,249 lines (already faithful); post-fix doc is 180,385 bytes \u002F 1,755 lines (canonical with proper Google Docs headings\u002Flists\u002Ftables rendered).\n\n### Step 5 — Create the new Google Doc\n\n```\ngog docs create \"\u003CCampaign> — \u003CSubtitle> + God Mechanics V1+V2\" 2>&1\n```\n\nNote the new doc ID from the response. The `--replace` flag in Step 7 will overwrite any prior content, so you can safely use the same title for updates.\n\n**Title conventions:**\n- God of Murder → \"God of Murder — Sanguine Architecture + God Mechanics V1+V2\"\n- Visenya → \"Visenya Campaign Bible — V\u003Cn> + Mechanics Spec\"\n- For any campaign: \"\u003CCampaign Name> — \u003COne-Line Pitch> + All Mechanics Versions\"\n\n### Step 6 — Stitch the master markdown\n\nUse `execute_code` (Python) to:\n1. Read each source file into memory.\n2. Replace the leading `# Title` line of each with `# PART N — \u003CSubtitle>\\n\\n*\u003COne-line description of which part this is>.*` — preserves the original content, just adds a part header.\n3. Concatenate: header (with TOC) + Part 1 + separator + Part 2 + separator + ... + footer (provenance + recommended next iterations).\n\n**Verified size ceiling:** 104,339 bytes \u002F 1,479 lines \u002F ~16,000 words in a SINGLE `gog docs write` call worked. Above ~120 KB or ~2,000 lines, expect to chunk via multiple `gog docs insert` calls (rare; only if the campaign is enormous).\n\n**Section structure (4-PART template):**\n```\n# \u003CCampaign Name> (with subtitle)\n*Last updated: \u003Cdate>. Compiled from \u003Cworktree-path>.*\n\n[Purpose paragraph]\n[Source conversation link if Gemini share]\n[GitHub PR link if there's a live PR]\n\n# TABLE OF CONTENTS\n1. PART 1: \u003Ccampaign bible>\n2. PART 2: \u003CV1 mechanic spec>\n3. PART 3: \u003CV2 mechanic spec \u002F overlay>\n4. PART 4: \u003Csetting-specific specialization>\n\n---\n# PART 1 — The Campaign Bible (\u003Csetting> specific)\n\u003Cfile contents, with leading # replaced>\n\n---\n# PART 2 — \u003CV1 spec title>\n\u003Cfile contents, with leading # replaced>\n\n[...]\n\n---\n# PROVENANCE & NEXT STEPS\n- SHA for each source file\n- PR links\n- Companion $PROJECT_ROOT\u002F files\n- Wiki source mirror\n- Recommended next iterations\n```\n\n### Step 7 — Write to Google Doc in ONE call\n\n```\ngog docs write \u003CdocId> -f \u002Ftmp\u002F\u003Ccampaign>_master_doc.md --replace --markdown\n```\n\nUse `--replace` to overwrite (append is the default — wrong here). Use `--markdown` to convert headings\u002Flists\u002Ftables to Google Docs formatting (requires `--replace`). Use `-f` to stream from disk rather than passing content as argv (avoids shell escaping issues with backticks\u002Fquotes in the markdown).\n\n**Verify the write succeeded:**\n```\ngog docs info \u003CdocId> | head -20\ngog docs cat \u003CdocId> | wc -l\ngog docs cat \u003CdocId> | grep -c \"PART \"\n```\n\nThe grep should return the count of PART headers you added (typically 4).\n\n### Step 8 — Post back to Slack\n\nUse `mcp_slack_conversations_add_message` to the originating thread (channel ID + thread_ts from the user's message). Reply must include:\n- **PR link** — full markdown hyperlink (not bare `#8488`), per `pr-hyperlink` rule\n- **Doc link** — full URL\n- **Doc stats** — KB \u002F lines \u002F words \u002F PART count\n- **Artifact table** — every source file mapped to its section in the doc, with SHA\n- **Verification status** — `gog docs cat` confirms content landed\n- **`? Memories used:` line** — per `response guardrail` (always-on)\n\nThen create a 20-minute status cron via `cronjob(action='create', deliver='slack:\u003Cchannel>', schedule='20m', ...)` per `one-time-status-cron-after-every-task`. Cron job ID goes in the reply.\n\n## Pitfalls (verified, do not skip)\n\n### Pitfall #1 — `--replace` is required, not the default\n\n`gog docs write` defaults to APPEND. If you skip `--replace`, the second call adds to the first call's content. The 4-PART doc will end up doubled or tripled. Always use `--replace --markdown -f`.\n\n### Pitfall #2 — `gog docs write` needs `-f \u003Cpath>`, not argv content\n\nPassing the full 104 KB markdown as the `\u003Ccontent>` arg causes shell escaping failures on backticks (`HP×5.4 → DR`) and quotes (`\"calculations which don't mean much\"`). Use `-f \u002Ftmp\u002F\u003Cfile>` and let gog stream from disk.\n\n### Pitfall #3 — `gog docs write --markdown` REQUIRES `--replace`\n\nThe `--markdown` flag (which converts `# headings`, tables, lists, etc. to Google Docs formatting) only works with `--replace`. Without `--replace`, the markdown stays as literal text. Both flags together is the magic combo.\n\n### Pitfall #4 — `gog drive ls` returns 20 items per page\n\nFirst call shows the 20 most recent files. If the campaign doc was created >20 files ago, you won't find it on page 1. Check `nextPageToken` in the response, fetch more pages, OR create a new doc with a known-good title (safe because of `--replace` overwrite).\n\n### Pitfall #5 — DRIVE `ls` only shows top-level files (no folder recursion)\n\nIf the doc lives in a subfolder (e.g. `$USER@gmail.com Drive > Campaigns > 2026\u002F`), `gog drive ls` won't find it. Use `gog drive ls --folder \u003CfolderId>` recursively, OR just create a new top-level doc.\n\n### Pitfall #6 — \"Don't miss anything\" means EVERY file in the worktree\n\nThe user said \"don't miss anything\" — they meant EVERY artifact, not just the headline campaign bible. Read each `*_general.md`, `*_v2-*.md`, `*_faerun*.md` separately and add a PART for each. Skipping files = the user will find the gap and be frustrated.\n\n### Pitfall #7 — Gemini source link must be in the header, not buried\n\nThe Gemini share URL is the upstream design source. Put it in the header block under \"Source conversation:\" so future readers can trace the design history without grepping the doc body.\n\n### Pitfall #8 — Include SHA + PR link in provenance footer\n\nThe user will eventually want to verify the doc matches `origin\u002Fmain`. Embed SHA + PR link + branch name + merge commit in the footer. Verified pattern:\n\n```\n- **Campaign module SHA:** `world_reference\u002Fcampaign_module_god_of_murder.md` @ HEAD `48472d7ed7` (PR #8488)\n- **V1 general spec SHA:** `world_reference\u002Fgod_mechanics_general.md` @ HEAD `48472d7ed7` (PR #8488)\n```\n\n### Pitfall #9 — Don't fabricate content for missing files\n\nIf a referenced file doesn't exist (e.g. user says \"update the Nocturne V2 doc\" but the file is only at `world_reference\u002Fnocturne-v2-god-mechanics-design.md`, not at the path the user named), say so in the reply. Don't invent placeholder text labeled \"TBD\" — that's fabrication. Verify with `ls` first.\n\n### Pitfall #10 — The `dark-factory-canonical-locations` COMMIT applies\n\nThe campaign module's source-of-truth lives in a specific worktree, NOT in your checkout dir. Use `git worktree list` to find it. If you read from the wrong dir, you'll get stale content from the previous PR.\n\n### Pitfall #11 — `gog docs info` returns revision ID but not content size\n\nThe `revision` field in `gog docs info` is a Google-side revision ID (not your content size). To verify content size, use `gog docs cat \u003CdocId> | wc -lc` instead.\n\n### Pitfall #12 — Markdown tables with `|` separators work via `--markdown`\n\nTables in the markdown survive the `--markdown` conversion. The 4-doc God of Murder master had ~20 tables (stat blocks, faction dissonance, ascension tiers) and they all rendered correctly. Don't bother pre-converting tables to plain text.\n\n### Pitfall #13 — Don't use `gws docs` for personal shared docs\n\nPer `google-credentials-fallback` skill, `gws docs` 403s on personal shared docs (service-account auth scope). Use `gog` exclusively — `gog` uses $USER@gmail.com personal OAuth and works for both creating AND reading personal docs.\n\n### Pitfall #14 — Slack reply must use full markdown hyperlinks (not bare `#N`)\n\nPer `pr-hyperlink` rule: every PR number must be `[#N](https:\u002F\u002Fgithub.com\u002FOWNER\u002FREPO\u002Fpull\u002FN)`, never bare `#N`. Same for the Doc URL — paste the full `https:\u002F\u002Fdocs.google.com\u002Fdocument\u002Fd\u002F\u003Cid>\u002Fedit` link.\n\n### Pitfall #15 — Cron `deliver` target must be `slack:C0XXXXXXXXX` (channel ID)\n\nPer `one-time-status-cron-after-every-task`: `--deliver 'slack:C0AH3RY3DK6'` (channel ID), not `slack:#worldai` (channel name). The cron resolver expects the ID format.\n\n### Pitfall #16 — An existing Google Doc may be richer than the merged PR module; don't blindly overwrite\n\nThe skill assumes \"doc exists → overwrite with stitched campaign bible.\" But campaign docs are often written *before* the PR — the brainstorm session produces a 900-line design spec (Personality, Family, Open PRs audit, etc.), then the PR condenses it to a 300-line campaign bible for `world_reference\u002F`. Both artifacts coexist, and the doc is typically the **richer** one.\n\nDetection: `wc -l` both files. If `gog docs cat \u003CdocId> | wc -l` >> `wc -l \u003Cworktree>\u002Fworld_reference\u002Fcampaign_module_*.md`, suspect the doc is a pre-PR brainstorm artifact, not a post-PR mirror. Read the doc's first 60 lines for `source_session:` \u002F `authors:` \u002F `date:` frontmatter to confirm.\n\nMitigation: report the diff and offer three options to the user — leave as-is, refresh from PR (lose sections), or stitch-and-replace (PART 1 = PR module + PART 2 = existing doc design spec). Do NOT auto-overwrite. Verified 2026-07-23 on Visenya v9: doc was 924 lines \u002F 15 sections from Slack `C0AH3RY3DK6\u002Fp1784584425.185909`; PR #8486 module was 307 lines \u002F 28 headings. Auto-overwrite would have erased 600+ lines of design rationale.\n\n### Pitfall #17 — \"It's just LLM input only\" means strip every audit\u002Fprovenance block\n\nJeffrey's explicit stance (verified 2026-07-23): campaign docs are read by the gameplay prompt layer as raw narrative input. The doc is NOT a design audit. Strip:\n\n- YAML frontmatter (title\u002Ftype\u002Fdate\u002Fstatus\u002Fauthors\u002Frelated\u002Fwiki\u002Freferences\u002Fsource_session)\n- \"Exit Criteria\" \u002F \"Done when\" \u002F \"Spec Self-Review\" \u002F \"Source accuracy check\" blocks\n- \"Open PRs In Flight\" tables (PR #XXXX columns)\n- Provenance \u002F SHA \u002F wiki-link footer blocks\n- \"End of \u003CX> Spec. Awaiting user review at...\" trailing lines\n- Section prefaces that link the spec back to WA issues\u002FPRs\n\nDetection: search the doc for `^title:`, `^date:`, `Exit Criteria`, `Spec Self-Review`, `Open PRs`, `$GITHUB_REPOSITORY`, `wiki\u002Fsources\u002F`, `wiki\u002Fconcepts\u002F`, `SHA`, `Provenance`. Each match is a strip candidate.\n\nDon't strip: campaign content (campaign concept, personality, family, mechanics, guardrails, endings, starting scenes). The guardrail *definitions* stay; only the audit columns (Status, WA Reference) drop. Verified 2026-07-23 on Visenya v9: doc dropped from 924 → 387 lines after hygiene pass; 0 Viserys\u002FJaehaerys, 0 V6 \u002F 0 v1-v8, 0 scar on PC, all 14 content sections intact.\n\n### Pitfall #18 — Canonical-fact errors in the doc must also be fixed in the merged PR module file\n\nThe campaign doc and the `world_reference\u002Fcampaign_module_\u003Ccampaign>.md` file should be in sync — both are read by the LLM as campaign input. If you fix a wrong king \u002F wrong date \u002F wrong name in the doc but leave the merged module file unchanged, the LLM gets contradictory inputs depending on which artifact the prompt layer samples.\n\nVerified 2026-07-23 on Visenya v9: doc said \"King Jaehaerys II \u002F Viserys\" in 209 AC; merged module file said the same. Both wrong — Daeron I is on the throne in 209 AC until the Ashford tourney. Fixed both with the same `patch` calls (line 3 + line 13 in the module file; lines 33 + 421 in the doc).\n\nAlways cross-check before editing:\n- 209 AC (year of *The Hedge Knight*) → **Daeron I** (dies at Ashford)\n- 282 AC → Maekar I on throne\n- 298 AC (Rhaegar-wins timeline) → depends on the divergence point\n- 129 AC → Viserys I (Dance of the Dragons) or Aegon II \u002F Rhaenyra\n- Slaver's Bay dates → Daenerys (≈298-300 AC)\n\nIf unsure, surface the ambiguity to the user — don't guess.\n\n### Pitfall #19 — Don't add scars, disfigurement, or \"ugly\" details to a player character\n\nPlayer characters in world_reference\u002F are aspirational figures — Visenya, Alexiel, Daenerys, Luke, etc. are *iconic*. The user has stated explicit preferences:\n\n- Visenya is \"extremely beautiful\". Never put a facial scar \u002F missing eye \u002F burn mark on her without explicit instruction.\n- Same for any PC: PC visual defects land only if the user types them in.\n\nIf the existing doc \u002F module has a scar \u002F mark \u002F disfigurement on a PC, treat it as an *artifact of a prior author* and strip on edit. Replace with an emphasizer of beauty \u002F presence \u002F power. Retainer \u002F NPC scars are fine (Ser Tommard Heddle's scar stayed in the Visenya v9 doc — he's a secondary character, not a PC).\n\nVerified 2026-07-23: \"A thin, white scar across the bridge of her nose\" on Visenya → \"A face that has never once been touched — angular, severe, the kind of beauty that makes a room go quiet when she walks in\".\n\n### Pitfall #20 — Don't leak cross-version framing into in-universe content\n\nThe user has stated: \"Don't talk about older versions of the campaign.\" That means:\n\n- Strip V1-V8 \u002F v1-v8 \u002F \"replaces v6's X\" \u002F \"v6 mirror mechanic\" \u002F \"pivot from social to physical geometry\" framing in narrative prose.\n- Drop \"(V6-Visenya, ~298 AC in her world)\" parenthetical labels — even when V6-Visenya is the in-universe elder self. Rename to \"the First Song\" \u002F \"her older self\" \u002F \"by her own calendar\" \u002F \"an older world\". The version label is a design-history artifact; the narrative doesn't need it.\n- KEEP: the campaign's own version name (e.g. \"v9 homebrew\" stays — it's identifying the current campaign). Stripping \"v9\" from a header would be wrong; it just becomes unlabeled.\n- KEEP: in-universe elder-self references that don't carry a version label (\"the First Song\", \"the elder Visenya\", \"her older self\").\n\nVerified 2026-07-23: doc went from 9 v1-v8 references + 10 V6 references → 0 v1-v8 + 0 V6 in narrative prose. Module file: 0 v1-v8 + 0 V6. The 4 remaining \"v9\" mentions in the doc are the campaign's own name (e.g. \"Visenya v9 — Hard Guardrails\").\n\n### Pitfall #21 — Module file edits don't auto-push; stash on the active branch\n\nWhen the active worktree is mid-flight on a different PR (e.g. `pr8399-w2verify` with 110 files \u002F +2178\u002F-14156 already changed), committing the v9 doc-only edit to that branch pollutes it. The v9 module file edit is on a *separate topic*.\n\nMitigation: `git stash push world_reference\u002Fcampaign_module_\u003Ccampaign>.md -m \"\u003Ccampaign> \u003Ctopic> edits (staged for fresh PR)\"`. The edit is preserved in the stash; the working tree returns to the active PR's state. When the user approves pushing as a fresh PR:\n\n```bash\ngit checkout -B docs\u002F\u003Ccampaign>-\u003Ctopic>-cleanup origin\u002Fmain\ngit stash pop  # if only this file is in the stash\n# OR: git stash show -p stash@{0} | git apply\ngit add world_reference\u002Fcampaign_module_\u003Ccampaign>.md\ngit commit -m \"docs(world_reference): strip audit trail + fix canonical fact (\u003Ccampaign> \u003Ctopic>)\"\ngit push origin HEAD:refs\u002Fheads\u002Fdocs\u002F\u003Ccampaign>-\u003Ctopic>-cleanup\n~\u002F.hermes\u002Fscripts\u002Fgh-safe-publish pr create --base main --title \"...\"\n```\n\nVerified 2026-07-23 on Visenya v9: stash landed on `pr8399-w2verify` cleanly without polluting the active PR's diff stat.\n\n### Pitfall #22 — A pre-existing bug in the source-of-truth file must be preserved in the Doc\n\nSome `world_reference\u002Fcampaign_module_*.md` files have pre-existing bugs (duplicate letter labels in appended lists, broken numbering, etc.) that the canonical author has not yet fixed. Per \"Do NOT modify the source bible file. It is the truth\" — when rebuilding the Doc from source, preserve these bugs verbatim. Do NOT silently fix them in the rebuild (the LLM-input layer reads both Doc and source; a divergence will trigger contradiction checks).\n\nVerified 2026-08-01 on Nocturne Ravencrest: source bible's Notes Appendix labeled its last bullet `(g)` even though the prior `(g)` was Sovereign Decoupling (it should have been `(l)`). The Doc was rebuilt with the duplicate `(g)` preserved. The canonical fix lives with the source author, not the doc-builder.\n\nDetection: after rebuilding, `grep -nE '^\\* ?\\([a-z]\\)' \u003Cdoc>` and visually scan for duplicates. Report any pre-existing source bugs to the user in the final reply so they're aware — but do NOT auto-fix.\n\n### Pitfall #23 — \"Rebuild from canonical source\" can be the right pattern even when the Doc looks clean\n\nThe parent task may describe orphan content (stray headings, partial sentence fragments) that no longer matches the current Doc state. Don't refuse the rebuild on those grounds — the orphan content may have been cleaned up between task-creation and execution, OR the description may be stale. Always verify with `gog docs cat` first, then if no orphan content is found AND the user explicitly said \"rebuild from canonical source,\" still do a full overwrite (`gog docs write --replace --markdown -f \u003Csource>`) to guarantee canonical state. The cost is one overwrite; the value is removing ambiguity about which Doc state is canonical.\n\nVerified 2026-08-01 on Nocturne Ravencrest: the pre-fix Doc was 1,249 lines \u002F 169 KB and structurally matched the source bible (13 sections, no orphan duplicate headings, no orphan sentence fragments). Despite the lack of orphan content, the user asked for a rebuild — and the rebuild landed cleanly at 1,755 lines \u002F 180 KB via a single `--markdown --replace -f` call.\n\n### Pitfall #24 — Single-source rebuild ≠ multi-PART stitch\n\nThe 4-PART stitch template (Step 6) is for consolidating MULTIPLE artifacts (V1 module + V1 spec + V2 overlay + setting specialization). A single-source rebuild (one `world_reference\u002Fcampaign_module_*.md` → one Google Doc) does NOT need PART headers, a stitched TOC, or a provenance footer block beyond what the source already carries. Just `cp` the source to `\u002Ftmp\u002F\u003Ccampaign>_doc_input.md` and `gog docs write --replace --markdown -f \u002Ftmp\u002F\u003Ccampaign>_doc_input.md`. Adding PART 1 \u002F PART 2 scaffolding to a single-source rebuild is over-engineering and changes the canonical structure.\n\n## Verification checklist\n\nBefore posting completion to Slack, verify ALL of:\n\n- [ ] `gog docs info \u003CdocId>` returns the doc + revision ID\n- [ ] `gog docs cat \u003CdocId> | wc -l` shows the expected line count (~1,400-1,500 for a 4-doc stitch)\n- [ ] `gog docs cat \u003CdocId> | grep -c \"PART \"` returns the expected PART count (typically 4)\n- [ ] `gog docs cat \u003CdocId> | head -20` shows the header + TOC\n- [ ] `gog docs cat \u003CdocId> | tail -20` shows the provenance footer\n- [ ] Slack thread reply includes PR link + Doc link + artifact table + memory citation\n- [ ] Cron job ID (`934cf6bee234` style) is in the reply + posted to correct channel\n- [ ] `gog docs export \u003CdocId> --format txt` round-trips cleanly (optional sanity check)\n\n**Pre-overwrite check (Step 4):** if a doc already exists for this campaign, confirm its size + section count against `wc -l \u003Cworktree>\u002Fworld_reference\u002Fcampaign_module_*.md` BEFORE running `gog docs write --replace`. If the doc is larger \u002F has more sections than the PR module, surface the diff to the user — don't auto-overwrite (Pitfall #16).\n\n## Cross-references\n\n- **Loaded skill `google-credentials-fallback`** — covers `gog docs info` + `gog docs export --format txt` for READING personal shared docs. This skill covers WRITING large consolidated docs.\n- **Loaded skill `campaign-bible-design`** — runs superpowers brainstorming to DESIGN a new campaign. This skill stitches EXISTING artifacts into a shareable doc.\n- **Loaded skill `download-campaign`** — exports a prod Firestore campaign to disk. This skill inverts: takes DISK campaigns and pushes them to a Google Doc.\n- **Loaded skill `campaign-design-iteration`** — designs next-version of a recurring campaign. This skill is the cross-platform-share step AFTER iteration work completes.\n- **SOUL.md `pr-hyperlink` rule** — every PR number must be a full markdown hyperlink.\n- **SOUL.md `dark-factory-canonical-locations`** — find the right worktree before reading source files.\n- **SOUL.md `one-time-status-cron-after-every-task`** — arm a 20m follow-up cron for every Slack-posted task.\n\n## Reference files\n\n- **`references\u002Fgog-docs-write-recipe.md`** — verified gog CLI flags + size limits + `--markdown` table rendering behavior (created this skill version)\n- **`references\u002Ffour-part-stitch-template.md`** — copy-paste-ready markdown template for the 4-PART header + TOC + provenance footer (created this skill version)\n",{"name":5,"description":7},"main","05df7380981a2c4af868ce0fa57962ae0eea62a9","hermes\u002Fskills\u002Fworldarchitect\u002Fworldai-campaign-to-google-doc",0,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills","https:\u002F\u002Fgithub.com\u002Fjleechanorg","2026-11-11 22:19:36",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add jleechanorg\u002Fjleechan-skills --skill worldai-campaign-to-google-doc",{"tool":73,"command":74},"bunx","bunx skills add jleechanorg\u002Fjleechan-skills --skill worldai-campaign-to-google-doc",{"tool":76,"command":77},"pnpm","pnpm dlx skills add jleechanorg\u002Fjleechan-skills --skill worldai-campaign-to-google-doc","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fworldarchitect\u002Fworldai-campaign-to-google-doc\u002FSKILL.md",true,[81,87],{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":86},"references\u002Ffour-part-stitch-template.md","REFERENCE","参考文档",5807,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fworldarchitect\u002Fworldai-campaign-to-google-doc\u002Freferences\u002Ffour-part-stitch-template.md",{"path":88,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":89,"sourceHtmlUrl":90},"references\u002Fgog-docs-write-recipe.md",3787,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fworldarchitect\u002Fworldai-campaign-to-google-doc\u002Freferences\u002Fgog-docs-write-recipe.md",[92,109,128,142,156,172],{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":98,"publishedAt":55},"01M716Y5MTJ6GYJZ2ATXCJK8G4","instinct","Use when the user invokes \u002Finstinct or \u002Fin, or asks to \"message Instinct\", \"ask Instinct\", \"tell Instinct\", \"check Instinct\", or read replies from the configured peer assistant. iMessage first, WhatsApp Web as fallback.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Finstinct\u002FSKILL.md",[],[94,99,100,101,102,42,103,104,105,106,107,108],"user","when","replies","check","identity","whatsapp","gmail","read","message","ask",{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":118,"publishedAt":55},"01M716Y4HF7FVVMJSA2CCVN5VF","hr","Compatibility alias for history-resume; produce the same fresh-state, provenance-aware resume briefing.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhr\u002FSKILL.md",[115],{"categoryNo":116,"categoryName":117,"taxonomyType":25,"taxonomyTypeDesc":26},"01JBSEEDCAT000000000000038","人力资源",[111,119,120,121,32,122,123,124,125,126,127],"resume","compatibility","provenance","history","produce","alias","briefing","state","fresh",{"skillNo":129,"name":130,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":135,"publishedAt":55},"01M716Y1FFNFKFJYYKF8HQA6T8","history-resume","Resume briefing for the current repository branch or worktree using fresh state and admitted history sources.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhistory-resume\u002FSKILL.md",[134],{"categoryNo":116,"categoryName":117,"taxonomyType":25,"taxonomyTypeDesc":26},[122,119,136,137,99,138,125,139,32,140,141,126,127],"history resume","branch","analysis","repository","worktree","sources",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":148,"publishedAt":55},"01M716XWXJ8EPHK4RH9T14TR85","grok","Alias for the canonical grokbot browser conversation workflow; \u002Fgrok talks to the Grok bot the same way \u002Fdot talks to Dot.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgrok\u002FSKILL.md",[],[144,149,150,151,32,152,124,153,154,155],"dot","bot","workflow","canonical","conversation","browser","grokbot",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":162,"publishedAt":55},"01M70N9Q07DTE0EW5KFXMMMSJ0","codexa-bench","Compare `codexa` and normal `codex` on a fair split of comparable work by default; use `--strict` for duplicate runs of the exact same task.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcodexa-bench\u002FSKILL.md",[],[163,164,165,42,166,32,167,168,169,170,171],"codexa bench","work","split","default","duplicate","task","compare","normal","codex",{"skillNo":173,"name":174,"nameZh":6,"description":175,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":176,"licenseFileUrl":177,"sourceHtmlUrl":178,"categories":179,"keywords":189,"publishedAt":55},"01M6C24S2X60SP8BBFGAEKPEGW","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\u002FCSS layouts, or when styling\u002Fbeautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[180,183,186],{"categoryNo":181,"categoryName":182,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":184,"categoryName":185,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":187,"categoryName":188,"taxonomyType":25,"taxonomyTypeDesc":26},"01JBSEEDCAT000000000000032","设计师",[190,33,191,42,192,193,194,99,195,196,51,50,197,198,199,200,201,202,203,204,205,206,207,208,209,210,100,211],"frontend","frontend design","generic","ui design","react","html","components","ui","aesthetics","Production","web components","landing","applications","quality","web","css","create","examples","with","react components","web ui","pages"]