{
"id": "dev.roe.ama",
"defs": {
"main": {
"key": "tid",
"type": "record",
"record": {
"type": "object",
"required": [
"status",
"createdAt"
],
"properties": {
"image": {
"type": "blob",
"accept": [
"image/*"
],
"maxSize": 5000000
},
"posts": {
"type": "array",
"items": {
"ref": "#post",
"type": "ref"
},
"maxLength": 16,
"description": "Thread of response posts. Each post is the body of one Bluesky-thread item (and one Mastodon status, one LinkedIn comment chain entry, etc)."
},
"status": {
"type": "string",
"knownValues": [
"unanswered",
"answered"
]
},
"question": {
"type": "string",
"maxLength": 500000,
"description": "Plaintext question. Present iff status=answered; the editor decrypts encryptedQuestion at publish time and writes it here so the record is self-contained going forward.",
"maxGraphemes": 50000
},
"createdAt": {
"type": "string",
"format": "datetime"
},
"platforms": {
"ref": "#platforms",
"type": "ref",
"description": "Which platforms the editor enabled when publishing."
},
"answeredAt": {
"type": "string",
"format": "datetime"
},
"publishedLinks": {
"ref": "#publishedLinks",
"type": "ref",
"description": "Resolved per-platform URLs after publish."
},
"backgroundStyle": {
"type": "string",
"maxLength": 128,
"description": "ID of the background style used to render the image, either a preset name or a serialised custom emoji-and-gradient id. The set of styles is internal to roe.dev."
},
"imageDimensions": {
"ref": "community.lexicon.app.defs#aspectRatio",
"type": "ref",
"description": "Pixel dimensions of `image`. Stored alongside because PDS blobs don't carry intrinsic dimensions and Bluesky's image embed needs `aspectRatio`."
},
"encryptedQuestion": {
"type": "string",
"maxLength": 500000,
"description": "AES-256-GCM envelope holding the raw question text. Present iff status=unanswered."
}
}
},
"description": "An anonymous question, optionally with a published answer. While unanswered the question text is encrypted server-side (private to roe.dev). Once published, the question is rewritten in plaintext alongside the answer and per-platform URLs."
},
"post": {
"type": "object",
"required": [
"text"
],
"properties": {
"text": {
"type": "string",
"maxLength": 500000,
"description": "Body text. Plain text with `@<entity-rkey>` placeholders for entity mentions (e.g. `Thanks @abc123def456 for the help`). The placeholder syntax is internal; the publisher swaps them for the right per-platform handle.",
"maxGraphemes": 50000
},
"mentions": {
"type": "array",
"items": {
"ref": "com.atproto.repo.strongRef",
"type": "ref"
},
"maxLength": 32,
"description": "Strong-refs to dev.roe.entity records. The rkey of each referenced record is the placeholder token used in `text`."
}
},
"description": "One post in the response thread. Mentions reference dev.roe.entity records by AT URI so the publisher can rewrite per-platform handles at publish time."
},
"platforms": {
"type": "object",
"properties": {
"bluesky": {
"type": "boolean",
"default": true
},
"linkedin": {
"type": "boolean",
"default": true
},
"mastodon": {
"type": "boolean",
"default": true
},
"youtubeShorts": {
"type": "boolean",
"default": false
}
}
},
"publishedLinks": {
"type": "object",
"properties": {
"bluesky": {
"type": "string",
"format": "uri"
},
"linkedin": {
"type": "string",
"format": "uri"
},
"mastodon": {
"type": "string",
"format": "uri"
},
"youtubeShorts": {
"type": "string",
"format": "uri"
}
}
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1
}