schema-author
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseschema-author — evolve your schema pack
schema-author — 升级你的schema包
Non-goals (use these other skills instead)
非目标(请改用以下其他技能)
This skill AUTHORS the schema pack (adds page types, link verbs, prefixes,
flags). For these adjacent jobs, route elsewhere:
- Filing one specific page → . Brain- taxonomist routes at WRITE TIME ("where does this note go?"). schema-author changes the rules at AUTHORING TIME ("what types and prefixes exist?").
skills/brain-taxonomist/SKILL.md - Schema-check as part of EIIRP iteration → already has a schema-check phase. Don't duplicate.
skills/eiirp/SKILL.md - Just looking up a type's settings → directly. This skill is for CHANGING the pack, not READING from it.
gbrain schema explain <type> - Querying who knows about X → (or
skills/expert-routing/SKILL.mddirectly). schema-author makes a type expert-routable; it does not run the query.gbrain whoknows
本技能用于编写(AUTHORS)schema包(添加页面类型、链接动词、前缀、标记)。对于以下相关任务,请转至其他技能:
- 归档单个特定页面 → 。Brain-taxonomist在写入阶段(“这条笔记应该放在哪里?”)进行路由,而schema-author在编写阶段(“存在哪些类型和前缀?”)修改规则。
skills/brain-taxonomist/SKILL.md - 作为EIIRP迭代一部分的schema检查 → 已包含schema检查阶段,请勿重复操作。
skills/eiirp/SKILL.md - 仅查询某类型的设置 → 直接使用。本技能用于修改包,而非读取包内容。
gbrain schema explain <type> - 查询谁了解X相关内容 → (或直接使用
skills/expert-routing/SKILL.md)。schema-author使类型支持专家路由,但不执行查询操作。gbrain whoknows
Convention
约定
Convention: see conventions/brain-first.md for the lookup chain (search → query → get_page → external).
Convention: see conventions/schema-evolution.md for "when to add a type vs alias vs prefix" — the heuristic.
约定: 查阅conventions/brain-first.md了解查找链(搜索→查询→get_page→外部)。
约定: 查阅conventions/schema-evolution.md了解“何时添加类型、别名或前缀”的启发式规则。
When to invoke
调用时机
Invoke when the user (or a sibling skill) says any of:
- "Add a type to my schema"
researcher - "I have 4000 untyped pages under "
meetings/ - "My brain doesn't know that is a type"
journal-article - "Set to be extractable"
paper - "Propose types from what I've ingested"
- "Sync the new types to backfill existing pages"
DON'T invoke for "where does THIS note go" (use brain-taxonomist) or
"who knows about X" (use expert-routing / ).
gbrain whoknows当用户(或同级技能)说出以下任意内容时调用:
- “为我的schema添加类型”
researcher - “我的目录下有4000个未分类页面”
meetings/ - “我的brain不知道是一种类型”
journal-article - “将设置为可提取”
paper - “根据我已导入的内容提议新类型”
- “同步新类型以回填现有页面”
请勿在“这条笔记应该放在哪里”(使用brain-taxonomist)或“谁了解X相关内容”(使用expert-routing / )时调用本技能。
gbrain whoknowsTutorial + vision
教程与愿景
- Why this matters: — 7 killer use cases (4000 invisible meetings made queryable, founder ops brain, research brain, legal brain, team brain, agent-as-co-curator) plus the structural argument for why types matter at query time. Read this before pitching schema authoring to a user — it's the doc that explains the difference between a pile of notes and a brain with structure.
docs/what-schemas-unlock.md - 5-minute walkthrough: — fork the bundled pack, add a researcher type, sync, prove the T1.5 wiring via
docs/schema-author-tutorial.md. Use placeholder pages so it runs against any brain without affecting real content.gbrain whoknows
- 重要性: — 7个关键用例(4000个不可见会议变为可查询、创始人运营brain、研究brain、法律brain、团队brain、Agent作为联合策展人),以及类型在查询阶段为何重要的结构化论证。在向用户推荐schema编写之前,请阅读本文档——它解释了一堆笔记与结构化brain之间的区别。
docs/what-schemas-unlock.md - 5分钟演练: — 复刻捆绑包、添加researcher类型、同步、通过
docs/schema-author-tutorial.md验证T1.5连接。使用占位页面,以便在不影响真实内容的情况下在任意brain上运行。gbrain whoknows
Workflow
工作流程
Phase 1 — Brain (know which pack is active)
阶段1 — Brain(了解当前激活的包)
gbrain schema active --jsonOutput gives you , , , , .
If , the user is on bundled and any
mutation will need a fork first (Phase 4).
pack_nameversionsha8page_types_countsource_tiersource_tier === "default"gbrain-basegbrain schema active --json输出将提供、、、、。如果,则用户使用的是捆绑的,任何修改都需要先复刻(阶段4)。
pack_nameversionsha8page_types_countsource_tiersource_tier === "default"gbrain-basePhase 2 — Assess (what does the current pack cover?)
阶段2 — 评估(当前包覆盖了哪些内容?)
gbrain schema stats --jsonReturns per-type page counts, untyped count, and (pack-
declared prefixes with zero matching pages — probable mis-declarations).
If coverage < 90%, there's untyped content worth typing.
dead_prefixesgbrain schema review-orphans --limit 50 --jsonUntyped pages drilldown. Look for shared path prefixes (e.g. "12 of these
are under ") — those are candidates for a new type.
research/papers/gbrain schema stats --json返回各类型页面数量、未分类页面数量,以及(包中声明但无匹配页面的前缀——可能是错误声明)。如果覆盖率<90%,则存在值得分类的未分类内容。
dead_prefixesgbrain schema review-orphans --limit 50 --json未分类页面详情。查找共享路径前缀(例如“其中12个位于下”)——这些是新类型的候选对象。
research/papers/Phase 3 — Propose (what types should the pack add?)
阶段3 — 提议(包应添加哪些类型?)
gbrain schema detect --jsonClusters pages by and proposes candidate types. Heuristic
only (no LLM call).
source_pathgbrain schema suggest --jsonLLM-refined candidates with confidence scores. Use the top-3 hit rate as
the signal for which to promote.
gbrain schema detect --json按聚类页面并提议候选类型。仅使用启发式规则(无LLM调用)。
source_pathgbrain schema suggest --json经LLM优化的候选类型,带有置信度评分。使用前3个候选的命中率作为选择依据。
Phase 4 — Apply (mutate the pack)
阶段4 — 应用(修改包)
If the active pack is bundled ( or ),
fork it first:
gbrain-basegbrain-recommendedgbrain schema fork gbrain-base mine
gbrain schema use mineThen add the types one at a time:
gbrain schema add-type researcher \
--primitive entity \
--prefix people/researchers/ \
--extractable \
--expertFor complex multi-mutation refactors (e.g. add a type AND the link verb
that points to it), agents reaching this surface over MCP can use the
batched op:
schema_apply_mutationsjsonl
{"op": "add_type", "name": "researcher", "primitive": "entity", "prefix": "people/researchers/", "extractable": true, "expert_routing": true}
{"op": "add_type", "name": "paper", "primitive": "annotation", "prefix": "research/papers/", "extractable": true}
{"op": "add_link_type", "name": "authored", "inference": {"page_type": "researcher", "target_type": "paper"}}Validate before sync:
gbrain schema lint --with-dbThe flag opts into the 2 DB-aware rules
(, ) that detect
mis-declared types you'd otherwise discover only at runtime.
--with-dbextractable_empty_corpusmutation_count_anomaly如果激活的包是捆绑包(或),请先复刻:
gbrain-basegbrain-recommendedgbrain schema fork gbrain-base mine
gbrain schema use mine然后逐个添加类型:
gbrain schema add-type researcher \
--primitive entity \
--prefix people/researchers/ \
--extractable \
--expert对于复杂的多修改重构(例如添加类型及其指向的链接动词),通过MCP访问此接口的Agent可使用批量操作:
schema_apply_mutationsjsonl
{"op": "add_type", "name": "researcher", "primitive": "entity", "prefix": "people/researchers/", "extractable": true, "expert_routing": true}
{"op": "add_type", "name": "paper", "primitive": "annotation", "prefix": "research/papers/", "extractable": true}
{"op": "add_link_type", "name": "authored", "inference": {"page_type": "researcher", "target_type": "paper"}}同步前验证:
gbrain schema lint --with-db--with-dbextractable_empty_corpusmutation_count_anomalyPhase 5 — Sync (backfill existing pages with the new types)
阶段5 — 同步(用新类型回填现有页面)
Dry-run first:
gbrain schema sync --jsonReturns per-prefix counts + sample slugs. If the numbers
look right:
would_applygbrain schema sync --applyChunked UPDATE in 1000-row batches; never wedges concurrent writers.
Idempotent on re-run (second finds nothing to backfill).
--apply先执行试运行:
gbrain schema sync --json返回每个前缀的计数+示例slug。如果数值合理:
would_applygbrain schema sync --apply以1000行批次进行分块更新;不会阻塞并发写入。重复执行具有幂等性(第二次将无内容可回填)。
--applyPhase 6 — Verify
阶段6 — 验证
gbrain schema stats --jsonCoverage should be ≥95% now. Spot-check the new type:
gbrain whoknows "machine learning"If was declared , results should include
researcher-typed pages. (The pack-aware wiring at the query path was
added in v0.40.6.0 — pre-v0.40.6 brains silently ignored custom
expert-routed types.)
researcher--expertgbrain schema stats --json现在覆盖率应≥95%。抽查新类型:
gbrain whoknows "machine learning"如果被声明为,结果应包含researcher类型的页面。(查询路径中的包感知连接在v0.40.6.0中添加——v0.40.6之前的brain会忽略自定义专家路由类型。)
researcher--expertPhase 7 — Commit (preserve the change)
阶段7 — 提交(保存更改)
If the pack is in source control, commit:
cd ~/.gbrain/schema-packs/mine
git add pack.json
git commit -m "schema: add researcher + paper types + authored link"
git pushIf the brain daemon is running (), other processes
pick up the change within 1 second (stat-mtime TTL gate in
loadActivePack — v0.40.6.0 closed the cross-process invalidation gap).
gbrain serve --http如果包处于版本控制中,请提交:
cd ~/.gbrain/schema-packs/mine
git add pack.json
git commit -m "schema: add researcher + paper types + authored link"
git push如果brain守护进程正在运行(),其他进程将在1秒内获取更改(loadActivePack中的stat-mtime TTL gate——v0.40.6.0修复了跨进程失效的问题)。
gbrain serve --httpOutputs
输出
- Mutated pack file at .
~/.gbrain/schema-packs/<name>/pack.{json,yaml} - Audit row in per mutation.
~/.gbrain/audit/schema-mutations-YYYY-Www.jsonl - backfilled on matching rows after
pages.type.sync --apply - Query paths (,
whoknows) now route through the new expert types.find_experts
- 修改后的包文件位于。
~/.gbrain/schema-packs/<name>/pack.{json,yaml} - 每次修改都会在中添加一条审核记录。
~/.gbrain/audit/schema-mutations-YYYY-Www.jsonl - 执行后,匹配行的
sync --apply将被回填。pages.type - 查询路径(、
whoknows)现在会通过新的专家类型进行路由。find_experts
Contract
契约
- Inputs: a natural-language request that names a type / prefix / link verb / flag change, OR the result of showing untyped pages that need a new type.
gbrain schema review-orphans - Outputs: mutated pack file at + an audit row in
~/.gbrain/schema-packs/<name>/pack.{json,yaml}+ (if~/.gbrain/audit/schema-mutations-YYYY-Www.jsonlran) backfilledsync --applyon matching rows.pages.type - Side effects: invalidates the in-process pack cache + the query cache for the source. Other processes pick up the change within 1 second (stat-mtime TTL).
- Idempotency: every primitive is idempotent. /
add-aliasno-op on duplicate;add-prefixfinds nothing to update on second run.sync --apply - Trust: CLI = local trust (no scope check). MCP = OAuth scope (write ops). Audit log captures
adminper mutation.actor: mcp:<clientId8> - Atomicity: every mutation is wrapped in 's atomic write (
withMutation) + per-pack.tmp + fsync + renamelock. Crash mid-write leaves the original file untouched.O_CREAT|O_EXCL
- 输入: 命名类型/前缀/链接动词/标记更改的自然语言请求,或显示的需要新类型的未分类页面结果。
gbrain schema review-orphans - 输出: 修改后的包文件位于+
~/.gbrain/schema-packs/<name>/pack.{json,yaml}中的审核记录 + (如果执行了~/.gbrain/audit/schema-mutations-YYYY-Www.jsonl)匹配行的sync --apply被回填。pages.type - 副作用: 使进程内包缓存和源查询缓存失效。其他进程将在1秒内获取更改(stat-mtime TTL)。
- 幂等性: 每个操作都是幂等的。/
add-alias在重复操作时无效果;add-prefix在第二次运行时无内容可更新。sync --apply - 信任: CLI = 本地信任(无范围检查)。MCP = OAuth 范围(写入操作)。审核日志会记录每次修改的
admin。actor: mcp:<clientId8> - 原子性: 每次修改都被的原子写入(
withMutation)+ 每个包的.tmp + fsync + rename锁包裹。写入中途崩溃会保留原始文件不变。O_CREAT|O_EXCL
Anti-Patterns
反模式
- Don't mutate or
gbrain-base. Fork first (gbrain-recommended). These are bundled packs; edits would be lost on upgrade. The mutation primitives refuse withgbrain schema fork gbrain-base mine.PACK_READONLY - Don't add a type for a directory you imported once for triage. Pack types are permanent decisions; one-time imports are not. See for the <20-pages-don't-pack-codify heuristic.
skills/conventions/schema-evolution.md - Don't add to a type with no
--expert. Thepath_prefixeslint warns about this — expert-routed types with no prefix never match a put_page inference, soexpert_routing_without_prefixsilently never surfaces them.whoknows - Don't promote a candidate without verifying the prefix matches real content. Run
schema suggestbeforelint --with-dbto catch prefix collisions pre-write.add-type - Don't conflate "filing one page" with "evolving the schema." Filing routes via ; schema-author is for authoring the type taxonomy itself. The Non-goals section above names the boundary.
brain-taxonomist - Don't skip the dry-run before . Always run
sync --applyfirst to seesynccounts + sample slugs. A pack prefix that matches 50,000 pages is recoverable but slow; verifying first is cheap.would_apply - Don't remove a type without checking references. refuses with
remove-typeif another type'sSTILL_REFERENCED/aliases/enrichable_types/link_typesreferences it. Break the references first; don't addfrontmatter_links.--force
- 不要修改或
gbrain-base。 先复刻(gbrain-recommended)。这些是捆绑包,升级时修改会丢失。修改操作会返回gbrain schema fork gbrain-base mine错误。PACK_READONLY - 不要为仅导入一次用于分类的目录添加类型。 包类型是永久决策;一次性导入不属于此类。查阅了解“少于20页则不纳入包”的启发式规则。
skills/conventions/schema-evolution.md - 不要为无的类型添加
path_prefixes。--expert规则会对此发出警告——无前缀的专家路由类型永远不会匹配put_page推断,因此expert_routing_without_prefix不会显示它们。whoknows - 不要在未验证前缀匹配真实内容的情况下推广候选类型。 在
schema suggest前运行add-type以在写入前捕获前缀冲突。lint --with-db - 不要混淆“归档单个页面”与“升级schema”。 归档通过路由;schema-author用于编写类型分类体系本身。上述非目标部分明确了边界。
brain-taxonomist - 不要在前跳过试运行。 始终先运行
sync --apply查看sync计数+示例slug。匹配50000个页面的包前缀可恢复但速度慢;提前验证成本低。would_apply - 不要在未检查引用的情况下删除类型。 如果其他类型的/
aliases/enrichable_types/link_types引用了该类型,frontmatter_links会返回remove-type错误。先删除这些引用;不要使用STILL_REFERENCED。--force
Output Format
输出格式
When invoked, this skill produces structured output suitable for both human + JSON consumption:
Per-mutation result (JSON):
json
{"schema_version": 1, "pack": "mine", "path": "/Users/.../pack.json", "format": "json", "prev_sha8": "a1b2c3d4", "new_sha8": "e5f6g7h8"}Per-batch result (from MCP op):
schema_apply_mutationsjson
{"schema_version": 1, "pack": "mine", "batch_id": "batch-1716491400-abc123", "mutations_applied": 3, "results": [{...}, {...}, {...}]}Stats JSON (per-source + aggregate + dead-prefix hints):
json
{"schema_version": 1, "pack_identity": "mine@1.0.0+abc12345", "aggregate": {"total_pages": 4823, "typed_pages": 4710, "untyped_pages": 113, "coverage": 0.9766, "by_type": [{"type": "person", "count": 2104}, ...]}, "per_source": [...], "dead_prefixes": [{"type": "researcher", "prefix": "people/researchers/"}]}Sync dry-run JSON:
json
{"schema_version": 1, "apply": false, "pack_identity": "mine@1.0.0+abc12345", "per_prefix": [{"type": "meeting", "prefix": "meetings/", "would_apply": 4000, "sample_slugs": ["meetings/2026-01-01-foo", ...], "dead_prefix": false, "applied": 0}], "total_would_apply": 4000, "total_applied": 0}Human output (the agent's final summary):
- One line per mutation: and
Pack: <name> (<format>)Sha8: <prev> → <new> - Stats: total pages, typed %, untyped count, per-type breakdown, dead-prefix list
- Sync: per-prefix /
would_applycount + sample slugs in dry-run modeapplied
On failure, the error envelope follows the standard shape from : . Codes from the mutation primitives: , , , , , , , , , .
StructuredAgentErrorsrc/core/errors.ts{error, code, message, details?}PACK_NOT_FOUNDPACK_READONLYPACK_CORRUPTTYPE_EXISTSTYPE_NOT_FOUNDINVALID_PRIMITIVEINVALID_RESULTIO_ERRORSTILL_REFERENCEDLOCK_BUSY调用本技能时,会生成适合人类和JSON消费的结构化输出:
每次修改的结果(JSON):
json
{"schema_version": 1, "pack": "mine", "path": "/Users/.../pack.json", "format": "json", "prev_sha8": "a1b2c3d4", "new_sha8": "e5f6g7h8"}批量操作结果(来自 MCP操作):
schema_apply_mutationsjson
{"schema_version": 1, "pack": "mine", "batch_id": "batch-1716491400-abc123", "mutations_applied": 3, "results": [{...}, {...}, {...}]}统计信息JSON(按源+汇总+无效前缀提示):
json
{"schema_version": 1, "pack_identity": "mine@1.0.0+abc12345", "aggregate": {"total_pages": 4823, "typed_pages": 4710, "untyped_pages": 113, "coverage": 0.9766, "by_type": [{"type": "person", "count": 2104}, ...]}, "per_source": [...], "dead_prefixes": [{"type": "researcher", "prefix": "people/researchers/"}]}同步试运行JSON:
json
{"schema_version": 1, "apply": false, "pack_identity": "mine@1.0.0+abc12345", "per_prefix": [{"type": "meeting", "prefix": "meetings/", "would_apply": 4000, "sample_slugs": ["meetings/2026-01-01-foo", ...], "dead_prefix": false, "applied": 0}], "total_would_apply": 4000, "total_applied": 0}人类可读输出(Agent的最终摘要):
- 每次修改一行:和
Pack: <name> (<format>)Sha8: <prev> → <new> - 统计信息:总页面数、已分类百分比、未分类页面数、各类型细分、无效前缀列表
- 同步:试运行模式下每个前缀的/
would_apply计数+示例slugapplied
失败时,错误信封遵循中的标准格式:。修改操作返回的错误码包括:、、、、、、、、、。
src/core/errors.tsStructuredAgentError{error, code, message, details?}PACK_NOT_FOUNDPACK_READONLYPACK_CORRUPTTYPE_EXISTSTYPE_NOT_FOUNDINVALID_PRIMITIVEINVALID_RESULTIO_ERRORSTILL_REFERENCEDLOCK_BUSYFailure modes
失败模式
- → you tried to mutate
PACK_READONLYorgbrain-base. Fork first.gbrain-recommended - → the mutation would create a dangling reference or prefix collision. The pre-write lint gate caught it. Read the error message; the lint rule name names the problem.
INVALID_RESULT - → you tried to remove a type that another type's
STILL_REFERENCED/aliases/enrichable_types/link_typesreferences. The error names every reference. Remove those first.frontmatter_links - → another process is mid-mutation. Wait 30s and retry, or pass
LOCK_BUSYif you know the holder is wedged.--force - (MCP only) → your OAuth client doesn't have
permission_deniedscope. Re-register withadmin.gbrain auth register-client --scopes admin
- → 你尝试修改
PACK_READONLY或gbrain-base。请先复刻。gbrain-recommended - → 修改会创建悬空引用或前缀冲突。写入前的检查规则已捕获此问题。阅读错误消息;规则名称指明了问题。
INVALID_RESULT - → 你尝试删除的类型被其他类型的
STILL_REFERENCED/aliases/enrichable_types/link_types引用。错误会列出所有引用。请先删除这些引用。frontmatter_links - → 另一个进程正在执行修改。等待30秒后重试,或在确认持有锁的进程已卡住时使用
LOCK_BUSY。--force - (仅MCP)→ 你的OAuth客户端没有
permission_denied范围。使用admin重新注册。gbrain auth register-client --scopes admin