utterplan 0.4.1__tar.gz → 0.5.1__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.
- {utterplan-0.4.1 → utterplan-0.5.1}/AGENTS.md +4 -3
- {utterplan-0.4.1 → utterplan-0.5.1}/PKG-INFO +37 -29
- {utterplan-0.4.1 → utterplan-0.5.1}/README.md +36 -28
- utterplan-0.5.1/docs/architecture.md +69 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/changelog.md +24 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/cli.md +36 -12
- utterplan-0.5.1/docs/consumer-guide.md +92 -0
- utterplan-0.5.1/docs/coordinate-spaces.md +26 -0
- utterplan-0.5.1/docs/debugging.md +30 -0
- utterplan-0.5.1/docs/format.md +68 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/getting-started.md +33 -15
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/index.md +1 -0
- utterplan-0.5.1/docs/pykokoro-integration.md +46 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/python-api.md +73 -56
- utterplan-0.5.1/docs/ssmdbook.md +72 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/examples/compile_file.py +1 -1
- {utterplan-0.4.1 → utterplan-0.5.1}/examples/inspect_plan.py +6 -5
- {utterplan-0.4.1 → utterplan-0.5.1}/examples/multilingual.py +1 -1
- utterplan-0.5.1/tests/compiler_helpers.py +36 -0
- utterplan-0.5.1/tests/fixtures/canonical_consumer_contract.expected.toml +35 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/goldens/multilingual_preparation.json +2 -2
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/goldens/ssmd_break.json +1 -1
- utterplan-0.5.1/tests/migration/test_legacy_json_import.py +38 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/test_semantic_migration_regressions.py +35 -8
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_batch.py +10 -6
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_boundaries.py +2 -1
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_cli.py +71 -45
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_cli_batch.py +17 -8
- utterplan-0.5.1/tests/test_cli_ssmdbook.py +470 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_compiler.py +39 -17
- utterplan-0.5.1/tests/test_consumer_contract.py +185 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_consumer_readiness.py +19 -38
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_coordinates.py +2 -1
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_directives.py +3 -6
- utterplan-0.5.1/tests/test_explain.py +121 -0
- utterplan-0.5.1/tests/test_fake_renderer.py +133 -0
- utterplan-0.5.1/tests/test_flow_compilation.py +220 -0
- utterplan-0.5.1/tests/test_format.py +110 -0
- utterplan-0.5.1/tests/test_golden.py +65 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_identity_units.py +2 -1
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_linguistics.py +62 -27
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_migration_framework.py +3 -3
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_migration_v3_to_v4.py +6 -6
- utterplan-0.5.1/tests/test_migration_v4_to_v5.py +179 -0
- utterplan-0.5.1/tests/test_pauses.py +213 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_planner.py +34 -16
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_preparation.py +10 -5
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_progress.py +3 -3
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_public_identity.py +3 -3
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_renderability.py +1 -1
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_renderability_repair.py +25 -32
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_schema_history.py +10 -7
- utterplan-0.5.1/tests/test_schema_registry.py +54 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_schema_strict.py +4 -2
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_segment_topology.py +36 -10
- utterplan-0.5.1/tests/test_segmentation_adapter.py +203 -0
- utterplan-0.5.1/tests/test_segmentation_recovery.py +114 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_semantic_boundaries.py +2 -2
- utterplan-0.5.1/tests/test_sentence_topology.py +361 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_ssmd_09_parser.py +25 -21
- utterplan-0.5.1/tests/test_ssmdbook.py +279 -0
- utterplan-0.5.1/tests/test_token_topology.py +73 -0
- utterplan-0.5.1/tests/test_toml_format.py +226 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/__init__.py +18 -4
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/_version.py +3 -3
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/attempt_serialization.py +17 -12
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/batch.py +4 -7
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/cli.py +414 -126
- utterplan-0.5.1/utterplan/codecs/__init__.py +1 -0
- utterplan-0.4.1/utterplan/toml_codec.py → utterplan-0.5.1/utterplan/codecs/v4_toml.py +50 -31
- utterplan-0.5.1/utterplan/codecs/v5_toml.py +504 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/compiler.py +41 -5
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/config.py +0 -54
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/explain.py +156 -54
- utterplan-0.5.1/utterplan/flow_projection.py +306 -0
- utterplan-0.5.1/utterplan/format.py +48 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/hashing.py +92 -2
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/migration.py +1 -1
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/migrations/__init__.py +2 -0
- utterplan-0.5.1/utterplan/migrations/v4_to_v5.py +580 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/model.py +737 -58
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/parsers.py +15 -117
- utterplan-0.5.1/utterplan/pauses.py +108 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/planner.py +303 -231
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/preparation.py +7 -7
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/renderability.py +8 -1
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/schema_registry.py +7 -5
- utterplan-0.5.1/utterplan/segmentation.py +847 -0
- utterplan-0.5.1/utterplan/serialization.py +40 -0
- utterplan-0.5.1/utterplan/ssmdbook.py +259 -0
- utterplan-0.5.1/utterplan/token_topology.py +102 -0
- utterplan-0.5.1/utterplan/toml_codec.py +100 -0
- utterplan-0.5.1/utterplan/trace_codec.py +137 -0
- utterplan-0.5.1/utterplan/versioning.py +11 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan.egg-info/PKG-INFO +37 -29
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan.egg-info/SOURCES.txt +19 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan.egg-info/scm_file_list.json +41 -0
- utterplan-0.5.1/utterplan.egg-info/scm_version.json +8 -0
- utterplan-0.4.1/docs/architecture.md +0 -110
- utterplan-0.4.1/docs/consumer-guide.md +0 -149
- utterplan-0.4.1/docs/coordinate-spaces.md +0 -16
- utterplan-0.4.1/docs/debugging.md +0 -31
- utterplan-0.4.1/docs/format.md +0 -39
- utterplan-0.4.1/docs/pykokoro-integration.md +0 -63
- utterplan-0.4.1/tests/fixtures/canonical_consumer_contract.expected.toml +0 -6
- utterplan-0.4.1/tests/migration/test_legacy_json_import.py +0 -29
- utterplan-0.4.1/tests/test_consumer_contract.py +0 -313
- utterplan-0.4.1/tests/test_explain.py +0 -180
- utterplan-0.4.1/tests/test_fake_renderer.py +0 -72
- utterplan-0.4.1/tests/test_format.py +0 -114
- utterplan-0.4.1/tests/test_golden.py +0 -64
- utterplan-0.4.1/tests/test_pauses.py +0 -212
- utterplan-0.4.1/tests/test_schema_registry.py +0 -54
- utterplan-0.4.1/tests/test_toml_format.py +0 -179
- utterplan-0.4.1/utterplan/format.py +0 -46
- utterplan-0.4.1/utterplan/pauses.py +0 -76
- utterplan-0.4.1/utterplan/serialization.py +0 -32
- utterplan-0.4.1/utterplan/versioning.py +0 -8
- utterplan-0.4.1/utterplan.egg-info/scm_version.json +0 -8
- {utterplan-0.4.1 → utterplan-0.5.1}/.codecrate.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/.github/workflows/codecov.yml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/.github/workflows/pre-commit.yml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/.github/workflows/python-publish.yml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/.github/workflows/tests.yml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/.gitignore +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/.pre-commit-config.yaml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/LICENSE +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/MANIFEST.in +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/NOTICE +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/Makefile +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/conf.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/make.bat +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/phase-a-completion.md +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/docs/requirements.txt +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/examples/basic.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/examples/chapter.ssmd +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/examples/ssmd_example.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/pyproject.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/setup.cfg +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/spec/schemas/v1.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/spec/schemas/v2.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/spec/schemas/v3.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/spec/schemas/v4.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/spec/utterplan.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/__init__.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/fixtures/canonical_consumer_contract.ssmd +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/fixtures/ssmd_09_comprehensive.ssmd +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/golden/basic_en.utterplan.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/golden/directives.utterplan.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/golden/markers.utterplan.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/golden/multilingual.utterplan.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/golden/parenthetical.utterplan.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/golden/spokenform_offsets.utterplan.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/golden/ssmd_09_comprehensive.utterplan.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/golden/ssmd_breaks.utterplan.toml +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/__init__.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/cases.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/fixtures/v4/basic_en.utterplan.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/fixtures/v4/directives.utterplan.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/fixtures/v4/markers.utterplan.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/fixtures/v4/multilingual.utterplan.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/fixtures/v4/parenthetical.utterplan.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/fixtures/v4/spokenform_offsets.utterplan.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/fixtures/v4/ssmd_09_comprehensive.utterplan.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/fixtures/v4/ssmd_breaks.utterplan.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/goldens/spokenform_numbers.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/goldens/ssmd_language_detection.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/goldens/ssmd_marker.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/migration/goldens/ssmd_pronunciation.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/README.md +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v1/basic.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v1/directives.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v1/markers.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v1/multilingual.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v1/parenthetical.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v1/spokenform_offsets.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v1/ssmd_breaks.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v2/directives.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v3/multilingual.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/schema_history/v3/ssmd_09_comprehensive.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_atomic_io.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_import_boundaries.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_language.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/tests/test_version.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/__main__.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/atomic_io.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/attempts.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/diagnostics.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/directives.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/exceptions.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/language.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/linguistics.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/migrations/registry.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/migrations/v1_to_v2.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/migrations/v2_to_v3.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/migrations/v3_to_v4.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/progress.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/py.typed +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/schemas/v1.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/schemas/v2.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/schemas/v3.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/schemas/v4.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/spacy_models.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/spans.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/stages/__init__.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/stages/document/__init__.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/stages/document/plain.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/stages/document/ssmd.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/stages/preparation/__init__.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/stages/preparation/identity.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/stages/preparation/spokenform.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/stages/protocols.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/units.py +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan/utterplan.schema.json +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan.egg-info/dependency_links.txt +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan.egg-info/entry_points.txt +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan.egg-info/requires.txt +0 -0
- {utterplan-0.4.1 → utterplan-0.5.1}/utterplan.egg-info/top_level.txt +0 -0
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
# UtterPlan development rules
|
|
2
2
|
|
|
3
3
|
1. UtterPlan is engine-independent.
|
|
4
|
-
2. `.utterplan.
|
|
4
|
+
2. `.utterplan.toml` schema v5 is the current inter-package contract; historical JSON schemas v1–v4 remain migration inputs only.
|
|
5
5
|
3. Python objects may not contain semantic state that cannot survive file roundtrip.
|
|
6
6
|
4. UtterPlan ends before G2P.
|
|
7
7
|
5. Core code must not import PyKokoro, PiperSynth, kokorog2p, piperg2p, ONNX Runtime, or audio packages.
|
|
8
|
-
6. Public
|
|
8
|
+
6. Public FlowPlan objects contain no phonemes, model token IDs, models, sessions, or audio.
|
|
9
9
|
7. Completed plans must not retain spaCy or provider documents.
|
|
10
10
|
8. Every offset has a documented coordinate space.
|
|
11
11
|
9. Default planning is deterministic.
|
|
12
12
|
10. Schema changes require explicit compatibility review.
|
|
13
13
|
11. Repository tests must be self-contained and must not require sibling consumer checkouts.
|
|
14
14
|
12. Consumer-specific compatibility testing belongs in the consumer repository.
|
|
15
|
-
13. Released schema files are immutable and retained under versioned paths.
|
|
15
|
+
13. Released schema files are immutable and retained under versioned paths; v5 has no historical JSON Schema resource.
|
|
16
16
|
14. Every supported older schema must retain a sequential migration path to current.
|
|
17
17
|
15. Migrations operate on serialized plain data and may not call parser, planner, G2P, renderer, or audio stages.
|
|
18
18
|
16. Schema changes require frozen historical fixture coverage, deterministic migration tests, and package artifact checks.
|
|
19
19
|
17. Package version and schema version remain independent. Migration preserves a compiled plan; replanning is a separate operation.
|
|
20
|
+
18. Optional compiler traces are sidecars; they must never alter executable plan content or identity.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: utterplan
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
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
|
|
@@ -250,10 +250,9 @@ Dynamic: license-file
|
|
|
250
250
|
|
|
251
251
|
UtterPlan is the canonical, engine-independent semantic compiler from one SSMD
|
|
252
252
|
document (or explicitly selected plain-text document) to an executable speech
|
|
253
|
-
plan. It produces deterministic
|
|
254
|
-
|
|
255
|
-
independent consumers such as ttsready and Readio. It does not manage
|
|
256
|
-
consumer workspaces, and stops before G2P, synthesis, and audio.
|
|
253
|
+
plan. It produces deterministic prepared text, ordered flow units, segment-local
|
|
254
|
+
semantics, pause intents, portable document metadata, and typed directives for
|
|
255
|
+
independent consumers such as ttsready and Readio. It does not manage or modify book workspaces; `compile-book` reads an SSMDBook manifest only to discover selected source chapters. It stops before G2P, synthesis, and audio.
|
|
257
256
|
|
|
258
257
|
## CLI
|
|
259
258
|
|
|
@@ -285,18 +284,39 @@ utterplan compile-many examples/*.ssmd --output-dir build/plans
|
|
|
285
284
|
|
|
286
285
|
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
286
|
|
|
287
|
+
Compile a selected chapter range directly from an editable SSMDBook workspace:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
cd "Platform Decay - Martha Wells.ssmdbook"
|
|
291
|
+
|
|
292
|
+
utterplan compile-book chapters --chapters 5-17
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
The command reads the workspace manifest to discover chapters and writes independent v5 plans and a report under `utterplan/`:
|
|
296
|
+
|
|
297
|
+
```text
|
|
298
|
+
utterplan/
|
|
299
|
+
├── compile-report.toml
|
|
300
|
+
├── chapter-0005.utterplan.toml
|
|
301
|
+
├── chapter-0006.utterplan.toml
|
|
302
|
+
├── ...
|
|
303
|
+
└── chapter-0017.utterplan.toml
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Omit `--chapters` to compile all manifest chapters. Use comma-separated source-number selections for non-contiguous ranges, for example `utterplan compile-book chapters --chapters 1,3-5`. The book root itself is also accepted as input; see the [SSMDBook guide](docs/ssmdbook.md).
|
|
288
307
|
The CLI also provides:
|
|
289
308
|
|
|
290
309
|
```bash
|
|
291
310
|
utterplan --version
|
|
292
311
|
utterplan validate chapter.utterplan.toml
|
|
293
312
|
utterplan inspect chapter.utterplan.toml --segment 0
|
|
294
|
-
utterplan inspect chapter.utterplan.toml --
|
|
295
|
-
utterplan explain chapter.utterplan.toml
|
|
313
|
+
utterplan inspect chapter.utterplan.toml --boundaries --tokens
|
|
314
|
+
utterplan explain chapter.utterplan.toml --trace chapter.trace.toml
|
|
315
|
+
utterplan inspect-trace chapter.trace.toml --preparation --boundaries
|
|
296
316
|
utterplan inspect-attempt chapter.attempt.toml --issues
|
|
297
317
|
```
|
|
298
318
|
|
|
299
|
-
`explain` presents
|
|
319
|
+
`explain` presents executable flow as a human-readable speech plan. Use `compile --trace PATH` to retain optional compiler provenance; `explain --trace PATH` and `inspect-trace` read that sidecar separately from the plan.
|
|
300
320
|
|
|
301
321
|
`inspect-attempt` reads the separate `utterplan.planning-attempt.v1` TOML artifact,
|
|
302
322
|
not a canonical plan. Use it to review renderability issues and safe repair
|
|
@@ -318,11 +338,11 @@ ssmd migrate old.ssmd --to 0.9
|
|
|
318
338
|
```
|
|
319
339
|
|
|
320
340
|
`utterplan migrate` explicitly imports supported historical `.utterplan.json` plans and writes current TOML. It does not migrate SSMD source.
|
|
321
|
-
Normal plan loading is TOML-only: `
|
|
341
|
+
Normal plan loading is TOML-only: `FlowPlan.load()` and plan-inspection commands reject JSON rather than auto-detecting it.
|
|
322
342
|
|
|
323
343
|
## Planning defaults
|
|
324
344
|
|
|
325
|
-
The minimal CLI defaults are explicit: `spokenform` is the default text-preparation backend, `tts` is the default pause mode, and `spacy off` is the default linguistic-resource policy. With `spacy off`, UtterPlan uses its deterministic fallback tokenizer and analysis and does not depend on an installed spaCy model.
|
|
345
|
+
The minimal CLI defaults are explicit: `spokenform` is the default text-preparation backend, `tts` is the default pause activation mode, and `spacy off` is the default linguistic-resource policy. With `spacy off`, UtterPlan uses its deterministic fallback tokenizer and analysis and does not depend on an installed spaCy model.
|
|
326
346
|
|
|
327
347
|
Python `PlannerConfig` defaults to `document_format="plain"`; set it to `"ssmd"` when a Python string contains SSMD source.
|
|
328
348
|
|
|
@@ -333,7 +353,7 @@ Python `PlannerConfig.renderability_mode` also defaults to safe punctuation-only
|
|
|
333
353
|
## Python API
|
|
334
354
|
|
|
335
355
|
```python
|
|
336
|
-
from utterplan import PlannerConfig,
|
|
356
|
+
from utterplan import PlannerConfig, FlowPlan, compile_document
|
|
337
357
|
|
|
338
358
|
ssmd_source = """---
|
|
339
359
|
ssmd_version: "0.9"
|
|
@@ -350,7 +370,7 @@ result = compile_document(
|
|
|
350
370
|
plan = result.plan
|
|
351
371
|
assert result.trace is not None
|
|
352
372
|
plan.save("example.utterplan.toml")
|
|
353
|
-
assert
|
|
373
|
+
assert FlowPlan.load("example.utterplan.toml") == plan
|
|
354
374
|
```
|
|
355
375
|
|
|
356
376
|
`compile_document` is the stable public one-document API shared by consumers. The
|
|
@@ -378,21 +398,9 @@ Callbacks run synchronously and exceptions propagate. See the [Python API guide]
|
|
|
378
398
|
|
|
379
399
|
## Renderer-consumer boundary
|
|
380
400
|
|
|
381
|
-
Renderers consume `
|
|
382
|
-
`spoken_start`/`spoken_end` for spoken-text coordinates. Resolved segment
|
|
383
|
-
pauses, language, directives, annotations, boundaries, semantic boundaries,
|
|
384
|
-
markers, units, and
|
|
385
|
-
document metadata are public plan fields. Semantic boundaries are stable
|
|
386
|
-
engine-neutral opportunities for spoken-text subdivision; they are not pause
|
|
387
|
-
events and carry no duration or renderer policy. Plans contain no phonemes, model
|
|
388
|
-
tokens, model sessions, renderer configuration, provider documents, or audio.
|
|
389
|
-
For SSMD input, `plan.annotations` preserve declared source semantics and source
|
|
390
|
-
provenance, `document_metadata` preserves portable header data, and
|
|
391
|
-
`segment.directives` carries effective typed semantics after scope and voice-default
|
|
392
|
-
resolution. Typed directives include voice, pronunciation, prosody, emphasis, say-as,
|
|
393
|
-
substitution, audio references, and extension references. Audio and extensions are
|
|
394
|
-
data only. UtterPlan does not fetch media or execute extension handlers.
|
|
401
|
+
Renderers consume `FlowPlan.flow` in order. Each `FlowUnit` contains local `FlowSegment` objects with already-prepared speech text, effective language, segment-local token views, semantic pause intents, directives, markers, and optional heading level. Token `start`/`end` offsets are Python-character indexes into that segment's `text`; they are never document-global coordinates. Pause intents express `none`, semantic strengths, or exact authored times and do not prescribe engine-specific duration policy.
|
|
395
402
|
|
|
403
|
+
`FlowPlan.document` carries compact document metadata and `FlowPlan.linguistics` identifies the analysis provider without retaining provider documents. Compiler source, preparation maps, diagnostics, and renderability details belong only in an optional trace sidecar. Plans contain no phonemes, model token IDs, models, sessions, renderer configuration, provider documents, or audio. UtterPlan does not fetch media or execute extension handlers.
|
|
396
404
|
The intended dependency direction is:
|
|
397
405
|
|
|
398
406
|
```text
|
|
@@ -407,6 +415,7 @@ renderer repository rather than UtterPlan's test suite.
|
|
|
407
415
|
|
|
408
416
|
- [Getting started](docs/getting-started.md)
|
|
409
417
|
- [CLI](docs/cli.md)
|
|
418
|
+
- [SSMDBook workflows](docs/ssmdbook.md)
|
|
410
419
|
- [Format and schema](docs/format.md)
|
|
411
420
|
- [Consumer guide](docs/consumer-guide.md)
|
|
412
421
|
- [Architecture](docs/architecture.md)
|
|
@@ -418,10 +427,9 @@ renderer repository rather than UtterPlan's test suite.
|
|
|
418
427
|
|
|
419
428
|
## Versions
|
|
420
429
|
|
|
421
|
-
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
|
|
430
|
+
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 v5. Historical JSON Schemas v1–v4 remain immutable and supported through sequential migrations; v5 deliberately has no JSON Schema resource because its canonical executable contract is the validated TOML/FlowPlan model.
|
|
422
431
|
|
|
423
|
-
Schema
|
|
424
|
-
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.
|
|
432
|
+
Schema v5 is a breaking redesign around ordered flow units and segment-local semantics. It preserves deterministic output and moves preparation/source provenance to an optional TOML trace sidecar, which does not affect plan identity. Migration converts serialized plan data only: v1–v4 migrate sequentially to v5 without reparsing, NLP, planning, G2P, rendering, or audio processing. The v4-to-v5 projection fails safely when historical token coordinates or pause semantics cannot be verified.
|
|
425
433
|
|
|
426
434
|
## Development
|
|
427
435
|
|
|
@@ -7,10 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
UtterPlan is the canonical, engine-independent semantic compiler from one SSMD
|
|
9
9
|
document (or explicitly selected plain-text document) to an executable speech
|
|
10
|
-
plan. It produces deterministic
|
|
11
|
-
|
|
12
|
-
independent consumers such as ttsready and Readio. It does not manage
|
|
13
|
-
consumer workspaces, and stops before G2P, synthesis, and audio.
|
|
10
|
+
plan. It produces deterministic prepared text, ordered flow units, segment-local
|
|
11
|
+
semantics, pause intents, portable document metadata, and typed directives for
|
|
12
|
+
independent consumers such as ttsready and Readio. It does not manage or modify book workspaces; `compile-book` reads an SSMDBook manifest only to discover selected source chapters. It stops before G2P, synthesis, and audio.
|
|
14
13
|
|
|
15
14
|
## CLI
|
|
16
15
|
|
|
@@ -42,18 +41,39 @@ utterplan compile-many examples/*.ssmd --output-dir build/plans
|
|
|
42
41
|
|
|
43
42
|
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
43
|
|
|
44
|
+
Compile a selected chapter range directly from an editable SSMDBook workspace:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
cd "Platform Decay - Martha Wells.ssmdbook"
|
|
48
|
+
|
|
49
|
+
utterplan compile-book chapters --chapters 5-17
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The command reads the workspace manifest to discover chapters and writes independent v5 plans and a report under `utterplan/`:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
utterplan/
|
|
56
|
+
├── compile-report.toml
|
|
57
|
+
├── chapter-0005.utterplan.toml
|
|
58
|
+
├── chapter-0006.utterplan.toml
|
|
59
|
+
├── ...
|
|
60
|
+
└── chapter-0017.utterplan.toml
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Omit `--chapters` to compile all manifest chapters. Use comma-separated source-number selections for non-contiguous ranges, for example `utterplan compile-book chapters --chapters 1,3-5`. The book root itself is also accepted as input; see the [SSMDBook guide](docs/ssmdbook.md).
|
|
45
64
|
The CLI also provides:
|
|
46
65
|
|
|
47
66
|
```bash
|
|
48
67
|
utterplan --version
|
|
49
68
|
utterplan validate chapter.utterplan.toml
|
|
50
69
|
utterplan inspect chapter.utterplan.toml --segment 0
|
|
51
|
-
utterplan inspect chapter.utterplan.toml --
|
|
52
|
-
utterplan explain chapter.utterplan.toml
|
|
70
|
+
utterplan inspect chapter.utterplan.toml --boundaries --tokens
|
|
71
|
+
utterplan explain chapter.utterplan.toml --trace chapter.trace.toml
|
|
72
|
+
utterplan inspect-trace chapter.trace.toml --preparation --boundaries
|
|
53
73
|
utterplan inspect-attempt chapter.attempt.toml --issues
|
|
54
74
|
```
|
|
55
75
|
|
|
56
|
-
`explain` presents
|
|
76
|
+
`explain` presents executable flow as a human-readable speech plan. Use `compile --trace PATH` to retain optional compiler provenance; `explain --trace PATH` and `inspect-trace` read that sidecar separately from the plan.
|
|
57
77
|
|
|
58
78
|
`inspect-attempt` reads the separate `utterplan.planning-attempt.v1` TOML artifact,
|
|
59
79
|
not a canonical plan. Use it to review renderability issues and safe repair
|
|
@@ -75,11 +95,11 @@ ssmd migrate old.ssmd --to 0.9
|
|
|
75
95
|
```
|
|
76
96
|
|
|
77
97
|
`utterplan migrate` explicitly imports supported historical `.utterplan.json` plans and writes current TOML. It does not migrate SSMD source.
|
|
78
|
-
Normal plan loading is TOML-only: `
|
|
98
|
+
Normal plan loading is TOML-only: `FlowPlan.load()` and plan-inspection commands reject JSON rather than auto-detecting it.
|
|
79
99
|
|
|
80
100
|
## Planning defaults
|
|
81
101
|
|
|
82
|
-
The minimal CLI defaults are explicit: `spokenform` is the default text-preparation backend, `tts` is the default pause mode, and `spacy off` is the default linguistic-resource policy. With `spacy off`, UtterPlan uses its deterministic fallback tokenizer and analysis and does not depend on an installed spaCy model.
|
|
102
|
+
The minimal CLI defaults are explicit: `spokenform` is the default text-preparation backend, `tts` is the default pause activation mode, and `spacy off` is the default linguistic-resource policy. With `spacy off`, UtterPlan uses its deterministic fallback tokenizer and analysis and does not depend on an installed spaCy model.
|
|
83
103
|
|
|
84
104
|
Python `PlannerConfig` defaults to `document_format="plain"`; set it to `"ssmd"` when a Python string contains SSMD source.
|
|
85
105
|
|
|
@@ -90,7 +110,7 @@ Python `PlannerConfig.renderability_mode` also defaults to safe punctuation-only
|
|
|
90
110
|
## Python API
|
|
91
111
|
|
|
92
112
|
```python
|
|
93
|
-
from utterplan import PlannerConfig,
|
|
113
|
+
from utterplan import PlannerConfig, FlowPlan, compile_document
|
|
94
114
|
|
|
95
115
|
ssmd_source = """---
|
|
96
116
|
ssmd_version: "0.9"
|
|
@@ -107,7 +127,7 @@ result = compile_document(
|
|
|
107
127
|
plan = result.plan
|
|
108
128
|
assert result.trace is not None
|
|
109
129
|
plan.save("example.utterplan.toml")
|
|
110
|
-
assert
|
|
130
|
+
assert FlowPlan.load("example.utterplan.toml") == plan
|
|
111
131
|
```
|
|
112
132
|
|
|
113
133
|
`compile_document` is the stable public one-document API shared by consumers. The
|
|
@@ -135,21 +155,9 @@ Callbacks run synchronously and exceptions propagate. See the [Python API guide]
|
|
|
135
155
|
|
|
136
156
|
## Renderer-consumer boundary
|
|
137
157
|
|
|
138
|
-
Renderers consume `
|
|
139
|
-
`spoken_start`/`spoken_end` for spoken-text coordinates. Resolved segment
|
|
140
|
-
pauses, language, directives, annotations, boundaries, semantic boundaries,
|
|
141
|
-
markers, units, and
|
|
142
|
-
document metadata are public plan fields. Semantic boundaries are stable
|
|
143
|
-
engine-neutral opportunities for spoken-text subdivision; they are not pause
|
|
144
|
-
events and carry no duration or renderer policy. Plans contain no phonemes, model
|
|
145
|
-
tokens, model sessions, renderer configuration, provider documents, or audio.
|
|
146
|
-
For SSMD input, `plan.annotations` preserve declared source semantics and source
|
|
147
|
-
provenance, `document_metadata` preserves portable header data, and
|
|
148
|
-
`segment.directives` carries effective typed semantics after scope and voice-default
|
|
149
|
-
resolution. Typed directives include voice, pronunciation, prosody, emphasis, say-as,
|
|
150
|
-
substitution, audio references, and extension references. Audio and extensions are
|
|
151
|
-
data only. UtterPlan does not fetch media or execute extension handlers.
|
|
158
|
+
Renderers consume `FlowPlan.flow` in order. Each `FlowUnit` contains local `FlowSegment` objects with already-prepared speech text, effective language, segment-local token views, semantic pause intents, directives, markers, and optional heading level. Token `start`/`end` offsets are Python-character indexes into that segment's `text`; they are never document-global coordinates. Pause intents express `none`, semantic strengths, or exact authored times and do not prescribe engine-specific duration policy.
|
|
152
159
|
|
|
160
|
+
`FlowPlan.document` carries compact document metadata and `FlowPlan.linguistics` identifies the analysis provider without retaining provider documents. Compiler source, preparation maps, diagnostics, and renderability details belong only in an optional trace sidecar. Plans contain no phonemes, model token IDs, models, sessions, renderer configuration, provider documents, or audio. UtterPlan does not fetch media or execute extension handlers.
|
|
153
161
|
The intended dependency direction is:
|
|
154
162
|
|
|
155
163
|
```text
|
|
@@ -164,6 +172,7 @@ renderer repository rather than UtterPlan's test suite.
|
|
|
164
172
|
|
|
165
173
|
- [Getting started](docs/getting-started.md)
|
|
166
174
|
- [CLI](docs/cli.md)
|
|
175
|
+
- [SSMDBook workflows](docs/ssmdbook.md)
|
|
167
176
|
- [Format and schema](docs/format.md)
|
|
168
177
|
- [Consumer guide](docs/consumer-guide.md)
|
|
169
178
|
- [Architecture](docs/architecture.md)
|
|
@@ -175,10 +184,9 @@ renderer repository rather than UtterPlan's test suite.
|
|
|
175
184
|
|
|
176
185
|
## Versions
|
|
177
186
|
|
|
178
|
-
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
|
|
187
|
+
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 v5. Historical JSON Schemas v1–v4 remain immutable and supported through sequential migrations; v5 deliberately has no JSON Schema resource because its canonical executable contract is the validated TOML/FlowPlan model.
|
|
179
188
|
|
|
180
|
-
Schema
|
|
181
|
-
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.
|
|
189
|
+
Schema v5 is a breaking redesign around ordered flow units and segment-local semantics. It preserves deterministic output and moves preparation/source provenance to an optional TOML trace sidecar, which does not affect plan identity. Migration converts serialized plan data only: v1–v4 migrate sequentially to v5 without reparsing, NLP, planning, G2P, rendering, or audio processing. The v4-to-v5 projection fails safely when historical token coordinates or pause semantics cannot be verified.
|
|
182
190
|
|
|
183
191
|
## Development
|
|
184
192
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
UtterPlan is an engine-independent compiler from one SSMD document (or explicitly selected plain-text document) to an executable speech plan. Consumers compile documents independently; UtterPlan does not load books or manage workspaces.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
one SSMD document / explicit plain text
|
|
7
|
+
|
|
|
8
|
+
v
|
|
9
|
+
parse -> language semantics -> spokenform preparation
|
|
10
|
+
-> segmentation -> directive resolution
|
|
11
|
+
-> semantic pause intent -> internal compiler plan
|
|
12
|
+
| |
|
|
13
|
+
| +--> optional trace sidecar
|
|
14
|
+
v
|
|
15
|
+
FlowPlan (ordered units, local segments)
|
|
16
|
+
/ \
|
|
17
|
+
consumer A consumer B
|
|
18
|
+
|
|
|
19
|
+
v
|
|
20
|
+
G2P / renderer / audio
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The dependency direction is from SSMD, spokenform, and phrasplit into UtterPlan, then from UtterPlan to consumer packages. UtterPlan must not depend on ttsready, Readio, engine registries, G2P packages, model runtimes, or audio packages. Book iteration belongs to consumers and conversion tools.
|
|
24
|
+
|
|
25
|
+
## Compiler and public plan boundary
|
|
26
|
+
|
|
27
|
+
`compile_document` returns a `CompileResult` containing the current immutable `FlowPlan`, renderer-independent diagnostics, and an optional `PreparationTrace`. `UtterancePlanner.plan` also returns `FlowPlan`. Compiler-only normalized graph state remains private. When requested, the trace retains source text/hash, coordinate maps, preparation provenance, diagnostics, and renderability evidence in a separate versioned TOML sidecar. Trace state is not renderer input and does not affect plan identity or TOML.
|
|
28
|
+
|
|
29
|
+
`FlowPlan` is the current v5 executable contract: ordered `FlowUnit` objects each own ordered `FlowSegment` records. Segments include prepared text, effective language, local tokens, semantic pause intents, directives, markers, and optional heading metadata. `DocumentInfo` retains compact portable document information; `LinguisticProvenance` identifies providers without retaining their documents. UtterPlan ends before G2P. Engine/model selection, synthesis, and audio composition happen downstream.
|
|
30
|
+
|
|
31
|
+
## Compiler-owned segmentation topology
|
|
32
|
+
|
|
33
|
+
Segmentation has four distinct layers: parser-owned paragraph events define paragraph regions; PhraseSplit supplies advisory sentence-boundary proposals; UtterPlan validates those proposals and owns canonical paragraph, sentence, and private sentence-part spans in prepared spoken-text coordinates; renderer-required language, directive, pause, marker, and media cuts subdivide a part into final segments. Positive-width atomic media spans protect their interiors from automatic sentence/part boundaries; zero-width media events remain renderer operations, not parts. The public v5 `FlowPlan` contains only the resulting compact ordered flow—there is no serialized sentence-parts table.
|
|
34
|
+
|
|
35
|
+
PhraseSplit failure or an invalid proposal batch falls back to deterministic, conservative terminal scanning. Unsafe automatic cuts inside provider-aware lexical content are merged or dropped before projection; the final flow-projection token-edge check remains defense in depth. Exact surface and non-whitespace coverage checks run before and after applicable repairs. This normalization is independent of `renderability_mode`: strict and repair compilation use the same topology, while renderability mode governs only the existing punctuation-repair policy. See the [coordinate-space contract](coordinate-spaces) for offset ownership.
|
|
36
|
+
|
|
37
|
+
## SSMD and preparation
|
|
38
|
+
|
|
39
|
+
The document parser calls SSMD with `dialect="0.9"` for every SSMD source path, including unversioned fragments selected with `document_format="ssmd"`. UtterPlan does not parse SSMD 0.8 or migrate source. Older documents must first be converted with `ssmd migrate FILE --to 0.9`. The `utterplan migrate` command imports serialized legacy plans and applies schema migrations only.
|
|
40
|
+
|
|
41
|
+
SSMD header language is authoritative over a fallback. The CLI can omit `--language` when the header declares a language; plain input always needs a fallback. A fallback never forces or rewrites document semantics.
|
|
42
|
+
|
|
43
|
+
Preparation creates structural and spoken representations internally. The executable FlowPlan retains only prepared segment text; it does not retain the exact source string, structural text, dense source-to-spoken maps, parser annotations, or global compiler token tables. These diagnostics/provenance survive only when an optional trace is requested. See the [coordinate-space contract](coordinate-spaces).
|
|
44
|
+
|
|
45
|
+
## Pause and directive semantics
|
|
46
|
+
|
|
47
|
+
Authored SSMD breaks and semantic pause strengths project to local `PauseIntent` values on segment edges. The plan does not invent numeric durations or serialize an activation policy. Application pause mode controls which intents the compiler activates; consumer-specific timing policy remains downstream. Exact authored timed breaks remain exact. Ambiguous historical pause evidence fails migration rather than being guessed.
|
|
48
|
+
|
|
49
|
+
Typed directives are renderer-neutral values resolved from SSMD scopes and voice defaults. Logical voice bindings remain references, not concrete engine voices. Audio references and extension names are data only; UtterPlan does not fetch media or execute handlers.
|
|
50
|
+
|
|
51
|
+
## Identity and determinism
|
|
52
|
+
|
|
53
|
+
Plan identity is deterministic and renderer-independent. The v5 `plan_id` hashes executable flow and compact portable metadata rather than source text or TOML formatting. Flow-unit hashes use `utterplan-flow-v1` over local ordered segment semantics. Trace data, provider documents, model sessions, diagnostics, producer/package version, G2P output, and audio do not define executable identity. Package version is independent of explicit plan `schema_version`.
|
|
54
|
+
|
|
55
|
+
## Persistence compatibility boundary
|
|
56
|
+
|
|
57
|
+
Current plans persist as deterministic `.utterplan.toml` files with schema v5; `FlowPlan.load()` accepts TOML only. The v5 TOML codec validates and constructs `FlowPlan`. Schema v5 deliberately has no JSON Schema resource or current JSON plan format. Frozen JSON Schema definitions for historical schemas v1–v4 remain under versioned resources.
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
current plan:
|
|
61
|
+
.utterplan.toml -- TOML decode / schema-v5 validation --> FlowPlan --> consumer
|
|
62
|
+
|
|
63
|
+
legacy saved plan:
|
|
64
|
+
.utterplan.json -- explicit `utterplan migrate` --> current .utterplan.toml
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Migration is not planning. Supported historical plans migrate through the registered sequential chain v1 -> v2 -> v3 -> v4 -> v5. Every step operates on serialized plain data and does not rerun source parsing, preparation, NLP, planning, G2P, rendering, or audio processing. The v4-to-v5 projection verifies token spans and pause evidence and fails rather than guessing. Downgrades are not supported.
|
|
68
|
+
|
|
69
|
+
`compile-many` orchestrates independent source documents in order. Each successful FlowPlan 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 TOML report is operational data, not a FlowPlan.
|
|
@@ -4,6 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.5.1] - 2026-10-10
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Improved sentence topology with validated fallback recovery and token-edge safeguards
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Fixed fallback token projection and sentence-boundary repair for punctuation-separated text
|
|
16
|
+
|
|
17
|
+
<!-- generated by releaseledger -->
|
|
18
|
+
|
|
19
|
+
## [0.5.0] - 2026-10-09
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Added compile-book for selecting and compiling SSMDBook chapters into independent v5 plans with operational reports
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **BREAKING:** Changed plan persistence to schema v5 with deterministic TOML, sequential legacy migration, and optional trace sidecars
|
|
28
|
+
|
|
29
|
+
<!-- generated by releaseledger -->
|
|
30
|
+
|
|
7
31
|
## [0.4.1] - 2026-10-07
|
|
8
32
|
|
|
9
33
|
### Added
|
|
@@ -9,7 +9,8 @@ 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
|
-
[--
|
|
12
|
+
[--trace TRACE] [--force] [--stdout]
|
|
13
|
+
[--renderability {strict,repair}]
|
|
13
14
|
[text ...]
|
|
14
15
|
```
|
|
15
16
|
|
|
@@ -65,6 +66,7 @@ Without `--output`, compile writes the pretty TOML plan to stdout. With
|
|
|
65
66
|
`--force` is supplied. Add `--stdout` with an output path to write the file and
|
|
66
67
|
also emit the same TOML plan to stdout.
|
|
67
68
|
|
|
69
|
+
`--trace PATH` writes optional compiler provenance to a separate TOML sidecar. The trace is not embedded in, or hashed as part of, the executable plan. Keep and distribute the sidecar only when source text, preparation maps, diagnostics, or renderability evidence must be retained.
|
|
68
70
|
Human status messages are written to stderr, never mixed into TOML stdout:
|
|
69
71
|
|
|
70
72
|
```bash
|
|
@@ -85,10 +87,35 @@ utterplan compile-many chapters/*.ssmd --output-dir build/plans \
|
|
|
85
87
|
--language en-us --report build/compile-report.toml
|
|
86
88
|
```
|
|
87
89
|
|
|
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 `
|
|
90
|
+
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 `FlowPlan.load()`.
|
|
89
91
|
|
|
90
92
|
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
93
|
|
|
94
|
+
## Compile chapters from an SSMDBook workspace
|
|
95
|
+
|
|
96
|
+
`compile-book` discovers selected SSMD chapters from an editable `.ssmdbook` manifest and compiles each chapter independently through the batch compiler. Pass either the book directory or its canonical `chapters/` directory:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
utterplan compile-book novel.ssmdbook --chapters 5-17
|
|
100
|
+
utterplan compile-book novel.ssmdbook/chapters --chapters 1,3-5
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The workflow used from inside the workspace is:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cd "Platform Decay - Martha Wells.ssmdbook"
|
|
107
|
+
|
|
108
|
+
utterplan compile-book chapters --chapters 5-17
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`--chapters` selects manifest `source_number` values, not filenames or manifest indexes. It accepts `all` (the default), one number, inclusive ranges, or comma-separated combinations such as `1,3-5,9`. Duplicate selections do not duplicate work, and selected chapters always follow manifest array order. A selected missing source number or malformed selector is rejected before compilation.
|
|
112
|
+
|
|
113
|
+
By default, plans and the operational report are written to `<book-root>/utterplan/`. Use `--output-dir PATH` to override the destination. One canonical v5 `.utterplan.toml` plan is written per selected chapter, plus `compile-report.toml`. Existing plans are protected unless `--force` is given; `--fail-fast` skips later chapters after the first failure. `--report PATH` overrides the report location. Duplicate output names, report/plan collisions, and writes into the source `chapters/` directory or over `manifest.json` are rejected before writing.
|
|
114
|
+
|
|
115
|
+
Shared planning options are `--language`/`--lang`, `--unit`, `--text-preparation`, `--pause-mode`, `--renderability`, and `--spacy`. Chapter documents are SSMD 0.9 by contract, so `compile-book` does not accept `--input-format`. The manifest is read-only: edited chapter content is compiled as it currently exists even if its recorded digest is stale, and UtterPlan never refreshes the manifest or chapter hashes. Only selected chapter files are opened, so an unrelated broken chapter outside the selection does not block the request.
|
|
116
|
+
|
|
117
|
+
For the full editable-workspace behavior and examples, see the [SSMDBook guide](ssmdbook.md).
|
|
118
|
+
|
|
92
119
|
## Explain a plan
|
|
93
120
|
|
|
94
121
|
Explain an existing compiled plan as a human-readable speech narrative:
|
|
@@ -98,7 +125,7 @@ utterplan explain chapter.utterplan.toml
|
|
|
98
125
|
utterplan explain chapter.utterplan.toml --details
|
|
99
126
|
```
|
|
100
127
|
|
|
101
|
-
The default output
|
|
128
|
+
The default output explains executable flow: prepared segment text, unit order, effective languages, semantic pause intents, headings, markers, and typed directives. Compiler source diagnostics and preparation provenance are intentionally absent from the plan unless a trace sidecar was saved. Add `--details` for local token offsets, flow hashes, plan identity, and trace preparation mappings. Pass `--trace PATH` to attach a matching sidecar; the TOML trace can also be read independently with `inspect-trace`.
|
|
102
129
|
|
|
103
130
|
## Inspect a persisted planning attempt
|
|
104
131
|
|
|
@@ -116,7 +143,7 @@ The default view summarizes status, renderability, and candidate size. `--issues
|
|
|
116
143
|
shows source context and conservative repair assessments; segment and unit selectors
|
|
117
144
|
accept an ID or zero-based index. `--json` emits the complete artifact as JSON for
|
|
118
145
|
inspection, but the persisted attempt itself remains TOML. A blocked candidate is an
|
|
119
|
-
inspect-only draft, not a canonical plan, and is rejected by `
|
|
146
|
+
inspect-only draft, not a canonical plan, and is rejected by `FlowPlan.load()`.
|
|
120
147
|
|
|
121
148
|
## Planning controls
|
|
122
149
|
|
|
@@ -142,12 +169,13 @@ utterplan validate chapter.ssmd.md
|
|
|
142
169
|
utterplan validate plain.txt --input-format plain --language en-us
|
|
143
170
|
utterplan inspect chapter.utterplan.toml --segment 0
|
|
144
171
|
utterplan inspect chapter.utterplan.toml --unit 0 --boundaries --tokens
|
|
145
|
-
utterplan
|
|
146
|
-
utterplan
|
|
172
|
+
utterplan compile chapter.ssmd.md -o chapter.utterplan.toml --trace chapter.trace.toml
|
|
173
|
+
utterplan explain chapter.utterplan.toml --trace chapter.trace.toml
|
|
174
|
+
utterplan inspect-trace chapter.trace.toml --preparation --boundaries
|
|
147
175
|
utterplan inspect-attempt chapter.attempt.toml --issues
|
|
148
176
|
```
|
|
149
177
|
|
|
150
|
-
`inspect --preparation` reports
|
|
178
|
+
`inspect-trace --preparation` reports source/prepared text lengths, maps, preparation changes, and repair/diagnostic evidence from the optional trace. `inspect-trace --boundaries` shows compiler-only boundary events and semantic candidates. These fields are intentionally absent from the executable plan TOML.
|
|
151
179
|
|
|
152
180
|
## Migrate a saved plan
|
|
153
181
|
|
|
@@ -167,11 +195,7 @@ route and reports source schema, target schema, and whether migration is require
|
|
|
167
195
|
without writing a file. A future schema version is rejected rather than guessed
|
|
168
196
|
or downgraded.
|
|
169
197
|
|
|
170
|
-
Schema migration is
|
|
171
|
-
preserves released schemas v1, v2, and v3 and migrates supported plans through the
|
|
172
|
-
registered chain to current schema v4. The v3-to-v4 step does not rerun parsing,
|
|
173
|
-
NLP, or planning. Use `ssmd migrate FILE --to 0.9` for older SSMD source
|
|
174
|
-
documents.
|
|
198
|
+
Schema migration is separate from SSMD source migration. Frozen JSON schemas v1–v4 migrate through the registered sequential chain to current schema v5. The v4-to-v5 projection does not rerun parsing, text preparation, NLP, or planning, and refuses ambiguous token coordinates or pause meanings rather than guessing. Use `ssmd migrate FILE --to 0.9` for older SSMD source documents.
|
|
175
199
|
|
|
176
200
|
For a saved TOML plan, `validate` verifies the current semantic schema and plan
|
|
177
201
|
invariants; JSON plan paths are rejected outside `migrate`. For an SSMD or
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Renderer consumer guide
|
|
2
|
+
|
|
3
|
+
UtterPlan ends at a semantic planning boundary. A renderer consumes the public `FlowPlan` and begins G2P after planning. It does not need a TOML round trip when planner and renderer run in the same process.
|
|
4
|
+
|
|
5
|
+
For persistence across processes, save a current plan as `.utterplan.toml` and load it with `FlowPlan.load()`. `to_toml()` / `from_toml()` provide text round-tripping, and `plan_id` identifies executable semantics rather than TOML formatting. Batch reports and optional compiler traces are operational/provenance artifacts, not plans.
|
|
6
|
+
|
|
7
|
+
UtterPlan accepts SSMD source syntax at version 0.9 only. Convert older source with `ssmd migrate FILE --to 0.9`; `utterplan migrate` is for importing serialized legacy plans.
|
|
8
|
+
|
|
9
|
+
## Importing legacy plans
|
|
10
|
+
|
|
11
|
+
Historical JSON schemas v1–v4 remain immutable and supported through sequential migrations to schema v5. Import explicitly:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
utterplan migrate old.utterplan.json -o current.utterplan.toml
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Migration operates on serialized plain data and does not reparse, reprepare, rerun NLP, or replan. The v4-to-v5 projection fails safely if token ownership/spans or authored pause semantics cannot be verified without guessing. Recompiling source is a separate operation. Normal `FlowPlan.load()` and plan-inspection commands reject JSON.
|
|
18
|
+
|
|
19
|
+
## Planning defaults
|
|
20
|
+
|
|
21
|
+
The default text-preparation backend is `spokenform`, pause activation mode is `tts`, and the default CLI linguistic-resource policy is `spacy off`. Deterministic fallback tokenization and analysis do not require an installed spaCy model. `spacy auto` is opt-in; it may expose richer tokenization, POS, lemmas, and tags, but provider documents remain internal.
|
|
22
|
+
|
|
23
|
+
In Python, `PlannerConfig.document_format` defaults to `"plain"`; select `"ssmd"` for SSMD source. `PauseConfig.mode` controls whether eligible semantic pause intents are activated by the compiler. The executable plan carries semantic intent (or an exact authored timed pause), not numeric durations invented from an activation policy. A renderer may interpret supported intents according to its own capabilities.
|
|
24
|
+
|
|
25
|
+
## Consumer contract
|
|
26
|
+
|
|
27
|
+
`FlowPlan.flow` is the render order. Each `FlowUnit` owns its ordered `FlowSegment` records; no ID join is required. A segment provides:
|
|
28
|
+
|
|
29
|
+
- `text`: prepared speech text for this segment.
|
|
30
|
+
- `language`: effective language, defaulting from `FlowPlan.language` when omitted on the wire.
|
|
31
|
+
- `tokens`: local token views with optional lemma, POS, tag, and morphology.
|
|
32
|
+
- `pause_before` and `pause_after`: semantic pause intents such as `none`, `sentence`, `parenthetical`, or an exact authored time.
|
|
33
|
+
- `directives`: typed voice, pronunciation, prosody, emphasis, say-as, substitution, audio, and extension data.
|
|
34
|
+
- `markers` and optional `heading` metadata already localized to the owning segment.
|
|
35
|
+
|
|
36
|
+
Token offsets are half-open Python-character ranges into the owning `segment.text`. Do not use them to slice document text or add offsets from another segment. Consumers render flow units and segments in their stored order.
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from utterplan import FlowPlan
|
|
40
|
+
|
|
41
|
+
plan = FlowPlan.load("chapter.utterplan.toml")
|
|
42
|
+
plan.validate()
|
|
43
|
+
|
|
44
|
+
for unit in plan.flow:
|
|
45
|
+
for segment in unit.segments:
|
|
46
|
+
token_views = [
|
|
47
|
+
(segment.text[token.start : token.end], token.lemma, token.pos, token.tag, token.morph)
|
|
48
|
+
for token in segment.tokens
|
|
49
|
+
]
|
|
50
|
+
render_speech(
|
|
51
|
+
text=segment.text,
|
|
52
|
+
language=segment.language,
|
|
53
|
+
tokens=token_views,
|
|
54
|
+
pause_before=segment.pause_before,
|
|
55
|
+
pause_after=segment.pause_after,
|
|
56
|
+
directives=segment.directives,
|
|
57
|
+
)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`FlowPlan.document` retains compact document information such as format, title, SSMD version, and portable semantics. `FlowPlan.linguistics` identifies analysis provider/model provenance without retaining provider state. Source text, source locations, compiler diagnostics, preparation mappings, and renderability details are intentionally not executable-plan fields.
|
|
61
|
+
|
|
62
|
+
## Optional compiler trace
|
|
63
|
+
|
|
64
|
+
When source-level evidence must survive a process boundary, request a separate trace sidecar:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
utterplan compile chapter.ssmd.md -o chapter.utterplan.toml --trace chapter.trace.toml
|
|
68
|
+
utterplan explain chapter.utterplan.toml --trace chapter.trace.toml
|
|
69
|
+
utterplan inspect-trace chapter.trace.toml --preparation --boundaries
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The trace contains source text/hash, structural/prepared text, coordinate maps, preparation changes, diagnostics, and renderability evidence. It is not renderer input, does not affect `FlowPlan.plan_id`, and does not change the resulting plan TOML. See the [coordinate-space contract](coordinate-spaces) for every trace offset's coordinate space.
|
|
73
|
+
|
|
74
|
+
## Directives and media
|
|
75
|
+
|
|
76
|
+
Voice bindings and directive voice references are logical names, not backend voice IDs; consumers translate them to engine-specific resources. UtterPlan resolves SSMD scopes and defaults but does not choose engine settings or recompute pause policy.
|
|
77
|
+
|
|
78
|
+
An audio directive is already attached to its owning segment. Its `src` is opaque data for an external resolver; UtterPlan does not select or invoke one. For an audio-bearing segment, `segment.text` is an optional spoken fallback. Identical source URIs on distinct segments are separate timeline occurrences and must not be deduplicated as playback events. Extension references are also data only; UtterPlan does not execute handlers.
|
|
79
|
+
|
|
80
|
+
## Stable renderer input
|
|
81
|
+
|
|
82
|
+
A completed plan is immutable consumer input. Consumers may derive data for G2P/rendering, but must not rewrite planning decisions or mutate the plan:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
before = plan.to_toml()
|
|
86
|
+
plan_id = plan.plan_id
|
|
87
|
+
consume_plan(plan)
|
|
88
|
+
assert plan.to_toml() == before
|
|
89
|
+
assert plan.plan_id == plan_id
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Plans contain no phonemes, model token IDs, model sessions, audio, renderer configuration, or model-derived timings. Acoustic retries and renderer-level randomness remain outside UtterPlan.
|