Astro site blueprints
Jampress is the source of truth for reusable packages and composition contracts used by independently owned Astro site collections. A blueprint release is an input to an owner repository, not a shared production service or permission boundary.
Ownership layers
Jampress fleet
└── owner collection / subfleet repository
├── site Worker A
├── site Worker B
└── site Worker C
- Fleet: the set of collections compatible with Jampress releases. Jampress contains no owner content, production IDs, or secrets.
- Collection/subfleet: one owner or trust boundary and normally one private
repository. It owns
fleet.yaml, shared brand heritage, vendored releases, content, and deployment receipts. - Site: one independently deployable Astro application, domain, Studio capability choice, and Worker configuration.
Package and directory boundary
The first implemented package was packages/fleet-schema; the bounded release
backbone, static scaffold, and host-neutral content/Studio contracts are now
implemented as well. Entries still labeled planned below remain boundaries,
not claims that the packages or applications exist yet.
jampress/
├── blueprints/
│ ├── astro-static/ implemented minimal static-site source scaffold
│ └── astro-studio/ planned Worker + same-origin Studio scaffold
├── packages/
│ ├── auth-*/ current host-owned auth packages
│ ├── fleet-schema/ implemented fleet.yaml contract
│ ├── blueprint-cli/ implemented release/lock validation, parameters, and materialization
│ ├── content-contracts/ implemented site-scoped editorial models
│ ├── site-runtime-astro/ planned storage-neutral Astro adapters
│ ├── site-kit/ planned generic accessible primitives
│ ├── studio-core/ implemented host-neutral command boundary
│ ├── studio-ui/ planned owner editing surface
│ ├── studio-cloudflare/ planned D1/R2 repositories and guards
│ ├── assets-core/ planned extraction from Jampress Assets
│ ├── assets-storage-r2/ planned streaming/recovery adapter
│ └── assets-ui/ planned upload/media picker UI
├── fixtures/
│ └── reference-collection/ fictional contract fixture
├── release/
│ ├── astro-static/0.1.0/ checked-in provisional reference fixture
│ ├── astro-static/0.1.2/ first clean, tagged immutable release
│ ├── astro-static/0.2.0/ parameterized multi-site package identities
│ ├── astro-static/0.3.0/ portable downstream verifier release
│ └── schema/ versioned release and lock schemas
└── docs/
EmDash is deliberately absent from the implemented blueprint surface. A later integration must start from the then-current upstream generator rather than freezing its current internals into Jampress.
The first Studio slice is deliberately storage-neutral. It defines Markdown post snapshots, mutable heads, immutable revisions, owner/editor/operator roles, and atomic repository commands for draft, revise, publish, rollback, and archive. It does not yet provide an HTTP route, D1 schema, R2 asset handling, authentication adapter, or editing UI.
The service validates commands and enforces the small role policy only after
a trusted host supplies current actor/scope authorization. Its caller-retained
idempotencyKey and optimistic version are persistence obligations, not an
implemented database transaction. See the
Studio repository acceptance contract.
These two private packages are not yet included in an immutable release or the
auth package exporter. No current blueprint gains a Studio runtime by adopting
this source slice.
fleet.yaml version 1
fleet.yaml is operator-maintained data. It describes one collection's place
in a fleet, its sites, capabilities, public hostnames, and logical storage
topology. The versioned JSON Schema rejects unknown fields so a Cloudflare
resource ID or secret cannot be mistaken for portable configuration.
D1 and R2 topology are independent axes. All combinations are valid:
| D1 | R2 | Meaning |
|---|---|---|
| collection | collection | One logical database and bucket for the collection |
| collection | site | One logical database; one logical bucket per site |
| site | collection | One logical database per site; one logical bucket |
| site | site | A logical database and bucket per site |
Collection topology requires storage.d1.database or storage.r2.bucket.
Site topology forbids the corresponding collection name and requires the
logical name under every sites[].resources entry. Per-site names must be
unique. Domains and asset hostnames are globally unique within the collection.
Studio is an explicit site capability. Its collection defaults are /studio
and /_studio/api, and a Studio-capable site may override either path. The
normalizer sorts sites/capabilities and materializes route defaults so later
tools receive canonical JSON.
pnpm fleet:validate
pnpm fleet:normalize
Validation and normalization do not provision, migrate, or deploy anything.
Resolved Cloudflare account IDs, D1 database IDs, R2 binding details, and
secrets belong in owner-controlled deployment state outside fleet.yaml.
Current shared-D1 blocker
Current Jampress authentication is one host per D1. Although version 1 can declare a collection-scoped D1, no Astro Studio runtime may share that database until a separately designed and tested realm/site contract scopes tokens, sessions, memberships, rate limits, content, revisions, and audit queries. Shared storage also does not create cross-domain browser SSO.
The CLI repeats this warning when a Studio-enabled configuration selects a collection D1. This slice does not change auth interfaces, tables, migrations, or runtime behavior.
Release and downstream adoption contract
The second bounded slice implements packages/blueprint-cli and one checked-in
release/astro-static/0.1.0/ provisional reference fixture. It is intentionally
marked source.dirty: true because the original fixture was generated from an
uncommitted worktree; it is not a
production release. A clean tagged release must regenerate its source receipt,
manifest, and checksums from the tagged source before downstream adoption. A
release directory contains
blueprint-release.json, a checksums.sha256 file, and the release's
blueprint files. The strict release schema records release, blueprint, and
product versions; the Jampress source identity and the same source receipt
fields used by private-package-export.json; checksummed, sized artifact files
mapped to downstream target paths; optional compatible private-package export
receipts and ordered migrations; and non-overlapping generated and extension
path scopes.
blueprint.lock.json is a distinct collection-root downstream adoption record.
It contains a deduplicated set of immutable release pins and maps each site ID
to one collection-relative target such as apps/field-notes. A release pin copies
the Jampress product, blueprint, source, checksummed artifact, and ownership
snapshot, then pins the vendored release manifest path plus its SHA-256. Several
sites can share one pin, while a staged upgrade can leave different sites on
different versions in the same lock. Adoption targets must be unique and may
not overlap as ancestors or descendants.
Every referenced migration or private-package receipt file is part of the
release's exact checksum set. The collection lock is not a replacement for
private-package-export.json: that existing receipt describes the separately
exported private auth tarball bundle, while a blueprint release may reference
such a receipt (the current static release has no package dependency).
Validate and materialize the checked-in release with:
pnpm blueprint:validate
pnpm blueprint:smoke
Single-site materialization remains useful for release verification. Collection
materialization additionally resolves the requested site through the lock,
verifies the supplied release directory against that exact pin, and writes only
under the recorded target. Materialization only writes files explicitly
classified as generated-owned.
Generated files are replaceable by a later pinned release; extension-owned
paths are downstream-owned and are never silently overwritten. Exact paths and
terminal directory scopes may not overlap across the two ownership lists, and
an artifact mapped to an extension path is invalid. Artifact, migration,
private-export, and manifest paths are literal safe paths; only ownership
scopes may use a trailing /**. The smoke test creates isolated single-site and
two-site collection consumers, validates checksums and the lock contract, keeps
a pre-existing owner extension intact, and verifies a tampered overlap is
refused.
astro-static@0.2.0 adds explicit adoption parameters. A release declares each
bounded string parameter and the exact generated-owned JSON target, JSON pointer, and
expected source value it may replace. The collection lock records values per site.
Materialization validates required and unknown names, named value formats,
target ownership, pointer uniqueness, and the expected source value before rendering.
It never performs an unconstrained text replacement. The initial package-name
parameter renders unique workspace identities such as @sable/katefolio from one
checksummed source artifact.
Publication, downstream update automation, GitHub operations, Cloudflare
provisioning, deployment, Studio UI, media extraction, and EmDash integration
remain explicitly outside this slice. The astro-static scaffold itself has
no auth, Studio, Cloudflare bindings, D1/R2 resources, or deployment logic.
Creating a clean release
Blueprint release configuration—including bounded parameters and substitutions—lives
beside its source as blueprint.release.json; the control file is included in source
provenance but is not copied into downstream applications. A release is generated
only when:
- the current branch is
main; - the entire Jampress worktree is clean;
- the versioned destination does not already exist; and
blueprint-<id>-v<version>points atHEAD.
For example:
git tag blueprint-astro-static-v0.2.0
git push origin blueprint-astro-static-v0.2.0
pnpm blueprint:release astro-static 0.2.0
The command copies only tracked, generated-owned blueprint artifacts. Tracked extension-owned source seams contribute to source provenance but are not materialized; an unclassified or overlapping file refuses the release. The exporter writes artifact sizes and SHA-256 digests, records the clean source commit, branch, tag, timestamp, and source-state digest, and then creates a new immutable release directory. Validate and consumer-smoke the new directory before committing it on a release pull request. Never overwrite an existing release directory.
astro-static@0.1.2 is the first clean release. Version 0.1.1 was reserved by a
published source tag, but its pre-commit acceptance check correctly found that the
initial exporter attempted to include an extension-owned stylesheet. No 0.1.1
release directory or downstream adoption was published, and the version was not
reused after the exporter was corrected.
astro-static@0.2.0 is generated from clean tag
blueprint-astro-static-v0.2.0 and is the first release that can render distinct,
lock-receipted package identities into several apps in one workspace.
astro-static@0.3.0 adds the portable downstream verification path. Each clean
release bundles a checksummed private tarball of @jampress/blueprint-cli; private
owner repositories install it from their vendored release with a relative file:
dependency. jampress-blueprint verify-adoptions blueprint.lock.json . then verifies
the strict lock, exact vendored manifests and release contents, parameter-rendered
generated files, and symlink/path boundaries while leaving extension-owned work out
of the comparison. This requires no npm publication or mutable access to Jampress.