dsh-research-report 0.1.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 (71) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE +201 -0
  3. package/README.es.md +155 -0
  4. package/README.hi.md +155 -0
  5. package/README.md +155 -0
  6. package/README.pt.md +155 -0
  7. package/README.zh.md +155 -0
  8. package/THIRD_PARTY_NOTICES.md +21 -0
  9. package/cordis.patch.yml +24 -0
  10. package/lib/index.js +2143 -0
  11. package/lib/types/assemble.d.ts +123 -0
  12. package/lib/types/assemble.d.ts.map +1 -0
  13. package/lib/types/assemble.js +239 -0
  14. package/lib/types/assemble.js.map +1 -0
  15. package/lib/types/config.d.ts +48 -0
  16. package/lib/types/config.d.ts.map +1 -0
  17. package/lib/types/config.js +60 -0
  18. package/lib/types/config.js.map +1 -0
  19. package/lib/types/gather.d.ts +119 -0
  20. package/lib/types/gather.d.ts.map +1 -0
  21. package/lib/types/gather.js +165 -0
  22. package/lib/types/gather.js.map +1 -0
  23. package/lib/types/index.d.ts +51 -0
  24. package/lib/types/index.d.ts.map +1 -0
  25. package/lib/types/index.js +71 -0
  26. package/lib/types/index.js.map +1 -0
  27. package/lib/types/ledger.d.ts +159 -0
  28. package/lib/types/ledger.d.ts.map +1 -0
  29. package/lib/types/ledger.js +276 -0
  30. package/lib/types/ledger.js.map +1 -0
  31. package/lib/types/provider-local.d.ts +137 -0
  32. package/lib/types/provider-local.d.ts.map +1 -0
  33. package/lib/types/provider-local.js +418 -0
  34. package/lib/types/provider-local.js.map +1 -0
  35. package/lib/types/service.d.ts +302 -0
  36. package/lib/types/service.d.ts.map +1 -0
  37. package/lib/types/service.js +31 -0
  38. package/lib/types/service.js.map +1 -0
  39. package/lib/types/tools/evidence-add.d.ts +36 -0
  40. package/lib/types/tools/evidence-add.d.ts.map +1 -0
  41. package/lib/types/tools/evidence-add.js +107 -0
  42. package/lib/types/tools/evidence-add.js.map +1 -0
  43. package/lib/types/tools/ledger-query.d.ts +42 -0
  44. package/lib/types/tools/ledger-query.d.ts.map +1 -0
  45. package/lib/types/tools/ledger-query.js +154 -0
  46. package/lib/types/tools/ledger-query.js.map +1 -0
  47. package/lib/types/tools/research-report.d.ts +67 -0
  48. package/lib/types/tools/research-report.d.ts.map +1 -0
  49. package/lib/types/tools/research-report.js +345 -0
  50. package/lib/types/tools/research-report.js.map +1 -0
  51. package/lib/types/verify.d.ts +128 -0
  52. package/lib/types/verify.d.ts.map +1 -0
  53. package/lib/types/verify.js +208 -0
  54. package/lib/types/verify.js.map +1 -0
  55. package/lib/types/version.d.ts +7 -0
  56. package/lib/types/version.d.ts.map +1 -0
  57. package/lib/types/version.js +7 -0
  58. package/lib/types/version.js.map +1 -0
  59. package/package.json +147 -0
  60. package/src/assemble.ts +302 -0
  61. package/src/config.ts +97 -0
  62. package/src/gather.ts +239 -0
  63. package/src/index.ts +139 -0
  64. package/src/ledger.ts +344 -0
  65. package/src/provider-local.ts +489 -0
  66. package/src/service.ts +322 -0
  67. package/src/tools/evidence-add.ts +132 -0
  68. package/src/tools/ledger-query.ts +191 -0
  69. package/src/tools/research-report.ts +424 -0
  70. package/src/verify.ts +285 -0
  71. package/src/version.ts +7 -0
