# Output Contract v1 Single source of truth for TranscriptX analysis **output layout**, naming, manifest schemas, and speaker-exclusion rules. Implementation: `output_standards.py`, `manifest_builder.py`, `run_manifest.py`, `run_schema.py`. Authority boundary: - This contract defines **what files and directories exist after a run** and how they are named and organized. - It also defines the **JSON structure** for manifests and related output files. - It does **not** define success/failure or run/module statuses, nor any truth about whether a run \"succeeded\" or \"failed\"; those are owned exclusively by `docs/run_outcome_contract.md`. ## 1. Directory layout - **Root:** `TRANSCRIPTX_OUTPUT_DIR` (default `{DATA_DIR}/outputs`). - **Run root:** `outputs///` where: - `slug` is the human-friendly folder name from the slug manager (derived from transcript identity). - `run_id` is `YYYYMMDD_HHMMSS_<8-char-uuid>` (or overridden via `RunManifestInput.run_id`). - **Per run:** At run root: - `manifest.json` — artifact index (see §4). - `run_results.json` — run summary (schema in `run_schema.RunResultsSummary`). - `report.json` / `report.md` / `report.txt` — run-level report projections generated by supported reporting modules (when enabled in the run profile). - `.transcriptx/manifest.json` — run manifest for reproducibility (`manifest_type: "run_manifest"`). - `.transcriptx/run_config_effective.json` — effective config snapshot. - **Per module:** `//` with standard subdirs: - `data/global/` — global (all-speaker) data files. - `data/speakers/` — per-speaker data (when applicable). - `charts/` (or `charts/global/`, `charts/speakers/`) — chart outputs. - **Versioned namespaces:** Modules that need a stable contract use `///` (e.g. `voice/v1/`). See `ModuleInfo.output_namespace` and `output_version`. ## 2. Naming rules - **Canonical base name:** From `_path_core.get_canonical_base_name(transcript_path)` (used for run dir and file prefixes). - **File prefixes:** Module artifacts use the canonical base name where applicable; e.g. `{base_name}_{module}_{descriptor}.{ext}` or as defined by `create_standard_output_structure()` and helpers in `output_standards.py`. - **Manifest and run summary:** `manifest.json` and `run_results.json` at run root only. ## 3. Required artifacts and scope - **Per-module:** Modules use `create_standard_output_structure()` and the helpers (`save_global_data`, `save_speaker_data`, `save_global_chart`, etc.) so paths stay consistent. - **Global vs per-speaker:** Unidentified speakers (e.g. `SPEAKER_00`) are excluded from per-speaker outputs when `exclude_unidentified_from_speaker_charts` (or equivalent) is true. Exceptions: transcript/CSV output and NER include all speakers. - **NER:** May use a distinct path for entity maps (e.g. `ner/maps/` or `ner/{base}_ner-entities.json`); see module implementation. ## 4. Manifest schemas ### 4.1 Artifact manifest (`manifest.json` at run root) - **Discriminator:** `manifest_type: "artifact_manifest"` (required in new manifests; backward compat accepts missing as artifact). - **Required keys:** `schema_version`, `run_id`, `run_metadata`, `artifacts`. - **run_metadata:** Includes `transcript_key`, `modules_enabled`, `version_hash`, `config_effective_path`, `config_hash`, `config_schema_version`, `config_source`. - **artifacts:** List of entries with `id`, `kind`, `rel_path`, `mime`, `tags`; optional `module`, `scope`, `speaker`. Load via `load_artifact_manifest(path)`; do not raw `json.load()` and guess type. ### 4.2 Run manifest (`.transcriptx/manifest.json`) - **Discriminator:** `manifest_type: "run_manifest"`. - Used for reproducibility. Load via `load_run_manifest(path)`. ### 4.3 Run results (`run_results.json`) - **Current:** `schema_version: 1` — includes `module_outcomes` (canonical execution rows) and `modules_skipped[]` entries with optional `execution_status` (`skipped` \| `blocked`). Pre-epoch `schema_version` values are refused; strict loaders use `transcriptx.core.pipeline.module_outcomes.assert_run_results_schema_supported`. - **Typed load path:** `transcriptx.core.pipeline.manifest_loader.load_run_results` rejects non-epoch-1 `schema_version` via `assert_run_results_schema_supported` **before** applying any default-filling for missing keys. Use that loader (or `load_run_outcome_context`) rather than raw `json.load` for truth-path consumption. - **Semantics:** Placement and schema shape for `run_results.json` live here; status meanings, precedence, and truth rules live in `docs/run_outcome_contract.md`. ## 5. Speaker exclusion (unidentified) - **Default:** Unidentified speakers (e.g. `SPEAKER_00`) are excluded from per-speaker charts and per-speaker data when config says so (`analysis.exclude_unidentified_from_speaker_charts` or equivalent). - **Included:** Transcript output, CSV export, and NER entity lists include all speakers (including unidentified). - **Predicate:** `is_named_speaker()` in `text_utils` (or equivalent) determines eligibility for per-speaker outputs. ## 6. Schema stamps (transcript JSON) - **Speaker mapping:** After any mapping write, transcript JSON must include: - `speaker_map_schema_version` (integer `1`). - `speaker_map_provenance` (tool, version, timestamp, method) when written via `SpeakerMappingService` / `TranscriptStore`. ## 7. Exceptions and versioning - **NER:** Path variance allowed for entity maps; see NER module. - **Voice:** Versioned namespace `voice/v1/` (and possible `voice/v2/` later). - **Stability (v0.41+):** Do not rename output folders or top-level layout without versioning. Prefer versioned namespaces for new layouts. --- ## Contract violations This section describes **output contract violations** related to layout and manifest structure. Execution truth and run outcome semantics remain the responsibility of `docs/run_outcome_contract.md`. - **Invalid states (examples)**: - `manifest.json` entries whose `rel_path` does not exist on disk or lives outside the expected run root. - Artifacts written to ad hoc paths that do not follow the standard layout, versioned namespaces, or naming rules in this contract. - Multiple artifacts that claim the same identity or path in ways that conflict with manifest uniqueness assumptions. - `run_results.json` present at locations other than the run root, or missing entirely when other run artifacts exist. - **Detection**: - Loaders and helpers that validate manifest schemas and run directory layout. - Tests that assert that module outputs are registered in `manifest.json` with consistent `rel_path`, `kind`, and `mime` fields. - Sanity checks that the run root contains exactly one `manifest.json` and one `run_results.json`. - **Expected behavior**: - Violations are treated as **fail-fast** for contract-aware tools: reject invalid manifests or layouts, log clear errors, and avoid guessing about artifact meaning. - Where possible, maintenance tools may offer **migration or cleanup commands** that repair outdated layouts, but they must not silently reinterpret invalid structures as valid. --- *This document supersedes `output_conventions.md` as the authority for output layout and contracts. Keep `output_conventions.md` for backward reference or redirect to this file.*