New:Socket for Asana Is Now Available.Learn more
Get Started

@double-coding/flow2spec-core

Package Overview
Dependencies
Maintainers
2
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@double-coding/flow2spec-core - npm Package Compare versions

Comparing version
3.6.0
to
3.7.0
+74
-1
lib/knowledgeEngine.js

@@ -22,3 +22,26 @@ const fs = require("fs");

const MATCHER_ID_RE = /^m-[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
// topic summary 作为初筛召回字段的质量约束:含 CJK 按字符数上限 40,纯英文按词数上限 20。
const SUMMARY_CJK_RE = /[\u3400-\u9fff\uf900-\ufaff]/;
const SUMMARY_MAX_CJK_CHARS = 40;
const SUMMARY_MAX_WORDS = 20;
const SUMMARY_PLACEHOLDER_RE = /^(todo|tbd|待补充|占位)/i;
function isPlaceholderSummary(summary, topicId) {
const value = String(summary || "").trim();
if (!value) return false;
if (value === topicId) return true;
if (value.includes("路由摘要")) return true;
if (/routing summary/i.test(value)) return true;
return SUMMARY_PLACEHOLDER_RE.test(value);
}
function isSummaryTooLong(summary) {
const value = String(summary || "").trim();
if (!value) return false;
if (SUMMARY_CJK_RE.test(value)) {
return Array.from(value).length > SUMMARY_MAX_CJK_CHARS;
}
return value.split(/\s+/).filter(Boolean).length > SUMMARY_MAX_WORDS;
}
function ensureDir(dir) {

@@ -337,5 +360,11 @@ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });

const topicDependencies = {};
const topicSummaries = {};
for (const topic of graph.topics) {
if (!topic.exists) continue;
const fm = topic.frontmatter || {};
const summary =
typeof fm.summary === "string" ? fm.summary.trim() : "";
if (summary) {
topicSummaries[topic.topicId] = summary;
}
const entry = {};

@@ -369,3 +398,3 @@ if (Object.prototype.hasOwnProperty.call(fm, "primary")) {

}
return { topicMetadata, topicDependencies };
return { topicMetadata, topicDependencies, topicSummaries };
}

@@ -415,2 +444,19 @@

}
// taskToTopicRules[].summary:初筛召回字段,唯一手写源为 topic frontmatter summary,
// 此处机械同步(多 topic 规则按“;”拼接);topic 无 summary 时保留规则既有值不清空。
if (Array.isArray(next.taskToTopicRules)) {
next.taskToTopicRules = next.taskToTopicRules.map((rule) => {
if (!rule || typeof rule !== "object" || !Array.isArray(rule.topics)) {
return rule;
}
const parts = rule.topics
.map((topicId) => overlay.topicSummaries[topicId])
.filter(Boolean);
if (parts.length === 0) return rule;
const summary = parts.join(";");
if (rule.summary === summary) return rule;
changed = true;
return { ...rule, summary };
});
}
return { routing: next, changed };

@@ -481,2 +527,21 @@ }

}
// summary 质量:仅 warning(不阻断旧项目);--strict 时才影响 check 结果。
const summaryValue =
typeof fm.summary === "string" ? fm.summary.trim() : "";
if (!summaryValue) {
warnings.push(
`topic summary missing (初筛召回依赖此字段,建议补写): ${topic.topicId}`,
);
} else {
if (isPlaceholderSummary(summaryValue, topic.topicId)) {
warnings.push(
`topic summary placeholder (需改写为含核心名词的一句话): ${topic.topicId} -> ${summaryValue}`,
);
}
if (isSummaryTooLong(summaryValue)) {
warnings.push(
`topic summary too long (上限 ${SUMMARY_MAX_CJK_CHARS} 字 / ${SUMMARY_MAX_WORDS} 词): ${topic.topicId}`,
);
}
}
}

