/roadmap and /changelog on nectenda.com #96

Closed
opened 2026-09-23 10:46:09 +01:00 by cruelacid · 1 comment
Owner

Why

Relay publishes a release-notes page and a public roadmap. We publish neither —
both /roadmap and /changelog return 404 today while the other six pages are
live.

The changelog is the sharper of the two. Relay ships roughly weekly and their
notes are text-only: no screenshots, no GIFs. Real-time collaboration is
inherently visual — two cursors moving in one note is a six-second loop — so this
is a content gap nobody in the niche is filling.

What to do

Two new copy modules, site/content/roadmap.mjs and site/content/changelog.mjs,
words separated from markup as the rest of the site does. These are composed
pages like /pricing, not PAGES entries — those render docs/*.md through
marked.

Register in site/build.mjs at four points that must agree:

  • the import, beside landing and pricing
  • a roadmapPage() / changelogPage() beside pricingPage()
  • the writeFileSync calls
  • SITEMAP (~line 924) — its own comment says a page missing from it is a
    page no search engine is told about, because IndexNow submits exactly that list

Navigation

HEADER_NAV carries three items; the footer comment says it carries "the legal
pages and only those". Put Roadmap in the header (it answers a buying question)
and Changelog in the footer — then rewrite that footer comment in the same
commit
. A stale comment asserting a rule the code no longer follows is how this
repository's worst findings started.

Changelog source: hand-written, with one build-time guard

Nothing existing can generate it. versions.json maps version to
minAppVersion and knows nothing about what changed, and
publish-plugin.mjs's releaseNotes() emits byte-identical build-verification
boilerplate every release — generating would publish six identical entries. It is
also the differentiator: a generated changelog reproduces the exact thing we are
trying to beat.

The guard is a build-time assertion that the newest changelog entry matches
packages/plugin/manifest.json's version, plus adding that manifest to
deploy-site.yml's paths:.

Say the consequence out loud: after this, a version bump fails the site
deploy until someone writes the entry. That is the intended pressure, and it
cannot block a release, because ci.yml does not build the site.

Constraints

  • Zero JavaScript. The deploy greps public/ for <script, </script> and
    inline on*= handlers and asserts script-src 'none' in _headers. Both
    pages are static lists, so this costs nothing — but a "filter by status"
    control would have to be :checked ~ radios, as the pricing toggle is.
  • page() throws if the title matches /nectenda/i. Use Roadmap, Changelog.
  • Meta descriptions must be 100–160 characters or page() throws. Count
    them; do not estimate.
  • The roadmap must not read as a promise. States only — shipped /
    in progress / considering — never dates or quarters, and an opening line
    saying plainly that nothing there is a commitment.
  • Every shipped item checked against docs/plan-master.md phase status, not
    memory
    (docs/positioning.md).
  • No link to a feedback board — that work is deferred. Point feature requests
    at hello@nectenda.com until a board exists. A dead "vote on this" link is
    worse than none.
  • Never "open source", never "audited", never "zero knowledge", never "we store
    no metadata" (docs/positioning.md).

Verification

  • node build.mjs locally, then mutation-check both new guards: a
    90-character description must throw, and a manifest bumped past the newest
    changelog entry must throw. A test that has never failed proves nothing.
  • grep -c '<url>' site/public/sitemap.xml is 8 and both new paths appear.
  • After deploy, against the live edge: curl -I https://nectenda.com/roadmap
    is 200. It is 404 today, which is the before-picture.
## Why Relay publishes a release-notes page and a public roadmap. We publish neither — both `/roadmap` and `/changelog` return 404 today while the other six pages are live. The changelog is the sharper of the two. Relay ships roughly weekly and their notes are **text-only: no screenshots, no GIFs**. Real-time collaboration is inherently visual — two cursors moving in one note is a six-second loop — so this is a content gap nobody in the niche is filling. ## What to do Two new copy modules, `site/content/roadmap.mjs` and `site/content/changelog.mjs`, words separated from markup as the rest of the site does. These are **composed** pages like `/pricing`, not `PAGES` entries — those render `docs/*.md` through `marked`. Register in `site/build.mjs` at four points that must agree: - the import, beside `landing` and `pricing` - a `roadmapPage()` / `changelogPage()` beside `pricingPage()` - the `writeFileSync` calls - **`SITEMAP` (~line 924)** — its own comment says a page missing from it is a page no search engine is told about, because IndexNow submits exactly that list ### Navigation `HEADER_NAV` carries three items; the footer comment says it carries "the legal pages and only those". Put Roadmap in the header (it answers a buying question) and Changelog in the footer — then **rewrite that footer comment in the same commit**. A stale comment asserting a rule the code no longer follows is how this repository's worst findings started. ### Changelog source: hand-written, with one build-time guard Nothing existing can generate it. `versions.json` maps version to `minAppVersion` and knows nothing about what changed, and `publish-plugin.mjs`'s `releaseNotes()` emits byte-identical build-verification boilerplate every release — generating would publish six identical entries. It is also the differentiator: a generated changelog reproduces the exact thing we are trying to beat. The guard is a build-time assertion that the newest changelog entry matches `packages/plugin/manifest.json`'s version, plus adding that manifest to `deploy-site.yml`'s `paths:`. **Say the consequence out loud:** after this, a version bump fails the *site* deploy until someone writes the entry. That is the intended pressure, and it cannot block a release, because `ci.yml` does not build the site. ## Constraints - **Zero JavaScript.** The deploy greps `public/` for `<script`, `</script>` and inline `on*=` handlers and asserts `script-src 'none'` in `_headers`. Both pages are static lists, so this costs nothing — but a "filter by status" control would have to be `:checked ~` radios, as the pricing toggle is. - `page()` throws if the title matches `/nectenda/i`. Use `Roadmap`, `Changelog`. - Meta descriptions must be **100–160 characters** or `page()` throws. Count them; do not estimate. - **The roadmap must not read as a promise.** States only — `shipped` / `in progress` / `considering` — never dates or quarters, and an opening line saying plainly that nothing there is a commitment. - Every `shipped` item checked against `docs/plan-master.md` phase status, **not memory** (`docs/positioning.md`). - **No link to a feedback board** — that work is deferred. Point feature requests at `hello@nectenda.com` until a board exists. A dead "vote on this" link is worse than none. - Never "open source", never "audited", never "zero knowledge", never "we store no metadata" (`docs/positioning.md`). ## Verification - `node build.mjs` locally, then **mutation-check both new guards**: a 90-character description must throw, and a manifest bumped past the newest changelog entry must throw. A test that has never failed proves nothing. - `grep -c '<url>' site/public/sitemap.xml` is 8 and both new paths appear. - After deploy, against the **live edge**: `curl -I https://nectenda.com/roadmap` is 200. It is 404 today, which is the before-picture.
cruelacid added this to the Marketing project 2026-09-23 10:48:13 +01:00
Author
Owner

Moved to the Vikunja board as NEC-72: https://projectron.nerchure.com/tasks/72

Moved to the Vikunja board as **NEC-72**: https://projectron.nerchure.com/tasks/72
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Nectenda/nectenda#96
No description provided.