v1.22.0 ·
The issue said nothing, and said it truthfully
One release earlier I shipped the ability to project the roadmap onto GitHub Issues. The first real output was read by the person who asked for it, and the verdict was two words: pretty lame.
An issue said, in full, that it was projected from the repository's roadmap, gave the item id and the file path, and explained that the file was the source of truth and the description was never rewritten after creation. Every word was true and none of it was useful.
It was a redirect, not a description. The path was inline code, not a link, so a reader without a checkout had nowhere to go. Product, support and a contributor on a phone were all locked out, and the point of putting the roadmap in the tracker was that they could read it. Every issue was also interchangeable. On a board of thirty, the bodies were thirty copies of one paragraph, so search, skimming and email notifications were worthless. And it could never become right. An item edited on disk left its issue stale for good.
The thin body had been argued for, on three real grounds. The item-to-issue link is an HTML comment, so an item that merely quotes a marker would stamp a second marker on a different issue. Mentions and issue references in item prose notify people and cross-link the moment they are published. And the platform caps a body at 65,536 characters. Three real hazards, and a conclusion that traded the feature's whole purpose for three mechanisms I did not want to write.
What changed
aidlc roadmap sync now publishes the item. The body has a facts block from the frontmatter: status, created date, author, source, dependencies and the instance it was promoted to, with not recorded for anything the item does not say. Then the item's whole prose, then links. The roadmap file is a working permalink, and item ids in the prose become links to their files.
The body is also kept in step now. A fifth write outcome, update-body, is planned whenever the stored region differs from a fresh render. The projection owns only the bytes between two delimiters, so a note someone adds above or below survives every sync. Comments were never at risk, since they are separate from the body. That was the stated reason for freezing it, and it did not hold.
Each old hazard has an answer. HTML comments are stripped from prose, which loses nothing because a comment renders as nothing. Mentions and references in prose are wrapped in backticks, so a sync notifies nobody. The body stays under a budget below the platform limit and says how much it cut.
What measurement decided
I planned to sanitize without regard to code. First I ran the predicate over all 76 real items, 451,503 characters. Of 41 hazard-shaped spans, 40 sit inside a fence or an inline code span, and exactly one is in prose. They are an npm scoped name, a pinned GitHub Action, and CSS colour hexes that a #123 pattern also matches. A code-blind rule would have corrupted forty spans to defuse one. So one primitive decides what counts as code, and both the sanitizer and the marker scanner use it.
That scan corrected the requirements twice, in a recorded amendment. A stricter scanner showed that one reference is in prose after all, and that all 32 item-id references are code spans holding only the id. The linking rule I had written for prose could never have fired on real data. I retired it and wrote a new one.
Permalinks use HEAD, not main. On the day, one well-known repository returned 200 for a file under blob/HEAD/ and 404 under blob/main/, because its default branch is trunk. I chose backticks over the invisible trick of an empty HTML comment, because the sanitizer strips comments and the identity marker is one. The cost is that one span in the corpus renders in code style.
Running things found six defects. The worst two would have shipped as the exact failure the design warned about. The renderer added a trailing newline the extractor could never return, so every item would have planned a refresh on every run, forever. And truncation could land inside a code block and leave a fence open.
A dry run against this repository planned a body refresh for the issue that prompted the work. Its rendered body is 8,304 characters, and its four superseded predecessors resolve to working links.