package/README.md ADDED
@@ -0,0 +1,155 @@
1
+ <div align="center">
2
+
3
+ # 📑 dsh-research-report
4
+
5
+ **A verifiable research-report engine for DeepSeek Harness.**
6
+
7
+ *Every claim is bound to immutable evidence snapshots, verified byte-for-byte, and sealed into a versioned report whose manifest hash anyone can recompute.*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-research-report/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-research-report/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-research-report?label=version)](https://github.com/PerryLink/dsh-research-report/releases)
14
+ [![npm version](https://img.shields.io/npm/v/dsh-research-report)](https://www.npmjs.com/package/dsh-research-report)
15
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-research-report)](https://www.npmjs.com/package/dsh-research-report)
16
+
17
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## Compatibility
24
+
25
+ - DeepSeek Harness `0.1.0-rc.6` (peers pinned to `0.1.0-rc.6`).
26
+ - Node `^22.19.0 || >=24.0.0`, ESM only (`"type": "module"`).
27
+ - Peer dependencies: `@deepseek-ai/cordis ^4.0.1`, `@deepseek-ai/schemastery ^3.18.0`, and `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-system-prompt`, `@deepseek-ai/dsh-web`, `@deepseek-ai/dsh-jobs` at `0.1.0-rc.6`.
28
+ - Optional siblings (never required): `ctx.web` providers for URL capture/gather, `ctx.jobs` for background assembly, `ctx.dataQuality` (dsh-data-quality) for dataset citation cross-checks.
29
+
30
+ ## What you get
31
+
32
+ - **Evidence ledger** — a content-addressed snapshot store (`<ledgerRoot>/objects/<sha256>` + JSONL journals). The same content is stored exactly once; snapshots are immutable; every read recomputes the hash, so tampering or deletion is detected instead of trusted.
33
+ - **Claim ↔ evidence binding** — claims register with the evidence ids they rely on; the ledger keeps the binding and every verification verdict (latest wins).
34
+ - **Byte-level verification** — every number and quoted span in a claim must be locatable verbatim in the bound snapshots. Missing citations mark the claim `unverified`; a label whose snapshot value differs (the claimed value absent) marks it `contradicted`. No semantics, no embeddings — auditable byte checks.
35
+ - **Optional numeric bridge** — when a claim cites a structured workspace dataset (CSV/JSON) and `dsh-data-quality` is mounted, citations are cross-checked with tolerances through its frozen `verifyCitations` contract.
36
+ - **Versioned sealed reports** — `<reportRoot>/<slug(topic)>/<YYYYMMDD-HHmmss>/report.md` + `manifest.json`; the seal hash is the SHA-256 of the manifest, which itself carries the report hash and every evidence hash.
37
+ - **Honest gaps** — unverified and contradicted claims keep a visible `[未核实]` / `[与证据矛盾]` marker in the report body and are listed in Appendix A. Nothing is silently passed.
38
+ - **No deep-research loop** — retrieval orchestration is deliberately reused: `ctx.web` for search/fetch, `ctx.jobs` for long runs. Planning and synthesis stay with the model (or an upstream plugin).
39
+
40
+ ## Quick start
41
+
42
+ ### git channel
43
+
44
+ ```sh
45
+ # From a scratch profile (pins the commit; runs the self-contained `prepare` build)
46
+ dsh plugin --profile demo add "github:YOUR_ORG/dsh-research-report#<sha>"
47
+ # The profile's pnpm-workspace.yaml gains an allowBuilds entry for dsh-research-report on first add.
48
+ ```
49
+
50
+ ### npm channel
51
+
52
+ ```sh
53
+ dsh plugin --profile demo add dsh-research-report
54
+ ```
55
+
56
+ Both channels install the bundle row (see `cordis.patch.yml`) into the profile's `dsh.profile.bundles` stack and take effect on restart.
57
+
58
+ Then, in a session:
59
+
60
+ ```
61
+ evidence_add({ origin: "docs/market.md", title: "Market snapshot" }) # → ev-1a2b3c4d5e6f
62
+ research_report({ topic: "示例行业概览", sections: [...], claims: [...], evidenceRefs: ["ev-1a2b…"] })
63
+ ledger_query({ claimId: "c1" }) # bindings + verdict
64
+ ```
65
+
66
+ ## Install & uninstall
67
+
68
+ ```sh
69
+ dsh plugin --profile demo add dsh-research-report # install
70
+ dsh plugin --profile demo remove dsh-research-report # uninstall
71
+ ```
72
+
73
+ Verify the row mounts: `dsh --profile demo --dump-config | grep dsh-research-report`.
74
+
75
+ ## Configuration
76
+
77
+ All tunables are Schemastery `Config` fields; invalid values fail the profile load loudly. Relative roots resolve against the harness working directory (the workspace).
78
+
79
+ | Key | Default | Description |
80
+ | --- | --- | --- |
81
+ | `enabled` | `true` | Master switch; `false` mounts nothing. |
82
+ | `ledgerRoot` | `.research-ledger` | Evidence-ledger directory (objects + JSONL journals). |
83
+ | `reportRoot` | `research-reports` | Sealed-report root (versioned per topic and timestamp). |
84
+ | `maxEvidenceBytes` | `2097152` | Hard cap on one evidence snapshot's UTF-8 bytes. |
85
+ | `maxEvidencePerReport` | `200` | Hard cap on evidence items bound into one report. |
86
+ | `fetchTimeoutMs` | `20000` | Deadline (ms) for one `ctx.web` fetch during capture. |
87
+
88
+ ## Tools & surfaces
89
+
90
+ - **`evidence_add({ origin, content?, title? })`** — register one evidence snapshot. With `content` the text is stored verbatim; without it a URL origin is fetched through `ctx.web` and a workspace-relative path is read from disk (reads never escape the workspace). Returns the evidence id and SHA-256 hash.
91
+ - **`research_report({ topic, title?, sections, claims, evidenceRefs, gather?, depth?, background? })`** — assemble and seal a report: validate (unregistered claim references are rejected loudly), verify every claim, render `report.md` with visible markers, write `manifest.json`, and return the seal hash. `gather: true` runs ONE search round over `ctx.web` and returns captured candidate evidence plus an explicit gap list — it never auto-assembles. `background: true` returns `{ kind: 'background', jobId }` over `ctx.jobs`.
92
+ - **`ledger_query({ claimId? | evidenceId? })`** — read-only binding/verdict queries; evidence is re-hashed on read so a tampered or missing snapshot is reported explicitly. With no id, returns a ledger summary.
93
+ - **`ctx.researchReport.assemble(request)`** — the frozen service surface for sibling plugins (see `src/service.ts`; gated byte-for-byte by `scripts/verify-frozen-contract.mjs`).
94
+
95
+ ## Permissions & data
96
+
97
+ `dsh-research-report` consumes only public seams: `ctx.tools`, `ctx.systemPrompt`, and optionally `ctx.web` / `ctx.jobs` / `ctx.dataQuality` (looked up at call time, never injected). It writes only inside the configured ledger and report roots (both default to workspace-local directories), reads workspace files only inside the workspace, and reaches the network exclusively through the harness web seam — never a direct `fetch`. Evidence snapshots are immutable and content-addressed; claim registrations are immutable; verdicts are append-only.
98
+
99
+ ## Security boundaries
100
+
101
+ - **Tamper-evidence by construction** — every snapshot read recomputes SHA-256 against the index; a mismatch verifies the bound claims `contradicted` and `ledger_query` reports `integrity: tampered`/`missing`.
102
+ - **Workspace confinement** — local evidence reads resolve against the workspace root and refuse escapes (both sides are `path.resolve`d before comparison).
103
+ - **Fail-loud configuration** — invalid bounds throw at mount; unregistered claim references, unknown evidence ids, and id/content conflicts throw at assemble.
104
+ - **No credential handling, no hidden network** — URL capture rides `ctx.web` (provider selection, error taxonomy, and any SSRF policy stay with the deployment's web providers).
105
+ - **Reversible registrations** — every contribution goes through `ctx.effect()` / `register()`, so uninstall and hot reload are clean.
106
+
107
+ ## Known limitations
108
+
109
+ - **Byte-level, not semantic** — the built-in check locates number/quote literals verbatim; paraphrased claims without a checkable literal verify as `unverified`, and a true claim whose number is absent while its label appears with a different value reads `contradicted`. This is a deliberate v1 choice (auditable beats clever).
110
+ - **Session events are adaptive** — the plugin declares typed `research-report/evidence`, `research-report/verify`, and `research-report/seal` session events, but rc.6's `Session.append` has no `ignorable` marker and no plugin event-registration surface, so appends activate only when the host build knows the types (otherwise the persistence layer would refuse the log on restore). The ledger journals are always the durable source of truth.
111
+ - **Default profiles mount no fetch provider** — the shipped `dsh-base` mounts search only, so URL capture fails loud (`WEB_UNAVAILABLE`/`WEB_PROVIDER_UNAVAILABLE`) until a fetch provider is configured; search-based `gather` lists uncaptured sources in the gap list.
112
+ - **Single-workspace scope** — ledger and report roots resolve against the harness working directory at mount; multi-workspace deployments should configure absolute roots per profile.
113
+
114
+ ## Development
115
+
116
+ ```sh
117
+ pnpm install
118
+ pnpm run typecheck && pnpm run typecheck:ci
119
+ pnpm test
120
+ pnpm run build
121
+ pnpm run verify:self-contained && pnpm run verify:artifacts
122
+ node scripts/check-readme-sync.mjs
123
+ node scripts/verify-frozen-contract.mjs
124
+ pnpm pack
125
+ ```
126
+
127
+ - `typecheck` resolves `@deepseek-ai/*` through the installed 0.1.0-rc.6 peers; `typecheck:ci` clears `skipLibCheck` and enables `verbatimModuleSyntax` against the published types. Both must stay green.
128
+ - Tests use the real `Context`/`Session`/`ToolRuntime`/`LocalJobRegistry`/`WebRuntime` from the 0.1.0-rc.6 peers; only network backends are scripted providers registered through the real `ctx.web` registries.
129
+ - Release: `node scripts/release.mjs <x.y.z>` (bumps, stamps CHANGELOG, re-runs the gate, commits + tags; never pushes).
130
+
131
+ ## Topics
132
+
133
+ `dsh`, `dsh-plugin`, `deepseek-harness`, `cordis`, `research`, `evidence-ledger`, `verifiable-report`, `audit`, `citation-verification`
134
+
135
+ ## Contributors
136
+
137
+ `dsh-research-report` contributors.
138
+
139
+ ## PerryLink DSH Plugin Family
140
+
141
+ This project is one of the DeepSeek Harness plugins maintained by [PerryLink](https://github.com/PerryLink). If this one helps you, the others likely will too:
142
+
143
+ | Plugin | One-liner |
144
+ |---|---|
145
+ | [dsh-data-quality](https://github.com/PerryLink/dsh-data-quality) | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) |
146
+ | [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | Engineering-discipline guard: requirements grill, test gates, adversary review |
147
+ | [dsh-fast](https://github.com/PerryLink/dsh-fast) | Read-only performance diagnostics for DeepSeek Harness. |
148
+ | [dsh-industry-research](https://github.com/PerryLink/dsh-industry-research) | Industry research orchestration that seals its deliverables through this plugin's `ctx.researchReport.assemble` |
149
+ | [dsh-memento](https://github.com/PerryLink/dsh-memento) | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool |
150
+ | [dsh-score](https://github.com/PerryLink/dsh-score) | Multi-dimensional quality scoring for DeepSeek Harness plugins. |
151
+ | [dsh-test-drive](https://github.com/PerryLink/dsh-test-drive) | Isolated install-and-smoke test drives for DeepSeek Harness plugins. |
152
+
153
+ ## License
154
+
155
+ Apache-2.0 — see [LICENSE](LICENSE).
package/README.pt.md ADDED
@@ -0,0 +1,155 @@
1
+ <div align="center">
2
+
3
+ # 📑 dsh-research-report
4
+
5
+ **Um motor de relatórios de pesquisa verificáveis para DeepSeek Harness.**
6
+
7
+ *Cada afirmação (claim) fica vinculada a snapshots de evidência imutáveis, é verificada byte a byte e é selada num relatório versionado cujo hash de manifesto qualquer pessoa pode recomputar.*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-research-report/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-research-report/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-research-report?label=version)](https://github.com/PerryLink/dsh-research-report/releases)
14
+ [![npm version](https://img.shields.io/npm/v/dsh-research-report)](https://www.npmjs.com/package/dsh-research-report)
15
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-research-report)](https://www.npmjs.com/package/dsh-research-report)
16
+
17
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## Compatibility
24
+
25
+ - DeepSeek Harness `0.1.0-rc.6` (peers fixados em `0.1.0-rc.6`).
26
+ - Node `^22.19.0 || >=24.0.0`, apenas ESM (`"type": "module"`).
27
+ - Dependências peer: `@deepseek-ai/cordis ^4.0.1`, `@deepseek-ai/schemastery ^3.18.0`, e `@deepseek-ai/dsh-session`, `@deepseek-ai/dsh-tools`, `@deepseek-ai/dsh-system-prompt`, `@deepseek-ai/dsh-web`, `@deepseek-ai/dsh-jobs` em `0.1.0-rc.6`.
28
+ - Irmãos opcionais (nunca obrigatórios): providers de `ctx.web` para captura de URL/coleta, `ctx.jobs` para montagem em segundo plano, `ctx.dataQuality` (dsh-data-quality) para verificação de citações em datasets.
29
+
30
+ ## What you get
31
+
32
+ - **Livro-razão de evidência** — armazenamento de snapshots endereçado por conteúdo (`<ledgerRoot>/objects/<sha256>` + diários JSONL). O mesmo conteúdo é guardado exatamente uma vez; snapshots são imutáveis; cada leitura recomputa o hash, de modo que adulteração ou remoção é detetada em vez de confiada.
33
+ - **Vínculo claim ↔ evidência** — claims registam-se com os ids de evidência em que se apoiam; o livro guarda o vínculo e cada veredito de verificação (o mais recente vence).
34
+ - **Verificação ao nível do byte** — cada número e cada trecho entre aspas de um claim tem de ser localizável literalmente nos snapshots vinculados. Citações em falta marcam o claim como `unverified`; um rótulo cujo valor difere no snapshot (estando o valor citado ausente) marca-o como `contradicted`. Sem semântica, sem embeddings — apenas verificações de bytes auditáveis.
35
+ - **Ponte numérica opcional** — quando um claim cita um dataset estruturado do workspace (CSV/JSON) e o `dsh-data-quality` está montado, as citações são verificadas com tolerâncias através do seu contrato congelado `verifyCitations`.
36
+ - **Relatórios selados versionados** — `<reportRoot>/<slug(topic)>/<YYYYMMDD-HHmmss>/report.md` + `manifest.json`; o hash de selo é o SHA-256 do manifesto, que por sua vez carrega o hash do relatório e os hashes de toda a evidência.
37
+ - **Lacunas honestas** — claims não verificados ou contraditos mantêm uma marca visível `[未核实]` / `[与证据矛盾]` no corpo do relatório e são listados no Apêndice A. Nada passa em silêncio.
38
+ - **Sem ciclo de deep-research** — a orquestração de recuperação é deliberadamente reutilizada: `ctx.web` para pesquisa/download, `ctx.jobs` para trabalhos longos. Planeamento e síntese ficam com o modelo (ou um plugin a montante).
39
+
40
+ ## Quick start
41
+
42
+ ### Canal git
43
+
44
+ ```sh
45
+ # A partir de um profile de teste (fixa o commit; executa o build `prepare` autossuficiente)
46
+ dsh plugin --profile demo add "github:YOUR_ORG/dsh-research-report#<sha>"
47
+ # O primeiro add acrescenta uma entrada allowBuilds para dsh-research-report no pnpm-workspace.yaml do profile.
48
+ ```
49
+
50
+ ### Canal npm
51
+
52
+ ```sh
53
+ dsh plugin --profile demo add dsh-research-report
54
+ ```
55
+
56
+ Ambos os canais instalam a linha do bundle (ver `cordis.patch.yml`) na pilha `dsh.profile.bundles` do profile e entram em vigor após reiniciar.
57
+
58
+ Depois, numa sessão:
59
+
60
+ ```
61
+ evidence_add({ origin: "docs/market.md", title: "Market snapshot" }) # → ev-1a2b3c4d5e6f
62
+ research_report({ topic: "示例行业概览", sections: [...], claims: [...], evidenceRefs: ["ev-1a2b…"] })
63
+ ledger_query({ claimId: "c1" }) # vínculos + veredito
64
+ ```
65
+
66
+ ## Install & uninstall
67
+
68
+ ```sh
69
+ dsh plugin --profile demo add dsh-research-report # instalar
70
+ dsh plugin --profile demo remove dsh-research-report # desinstalar
71
+ ```
72
+
73
+ Verifica que a linha monta: `dsh --profile demo --dump-config | grep dsh-research-report`.
74
+
75
+ ## Configuration
76
+
77
+ Todos os ajustes são campos `Config` de Schemastery; valores inválidos falham ruidosamente no carregamento do profile. Raízes relativas resolvem contra o diretório de trabalho do harness (o workspace).
78
+
79
+ | Key | Default | Description |
80
+ | --- | --- | --- |
81
+ | `enabled` | `true` | Interruptor mestre; `false` não monta nada. |
82
+ | `ledgerRoot` | `.research-ledger` | Diretório do livro de evidência (objetos + diários JSONL). |
83
+ | `reportRoot` | `research-reports` | Raiz dos relatórios selados (versionados por tópico e timestamp). |
84
+ | `maxEvidenceBytes` | `2097152` | Teto rígido de bytes UTF-8 por snapshot de evidência. |
85
+ | `maxEvidencePerReport` | `200` | Teto rígido de evidências vinculadas a um relatório. |
86
+ | `fetchTimeoutMs` | `20000` | Prazo (ms) de cada `ctx.web` fetch durante a captura. |
87
+
88
+ ## Tools & surfaces
89
+
90
+ - **`evidence_add({ origin, content?, title? })`** — regista um snapshot de evidência. Com `content`, o texto é guardado literal; sem ele, uma origem URL é descarregada via `ctx.web` e um caminho relativo do workspace é lido do disco (leituras nunca escapam do workspace). Devolve o id da evidência e o hash SHA-256.
91
+ - **`research_report({ topic, title?, sections, claims, evidenceRefs, gather?, depth?, background? })`** — monta e sela um relatório: valida (referências a claims não registados são rejeitadas ruidosamente), verifica cada claim, renderiza `report.md` com marcas visíveis, escreve `manifest.json` e devolve o hash de selo. `gather: true` executa UMA ronda de pesquisa sobre `ctx.web` e devolve evidência candidata capturada mais uma lista explícita de lacunas — nunca monta automaticamente. `background: true` devolve `{ kind: 'background', jobId }` sobre `ctx.jobs`.
92
+ - **`ledger_query({ claimId? | evidenceId? })`** — consultas só de leitura de vínculos/vereditos; a evidência é re-hasheada na leitura, por isso um snapshot adulterado ou em falta é reportado explicitamente. Sem id, devolve um resumo do livro.
93
+ - **`ctx.researchReport.assemble(request)`** — a superfície de serviço congelada para plugins irmãos (ver `src/service.ts`; protegida byte a byte por `scripts/verify-frozen-contract.mjs`).
94
+
95
+ ## Permissions & data
96
+
97
+ `dsh-research-report` consome apenas seams públicos: `ctx.tools`, `ctx.systemPrompt`, e opcionalmente `ctx.web` / `ctx.jobs` / `ctx.dataQuality` (consultados no momento da chamada, nunca injetados). Escreve apenas dentro das raízes configuradas de livro e relatórios (ambas por omissão diretórios locais do workspace), lê ficheiros do workspace apenas dentro do workspace, e acede à rede exclusivamente através do seam web do harness — nunca um `fetch` direto. Snapshots de evidência são imutáveis e endereçados por conteúdo; registos de claims são imutáveis; vereditos são apenas de anexação.
98
+
99
+ ## Security boundaries
100
+
101
+ - **Evidência de adulteração por construção** — cada leitura de snapshot recomputa o SHA-256 contra o índice; uma discrepância verifica os claims vinculados como `contradicted` e o `ledger_query` reporta `integrity: tampered`/`missing`.
102
+ - **Confinamento ao workspace** — leituras locais de evidência resolvem contra a raiz do workspace e recusam escapes (ambos os lados passam por `path.resolve` antes de comparar).
103
+ - **Configuração que falha ruidosamente** — limites inválidos lançam no mount; referências a claims não registados, ids de evidência desconhecidos e conflitos id/conteúdo lançam na montagem.
104
+ - **Sem gestão de credenciais, sem rede oculta** — a captura de URLs passa por `ctx.web` (seleção de provider, taxonomia de erros e qualquer política SSRF ficam nos providers web do deployment).
105
+ - **Registos reversíveis** — cada contribuição passa por `ctx.effect()` / `register()`, logo desinstalação e hot reload são limpos.
106
+
107
+ ## Known limitations
108
+
109
+ - **Ao nível do byte, não semântico** — a verificação incorporada localiza literais numéricos/entre aspas verbatim; claims parafraseados sem literal verificável ficam `unverified`, e um claim verdadeiro cujo número está ausente enquanto o seu rótulo aparece com outro valor fica `contradicted`. É uma escolha deliberada da v1 (auditável acima de inteligente).
110
+ - **Eventos de sessão adaptativos** — o plugin declara os eventos de sessão tipados `research-report/evidence`, `research-report/verify` e `research-report/seal`, mas o `Session.append` de rc.6 não tem marcador `ignorable` nem superficie de registo de eventos para plugins, por isso os appends só ativam quando o build do host conhece os tipos (caso contrário a camada de persistência recusaria o log no restore). Os diários do livro são sempre a fonte durável da verdade.
111
+ - **Profiles por omissão não montam provider de fetch** — o `dsh-base` distribuído monta apenas pesquisa, por isso a captura de URLs falha ruidosamente (`WEB_UNAVAILABLE`/`WEB_PROVIDER_UNAVAILABLE`) até configurar um provider de fetch; o `gather` baseado em pesquisa lista as fontes não capturadas na lista de lacunas.
112
+ - **Âmbito de um só workspace** — as raízes de livro e relatórios resolvem contra o diretório de trabalho do harness no mount; deployments multi-workspace devem configurar raízes absolutas por profile.
113
+
114
+ ## Development
115
+
116
+ ```sh
117
+ pnpm install
118
+ pnpm run typecheck && pnpm run typecheck:ci
119
+ pnpm test
120
+ pnpm run build
121
+ pnpm run verify:self-contained && pnpm run verify:artifacts
122
+ node scripts/check-readme-sync.mjs
123
+ node scripts/verify-frozen-contract.mjs
124
+ pnpm pack
125
+ ```
126
+
127
+ - `typecheck` resolve `@deepseek-ai/*` através dos peers 0.1.0-rc.6 instalados; `typecheck:ci` desativa `skipLibCheck` e ativa `verbatimModuleSyntax` contra os tipos publicados. Ambos têm de ficar verdes.
128
+ - Os testes usam os `Context`/`Session`/`ToolRuntime`/`LocalJobRegistry`/`WebRuntime` reais dos peers 0.1.0-rc.6; apenas os backends de rede são providers scriptados registados através dos registos reais de `ctx.web`.
129
+ - Release: `node scripts/release.mjs <x.y.z>` (sobe versão, carimba CHANGELOG, re-executa a gate, commita + etiqueta; nunca faz push).
130
+
131
+ ## Topics
132
+
133
+ `dsh`, `dsh-plugin`, `deepseek-harness`, `cordis`, `research`, `evidence-ledger`, `verifiable-report`, `audit`, `citation-verification`
134
+
135
+ ## Contributors
136
+
137
+ Contribuidores de `dsh-research-report`.
138
+
139
+ ## PerryLink DSH Plugin Family
140
+
141
+ Este projeto é um dos plugins de DeepSeek Harness mantidos por [PerryLink](https://github.com/PerryLink). Se este te ajuda, os outros provavelmente também:
142
+
143
+ | Plugin | One-liner |
144
+ |---|---|
145
+ | [dsh-data-quality](https://github.com/PerryLink/dsh-data-quality) | Verificações de qualidade de datasets e verificação de citações (a ponte numérica opcional consumida aqui) |
146
+ | [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | Guarda de disciplina de engenharia: interrogatório de requisitos, gates de testes, revisão adversarial |
147
+ | [dsh-fast](https://github.com/PerryLink/dsh-fast) | Diagnóstico de desempenho só de leitura para DeepSeek Harness. |
148
+ | [dsh-industry-research](https://github.com/PerryLink/dsh-industry-research) | Orquestração de pesquisa setorial que sela as suas entregas através do `ctx.researchReport.assemble` deste plugin |
149
+ | [dsh-memento](https://github.com/PerryLink/dsh-memento) | Memória entre sessões com porta de aprovação: seam ctx.memory + SQLite + ferramenta memory |
150
+ | [dsh-score](https://github.com/PerryLink/dsh-score) | Pontuação de qualidade multidimensional para plugins de DeepSeek Harness. |
151
+ | [dsh-test-drive](https://github.com/PerryLink/dsh-test-drive) | Test drives isolados de instalação e smoke para plugins de DeepSeek Harness. |
152
+
153
+ ## License
154
+
155
+ Apache-2.0 — ver [LICENSE](LICENSE).
package/README.zh.md ADDED
@@ -0,0 +1,155 @@
1
+ <div align="center">
2
+
3
+ # 📑 dsh-research-report
4
+
5
+ **DeepSeek Harness 的可核查研究报告引擎。**
6
+
7
+ *每条结论(claim)都绑定到不可变的证据快照,逐字节核查,并封存进版本化报告——其 manifest 哈希任何人都可重算验证。*
8
+
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-research-report/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-research-report/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-research-report?label=version)](https://github.com/PerryLink/dsh-research-report/releases)
14
+ [![npm version](https://img.shields.io/npm/v/dsh-research-report)](https://www.npmjs.com/package/dsh-research-report)
15
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-research-report)](https://www.npmjs.com/package/dsh-research-report)
16
+
17
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## Compatibility
24
+
25
+ - DeepSeek Harness `0.1.0-rc.6`(peer 依赖钉版 `0.1.0-rc.6`)。
26
+ - Node `^22.19.0 || >=24.0.0`,仅 ESM(`"type": "module"`)。
27
+ - Peer 依赖:`@deepseek-ai/cordis ^4.0.1`、`@deepseek-ai/schemastery ^3.18.0`,以及 `0.1.0-rc.6` 的 `@deepseek-ai/dsh-session`、`@deepseek-ai/dsh-tools`、`@deepseek-ai/dsh-system-prompt`、`@deepseek-ai/dsh-web`、`@deepseek-ai/dsh-jobs`。
28
+ - 可选协同(绝不强制):URL 抓取/检索用 `ctx.web` provider;后台组装用 `ctx.jobs`;数据集引文核查用 `ctx.dataQuality`(dsh-data-quality)。
29
+
30
+ ## What you get
31
+
32
+ - **证据账本**——内容寻址快照存储(`<ledgerRoot>/objects/<sha256>` + JSONL 日志)。同一内容只存一份;快照不可变;每次读取都重算哈希——篡改或删除会被发现,而不是被信任。
33
+ - **claim ↔ 证据绑定**——claim 登记时声明其依赖的证据 id;账本保存绑定关系与每一次核查结论(最新为准)。
34
+ - **字节级核查**——claim 文本中的每个数字与引文子串都必须能在其绑定快照中字面定位。定位不到 → `unverified`;标签在快照中对应不同数值(且声称值不存在)→ `contradicted`。不做语义理解、不做向量相似——只做可审计的字节核对。
35
+ - **可选数字核查桥**——当 claim 引用 workspace 内结构化数据集(CSV/JSON)且 `dsh-data-quality` 已挂载时,经其冻结的 `verifyCitations` 契约做容差核对。
36
+ - **版本化封存报告**——`<reportRoot>/<slug(topic)>/<YYYYMMDD-HHmmss>/report.md` + `manifest.json`;封印哈希 = manifest 的 SHA-256,manifest 内含报告哈希与全部证据哈希。
37
+ - **诚实缺口**——未核实/有矛盾的 claim 在正文中保留醒目标记 `[未核实]` / `[与证据矛盾]`,并在附录 A 列明。绝不静默通过。
38
+ - **不做深研循环**——检索编排刻意复用官方底座:搜索/抓取走 `ctx.web`,长任务走 `ctx.jobs`。规划与综合交给模型(或上游插件)。
39
+
40
+ ## Quick start
41
+
42
+ ### git 通道
43
+
44
+ ```sh
45
+ # 在 scratch profile 中(钉住 commit;运行自包含的 `prepare` 构建)
46
+ dsh plugin --profile demo add "github:YOUR_ORG/dsh-research-report#<sha>"
47
+ # 首次 add 时,profile 的 pnpm-workspace.yaml 会增加 dsh-research-report 的 allowBuilds 条目。
48
+ ```
49
+
50
+ ### npm 通道
51
+
52
+ ```sh
53
+ dsh plugin --profile demo add dsh-research-report
54
+ ```
55
+
56
+ 两条通道都会把 bundle 行(见 `cordis.patch.yml`)装入 profile 的 `dsh.profile.bundles` 层栈,**重启生效**。
57
+
58
+ 然后,在会话中:
59
+
60
+ ```
61
+ evidence_add({ origin: "docs/market.md", title: "市场快照" }) # → ev-1a2b3c4d5e6f
62
+ research_report({ topic: "示例行业概览", sections: [...], claims: [...], evidenceRefs: ["ev-1a2b…"] })
63
+ ledger_query({ claimId: "c1" }) # 绑定关系 + 核查结论
64
+ ```
65
+
66
+ ## Install & uninstall
67
+
68
+ ```sh
69
+ dsh plugin --profile demo add dsh-research-report # 安装
70
+ dsh plugin --profile demo remove dsh-research-report # 卸载
71
+ ```
72
+
73
+ 验证行已挂载:`dsh --profile demo --dump-config | grep dsh-research-report`。
74
+
75
+ ## Configuration
76
+
77
+ 全部可调项都是 Schemastery `Config` 字段;非法值在加载期响亮失败。相对路径根目录相对 harness 工作目录(workspace)解析。
78
+
79
+ | Key | Default | Description |
80
+ | --- | --- | --- |
81
+ | `enabled` | `true` | 总开关;`false` 时什么都不挂载。 |
82
+ | `ledgerRoot` | `.research-ledger` | 证据账本目录(对象 + JSONL 日志)。 |
83
+ | `reportRoot` | `research-reports` | 封存报告根目录(按主题 + 时间戳版本化)。 |
84
+ | `maxEvidenceBytes` | `2097152` | 单条证据快照的 UTF-8 字节硬上限。 |
85
+ | `maxEvidencePerReport` | `200` | 单份报告可绑定证据条数硬上限。 |
86
+ | `fetchTimeoutMs` | `20000` | 抓取时单次 `ctx.web` fetch 的超时(毫秒)。 |
87
+
88
+ ## Tools & surfaces
89
+
90
+ - **`evidence_add({ origin, content?, title? })`**——登记一条证据。给 `content` 则按原文存储;不给时 URL 源经 `ctx.web` 抓取、workspace 相对路径从磁盘读取(读取绝不逃逸 workspace)。返回证据 id 与 SHA-256 哈希。
91
+ - **`research_report({ topic, title?, sections, claims, evidenceRefs, gather?, depth?, background? })`**——组装并封存报告:校验(claim 引用不全响亮拒绝)→ 逐条核查 → 渲染带醒目标记的 `report.md` → 写 `manifest.json` → 返回封印哈希。`gather: true` 先经 `ctx.web` 做一轮检索,返回已捕获候选证据与显式缺口清单——绝不自动成稿。`background: true` 经 `ctx.jobs` 返回 `{ kind: 'background', jobId }`。
92
+ - **`ledger_query({ claimId? | evidenceId? })`**——只读查询绑定关系与核查结论;证据读取时重算哈希,篡改/丢失会显式报告。不带 id 时返回账本摘要。
93
+ - **`ctx.researchReport.assemble(request)`**——面向兄弟插件的冻结服务表面(见 `src/service.ts`;由 `scripts/verify-frozen-contract.mjs` 逐字节门禁)。
94
+
95
+ ## Permissions & data
96
+
97
+ `dsh-research-report` 只消费公开 seam:`ctx.tools`、`ctx.systemPrompt`,以及可选的 `ctx.web` / `ctx.jobs` / `ctx.dataQuality`(调用时经 `ctx.get` 判空使用,绝不写入 inject)。写入只发生在配置的账本与报告根目录内(默认都是 workspace 本地目录);本地文件读取不越出 workspace;网络访问只经 harness web seam——绝不直接 `fetch`。证据快照不可变且内容寻址;claim 登记不可变;核查结论只追加。
98
+
99
+ ## Security boundaries
100
+
101
+ - **构造级防篡改**——每次快照读取都对照索引重算 SHA-256;不匹配时绑定 claim 核查为 `contradicted`,`ledger_query` 报告 `integrity: tampered`/`missing`。
102
+ - **workspace 限制**——本地证据读取相对 workspace 根解析并拒绝逃逸(比较前两侧都经 `path.resolve`)。
103
+ - **配置响亮失败**——非法边界在挂载期抛错;claim 引用不全、未知证据 id、id/内容冲突在组装期抛错。
104
+ - **不碰凭据、无隐藏网络**——URL 抓取走 `ctx.web`(provider 选择、错误分类、SSRF 策略都留在部署方的 web provider)。
105
+ - **注册可逆**——所有贡献经 `ctx.effect()` / `register()`,卸载与热重载干净。
106
+
107
+ ## Known limitations
108
+
109
+ - **字节级而非语义级**——内置核查只做数字/引文字面定位;没有可核查字面量的转述性 claim 判 `unverified`;声称值缺失而标签对应其他数值时判 `contradicted`。这是 v1 的刻意选择(可审计优先于聪明)。
110
+ - **会话事件自适应**——插件声明了类型化的 `research-report/evidence`、`research-report/verify`、`research-report/seal` 会话事件,但 rc.6 的 `Session.append` 没有 `ignorable` 标记、也没有插件事件注册面,所以只有宿主 build 认识这些类型时才真正落盘(否则持久化层会在恢复时拒绝该日志)。账本日志始终是权威的持久事实源。
111
+ - **默认 profile 不挂载 fetch provider**——官方 `dsh-base` 只挂搜索,所以配置 fetch provider 之前 URL 抓取会响亮失败(`WEB_UNAVAILABLE`/`WEB_PROVIDER_UNAVAILABLE`);基于搜索的 `gather` 会把未捕获的来源列入缺口清单。
112
+ - **单 workspace 作用域**——账本与报告根目录在挂载时相对 harness 工作目录解析;多 workspace 部署应在各 profile 配置绝对路径。
113
+
114
+ ## Development
115
+
116
+ ```sh
117
+ pnpm install
118
+ pnpm run typecheck && pnpm run typecheck:ci
119
+ pnpm test
120
+ pnpm run build
121
+ pnpm run verify:self-contained && pnpm run verify:artifacts
122
+ node scripts/check-readme-sync.mjs
123
+ node scripts/verify-frozen-contract.mjs
124
+ pnpm pack
125
+ ```
126
+
127
+ - `typecheck` 经已安装的 0.1.0-rc.6 peer 解析 `@deepseek-ai/*`;`typecheck:ci` 关闭 `skipLibCheck` 并开启 `verbatimModuleSyntax` 对照已发布类型。两者都必须保持绿。
128
+ - 测试使用 0.1.0-rc.6 peer 的真实 `Context`/`Session`/`ToolRuntime`/`LocalJobRegistry`/`WebRuntime`;只有网络后端是注册进真实 `ctx.web` 注册表的脚本化 provider。
129
+ - 发布:`node scripts/release.mjs <x.y.z>`(bump、盖 CHANGELOG、重跑门禁、提交 + 打 tag;绝不 push)。
130
+
131
+ ## Topics
132
+
133
+ `dsh`、`dsh-plugin`、`deepseek-harness`、`cordis`、`research`、`evidence-ledger`、`verifiable-report`、`audit`、`citation-verification`
134
+
135
+ ## Contributors
136
+
137
+ `dsh-research-report` contributors。
138
+
139
+ ## PerryLink DSH Plugin Family
140
+
141
+ 本项目是 [PerryLink](https://github.com/PerryLink) 维护的 DeepSeek Harness 插件家族成员。如果它对你有帮助,其他成员大概率也有用:
142
+
143
+ | Plugin | One-liner |
144
+ |---|---|
145
+ | [dsh-data-quality](https://github.com/PerryLink/dsh-data-quality) | 数据集质量检查与引文核查(本插件可选消费的数字核查桥) |
146
+ | [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | 工程纪律守卫:需求拷问、测试门禁、对抗性复核 |
147
+ | [dsh-fast](https://github.com/PerryLink/dsh-fast) | DeepSeek Harness 只读性能诊断。 |
148
+ | [dsh-industry-research](https://github.com/PerryLink/dsh-industry-research) | 行业研究编排,经本插件的 `ctx.researchReport.assemble` 封存交付物 |
149
+ | [dsh-memento](https://github.com/PerryLink/dsh-memento) | 审批门跨会话记忆:ctx.memory seam + SQLite + memory 工具 |
150
+ | [dsh-score](https://github.com/PerryLink/dsh-score) | DeepSeek Harness 插件的多维质量评分。 |
151
+ | [dsh-test-drive](https://github.com/PerryLink/dsh-test-drive) | DeepSeek Harness 插件的隔离试装冒烟。 |
152
+
153
+ ## License
154
+
155
+ Apache-2.0 — 见 [LICENSE](LICENSE)。
@@ -0,0 +1,21 @@
1
+ # Third-party notices
2
+
3
+ `dsh-research-report` bundles no third-party source code. All
4
+ TypeScript/JavaScript sources in this repository are original works by the
5
+ dsh-research-report contributors, licensed under Apache-2.0 (see `LICENSE`).
6
+
7
+ The package depends on the following software. None of it is bundled into the
8
+ published tarball except where noted; these are install-time dependencies:
9
+
10
+ | Package | Version range | License | Purpose |
11
+ |---|---|---|---|
12
+ | [tsdown](https://github.com/rolldown/tsdown) | `^0.22.14` | MIT | Build-time bundling of `lib/` (a regular dependency so the git-install channel's `prepare` script can build) |
13
+ | [typescript](https://github.com/microsoft/TypeScript) | `^5.9.0` | Apache-2.0 | Build-time declaration emission (`lib/types/`) |
14
+ | [@deepseek-ai/cordis](https://www.npmjs.com/package/@deepseek-ai/cordis) | `^4.0.1` (peer) | See package | The plugin runtime |
15
+ | [@deepseek-ai/schemastery](https://www.npmjs.com/package/@deepseek-ai/schemastery) | `^3.18.0` (peer) | See package | Configuration schema |
16
+ | `@deepseek-ai/dsh-*` peers | `0.1.0-rc.6` (peer) | See packages | Official harness seams (`dsh-session`, `dsh-tools`, `dsh-system-prompt`, `dsh-web`, `dsh-jobs`) |
17
+
18
+ At runtime the plugin talks only to the harness services listed as
19
+ peerDependencies (plus the optional `ctx.dataQuality` sibling, consumed
20
+ structurally through `ctx.get`); it performs no direct network requests and
21
+ stores no credentials. Hashing uses `node:crypto` only.
@@ -0,0 +1,24 @@
1
+ # dsh-research-report bundle patch: mount the verifiable research-report engine.
2
+ #
3
+ # Every key below is a Config field (Schemastery schema); invalid values fail
4
+ # the profile load loudly. See README.md "Configuration" for the full table.
5
+ # The plugin writes only inside the workspace (ledger + sealed reports), so it
6
+ # defaults to enabled.
7
+ - insert:
8
+ - id: dsh-research-report
9
+ name: dsh-research-report
10
+ config:
11
+ # Master switch. On by default; `false` mounts nothing at all.
12
+ enabled: true
13
+ # Evidence ledger directory (content-addressed objects + JSONL index),
14
+ # resolved against the harness working directory when relative.
15
+ ledgerRoot: .research-ledger
16
+ # Sealed-report root; each assemble writes
17
+ # <reportRoot>/<slug(topic)>/<YYYYMMDD-HHmmss>/{report.md,manifest.json}.
18
+ reportRoot: research-reports
19
+ # Hard cap on one evidence snapshot's UTF-8 byte size.
20
+ maxEvidenceBytes: 2097152
21
+ # Hard cap on how many evidence items one report may bind.
22
+ maxEvidencePerReport: 200
23
+ # Deadline (ms) for one ctx.web fetch during evidence capture.
24
+ fetchTimeoutMs: 20000