Section Merger
Goal: assemble a paper-like output/DRAFT.md from:
-
sections/ (per-section/per-subsection prose)
-
outline/transitions.md (short hand-offs; generated by transition-weaver )
-
outline/tables_appendix.md (reader-facing Appendix tables; generated by appendix-table-writer )
Merge order is driven by outline/outline.yml . The draft title is taken from GOAL.md when present. sections/sections_manifest.jsonl is an optional diagnostics input.
This skill is deterministic: it does not rewrite content or invent prose; it only merges already-generated artifacts.
Transitions (injected text)
-
By default, section-merger inserts only within-chapter H3->H3 transitions.
-
Optional: if you want between-H2 transitions inserted too, create outline/transitions.insert_h2.ok in the workspace.
-
Format contract: only lines matching - 3.1 -> 3.2: <text> are injected by default.
-
Compatibility: → is accepted, but -> is the preferred contract (avoids control-character encoding issues).
-
Treat transitions as injected draft text: run post-merge-voice-gate after merging, and route fixes back to outline/transitions.md (do not patch the merged draft).
Tables (two layers)
This pipeline uses two table layers:
outline/tables_index.md (internal index; produced by table-filler )
-
planning/debugging artifact
-
should NOT be inserted into the paper
outline/tables_appendix.md (reader-facing Appendix tables; produced by appendix-table-writer )
-
publishable tables (clean layout + high information density)
-
inserted by section-merger under a single Appendix heading
Appendix insertion behavior
-
section-merger inserts outline/tables_appendix.md at the end of the draft under ## Appendix: Tables .
-
The inserted block is heading-free (any accidental # headings inside the tables file are stripped).
-
Opt-out (rare): create outline/tables.insert.off in the workspace.
Inputs
-
outline/outline.yml (drives section/subsection order)
-
outline/transitions.md (required)
-
sections/sections_manifest.jsonl (optional diagnostics)
-
GOAL.md (optional title)
For arxiv-survey pipelines (default contract):
- outline/tables_appendix.md (required unless opted out)
Outputs
-
output/DRAFT.md
-
output/MERGE_REPORT.md
Script
Quick Start
-
python .codex/skills/section-merger/scripts/run.py --help
-
python .codex/skills/section-merger/scripts/run.py --workspace workspaces/<ws>
All Options
-
--workspace <workspace_dir> (required)
-
--unit-id <id> (optional; used only for runner bookkeeping)
-
--inputs <a;b;c> (optional; override inputs; defaults are profile-aware)
-
--outputs <draft_rel;report_rel> (optional; defaults to output/DRAFT.md;output/MERGE_REPORT.md )
-
--checkpoint <C#> (optional; ignored by the merger)
Examples
Merge with defaults (profile-aware table insertion):
python .codex/skills/section-merger/scripts/run.py --workspace workspaces/<ws>
Merge with explicit outputs:
python .codex/skills/section-merger/scripts/run.py --workspace workspaces/<ws> --outputs output/DRAFT.md;output/MERGE_REPORT.md
Troubleshooting
Issue: merge report says a subsection file is missing
Likely cause:
- A required sections/*.md file has not been written yet.
Fix:
- Write the missing units under sections/ (typically via subsection-writer ) and rerun merge.
Issue: Appendix tables are missing in the merged draft
Fix:
-
Ensure outline/tables_appendix.md exists and contains >=2 Markdown tables (no placeholders).
-
Ensure you did not create outline/tables.insert.off .
-
Rerun section-merger .