Skip to content

Drop the <!-- markfluence-version --> comment directive - #159

Merged
willkg merged 3 commits into
mainfrom
drop-version-token
Sep 13, 2026
Merged

Drop the <!-- markfluence-version --> comment directive#159
willkg merged 3 commits into
mainfrom
drop-version-token

Conversation

@willkg

@willkg willkg commented Sep 13, 2026

Copy link
Copy Markdown
Member

Closes #158.

The <!-- markfluence-version --> directive substituted the build stamp into a published page. It failed at the one thing it was for, and broke two things that matter.

It answered none of a reader's questions. markfluence 1.2.3 (abc1234, 2026-09-13) names the tool's version — not the repository, not the file, not what to do instead of editing. The banner that does is a callout linking the source, which needs no token and is already documented in docs/github-actions.md. GitHub alerts already convert to Confluence panels.

It had no inverse, so it corrupted a round trip. <!-- confluence-toc --> survives one — storage_to_md.go:634 turns the toc macro back into the token. This emitted a bare string with no marker, so export wrote the old version into the markdown as literal text and the token was gone: an L5/L6 defect that got worse every release.

It made unchanged content look changed. #149's idempotence check compares rendered storage against the live body to decide whether publishing would change anything — which is what lets a CI run skip pages instead of notifying every watcher. A page carrying this token re-rendered on every markfluence upgrade. #149 recorded that as a wart needing a workaround; this removes the wart.

And it made check machine-dependent, contradicting CLAUDE.md. cmd/check/check.go passed buildinfo.Stamp(), which embeds the commit SHA and build date, while CLAUDE.md claimed check hardcodes baseURL/spaceKey so its output is byte-identical across machines. That was false for any file using the token. It is true now.

What changed

MdToConfluence loses its version string parameter, which is most of the value: three commands stop importing buildinfo for a value the converter did not otherwise need, and the converter's output now depends only on its arguments and the files under root — no build state, no clock, nothing from the environment. regression_test.go passed a fixed stamp precisely to neutralize that, so the goldens are deterministic by construction now rather than by a pinned constant. No fixture used the token, so nothing moved.

buildinfo.Stamp stays — cmd/root.go prints it for --version — with a comment saying nothing published carries a build stamp, so it does not drift back into convert.

TestVersionTokenReplaced is deleted; it tested only the removed substitution.

A claim I had to measure, and got wrong

The first draft documented that a file still holding the token "publishes it as an ordinary HTML comment, which is inert in storage format and invisible on the page." This repo establishes Confluence claims by experiment, so I probed it — and the claim was wrong.

Confluence strips every HTML comment on write. Measured 2026-09-13, block and inline, and the removal is not even whitespace-clean:

- <p>before</p><!-- generic block comment --><p>mid <!-- inline comment --> text</p><p>after</p>
+ <p>before</p><p>mid  text</p><p>after</p>

Note mid text. Recorded in docs/confluence/storage-format.md under the existing does-not-round-trip section, with two consequences that outlive this PR:

  • client.updateLanded can never match for a page whose markdown holds an HTML comment. It recovers a lost response by accepting a write only when version, title and body.storage all equal what was sent, and the stored body always differs by the stripped comment — so a write that actually landed is reported as a failure. Pre-existing and narrow, since nothing markfluence generates is a comment (<!-- bg:COLOR --> is consumed by the AST transformer, <!-- confluence-toc --> is substituted), but an author-written comment is legal markdown and passes straight through html.WithUnsafe().
  • A content-based idempotence check has to normalize comments away, and by more than stripping: the sent body has mid <!-- c --> text while the stored body has mid text, so whitespace has to collapse too. Posted on update silently overwrites a page that moved on: nothing records what a local copy was derived from #149, with a note that whatever lands should be shared with updateLanded rather than written twice.

This is also the first HTML comment markfluence would ever have actually published, which is why nothing had measured it before.

No compatibility notes

ce5a369 removes every remaining mention of the token from the repository. markfluence is unreleased, so there is nobody to keep compatible with and no reason for a "this used to exist" note; each of the five sites that described it in the past tense now states the property positively instead — which is the thing worth knowing anyway, expressed as a rule for what may not be substituted into the converter rather than the history of one thing that was.

docs/markdown_file.md's comment-directives section gains the fact that matters to an author: confluence-toc is the only directive, and any other HTML comment is discarded by Confluence.

The only surviving mention is _plans/012_read-markdown-format.md, deliberately — it is a historical plan, and rewriting it would make the record lie.

Verification

  • make check green on each commit.
  • Verified behaviourally rather than assumed: a file still holding the token now passes it through to the storage body unchanged (and Confluence then discards it, per above), <!-- confluence-toc --> still becomes the macro, and --version still prints markfluence dev (487ed70, 2026-09-13).
  • grep over git ls-files for markfluence-version returns _plans/012 alone.
  • Probe pages created, measured, deleted and purged.

