spec 1.0 · 规范性

Leji 上下文变更日志

AI 智能体辅助翻译。如有出入,以英文页面为准。如果你发现文本有任何问题,欢迎提交议题或发起拉取请求

仅可追加的、机器可读的上下文层变更记录。

权威 $idhttps://leji.org/schemas/v1.0/context-changelog.schema.json
原始文件:context-changelog.schema.json

字段

#schemaVersionstring必填

本产物所依据撰写的 Leji 规范版本系列,例如 "1.0"。

匹配模式 ^\d+\.\d+$

#entries对象数组必填

上下文层的各项变更。权威顺序由按 (date, id) 升序排序推导而来;数组位置不承载任何含义。新条目可以出现在任何位置;最旧的条目可以被压缩掉,并以一条 compaction 条目记录。至少要有一条条目:生来为空的变更日志是非法的,而压缩总会留下它自己的 compaction 条目。

idstring必填

本变更条目的稳定标识符,在变更日志内唯一。

datestring必填

UTC 的 ISO 8601:要么是日历日期 YYYY-MM-DD(按当天起点排序),要么是以 Z 结尾的完整时间戳,例如 2026-06-13T15:04:05Z。不允许时区偏移和不带时区的时间,因此字典序即时间顺序。

type"added" · "changed" · "deprecated" · "removed" · "fixed" · "decision" · "governance" · "compaction"必填

变更的类型。

summarystring必填

一行描述,说明改动了什么。

paths字符串数组必填

本次变更影响到的路径,相对仓库根目录。至少一条;compaction 条目记录它所折叠的那些路径的并集,若该并集为空,则记录变更日志自身的路径。

categories由 "domain" · "system" · "practice" · "governance" · "decisions" 构成的数组

本次变更触及的内容类别。

decisionRefs字符串数组

与本次变更相关的决策记录的 id。

proposedBystring

提议本次变更的人或智能体。

approvedBystring

批准本次变更的人。

breakingboolean

本次变更是否会破坏上下文层的消费者。

compactedobject

compaction 条目必须携带:本次压缩从最旧的一端移除了什么。

entriesinteger必填

本次压缩从最旧的一端移除了多少条条目。

firstIdstring必填

本次压缩移除的最旧条目的 id。

lastIdstring必填

本次压缩移除的最新条目的 id。

Schema 与示例

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://leji.org/schemas/v1.0/context-changelog.schema.json",
  "title": "Leji context changelog",
  "description": "Append-only machine-readable record of context layer changes.",
  "type": "object",
  "required": [
    "schemaVersion",
    "entries"
  ],
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "description": "Optional pointer to this schema, for editor validation and tooling.",
      "type": "string"
    },
    "schemaVersion": {
      "description": "The Leji spec line this artifact was written against, e.g. \"1.0\".",
      "type": "string",
      "pattern": "^\\d+\\.\\d+$"
    },
    "entries": {
      "description": "Context layer changes. Canonical order is derived by sorting on (date, id) ascending; array position is not significant. New entries may appear anywhere; the oldest may be compacted with a compaction entry. At least one entry: a born-empty changelog is invalid, and compaction always leaves its compaction entry behind.",
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": [
          "id",
          "date",
          "type",
          "summary",
          "paths"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "description": "Stable identifier for this change entry, unique within the changelog.",
            "type": "string",
            "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
          },
          "date": {
            "description": "ISO 8601 in UTC: a calendar date YYYY-MM-DD (ordered as start of day) or a full timestamp ending in Z, e.g. 2026-06-13T15:04:05Z. Offsets and zoneless times are not allowed, so lexical order is chronological.",
            "type": "string",
            "pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])(T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\dZ)?$"
          },
          "type": {
            "description": "The kind of change.",
            "enum": [
              "added",
              "changed",
              "deprecated",
              "removed",
              "fixed",
              "decision",
              "governance",
              "compaction"
            ]
          },
          "summary": {
            "description": "One-line description of what changed.",
            "type": "string",
            "minLength": 1
          },
          "paths": {
            "description": "Repository-root-relative paths the change affected. At least one; a compaction entry records the union of the paths it folded, or the changelog's own path when that union is empty.",
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).+$"
            }
          },
          "categories": {
            "description": "Content categories the change touched.",
            "type": "array",
            "items": {
              "enum": [
                "domain",
                "system",
                "practice",
                "governance",
                "decisions"
              ]
            }
          },
          "decisionRefs": {
            "description": "Ids of decision records related to this change.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "proposedBy": {
            "type": "string",
            "description": "Human or agent that proposed the change."
          },
          "approvedBy": {
            "type": "string",
            "description": "Human who approved the change."
          },
          "breaking": {
            "description": "Whether the change breaks consumers of the context layer.",
            "type": "boolean"
          },
          "compacted": {
            "type": "object",
            "description": "Required on compaction entries: what the compaction removed from the oldest end.",
            "required": [
              "entries",
              "firstId",
              "lastId"
            ],
            "additionalProperties": false,
            "properties": {
              "entries": {
                "description": "How many entries this compaction removed from the oldest end.",
                "type": "integer",
                "minimum": 1
              },
              "firstId": {
                "description": "Id of the oldest entry removed by this compaction.",
                "type": "string",
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
              },
              "lastId": {
                "description": "Id of the newest entry removed by this compaction.",
                "type": "string",
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
              }
            }
          }
        },
        "if": {
          "properties": {
            "type": {
              "const": "compaction"
            }
          },
          "required": [
            "type"
          ]
        },
        "then": {
          "required": [
            "compacted"
          ]
        }
      }
    }
  }
}

一份机器可读的上下文层变更日志。

{
  "$schema": "https://leji.org/schemas/v1.0/context-changelog.schema.json",
  "schemaVersion": "1.0",
  "entries": [
    {
      "id": "seed-layer",
      "date": "2026-06-10",
      "type": "added",
      "summary": "初始化上下文层:引导配置、术语表、系统不变量、第一份决策记录。",
      "paths": [
        "docs/boot-profile.md",
        "docs/domain/glossary.md",
        "docs/system/invariants.md",
        "docs/decisions/0001-adopt-leji.md"
      ],
      "categories": [
        "domain",
        "system",
        "decisions"
      ],
      "proposedBy": "agent:claude",
      "approvedBy": "Jo Lee"
    },
    {
      "id": "thought-partner-profile",
      "date": "2026-06-12",
      "type": "added",
      "summary": "新增 thought-partner 智能体配置,并在清单的 agents 映射中把它绑定到该角色。",
      "paths": [
        "docs/agents/thought-partner.md",
        "leji.json"
      ],
      "proposedBy": "agent:claude",
      "approvedBy": "Jo Lee"
    },
    {
      "id": "ownership-to-platform-team",
      "date": "2026-09-11",
      "type": "governance",
      "summary": "上下文层的所有权由 Jo Lee 移交给 Acme Platform Team。",
      "paths": [
        "leji.json"
      ],
      "approvedBy": "Acme Platform Team"
    }
  ]
}

← 全部 Schema