utterplan 0.3.5__tar.gz → 0.4.0__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 (294) hide show
  1. {utterplan-0.3.5 → utterplan-0.4.0}/.codecrate.toml +1 -0
  2. {utterplan-0.3.5 → utterplan-0.4.0}/.github/workflows/python-publish.yml +2 -1
  3. {utterplan-0.3.5 → utterplan-0.4.0}/.github/workflows/tests.yml +28 -9
  4. {utterplan-0.3.5 → utterplan-0.4.0}/.gitignore +1 -1
  5. utterplan-0.4.0/MANIFEST.in +1 -0
  6. {utterplan-0.3.5/utterplan.egg-info → utterplan-0.4.0}/PKG-INFO +34 -19
  7. {utterplan-0.3.5 → utterplan-0.4.0}/README.md +31 -17
  8. {utterplan-0.3.5 → utterplan-0.4.0}/docs/architecture.md +26 -33
  9. {utterplan-0.3.5 → utterplan-0.4.0}/docs/changelog.md +33 -0
  10. {utterplan-0.3.5 → utterplan-0.4.0}/docs/cli.md +53 -24
  11. {utterplan-0.3.5 → utterplan-0.4.0}/docs/consumer-guide.md +24 -9
  12. {utterplan-0.3.5 → utterplan-0.4.0}/docs/coordinate-spaces.md +5 -0
  13. {utterplan-0.3.5 → utterplan-0.4.0}/docs/debugging.md +4 -2
  14. utterplan-0.4.0/docs/format.md +39 -0
  15. {utterplan-0.3.5 → utterplan-0.4.0}/docs/getting-started.md +36 -15
  16. {utterplan-0.3.5 → utterplan-0.4.0}/docs/index.md +3 -3
  17. {utterplan-0.3.5 → utterplan-0.4.0}/docs/make.bat +2 -2
  18. {utterplan-0.3.5 → utterplan-0.4.0}/docs/python-api.md +74 -4
  19. {utterplan-0.3.5 → utterplan-0.4.0}/examples/basic.py +1 -1
  20. {utterplan-0.3.5 → utterplan-0.4.0}/examples/compile_file.py +1 -1
  21. {utterplan-0.3.5 → utterplan-0.4.0}/examples/inspect_plan.py +1 -1
  22. {utterplan-0.3.5 → utterplan-0.4.0}/examples/ssmd_example.py +1 -1
  23. {utterplan-0.3.5 → utterplan-0.4.0}/pyproject.toml +2 -1
  24. utterplan-0.4.0/spec/schemas/v4.schema.json +425 -0
  25. {utterplan-0.3.5 → utterplan-0.4.0}/spec/utterplan.schema.json +21 -3
  26. utterplan-0.4.0/tests/fixtures/canonical_consumer_contract.expected.toml +6 -0
  27. utterplan-0.4.0/tests/golden/basic_en.utterplan.toml +117 -0
  28. utterplan-0.4.0/tests/golden/directives.utterplan.toml +150 -0
  29. utterplan-0.4.0/tests/golden/markers.utterplan.toml +175 -0
  30. utterplan-0.4.0/tests/golden/multilingual.utterplan.toml +166 -0
  31. utterplan-0.4.0/tests/golden/parenthetical.utterplan.toml +223 -0
  32. utterplan-0.4.0/tests/golden/spokenform_offsets.utterplan.toml +150 -0
  33. utterplan-0.4.0/tests/golden/ssmd_09_comprehensive.utterplan.toml +1189 -0
  34. utterplan-0.4.0/tests/golden/ssmd_breaks.utterplan.toml +191 -0
  35. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/cases.py +23 -8
  36. {utterplan-0.3.5/tests/golden → utterplan-0.4.0/tests/migration/fixtures/v4}/basic_en.utterplan.json +16 -6
  37. {utterplan-0.3.5/tests/golden → utterplan-0.4.0/tests/migration/fixtures/v4}/directives.utterplan.json +19 -4
  38. {utterplan-0.3.5/tests/golden → utterplan-0.4.0/tests/migration/fixtures/v4}/markers.utterplan.json +34 -25
  39. utterplan-0.4.0/tests/migration/fixtures/v4/multilingual.utterplan.json +214 -0
  40. {utterplan-0.3.5/tests/golden → utterplan-0.4.0/tests/migration/fixtures/v4}/parenthetical.utterplan.json +51 -8
  41. {utterplan-0.3.5/tests/golden → utterplan-0.4.0/tests/migration/fixtures/v4}/spokenform_offsets.utterplan.json +16 -6
  42. utterplan-0.4.0/tests/migration/fixtures/v4/ssmd_09_comprehensive.utterplan.json +1655 -0
  43. {utterplan-0.3.5/tests/golden → utterplan-0.4.0/tests/migration/fixtures/v4}/ssmd_breaks.utterplan.json +27 -24
  44. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/goldens/multilingual_preparation.json +78 -79
  45. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/goldens/spokenform_numbers.json +61 -55
  46. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/goldens/ssmd_break.json +75 -69
  47. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/goldens/ssmd_language_detection.json +61 -55
  48. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/goldens/ssmd_marker.json +77 -71
  49. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/goldens/ssmd_pronunciation.json +64 -58
  50. utterplan-0.4.0/tests/migration/test_legacy_json_import.py +29 -0
  51. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/test_semantic_migration_regressions.py +1 -1
  52. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/README.md +1 -1
  53. utterplan-0.3.5/tests/golden/multilingual.utterplan.json → utterplan-0.4.0/tests/schema_history/v3/multilingual.json +38 -81
  54. utterplan-0.3.5/tests/golden/ssmd_09_comprehensive.utterplan.json → utterplan-0.4.0/tests/schema_history/v3/ssmd_09_comprehensive.json +48 -3
  55. utterplan-0.4.0/tests/test_atomic_io.py +44 -0
  56. utterplan-0.4.0/tests/test_batch.py +264 -0
  57. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_boundaries.py +7 -1
  58. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_cli.py +147 -51
  59. utterplan-0.4.0/tests/test_cli_batch.py +302 -0
  60. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_consumer_contract.py +97 -7
  61. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_consumer_readiness.py +22 -3
  62. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_directives.py +1 -1
  63. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_explain.py +38 -16
  64. utterplan-0.4.0/tests/test_format.py +114 -0
  65. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_golden.py +11 -6
  66. utterplan-0.4.0/tests/test_identity_units.py +185 -0
  67. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_linguistics.py +88 -6
  68. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_migration_framework.py +4 -12
  69. utterplan-0.4.0/tests/test_migration_v3_to_v4.py +160 -0
  70. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_planner.py +2 -2
  71. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_preparation.py +3 -4
  72. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_progress.py +2 -2
  73. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_public_identity.py +2 -2
  74. utterplan-0.4.0/tests/test_renderability.py +209 -0
  75. utterplan-0.4.0/tests/test_renderability_repair.py +329 -0
  76. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_schema_history.py +52 -12
  77. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_schema_registry.py +12 -7
  78. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_segment_topology.py +14 -15
  79. utterplan-0.4.0/tests/test_semantic_boundaries.py +195 -0
  80. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_ssmd_09_parser.py +29 -6
  81. utterplan-0.4.0/tests/test_toml_format.py +179 -0
  82. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/__init__.py +34 -2
  83. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/_version.py +3 -3
  84. utterplan-0.4.0/utterplan/atomic_io.py +50 -0
  85. utterplan-0.4.0/utterplan/batch.py +407 -0
  86. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/cli.py +235 -41
  87. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/config.py +3 -0
  88. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/exceptions.py +41 -0
  89. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/explain.py +20 -0
  90. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/format.py +14 -2
  91. utterplan-0.4.0/utterplan/hashing.py +144 -0
  92. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/migration.py +0 -19
  93. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/migrations/__init__.py +2 -0
  94. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/migrations/v1_to_v2.py +6 -4
  95. utterplan-0.4.0/utterplan/migrations/v3_to_v4.py +221 -0
  96. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/model.py +236 -23
  97. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/parsers.py +191 -1
  98. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/planner.py +392 -53
  99. utterplan-0.4.0/utterplan/renderability.py +709 -0
  100. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/schema_registry.py +1 -0
  101. utterplan-0.4.0/utterplan/schemas/v4.schema.json +425 -0
  102. utterplan-0.4.0/utterplan/serialization.py +32 -0
  103. utterplan-0.4.0/utterplan/toml_codec.py +824 -0
  104. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/units.py +9 -2
  105. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/utterplan.schema.json +21 -3
  106. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/versioning.py +2 -2
  107. {utterplan-0.3.5 → utterplan-0.4.0/utterplan.egg-info}/PKG-INFO +34 -19
  108. utterplan-0.4.0/utterplan.egg-info/SOURCES.txt +174 -0
  109. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan.egg-info/requires.txt +2 -1
  110. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan.egg-info/scm_file_list.json +56 -9
  111. utterplan-0.4.0/utterplan.egg-info/scm_version.json +8 -0
  112. utterplan-0.3.5/.ledger/ledger.toml +0 -24
  113. utterplan-0.3.5/.ledger/releaseledger/.ledger-project.toml +0 -6
  114. utterplan-0.3.5/.ledger/releaseledger/config.toml +0 -56
  115. utterplan-0.3.5/.ledger/releaseledger/data/.ledger-project.toml +0 -6
  116. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/events/events.jsonl +0 -75
  117. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.0/entries/entry-0001.md +0 -25
  118. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.0/entries/entry-0002.md +0 -25
  119. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.0/entries/entry-0003.md +0 -28
  120. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.0/entries/entry-0004.md +0 -25
  121. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.0/release.md +0 -29
  122. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.1/entries/entry-0001.md +0 -24
  123. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.1/release.md +0 -27
  124. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.3/audit/commit-audit.yaml +0 -257
  125. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.3/entries/entry-0001.md +0 -32
  126. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.3/entries/entry-0002.md +0 -33
  127. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.3/entries/entry-0003.md +0 -37
  128. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.3/entries/entry-0004.md +0 -25
  129. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.3/entries/entry-0005.md +0 -25
  130. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.3/entries/entry-0006.md +0 -27
  131. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.1.3/release.md +0 -27
  132. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.2.0/audit/commit-audit.yaml +0 -241
  133. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.2.0/entries/entry-0001.md +0 -74
  134. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.2.0/entries/entry-0002.md +0 -31
  135. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.2.0/entries/entry-0003.md +0 -38
  136. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.2.0/entries/entry-0004.md +0 -53
  137. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.2.0/release.md +0 -27
  138. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.0/audit/commit-audit.yaml +0 -148
  139. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.0/entries/entry-0001.md +0 -85
  140. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.0/entries/entry-0002.md +0 -29
  141. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.0/entries/entry-0003.md +0 -32
  142. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.0/entries/entry-0004.md +0 -28
  143. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.0/entries/entry-0005.md +0 -30
  144. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.0/entries/entry-0006.md +0 -29
  145. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.0/release.md +0 -27
  146. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.1/audit/commit-audit.yaml +0 -57
  147. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.1/entries/entry-0001.md +0 -42
  148. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.1/release.md +0 -27
  149. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.2/audit/commit-audit.yaml +0 -105
  150. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.2/entries/entry-0001.md +0 -32
  151. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.2/entries/entry-0002.md +0 -41
  152. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.2/release.md +0 -27
  153. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.3/audit/commit-audit.yaml +0 -90
  154. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.3/entries/entry-0001.md +0 -45
  155. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.3/entries/entry-0002.md +0 -27
  156. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.3/release.md +0 -27
  157. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.4/audit/commit-audit.yaml +0 -13
  158. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.4/entries/entry-0001.md +0 -34
  159. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.4/entries/entry-0002.md +0 -29
  160. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.4/release.md +0 -27
  161. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.5/audit/commit-audit.yaml +0 -55
  162. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.5/entries/entry-0001.md +0 -39
  163. utterplan-0.3.5/.ledger/releaseledger/data/ledgers/main/releases/0.3.5/release.md +0 -27
  164. utterplan-0.3.5/.ledger/releaseledger/work/0.1.2/audit-decisions.yaml +0 -52
  165. utterplan-0.3.5/.ledger/releaseledger/work/0.1.2/audit.yaml +0 -128
  166. utterplan-0.3.5/.ledger/releaseledger/work/0.1.2/entries.yaml +0 -56
  167. utterplan-0.3.5/.ledger/releaseledger/work/0.1.2/evidence/2c64e29.patch +0 -1740
  168. utterplan-0.3.5/.ledger/releaseledger/work/0.1.2/evidence/4022753.patch +0 -677
  169. utterplan-0.3.5/.ledger/releaseledger/work/0.1.2/evidence/66a88b6.patch +0 -2657
  170. utterplan-0.3.5/.ledger/releaseledger/work/0.1.2/evidence/manifest.json +0 -116
  171. utterplan-0.3.5/.ledger/releaseledger/work/0.1.2/range.json +0 -13
  172. utterplan-0.3.5/.ledger/releaseledger/work/0.2.0/audit-decisions.yaml +0 -131
  173. utterplan-0.3.5/.ledger/releaseledger/work/0.2.0/audit.yaml +0 -135
  174. utterplan-0.3.5/.ledger/releaseledger/work/0.2.0/entries.yaml +0 -165
  175. utterplan-0.3.5/.ledger/releaseledger/work/0.2.0/evidence/9637182.patch +0 -991
  176. utterplan-0.3.5/.ledger/releaseledger/work/0.2.0/evidence/c52aa68.patch +0 -3109
  177. utterplan-0.3.5/.ledger/releaseledger/work/0.2.0/evidence/e49a6dd.patch +0 -178
  178. utterplan-0.3.5/.ledger/releaseledger/work/0.2.0/evidence/manifest.json +0 -123
  179. utterplan-0.3.5/.ledger/releaseledger/work/0.2.0/range.json +0 -13
  180. utterplan-0.3.5/.ledger/releaseledger/work/0.3.0/audit-decisions.yaml +0 -72
  181. utterplan-0.3.5/.ledger/releaseledger/work/0.3.0/audit.yaml +0 -85
  182. utterplan-0.3.5/.ledger/releaseledger/work/0.3.0/entries.yaml +0 -160
  183. utterplan-0.3.5/.ledger/releaseledger/work/0.3.0/evidence/49023f0.patch +0 -6377
  184. utterplan-0.3.5/.ledger/releaseledger/work/0.3.0/evidence/manifest.json +0 -81
  185. utterplan-0.3.5/.ledger/releaseledger/work/0.3.0/range.json +0 -13
  186. utterplan-0.3.5/.ledger/releaseledger/work/0.3.1/audit-decisions.yaml +0 -23
  187. utterplan-0.3.5/.ledger/releaseledger/work/0.3.1/audit.yaml +0 -40
  188. utterplan-0.3.5/.ledger/releaseledger/work/0.3.1/entries.yaml +0 -37
  189. utterplan-0.3.5/.ledger/releaseledger/work/0.3.1/evidence/70adac0.patch +0 -916
  190. utterplan-0.3.5/.ledger/releaseledger/work/0.3.1/evidence/manifest.json +0 -36
  191. utterplan-0.3.5/.ledger/releaseledger/work/0.3.1/range.json +0 -13
  192. utterplan-0.3.5/.ledger/releaseledger/work/0.3.2/audit-decisions.yaml +0 -48
  193. utterplan-0.3.5/.ledger/releaseledger/work/0.3.2/audit.yaml +0 -75
  194. utterplan-0.3.5/.ledger/releaseledger/work/0.3.2/entries.yaml +0 -54
  195. utterplan-0.3.5/.ledger/releaseledger/work/0.3.2/evidence/6c2a1ac.patch +0 -64
  196. utterplan-0.3.5/.ledger/releaseledger/work/0.3.2/evidence/a2bc20d.patch +0 -1923
  197. utterplan-0.3.5/.ledger/releaseledger/work/0.3.2/evidence/ba3b5af.patch +0 -414
  198. utterplan-0.3.5/.ledger/releaseledger/work/0.3.2/evidence/manifest.json +0 -57
  199. utterplan-0.3.5/.ledger/releaseledger/work/0.3.2/range.json +0 -13
  200. utterplan-0.3.5/.ledger/releaseledger/work/0.3.3/audit-decisions.yaml +0 -39
  201. utterplan-0.3.5/.ledger/releaseledger/work/0.3.3/audit.yaml +0 -61
  202. utterplan-0.3.5/.ledger/releaseledger/work/0.3.3/entries.yaml +0 -54
  203. utterplan-0.3.5/.ledger/releaseledger/work/0.3.3/evidence/66e2d83.patch +0 -1339
  204. utterplan-0.3.5/.ledger/releaseledger/work/0.3.3/evidence/ac797e4.patch +0 -27
  205. utterplan-0.3.5/.ledger/releaseledger/work/0.3.3/evidence/manifest.json +0 -51
  206. utterplan-0.3.5/.ledger/releaseledger/work/0.3.3/range.json +0 -13
  207. utterplan-0.3.5/.ledger/releaseledger/work/0.3.4/audit-decisions.yaml +0 -1
  208. utterplan-0.3.5/.ledger/releaseledger/work/0.3.4/audit.yaml +0 -13
  209. utterplan-0.3.5/.ledger/releaseledger/work/0.3.4/entries.preview.yaml +0 -11
  210. utterplan-0.3.5/.ledger/releaseledger/work/0.3.4/entries.yaml +0 -11
  211. utterplan-0.3.5/.ledger/releaseledger/work/0.3.4/evidence/manifest.json +0 -12
  212. utterplan-0.3.5/.ledger/releaseledger/work/0.3.4/range.json +0 -13
  213. utterplan-0.3.5/.ledger/releaseledger/work/0.3.5/audit-decisions.yaml +0 -22
  214. utterplan-0.3.5/.ledger/releaseledger/work/0.3.5/audit.yaml +0 -39
  215. utterplan-0.3.5/.ledger/releaseledger/work/0.3.5/entries.yaml +0 -34
  216. utterplan-0.3.5/.ledger/releaseledger/work/0.3.5/evidence/a19ceb4.patch +0 -1226
  217. utterplan-0.3.5/.ledger/releaseledger/work/0.3.5/evidence/manifest.json +0 -35
  218. utterplan-0.3.5/.ledger/releaseledger/work/0.3.5/range.json +0 -13
  219. utterplan-0.3.5/.ledger/releaseledger/write.lock +0 -0
  220. utterplan-0.3.5/.ledger/taskledger/.ledger-project.toml +0 -6
  221. utterplan-0.3.5/.ledger/taskledger/config.toml +0 -7
  222. utterplan-0.3.5/docs/format.md +0 -32
  223. utterplan-0.3.5/tests/fixtures/canonical_consumer_contract.expected.json +0 -10
  224. utterplan-0.3.5/tests/test_format.py +0 -91
  225. utterplan-0.3.5/tests/test_identity_units.py +0 -42
  226. utterplan-0.3.5/utterplan/hashing.py +0 -59
  227. utterplan-0.3.5/utterplan/serialization.py +0 -22
  228. utterplan-0.3.5/utterplan.egg-info/SOURCES.txt +0 -257
  229. utterplan-0.3.5/utterplan.egg-info/scm_version.json +0 -8
  230. {utterplan-0.3.5 → utterplan-0.4.0}/.github/workflows/codecov.yml +0 -0
  231. {utterplan-0.3.5 → utterplan-0.4.0}/.github/workflows/pre-commit.yml +0 -0
  232. {utterplan-0.3.5 → utterplan-0.4.0}/.pre-commit-config.yaml +0 -0
  233. {utterplan-0.3.5 → utterplan-0.4.0}/AGENTS.md +0 -0
  234. {utterplan-0.3.5 → utterplan-0.4.0}/LICENSE +0 -0
  235. {utterplan-0.3.5 → utterplan-0.4.0}/NOTICE +0 -0
  236. {utterplan-0.3.5 → utterplan-0.4.0}/docs/Makefile +0 -0
  237. {utterplan-0.3.5 → utterplan-0.4.0}/docs/conf.py +0 -0
  238. {utterplan-0.3.5 → utterplan-0.4.0}/docs/phase-a-completion.md +0 -0
  239. {utterplan-0.3.5 → utterplan-0.4.0}/docs/pykokoro-integration.md +0 -0
  240. {utterplan-0.3.5 → utterplan-0.4.0}/docs/requirements.txt +0 -0
  241. {utterplan-0.3.5 → utterplan-0.4.0}/examples/chapter.ssmd +0 -0
  242. {utterplan-0.3.5 → utterplan-0.4.0}/examples/multilingual.py +0 -0
  243. {utterplan-0.3.5 → utterplan-0.4.0}/setup.cfg +0 -0
  244. {utterplan-0.3.5 → utterplan-0.4.0}/spec/schemas/v1.schema.json +0 -0
  245. {utterplan-0.3.5 → utterplan-0.4.0}/spec/schemas/v2.schema.json +0 -0
  246. {utterplan-0.3.5 → utterplan-0.4.0}/spec/schemas/v3.schema.json +0 -0
  247. {utterplan-0.3.5 → utterplan-0.4.0}/tests/__init__.py +0 -0
  248. {utterplan-0.3.5 → utterplan-0.4.0}/tests/fixtures/canonical_consumer_contract.ssmd +0 -0
  249. {utterplan-0.3.5 → utterplan-0.4.0}/tests/fixtures/ssmd_09_comprehensive.ssmd +0 -0
  250. {utterplan-0.3.5 → utterplan-0.4.0}/tests/migration/__init__.py +0 -0
  251. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/v1/basic.json +0 -0
  252. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/v1/directives.json +0 -0
  253. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/v1/markers.json +0 -0
  254. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/v1/multilingual.json +0 -0
  255. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/v1/parenthetical.json +0 -0
  256. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/v1/spokenform_offsets.json +0 -0
  257. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/v1/ssmd_breaks.json +0 -0
  258. {utterplan-0.3.5 → utterplan-0.4.0}/tests/schema_history/v2/directives.json +0 -0
  259. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_compiler.py +0 -0
  260. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_coordinates.py +0 -0
  261. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_fake_renderer.py +0 -0
  262. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_import_boundaries.py +0 -0
  263. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_language.py +0 -0
  264. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_pauses.py +0 -0
  265. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_schema_strict.py +0 -0
  266. {utterplan-0.3.5 → utterplan-0.4.0}/tests/test_version.py +0 -0
  267. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/__main__.py +0 -0
  268. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/compiler.py +0 -0
  269. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/diagnostics.py +0 -0
  270. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/directives.py +0 -0
  271. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/language.py +0 -0
  272. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/linguistics.py +0 -0
  273. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/migrations/registry.py +0 -0
  274. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/migrations/v2_to_v3.py +0 -0
  275. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/pauses.py +0 -0
  276. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/preparation.py +0 -0
  277. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/progress.py +0 -0
  278. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/py.typed +0 -0
  279. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/schemas/v1.schema.json +0 -0
  280. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/schemas/v2.schema.json +0 -0
  281. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/schemas/v3.schema.json +0 -0
  282. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/spacy_models.py +0 -0
  283. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/spans.py +0 -0
  284. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/stages/__init__.py +0 -0
  285. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/stages/document/__init__.py +0 -0
  286. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/stages/document/plain.py +0 -0
  287. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/stages/document/ssmd.py +0 -0
  288. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/stages/preparation/__init__.py +0 -0
  289. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/stages/preparation/identity.py +0 -0
  290. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/stages/preparation/spokenform.py +0 -0
  291. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan/stages/protocols.py +0 -0
  292. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan.egg-info/dependency_links.txt +0 -0
  293. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan.egg-info/entry_points.txt +0 -0
  294. {utterplan-0.3.5 → utterplan-0.4.0}/utterplan.egg-info/top_level.txt +0 -0
