name: validate description: 笔记的架构验证。根据特定领域模板进行检查。验证必填字段、枚举值、描述质量和链接健康度。非阻塞式——仅警告但不阻止捕获。触发条件:“/validate”、“/validate [note]”、“check schema”、“validate note”、“validate all”。 user-invocable: true allowed-tools: Read, Grep, Glob context: fork model: sonnet
运行时配置(步骤0 — 在任何处理之前)
读取以下文件以配置特定领域行为:
-
ops/derivation-manifest.md— 词汇表映射,平台提示- 使用
vocabulary.notes作为笔记文件夹名称 - 使用
vocabulary.note/vocabulary.note_plural作为笔记类型引用 - 使用
vocabulary.topic_map作为MOC引用 - 使用
vocabulary.templates作为模板文件夹路径
- 使用
-
ops/config.yaml— 处理深度processing.depth: deep | standard | quick
如果这些文件不存在,则使用通用默认值。
处理深度适配:
| 深度 | 验证行为 |
|---|---|
| deep | 完整架构验证。启用所有检查,包括可组合性分析和交叉引用验证 |
| standard | 完整验证 — 启用所有检查 |
| quick | 仅基础架构验证 — 必填字段、YAML有效性、枚举值 |
立即执行
目标:$ARGUMENTS
立即解析:
- 如果目标包含笔记名称:验证该特定笔记
- 如果目标包含
--handoff:在末尾输出RALPH HANDOFF块 - 如果目标是 “all” 或 “notes”:验证 {DOMAIN:notes}/ 目录中的所有笔记
- 如果目标为空:询问要验证哪个笔记
执行以下步骤:
步骤1:定位模板
确定适用于目标笔记的模板:
- 检查笔记的位置 — {DOMAIN:notes}/ 中的笔记使用标准笔记模板
- 检查frontmatter中的
type字段 — 特殊类型可能有专用模板 - 查找模板目录(检查
ops/templates/或派生清单中的领域特定路径) - 如果模板有
_schema块,请读取它 — 这是权威的架构定义
如果未找到模板,则使用下面的默认架构检查。
步骤2:读取目标笔记
读取目标笔记的完整YAML frontmatter。解析:
- 所有YAML字段及其值
- 正文内容(用于链接扫描)
- 页脚部分(用于主题和相关笔记)
步骤3:运行架构检查
运行所有验证检查。每项检查产生PASS、WARN或FAIL。
现在开始。
架构检查
必填字段(如果缺失则FAIL)
| 检查项 | 规则 | 如何验证 |
|---|---|---|
description |
必须存在且非空 | 检查YAML frontmatter中的 description: 字段是否具有非空值 |
| 主题 | 必须链接到至少一个 {DOMAIN:topic map} | 检查YAML中的 topics: 或页脚中的 Topics: 部分。必须包含至少一个wiki链接 |
缺失必填字段是硬性失败。没有这些,笔记无法通过验证。
描述质量(如果弱则WARN)
| 检查项 | 规则 | 如何验证 |
|---|---|---|
| 长度 | 应为约50-200个字符 | 计算描述值中的字符数 |
| 新信息 | 必须添加超出标题的上下文 | 将描述文本与文件名/标题进行比较 — 如果语义上等效,则WARN |
| 无尾随句号 | 约定:描述不以句号结尾 | 检查最后一个字符 |
| 单一句子 | 应为一个连贯的陈述 | 检查描述中是否有句子结束标点符号 |
如何检查“添加新信息”: 读取标题(不带.md的文件名)。读取描述。如果描述仅用不同的词语重述标题,则此项检查失败。好的描述添加以下之一:
- 机制 — 主张如何或为何有效
- 范围 — 主张具有哪些边界
- 含义 — 从主张中得出什么
- 上下文 — 主张适用于何处
示例:
差(重述标题):
- 标题:
向量邻近度测量表面重叠而非深层连接 - 描述:“语义相似性捕获表面级别的重叠,而非真正的概念关系”
好(添加机制):
- 标题:
向量邻近度测量表面重叠而非深层连接 - 描述:“关于同一概念但使用不同词汇的两个笔记得分高,而跨领域的真正相关想法得分低”
YAML有效性(如果损坏则FAIL)
| 检查项 | 规则 | 如何验证 |
|---|---|---|
| Frontmatter分隔符 | 必须以第1行的 --- 开头并以 --- 关闭 |
读取第一行并扫描关闭分隔符 |
| 有效YAML | 必须无错误解析 | 检查常见YAML错误:值中未加引号的冒号、引号不匹配、缩进错误 |
| 无重复键 | 每个YAML键仅出现一次 | 扫描重复的字段名 |
| 无未知字段 | 不在模板架构中的字段 | 如果可用,与 _schema.required 和 _schema.optional 比较 — 未知字段获得WARN |
领域特定枚举检查(如果无效则WARN)
如果笔记具有枚举值字段,请根据模板的 _schema.enums 块检查它们:
| 字段 | 预期值 | 严重性 |
|---|---|---|
type |
模板枚举中的值(例如:claim, methodology, tension, problem, learning) | WARN |
status |
模板枚举中的值(例如:preliminary, open, dissolved) | WARN |
classification |
模板枚举中的值(例如:open, closed) | WARN |
| 自定义领域字段 | 模板枚举中的值 | WARN |
如果字段的值不在枚举列表中,则报告无效值并列出有效选项。
链接健康度(每个损坏的链接WARN)
| 检查项 | 规则 | 如何验证 |
|---|---|---|
| 正文wiki链接 | 每个 [[link]] 应指向现有文件 |
从正文中提取所有 [[...]] 模式,检查每个是否针对文件树 |
| 主题链接 | 主题中引用的 {DOMAIN:topic map} 必须存在 | 验证每个主题wiki链接是否可解析 |
| 相关笔记链接 | relevant_notes 中的每个笔记必须存在 |
验证relevant_notes中的每个wiki链接是否可解析 |
| 反引号排除 | 反引号内的wiki链接是示例,不是真实链接 | 跳过单引号或三引号块内的 [[...]] 模式 |
如何验证链接解析: 对于每个 [[link text]],检查是否存在名为 link text.md 的文件。Wiki链接通过文件名解析,而非路径。
相关笔记格式(如果不正确则WARN)
| 检查项 | 规则 | 严重性 |
|---|---|---|
| 格式 | 带上下文的数组:["[[note]] -- relationship"] |
WARN |
| 上下文短语存在 | 每个条目应包含 -- 或 — 后跟关系描述 |
WARN |
| 关系类型 | 标准类型:extends, foundation, contradicts, enables, example | INFO |
| 无裸链接 | ["[[note]]"] 没有上下文是裸链接 — 对导航无用 |
WARN |
可组合性(如果失败则WARN)
| 检查项 | 规则 | 如何验证 |
|---|---|---|
| 标题测试 | 你能完成“本笔记主张[标题]”吗? | 将标题作为句子片段读取 — 它是否构成一个主张? |
| 特异性 | 主张是否足够具体以至于可以反对? | 有人能合理地提出相反论点吗? |
| 散文适用性 | since [[title]] 在另一笔记中读起来自然吗? |
检查标题是否作为内联wiki链接有效 |
主题标签与主张:
- “知识管理” — 主题标签,不是主张,可组合性FAIL
- “知识管理需要策展而非积累” — 主张,可组合性PASS
批处理模式
当验证所有笔记时(目标为“all”或“notes”):
- 发现 {DOMAIN:notes}/ 目录中的所有 .md 文件
- 可选地包括其他目录(例如:self/memory/),如果它们存在
- 对每个笔记运行所有架构检查
- 生成摘要报告:
- 检查的笔记总数
- PASS / WARN / FAIL 计数
- 按检查类型分组的主要问题
- 需要立即关注的笔记(FAIL项)
- 模式分析:某些检查类型是否系统性地失败?
批处理输出格式:
## 验证摘要
已检查:N 个笔记
- PASS:M (X%)
- WARN:K (Y%)
- FAIL:J (Z%)
### FAIL项(需要立即关注)
| 笔记 | 检查项 | 详情 |
|------|-------|--------|
| [[note]] | description | 缺失 |
| [[note]] | topics | 无主题页脚 |
### 主要WARN模式
- 描述重述标题:N 个笔记
- relevant_notes中缺少上下文短语:N 个笔记
- 枚举值不在模板中:N 个笔记
### 需要关注的笔记
1. [[note]] — 2 FAIL, 1 WARN
2. [[note]] — 1 FAIL, 3 WARN
输出格式(单个笔记)
=== 验证:[[笔记标题]] ===
PASS:
- description:存在,147个字符,添加了超出标题的机制
- topics:["[[topic-name]]"] — 存在
- yaml:格式正确,有效分隔符
- 可组合性:标题作为散文有效(“本笔记主张[标题]”)
WARN:
- relevant_notes:[[note-x]] 的裸链接没有上下文短语
- type:"observation" 不在模板枚举中(有效值:claim, methodology, tension, problem, learning)
FAIL:
- (无)
总体:PASS(2个警告)
===
如果存在WARN或FAIL项,包括:
### 建议修复
- **relevant_notes**:添加上下文短语 — 例如:`["[[note-x]] -- 通过添加...扩展了这一点"]`
- **type**:更改为有效枚举值或提议将“observation”添加到模板
交接模式(–handoff 标志)
当使用 --handoff 调用时,在末尾输出此结构化格式:
=== RALPH 交接:validate ===
目标:[[笔记标题]]
已完成工作:
- 根据[模板名称]架构验证
- 运行的检查:N
- 状态:PASS | WARN | FAIL
发现:
- PASS:[列表]
- WARN:[列表或“无”]
- FAIL:[列表或“无”]
已修改文件:
- [任务文件路径](如果适用,更新了验证部分)
学习:
- [摩擦]:[描述] | 无
- [惊喜]:[描述] | 无
- [方法论]:[描述] | 无
- [流程缺口]:[描述] | 无
队列更新:
- 标记:此任务的验证已完成
=== 交接结束 ===
任务文件更新
当任务文件在上下文中(管道执行)时,更新 ## Validate 部分:
## Validate
**已验证:** [UTC时间戳]
根据[模板名称]的架构检查:
- description:PASS(147个字符,添加了超出标题的机制)
- topics:PASS(["[[topic-name]]"])
- yaml:PASS(格式正确)
- type:未指定(可选)
- relevant_notes:WARN([[note-x]]的裸链接)
- 可组合性:PASS
总体:PASS(1个警告)
严重性级别
| 级别 | 含义 | 操作 |
|---|---|---|
| PASS | 完全满足要求 | 无需操作 |
| WARN | 可选问题或轻微违规 | 考虑修复,不阻塞 |
| FAIL | 必填字段缺失或格式无效 | 在验证通过前必须修复 |
| INFO | 信息性观察 | 无需操作 |
FAIL阻塞管道完成。 具有任何FAIL级别问题的笔记不应在队列中标记为完成。它保持在 current_phase: "verify"(或如果独立运行则为“validate”)以在修复后重新验证。
WARN不阻塞。 警告是质量信号,不是关卡。笔记可以带着警告继续通过管道。
关键约束
绝不:
- 基于验证失败阻止笔记创建(验证是质量检查,不是关卡)
- 不先报告问题就自动修复
- 因为笔记“看起来没问题”而跳过检查
- 不实际运行检查就报告PASS
- 当模板中存在
_schema块时忽略它们
总是:
- 检查所有架构要求,而非子集
- 在FAIL/WARN消息中报告特定字段值(不仅仅是“描述弱”)
- 为每个WARN和FAIL建议具体修复
- 当可用时,使用模板
_schema作为权威来源 - 当不存在模板时,优雅地回退到默认检查
- 运行批处理验证时记录模式(重复出现的问题表明系统性问题)