Introduction
The standard.site shared lexicon specification was introduced earlier this week by the developers of Leaflet, pckt.blog, and Offprint, with the goal of making long-form content easier to discover, index, and move across the ATmosphere.
The GreenGale V1 lexicon was derived from the existing WhiteWind lexicon, with a few added features. GreenGale is designed with content stored in standard markdown, and a straightforward lexicon for easy integration with programmatic publishing. The standard.site specification defines a set of minimal requirements that are compatible with this goal.
As such, the GreenGale V2 lexicon only needed a few changes to provide increased interoperability with the AT Protocol ecosystem, which made implementing this a natural choice.
Publications
standard.site defines lexicons for publications and documents. GreenGale thus far has only had a single lexicon for posts, without defining a publication separately from a user account—everything you post goes to your GreenGale/WhiteWind unified profile rather than separately defined blogs or publications.
However, the GreenGale approach is not necessarily incompatible with the standard.site definition of a publication. GreenGale now implements a publication as a per-user singleton, which stores your blog name, description, and theme in a standard.site-compatible lexicon.
After defining a publication theme, your profile page, and posts you create without defining another theme, will use that theme. As before, viewers can choose to override themes with their own preferences, or see the author's chosen theme.
The V1 → V2 changes are detailed below.
V1 Schema
{
"id": "app.greengale.blog.entry",
"record": {
"required": ["content"],
"properties": {
"content": { "type": "string", "maxLength": 100000 },
"title": { "type": "string", "maxLength": 1000 },
"subtitle": { "type": "string", "maxLength": 1000 },
"createdAt": { "type": "string", "format": "datetime" },
"theme": { "ref": "app.greengale.blog.defs#theme" },
"visibility": { "enum": ["public", "url", "author"] },
"ogp": { "ref": "app.greengale.blog.defs#ogp" },
"blobs": { "type": "array" },
"latex": { "type": "boolean" }
}
}
}
V2 Schema
{
"id": "app.greengale.document",
"record": {
"required": ["content", "url", "path", "title", "publishedAt"],
"properties": {
"content": { "type": "string", "maxLength": 100000 },
"url": { "type": "string", "format": "uri" },
"path": { "type": "string", "maxLength": 500 },
"title": { "type": "string", "maxLength": 1000 },
"subtitle": { "type": "string", "maxLength": 1000 },
"publishedAt": { "type": "string", "format": "datetime" },
"theme": { "ref": "app.greengale.blog.defs#theme" },
"visibility": { "enum": ["public", "url", "author"] },
"ogp": { "ref": "app.greengale.blog.defs#ogp" },
"blobs": { "type": "array" },
"latex": { "type": "boolean" }
}
}
}
New Required Fields
| Field | Type | Description |
|-------|------|-------------|
| url | string (uri) | Base publication URL (e.g., https://greengale.app) |
| path | string | Document path relative to publication URL (e.g., /@handle/rkey) |
Renamed Fields
| V1 Field | V2 Field | Notes |
|----------|----------|-------|
| createdAt | publishedAt | Aligns with site.standard terminology |
Changed Fields
| Field | V1 | V2 | Notes |
|-------|----|----|-------|
| title | optional | required | Required per site.standard spec |
| publishedAt | optional (as createdAt) | required | Required per site.standard spec |
Publication Record
New in V2
The app.greengale.publication lexicon is a singleton record (rkey: self) that stores blog-level configuration.
{
"id": "app.greengale.publication",
"key": "self",
"record": {
"required": ["url", "name"],
"properties": {
"url": { "type": "string", "format": "uri" },
"name": { "type": "string", "maxLength": 200 },
"description": { "type": "string", "maxLength": 1000 },
"theme": { "ref": "app.greengale.blog.defs#theme" }
}
}
}
Migration
The GreenGale frontend remains backwards compatible with all existing and future WhiteWind and GreenGale V1 posts. All new posts created through the web interface will use GreenGale V2. Editing an existing GreenGale V1 post also automatically updates it to V2.
Verification
Try verifying this post:
curl https://greengale.app/greengale.app/3mbiklmhghr2p | grep "app.greengale.document"
You should see:
<link rel="app.greengale.document" href="at://did:plc:purpkfw7haimc4zu5a57slza/app.greengale.document/3mbiklmhghr2p">
GreenGale remains open to consideration of further additions to the lexicon. If you have questions, comments, or feature requests, feel free to reach out to GreenGale on Bluesky or leave an an issue on GitHub.