@cyber-dash-tech/revela 0.16.4 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +7 -5
  2. package/README.zh-CN.md +7 -5
  3. package/lib/commands/brief.ts +9 -0
  4. package/lib/commands/help.ts +5 -2
  5. package/lib/commands/init.ts +42 -27
  6. package/lib/commands/narrative.ts +26 -2
  7. package/lib/commands/research.ts +36 -20
  8. package/lib/commands/review.ts +21 -18
  9. package/lib/ctx.ts +1 -1
  10. package/lib/decks-state.ts +38 -4
  11. package/lib/edit/prompt.ts +1 -1
  12. package/lib/hook-notifications.ts +53 -0
  13. package/lib/narrative-state/render-plan.ts +114 -27
  14. package/lib/narrative-state/research-binding-eval.ts +260 -0
  15. package/lib/narrative-state/research-gaps.ts +2 -88
  16. package/lib/narrative-vault/authoring-contract.ts +127 -0
  17. package/lib/narrative-vault/authoring-guard.ts +122 -0
  18. package/lib/narrative-vault/auto-compile.ts +134 -0
  19. package/lib/narrative-vault/bootstrap.ts +63 -0
  20. package/lib/narrative-vault/cache.ts +14 -0
  21. package/lib/narrative-vault/compile-mirror.ts +45 -0
  22. package/lib/narrative-vault/compile.ts +350 -0
  23. package/lib/narrative-vault/constants.ts +6 -0
  24. package/lib/narrative-vault/diagnostic-report.ts +117 -0
  25. package/lib/narrative-vault/export.ts +71 -0
  26. package/lib/narrative-vault/frontmatter.ts +41 -0
  27. package/lib/narrative-vault/hook-targets.ts +40 -0
  28. package/lib/narrative-vault/index.ts +18 -0
  29. package/lib/narrative-vault/inventory.ts +392 -0
  30. package/lib/narrative-vault/markdown-qa.ts +237 -0
  31. package/lib/narrative-vault/markdown.ts +34 -0
  32. package/lib/narrative-vault/migration.ts +52 -0
  33. package/lib/narrative-vault/mutate.ts +361 -0
  34. package/lib/narrative-vault/paths.ts +19 -0
  35. package/lib/narrative-vault/read.ts +52 -0
  36. package/lib/narrative-vault/relations.ts +32 -0
  37. package/lib/narrative-vault/source-loader.ts +19 -0
  38. package/lib/narrative-vault/timestamp.ts +32 -0
  39. package/lib/narrative-vault/types.ts +44 -0
  40. package/lib/source-materials.ts +98 -0
  41. package/lib/tool-result.ts +34 -0
  42. package/package.json +2 -2
  43. package/plugin.ts +60 -22
  44. package/skill/NARRATIVE_SKILL.md +25 -10
  45. package/tools/decks.ts +363 -67
  46. package/tools/research-save.ts +3 -0
  47. package/tools/workspace-scan.ts +1 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **English** | [中文](README.zh-CN.md)
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/@cyber-dash-tech/revela)](https://www.npmjs.com/package/@cyber-dash-tech/revela) [![license](https://img.shields.io/npm/l/@cyber-dash-tech/revela)](LICENSE) [![tests](https://img.shields.io/badge/tests-380%20passing-brightgreen)](tests/) [![OpenCode plugin](https://img.shields.io/badge/OpenCode-plugin-blue)](https://opencode.ai) [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.0-orange)](https://bun.sh)
5
+ [![npm version](https://img.shields.io/npm/v/@cyber-dash-tech/revela)](https://www.npmjs.com/package/@cyber-dash-tech/revela) [![license](https://img.shields.io/npm/l/@cyber-dash-tech/revela)](LICENSE) [![tests](https://img.shields.io/badge/tests-470%20passing-brightgreen)](tests/) [![OpenCode plugin](https://img.shields.io/badge/OpenCode-plugin-blue)](https://opencode.ai) [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.0-orange)](https://bun.sh)
6
6
 
7
7
  <p align="center">
8
8
  <img src="assets/img/logo.png" alt="Revela" width="800" />
@@ -20,7 +20,7 @@ Its first render target is still the HTML slide deck: start a Revela workflow co
20
20
  - injects one-shot workflow instructions for explicit commands such as `/revela init`, `/revela story`, and `/revela make --deck`
21
21
  - switches into deck-render prompt mode only when you explicitly start `/revela make --deck`
22
22
  - supports workspace document discovery, transparent text extraction for `.pdf`, `.docx`, `.pptx`, and `.xlsx`, and cached embedded-material extraction for those formats
23
- - keeps `DECKS.json` as the current workspace state engine for sources, research actions, findings, claims, evidence, narrative intent, render targets, and readiness
23
+ - uses `revela-narrative/` as the editable Markdown narrative vault when present, with `DECKS.json` as the compatibility/render-state mirror
24
24
  - reviews narrative readiness before artifact rendering, then separately gates deck HTML writes through deck/artifact readiness
25
25
  - records review snapshots so stale readiness cannot silently authorize new deck HTML after important state changes
26
26
  - treats HTML decks, PDF, and PPTX as render targets from shared workspace state rather than isolated output files
@@ -168,17 +168,19 @@ The ambient enabled or disabled state is session-level only.
168
168
 
169
169
  ### Workspace State
170
170
 
171
- `DECKS.json` is Revela's workspace state engine and compatibility file. It is still stored at the workspace root and remains readable as the current deck project state, but internally Revela now treats it as a lightweight persistence layer for more than a deck checklist.
171
+ `revela-narrative/` is Revela's editable Markdown narrative vault when present. It stores the human/LLM-editable source for audience, decision, thesis, claims, evidence nodes, objections, risks, research gaps, and typed narrative relations.
172
+
173
+ `DECKS.json` remains Revela's compatibility and render-state file. It is still stored at the workspace root and remains readable as the current deck project state, but when a vault exists its top-level `narrative` is a compiled mirror from Markdown rather than the primary editing surface.
172
174
 
173
175
  The state records:
174
176
 
175
177
  - workspace source materials and reusable extraction cache paths
176
178
  - research plans, saved findings, and compact action provenance
177
- - canonical narrative state, approvals, objections, risks, slide specs, claim candidates, and evidence trace
179
+ - compiled canonical narrative mirror, approvals, objections, risks, slide specs, claim candidates, and evidence trace
178
180
  - render targets such as the active HTML deck plus derived PDF and PPTX artifacts
179
181
  - review snapshots with input hashes so old readiness results become stale after meaningful state changes
180
182
 
181
- Existing root `DECKS.json` workspaces remain compatible. Running `/revela init` or `/revela story` on an older project can normalize canonical narrative state and refresh projection fields without requiring a manual migration, moving files, or replacing `DECKS.json` with a database. `writeReadiness.status: "ready"` is deck/artifact readiness only; it is never narrative approval.
183
+ New workspaces bootstrap `revela-narrative/` directly with `initNarrativeVault`; stable findings can be recorded as partial Markdown nodes without waiting for a complete story. `/revela init` is repeatable ingest: first runs consider all supported source files, later runs prioritize files added or modified after the latest vault Markdown timestamp plus same-path files whose fingerprint changed, then distill stable findings into vault nodes. Developer workspaces that still have a JSON narrative but no Markdown vault receive a migration hint from `revela-decks read` with `summary: true`; `exportNarrativeVault` can export that narrative into `revela-narrative/` without moving approvals, render targets, review snapshots, artifact coverage, actions, deck specs, or source material records into Markdown. Generated cache files live under `.opencode/revela/narrative-cache/` and should not be edited by hand. `writeReadiness.status: "ready"` is deck/artifact readiness only; it is never narrative approval.
182
184
 
183
185
  Decks remain the primary authored artifact, but they are now treated as render targets from the same workspace state that can later support briefs, appendix material, Evidence Inspector views, Q&A, and interactive reading layers without duplicating source/evidence logic.
184
186
 
package/README.zh-CN.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](README.md) | **中文**
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/@cyber-dash-tech/revela)](https://www.npmjs.com/package/@cyber-dash-tech/revela) [![license](https://img.shields.io/npm/l/@cyber-dash-tech/revela)](LICENSE) [![tests](https://img.shields.io/badge/tests-380%20passing-brightgreen)](tests/) [![OpenCode plugin](https://img.shields.io/badge/OpenCode-plugin-blue)](https://opencode.ai) [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.0-orange)](https://bun.sh)
5
+ [![npm version](https://img.shields.io/npm/v/@cyber-dash-tech/revela)](https://www.npmjs.com/package/@cyber-dash-tech/revela) [![license](https://img.shields.io/npm/l/@cyber-dash-tech/revela)](LICENSE) [![tests](https://img.shields.io/badge/tests-470%20passing-brightgreen)](tests/) [![OpenCode plugin](https://img.shields.io/badge/OpenCode-plugin-blue)](https://opencode.ai) [![Bun](https://img.shields.io/badge/Bun-%E2%89%A51.0-orange)](https://bun.sh)
6
6
 
7
7
  <p align="center">
8
8
  <img src="assets/img/logo.png" alt="Revela" width="800" />
@@ -20,7 +20,7 @@ Revela 是一个 [OpenCode](https://opencode.ai) 插件,用来把工作区来
20
20
  - 为 `/revela init`、`/revela story`、`/revela make --deck` 等显式命令注入一次性 workflow instructions
21
21
  - 只有在显式运行 `/revela make --deck` 时,才切换到 deck-render prompt mode
22
22
  - 支持工作区文档扫描,以及 `.pdf`、`.docx`、`.pptx`、`.xlsx` 的透明文本提取和嵌入素材缓存提取
23
- - `DECKS.json` 作为当前 workspace state engine,持续记录来源材料、调研动作、findings、claims、证据、叙事意图、render targets 和 readiness
23
+ - 存在 `revela-narrative/` 时,将它作为可编辑 Markdown narrative vault,并让 `DECKS.json` 作为兼容/render-state mirror
24
24
  - 先检查 narrative readiness,再用独立 deck/artifact gate 保护 deck HTML 写入
25
25
  - 记录 review snapshots,避免重要状态变化后旧的 ready 结果继续默默授权写入 deck HTML
26
26
  - 把 HTML deck、PDF 和 PPTX 视为来自同一 workspace state 的 render targets,而不是互相孤立的输出文件
@@ -166,17 +166,19 @@ Active domain 只进入 narrative pipeline。它帮助 `init`、`research`、`st
166
166
 
167
167
  ### Workspace State
168
168
 
169
- `DECKS.json` Revela 当前的 workspace state engine,也是兼容旧工作流的状态文件。它仍然保存在工作区根目录,也仍然可以理解为当前 deck 项目的状态入口,但 Revela 内部已经不再把它当成单纯的 deck checklist
169
+ 存在 `revela-narrative/` 时,它就是 Revela 可编辑的 Markdown narrative vault,用来保存 audience、decision、thesis、claims、evidence nodes、objections、risks、research gaps typed narrative relations
170
+
171
+ `DECKS.json` 仍然是 Revela 的兼容状态和 render-state 文件。它仍然保存在工作区根目录,也仍然可以理解为当前 deck 项目的状态入口;但当 vault 存在时,顶层 `narrative` 是从 Markdown 编译得到的 mirror,不再是主要编辑面。
170
172
 
171
173
  状态中会记录:
172
174
 
173
175
  - 工作区来源材料和可复用的 extraction cache 路径
174
176
  - 调研计划、已保存 findings,以及精简的 action provenance
175
- - canonical narrative state、approvals、objections、risks、slide specs、claim candidates 和 evidence trace
177
+ - 编译得到的 canonical narrative mirror、approvals、objections、risks、slide specs、claim candidates 和 evidence trace
176
178
  - active HTML deck 以及派生 PDF、PPTX 等 render targets
177
179
  - 带 input hash 的 review snapshots,使重要状态变化后旧的 readiness 自动变 stale
178
180
 
179
- 已有的根目录 `DECKS.json` 工作区继续兼容。对旧项目运行 `/revela init` `/revela story` 时,可以安全 normalize canonical narrative state 并刷新 projection 字段;用户不需要手动迁移、不需要移动文件,也不需要把 `DECKS.json` 换成数据库。`writeReadiness.status: "ready"` 只代表 deck/artifact readiness,永远不等于 narrative approval。
181
+ 新工作区会直接用 `initNarrativeVault` bootstrap `revela-narrative/`;LLM 扫描到稳定 finding 后,可以先写入 partial Markdown nodes,不需要等待完整故事成型。`/revela init` 是可重复 ingest:首次运行会考虑所有支持的 source files,后续运行优先处理晚于最新 vault Markdown timestamp 的新增/修改文件,以及同一路径 fingerprint 变化的文件,并把稳定 finding 提炼进 vault nodes。仍只有 JSON narrative、还没有 Markdown vault 的开发期工作区,会在 `revela-decks read``summary: true` 时收到 migration hint;`exportNarrativeVault` 可以把该 narrative 导出到 `revela-narrative/`,同时不会把 approvals、render targets、review snapshots、artifact coverage、actions、deck specs 或 source material records 搬进 Markdown。生成缓存位于 `.opencode/revela/narrative-cache/`,不应手工编辑。`writeReadiness.status: "ready"` 只代表 deck/artifact readiness,永远不等于 narrative approval。
180
182
 
181
183
  Deck 仍然是主要 authored artifact,但现在它是从同一份 workspace state 渲染出来的目标之一。后续 briefs、appendix material、Evidence Inspector views、Q&A 和 interactive reading layers 都可以复用同一套来源/证据逻辑,而不是各自生成孤立内容。
182
184
 
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, writeFileSync } from "fs"
2
2
  import { dirname, isAbsolute, join, normalize, resolve } from "path"
3
3
  import { readDecksState, writeDecksState } from "../decks-state"
4
4
  import { compileExecutiveBrief, DEFAULT_EXECUTIVE_BRIEF_PATH } from "../narrative-state/executive-brief"
5
+ import { compileNarrativeVault, formatVaultDiagnosticMarkdown, formatVaultDiagnosticReport, hasNarrativeVault } from "../narrative-vault"
5
6
 
6
7
  export interface BriefArgs {
7
8
  outputPath?: string
@@ -29,6 +30,14 @@ export async function handleBrief(
29
30
  }
30
31
 
31
32
  const state = readDecksState(input.workspaceRoot)
33
+ if (hasNarrativeVault(input.workspaceRoot)) {
34
+ const vault = compileNarrativeVault(input.workspaceRoot, { fallbackApprovals: state.narrative?.approvals ?? [] })
35
+ const report = formatVaultDiagnosticReport(vault.diagnostics)
36
+ if (!report.ok) {
37
+ await send(`**Executive brief not rendered**\n\n${formatVaultDiagnosticMarkdown(report)}\n\nFix the narrative vault blockers before rendering.`)
38
+ return
39
+ }
40
+ }
32
41
  const result = compileExecutiveBrief(state, { outputPath: input.outputPath })
33
42
  if (!result.ok) {
34
43
  await send(
@@ -14,7 +14,7 @@ export async function handleHelp(
14
14
  ): Promise<void> {
15
15
  const design = activeDesign()
16
16
  const domain = activeDomain()
17
- const status = ctx.enabled ? "enabled " : "disabled"
17
+ const status = ctx.enabled ? "enabled - Revela prompt is loaded" : "disabled - run `/revela enable` or any workflow command"
18
18
  await send(
19
19
  `\`\`\`\n` +
20
20
  ` R E V E L A H e l p v${pkg.version}\n` +
@@ -23,7 +23,8 @@ export async function handleHelp(
23
23
  `**Current**\n\n` +
24
24
  `Status: ${status}\n` +
25
25
  `Design: \`${design}\`\n` +
26
- `Domain: \`${domain}\`\n\n` +
26
+ `Domain: \`${domain}\`\n` +
27
+ `Run \`/revela enable\` to load Revela context without starting a workflow, or run \`/revela disable\` to pause it. Workflow commands still auto-enable Revela.\n\n` +
27
28
  `---\n\n` +
28
29
  `**Workflow**\n\n` +
29
30
  `1. \`init\` — discover workspace sources and capture intent\n` +
@@ -35,6 +36,8 @@ export async function handleHelp(
35
36
  `---\n\n` +
36
37
  `**Commands**\n\n` +
37
38
  `\`/revela\` — show REVELA help\n` +
39
+ `\`/revela enable\` — enable Revela prompt/context without starting a workflow\n` +
40
+ `\`/revela disable\` — disable Revela prompt/context for this session\n` +
38
41
  `\`/revela init\` — initialize or refresh workspace story state\n` +
39
42
  `\`/revela research\` — research, bind evidence, and reduce story gaps\n` +
40
43
  `\`/revela story [-l language]\` — open the read-only story workspace UI\n` +
@@ -9,17 +9,15 @@ export function buildInitPrompt({
9
9
  }): string {
10
10
  const mode = exists
11
11
  ? `A ${DECKS_STATE_FILE} file already exists. Read it first through the revela-decks tool and update it conservatively.`
12
- : `No ${DECKS_STATE_FILE} file exists yet. Create it through the revela-decks tool only when there is enough stable workspace or narrative context.`
12
+ : `No ${DECKS_STATE_FILE} file exists yet. Initialize the Markdown narrative vault through the revela-decks tool before writing narrative meaning.`
13
13
 
14
14
  return `Initialize Revela narrative workspace state.
15
15
 
16
16
  Goal:
17
- - Build or update ${DECKS_STATE_FILE}, the workspace-level machine-readable state file for Revela narrative and artifact work.
18
- - Use the \`revela-decks\` tool for state updates. Do not write or patch ${DECKS_STATE_FILE} directly.
19
- - Capture stable narrative context first: primary audience, belief before, belief after, decision/action, thesis, central claims, evidence availability, objections, risks, available source materials, existing artifact history, and open questions.
20
- - Do not treat initialization as permission to write a deck. Narrative readiness is reviewed later by \`/revela story\`; deck/artifact readiness is handled by \`/revela make --deck\` after story approval and deck-plan confirmation.
21
- - Do not require slide count, visual style, design selection, output path, layout choices, or component choices during narrative initialization unless the user explicitly asks to render a deck now.
22
- - ${DECKS_STATE_FILE} is the compatibility workspace-state file. Deck specs are render-target projections, not the center of initialization.
17
+ - Build or refresh ${DECKS_STATE_FILE} and the Markdown narrative vault from local workspace evidence.
18
+ - Treat init as repeatable ingest: discover files, register source materials, follow returned ingest task hints, and distill stable narrative meaning.
19
+ - Capture primary audience, belief before/after, decision/action, thesis, central claims, evidence availability, objections, risks, source materials, artifact history, and open questions.
20
+ - Do not treat initialization as permission to write a deck. Do not require slide count, visual style, design selection, output path, layout choices, or component choices unless the user explicitly asks to render.
23
21
 
24
22
  Current state:
25
23
  - ${mode}
@@ -33,26 +31,43 @@ Workspace boundary rules:
33
31
  - Do not use \`~\`, \`..\`, or parent-directory traversal to discover files.
34
32
  - If the current workspace appears too broad, stop and ask the user which workspace subdirectory to initialize instead of scanning outside or deeply across everything.
35
33
 
36
- Workflow:
37
- 1. Use the \`revela-workspace-scan\` tool to inspect document and data files in the workspace. Start with no \`path\` and \`max_depth: 2\`.
38
- 2. Separately search for existing artifact history, especially:
39
- - \`decks/**/*.html\`
40
- - \`slides/**/*.html\`
41
- - \`presentations/**/*.html\`
42
- - \`decks/**/*.pdf\`
43
- - \`slides/**/*.pdf\`
44
- Run these searches only inside the current workspace root. These are generated/output artifacts, not necessarily source materials. If \`decks/\` contains exactly one HTML file, record it as existing artifact history and possible current deck artifact. If \`decks/\` contains multiple HTML files, do not guess which one is canonical; ask the user which artifact belongs to this workspace or whether extra decks should move to separate workspaces.
45
- 3. Register or refresh source material records by passing the scan result's \`sourceMaterial\` objects to \`revela-decks\` action \`init\`. Preserve unchanged existing records; the tool will upsert by path and fingerprint.
46
- 4. Select the files that look most relevant for understanding the narrative problem. Prioritize source decks, PDFs, Word docs, spreadsheets, CSVs, Markdown, text notes, and relevant existing generated artifacts.
47
- 5. Do not automatically extract every PDF/PPTX/DOCX/XLSX during init. Call \`revela-extract-document-materials\` only for selected files that are clearly needed to form conservative narrative memory, or when the user explicitly asked to analyze the material now.
48
- 6. Before extracting or deeply reading a selected document, check \`DECKS.json.workspace.sourceMaterials\`. If the same path has the same fingerprint and valid extraction paths, reuse those paths instead of repeating extraction.
49
- 7. Read only the materials needed to form conservative narrative memory. Do not exhaustively read every file if the workspace is large.
50
- 8. If enough information is available, preserve canonical narrative intent through \`revela-decks\` action \`upsertNarrative\`: audience intent, decision intent, thesis, central claims, explicit evidence bindings where known, objections, and risks. This does not require deck rendering inputs.
51
- 9. If the workspace has explicit slide/deck information, existing HTML, or a user-requested deck task, you may also call \`upsertDeck\` and \`upsertSlides\` for explicit deck information. The tool projects canonical narrative state back to compatibility \`narrativeBrief\` when a deck record exists. Do not pass or ask for a deck key; the tool uses the workspace folder name internally. Do not mark deck readiness ready during init.
52
- 10. When adopting an existing HTML deck, analyze the artifact and create one conservative \`SlideSpec\` per identifiable slide/page only if the artifact is clearly the current workspace artifact. Record only visible source notes or explicit source information as evidence; do not infer original evidence that is not present in the artifact.
53
- 11. When a read or extracted source material clearly supports a specific narrative or slide claim, preserve compact evidence trace such as \`sourcePath\`, \`location\`, \`extractedTextPath\`, or \`extractedManifestPath\`. Attach extraction cache paths only when they support that specific claim, not to every claim or slide by default.
54
- 12. Treat \`workspace.sourceMaterials\` as a reusable candidate index, not proof by itself. A source material record alone is not narrative evidence or slide evidence.
55
- 13. Report what was initialized or updated and list the smallest open narrative questions needed to proceed.
34
+ Expected tool use during init:
35
+ - \`revela-decks init\` and \`revela-decks initNarrativeVault\` are expected controlled workspace-state/vault boundaries. Empty-looking optional fields in tool UI are a schema display artifact, not user-provided evidence.
36
+ - Treat \`authoringContract\` returned by \`read(summary: true)\`, \`initNarrativeVault\`, or \`narrativeInventory\` as the Markdown authoring guide: valid node types, plain id convention, inline relation syntax, forbidden compatibility actions, and optional helper templates.
37
+ - Treat \`markdownQa\` returned by \`read(summary: true)\`, \`compileNarrativeVault\`, or \`revela-decks markdownQa\` as post-authoring repair feedback that is separate from compiler diagnostics. Fix \`repairCards\` by smallest repair; do not invent missing claims, evidence, source paths, URLs, quotes, or caveats just to clear QA. If \`compileNarrativeVault\` output does not visibly include \`markdownQa\`, call \`revela-decks markdownQa\` before final reporting.
38
+ - Before authoring claims, evidence, relations, objections, risks, or research gaps, inspect \`narrativeInventory\` from \`read(summary: true)\` or call \`revela-decks narrativeInventory\`. Reuse existing ids and relation targets. Do not invent evidence ids, claim ids, or relation targets before checking inventory unless you are intentionally creating the missing node in Markdown.
39
+ - Create/update content nodes first. Add graph edges afterward in the source node's \`## Relations\` section with plain node-id wikilinks. Do not use \`relations.md\`, typed wikilinks, or hand-written relation ids.
40
+ - You may directly maintain \`revela-narrative/**/*.md\` knowledge nodes. Use structured vault helpers only when they reduce schema risk or express a narrow lifecycle/evidence-binding action: \`bindResearchFindings\`, \`upsertVaultEvidence\`, \`upsertVaultResearchGap\`, \`updateVaultResearchGap\`, or similar targeted helpers.
41
+ - Use targeted vault helpers only when you have a complete payload for that node/action. If a helper returns missing fields, report the gap or repair Markdown directly; do not invent fields.
42
+ - Do not use JSON-era compatibility actions such as \`upsertResearchGaps\`, \`deriveResearchGaps\`, \`updateResearchGap\`, \`closeResearchGap\`, \`applyEvidenceCandidates\`, or \`upsertNarrative\` in vault workspaces. Follow the tool error and \`authoringContract\` replacement action.
43
+ - Direct Markdown patches must update existing sections in place. Do not duplicate stable headings such as \`## Evidence\`, \`## Caveats\`, \`## Relations\`, \`## Response\`, or \`## Mitigation\`.
44
+ - Do not append a second frontmatter block. A vault Markdown file must have one leading \`---\` frontmatter block only.
45
+
46
+ Minimum vault authoring contract:
47
+ - Supported \`type\` values are \`index\`, \`audience\`, \`decision\`, \`thesis\`, \`claim\`, \`evidence\`, \`objection\`, \`risk\`, and \`research-gap\`. Use \`research-gap\`, not \`researchGap\` or \`research_gap\`.
48
+ - New graph relations belong in node-local \`## Relations\` sections, for example \`- supports: [[claim-belief-change-purpose]] - Optional rationale.\` Compiler-generated ids are deterministic; never hand-write relation ids.
49
+ - Relation wikilinks reference plain frontmatter node ids directly. Do not write typed targets such as \`[[claim:claim-belief-change-purpose]]\`.
50
+ - Evidence nodes require source trace (\`source\`, \`sourcePath\` or \`url\` when known, \`location\` when known), \`supportScope\`, \`unsupportedScope\`, \`caveat\`, \`strength\`, a quoted/snippet body, and a \`## Relations\` line such as \`- supports: [[claim-id]]\` when the supported claim is explicit. Keep \`claimId\` only as compatibility fallback for existing vaults or helper outputs.
51
+ - When fixing a new node created earlier in the same turn, patch the broken line or section. Do not delete and recreate existing nodes just to fix \`type\`, frontmatter, or relation syntax.
52
+
53
+ Required workflow:
54
+ 1. If ${DECKS_STATE_FILE} exists, call \`revela-decks read\` with \`summary: true\`. If \`migration.available: true\`, prefer \`exportNarrativeVault\`; if no vault exists, call \`initNarrativeVault\` before recording narrative meaning.
55
+ 2. Call \`revela-workspace-scan\` with no \`path\` and \`max_depth: 2\`. Scan deeper only when the user points to a workspace-relative folder or expected files are missing.
56
+ 3. Search workspace-local generated artifact history only when useful: \`decks/**/*.html\`, \`slides/**/*.html\`, \`presentations/**/*.html\`, \`decks/**/*.pdf\`, and \`slides/**/*.pdf\`.
57
+ 4. Register scan results with \`revela-decks init\`. Treat returned \`ingest.suggestedTasks\` as the authoritative init task list. Each task includes \`path\`, \`reason\`, \`materialType\`, \`needsExtraction\`, and \`suggestedAction\`.
58
+ 5. For selected relevant tasks, read directly when \`suggestedAction: "read_directly"\`; call \`revela-extract-document-materials\` first when \`suggestedAction: "extract_then_read"\`. Do not extract every document by default.
59
+ 6. Before writing narrative meaning, inspect \`narrativeInventory\` from the latest \`read(summary: true)\` result or call \`revela-decks narrativeInventory\`. Then distill stable findings into \`revela-narrative/**/*.md\` using the Markdown authoring guide. Completeness is not a gate: write partial claims, caveats, unsupported scope, and research gaps rather than waiting for a complete story. Use optional helpers such as \`upsertVaultResearchGap\`, \`upsertVaultEvidence\`, or \`bindResearchFindings\` only when they fit the exact update. Preserve frontmatter ids and existing section headings when editing Markdown. Write nodes first; add inline \`## Relations\` edges afterward only when explicit.
60
+ 7. After Markdown changes, rely on the vault write hook or call \`revela-decks markdownQa\`, then \`revela-decks compileNarrativeVault\`; keep \`markdownQa.repairCards\` separate from compiler blockers and fix both before treating the narrative as usable. If no explicit \`markdownQa\` result is visible after compile, call \`revela-decks markdownQa\` as a manual fallback. Do not use \`upsertNarrative\`.
61
+ 8. If explicit deck/artifact information exists, record conservative deck specs only from visible information. Do not infer hidden evidence from generated artifacts.
62
+ 9. Report initialized/updated/migrated state plus counts and paths for added, changed, newer-than-vault, unchanged, \`ingest.ingestCandidates\`, and \`ingest.suggestedTasks\`. Always include \`Markdown QA: clean\` or \`Markdown QA blockers:\` in the final report. If Markdown QA blockers remain, do not say the workspace initialized cleanly; say the vault was initialized but Markdown repairs remain.
63
+
64
+ Evidence boundary:
65
+ - \`workspace.sourceMaterials\` and ingest task hints are candidate context, not proof.
66
+ - A finding becomes canonical only when a vault node preserves source trace, quote/snippet, support scope, unsupported scope, caveat, and strength.
67
+ - Preserve graph meaning by writing explicit edges in node-local \`## Relations\` sections after nodes exist. Use plain node-id wikilinks and optional inline rationale.
68
+ - Intent briefs, proposals, and user-authored plans may support audience, decision, thesis, stakeholder framing, and stated internal intent. They do not by themselves prove market size, competitor performance, product-market fit, operating-model effectiveness, or external factual claims.
69
+ - If a source states an intended strategy but not its external factual basis, record the strategy as a claim with partial or missing support and add a research gap instead of binding it as strong evidence.
70
+ - A successful vault compile means the vault is structurally valid. It is not evidence readiness, narrative approval, or permission to make a deck/brief.
56
71
 
57
72
  Narrative questions to ask only when missing:
58
73
  - Who is the primary audience?
@@ -6,6 +6,8 @@ import { hasDecksState, readDecksState } from "../decks-state"
6
6
  import { buildNarrativeMap, formatNarrativeMap } from "../narrative-state/map"
7
7
  import { renderNarrativeMapHtmlWithDisplay } from "../narrative-state/map-html"
8
8
  import { emptyDisplayModel, type NarrativeViewLanguage, type ValidatedNarrativeDisplayModel } from "../narrative-state/display"
9
+ import type { NarrativeApproval } from "../narrative-state/types"
10
+ import { compileNarrativeVault, formatVaultDiagnosticMarkdown, formatVaultDiagnosticReport, hasNarrativeVault } from "../narrative-vault"
9
11
 
10
12
  export interface NarrativeArgs {
11
13
  language: NarrativeViewLanguage
@@ -82,7 +84,8 @@ export async function handleNarrative(
82
84
 
83
85
  const state = readDecksState(options.workspaceRoot)
84
86
  const map = buildNarrativeMap(state)
85
- const markdown = formatNarrativeMap(map)
87
+ const diagnosticsMarkdown = vaultDiagnosticsMarkdown(options.workspaceRoot, state.narrative?.approvals ?? [])
88
+ const markdown = [diagnosticsMarkdown, formatNarrativeMap(map)].filter(Boolean).join("\n\n")
86
89
 
87
90
  if (options.openBrowser) {
88
91
  const htmlPath = writeNarrativeMapHtml(map, options.display ?? emptyDisplayModel(options.language ?? "en"))
@@ -102,16 +105,35 @@ export async function handleNarrative(
102
105
  }
103
106
  }
104
107
 
108
+ function vaultDiagnosticsMarkdown(workspaceRoot: string, fallbackApprovals: NarrativeApproval[]): string {
109
+ if (!hasNarrativeVault(workspaceRoot)) return ""
110
+ const result = compileNarrativeVault(workspaceRoot, { fallbackApprovals })
111
+ return formatVaultDiagnosticMarkdown(formatVaultDiagnosticReport(result.diagnostics))
112
+ }
113
+
105
114
  export function buildNarrativeViewPrompt(options: { workspaceRoot: string; language: NarrativeViewLanguage }): string {
106
115
  if (!hasDecksState(options.workspaceRoot)) {
107
116
  return "No `DECKS.json` found. Tell the user to run `/revela init` before opening the narrative view. Do not call any tool."
108
117
  }
109
118
 
110
- const map = buildNarrativeMap(readDecksState(options.workspaceRoot))
119
+ const state = readDecksState(options.workspaceRoot)
120
+ const map = buildNarrativeMap(state)
121
+ const vaultDiagnostics = hasNarrativeVault(options.workspaceRoot)
122
+ ? formatVaultDiagnosticReport(compileNarrativeVault(options.workspaceRoot, { fallbackApprovals: state.narrative?.approvals ?? [] }).diagnostics)
123
+ : undefined
111
124
  const projection = {
112
125
  narrativeHash: map.snapshot.narrativeHash,
113
126
  language: options.language,
114
127
  snapshot: map.snapshot,
128
+ vaultDiagnostics: vaultDiagnostics
129
+ ? {
130
+ ok: vaultDiagnostics.ok,
131
+ errorCount: vaultDiagnostics.errorCount,
132
+ warningCount: vaultDiagnostics.warningCount,
133
+ blockers: vaultDiagnostics.blockers.map((diagnostic) => ({ file: diagnostic.file, nodeId: diagnostic.nodeId, code: diagnostic.code, message: diagnostic.message, suggestedAction: diagnostic.suggestedAction })),
134
+ warnings: vaultDiagnostics.warnings.map((diagnostic) => ({ file: diagnostic.file, nodeId: diagnostic.nodeId, code: diagnostic.code, message: diagnostic.message, suggestedAction: diagnostic.suggestedAction })),
135
+ }
136
+ : undefined,
115
137
  claims: map.claimFlow.map((claim) => ({
116
138
  id: claim.id,
117
139
  kind: claim.kind,
@@ -153,6 +175,8 @@ Hard rules:
153
175
  - Do not translate claim IDs, relation endpoints, narrative hash, source paths, findings files, URLs, numbers, or quoted/source facts.
154
176
  - Use natural business and manufacturing terminology in the target language, not word-by-word machine translation.
155
177
  - If a fact is missing, describe it as missing instead of filling it in.
178
+ - If vaultDiagnostics.blockers is present in the compact map, keep Story read-only but surface the blocker state in summaryLine and the relevant claim card riskOrGapSummary when applicable. Include diagnostic file/nodeId/code/message/suggestedAction in display copy; do not invent missing evidence, source trace, quotes, or caveats to hide the blocker.
179
+ - Do not turn Story into a workflow dashboard: diagnostic copy is for reading context only, not command suggestions or mutation planning.
156
180
 
157
181
  Chinese localization rules when the target language request is Chinese, zh, zh-CN, --cn, 中文, or Simplified Chinese:
158
182
  - Use natural business/manufacturing Chinese, not word-by-word machine translation.
@@ -11,12 +11,12 @@ export function buildResearchPrompt({
11
11
  ? `${DECKS_STATE_FILE} exists. Read it through the revela-decks tool before researching.`
12
12
  : `${DECKS_STATE_FILE} does not exist yet. Do not start broad internet research; initialize the workspace first with /revela init unless the user supplied a specific research question in chat.`
13
13
 
14
- return `Run Revela closed-loop research.
14
+ return `Run Revela research from deterministic state.
15
15
 
16
16
  Goal:
17
17
  - Reduce open gaps, unsupported scope, weak evidence, unattached findings, and overextended relation rationale for the current story.
18
18
  - Drive research from canonical narrative gaps: unsupported central claims, objections, risks, decision questions, explicit researchGaps, and claim_chain_gap warnings.
19
- - Treat /revela research as authorization to bind clearly supported findings into canonical evidence without asking for item-by-item user confirmation.
19
+ - Treat /revela research as authorization to bind clearly supported findings through the safe \`bindResearchFindings\` boundary without asking for item-by-item user confirmation.
20
20
  - Preserve evidence boundaries: eliminate caveats only when evidence or narrower wording actually resolves them; otherwise keep precise caveats visible.
21
21
  - Do not write decks, briefs, or design artifacts during research.
22
22
 
@@ -24,20 +24,32 @@ Current state:
24
24
  - ${state}
25
25
  ${workspaceRoot ? `- Current workspace root: \`${workspaceRoot}\`` : ""}
26
26
 
27
- Closed-loop workflow:
28
- 1. Call \`revela-decks\` action \`read\`, then \`reviewNarrative\`, then \`deriveResearchTargets\`. Treat the returned \`selected\` target as the deterministic first target unless it is clearly blocked by user-only information.
29
- 2. If current research gaps are missing or stale, call \`deriveResearchGaps\` when useful, then call \`deriveResearchTargets\` again. Do not invent gaps that are not tied to a claim, objection, risk, decision, or narrative issue.
30
- 3. Run up to 3 research loops unless the stop conditions below are met earlier.
31
- 4. At the start of each loop, use \`deriveResearchTargets\` as the target order. Work the \`selected\` target first, then the next 1-2 highest-priority targets only when they are related. Do not repeat searches for claims already strongly supported.
32
- 5. If a target has \`findingsFile\` or \`kind: "unattached_findings"\`, inspect \`bindingDiagnostic\` before doing external search. Prefer existing findings before external research.
33
- 6. When \`bindingDiagnostic.bindable\` is false, do not bind or package the findings as strong evidence. Report the exact \`failureReasons\` such as \`missing_quote\`, \`unclear_source\`, \`unsupported_scope\`, \`caveat_conflict\`, \`weak_source\`, \`source_mismatch\`, or \`context_only_finding\`, then either narrow the claim safely or run targeted research for the missing fields.
34
- 7. For targets needing external evidence, mark matching gaps \`in_progress\` with \`revela-decks updateResearchGap\`, then delegate search to the \`revela-research\` subagent. Ask it for source URLs, quotes/snippets, dates or locations when available, caveats, remaining gaps, and a \`## Recommended evidence bindings\` section with claimId, quote, source, supportScope, unsupportedScope, caveat, and strength. Save findings with \`revela-research-save\` under \`researches/{topic}/{axis}.md\` using \`## Data\`, \`## Cases\`, \`## Images\`, and \`## Gaps\` sections as applicable.
35
- 8. After findings are saved or existing findings are selected, read or inspect the findings file. Attach it with \`revela-decks attachResearchFindings\` when it maps to an existing research axis. Re-run \`deriveResearchTargets\` so the next loop sees updated \`bindingDiagnostic\` and target order.
36
- 9. Automatically bind evidence only when all binding criteria are met and the diagnostic is \`bindable: true\` or the same fields are explicit in the findings. Use \`revela-decks applyEvidenceCandidates\` for concrete candidate ids when available. Do not use \`upsertNarrative\` during research to add evidence or update narrative arrays.
37
- 10. Binding criteria: claimId exists; quote/snippet is traceable to the source and is not invented; source URL or workspace source path is present; supportScope and unsupportedScope are explicit; strength is strong or useful partial; caveat is preserved; binding does not expand the claim beyond the evidence.
38
- 11. If a claim or relation is broader than the evidence, do not mutate canonical claims during research. Report the needed claim/relation narrowing in \`Narrative changes\`, keep unsupported scope visible, and make \`/revela story\` or explicit user confirmation the next action when strategic wording must change.
39
- 12. Update matching gaps after binding: use \`evidence_bound\` when canonical evidence was added, \`closed\` when the gap is resolved or non-researchable, \`findings_saved\` only when findings exist but binding criteria are not met, and \`open\` with notes when more external research is still warranted.
40
- 13. Re-run \`reviewNarrative\` and \`deriveResearchTargets\` after each loop. Compare against the previous loop: fewer open gaps, fewer unattached findings, stronger evidence, narrower unsupported scope, or clearer internal-data caveats should count as progress.
27
+ Required first calls:
28
+ 1. Call \`revela-decks read\` with \`summary: true\`.
29
+ 2. If the workspace has a Markdown narrative vault, inspect \`narrativeInventory\` from the read summary or call \`revela-decks narrativeInventory\` before editing claims, gaps, evidence, or relations. If \`markdownQa.repairCards\` are present, fix structural repair cards before binding or research mutations unless the selected target is the exact repair.
30
+ 3. Call \`revela-decks reviewNarrative\`.
31
+ 4. Call \`revela-decks deriveResearchTargets\` and treat \`selected\`, \`bindingDiagnostic\`, and target order as deterministic inputs, not LLM judgement.
32
+
33
+ Tool-driven research contract:
34
+ - If \`selected\` or any high-priority target references a \`findingsFile\`, call \`revela-decks evaluateResearchFindings\` before external search.
35
+ - If \`bindingEval.status === "bindable"\`, call \`revela-decks bindResearchFindings\` with that \`findingsFile\`. Do not hand-author evidence Markdown for bindable findings.
36
+ - If findings are not bindable, report \`missingFields\` and \`failureReasons\`; then run only targeted research for those missing fields.
37
+ - Treat \`markdownQa\` as structural authoring feedback only. It does not prove evidence strength; \`bindingEval\`, \`bindingDiagnostic\`, and compiled claim \`evidenceStatus\` remain the trust/evidence boundary.
38
+ - For external research, use the \`revela-research\` subagent and save findings with \`revela-research-save\`. Ask for source URLs/paths, quotes/snippets, supportScope, unsupportedScope, caveat, strength, and the supported claim id/relation target when available.
39
+ - Re-run \`deriveResearchTargets\` after attachment, binding, or explicit vault edits. Stop after at most 3 rounds.
40
+ - After explicit Markdown edits, rely on the write hook feedback or call \`revela-decks markdownQa\`, then \`compileNarrativeVault\`; keep Markdown QA repair cards separate from compiler diagnostics and repair both before treating the edit as usable research state.
41
+ - For relation changes, update content nodes first, then add explicit edges in the source node's \`## Relations\` section using plain node-id wikilinks. Do not use \`relations.md\`, typed wikilinks, or hand-written relation ids.
42
+
43
+ Allowed mutations:
44
+ - Canonical evidence: use \`bindResearchFindings\` for bindable saved findings; the safe boundary writes \`revela-narrative/evidence/*.md\` and compiles the vault.
45
+ - Research gap lifecycle: after checking inventory and reading the target node, edit \`revela-narrative/research-gaps/*.md\` or use \`updateVaultResearchGap\` when the update is explicit.
46
+ - Safe claim narrowing: after checking inventory and reading the target node, edit \`revela-narrative/claims/*.md\` only when it preserves strategic meaning and evidence boundaries.
47
+ - Relation rewrites must patch node-local \`## Relations\` lines and be reported in \`Narrative changes\`; broader strategic claim changes require Story/user confirmation.
48
+ - Initialize the vault with \`initNarrativeVault\` if a canonical vault is needed and missing.
49
+ - Never call \`upsertNarrative\` during research.
50
+
51
+ Binding criteria:
52
+ - supported claim id exists and is expressed as \`## Relations\` with \`- supports: [[claim-id]]\` for new evidence; quote/snippet is traceable and not invented; source URL/path/findingsFile is present; supportScope and unsupportedScope are explicit; caveat is preserved; strength is strong or useful partial; binding does not expand the claim. Frontmatter \`claimId\` is compatibility fallback, not the preferred graph source.
41
53
 
42
54
  Stop conditions:
43
55
  - No open externally researchable gaps remain.
@@ -50,7 +62,10 @@ Report format:
50
62
  - Start with \`Research loop completed after <n> round(s).\`
51
63
  - Then use these exact sections in order:
52
64
  - \`Selected target\`: report \`kind\`, \`priority\`, \`reason\`, \`question\`, \`targetId\`, \`claimId\`, and any \`findingsFile\`.
53
- - \`Existing findings inspected\`: for each file, report \`findingsFile\`, \`bindingDiagnostic.bindable\`, \`failureReasons\`, and which explicit fields were present: \`source\`, \`quoteOrSnippet\`, \`supportScope\`, \`unsupportedScope\`, \`caveat\`, \`strength\`. If none were inspected, write \`none\`.
65
+ - \`Vault diagnostics\`: if \`vaultDiagnostics\` or a mutation \`diagnosticReport\` was returned, list blockers first with file/node/code/message and the suggested next action; otherwise write \`clean\` or \`not a vault workspace\`. If blockers exist, pause binding and research mutations unless the selected target is the exact diagnostic fix.
66
+ - \`Markdown QA\`: if \`markdownQa.repairCards\` was returned, list repair cards by severity, file, nodeId, issueCode, message, and smallestRepair. If no cards were returned, write \`clean\` or \`not checked\`.
67
+ - \`Evidence trust\`: report \`bindingEval.status\`, \`bindingDiagnostic.bindable\`, and compiled claim \`evidenceStatus\` separately from Markdown QA so structurally valid weak/partial evidence remains visible as weak/partial/missing support.
68
+ - \`Existing findings inspected\`: for each file, report \`findingsFile\`, \`bindingEval.status\` when available, \`bindingDiagnostic.bindable\`, \`missingFields\`, \`failureReasons\`, and which explicit fields were present: \`source\`, \`quoteOrSnippet\`, \`supportScope\`, \`unsupportedScope\`, \`caveat\`, \`strength\`. If none were inspected, write \`none\`.
54
69
  - \`Attachments\`: list findings attached with axis/status, or \`none\`.
55
70
  - \`Evidence bound\`: list evidence bindings by claim id, source, quote/snippet, supportScope, unsupportedScope, caveat, and strength, or \`none\`.
56
71
  - \`Unbound findings\`: list every inspected but unbound findings file with structured failure reasons such as \`missing_quote\`, \`unclear_source\`, \`unsupported_scope\`, \`caveat_conflict\`, \`weak_source\`, \`source_mismatch\`, or \`context_only_finding\`. If none, write \`none\`.
@@ -63,12 +78,13 @@ Report format:
63
78
  Rules:
64
79
  - Do not use primary-agent broad websearch. Use the \`revela-research\` subagent for external search.
65
80
  - Do not invent quotes, source paths, URLs, page references, locations, or caveats.
81
+ - Do not invent claim ids, evidence ids, research-gap ids, or relation targets before checking \`narrativeInventory\` unless you are intentionally creating the missing node in Markdown.
66
82
  - Do not treat \`researches/**/*.md\` as canonical evidence until attached or evidence-bound, but do not stop at findings_saved when binding criteria are met.
67
- - Do not bypass \`deriveResearchTargets\`; target selection, \`selected\`, and \`bindingDiagnostic\` are deterministic inputs, not LLM judgement.
83
+ - Do not bypass \`deriveResearchTargets\` or \`evaluateResearchFindings\`; target selection, \`selected\`, \`bindingDiagnostic\`, and \`bindingEval\` are deterministic inputs, not LLM judgement.
68
84
  - Do not mutate canonical claims merely to fit a source; narrow only to preserve evidence boundaries and avoid overstated claims.
69
- - Do not call \`upsertNarrative\` during research. Research may update gaps, attach findings, and apply explicit evidence candidates; broader narrative rewrites must be reported for Story/user confirmation.
85
+ - Do not call \`upsertNarrative\` during research. Initialize the Markdown vault with \`initNarrativeVault\` if needed; research should author bindable canonical evidence through \`bindResearchFindings\`, then use explicit Markdown edits for \`research-gaps/*.md\` and safe \`claims/*.md\` when needed. Targeted vault actions are fallback helpers, not the primary writing path. Broader narrative rewrites must be reported for Story/user confirmation.
70
86
  - Do not ask the user to approve each evidence binding. Ask only when binding would change strategic meaning, downgrade a central claim, rely on suspicious sources, or require narrative approval.
71
87
  - Do not store secrets, credentials, tokens, or sensitive personal information.
72
88
 
73
- Start now by reading ${DECKS_STATE_FILE} through \`revela-decks\`, reviewing current readiness, deriving research targets, and running the first research/binding loop from the selected target.`
89
+ Start now by reading ${DECKS_STATE_FILE} through \`revela-decks\`, inspecting narrative inventory when a vault exists, reviewing current readiness, deriving research targets, and running the first research/binding loop from the selected target.`
74
90
  }
@@ -35,10 +35,10 @@ Workspace boundary rules:
35
35
  - For Glob/file searches, use the current workspace as the search root. Do not set the search root to a parent directory or home directory.
36
36
 
37
37
  Workflow:
38
- 1. Call \`revela-decks\` with action \`read\` to inspect the current workspace state.
38
+ 1. Call \`revela-decks\` with action \`read\` and \`summary: true\` to inspect the current workspace state, \`vaultDiagnostics\`, \`markdownQa\`, and \`narrativeInventory\` when a vault exists.
39
39
  2. If ${DECKS_STATE_FILE} is missing or empty, do not invent a deck plan, slide count, design, output path, or visual style. Report the smallest narrative inputs needed, usually audience, belief-before, belief-after, decision/action, thesis, central claims, evidence availability, objections, and risks.
40
40
  3. If legacy deck state exists, let the tool-normalized canonical narrative derived from \`narrativeBrief\`, slide roles, slide content, and slide evidence be reviewed. Do not assume old deck readiness means approval.
41
- 4. Call \`revela-decks\` action \`reviewNarrative\`. Use its returned \`status\`, \`blockers\`, \`warnings\`, \`issues\`, \`narrativeHash\`, \`approval\`, and \`nextActions\` as authoritative.
41
+ 4. Call \`revela-decks\` action \`reviewNarrative\`. Use its returned \`status\`, \`blockers\`, \`warnings\`, \`issues\`, \`narrativeHash\`, \`approval\`, and \`nextActions\` as authoritative. If the read summary returned \`markdownQa.repairCards\` or \`vaultDiagnostics\`, report Markdown QA repair cards and compile diagnostics before readiness blockers and include file/node/code/message plus smallest repair or suggested next action.
42
42
  5. If research findings have been saved but not attached or evidence-bound, report them as unattached research state, not proof.
43
43
  6. If central claims lack required evidence, report the named claim and the exact next action: attach findings, bind evidence, run targeted research, narrow unsupported scope, or rewrite the claim.
44
44
  7. If approval is missing or stale, clearly distinguish \`ready_for_approval\`, \`approved\`, and render override.
@@ -46,7 +46,7 @@ Workflow:
46
46
  Report format:
47
47
  - Start with \`Narrative readiness: <status>\`.
48
48
  - Include \`Narrative hash: <hash>\` when returned.
49
- - If blocked or needs research, list each blocker with issue type, claim text when available, and suggested next action.
49
+ - If blocked or needs research, list each blocker with issue type, claim text when available, and suggested next action. Keep Markdown QA repair cards separate from compiler diagnostics and narrative readiness blockers.
50
50
  - If warnings exist, list them after blockers as residual risks.
51
51
  - If approval is missing, ask whether the user wants to approve the narrative or revise it.
52
52
  - If approval is stale, say the prior approval no longer matches the current narrative hash.
@@ -89,9 +89,9 @@ Current state:
89
89
  ${workspaceRoot ? `- Current workspace root: \`${workspaceRoot}\`` : ""}
90
90
 
91
91
  Workflow:
92
- 1. Call \`revela-decks\` action \`read\`.
92
+ 1. Call \`revela-decks\` action \`read\` with \`summary: true\`.
93
93
  2. Call \`revela-decks\` action \`reviewNarrative\` before planning deck slides.
94
- 3. If narrative readiness is \`approved\`, continue. If it is \`ready_for_approval\`, ask the user for explicit approval before continuing. If it is blocked, stale, or needs research, stop and report the smallest next action. Do not call \`approveNarrative\` unless the user explicitly approves or requests a render override.
94
+ 3. If the read summary returned \`markdownQa.blockers\` or \`vaultDiagnostics.blockers\`, stop before deck planning and report Markdown QA repair cards separately from compile diagnostics with file/node/code/message and smallest repair or suggested next action. If narrative readiness is \`approved\`, continue. If it is \`ready_for_approval\`, ask the user for explicit approval before continuing. If it is blocked, stale, or needs research, stop and report the smallest next action. Do not call \`approveNarrative\` unless the user explicitly approves or requests a render override.
95
95
  4. After approval or explicit render override exists, call \`revela-decks\` action \`compileDeckPlan\`. This projects canonical narrative claims and evidence bindings into compatibility \`slides[]\` and \`slides[].evidence[]\`; it must not write HTML.
96
96
  5. If \`compileDeckPlan\` returns \`skipped\`, stop and report the reason. Do not invent slide specs manually to bypass approval.
97
97
  6. Present the compiled deck plan to the user and include a low-fidelity layout sketch for every slide. The plan must identify the chapter structure first: 3-5 chapter headings, each chapter's slide range, and which non-structural slides belong to each chapter. The sketch is ASCII/text structure only; do not generate visual images or HTML mockups.
@@ -107,6 +107,7 @@ Workflow:
107
107
  Deck plan report format:
108
108
  - Start with \`Deck plan: awaiting confirmation\` when a plan was compiled and has not yet been confirmed.
109
109
  - Include narrative readiness status and narrative hash when available.
110
+ - Include Markdown QA repair cards and vault diagnostic blockers or warnings when returned by \`read(summary: true)\`; blockers prevent deck planning until fixed.
110
111
  - Include whether \`compileDeckPlan\` compiled or skipped.
111
112
  - Include \`Required structure: Cover + Table of Contents + Closing\` and do not omit any of those slides.
112
113
  - Include a \`Chapters\` section before the slide list. It must list 3-5 TOC headings, their slide ranges, and the non-structural slides assigned to each chapter.
@@ -181,7 +182,7 @@ Goal:
181
182
  - Treat \`revela-narrative-reviewer\` findings as advisory critique only. Do not represent them as \`revela-decks\` readiness issues, blockers, or authoritative \`writeReadiness\`.
182
183
  - Treat source trace mapping as part of evidence readiness: when research findings have been read, relevant findings should appear in slide-level \`slides[].evidence[]\` records rather than only in raw research files.
183
184
  - When \`revela-decks review\` returns \`evidenceCandidates\`, treat them as conservative binding candidates only. They are not proof that the full slide is supported, and they are not automatically applied to \`slides[].evidence[]\`. If a candidate has \`sourceKind: "researchesFallback"\`, say it was discovered from workspace \`researches/\` files that are not currently referenced by \`researchPlan\`.
184
- - When an evidence candidate includes \`evidenceDraft\`, report it as a proposed slide evidence record with its \`candidateId\`; it still requires explicit user/agent confirmation before calling \`revela-decks\` action \`applyEvidenceCandidates\`. Also report \`unsupportedScope\` and \`recommendedRewrite\` so partial evidence is not stretched to future-state claims.
185
+ - When an evidence candidate includes \`evidenceDraft\`, report it as a proposed slide evidence record with its \`candidateId\`; it still requires explicit user/agent confirmation before binding. Binding canonical evidence means using \`initNarrativeVault\` if needed, writing \`revela-narrative/evidence/*.md\` with explicit source trace, and running \`compileNarrativeVault\`. Also report \`unsupportedScope\` and \`recommendedRewrite\` so partial evidence is not stretched to future-state claims.
185
186
  - When a missing-evidence issue has \`evidenceCandidateSearch\`, use it to explain search coverage: which \`researchPlan\` findings were searched, which fallback \`researches/**/*.md\` files were searched, and any near misses that were below binding threshold.
186
187
 
187
188
  Current state:
@@ -195,17 +196,18 @@ Workspace boundary rules:
195
196
  - For Glob/file searches, use the current workspace as the search root. Do not set the search root to a parent directory or home directory.
196
197
 
197
198
  Workflow:
198
- 1. Call \`revela-decks\` with action \`read\` for the current workspace deck.
199
- 2. If no current deck exists but the conversation contains enough deck context, call \`revela-decks\` action \`upsertDeck\` with goal, outputPath, theme, requiredInputs, researchPlan, and narrativeBrief if the story intent is clear. Do not invent or ask for a deck key; the tool uses the workspace folder name internally.
200
- 3. If \`researchPlan[].status\` is \`done\` or \`read\` and \`researchPlan[].findingsFile\` exists, verify that evidence-sensitive slide claims are backed by compact \`slides[].evidence[]\` records that reference the relevant findings file or source material where known. The review tool may surface conservative \`evidenceCandidates\` for missing evidence by matching slide text against those findings files, and may fall back to bounded workspace \`researches/**/*.md\` discovery when the research plan has no matching findings file; report these as candidate bindings, not as already-bound evidence.
201
- 4. If a user-confirmed slide plan is available, call \`revela-decks\` action \`upsertSlides\` with every slide's title, purpose, narrativeRole, layout, components, structured content, evidence, visuals, and status. Use only lightweight narrativeRole values that are clear from the plan: \`context\`, \`tension\`, \`evidence\`, \`recommendation\`, \`risk\`, \`ask\`, \`appendix\`, or \`close\`.
202
- 5. Prefer evidence records with \`findingsFile\`, \`sourcePath\`, \`location\`, \`quote\`, \`url\`, \`caveat\`, \`extractedTextPath\`, or \`extractedManifestPath\` when those fields are known from research files or extracted workspace materials.
203
- 6. Do not invent quotes, page references, locations, URLs, caveats, or extraction paths. If source trace is missing, preserve the blocker or warning and report exactly what trace is needed.
204
- 7. Only set requiredInputs fields true when explicit conversation state, files read, research findings read, selected design, fetched layouts/components, or user confirmation supports them. Do not infer completion.
205
- 8. For substantial decision decks, preserve a compact \`narrativeBrief\` through \`upsertDeck\` when the conversation or confirmed plan supports it. Do not invent stakeholder beliefs, objections, or risks; leave gaps visible if unknown.
206
- 9. For substantial decision decks, launch the Task subagent with \`subagent_type: "revela-narrative-reviewer"\` after deck/slides are up to date. Ask it to read the current \`DECKS.json\`, run only its fixed rubric, use stable finding IDs, return \`Findings: none\` when all checks pass, and avoid optional pre-write improvements. Do not ask it to write state, call \`revela-decks review\`, or produce HTML.
207
- 10. Call \`revela-decks\` action \`review\`. The tool computes and writes \`writeReadiness\` plus structured readiness issues for the current workspace deck.
208
- 11. Briefly report whether the deck is ready. If blocked, list the exact blockers returned by the tool. If warnings exist, list them after blockers as residual risks; separate evidence/source warnings from narrative warnings when possible. If the review result includes \`diagnostics\`, include a \`Plan and coverage diagnostics\` section with plan quality blockers/warnings, artifact \`coverageStatus\`, \`missingClaimIds\`, \`affectedClaimIds\`, stale reasons, and \`nextActions\`. If the review result includes \`evidenceCandidates\`, add a separate \`Candidate evidence bindings\` section with candidateId, slide index/title, supported claim scope, sourceKind, findingsFile/sourcePath, quote/snippet, caveat, evidenceDraft summary, unsupportedScope, and recommendedRewrite. Tell the user they may explicitly ask to apply selected candidate IDs; do not apply them during review. If candidates are absent but \`evidenceCandidateSearch\` is present, briefly report searched file counts and the best near misses so the user can tell whether review failed to search or searched but did not find a bindable match. If the reviewer returned findings, include them in a separate \`Narrative reviewer notes\` section and label them advisory.
199
+ 1. Call \`revela-decks\` with action \`read\` and \`summary: true\` for the current workspace deck and any \`markdownQa\`, \`vaultDiagnostics\`, and \`narrativeInventory\`.
200
+ 2. If the read summary returned \`markdownQa.blockers\` or \`vaultDiagnostics.blockers\`, report Markdown QA repair cards separately from compile diagnostics before artifact readiness with file/node/code/message and smallestRepair/suggestedAction; stop before \`revela-decks review\`, deck HTML writes, or export guidance until the blocker is fixed.
201
+ 3. If no current deck exists but the conversation contains enough deck context, call \`revela-decks\` action \`upsertDeck\` with goal, outputPath, theme, requiredInputs, researchPlan, and narrativeBrief if the story intent is clear. Do not invent or ask for a deck key; the tool uses the workspace folder name internally.
202
+ 4. If \`researchPlan[].status\` is \`done\` or \`read\` and \`researchPlan[].findingsFile\` exists, verify that evidence-sensitive slide claims are backed by compact \`slides[].evidence[]\` records that reference the relevant findings file or source material where known. The review tool may surface conservative \`evidenceCandidates\` for missing evidence by matching slide text against those findings files, and may fall back to bounded workspace \`researches/**/*.md\` discovery when the research plan has no matching findings file; report these as candidate bindings, not as already-bound evidence.
203
+ 5. If a user-confirmed slide plan is available, call \`revela-decks\` action \`upsertSlides\` with every slide's title, purpose, narrativeRole, layout, components, structured content, evidence, visuals, and status. Use only lightweight narrativeRole values that are clear from the plan: \`context\`, \`tension\`, \`evidence\`, \`recommendation\`, \`risk\`, \`ask\`, \`appendix\`, or \`close\`.
204
+ 6. Prefer evidence records with \`findingsFile\`, \`sourcePath\`, \`location\`, \`quote\`, \`url\`, \`caveat\`, \`extractedTextPath\`, or \`extractedManifestPath\` when those fields are known from research files or extracted workspace materials.
205
+ 7. Do not invent quotes, page references, locations, URLs, caveats, or extraction paths. If source trace is missing, preserve the blocker or warning and report exactly what trace is needed.
206
+ 8. Only set requiredInputs fields true when explicit conversation state, files read, research findings read, selected design, fetched layouts/components, or user confirmation supports them. Do not infer completion.
207
+ 9. For substantial decision decks, preserve a compact \`narrativeBrief\` through \`upsertDeck\` when the conversation or confirmed plan supports it. Do not invent stakeholder beliefs, objections, or risks; leave gaps visible if unknown.
208
+ 10. For substantial decision decks, launch the Task subagent with \`subagent_type: "revela-narrative-reviewer"\` after deck/slides are up to date. Ask it to read the current \`DECKS.json\`, run only its fixed rubric, use stable finding IDs, return \`Findings: none\` when all checks pass, and avoid optional pre-write improvements. Do not ask it to write state, call \`revela-decks review\`, or produce HTML.
209
+ 11. Call \`revela-decks\` action \`review\`. The tool computes and writes \`writeReadiness\` plus structured readiness issues for the current workspace deck.
210
+ 12. Briefly report whether the deck is ready. If blocked, list the exact blockers returned by the tool. If warnings exist, list them after blockers as residual risks; separate evidence/source warnings from narrative warnings when possible. If the read summary or review result includes \`markdownQa\`, \`vaultDiagnostics\`, or \`diagnosticReport\`, include \`Markdown QA\` and \`Vault diagnostics\` sections before artifact readiness with file/node/code/message and smallestRepair/suggestedAction. If the review result includes \`diagnostics\`, include a \`Plan and coverage diagnostics\` section with plan quality blockers/warnings, artifact \`coverageStatus\`, \`missingClaimIds\`, \`affectedClaimIds\`, stale reasons, and \`nextActions\`. If the review result includes \`evidenceCandidates\`, add a separate \`Candidate evidence bindings\` section with candidateId, slide index/title, supported claim scope, sourceKind, findingsFile/sourcePath, quote/snippet, caveat, evidenceDraft summary, unsupportedScope, and recommendedRewrite. Tell the user they may explicitly ask to apply selected candidate IDs; do not apply them during review. If candidates are absent but \`evidenceCandidateSearch\` is present, briefly report searched file counts and the best near misses so the user can tell whether review failed to search or searched but did not find a bindable match. If the reviewer returned findings, include them in a separate \`Narrative reviewer notes\` section and label them advisory.
209
211
 
210
212
  Minimum conditions for \`ready\`:
211
213
  - Topic, audience, slide count, language, and visual style/design are decided.
@@ -231,8 +233,9 @@ Report format:
231
233
  - Do not convert \`revela-narrative-reviewer\` advisory findings into tool readiness issues. Keep them separate from \`revela-decks review\` blockers and warnings, and preserve the reviewer's stable finding IDs when reporting them.
232
234
  - When reporting weak evidence, say whether the missing trace is \`findingsFile\`, \`sourcePath\`, \`location\`, \`quote\`, \`url\`, or \`caveat\` if that is clear from the reviewed materials.
233
235
  - When reporting candidate evidence bindings, distinguish partial support from full-slide support. Never say a candidate supports unrelated future-state, recommendation, roadmap, or product-vision claims unless the candidate explicitly supports those claims.
234
- - Treat \`evidenceDraft\` as a proposed record, not a mutation. Do not call \`upsertSlides\` to bind it. Only call \`revela-decks\` action \`applyEvidenceCandidates\` with explicit \`candidateIds\` if the user asks to apply candidate bindings.
236
+ - Treat \`evidenceDraft\` as a proposed record, not a mutation. Do not call \`upsertSlides\` to bind it. If the user asks to apply candidate bindings, use \`initNarrativeVault\` if needed, write \`revela-narrative/evidence/*.md\` directly with explicit source trace, then run \`compileNarrativeVault\`. Use \`upsertVaultEvidence\` only as a fallback helper when direct Markdown editing is unavailable or unsafe.
235
237
  - When reporting candidate search diagnostics, do not present near misses as evidence. Say they are below binding threshold and use them only to explain why no candidate was returned.
238
+ - When reporting vault diagnostics, do not fill missing evidence, source trace, quotes, URLs, page references, or caveats from model memory. Preserve the blocker until the Markdown source is fixed and compiled.
236
239
 
237
240
  Rules:
238
241
  - Do not write or overwrite \`decks/*.html\` during review.
package/lib/ctx.ts CHANGED
@@ -22,6 +22,6 @@ export interface RevelaCtx {
22
22
 
23
23
  /** Global singleton. Import and use directly from any module. */
24
24
  export const ctx: RevelaCtx = {
25
- enabled: false,
25
+ enabled: true,
26
26
  isResearchAgent: false,
27
27
  }