{
"id": "net.anisota.chronicle.log.yearly",
"defs": {
"main": {
"key": "any",
"type": "record",
"record": {
"type": "object",
"required": [
"year",
"aggregates",
"status",
"signature",
"createdAt"
],
"properties": {
"year": {
"type": "string",
"description": "Year string in YYYY format (e.g. 2026)"
},
"status": {
"enum": [
"active",
"finalized"
],
"type": "string",
"description": "Whether this year is still being updated or has been finalized"
},
"patterns": {
"ref": "#yearlyPatterns",
"type": "ref"
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "When the yearly record was first created"
},
"signature": {
"ref": "#chronicleSignature",
"type": "ref"
},
"aggregates": {
"ref": "#yearlyAggregates",
"type": "ref"
},
"finalizedAt": {
"type": "string",
"format": "datetime",
"description": "When the yearly record was finalized (end of year)"
},
"lowerLogRefs": {
"type": "array",
"items": {
"type": "string"
},
"description": "AT URIs of monthly log records included in this year"
}
}
},
"description": "Yearly aggregation of monthly records. rkey is YYYY. Updated once per month, finalized when year ends."
},
"yearlyPatterns": {
"type": "object",
"properties": {
"peakBlocks": {
"type": "integer",
"maximum": 48,
"minimum": 0,
"description": "Highest activeBlockCount for any single day in the year"
},
"avgBlocksPerDay": {
"type": "integer",
"minimum": 0,
"description": "Average active blocks per day (totalActiveBlocks / daysActive, rounded)"
},
"totalActiveBlocks": {
"type": "integer",
"minimum": 0,
"description": "Sum of activeBlockCount across all days in the year"
}
},
"description": "Activity pattern aggregation for the year based on half-hour blocks"
},
"yearlyAggregates": {
"type": "object",
"properties": {
"postsRead": {
"type": "integer",
"minimum": 0,
"description": "Total posts read this year"
},
"daysActive": {
"type": "integer",
"minimum": 0,
"description": "Total days with activity this year"
},
"levelsGained": {
"type": "integer",
"minimum": 0,
"description": "Levels gained this year"
},
"monthsActive": {
"type": "integer",
"minimum": 0,
"description": "Number of months with activity this year"
},
"postsCreated": {
"type": "integer",
"minimum": 0,
"description": "Total posts created this year"
},
"likesReceived": {
"type": "integer",
"minimum": 0,
"description": "Total likes received this year"
},
"totalXPGained": {
"type": "integer",
"minimum": 0,
"description": "Total XP gained this year"
},
"repliesReceived": {
"type": "integer",
"minimum": 0,
"description": "Total replies received this year"
},
"specimensPhotographed": {
"type": "integer",
"minimum": 0,
"description": "New specimens photographed this year"
}
},
"description": "Rolled-up counts from monthly records"
},
"chronicleSignature": {
"type": "object",
"required": [
"sig",
"alg",
"kid",
"signedAt",
"nonce",
"version"
],
"properties": {
"alg": {
"type": "string",
"description": "Signing algorithm (ES256)"
},
"kid": {
"type": "string",
"description": "Key identifier for the signing key"
},
"sig": {
"type": "string",
"description": "Base64-encoded ES256 signature"
},
"nonce": {
"type": "string",
"description": "Unique random nonce to prevent replay"
},
"version": {
"type": "integer",
"description": "Signature schema version"
},
"signedAt": {
"type": "string",
"format": "datetime",
"description": "When the record was signed"
}
},
"description": "ES256 cryptographic signature proving record authenticity"
}
},
"$type": "com.atproto.lexicon.schema",
"lexicon": 1
}