review 130 feature ideas, and delete the lists that held them
One idea at a time: definition, necessity, priority, layer, recommendation. Every row is now shipped, scheduled, parked with a trigger, or dropped with a reason — so both tracking files are gone rather than left as a parallel backlog. Roughly a third already shipped. A quarter needed only a theme fragment or CSS, including several the list assumed were features: arbitrary `theme.*` frontmatter attributes already reach templates through Extra (verified), native lazy loading already ships and is deliberately absent on lead figures, and in-page timelines are a theme-defined container. roadmap.md gains an "Order of work" — nine bodies of work in sequence, because the sections this review added had accumulated without one. Item 0 is a decision, not work: core sits at ~2965 of 3000 and logging alone wants the remainder, so discover.go moves out *and* the ceiling rises with an ADR. feed.go and web/extras.go cannot move; they are resolver cases, and three parked items now wait on that same seam decision. Two ADRs came out of it. ADR-0083: the dependency rule described a practice it forbade. "Stdlib first, always" and "usually 40 lines of stdlib" would, read literally, have argued against all five modules here — every one is a format or algorithm somebody else specified, and their allowlist comments say so. Surfaced when this agent proposed hand-rolling Reed–Solomon for QR encoding. The test is now whether you can verify it, not whether you can write it, with compute-versus-hold as the counterweight. conventions.md and allowed-deps.txt contradicted it and were realigned. ADR-0084: the Effect primitive said every Effect is "idempotent and re-runnable from scratch" — true of derivatives, false of anything outbound, since a sent message cannot be recalled. Split into artifact-producing and outbound, the latter idempotent only against a delivery ledger, at-least-once with a dedupe key, and ledgers in a -state directory distinct from the disposable cache. Asked for as forward-looking design so webmentions need no redesign; recorded as a shape rather than built, the way extensions.md records the Extension struct. Also fixed a STATUS claiming Effects were "not buildable yet" when the derivative pass has inhabited them since ADR-0042. Findings that were defects rather than ideas: the Atom feed emits no <author>, which RFC 4287 requires. HTML comments in content are published verbatim — verified — so anything commented out is already public, and a check warning is scheduled rather than the engine deleting authored bytes. `Page` has no Date, so a theme cannot mark up dt-published or show an article's own date. A frontmatter naming rule after this agent proposed `archive` alongside the accepted `archived`: no near-homograph keys, and name the benefit rather than the vendor. reference/microformats-and-indieweb.md is new and is the reference asked for — microformats2 properties and IndieWeb rel values mapped to where a theme puts them, with spec URLs, marked scheduled. rel="me" is the highest-value lowest-cost item in that space and needs no endpoint at all. Four things this agent got wrong and the human caught: asserting "the engine never fetches" from a sentence scoped to the content repo, twice; inventing a data-sovereignty argument for an item he had filed as "a cool geeky thing", when the raw Markdown in his git already is the sovereignty; the archive naming; and claiming microformats could be fully implemented today. 15 files, +556/-385. No code changed. Nothing was scheduled that this agent could not name a consumer for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+50
-5
@@ -18,14 +18,59 @@ Use `/leaf <topic>` to get a verdict written into this file.
|
||||
|
||||
## Verdicts
|
||||
|
||||
One row per body of work triaged, not per item — the item-level verdicts live in the file each row names,
|
||||
because 130 rows here would make a catalogue nobody can skim.
|
||||
The human's 130-item feature list was reviewed one item at a time on 2026-08-02 and the file holding it is
|
||||
gone: everything is now either shipped, scheduled in `harness/roadmap.md`, parked below, or dropped below.
|
||||
Roughly a third already shipped, a quarter needed only a theme fragment or CSS, and nine bodies of work were
|
||||
scheduled. Two ADRs came out of it — ADR-0083 (dependencies) and ADR-0084 (Effects).
|
||||
|
||||
| Body of work | Verdict | Reduces to | Note |
|
||||
|---|---|---|---|
|
||||
| The human's feature list, 130 items | triaged in full | mostly nothing new | [feature-list-triage.md](feature-list-triage.md): 42 BUILT, 24 THEME (a fragment or CSS, no engine code), 29 LEAF, 2 TRUNK, 4 PARK. Three LEAF items have shipped since — task lists (ADR-0078), page assets (ADR-0079), passthrough routes (ADR-0081) |
|
||||
| Corrections and updates per post | **rejected in its cheap form**, parked in its real one | Effect | [corrections-from-history.md](corrections-from-history.md). A hand-maintained frontmatter list was dropped because a half-remembered list of corrections misleads where none would not; deriving it from repository history waits on the Effect runner and on whether the engine may read git at all |
|
||||
| Per-piece template variants | the highest-value item in the list | **View** | Not parked — it is the second concrete use that earns the View primitive, and `harness/roadmap.md` closes Arc 2 when that lands. Tracked as scheduled work, not as an idea |
|
||||
| Corrections and updates per post | **rejected in its cheap form**, parked in its real one | Effect | [corrections-from-history.md](corrections-from-history.md). A hand-maintained frontmatter list misleads where none would not; deriving it from repository history waits on the Effect runner and on whether the engine may read git at all. Per-post edit history is parked in that same file |
|
||||
| Per-piece template variants | the highest-value item in the list | **View** | Scheduled, not parked: the second concrete use that earns the View primitive, and `roadmap.md` closes Arc 2 when it lands |
|
||||
| Bengali morphology for search | original work, not a sub-task | — | [bengali-search-morphology.md](bengali-search-morphology.md). Exact-form search is scheduled without it and documents its own absence |
|
||||
|
||||
## Parked, with triggers
|
||||
|
||||
Each of these was reviewed and deliberately not scheduled. The trigger is what would change that — a
|
||||
condition, not a mood.
|
||||
|
||||
| Item | Trigger | What was decided |
|
||||
|---|---|---|
|
||||
| Date-grouped listings | wanting any one of: a cross-page timeline, a yearly wrap-up, a date-grouped archive | One partition beside the existing section one serves all three, following ADR-0046's rule that the engine partitions and the theme decides whether it *looks* grouped. Individually none justifies the work |
|
||||
| Inline code highlighting | writing enough technical prose to feel the lack | Syntax settled in advance: a trailing attribute block — `` `code`{lang=python} `` — never a marker inside the span, since a code span is literal and this engine's recurring defect is new syntax eating prose. Matches Pandoc/Djot and the existing `## Title {#id}` form. Wants its own ADR, because authored syntax is a contract with the author's files |
|
||||
| Ruby annotations for glosses | the free path failing | Works today via raw HTML. The zero-cost path first: a theme rendering existing `*[TERM]:` abbreviations as `<ruby>`, since a gloss above versus on hover is presentation over data already collected. Caveat: abbreviations expand at *every* occurrence. Standing note — the inline delimiter budget is nearly spent (`~ ^ = *` all taken), which argues against inventing marks |
|
||||
| Archive.org snapshot links beside external links | something wanting a pass over authored anchors more than this does | Needs a parse-phase walk over link nodes; a theme cannot do it. Modest value. Distinct from *submitting* links, which is scheduled |
|
||||
| JSON Feed | a reader or client you actually use asking for it | Atom covers every consumer. `/feed.json` site-wide is an exact path and could be a feature cheaply; section and tag scopes are resolver cases, so decide it with that seam |
|
||||
| Content as data / a personal JSON API | wanting it for its own sake | The human's own framing: "a cool geeky thing", may never be used. The sovereignty argument for it is **wrong** — the raw Markdown in his git already is the sovereignty. `/all.json` site-wide is an exact-path escape; per-bundle is resolver-gated |
|
||||
| oEmbed | building the capture feature below | Reframed: not a render-time embed, which ADR-0080 refuses, but *capture-time metadata discovery* — how a snapshot learns a URL's title, author and thumbnail |
|
||||
| Static copies of external content | wanting to quote something that may vanish | Engine-produced, not by another tool. Shape decided: a `khosra snapshot` subcommand following `scaffold`'s precedent for writing to the site root, into **the bundle** rather than the disposable cache since a snapshot must outlive its source, storing **sanitised** text, image and attribution — never the remote HTML, which would execute, because site-root content is trusted by location (ADR-0060) |
|
||||
| Image processing, as one cluster | any one of them mattering | Cropping (a parameter on the derivative pass, folded into the content hash), EXIF display (the engine already inspects every image for dimensions, so this extends a shipped pass), a view-full-resolution link (nearly free — the original is already `src`), before/after comparison (CSS-only variants exist; the draggable one is JS and refused), and the AVIF gap (no Go decoder, so it passes through unresized). Clustered at the human's request rather than scattered |
|
||||
| POSSE back-links | wanting a page to link its own copies | Syndication itself is absorbed by the scheduled notify work — n8n posts to platforms. The residual is `u-syndication`: recording where copies live, which needs somewhere to put the URLs |
|
||||
| Micropub | wanting to publish from a phone | The endpoint is easy; **IndieAuth is the bulk**. Persistence is not a blocker and the resolution is recorded: the engine writes through `os.Root` (scaffold's precedent) and the operator's existing pull/commit picks it up, so the engine still never touches git |
|
||||
| "View as Markdown" / raw source per post | the comment problem being solved | `?raw` on the existing bundle URL avoids inventing a resolver path and reuses the convention extras already use. **Blocked on a leak**: HTML comments in content are published verbatim today (verified), so serving raw source would expose anything commented out. The scheduled `check` warning is the prerequisite |
|
||||
| IndexNow ping on publish | caring about Bing and Yandex | An outbound Effect, nearly free once the dispatcher exists. Honest limit: Google ignores IndexNow, so it is cheap and marginal rather than cheap and valuable |
|
||||
| Blogroll and OPML export | wanting others to subscribe to your whole list | The blogroll is content and free today. OPML is one marshaller at an exact path, so a feature with no core growth |
|
||||
| Random post | wanting a discovery affordance | One exact-path route, architecturally free, and honestly a toy. Note: randomness deserves the containment `time.Now()` already gets — `verify.sh` confines the clock to `clock.go` because ambient nondeterminism hides staleness |
|
||||
|
||||
## Dropped, with reasons
|
||||
|
||||
Kept because a one-line reason is the cheapest defence against relitigating a decision in four months.
|
||||
|
||||
| Item | Why |
|
||||
|---|---|
|
||||
| EPUB generation | Calibre, Pandoc and percollate already convert web to EPUB. The engine's real contribution is *structure* — sequences already publish reading order — so the revisit trigger is "external tools produce a bad book", not "want EPUB" |
|
||||
| Gemtext output | Readership is approximately zero, and its only real value was proving a View can target something other than HTML. Not worth carrying for that |
|
||||
| Static export | Cannot serve Arc 3's write endpoints or in-memory search, so it is a second permanently crippled product rather than a hedge. The hosting insurance it appears to buy already exists: Markdown in git, one portable binary |
|
||||
| Incremental rebuilds | A whole page renders in ~63µs. This solves a build measured in minutes, a scale this site will notice instantly if it ever reaches |
|
||||
| Live reload | Buys not pressing refresh, at the price of JS or SSE on every page — and the rebuild already lands within one poll |
|
||||
| Self-hosted analytics counting | Write-on-read means state and IO on the hot path. Access logs contain every fact a counter would, cost zero engine code, and leak nothing. `goaccess` answers it in an afternoon |
|
||||
| Incoming rebuild webhook | Polling already covers it, so this spends a write endpoint, the untrusted boundary and rate limiting to save two seconds |
|
||||
| Outgoing chat webhooks as a general system | Absorbed: the scheduled notify Effect emits events and n8n owns routing, formatting and per-platform posting. A configurable per-target rule engine in the engine would serve one caller forever |
|
||||
| Twitter cards, meta description | Theme work once `.Summary` exists; Twitter reads the OpenGraph already emitted |
|
||||
| Design tokens, print stylesheet, columnar layout, in-page timeline | All CSS or a theme-defined container, in a file the engine does not own (ADR-0023) |
|
||||
| Copy-to-clipboard on code blocks, Cmd+K palette | JS on ordinary pages, refused by ADR-0080. The palette also needs search first, and the search page is one keystroke from the address bar |
|
||||
| WebSub (`rel="hub"`) | Push instead of polling for feeds, at a scale this site does not have |
|
||||
| Writing stats page | "Just for fun" by the human's own framing, the same standard that dropped readability scoring |
|
||||
|
||||
## Catalog
|
||||
|
||||
|
||||
Reference in New Issue
Block a user