textflowkit 0.1.12__tar.gz → 0.1.14__tar.gz

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 (238) hide show
  1. {textflowkit-0.1.12 → textflowkit-0.1.14}/.github/workflows/ci.yml +13 -2
  2. textflowkit-0.1.14/AGENTS.md +27 -0
  3. {textflowkit-0.1.12 → textflowkit-0.1.14}/CHANGELOG.md +44 -0
  4. {textflowkit-0.1.12 → textflowkit-0.1.14}/CONTRIBUTING.md +4 -0
  5. {textflowkit-0.1.12 → textflowkit-0.1.14}/PKG-INFO +62 -25
  6. {textflowkit-0.1.12 → textflowkit-0.1.14}/README.md +61 -24
  7. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/adapters.md +13 -7
  8. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/architecture.md +21 -6
  9. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/assets/architecture-overview.svg +1 -1
  10. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/assets/whistle-resume.svg +5 -5
  11. textflowkit-0.1.14/docs/deepseek-worker.md +29 -0
  12. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/index.html +16 -14
  13. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/install.md +12 -8
  14. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/release-checklist.md +51 -2
  15. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/roadmap.md +18 -1
  16. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/streaming.md +4 -4
  17. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/user-manual.md +43 -22
  18. textflowkit-0.1.14/docs/verification/whistle-coverage-20261019.md +77 -0
  19. textflowkit-0.1.14/docs/verification/windows-sources-20261019.md +51 -0
  20. {textflowkit-0.1.12 → textflowkit-0.1.14}/packaging/windows/README.md +12 -5
  21. {textflowkit-0.1.12 → textflowkit-0.1.14}/packaging/windows/THIRD-PARTY-NOTICES.txt +13 -1
  22. textflowkit-0.1.14/packaging/windows/source-materials.json +39 -0
  23. {textflowkit-0.1.12 → textflowkit-0.1.14}/pyproject.toml +5 -1
  24. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/prepare_windows_payload.py +18 -0
  25. textflowkit-0.1.14/scripts/run_deepseek_worker.py +110 -0
  26. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/__init__.py +1 -1
  27. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/checkpoint.py +1 -1
  28. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/whistle.py +220 -21
  29. textflowkit-0.1.14/tests/fixtures/whistle_seam_regressions.json +3767 -0
  30. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_sdist_allowlist.py +4 -0
  31. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_whistle_engine.py +13 -13
  32. textflowkit-0.1.14/tests/test_whistle_seams.py +187 -0
  33. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_windows_payload.py +70 -0
  34. textflowkit-0.1.12/packaging/windows/source-materials.json +0 -20
  35. {textflowkit-0.1.12 → textflowkit-0.1.14}/.dockerignore +0 -0
  36. {textflowkit-0.1.12 → textflowkit-0.1.14}/.env.example +0 -0
  37. {textflowkit-0.1.12 → textflowkit-0.1.14}/.gitattributes +0 -0
  38. {textflowkit-0.1.12 → textflowkit-0.1.14}/.github/dependabot.yml +0 -0
  39. {textflowkit-0.1.12 → textflowkit-0.1.14}/.github/workflows/publish-pypi.yml +0 -0
  40. {textflowkit-0.1.12 → textflowkit-0.1.14}/.gitignore +0 -0
  41. {textflowkit-0.1.12 → textflowkit-0.1.14}/.pre-commit-config.yaml +0 -0
  42. {textflowkit-0.1.12 → textflowkit-0.1.14}/Dockerfile +0 -0
  43. {textflowkit-0.1.12 → textflowkit-0.1.14}/LEGAL.md +0 -0
  44. {textflowkit-0.1.12 → textflowkit-0.1.14}/LICENSE +0 -0
  45. {textflowkit-0.1.12 → textflowkit-0.1.14}/SECURITY.md +0 -0
  46. {textflowkit-0.1.12 → textflowkit-0.1.14}/compose.yaml +0 -0
  47. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/.nojekyll +0 -0
  48. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/404.html +0 -0
  49. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/assets/live-streaming-flow.svg +0 -0
  50. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/assets/local-ui-flow.svg +0 -0
  51. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/site-deployment.md +0 -0
  52. {textflowkit-0.1.12 → textflowkit-0.1.14}/docs/sources.md +0 -0
  53. {textflowkit-0.1.12 → textflowkit-0.1.14}/packaging/windows/assets.lock.json +0 -0
  54. {textflowkit-0.1.12 → textflowkit-0.1.14}/packaging/windows/launch.py +0 -0
  55. {textflowkit-0.1.12 → textflowkit-0.1.14}/packaging/windows/textflowkit.iss +0 -0
  56. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/build_windows_installer.py +0 -0
  57. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/fetch_published_fonts.py +0 -0
  58. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/smoke_installed_wheel.py +0 -0
  59. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/smoke_live_youtube.py +0 -0
  60. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/verify_readme_release.py +0 -0
  61. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/verify_release_ci.py +0 -0
  62. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/verify_release_versions.py +0 -0
  63. {textflowkit-0.1.12 → textflowkit-0.1.14}/scripts/write_release_manifest.py +0 -0
  64. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/adapters/__init__.py +0 -0
  65. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/adapters/http_server.py +0 -0
  66. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/adapters/mcp_server.py +0 -0
  67. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/adapters/streaming_ws.py +0 -0
  68. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/assets/README.md +0 -0
  69. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/assets/selftest-speech.wav +0 -0
  70. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/cli.py +0 -0
  71. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/__init__.py +0 -0
  72. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/batch.py +0 -0
  73. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/bind.py +0 -0
  74. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/cancel.py +0 -0
  75. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/diarize.py +0 -0
  76. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/engine.py +0 -0
  77. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/executor.py +0 -0
  78. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/jobs.py +0 -0
  79. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/model.py +0 -0
  80. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/paths.py +0 -0
  81. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/pipeline.py +0 -0
  82. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/retrieval.py +0 -0
  83. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/runner.py +0 -0
  84. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/service.py +0 -0
  85. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/sqlite_store.py +0 -0
  86. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/startup.py +0 -0
  87. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/stream_worker.py +0 -0
  88. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/streaming.py +0 -0
  89. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/streaming_assets.py +0 -0
  90. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/streaming_events.py +0 -0
  91. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/streaming_process.py +0 -0
  92. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/submission.py +0 -0
  93. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/timeutil.py +0 -0
  94. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/translate.py +0 -0
  95. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/whistle_assets.py +0 -0
  96. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/core/windows_process.py +0 -0
  97. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/__init__.py +0 -0
  98. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/_cue_layout.py +0 -0
  99. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/_cue_text.py +0 -0
  100. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/_rename_excl.py +0 -0
  101. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/_rename_noreplace.py +0 -0
  102. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/docx.py +0 -0
  103. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/markdown.py +0 -0
  104. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/pdf.py +0 -0
  105. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/srt.py +0 -0
  106. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/txt.py +0 -0
  107. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/render/vtt.py +0 -0
  108. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/sources/__init__.py +0 -0
  109. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/sources/acquire.py +0 -0
  110. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/sources/detect.py +0 -0
  111. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/sources/scratch.py +0 -0
  112. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/__init__.py +0 -0
  113. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/app.py +0 -0
  114. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/capabilities.py +0 -0
  115. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/cleanup.py +0 -0
  116. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/launcher.py +0 -0
  117. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/ownership.py +0 -0
  118. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/paths.py +0 -0
  119. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/security.py +0 -0
  120. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/static/app.css +0 -0
  121. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/static/app.js +0 -0
  122. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/static/cleanup.js +0 -0
  123. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/static/index.html +0 -0
  124. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/static/streaming-capture-worklet.js +0 -0
  125. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/static/streaming-example.html +0 -0
  126. {textflowkit-0.1.12 → textflowkit-0.1.14}/src/textflowkit/ui/uploads.py +0 -0
  127. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/__init__.py +0 -0
  128. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/ollama_stub.py +0 -0
  129. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_acquire.py +0 -0
  130. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_adapters.py +0 -0
  131. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_admission_ownership.py +0 -0
  132. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_atomic_resume.py +0 -0
  133. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_atomic_resume_aba.py +0 -0
  134. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_batch.py +0 -0
  135. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_batch_item_boundary.py +0 -0
  136. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_batch_resume_shared.py +0 -0
  137. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_bind.py +0 -0
  138. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_cancellation_finalization.py +0 -0
  139. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_checkpoint.py +0 -0
  140. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_checkpoint_single_copy.py +0 -0
  141. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_cli.py +0 -0
  142. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_cli_batch_feedback.py +0 -0
  143. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_cli_owning_recovery.py +0 -0
  144. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_cli_resume_batch.py +0 -0
  145. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_cli_stage_feedback.py +0 -0
  146. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_cli_stdout_format.py +0 -0
  147. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_confined_decoder_boundary.py +0 -0
  148. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_confined_indirect_media.py +0 -0
  149. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_confined_resume_boundary.py +0 -0
  150. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_container_example.py +0 -0
  151. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_cue_layout.py +0 -0
  152. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_diarize.py +0 -0
  153. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_diarize_example_flags.py +0 -0
  154. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_diarize_token_docs.py +0 -0
  155. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_docx_publication_identity.py +0 -0
  156. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_done_output_integrity.py +0 -0
  157. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_empty_formats_resume.py +0 -0
  158. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_engine_adapters.py +0 -0
  159. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_engine_cache.py +0 -0
  160. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_engine_faster.py +0 -0
  161. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_engine_quiet.py +0 -0
  162. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_executor.py +0 -0
  163. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_executor_store_failure.py +0 -0
  164. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_export.py +0 -0
  165. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_export_file_mode.py +0 -0
  166. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_export_preflight.py +0 -0
  167. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_faster_whisper_docs.py +0 -0
  168. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_fetch_published_fonts.py +0 -0
  169. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_font_notices.py +0 -0
  170. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_http_host_boundary.py +0 -0
  171. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_http_trusted_proxy.py +0 -0
  172. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_job_progress.py +0 -0
  173. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_jobs.py +0 -0
  174. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_landing_commands.py +0 -0
  175. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_landing_page.py +0 -0
  176. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_legal_summary.py +0 -0
  177. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_linux_no_hardlink.py +0 -0
  178. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_live_smoke_script.py +0 -0
  179. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_macos_no_hardlink.py +0 -0
  180. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_mcp_batch_cookie_docs.py +0 -0
  181. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_mcp_http_boundary.py +0 -0
  182. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_mcp_protocol_cleanliness.py +0 -0
  183. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_mcp_terminal_guidance.py +0 -0
  184. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_mcp_tool_descriptions.py +0 -0
  185. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_mcp_work_root.py +0 -0
  186. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_model.py +0 -0
  187. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_partial_output_resume.py +0 -0
  188. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_partial_pdf_resume.py +0 -0
  189. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_paths.py +0 -0
  190. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_pipeline_integrity.py +0 -0
  191. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_pipeline_resume_setup.py +0 -0
  192. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_production_browser_cookies.py +0 -0
  193. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_publish_ci_gate.py +0 -0
  194. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_publish_fonts_wiring.py +0 -0
  195. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_publish_manifest_wiring.py +0 -0
  196. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_publish_workflow_gate.py +0 -0
  197. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_readme_layout.py +0 -0
  198. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_readme_release_guard.py +0 -0
  199. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_release_boundaries.py +0 -0
  200. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_release_manifest.py +0 -0
  201. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_release_surfaces.py +0 -0
  202. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_render.py +0 -0
  203. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_retrieval.py +0 -0
  204. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_service_profile.py +0 -0
  205. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_site_not_found.py +0 -0
  206. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_sources.py +0 -0
  207. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_stage_reuse_resume.py +0 -0
  208. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_startup_recovery.py +0 -0
  209. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_stdio_protocol.py +0 -0
  210. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_streaming_assets.py +0 -0
  211. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_streaming_browser_lifecycle.py +0 -0
  212. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_streaming_core.py +0 -0
  213. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_streaming_example.py +0 -0
  214. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_streaming_repairs.py +0 -0
  215. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_streaming_transport.py +0 -0
  216. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_streaming_u5_repairs.py +0 -0
  217. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_streaming_ui_integration.py +0 -0
  218. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_submission.py +0 -0
  219. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_submission_validation.py +0 -0
  220. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_translate.py +0 -0
  221. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_translate_completeness.py +0 -0
  222. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_assets_and_capabilities.py +0 -0
  223. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_cleanup.py +0 -0
  224. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_consoleless_logging.py +0 -0
  225. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_existing_routes_unchanged.py +0 -0
  226. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_launcher.py +0 -0
  227. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_ownership_and_shutdown.py +0 -0
  228. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_packaging.py +0 -0
  229. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_real_serve.py +0 -0
  230. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_security.py +0 -0
  231. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_submission_and_download.py +0 -0
  232. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_ui_uploads.py +0 -0
  233. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_verify_release_versions.py +0 -0
  234. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_whistle_assets.py +0 -0
  235. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_whistle_defaults.py +0 -0
  236. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_whistle_job_resume.py +0 -0
  237. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_windows_installer.py +0 -0
  238. {textflowkit-0.1.12 → textflowkit-0.1.14}/tests/test_windows_no_hardlink.py +0 -0
@@ -45,9 +45,20 @@ jobs:
45
45
  if: runner.os == 'Linux'
46
46
  run: sudo apt-get update && sudo apt-get install -y ffmpeg
47
47
 
48
- - name: Install ffmpeg (Windows)
48
+ - name: Install pinned ffmpeg (Windows)
49
49
  if: runner.os == 'Windows'
50
- run: choco install ffmpeg --no-progress -y
50
+ shell: python
51
+ run: |
52
+ import os, runpy
53
+ from pathlib import Path
54
+ ns = runpy.run_path('scripts/prepare_windows_payload.py')
55
+ spec = ns['load_asset_lock'](Path('packaging/windows/assets.lock.json'))['assets']['ffmpeg']
56
+ cache = Path(os.environ['RUNNER_TEMP']) / 'textflowkit-ci-ffmpeg'
57
+ archive = ns['_download_locked_asset'](cache, spec)
58
+ destination = cache / 'payload'
59
+ ns['prepare_ffmpeg_archive'](archive, destination)
60
+ with open(os.environ['GITHUB_PATH'], 'a', encoding='utf-8') as f:
61
+ f.write(str(destination / 'bin') + '\n')
51
62
 
52
63
  - name: Install ffmpeg (macOS)
53
64
  if: runner.os == 'macOS'
@@ -0,0 +1,27 @@
1
+ # TextFlowKit agent instructions
2
+
3
+ Scott's current bounded completion contract governs this work. Follow the active task and repository-required CI; preserve unrelated work and credentials. Keep one concise execution record, reuse unaffected evidence, and distinguish prepared, executed, verified and delivered work. A documented blocker remains incomplete. Do not invent adjacent features or weaken checks.
4
+
5
+ ## Roles and delegation
6
+
7
+ The main assistant coordinates, plans and oversees. A worker invoked for an implementation unit performs that assigned unit directly; it is not another coordinator. Do not launch nested workers or automatic review/fan-out unless the owner or assignment explicitly authorizes it. Default to serial execution and one release candidate.
8
+
9
+ ## Model selection
10
+
11
+ Follow Scott's active task selection; do not impose a project-wide Ollama default. His normal substantial-work/coordination preference is gpt-6.1-sol at medium, with gpt-6-luna at xhigh for small bounded work when available. Do not spawn a worker merely to switch models or add providers without authorization.
12
+
13
+ ## Required harness for all TextFlowKit DeepSeek coding (owner directive, 2026-10-19)
14
+
15
+ Whenever DeepSeek is selected for coding work on TextFlowKit, use native **headless Codex exec through Ollama**, model **`deepseek-v4.1-flash:1017-cloud`**, thinking OFF (`model_reasoning_effort = "none"`). This is a standing project instruction, not limited to one release. The observed provider response ID is `deepseek-v4.1-flash:1017`; verify it from transport receipts, not model self-description.
16
+
17
+ **Do not use `scripts/run_deepseek_worker.py`, another custom agent loop, or Claude Code for this work.** If the approved setup is missing, blocked or broken after restart, inspect/repair it within authorization or report the concrete blocker; never silently fall back, change the model, enable reasoning, or bypass safeguards.
18
+
19
+ Use the dedicated worker worktree, separate CODEX_HOME/profile/temp directories, allowlisted environment and supported Windows workspace-write sandbox. No personal auth/settings/hooks/MCP configuration copied; no inherited provider/GitHub tokens; no nested workers or publishing. A worktree isolates changes, not all disk reads. Supply a scoped brief through stdin and retain native Codex events, provider model/reasoning evidence and actual tool results.
20
+
21
+ Read `docs/deepseek-worker.md` before the next DeepSeek unit and after restart. Verified local launcher: `C:\Users\scott\Documents\Codex\2026-09-21\re\outputs\headless-codex-deepseek-20261019\run-codex.ps1`; local state and evidence are alongside it. This selects the harness whenever DeepSeek is used; it does not make DeepSeek the default for unrelated work.
22
+
23
+ This does not change the application's transcription or AI-cleanup defaults. Whistle remains the default transcription engine.
24
+
25
+ ## Scope and delivery safeguards
26
+
27
+ Preserve unfinished work. Workers must not push, merge, tag, publish, release, stop unrelated processes, or change global configuration unless that unit is explicitly authorized to do so. The coordinating release task has Scott's push/merge/tag/publication authorization and separately his authorization to complete issue #31. Keep scratch, caches and build outputs outside the checkout. Verify process identity before acting on a PID; record ownership and terminal result for background jobs. Follow enforced controls rather than disguising a rejected action.
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.1.14 — 2026-10-19
4
+
5
+ Documentation-only patch; core 0.1.14, unchanged optional fonts 0.1.6.
6
+
7
+ - Persist the required native headless Codex workflow for all TextFlowKit DeepSeek coding: exact `deepseek-v4.1-flash:1017-cloud`, thinking off, isolated worktree/configuration/environment, supported Windows sandbox, and no silent fallback to the historical Python runner or Claude Code.
8
+ - Link the workflow from contributor and integration documentation and update current package/manual/website release references.
9
+ - No transcription, cleanup, streaming, dependency, or installer behavior change. The latest verified Windows installer remains v0.1.13 and retains its matching FFmpeg sources/notices. Native/live proof remains explicitly attributed to that earlier release; no new accuracy claim.
10
+ - Math comparison fixtures, local logs, model credentials and machine-local launcher/profile files are not included.
11
+
12
+ ## v0.1.13 — 2026-10-19
13
+
14
+ Core: 0.1.13; unchanged optional fonts: 0.1.6. Whistle missing-speech fixes and a
15
+ native Windows installer distributed with matching FFmpeg sources and notices.
16
+
17
+ - Bound native Whistle decode inputs to 15 seconds with 11-second owned cores
18
+ and up to two seconds of context per side. The former 30-second inputs
19
+ reproducibly omitted passages recovered by shorter inputs. Window policy is
20
+ part of resume identity; partial progress from the old plan requires a fresh
21
+ run. The engine and pinned model remain Whistle.
22
+ - Check short gaps with a bounded, differently framed native decode. Add words
23
+ only between two matching timed anchors; retain original words/repetitions,
24
+ skip long pauses, and cap extra calls per core. Record recovery counts.
25
+ - Correct Whistle shared-context assembly when independently estimated word
26
+ timestamps cause both neighboring cores to keep or discard the same occurrence.
27
+ Match occurrences one-to-one; preserve real repeated speech and leave ambiguous
28
+ collapsed repetitions untouched rather than using global text deduplication.
29
+ - Persist raw boundary context in Whistle progress schema 2 so resumed assembly
30
+ matches uninterrupted output. Old schema-1 partial runs require a fresh start;
31
+ completed jobs remain unchanged. Default engine remains Whistle.
32
+ - The native 30-second omission cases remain reproducible upstream; shorter
33
+ input windows and anchored gap checks mitigate them in TextFlowKit without
34
+ changing the engine or model weights.
35
+ - Verification on one four-hour public meeting (1310 native cores, 18 min 34 s
36
+ native decode, 34,723 final words): the two long missing passages were
37
+ restored (2 to 50 and 0 to 47 words), 62 short-gap checks accepted 7 for 53
38
+ added words, resume after cores 350 and 700 reproduced exact word text and
39
+ timings, and no invalid bounds or backwards starts remained. Focused suite:
40
+ 113 passed. Full suite: 2,097 passed, 18 skipped; skips are not passes. This is
41
+ coverage evidence for one recording, not human WER or perfect accuracy; normal
42
+ spelling errors remain. See
43
+ [the verification note](docs/verification/whistle-coverage-20261019.md).
44
+
45
+ - Package matching FFmpeg sources, pinned build recipes, dependency archives and full notices alongside the Windows installer; record source hashes and preserve compatible DLL replacement. See [source verification](docs/verification/windows-sources-20261019.md).
46
+
3
47
  ## v0.1.12 — 2026-10-17
4
48
 
5
49
  Core: 0.1.12; unchanged optional fonts: 0.1.6. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available.
@@ -99,3 +99,7 @@ Read [LEGAL.md](LEGAL.md) before adding a source adapter.
99
99
  ## Security
100
100
 
101
101
  Do not open a public issue for a vulnerability. See [SECURITY.md](SECURITY.md).
102
+
103
+ ## DeepSeek coding workers
104
+
105
+ When DeepSeek is selected for TextFlowKit coding, follow the required [isolated headless Codex workflow](docs/deepseek-worker.md): exact `deepseek-v4.1-flash:1017-cloud`, thinking off. Do not use the historical Python agent loop or Claude Code. This does not change application engines or make DeepSeek the default for unrelated work.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: textflowkit
3
- Version: 0.1.12
3
+ Version: 0.1.14
4
4
  Summary: Cross-platform media transcription toolkit: URL or file in, timestamped transcripts and subtitle files out.
