Skip to content

fix: judge feeds by the spec version they declare, not 0.3.0 only - #12

Merged
hhkaos merged 1 commit into
mainfrom
fix/spec-version-support
Nov 5, 2026
Merged

hhkaos merged 1 commit into
mainfrom
fix/spec-version-support

Conversation

@hhkaos

@hhkaos hhkaos commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #11. Supersedes #10, closed as a duplicate.

The bug

isOteFeed / isOteEvent tested specVersion === '0.3.0', which made the
version a document declares decide whether it was OTE at all. Against the live
registry today:

Feed specVersion Before After
Community Builders 0.3.0 opens opens, flagged out-of-window
eventos.wiki 0.4.0 silently not OTE 485 events
Sarao 0.4.0 silently not OTE 180 events
CoruñaJUG 0.5.0 silently not OTE 11 events

25 events before, 701 after, driven in a browser against the four real feeds.
The only feed that opened was the one outside the support window.
hydrateFeedCache() ran the same check, so those feeds were also evicted from
the IndexedDB cache on every start.

What changed

  • Shape decides what is OTE; the declared version decides which rules apply.
    A feed is a feed because it declares a specVersion and carries events[].
  • Support window = last three minors, computed from PUBLISHED_SPEC_VERSIONS,
    so a spec release moves it by itself. Appending a version there is the only
    edit a release needs. Classification is by minor, so 0.4.1 is as supported
    as 0.4.0 before this build has heard of it.
  • Notes, not refusals. An older supported release says so when you open that
    feed and stays quiet on aggregate screens; out-of-window, newer-than-known and
    unpublished are flagged in the sidebar too. Nothing stops a feed from being
    read and no message asks the publisher for anything.
  • contributing inherits feed→event, completing the five fields the event
    schema marks with x-inheritsFrom since 0.5.
  • npm run check now reads the npm registry and the published event schema
    and fails when the mirrored version list or the inheritance list has drifted.

Why no @opentechevents/validate

Decided before writing code, since it conditions everything else.

The decisive argument is semantics, not size: the reader must be more tolerant
than a validator.
validateDocument reports an out-of-window or unpublished
version as an error. Gating on report.valid would make Community Builders'
0.3.0 feed unopenable — it works today — and would break every feed again at
0.7.0, which is this issue's bug with a better pedigree. A schema failure in one
event would also invalidate a whole feed where the right behaviour is to show
the other 484.

Size confirms rather than decides: ESM-only with per-version dynamic import()
aimed at a bundler, ~3.7 MB of compiled validators, against a no-build PWA whose
whole app.js is 86 kB. Vendoring means megabytes in the repo and the SW
precache; a CDN means an offline-first reader depending on a third party to
decide whether it can open a file.

So the policy is mirrored, not the schemas — same vocabulary (current /
outdated / out-of-window), plus future for a version newer than this build
knows, which a validator has nothing to check against but a reader can show and
label. Drift is covered by npm run check.

Verification

  • Four live feeds in a browser: all four load, notes render as intended, a
    single-feed view shows the full sentence and aggregate views stay quiet about
    merely-outdated feeds.
  • A synthetic 0.7.0 feed with unknown fields: opens, renders, warns.
  • Classification unit-checked across 0.1–1.0, patches, banana, missing, and
    recognition/inheritance cases.
  • npm run check green.

Follow-ups that are not this PR are in #13.

🤖 Generated with Claude Code

The reader decided whether a document was OTE with `specVersion ===
'0.3.0'`, so three of the four registered feeds — eventos.wiki and Sarao
(0.4.0) and CoruñaJUG (0.5.0) — could not be opened, and the failure was
silent: the document downloaded fine and was simply not recognised. The
same check ran over the IndexedDB cache, so those feeds were also evicted
from the offline cache on every start.

A document is now OTE because of its shape — a declared specVersion plus
events[] — and the version it declares decides which rules apply to it,
never whether it is OTE. Across the four live feeds that moves the reader
from 25 events to 701.

The support window is the last three minors, computed from the published
list rather than written out, so a spec release moves it by itself, and
classification is by minor so a patch inside a supported minor is
supported before this build has heard of it. Versions outside the window,
newer than known, or unpublished are notes next to the events and in the
sidebar — never a refusal, and never a reproach: running last season's
release is a legitimate choice.

No dependency on @opentechevents/validate, deliberately. It reports an
out-of-window or unpublished version as an error, so gating on it would
make the 0.3.0 feed that works today unopenable and would break every
feed again at 0.7.0 — this bug, reintroduced. What the reader needs is the
policy, not 3.7 MB of compiled schemas in a no-build PWA, so the policy is
mirrored with the same vocabulary and `npm run check` now fails when it
drifts from the registry or the published event schema.

Also adds `contributing` to the fields an event inherits from its feed,
completing the set the event schema marks with x-inheritsFrom since 0.5.

Closes #11

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The reader only accepts specVersion 0.3.0, so it cannot open half the registered feeds

1 participant