spec 1.0 · 规范性

Leji 上下文清单(leji.json)

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

Leji 上下文层的机器入口。以 leji.json 的形式位于仓库根目录。

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

字段

#lejistring必填

本上下文层面向的 Leji 规范版本系列,例如 "1.0"。这个自命名的键沿用 OpenAPI 的惯例,用来表明该文件是一份 Leji 清单。

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

#namestring必填

本上下文层的一个简短、稳定的标识符,例如 "acme-billing-context"。

#descriptionstring

一行摘要,说明本上下文层涵盖什么。

#rootPathstring必填

上下文根目录,相对仓库根目录的 POSIX 路径。它声明上下文层位于何处,但不会为它所治理的路径重设基准:索引条目、侧边栏固定页面、配置路径,以及 Leji 产物中的其他所有路径,都从仓库根目录解析。查看器的 homepagelogofavicon 是例外:它们相对上下文根目录书写,落在该根目录之下的、相对仓库根目录的路径也会被接受。

匹配模式 ^(?!/)(?!\./)(?!.*(^|/)\.\.(/|$))(?!.*\\).*$

#bootProfilePathstring必填

引导配置的路径,即每个智能体宿主和每个人都从这里开始的、不依赖具体智能体的入口。

匹配模式 ^(?!/)(?!\./)(?!.*(^|/)\.\.(/|$))(?!.*\\).+\.md$

#categoriesobject必填

逻辑类别到索引文件的映射。键是五个类别标识符;每个键映射到一份或多份撰写好的索引文件,由它们列出该类别的内容。

下面每个键都具有相同的形态:

indexes字符串数组必填

本类别的一份或多份索引文件,路径相对仓库根目录。每份索引文件都是撰写好的 markdown,其中带有一个 leji-index 围栏代码块,块内的 - path: <dir-or-file> 行选出属于本类别的内容。内容仍留在原处;由索引文件声明纳入。

domainobject

domain 类内容所在之处:业务语言与产品语义。

systemobject

system 类内容所在之处:架构,以及每一次变更都要遵守的不变量。

practiceobject

practice 类内容所在之处:约定与已被验证有效的模式。

governanceobject

governance 类内容所在之处:智能体护栏与运作规则。

decisionsobject

决策记录所在之处:带日期的记录,说明事情为何如此。

#machineobject

机器可读产物的位置:索引、变更日志、智能体配置和决策记录。

indexPathstring

生成的上下文索引的路径。

changelogPathstring

机器可读的上下文变更日志的路径。

agentProfilesPathstring

存放智能体配置文档的目录。

decisionRecordsPathstring

存放决策记录的目录。

#agents映射

角色到智能体配置的绑定。键是角色标识符(例如 "thought-partner"、"reviewer");值是智能体配置文档的路径。协议启用角色,而这个映射决定由谁来担任。

#actors映射

可选的 actor 注册表,登记能够担任角色的参与者。键是稳定的 actor 标识符。每个 actor 声明它有资格担任的角色,以及按角色划分的命令模板。当某个角色有多于一个合格 actor,或者同一个 actor 因担任角色不同而需要不同调用方式时使用它;任一条件单独成立即足够。一个只有单一 actor、只需一条命令的角色,由智能体配置自身的 host 与 invocation 即可满足。

#ownersobject必填

谁对上下文层的健康负责。负责人要为上下文层保持当前有效、及时精简负责;但并不由他们独自撰写或编排(governance.md)。

下面每个键都具有相同的形态:

namestring必填

这个人的姓名。

contactstring

如何联系到他们,例如一个电子邮件地址。

primaryobject必填

对上下文层是否当前有效负责的那个人。没有负责人的上下文层会腐坏。

continuityobject

可选。当主负责人无法履职或离开时,由另一个人承担同样的责任;有外部协助的接入应当在协助方撤出之前指定一位。重复填写主负责人不构成任何延续性,智能体也无法担任:负责人是承担责任的人。

