wiki-ingest

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

wiki-ingest: Source Ingestion

wiki-ingest:来源内容导入

Read the source. Write the wiki. Cross-reference everything. A single source typically touches 8-15 wiki pages.
Syntax standard: Write all Obsidian Markdown using proper Obsidian Flavored Markdown. Wikilinks as
[[Note Name]]
, callouts as
> [!type] Title
, embeds as
![[file]]
, properties as YAML frontmatter. If the kepano/obsidian-skills plugin is installed, prefer its canonical obsidian-markdown skill for Obsidian syntax reference. Otherwise, follow the guidance in this skill.

读取来源内容,生成wiki页面,建立所有交叉引用。单个来源通常会关联8-15个wiki页面。
语法标准:使用标准Obsidian Flavored Markdown编写内容。Wikilinks格式为
[[Note Name]]
,提示框格式为
> [!type] Title
,嵌入内容格式为
![[file]]
,属性信息采用YAML前置元数据。若已安装kepano/obsidian-skills插件,优先参考其官方obsidian-markdown技能的语法规范;否则遵循本技能中的指导说明。

Transport (v1.7+)

传输机制(v1.7+)

Before mutating any vault file, consult
.vault-meta/transport.json
(auto-created by
bash scripts/detect-transport.sh
). Use the
preferred
transport per the fallback chain:
  • cli
    obsidian-cli write "$VAULT" "$NOTE" < content.md
    (or
    append
    ,
    property:set
    ); see
    skills/wiki-cli/SKILL.md
  • mcp-obsidian / mcpvault
    mcp__obsidian-vault__write_note
    and friends; see
    skills/wiki/references/mcp-setup.md
  • filesystem — Claude's
    Write
    /
    Edit
    tools with absolute vault-rooted paths (final floor; always works)
Full decision tree:
wiki/references/transport-fallback.md
.

在修改任何vault文件前,请查阅
.vault-meta/transport.json
(由
bash scripts/detect-transport.sh
自动生成)。按照以下优先级选择
preferred
传输方式:
  • cli — 使用
    obsidian-cli write "$VAULT" "$NOTE" < content.md
    (或
    append
    property:set
    );详见
    skills/wiki-cli/SKILL.md
  • mcp-obsidian / mcpvault — 使用
    mcp__obsidian-vault__write_note
    及相关工具;详见
    skills/wiki/references/mcp-setup.md
  • filesystem — 使用Claude的
    Write
    /
    Edit
    工具,采用vault根目录的绝对路径(最终兜底方案,始终可用)
完整决策树详见:
wiki/references/transport-fallback.md

Mode awareness (v1.8+)

模式感知(v1.8+)

Before creating any new wiki page, consult the vault's methodology mode via
python3 scripts/wiki-mode.py route <type> "<name>"
. The router returns the vault-relative path where the page should be filed.
bash
SRC_PATH=$(python3 scripts/wiki-mode.py route source "Karpathy 2025 LLM Wiki essay")
在创建任何新wiki页面之前,请通过
python3 scripts/wiki-mode.py route <type> "<name>"
查询vault的方法论模式。路由工具会返回页面应存放的vault相对路径。
bash
SRC_PATH=$(python3 scripts/wiki-mode.py route source "Karpathy 2025 LLM Wiki essay")

generic: wiki/sources/Karpathy-2025-LLM-Wiki-essay.md

generic: wiki/sources/Karpathy-2025-LLM-Wiki-essay.md

lyt: wiki/notes/Karpathy-2025-LLM-Wiki-essay.md (also update relevant MOC)

lyt: wiki/notes/Karpathy-2025-LLM-Wiki-essay.md (同时更新相关MOC)

para: wiki/resources/incoming/Karpathy-2025-LLM-Wiki-essay.md

para: wiki/resources/incoming/Karpathy-2025-LLM-Wiki-essay.md

zettelkasten: wiki/20260517123456-Karpathy-2025-LLM-Wiki-essay.md

zettelkasten: wiki/20260517123456-Karpathy-2025-LLM-Wiki-essay.md

ENT_PATH=$(python3 scripts/wiki-mode.py route entity "Andrej Karpathy") CON_PATH=$(python3 scripts/wiki-mode.py route concept "Compounding Vault Pattern")

If `.vault-meta/mode.json` is absent, the router returns mode=generic paths (identical to v1.7 behavior). No special-casing needed in this skill.