No _plans/ file: two constants and a parameter, with #158 as the design record and the one durable finding in docs/confluence/.

Closes #158. The token substituted the build stamp into a published page, and
it failed at the one thing it was for while breaking two things that matter.

**It answers none of a reader's questions.** "markfluence 1.2.3 (abc1234,
2026-09-13)" names the tool's version, not the repository, the file, or what to
do instead of editing. The banner that does is a callout linking the source,
which needs no token and is already documented in docs/github-actions.md -- a
GitHub alert converts to a Confluence panel.

**It had no inverse, so it corrupted a round trip.** confluence-toc survives one
(storage_to_md.go turns the macro back into the token); this emitted a bare
string with no marker, so export wrote the old version into the markdown as
literal text and the token was gone -- an L5/L6 defect that got worse every
release.

**It made unchanged content look changed.** #149's idempotence check compares
rendered storage against the live body to decide whether publishing would change
anything, which is what lets a CI run skip pages instead of notifying every
watcher. A page carrying this token re-rendered on every upgrade. #149 recorded
that as a wart needing a workaround; this removes the wart.

**And it made check machine-dependent.** check passed buildinfo.Stamp(), which
embeds the commit SHA and build date, while CLAUDE.md claimed check hardcodes
baseURL/spaceKey so its output is byte-identical across machines. That was false
for any file using the token. It is true now.

MdToConfluence loses its version parameter, which is most of the value: three
commands stop importing buildinfo for a value the converter did not otherwise
need, and the converter's output now depends only on its arguments and the files
under root -- no build state, no clock. regression_test.go's fixed stamp existed
to neutralize exactly that, so the goldens are deterministic by construction
now; no fixture used the token, so nothing moved.

buildinfo.Stamp stays -- cmd/root.go prints it for --version -- with a comment
saying nothing published carries it, so it does not drift back into convert.

A file still holding the token publishes it as an ordinary HTML comment, inert
in storage format and invisible on the page. Verified, along with the toc token
still converting and --version unchanged.
**CLAUDE.md contradicted itself on one line.** The internal/convert bullet
stated the old six-argument MdToConfluence signature at its head while the tail,
which the previous commit edited, said the version argument is gone. CLAUDE.md
is the authority for signatures, so a reader taking the first thing in the
bullet would write a six-arg call.

**cmd/root.go was the last claim in source that the token exists.** The Version
field's comment still described the stamp as "the same string the converter
substitutes for the <!-- markfluence-version --> token", which is where anyone
grepping cmd/ for the token lands.

**And the docs asserted Confluence behaviour I had not measured**, which this
repo does not allow. I wrote that a file still holding the token "publishes it
as an ordinary HTML comment, which is inert in storage format and invisible on
the page". Measuring it says otherwise: Confluence strips every HTML comment on
write, block and inline, so it never reaches the stored body -- and an inline one
leaves its surrounding whitespace, turning "mid <!-- c --> text" into
"mid  text" with a doubled space. The removal is not even positionally clean.

Recorded in docs/confluence/storage-format.md under the existing
does-not-round-trip section, with two consequences that matter more than the
wording:

client.updateLanded can never match for a page whose markdown holds an HTML
comment. It accepts a write only when version, title and body.storage all equal
what was sent, and the stored body always differs by the stripped comment -- so
a write that landed is reported as a failure. Narrow today, since nothing
markfluence generates is a comment (bg:COLOR is consumed by the transformer,
confluence-toc is substituted), but an author-written comment is legal markdown
and passes through html.WithUnsafe().

And #149's content-based idempotence check has to normalize comments away or it
reports a difference on every run for an unchanged file, which is the opposite
of its purpose.
markfluence is unreleased, so there is nobody to keep compatible with and no
reason for a "this used to exist" note. Five sites described the token in the
past tense; each now states the property positively instead, which is the thing
worth knowing anyway:

- convert.go and CLAUDE.md: MdToConfluence's output depends only on its
  arguments and the files under root -- no build state, no clock, nothing from
  the environment -- which is what makes the goldens deterministic by
  construction and check --show-html byte-identical across machines at one
  commit. Stated as a rule for what may not be substituted in, rather than as
  the history of one thing that was.
- buildinfo.go: only --version uses Stamp, nothing published carries a build
  stamp, keep it out of internal/convert.
- root.go: the same, from the caller's side.
- regression_test.go: the goldens need nothing pinned to stay stable.

docs/markdown_file.md's comment-directives section gains the fact that matters
to an author instead: confluence-toc is the only directive, and **any other HTML
comment is discarded by Confluence**, which strips every one on write. So a
comment is not a way to leave a note on a published page, and the remedy for
"say where this came from" is a callout linking the source file.

The only surviving mention is _plans/012, which is a historical plan and is left
alone -- rewriting it would make the record lie.
@willkg
willkg merged commit 4301091 into main Sep 13, 2026
1 check passed
@willkg
willkg deleted the drop-version-token branch September 13, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drop the <!-- markfluence-version --> comment directive

1 participant