@@ -17,6 +17,7 @@ include = [
17
17
  "**/*.yaml",
18
18
  "**/*.yml",
19
19
  "**/*.ssmd",
20
+ "**/*.typed",
20
21
  "LICENSE",
21
22
  ]
22
23
  split_max_chars = 0
@@ -80,7 +80,7 @@ jobs:
80
80
  Requirement(value) for value in metadata.get_all("Requires-Dist", [])
81
81
  ]
82
82
  assert has_range(requirements, "phrasplit", "0.3.9", "0.4")
83
- assert has_range(requirements, "ssmd", "0.9.0", "0.10")
83
+ assert has_range(requirements, "ssmd", "0.9.3", "0.10")
84
84
  assert has_range(requirements, "spokenform", "0.4.3", "0.5")
85
85
  names = set(archive.namelist())
86
86
  expected = {
@@ -89,6 +89,7 @@ jobs:
89
89
  "utterplan/schemas/v1.schema.json",
90
90
  "utterplan/schemas/v2.schema.json",
91
91
  "utterplan/schemas/v3.schema.json",
92
+ "utterplan/schemas/v4.schema.json",
92
93
  }
93
94
  assert expected <= names
94
95
  PY
@@ -43,12 +43,15 @@ jobs:
43
43
  - name: Install lower-bound dependencies