5
5
  Project-URL: Homepage, https://www.textflowkit.org/
6
6
  Project-URL: Issues, https://github.com/scottconverse/textflowkit/issues
@@ -73,7 +73,7 @@ Cross-platform media transcription toolkit. **One core, one CLI, thin adapters.*
73
73
  [User manual](https://github.com/scottconverse/textflowkit/blob/main/docs/user-manual.md) ·
74
74
  [Developer and integration manual](https://github.com/scottconverse/textflowkit/blob/main/docs/adapters.md)
75
75
 
76
- **Current release: [v0.1.12](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.12).**
76
+ **Current release: [v0.1.14](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.14).**
77
77
 
78
78
  The [static site deployment](https://github.com/scottconverse/textflowkit/blob/main/docs/site-deployment.md) is hosted on Cloudflare
79
79
  Pages. GitHub remains the source and CI host; the website does not run the
@@ -134,7 +134,7 @@ DOCX and PDF are available through the optional `export` extra.
134
134
 
135
135
  ## Architecture
136
136
 
137
- ![TextFlowKit shared-core architecture: five thin entry points feed one core. The CLI, Python API, MCP, HTTP API, and the local browser UI (a fifth door that mounts the existing HTTP app under /api and shares the same job store, adding transport only, not a new pipeline) sit above one core that acquires and decodes media, transcribes with the default Whistle engine or an explicitly selected openai-whisper, keeps job state and resume checkpoints in an optional SQLite store, adds optional speaker or translation postprocessing, and publishes TXT, SRT, VTT, JSON, Markdown, and optional DOCX/PDF exports.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/architecture-overview.svg)
137
+ ![TextFlowKit shared-core architecture: five thin entry points feed one core. The CLI, Python API, MCP, HTTP API, and the local browser UI (a fifth door that mounts the existing HTTP app under /api and shares the same job store, adding transport only, not a new pipeline) sit above one core that acquires and decodes media, transcribes with the default Whistle engine or an explicitly selected openai-whisper, keeps job state and resume checkpoints in an optional SQLite store, adds optional speaker or translation postprocessing, and publishes TXT, SRT, VTT, JSON, Markdown, and optional DOCX/PDF exports.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.14/docs/assets/architecture-overview.svg)
138
138
 
139
139
  The design principle is **one shared core, thin doors**. Everything of substance
140
140
  lives in the core; the interfaces are thin — the local browser UI is a fifth door
@@ -158,7 +158,7 @@ see [docs/architecture.md](https://github.com/scottconverse/textflowkit/blob/mai
158
158
 
159
159
  ## Live microphone streaming (opt-in)
160
160
 
161
- In v0.1.12, live streaming supports **Windows x86_64 only**. When
161
+ In v0.1.14, live streaming supports **Windows x86_64 only**. When
162
162
  `TEXTFLOWKIT_STREAMING=1` is set, the developer HTTP app serves a `/stream`
163
163
  WebSocket and the local UI serves `/api/stream`, both transcribing a live microphone
164
164
  as you speak. A **runnable, self-hosted browser example** ships at
@@ -167,7 +167,7 @@ as you speak. A **runnable, self-hosted browser example** ships at
167
167
  No CDN, no analytics, no external fetch. Requires the `streaming` extra:
168
168
 
169
169
  ```bash
170
- python -m pip install "textflowkit[streaming]==0.1.12"
170
+ python -m pip install "textflowkit[streaming]==0.1.14"
171
171
  ```
172
172
 
173
173
  It is **off by default** — with the switch unset the endpoint does not exist — and
@@ -233,11 +233,13 @@ installs `textflowkit-fonts` for offline multilingual PDF rendering:
233
233
  python -m pip install 'textflowkit[export]'
234
234
  ```
235
235
 
236
- ## Windows desktop installer (v0.1.12; public EXE pending)
236
+ ## Windows desktop installer (latest verified installer: v0.1.13)
237
237
 
238
- An installer for the existing local browser workspace accompanies core v0.1.12. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available. The Python package remains supported for developers and integrations.
238
+ [Download Windows x64 setup](https://github.com/scottconverse/textflowkit/releases/download/v0.1.13/TextFlowKit-0.1.13-windows-x64-setup.exe) · [Matching sources and notices](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13)
239
239
 
240
- The candidate is designed to run without a separately installed Python, WSL, or
240
+ An installer for the existing local browser workspace accompanies core v0.1.13. The Windows installer and its matching FFmpeg source and notice bundles are distributed together through the [v0.1.13 release](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13). The Python package remains supported for developers and integrations.
241
+
242
+ The installer is designed to run without a separately installed Python, WSL, or
241
243
  Docker. Its bundle includes a private embeddable CPython runtime, the
242
244
  browser UI and HTTP, export, and streaming dependencies, the pinned Whistle model
243
245
  and runtime, and ffmpeg, ffprobe, and Node. The setup installs per user,
@@ -254,16 +256,16 @@ bundled; those features remain documented for the Python package when separately
254
256
  installed and configured. Streaming dependencies are bundled, but live streaming
255
257
  remains opt-in and physical browser microphone capture has not been verified.
256
258
 
257
- The candidate is designed to keep UI data outside the application install
259
+ The installer is designed to keep UI data outside the application install
258
260
  directory and preserve it on upgrades and uninstall. Stop the UI server with
259
261
  **Stop server** and wait for it to exit before upgrading or uninstalling; the
260
262
  installer will block while it is running rather than force-killing active jobs.
261
263
  Cancel a job first if it should not drain to completion. The bundle also
262
264
  includes third-party license and notice files, including FFmpeg's LGPL notices
263
265
  and corresponding-source information. Check exact notices and source-distribution
264
- details against the final bundled binaries before publication. The candidate is
266
+ details in the matching source bundles distributed with this release. The installer is
265
267
  unsigned, so Windows may show a SmartScreen warning. See the [installer candidate
266
- notes](docs/install.md#windows-desktop-installer-v0112-public-exe-pending).
268
+ notes](https://github.com/scottconverse/textflowkit/blob/main/docs/install.md#windows-desktop-installer-v0113).
267
269
 
268
270
  ## Python API
269
271
 
@@ -360,7 +362,7 @@ textflowkit export ./transcript.json --format vtt
360
362
  needs no PyTorch, so a fresh `pip install textflowkit` stays small and pulls no
361
363
  torch; `openai-whisper` is an explicitly selectable opt-in engine.
362
364
 
363
- ![Whistle bounded block run and durable resume: a decoded PCM WAV is split into 26-second cores with up to 2 seconds of context (each clip ≤ 30 s), each core runs as one owned child with forced telemetry-off flags, a partial checkpoint is written after each core, and a resume validates the source and decoded-WAV hashes then re-runs only the unfinished cores.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/whistle-resume.svg)
365
+ ![Whistle bounded block run and durable resume: a decoded PCM WAV is split into 11-second cores with up to 2 seconds of context (each clip ≤ 15 s), each core runs as one owned child with forced telemetry-off flags, a partial checkpoint is written after each core, and a resume validates the source and decoded-WAV hashes then re-runs only the unfinished cores.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.14/docs/assets/whistle-resume.svg)
364
366
 
365
367
  - **CPU only, no torch.** It runs a pinned native binary and downloads one pinned
366
368
  model on first use. Naming a GPU device is refused rather than silently
@@ -373,16 +375,26 @@ torch; `openai-whisper` is an explicitly selectable opt-in engine.
373
375
  Apple Silicon. **Intel Macs are not supported**; a request there is refused
374
376
  with a message that names the explicit `whisper` engine instead. No WSL layer
375
377
  is involved.
376
- - **How it works:** long audio is split into 26-second cores with up to 2 seconds
377
- of context on each side, so every standalone clip is ≤ 30 seconds (the native
378
- CLI's limit). Overlap words are selected by core midpoint rather than text
379
- deduplication, so repeated spoken phrases are preserved.
378
+ - **How it works:** long audio is split into 11-second cores with up to 2 seconds
379
+ of context on each side, so every standalone clip is ≤ 15 seconds. This conservative
380
+ ceiling avoids reproduced omissions on 30-second inputs. Midpoints provide initial ownership; shared-context matching
381
+ reconciles duplicate or dropped occurrences when neighboring timestamps
382
+ disagree. This is not global text deduplication: real repetitions and ambiguous
383
+ recognition are preserved. The 15-second ceiling and this assembly behavior ship
384
+ in v0.1.13; neither recovers speech the native recognizer never emits.
385
+ - **Speech-gap check (v0.1.13).** Short gaps between recognized words receive a
386
+ bounded second listen with different clip boundaries. Extra words are accepted
387
+ only between matching words on both sides at nearby times. Existing words and
388
+ repetitions stay intact; long pauses do not trigger this check. The model is
389
+ still Whistle, with the same pinned weights and telemetry settings.
380
390
  - **Standalone streaming is not used.** The native `--audio-stream` mode failed its
381
391
  coverage and is never passed; only the committed standalone output is parsed.
382
392
  - **Durable block resume.** With `TEXTFLOWKIT_DB` set, a long run writes partial
383
393
  per-block checkpoints; a resume checks the source and decoded-WAV hashes and the
384
394
  config, then re-runs only the blocks that were not finished. The durable store
385
- still assumes one owning process.
395
+ still assumes one owning process. The v0.1.13 assembly policy saves raw
396
+ boundary context with schema 2; old schema-1 partial runs must be restarted,
397
+ not resumed under the new assembly policy. Existing completed jobs are unchanged.
386
398
  - **Cancellation.** A running Whistle run terminates its exact owned child
387
399
  process bounded by a per-clip timeout. A single long `openai-whisper` model call
388
400
  is still only cancellable at its next stage boundary, as documented for the
@@ -471,7 +483,7 @@ its own beyond the `http` extra. It ships with the core package as of v0.1.10:
471
483
  a regular install of the current release carries it.
472
484
 
473
485
  ```bash
474
- python -m pip install 'textflowkit[http,export]==0.1.12'
486
+ python -m pip install 'textflowkit[http,export]==0.1.14'
475
487
  textflowkit-ui
476
488
  ```
477
489
 
@@ -542,9 +554,18 @@ browser interface share the job contract without blocking a request.
542
554
 
543
555
  ## Status
544
556
 
545
- **v0.1.12 release.** Adds optional UI-only local Ollama proofreading and native
546
- Windows installer packaging; public EXE distribution remains gated on unresolved
547
- corresponding-source compliance review, with no public installer download link.
557
+ **v0.1.14 release.** Documentation-only patch: records the required isolated headless Codex workflow for DeepSeek coding contributors. Transcription, AI cleanup and streaming behavior are unchanged from v0.1.13; fonts remain 0.1.6. The latest verified Windows installer remains v0.1.13, with its matching source and notice bundles. No new native transcription proof is claimed for this documentation patch.
558
+
559
+ **Whistle behavior introduced in v0.1.13.** Fixes reproduced Whistle speech omissions. Native decode
560
+ inputs are now bounded to 15 seconds (11-second owned cores with up to 2 seconds
561
+ of context per side), short interior speech gaps get a bounded second listen that
562
+ accepts words only between matching timed anchors, and shared-context words are
563
+ reconciled one-to-one before durable resume. Whistle remains the default engine
564
+ with the same pinned model and runtime; fonts remain 0.1.6. Progress schema 2
565
+ stores raw boundary context, so an unfinished partial job from the previous
566
+ 26-second-core plan (schema 1) must be restarted instead of resumed; completed
567
+ records are unchanged. The native Windows installer is rebuilt at v0.1.13 and
568
+ distributed with matching FFmpeg sources, notices, hashes and build instructions.
548
569
  Existing optional live streaming provides a transport-neutral
549
570
  `StreamingSession` Python API, incremental transcript events, and authenticated
550
571
  loopback WebSockets (`/stream` on the developer HTTP API and `/api/stream` on the
@@ -567,6 +588,22 @@ Linux/macOS, and the six other accepted languages were not verified. The public
567
588
  website remains static documentation and serves no streaming endpoint. Local source
568
589
  validation does not establish published-package or exact-commit CI results.
569
590
 
591
+ **v0.1.12 cleanup (historical).** The opt-in local Ollama proofreading path remains
592
+ as introduced in v0.1.12, covering the local browser UI only; it was not changed by
593
+ v0.1.13. It keeps the published 39-segment cleanup proof from v0.1.12 with no
594
+ audio-accuracy claim: that proof records segment/format handling, not recognition
595
+ accuracy.
596
+
597
+ **v0.1.13 Whistle coverage, omission, and resume.** The 15-second bound (11-second
598
+ cores plus up to 2 s context per side) fixes reproduced speech omissions on
599
+ 30-second inputs; the interior speech-gap second listen accepts extra words only
600
+ between matching timed anchors; shared-context words are reconciled one-to-one
601
+ before durable resume so a partial run rejoins without double ownership. Recognized
602
+ language coverage remains the same accepted set, and nothing here recovers speech
603
+ the native recognizer never emits. See
604
+ [docs/verification/whistle-coverage-20261019.md](https://github.com/scottconverse/textflowkit/blob/main/docs/verification/whistle-coverage-20261019.md)
605
+ for the run-by-run coverage, omission, and resume evidence.
606
+
570
607
  **Verification limit.** The local browser interface is covered by an automated
571
608
  suite, and the UI's behavior was proved on a **native Windows** machine in a real
572
609
  browser. No live optional-backend (translation/diarization) run through the UI is
@@ -589,7 +626,7 @@ MCP speech, seven-format exports and completed resume; the v0.1.8 runtime fixes
589
626
  were independently checked through fresh-process CLI restart probes, real SQLite
590
627
  setup-failure tests, and the full Windows test suite. Those checks are not new
591
628
  individual-harness receipts. That is the previous releases' record, not evidence
592
- for v0.1.12.
629
+ for v0.1.13.
593
630
 
594
631
  The v0.1.6 release was the post-v0.1.5 review repair set: security hardening
595
632
  for media acquisition and the HTTP and MCP adapters, safer subtitle wrapping and
@@ -608,7 +645,7 @@ and both [core](https://pypi.org/project/textflowkit/0.1.6/) and
608
645
  [fonts](https://pypi.org/project/textflowkit-fonts/0.1.6/) PyPI projects are
609
646
  live — that is the v0.1.6 release's evidence, not a receipt for a later release.
610
647
  Everything from here to the end of this section is the v0.1.6 release's
611
- historical record as published: it is not re-verified for v0.1.12, whose separate release evidence is not supplied by these historical paragraphs.
648
+ historical record as published: it is not re-verified for v0.1.13, whose separate release evidence is not supplied by these historical paragraphs.
612
649
  Merged-main CI passed 16/16 on the tagged commit; the published wheel and
613
650
  sdist digests match the GitHub release assets and their SHA-256 list; and a fresh
614
651
  Windows Python 3.12 install of `textflowkit[export,mcp,http]==0.1.6` from PyPI
@@ -647,9 +684,9 @@ Issues and PRs welcome. Please read [LEGAL.md](https://github.com/scottconverse/
647
684
  adapter.
648
685
 
649
686
 
650
- ## Optional local AI transcript cleanup (v0.1.12)
687
+ ## Optional local AI transcript cleanup (introduced in v0.1.12)
651
688
 
652
- v0.1.12 adds **opt-in proofreading in the local browser UI only**. After a transcription finishes, choose an
689
+ v0.1.12 adds **opt-in proofreading in the local browser UI only** (introduced in v0.1.12; unchanged in v0.1.13). After a transcription finishes, choose an
653
690
  installed local Ollama model and click **Proofread with local AI**. Cleanup never
654
691
  runs automatically. Ollama and cleanup models are not bundled in the installer.
655
692
  The optional default preference is `qwen3.5:9b` only if already installed; its
@@ -8,7 +8,7 @@ Cross-platform media transcription toolkit. **One core, one CLI, thin adapters.*
8
8
  [User manual](https://github.com/scottconverse/textflowkit/blob/main/docs/user-manual.md) ·
9
9
  [Developer and integration manual](https://github.com/scottconverse/textflowkit/blob/main/docs/adapters.md)
10
10
 
11
- **Current release: [v0.1.12](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.12).**
11
+ **Current release: [v0.1.14](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.14).**
12
12
 
13
13
  The [static site deployment](https://github.com/scottconverse/textflowkit/blob/main/docs/site-deployment.md) is hosted on Cloudflare
14
14
  Pages. GitHub remains the source and CI host; the website does not run the
@@ -69,7 +69,7 @@ DOCX and PDF are available through the optional `export` extra.
69
69
 
70
70
  ## Architecture
71
71
 
72
- ![TextFlowKit shared-core architecture: five thin entry points feed one core. The CLI, Python API, MCP, HTTP API, and the local browser UI (a fifth door that mounts the existing HTTP app under /api and shares the same job store, adding transport only, not a new pipeline) sit above one core that acquires and decodes media, transcribes with the default Whistle engine or an explicitly selected openai-whisper, keeps job state and resume checkpoints in an optional SQLite store, adds optional speaker or translation postprocessing, and publishes TXT, SRT, VTT, JSON, Markdown, and optional DOCX/PDF exports.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/architecture-overview.svg)
72
+ ![TextFlowKit shared-core architecture: five thin entry points feed one core. The CLI, Python API, MCP, HTTP API, and the local browser UI (a fifth door that mounts the existing HTTP app under /api and shares the same job store, adding transport only, not a new pipeline) sit above one core that acquires and decodes media, transcribes with the default Whistle engine or an explicitly selected openai-whisper, keeps job state and resume checkpoints in an optional SQLite store, adds optional speaker or translation postprocessing, and publishes TXT, SRT, VTT, JSON, Markdown, and optional DOCX/PDF exports.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.14/docs/assets/architecture-overview.svg)
73
73
 
74
74
  The design principle is **one shared core, thin doors**. Everything of substance
75
75
  lives in the core; the interfaces are thin — the local browser UI is a fifth door
@@ -93,7 +93,7 @@ see [docs/architecture.md](https://github.com/scottconverse/textflowkit/blob/mai
93
93
 
94
94
  ## Live microphone streaming (opt-in)
95
95
 
96
- In v0.1.12, live streaming supports **Windows x86_64 only**. When
96
+ In v0.1.14, live streaming supports **Windows x86_64 only**. When
97
97
  `TEXTFLOWKIT_STREAMING=1` is set, the developer HTTP app serves a `/stream`
98
98
  WebSocket and the local UI serves `/api/stream`, both transcribing a live microphone
99
99
  as you speak. A **runnable, self-hosted browser example** ships at
@@ -102,7 +102,7 @@ as you speak. A **runnable, self-hosted browser example** ships at
102
102
  No CDN, no analytics, no external fetch. Requires the `streaming` extra:
103
103
 
104
104
  ```bash
105
- python -m pip install "textflowkit[streaming]==0.1.12"
105
+ python -m pip install "textflowkit[streaming]==0.1.14"
106
106
  ```
107
107
 
108
108
  It is **off by default** — with the switch unset the endpoint does not exist — and
@@ -168,11 +168,13 @@ installs `textflowkit-fonts` for offline multilingual PDF rendering:
168
168
  python -m pip install 'textflowkit[export]'
169
169
  ```
170
170
 
171
- ## Windows desktop installer (v0.1.12; public EXE pending)
171
+ ## Windows desktop installer (latest verified installer: v0.1.13)
172
172
 
173
- An installer for the existing local browser workspace accompanies core v0.1.12. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available. The Python package remains supported for developers and integrations.
173
+ [Download Windows x64 setup](https://github.com/scottconverse/textflowkit/releases/download/v0.1.13/TextFlowKit-0.1.13-windows-x64-setup.exe) · [Matching sources and notices](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13)
174
174
 
175
- The candidate is designed to run without a separately installed Python, WSL, or
175
+ An installer for the existing local browser workspace accompanies core v0.1.13. The Windows installer and its matching FFmpeg source and notice bundles are distributed together through the [v0.1.13 release](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13). The Python package remains supported for developers and integrations.
176
+
177
+ The installer is designed to run without a separately installed Python, WSL, or
176
178
  Docker. Its bundle includes a private embeddable CPython runtime, the
177
179
  browser UI and HTTP, export, and streaming dependencies, the pinned Whistle model
178
180
  and runtime, and ffmpeg, ffprobe, and Node. The setup installs per user,
@@ -189,16 +191,16 @@ bundled; those features remain documented for the Python package when separately
189
191
  installed and configured. Streaming dependencies are bundled, but live streaming
190
192
  remains opt-in and physical browser microphone capture has not been verified.
191
193
 
192
- The candidate is designed to keep UI data outside the application install
194
+ The installer is designed to keep UI data outside the application install
193
195
  directory and preserve it on upgrades and uninstall. Stop the UI server with
194
196
  **Stop server** and wait for it to exit before upgrading or uninstalling; the
195
197
  installer will block while it is running rather than force-killing active jobs.
196
198
  Cancel a job first if it should not drain to completion. The bundle also
197
199
  includes third-party license and notice files, including FFmpeg's LGPL notices
198
200
  and corresponding-source information. Check exact notices and source-distribution
199
- details against the final bundled binaries before publication. The candidate is
201
+ details in the matching source bundles distributed with this release. The installer is
200
202
  unsigned, so Windows may show a SmartScreen warning. See the [installer candidate
201
- notes](docs/install.md#windows-desktop-installer-v0112-public-exe-pending).
203
+ notes](https://github.com/scottconverse/textflowkit/blob/main/docs/install.md#windows-desktop-installer-v0113).
202
204
 
203
205
  ## Python API
204
206
 
@@ -295,7 +297,7 @@ textflowkit export ./transcript.json --format vtt
295
297
  needs no PyTorch, so a fresh `pip install textflowkit` stays small and pulls no
296
298
  torch; `openai-whisper` is an explicitly selectable opt-in engine.
297
299
 
298
- ![Whistle bounded block run and durable resume: a decoded PCM WAV is split into 26-second cores with up to 2 seconds of context (each clip ≤ 30 s), each core runs as one owned child with forced telemetry-off flags, a partial checkpoint is written after each core, and a resume validates the source and decoded-WAV hashes then re-runs only the unfinished cores.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.12/docs/assets/whistle-resume.svg)
300
+ ![Whistle bounded block run and durable resume: a decoded PCM WAV is split into 11-second cores with up to 2 seconds of context (each clip ≤ 15 s), each core runs as one owned child with forced telemetry-off flags, a partial checkpoint is written after each core, and a resume validates the source and decoded-WAV hashes then re-runs only the unfinished cores.](https://raw.githubusercontent.com/scottconverse/textflowkit/v0.1.14/docs/assets/whistle-resume.svg)
299
301
 
300
302
  - **CPU only, no torch.** It runs a pinned native binary and downloads one pinned
301
303
  model on first use. Naming a GPU device is refused rather than silently
@@ -308,16 +310,26 @@ torch; `openai-whisper` is an explicitly selectable opt-in engine.
308
310
  Apple Silicon. **Intel Macs are not supported**; a request there is refused
309
311
  with a message that names the explicit `whisper` engine instead. No WSL layer
310
312
  is involved.
311
- - **How it works:** long audio is split into 26-second cores with up to 2 seconds
312
- of context on each side, so every standalone clip is ≤ 30 seconds (the native
313
- CLI's limit). Overlap words are selected by core midpoint rather than text
314
- deduplication, so repeated spoken phrases are preserved.
313
+ - **How it works:** long audio is split into 11-second cores with up to 2 seconds
314
+ of context on each side, so every standalone clip is ≤ 15 seconds. This conservative
315
+ ceiling avoids reproduced omissions on 30-second inputs. Midpoints provide initial ownership; shared-context matching
316
+ reconciles duplicate or dropped occurrences when neighboring timestamps
317
+ disagree. This is not global text deduplication: real repetitions and ambiguous
318
+ recognition are preserved. The 15-second ceiling and this assembly behavior ship
319
+ in v0.1.13; neither recovers speech the native recognizer never emits.
320
+ - **Speech-gap check (v0.1.13).** Short gaps between recognized words receive a
321
+ bounded second listen with different clip boundaries. Extra words are accepted
322
+ only between matching words on both sides at nearby times. Existing words and
323
+ repetitions stay intact; long pauses do not trigger this check. The model is
324
+ still Whistle, with the same pinned weights and telemetry settings.
315
325
  - **Standalone streaming is not used.** The native `--audio-stream` mode failed its
316
326
  coverage and is never passed; only the committed standalone output is parsed.
317
327
  - **Durable block resume.** With `TEXTFLOWKIT_DB` set, a long run writes partial
318
328
  per-block checkpoints; a resume checks the source and decoded-WAV hashes and the
319
329
  config, then re-runs only the blocks that were not finished. The durable store
320
- still assumes one owning process.
330
+ still assumes one owning process. The v0.1.13 assembly policy saves raw
331
+ boundary context with schema 2; old schema-1 partial runs must be restarted,
332
+ not resumed under the new assembly policy. Existing completed jobs are unchanged.
321
333
  - **Cancellation.** A running Whistle run terminates its exact owned child
322
334
  process bounded by a per-clip timeout. A single long `openai-whisper` model call
323
335
  is still only cancellable at its next stage boundary, as documented for the
@@ -406,7 +418,7 @@ its own beyond the `http` extra. It ships with the core package as of v0.1.10:
406
418
  a regular install of the current release carries it.
407
419
 
408
420
  ```bash
409
- python -m pip install 'textflowkit[http,export]==0.1.12'
421
+ python -m pip install 'textflowkit[http,export]==0.1.14'
410
422
  textflowkit-ui
411
423
  ```
412
424
 
@@ -477,9 +489,18 @@ browser interface share the job contract without blocking a request.
477
489
 
478
490
  ## Status
479
491
 
480
- **v0.1.12 release.** Adds optional UI-only local Ollama proofreading and native
481
- Windows installer packaging; public EXE distribution remains gated on unresolved
482
- corresponding-source compliance review, with no public installer download link.
492
+ **v0.1.14 release.** Documentation-only patch: records the required isolated headless Codex workflow for DeepSeek coding contributors. Transcription, AI cleanup and streaming behavior are unchanged from v0.1.13; fonts remain 0.1.6. The latest verified Windows installer remains v0.1.13, with its matching source and notice bundles. No new native transcription proof is claimed for this documentation patch.
493
+
494
+ **Whistle behavior introduced in v0.1.13.** Fixes reproduced Whistle speech omissions. Native decode
495
+ inputs are now bounded to 15 seconds (11-second owned cores with up to 2 seconds
496
+ of context per side), short interior speech gaps get a bounded second listen that
497
+ accepts words only between matching timed anchors, and shared-context words are
498
+ reconciled one-to-one before durable resume. Whistle remains the default engine
499
+ with the same pinned model and runtime; fonts remain 0.1.6. Progress schema 2
500
+ stores raw boundary context, so an unfinished partial job from the previous
501
+ 26-second-core plan (schema 1) must be restarted instead of resumed; completed
502
+ records are unchanged. The native Windows installer is rebuilt at v0.1.13 and
503
+ distributed with matching FFmpeg sources, notices, hashes and build instructions.
483
504
  Existing optional live streaming provides a transport-neutral
484
505
  `StreamingSession` Python API, incremental transcript events, and authenticated
485
506
  loopback WebSockets (`/stream` on the developer HTTP API and `/api/stream` on the
@@ -502,6 +523,22 @@ Linux/macOS, and the six other accepted languages were not verified. The public
502
523
  website remains static documentation and serves no streaming endpoint. Local source
503
524
  validation does not establish published-package or exact-commit CI results.
504
525
 
526
+ **v0.1.12 cleanup (historical).** The opt-in local Ollama proofreading path remains
527
+ as introduced in v0.1.12, covering the local browser UI only; it was not changed by
528
+ v0.1.13. It keeps the published 39-segment cleanup proof from v0.1.12 with no
529
+ audio-accuracy claim: that proof records segment/format handling, not recognition
530
+ accuracy.
531
+
532
+ **v0.1.13 Whistle coverage, omission, and resume.** The 15-second bound (11-second
533
+ cores plus up to 2 s context per side) fixes reproduced speech omissions on
534
+ 30-second inputs; the interior speech-gap second listen accepts extra words only
535
+ between matching timed anchors; shared-context words are reconciled one-to-one
536
+ before durable resume so a partial run rejoins without double ownership. Recognized
537
+ language coverage remains the same accepted set, and nothing here recovers speech
538
+ the native recognizer never emits. See
539
+ [docs/verification/whistle-coverage-20261019.md](https://github.com/scottconverse/textflowkit/blob/main/docs/verification/whistle-coverage-20261019.md)
540
+ for the run-by-run coverage, omission, and resume evidence.
541
+
505
542
  **Verification limit.** The local browser interface is covered by an automated
506
543
  suite, and the UI's behavior was proved on a **native Windows** machine in a real
507
544
  browser. No live optional-backend (translation/diarization) run through the UI is
@@ -524,7 +561,7 @@ MCP speech, seven-format exports and completed resume; the v0.1.8 runtime fixes
524
561
  were independently checked through fresh-process CLI restart probes, real SQLite
525
562
  setup-failure tests, and the full Windows test suite. Those checks are not new
526
563
  individual-harness receipts. That is the previous releases' record, not evidence
527
- for v0.1.12.
564
+ for v0.1.13.
528
565
 
529
566
  The v0.1.6 release was the post-v0.1.5 review repair set: security hardening
530
567
  for media acquisition and the HTTP and MCP adapters, safer subtitle wrapping and
@@ -543,7 +580,7 @@ and both [core](https://pypi.org/project/textflowkit/0.1.6/) and
543
580
  [fonts](https://pypi.org/project/textflowkit-fonts/0.1.6/) PyPI projects are
544
581
  live — that is the v0.1.6 release's evidence, not a receipt for a later release.
545
582
  Everything from here to the end of this section is the v0.1.6 release's
546
- historical record as published: it is not re-verified for v0.1.12, whose separate release evidence is not supplied by these historical paragraphs.
583
+ historical record as published: it is not re-verified for v0.1.13, whose separate release evidence is not supplied by these historical paragraphs.
547
584
  Merged-main CI passed 16/16 on the tagged commit; the published wheel and
548
585
  sdist digests match the GitHub release assets and their SHA-256 list; and a fresh
549
586
  Windows Python 3.12 install of `textflowkit[export,mcp,http]==0.1.6` from PyPI
@@ -582,9 +619,9 @@ Issues and PRs welcome. Please read [LEGAL.md](https://github.com/scottconverse/
582
619
  adapter.
583
620
 
584
621
 
585
- ## Optional local AI transcript cleanup (v0.1.12)
622
+ ## Optional local AI transcript cleanup (introduced in v0.1.12)
586
623
 
587
- v0.1.12 adds **opt-in proofreading in the local browser UI only**. After a transcription finishes, choose an
624
+ v0.1.12 adds **opt-in proofreading in the local browser UI only** (introduced in v0.1.12; unchanged in v0.1.13). After a transcription finishes, choose an
588
625
  installed local Ollama model and click **Proofread with local AI**. Cleanup never
589
626
  runs automatically. Ollama and cleanup models are not bundled in the installer.
590
627
  The optional default preference is `qwen3.5:9b` only if already installed; its
@@ -1,6 +1,10 @@
1
1
  # Developer and integration manual
2
2
 
3
- Current release: [v0.1.12](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.12).
3
+ Current release: [v0.1.14](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.14).
4
+
5
+ v0.1.14 updates developer workflow documentation only; runtime behavior is unchanged. The latest verified Windows installer remains v0.1.13 with its matching sources and notices.
6
+ For DeepSeek coding contributions, use the required [headless Codex worker workflow](deepseek-worker.md); this is a development tool, not a transcription-engine setting.
7
+
4
8
  Start with the [user manual](user-manual.md) for everyday use. Harness versions
5
9
  in the compatibility table below identify **historical test sessions**, not
6
10
  the version of TextFlowKit currently published.
@@ -22,9 +26,11 @@ API and WebSockets are ephemeral and bypass durable job submission.
22
26
  HTTP ───────────►└──────────────────────┘
23
27
  ```
24
28
 
25
- ## Windows desktop installer (v0.1.12; public EXE pending)
29
+ ## Windows desktop installer (v0.1.13)
30
+
31
+ [Download Windows x64 setup](https://github.com/scottconverse/textflowkit/releases/download/v0.1.13/TextFlowKit-0.1.13-windows-x64-setup.exe) · [Matching sources and notices](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13)
26
32
 
27
- The Windows x86_64 installer packages the existing browser interface for core v0.1.12. The native Windows installer has been built and tested locally. The installer recipe ships in v0.1.12; the EXE remains local-only until unresolved corresponding-source compliance review is cleared. No public installer download link is available. Its bundle includes private embeddable CPython, the UI and HTTP, export, and streaming dependencies, the pinned Whistle model and runtime, and ffmpeg, ffprobe, and Node. It requires no separately installed Python, WSL, or Docker. The Python package remains supported for developers and integrations; Docker remains a separate operator deployment example.
33
+ The Windows x86_64 installer packages the existing browser interface for core v0.1.13. The Windows installer and its matching FFmpeg source and notice bundles are distributed together through the [v0.1.13 release](https://github.com/scottconverse/textflowkit/releases/tag/v0.1.13). Its bundle includes private embeddable CPython, the UI and HTTP, export, and streaming dependencies, the pinned Whistle model and runtime, and ffmpeg, ffprobe, and Node. It requires no separately installed Python, WSL, or Docker. The Python package remains supported for developers and integrations; Docker remains a separate operator deployment example.
28
34
 
29
35
  The setup installs per user, adds a Start Menu entry, and offers an
30
36
  optional desktop shortcut. Launching it will start the local server and open the
@@ -551,7 +557,7 @@ observation rather than forwarding the caller's header, and keep
551
557
 
552
558
  ## Live microphone streaming (`/stream`, opt-in)
553
559
 
554
- In v0.1.12, native live streaming supports **Windows x86_64 only**. Other live
560
+ In v0.1.14, native live streaming (introduced in v0.1.11) supports **Windows x86_64 only**. Other live
555
561
  platforms are unsupported; existing standalone defaults and platform support are
556
562
  unchanged. Physical browser microphone capture was not verified. The public site
557
563
  is static documentation and serves no streams. Both local server surfaces can
@@ -562,7 +568,7 @@ exist and a connection is refused before any session is allocated - and it needs
562
568
  `streaming` extra (`websockets`).
563
569
 
564
570
  ```powershell
565
- python -m pip install "textflowkit[streaming]==0.1.12"
571
+ python -m pip install "textflowkit[streaming]==0.1.14"
566
572
  # Native Windows PowerShell:
567
573
  $env:TEXTFLOWKIT_API_TOKEN="choose-a-long-random-token"
568
574
  $env:TEXTFLOWKIT_STREAMING="1"
@@ -602,7 +608,7 @@ supplies FastAPI and uvicorn, and adds no new dependency). It has no public site
602
608
  of its own: it is a local app, not a hosted service.
603
609
 
604
610
  ```bash
605
- python -m pip install 'textflowkit[http,export]==0.1.12'
611
+ python -m pip install 'textflowkit[http,export]==0.1.14'
606
612
  textflowkit-ui # serve on 127.0.0.1 and open a browser
607
613
  textflowkit-ui --no-browser --port 8901
608
614
  ```
@@ -986,7 +992,7 @@ By default the job store is in-memory and bounded (`max_jobs=200`, terminal
986
992
  jobs evicted first). Set `TEXTFLOWKIT_DB` to use the durable SQLite store for
987
993
  restart-safe jobs and checkpoints. The SQLite store assumes one owning process.
988
994
 
989
- ## UI-only proofreading routes (v0.1.12)
995
+ ## UI-only proofreading routes (introduced in v0.1.12)
990
996
 
991
997
  These routes belong to the local UI session gate, not the developer HTTP or MCP
992
998
  API. POST requires the existing `x-textflowkit-ui-capability` header. Host, peer