#conformanceobject

本上下文层所声明的一致性级别,可由工具检查。

claimedLevel"core" · "indexed" · "governed" · "federated"

所声明的一致性级别:core、indexed、governed 或 federated。

claimedAtstring

最近一次作出该声明的 ISO 8601 日期。

#federationobject

挂载进本仓库的同级层(规范:distribution.md 模式 3)。圆环组合各方的归属,而不是把归属集中起来。

mounts对象数组

每个挂载都是一个同级上下文层,通过解析器填充的层投影在固定版本处读取,并保有自己的仓库、归属和评审关卡。物化后的内容存放在被 git 忽略的解析器缓存中,绝不提交到这里。

namestring必填

同级层的名称;必须与该同级层自身清单中的 name 一致。

sourcestring必填

同级层的归一化仓库定位符:一个 https://、ssh:// 或 SCP 风格的远程 URL。它既是解析的根,也是固定版本的命名空间。本地文件系统路径只在机器本地的提示中有效,绝不出现在这里。

pinstring必填

本宿主层所读取的同级层修订版的完整不可变提交 id(SHA-1 或 SHA-256)。它是保存在清单中的目标状态:固定版本的更新是有意为之、经过评审的编排。

trackingRefstring

可选的、位于 source 上的全限定见证 ref(refs/heads/* 或 refs/tags/*),过期固定版本的报告与联邦可达性都相对它来比较。未声明时,使用 source 所公布的默认分支,并写入命令输出。

ownerobject必填

同级层的负责人。归属留在同级层所属的团队;宿主层绝不吸收它的内容。

rolestring

用散文说明这个同级层承载什么,例如 "product-side context"。它是给人读的;路由使用下面那些结构化字段。

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

这个同级层可以应答的内容类别范围。仅为路由元数据;同级层的内容仍留在同级层。federated 级一致性要求声明它。

topics字符串数组

简短的、宿主层可见的主题标签,用于把一项任务路由到这个同级层,例如 "billing"、"checkout"。仅为路由元数据。

requiredWhen字符串数组

在这些任务条件下,读取者必须解析这个挂载,无法解析时则停下并报告上下文不完整(失败即关闭)。它对宿主层可见;不得披露任何宿主层受众不该看到的内容。

#vendorAdapters字符串数组

本仓库中存在的厂商入口文件;每一个都必须重定向到引导配置。

#viewerobject

leji viewer 读取的呈现偏好。这是非规范性的便利配置;呈现本身不属于规范范围。

portinteger

leji viewer serve 首选的本地预览端口。--port 参数会覆盖它;默认值是 5354(手机键盘上的 LEJI)。

logostring

查看器使用的标志图片,以上下文根目录下的路径给出(例如 "assets/logo.svg")。默认使用 Leji 标志。

titlestring

查看器的显示标题(侧边栏标题与页面标题)。默认使用上下文层的名称。

agentsLabelstring

智能体配置分组在侧边栏中的标签(欢迎使用 emoji)。默认为 "🤖 Agents"。该分组列出本层的智能体配置,并像其他分组一样由 viewer.groupOrder 排序。

faviconstring

查看器使用的站点图标,以上下文根目录下的路径给出(例如 "assets/icon.svg")。默认使用 Leji 标志。

homepagestring

查看器的首页,以相对上下文根目录的路径给出(例如 "README.md")。默认使用脚手架生成的 overview.md。

pins元素数组

固定在侧边栏顶部的页面:相对仓库根目录的 markdown 路径,或者用 {path, label} 指定一个自行编排的标签。固定引导配置会替换它默认的那一行。

groupOrder字符串数组

自行编排的侧边栏分组顺序,按分组标签精确匹配(即索引文件的 H1)。列出的分组按此顺序排在前面;未列出的分组按推导顺序排在后面。

themeobject

查看器主题的覆盖设置。

primarystring

主色/强调色,用十六进制 CSS 颜色表示(例如 "#009F71")。它决定查看器外框、激活状态和图表强调色;正文链接与行内代码使用那个固定的无障碍色调,除非 viewer.theme.link 提供了一个能通过对比度检查的颜色。

linkstring

链接颜色,用十六进制 CSS 颜色表示(例如 "#5A50F9")。只有当它相对行内代码背景(正文链接与行内代码所落在的两种背景中较窄的那一个)达到 4.5:1 时,才会应用到正文链接与行内代码;否则仍保留那个固定的无障碍色调,并由 leji view / leji export 发出告警。

mermaidboolean

在查看器中把 ```mermaid 围栏代码块渲染为图表。默认为 true。

poweredByboolean

在查看器角落显示那个小小的 "Powered by Leji" 标记。默认为 true;设为 false 即可移除。

categoryEmojisobject

覆盖生成的层地图中每个类别旁默认显示的 emoji。(侧边栏分组的标签取自各索引文件自己的 H1。)

Schema 与示例

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://leji.org/schemas/v1.0/context-manifest.schema.json",
  "title": "Leji context manifest (leji.json)",
  "description": "The machine entrypoint of a Leji context layer. Lives at the repository root as leji.json.",
  "type": "object",
  "required": [
    "leji",
    "name",
    "rootPath",
    "bootProfilePath",
    "categories",
    "owners"
  ],
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "description": "Optional pointer to this schema, for editor validation and tooling.",
      "type": "string"
    },
    "leji": {
      "type": "string",
      "description": "The Leji spec line this context layer targets, e.g. \"1.0\". The self-naming key follows the OpenAPI convention and identifies the file as a Leji manifest.",
      "pattern": "^\\d+\\.\\d+$"
    },
    "name": {
      "description": "A short, stable identifier for this context layer, e.g. \"acme-billing-context\".",
      "type": "string",
      "minLength": 1
    },
    "description": {
      "description": "One-line summary of what this context layer covers.",
      "type": "string"
    },
    "rootPath": {
      "type": "string",
      "description": "Context root, POSIX path relative to the repository root. Declares where the context layer lives; it does not re-base the paths it governs: index entries, pinned pages, profile paths, and every other path in Leji artifacts resolve from the repository root. The viewer's `homepage`, `logo`, and `favicon` are the exception: they are written relative to the context root, and a repository-root-relative path under it is accepted too.",
      "pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).*$"
    },
    "bootProfilePath": {
      "description": "Path to the boot profile, the agent-agnostic entrypoint every host and person starts from.",
      "type": "string",
      "pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).+\\.md$"
    },
    "categories": {
      "type": "object",
      "description": "Logical category to index-file mapping. Keys are the five category identifiers; each maps to one or more curated index files that list the category's content.",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "domain": {
          "description": "Where domain content lives: business language and product semantics.",
          "$ref": "#/$defs/categoryMapping"
        },
        "system": {
          "description": "Where system content lives: architecture and the invariants every change respects.",
          "$ref": "#/$defs/categoryMapping"
        },
        "practice": {
          "description": "Where practice content lives: conventions and proven patterns.",
          "$ref": "#/$defs/categoryMapping"
        },
        "governance": {
          "description": "Where governance content lives: agent guardrails and operating rules.",
          "$ref": "#/$defs/categoryMapping"
        },
        "decisions": {
          "description": "Where decision records live: dated records of why things are the way they are.",
          "$ref": "#/$defs/categoryMapping"
        }
      }
    },
    "machine": {
      "description": "Locations of the machine-readable artifacts: index, changelog, profiles, and decision records.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "indexPath": {
          "description": "Path to the generated context index.",
          "$ref": "#/$defs/relPath"
        },
        "changelogPath": {
          "description": "Path to the machine-readable context changelog.",
          "$ref": "#/$defs/relPath"
        },
        "agentProfilesPath": {
          "description": "Directory holding agent profile documents.",
          "$ref": "#/$defs/relPath"
        },
        "decisionRecordsPath": {
          "description": "Directory holding decision records.",
          "$ref": "#/$defs/relPath"
        }
      }
    },
    "agents": {
      "type": "object",
      "description": "Role to agent-profile binding. Keys are role identifiers (e.g. \"thought-partner\", \"reviewer\"); values are paths to agent profile documents. Protocols engage roles; this map decides who fills them.",
      "additionalProperties": false,
      "patternProperties": {
        "^[a-z0-9]+(-[a-z0-9]+)*$": {
          "$ref": "#/$defs/relPath"
        }
      }
    },
    "actors": {
      "type": "object",
      "description": "Optional registry of actors that can fill roles. Keys are stable actor identifiers. An actor declares the roles it is eligible for and a command template per role. Use it when a role has more than one eligible actor, or when one actor needs a different invocation depending on which role it is filling; either alone is reason enough. A role whose single actor needs only one command is served by the agent profile's own host and invocation.",
      "additionalProperties": false,
      "patternProperties": {
        "^[a-z0-9]+(-[a-z0-9]+)*$": {
          "$ref": "#/$defs/actor"
        }
      }
    },
    "owners": {
      "type": "object",
      "description": "Who is accountable for the context layer's health. Owners answer for the context layer staying current and pruned; they do not author or curate it alone (governance.md).",
      "required": [
        "primary"
      ],
      "additionalProperties": false,
      "properties": {
        "primary": {
          "$ref": "#/$defs/owner",
          "description": "The person accountable for the context layer's currency. Ownerless context layers rot."
        },
        "continuity": {
          "$ref": "#/$defs/owner",
          "description": "Optional. A different person who carries the same accountability when the primary is unavailable or steps away; assisted adoptions should name one before outside help leaves. Naming the primary again provides no continuity, and an agent cannot fill it: owners are accountable people."
        }
      }
    },
    "conformance": {
      "description": "The conformance level this context layer claims, checkable by tooling.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "claimedLevel": {
          "description": "The conformance level claimed: core, indexed, governed, or federated.",
          "enum": [
            "core",
            "indexed",
            "governed",
            "federated"
          ]
        },
        "claimedAt": {
          "description": "ISO 8601 date the claim was last asserted.",
          "$ref": "#/$defs/isoDate"
        }
      }
    },
    "federation": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "mounts": {
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "name",
              "source",
              "pin",
              "owner"
            ],
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "description": "The sibling layer's name; must match the `name` in the sibling's own manifest."
              },
              "source": {
                "type": "string",
                "minLength": 1,
                "description": "Normalized repository locator of the sibling layer: an https://, ssh://, or SCP-style remote URL. The resolution root and the pin's namespace. Local filesystem paths are valid only in machine-local hints, never here."
              },
              "pin": {
                "type": "string",
                "pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$",
                "description": "Full immutable commit id (SHA-1 or SHA-256) of the sibling revision this host reads. Manifest-held desired state: pin updates are deliberate, reviewed curation."
              },
              "trackingRef": {
                "type": "string",
                "pattern": "^refs/(heads|tags)/.+$",
                "description": "Optional fully qualified witness ref on the source (refs/heads/* or refs/tags/*) that stale-pin reporting and federated reachability compare against. Absent, the source's advertised default branch is used and recorded in command output."
              },
              "owner": {
                "$ref": "#/$defs/owner",
                "description": "The owner of the sibling layer. Ownership stays with the sibling's team; the host never absorbs its content."
              },
              "role": {
                "type": "string",
                "description": "What this sibling layer carries, in prose, e.g. \"product-side context\". For humans; routing uses the structured fields below."
              },
              "categories": {
                "type": "array",
                "items": {
                  "enum": [
                    "domain",
                    "system",
                    "practice",
                    "governance",
                    "decisions"
                  ]
                },
                "minItems": 1,
                "description": "The content-category scopes this sibling can answer for. Routing metadata only; the sibling's content stays in the sibling. Required for federated conformance."
              },
              "topics": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                },
                "description": "Short host-visible topic labels used to route a task to this sibling, e.g. \"billing\", \"checkout\". Routing metadata only."
              },
              "requiredWhen": {
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                },
                "description": "Task conditions under which a reader must resolve this mount, or stop and report incomplete context if it cannot (fail closed). Host-visible; must not disclose anything the host's audience may not see."
              }
            }
          },
          "description": "Each mount is a sibling context layer read at a pinned version through a resolver-hydrated layer projection, keeping its own repository, ownership, and review gate. Materialized content lives in the gitignored resolver cache, never committed here."
        }
      },
      "description": "Sibling layers mounted into this repository (spec: distribution.md pattern 3). The circle composes ownership; it doesn't centralize it."
    },
    "vendorAdapters": {
      "type": "array",
      "description": "Vendor entrypoint files present in this repository; each must redirect to the boot profile.",
      "items": {
        "$ref": "#/$defs/relPath"
      }
    },
    "viewer": {
      "type": "object",
      "description": "Presentation preferences read by `leji viewer`. Non-normative convenience configuration; presentation itself is out of normative scope.",
      "additionalProperties": false,
      "properties": {
        "port": {
          "type": "integer",
          "minimum": 1,
          "maximum": 65535,
          "description": "Preferred local-preview port for `leji viewer serve`. The --port flag overrides; the default is 5354 (LEJI on a phone keypad)."
        },
        "logo": {
          "type": "string",
          "description": "Logo image for the viewer, as a path under the context root (e.g. \"assets/logo.svg\"). Defaults to the Leji mark."
        },
        "title": {
          "type": "string",
          "description": "Display title for the viewer (sidebar header and page title). Defaults to the context layer name."
        },
        "agentsLabel": {
          "type": "string",
          "description": "Sidebar label for the agent-profiles group (emoji welcome). Defaults to \"🤖 Agents\". The group lists the layer's agent profiles and is ordered by viewer.groupOrder like any other group."
        },
        "favicon": {
          "type": "string",
          "description": "Favicon for the viewer, as a path under the context root (e.g. \"assets/icon.svg\"). Defaults to the Leji mark."
        },
        "homepage": {
          "type": "string",
          "description": "The viewer's landing page, as a path relative to the context root (e.g. \"README.md\"). Defaults to the seeded overview.md."
        },
        "pins": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "path"
                ],
                "properties": {
                  "path": {
                    "type": "string",
                    "description": "Repository-root-relative markdown path to pin."
                  },
                  "label": {
                    "type": "string",
                    "description": "Curated sidebar label for the pin (emoji welcome). Derived from the file when omitted."
                  }
                }
              }
            ]
          },
          "description": "Pages pinned at the top of the sidebar: repository-root-relative markdown paths, or {path, label} for a curated label. Pinning the boot profile replaces its default line."
        },
        "groupOrder": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Curated sidebar group sequence, by exact group label (the index file's H1). Listed groups come first in this order; unlisted groups follow in derived order."
        },
        "theme": {
          "type": "object",
          "additionalProperties": false,
          "description": "Viewer theme overrides.",
          "properties": {
            "primary": {
              "type": "string",
              "description": "Primary/accent color as a hex CSS color (e.g. \"#009F71\"). Drives the viewer chrome, active states, and diagram accents; body links and inline code use the fixed accessible tone unless viewer.theme.link supplies one that clears the contrast guard."
            },
            "link": {
              "type": "string",
              "description": "Link color as a hex CSS color (e.g. \"#5A50F9\"). Applied to body links and inline code only when it reaches 4.5:1 against the inline-code ground, the narrower of the two backgrounds they land on; otherwise the fixed accessible tone stays and `leji view` / `leji export` warn."
            }
          }
        },
        "mermaid": {
          "type": "boolean",
          "description": "Render fenced ```mermaid code blocks as diagrams in the viewer. Defaults to true."
        },
        "poweredBy": {
          "type": "boolean",
          "description": "Show the small \"Powered by Leji\" mark in the viewer's corner. Defaults to true; set false to remove it."
        },
        "categoryEmojis": {
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "propertyNames": {
            "enum": [
              "domain",
              "system",
              "practice",
              "governance",
              "decisions"
            ]
          },
          "description": "Override the default emoji shown beside each category in the generated layer map. (Sidebar groups are labeled by each index file's own H1.)"
        }
      }
    }
  },
  "$defs": {
    "relPath": {
      "type": "string",
      "pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).+$"
    },
    "isoDate": {
      "type": "string",
      "pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])([T ].*)?$"
    },
    "owner": {
      "type": "object",
      "required": [
        "name"
      ],
      "additionalProperties": false,
      "properties": {
        "name": {
          "description": "The person's name.",
          "type": "string",
          "minLength": 1
        },
        "contact": {
          "description": "How to reach them, e.g. an email address.",
          "type": "string"
        }
      }
    },
    "categoryMapping": {
      "type": "object",
      "required": [
        "indexes"
      ],
      "additionalProperties": false,
      "properties": {
        "indexes": {
          "description": "One or more repository-root-relative index files for this category. Each index file is curated markdown carrying a fenced `leji-index` block whose `- path: <dir-or-file>` lines select the content that belongs to this category. Content stays where it lives; the index file declares inclusion.",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).+\\.md$"
          }
        }
      }
    },
    "actor": {
      "type": "object",
      "required": [
        "roles",
        "commands"
      ],
      "additionalProperties": false,
      "properties": {
        "roles": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "$ref": "#/$defs/roleId"
          },
          "description": "Role identifiers this actor is eligible to fill. Every entry must have a matching key in commands."
        },
        "commands": {
          "type": "object",
          "minProperties": 1,
          "propertyNames": {
            "$ref": "#/$defs/roleId"
          },
          "additionalProperties": {
            "$ref": "#/$defs/actorCommand"
          },
          "description": "Command templates keyed by role identifier. The key set must equal roles. Keying by role is the point: one actor can need different invocations for different roles."
        }
      }
    },
    "actorCommand": {
      "type": "string",
      "minLength": 1,
      "pattern": "<prompt>",
      "description": "Command template used to engage this actor in the keyed role. Must carry the <prompt> placeholder, standing as its own unquoted shell word; the pattern verifies the substitution site exists, placement is the spec's rule."
    },
    "roleId": {
      "type": "string",
      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
      "description": "A role identifier, lowercase and hyphen-separated, as used by the agents map."
    }
  }
}

位于仓库根目录的一份符合规范的清单。

{
  "$schema": "https://leji.org/schemas/v1.0/context-manifest.schema.json",
  "leji": "1.0",
  "name": "acme-billing-context",
  "description": "Acme 计费平台 monorepo 的共享上下文层。",
  "rootPath": "docs/",
  "bootProfilePath": "docs/boot-profile.md",
  "categories": {
    "domain": {
      "indexes": [
        "docs/context/domain.md"
      ]
    },
    "system": {
      "indexes": [
        "docs/context/system.md"
      ]
    },
    "decisions": {
      "indexes": [
        "docs/context/decisions.md"
      ]
    }
  },
  "machine": {
    "indexPath": "docs/context-index.json",
    "changelogPath": "docs/context-changelog.json",
    "agentProfilesPath": "docs/agents/",
    "decisionRecordsPath": "docs/decisions/"
  },
  "agents": {
    "thought-partner": "docs/agents/thought-partner.md"
  },
  "owners": {
    "primary": {
      "name": "Acme Platform Team",
      "contact": "platform@acme.example"
    }
  },
  "conformance": {
    "claimedLevel": "indexed",
    "claimedAt": "2026-06-10"
  }
}

← 全部 Schema