utterplan 0.4.0__tar.gz → 0.5.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.
- {utterplan-0.4.0 → utterplan-0.5.0}/.github/workflows/tests.yml +2 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/AGENTS.md +4 -3
- {utterplan-0.4.0 → utterplan-0.5.0}/PKG-INFO +42 -29
- {utterplan-0.4.0 → utterplan-0.5.0}/README.md +41 -28
- utterplan-0.5.0/docs/architecture.md +63 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/changelog.md +32 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/cli.md +54 -11
- utterplan-0.5.0/docs/consumer-guide.md +92 -0
- utterplan-0.5.0/docs/coordinate-spaces.md +22 -0
- utterplan-0.5.0/docs/debugging.md +28 -0
- utterplan-0.5.0/docs/format.md +62 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/getting-started.md +33 -15
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/index.md +1 -0
- utterplan-0.5.0/docs/pykokoro-integration.md +46 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/python-api.md +105 -53
- utterplan-0.5.0/docs/ssmdbook.md +72 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/examples/compile_file.py +1 -1
- {utterplan-0.4.0 → utterplan-0.5.0}/examples/inspect_plan.py +6 -5
- {utterplan-0.4.0 → utterplan-0.5.0}/examples/multilingual.py +1 -1
- utterplan-0.5.0/tests/compiler_helpers.py +36 -0
- utterplan-0.5.0/tests/fixtures/canonical_consumer_contract.expected.toml +35 -0
- utterplan-0.5.0/tests/migration/test_legacy_json_import.py +38 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/test_semantic_migration_regressions.py +35 -8
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_batch.py +10 -6
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_boundaries.py +2 -1
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_cli.py +124 -42
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_cli_batch.py +9 -4
- utterplan-0.5.0/tests/test_cli_ssmdbook.py +431 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_compiler.py +39 -17
- utterplan-0.5.0/tests/test_consumer_contract.py +182 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_consumer_readiness.py +19 -38
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_coordinates.py +2 -1
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_directives.py +3 -6
- utterplan-0.5.0/tests/test_explain.py +121 -0
- utterplan-0.5.0/tests/test_fake_renderer.py +133 -0
- utterplan-0.5.0/tests/test_flow_compilation.py +97 -0
- utterplan-0.5.0/tests/test_format.py +110 -0
- utterplan-0.5.0/tests/test_golden.py +65 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_identity_units.py +2 -1
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_linguistics.py +59 -11
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_migration_framework.py +3 -3
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_migration_v3_to_v4.py +6 -6
- utterplan-0.5.0/tests/test_migration_v4_to_v5.py +179 -0
- utterplan-0.5.0/tests/test_pauses.py +213 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_planner.py +7 -5
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_preparation.py +10 -5
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_progress.py +3 -3
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_public_identity.py +3 -3
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_renderability.py +1 -1
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_renderability_repair.py +110 -5
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_schema_history.py +10 -7
- utterplan-0.5.0/tests/test_schema_registry.py +54 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_schema_strict.py +4 -2
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_segment_topology.py +4 -3
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_semantic_boundaries.py +2 -2
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_ssmd_09_parser.py +96 -20
- utterplan-0.5.0/tests/test_ssmdbook.py +279 -0
- utterplan-0.5.0/tests/test_toml_format.py +226 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/__init__.py +24 -4
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/_version.py +3 -3
- utterplan-0.5.0/utterplan/attempt_serialization.py +250 -0
- utterplan-0.5.0/utterplan/attempts.py +103 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/batch.py +4 -7
- utterplan-0.5.0/utterplan/cli.py +1048 -0
- utterplan-0.5.0/utterplan/codecs/__init__.py +1 -0
- utterplan-0.4.0/utterplan/toml_codec.py → utterplan-0.5.0/utterplan/codecs/v4_toml.py +71 -33
- utterplan-0.5.0/utterplan/codecs/v5_toml.py +504 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/compiler.py +73 -5
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/config.py +0 -54
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/explain.py +156 -54
- utterplan-0.5.0/utterplan/flow_projection.py +276 -0
- utterplan-0.5.0/utterplan/format.py +48 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/hashing.py +92 -2
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/migration.py +1 -1
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/migrations/__init__.py +2 -0
- utterplan-0.5.0/utterplan/migrations/v4_to_v5.py +580 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/model.py +748 -64
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/parsers.py +194 -177
- utterplan-0.5.0/utterplan/pauses.py +108 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/planner.py +149 -89
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/preparation.py +7 -7
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/renderability.py +8 -1
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/schema_registry.py +7 -5
- utterplan-0.5.0/utterplan/serialization.py +40 -0
- utterplan-0.5.0/utterplan/ssmdbook.py +259 -0
- utterplan-0.5.0/utterplan/toml_codec.py +100 -0
- utterplan-0.5.0/utterplan/trace_codec.py +137 -0
- utterplan-0.5.0/utterplan/versioning.py +11 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan.egg-info/PKG-INFO +42 -29
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan.egg-info/SOURCES.txt +15 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan.egg-info/scm_file_list.json +38 -0
- utterplan-0.5.0/utterplan.egg-info/scm_version.json +8 -0
- utterplan-0.4.0/docs/architecture.md +0 -110
- utterplan-0.4.0/docs/consumer-guide.md +0 -149
- utterplan-0.4.0/docs/coordinate-spaces.md +0 -16
- utterplan-0.4.0/docs/debugging.md +0 -31
- utterplan-0.4.0/docs/format.md +0 -39
- utterplan-0.4.0/docs/pykokoro-integration.md +0 -63
- utterplan-0.4.0/tests/fixtures/canonical_consumer_contract.expected.toml +0 -6
- utterplan-0.4.0/tests/migration/test_legacy_json_import.py +0 -29
- utterplan-0.4.0/tests/test_consumer_contract.py +0 -313
- utterplan-0.4.0/tests/test_explain.py +0 -180
- utterplan-0.4.0/tests/test_fake_renderer.py +0 -72
- utterplan-0.4.0/tests/test_format.py +0 -114
- utterplan-0.4.0/tests/test_golden.py +0 -64
- utterplan-0.4.0/tests/test_pauses.py +0 -212
- utterplan-0.4.0/tests/test_schema_registry.py +0 -54
- utterplan-0.4.0/tests/test_toml_format.py +0 -179
- utterplan-0.4.0/utterplan/cli.py +0 -656
- utterplan-0.4.0/utterplan/format.py +0 -46
- utterplan-0.4.0/utterplan/pauses.py +0 -76
- utterplan-0.4.0/utterplan/serialization.py +0 -32
- utterplan-0.4.0/utterplan/versioning.py +0 -8
- utterplan-0.4.0/utterplan.egg-info/scm_version.json +0 -8
- {utterplan-0.4.0 → utterplan-0.5.0}/.codecrate.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/.github/workflows/codecov.yml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/.github/workflows/pre-commit.yml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/.github/workflows/python-publish.yml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/.gitignore +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/.pre-commit-config.yaml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/LICENSE +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/MANIFEST.in +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/NOTICE +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/Makefile +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/conf.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/make.bat +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/phase-a-completion.md +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/docs/requirements.txt +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/examples/basic.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/examples/chapter.ssmd +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/examples/ssmd_example.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/pyproject.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/setup.cfg +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/spec/schemas/v1.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/spec/schemas/v2.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/spec/schemas/v3.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/spec/schemas/v4.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/spec/utterplan.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/__init__.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/fixtures/canonical_consumer_contract.ssmd +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/fixtures/ssmd_09_comprehensive.ssmd +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/golden/basic_en.utterplan.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/golden/directives.utterplan.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/golden/markers.utterplan.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/golden/multilingual.utterplan.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/golden/parenthetical.utterplan.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/golden/spokenform_offsets.utterplan.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/golden/ssmd_09_comprehensive.utterplan.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/golden/ssmd_breaks.utterplan.toml +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/__init__.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/cases.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/fixtures/v4/basic_en.utterplan.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/fixtures/v4/directives.utterplan.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/fixtures/v4/markers.utterplan.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/fixtures/v4/multilingual.utterplan.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/fixtures/v4/parenthetical.utterplan.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/fixtures/v4/spokenform_offsets.utterplan.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/fixtures/v4/ssmd_09_comprehensive.utterplan.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/fixtures/v4/ssmd_breaks.utterplan.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/goldens/multilingual_preparation.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/goldens/spokenform_numbers.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/goldens/ssmd_break.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/goldens/ssmd_language_detection.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/goldens/ssmd_marker.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/migration/goldens/ssmd_pronunciation.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/README.md +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v1/basic.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v1/directives.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v1/markers.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v1/multilingual.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v1/parenthetical.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v1/spokenform_offsets.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v1/ssmd_breaks.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v2/directives.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v3/multilingual.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/schema_history/v3/ssmd_09_comprehensive.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_atomic_io.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_import_boundaries.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_language.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/tests/test_version.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/__main__.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/atomic_io.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/diagnostics.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/directives.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/exceptions.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/language.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/linguistics.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/migrations/registry.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/migrations/v1_to_v2.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/migrations/v2_to_v3.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/migrations/v3_to_v4.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/progress.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/py.typed +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/schemas/v1.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/schemas/v2.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/schemas/v3.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/schemas/v4.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/spacy_models.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/spans.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/stages/__init__.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/stages/document/__init__.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/stages/document/plain.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/stages/document/ssmd.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/stages/preparation/__init__.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/stages/preparation/identity.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/stages/preparation/spokenform.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/stages/protocols.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/units.py +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan/utterplan.schema.json +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan.egg-info/dependency_links.txt +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan.egg-info/entry_points.txt +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan.egg-info/requires.txt +0 -0
- {utterplan-0.4.0 → utterplan-0.5.0}/utterplan.egg-info/top_level.txt +0 -0
|
@@ -53,6 +53,8 @@ jobs:
|
|
|
53
53
|
"typing_extensions==4.0.0" \
|
|
54
54
|
"tomlkit==0.13.0"
|
|
55
55
|
python -m pip install --no-deps -e .
|
|
56
|
+
- name: Verify SSMD 0.9.3 front-matter scene-break handling
|
|
57
|
+
run: python -m pytest -q tests/test_ssmd_09_parser.py -k front_matter_scene_break
|
|
56
58
|
- name: Run lower-bound tests
|
|
57
59
|
run: python -m pytest -q
|
|
58
60
|
|
|
@@ -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.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
|
|
@@ -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,17 +284,43 @@ 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
|
|
316
|
+
utterplan inspect-attempt chapter.attempt.toml --issues
|
|
296
317
|
```
|
|
297
318
|
|
|
298
|
-
`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.
|
|
320
|
+
|
|
321
|
+
`inspect-attempt` reads the separate `utterplan.planning-attempt.v1` TOML artifact,
|
|
322
|
+
not a canonical plan. Use it to review renderability issues and safe repair
|
|
323
|
+
assessments on blocked planning outcomes; such candidates remain inspect-only drafts.
|
|
299
324
|
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.
|
|
300
325
|
|
|
301
326
|
## SSMD source contract
|
|
@@ -313,11 +338,11 @@ ssmd migrate old.ssmd --to 0.9
|
|
|
313
338
|
```
|
|
314
339
|
|
|
315
340
|
`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: `
|
|
341
|
+
Normal plan loading is TOML-only: `FlowPlan.load()` and plan-inspection commands reject JSON rather than auto-detecting it.
|
|
317
342
|
|
|
318
343
|
## Planning defaults
|
|
319
344
|
|
|
320
|
-
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.
|
|
321
346
|
|
|
322
347
|
Python `PlannerConfig` defaults to `document_format="plain"`; set it to `"ssmd"` when a Python string contains SSMD source.
|
|
323
348
|
|
|
@@ -328,7 +353,7 @@ Python `PlannerConfig.renderability_mode` also defaults to safe punctuation-only
|
|
|
328
353
|
## Python API
|
|
329
354
|
|
|
330
355
|
```python
|
|
331
|
-
from utterplan import PlannerConfig,
|
|
356
|
+
from utterplan import PlannerConfig, FlowPlan, compile_document
|
|
332
357
|
|
|
333
358
|
ssmd_source = """---
|
|
334
359
|
ssmd_version: "0.9"
|
|
@@ -345,7 +370,7 @@ result = compile_document(
|
|
|
345
370
|
plan = result.plan
|
|
346
371
|
assert result.trace is not None
|
|
347
372
|
plan.save("example.utterplan.toml")
|
|
348
|
-
assert
|
|
373
|
+
assert FlowPlan.load("example.utterplan.toml") == plan
|
|
349
374
|
```
|
|
350
375
|
|
|
351
376
|
`compile_document` is the stable public one-document API shared by consumers. The
|
|
@@ -373,21 +398,9 @@ Callbacks run synchronously and exceptions propagate. See the [Python API guide]
|
|
|
373
398
|
|
|
374
399
|
## Renderer-consumer boundary
|
|
375
400
|
|
|
376
|
-
Renderers consume `
|
|
377
|
-
`spoken_start`/`spoken_end` for spoken-text coordinates. Resolved segment
|
|
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
|
|
383
|
-
tokens, model sessions, renderer configuration, provider documents, or audio.
|
|
384
|
-
For SSMD input, `plan.annotations` preserve declared source semantics and source
|
|
385
|
-
provenance, `document_metadata` preserves portable header data, and
|
|
386
|
-
`segment.directives` carries effective typed semantics after scope and voice-default
|
|
387
|
-
resolution. Typed directives include voice, pronunciation, prosody, emphasis, say-as,
|
|
388
|
-
substitution, audio references, and extension references. Audio and extensions are
|
|
389
|
-
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.
|
|
390
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.
|
|
391
404
|
The intended dependency direction is:
|
|
392
405
|
|
|
393
406
|
```text
|
|
@@ -402,6 +415,7 @@ renderer repository rather than UtterPlan's test suite.
|
|
|
402
415
|
|
|
403
416
|
- [Getting started](docs/getting-started.md)
|
|
404
417
|
- [CLI](docs/cli.md)
|
|
418
|
+
- [SSMDBook workflows](docs/ssmdbook.md)
|
|
405
419
|
- [Format and schema](docs/format.md)
|
|
406
420
|
- [Consumer guide](docs/consumer-guide.md)
|
|
407
421
|
- [Architecture](docs/architecture.md)
|
|
@@ -413,10 +427,9 @@ renderer repository rather than UtterPlan's test suite.
|
|
|
413
427
|
|
|
414
428
|
## Versions
|
|
415
429
|
|
|
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
|
|
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.
|
|
417
431
|
|
|
418
|
-
Schema
|
|
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.
|
|
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.
|
|
420
433
|
|
|
421
434
|
## Development
|
|
422
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,17 +41,43 @@ 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
|
|
73
|
+
utterplan inspect-attempt chapter.attempt.toml --issues
|
|
53
74
|
```
|
|
54
75
|
|
|
55
|
-
`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.
|
|
77
|
+
|
|
78
|
+
`inspect-attempt` reads the separate `utterplan.planning-attempt.v1` TOML artifact,
|
|
79
|
+
not a canonical plan. Use it to review renderability issues and safe repair
|
|
80
|
+
assessments on blocked planning outcomes; such candidates remain inspect-only drafts.
|
|
56
81
|
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.
|
|
57
82
|
|
|
58
83
|
## SSMD source contract
|
|
@@ -70,11 +95,11 @@ ssmd migrate old.ssmd --to 0.9
|
|
|
70
95
|
```
|
|
71
96
|
|
|
72
97
|
`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: `
|
|
98
|
+
Normal plan loading is TOML-only: `FlowPlan.load()` and plan-inspection commands reject JSON rather than auto-detecting it.
|
|
74
99
|
|
|
75
100
|
## Planning defaults
|
|
76
101
|
|
|
77
|
-
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.
|
|
78
103
|
|
|
79
104
|
Python `PlannerConfig` defaults to `document_format="plain"`; set it to `"ssmd"` when a Python string contains SSMD source.
|
|
80
105
|
|
|
@@ -85,7 +110,7 @@ Python `PlannerConfig.renderability_mode` also defaults to safe punctuation-only
|
|
|
85
110
|
## Python API
|
|
86
111
|
|
|
87
112
|
```python
|
|
88
|
-
from utterplan import PlannerConfig,
|
|
113
|
+
from utterplan import PlannerConfig, FlowPlan, compile_document
|
|
89
114
|
|
|
90
115
|
ssmd_source = """---
|
|
91
116
|
ssmd_version: "0.9"
|
|
@@ -102,7 +127,7 @@ result = compile_document(
|
|
|
102
127
|
plan = result.plan
|
|
103
128
|
assert result.trace is not None
|
|
104
129
|
plan.save("example.utterplan.toml")
|
|
105
|
-
assert
|
|
130
|
+
assert FlowPlan.load("example.utterplan.toml") == plan
|
|
106
131
|
```
|
|
107
132
|
|
|
108
133
|
`compile_document` is the stable public one-document API shared by consumers. The
|
|
@@ -130,21 +155,9 @@ Callbacks run synchronously and exceptions propagate. See the [Python API guide]
|
|
|
130
155
|
|
|
131
156
|
## Renderer-consumer boundary
|
|
132
157
|
|
|
133
|
-
Renderers consume `
|
|
134
|
-
`spoken_start`/`spoken_end` for spoken-text coordinates. Resolved segment
|
|
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
|
|
140
|
-
tokens, model sessions, renderer configuration, provider documents, or audio.
|
|
141
|
-
For SSMD input, `plan.annotations` preserve declared source semantics and source
|
|
142
|
-
provenance, `document_metadata` preserves portable header data, and
|
|
143
|
-
`segment.directives` carries effective typed semantics after scope and voice-default
|
|
144
|
-
resolution. Typed directives include voice, pronunciation, prosody, emphasis, say-as,
|
|
145
|
-
substitution, audio references, and extension references. Audio and extensions are
|
|
146
|
-
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.
|
|
147
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.
|
|
148
161
|
The intended dependency direction is:
|
|
149
162
|
|
|
150
163
|
```text
|
|
@@ -159,6 +172,7 @@ renderer repository rather than UtterPlan's test suite.
|
|
|
159
172
|
|
|
160
173
|
- [Getting started](docs/getting-started.md)
|
|
161
174
|
- [CLI](docs/cli.md)
|
|
175
|
+
- [SSMDBook workflows](docs/ssmdbook.md)
|
|
162
176
|
- [Format and schema](docs/format.md)
|
|
163
177
|
- [Consumer guide](docs/consumer-guide.md)
|
|
164
178
|
- [Architecture](docs/architecture.md)
|
|
@@ -170,10 +184,9 @@ renderer repository rather than UtterPlan's test suite.
|
|
|
170
184
|
|
|
171
185
|
## Versions
|
|
172
186
|
|
|
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
|
|
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.
|
|
174
188
|
|
|
175
|
-
Schema
|
|
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.
|
|
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.
|
|
177
190
|
|
|
178
191
|
## Development
|
|
179
192
|
|
|
@@ -0,0 +1,63 @@
|
|
|
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
|
+
## SSMD and preparation
|
|
32
|
+
|
|
33
|
+
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.
|
|
34
|
+
|
|
35
|
+
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.
|
|
36
|
+
|
|
37
|
+
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).
|
|
38
|
+
|
|
39
|
+
## Pause and directive semantics
|
|
40
|
+
|
|
41
|
+
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.
|
|
42
|
+
|
|
43
|
+
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.
|
|
44
|
+
|
|
45
|
+
## Identity and determinism
|
|
46
|
+
|
|
47
|
+
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`.
|
|
48
|
+
|
|
49
|
+
## Persistence compatibility boundary
|
|
50
|
+
|
|
51
|
+
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.
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
current plan:
|
|
55
|
+
.utterplan.toml -- TOML decode / schema-v5 validation --> FlowPlan --> consumer
|
|
56
|
+
|
|
57
|
+
legacy saved plan:
|
|
58
|
+
.utterplan.json -- explicit `utterplan migrate` --> current .utterplan.toml
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
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.
|
|
62
|
+
|
|
63
|
+
`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,38 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.5.0] - 2026-10-09
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added compile-book for selecting and compiling SSMDBook chapters into independent v5 plans with operational reports
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **BREAKING:** Changed plan persistence to schema v5 with deterministic TOML, sequential legacy migration, and optional trace sidecars
|
|
16
|
+
|
|
17
|
+
<!-- generated by releaseledger -->
|
|
18
|
+
|
|
19
|
+
## [0.4.1] - 2026-10-07
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Added persistable planning attempts with inspectable renderability outcomes and safe repair assessments
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Changed planning APIs to expose blocked candidates without weakening canonical plan validation
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Fixed legacy SSMD scene breaks to preserve front-matter boundaries and clean-to-source offsets
|
|
32
|
+
|
|
33
|
+
### Documentation
|
|
34
|
+
|
|
35
|
+
- Documented planning-attempt artifacts, inspection workflows, and renderability guarantees
|
|
36
|
+
|
|
37
|
+
<!-- generated by releaseledger -->
|
|
38
|
+
|
|
7
39
|
## [0.4.0] - 2026-10-06
|
|
8
40
|
|
|
9
41
|
### 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,25 @@ 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`.
|
|
129
|
+
|
|
130
|
+
## Inspect a persisted planning attempt
|
|
131
|
+
|
|
132
|
+
`inspect` reads canonical plans. Persistable planning outcomes use the separate
|
|
133
|
+
`utterplan.planning-attempt.v1` artifact and are opened with `inspect-attempt`:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
utterplan inspect-attempt chapter.attempt.toml
|
|
137
|
+
utterplan inspect-attempt chapter.attempt.toml --issues
|
|
138
|
+
utterplan inspect-attempt chapter.attempt.toml --segment seg-000001 --unit unit-000001
|
|
139
|
+
utterplan inspect-attempt chapter.attempt.toml --json
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The default view summarizes status, renderability, and candidate size. `--issues`
|
|
143
|
+
shows source context and conservative repair assessments; segment and unit selectors
|
|
144
|
+
accept an ID or zero-based index. `--json` emits the complete artifact as JSON for
|
|
145
|
+
inspection, but the persisted attempt itself remains TOML. A blocked candidate is an
|
|
146
|
+
inspect-only draft, not a canonical plan, and is rejected by `FlowPlan.load()`.
|
|
102
147
|
|
|
103
148
|
## Planning controls
|
|
104
149
|
|
|
@@ -124,11 +169,13 @@ utterplan validate chapter.ssmd.md
|
|
|
124
169
|
utterplan validate plain.txt --input-format plain --language en-us
|
|
125
170
|
utterplan inspect chapter.utterplan.toml --segment 0
|
|
126
171
|
utterplan inspect chapter.utterplan.toml --unit 0 --boundaries --tokens
|
|
127
|
-
utterplan
|
|
128
|
-
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
|
|
175
|
+
utterplan inspect-attempt chapter.attempt.toml --issues
|
|
129
176
|
```
|
|
130
177
|
|
|
131
|
-
`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.
|
|
132
179
|
|
|
133
180
|
## Migrate a saved plan
|
|
134
181
|
|
|
@@ -148,11 +195,7 @@ route and reports source schema, target schema, and whether migration is require
|
|
|
148
195
|
without writing a file. A future schema version is rejected rather than guessed
|
|
149
196
|
or downgraded.
|
|
150
197
|
|
|
151
|
-
Schema migration is
|
|
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.
|
|
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.
|
|
156
199
|
|
|
157
200
|
For a saved TOML plan, `validate` verifies the current semantic schema and plan
|
|
158
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.
|