44
44
  run: |
45
45
  python -m pip install --upgrade pip
46
- python -m pip install pytest jsonschema
46
+ # exceptiongroup 1.3+ requires typing_extensions >=4.6; keep the 4.0 lower-bound check viable.
47
+ # referencing 0.36+ uses TypeVar(default=...) unavailable in typing_extensions 4.0.
48
+ python -m pip install pytest jsonschema "exceptiongroup==1.2.2" "referencing<0.36"
47
49
  python -m pip install \
48
50
  "phrasplit==0.3.9" \
49
- "ssmd==0.9.0" \
51
+ "ssmd==0.9.3" \
50
52
  "spokenform==0.4.3" \
51
- "typing_extensions>=4.0"
53
+ "typing_extensions==4.0.0" \
54
+ "tomlkit==0.13.0"
52
55
  python -m pip install --no-deps -e .
53
56
  - name: Run lower-bound tests
54
57
  run: python -m pytest -q
@@ -87,10 +90,11 @@ jobs:
87
90
  "utterplan/schemas/v1.schema.json",
88
91
  "utterplan/schemas/v2.schema.json",
89
92
  "utterplan/schemas/v3.schema.json",
93
+ "utterplan/schemas/v4.schema.json",
90
94
  }
91
95
  expected_ranges = {
92
96
  "phrasplit": ("0.3.9", "0.4"),
93
- "ssmd": ("0.9.0", "0.10"),
97
+ "ssmd": ("0.9.3", "0.10"),
94
98
  "spokenform": ("0.4.3", "0.5"),
95
99
  }
