mirror of
https://github.com/jacobinwwey/obsidian-NotEMD.git
synced 2026-07-22 05:48:27 +00:00
feat(stage-c): land local-kb offline evaluation fixture
This commit is contained in:
parent
d199238cea
commit
318130bc78
9 changed files with 261 additions and 10 deletions
|
|
@ -173,6 +173,7 @@ This is mandatory. Do not publish a release that omits `README.md`.
|
|||
- Treat `.trellis/` as local workflow state, not as a repo-deliverable source of truth.
|
||||
- Never delete, overwrite, or bulk-replace `.trellis/` during sync, merge, cleanup, release prep, or branch recovery work.
|
||||
- If a mainline sync step could touch `.trellis/`, preserve the existing local copy first and keep the repo clean by ignoring it rather than removing it.
|
||||
- Do not make committed tests, verification scripts, or release gates depend on `.trellis/` contents; if a workflow insight needs to affect CI or shipped documentation, mirror that truth into tracked files under the repository proper.
|
||||
|
||||
## Repository Notes
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ This matrix is grounded in:
|
|||
| A. Packaging / semantic verification | Live build/audit truth is still single-entry `main.js` + inline `srcdoc`; source still contains render-host runtime candidate modules, but current execution and audit truth now explicitly keep them non-shipped by rejecting stray `render-host.mjs` assets/references | Later backup branch had a wider dedicated runtime-asset lane | Keep the current source-only decision explicit until a future batch ships a real multi-entry contract with build + release + audit + docs all updated together | Do not keep saying `render-host.mjs` is currently shipped on main just because candidate runtime code exists in `src/` | P0 |
|
||||
| B. CLI / automation surface | Current main now has registry-backed config/profile export/import, redacted provider export, public-surface export, registry-backed typed `content.split-note-by-chapters`, and repo-local maintainer help/invoke scripts for bounded path-based operations plus exports | Backup branch also carried broader maintainer-bridge aspirations, but the current reintegration keeps the surface intentionally narrow | Keep maintainer helper scope explicit and only promote path-based operations to broader/public CLI status with same-batch contract/test/doc proof | Do not describe the current surface as a general-purpose public CLI or a free-form maintainer mutation API | P1 |
|
||||
| C. User-facing settings / preview / onboarding | Current main now has preview flows, preview history, release-note digest in onboarding, provider diagnostics, settings reset, concept-note prerequisite guidance, API liveness/activity UI, and saved-artifact-aware preview recovery with `1.8.9` version truth resynced | Backup branch carried additional UX closure work, but the recovered slice is now re-proved on current main | Keep sidebar/preview/settings wording, i18n, saved-artifact behavior, and release-facing version truth aligned as the user-facing truth source | Do not regress to “these UX guardrails are missing on current main,” but also do not overclaim unrecovered UX ideas | P1 |
|
||||
| D. Regex / file selection / local-KB / chapter split | Current main now has file-selection profiles, folder regex/glob filtering, `relativePath` / `basename` matching, optional subfolder inclusion control, local-KB retrieval, chapter split, their regression tests, and machine-readable retrieval summaries plus timing/size telemetry on the title-generation, research, and artifact-mode diagram result paths | Backup branch provided the original recovery evidence; current main now carries the bounded product slice directly and the latest Stage C follow-through work | Treat the next step as remaining chapter-split evidence framing and offline retrieval-quality evaluation follow-through, not existence re-proof | Do not keep writing these capabilities as backup-only or absent from live mainline, and do not flatten retrieval back down to boolean-only signaling in docs or contracts | P1 |
|
||||
| D. Regex / file selection / local-KB / chapter split | Current main now has file-selection profiles, folder regex/glob filtering, `relativePath` / `basename` matching, optional subfolder inclusion control, local-KB retrieval, chapter split, their regression tests, machine-readable retrieval summaries plus timing/size telemetry on the title-generation, research, and artifact-mode diagram result paths, and a dedicated offline fixture via `npm run verify:local-kb-fixtures` | Backup branch provided the original recovery evidence; current main now carries the bounded product slice directly and the latest Stage C follow-through work | Treat the next step as chapter-split evidence framing plus expanding offline retrieval-quality fixture coverage, not existence re-proof | Do not keep writing these capabilities as backup-only or absent from live mainline, and do not flatten retrieval back down to boolean-only signaling in docs or contracts | P1 |
|
||||
| E. Release / repo-saga / clean-state hygiene | Current main now has release/repo-saga scripts plus shared repo-saga execution lock, tests, docs, and local-artifact ignore guardrails | Backup branch motivated the guardrails; the bounded serial-safety slice is now back on current main | Preserve serial execution discipline for repo-saga refresh flows and keep clean-state proof as part of finish criteria | Do not confuse “script still exists” with permission to run repo-saga refresh paths in parallel | P0 |
|
||||
|
||||
## 4. Reconfirmed Current-Main Register
|
||||
|
|
@ -51,7 +51,7 @@ These items are safe to describe as present on current main:
|
|||
6. redacted/public-safe CLI export surfaces plus repo-local maintainer help/invoke for bounded path-based operations;
|
||||
7. settings reset, concept-note prerequisite guidance, and concept synonym suppression;
|
||||
8. file-selection profiles and folder-scope regex/glob control;
|
||||
9. local knowledge-base retrieval, including machine-readable retrieval summaries on the title-generation, research, and artifact-mode diagram result paths;
|
||||
9. local knowledge-base retrieval, including machine-readable retrieval summaries on the title-generation, research, and artifact-mode diagram result paths, plus the bounded offline fixture exposed as `npm run verify:local-kb-fixtures`;
|
||||
10. chapter split;
|
||||
11. `1.8.9` release-facing version truth resync across package metadata, welcome digest, and README family.
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ canonical: true
|
|||
| A. Packaging / semantic verification | 当前 live build/audit 真值仍是单入口 `main.js` + inline `srcdoc`;源码中仍保留 render-host runtime 候选模块,但当前执行链与审计真值已明确把它们保持为 non-shipped,并拒绝残留的 `render-host.mjs` 资产/引用 | 更晚的备份分支曾进入更宽的 dedicated runtime-asset 通道 | 在未来真正补齐 build + release + audit + 文档之前,继续把当前 source-only 决策写清楚 | 不要因为 `src/` 里重新出现 runtime 候选代码,就继续把 `render-host.mjs` 写成当前主线已发货 | P0 |
|
||||
| B. CLI / automation surface | 当前主线现已具备 registry-backed 的 config/profile export/import、脱敏 provider 导出、public-surface 导出、已进入 registry-backed typed contract 的 `content.split-note-by-chapters`,以及覆盖有界 path-based 操作与 export 操作的 repo-local maintainer help/invoke 脚本 | 备份分支还承载过更宽的 maintainer-bridge 设想,但当前 reintegration 刻意保持在窄边界内 | 继续把 maintainer helper 的边界写清楚;若任何 path-based operation 要提升为更广或更公共的 CLI 面,必须同批补齐契约/测试/文档 | 不要把当前能力面写成通用 public CLI,或无边界的 maintainer mutation API | P1 |
|
||||
| C. 用户可见 settings / preview / onboarding | 当前主线现已具备 preview flows、preview history、欢迎弹窗 release digest、provider diagnostics、settings reset、concept-note 前置配置提示、API liveness/activity UI,以及面向已保存工件的 preview 恢复链路,并已重新同步 `1.8.9` release-facing version truth | 备份分支还有更多 UX 收口尝试,但目前已恢复切片已在当前主线上重新证明 | 继续保持 sidebar / preview / settings 的文案、i18n、已保存工件行为与 release-facing version truth 一致 | 不要再把这些 UX guardrail 写成“当前主线缺失”,但也不要顺手高估尚未恢复的 UX 想法 | P1 |
|
||||
| D. Regex / 文件筛选 / local-KB / chapter split | 当前主线现已具备 file-selection profiles、文件夹 regex/glob 筛选、`relativePath` / `basename` 匹配、可选子目录范围控制、local-KB retrieval、chapter split、对应回归测试,以及面向标题生成、研究总结与 artifact-mode 图形结果路径的 machine-readable retrieval 摘要与 timing/size telemetry | 备份分支提供了最初恢复证据;当前主线现在已直接携带该有界产品切片与最新 Stage C 收口结果 | 下一步应转向剩余 chapter-split evidence framing 与 offline retrieval-quality evaluation 跟进,而不是继续证明这些能力“是否存在” | 不要继续把这些能力写成只存在于 backup、或 live mainline 尚未具备,也不要在文档或契约里把 retrieval 再压回 boolean-only signaling | P1 |
|
||||
| D. Regex / 文件筛选 / local-KB / chapter split | 当前主线现已具备 file-selection profiles、文件夹 regex/glob 筛选、`relativePath` / `basename` 匹配、可选子目录范围控制、local-KB retrieval、chapter split、对应回归测试、面向标题生成/研究总结/artifact-mode 图形结果路径的 machine-readable retrieval 摘要与 timing/size telemetry,以及通过 `npm run verify:local-kb-fixtures` 暴露的专用离线夹具 | 备份分支提供了最初恢复证据;当前主线现在已直接携带该有界产品切片与最新 Stage C 收口结果 | 下一步应转向 chapter-split evidence framing 与离线 retrieval-quality fixture coverage 扩充,而不是继续证明这些能力“是否存在” | 不要继续把这些能力写成只存在于 backup、或 live mainline 尚未具备,也不要在文档或契约里把 retrieval 再压回 boolean-only signaling | P1 |
|
||||
| E. Release / repo-saga / clean-state hygiene | 当前主线现已具备 release/repo-saga 脚本,以及 repo-saga 执行锁、测试、文档与本地工件忽略 guardrail | 备份分支推动了这些 guardrail;当前主线已恢复有界串行安全切片 | 保持 repo-saga 刷新流程的串行纪律,并把 clean-state 证明保留为收尾要求 | 不要把“脚本还在”误读为“可以并行跑 repo-saga 刷新路径” | P0 |
|
||||
|
||||
## 4. 当前主线已确认 register
|
||||
|
|
@ -51,7 +51,7 @@ canonical: true
|
|||
6. 脱敏 / public-safe CLI 导出表面与仓库内 maintainer help/invoke(含有界 path-based 操作);
|
||||
7. settings reset、concept-note 前置提示与 concept synonym suppression;
|
||||
8. file-selection profiles 与 folder-scope regex/glob 控制;
|
||||
9. local knowledge-base retrieval,以及面向标题生成、研究总结与 artifact-mode 图形结果路径的 machine-readable retrieval 摘要;
|
||||
9. local knowledge-base retrieval,以及面向标题生成、研究总结与 artifact-mode 图形结果路径的 machine-readable retrieval 摘要,外加 `npm run verify:local-kb-fixtures` 这条有界离线夹具;
|
||||
10. chapter split;
|
||||
11. package metadata、welcome digest 与 README family 上重新同步到 `1.8.9` 的 release-facing version truth。
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ The previously recovered product slices are now real current-main facts and no l
|
|||
3. preview history and saved-artifact-aware reopening are live in the reusable preview shell.
|
||||
4. settings reset, concept-note prerequisite guidance, concept synonym suppression, and folder file-selection profiles are already back on current main.
|
||||
5. retrieval-dependent note-processing results now expose machine-readable `localKnowledgeRetrieval` summaries for title generation and research, including matched/returned counts, source paths, requested `topK`, sliding-window size, current-file exclusion telemetry, index/query timing, and context-char count.
|
||||
6. a dedicated offline retrieval-quality maintainer fixture now exists as `npm run verify:local-kb-fixtures`; it exercises the live MiniSearch-based retriever against a small regression corpus instead of introducing a separate evaluation-only retrieval path.
|
||||
|
||||
Code-backed evidence includes:
|
||||
|
||||
|
|
@ -146,7 +147,7 @@ PRD requirement status on current `main`:
|
|||
| R6 add `章节拆分` action | Landed | Command/sidebar wiring exists on current main |
|
||||
| R7 heading-based split + TOC artifact | Landed | `src/chapterSplit.ts` plus tests |
|
||||
| R8 no regression to packaging / semantic truth | Landed | build/audit still prove `main.js`-only shipping |
|
||||
| R9 tests/docs/progress artifacts compare current code to prior plans | Landed, but should keep moving | This document and the matrix updates are part of that closure |
|
||||
| R9 tests/docs/progress artifacts compare current code to prior plans | Landed, and now deeper | This document, the matrix updates, and `verify:local-kb-fixtures` together now cover both narrative progress alignment and a bounded offline retrieval-quality regression check |
|
||||
| R10 keep CI green and stability bar intact | Landed at current checkpoint | Verified by current repo gates |
|
||||
|
||||
Interpretation:
|
||||
|
|
@ -247,7 +248,7 @@ Likely areas:
|
|||
|
||||
1. keep extending richer result/evidence framing to the remaining chapter-split paths now that retrieval summaries plus timing telemetry are landed for title-generation, research, and artifact-mode diagram generation;
|
||||
2. the shared maintainer helper now carries compact payload examples for the retrieval-dependent paths, so the next step is to keep those examples aligned as result schemas evolve;
|
||||
3. continue tuning/documentation around sliding-window size, snippet shaping, folder-scope expectations, and offline evaluation fixtures.
|
||||
3. keep tuning/documentation around sliding-window size, snippet shaping, and folder-scope expectations, but treat the offline fixture as landed baseline work and expand it via richer query classes / chapter-split evidence coverage rather than re-proving that the harness should exist.
|
||||
|
||||
## 6. Task And Documentation Follow-Through Rule
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ canonical: true
|
|||
3. preview history 与 saved-artifact-aware reopening 已进入可复用 preview shell。
|
||||
4. settings reset、concept-note prerequisite guidance、concept synonym suppression 与 folder file-selection profiles 都已回到当前主线。
|
||||
5. 面向 retrieval 的 note-processing 结果现在也已为标题生成与研究总结暴露 machine-readable 的 `localKnowledgeRetrieval` 摘要,包含 matched/returned counts、source paths、请求的 `topK`、sliding-window size、current-file exclusion telemetry、index/query timing 与 context-char count。
|
||||
6. 现在也已有专用的离线 retrieval-quality maintainer fixture:`npm run verify:local-kb-fixtures`。它直接对当前线上 MiniSearch retriever 跑一组小型回归语料,而不是再造一条评测专用检索路径。
|
||||
|
||||
代码证据包括:
|
||||
|
||||
|
|
@ -146,7 +147,7 @@ release-facing 真值也已在当前主线上重新对齐:
|
|||
| R6 新增 `章节拆分` 动作 | 已落地 | command/sidebar wiring 已存在于 current main |
|
||||
| R7 按标题拆分并生成 TOC 工件 | 已落地 | `src/chapterSplit.ts` 与对应测试已证明 |
|
||||
| R8 不回归 packaging / semantic 真值 | 已落地 | build/audit 仍只证明 `main.js` 单资产发货 |
|
||||
| R9 tests/docs/progress artifacts 对齐先前方案 | 已落地,但仍应继续维护 | 本文与矩阵更新就是这轮收口的一部分 |
|
||||
| R9 tests/docs/progress artifacts 对齐先前方案 | 已落地,且已进一步收紧 | 本文、矩阵更新以及 `verify:local-kb-fixtures` 现在同时覆盖了叙述层进度对齐与有界离线 retrieval-quality 回归检查 |
|
||||
| R10 keep CI green and stability bar intact | 当前检查点已落地 | 已由当前 repo gates 重新验证 |
|
||||
|
||||
正确解释:
|
||||
|
|
@ -247,7 +248,7 @@ release-facing 真值也已在当前主线上重新对齐:
|
|||
|
||||
1. 在标题生成、研究总结与 artifact-mode 图形生成已经落地 retrieval 摘要与 timing telemetry 之后,继续把 richer result/evidence framing 推进到剩余的 chapter-split 路径;
|
||||
2. shared maintainer helper 现已为依赖 retrieval 的路径补上简洁 payload 示例,下一步重点是让这些示例持续跟随 result schema 演进;
|
||||
3. 继续完善 sliding-window、snippet shaping、folder-scope 预期与 offline evaluation fixture 等调优文档。
|
||||
3. 继续完善 sliding-window、snippet shaping 与 folder-scope 预期等调优文档;对 offline fixture 则应把它视为已落地基线,后续重点转向扩充 query class 与 chapter-split evidence coverage,而不是重复证明“需要有这条夹具”。
|
||||
|
||||
## 6. Task 与文档收口规则
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ Boundary:
|
|||
- `src/operations/publicCliSurface.ts` now derives the bounded public-safe slice from the same registry/capability/contract pair instead of maintaining a parallel command allowlist.
|
||||
- `file.process-add-links`, `file.process-folder-add-links`, `content.generate-from-title`, `content.batch-generate-from-titles`, `mermaid.batch-fix`, `concept.dedupe`, `translate.*`, `formula.*`, and `content.extract-original-text` now form the current proof set for write-heavy contract enrichment: utility cores return structured results, host adapters own localized success/no-file/confirmation semantics, and the registry exports the richer schemas directly.
|
||||
- `content.generate-from-title`, `content.batch-generate-from-titles`, `research.summarize-topic`, and artifact-mode `diagram.generate` now also expose machine-readable local-KB retrieval summaries instead of reducing retrieval to a boolean-only side note. Current summaries include indexed counts, matched/returned section counts, expanded section counts, source paths, requested `topK`, sliding-window size, current-file exclusion telemetry, index-build ms, query ms, and final context-char count.
|
||||
- a dedicated offline retrieval-quality fixture now exists as `npm run verify:local-kb-fixtures`; it reuses the live MiniSearch-based runtime path against a small maintainer fixture set instead of introducing a separate evaluation-only retriever.
|
||||
- `content.split-note-by-chapters` now follows the same direction more explicitly: the result shape names the requested heading level, chapter note paths, full managed artifact set, and stale removals instead of forcing callers to infer them indirectly from counts or filenames.
|
||||
- `diagram.generate` now carries an explicit typed follow-through layer beneath the host-neutral generation core: `followThrough.kind` differentiates Mermaid save, artifact save, and preview completion while preserving backward-compatible top-level `outputPath` / `previewOpened`, and artifact-generation modes now also surface the local-KB retrieval telemetry through the same structured result.
|
||||
- The first checked-in semantic-verification helper now exists as `npm run verify:diagram-semantics`; it turns the maintainer runbook into a reusable, secret-free checklist artifact instead of leaving semantic verification as prose-only guidance.
|
||||
|
|
@ -150,7 +151,7 @@ These are the best remaining candidates for registry-backed or more host-neutral
|
|||
|---|---|---|---|
|
||||
| P0 | Packaging source/build convergence around the latent render-host runtime lane | Current source now contains reusable runtime helpers (`src/rendering/runtime/renderHostEntry.ts`, `src/rendering/preview/renderHostRuntimeClient.ts`), but build/audit truth still proves `main.js`-only shipping. The highest-value next step is to remove that ambiguity explicitly: either keep the runtime lane source-only and document it as non-shipped, or ship a true multi-entry boundary in one batch | `esbuild.config.mjs`, `scripts/audit-render-host-bundle.js`, `src/rendering/runtime/renderHostEntry.ts`, `src/rendering/preview/renderHostRuntimeClient.ts` |
|
||||
| P1 | Bounded public-CLI promotion for explicit path-based operations | The maintainer helper already proves there is demand for path-based operations, but public promotion should happen only for operations whose write semantics and output contracts are stable enough to document and regression-lock | `src/maintainerCliBridge.ts`, `scripts/lib/maintainer-cli-operation-help.js`, `src/operations/registry.ts`, `src/tests/maintainerCliBridge.test.ts` |
|
||||
| P1 | Contract/result hardening for retrieval and chapter-split writes | Retrieval-dependent note-processing results, including artifact-mode `diagram.generate`, now expose machine-readable `localKnowledgeRetrieval` summaries with timing/size telemetry, and the shared maintainer helper now carries compact payload examples; the next maturity gain is to keep chapter-split evidence framing and offline retrieval-quality evaluation aligned rather than broadening the surface count | `src/chapterSplit.ts`, `src/localKnowledgeBase.ts`, `src/fileUtils.ts`, `src/searchUtils.ts`, `src/main.ts`, `scripts/lib/maintainer-cli-operation-help.js`, `src/tests/chapterSplit.test.ts`, `src/tests/localKnowledgeTaskIntegration.test.ts`, `src/tests/diagramCommandArchitecture.test.ts` |
|
||||
| P1 | Contract/result hardening for retrieval and chapter-split writes | Retrieval-dependent note-processing results, including artifact-mode `diagram.generate`, now expose machine-readable `localKnowledgeRetrieval` summaries with timing/size telemetry, the shared maintainer helper now carries compact payload examples, and `npm run verify:local-kb-fixtures` now locks a small offline retrieval-quality fixture; the next maturity gain is to deepen chapter-split evidence framing and expand fixture coverage rather than broadening the surface count | `src/chapterSplit.ts`, `src/localKnowledgeBase.ts`, `src/fileUtils.ts`, `src/searchUtils.ts`, `src/main.ts`, `src/tests/localKnowledgeEvaluationFixture.test.ts`, `scripts/lib/maintainer-cli-operation-help.js`, `src/tests/chapterSplit.test.ts`, `src/tests/localKnowledgeTaskIntegration.test.ts`, `src/tests/diagramCommandArchitecture.test.ts` |
|
||||
| P2 | Workflow/settings packaging | Workflow DSL and output-path toggles remain useful metadata but not yet stable public interfaces | `src/workflowButtons.ts`, settings-driven output controls |
|
||||
|
||||
## Settings Readiness
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@
|
|||
- `src/operations/publicCliSurface.ts` 现在会从同一套 registry/capability/contract 组合直接推导 bounded public-safe slice,而不是维护另一份并行 allowlist。
|
||||
- `file.process-add-links`、`file.process-folder-add-links`、`content.generate-from-title`、`content.batch-generate-from-titles`、`mermaid.batch-fix`、`concept.dedupe`、`translate.*`、`formula.*` 与 `content.extract-original-text` 现在已经组成当前已验证的 write-heavy contract-enrichment proof set:utility core 返回结构化结果,host adapter 接管本地化成功/no-file/confirmation 语义,registry 直接导出 richer schema。
|
||||
- `content.generate-from-title`、`content.batch-generate-from-titles`、`research.summarize-topic` 以及 artifact-mode 的 `diagram.generate` 现在也已直接暴露 machine-readable 的 local-KB retrieval 摘要,而不再只剩一个 boolean 侧记。当前摘要会带出 indexed counts、matched/returned section counts、expanded section counts、source paths、请求的 `topK`、sliding-window size、current-file exclusion telemetry、index-build ms、query ms 与最终 context-char count。
|
||||
- 现在也已有专用的离线 retrieval-quality fixture:`npm run verify:local-kb-fixtures`。它直接复用线上 MiniSearch runtime path 跑一组小型维护者夹具,而不是再造一条只给评测用的分叉 retriever。
|
||||
- `content.split-note-by-chapters` 现在也更明确地遵循同一方向:结果结构会直接命名请求的 heading level、章节文件路径、完整 managed artifact 集合以及 stale removal 明细,而不是继续逼调用方只靠 count 或文件名间接推断。
|
||||
- `diagram.generate` 现在已经在宿主无关 generation core 之下携带显式 typed follow-through:`followThrough.kind` 用来区分 Mermaid 保存、artifact 保存与 preview 完成,同时继续保留向后兼容的顶层 `outputPath` / `previewOpened`;artifact-generation modes 还会沿同一结构化结果暴露 local-KB retrieval telemetry。
|
||||
- 第一份已检入的 semantic-verification helper 现在也已经存在:`npm run verify:diagram-semantics` 会把维护者 runbook 落成可复用、无 secrets 的检查模板,而不是继续停留在纯文字指引层面。
|
||||
|
|
@ -150,7 +151,7 @@
|
|||
|---|---|---|---|
|
||||
| P0 | 围绕潜在 render-host runtime lane 的 source/build 收敛 | 当前源码已出现可复用的 runtime helper(`src/rendering/runtime/renderHostEntry.ts`、`src/rendering/preview/renderHostRuntimeClient.ts`),但 build/audit 真值仍只证明 `main.js` 单资产发货。下一步最高杠杆工作,是明确消除这层歧义:要么继续保持 source-only 候选态并写清非发货事实,要么同批落地真正的多入口构建边界 | `esbuild.config.mjs`、`scripts/audit-render-host-bundle.js`、`src/rendering/runtime/renderHostEntry.ts`、`src/rendering/preview/renderHostRuntimeClient.ts` |
|
||||
| P1 | 显式 path-based operations 的有界 public-CLI 提升 | maintainer helper 已证明 path-based operations 有真实需求,但只有当写入副作用与输出契约足够稳定、可文档化、可回归锁定时,才应该进入 public-safe slice | `src/maintainerCliBridge.ts`、`scripts/lib/maintainer-cli-operation-help.js`、`src/operations/registry.ts`、`src/tests/maintainerCliBridge.test.ts` |
|
||||
| P1 | retrieval / chapter-split 写入路径的契约与结果加固 | 面向 retrieval 的 note-processing 结果现在已为标题生成、研究总结以及 artifact-mode 的 `diagram.generate` 显式暴露带 timing/size telemetry 的 machine-readable `localKnowledgeRetrieval` 摘要,shared maintainer helper 也已补上简洁 payload 示例;下一步成熟度提升点应是持续保持 chapter-split evidence framing 与 offline retrieval-quality evaluation 对齐,而不是继续扩操作数量 | `src/chapterSplit.ts`、`src/localKnowledgeBase.ts`、`src/fileUtils.ts`、`src/searchUtils.ts`、`src/main.ts`、`scripts/lib/maintainer-cli-operation-help.js`、`src/tests/chapterSplit.test.ts`、`src/tests/localKnowledgeTaskIntegration.test.ts`、`src/tests/diagramCommandArchitecture.test.ts` |
|
||||
| P1 | retrieval / chapter-split 写入路径的契约与结果加固 | 面向 retrieval 的 note-processing 结果现在已为标题生成、研究总结以及 artifact-mode 的 `diagram.generate` 显式暴露带 timing/size telemetry 的 machine-readable `localKnowledgeRetrieval` 摘要,shared maintainer helper 也已补上简洁 payload 示例,`npm run verify:local-kb-fixtures` 还锁定了一组小型离线 retrieval-quality fixture;下一步成熟度提升点应是深化 chapter-split evidence framing 与扩充 fixture coverage,而不是继续扩操作数量 | `src/chapterSplit.ts`、`src/localKnowledgeBase.ts`、`src/fileUtils.ts`、`src/searchUtils.ts`、`src/main.ts`、`src/tests/localKnowledgeEvaluationFixture.test.ts`、`scripts/lib/maintainer-cli-operation-help.js`、`src/tests/chapterSplit.test.ts`、`src/tests/localKnowledgeTaskIntegration.test.ts`、`src/tests/diagramCommandArchitecture.test.ts` |
|
||||
| P2 | workflow/settings 打包 | Workflow DSL 与 output-path toggles 仍是有价值 metadata,但还不是稳定公共接口 | `src/workflowButtons.ts`, 设置驱动的输出控制 |
|
||||
|
||||
## 设置就绪度
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
"audit:i18n-ui": "node scripts/audit-hardcoded-ui-strings.js",
|
||||
"audit:render-host": "node scripts/audit-render-host-bundle.js",
|
||||
"verify:diagram-semantics": "node scripts/diagram-semantic-verification.js",
|
||||
"verify:local-kb-fixtures": "jest --runInBand src/tests/localKnowledgeEvaluationFixture.test.ts",
|
||||
"release:github": "node scripts/release/publish-github-release.js",
|
||||
"regression:language-baseline": "bash scripts/regression/language-support-baseline.sh",
|
||||
"regression:language-compare": "bash scripts/regression/language-support-compare.sh"
|
||||
|
|
|
|||
245
src/tests/localKnowledgeEvaluationFixture.test.ts
Normal file
245
src/tests/localKnowledgeEvaluationFixture.test.ts
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { TFile } from 'obsidian';
|
||||
import { buildLocalKnowledgeBaseRetriever } from '../localKnowledgeBase';
|
||||
import { mockApp } from './__mocks__/app';
|
||||
import { mockSettings } from './__mocks__/settings';
|
||||
|
||||
interface FixtureFile {
|
||||
path: string;
|
||||
markdown: string;
|
||||
}
|
||||
|
||||
interface EvaluationCase {
|
||||
id: string;
|
||||
query: string;
|
||||
expectedSourcePaths: string[];
|
||||
currentFilePath?: string;
|
||||
topK: number;
|
||||
slidingWindowSize: number;
|
||||
maxSnippetChars: number;
|
||||
minExpectedPathRecall: number;
|
||||
minReturnedHitCount: number;
|
||||
expectedContextFragments?: string[];
|
||||
}
|
||||
|
||||
const FIXTURE_FILES: FixtureFile[] = [
|
||||
{
|
||||
path: 'Knowledge/Deep Learning.md',
|
||||
markdown: [
|
||||
'# Deep Learning',
|
||||
'Foundation overview for modern neural networks.',
|
||||
'',
|
||||
'## Attention',
|
||||
'Attention mechanisms help transformer models focus on relevant tokens.',
|
||||
'',
|
||||
'## Training',
|
||||
'Gradient descent and scaling laws shape model quality.'
|
||||
].join('\n')
|
||||
},
|
||||
{
|
||||
path: 'Knowledge/Transformers.md',
|
||||
markdown: [
|
||||
'# Transformers',
|
||||
'Transformers replaced many recurrent bottlenecks.',
|
||||
'',
|
||||
'## Architecture',
|
||||
'Transformer blocks rely on attention, feed-forward layers, and residual paths.',
|
||||
'',
|
||||
'## Deployment',
|
||||
'Inference deployment requires batching, caching, and latency control.'
|
||||
].join('\n')
|
||||
},
|
||||
{
|
||||
path: 'Knowledge/Diagram Platform.md',
|
||||
markdown: [
|
||||
'# Diagram Platform',
|
||||
'The rendering platform has multiple layers.',
|
||||
'',
|
||||
'## Retrieval',
|
||||
'Sliding window retrieval keeps adjacent sections together for diagram generation.',
|
||||
'',
|
||||
'## Evaluation',
|
||||
'RAGPerf measures end-to-end latency and throughput for retrieval systems.',
|
||||
'',
|
||||
'## Packaging',
|
||||
'Single-entry packaging keeps runtime truth narrow and auditable.'
|
||||
].join('\n')
|
||||
}
|
||||
];
|
||||
|
||||
const EVALUATION_CASES: EvaluationCase[] = [
|
||||
{
|
||||
id: 'cross-file-attention',
|
||||
query: 'transformer attention',
|
||||
currentFilePath: 'Knowledge/Transformers.md',
|
||||
expectedSourcePaths: ['Knowledge/Deep Learning.md'],
|
||||
topK: 2,
|
||||
slidingWindowSize: 0,
|
||||
maxSnippetChars: 220,
|
||||
minExpectedPathRecall: 1,
|
||||
minReturnedHitCount: 1,
|
||||
expectedContextFragments: ['Attention mechanisms help transformer models focus on relevant tokens.']
|
||||
},
|
||||
{
|
||||
id: 'sliding-window-adjacency',
|
||||
query: 'sliding window retrieval',
|
||||
expectedSourcePaths: ['Knowledge/Diagram Platform.md'],
|
||||
topK: 1,
|
||||
slidingWindowSize: 1,
|
||||
maxSnippetChars: 500,
|
||||
minExpectedPathRecall: 1,
|
||||
minReturnedHitCount: 1,
|
||||
expectedContextFragments: [
|
||||
'The rendering platform has multiple layers.',
|
||||
'Sliding window retrieval keeps adjacent sections together for diagram generation.',
|
||||
'RAGPerf measures end-to-end latency and throughput for retrieval systems.'
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'packaging-truth',
|
||||
query: 'single-entry packaging runtime truth',
|
||||
expectedSourcePaths: ['Knowledge/Diagram Platform.md'],
|
||||
topK: 1,
|
||||
slidingWindowSize: 0,
|
||||
maxSnippetChars: 240,
|
||||
minExpectedPathRecall: 1,
|
||||
minReturnedHitCount: 1,
|
||||
expectedContextFragments: ['Single-entry packaging keeps runtime truth narrow and auditable.']
|
||||
}
|
||||
];
|
||||
|
||||
function createFile(pathValue: string): TFile {
|
||||
const name = pathValue.split('/').pop() || pathValue;
|
||||
const extension = name.split('.').pop() || 'md';
|
||||
return Object.assign(new (TFile as any)(), {
|
||||
path: pathValue,
|
||||
name,
|
||||
extension,
|
||||
basename: name.replace(/\.[^.]+$/, ''),
|
||||
parent: { path: pathValue.split('/').slice(0, -1).join('/') || '/' }
|
||||
});
|
||||
}
|
||||
|
||||
function configureFixtureVault(): void {
|
||||
const files = FIXTURE_FILES.map(file => createFile(file.path));
|
||||
const markdownByPath = new Map(FIXTURE_FILES.map(file => [file.path, file.markdown]));
|
||||
|
||||
(mockApp.vault.getFiles as jest.Mock).mockReturnValue(files);
|
||||
(mockApp.vault.read as jest.Mock).mockImplementation(async (file: TFile) => {
|
||||
return markdownByPath.get(file.path) || '# Missing\n';
|
||||
});
|
||||
}
|
||||
|
||||
function computeExpectedPathRecall(actualPaths: string[], expectedPaths: string[]): number {
|
||||
if (expectedPaths.length === 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const actual = new Set(actualPaths);
|
||||
const matched = expectedPaths.filter(expectedPath => actual.has(expectedPath)).length;
|
||||
return matched / expectedPaths.length;
|
||||
}
|
||||
|
||||
describe('local knowledge offline evaluation fixture', () => {
|
||||
const repoRoot = path.join(__dirname, '..', '..');
|
||||
const packageJsonPath = path.join(repoRoot, 'package.json');
|
||||
const capabilityMatrixPath = path.join(repoRoot, 'docs', 'maintainer', 'notemd-cli-capability-matrix.md');
|
||||
const capabilityMatrixZhPath = path.join(repoRoot, 'docs', 'maintainer', 'notemd-cli-capability-matrix.zh-CN.md');
|
||||
const postRecoveryAuditPath = path.join(
|
||||
repoRoot,
|
||||
'docs',
|
||||
'brainstorms',
|
||||
'2026-05-25-post-bounded-recovery-audit-and-next-level-direction.md'
|
||||
);
|
||||
const postRecoveryAuditZhPath = path.join(
|
||||
repoRoot,
|
||||
'docs',
|
||||
'brainstorms',
|
||||
'2026-05-25-post-bounded-recovery-audit-and-next-level-direction.zh-CN.md'
|
||||
);
|
||||
const unifiedMatrixPath = path.join(
|
||||
repoRoot,
|
||||
'docs',
|
||||
'brainstorms',
|
||||
'2026-05-20-unified-follow-through-matrix.md'
|
||||
);
|
||||
const unifiedMatrixZhPath = path.join(
|
||||
repoRoot,
|
||||
'docs',
|
||||
'brainstorms',
|
||||
'2026-05-20-unified-follow-through-matrix.zh-CN.md'
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
configureFixtureVault();
|
||||
});
|
||||
|
||||
test('registers a dedicated offline verification entrypoint and documents it', () => {
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
const documentationSurfaces = [
|
||||
capabilityMatrixPath,
|
||||
capabilityMatrixZhPath,
|
||||
postRecoveryAuditPath,
|
||||
postRecoveryAuditZhPath,
|
||||
unifiedMatrixPath,
|
||||
unifiedMatrixZhPath
|
||||
].map(filePath => fs.readFileSync(filePath, 'utf8'));
|
||||
|
||||
expect(packageJson.scripts['verify:local-kb-fixtures'])
|
||||
.toBe('jest --runInBand src/tests/localKnowledgeEvaluationFixture.test.ts');
|
||||
|
||||
for (const documentation of documentationSurfaces) {
|
||||
expect(documentation).toContain('verify:local-kb-fixtures');
|
||||
}
|
||||
});
|
||||
|
||||
test('keeps the offline fixture cases above minimum retrieval thresholds', async () => {
|
||||
const settings = {
|
||||
...mockSettings,
|
||||
enableLocalKnowledgeRetrieval: true,
|
||||
localKnowledgeBasePaths: 'Knowledge',
|
||||
localKnowledgeTopK: 3,
|
||||
localKnowledgeSlidingWindowSize: 1,
|
||||
localKnowledgeMaxSnippetChars: 500,
|
||||
localKnowledgeExcludeCurrentFile: true
|
||||
};
|
||||
|
||||
const retriever = await buildLocalKnowledgeBaseRetriever(mockApp as any, settings);
|
||||
expect(retriever).not.toBeNull();
|
||||
|
||||
const recalls: number[] = [];
|
||||
|
||||
for (const evaluationCase of EVALUATION_CASES) {
|
||||
const details = retriever!.buildContextDetails(evaluationCase.query, {
|
||||
currentFilePath: evaluationCase.currentFilePath,
|
||||
topK: evaluationCase.topK,
|
||||
slidingWindowSize: evaluationCase.slidingWindowSize,
|
||||
maxSnippetChars: evaluationCase.maxSnippetChars
|
||||
});
|
||||
|
||||
const recall = computeExpectedPathRecall(details.sourcePaths, evaluationCase.expectedSourcePaths);
|
||||
recalls.push(recall);
|
||||
|
||||
expect(recall).toBeGreaterThanOrEqual(evaluationCase.minExpectedPathRecall);
|
||||
expect(details.returnedHitCount).toBeGreaterThanOrEqual(evaluationCase.minReturnedHitCount);
|
||||
expect(details.indexedFileCount).toBe(FIXTURE_FILES.length);
|
||||
expect(details.indexedSectionCount).toBeGreaterThanOrEqual(FIXTURE_FILES.length);
|
||||
expect(details.indexBuildMs).toBeGreaterThanOrEqual(0);
|
||||
expect(details.queryMs).toBeGreaterThanOrEqual(0);
|
||||
expect(details.contextCharCount).toBeGreaterThan(0);
|
||||
|
||||
for (const expectedPath of evaluationCase.expectedSourcePaths) {
|
||||
expect(details.sourcePaths).toContain(expectedPath);
|
||||
}
|
||||
|
||||
for (const expectedFragment of evaluationCase.expectedContextFragments || []) {
|
||||
expect(details.context).toContain(expectedFragment);
|
||||
}
|
||||
}
|
||||
|
||||
const averageRecall = recalls.reduce((sum, value) => sum + value, 0) / recalls.length;
|
||||
expect(averageRecall).toBeGreaterThanOrEqual(0.95);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue