mednotes-opencode 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 (430) hide show
  1. package/.opencode/agents/med-chat-triager.md +204 -0
  2. package/.opencode/agents/med-flashcard-maker.md +63 -0
  3. package/.opencode/agents/med-knowledge-architect.md +230 -0
  4. package/.opencode/agents/med-link-graph-curator.md +177 -0
  5. package/.opencode/agents/med-publish-guard.md +62 -0
  6. package/.opencode/commands/flashcards.md +25 -0
  7. package/.opencode/commands/mednotes/create.md +25 -0
  8. package/.opencode/commands/mednotes/enrich.md +27 -0
  9. package/.opencode/commands/mednotes/fix-wiki.md +27 -0
  10. package/.opencode/commands/mednotes/history.md +22 -0
  11. package/.opencode/commands/mednotes/link-body.md +25 -0
  12. package/.opencode/commands/mednotes/link-related.md +27 -0
  13. package/.opencode/commands/mednotes/link.md +27 -0
  14. package/.opencode/commands/mednotes/pdf-library.md +27 -0
  15. package/.opencode/commands/mednotes/process-chats.md +23 -0
  16. package/.opencode/commands/mednotes/setup.md +21 -0
  17. package/.opencode/commands/mednotes/status.md +27 -0
  18. package/.opencode/commands/mednotes/telemetry.md +27 -0
  19. package/.opencode/commands/report.md +26 -0
  20. package/.opencode/mednotes/AGENTS.md +57 -0
  21. package/.opencode/mednotes/agents/med-chat-triager.md +197 -0
  22. package/.opencode/mednotes/agents/med-flashcard-maker.md +56 -0
  23. package/.opencode/mednotes/agents/med-knowledge-architect.md +224 -0
  24. package/.opencode/mednotes/agents/med-link-graph-curator.md +171 -0
  25. package/.opencode/mednotes/agents/med-publish-guard.md +55 -0
  26. package/.opencode/mednotes/contracts/.gitkeep +1 -0
  27. package/.opencode/mednotes/contracts/agents.json +116 -0
  28. package/.opencode/mednotes/contracts/opencode-plugin.json +70 -0
  29. package/.opencode/mednotes/docs/agent-prompt-hardening.md +567 -0
  30. package/.opencode/mednotes/docs/agent-role-contracts.md +94 -0
  31. package/.opencode/mednotes/docs/anki-mcp-twenty-rules.md +214 -0
  32. package/.opencode/mednotes/docs/anki-templates/README.md +39 -0
  33. package/.opencode/mednotes/docs/anki-templates/cloze.back.html +23 -0
  34. package/.opencode/mednotes/docs/anki-templates/cloze.front.html +14 -0
  35. package/.opencode/mednotes/docs/anki-templates/qa.back.html +24 -0
  36. package/.opencode/mednotes/docs/anki-templates/qa.front.html +14 -0
  37. package/.opencode/mednotes/docs/anki-templates/style.css +182 -0
  38. package/.opencode/mednotes/docs/atomicity-splitting-policy.md +113 -0
  39. package/.opencode/mednotes/docs/extension-docs.md +40 -0
  40. package/.opencode/mednotes/docs/flashcard-ingestion.md +278 -0
  41. package/.opencode/mednotes/docs/knowledge-architect.md +208 -0
  42. package/.opencode/mednotes/docs/merge-policy.md +110 -0
  43. package/.opencode/mednotes/docs/public-vocabulary.md +104 -0
  44. package/.opencode/mednotes/docs/semantic-linker.md +141 -0
  45. package/.opencode/mednotes/docs/taxonomy-policy.md +90 -0
  46. package/.opencode/mednotes/docs/triage-policy.md +187 -0
  47. package/.opencode/mednotes/docs/vault-version-control.md +758 -0
  48. package/.opencode/mednotes/docs/vocabulary-db-recovery.md +58 -0
  49. package/.opencode/mednotes/docs/workflow-output-contract.md +779 -0
  50. package/.opencode/mednotes/hooks/hooks.json +79 -0
  51. package/.opencode/mednotes/package-lock.json +6361 -0
  52. package/.opencode/mednotes/package.json +15 -0
  53. package/.opencode/mednotes/pyproject.toml +48 -0
  54. package/.opencode/mednotes/scripts/bootstrap_windows_python_uv.cmd +13 -0
  55. package/.opencode/mednotes/scripts/bootstrap_windows_python_uv.ps1 +172 -0
  56. package/.opencode/mednotes/scripts/enrich_notes.py +23 -0
  57. package/.opencode/mednotes/scripts/full_reset_windows_python_uv.cmd +13 -0
  58. package/.opencode/mednotes/scripts/hooks/antigravity_hook_status.mjs +212 -0
  59. package/.opencode/mednotes/scripts/hooks/mednotes_hook/adapters/antigravity.mjs +169 -0
  60. package/.opencode/mednotes/scripts/hooks/mednotes_hook/adapters/harness_payload.mjs +103 -0
  61. package/.opencode/mednotes/scripts/hooks/mednotes_hook/adapters/opencode_plugin.mjs +341 -0
  62. package/.opencode/mednotes/scripts/hooks/mednotes_hook/adapters/opencode_user_config_sync.mjs +177 -0
  63. package/.opencode/mednotes/scripts/hooks/mednotes_hook/anki_preflight.mjs +214 -0
  64. package/.opencode/mednotes/scripts/hooks/mednotes_hook/cli.mjs +143 -0
  65. package/.opencode/mednotes/scripts/hooks/mednotes_hook/diagnostics.mjs +11 -0
  66. package/.opencode/mednotes/scripts/hooks/mednotes_hook/domain/agent_directive_core.mjs +160 -0
  67. package/.opencode/mednotes/scripts/hooks/mednotes_hook/fsm_directive.mjs +1470 -0
  68. package/.opencode/mednotes/scripts/hooks/mednotes_hook/hook_errors.mjs +120 -0
  69. package/.opencode/mednotes/scripts/hooks/mednotes_hook/retention.mjs +114 -0
  70. package/.opencode/mednotes/scripts/hooks/mednotes_hook/runtime.mjs +174 -0
  71. package/.opencode/mednotes/scripts/hooks/mednotes_hook/telemetry_capture.mjs +511 -0
  72. package/.opencode/mednotes/scripts/hooks/mednotes_hook/vault_guard.mjs +624 -0
  73. package/.opencode/mednotes/scripts/hooks/mednotes_hook.mjs +5 -0
  74. package/.opencode/mednotes/scripts/mednotes/_runtime_paths.py +24 -0
  75. package/.opencode/mednotes/scripts/mednotes/anki_model_validator.py +18 -0
  76. package/.opencode/mednotes/scripts/mednotes/capture_extension_diff.py +1562 -0
  77. package/.opencode/mednotes/scripts/mednotes/feedback_report.py +16 -0
  78. package/.opencode/mednotes/scripts/mednotes/flashcard_index.py +18 -0
  79. package/.opencode/mednotes/scripts/mednotes/flashcard_pipeline.py +18 -0
  80. package/.opencode/mednotes/scripts/mednotes/flashcard_report.py +18 -0
  81. package/.opencode/mednotes/scripts/mednotes/flashcard_sources.py +18 -0
  82. package/.opencode/mednotes/scripts/mednotes/obsidian/README.md +6 -0
  83. package/.opencode/mednotes/scripts/mednotes/obsidian_note_utils.py +20 -0
  84. package/.opencode/mednotes/scripts/mednotes/pdf_library/cli.py +16 -0
  85. package/.opencode/mednotes/scripts/mednotes/project_fsm.py +229 -0
  86. package/.opencode/mednotes/scripts/mednotes/setup_telemetry_email.py +404 -0
  87. package/.opencode/mednotes/scripts/mednotes/sync_anki_twenty_rules.py +18 -0
  88. package/.opencode/mednotes/scripts/mednotes/sync_opencode_user_config.py +36 -0
  89. package/.opencode/mednotes/scripts/mednotes/wiki/cli.py +20 -0
  90. package/.opencode/mednotes/scripts/mednotes/wiki_graph.py +18 -0
  91. package/.opencode/mednotes/scripts/mednotes/wiki_tree.py +134 -0
  92. package/.opencode/mednotes/scripts/reset_windows_python_uv.ps1 +625 -0
  93. package/.opencode/mednotes/scripts/run_python.mjs +109 -0
  94. package/.opencode/mednotes/scripts/vault/vault_commit.ps1 +19 -0
  95. package/.opencode/mednotes/scripts/vault/vault_commit.sh +18 -0
  96. package/.opencode/mednotes/scripts/vault/vault_git.ps1 +19 -0
  97. package/.opencode/mednotes/scripts/vault/vault_git.py +3107 -0
  98. package/.opencode/mednotes/scripts/vault/vault_git.sh +18 -0
  99. package/.opencode/mednotes/scripts/vault/vault_precommit.ps1 +19 -0
  100. package/.opencode/mednotes/scripts/vault/vault_precommit.sh +18 -0
  101. package/.opencode/mednotes/skills/THIRD_PARTY_NOTICES.md +45 -0
  102. package/.opencode/mednotes/skills/create-medical-flashcards/SKILL.md +113 -0
  103. package/.opencode/mednotes/skills/create-medical-note/SKILL.md +90 -0
  104. package/.opencode/mednotes/skills/enrich-medical-note/SKILL.md +120 -0
  105. package/.opencode/mednotes/skills/fix-medical-wiki/SKILL.md +559 -0
  106. package/.opencode/mednotes/skills/link-medical-wiki/SKILL.md +224 -0
  107. package/.opencode/mednotes/skills/obsidian-cli/SKILL.md +118 -0
  108. package/.opencode/mednotes/skills/obsidian-markdown/SKILL.md +207 -0
  109. package/.opencode/mednotes/skills/obsidian-markdown/references/CALLOUTS.md +58 -0
  110. package/.opencode/mednotes/skills/obsidian-markdown/references/EMBEDS.md +63 -0
  111. package/.opencode/mednotes/skills/obsidian-markdown/references/PROPERTIES.md +61 -0
  112. package/.opencode/mednotes/skills/obsidian-ops/SKILL.md +136 -0
  113. package/.opencode/mednotes/skills/pdf-library/SKILL.md +45 -0
  114. package/.opencode/mednotes/skills/process-medical-chats/SKILL.md +246 -0
  115. package/.opencode/mednotes/skills/workflow-report/SKILL.md +100 -0
  116. package/.opencode/mednotes/src/mednotes/__init__.py +5 -0
  117. package/.opencode/mednotes/src/mednotes/domains/__init__.py +5 -0
  118. package/.opencode/mednotes/src/mednotes/domains/flashcards/README.md +26 -0
  119. package/.opencode/mednotes/src/mednotes/domains/flashcards/__init__.py +2 -0
  120. package/.opencode/mednotes/src/mednotes/domains/flashcards/build_demo_apkg.py +177 -0
  121. package/.opencode/mednotes/src/mednotes/domains/flashcards/contracts.py +385 -0
  122. package/.opencode/mednotes/src/mednotes/domains/flashcards/flashcards_machine.py +522 -0
  123. package/.opencode/mednotes/src/mednotes/domains/flashcards/fsm.py +817 -0
  124. package/.opencode/mednotes/src/mednotes/domains/flashcards/index.py +630 -0
  125. package/.opencode/mednotes/src/mednotes/domains/flashcards/install_models.py +445 -0
  126. package/.opencode/mednotes/src/mednotes/domains/flashcards/model.py +359 -0
  127. package/.opencode/mednotes/src/mednotes/domains/flashcards/obsidian_links.py +135 -0
  128. package/.opencode/mednotes/src/mednotes/domains/flashcards/obsidian_note_utils.py +546 -0
  129. package/.opencode/mednotes/src/mednotes/domains/flashcards/pipeline.py +580 -0
  130. package/.opencode/mednotes/src/mednotes/domains/flashcards/report.py +510 -0
  131. package/.opencode/mednotes/src/mednotes/domains/flashcards/sources.py +682 -0
  132. package/.opencode/mednotes/src/mednotes/domains/flashcards/sync_rules.py +184 -0
  133. package/.opencode/mednotes/src/mednotes/domains/history/__init__.py +1 -0
  134. package/.opencode/mednotes/src/mednotes/domains/history/history_fsm.py +852 -0
  135. package/.opencode/mednotes/src/mednotes/domains/history/history_machine.py +453 -0
  136. package/.opencode/mednotes/src/mednotes/domains/setup/__init__.py +7 -0
  137. package/.opencode/mednotes/src/mednotes/domains/setup/setup_fsm.py +808 -0
  138. package/.opencode/mednotes/src/mednotes/domains/setup/setup_machine.py +973 -0
  139. package/.opencode/mednotes/src/mednotes/domains/wiki/README.md +64 -0
  140. package/.opencode/mednotes/src/mednotes/domains/wiki/__init__.py +1 -0
  141. package/.opencode/mednotes/src/mednotes/domains/wiki/api.py +668 -0
  142. package/.opencode/mednotes/src/mednotes/domains/wiki/batch_state.py +102 -0
  143. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/__init__.py +1 -0
  144. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/atomicity/__init__.py +1 -0
  145. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/atomicity/atomicity.py +877 -0
  146. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/body_link/__init__.py +1 -0
  147. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/body_link/body_linker.py +1562 -0
  148. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/effects/__init__.py +1 -0
  149. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/effects/effect_adapters.py +949 -0
  150. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/effects/fix_wiki_runtime_adapters.py +433 -0
  151. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/graph/__init__.py +1 -0
  152. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/graph/coverage.py +413 -0
  153. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/graph/graph.py +396 -0
  154. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/graph/graph_fixes.py +161 -0
  155. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/hygiene/__init__.py +1 -0
  156. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/hygiene/hygiene.py +483 -0
  157. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/__init__.py +2 -0
  158. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/anchors.py +185 -0
  159. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/__init__.py +0 -0
  160. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/cache.py +223 -0
  161. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/config.py +131 -0
  162. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/download.py +224 -0
  163. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/frontmatter.py +59 -0
  164. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/insert.py +227 -0
  165. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/core/local_import.py +54 -0
  166. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/sources/__init__.py +42 -0
  167. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/sources/web_profiles.py +99 -0
  168. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/sources/web_search.py +203 -0
  169. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/illustrate/sources/wikimedia.py +102 -0
  170. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/markdown/__init__.py +1 -0
  171. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/markdown/markdown_db_adapter.mjs +434 -0
  172. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/markdown/markdown_node_runtime.py +274 -0
  173. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/markdown/markdown_query.py +227 -0
  174. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/__init__.py +1 -0
  175. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/artifacts.py +605 -0
  176. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/canonical_merge.py +277 -0
  177. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/markdown_zones.py +85 -0
  178. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/meaning_planner.py +307 -0
  179. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_iter.py +67 -0
  180. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_merge.py +278 -0
  181. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_plan.py +409 -0
  182. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_policy.py +22 -0
  183. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/__init__.py +79 -0
  184. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/fixes.py +264 -0
  185. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/frontmatter.py +435 -0
  186. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/models.py +208 -0
  187. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/prompts.py +37 -0
  188. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/tables.py +236 -0
  189. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/note_style/validate.py +404 -0
  190. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/provenance.py +478 -0
  191. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/raw_chats.py +273 -0
  192. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/notes/sources_backfill.py +235 -0
  193. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/__init__.py +10 -0
  194. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/anchors.py +16 -0
  195. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/captions.py +47 -0
  196. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/cli.py +179 -0
  197. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/cloud.py +52 -0
  198. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/config.py +196 -0
  199. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/context_packets.py +76 -0
  200. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/db.py +81 -0
  201. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/doctor.py +102 -0
  202. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/figure_ids.py +42 -0
  203. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/ingest.py +326 -0
  204. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/insert.py +316 -0
  205. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/mentions.py +57 -0
  206. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/ocr.py +71 -0
  207. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/paths.py +35 -0
  208. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/pdf_engine.py +77 -0
  209. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/schema.py +155 -0
  210. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/search.py +188 -0
  211. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/tui/__init__.py +1 -0
  212. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/tui/app.py +89 -0
  213. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/tui/image_backend.py +29 -0
  214. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/pdf/tui/state.py +65 -0
  215. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/publish/__init__.py +1 -0
  216. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/publish/publish.py +1139 -0
  217. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/publish/publish_receipts.py +365 -0
  218. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/publish/publish_recovery.py +240 -0
  219. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/__init__.py +1 -0
  220. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/agent_behavior_corpus.py +2069 -0
  221. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/agent_report_validation.py +4448 -0
  222. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/agent_run_audit.py +852 -0
  223. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/architect_prompt_eval.py +341 -0
  224. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/body_linker_eval.py +240 -0
  225. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/curator_output_validation.py +175 -0
  226. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/curator_prompt_eval.py +865 -0
  227. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/quality/triager_prompt_eval.py +1295 -0
  228. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/related_notes/__init__.py +1 -0
  229. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/related_notes/related_notes.py +1920 -0
  230. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/related_notes/related_notes_headless.py +1186 -0
  231. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/__init__.py +1 -0
  232. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/plan_attestation.py +148 -0
  233. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/specialist_receipts.py +360 -0
  234. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/specialist_runtime.py +52 -0
  235. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/specialist/specialist_task_runner.py +2470 -0
  236. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/style/__init__.py +1 -0
  237. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/style/style.py +1952 -0
  238. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/subagents/__init__.py +1 -0
  239. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/subagents/agents.py +1767 -0
  240. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/__init__.py +1 -0
  241. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/alias_projection.py +331 -0
  242. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/link_terms.py +151 -0
  243. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/llm_disambiguation.py +182 -0
  244. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/__init__.py +116 -0
  245. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/audit.py +201 -0
  246. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/migration.py +314 -0
  247. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/normalize.py +72 -0
  248. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/policy.py +135 -0
  249. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/resolve.py +413 -0
  250. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/schema.py +157 -0
  251. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/taxonomy/status.py +137 -0
  252. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_bootstrap.py +509 -0
  253. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_curator_batch.py +1115 -0
  254. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_ingestion.py +632 -0
  255. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_map.py +930 -0
  256. package/.opencode/mednotes/src/mednotes/domains/wiki/capabilities/vocabulary/vocabulary_recovery.py +1388 -0
  257. package/.opencode/mednotes/src/mednotes/domains/wiki/cli.py +6665 -0
  258. package/.opencode/mednotes/src/mednotes/domains/wiki/common.py +69 -0
  259. package/.opencode/mednotes/src/mednotes/domains/wiki/config.py +210 -0
  260. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/__init__.py +74 -0
  261. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/agent_report.py +242 -0
  262. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/agent_run_audit.py +196 -0
  263. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/agents.py +601 -0
  264. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/curator.py +256 -0
  265. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/effect_payloads.py +519 -0
  266. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/happy_path.py +190 -0
  267. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/link_git.py +110 -0
  268. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/link_runtime_artifact.py +52 -0
  269. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/note_plan.py +75 -0
  270. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/paths.py +114 -0
  271. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/public_report.py +53 -0
  272. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/publish.py +111 -0
  273. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/raw_coverage.py +217 -0
  274. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/related_notes.py +136 -0
  275. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/related_notes_headless.py +153 -0
  276. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/related_notes_runtime.py +395 -0
  277. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/schema_registry.py +637 -0
  278. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/specialist.py +432 -0
  279. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/status.py +62 -0
  280. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/style_rewrite.py +568 -0
  281. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/vocabulary_ingestion.py +223 -0
  282. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/workflow_blockers.py +510 -0
  283. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/workflow_guardrails.py +637 -0
  284. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/workflow_outcomes.py +121 -0
  285. package/.opencode/mednotes/src/mednotes/domains/wiki/contracts/workflow_receipts.py +100 -0
  286. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/__init__.py +1 -0
  287. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/__init__.py +1 -0
  288. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/__main__.py +4 -0
  289. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/cli.py +275 -0
  290. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/__init__.py +2 -0
  291. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/candidates.py +193 -0
  292. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/cli.py +189 -0
  293. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/gemini.py +220 -0
  294. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/inputs.py +120 -0
  295. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/models.py +34 -0
  296. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/parsing.py +48 -0
  297. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/prompts.py +216 -0
  298. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/quality.py +54 -0
  299. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/reporting.py +24 -0
  300. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/runner.py +433 -0
  301. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/utils.py +39 -0
  302. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/enrich/workflow/vault_guard_bridge.py +17 -0
  303. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/__init__.py +1 -0
  304. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_context_packets.py +454 -0
  305. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_decision_projection.py +133 -0
  306. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_effects.py +1260 -0
  307. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_fsm.py +2768 -0
  308. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_machine.py +1588 -0
  309. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_plan.py +306 -0
  310. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_primary_objective.py +316 -0
  311. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_problem.py +153 -0
  312. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_receipt_evidence.py +306 -0
  313. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_states.py +290 -0
  314. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/fix_wiki_user_report.py +342 -0
  315. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/fix_wiki/health.py +6332 -0
  316. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/__init__.py +1 -0
  317. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_fsm.py +1119 -0
  318. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_git.py +638 -0
  319. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_machine.py +1106 -0
  320. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_retry_governance.py +374 -0
  321. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_runtime_result.py +485 -0
  322. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/link_triggers.py +183 -0
  323. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/linking.py +2758 -0
  324. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/reference_repair.py +718 -0
  325. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link/related_notes_fsm.py +1855 -0
  326. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link_related/__init__.py +1 -0
  327. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/link_related/link_related_machine.py +834 -0
  328. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/__init__.py +1 -0
  329. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/process_chats_fsm.py +1592 -0
  330. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/process_chats_machine.py +3097 -0
  331. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/process_chats_primary_objective.py +28 -0
  332. package/.opencode/mednotes/src/mednotes/domains/wiki/flows/process_chats/process_chats_runtime_result.py +185 -0
  333. package/.opencode/mednotes/src/mednotes/domains/wiki/performance.py +97 -0
  334. package/.opencode/mednotes/src/mednotes/kernel/__init__.py +6 -0
  335. package/.opencode/mednotes/src/mednotes/kernel/agent_directive.py +336 -0
  336. package/.opencode/mednotes/src/mednotes/kernel/base.py +51 -0
  337. package/.opencode/mednotes/src/mednotes/kernel/blockers.py +39 -0
  338. package/.opencode/mednotes/src/mednotes/kernel/effect_executor.py +55 -0
  339. package/.opencode/mednotes/src/mednotes/kernel/effect_intent.py +69 -0
  340. package/.opencode/mednotes/src/mednotes/kernel/effects.py +160 -0
  341. package/.opencode/mednotes/src/mednotes/kernel/errors.py +38 -0
  342. package/.opencode/mednotes/src/mednotes/kernel/fsm_event.py +35 -0
  343. package/.opencode/mednotes/src/mednotes/kernel/fsm_model.py +55 -0
  344. package/.opencode/mednotes/src/mednotes/kernel/fsm_transition_result.py +75 -0
  345. package/.opencode/mednotes/src/mednotes/kernel/guardrails.py +188 -0
  346. package/.opencode/mednotes/src/mednotes/kernel/progress.py +319 -0
  347. package/.opencode/mednotes/src/mednotes/kernel/public_report.py +346 -0
  348. package/.opencode/mednotes/src/mednotes/kernel/state_machine.py +164 -0
  349. package/.opencode/mednotes/src/mednotes/kernel/workflow.py +619 -0
  350. package/.opencode/mednotes/src/mednotes/platform/__init__.py +5 -0
  351. package/.opencode/mednotes/src/mednotes/platform/backup_policy.py +382 -0
  352. package/.opencode/mednotes/src/mednotes/platform/feedback/__init__.py +62 -0
  353. package/.opencode/mednotes/src/mednotes/platform/feedback/cli.py +275 -0
  354. package/.opencode/mednotes/src/mednotes/platform/feedback/contracts.py +83 -0
  355. package/.opencode/mednotes/src/mednotes/platform/feedback/core.py +4168 -0
  356. package/.opencode/mednotes/src/mednotes/platform/feedback/integrity.py +989 -0
  357. package/.opencode/mednotes/src/mednotes/platform/feedback/operational_contract.py +2293 -0
  358. package/.opencode/mednotes/src/mednotes/platform/feedback/telemetry.py +875 -0
  359. package/.opencode/mednotes/src/mednotes/platform/feedback/telemetry_config.py +65 -0
  360. package/.opencode/mednotes/src/mednotes/platform/opencode_runtime_config.py +182 -0
  361. package/.opencode/mednotes/src/mednotes/platform/paths/__init__.py +1560 -0
  362. package/.opencode/mednotes/src/mednotes/platform/secrets.py +89 -0
  363. package/.opencode/mednotes/src/mednotes/platform/user_config.py +103 -0
  364. package/.opencode/mednotes/src/mednotes/platform/vault_guard.py +214 -0
  365. package/.opencode/mednotes/uv.lock +932 -0
  366. package/.opencode/mednotes.generated.json +395 -0
  367. package/.opencode/opencode.json +31 -0
  368. package/.opencode/plugins/mednotes-fsm.mjs +7 -0
  369. package/.opencode/plugins/mednotes_hook/adapters/antigravity.mjs +169 -0
  370. package/.opencode/plugins/mednotes_hook/adapters/harness_payload.mjs +103 -0
  371. package/.opencode/plugins/mednotes_hook/adapters/opencode_plugin.mjs +341 -0
  372. package/.opencode/plugins/mednotes_hook/adapters/opencode_user_config_sync.mjs +177 -0
  373. package/.opencode/plugins/mednotes_hook/anki_preflight.mjs +214 -0
  374. package/.opencode/plugins/mednotes_hook/cli.mjs +143 -0
  375. package/.opencode/plugins/mednotes_hook/diagnostics.mjs +11 -0
  376. package/.opencode/plugins/mednotes_hook/domain/agent_directive_core.mjs +160 -0
  377. package/.opencode/plugins/mednotes_hook/fsm_directive.mjs +1470 -0
  378. package/.opencode/plugins/mednotes_hook/hook_errors.mjs +120 -0
  379. package/.opencode/plugins/mednotes_hook/retention.mjs +114 -0
  380. package/.opencode/plugins/mednotes_hook/runtime.mjs +174 -0
  381. package/.opencode/plugins/mednotes_hook/telemetry_capture.mjs +511 -0
  382. package/.opencode/plugins/mednotes_hook/vault_guard.mjs +624 -0
  383. package/AGENTS.md +57 -0
  384. package/README.md +194 -0
  385. package/adapters/antigravity/agents.json +80 -0
  386. package/adapters/antigravity/templates/med-chat-triager.md +214 -0
  387. package/adapters/antigravity/templates/med-flashcard-maker.md +72 -0
  388. package/adapters/antigravity/templates/med-knowledge-architect.md +241 -0
  389. package/adapters/antigravity/templates/med-link-graph-curator.md +187 -0
  390. package/adapters/antigravity/templates/med-publish-guard.md +71 -0
  391. package/adapters/gemini-cli/gemini-extension.json +14 -0
  392. package/adapters/gemini-cli/package.json +15 -0
  393. package/adapters/gemini-cli/pyproject.toml +48 -0
  394. package/bin/mednotes-opencode.mjs +155 -0
  395. package/contracts/agents.json +116 -0
  396. package/core/agents/med-chat-triager.md +197 -0
  397. package/core/agents/med-flashcard-maker.md +56 -0
  398. package/core/agents/med-knowledge-architect.md +224 -0
  399. package/core/agents/med-link-graph-curator.md +171 -0
  400. package/core/agents/med-publish-guard.md +55 -0
  401. package/core/commands/flashcards.toml +22 -0
  402. package/core/commands/mednotes/create.toml +22 -0
  403. package/core/commands/mednotes/enrich.toml +24 -0
  404. package/core/commands/mednotes/fix-wiki.toml +24 -0
  405. package/core/commands/mednotes/history.toml +19 -0
  406. package/core/commands/mednotes/link-body.toml +22 -0
  407. package/core/commands/mednotes/link-related.toml +24 -0
  408. package/core/commands/mednotes/link.toml +24 -0
  409. package/core/commands/mednotes/pdf-library.toml +24 -0
  410. package/core/commands/mednotes/process-chats.toml +20 -0
  411. package/core/commands/mednotes/setup.toml +18 -0
  412. package/core/commands/mednotes/status.toml +24 -0
  413. package/core/commands/mednotes/telemetry.toml +24 -0
  414. package/core/commands/report.toml +23 -0
  415. package/core/skills/THIRD_PARTY_NOTICES.md +45 -0
  416. package/core/skills/create-medical-flashcards/SKILL.md +113 -0
  417. package/core/skills/create-medical-note/SKILL.md +90 -0
  418. package/core/skills/enrich-medical-note/SKILL.md +120 -0
  419. package/core/skills/fix-medical-wiki/SKILL.md +559 -0
  420. package/core/skills/link-medical-wiki/SKILL.md +224 -0
  421. package/core/skills/obsidian-cli/SKILL.md +118 -0
  422. package/core/skills/obsidian-markdown/SKILL.md +207 -0
  423. package/core/skills/obsidian-markdown/references/CALLOUTS.md +58 -0
  424. package/core/skills/obsidian-markdown/references/EMBEDS.md +63 -0
  425. package/core/skills/obsidian-markdown/references/PROPERTIES.md +61 -0
  426. package/core/skills/obsidian-ops/SKILL.md +136 -0
  427. package/core/skills/pdf-library/SKILL.md +45 -0
  428. package/core/skills/process-medical-chats/SKILL.md +246 -0
  429. package/core/skills/workflow-report/SKILL.md +100 -0
  430. package/package.json +45 -0
