# W26 — The text half is machine-generated (Request #6, the real fix)

Supersedes W24. W24 shipped an escaper in v0.4.2 on a hypothesis that live proof has now
falsified; this wave replaces it with the construct the proofs actually support, and
removes the regression the escaper introduced.

## What the proofs established

Three discriminating experiments in the testbed channel, all read on the live surface:

| proof | title content | render |
| --- | --- | --- |
| [#30](https://github.com/BigscreenVR/alchemy-testbed/issues/30) | a code span | LITERAL, visible backslashes |
| [#32](https://github.com/BigscreenVR/alchemy-testbed/issues/32) | brackets + `](`, no backticks | LITERAL, visible backslashes |
| [#33](https://github.com/BigscreenVR/alchemy-testbed/issues/33) | no symbols at all | **one clickable link** |

Read together: **masked links render fine on this surface — Discord simply does not honor
backslash escapes inside the text half of one.** An escaped `\]` is not an escaped
bracket there; it is a backslash and a bracket, which malforms the construct and drops the
whole line to plain text. So W24's premise ("Discord honors backslash escapes, so it
renders as written" — `botpost.rs`) was wrong, and every escape site has been *causing*
the literal render it was written to prevent.

The escaper also regressed input that worked before it: a title with `[` and no `]` used
to render as a clean link, and since v0.4.2 shows a stray backslash.

## The fix

**Operator-authored text never enters the text half.** The text half becomes
machine-generated only — the `#N` ref the daemon already computes, or a fixed word — and
the title trails the closed construct as plain text, where markdown in it is a cosmetic
rendering of the Operator's own words rather than a broken link.

Five sites, all moving to the same rule:

| site | v0.4.2 (broken) | W26 |
| --- | --- | --- |
| Seeds-thread entry | `- [<title>](jump)` | `- [seed](jump) — <title>` |
| Updates: capture | `🌱 [<title>](mirror) — new seed` | `🌱 [new seed](mirror) — <title>` |
| Updates: mint | `[#N \| <title>](card) — seed → Backlog` | `[#N](card) \| <title> — seed → Backlog` |
| Updates: transition | `[#N \| <title>](url) — now <thread>` | `[#N](url) \| <title> — now <thread>` |
| Milestone sub-issue line | `- [#N \| <title>](url)` | `- [#N](url) \| <title>` |

`botpost::escape_link_text` is deleted, not rewritten: with the title outside the
construct there is nothing left to escape, and keeping a disproven escaper around invites
re-application.

Unchanged and load-bearing: the **url half stays byte-exact** — `seed_entry_matches` keys
the Seeds-thread mirror lookup on `](<url>)`, and both the current and the legacy
`<url> — <title>` shapes must keep matching. Emoji stay OUTSIDE the brackets
(Operator-confirmed live, 2026-07-23); that constraint survives this change untouched.

## What this repairs, and what stays broken

Same asymmetry W24 got wrong once and the v0.4.2 release body was corrected for — stated
here so the changelog does not overclaim again: only the **milestone sub-issue line** is
content the reconcile diffs against, so only milestone posts self-repair on the next
cycle. Seeds-thread entries and Updates notes are written once and never revisited; every
one already posted stays broken. No migration pass is planned — the Request card carries
the same facts and renders correctly.

Changing the sub-issue line changes reconcile-diffed content, so the first cycle after
install rewrites every milestone post once and then holds at zero mutations
(REQ-HAZARD-RECONCILE-IDEMPOTENT's bar).

## Open design questions

- **Should the trailing title be neutralized too?** A title containing `[x](y)` will now
  render as a link of the Operator's own making, outside our construct. Ruling: leave it.
  Discord renders user markdown everywhere else in the surface, the payload is their
  words, and the alternatives (a code span that breaks on backticks, or stripping) are
  each a fresh hypothesis about someone else's parser — which is the exact mistake W24
  made. Revisit only on a live report.

## Tasks

- **T1 — registry.** Retire `REQ-LINK-TEXT-ESCAPE` (its title states a disproven
  mechanism); add `REQ-LINK-TEXT-MACHINE`, activated `["doc","impl","unit"]`.
- **T2 — doc.** Rewrite `CONTEXT.md`'s masked-link section to the machine-text rule, with
  the proof table as the evidence. `<!-- [doc->REQ-LINK-TEXT-MACHINE] -->`
- **T3 — impl.** Delete `escape_link_text`; rewrite all five sites.
- **T4 — unit.** A hostile title (this repo's Request #5 shape) at every site: the text
  half is byte-equal to the machine string, the url half is byte-exact, the mirror lookup
  still finds the entry, and no backslash is ever emitted.
- **T5 — gate + ship.** `cargo test` + `traceable-reqs check` green, cut **0.4.3** per
  `docs/RELEASE-RUNBOOK.md`, install on this node, relink shells.
- **T6 — live proof.** A fourth testbed Request whose title carries `](` — the #32 shape
  that rendered literal — posted through the real daemon. Renders as `#N` clickable with
  the title beside it, or the fix is not proven. **Unit-green is not proof here: the
  subject of this fix is how another system renders.** Only T6 closes Request #6.

## Gate

`cargo test` green, `traceable-reqs check` exit 0, and T6's live render read on the
surface before Request #6 is recommended for Done.