Mode-specific follow-up:
- **LYT**: after filing the atomic note, update the relevant MOC (`wiki/mocs/<topic>-moc.md`) to link the new note. If no MOC exists for the topic, create one using `skills/wiki-mode/templates/lyt/moc-template.md`.
- **Zettelkasten**: filename already includes the timestamp ID. Populate the `id:` frontmatter field to match.
- **PARA**: new ingests land in `wiki/resources/incoming/` by default. Do NOT auto-guess the topic; leave in incoming/ for user review.
ENT_PATH=$(python3 scripts/wiki-mode.py route entity "Andrej Karpathy") CON_PATH=$(python3 scripts/wiki-mode.py route concept "Compounding Vault Pattern")

若`.vault-meta/mode.json`不存在,路由工具会返回generic模式路径(与v1.7版本行为一致),本技能无需特殊处理。

模式特定后续操作:
- **LYT**:在归档原子笔记后,更新相关MOC(`wiki/mocs/<topic>-moc.md`)以链接新笔记。若该主题无MOC,使用`skills/wiki-mode/templates/lyt/moc-template.md`创建。
- **Zettelkasten**:文件名已包含时间戳ID,需在前置元数据中填充`id:`字段以匹配。
- **PARA**:新导入内容默认存放在`wiki/resources/incoming/`,请勿自动猜测主题,保留在incoming目录供用户审核。

Concurrency (v1.7+)

并发处理(v1.7+)

Multi-writer is safe in v1.7. The latent corruption bug from v1.6 — where two parallel sub-agents writing to the same page could silently trample each other — is closed by per-file advisory locking. Every wiki page write MUST be preceded by
wiki-lock acquire <path>
.
bash
undefined
v1.7版本支持安全多写入操作。v1.6版本中存在的潜在损坏漏洞(两个并行子代理写入同一页面时可能静默覆盖内容)已通过按文件的咨询锁机制修复。所有wiki页面写入操作前必须执行
wiki-lock acquire <path>
bash
undefined

Acquire — blocks (returns 75 EX_TEMPFAIL) if another writer holds the lock

获取锁 — 若其他写入者持有锁则阻塞(返回75 EX_TEMPFAIL)

if bash scripts/wiki-lock.sh acquire wiki/concepts/Foo.md; then

... do the write via the §Transport-selected method ...

bash scripts/wiki-lock.sh release wiki/concepts/Foo.md else

rc=75: another writer is in flight. Retry once after 2s; if still held,

log to wiki/log.md and skip this page rather than overwrite.