@@ -566,2 +631,10 @@

}
if (
Object.prototype.hasOwnProperty.call(rule, "summary") &&
typeof rule.summary !== "string"
) {
issues.push(
`taskToTopicRules(${rule.task || "unknown"}) summary must be a string`,
);
}
if (!Array.isArray(rule.topics) || rule.topics.length === 0) {

@@ -568,0 +641,0 @@ issues.push(`taskToTopicRules(${rule.task || "unknown"}) must contain topics`);

+2
-2
{
"name": "@double-coding/flow2spec-core",
"version": "3.6.0",
"templateVersion": "3.5.0",
"version": "3.7.0",
"templateVersion": "3.6.0",
"description": "Flow2Spec Core APIs, knowledge engine, project initialization and shared resources",

@@ -6,0 +6,0 @@ "homepage": "https://github.com/double-coding-lab/Flow2Spec#readme",

{
"version": "3.5.0",
"projectRev": 2,
"version": "3.6.0",
"projectRev": 3,
"knowledgeRoot": ".Knowledge",

@@ -47,3 +47,5 @@ "matcherKey": "matcherId",

"confidence": "inferred",
"tags": ["module"]
"tags": [
"module"
]
}

@@ -67,3 +69,4 @@ },

"config-precheck"
]
],
"summary": "Read flow2spec.config.json switches before running any f2s skill"
},

@@ -77,3 +80,4 @@ {

"implement-tech-design"
]
],
"summary": "Directory split between stock-docs and req-docs: where requirements, designs, and distilled docs live;Workflow and gates for implementing code from tech designs and requirement docs"
},

@@ -86,3 +90,4 @@ {

"f2s-doc-routing"
]
],
"summary": "Directory split between stock-docs and req-docs: where requirements, designs, and distilled docs live"
},

@@ -95,3 +100,4 @@ {

"f2s-task"
]
],
"summary": "Rules for creating, resuming, and archiving .task checklists"
},

@@ -104,3 +110,4 @@ {

"f2s-req-plan"
]
],
"summary": "Task planning breakdown and parallel implementation for requirements and changes"
},

@@ -113,5 +120,6 @@ {

"flow2spec-dsh-adapter"
]
],
"summary": "DeepSeek Harness project skill initialization and directory adapter"
}
]
}
---
id: config-precheck
revision: 0
summary: "config-precheck (routing summary)"
summary: "Read flow2spec.config.json switches before running any f2s skill"
primary: config

@@ -6,0 +6,0 @@ confidence: manual

---
id: fallback-triage
revision: 0
summary: fallback-triage
summary: "Fallback triage and recall recovery when task routing misses"
primary: policy

@@ -6,0 +6,0 @@ confidence: manual

---
id: implement-tech-design
revision: 0
summary: "implement-tech-design (routing summary)"
summary: "Workflow and gates for implementing code from tech designs and requirement docs"
dependsOn: [f2s-doc-routing]

@@ -6,0 +6,0 @@ primary: policy

---
id: f2s-req-plan
revision: 0
summary: "f2s-req-plan (routing summary)"
summary: "Task planning breakdown and parallel implementation for requirements and changes"
dependsOn: [f2s-task]

@@ -6,0 +6,0 @@ primary: policy

---
id: f2s-doc-routing
revision: 0
summary: "f2s-doc-routing (routing summary)"
summary: "Directory split between stock-docs and req-docs: where requirements, designs, and distilled docs live"
primary: policy

@@ -6,0 +6,0 @@ confidence: manual

---
id: f2s-task
revision: 0
summary: "f2s-task (routing summary)"
summary: "Rules for creating, resuming, and archiving .task checklists"
primary: policy

@@ -6,0 +6,0 @@ confidence: manual

@@ -32,3 +32,3 @@ ---

1. First read `.Knowledge/manifest-routing.json`, prefer routing by `taskToTopicRules`; as needed, read the matcher shard from `matcherPath` to obtain `includeAny` keywords. If nothing matches, enter fallback recall.
1. First read `.Knowledge/manifest-routing.json`, prefer routing by `taskToTopicRules`; first-pass evidence is each rule's `task` name and `summary` (one-line intent digest); as needed, read the matcher shard from `matcherPath` to obtain `includeAny` keywords. If nothing matches, enter fallback recall.
- If the matched topic has dependencies in `topicDependencies`, read dependency topics first, then the main topic.

@@ -41,5 +41,5 @@ - Routing manifests are maintained only by `f2s-*` skill flows and do not depend on extra CLI subcommands.

6. After a match, always run `match -> expand -> verify -> act`:
- `match`: take the primary candidate first;
- `match`: pick the primary candidate by semantic matching against each rule's `task` name and `summary`; both `summary` and `includeAny` are semantic anchors, not literal allowlists—near-synonym hits are allowed;
- `expand`: expand `topicDependencies` and keep the next-highest candidate for supplementary verification;
- `verify`: check gaps before acting (missing key topics, boundaries, or context);
- `verify`: check gaps before acting (missing key topics, boundaries, or context); **if the matched topic body does not cover the core nouns of the user's question, you must also read the next-highest candidate's `summary` and matcher shard before deciding—do not answer directly**;
- `act`: act only when confidence is sufficient; clarify first when confidence is low.

