# net.anisota.chronicle.log.yearly

> Published by [anisota.net](https://lexicon.garden/identity/did:plc:lcieujcfkv4jx7gehsvok3pr)

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:lcieujcfkv4jx7gehsvok3pr/net.anisota.chronicle.log.yearly)
- [Documentation](https://lexicon.garden/lexicon/did:plc:lcieujcfkv4jx7gehsvok3pr/net.anisota.chronicle.log.yearly/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:lcieujcfkv4jx7gehsvok3pr/net.anisota.chronicle.log.yearly/examples)

## Definitions

### `net.anisota.chronicle.log.yearly`

**Type**: `record`

Yearly aggregation of monthly records. rkey is YYYY. Updated once per month, finalized when year ends.

**Key**: `any`

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `year` | `string` | Yes | Year string in YYYY format (e.g. 2026) |
| `status` | `string` | Yes | Whether this year is still being updated or has been finalized |
| `patterns` | `ref` → `#yearlyPatterns` | No |  |
| `createdAt` | `string` (datetime) | Yes | When the yearly record was first created |
| `signature` | `ref` → `#chronicleSignature` | Yes |  |
| `aggregates` | `ref` → `#yearlyAggregates` | Yes |  |
| `finalizedAt` | `string` (datetime) | No | When the yearly record was finalized (end of year) |
| `lowerLogRefs` | `array` | No | AT URIs of monthly log records included in this year |

### `net.anisota.chronicle.log.yearly#yearlyPatterns`

**Type**: `object`

Activity pattern aggregation for the year based on half-hour blocks

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `peakBlocks` | `integer` | No | Highest activeBlockCount for any single day in the year |
| `avgBlocksPerDay` | `integer` | No | Average active blocks per day (totalActiveBlocks / daysActive, rounded) |
| `totalActiveBlocks` | `integer` | No | Sum of activeBlockCount across all days in the year |

### `net.anisota.chronicle.log.yearly#yearlyAggregates`

**Type**: `object`

Rolled-up counts from monthly records

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `postsRead` | `integer` | No | Total posts read this year |
| `daysActive` | `integer` | No | Total days with activity this year |
| `levelsGained` | `integer` | No | Levels gained this year |
| `monthsActive` | `integer` | No | Number of months with activity this year |
| `postsCreated` | `integer` | No | Total posts created this year |
| `likesReceived` | `integer` | No | Total likes received this year |
| `totalXPGained` | `integer` | No | Total XP gained this year |
| `repliesReceived` | `integer` | No | Total replies received this year |
| `specimensPhotographed` | `integer` | No | New specimens photographed this year |

### `net.anisota.chronicle.log.yearly#chronicleSignature`

**Type**: `object`

ES256 cryptographic signature proving record authenticity

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `alg` | `string` | Yes | Signing algorithm (ES256) |
| `kid` | `string` | Yes | Key identifier for the signing key |
| `sig` | `string` | Yes | Base64-encoded ES256 signature |
| `nonce` | `string` | Yes | Unique random nonce to prevent replay |
| `version` | `integer` | Yes | Signature schema version |
| `signedAt` | `string` (datetime) | Yes | When the record was signed |

## Raw Schema

```json
{
  "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
}
```
