Fix ia-candidate marker HTML-comment wrapper loss (kotkan/claude-plugin-inference-arbitrage#23) #27

Merged
oleks merged 3 commits from fix/issue-23-marker-wrapper into main 2026-07-30 19:54:28 +03:00
Owner

Fixes kotkan/claude-plugin-inference-arbitrage#23.

Root cause. bin/filing-plan and references/issue-template.md always render the ia-candidate marker HTML-comment-wrapped (&lt;!-- ia-candidate: &lt;id&gt; --&gt;). A direct issue_write probe against the live Gitea (create + update with a literal <!-- --> in the body, then read it back) confirmed the Gitea MCP write path preserves the wrapper unchanged — so the loss on oleks/claude-plugin-cluster#56 and #57 did not happen in filing-plan's rendering or in the Gitea/MCP write path. It happened on the relay hop: Agent(anxious:issuer-agent) composing the actual Gitea call from a prompt that inlined the rendered body as bare markdown. An HTML comment is invisible when read as markdown, so the relaying agent could describe/retype "what the body says" without ever seeing (and thus reproducing) the marker line.

Fixes, both implemented per the issue's ask:

  1. bin/filing-plan: marker_re() / find_existing() now also match the bare, unwrapped ia-candidate: <id> line (end-of-line anchored under re.MULTILINE, not \b — candidate ids contain -, and a word-boundary check would false-match a longer id sharing a prefix, e.g. label-derivation inside label-derivation-longer). This is backward compatibility for already-filed issues like cluster#56/#57, not a second accepted format going forward.
  2. skills/offload-audit/SKILL.md §5d: the issuer-agent delegation prompt now embeds the rendered body inside its own fenced code block and explicitly warns that the leading marker is an invisible-by-design HTML comment, not stray syntax to "clean up" — instead of inlining it as bare markdown the relaying agent could read straight through.
  3. references/issue-template.md: documents the failure mode and both fixes under "The marker is load-bearing", including the write-path probe evidence.
  4. tests/filing.test.sh: new cases — a bare (unwrapped) marker on the tracker is still found and produces comment, not a duplicate file; a different candidate id that merely shares a prefix with a bare marker still files fresh (guards the \b→end-of-line regex fix against a false-positive regression).

Also bumped plugin.json to 0.7.1.

Verification

$ bash tests/filing.test.sh
... (all checks "ok", including the new bare-marker cases)
== kotkan/claude-plugin-inference-arbitrage#23: a marker that lost its
   HTML-comment wrapper on write (oleks/claude-plugin-cluster#56, #57)
   is still found — backward compat, not a second accepted format ==
  ok   bare marker still found, no duplicate filed = 0
  ok   recognized as a comment on the existing issue = comment
  ok   on issue 56, matching the observed failure = 56
== a bare marker for a DIFFERENT id still does not false-match ==
  ok   different id (even as a prefix) still files fresh = 1

exit 0.

Not armed for auto-merge — leaving that to the parent session per standing process.

Fixes kotkan/claude-plugin-inference-arbitrage#23. **Root cause.** `bin/filing-plan` and `references/issue-template.md` always render the `ia-candidate` marker HTML-comment-wrapped (`&lt;!-- ia-candidate: &lt;id&gt; --&gt;`). A direct `issue_write` probe against the live Gitea (create + update with a literal `<!-- -->` in the body, then read it back) confirmed the Gitea MCP write path preserves the wrapper unchanged — so the loss on oleks/claude-plugin-cluster#56 and #57 did not happen in `filing-plan`'s rendering or in the Gitea/MCP write path. It happened on the relay hop: `Agent(anxious:issuer-agent)` composing the actual Gitea call from a prompt that inlined the rendered body as bare markdown. An HTML comment is invisible when read as markdown, so the relaying agent could describe/retype "what the body says" without ever seeing (and thus reproducing) the marker line. **Fixes, both implemented per the issue's ask:** 1. `bin/filing-plan`: `marker_re()` / `find_existing()` now also match the bare, unwrapped `ia-candidate: <id>` line (end-of-line anchored under `re.MULTILINE`, not `\b` — candidate ids contain `-`, and a word-boundary check would false-match a longer id sharing a prefix, e.g. `label-derivation` inside `label-derivation-longer`). This is backward compatibility for already-filed issues like cluster#56/#57, not a second accepted format going forward. 2. `skills/offload-audit/SKILL.md` §5d: the `issuer-agent` delegation prompt now embeds the rendered body inside its own fenced code block and explicitly warns that the leading marker is an invisible-by-design HTML comment, not stray syntax to "clean up" — instead of inlining it as bare markdown the relaying agent could read straight through. 3. `references/issue-template.md`: documents the failure mode and both fixes under "The marker is load-bearing", including the write-path probe evidence. 4. `tests/filing.test.sh`: new cases — a bare (unwrapped) marker on the tracker is still found and produces `comment`, not a duplicate `file`; a different candidate id that merely shares a prefix with a bare marker still files fresh (guards the `\b`→end-of-line regex fix against a false-positive regression). Also bumped `plugin.json` to `0.7.1`. **Verification** ``` $ bash tests/filing.test.sh ... (all checks "ok", including the new bare-marker cases) == kotkan/claude-plugin-inference-arbitrage#23: a marker that lost its HTML-comment wrapper on write (oleks/claude-plugin-cluster#56, #57) is still found — backward compat, not a second accepted format == ok bare marker still found, no duplicate filed = 0 ok recognized as a comment on the existing issue = comment ok on issue 56, matching the observed failure = 56 == a bare marker for a DIFFERENT id still does not false-match == ok different id (even as a prefix) still files fresh = 1 ``` exit 0. Not armed for auto-merge — leaving that to the parent session per standing process.
oleks added 3 commits 2026-07-30 19:25:56 +03:00
Root cause: bin/filing-plan and references/issue-template.md always render
the ia-candidate marker HTML-comment-wrapped. A direct issue_write probe
confirmed the Gitea MCP write path preserves a literal <!-- --> unchanged, so
the loss on oleks/claude-plugin-cluster#56 and #57 happened on the
Agent(anxious:issuer-agent) relay hop: an HTML comment is invisible when its
surrounding text is read as markdown, so an agent relaying "what the body
should say" instead of pasting it verbatim can silently drop it.

Two fixes:
- bin/filing-plan: find_existing()'s marker_re() now also matches the bare,
  unwrapped "ia-candidate: <id>" line (end-of-line anchored, not \b, since
  candidate ids contain "-" and a word-boundary check would false-match a
  longer id sharing a prefix) so already-filed issues like cluster#56/#57
  are still recognized and not duplicate-filed.
- skills/offload-audit/SKILL.md: the issuer delegation prompt now fences the
  rendered body in its own code block and explicitly warns that the leading
  marker is an invisible-by-design HTML comment, not stray syntax to clean
  up, instead of inlining it as bare markdown the relaying agent could read
  right through.

references/issue-template.md documents both, and tests/filing.test.sh adds
coverage for the bare-marker match plus a same-prefix-different-id
non-match case.

Bumps plugin.json to 0.7.1.
The previous commit nested a triple-backtick example fence inside a
triple-backtick pseudocode block; the repo's markdown auto-formatter treated
the inner ``` as closing the outer block and reindented/moved the "for
action == comment" case out of the Agent(...) call. Use ~~~ for the outer
fence so the real triple-backtick example nests without collision.
Use 4-backtick outer fence (markdownlint MD048 requires backtick, not tilde)
ci/woodpecker/push/test Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
5f5462571c
The tilde fence from the previous commit avoided the nesting collision but
violated this repo's markdownlint style (backtick-only), which the pre-push
hook enforces and rejected. A 4-backtick outer fence with the real 3-backtick
example nested inside satisfies both: CommonMark only closes a fence on a
matching-or-longer run of the same character, and MD048 sees backticks
throughout.
oleks scheduled this pull request to auto merge when all checks succeed 2026-07-30 19:30:35 +03:00
oleks merged commit 9a25402d37 into main 2026-07-30 19:54:28 +03:00
Sign in to join this conversation.