@researai/deepscientist 1.5.0 → 1.5.1

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 (163) hide show
  1. package/AGENTS.md +26 -0
  2. package/README.md +19 -179
  3. package/assets/connectors/lingzhu/openclaw-bridge/README.md +124 -0
  4. package/assets/connectors/lingzhu/openclaw-bridge/index.ts +162 -0
  5. package/assets/connectors/lingzhu/openclaw-bridge/openclaw.plugin.json +145 -0
  6. package/assets/connectors/lingzhu/openclaw-bridge/package.json +35 -0
  7. package/assets/connectors/lingzhu/openclaw-bridge/src/cli.ts +180 -0
  8. package/assets/connectors/lingzhu/openclaw-bridge/src/config.ts +196 -0
  9. package/assets/connectors/lingzhu/openclaw-bridge/src/debug-log.ts +111 -0
  10. package/assets/connectors/lingzhu/openclaw-bridge/src/events.ts +4 -0
  11. package/assets/connectors/lingzhu/openclaw-bridge/src/http-handler.ts +1133 -0
  12. package/assets/connectors/lingzhu/openclaw-bridge/src/image-cache.ts +75 -0
  13. package/assets/connectors/lingzhu/openclaw-bridge/src/lingzhu-tools.ts +246 -0
  14. package/assets/connectors/lingzhu/openclaw-bridge/src/transform.ts +541 -0
  15. package/assets/connectors/lingzhu/openclaw-bridge/src/types.ts +131 -0
  16. package/assets/connectors/lingzhu/openclaw-bridge/tsconfig.json +14 -0
  17. package/assets/connectors/lingzhu/openclaw.lingzhu.config.template.json +39 -0
  18. package/bin/ds.js +233 -53
  19. package/docs/en/00_QUICK_START.md +134 -0
  20. package/docs/en/01_SETTINGS_REFERENCE.md +1104 -0
  21. package/docs/en/02_START_RESEARCH_GUIDE.md +404 -0
  22. package/docs/en/03_QQ_CONNECTOR_GUIDE.md +325 -0
  23. package/docs/en/04_LINGZHU_CONNECTOR_GUIDE.md +216 -0
  24. package/docs/en/05_TUI_GUIDE.md +141 -0
  25. package/docs/en/06_RUNTIME_AND_CANVAS.md +679 -0
  26. package/docs/en/07_MEMORY_AND_MCP.md +253 -0
  27. package/docs/en/08_FIGURE_STYLE_GUIDE.md +97 -0
  28. package/docs/en/09_DOCTOR.md +108 -0
  29. package/docs/en/90_ARCHITECTURE.md +245 -0
  30. package/docs/en/91_DEVELOPMENT.md +195 -0
  31. package/docs/en/99_ACKNOWLEDGEMENTS.md +29 -0
  32. package/docs/zh/00_QUICK_START.md +134 -0
  33. package/docs/zh/01_SETTINGS_REFERENCE.md +1137 -0
  34. package/docs/zh/02_START_RESEARCH_GUIDE.md +414 -0
  35. package/docs/zh/03_QQ_CONNECTOR_GUIDE.md +324 -0
  36. package/docs/zh/04_LINGZHU_CONNECTOR_GUIDE.md +230 -0
  37. package/docs/zh/05_TUI_GUIDE.md +128 -0
  38. package/docs/zh/06_RUNTIME_AND_CANVAS.md +271 -0
  39. package/docs/zh/07_MEMORY_AND_MCP.md +235 -0
  40. package/docs/zh/08_FIGURE_STYLE_GUIDE.md +97 -0
  41. package/docs/zh/09_DOCTOR.md +112 -0
  42. package/docs/zh/99_ACKNOWLEDGEMENTS.md +29 -0
  43. package/install.sh +32 -8
  44. package/package.json +4 -2
  45. package/pyproject.toml +1 -1
  46. package/src/deepscientist/artifact/guidance.py +9 -2
  47. package/src/deepscientist/artifact/service.py +482 -22
  48. package/src/deepscientist/bash_exec/monitor.py +27 -5
  49. package/src/deepscientist/bash_exec/runtime.py +639 -0
  50. package/src/deepscientist/bash_exec/service.py +99 -16
  51. package/src/deepscientist/bridges/base.py +3 -0
  52. package/src/deepscientist/bridges/connectors.py +292 -13
  53. package/src/deepscientist/channels/qq.py +19 -2
  54. package/src/deepscientist/channels/relay.py +1 -0
  55. package/src/deepscientist/cli.py +32 -25
  56. package/src/deepscientist/config/models.py +28 -2
  57. package/src/deepscientist/config/service.py +201 -6
  58. package/src/deepscientist/connector_runtime.py +2 -0
  59. package/src/deepscientist/daemon/api/handlers.py +50 -5
  60. package/src/deepscientist/daemon/api/router.py +1 -0
  61. package/src/deepscientist/daemon/app.py +442 -15
  62. package/src/deepscientist/doctor.py +444 -0
  63. package/src/deepscientist/home.py +1 -0
  64. package/src/deepscientist/latex_runtime.py +17 -4
  65. package/src/deepscientist/lingzhu_support.py +182 -0
  66. package/src/deepscientist/mcp/server.py +49 -2
  67. package/src/deepscientist/prompts/builder.py +181 -58
  68. package/src/deepscientist/quest/layout.py +1 -0
  69. package/src/deepscientist/quest/service.py +63 -2
  70. package/src/deepscientist/quest/stage_views.py +19 -1
  71. package/src/deepscientist/runtime_tools/__init__.py +16 -0
  72. package/src/deepscientist/runtime_tools/builtins.py +19 -0
  73. package/src/deepscientist/runtime_tools/models.py +29 -0
  74. package/src/deepscientist/runtime_tools/registry.py +40 -0
  75. package/src/deepscientist/runtime_tools/service.py +59 -0
  76. package/src/deepscientist/runtime_tools/tinytex.py +25 -0
  77. package/src/deepscientist/tinytex.py +276 -0
  78. package/src/prompts/connectors/lingzhu.md +12 -0
  79. package/src/prompts/connectors/qq.md +121 -0
  80. package/src/prompts/system.md +177 -33
  81. package/src/skills/analysis-campaign/SKILL.md +22 -6
  82. package/src/skills/baseline/SKILL.md +5 -4
  83. package/src/skills/decision/SKILL.md +4 -3
  84. package/src/skills/experiment/SKILL.md +5 -4
  85. package/src/skills/finalize/SKILL.md +5 -4
  86. package/src/skills/idea/SKILL.md +5 -4
  87. package/src/skills/intake-audit/SKILL.md +277 -0
  88. package/src/skills/intake-audit/references/state-audit-template.md +41 -0
  89. package/src/skills/rebuttal/SKILL.md +407 -0
  90. package/src/skills/rebuttal/references/action-plan-template.md +63 -0
  91. package/src/skills/rebuttal/references/evidence-update-template.md +30 -0
  92. package/src/skills/rebuttal/references/response-letter-template.md +113 -0
  93. package/src/skills/rebuttal/references/review-matrix-template.md +55 -0
  94. package/src/skills/review/SKILL.md +293 -0
  95. package/src/skills/review/references/experiment-todo-template.md +29 -0
  96. package/src/skills/review/references/review-report-template.md +83 -0
  97. package/src/skills/review/references/revision-log-template.md +40 -0
  98. package/src/skills/scout/SKILL.md +5 -4
  99. package/src/skills/write/SKILL.md +7 -3
  100. package/src/tui/dist/components/WelcomePanel.js +17 -43
  101. package/src/tui/dist/components/messages/BashExecOperationMessage.js +3 -2
  102. package/src/tui/package.json +1 -1
  103. package/src/ui/dist/assets/{AiManusChatView-7v-dHngU.js → AiManusChatView-w5lF2Ttt.js} +109 -575
  104. package/src/ui/dist/assets/{AnalysisPlugin-B_Xmz-KE.js → AnalysisPlugin-DJOED79I.js} +1 -1
  105. package/src/ui/dist/assets/{AutoFigurePlugin-Cko-0tm1.js → AutoFigurePlugin-DaG61Y0M.js} +63 -8
  106. package/src/ui/dist/assets/{CliPlugin-BsU0ht7q.js → CliPlugin-CV4LqUB_.js} +43 -609
  107. package/src/ui/dist/assets/{CodeEditorPlugin-DcMMP0Rt.js → CodeEditorPlugin-DylfAea4.js} +8 -8
  108. package/src/ui/dist/assets/{CodeViewerPlugin-BqoQ5QyY.js → CodeViewerPlugin-F7saY0LM.js} +5 -5
  109. package/src/ui/dist/assets/{DocViewerPlugin-D7eHNhU6.js → DocViewerPlugin-COP0c7jf.js} +3 -3
  110. package/src/ui/dist/assets/{GitDiffViewerPlugin-DLJN42T5.js → GitDiffViewerPlugin-CAS05pT9.js} +1 -1
  111. package/src/ui/dist/assets/{ImageViewerPlugin-gJMV7MOu.js → ImageViewerPlugin-Bco1CN_w.js} +5 -6
  112. package/src/ui/dist/assets/{LabCopilotPanel-B857sfxP.js → LabCopilotPanel-CvMlCD99.js} +12 -15
  113. package/src/ui/dist/assets/LabPlugin-BYankkE4.js +2676 -0
  114. package/src/ui/dist/assets/LabPlugin-D9jVIo0A.css +2698 -0
  115. package/src/ui/dist/assets/{LatexPlugin-DWKEo-Wj.js → LatexPlugin-LDSMR-t-.js} +16 -16
  116. package/src/ui/dist/assets/{MarkdownViewerPlugin-DBzoEmhv.js → MarkdownViewerPlugin-B7o80jgm.js} +4 -4
  117. package/src/ui/dist/assets/{MarketplacePlugin-DoHc-8vo.js → MarketplacePlugin-CM6ZOcpC.js} +3 -3
  118. package/src/ui/dist/assets/{NotebookEditor-CKjKH-yS.js → NotebookEditor-Dc61cXmK.js} +3 -3
  119. package/src/ui/dist/assets/{PdfLoader-zFoL0VPo.js → PdfLoader-DWowuQwx.js} +1 -1
  120. package/src/ui/dist/assets/{PdfMarkdownPlugin-DXPaL9Nt.js → PdfMarkdownPlugin-BsJM1q_a.js} +3 -3
  121. package/src/ui/dist/assets/{PdfViewerPlugin-DhK8qCFp.js → PdfViewerPlugin-DB2eEEFQ.js} +10 -10
  122. package/src/ui/dist/assets/{SearchPlugin-CdSi6krf.js → SearchPlugin-CraThSvt.js} +1 -1
  123. package/src/ui/dist/assets/{Stepper-V-WiDQJl.js → Stepper-CgocRTPq.js} +1 -1
  124. package/src/ui/dist/assets/{TextViewerPlugin-hIs1Efiu.js → TextViewerPlugin-B1JGhKtd.js} +4 -4
  125. package/src/ui/dist/assets/{VNCViewer-DG8b0q2X.js → VNCViewer-CclFC7FM.js} +9 -10
  126. package/src/ui/dist/assets/{bibtex-HDac6fVW.js → bibtex-D3IKsMl7.js} +1 -1
  127. package/src/ui/dist/assets/{code-BnBeNxBc.js → code-BP37Xx0p.js} +1 -1
  128. package/src/ui/dist/assets/{file-content-IRQ3jHb8.js → file-content-BAJSu-9r.js} +1 -1
  129. package/src/ui/dist/assets/{file-diff-panel-DZoQ9I6r.js → file-diff-panel-DUGeCTuy.js} +1 -1
  130. package/src/ui/dist/assets/{file-socket-BMCdLc-P.js → file-socket-CXc1Ojf7.js} +1 -1
  131. package/src/ui/dist/assets/{file-utils-CltILB3w.js → file-utils-2J21jt7M.js} +1 -1
  132. package/src/ui/dist/assets/{image-Boe6ffhu.js → image-CMMmgvcn.js} +1 -1
  133. package/src/ui/dist/assets/{index-BlplpvE1.js → index-BaVumsQT.js} +2 -2
  134. package/src/ui/dist/assets/{index-DZqJ-qAM.js → index-CWgMgpow.js} +60 -2154
  135. package/src/ui/dist/assets/{index-DO43pFZP.js → index-DmwmJmbW.js} +6372 -8434
  136. package/src/ui/dist/assets/{index-Bq2bvfkl.css → index-KGt-z-dD.css} +225 -2920
  137. package/src/ui/dist/assets/{index-2Zf65FZt.js → index-s7aHnNQ4.js} +1 -1
  138. package/src/ui/dist/assets/{message-square-mUHn_Ssb.js → message-square-CQRfX0Am.js} +1 -1
  139. package/src/ui/dist/assets/{monaco-fe0arNEU.js → monaco-B4TbdsrF.js} +1 -1
  140. package/src/ui/dist/assets/{popover-D_7i19qU.js → popover-B8Rokodk.js} +1 -1
  141. package/src/ui/dist/assets/{project-sync-DyVGrU7H.js → project-sync-D_i96KH4.js} +2 -8
  142. package/src/ui/dist/assets/{sigma-BzazRyxQ.js → sigma-D12PnzCN.js} +1 -1
  143. package/src/ui/dist/assets/{tooltip-DN_yjHFH.js → tooltip-B6YrI4aJ.js} +1 -1
  144. package/src/ui/dist/assets/trash-Bc8jGp0V.js +32 -0
  145. package/src/ui/dist/assets/{useCliAccess-DV2L2Qxy.js → useCliAccess-mXVCYSZ-.js} +12 -42
  146. package/src/ui/dist/assets/{useFileDiffOverlay-DyTj-p_V.js → useFileDiffOverlay-Bg6b9H9K.js} +1 -1
  147. package/src/ui/dist/assets/{wrap-text-ozYHtUwq.js → wrap-text-Drh5GEnL.js} +1 -1
  148. package/src/ui/dist/assets/{zoom-out-BN9MUyCQ.js → zoom-out-CJj9DZLn.js} +1 -1
  149. package/src/ui/dist/index.html +2 -2
  150. package/assets/fonts/Inter-Variable.ttf +0 -0
  151. package/assets/fonts/NotoSerifSC-Regular-C94HN_ZN.ttf +0 -0
  152. package/assets/fonts/NunitoSans-Variable.ttf +0 -0
  153. package/assets/fonts/Satoshi-Medium-ByP-Zb-9.woff2 +0 -0
  154. package/assets/fonts/SourceSans3-Variable.ttf +0 -0
  155. package/assets/fonts/ds-fonts.css +0 -83
  156. package/src/ui/dist/assets/Inter-Variable-VF2RPR_K.ttf +0 -0
  157. package/src/ui/dist/assets/LabPlugin-bL7rpic8.js +0 -43
  158. package/src/ui/dist/assets/NotoSerifSC-Regular-C94HN_ZN-C94HN_ZN.ttf +0 -0
  159. package/src/ui/dist/assets/NunitoSans-Variable-B_ZymHAd.ttf +0 -0
  160. package/src/ui/dist/assets/Satoshi-Medium-ByP-Zb-9-GkA34YXu.woff2 +0 -0
  161. package/src/ui/dist/assets/SourceSans3-Variable-CD-WOsSK.ttf +0 -0
  162. package/src/ui/dist/assets/info-CcsK_htA.js +0 -18
  163. package/src/ui/dist/assets/user-plus-BusDx-hF.js +0 -79