@@ -60,2 +60,3 @@ 7. A full cross-matcher supplemental search (top-k) is allowed only when one of these conditions is true:

- `taskToTopicRules`: first-priority task routing.
- `taskToTopicRules[].summary`: first-pass recall field (one-line intent digest), mechanically synced by `flow2spec kb build` from the topic frontmatter `summary`; never handwritten on the manifest side; participates in `match` as a semantic anchor.
- `taskToTopicRules[].matcherPath`: direct path to the matcher-word shard; read a single matcher file as needed.

@@ -62,0 +63,0 @@ - `taskToTopicRules[].matcherId`: stable matcher identifier; must match `id` inside the matcher shard.

@@ -112,2 +112,8 @@ ---

## Routing-Miss Backfill (Mandatory)
- **Judgment**: the core facts of this turn's answer were provided by some topic, but that topic was **not the first-pass primary match** (it was found only via a full supplemental search, by co-reading the next-highest candidate, or because the user named it) → count this as a routing miss.
- **Action**: in addition to the four-case closing, backfill the user's original phrasing into that topic's recall anchors — per the "first-pass recall" rules in `f2s-topic-authoring`, add the core nouns to the frontmatter `summary` or single-concept terms to the matcher `includeAny`, then run `flow2spec kb build` to sync `rule.summary`. This is a minimal fix written directly to disk; it does not depend on the user running distill.
- Even when the closing uses case 4 (KB already covers it), if the hit path was a post-miss rescue, this backfill must still run, and append one line after the closing block: `Routing backfilled: <topicId> summary/includeAny added "<term>"`.
## Output Format

@@ -114,0 +120,0 @@

@@ -42,2 +42,11 @@ ---

### Authoring rules for frontmatter `summary` and `includeAny` (first-pass recall, hard constraint)
The topic frontmatter `summary` is synced by `flow2spec kb build` into `manifest-routing.taskToTopicRules[].summary`—the always-resident semantic anchor for the Agent's first-pass routing. Its quality directly decides whether the topic can be hit by natural phrasing:
- **`summary`**: one sentence stating "responsibility + the core nouns users will actually ask with", covering all of the topic's responsibility domains (e.g. if it carries both "scope boundary" and "asset locations", both must appear); soft limit 15 words (30 CJK chars), hard limit 20 words / 40 chars (validated by `kb check`); placeholder styles like `<topicId> (routing summary)` or `TODO` are prohibited.
- **`includeAny`**: prefer single-concept core words (the smallest words that appear standalone in natural questions, e.g. "prototype", "flowchart" rather than "prototype location", "business flowchart"); compound words are supplements only; when distilling from user dictation, add 1–2 "future natural phrasing" words instead of copying the dictation verbatim.
- **Self-test (mandatory before writing to disk)**: simulate 2–3 natural user questions (imagine how users would ask, without looking at the word list) and check each hits at least one of `summary` or `includeAny`; revise on miss.
- **`taskToTopicRules[].task`**: keep stable id semantics (the kb engine merges by `task`); do not stuff long phrases into it—recall semantics live in `summary`, and the manifest side is generated by `kb build`, never handwritten.
## 3. topicMetadata Decision Criteria

@@ -44,0 +53,0 @@

@@ -86,3 +86,3 @@ ---

- Add `taskToTopicRules[]` only when this rule should be matched as **user task routing** (see `f2s-topic-authoring` section 5 criteria); internal rules that are only referenced by other rules / SKILLs **do not enter** `taskToTopicRules`.
- If `taskToTopicRules[]` is added, create `.Knowledge/matchers/<matcherId>.json`, extracting `includeAny` keywords from the user's wording (the original words + 1-2 obvious synonyms; prefer missing terms over over-broad terms).
- If `taskToTopicRules[]` is added, create `.Knowledge/matchers/<matcherId>.json`, extracting `includeAny` per the "first-pass recall" rules in `f2s-topic-authoring`: **single-concept core terms first**, compound terms only as supplements; besides the user's original wording, add 1-2 terms matching "how the user would naturally ask later", and self-test with 2-3 simulated questions; write the topic frontmatter `summary` per the same rules (kb build syncs it into `rule.summary` as the first-pass anchor).
- **Merge into existing topic**:

@@ -89,0 +89,0 @@ - `topicPaths` does not change.

@@ -50,5 +50,6 @@ ---