96
100
 
@@ -153,10 +157,10 @@ jobs:
153
157
  [Hello]{voice-name="test"} ...200ms world.
154
158
  EOF
155
159
  "$RUNNER_TEMP/utterplan-wheel-venv/bin/utterplan" compile \
156
- "$RUNNER_TEMP/test.ssmd.md" --lang en-us --text-preparation identity --json \
157
- > "$RUNNER_TEMP/test.utterplan.json"
160
+ "$RUNNER_TEMP/test.ssmd.md" --lang en-us --text-preparation identity \
161
+ > "$RUNNER_TEMP/test.utterplan.toml"
158
162
  "$RUNNER_TEMP/utterplan-wheel-venv/bin/utterplan" validate \
159
- "$RUNNER_TEMP/test.utterplan.json"
163
+ "$RUNNER_TEMP/test.utterplan.toml"
160
164
  cat > "$RUNNER_TEMP/test-0.8.ssmd.md" <<'EOF'
161
165
  ---
162
166
  ssmd_version: "0.8"
@@ -164,7 +168,7 @@ jobs:
164
168
  Hello.
165
169
  EOF
166
170
  if "$RUNNER_TEMP/utterplan-wheel-venv/bin/utterplan" compile \
167
- "$RUNNER_TEMP/test-0.8.ssmd.md" --lang en-us --text-preparation identity --json \
171
+ "$RUNNER_TEMP/test-0.8.ssmd.md" --lang en-us --text-preparation identity \
168
172
  > "$RUNNER_TEMP/test-0.8.out" 2>&1; then
169
173
  cat "$RUNNER_TEMP/test-0.8.out"
170
174
  echo "Installed wheel accepted an SSMD 0.8 document" >&2
@@ -174,4 +178,19 @@ jobs:
174
178
  "$RUNNER_TEMP/utterplan-wheel-venv/bin/utterplan" migrate \
175
179
  "$GITHUB_WORKSPACE/tests/schema_history/v1/basic.json" --check
176
180
  "$RUNNER_TEMP/utterplan-wheel-venv/bin/utterplan" inspect \
177
- "$RUNNER_TEMP/test.utterplan.json" --segment 0
181
+ "$RUNNER_TEMP/test.utterplan.toml" --segment 0
182
+
183
+ docs:
184
+ runs-on: ubuntu-latest
185
+ steps:
186
+ - uses: actions/checkout@v4
187
+ - name: Set up Python
188
+ uses: actions/setup-python@v5
189
+ with:
190
+ python-version: "3.12"
191
+ - name: Install documentation dependencies
192
+ run: |
193
+ python -m pip install --upgrade pip
194
+ python -m pip install -e ".[docs]"
195
+ - name: Build documentation
196
+ run: sphinx-build -W --keep-going -b html docs docs/_build/html
@@ -221,4 +221,4 @@ context_utterplan*.*
221
221
  utterplan/_version.py
222
222
 
223
223
  # Generated outputs from the runnable examples
