← ClaudeAtlas

markdown-idempotent-section-mergelisted

Idempotently replace-or-append one Markdown section (a "## Heading" block) without corrupting code fences. Use on symptoms like: an automated section merge duplicated the section on every run, a replace range was cut short at a "##" line inside a code fence, a heading inside a code fence was treated as the next section boundary, a "###" subheading ended the section early, a README / AGENTS.md / CLAUDE.md updater never converges (the second run still changes the file), or a leftover fence swallowed the rest of the document after a bad merge. Covers fence-aware heading scanning, fixed begin/end marker boundaries, the single-H2 invariant (^##[^#]), and an apply-twice-diff-zero verification recipe with a tested reference implementation.
h8nc4y/markdown-idempotent-section-merge · ★ 0 · Code & Development · score 72
Install: claude install-skill h8nc4y/markdown-idempotent-section-merge
# Markdown Idempotent Section Merge Procedure for maintaining one canonical `## Heading` section in a Markdown document under automation: replace the section when it exists, append it when it does not, and produce byte-identical output when applied twice. The non-obvious part is where the section *ends* — and the classic mistake is trusting a bare `^##` regex to find that boundary. ## When To Use - An agent or script keeps a canonical section up to date in a document it does not fully own — `README.md`, `AGENTS.md`, `CLAUDE.md`, a handbook, a changelog preamble — on a "replace if present, append if missing" rule. - You see any of these symptoms: - The maintained section is duplicated after every run. - A merge cut the section short in the middle of a fenced code block. - A `## ...` line *inside* a code fence was treated as the next section. - A `###` subheading ended the replace range early. - The updater never converges: the second run still changes the file. - After a merge, everything below some point renders as one giant code block (a leftover fence delimiter re-opened as a new fence). - You are *reading* or *counting* sections with `^##`-style patterns, not only writing them — extraction and verification hit the same trap. ## The Trap: Headings Inside Code Fences The naive implementation takes the replace range as "the `## X` line up to the line before the next `^##` match". It breaks in two ways. **Trap 1 — fenced literals.** Section bodies l