- Topic name and topic intent (can form a topic id)
- Frontmatter `summary` (first-pass recall anchor: responsibility + core nouns the user would ask about, written per the "first-pass recall" rules in `f2s-topic-authoring`; kb build syncs it into manifest `rule.summary`)
- Core concepts and key flows
- Business rules and boundary conditions
- Task trigger terms (write to the corresponding `matchers/<matcherId>.json` `includeAny`)
- Task trigger terms (write to the corresponding `matchers/<matcherId>.json` `includeAny`; single-concept core terms first, compound terms only as supplements)
- Dependencies on existing topics (for `topicDependencies`)

@@ -55,0 +56,0 @@

@@ -281,4 +281,5 @@ ---

- Terms extracted from answer
- Suggested `includeAny`: 5-10 trigger words
- Suggested `includeAny`: 5-10 trigger words (single-concept core terms first, compound terms only as supplements; see the "first-pass recall" rules in `f2s-topic-authoring`)
- Add routing rule in `taskToTopicRules`
- Write topic frontmatter `summary` per the "first-pass recall" rules (responsibility + core nouns the user would ask about; kb build syncs it into `rule.summary`)

@@ -288,2 +289,3 @@ - If updating existing topic:

- Extract uncovered keywords from user question, append to `includeAny`
- If this turn's phrasing is not covered by the topic's `summary`, revise the frontmatter `summary` to add the core nouns

@@ -371,3 +373,3 @@ #### 5.2 Update index.md

- Avoid over-splitting: unless drill-down depth ≥ deep and knowledge description depth ≥ detailed level, prioritize appending to existing topic
- Generated matcher includeAny should cover expressions users actually use, not just technical terms
- Generated matcher includeAny should cover expressions users actually use, not just technical terms; the topic frontmatter `summary` should likewise cover the core nouns of this turn's phrasing

@@ -374,0 +376,0 @@ ## Self-Check After Completion

@@ -90,3 +90,3 @@ ---

- `.Knowledge/index.md` (sync the "Associated documents (summary)" column in the topic routing table)
- Routing manifest (as needed). When creating a new topic, also sync `topicPaths` and necessary `taskToTopicRules` / matcher shards. Write `topicMetadata` only when evidence is clear; classification is only for governance, audit, and reading expectations, does not participate in route matching or execution requirements, and must not be used to create, rename, or split topics.
- Routing manifest (as needed). When creating a new topic, also sync `topicPaths` and necessary `taskToTopicRules` / matcher shards; write the frontmatter `summary` and matcher `includeAny` of new/updated topics per the "first-pass recall" rules in `f2s-topic-authoring` (`summary` is synced into `rule.summary` by kb build). Write `topicMetadata` only when evidence is clear; classification is only for governance, audit, and reading expectations, does not participate in route matching or execution requirements, and must not be used to create, rename, or split topics.
- `.Knowledge/stock-docs/*.md` (add source documents as needed)

@@ -93,0 +93,0 @@

@@ -232,3 +232,4 @@ ---

- The topic is frequently matched by multiple unrelated task types (can be judged from `taskToTopicRules` and matcher term breadth).
7. **Automatic old-topic frontmatter repair**: in the full flow, the agent must run `flow2spec kb build --fix-topics` (or the equivalent internal capability) to add `id`, `revision`, and `summary` to existing topics that lack frontmatter / `revision`, and to fill `dependsOn` / `primary` / `confidence` / `tags` from `manifest-routing.json`. Then run `flow2spec kb check --strict`; if strict validation fails, stop and list the concrete topic / reason in the summary. Do not ask the user to manually add topic headers one by one.
7. **Automatic old-topic frontmatter repair**: in the full flow, the agent must run `flow2spec kb build --fix-topics` (or the equivalent internal capability) to add `id`, `revision`, and `summary` to existing topics that lack frontmatter / `revision`, and to fill `dependsOn` / `primary` / `confidence` / `tags` from `manifest-routing.json`. Then run `flow2spec kb check --strict`; if the failing items are **summary quality warnings** (missing / placeholder / too long), go to item 8 to rewrite them; for any other failure, stop and list the concrete topic / reason in the summary. Do not ask the user to manually add topic headers one by one.
8. **Summary first-pass anchor rewrite (required; only the agent can write semantic summaries)**: for each summary quality warning reported by `kb check --strict`, Read the corresponding `.Knowledge/topics/<id>.md` body one by one and write the frontmatter `summary` per the "first-pass recall" rules in `f2s-topic-authoring` (responsibility + core nouns the user would ask about; soft limit 15 words / hard limit 20 words). After all are written, run `flow2spec kb build` to sync them into `rule.summary`, then rerun `flow2spec kb check --strict` until no summary warnings remain. Do not pass with placeholder text (`<topicId> (routing summary)` / TODO).