@@ -0,0 +1,278 @@
1
+ # Flashcard Ingestion Design
2
+
3
+ Doc e fonte unica de regras locais de ingestao p/ flashcards medicos no Anki. Metodologia vive em `${extensionPath}/docs/anki-mcp-twenty-rules.md`, copia operacional do prompt MCP `/twenty_rules` do servidor `anki-mcp`. Copia local existe pq subagents Gemini CLI nao chamam slash prompts MCP. Doc define decisoes de design da extensao Medical Notes Workbench.
4
+
5
+ ## Contrato Runtime
6
+
7
+ `/flashcards` e FSM-first. Agentes e consumidores devem orientar o fluxo por
8
+ `progress_view_model`, `state_machine_snapshot`, `decision`, `receipt`,
9
+ `reports` e `agent_directive.control`, nao por conclusoes soltas do agente.
10
+ Quando existir, `diagnostic_context` e apenas evidencia opcional para explicar
11
+ problema, retry, bloqueio ou investigacao; ele nao escolhe rota nem autoriza
12
+ efeito.
13
+
14
+ ## Modelos Anki Gerenciados
15
+
16
+ Skill mantem **dois** note types no Anki, provisionados via Anki MCP de `${extensionPath}/docs/anki-templates/`:
17
+
18
+ - `Medicina` (Q&A, `isCloze: false`) — campos `Frente`, `Verso`, `Verso Extra`, `Obsidian`. Cards pergunta/resposta classica.
19
+ - `Medicina Cloze` (cloze, `isCloze: true`) — campos `Texto`, `Verso Extra`, `Obsidian`. Campo `Texto` carrega `{{c1::...}}`, `{{c2::...}}`. Um card por grupo de cloze.
20
+
21
+ **Roteamento por card:** subagent decide modelo por candidato. Use `Medicina Cloze` p/ definicao/fato encadeado/enumeracao curta (Twenty Rules #5, #9). Use `Medicina` p/ pergunta com resposta atomica. Cada `candidate_card` deve declarar `note_model`.
22
+
23
+ **Provisao dos modelos:** antes de gravar, skill chama `mcp_anki-mcp_modelNames` + `mcp_anki-mcp_modelFieldNames` e roda:
24
+
25
+ ```bash
26
+ uv run python ${extensionPath}/scripts/mednotes/flashcards/install_models.py ensure --existing - --output -
27
+ ```
28
+
29
+ JSON resultante traz lista `actions` com `mcp_anki-mcp_createModel` (modelo ausente) ou `mcp_anki-mcp_updateModelTemplates` + `mcp_anki-mcp_updateModelStyling` (HTML/CSS divergiu). Se modelo aparecer como `incompatible` (mesmo nome, campos diferentes), pare e peca usuario apagar/renomear no Anki Desktop.
30
+
31
+ Arquivos HTML/CSS em `${extensionPath}/docs/anki-templates/` sao fonte de verdade. Nao edite modelos no Anki Desktop — alteracoes sao sobrescritas no proximo run.
32
+
33
+ ## Regras De Conteúdo Para Cards Bonitos
34
+
35
+ Templates dao consistencia visual; conteudo limpo e responsabilidade da skill. Aplique sempre:
36
+
37
+ - **Frente Q&A:** pergunta atomica, ate 120 chars. Sem ponto-final desnecessario, sem prefixo "Pergunta:".
38
+ - **Verso Q&A:** 1-2 frases curtas, direto. Nao repita pergunta, nao comece com "A resposta e".
39
+ - **Verso Extra (ambos):** raciocinio, contexto, mnemonicos, fontes curtas. Comece com `\n\n` (texto puro) ou `<br><br>` (HTML). Use bullets `<ul><li>` ou `-`. Nunca repita Verso/cloze.
40
+ - **Cloze (`Texto`):** enunciado fluente. Max 2-3 grupos `{{cN::...}}` por card. Cada cloze = unidade atomica; nunca paragrafo inteiro. Mantenha contexto suficiente p/ leitura com sentido.
41
+ - **Obsidian:** deeplink copiado do manifest tipado da fonte. Dentro de vault
42
+ confiavel, prefira `obsidian://open?vault=Wiki_Medicina&file=Cardio%2FPonte.md`
43
+ com path POSIX relativo ao vault. Fora de vault confiavel, use fallback de
44
+ path real como
45
+ `obsidian://open?path=%2FUsers%2Fleo%2FWiki%20Medicina%2FCardio%2FPonte.md`.
46
+ Template renderiza como botao "Abrir no Obsidian".
47
+ - **Sem markdown solto:** evite headings (`#`, `##`), negrito Markdown (`**...**`), codigo com crase. Use HTML p/ enfase (`<strong>`, `<em>`, `<code>`); Anki nao converte Markdown.
48
+
49
+ ## Especificacoes De Design
50
+
51
+ 1. Hierarquia de decks: reproduza estrutura de diretorios do Obsidian como subdecks no Anki.
52
+
53
+ Exemplo:
54
+
55
+ ```text
56
+ Wiki_Medicina/Cardiologia/Ponte_Miocardica.md
57
+ -> Wiki_Medicina::Cardiologia::Ponte_Miocardica
58
+ ```
59
+
60
+ Para arquivos em `Wiki_Medicina`, use `Wiki_Medicina` como raiz, preserve diretorios intermediarios, nome do arquivo sem `.md` como folha.
61
+
62
+ Nao achate hierarquia. Se `mcp_anki-mcp_createDeck` recusar mais de dois niveis, tente criar cards diretamente no deck completo com `mcp_anki-mcp_addNotes`/`mcp_anki-mcp_addNote`; se ainda recusar, reporte falha sem trocar deck.
63
+
64
+ 2. Tags Anki: nao adicionar tags. Omita `tags` ou envie lista vazia. Tags Obsidian podem selecionar notas mas nao viram tags Anki.
65
+
66
+ 3. Formatacao do campo: antes de inserir em `Verso Extra`, adicione espaco visual no inicio — `\n\n` (texto puro) ou `<br><br>` (HTML).
67
+
68
+ 4. Campo de origem: todo card de nota Markdown usa o deeplink do
69
+ `FlashcardSourceManifest`. O agente copia `fields.Obsidian` do manifest ou
70
+ deixa vazio para o pipeline tipado preencher; ele nunca fabrica uma URI.
71
+
72
+ ```bash
73
+ uv run python ${extensionPath}/scripts/mednotes/obsidian_note_utils.py deeplink <nota.md>
74
+ ```
75
+
76
+ O comando acima e utilitario tecnico para diagnostico/geracao do manifest;
77
+ nao substitui o manifest tipado. Dentro de vault, o link preferido e
78
+ `obsidian://open?vault=Wiki_Medicina&file=Cardio%2FPonte.md`, com path POSIX
79
+ vault-relativo. Fora de vault confiavel, o fallback e
80
+ `obsidian://open?path=%2FUsers%2Fleo%2FWiki%20Medicina%2FCardio%2FPonte.md`,
81
+ usando path real resolvido. Nao dependa da Obsidian CLI p/ extrair esse link.
82
+
83
+ Resolver pode inferir raiz do vault por `--vault-root`, `[paths].wiki_dir` em
84
+ `~/.gemini/medical-notes-workbench/config.toml`, compatibilidade
85
+ (`MED_WIKI_DIR`/config legado) ou diretorio `.obsidian` ancestral p/
86
+ preencher metadata (`vault_root`, `vault_relative_path`), deck e deeplink
87
+ preferido. `--vault-file` continua existindo como compatibilidade tecnica,
88
+ mas o padrao de manifest dentro do vault ja prefere `vault=...&file=...`.
89
+
90
+ 5. Marcacao da nota-fonte: apos pelo menos um card criado com sucesso, marque apenas essa nota com tag Obsidian `anki` via:
91
+
92
+ ```bash
93
+ uv run python ${extensionPath}/scripts/mednotes/obsidian_note_utils.py add-tag --tag anki <nota.md>
94
+ ```
95
+
96
+ Para desfazer:
97
+
98
+ ```bash
99
+ uv run python ${extensionPath}/scripts/mednotes/obsidian_note_utils.py remove-tag --tag anki <nota.md>
100
+ ```
101
+
102
+ Nao marque notas sem cards criados. Em sucesso parcial, marque so arquivos com pelo menos um card aceito.
103
+
104
+ ## Regra De Base De Conhecimento
105
+
106
+ `/twenty_rules` sem namespace e reservado para prompt MCP `twenty_rules` do servidor global `anki-mcp`. Extensao nao declara outro Anki MCP no manifest (evita duplicacao com `~/.gemini/settings.json`) e nao cria comando local `/twenty_rules` (evita colisao).
107
+ Referencia upstream: `@ankimcp/anki-mcp-server/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/content.md`.
108
+ Agente carrega metodologia por `read_file` em `${extensionPath}/docs/anki-mcp-twenty-rules.md`.
109
+ Comando `/flashcards` aceita arquivo, multiplos arquivos, diretorios, globs, filtros por tag Obsidian e instrucoes em linguagem natural.
110
+ Tag Obsidian `anki` e reservada p/ notas que ja geraram cards com sucesso.
111
+
112
+ Ao receber `/flashcards <escopo>`, agente deve:
113
+
114
+ 1. Resolver escopo com `flashcard_sources.py resolve --scope "<escopo>" --dry-run`.
115
+ 2. Usar `read_file` p/ extrair conteudo de cada arquivo em `manifest.notes[].path`.
116
+ 3. Formular cards candidatos sem gravar no Anki.
117
+ 4. Preparar plano com `flashcard_pipeline.py prepare`.
118
+ 5. No modo padrao, mostrar cards no terminal e pedir confirmacao antes de gravar. Criacao direta so permitida quando usuario pedir explicitamente.
119
+ 6. Usar exclusivamente conteudo lido desses arquivos como base (o "O QUE" dos flashcards).
120
+ 7. Aplicar rigorosamente `${extensionPath}/docs/anki-mcp-twenty-rules.md` e especificacoes deste doc como "COMO".
121
+
122
+ Nao use conhecimento externo p/ acrescentar fatos. Conhecimento medico geral pode ser usado apenas p/ entender, segmentar e redigir melhor o conteudo ja presente.
123
+
124
+ ## Resolucao De Escopo Para `/flashcards`
125
+
126
+ 1. Use resolver deterministico antes de ler notas ou chamar subagent:
127
+
128
+ ```bash
129
+ uv run python ${extensionPath}/scripts/mednotes/flashcard_sources.py resolve --scope "<argumentos>" --dry-run --skip-tag anki
130
+ ```
131
+
132
+ Retorna JSON com `schema`, `summary`, `scope`, `notes`, `skipped_notes` e `warnings`.
133
+
134
+ 2. Arquivos explicitos, diretorios e globs: resolver inclui apenas Markdown (`.md`/`.markdown`), ignora `dist/`, `.git/`, caches, anexos, imagens e nao-Markdown.
135
+ 3. Tags Obsidian: resolver filtra por frontmatter `tags`/`tag` e hashtags inline. Tag e criterio de selecao, exceto marcacao pos-sucesso `anki`.
136
+ 4. Pastas em linguagem natural: p/ frases como `notas com tag #revisar na
137
+ pasta Cardiologia`, resolver procura pasta dentro de `--vault-root`, `--wiki-dir` ou `wiki_dir` de `~/.gemini/medical-notes-workbench/config.toml`; env/config legado aceitos como compatibilidade.
138
+ 5. Escopo ambiguo: se resolver falhar pedindo raiz, pergunte qual vault/wiki e rode com `--vault-root <pasta>` ou `--wiki-dir <pasta>`.
139
+ 6. Notas ja processadas: por padrao, `/flashcards` deve passar `--skip-tag anki` p/ evitar duplicacao. Se usuario pedir refazer/regenerar, rode sem esse filtro. Notas puladas aparecem em `skipped_notes` com `skip_reason: "skip_tag"` e `skip_tags: ["anki"]`.
140
+ 7. Manifest por nota: cada item em `notes` traz `path`, `deck`, `deeplink`, `vault_relative_path`, `link_mode`, `tags`, `already_marked_anki`, `content_sha256`, `line_count` e `heading_count`. Use esses campos como fonte operacional de deck/link; leia conteudo factual separadamente com `read_file`.
141
+ 8. Lotes grandes: se `summary.requires_confirmation` for verdadeiro, mostre previa e peca confirmacao antes de formular/gravar. Para previa textual:
142
+
143
+ ```bash
144
+ uv run python ${extensionPath}/scripts/mednotes/flashcard_sources.py preview --scope "<argumentos>" --dry-run --skip-tag anki
145
+ ```
146
+
147
+ `preview` usa mesma resolucao de `resolve` mas emite texto humano em vez de JSON.
148
+
149
+ ## Manifest De Cards Candidatos E Idempotencia
150
+
151
+ Apos resolver fontes e ler arquivos com `read_file`, agente formula cards candidatos antes de chamar Anki MCP. Formato minimo:
152
+
153
+ ```json
154
+ {
155
+ "source_manifest": {},
156
+ "preferred_models": {
157
+ "qa": "Medicina",
158
+ "cloze": "Medicina Cloze"
159
+ },
160
+ "models": {
161
+ "Medicina": ["Frente", "Verso", "Verso Extra", "Obsidian"],
162
+ "Medicina Cloze": ["Texto", "Verso Extra", "Obsidian"]
163
+ },
164
+ "candidate_cards": [
165
+ {
166
+ "source_path": "/path/nota.md",
167
+ "source_content_sha256": "sha256-da-nota",
168
+ "deck": "Wiki_Medicina::Cardiologia::Ponte_Miocardica",
169
+ "note_model": "Medicina",
170
+ "fields": {
171
+ "Frente": "...",
172
+ "Verso": "...",
173
+ "Verso Extra": "\n\n...",
174
+ "Obsidian": "obsidian://open?vault=Wiki_Medicina&file=Cardiologia%2FPonte_Miocardica.md"
175
+ }
176
+ },
177
+ {
178
+ "source_path": "/path/nota.md",
179
+ "source_content_sha256": "sha256-da-nota",
180
+ "deck": "Wiki_Medicina::Cardiologia::Ponte_Miocardica",
181
+ "note_model": "Medicina Cloze",
182
+ "fields": {
183
+ "Texto": "A {{c1::ponte miocárdica}} envolve mais frequentemente a {{c2::DA}}.",
184
+ "Verso Extra": "\n\nDescrita pela primeira vez em 1737.",
185
+ "Obsidian": "obsidian://open?vault=Wiki_Medicina&file=Cardiologia%2FPonte_Miocardica.md"
186
+ }
187
+ }
188
+ ]
189
+ }
190
+ ```
191
+
192
+ `preferred_model` (singular) ainda aceito como atalho legado quando todos cards sao Q&A. Para fluxo padrao, use `preferred_models` com duas chaves.
193
+
194
+ Antes de gravar, filtre duplicados locais:
195
+
196
+ ```bash
197
+ uv run python ${extensionPath}/scripts/mednotes/flashcard_index.py check --candidates <candidate_cards.json>
198
+ ```
199
+
200
+ Grave somente `new_cards`. Apos Anki MCP aceitar, registre apenas cards aceitos:
201
+
202
+ ```bash
203
+ uv run python ${extensionPath}/scripts/mednotes/flashcard_index.py record --accepted <accepted_cards.json>
204
+ ```
205
+
206
+ Indice padrao em `~/.gemini/medical-notes-workbench/FLASHCARDS_INDEX.json`, sobrescrito por `MED_FLASHCARDS_INDEX` ou `--index`. Tag Obsidian `anki` continua como marcador visual/filtro; idempotencia real passa pelo indice local.
207
+
208
+ Para fluxo completo, prefira orquestrador deterministico:
209
+
210
+ ```bash
211
+ uv run python ${extensionPath}/scripts/mednotes/flashcard_pipeline.py prepare --input <run.json>
212
+ uv run python ${extensionPath}/scripts/mednotes/flashcard_pipeline.py apply --input <accepted-run.json>
213
+ ```
214
+
215
+ `prepare` combina validacao de modelo, status de fontes alteradas, checagem de duplicidade, queries de `findNotes` e payload `anki_notes` p/ `addNotes`. `apply` registra cards aceitos e devolve relatorio estruturado.
216
+
217
+ Payload de `prepare` precisa incluir campos de modelo capturados do Anki MCP. Em modo candidato, subagent chama `mcp_anki-mcp_modelNames` + `mcp_anki-mcp_modelFieldNames`, escolhe `preferred_model` quando compativel e devolve `models` como `{modelo: [campos...]}` ou lista `{name, fields}`. Em modo de gravacao, use `anki_find_queries` do plano p/ rodar `mcp_anki-mcp_findNotes` antes de `addNotes`; cards encontrados no Anki sao pulados como duplicados.
218
+
219
+ ## Preview Antes Da Escrita
220
+
221
+ Comportamento padrao de `/flashcards` e preview-first: apos formular `candidate_cards` e rodar `flashcard_pipeline.py prepare`, mostre cards no terminal e aguarde confirmacao antes de chamar `mcp_anki-mcp_addNotes`/`mcp_anki-mcp_addNote`.
222
+
223
+ Use plano retornado por `prepare` como entrada:
224
+
225
+ ```bash
226
+ uv run python ${extensionPath}/scripts/mednotes/flashcard_report.py preview-cards --input <write-plan.json>
227
+ ```
228
+
229
+ Se usuario nao confirmar, finalize sem escrever no Anki, sem registrar no `FLASHCARDS_INDEX.json` e sem marcar notas com tag `anki`.
230
+
231
+ Modo direto opcional: se usuario pedir explicitamente `--create`, `--direct`, `--yes`, `--no-preview`, "criar diretamente", "crie direto", "sem preview", "sem previa" ou "sem confirmacao", pule apenas essa confirmacao de preview. Fluxo direto ainda valida modelo, filtra duplicados, respeita falhas do Anki MCP e registra apenas cards aceitos.
232
+
233
+ Se houver mais de 40 cards candidatos, modo padrao mostra preview completo e pede confirmacao antes de qualquer escrita.
234
+
235
+ ## Validacao De Modelo Anki
236
+
237
+ Antes de chamar `mcp_anki-mcp_addNotes`/`mcp_anki-mcp_addNote`, valide modelo:
238
+
239
+ ```bash
240
+ uv run python ${extensionPath}/scripts/mednotes/anki_model_validator.py validate --models-json <models.json>
241
+ ```
242
+
243
+ JSON de entrada representa resultado de `modelNames` + `modelFieldNames`:
244
+
245
+ ```json
246
+ {
247
+ "Medicina": ["Frente", "Verso", "Verso Extra", "Obsidian"],
248
+ "Medicina Cloze": ["Texto", "Verso Extra", "Obsidian"]
249
+ }
250
+ ```
251
+
252
+ Para validar os dois modelos juntos, use `validate-set`:
253
+
254
+ ```bash
255
+ uv run python ${extensionPath}/scripts/mednotes/anki_model_validator.py validate-set --models-json <models.json>
256
+ ```
257
+
258
+ Se algum modelo faltar campos obrigatorios, pare e rode `flashcards/install_models.py ensure` p/ instalar/atualizar.
259
+
260
+ ## Sincronizacao Das Twenty Rules
261
+
262
+ Para auditar copia local contra pacote Anki MCP instalado:
263
+
264
+ ```bash
265
+ uv run python ${extensionPath}/scripts/mednotes/sync_anki_twenty_rules.py check
266
+ ```
267
+
268
+ Use `--source <content.md>` p/ apontar explicitamente para o prompt upstream. Use `write` apenas p/ substituir copia local pela upstream.
269
+
270
+ ## Relatorio Final
271
+
272
+ Quando fluxo tiver dados estruturados de fontes, duplicados, cards aceitos, validacao de modelo e erros do Anki MCP, gere resposta final com:
273
+
274
+ ```bash
275
+ uv run python ${extensionPath}/scripts/mednotes/flashcard_report.py final --input <run-result.json>
276
+ ```
277
+
278
+ Relatorio deve separar: notas processadas, cards criados, cards pulados por duplicidade, notas puladas, erros de modelo/campos e erros do Anki MCP.
@@ -0,0 +1,208 @@
1
+ ---
2
+ name: med-knowledge-architect
3
+ description: Guardião do Padrão Ouro da Wiki Medicina. Define estrutura de Mini-Aula, taxonomia por especialidades e zonas gerenciadas pelo linker.
4
+ ---
5
+
6
+ # Med Knowledge Architect (A Mente)
7
+
8
+ Autoridade de estrutura, estilo e taxonomia da `Wiki_Medicina`. Grafo,
9
+ WikiLinks, aliases e `Notas Relacionadas` pertencem a `semantic-linker.md`.
10
+
11
+ ## 🏆 O Padrão Ouro: Estrutura de Mini-Aula
12
+
13
+ Toda nota deve funcionar como aula de alto rendimento para residência. Cubra,
14
+ quando aplicável: título médico preciso; epidemiologia; etiologia/fisiopatologia;
15
+ apresentação clínica; diferenciais; diagnóstico com padrão-ouro vs exame inicial;
16
+ manejo/tratamento; fechamento; notas relacionadas.
17
+
18
+ Fechamento obrigatório: `## 🏁 Fechamento`, com `### Resumo`,
19
+ `### Key Points` e `### Frase de Prova`.
20
+
21
+ ## 🧱 Formato Wiki
22
+
23
+ - Primeiro heading após YAML: `# Título Médico Preciso`.
24
+ - YAML mínimo e canônico: somente `aliases`, tags operacionais (`anki`,
25
+ `revisar`, `indice`/`índice`), `chats[]` e metadados `images_*`
26
+ preservados/adicionados por workflows. Não inclua `title`, `tipo`, `status`,
27
+ `fonte`, taxonomia, categoria ou tag clínica. Omita YAML se tudo estiver
28
+ vazio.
29
+ - Quando YAML existir, listas devem ser sempre multiline (`aliases:\n - ...`,
30
+ `tags:\n - ...`); nunca use listas inline como `aliases: [...]` ou
31
+ `tags: [...]`. Nunca adicione `tags: [medicina]` ou tag clínica genérica.
32
+ - `indice`/`índice` marca notas operacionais que devem ser ignoradas por grafo,
33
+ linker, bootstrap/reset e auditorias de estilo; não use essa tag em nota
34
+ clínica comum.
35
+ - Nota operacional Dataview ou de índice não segue o modelo de nota médica:
36
+ preserve frontmatter, queries, code blocks e layout operacional; não adicione
37
+ seções clínicas, `## 🏁 Fechamento`, `## 🔗 Notas Relacionadas`, provenance ou
38
+ reescrita didática.
39
+ - Não invente tags; não use `cardio`, `gastro`, especialidades ou categorias em
40
+ `tags`. Taxonomia clínica é caminho de pasta.
41
+ - Após o título, escreva definição de 2-4 linhas: o que é e por que cai.
42
+ - A nota deve responder: quando pensar? como confirmar? o que fazer? qual
43
+ pegadinha?
44
+ - Todo `##` começa com um emoji semântico: `🎯`, `🧠`, `🔎`, `🩺`, `⚖️`, `⚠️`,
45
+ `🏁`, `🔗`, `🧬`.
46
+ - Separe parágrafos, listas, tabelas, callouts e headings por linha em branco.
47
+ - Callouts Obsidian ficam isolados: `> [!tip]`, `> [!warning]`, `> [!danger]`,
48
+ `> [!info]`.
49
+ - Tabelas Markdown devem ter colunas consistentes. Em tabela, escape pipe de
50
+ alias: `[[Cineangiocoronariografia (Cateterismo)\|CATE]]`.
51
+ - Sempre inclua `## 🔗 Notas Relacionadas` como heading estrutural. Não
52
+ preencha bullets manualmente; `/mednotes:link` reescreve o bloco gerenciado.
53
+ - Proveniência de chat é contrato do parent: `chats[]` é o campo consultável e
54
+ `## 🧬 Fontes Consolidadas` é a seção visível final. Não use rodapé legado.
55
+
56
+ ```markdown
57
+ ---
58
+ chats:
59
+ - id: <fonte_id>
60
+ ---
61
+ ...
62
+ ## 🧬 Fontes Consolidadas
63
+ - [Título do chat](https://gemini.google.com/app/<fonte_id>)
64
+ ```
65
+
66
+ Não troque por URL local, deeplink Obsidian, `Fonte`, `Original` ou backlink
67
+ para o índice. Não escreva bullets de `## 🔗 Notas Relacionadas`; essa seção é
68
+ gerenciada pelo linker.
69
+
70
+ ## Diagramas Mermaid E Equacoes
71
+
72
+ Use Mermaid ou equacoes quando uma secao clinica tiver fluxo, classificacao,
73
+ cadeia causal, algoritmo decisorio ou calculo que fique mais claro como
74
+ representacao visual ou matematica. O bloco deve ficar dentro da secao clinica
75
+ correspondente, logo depois do texto que o justifica.
76
+
77
+ Nao crie secao generica de "Mapa Mental", "Diagramas" ou "Formulas". Nao use
78
+ visual decorativo. Nao invente relacoes, etapas, numeros, limiares ou formulas
79
+ que nao estejam sustentados pelo material-fonte.
80
+
81
+ Se a secao ja estiver clara em texto linear, nao force Mermaid nem equacao.
82
+
83
+ ## Artefatos Do Gemini
84
+
85
+ Se o parent fornecer `artifact_manifests` com schema
86
+ `gemini-md-export.artifact-html-manifest.v1`, cada HTML é insumo obrigatório do
87
+ grupo de notas do raw chat. Não inline HTML no Markdown. A nota que carregar o
88
+ artefato deve incluir iframe, link auditável e comentário:
89
+
90
+ ```markdown
91
+ <iframe src="file:///CAMINHO/ARTEFATO.html" width="100%" height="820" loading="lazy"></iframe>
92
+ [abrir artefato HTML](file:///CAMINHO/ARTEFATO.html)
93
+ <!-- gemini-artifact
94
+ chat_id: <chatId>
95
+ manifest: <artifact-manifest-path>
96
+ file: <artifact-html-path>
97
+ sha256: <hash>
98
+ -->
99
+ ```
100
+
101
+ Se o parent fornecer `gemini-md-export.artifact-image-manifest.v1`, cada imagem
102
+ gerada/exportada pelo Gemini também é insumo obrigatório. A nota que carregar a
103
+ imagem deve incluir embed Markdown, legenda didática e o mesmo comentário de
104
+ proveniência:
105
+
106
+ ```markdown
107
+ ![Legenda didática](file:///CAMINHO/IMAGEM.png)
108
+
109
+ *Figura: Legenda didática.* *Fonte: Gemini Web — https://gemini.google.com/app/<chatId>*
110
+
111
+ <!-- gemini-artifact
112
+ kind: image
113
+ chat_id: <chatId>
114
+ manifest: <artifact-manifest-path>
115
+ file: <artifact-image-path>
116
+ sha256: <hash>
117
+ -->
118
+ ```
119
+
120
+ Se algum HTML ou imagem obrigatória faltar, bloqueie o raw chat e nomeie o
121
+ arquivo. Não contorne autenticação, cookies, sandbox, CORS ou permissões.
122
+
123
+ ## 🇧🇷 Brasil vs Internacional
124
+
125
+ - Se UpToDate/diretriz internacional divergir de diretriz brasileira, mostre
126
+ ambas e destaque a conduta esperada em prova brasileira.
127
+ - Inclua pegadinhas de ENARE/SES-DF/SUS-SP quando conhecidas.
128
+
129
+ ## 🎨 Callouts
130
+
131
+ - `> [!tip] Pulo do Gato`: mnemônicos.
132
+ - `> [!warning] Pegadinha de Banca`: confusões frequentes.
133
+ - `> [!danger] Red Flag`: sinais de alarme.
134
+ - `> [!info] Diretriz Brasileira`: divergência nacional relevante.
135
+
136
+ ## 📂 Taxonomia
137
+
138
+ A taxonomia operacional é somente caminho de pastas de categoria sob
139
+ `Wiki_Medicina`; o `title` vira o arquivo `.md`. Use
140
+ `1. Clínica Médica/Cardiologia/Arritmias` + título `Fibrilação Atrial`; nunca
141
+ inclua o título como pasta final.
142
+
143
+ Fonte de verdade: `scripts/mednotes/wiki_tree.py --max-depth 4 --audit`
144
+ (`--format text` para leitura humana). Alternativas operacionais:
145
+ `taxonomy-canonical`, `taxonomy-tree`, `taxonomy-audit`. Política canônica:
146
+ `bundle/docs/taxonomy-policy.md`, derivada de `wiki/taxonomy/policy.py`.
147
+
148
+ Áreas fixas: `1. Clínica Médica`, `2. Cirurgia`,
149
+ `3. Ginecologia e Obstetrícia`, `4. Pediatria`, `5. Medicina Preventiva`.
150
+ Não invente sexta área, categoria canônica, grafia, singular/plural, pasta
151
+ intermediária ou variação de acento/underscore. Reuse a árvore real exatamente.
152
+ Nova pasta fora do prefixo canônico só pode ser **uma folha única** sob pai
153
+ coerente e autorizada pelo dry-run em `taxonomy_new_dirs`.
154
+ Nova leaf pode aparecer em dry-run, mas publish real só pode criar a pasta se o
155
+ recibo do dry-run para o mesmo manifest autorizar exatamente aqueles
156
+ `taxonomy_new_dirs`.
157
+ Em `3. Ginecologia e Obstetrícia`, a grande área é combinada, mas as categorias
158
+ filhas são separadas: use `Ginecologia` ou `Obstetrícia`; nunca crie ou mire
159
+ `3. Ginecologia e Obstetrícia/Ginecologia e Obstetrícia`.
160
+
161
+ Mínimo: `Grande Área/Categoria/Título.md`. Grupos abaixo da categoria são
162
+ opcionais quando já existem ou quando o dry-run autoriza. Não crie
163
+ `1. Clínica Médica/Clínica Médica/Semiologia`.
164
+
165
+ Movimentos preexistentes são CLI, não manuais:
166
+ `taxonomy-migrate --dry-run --plan-output <plano.json>`;
167
+ `taxonomy-migrate --apply --plan <plano.json> --receipt <recibo.json>`;
168
+ `taxonomy-migrate --rollback --receipt <recibo.json>`.
169
+
170
+ Distribuição canônica: `1. Clínica Médica` inclui Cardiologia, Dermatologia,
171
+ Endocrinologia, Gastroenterologia, Geriatria, Hematologia, Imunologia,
172
+ Infectologia, Medicina Interna, Nefrologia, Neurologia, Nutrologia, Oncologia,
173
+ Pneumologia, Reumatologia, Semiologia, Psiquiatria; `2. Cirurgia` inclui
174
+ Cirurgia Geral, Clínica Cirúrgica, Oftalmologia, Urologia, Trauma,
175
+ Anestesiologia; `3. Ginecologia e Obstetrícia` inclui Ginecologia e Obstetrícia
176
+ como categorias filhas separadas;
177
+ `4. Pediatria` inclui Pediatria, Neonatologia, Puericultura, Infecto Pediátrica;
178
+ `5. Medicina Preventiva` inclui Medicina Preventiva, SUS, Epidemiologia, Ética
179
+ Médica, Saúde do Trabalho.
180
+
181
+ ## 🔗 Grafo E Triagem
182
+
183
+ - **Identidade:** `1 meaning canônico = 1 nota Wiki`. Quando mais de um chat
184
+ cobre o mesmo meaning, escreva uma nota canônica com múltiplos `chats[]` e
185
+ deltas em `## 🧬 Fontes Consolidadas`.
186
+ - **Grafo/linker:** A nota médica deve reservar a seção `## 🔗 Notas Relacionadas`,
187
+ mas WikiLinks, aliases, body linker e Related Notes são do
188
+ `/mednotes:link`. Não invente links nem bullets manuais para cumprir quota.
189
+ - **Triagem:** Toda nota vem de raw chat triado com `titulo_triagem` e
190
+ `note_plan` descritivo/exaustivo.
191
+ - **Chats longos:** A triagem inventaria todos os temas duráveis. Cada tema vira
192
+ `planned_meaning` ou recebe motivo tipado para não virar nota. Architect segue
193
+ esse plano, não subconjunto.
194
+ - **Fidelidade ao chat-fonte:** Em notas derivadas de `Chats_Raw`, o architect
195
+ deve preservar toda informação médica relevante do raw chat nas notas
196
+ planejadas. O Padrão Ouro organiza/complementa, mas não pode substituir,
197
+ omitir ou diluir critérios, achados, condutas, exceções, comparações,
198
+ exemplos, perguntas/respostas, mecanismos, exames, contraindicações ou
199
+ detalhes de prova.
200
+ - **Deduplicação:** `planned_meaning` não pode duplicar outro item por normalização
201
+ de acento/caixa, nota existente ou raw chat do lote. Duplicata de alvo novo
202
+ vira um único `canonical_merge`; duplicata de nota existente chama o architect
203
+ para reescrever o alvo canônico e o parent aplica com `apply-canonical-merge`.
204
+ Ambiguidade bloqueia com decisão humana; nunca escreva nota paralela.
205
+ - **Índice Dataview:** o índice do vault é operacional e mantido pelo plugin
206
+ Dataview/Obsidian, não pelo architect. Se receber uma nota marcada
207
+ `indice`/`índice`, preserve-a como operacional e não tente convertê-la em
208
+ mini-aula médica.
@@ -0,0 +1,110 @@
1
+ # Merge Policy
2
+
3
+ Política canônica de merge para notas da `Wiki_Medicina`. Pareada com
4
+ `agent-role-contracts.md`, `triage-policy.md` e `semantic-linker.md`.
5
+
6
+ Regra-âncora:
7
+
8
+ > 1 meaning canônico = 1 nota Wiki.
9
+
10
+ ## Onde Cada Camada Decide
11
+
12
+ - **Identidade na triagem** vive como `meaning_claim` na ação
13
+ `planned_meaning` do `triage-note-plan.v2`. O triager declara meaning a
14
+ partir do raw chat; ele não consulta a Wiki nem o vocabulary DB.
15
+ - **Identidade no DB** vive como `primary_meaning` na curadoria do
16
+ `med-link-graph-curator`. Curator lê notas publicadas e consolida
17
+ meaning/aliases/surfaces no vocabulary DB. Pode propor `NoteMergeCandidate`,
18
+ nunca aplicar merge.
19
+ - **Identidade no plano de execução** vive como `target_policy` nos work
20
+ items do planner (`new_note`, `canonical_rewrite`, `note_merge_candidate`
21
+ ou `blocked`). O planner cruza `meaning_claim` contra Wiki e DB.
22
+
23
+ ## Único Merge Permitido: `note_merge`
24
+
25
+ A única API de merge entre notas publicadas é
26
+ `bundle/scripts/mednotes/wiki/note_merge.py`. Caminho canônico:
27
+
28
+ ```text
29
+ identidade semântica explícita / curator / decisão humana
30
+ → NoteMergeCandidate
31
+ → NoteMergePlan
32
+ → med-knowledge-architect rewrite (com preservation_report)
33
+ → apply-note-merge --dry-run
34
+ → apply-note-merge
35
+ → link trigger + reference repair
36
+ ```
37
+
38
+ Hash de fontes prova estabilidade de input, não preservação clínica. O
39
+ `preservation_report` do architect é o gate de preservação.
40
+
41
+ ## Proibições
42
+
43
+ - **Sem merge title-driven**: detectores `duplicate_stem`, `duplicate_title`
44
+ ou similar não podem alimentar merge automático. Título parecido vira
45
+ diagnóstico de higiene no `fix-wiki`, nunca candidato.
46
+ - **Sem `duplicate_merge` API**: `bundle/scripts/mednotes/wiki/duplicate_merge.py`
47
+ e `fix-wiki --phase duplicate-merge` estão deprecados; o caminho novo é
48
+ `note-merge`.
49
+ - **Sem merge no architect**: architect rewrites a nota canônica quando
50
+ recebe `target_policy=canonical_rewrite` ou um work item de
51
+ `note_merge_candidate`, mas nunca decide identidade nem escolhe winner.
52
+ - **Sem merge no triager**: triager não declara que duas unidades do mesmo
53
+ raw são o mesmo meaning de notas existentes; ele só descreve unidades
54
+ daquele raw.
55
+ - **Sem merge silencioso**: quando há ambiguidade real, o planner emite
56
+ `human_decision_packet`; nada de chute por similaridade textual.
57
+
58
+ ## Como `meaning_claim` Resolve
59
+
60
+ Para cada `planned_meaning` do triager, o planner faz uma lookup contra
61
+ `vocabulary DB` (camada de identidade canônica) e contra a Wiki publicada.
62
+ Saídas determinísticas:
63
+
64
+ - **Match direto** (DB tem `primary_meaning` equivalente e Wiki tem nota
65
+ canônica): `target_policy = canonical_rewrite` apontando a nota existente.
66
+ - **Match com divergência** (DB indica meaning igual a uma nota, mas outra
67
+ nota publicada também aparenta cobrir): `target_policy = note_merge_candidate`
68
+ com referência ao candidato emitido pelo curator ou bloqueio para decisão
69
+ humana.
70
+ - **Sem match** (DB não tem meaning equivalente): `target_policy = new_note`
71
+ com path resolvido a partir de taxonomia + `staged_title`.
72
+ - **Ambiguidade real** (claim conflita com mais de um canonical ou DB não
73
+ consegue cravar): `target_policy = blocked` com
74
+ `human_decision_packet`.
75
+
76
+ Nenhuma dessas decisões usa título ou stem como chave primária. A chave é o
77
+ `primary_meaning` no DB e o `meaning_claim` no plano.
78
+
79
+ ## Provenance Final
80
+
81
+ Toda nota canônica com chats conhecidos termina com
82
+ `## 🧬 Fontes Consolidadas` aplicada por `wiki.provenance`. O rodapé legado
83
+ `Chat Original` é deprecado e removido pelo backfill interno de
84
+ `/mednotes:fix-wiki`.
85
+
86
+ ## Aplicabilidade Universal
87
+
88
+ - `/mednotes:process-chats` cria nota nova ou rewrite canônico usando
89
+ `meaning_claim` da triagem, provenance via `wiki.provenance`, sem
90
+ `duplicate_merge`. A resolução de `meaning_claim` pelo planner
91
+ determinístico é a direção canônica (implementação em plano separado).
92
+ - `/mednotes:fix-wiki` normaliza o acervo antigo (backfill de `chats[]`,
93
+ remoção do rodapé legado, sincronização de `Fontes Consolidadas`) e gera
94
+ diagnósticos de higiene, mas **não** aplica merge title-driven.
95
+ - `/mednotes:link` opera somente em grafo/linker; nunca faz merge.
96
+ - Note merge real só roda via fase própria, alimentada por
97
+ `NoteMergeCandidate` semanticamente justificado.
98
+
99
+ ## Migração De Candidatos Legados
100
+
101
+ Candidatos `duplicate_stem` ainda persistidos no vocabulary DB precisam ser
102
+ revisados antes do detector ser removido. O caminho é um job de curator que:
103
+
104
+ - relê cada candidato;
105
+ - propõe `NoteMergeCandidate` quando há identidade semântica real (com
106
+ evidência citável do DB ou da nota);
107
+ - descarta com motivo redigido quando o candidato era ruído title-driven.
108
+
109
+ Sem essa migração, candidatos legados ficam órfãos e a remoção do detector
110
+ perde trabalho.