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,567 @@
1
+ # Agent Prompt Hardening
2
+
3
+ Este contrato orienta agentes e subagentes da extensão quando um workflow
4
+ falha. A regra principal: diagnosticar com comando oficial, preservar contexto,
5
+ usar dry-run/recibo e parar em drift.
6
+
7
+ ## Pacote Obrigatório
8
+
9
+ Todo agente chamado para investigar ou corrigir erro deve receber:
10
+
11
+ - `app_version`;
12
+ - workflow público e fase;
13
+ - comando oficial executado;
14
+ - erro exato;
15
+ - `blocked_reason`;
16
+ - `next_action`;
17
+ - paths operacionais permitidos;
18
+ - diagnóstico JSON e recibo/dry-run quando houver;
19
+ - schema esperado;
20
+ - hashes relevantes;
21
+ - `agent_metrics` somente quando vier de runtime/harness; não peça ao modelo
22
+ para inventar contadores;
23
+ - estado resumido de DB/fila/manifest;
24
+ - status da ferramenta, exit code do processo e status semântico do workflow
25
+ quando houver comando executado;
26
+ - escopo da evidência auditada, inclusive paths fora do escopo principal ou
27
+ superfícies não examinadas;
28
+ - stop rules aplicáveis.
29
+
30
+ Não incluir conteúdo clínico bruto, raw chats, Markdown de notas, HTML, imagens,
31
+ tokens, chaves, `.env` ou logs completos.
32
+ Não imprima `config.toml`, `.env`, defaults de telemetria, feedback records ou
33
+ hook events. `auth_token`, tokens, senhas e chaves são segredo mesmo em ambiente
34
+ de laboratório. Para conferir configuração, prefira o JSON redigido de
35
+ `validate` e reporte só paths, booleanos, status e códigos.
36
+
37
+ ## Escada De Decisão
38
+
39
+ 1. Ler workflow, phase, contrato e comando oficial.
40
+ 2. Rodar diagnóstico oficial antes de mutar.
41
+ 3. Se houver dry-run, revisar dry-run antes de apply.
42
+ 4. Aplicar apenas comando oficial com recibo.
43
+ 5. Revalidar com diagnóstico oficial.
44
+ 6. Se continuar bloqueado, produzir `diagnostic_context` e parar.
45
+ 7. Se não houver ferramenta oficial, registrar backlog; não criar script ad hoc.
46
+
47
+ ## Contratos
48
+
49
+ Cada contrato tem código `C<n>`, definição curta e, quando aplicável,
50
+ bloco-alvo do template Diagnóstico Read-Only (Bloco A–E em
51
+ `docs/workflow-output-contract.md`). Stop Rules, Pré-vôo e skills citam esses
52
+ códigos; suas definições vivem aqui.
53
+
54
+ A motivação é empírica: modelos rápidos (Flash) e grandes (Pro) exibiram
55
+ modos de falha recorrentes em runs contra o vault Wiki_Medicina quando o
56
+ contrato era prosa aberta. Cada contrato fixa um modo conhecido. Os códigos
57
+ são preservados entre relatórios para rastreabilidade.
58
+
59
+ ### C1–C8: Diagnóstico Read-Only
60
+
61
+ - **C1 NEXT_ACTION_LITERAL — Fidelidade Literal A `next_action`.** Quando um payload fresco contém
62
+ `next_action`, a resposta final copia a string literal. Caminho absoluto
63
+ permanece absoluto. Reescrita exige `literal_match=não` + justificativa no
64
+ Bloco D. Violação típica: agente recomenda
65
+ `cli.py vocabulary-recover --mode rebuild-db` quando o JSON fresco do
66
+ `vocabulary-status` traz comando absoluto com `--mode rebuild-db --dry-run`
67
+ para DB ausente. Bloco-alvo: D.
68
+ - **C2 STALE_NEEDS_FRESH — Escopo De Confirmação De Artefatos Stale.** Artefato stale só vira
69
+ "confirmado" quando o mesmo campo foi reemitido por comando fresco deste
70
+ run. Violação típica: agente diz "todos os artefatos stale foram
71
+ confirmados" depois de rodar apenas `graph-audit` e `vocabulary-status`
72
+ frescos, deixando `run-linker-diagnose` baseline sem equivalente. Bloco-alvo:
73
+ C.
74
+ - **C3 TOOL_OK_NOT_WORKFLOW_OK — Falhas De Ferramenta Mesmo Com Tool Status Success.** Se tool output
75
+ contém `Blocked`, `Command injection detected`, `Exit Code:` ≠ 0, erro de
76
+ parser, comando inexistente ou permissão negada, isso entra em "Comandos
77
+ Falhos Ou Bloqueados" mesmo que a tool call apareça como `success` e mesmo
78
+ que um comando posterior tenha funcionado. Violação típica: comparação de
79
+ artefatos stale agrupada num shell com `$(cat ...)` é bloqueada pelo guard,
80
+ e o agente omite o bloqueio no relatório final. Bloco-alvo: B (com
81
+ sentinela literal quando vazio).
82
+ - **C4 NO_UNIVERSAL_WITHOUT_DISTRIBUTION — Não Reduzir Muitos Erros A Um Único Exemplo.** Quando
83
+ `error_count > 1`, o agente não pode usar "estritamente", "apenas", "todos",
84
+ "exclusivamente", "somente" sem computar distribuição (por path e por
85
+ código) do output completo. Violação típica: declarar que os 21 erros de
86
+ `validate-wiki` "são estritamente da nota `medicine.md`" quando o arquivo
87
+ completo mostra reports distribuídos por várias notas. Bloco-alvo: E.
88
+ - **C5 DRY_RUN_IS_PLAN — Diferenciar Próxima Bateria De Resultado Prometido.** Dry-run produz
89
+ plano/diagnóstico. Nunca pode ser descrito como aplicação, eliminação,
90
+ correção ou limpeza. Violação típica: dizer que `fix-wiki --dry-run`
91
+ "elimina nós/links órfãos". Bloco-alvo: D (`expected_mutation=nenhuma`).
92
+ - **C6 ONE_AUDITABLE_COMMAND — Um Comando Auditável Por Chamada.** Cada comando auditável precisa
93
+ de exit code próprio. Ficam proibidos blocos `if`, loops, `$(...)`,
94
+ backticks, múltiplos `jq` sobre artefatos diferentes na mesma chamada e
95
+ mini scripts shell de diagnóstico. Violação típica: agrupar comparação de
96
+ artefatos antigos num único shell com `BASE_DIR=$(cat ...)` e
97
+ `for f in ...; do jq ...; done`. Bloco-alvo: A.
98
+ - **C7 DRY_RUN_FIRST_SHELL — Dry-Run Explícito Não Vira Preflight Livre.** Se o usuário pediu
99
+ `fix-wiki --dry-run`, a primeira chamada shell executa o comando oficial
100
+ `fix-wiki --dry-run --json`. `environment-preflight`, `validate-wiki`,
101
+ `taxonomy-status`, `vocabulary-status`, `graph-audit` e
102
+ `run-linker --diagnose` só entram depois se o JSON fresco pedir. Bloco-alvo:
103
+ A + D.
104
+ - **C8 TOOL_ERROR_IS_FINDING — Erro De Tool Não-Shell É Achado.** `read_file`, `activate_skill`,
105
+ tracker ou qualquer tool com `status=error` deve aparecer no relatório de
106
+ debugging, inclusive `invalid_tool_params` e path fora do workspace. Bloco B
107
+ não pode usar a sentinela vazia quando houve erro de ferramenta. Bloco-alvo:
108
+ B.
109
+
110
+ ### C9–C11: Shell E Retry
111
+
112
+ - **C9 NO_SHELL_PROBES — Probes Shell Antes De Dry-Run Explícito.** Pedido explícito de
113
+ `fix-wiki --dry-run` proíbe probes preparatórios (`ls`, `uv --version`,
114
+ teste de venv, descoberta de path). O primeiro shell command auditável é o
115
+ dry-run oficial; se ele falhar por path ou venv, a falha do comando oficial
116
+ vira evidência. Bloco-alvo: A.
117
+ - **C10 INHERIT_UV_ENV — `UV_PROJECT_ENVIRONMENT` Sobrescrito.** Não usar
118
+ `export UV_PROJECT_ENVIRONMENT=<...> && uv run ...`; herdar o ambiente
119
+ recebido pelo harness/runtime. Sobrescrita contamina o laboratório e
120
+ mascara isolamento. Operacional; sem bloco-alvo direto.
121
+ - **C11 RETRY_DOESNT_ERASE_ERROR — Retry Apaga Erro Anterior.** Quando um comando falha e um retry
122
+ recupera, o erro original continua sendo achado do run. *A successful
123
+ retry does not erase the earlier tool error.* Bloco-alvo: B.
124
+
125
+ ### C12–C18: Orquestração
126
+
127
+ Estes contratos operam fora da bateria read-only: mutação, avaliação,
128
+ subagentes e UX pública. Eles travam os modos de falha mais caros (apply
129
+ indevido, schema fabricado, bypass de evaluator).
130
+
131
+ - **C12 NEXT_ACTION_NOT_AUTHZ — `next_action` Orienta, Não Autoriza.** `next_action` indica o que
132
+ reportar/preparar; só continue quando o payload canônico trouxer
133
+ `agent_directive.control.capabilities.continue=true`, efeito executável e o
134
+ pedido original permitir continuidade. Violação típica: ler `next_action` e
135
+ executar enquanto `decision.kind=ask_human` ainda está pendente.
136
+ - **C13 OFFICIAL_ROUTE_ONLY — Rota Oficial Bloqueada Não Autoriza Fallback Paralelo.** Quando o
137
+ comando oficial retornar `blocked`, NÃO usar Obsidian CLI direto, plugin
138
+ export manual, regex de linkagem, `@generalist`, edição de SQLite/JSON ou
139
+ script ad hoc. Reportar `blocked_reason` + `next_action` e parar.
140
+ - **C14 NO_PARENT_SCHEMA — Agente Pai Não Emite Schema De Subagente.** Pai NUNCA escreve
141
+ `note-semantic-ingestion.v1`, `triage-note-plan.v2`,
142
+ `atomicity-split-bundle.v1` ou outputs por `work_item` de
143
+ `vocabulary-curator-batch-plan.v1`. Pai orquestra (`plan-subagents`,
144
+ `collect-*`, `eval-*`, `apply-*`); o subagente designado é o único emissor
145
+ do schema correspondente.
146
+ - **C15 EVAL_TERMINAL — `needs_review` É Terminal Até Output/Prompt Regenerado.**
147
+ `needs_review` em `eval-curator-batch`, `eval-triager-output` ou outro
148
+ evaluator oficial NÃO vira `approved` por edição manual do JSON de
149
+ avaliação. Editar `curator-prompt-eval.json` para destravar apply é
150
+ violação grave. Caminho oficial: regenerar output do subagent OU corrigir
151
+ prompt e reexecutar o evaluator.
152
+ - **C16 NO_EVAL_BYPASS_IN_PUBLIC — `--skip-prompt-eval` Só Como Escape Técnico Local.** O flag (ou
153
+ equivalente de bypass) exige `MEDNOTES_ALLOW_DEV_ESCAPE=1` +
154
+ `--skip-prompt-eval-reason`. Workflow público do usuário nunca usa esse
155
+ escape para destravar fluxo real; emerge como
156
+ `agent.curator_prompt_eval_skip` no recibo se for usado.
157
+ - **C17 GAP_IS_STOP — `contract_gap.missing_next_action` É Stop Rule Pura.** Reportar,
158
+ preservar `error_context.contract_gap`, parar. Não improvisar script,
159
+ `@generalist`, shell paralelo, edição manual ou bypass para "destravar".
160
+ - **C18 HARD_STOP_DECISION — `decision.kind=ask_human` É HARD STOP.** Até receber resposta
161
+ válida do usuário, NÃO avançar fase, NÃO chamar subagent, NÃO mutar, NÃO
162
+ rodar recovery/reindex/curadoria automática. Mostrar
163
+ `human_decision_packet` (opções, item afetado, `resume_action`); retomar
164
+ só após resposta.
165
+
166
+ ### C19–C20: Esqueleto Da Resposta (Mutação)
167
+
168
+ Esses contratos protegem a UX pública de workflows mutantes
169
+ (`fix-wiki --apply`, `publish-batch --apply`, `apply-*`, `run-linker --apply`,
170
+ restauração aplicada). Eles emergem do experimento C-pos-main Flash
171
+ (`docs/reports/controlled-experiments/2026-05-20-fix-wiki-apply-v70-post-main-cpos.md`),
172
+ onde Flash deslocou o `Exit Code: 3` central para uma seção auxiliar e
173
+ silenciou o pós-decisão quando `next_command=null` veio com
174
+ `resume_command` preenchido.
175
+
176
+ - **C19 PRIMARY_EXIT_CODE_IS_RESULT — Exit Code Do Comando Principal É Resultado.**
177
+ Em workflow mutante, o `Exit Code:` do comando principal (`fix-wiki --apply`,
178
+ `publish-batch --apply`, `apply-*`, `run-linker --apply`) pertence ao Bloco 1
179
+ (Resultado Do Workflow), mesmo quando ≠ 0. `Exit Code: 3` com JSON
180
+ `progress_view_model.status=blocked` ou `receipt.status=blocked` é o sinal
181
+ central do workflow, não warning auxiliar.
182
+ Avisos Auxiliares (Bloco 4) é seção restrita: tool calls `status=error`,
183
+ retries, hook errors, parâmetros inventados. Violação típica: Flash classifica
184
+ `Exit Code: 3` em "Aviso de execução" e mantém o estado bloqueado separado,
185
+ ensinando o leitor que exit code central é evento auxiliar. Bloco-alvo:
186
+ Bloco 1 do esqueleto de mutação (`docs/workflow-output-contract.md`).
187
+ - **C20 RESUME_COMMAND_AFTER_DECISION — `resume_command` Pós-Decisão Tem Texto Canônico.**
188
+ Quando o payload bloqueado traz `next_command=null` e `resume_command`
189
+ preenchido, o agente não pode (a) inventar próxima ação executável, (b)
190
+ promover `resume_command` a `next_command` sem resposta humana, nem (c)
191
+ silenciar o pós-decisão. Bloco 2 declara explicitamente: "Nenhuma próxima
192
+ ação automática agora; após decisão, retomar pelo workflow oficial."
193
+ Mostrar opções de `human_decision_packet`, item afetado e citar
194
+ `resume_action` literal (com `--run-id <run_id>` redigido) como rota
195
+ pós-decisão. Violação típica: o agente vê `next_command=null` e encerra
196
+ sem texto pós-decisão, ou copia `resume_command` para "próximos passos"
197
+ como se fosse executável agora. Bloco-alvo: Bloco 2 do esqueleto de mutação.
198
+
199
+ ### Pares Positivo/Negativo
200
+
201
+ Exemplos compactos em pt-BR, ancorados em comandos reais do `wiki/cli.py`.
202
+ Caminhos `<abs>` representam o caminho absoluto literal vindo do payload
203
+ fresco.
204
+
205
+ ```text
206
+ C1 Negativo: recomendar `cli.py vocabulary-recover --mode rebuild-db`.
207
+ C1 Positivo: copiar literal `next_action` do JSON fresco do `vocabulary-status`:
208
+ `uv run python <abs>/bundle/scripts/mednotes/wiki/cli.py vocabulary-recover
209
+ --mode rebuild-db --dry-run --json`.
210
+
211
+ C2 Negativo: "todos os artefatos stale foram confirmados pela telemetria fresca".
212
+ C2 Positivo: "`graph-audit` stale teve `error_count` e `dangling_link`
213
+ reemitidos pelo `graph-audit` fresco (confirmado). `run-linker-diagnose`
214
+ stale permanece baseline histórico apenas — não foi reexecutado nesta
215
+ rodada".
216
+
217
+ C3 Negativo: encerrar a resposta sem mencionar o comando que foi bloqueado por
218
+ `Command injection detected` mais cedo na bateria.
219
+ C3 Positivo: "Bloco B — Comandos Falhos Ou Bloqueados: `bash -c 'BASE_DIR=$(cat
220
+ manifest.env | ...); for f in ...; do jq ... < $BASE_DIR/$f; done'` —
221
+ bloqueado pelo guard em `stream-events.ndjson` com mensagem
222
+ `Command injection detected: command substitution syntax`."
223
+
224
+ C4 Negativo: "os 21 erros de `validate-wiki` são estritamente da nota
225
+ `medicine.md`."
226
+ C4 Positivo: "21 reports com erro distribuídos por várias notas; top 3 paths:
227
+ `medicine.md` (N1), `cardio/<nota>.md` (N2), `pneumo/<nota>.md` (N3); total
228
+ restante: 21 − (N1+N2+N3). Distribuição calculada a partir de
229
+ `tool-output-files/<id>.txt`."
230
+
231
+ C5 Negativo: "`fix-wiki --dry-run` proverá eliminação de nós e links órfãos."
232
+ C5 Positivo: "Próxima bateria: `fix-wiki --dry-run` (`expected_mutation=nenhuma`);
233
+ produz plano que detalha `dangling_link`, `orphan_note` e
234
+ `few_related_links`; aplicação real fica para passo subsequente após
235
+ revisão do plano."
236
+
237
+ C6 Negativo: uma única tool call rodando
238
+ `bash -lc 'BASE_DIR=$(cat manifest.env); for f in graph-audit.json
239
+ run-linker-diagnose.json; do jq "<seletor>" $BASE_DIR/$f; done'`.
240
+ Sem exit code próprio por arquivo, e qualquer falha do `jq` mascarada.
241
+ C6 Positivo: três tool calls separadas, uma por arquivo: cada uma roda
242
+ `uv run python <abs>/bundle/scripts/mednotes/wiki/cli.py <comando> --json`
243
+ ou `jq "<seletor>" <abs>/<arquivo>.json`, com exit code e stdout próprios.
244
+
245
+ C7 Negativo: para `/mednotes:fix-wiki --dry-run`, rodar antes
246
+ `validate-wiki --json`, `taxonomy-status --json` e só então
247
+ `fix-wiki --dry-run --json`.
248
+ C7 Positivo: primeira chamada shell:
249
+ `uv run python <abs>/scripts/mednotes/wiki/cli.py fix-wiki --dry-run --json`;
250
+ depois reportar/parar se a FSM trouxer `decision.kind=ask_human`, blocker
251
+ ou ausência de efeito executável.
252
+
253
+ C8 Negativo: `read_file` retorna `Path not in workspace`, mas o relatório diz
254
+ "Nenhum comando bloqueado observado".
255
+ C8 Positivo: "Bloco B — Tool errors: `read_file` em `<path>` falhou com
256
+ `Path not in workspace`; o workflow principal ainda emitiu JSON fresco,
257
+ mas o erro de ferramenta permanece achado do run."
258
+
259
+ C9 Negativo: antes do dry-run, rodar `ls` no CLI ou na venv.
260
+ C9 Positivo: primeira chamada shell é o dry-run oficial; se falhar por path ou
261
+ venv, a falha do comando oficial vira evidência.
262
+
263
+ C10 Negativo: `export UV_PROJECT_ENVIRONMENT=<global> && uv run ...`.
264
+ C10 Positivo: `uv run python <abs>/scripts/mednotes/wiki/cli.py fix-wiki --dry-run --json`
265
+ herdando o ambiente já configurado pelo harness/runtime.
266
+
267
+ C11 Negativo: `read_file` falha com `invalid_tool_params`, retry em path local
268
+ passa, e Bloco B só lista o Exit Code do workflow.
269
+ C11 Positivo: Bloco B lista o `read_file` falho e informa que o retry recuperou
270
+ leitura, sem apagar o erro original.
271
+
272
+ C12 Negativo: payload traz `decision.kind=ask_human` + `next_action`; agente lê
273
+ `next_action` como instrução,
274
+ executa `vocabulary-recover --apply` e segue.
275
+ C12 Positivo: copiar literal `decision.next_action`, reportar a decisão
276
+ pendente, mostrar `human_decision_packet.options` e parar; retomar só após
277
+ resposta humana.
278
+
279
+ C13 Negativo: `related-notes-sync --recover-export --mode auto --json` retorna
280
+ `blocked_reason: export_stale`; agente abre Obsidian CLI direto, dispara
281
+ comando do plugin Related Notes e gera o export por fora.
282
+ C13 Positivo: reportar `export_stale`, copiar `next_action` literal,
283
+ mostrar fallback oficial (`/mednotes:link-body` se
284
+ `body_only_fallback.safe=true`) e parar.
285
+
286
+ C14 Negativo: pai lê notas em
287
+ `Wiki_Medicina/cardio/<nota>.md`, infere `primary_meaning` e `aliases`,
288
+ e escreve `note-semantic-ingestion.v1` em `output_path` por conta própria.
289
+ C14 Positivo: pai roda
290
+ `plan-subagents --phase vocabulary-curation`, lança
291
+ `med-link-graph-curator` por `work_item`, coleta com
292
+ `collect-curator-outputs`, avalia com `eval-curator-batch` e aplica com
293
+ `apply-curator-batch --prompt-eval`.
294
+
295
+ C15 Negativo: `eval-curator-batch` retorna `status=needs_review`; agente
296
+ reescreve `curator-prompt-eval.json` ajustando `status=approved` e
297
+ re-roda `apply-curator-batch --prompt-eval <edited>`.
298
+ C15 Positivo: agente identifica defeito do output (alias amplo, evidência
299
+ vazada, defer ausente, rota complexa sem split), relança
300
+ `med-link-graph-curator` com `error_context`, refaz `eval-curator-batch`
301
+ e só aplica se o evaluator passar limpo.
302
+
303
+ C16 Negativo: para destravar `/mednotes:fix-wiki` com fila bloqueada em
304
+ `needs_review`, agente roda
305
+ `apply-curator-batch ... --skip-prompt-eval --skip-prompt-eval-reason
306
+ "destravar"` sem `MEDNOTES_ALLOW_DEV_ESCAPE=1` e dentro de fluxo público.
307
+ C16 Positivo: reportar `needs_review`, regenerar outputs do batch ou ajustar
308
+ prompt do curator; se inviável neste run, registrar
309
+ `contract_gap`/feedback e parar.
310
+
311
+ C17 Negativo: workflow retorna `status=blocked`,
312
+ `error_context.contract_gap=missing_next_action`; agente trata como
313
+ "preciso destravar" e improvisa apply manual, edita JSON ou chama
314
+ `@generalist`.
315
+ C17 Positivo: reportar gap literal, citar
316
+ `error_context.contract_gap`, abrir registro de feedback redigido e parar
317
+ sem mutação.
318
+
319
+ C18 Negativo: `run-linker --diagnose` retorna `decision.kind=ask_human` com
320
+ `human_decision_packet`; agente
321
+ continua para recovery do vocabulary DB, lança curator, gera outputs e
322
+ aplica batch antes de pedir decisão.
323
+ C18 Positivo: mostrar `human_decision_packet.options`, item afetado e
324
+ `resume_action`; pausar todo o pipeline; só após
325
+ resposta humana explícita, executar `resume_action`.
326
+
327
+ C19 Negativo: relatório final de `/mednotes:fix-wiki --apply` blocked traz
328
+ "Status: blocked" no topo e, em seção separada "Aviso de execução",
329
+ coloca "Exit Code: 3 durante o processamento da Wiki". Exit code central
330
+ classificado como auxiliar.
331
+ C19 Positivo: Bloco 1 — Resultado Do Workflow: `status=blocked`,
332
+ `phase=fix_wiki_apply`, `Exit Code: 3` (bloqueio do workflow),
333
+ `blocked_reason=requires_llm_rewrite`,
334
+ `primary_human_decision_kind=taxonomy_review_required`,
335
+ `changed_count=771`. Bloco 4 — Avisos Auxiliares: "Nenhum aviso auxiliar
336
+ observado após varredura dos tool outputs."
337
+
338
+ C20 Negativo: payload bloqueado traz `next_command=null` e
339
+ `resume_command` preenchido; agente encerra com "Próxima ação: nenhuma"
340
+ sem citar a rota pós-decisão, ou copia `resume_command` literal para
341
+ "Próximo comando" como se fosse executável agora.
342
+ C20 Positivo: Bloco 2 — Decisão Humana: opções de
343
+ `human_decision_packet`, item afetado, e "Nenhuma próxima ação
344
+ automática agora; após decisão, retomar pelo workflow oficial." Mostra
345
+ `--run-id <run_id>` redigido; não executa `resume_action` antes de
346
+ receber resposta humana válida.
347
+ ```
348
+
349
+ ### Como Cada Contrato Trava A Falha
350
+
351
+ Diagnóstico Read-Only (C1–C8) usa o template fechado de 5 blocos em
352
+ `docs/workflow-output-contract.md`:
353
+
354
+ - Bloco A trava C1/C6/C7 ao exigir a string exata do comando + literal de
355
+ `next_action`.
356
+ - Bloco B trava C3/C8/C11 ao tornar a varredura por comandos
357
+ bloqueados/falhos + tool errors obrigatória, com sentinela literal quando
358
+ vazia.
359
+ - Bloco C trava C2 ao exigir resposta explícita "equivalente fresco rodado?"
360
+ + "confirmado?" por artefato.
361
+ - Bloco D trava C1 (literal_match), C5 (`expected_mutation=nenhuma` em
362
+ dry-run) e a prioridade fresco-sobre-stale; reforça C7.
363
+ - Bloco E trava C4 ao proibir quantificadores universais sem distribuição
364
+ computada.
365
+
366
+ C9 é coberto por Bloco A (primeiro shell command auditável é o dry-run
367
+ oficial). C10 é operacional e auditável por `agent_events` /
368
+ `environment_context`. C11 é cobertura adicional de Bloco B.
369
+
370
+ Orquestração (C12–C18) opera fora do Diagnóstico Read-Only:
371
+
372
+ - C12 trava confusão entre orientação (relatar) e autorização (executar).
373
+ - C13 fecha rota: bloqueio oficial não autoriza shadow path.
374
+ - C14 protege divisão de papéis: pai não escreve schema de subagent.
375
+ - C15 protege o evaluator: avaliação não vira aprovação por edição.
376
+ - C16 isola o escape técnico: bypass exige env explícito e fica visível no
377
+ recibo.
378
+ - C17 transforma gap em parada limpa, não em pretexto para improviso.
379
+ - C18 transforma decisão pendente em hard stop verificável antes de
380
+ qualquer subagent/mutação.
381
+
382
+ Esqueleto Da Resposta (Mutação) (C19–C20) usa os 4 blocos fechados em
383
+ `docs/workflow-output-contract.md` §Esqueleto Da Resposta (Mutação):
384
+
385
+ - Bloco 1 trava C19 ao colocar `Exit Code:` do comando principal junto do
386
+ `status` semântico do workflow, mesmo quando ≠ 0.
387
+ - Bloco 2 trava C20 ao exigir texto canônico pós-decisão quando
388
+ `next_command=null` vem com `resume_command` preenchido, sem promover
389
+ `resume_command` a comando executável.
390
+ - Bloco 4 reforça C19/C3/C8/C11: avisos auxiliares são seção restrita a tool
391
+ errors auxiliares, retries, hook errors e parâmetros inventados;
392
+ `Exit Code:` do comando principal não entra aqui.
393
+
394
+ ## Stop Rules
395
+
396
+ Pare e escale. Condições gerais (sem código) acima; recap dos contratos
397
+ indexados abaixo.
398
+
399
+ Condições gerais:
400
+
401
+ - `UNIQUE constraint failed`;
402
+ - `sqlite_integrity_error`;
403
+ - schema drift não reparável por comando oficial;
404
+ - fila inconsistente sem dry-run oficial;
405
+ - path/hash mismatch;
406
+ - `next_action` ausente ou ignorado;
407
+ - argumento de ferramenta inventado, como `wait_for_previous`, ou qualquer
408
+ parâmetro não documentado pelo schema da tool; sequencie comandos esperando
409
+ o resultado da chamada anterior, não passando flags extras;
410
+ - `null` inesperado usado como dado válido em resumo JSON;
411
+ - artefato stale ou baseline preexistente misturado com output fresco sem
412
+ rotulagem explícita;
413
+ - artefato salvo contradizendo output fresco sem reportar divergência e sem
414
+ preferir a evidência mais recente;
415
+ - inferência sem evidência direta, como transformar "catálogo vazio" em
416
+ "corrupção" sem erro, hash, validação ou diagnóstico específico;
417
+ - conclusão final contradizer os comandos realmente executados, como declarar
418
+ que usou a rota oficial quando o terminal mostra comandos de descoberta,
419
+ caminhos errados ou shells diferentes;
420
+ - conclusão ampla demais para a evidência, como declarar isolamento total,
421
+ sucesso integral ou ambiente rigorosamente respeitado quando houve path fora
422
+ do escopo principal ou artefato relevante só contado/não auditado;
423
+ - timeout, timeout repetido ou `max_turns` esgotado;
424
+ - output sem `agent_metrics`, especialmente em `timeout_or_max_turns`;
425
+ - tentativa de usar `@generalist` ou outro agente intermediário para
426
+ orquestrar curadoria de vocabulário; o agente pai é o único orquestrador e
427
+ deve lançar `med-link-graph-curator` diretamente;
428
+ - tentativa de editar SQLite diretamente;
429
+ - tentativa de mutar Markdown em massa sem dry-run/recibo;
430
+ - drift local de prompt/runbook/script da extensão.
431
+
432
+ Contratos indexados (definições e pares em §Contratos):
433
+
434
+ - C1 NEXT_ACTION_LITERAL — `next_action` reescrita sem `literal_match=não` justificado.
435
+ - C2 STALE_NEEDS_FRESH — "stale confirmado" sem equivalente fresco neste run.
436
+ - C3 TOOL_OK_NOT_WORKFLOW_OK — `tool status=success` mascarando `Exit Code:`≠0,
437
+ `Blocked` ou parser error.
438
+ - C4 NO_UNIVERSAL_WITHOUT_DISTRIBUTION — quantificador universal sem distribuição computada.
439
+ - C5 DRY_RUN_IS_PLAN — dry-run descrito como aplicação/eliminação/correção/limpeza.
440
+ - C6 ONE_AUDITABLE_COMMAND — múltiplos comandos auditáveis empacotados em um único shell.
441
+ - C7 DRY_RUN_FIRST_SHELL — preflight antes de dry-run explícito.
442
+ - C8 TOOL_ERROR_IS_FINDING — tool `status=error` (não-shell) omitido do relatório.
443
+ - C9 NO_SHELL_PROBES — probes shell antes de dry-run oficial.
444
+ - C10 INHERIT_UV_ENV — `UV_PROJECT_ENVIRONMENT` sobrescrito em vez de herdado.
445
+ - C11 RETRY_DOESNT_ERASE_ERROR — retry "apagando" erro anterior.
446
+ - C12 NEXT_ACTION_NOT_AUTHZ — `next_action` tratado como autorização.
447
+ - C13 OFFICIAL_ROUTE_ONLY — fallback paralelo após rota oficial `blocked`.
448
+ - C14 NO_PARENT_SCHEMA — pai emitindo schema de subagente.
449
+ - C15 EVAL_TERMINAL — `needs_review` destravado por edição manual do JSON de eval.
450
+ - C16 NO_EVAL_BYPASS_IN_PUBLIC — `--skip-prompt-eval` em fluxo público sem env explícito.
451
+ - C17 GAP_IS_STOP — `contract_gap.missing_next_action` tratado como pretexto
452
+ para workaround.
453
+ - C18 HARD_STOP_DECISION — `decision.kind=ask_human` ignorado.
454
+ - C19 PRIMARY_EXIT_CODE_IS_RESULT — `Exit Code:` do comando principal
455
+ classificado como aviso auxiliar.
456
+ - C20 RESUME_COMMAND_AFTER_DECISION — `next_command=null` +
457
+ `resume_command` preenchido sem texto pós-decisão canônico, ou
458
+ `resume_command` promovido a `next_command` sem resposta humana.
459
+
460
+ ## Pré-vôo
461
+
462
+ Antes de declarar aplicado/concluído/sucesso, o agente responde mentalmente
463
+ sete perguntas. Falha em qualquer uma = reportar estado real, não conclusão.
464
+
465
+ 1. `decision.kind=ask_human` em algum payload sem resposta humana registrada?
466
+ Pare (C18).
467
+ 2. `eval-*` retornou `needs_review` que foi contornado por edição do JSON de
468
+ avaliação ou `--skip-prompt-eval` em fluxo público? Bloqueio (C15/C16).
469
+ 3. Algum comando oficial retornou `blocked_reason` e eu segui rota paralela
470
+ (Obsidian CLI direto, regex, `@generalist`, edição manual)? Bloqueio (C13).
471
+ 4. O pai emitiu schema designado a subagente
472
+ (`note-semantic-ingestion.v1`, `triage-note-plan.v2`,
473
+ `atomicity-split-bundle.v1`, output de
474
+ `vocabulary-curator-batch-plan.v1`)? Bloqueio (C14).
475
+ 5. Algum tool call `success` esconde `Exit Code:` ≠ 0 / `status=blocked` /
476
+ parser error / `invalid_tool_params`? Reporte falha (C3/C8/C11).
477
+ 6. Em mutação, `Exit Code:` do comando principal está no Bloco 1 (Resultado),
478
+ e Bloco 4 (Avisos Auxiliares) lista só tool errors auxiliares/retries/hook
479
+ errors/parâmetros inventados? `Exit Code: 3` central em "Aviso de execução"
480
+ é bug de relatório (C19). Se o payload trouxer `next_command=null` com
481
+ `resume_command` preenchido, Bloco 2 mostra opções, item afetado e a frase
482
+ canônica "Nenhuma próxima ação automática agora; após decisão, retomar
483
+ pelo workflow oficial." sem promover `resume_command` a `next_command`
484
+ (C20).
485
+ 7. A resposta visível menciona termo interno fora de `<details>`? Traduza
486
+ por `docs/public-vocabulary.md`. Categorias a escanear:
487
+ - Execução: `uv`, `--dry-run`, `--apply`, `manifest`, `batch`, `hash`,
488
+ `schema drift`, `Exit Code`.
489
+ - Estado: `next_action`, `blocked_reason`, `needs_review`,
490
+ `status=blocked`, `human_decision_required`.
491
+ - Armazenamento: `SQLite`, vocabulary DB.
492
+ - Versionamento: `commit`, `branch`, `push`, `sync_status`.
493
+ - Bypass técnico: `--skip-prompt-eval`, `MEDNOTES_ALLOW_DEV_ESCAPE`.
494
+ - Agentes: `med-link-graph-curator`, `med-knowledge-architect`,
495
+ `med-chat-triager`, `med-publish-guard`, `med-flashcard-maker`.
496
+
497
+ ## Diagnóstico Read-Only
498
+
499
+ Quando o run é uma bateria de comandos `--json` sem mutação
500
+ (`environment-preflight`, `validate-wiki`, `taxonomy-status`,
501
+ `vocabulary-status`, `graph-audit`, `run-linker --diagnose`, ou equivalentes),
502
+ o agente herda um contrato fechado de relatório final, ancorado nos 5 blocos
503
+ da seção `Diagnóstico Read-Only` em `docs/workflow-output-contract.md`:
504
+
505
+ - Bloco A — comando exato + tool status + `Exit Code:` + workflow `status` +
506
+ `next_action` literal.
507
+ - Bloco B — comandos falhos/bloqueados + tool calls `status=error` (com
508
+ sentinela literal quando vazio).
509
+ - Bloco C — artefatos stale (só "confirmado" se reemitido por comando fresco).
510
+ - Bloco D — `source`/`freshness`/`payload_next_action_literal`/`literal_match`/
511
+ `expected_mutation`.
512
+ - Bloco E — escopo quantitativo (distribuição por path/código antes de
513
+ quantificador universal).
514
+
515
+ C1–C8 são os modos de falha que o template trava (ver §Contratos para
516
+ definições e §Como Cada Contrato Trava A Falha para o mapeamento). Onde a
517
+ violação escapa do bloco (ex. caminho absoluto reescrito com
518
+ `literal_match=sim` indevido), continua existindo a Stop Rule indexada.
519
+
520
+ ## Ferramentas Oficiais
521
+
522
+ Vocabulary DB:
523
+
524
+ ```bash
525
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" vocabulary-status --json
526
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" vocabulary-recover --mode rebuild-db --dry-run --plan-output "<vocabulary-recovery-plan.json>" --json
527
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" vocabulary-recover --mode reconcile-queue --dry-run --plan-output "<vocabulary-recovery-plan.json>" --json
528
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" vocabulary-recover --mode <rebuild-db|reconcile-queue> --apply --plan "<vocabulary-recovery-plan.json>" --receipt "<vocabulary-recovery-receipt.json>" --json
529
+ ```
530
+
531
+ Publish/manifest:
532
+
533
+ ```bash
534
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" publish-status --manifest "<manifest.json>" --json
535
+ ```
536
+
537
+ Curator batch:
538
+
539
+ ```bash
540
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" eval-curator-batch --plan "<plan.json>" --outputs "<manifest.json>" --report "<eval.json>" --json
541
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" apply-curator-batch --plan "<plan.json>" --outputs "<manifest.json>" --prompt-eval "<eval.json>" --receipt "<receipt.json>" --json
542
+ ```
543
+
544
+ Triager:
545
+
546
+ ```bash
547
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" eval-triager-output --raw-file "<raw.md>" --output "<triager-output.json>" --subagent-run-receipt "<subagent-run-receipt.json>" --require-subagent-run-receipt --report "<eval.json>" --json
548
+ uv run python "${extensionPath}/scripts/mednotes/wiki/cli.py" triage --raw-file "<raw.md>" --tipo medicina --titulo "<titulo_triagem>" --fonte-id "<fonte_id>" --note-plan "<note-plan.json>" --triager-eval "<eval.json>" --json
549
+ ```
550
+
551
+ O `subagent-run-receipt.json` deve ser assinado/atestado pelo runner oficial.
552
+ O parent não cria, edita nem re-assina recibo; assinatura ausente, inválida ou
553
+ sem chave pública confiável é bloqueio de autoria, não tarefa para remendar JSON.
554
+
555
+ ## Garantia Esperada
556
+
557
+ O próximo run deve conseguir explicar, com telemetria redigida, por que um
558
+ agente escolheu continuar, aplicar, bloquear ou escalar. Root causes de
559
+ telemetria nunca devem ser consolidadas sem preservar `app_version`.
560
+
561
+ ## Installed Runtime Is Not Source
562
+
563
+ Public workflow agents must never repair a Workbench bug by editing the
564
+ installed bundle/plugin directory. Installed paths are runtime projections
565
+ and can be overwritten by update/reinstall. Report
566
+ `installed_extension_runtime_edit_forbidden`, name the canonical source file
567
+ under `bundle/`, and stop or open a development task.
@@ -0,0 +1,94 @@
1
+ # Agent Role Contracts
2
+
3
+ Contrato canônico de fronteiras entre os agentes e códigos que participam de
4
+ `process-chats`, `link` e `fix-wiki`. Prompts de agentes referenciam este
5
+ documento em vez de duplicar política.
6
+
7
+ Regra-âncora:
8
+
9
+ > 1 meaning canônico = 1 nota Wiki.
10
+
11
+ Quem pode propor identidade semântica está fixado por papel. Quem pode
12
+ escrever Markdown está fixado por papel. Quem pode aplicar mutação na Wiki
13
+ está fixado por papel. Nenhum agente pode tomar decisão fora do seu papel,
14
+ mesmo que pareça mais eficiente.
15
+
16
+ ## Matriz De Responsabilidade
17
+
18
+ | Papel | Lê | Produz | Não decide |
19
+ | --- | --- | --- | --- |
20
+ | **Triager** (`med-chat-triager`) | exatamente 1 raw chat atribuído | output top-level de triagem contendo `triage-note-plan.v2` com `meaning_claim` por unidade | existência na Wiki, merge target, canonical winner, cobertura |
21
+ | **Planner** (Python determinístico, camada de código fora dos prompts) | `note_plan` validado, Wiki, vocabulary DB, curator state | work items autocontidos para architect, ou bloqueios | corpo clínico, escrita de Markdown |
22
+ | **Architect** (`med-knowledge-architect`) | raw chat + work item + arquivos citados pelo work item | Markdown temporário ou rewrite exatamente da unidade pedida + `preservation_report` quando exigido | escopo da unidade, identidade semântica nova, decisão de merge, publicação, linker |
23
+ | **Graph Curator** (`med-link-graph-curator`) | nota publicada via path + content_hash + vocabulary DB | `note-semantic-ingestion.v1` (primary_meaning, aliases, surfaces, policies, `NoteMergeCandidate`) | re-triagem de raw chat, edição de Markdown, aplicação de merge |
24
+ | **Publish Guard** (`med-publish-guard`) | manifest, coverage, staged notes | parecer go/no-go com checklist auditável | clínica, meaning, qualidade de texto |
25
+
26
+ ## Artefatos Permitidos Por Papel
27
+
28
+ - Triager: output top-level de triagem com `decision`, `raw_file` e
29
+ `medical-notes-workbench.triage-note-plan.v2`. `agent_metrics` só é aceito
30
+ como métrica de runtime; o agente não deve inventar contadores.
31
+ - Planner: artefatos internos de execução; nunca emite Markdown.
32
+ - Architect: Markdown em `temp_output`, mais
33
+ `medical-notes-workbench.architect-preservation-report.v1` quando o work
34
+ item exigir.
35
+ - Curator: `medical-notes-workbench.note-semantic-ingestion.v1`; pode propor
36
+ `NoteMergeCandidate` dentro do mesmo envelope.
37
+ - Publish guard: `medical-notes-workbench.publish-guard-report.v1`.
38
+
39
+ ## Decisões Proibidas Por Papel
40
+
41
+ ### Triager nunca
42
+
43
+ - consulta vocabulary DB ou Wiki como autoridade de existência;
44
+ - emite ação de cobertura existente removida do contrato v2;
45
+ - escolhe `winner_path`, canonical target ou merge;
46
+ - usa título/stem/alias como identidade canônica;
47
+ - pede decisão humana para insegurança genérica que deveria virar
48
+ `needs_context` ou critério editorial;
49
+ - divide o raw chat em fragmentos abaixo da unidade semântica.
50
+
51
+ ### Planner nunca
52
+
53
+ - escreve corpo clínico;
54
+ - inventa `meaning_claim` que não veio do triager;
55
+ - decide existência por título/stem;
56
+ - substitui decisão humana por chute silencioso.
57
+
58
+ ### Architect nunca
59
+
60
+ - re-triagena o raw chat;
61
+ - adiciona, remove, funde ou renomeia unidades planejadas;
62
+ - decide se um meaning já existe;
63
+ - escolhe merge target;
64
+ - aplica publicação, linker ou edição direta na Wiki;
65
+ - carrega caminhos antigos de `duplicate_merge` ou rodapé `Chat Original`.
66
+
67
+ ### Curator nunca
68
+
69
+ - re-triagena raw chat;
70
+ - decide que um raw deveria ter gerado outra nota;
71
+ - edita Markdown;
72
+ - chama subagente;
73
+ - usa título/stem como detector de merge.
74
+
75
+ ### Publish Guard nunca
76
+
77
+ - avalia qualidade clínica;
78
+ - resolve meaning;
79
+ - aceita publish sem consistência entre manifest, coverage e staged notes.
80
+
81
+ ## Fronteira Code Vs Agente
82
+
83
+ Quando o que está em jogo é determinístico — leitura de vocabulary DB,
84
+ hashing, cruzamento de coverage, derivação de path canônico — a decisão
85
+ pertence ao planner Python, não a um agente. Agentes existem para tarefas
86
+ que exigem julgamento sobre conteúdo médico em linguagem natural. Tudo o que
87
+ puder ser implementado como função pura em `wiki.*` deve ficar lá.
88
+
89
+ ## Como Os Prompts Referenciam Este Documento
90
+
91
+ Todo prompt sob `bundle/agents/` que toca process-chats / link / fix-wiki
92
+ carrega este doc via `${extensionPath}/docs/agent-role-contracts.md` e
93
+ acrescenta apenas o checklist específico do seu papel. Política compartilhada
94
+ não deve ser duplicada em prompt.