@@ -321,2 +322,3 @@ ### Step 3b: `index.md` Merge and `template/index.template.md` (Required)

- **topic frontmatter**: `auto-filled N topics` / `already complete` / `strict validation failed` / `not executed on fast path`
- **summary first-pass anchor**: `rewrote N summaries (synced into rule.summary via kb build)` / `already compliant` / `not executed on fast path`
- **f2s-kb-upgrade SKILL**: `unchanged after init` / `reran N rounds from step 2c per new SKILL (no second init)` / `loop skipped on fast path` / `pending confirmation`

@@ -350,3 +352,3 @@ - **`projectRev` write-back**: `written to project manifest (value=pkgRev)` / `not executed on fast path` / `pkgRev=null, field untouched`

8. **On full flow**: **Step 3a** was executed: `topicMetadata` audited, with no orphan keys / illegal primary / illegal confidence; missing old topics were filled with `inferred` based on evidence or listed as pending confirmation.
9. **On full flow**: `flow2spec kb build --fix-topics` or an equivalent internal capability was executed, followed by `flow2spec kb check --strict`, ensuring existing topics have `revision`.
9. **On full flow**: `flow2spec kb build --fix-topics` or an equivalent internal capability was executed, followed by `flow2spec kb check --strict`, ensuring existing topics have `revision`; summary quality warnings were rewritten to zero per step 3a.8 and synced into `rule.summary` via `kb build`.
10. **On full flow**: **Step 3b** was executed: `index.md` was **merged** (from **`Topic Overview`** section through before "Match and Execute" is project-maintained; the rest matches the package version), and `topicPaths` were checked; **at the end of full flow**, the project-side `projectRev` was **written back** to `pkgRev` (if `pkgRev=null`, the field was left unchanged).

@@ -353,0 +355,0 @@ 11. **On fast path**: steps 3 / 3a / 3b were actually skipped (no unrelated scans), and the summary explicitly labels "not executed on fast path".

{
"version": "3.5.0",
"projectRev": 2,
"version": "3.6.0",
"projectRev": 3,
"knowledgeRoot": ".Knowledge",

@@ -47,3 +47,5 @@ "matcherKey": "matcherId",

"confidence": "inferred",
"tags": ["module"]
"tags": [
"module"
]
}

@@ -67,3 +69,4 @@ },

"config-precheck"
]
],
"summary": "f2s 技能执行前必读 flow2spec.config.json 的开关口径"
},

@@ -77,3 +80,4 @@ {

"implement-tech-design"
]
],
"summary": "stock-docs 与 req-docs 目录分工:需求、方案、沉淀文档放哪;按技术方案/需求文档实现代码的流程与门禁"
},

@@ -86,3 +90,4 @@ {

"f2s-doc-routing"
]
],
"summary": "stock-docs 与 req-docs 目录分工:需求、方案、沉淀文档放哪"
},

@@ -95,3 +100,4 @@ {

"f2s-task"
]
],
"summary": "任务清单 .task 目录的创建、续作与归档规则"
},

@@ -104,3 +110,4 @@ {

"f2s-req-plan"
]
],
"summary": "需求/变更的任务规划拆解与并行实现流程"
},

@@ -113,5 +120,6 @@ {

"flow2spec-dsh-adapter"
]
],
"summary": "DeepSeek Harness 项目级技能初始化与目录适配"
}
]
}
---
id: config-precheck
revision: 0
summary: "config-precheck(路由摘要)"
summary: "f2s 技能执行前必读 flow2spec.config.json 的开关口径"
primary: config

@@ -6,0 +6,0 @@ confidence: manual

---
id: fallback-triage
revision: 0
summary: fallback-triage
summary: "路由未命中时的兜底分诊与补召回流程"
primary: policy

@@ -6,0 +6,0 @@ confidence: manual

---
id: implement-tech-design
revision: 0
summary: "implement-tech-design(路由摘要)"
summary: "按技术方案/需求文档实现代码的流程与门禁"
dependsOn: [f2s-doc-routing]

@@ -6,0 +6,0 @@ primary: policy

---
id: f2s-req-plan
revision: 0
summary: "f2s-req-plan(路由摘要)"
summary: "需求/变更的任务规划拆解与并行实现流程"
dependsOn: [f2s-task]

@@ -6,0 +6,0 @@ primary: policy

---
id: f2s-doc-routing
revision: 0
summary: "f2s-doc-routing(路由摘要)"
summary: "stock-docs 与 req-docs 目录分工:需求、方案、沉淀文档放哪"
primary: policy

@@ -6,0 +6,0 @@ confidence: manual

---
id: f2s-task
revision: 0
summary: "f2s-task(路由摘要)"
summary: "任务清单 .task 目录的创建、续作与归档规则"
primary: policy

@@ -6,0 +6,0 @@ confidence: manual

@@ -32,3 +32,3 @@ ---

1. 先读 `.Knowledge/manifest-routing.json`,优先按 `taskToTopicRules` 路由;按需根据 `matcherPath` 读取 matcher 分片获取 `includeAny` 关键词;无法命中时进入补召回阶段。
1. 先读 `.Knowledge/manifest-routing.json`,优先按 `taskToTopicRules` 路由;初筛证据为每条规则的 `task` 名与 `summary`(一句话意图摘要);按需根据 `matcherPath` 读取 matcher 分片获取 `includeAny` 关键词;无法命中时进入补召回阶段。
- 若命中主题在 `topicDependencies` 中存在依赖,先读依赖主题,再读主主题。

@@ -41,5 +41,5 @@ - 路由清单仅通过 `f2s-*` 技能流程维护,不依赖额外 CLI 子命令。

6. 命中后必须执行 `match -> expand -> verify -> act`:
- `match`:先取主候选;
- `match`:以规则的 `task` 名与 `summary` 做语义匹配取主候选;`summary` 与 `includeAny` 均为语义锚而非字面白名单,允许近义命中;
- `expand`:展开 `topicDependencies`,并保留次高候选做补充校验;
- `verify`:执行前做缺口检查(关键主题/边界/上下文是否缺失);
- `verify`:执行前做缺口检查(关键主题/边界/上下文是否缺失);**若命中主题正文未覆盖用户问句的核心名词,必须并读次高候选的 `summary` 与 matcher 分片再定,不得直接作答**;
- `act`:仅在置信度足够时执行;低置信度必须先澄清。

@@ -60,2 +60,3 @@ 7. 仅在以下条件之一成立时,允许执行跨 matcher 全量补检索(top-k):

- `taskToTopicRules`:任务路由第一优先级。
- `taskToTopicRules[].summary`:初筛召回字段(一句话意图摘要),由 `flow2spec kb build` 从 topic frontmatter `summary` 机械同步,不手写 manifest 侧;作语义锚参与 match 初筛。
- `taskToTopicRules[].matcherPath`:匹配词分片直链路径,按需读取单个 matcher 文件。

@@ -62,0 +63,0 @@ - `taskToTopicRules[].matcherId`:matcher 的稳定标识,需与 matcher 分片内 `id` 一致。

@@ -110,2 +110,8 @@ ---

## 路由 miss 反哺(强制)
- **判定**:本轮答案的核心事实由某 topic 提供,但该 topic **不是初筛主命中**(靠全量补检索、次高候选并读或用户点名才找到)→ 计为一次路由 miss。
- **动作**:在四 case 收口之外,把本轮用户的原始问法回填该 topic 的召回锚——按 `f2s-topic-authoring`「初筛召回规范」补 frontmatter `summary` 的核心名词或 matcher `includeAny` 的单概念词,并跑 `flow2spec kb build` 同步 rule.summary。此项是直接落盘的最小修复,不依赖用户再跑 distill。
- 即使收口走 case 4(知识库已覆盖),只要命中路径是 miss 后补救,仍须执行本反哺,并在收口块后追加一行:`已回填路由:<topicId> 的 summary/includeAny 补「<词>」`。
## 输出格式

@@ -112,0 +118,0 @@

@@ -41,2 +41,11 @@ ---

### frontmatter `summary` 与 `includeAny` 创作规范(初筛召回,硬约束)
topic frontmatter 的 `summary` 会被 `flow2spec kb build` 同步进 `manifest-routing.taskToTopicRules[].summary`,是 Agent 初筛的常驻语义锚——写作质量直接决定该 topic 能否被自然问法命中:
- **`summary`**:一句话写清「职责 + 用户会问的核心名词」,覆盖 topic 的全部职责域(如同时承担“职责边界”与“资料入口”,两者都要出现);软上限 30 字(英文 15 词),硬上限 40 字 / 20 词(`kb check` 校验);禁止 `<topicId>(路由摘要)`、`TODO` 等占位写法。
- **`includeAny`**:单概念核心词优先(自然问法中会独立出现的最小词,如「原型」「流程图」而非「原型位置」「业务流程图」);复合词仅作补充;从用户口述沉淀时须补 1–2 个“日后自然问法”词,不只抄口述原文。
- **自测(落盘前必做)**:模拟 2–3 个用户自然问句(凭空想“用户会怎么问”,不看词表),检查每句至少命中 `summary` 或 `includeAny` 之一;不命中则回改。
- **`taskToTopicRules[].task`**:保持稳定 id 语义(kb 引擎按 `task` 合并),不塞长短语;召回语义由 `summary` 承载,manifest 侧由 `kb build` 生成,不手写。
## 3. topicMetadata 判定准则

@@ -43,0 +52,0 @@

@@ -86,3 +86,3 @@ ---

- 视情况补 `taskToTopicRules[]`——**仅当**该规则会作为**用户任务路由命中**(参见 `f2s-topic-authoring` 第 5 节判据)才补;纯被其它规则 / SKILL 引用的内部规则**不进** `taskToTopicRules`;
- 若补了 `taskToTopicRules[]`,须新建 `.Knowledge/matchers/<matcherId>.json`,从用户口述中抽取 `includeAny` 关键词(用户原话 + 1–2 个明显近义说法,宁缺勿滥);
- 若补了 `taskToTopicRules[]`,须新建 `.Knowledge/matchers/<matcherId>.json`,`includeAny` 按 `f2s-topic-authoring`「初筛召回规范」抽取:**单概念核心词优先**,复合词仅作补充;除用户口述原词外须补 1–2 个“日后自然问法”词,并用 2–3 个模拟问句自测命中;topic frontmatter `summary` 同步按该规范写(kb build 会将其同步进 rule.summary 作初筛锚);
- **并入存量主题**:

@@ -89,0 +89,0 @@ - `topicPaths` 不变;

@@ -50,5 +50,6 @@ ---

- 主题名与主题意图(可形成 topic id)
- frontmatter `summary`(初筛召回锚:职责 + 用户会问的核心名词,按 `f2s-topic-authoring`「初筛召回规范」写;kb build 会同步进 manifest rule.summary)
- 核心概念与关键流程
- 业务规则与边界条件
- 任务触发词(写入对应 `matchers/<matcherId>.json` 的 `includeAny`)
- 任务触发词(写入对应 `matchers/<matcherId>.json` 的 `includeAny`;单概念核心词优先,复合词仅作补充)
- 与现有主题的依赖关系(用于 `topicDependencies`)

@@ -55,0 +56,0 @@

@@ -288,4 +288,5 @@ ---

- 从回答中提取的术语
- 建议 `includeAny`:5-10 个触发词
- 建议 `includeAny`:5-10 个触发词(单概念核心词优先,复合词仅作补充;见 `f2s-topic-authoring`「初筛召回规范」)
- 在 `taskToTopicRules` 中添加路由规则
- topic frontmatter `summary` 按「初筛召回规范」写(职责 + 用户会问的核心名词;kb build 会同步进 rule.summary)

@@ -295,2 +296,3 @@ - 如果更新既有 topic:

- 从用户问题中提取未覆盖的关键词,追加到 `includeAny`
- 若本轮问法未被该 topic 的 `summary` 覆盖,回改 frontmatter `summary` 补上核心名词

@@ -378,3 +380,3 @@ #### 5.2 更新 index.md

- 避免过度拆分:除非下钻深度 ≥ 深且知识描述深度 ≥ 详细级,否则优先补充既有 topic
- 生成的 matcher includeAny 应覆盖用户实际会用的表述,不只是技术术语
- 生成的 matcher includeAny 应覆盖用户实际会用的表述,不只是技术术语;topic frontmatter `summary` 同步覆盖本轮问法的核心名词

@@ -381,0 +383,0 @@ ## 完成后自检

@@ -90,3 +90,3 @@ ---

- `.Knowledge/index.md`(同步主题路由表的“关联文档(摘要)”列)
- 路由清单(按需);若创建新 topic,须同步 `topicPaths`、必要的 `taskToTopicRules` / matcher 分片;可在证据明确时写 `topicMetadata`,但分类只用于治理、审计和阅读预期,不参与路由命中或执行强制性,不得为了分类创建、重命名或拆分 topic
- 路由清单(按需);若创建新 topic,须同步 `topicPaths`、必要的 `taskToTopicRules` / matcher 分片;新建 / 更新 topic 的 frontmatter `summary` 与 matcher `includeAny` 按 `f2s-topic-authoring`「初筛召回规范」写(summary 由 kb build 同步进 rule.summary);可在证据明确时写 `topicMetadata`,但分类只用于治理、审计和阅读预期,不参与路由命中或执行强制性,不得为了分类创建、重命名或拆分 topic
- `.Knowledge/stock-docs/*.md`(按需补充索源文档)

