Skip to content

Tracking: core work needed by the site-generator project, and the order it wants doing in #205

Description

@cuibonobo

Motivation

A static-site generator reading a stack is the first real consumer of the commons
publishing types. page@1 already names it as its intended writer:

Status: Draft. Intended writer: a static-site-generator integration reading a
stack (in progress by the project maintainer — either a standalone generator or an
Eleventy data source).

That project is now concrete. It is three pieces:

  • @haverstack/eleventy — an Eleventy plugin that builds a site from a stack
  • @haverstack/cli — a general-purpose, type-agnostic record editing tool
  • A migration of an existing Cloudflare Pages + D1 + R2 site onto a stack, including
    a one-time import of several years of dated records

Between them they exercise most of the commons publishing cluster, the attachment path,
the query path, permissions, and the change feed — which is why they surface a specific
set of core gaps rather than a diffuse wish list.

This issue exists to say what those gaps are and why they want doing in a particular
order
, so the sequencing is a recorded decision rather than something rediscovered
later. None of the linked issues is blocked on this one; it is a map, not a gate.


The issues

Issue What it is Track
#202 unlisted permission tier — reachable by URI, absent from feeds Types
#204 Commons post@1 — the broadcast utterance Types
#203 Settable createdAt/updatedAt for owner-side imports Core
#16 Discriminated union for relationship targets Core
#160 blob-adapter-s3 Deployment
#161 record-adapter-do-sqlite Deployment
#194 subscribe() cannot resume Later

Dependencies

graph TD
  A["#202 unlisted<br/><i>decision</i>"] --> S["sidecar type set"]
  B["#204 post@1"] --> I["one-time import"]
  C["#203 settable createdAt"] --> I
  D["#16 relationship union"] --> E["@haverstack/eleventy"]
  D --> F["@haverstack/cli"]
  S --> E
  I --> E
  G["#194 resume"] -.-> H["incremental builds<br/><i>v2</i>"]
  E -.-> H
Loading

Three tracks that barely touch each other:

Types track — #202, then #204. #202 is a decision, not an implementation: it
determines whether the generator's sidecar type carries a hidden field or defers to a
permission tier. Cheap to settle, and settling it late means rewriting a type that
already has records written against it. #204 is independent of #202 and can proceed in
parallel.

Core track — #203 and #16. Independent of each other and of the types track.

Deployment track — #160 and #161. Entirely independent of everything above. These
decide where the stack runs, which no type or API decision depends on.


Ordering, and why

1. #202unlisted. First because it is the cheapest and the most downstream-shaping.
The sidecar type set is waiting on the answer, and it is a design decision rather than
work. Deciding it wrong is recoverable; deciding it late is not, because by then there
are records.

2. #203 — settable createdAt. A hard blocker for the import, not a convenience.
Without it every imported record is stamped with the import moment and years of archive
collapse to a single day. It is also load-bearing for #204 specifically: post@1
carries no content date by design, so native createdAt is the only ordering key a post
will ever have.

3. #16 — relationship target union. Before the two new repos exist, not after. Both
read and write relationship associations — the commons cross-type conventions
(author, location, series, about), curated collection membership, and
Filter.relatedTo on the generator's read path. Landing it afterwards means paying the
migration across two fresh codebases simultaneously, neither of which has users to
justify the churn. The window where this is nearly free is open now and closes when the
first of those repos gets written.

4. #204post@1. Blocks the import from landing short-form entries on a correct
type. The fallback — filing them as note@1 and migrating later — collides with the
commons' own rule that contracts don't convert in place, and re-minting records would
destroy permalinks that are otherwise preserved exactly. Can start any time; needs to
finish before the import runs.

5. #160blob-adapter-s3. Only if attachment bytes stay in R2. Determines whether
media is a data migration or a config change.

6. #161record-adapter-do-sqlite. The deployment fork: VPS versus staying on
Cloudflare. Needs deciding before deployment work starts, since almost none of that work
transfers between the two targets. The decision is urgent; the implementation may well
be "not now."

7. #194 — feed resume. Incremental builds. Full rebuilds work at this scale, so this
is a v2 improvement rather than a launch requirement.


What can run in parallel

What is explicitly not blocking


Notes

The site generator's own design documents — the type set it uses and the shape of the
two new packages — live outside this repository for now, since neither package exists
yet. Sidecar types are namespaced under the integration rather than under any one site,
so org.haverstack stays reserved for the commons as specified.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions