@double-coding/flow2spec-core
Advanced tools
@@ -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 是否真的跳过(未做无关扫描),摘要中明确标注「快速路径下未执行」。 |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
863113
1.77%6165
1.43%