sleep 2 bash scripts/wiki-lock.sh acquire wiki/concepts/Foo.md && { # write … bash scripts/wiki-lock.sh release wiki/concepts/Foo.md } || echo "skipped wiki/concepts/Foo.md (locked); logged to wiki/log.md" fi

Properties:
- **Per-file granularity.** Locks key on `sha1(<vault-relative-path>)`; concurrent writes to DIFFERENT pages run in parallel.
- **Age-based staleness.** Default `STALE_AFTER_SEC=60`. A crashed holder unblocks in ≤60 seconds without manual intervention. See `scripts/wiki-lock.sh` header for the full semantics.
- **Cross-process release.** Release is `rm -f` (no PID match required). Skill authors are trusted to release locks they acquire; cross-skill release is allowed by design (a janitor running `wiki-lock clear-stale --max-age 0` is the canonical recovery path).
- **The PostToolUse hook now defers `git add` if any locks are currently held**, so the auto-commit doesn't fire mid-ingest and produce torn commits. See `hooks/hooks.json`.

`wiki-lock` is unconditional in v1.7+ — there is no feature gate, no fallback. Skills that don't acquire locks are racing against any other writer. The script is in core, not opt-in.

Sub-agent rule from v1.6 — *"Sub-agents MUST NOT call `scripts/allocate-address.sh`"* — is preserved (orchestrator still backfills addresses to keep the counter monotonic). The NEW rule is: *sub-agents MAY now write pages, but MUST acquire locks first.* See `agents/wiki-ingest.md`.

---
if bash scripts/wiki-lock.sh acquire wiki/concepts/Foo.md; then

... 通过§Transport选择的方式执行写入操作 ...

bash scripts/wiki-lock.sh release wiki/concepts/Foo.md else

返回码75:其他写入者正在操作。等待2秒后重试一次;若仍被锁定,

记录到wiki/log.md并跳过该页面,避免覆盖内容。

sleep 2 bash scripts/wiki-lock.sh acquire wiki/concepts/Foo.md && { # 执行写入 … bash scripts/wiki-lock.sh release wiki/concepts/Foo.md } || echo "skipped wiki/concepts/Foo.md (locked); logged to wiki/log.md" fi

特性:
- **按文件粒度锁定**:锁基于`sha1(<vault-relative-path>)`;不同页面的并发写入可并行执行。
- **基于时长的过期机制**:默认`STALE_AFTER_SEC=60`。崩溃的锁持有者会在≤60秒内自动解锁,无需人工干预。详见`scripts/wiki-lock.sh`头部的完整语义说明。
- **跨进程释放**:释放操作通过`rm -f`实现(无需匹配PID)。信任技能开发者会释放自己获取的锁;设计上允许跨技能释放(执行`wiki-lock clear-stale --max-age 0`的清理工具是标准恢复路径)。
- **PostToolUse钩子现在会在持有锁时延迟执行`git add`**,避免在导入过程中触发自动提交导致不完整的提交记录。详见`hooks/hooks.json`。

`wiki-lock`在v1.7+版本中是强制要求的 — 无功能开关,无兜底方案。未获取锁的技能会与其他写入者产生竞争。该脚本属于核心组件,非可选功能。

保留v1.6版本的子代理规则 — *"子代理不得调用`scripts/allocate-address.sh`"*(协调器仍会回填地址以保持计数器单调递增)。新增规则:*子代理现在可以写入页面,但必须先获取锁*。详见`agents/wiki-ingest.md`。

---

Delta Tracking

增量追踪

Before ingesting any file, check
.raw/.manifest.json
to avoid re-processing unchanged sources.
bash
undefined
在导入任何文件前,检查
.raw/.manifest.json
以避免重复处理未修改的来源。
bash
undefined

Check if manifest exists

检查清单是否存在

[ -f .raw/.manifest.json ] && echo "exists" || echo "no manifest yet"

**Manifest format** (create if missing):
```json
{
  "sources": {
    ".raw/articles/article-slug-2026-04-08.md": {
      "hash": "abc123",
      "ingested_at": "2026-04-08",
      "pages_created": ["wiki/sources/article-slug.md", "wiki/entities/Person.md"],
      "pages_updated": ["wiki/index.md"]
    }
  }
}
Before ingesting a file:
  1. Compute a hash:
    md5sum [file] | cut -d' ' -f1
    (or
    sha256sum
    on Linux).
  2. Check if the path exists in
    .manifest.json
    with the same hash.
  3. If hash matches, skip. Report: "Already ingested (unchanged). Use
    force
    to re-ingest."
  4. If missing or hash differs, proceed with ingest.
After ingesting a file:
  1. Record
    {hash, ingested_at, pages_created, pages_updated}
    in
    .manifest.json
    .
  2. Write the updated manifest back.
Skip delta checking if the user says "force ingest" or "re-ingest".

[ -f .raw/.manifest.json ] && echo "exists" || echo "no manifest yet"

**清单格式**(若不存在则创建):
```json
{
  "sources": {
    ".raw/articles/article-slug-2026-04-08.md": {
      "hash": "abc123",
      "ingested_at": "2026-04-08",
      "pages_created": ["wiki/sources/article-slug.md", "wiki/entities/Person.md"],
      "pages_updated": ["wiki/index.md"]
    }
  }
}
导入文件前的步骤
  1. 计算哈希值:
    md5sum [file] | cut -d' ' -f1
    (Linux系统可使用
    sha256sum
    )。
  2. 检查
    .manifest.json
    中是否存在相同路径且哈希值一致的记录。
  3. 若哈希值匹配,跳过导入。提示:"已导入(未修改)。使用
    force
    参数重新导入。"
  4. 若记录缺失或哈希值不同,继续导入流程。
导入文件后的步骤
  1. .manifest.json
    中记录
    {hash, ingested_at, pages_created, pages_updated}
    信息。
  2. 将更新后的清单写回文件。
若用户指定"force ingest"或"re-ingest",则跳过增量检查。

URL Ingestion

URL导入

Trigger: user passes a URL starting with
https://
.
Steps:
  1. Fetch the page using WebFetch.
  2. Clean (optional): if
    defuddle
    is available (
    which defuddle 2>/dev/null
    ), run
    defuddle [url]
    to strip ads, nav, and clutter. Typically saves 40-60% tokens. Fall back to raw WebFetch output if not installed.
  3. Derive slug from the URL path (last segment, lowercased, spaces→hyphens, strip query strings).
  4. Save to
    .raw/articles/[slug]-[YYYY-MM-DD].md
    with a frontmatter header:
    markdown
    ---
    source_url: [url]
    fetched: [YYYY-MM-DD]
    ---
  5. Proceed with Single Source Ingest starting at step 2 (file is now in
    .raw/
    ).

触发条件:用户传入以
https://
开头的URL。
步骤:
  1. 获取内容:使用WebFetch获取页面内容。
  2. 清理内容(可选):若已安装
    defuddle
    (执行
    which defuddle 2>/dev/null
    检查),运行
    defuddle [url]
    以移除广告、导航栏和冗余内容,通常可减少40-60%的token消耗。若未安装则直接使用WebFetch的原始输出。
  3. 生成slug:从URL路径中提取(最后一段,转为小写,空格替换为连字符,移除查询字符串)。
  4. 保存内容:保存至
    .raw/articles/[slug]-[YYYY-MM-DD].md
    ,并添加前置元数据:
    markdown
    ---
    source_url: [url]
    fetched: [YYYY-MM-DD]
    ---
  5. 继续执行单来源导入的第2步(文件已存放在
    .raw/
    目录)。

Image / Vision Ingestion

图片/视觉内容导入

Trigger: user passes an image file path (
.png
,
.jpg
,
.jpeg
,
.gif
,
.webp
,
.svg
,
.avif
).
Steps:
  1. Read the image file using the Read tool. Claude can process images natively.
  2. Describe the image contents: extract all text (OCR), identify key concepts, entities, diagrams, and data visible in the image.
  3. Save the description to
    .raw/images/[slug]-[YYYY-MM-DD].md
    :
    markdown
    ---
    source_type: image
    original_file: [original path]
    fetched: YYYY-MM-DD
    ---
    # Image: [slug]
    
    [Full description of image contents, transcribed text, entities visible, etc.]
  4. Copy the image to
    _attachments/images/[slug].[ext]
    if it's not already in the vault.
  5. Proceed with Single Source Ingest on the saved description file.
Use cases: whiteboard photos, screenshots, diagrams, infographics, document scans.

触发条件:用户传入图片文件路径(
.png
,
.jpg
,
.jpeg
,
.gif
,
.webp
,
.svg
,
.avif
)。
步骤:
  1. 读取图片:使用Read工具读取图片文件,Claude可原生处理图片。
  2. 描述内容:提取所有文本(OCR),识别关键概念、实体、图表和可见数据。
  3. 保存描述:将描述保存至
    .raw/images/[slug]-[YYYY-MM-DD].md
    markdown
    ---
    source_type: image
    original_file: [original path]
    fetched: YYYY-MM-DD
    ---
    # Image: [slug]
    
    [图片内容的完整描述、转录文本、可见实体等]
  4. 若图片尚未在vault中,将其复制到
    _attachments/images/[slug].[ext]
  5. 对保存的描述文件执行单来源导入流程。
适用场景:白板照片、截图、图表、信息图、文档扫描件。

Single Source Ingest

单来源导入

Trigger: user drops a file into
.raw/
or pastes content.
Steps:
  1. Read the source completely. Do not skim.
  2. Discuss key takeaways with the user. Ask: "What should I emphasize? How granular?" Skip this if the user says "just ingest it."
  3. Create source summary in
    wiki/sources/
    . Use the source frontmatter schema from
    references/frontmatter.md
    . Assign an address per the Address Assignment section below.
  4. Create or update entity pages for every person, org, product, and repo mentioned. One page per entity. Assign addresses to new entity pages.
  5. Create or update concept pages for significant ideas and frameworks. Assign addresses to new concept pages.
  6. Update relevant domain page(s) and their
    _index.md
    sub-indexes.
  7. Update
    wiki/overview.md
    if the big picture changed.
  8. Update
    wiki/index.md
    . Add entries for all new pages.
  9. Update
    wiki/hot.md
    with this ingest's context.
  10. Append to
    wiki/log.md
    (new entries at the TOP):
    markdown
    ## [YYYY-MM-DD] ingest | Source Title
    - Source: `.raw/articles/filename.md`
    - Summary: [[Source Title]]
    - Pages created: [[Page 1]], [[Page 2]]
    - Pages updated: [[Page 3]], [[Page 4]]
    - Key insight: One sentence on what is new.
  11. Check for contradictions. If new info conflicts with existing pages, add
    > [!contradiction]
    callouts on both pages.

触发条件:用户将文件放入
.raw/
目录或粘贴内容。
步骤:
  1. 完整读取:完整读取来源内容,请勿略读。
  2. 确认需求:与用户讨论关键要点,询问:"需要重点强调哪些内容?粒度要求如何?"若用户要求"直接导入"则跳过此步骤。
  3. 创建来源摘要:在
    wiki/sources/
    目录创建来源摘要,使用
    references/frontmatter.md
    中的来源前置元数据 schema,按照下方地址分配部分的规则分配地址。
  4. 创建或更新实体页面:为提及的每个人物、组织、产品和仓库创建或更新实体页面,每个实体对应一个页面,为新实体页面分配地址。
  5. 创建或更新概念页面:为重要的想法和框架创建或更新概念页面,为新概念页面分配地址。
  6. 更新相关领域页面:更新相关领域页面及其
    _index.md
    子索引。
  7. 更新总览页面:若整体内容发生变化,更新
    wiki/overview.md
  8. 更新索引页面:更新
    wiki/index.md
    ,添加所有新页面的条目。
  9. 更新热点缓存:更新
    wiki/hot.md
    ,添加本次导入的上下文信息。
  10. 记录操作日志:在
    wiki/log.md
    顶部追加新条目:
    markdown
    ## [YYYY-MM-DD] ingest | 来源标题
    - 来源:`.raw/articles/filename.md`
    - 摘要:[[来源标题]]
    - 创建页面:[[页面1]], [[页面2]]
    - 更新页面:[[页面3]], [[页面4]]
    - 关键见解:一句话说明新增内容
  11. 检查内容冲突:若新信息与现有页面冲突,在两个页面中添加
    > [!contradiction]
    提示框。

Batch Ingest

批量导入

Trigger: user drops multiple files or says "ingest all of these."
Steps:
  1. List all files to process. Confirm with user before starting.
  2. Process each source following the single ingest flow. Defer cross-referencing between sources until step 3.
  3. After all sources: do a cross-reference pass. Look for connections between the newly ingested sources.
  4. Update index, hot cache, and log once at the end (not per-source).
  5. Report: "Processed N sources. Created X pages, updated Y pages. Here are the key connections I found."
Batch ingest is less interactive. For 30+ sources, expect significant processing time. Check in with the user after every 10 sources.

触发条件:用户放入多个文件或指令为"ingest all of these"。
步骤:
  1. 列出所有待处理文件,开始前与用户确认。
  2. 按照单来源导入流程处理每个来源,跨来源的交叉引用延迟至第3步处理。
  3. 所有来源处理完成后:执行交叉引用步骤,查找新导入来源之间的关联。
  4. 最后统一更新索引、热点缓存和日志(而非每个来源单独更新)。
  5. 反馈结果:"已处理N个来源,创建X个页面,更新Y个页面。以下是发现的关键关联。"
批量导入的交互性较低。若处理30个以上来源,预计需要较长时间,每处理10个来源后需与用户确认进度。

Context Window Discipline

上下文窗口规范

Token budget matters. Follow these rules during ingest:
  • Read
    wiki/hot.md
    first. If it contains the relevant context, don't re-read full pages.
  • Read
    wiki/index.md
    to find existing pages before creating new ones.
  • Read only 3-5 existing pages per ingest. If you need 10+, you are reading too broadly.
  • Use PATCH for surgical edits. Never re-read an entire file just to update one field.
  • Keep wiki pages short. 100-300 lines max. If a page grows beyond 300 lines, split it.
  • Use search (
    /search/simple/
    ) to find specific content without reading full pages.

Token预算至关重要,导入过程中请遵循以下规则:
  • 先读取
    wiki/hot.md
    ,若包含相关上下文,无需重新读取完整页面。
  • 读取
    wiki/index.md
    查找现有页面,避免创建重复页面。
  • 每次导入仅读取3-5个现有页面,若需要读取10个以上,说明范围过宽。
  • 使用PATCH进行精准编辑,切勿为了更新一个字段而重新读取整个文件。
  • 保持wiki页面简洁,最多100-300行。若页面超过300行,需拆分。
  • 使用搜索功能(
    /search/simple/
    )查找特定内容,无需读取完整页面。

Contradictions

内容冲突处理

[!note] Custom callout dependency The
[!contradiction]
callout type used below is a custom callout defined in
.obsidian/snippets/vault-colors.css
(auto-installed by
/wiki
scaffold). It renders with reddish-brown styling and an alert-triangle icon when the snippet is enabled. If the snippet is missing, Obsidian falls back to default callout styling, so the page still works without the visual flourish. See [[skills/wiki/references/css-snippets.md]] for the four custom callouts (
contradiction
,
gap
,
key-insight
,
stale
).
When new info contradicts an existing wiki page:
On the existing page, add:
markdown
> [!contradiction] Conflict with [[New Source]]
> [[Existing Page]] claims X. [[New Source]] says Y.
> Needs resolution. Check dates, context, and primary sources.
On the new source summary, reference it:
markdown
> [!contradiction] Contradicts [[Existing Page]]
> This source says Y, but existing wiki says X. See [[Existing Page]] for details.
Do not silently overwrite old claims. Flag and let the user decide.

[!note] 自定义提示框依赖 以下使用的
[!contradiction]
提示框类型是自定义提示框,定义在
.obsidian/snippets/vault-colors.css
中(由
/wiki
脚手架自动安装)。启用该代码片段时,会显示红棕色样式和警告三角图标。若代码片段缺失,Obsidian会回退到默认提示框样式,页面仍可正常显示,仅无视觉增强效果。详见[[skills/wiki/references/css-snippets.md]]中的四个自定义提示框(
contradiction
gap
key-insight
stale
)。
当新信息与现有wiki页面冲突时:
在现有页面中添加:
markdown
> [!contradiction] 与[[新来源]]冲突
> [[现有页面]]主张X,[[新来源]]称Y。
> 需要解决冲突,请检查日期、上下文和原始来源。
在新来源摘要中引用冲突:
markdown
> [!contradiction] 与[[现有页面]]冲突
> 本来源称Y,但现有wiki内容为X。详情请见[[现有页面]]。
请勿静默覆盖旧内容,需标记冲突并由用户决定如何处理。

What Not to Do

注意事项

  • Source files under
    .raw/
    are immutable.
    Do not modify the files that users drop there (articles, transcripts, images). The
    .raw/.manifest.json
    delta tracker and its
    address_map
    (DragonScale Mechanism 2) are the only files under
    .raw/
    that
    wiki-ingest
    itself maintains. Treat every other file under
    .raw/
    as read-only source content.
  • Do not create duplicate pages. Always check the index and search before creating.
  • Do not skip the log entry. Every ingest must be recorded.
  • Do not skip the hot cache update. It is what keeps future sessions fast.

  • .raw/
    目录下的来源文件为只读
    :请勿修改用户放入的文件(文章、转录稿、图片等)。
    .raw/.manifest.json
    增量追踪器及其
    address_map
    (DragonScale机制2)是
    wiki-ingest
    .raw/
    目录下维护的唯一文件。
    .raw/
    目录下的其他所有文件均视为只读来源内容。
  • 请勿创建重复页面:创建前务必检查索引和搜索结果。
  • 请勿跳过日志记录:每次导入必须记录。
  • 请勿跳过热点缓存更新:这是保证后续会话速度的关键。

Address Assignment (DragonScale Mechanism 2 MVP)

地址分配(DragonScale机制2 最小可行版本)

Opt-in feature. DragonScale address assignment runs only if
scripts/allocate-address.sh
is present AND
.vault-meta/
exists. Otherwise, skip this entire section and proceed with ingest normally.
Feature detection (run at start of every ingest):
bash
if [ -x ./scripts/allocate-address.sh ] && [ -d ./.vault-meta ]; then
  DRAGONSCALE_ADDRESSES=1
else
  DRAGONSCALE_ADDRESSES=0
fi
When
DRAGONSCALE_ADDRESSES=0
, pages are created without an
address:
frontmatter field, and
wiki-lint
's Address Validation section is skipped entirely (missing addresses are not flagged in any severity). This preserves default plugin behavior for vaults that have not adopted DragonScale.
When
DRAGONSCALE_ADDRESSES=1
, proceed with the rest of this section.

Every newly created non-meta wiki page gets a stable address in its frontmatter:
yaml
address: c-000042
Format:
c-<6-digit-counter>
. The
c-
prefix stands for "creation-order counter." Zero-padded.
Rollout baseline: 2026-04-23 (Phase 2 ship date). Pages with
created:
>= this date are post-rollout and MUST have an address (unless excluded below). Pages with
created:
earlier are legacy-exempt until a deliberate backfill pass assigns
l-NNNNNN
addresses.
可选功能。仅当
scripts/allocate-address.sh
存在且
.vault-meta/
目录存在时,才会启用DragonScale地址分配。否则跳过本节内容,正常执行导入流程。
功能检测(每次导入开始时执行)
bash
if [ -x ./scripts/allocate-address.sh ] && [ -d ./.vault-meta ]; then
  DRAGONSCALE_ADDRESSES=1
else
  DRAGONSCALE_ADDRESSES=0
fi
DRAGONSCALE_ADDRESSES=0
时,创建页面时不添加
address:
前置元数据字段,
wiki-lint
的地址验证部分会完全跳过(缺失地址不会被标记为任何级别的问题)。这为未采用DragonScale的vault保留了默认插件行为。
DRAGONSCALE_ADDRESSES=1
时,继续执行本节内容。

每个新建的非元数据wiki页面都会在前置元数据中获得一个稳定地址:
yaml
address: c-000042
格式:
c-<6位计数器>
c-
前缀代表"创建顺序计数器",前置补零。
启用基线:2026-04-23(第2阶段发布日期)。
created:
日期≥此日期的页面属于发布后页面,必须包含地址(以下排除情况除外)。
created:
日期早于此日期的页面属于遗留页面,仅在主动回填操作时分配
l-NNNNNN
地址。

Required tool:
scripts/allocate-address.sh

必备工具:
scripts/allocate-address.sh

Address allocation is delegated to an atomic Bash helper. The helper uses
flock
on
.vault-meta/.address.lock
to prevent read-use-increment races and recovers the counter by scanning existing frontmatter if the counter file is missing.
bash
ADDR=$(./scripts/allocate-address.sh)
地址分配由原子性Bash脚本处理。该脚本使用
flock
锁定
.vault-meta/.address.lock
,防止读取-使用-递增的竞争条件;若计数器文件缺失,会通过扫描现有前置元数据恢复计数器。
bash
ADDR=$(./scripts/allocate-address.sh)

ADDR is now e.g. "c-000042"; counter is already incremented

ADDR示例值:"c-000042";计数器已自动递增


**CRITICAL**: never use the Write or Edit tool on `.vault-meta/address-counter.txt`. That would fire the PostToolUse hook, which runs `git add wiki/ .raw/` and can accidentally commit unrelated pending wiki changes under a generic message. Counter mutation is **only** permitted through the helper script (Bash tool).

**关键注意事项**:切勿使用Write或Edit工具修改`.vault-meta/address-counter.txt`。这会触发PostToolUse钩子,执行`git add wiki/ .raw/`,可能会将未相关的wiki待提交变更意外提交到通用消息下。仅允许通过辅助脚本(Bash工具)修改计数器。

Helper modes

辅助脚本模式

  • ./scripts/allocate-address.sh
    — atomically reserves and returns the next address.
  • ./scripts/allocate-address.sh --peek
    — prints the next value without reserving (safe, read-only).
  • ./scripts/allocate-address.sh --rebuild
    — recomputes the counter from the highest observed
    c-NNNNNN
    in existing frontmatter. Never resets to 1 silently if pages already have addresses. Run this if the counter file is suspected corrupt.
  • ./scripts/allocate-address.sh
    — 原子性保留并返回下一个地址。
  • ./scripts/allocate-address.sh --peek
    — 打印下一个地址但不保留(安全的只读操作)。
  • ./scripts/allocate-address.sh --rebuild
    — 从现有前置元数据中最高的
    c-NNNNNN
    值重新计算计数器。若页面已存在地址,不会静默重置为1。当怀疑计数器文件损坏时执行此操作。

Assignment procedure (per new page)

地址分配流程(每个新页面)

  1. Before writing a new non-meta page, call
    ./scripts/allocate-address.sh
    and capture the output.
  2. Include
    address: c-XXXXXX
    in the page's frontmatter.
  3. Record the path-to-address mapping in
    .raw/.manifest.json
    under a new top-level key
    address_map
    (see schema below).
  1. 在写入新的非元数据页面之前,调用
    ./scripts/allocate-address.sh
    并捕获输出。
  2. 在页面前置元数据中包含
    address: c-XXXXXX
  3. .raw/.manifest.json
    的新顶级键
    address_map
    中记录路径到地址的映射(见下方schema)。

address_map
in
.raw/.manifest.json

.raw/.manifest.json
中的
address_map

json
{
  "sources": { ... },
  "address_map": {
    "wiki/concepts/Example.md": "c-000042",
    "wiki/entities/Another.md": "c-000043"
  }
}
On re-ingest of the same source (whether by
--force
or a changed hash), always consult
address_map
first. If the target page path has a prior address, REUSE it. Do not allocate a new one.
On a page rename, the skill must update the
address_map
key (old path -> new path) while preserving the address value.
json
{
  "sources": { ... },
  "address_map": {
    "wiki/concepts/Example.md": "c-000042",
    "wiki/entities/Another.md": "c-000043"
  }
}
当重新导入同一来源(无论是通过
--force
参数还是哈希值变更),务必先查阅
address_map
。若目标页面路径已有历史地址,复用该地址,请勿分配新地址。
当页面重命名时,技能必须更新
address_map
中的键(旧路径→新路径),同时保留地址值。

Exclusions (do NOT assign an address to)

排除情况(不分配地址)

  • Meta files:
    _index.md
    ,
    index.md
    ,
    log.md
    ,
    hot.md
    ,
    overview.md
    ,
    dashboard.md
    ,
    dashboard.base
    ,
    Wiki Map.md
    ,
    getting-started.md
    .
  • Fold pages under
    wiki/folds/
    (they use their own deterministic
    fold_id
    ).
  • Pre-rollout legacy pages (
    created:
    < 2026-04-23). Legacy pages get
    l-NNNNNN
    addresses only via a deliberate backfill operation.
  • 元数据文件:
    _index.md
    index.md
    log.md
    hot.md
    overview.md
    dashboard.md
    dashboard.base
    Wiki Map.md
    getting-started.md
  • wiki/folds/
    目录下的折叠页面(使用自身的确定性
    fold_id
    )。
  • 发布前遗留页面(
    created:
    < 2026-04-23)。遗留页面仅在主动回填操作时获得
    l-NNNNNN
    地址。

Idempotency rules

幂等性规则

  • If a page being (re)written already has an
    address:
    field in its current content, REUSE it. Do not allocate a new one.
  • If a source is re-ingested and
    address_map
    has a mapping for the target path, reuse that mapping.
  • If the source has been ingested before AND the target page has no address AND the page
    created:
    date is post-rollout, allocate an address and record it. This covers the case where an older ingest produced a page before Phase 2 rollout; the rollout cutoff still applies (pages dated pre-2026-04-23 stay legacy).
  • 若待(重新)写入的页面当前内容已包含
    address:
    字段,复用该地址,请勿分配新地址。
  • 若来源已导入过且
    address_map
    中有目标路径的映射,复用该映射。
  • 若来源已导入过且目标页面无地址且页面
    created:
    日期在发布后,分配地址并记录。这适用于第2阶段发布前导入的页面;发布截止日期仍适用(2026-04-23之前的页面仍为遗留页面)。

Concurrency policy

并发策略

  • Single-writer only in Phase 2. Do not run parallel ingests from multiple Claude sessions or sub-agents that assign addresses. The
    flock
    in the helper prevents counter corruption but does not serialize page writes themselves.
  • Sub-agents (codex, general-purpose) that are dispatched for research or review MUST NOT call the allocator. They are read-only in this respect.
  • Multi-writer support is a deferred feature.
  • 第2阶段仅支持单写入者:请勿从多个Claude会话或分配地址的子代理执行并行导入。辅助脚本中的
    flock
    可防止计数器损坏,但无法序列化页面写入操作本身。
  • 用于研究或审核的子代理(codex、通用型)不得调用分配器,在此场景下它们为只读。
  • 多写入者支持为延迟特性。

Batch ingest

批量导入

Assign addresses sequentially during single-source-ingest for each source. Do not pre-reserve a block of counter values. The helper is cheap (one lock, one integer read/write).

在单来源导入流程中为每个来源依次分配地址,请勿预先保留一段计数器值。辅助脚本开销极低(一次锁操作,一次整数读写)。

How to think (10-principle mapping)

思考框架(10原则映射)

When working on this skill, apply the 10-principle loop. See
skills/think/SKILL.md
for the canonical framework.
#PrincipleApplication here
1OBSERVE (ext)Read the source file completely before extracting anything. No shortcuts on long sources.
2OBSERVE (int)Am I biased toward the source's framing? Where do my disagreements live? Note them as contradiction callouts.
3LISTENThe user's source-selection intent — what made THIS source worth ingesting, and what is the user hoping to extract?
4THINKWhich entities deserve pages? Which concepts? What cross-references? What contradictions with existing pages?
5CONNECT (lat)This source's claims vs other sources already in the wiki. Contradictions are the highest-signal finding.
6CONNECT (sys)
wiki-mode.py route
for paths +
wiki-lock.sh
for safety + index/log/hot for consumer visibility.
7FEELA page that compounds — useful in 6 months, not just today. Skip filler; favor synthesis over transcription.
8ACCEPTNot every claim is wiki-worthy. Editorial judgment is part of ingest, not a bug to remove.
9CREATESource + entity + concept pages with full frontmatter; cross-references; contradiction callouts where needed.
10GROWContradictions found mid-ingest are the most valuable wiki signal. File them as questions for follow-up, not silently.
处理本技能时,请遵循10原则循环。详见
skills/think/SKILL.md
中的标准框架。
#原则本技能中的应用
1观察(外部)在提取任何内容前完整读取来源文件,长来源内容请勿捷径处理。
2观察(内部)我是否偏向来源的框架?我的分歧点在哪里?将这些标记为冲突提示框。
3倾听用户选择该来源的意图 — 为什么这个来源值得导入,用户希望提取什么内容?
4思考哪些实体值得创建页面?哪些概念?需要建立哪些交叉引用?与现有页面有哪些冲突?
5关联(潜在)本来源的主张与wiki中已有的其他来源对比,冲突是最高信号的发现。
6关联(系统)使用
wiki-mode.py route
获取路径 +
wiki-lock.sh
保障安全 + 索引/日志/热点缓存提升用户可见性。
7感知创建有长期价值的页面 — 6个月后仍有用,而非仅当下有用。跳过冗余内容,优先合成而非转录。
8接纳并非所有主张都值得纳入wiki,编辑判断是导入流程的一部分,而非需要消除的缺陷。
9创建生成包含完整前置元数据的来源+实体+概念页面;建立交叉引用;必要时添加冲突提示框。
10成长导入过程中发现的冲突是wiki最有价值的信号,将其记录为后续跟进的问题,而非静默忽略。