@@ -0,0 +1,679 @@
1
+ # 06 Runtime and Canvas: Understand Runtime Flow and Canvas
2
+
3
+ This document describes the **current implemented behavior** of DeepScientist Core in this repository.
4
+
5
+ It is intentionally based on the real runtime code rather than older architecture drafts.
6
+
7
+ ## 1. Source Of Truth
8
+
9
+ The behavior described here is derived from these files:
10
+
11
+ - `src/prompts/system.md`
12
+ - `src/skills/scout/SKILL.md`
13
+ - `src/skills/baseline/SKILL.md`
14
+ - `src/skills/idea/SKILL.md`
15
+ - `src/skills/experiment/SKILL.md`
16
+ - `src/skills/analysis-campaign/SKILL.md`
17
+ - `src/skills/write/SKILL.md`
18
+ - `src/skills/finalize/SKILL.md`
19
+ - `src/skills/decision/SKILL.md`
20
+ - `src/deepscientist/prompts/builder.py`
21
+ - `src/deepscientist/daemon/app.py`
22
+ - `src/deepscientist/daemon/api/handlers.py`
23
+ - `src/deepscientist/runners/codex.py`
24
+ - `src/deepscientist/mcp/server.py`
25
+ - `src/deepscientist/artifact/service.py`
26
+ - `src/deepscientist/quest/service.py`
27
+ - `src/deepscientist/quest/node_traces.py`
28
+ - `src/deepscientist/gitops/diff.py`
29
+ - `src/ui/src/lib/api/lab.ts`
30
+ - `src/ui/src/lib/plugins/lab/components/LabQuestGraphCanvas.tsx`
31
+
32
+ ## 2. One-Sentence Summary
33
+
34
+ The current system is **not** a heavy daemon-driven stage engine.
35
+
36
+ It is a **prompt-led, skill-led, file-led quest runtime** where:
37
+
38
+ - the daemon handles queueing, turn execution, API, connectors, and recovery
39
+ - the prompt and skill files define most of the research discipline
40
+ - durable state lives in quest files, memory cards, artifacts, Git, and run logs
41
+ - the UI Canvas is reconstructed from Git branches plus durable artifact records and raw quest events
42
+
43
+ ## 3. Canonical Anchor Model
44
+
45
+ The current system prompt defines these canonical stage anchors:
46
+
47
+ - `scout`
48
+ - `baseline`
49
+ - `idea`
50
+ - `experiment`
51
+ - `analysis-campaign`
52
+ - `write`
53
+ - `finalize`
54
+
55
+ `decision` is **not** a stage anchor.
56
+ It is a cross-cutting skill used when continuation, branching, reset, stop, or user decision handling is non-trivial.
57
+
58
+ The graph is explicitly non-linear.
59
+ The prompt allows backward motion such as:
60
+
61
+ - `write -> analysis-campaign`
62
+ - `write -> experiment`
63
+ - `write -> scout`
64
+ - `experiment -> idea`
65
+ - `analysis-campaign -> experiment`
66
+
67
+ ## 4. What Actually Happens When A User Sends A Command
68
+
69
+ There are two different paths:
70
+
71
+ ### 4.1 Structured slash/control path
72
+
73
+ Commands such as status, graph, pause, stop, and resume are handled directly by the daemon/API layer.
74
+
75
+ Typical examples:
76
+
77
+ - `GET /api/quests/<id>/workflow`
78
+ - `GET /api/quests/<id>/node-traces`
79
+ - `GET /api/quests/<id>/artifacts`
80
+ - `GET /api/quests/<id>/events?format=raw`
81
+ - `GET /api/quests/<id>/git/branches`
82
+ - `POST /api/quests/<id>/control`
83
+
84
+ This path does **not** invoke the runner unless the action itself causes a new turn to be scheduled.
85
+
86
+ ### 4.2 Plain user message path
87
+
88
+ Normal conversation text goes through the quest mailbox and turn scheduler.
89
+
90
+ The actual sequence is:
91
+
92
+ 1. UI, TUI, or connector submits a user message.
93
+ 2. The daemon appends it to quest history.
94
+ 3. If the quest is idle, the daemon schedules a new turn immediately.
95
+ 4. If a turn is already running, the message is queued for later delivery through `artifact.interact(...)`.
96
+
97
+ This means the first message typically launches the turn, while later follow-up messages are delivered through the artifact-thread continuity mechanism.
98
+
99
+ ## 5. Actual Turn Lifecycle
100
+
101
+ The current runtime flow is:
102
+
103
+ 1. `submit_user_message(...)`
104
+ 2. `schedule_turn(...)`
105
+ 3. worker thread enters `_drain_turns(...)`
106
+ 4. `_run_quest_turn(...)`
107
+ 5. choose runner
108
+ 6. choose skill
109
+ 7. build prompt
110
+ 8. start Codex runner
111
+ 9. agent uses MCP tools, files, Git, and shell
112
+ 10. runner exits and runtime records run outputs
113
+
114
+ ### 5.1 Scheduling behavior
115
+
116
+ The daemon keeps a per-quest turn state:
117
+
118
+ - `running`
119
+ - `pending`
120
+ - `stop_requested`
121
+
122
+ If a quest is already running, new user messages do **not** start a second runner process.
123
+ They mark the turn as pending and are later surfaced via `artifact.interact(include_recent_inbound_messages=True)`.
124
+
125
+ ### 5.2 Which skill is used for the turn
126
+
127
+ The skill selection rule is currently simple and important:
128
+
129
+ 1. If the latest user message replies to an active blocking interaction thread, use `decision`.
130
+ 2. Otherwise read `quest.yaml.active_anchor`.
131
+ 3. If `active_anchor` is one of the standard skills, use that.
132
+ 4. Otherwise fall back to `decision`.
133
+
134
+ This is implemented in `src/deepscientist/daemon/app.py` via `_turn_skill_for(...)`.
135
+
136
+ ## 6. Important Reality: Anchor Progression Is Not Strongly Automated
137
+
138
+ This is the most important implementation fact to understand.
139
+
140
+ New quests start with:
141
+
142
+ - `active_anchor: baseline`
143
+
144
+ But the daemon currently does **not** act like a strict workflow engine that automatically advances every quest from stage to stage.
145
+
146
+ In practice:
147
+
148
+ - the prompt explains the canonical research graph
149
+ - the active skill for a turn usually comes from `quest.yaml.active_anchor`
150
+ - the agent is expected to follow the skill, write durable outputs, and use `decision` when routing changes
151
+ - durable files and artifacts carry continuity much more than a centralized stage-transition table does
152
+
153
+ So today the system behaves more like:
154
+
155
+ - a disciplined research copilot runtime
156
+ - with durable state and strong conventions
157
+ - not yet a full automatic stage controller
158
+
159
+ ## 7. How The Prompt Is Built
160
+
161
+ For each turn, `PromptBuilder.build(...)` composes a single prompt from these blocks:
162
+
163
+ 1. system prompt from `src/prompts/system.md`
164
+ 2. runtime context
165
+ 3. active communication surface
166
+ 4. canonical skill root and skill paths
167
+ 5. quest context files
168
+ 6. recent durable state
169
+ 7. interaction style instructions
170
+ 8. priority memory for this turn
171
+ 9. recent conversation window
172
+ 10. current turn attachments
173
+ 11. current user message
174
+
175
+ The runtime context includes:
176
+
177
+ - `ds_home`
178
+ - `quest_id`
179
+ - `quest_root`
180
+ - `active_anchor`
181
+ - `active_branch`
182
+ - `requested_skill`
183
+ - `runner_name`
184
+ - `model`
185
+ - `conversation_id`
186
+ - `default_locale`
187
+ - built-in MCP namespace list
188
+
189
+ ### 7.1 Active communication surface
190
+
191
+ The builder now injects a surface block that tells the agent which user-facing surface is active for the current turn.
192
+
193
+ Typical fields include:
194
+
195
+ - latest user source
196
+ - whether the surface is local or connector-driven
197
+ - active connector name and chat type when applicable
198
+ - QQ-specific milestone media policy when the current turn came from QQ
199
+
200
+ This is intentionally lightweight.
201
+ It does not create a separate per-connector workflow engine.
202
+ It only makes the current turn's communication contract explicit.
203
+
204
+ ### 7.2 Current turn attachments
205
+
206
+ If the newest inbound user message carries attachment metadata, the builder injects a small attachment summary block.
207
+
208
+ The intent is:
209
+
210
+ - tell the agent that attachments exist
211
+ - point the agent toward readable sidecars when available
212
+ - avoid forcing the agent to guess whether a binary attachment matters
213
+
214
+ This block is a summary surface, not a full attachment-processing pipeline.
215
+
216
+ ### 7.3 Skill files are referenced by path, not inlined
217
+
218
+ The builder injects the canonical skill root and the concrete stage skill file paths.
219
+
220
+ The system prompt then tells the agent to open the corresponding skill file for the active stage.
221
+
222
+ That means the runtime currently works like this:
223
+
224
+ - prompt gives the agent the skill file locations
225
+ - agent reads the appropriate skill file
226
+ - skill body stays on disk instead of being pasted into every prompt
227
+
228
+ ### 7.4 Memory injection is stage-aware
229
+
230
+ `PromptBuilder` uses a stage-specific memory plan.
231
+
232
+ Examples:
233
+
234
+ - `scout` prioritizes quest/global `papers`, `knowledge`, `decisions`
235
+ - `baseline` prioritizes `papers`, `decisions`, `episodes`, `knowledge`
236
+ - `idea` prioritizes `papers`, `ideas`, `decisions`, `knowledge`
237
+ - `experiment` prioritizes `ideas`, `decisions`, `episodes`, `knowledge`
238
+ - `analysis-campaign` also pulls relevant `papers`
239
+
240
+ So memory retrieval is not random.
241
+ It is biased by the active stage and then expanded by user-message search terms.
242
+
243
+ ## 8. Runner Behavior
244
+
245
+ The current authoritative runner path is Codex.
246
+
247
+ The Codex runner:
248
+
249
+ - prepares a quest-local `.codex/`
250
+ - copies local auth/config if needed
251
+ - injects DeepScientist built-in MCP servers into `.codex/config.toml`
252
+ - runs `codex --search exec --json --cd <quest_root> --skip-git-repo-check --model <model> -`
253
+
254
+ The injected built-in MCP namespaces are exactly:
255
+
256
+ - `memory`
257
+ - `artifact`
258
+ - `bash_exec`
259
+
260
+ This matches the repo rule that built-in Core MCP stays minimal at the namespace level.
261
+
262
+ ## 9. Built-In MCP Surface
263
+
264
+ ### 9.1 `memory`
265
+
266
+ The `memory` namespace currently provides:
267
+
268
+ - `write`
269
+ - `read`
270
+ - `search`
271
+ - `list_recent`
272
+ - `promote_to_global`
273
+
274
+ Memory cards are Markdown files with YAML frontmatter and are managed as durable files.
275
+
276
+ ### 9.2 `artifact`
277
+
278
+ The `artifact` namespace currently provides the main structured continuity and Git-aware operations:
279
+
280
+ - `record`
281
+ - `checkpoint`
282
+ - `prepare_branch`
283
+ - `publish_baseline`
284
+ - `attach_baseline`
285
+ - `arxiv`
286
+ - `refresh_summary`
287
+ - `render_git_graph`
288
+ - `interact`
289
+
290
+ This is intentional:
291
+
292
+ - Git behavior is exposed through `artifact`
293
+ - there is no separate public `git` MCP namespace
294
+
295
+ ### 9.3 `bash_exec`
296
+
297
+ The `bash_exec` namespace is the durable shell execution surface.
298
+
299
+ It supports:
300
+
301
+ - detached execution
302
+ - wait/create execution
303
+ - read log
304
+ - kill session
305
+ - list sessions
306
+
307
+ This is the correct shell path for long-running, auditable quest-local commands.
308
+
309
+ ## 10. Why `artifact.interact(...)` Is Central
310
+
311
+ `artifact.interact(...)` is the real continuity spine across:
312
+
313
+ - web UI
314
+ - TUI
315
+ - local conversation surfaces
316
+ - external connectors
317
+
318
+ It does several jobs at once:
319
+
320
+ 1. writes a durable artifact
321
+ 2. optionally checkpoints important interactions
322
+ 3. updates interaction thread state
323
+ 4. optionally pushes the message to bound conversations/connectors
324
+ 5. consumes queued inbound user messages back to the agent
325
+ 6. returns recent interaction context and delivery results
326
+
327
+ ### 10.1 Interaction kinds
328
+
329
+ The main kinds are:
330
+
331
+ - `progress`
332
+ - `milestone`
333
+ - `decision_request`
334
+ - `approval_result`
335
+
336
+ ### 10.2 Reply modes
337
+
338
+ The main reply modes are:
339
+
340
+ - `none`
341
+ - `threaded`
342
+ - `blocking`
343
+
344
+ Current runtime rule:
345
+
346
+ - blocking requests become waiting user decisions
347
+ - threaded updates remain conversational progress threads
348
+
349
+ ### 10.3 Mailbox behavior
350
+
351
+ If the agent calls `artifact.interact(include_recent_inbound_messages=True)`:
352
+
353
+ - queued user messages can be consumed
354
+ - the agent receives them as recent inbound messages
355
+ - the runtime also returns recent interaction records
356
+ - if there is no new user message, the runtime explicitly tells the agent to continue current work
357
+
358
+ This is why later user follow-up messages can reach a long-running turn without launching a second runner.
359
+
360
+ ## 11. Connector Delivery Reality
361
+
362
+ When `artifact.interact(...)` is allowed to deliver outward, delivery targets are selected from quest bindings.
363
+
364
+ The runtime currently uses:
365
+
366
+ - bound conversations from `<quest_root>/.ds/bindings.json`
367
+ - connector config from the home config
368
+ - a routing policy
369
+
370
+ The current routing policy options are:
371
+
372
+ - `fanout_all`
373
+ - `primary_only`
374
+ - `primary_plus_local`
375
+
376
+ The default behavior is effectively:
377
+
378
+ - local conversation stays included
379
+ - one preferred non-local connector may also receive the update
380
+
381
+ So if multiple connectors are configured, the system does **not** blindly broadcast everywhere unless the routing policy asks for that.
382
+
383
+ ## 12. Durable Runtime Outputs
384
+
385
+ During and after a run, continuity is reconstructed from durable files such as:
386
+
387
+ - `quest.yaml`
388
+ - `brief.md`
389
+ - `plan.md`
390
+ - `status.md`
391
+ - `SUMMARY.md`
392
+ - `memory/*`
393
+ - `artifacts/*`
394
+ - `.ds/events.jsonl`
395
+ - `.ds/user_message_queue.json`
396
+ - `.ds/interaction_journal.jsonl`
397
+ - `.ds/codex_history/<run_id>/events.jsonl`
398
+ - `.ds/bash_exec/*`
399
+
400
+ This is why the system can recover context from files without needing a database.
401
+
402
+ ## 13. Quest Event Stream And ACP Compatibility
403
+
404
+ The daemon also exposes quest events through:
405
+
406
+ - `GET /api/quests/<id>/events`
407
+
408
+ This endpoint can return:
409
+
410
+ - native event payloads
411
+ - ACP-compatible updates
412
+ - optional ACP Python SDK notifications when the bridge is available
413
+
414
+ Current practical rule:
415
+
416
+ - web and TUI should treat the quest event stream as the live update channel
417
+ - `format=acp` returns ACP-style session updates derived from quest events
418
+ - the ACP bridge is optional and is not the core source of truth
419
+
420
+ So the runtime model remains:
421
+
422
+ - quest files and artifacts are the durable source of truth
423
+ - quest events are the live operational stream
424
+ - ACP is a compatibility envelope layered on top
425
+
426
+ ## 14. How Operational Views Are Reconstructed
427
+
428
+ Neither workflow nor Canvas is stored as one authoritative graph document.
429
+
430
+ Instead, the runtime reconstructs operational views from:
431
+
432
+ - core quest documents
433
+ - recent runs
434
+ - recent artifacts
435
+ - raw quest events from `.ds/events.jsonl`
436
+ - parsed Codex history events for compatibility surfaces
437
+
438
+ The compatibility workflow payload from `QuestService.workflow(...)` contains:
439
+
440
+ - `entries`
441
+ - `changed_files`
442
+
443
+ ### 13.1 `entries`
444
+
445
+ Entries can include at least:
446
+
447
+ - quest documents
448
+ - run summaries
449
+ - parsed tool calls from Codex history
450
+ - artifacts
451
+
452
+ ### 13.2 `changed_files`
453
+
454
+ This is a compact recent file set assembled from:
455
+
456
+ - core quest documents
457
+ - run outputs
458
+ - artifact paths
459
+
460
+ It is mainly used by the UI to show relevant recent files.
461
+
462
+ ## 15. How Canvas Is Built
463
+
464
+ There are currently three practical Canvas views:
465
+
466
+ - branch view
467
+ - event view
468
+ - stage view
469
+
470
+ These do **not** come from the same source.
471
+
472
+ ## 16. Branch View: Git-Derived Canvas
473
+
474
+ Branch Canvas comes from:
475
+
476
+ - `list_branch_canvas(...)`
477
+
478
+ This inspects Git refs and quest branch metadata, then produces:
479
+
480
+ - `nodes`
481
+ - `edges`
482
+ - `views.ideas`
483
+ - `views.analysis`
484
+
485
+ ### 15.1 Branch nodes
486
+
487
+ Each branch node includes fields such as:
488
+
489
+ - `ref`
490
+ - `label`
491
+ - `branch_kind`
492
+ - `tier`
493
+ - `mode`
494
+ - `parent_ref`
495
+ - `compare_base`
496
+ - `current`
497
+ - `head`
498
+ - `updated_at`
499
+ - `subject`
500
+ - `commit_count`
501
+ - `ahead`
502
+ - `behind`
503
+ - `run_id`
504
+ - `run_kind`
505
+ - `idea_id`
506
+ - `worktree_root`
507
+ - `latest_metric`
508
+ - `latest_summary`
509
+ - `recent_artifacts`
510
+
511
+ ### 15.2 Branch edges
512
+
513
+ Branch edges are Git/branch-structure edges:
514
+
515
+ - relation = `branch`
516
+ - source = parent ref
517
+ - target = child ref
518
+
519
+ ### 15.3 Two branch modes already exist conceptually
520
+
521
+ The branch view already has enough metadata to support the two user mental models:
522
+
523
+ 1. major branches for different ideas / main implementations
524
+ 2. smaller analysis branches under one accepted main experimental line
525
+
526
+ The backend exposes `tier`, `mode`, `branch_kind`, `idea_id`, and related metadata specifically to support this kind of UI distinction.
527
+
528
+ ### 15.4 Extra experiments become child branches
529
+
530
+ The current runtime contract is:
531
+
532
+ - whenever extra experiments are needed after a durable result, they should be launched through `artifact.create_analysis_campaign(...)`
533
+ - this applies even when there is only one extra experiment; a one-slice campaign is still the correct shape
534
+ - the campaign should branch from the current workspace/result node, not silently rewrite the completed parent node in place
535
+ - this is what keeps Git history and Canvas lineage aligned
536
+
537
+ ## 17. Event View: Artifact-And-Event-Derived Canvas
538
+
539
+ The current Lab Canvas event view is reconstructed from durable artifact records plus raw quest events.
540
+
541
+ In local quest mode the pipeline is:
542
+
543
+ 1. `QuestService.artifacts(...)`
544
+ 2. raw quest events from `.ds/events.jsonl` through `GET /api/quests/<id>/events?format=raw`
545
+ 3. frontend local trace builder in `src/ui/src/lib/api/lab.ts`
546
+ 4. frontend maps trace items into graph nodes
547
+
548
+ ### 16.1 Event nodes
549
+
550
+ Each durable artifact becomes one primary `event_node` trace item.
551
+
552
+ The trace captures:
553
+
554
+ - selection ref
555
+ - title
556
+ - branch name
557
+ - inferred stage key
558
+ - worktree relative path
559
+ - action list
560
+ - summary
561
+ - counts
562
+ - updated time
563
+ - artifact id / kind
564
+ - head commit
565
+ - changed files
566
+ - payload snapshot
567
+
568
+ An event node may represent:
569
+
570
+ - an artifact
571
+ - a stage-significant decision or report
572
+ - the related MCP / tool-call history attached to that artifact
573
+ - another operational event when no durable artifact exists yet
574
+
575
+ ### 16.2 Event edges
576
+
577
+ The current frontend edge rule is simple:
578
+
579
+ - group event nodes by branch
580
+ - sort by `updated_at`
581
+ - connect each item to the next item on the same branch
582
+
583
+ So current event edges are **sequence edges**, not deep semantic-causal edges.
584
+
585
+ ## 18. Stage View: Aggregated Trace Canvas
586
+
587
+ Stage view is also built from node traces, but durable artifact traces are grouped by:
588
+
589
+ - branch name
590
+ - inferred stage key
591
+
592
+ Each group becomes one `stage_node`.
593
+
594
+ Current stage edges are also built as chronological edges **within a branch** after sorting by `updated_at`.
595
+
596
+ So stage view is:
597
+
598
+ - aggregated
599
+ - branch-aware
600
+ - time-ordered
601
+ - but still not a fully explicit research dependency graph
602
+
603
+ ## 19. Important Normalization Rules In Trace Materialization
604
+
605
+ Current local trace materialization uses the canonical prompt anchors:
606
+
607
+ - `scout`
608
+ - `baseline`
609
+ - `idea`
610
+ - `experiment`
611
+ - `analysis-campaign`
612
+ - `write`
613
+ - `finalize`
614
+
615
+ `decision` is treated as cross-cutting.
616
+ Decision artifacts are merged into the effective canonical stage for branch and stage summaries instead of becoming a standalone stage anchor.
617
+
618
+ ## 20. What Canvas Does Not Yet Mean
619
+
620
+ The current Canvas should **not** be interpreted as:
621
+
622
+ - a fully authoritative workflow state machine
623
+ - a complete semantic dependency graph
624
+ - a perfect mirror of the canonical prompt graph
625
+
626
+ Today it is better understood as:
627
+
628
+ - a reconstructed operational map
629
+ - from Git topology plus durable artifacts plus raw quest events
630
+
631
+ ## 21. Current Gaps To Keep In Mind
632
+
633
+ The following gaps are real in the current implementation:
634
+
635
+ ### 20.1 Anchor progression is weakly enforced
636
+
637
+ `active_anchor` is not robustly auto-advanced by a central scheduler.
638
+
639
+ ### 20.2 Prompt graph is richer than visualization graph
640
+
641
+ Prompt anchors include `analysis-campaign`, `write`, and `finalize` distinctly, but node trace grouping compresses some of them.
642
+
643
+ ### 20.3 Event/stage edges are mostly chronological
644
+
645
+ They are useful and readable, but they are not yet explicit evidence edges or decision-dependency edges.
646
+
647
+ ### 20.4 Canvas is reconstructed, not authored directly
648
+
649
+ There is no single canonical graph database or graph file that the runtime treats as the one true source.
650
+
651
+ ## 22. Practical Mental Model For Developers
652
+
653
+ If you are modifying this system, the safest current mental model is:
654
+
655
+ 1. user message or connector event enters the daemon
656
+ 2. daemon schedules one quest turn
657
+ 3. active skill is chosen from `active_anchor` or `decision`
658
+ 4. prompt is assembled from system prompt, skill paths, quest files, memory, and recent history
659
+ 5. Codex runs inside the quest repo with built-in MCP namespaces
660
+ 6. agent writes memory, artifacts, shell sessions, Git checkpoints, and reports
661
+ 7. `artifact.interact(...)` keeps user-facing continuity alive
662
+ 8. workflow and Canvas are reconstructed from those durable outputs and the raw quest event stream
663
+
664
+ ## 23. Suggested Next Hardening Direction
665
+
666
+ If this runtime is tightened further, the most valuable next steps would be:
667
+
668
+ 1. make `active_anchor` advancement more explicit and durable
669
+ 2. keep remote and local Canvas semantics equally artifact-first
670
+ 3. add stronger decision/evidence edges in Canvas
671
+ 4. keep the core small while making the protocol clearer rather than adding a large scheduler
672
+
673
+ That direction stays aligned with the current repository constraints:
674
+
675
+ - small core
676
+ - prompt-led workflow
677
+ - artifact-led Git behavior
678
+ - minimal built-in MCP namespaces
679
+ - durable file state instead of database-first orchestration