@@ -93,0 +93,0 @@

@@ -232,3 +232,4 @@ ---

- 该 topic 同时被多种不相干任务类型频繁命中(可从 `taskToTopicRules` 和 matcher 词宽度判断)。
7. **旧 topic frontmatter 自动补齐**:完整流程中必须由 agent 自行执行 `flow2spec kb build --fix-topics`(或等价内部能力),为缺少 frontmatter / `revision` 的存量 topic 补 `id`、`revision`、`summary`,并按 `manifest-routing.json` 补 `dependsOn` / `primary` / `confidence` / `tags`。随后执行 `flow2spec kb check --strict`;若 strict 失败,停止并在摘要中列出具体 topic / reason。不得要求用户手动逐个 topic 添加头部。
7. **旧 topic frontmatter 自动补齐**:完整流程中必须由 agent 自行执行 `flow2spec kb build --fix-topics`(或等价内部能力),为缺少 frontmatter / `revision` 的存量 topic 补 `id`、`revision`、`summary`,并按 `manifest-routing.json` 补 `dependsOn` / `primary` / `confidence` / `tags`。随后执行 `flow2spec kb check --strict`;若失败项为 **summary 质量 warning**(缺失 / 占位 / 超长),转第 8 条补写;其余失败停止并在摘要中列出具体 topic / reason。不得要求用户手动逐个 topic 添加头部。
8. **summary 初筛锚补写(必须,agent 才能写出语义摘要)**:对 `kb check --strict` 报出的每个 summary 质量 warning,逐个 Read 对应 `.Knowledge/topics/<id>.md` 正文,按 `f2s-topic-authoring`「初筛召回规范」补写 frontmatter `summary`(职责 + 用户会问的核心名词,软 30 字 / 硬 40 字);全部补完后执行 `flow2spec kb build` 同步进 `rule.summary`,再跑 `flow2spec kb check --strict` 直至无 summary warning。禁止用占位文案(`<topicId>(路由摘要)` / TODO)敷衍通过。

@@ -321,2 +322,3 @@ ### 步骤 3b:`index.md` 融合与 `template/index.template.md`(必须执行)

- **topic frontmatter**:`已自动补齐 N 个` / `已完整无需补齐` / `strict 校验失败` / `快速路径下未执行`
- **summary 初筛锚**:`已补写 N 个(已 kb build 同步 rule.summary)` / `已合规无需补写` / `快速路径下未执行`
- **f2s-kb-upgrade SKILL**:`init 后无变化` / `已按新版从 2c 起重跑 N 轮(不再次 init)` / `快速路径下跳过该闭环` / `待确认`

@@ -350,3 +352,3 @@ - **`projectRev` 回写**:`已写入项目 manifest(值=pkgRev)` / `快速路径下未执行` / `pkgRev=null 未动`

8. **完整流程时**:是否已执行 **步骤 3a**:审计 `topicMetadata`,确保无孤儿 key / 非法 primary / 非法 confidence;缺失旧主题已按证据补 `inferred` 或列为待确认。
9. **完整流程时**:是否已执行 `flow2spec kb build --fix-topics` 或等价内部能力,并随后执行 `flow2spec kb check --strict`,确保存量 topic 已具备 `revision`。
9. **完整流程时**:是否已执行 `flow2spec kb build --fix-topics` 或等价内部能力,并随后执行 `flow2spec kb check --strict`,确保存量 topic 已具备 `revision`;summary 质量 warning 是否已按步骤 3a.8 补写清零并 `kb build` 同步 `rule.summary`。
10. **完整流程时**:是否已执行 **步骤 3b**:**融合** `index.md`(**主题一览**节起至命中与执行前为项目维护区,其余同包版),并核对 `topicPaths`;**完整流程末尾**是否已**回写** 项目侧 `projectRev = pkgRev`(`pkgRev=null` 则保留原值)。

@@ -353,0 +355,0 @@ 11. **快速路径时**:步骤 3 / 3a / 3b 是否真的跳过(未做无关扫描),摘要中明确标注「快速路径下未执行」。