224
- examples/*.utterplan.json
224
+ examples/*.utterplan.toml
@@ -0,0 +1 @@
1
+ prune .ledger
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: utterplan
3
- Version: 0.3.5
3
+ Version: 0.4.0
4
4
  Summary: Engine-independent text-to-speech planning compiler and interchange format
5
5
  Author-email: Holger Nahrstaedt <nahrstaedt@gmail.com>
6
6
  License: Apache License
@@ -223,9 +223,10 @@ Description-Content-Type: text/markdown
223
223
  License-File: LICENSE
224
224
  License-File: NOTICE
225
225
  Requires-Dist: phrasplit<0.4,>=0.3.9
226
- Requires-Dist: ssmd<0.10,>=0.9.0
226
+ Requires-Dist: ssmd<0.10,>=0.9.3
227
227
  Requires-Dist: spokenform<0.5,>=0.4.3
228
228
  Requires-Dist: typing_extensions>=4.0
229
+ Requires-Dist: tomlkit<1,>=0.13
229
230
  Provides-Extra: dev
230
231
  Requires-Dist: build; extra == "dev"
231
232
  Requires-Dist: jsonschema; extra == "dev"
@@ -259,13 +260,13 @@ consumer workspaces, and stops before G2P, synthesis, and audio.
259
260
  Compile literal text directly:
260
261
 
261
262
  ```bash
262
- utterplan compile "Doctor Smith bought 5 kg." --input-format plain --language en-us --json
263
+ utterplan compile "Doctor Smith bought 5 kg." --input-format plain --language en-us
263
264
  ```
264
265
 
265
266
  Compile a file to a plan file:
266
267
 
267
268
  ```bash
268
- utterplan compile examples/chapter.ssmd -o chapter.utterplan.json
269
+ utterplan compile examples/chapter.ssmd -o chapter.utterplan.toml
269
270
  ```
270
271
 
271
272
  SSMD header `language` is authoritative, so `--language` is optional when it is present. Otherwise pass `--language` as the fallback; plain input always requires a language. `--language` never forces a language over SSMD semantics.
@@ -273,21 +274,29 @@ SSMD header `language` is authoritative, so `--language` is optional when it is
273
274
  Use stdin and shell pipelines:
274
275
 
275
276
  ```bash
276
- cat examples/chapter.ssmd | utterplan compile --lang en-us --input-format ssmd | jq .
277
+ cat examples/chapter.ssmd | utterplan compile --lang en-us --input-format ssmd > chapter.utterplan.toml
277
278
  ```
278
279
 
280
+ Compile independent documents incrementally; every successful plan is saved immediately, and ordinary failures do not discard earlier outputs:
281
+
282
+ ```bash
283
+ utterplan compile-many examples/*.ssmd --output-dir build/plans
284
+ ```
285
+
286
+ This writes one `.utterplan.toml` per source plus an atomically refreshed `compile-report.toml`. Use `--fail-fast` to skip later inputs after a failure, `--force` to replace existing plans, or `--report PATH` to choose another report location.
287
+
279
288
  The CLI also provides:
280
289
 
281
290
  ```bash
282
291
  utterplan --version
283
- utterplan validate chapter.utterplan.json
284
- utterplan inspect chapter.utterplan.json --segment 0
285
- utterplan explain chapter.utterplan.json
292
+ utterplan validate chapter.utterplan.toml
293
+ utterplan inspect chapter.utterplan.toml --segment 0
294
+ utterplan inspect chapter.utterplan.toml --semantic-boundaries
295
+ utterplan explain chapter.utterplan.toml
286
296
  ```
287
297
 
288
298
  `explain` presents the compiled plan as a human-readable speech plan, while `inspect` exposes lower-level diagnostic fields.
289
- Compile JSON is written to stdout when no output file is supplied. Status
290
- messages use stderr, and existing output files require `--force`.
299
+ Canonical plan output is TOML (`.utterplan.toml`) and is written to stdout when no output file is supplied. Status messages use stderr, and existing output files require `--force`. Safe punctuation repair is the default; use `--renderability strict` to reject every repair opportunity.
291
300
 
292
301
  ## SSMD source contract
293
302
 
@@ -303,7 +312,8 @@ command:
303
312
  ssmd migrate old.ssmd --to 0.9
304
313
  ```
305
314
 
306
- `utterplan migrate` is only for historical `.utterplan.json` schema migration. It does not migrate SSMD source.
315
+ `utterplan migrate` explicitly imports supported historical `.utterplan.json` plans and writes current TOML. It does not migrate SSMD source.
316
+ Normal plan loading is TOML-only: `UtterancePlan.load()` and plan-inspection commands reject JSON rather than auto-detecting it.
307
317
 
308
318
  ## Planning defaults
309
319
 
@@ -311,6 +321,8 @@ The minimal CLI defaults are explicit: `spokenform` is the default text-preparat
311
321
 
312
322
  Python `PlannerConfig` defaults to `document_format="plain"`; set it to `"ssmd"` when a Python string contains SSMD source.
313
323
 
324
+ Python `PlannerConfig.renderability_mode` also defaults to safe punctuation-only repair; choose `"strict"` to reject every repair opportunity. Neither mode guesses a symbol's pronunciation or crosses semantic blockers.
325
+
314
326
  `spacy auto` is opt-in. When enabled and a compatible local model is available, UtterPlan may expose richer tokenization, POS tags, lemmas, and tags; `auto` is not the default.
315
327
 
316
328
  ## Python API
@@ -332,8 +344,8 @@ result = compile_document(
332
344
  )
333
345
  plan = result.plan
334
346
  assert result.trace is not None
335
- plan.save("example.utterplan.json")
336
- assert UtterancePlan.load("example.utterplan.json") == plan
347
+ plan.save("example.utterplan.toml")
348
+ assert UtterancePlan.load("example.utterplan.toml") == plan
337
349
  ```
338
350
 
339
351
  `compile_document` is the stable public one-document API shared by consumers. The
@@ -341,7 +353,7 @@ immutable `CompileResult` contains the semantic plan, diagnostics, and optional
341
353
  explanatory trace. Trace is not serialized in the plan and does not affect its
342
354
  identity. Plain text must be explicitly selected in Python and always requires a
343
355
  language fallback. Existing `UtterancePlanner.plan` remains supported and returns
344
- only the plan; JSON is the portable persistence and interchange format.
356
+ only the plan; TOML is the portable persistence and interchange format.
345
357
 
346
358
  For operational progress from a long-running Python plan, pass `on_progress` to
347
359
  `UtterancePlanner.plan`, `UtterancePlanner.compile`, or `compile_document`. The
@@ -363,8 +375,11 @@ Callbacks run synchronously and exceptions propagate. See the [Python API guide]
363
375
 
364
376
  Renderers consume `PlanSegment.text`, which is prepared/spoken text, and use
365
377
  `spoken_start`/`spoken_end` for spoken-text coordinates. Resolved segment
366
- pauses, language, directives, annotations, boundaries, markers, units, and
367
- document metadata are public plan fields. Plans contain no phonemes, model
378
+ pauses, language, directives, annotations, boundaries, semantic boundaries,
379
+ markers, units, and
380
+ document metadata are public plan fields. Semantic boundaries are stable
381
+ engine-neutral opportunities for spoken-text subdivision; they are not pause
382
+ events and carry no duration or renderer policy. Plans contain no phonemes, model
368
383
  tokens, model sessions, renderer configuration, provider documents, or audio.
369
384
  For SSMD input, `plan.annotations` preserve declared source semantics and source
370
385
  provenance, `document_metadata` preserves portable header data, and
@@ -398,10 +413,10 @@ renderer repository rather than UtterPlan's test suite.
398
413
 
399
414
  ## Versions
400
415
 
401
- The package version is dynamically derived from Git tags by setuptools-scm. Package version and UtterPlan schema version are independent. Current plans use schema v3; released schema v1 and v2 remain immutable and supported through sequential v1-to-v2-to-v3 and direct v2-to-v3 migrations.
416
+ The package version is dynamically derived from Git tags by setuptools-scm. Package version and UtterPlan schema version are independent. Current `.utterplan.toml` plans use semantic schema v4; released schema v1, v2, and v3 remain immutable and supported through sequential migrations.
402
417
 
403
- Schema v3 adds typed renderer-neutral SSMD semantics. Migration converts serialized plan data only. It does not reparse source, replan, or rerun linguistic analysis, G2P, rendering, or audio processing. Unit hashes retain the `utterplan-unit-v2` algorithm.
404
- Schema v3 persists final pass-B token facts, including optional POS, tag, lemma, and morphology, plus per-language-run provider provenance. Unit hashes include pronunciation-relevant token semantics but exclude model/audio state.
418
+ Schema v4 adds stable `SemanticBoundary` records in spoken-text coordinates. Migration converts serialized plan data only: the registered v3-to-v4 step preserves existing evidence and derives topology where possible, but does not rerun parsing, NLP, planning, G2P, rendering, or audio processing. Unit hashes use `utterplan-unit-v3` and include relative semantic-boundary positions; older hash algorithms remain available for their historical migration paths.
419
+ Schema v4 retains typed renderer-neutral SSMD semantics, final pass-B token facts, and per-language-run provider provenance. Plans never serialize provider documents, models, sessions, phonemes, token IDs, or audio.
405
420
 
406
421
  ## Development
407
422
 
@@ -17,13 +17,13 @@ consumer workspaces, and stops before G2P, synthesis, and audio.
17
17
  Compile literal text directly:
18
18
 
19
19
  ```bash
20
- utterplan compile "Doctor Smith bought 5 kg." --input-format plain --language en-us --json
20
+ utterplan compile "Doctor Smith bought 5 kg." --input-format plain --language en-us
21
21
  ```
22
22
 
23
23
  Compile a file to a plan file:
24
24
 
25
25
  ```bash
26
- utterplan compile examples/chapter.ssmd -o chapter.utterplan.json
26
+ utterplan compile examples/chapter.ssmd -o chapter.utterplan.toml
27
27
  ```
28
28
 
29
29
  SSMD header `language` is authoritative, so `--language` is optional when it is present. Otherwise pass `--language` as the fallback; plain input always requires a language. `--language` never forces a language over SSMD semantics.
@@ -31,21 +31,29 @@ SSMD header `language` is authoritative, so `--language` is optional when it is
31
31
  Use stdin and shell pipelines:
32
32
 
33
33
  ```bash
34
- cat examples/chapter.ssmd | utterplan compile --lang en-us --input-format ssmd | jq .
34
+ cat examples/chapter.ssmd | utterplan compile --lang en-us --input-format ssmd > chapter.utterplan.toml
35
35
  ```
36
36
 
37
+ Compile independent documents incrementally; every successful plan is saved immediately, and ordinary failures do not discard earlier outputs:
38
+
39
+ ```bash
40
+ utterplan compile-many examples/*.ssmd --output-dir build/plans
41
+ ```
42
+
43
+ This writes one `.utterplan.toml` per source plus an atomically refreshed `compile-report.toml`. Use `--fail-fast` to skip later inputs after a failure, `--force` to replace existing plans, or `--report PATH` to choose another report location.
44
+
37
45
  The CLI also provides:
38
46
 
39
47
  ```bash
40
48
  utterplan --version
41
- utterplan validate chapter.utterplan.json
42
- utterplan inspect chapter.utterplan.json --segment 0
43
- utterplan explain chapter.utterplan.json
49
+ utterplan validate chapter.utterplan.toml
50
+ utterplan inspect chapter.utterplan.toml --segment 0
51
+ utterplan inspect chapter.utterplan.toml --semantic-boundaries
52
+ utterplan explain chapter.utterplan.toml
44
53
  ```
45
54
 
46
55
  `explain` presents the compiled plan as a human-readable speech plan, while `inspect` exposes lower-level diagnostic fields.
47
- Compile JSON is written to stdout when no output file is supplied. Status
48
- messages use stderr, and existing output files require `--force`.
56
+ Canonical plan output is TOML (`.utterplan.toml`) and is written to stdout when no output file is supplied. Status messages use stderr, and existing output files require `--force`. Safe punctuation repair is the default; use `--renderability strict` to reject every repair opportunity.
49
57
 
50
58
  ## SSMD source contract
51
59
 
@@ -61,7 +69,8 @@ command:
61
69
  ssmd migrate old.ssmd --to 0.9
62
70
  ```
63
71
 
64
- `utterplan migrate` is only for historical `.utterplan.json` schema migration. It does not migrate SSMD source.
72
+ `utterplan migrate` explicitly imports supported historical `.utterplan.json` plans and writes current TOML. It does not migrate SSMD source.
73
+ Normal plan loading is TOML-only: `UtterancePlan.load()` and plan-inspection commands reject JSON rather than auto-detecting it.
65
74
 
66
75
  ## Planning defaults
67
76
 
@@ -69,6 +78,8 @@ The minimal CLI defaults are explicit: `spokenform` is the default text-preparat
69
78
 
70
79
  Python `PlannerConfig` defaults to `document_format="plain"`; set it to `"ssmd"` when a Python string contains SSMD source.
71
80
 
81
+ Python `PlannerConfig.renderability_mode` also defaults to safe punctuation-only repair; choose `"strict"` to reject every repair opportunity. Neither mode guesses a symbol's pronunciation or crosses semantic blockers.
82
+
72
83
  `spacy auto` is opt-in. When enabled and a compatible local model is available, UtterPlan may expose richer tokenization, POS tags, lemmas, and tags; `auto` is not the default.
73
84
 
74
85
  ## Python API
@@ -90,8 +101,8 @@ result = compile_document(
90
101
  )
91
102
  plan = result.plan
92
103
  assert result.trace is not None
93
- plan.save("example.utterplan.json")
94
- assert UtterancePlan.load("example.utterplan.json") == plan
104
+ plan.save("example.utterplan.toml")
105
+ assert UtterancePlan.load("example.utterplan.toml") == plan
95
106
  ```
96
107
 
97
108
  `compile_document` is the stable public one-document API shared by consumers. The
@@ -99,7 +110,7 @@ immutable `CompileResult` contains the semantic plan, diagnostics, and optional
99
110
  explanatory trace. Trace is not serialized in the plan and does not affect its
100
111
  identity. Plain text must be explicitly selected in Python and always requires a
101
112
  language fallback. Existing `UtterancePlanner.plan` remains supported and returns
102
- only the plan; JSON is the portable persistence and interchange format.
113
+ only the plan; TOML is the portable persistence and interchange format.
103
114
 
104
115
  For operational progress from a long-running Python plan, pass `on_progress` to
105
116
  `UtterancePlanner.plan`, `UtterancePlanner.compile`, or `compile_document`. The
@@ -121,8 +132,11 @@ Callbacks run synchronously and exceptions propagate. See the [Python API guide]
121
132
 
122
133
  Renderers consume `PlanSegment.text`, which is prepared/spoken text, and use
123
134
  `spoken_start`/`spoken_end` for spoken-text coordinates. Resolved segment
124
- pauses, language, directives, annotations, boundaries, markers, units, and
125
- document metadata are public plan fields. Plans contain no phonemes, model
135
+ pauses, language, directives, annotations, boundaries, semantic boundaries,
136
+ markers, units, and
137
+ document metadata are public plan fields. Semantic boundaries are stable
138
+ engine-neutral opportunities for spoken-text subdivision; they are not pause
139
+ events and carry no duration or renderer policy. Plans contain no phonemes, model
126
140
  tokens, model sessions, renderer configuration, provider documents, or audio.
127
141
  For SSMD input, `plan.annotations` preserve declared source semantics and source
128
142
  provenance, `document_metadata` preserves portable header data, and
@@ -156,10 +170,10 @@ renderer repository rather than UtterPlan's test suite.
156
170
 
157
171
  ## Versions
158
172
 
159
- The package version is dynamically derived from Git tags by setuptools-scm. Package version and UtterPlan schema version are independent. Current plans use schema v3; released schema v1 and v2 remain immutable and supported through sequential v1-to-v2-to-v3 and direct v2-to-v3 migrations.
173
+ The package version is dynamically derived from Git tags by setuptools-scm. Package version and UtterPlan schema version are independent. Current `.utterplan.toml` plans use semantic schema v4; released schema v1, v2, and v3 remain immutable and supported through sequential migrations.
160
174
 
161
- Schema v3 adds typed renderer-neutral SSMD semantics. Migration converts serialized plan data only. It does not reparse source, replan, or rerun linguistic analysis, G2P, rendering, or audio processing. Unit hashes retain the `utterplan-unit-v2` algorithm.
162
- Schema v3 persists final pass-B token facts, including optional POS, tag, lemma, and morphology, plus per-language-run provider provenance. Unit hashes include pronunciation-relevant token semantics but exclude model/audio state.
175
+ Schema v4 adds stable `SemanticBoundary` records in spoken-text coordinates. Migration converts serialized plan data only: the registered v3-to-v4 step preserves existing evidence and derives topology where possible, but does not rerun parsing, NLP, planning, G2P, rendering, or audio processing. Unit hashes use `utterplan-unit-v3` and include relative semantic-boundary positions; older hash algorithms remain available for their historical migration paths.
176
+ Schema v4 retains typed renderer-neutral SSMD semantics, final pass-B token facts, and per-language-run provider provenance. Plans never serialize provider documents, models, sessions, phonemes, token IDs, or audio.
163
177
 
164
178
  ## Development
165
179
 
@@ -35,17 +35,17 @@ Legacy `UtterancePlanner.plan` remains a compatibility API returning only the
35
35
  plan.
36
36
 
37
37
  The public `UtterancePlan` Python object is immutable in-process renderer input;
38
- the `.utterplan.json` schema is the portable persistence and semantic interchange
39
- contract. UtterPlan ends before G2P. Engine/model selection, synthesis, and audio
40
- composition happen downstream.
38
+ the `.utterplan.toml` document is the portable persistence and semantic interchange
39
+ format; it encodes semantic schema v4. UtterPlan ends before G2P. Engine/model
40
+ selection, synthesis, and audio composition happen downstream.
41
41
 
42
42
  ## SSMD source contract
43
43
 
44
44
  The document parser calls SSMD with `dialect="0.9"` for every SSMD source path,
45
45
  including unversioned fragments selected with `document_format="ssmd"`. UtterPlan
46
46
  does not parse SSMD 0.8 or migrate source. Older documents must first be converted
47
- with `ssmd migrate FILE --to 0.9`. The `utterplan migrate` command is reserved for
48
- serialized UtterPlan schema migrations.
47
+ with `ssmd migrate FILE --to 0.9`. The `utterplan migrate` command explicitly
48
+ imports legacy JSON plans and applies serialized schema migrations.
49
49
 
50
50
  SSMD header language is authoritative over a fallback language. The CLI can omit
51
51
  `--language` when the header declares a language; plain input always needs an
@@ -66,7 +66,7 @@ text. Preparation-trace source offsets address SSMD-clean structural text, while
66
66
  its transformation output offsets address prepared spoken text.
67
67
 
68
68
  Linguistic analysis and provider documents are request-local. Returned plans
69
- contain JSON-compatible semantic results only: no live parser objects, spaCy
69
+ contain plain, round-trippable semantic data only: no live parser objects, spaCy
70
70
  documents, models, sessions, provider caches, phonemes, engine token IDs, or audio.
71
71
  A reusable planner may share sequential resource caches, but concurrent use is not
72
72
  promised.
@@ -77,41 +77,34 @@ preparation can invalidate their offsets.
77
77
 
78
78
  Pause events retain provenance and resolved event IDs. Pause defaults are
79
79
  normalized to finite seconds with explicit precedence, and segments expose
80
- resolved pauses directly. Logical voices are intent references; document
81
- `voice_bindings` metadata remains separate and no concrete engine voice is
82
- selected.
80
+ resolved pauses directly. Semantic boundaries are a separate immutable
81
+ collection of stable spoken-text split opportunities; they have no duration,
82
+ activation state, or renderer choice. Logical voices are intent references;
83
+ document `voice_bindings` metadata remains separate and no concrete engine
84
+ voice is selected.
83
85
 
84
- Plan identity is deterministic and renderer-independent. It covers semantic
85
- source/configuration/metadata; it does not include renderer-only model, sample
86
+ Plan identity is deterministic and renderer-independent. It covers semantic source/configuration/metadata; it does not include renderer-only model, sample
86
87
  rate, or output-file settings. Unit hashes include ordered segment semantics,
87
88
  resolved pauses, marker content, and semantic token facts referenced by each
88
- segment. Diagnostics and producer metadata do not define unit identity. Package
89
- version is derived by setuptools-scm and is independent of the explicit UtterPlan
90
- `schema_version`.
89
+ segment. Semantic-boundary positions relative to each unit are part of the
90
+ `utterplan-unit-v3` hash; diagnostics and producer metadata do not define unit
91
+ identity. Package version is derived by setuptools-scm and is independent of
92
+ the explicit UtterPlan `schema_version`.
93
+
94
+ Current plans persist as deterministic `.utterplan.toml` files; schema v4 remains the semantic contract, and `plan_id` is derived from canonical semantic data rather than TOML bytes. `UtterancePlan.load()` accepts TOML only. Legacy JSON plan import is an explicit migration command, never a normal load fallback.
95
+
96
+ `compile-many` orchestrates independent source documents in order. Each successful plan is validated and atomically saved before the next source is processed; ordinary failures are reported and later inputs continue unless fail-fast is requested. Its atomically refreshed TOML report is operational data, not an `UtterancePlan`.
91
97
 
92
98
  ## Persistence compatibility boundary
93
99
 
94
100
  ```text
95
- .utterplan.json
96
- |
97
- v
98
- inspect schema version
99
- |
100
- +-----------+-----------+
101
- | |
102
- current old
103
- | |
104
- | migration chain
105
- | |
106
- +-----------+-----------+
107
- |
108
- v
109
- current UtterancePlan
110
- |
111
- v
112
- renderer
101
+ current plan file:
102
+ .utterplan.toml -- TOML decode / schema-v4 validation --> UtterancePlan --> renderer
103
+
104
+ legacy saved plan:
105
+ .utterplan.json -- explicit `utterplan migrate` --> current .utterplan.toml
113
106
  ```
114
107
 
115
108
  Migration is not planning. UtterPlan owns persistence, schema validation, and migration. Renderers consume only the current in-memory `UtterancePlan` and do not implement historical schema branches.
116
109
 
117
- Schema v3 is current. Released schema v1 and v2 remain frozen; v1 migration proceeds sequentially through v2 to v3, while v2 plans migrate directly to v3. These migrations transform serialized data only and never reparse or replan source.
110
+ Schema v4 is current. Released schemas v1, v2, and v3 remain frozen; supported plans migrate through the registered sequential chain to v4. The v3-to-v4 step transforms serialized data only and does not rerun parsing, NLP, planning, G2P, rendering, or audio processing. Consumers receive only the current in-memory model.
@@ -4,6 +4,39 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.4.0] - 2026-10-06
8
+
9
+ ### Added
10
+
11
+ - Added stable spoken-coordinate semantic boundaries for clause, parenthetical, sentence, and paragraph splits
12
+
13
+ ### Changed
14
+
15
+ - Changed serialized plans to schema v4 with deterministic v3-to-v4 migration and boundary-sensitive unit identity
16
+ - Changed plan persistence to deterministic TOML with explicit legacy JSON import and incremental batch compilation
17
+
18
+ ### Documentation
19
+
20
+ - Documented spoken-coordinate semantics, pause separation, migration limits, and consumer lowering
21
+
22
+ <!-- generated by releaseledger -->
23
+
24
+ ## [0.3.7] - 2026-10-05
25
+
26
+ ### Quality
27
+
28
+ - Improved package publishing workflow for the release toolchain
29
+
30
+ <!-- generated by releaseledger -->
31
+
32
+ ## [0.3.6] - 2026-10-05
33
+
34
+ ### Added
35
+
36
+ - Added strict renderability checks and deterministic repair for isolated neutral punctuation segments
37
+
38
+ <!-- generated by releaseledger -->
39
+
7
40
  ## [0.3.5] - 2026-10-05
8
41
 
9
42
  ### Fixed
@@ -9,7 +9,7 @@ usage: utterplan compile [-h] [--file FILE] [--language LANGUAGE]
9
9
  [--text-preparation {spokenform,identity}]
10
10
  [--pause-mode {tts,manual,auto}]
11
11
  [--spacy {auto,off,sm,md,lg,trf}] [-o OUTPUT]
12
- [--force] [--json]
12
+ [--force] [--stdout] [--renderability {strict,repair}]
13
13
  [text ...]
14
14
  ```
15
15
 
@@ -56,33 +56,46 @@ ssmd migrate old.ssmd --to 0.9 --output migrated.ssmd
56
56
  utterplan compile migrated.ssmd --lang en-us
57
57
  ```
58
58
 
59
- `utterplan migrate` applies only to `.utterplan.json` schema versions. It cannot migrate SSMD source.
59
+ `utterplan migrate` is the explicit JSON-plan import path: it applies supported schema migrations and writes canonical TOML. It cannot migrate SSMD source.
60
60
 
61
61
  ## Output and errors
62
62
 
63
- Without `--output`, compile writes the actual pretty plan JSON to stdout. With
64
- `--output`, the file is written and an existing file is refused unless
65
- `--force` is supplied. Add `--json` with an output path to write the file and
66
- also emit the same plan JSON to stdout.
63
+ Without `--output`, compile writes the pretty TOML plan to stdout. With
64
+ `--output`, the TOML file is written and an existing file is refused unless
65
+ `--force` is supplied. Add `--stdout` with an output path to write the file and
66
+ also emit the same TOML plan to stdout.
67
67
 
68
- Human status messages are written to stderr, never mixed into JSON stdout:
68
+ Human status messages are written to stderr, never mixed into TOML stdout:
69
69
 
70
70
  ```bash
71
- utterplan compile chapter.ssmd.md -o chapter.utterplan.json
71
+ utterplan compile chapter.ssmd.md -o chapter.utterplan.toml
72
72
  # status is written to stderr
73
- utterplan compile chapter.ssmd.md -o chapter.utterplan.json --json | jq .
73
+ utterplan compile chapter.ssmd.md -o chapter.utterplan.toml --stdout
74
74
  ```
75
75
 
76
76
  Argparse usage errors use exit code 2. Input, planning, file, and plan
77
77
  validation errors use exit code 1 and are reported without a traceback.
78
78
 
79
+ ## Compile many documents incrementally
80
+
81
+ `compile-many` reads source files in the requested order, compiles each independently, and atomically saves each successful plan before reading the next. Ordinary input, planning, and write failures are reported per item and do not roll back earlier plans; processing continues unless `--fail-fast` is set.
82
+
83
+ ```bash
84
+ utterplan compile-many chapters/*.ssmd --output-dir build/plans \
85
+ --language en-us --report build/compile-report.toml
86
+ ```
87
+
88
+ Source names determine output names: `chapter.ssmd`, `chapter.ssmd.md`, and `chapter.md` each map to `chapter.utterplan.toml`. Duplicate output names and a report path that collides with a plan output are rejected before any writes. Existing plans are protected unless `--force` is supplied. By default the command writes an atomically refreshed `compile-report.toml` in the output directory; the report is operational TOML, not a plan accepted by `UtterancePlan.load()`.
89
+
90
+ Shared planning options include `--language`, `--input-format auto|plain|ssmd`, `--unit`, `--text-preparation`, `--pause-mode`, `--spacy`, and `--renderability`. Progress, repair notices, actionable errors, and the final counts are written to stderr. Exit status is 0 if every input succeeds, 1 if any input fails, and 2 for usage errors such as output collisions. `--fail-fast` skips later requests after the first failure but preserves all completed outputs and updates the report.
91
+
79
92
  ## Explain a plan
80
93
 
81
94
  Explain an existing compiled plan as a human-readable speech narrative:
82
95
 
83
96
  ```bash
84
- utterplan explain chapter.utterplan.json
85
- utterplan explain chapter.utterplan.json --details
97
+ utterplan explain chapter.utterplan.toml
98
+ utterplan explain chapter.utterplan.toml --details
86
99
  ```
87
100
 
88
101
  The default output shows prepared wording, render units, ordered segments, languages, resolved pauses, headings, SSMD version/title/document language, effective typed directives, metadata, and warning/error codes with source locations. Add `--details` for IDs, offsets, provenance, hashes, plan identity, and token analysis beneath each segment. Use `inspect --tokens` for a compact token/provenance view.
@@ -94,6 +107,7 @@ The default output shows prepared wording, render units, ordered segments, langu
94
107
  - `--pause-mode tts|manual|auto` selects semantic pause policy.
95
108
  - `--spacy off|auto|sm|md|lg|trf` selects deterministic fallback, automatic
96
109
  spaCy use, or a required model tier.
110
+ - `--renderability repair|strict` defaults to safe punctuation-only repair. Semantic blockers remain failures with source context and an actionable next step; strict mode reports safe repair opportunities without applying them.
97
111
 
98
112
  The default spaCy policy is `off`, so the CLI does not depend on whichever optional model happens to be installed.
99
113
 
@@ -105,28 +119,43 @@ Use `--spacy auto` only as an opt-in enrichment policy. If a compatible local mo
105
119
 
106
120
  ```bash
107
121
  utterplan --version
108
- utterplan validate chapter.utterplan.json
122
+ utterplan validate chapter.utterplan.toml
109
123
  utterplan validate chapter.ssmd.md
110
124
  utterplan validate plain.txt --input-format plain --language en-us
111
- utterplan inspect chapter.utterplan.json --segment 0
112
- utterplan inspect chapter.utterplan.json --unit 0 --boundaries --tokens
113
- utterplan inspect chapter.utterplan.json --preparation
125
+ utterplan inspect chapter.utterplan.toml --segment 0
126
+ utterplan inspect chapter.utterplan.toml --unit 0 --boundaries --tokens
127
+ utterplan inspect chapter.utterplan.toml --preparation
128
+ utterplan inspect chapter.utterplan.toml --semantic-boundaries
114
129
  ```
115
130
 
116
- `inspect --preparation` reports the preparation backend and version, structural and spoken text lengths, replacement count, and each replacement's structural and spoken ranges and text. This is the supported human-facing preparation diagnostic; raw coordinate lookup tables are intentionally absent from plan JSON.
131
+ `inspect --preparation` reports the preparation backend and version, structural and spoken text lengths, replacement count, and each replacement's structural and spoken ranges and text. This is the supported human-facing preparation diagnostic; raw coordinate lookup tables are intentionally absent from the persisted TOML plan.
117
132
 
118
133
  ## Migrate a saved plan
119
134
 
120
- Migrate a supported saved plan to the current schema without rerunning planning:
135
+ Import a supported legacy JSON plan to the current schema without rerunning
136
+ planning. `migrate` is the only CLI path that reads saved plan JSON; its output is
137
+ always canonical TOML:
121
138
 
122
139
  ```bash
123
- utterplan migrate old.utterplan.json -o current.utterplan.json
140
+ utterplan migrate old.utterplan.json -o current.utterplan.toml
124
141
  utterplan migrate old.utterplan.json --check
125
- utterplan migrate old.utterplan.json | jq .
142
+ utterplan migrate old.utterplan.json > current.utterplan.toml
126
143
  ```
127
144
 
128
- Without `-o`, migrated JSON is written to stdout. Status is written to stderr. Existing output files are refused unless `--force` is supplied. `--check` validates the route and reports source schema, target schema, and whether migration is required without writing a file. A future schema version is rejected rather than guessed or downgraded.
129
-
130
- Schema migration is a separate operation from SSMD source migration. UtterPlan preserves released schema v1 and v2 and migrates v1 plans sequentially through v2 to current schema v3. It never reparses source or replans. Use `ssmd migrate FILE --to 0.9` for older SSMD source documents.
131
-
132
- For a saved JSON plan, `validate` performs the in-memory schema compatibility check and reports source/current schema versions without modifying the file. For an SSMD or plain-text source document, it runs the canonical one-document semantic compiler without writing a plan; plain input requires `--language`, while SSMD can use its header language or an explicit fallback.
145
+ Without `-o`, TOML is written to stdout and status is written to stderr. Existing
146
+ output files are refused unless `--force` is supplied. `--check` validates the
147
+ route and reports source schema, target schema, and whether migration is required
148
+ without writing a file. A future schema version is rejected rather than guessed
149
+ or downgraded.
150
+
151
+ Schema migration is a separate operation from SSMD source migration. UtterPlan
152
+ preserves released schemas v1, v2, and v3 and migrates supported plans through the
153
+ registered chain to current schema v4. The v3-to-v4 step does not rerun parsing,
154
+ NLP, or planning. Use `ssmd migrate FILE --to 0.9` for older SSMD source
155
+ documents.
156
+
157
+ For a saved TOML plan, `validate` verifies the current semantic schema and plan
158
+ invariants; JSON plan paths are rejected outside `migrate`. For an SSMD or
159
+ plain-text source document, it runs the canonical one-document semantic compiler
160
+ without writing a plan; plain input requires `--language`, while SSMD can use its
161
+ header language or an explicit fallback.