Analysis result¶
Durable envelope for a single module’s published or historical analysis run. Storage/publish rules: analysis-run-storage.md. Input document: analysis-document.md. Eligibility: notebook-eligibility.md.
Ports supply payloads only. They must not invent alternate envelope shapes, identity fields, or outcome enums — adapters wrap core outputs in this contract.
Identity¶
formatmust be"transcribe.analysis-result"schema_versionmust be1Unsupported
schema_version→ refuse
This envelope schema is frozen before module ports land. Payload schemas may evolve per module behind module_id + module_version; the envelope does not.
Envelope (v1) — required fields¶
Every durable envelope binds:
Field |
Required |
Notes |
|---|---|---|
|
yes |
|
|
yes |
|
|
yes |
Canonical id from |
|
yes |
Analysis module identity |
|
yes |
Transcribe module version / code fingerprint |
|
yes |
Full identity per analysis-run-storage.md |
|
yes |
Input document fingerprint from analysis-document.md (also inside cache identity) |
|
yes |
Execution lifecycle |
|
yes |
Terminal semantic result (when attempt finished cleanly enough to conclude) |
|
yes |
UI/runtime capability presentation (below) |
|
yes |
Object with required provenance fields (below) |
|
yes |
Array (may be empty) of |
|
yes |
Array (may be empty) of |
|
yes |
Canonical subset of module configuration |
|
yes |
Module-specific object; empty object allowed for non-success terminals |
Optional when applicable:
Field |
Notes |
|---|---|
|
Package/lexicon/model identities |
|
When a model was resolved |
|
Prompt/template version, generation settings, grounding strategy, question text, chunking policy id |
|
Array of evidence objects (below) when the payload cites notebook text |
|
|
Attempt state vs result outcome¶
These are separate axes. Do not conflate them.
Concept |
Values |
Meaning |
|---|---|---|
Attempt state |
|
Whether execution finished cleanly |
Result outcome |
|
What the module concluded |
Attempt lifecycle aligns with page-result.md: when the project mutation lock is free, abandoned running attempts reconcile to interrupted. Reconciliation updates attempt history only — it does not clear or overwrite a prior published reusable result (see analysis-run-storage).
Committed reusable artifact¶
A published reusable artifact for (project_id, module_id) may be written or updated only when all of:
attempt_state == succeededoutcome ∈ {success, skipped_not_applicable, unavailable_dependency, insufficient_data}Envelope includes matching
cache_identityand bindingproject_id
Outcome |
Durable attempt/history |
Cacheable terminal (skip rerun when identity matches) |
May become published reusable |
|---|---|---|---|
|
yes |
yes |
yes (with attempt |
|
yes |
yes |
yes |
|
yes |
yes |
yes |
|
yes |
yes |
yes |
|
yes (history) |
no |
no |
Publication / non-clobber¶
Attempt states
running,failed,cancelled, andinterruptedmust never replace the last published reusable artifactDistinguish attempt history (retained runs) from current published result (single reusable pointer per module under the project)
Only
attempt_state == succeededcombined with a cacheable terminal outcome may update the published pointer
Capability presentation (UI / optional deps)¶
capability is the sole vocabulary for UI and runtime gating of optional dependencies. It is derived from outcome + reason; UIs must not invent parallel enums.
|
Meaning |
Typical |
|---|---|---|
|
Module can run or has a reusable success |
|
|
Completed with usable payload |
|
|
Completed with intentionally incomplete payload; warnings explain gaps |
|
|
Optional Python/extra package not installed (e.g. BERTopic) |
|
|
Required local model/runtime missing (e.g. Ollama model, transformer weights) |
|
|
Policy/corpus gate skipped the module without error (e.g. zero eligible units after |
|
|
Document failed validation before the core ran |
|
|
Valid document but too little / wrong-shaped corpus for the algorithm |
|
|
Hard parent missing, mismatched, or non-acceptable outcome |
|
|
Execution error |
|
Optional BERTopic, transformer emotion, embeddings, and Ollama must degrade to a named capability above — never tracebacks to the UI, never ambiguous empty success payloads that look like “no findings”.
Provenance¶
Not "TranscriptX 1.x / <module>" alone. Required fields under provenance:
Field |
Notes |
|---|---|
|
Source repository identity |
|
Concrete upstream commit (or tag that resolves to commit) used for the copied core |
|
Upstream module id |
|
|
|
Transcribe module version |
|
Adapter version that built the |
|
Application version |
|
|
|
Short string when not pure parity |
Pin registry process: …/dev/analysis_port_pins.md. The commit recorded here must match the pin row so later TX diffs are reproducible.
External analytical dependencies¶
Model, lexicon, and package identities that affect reproducibility belong in provenance and in cache identity even when they are not rows in the TX pin registry:
package name + version (or equivalent lock)
lexicon id + version
model name + resolved digest where applicable
optional-extra identity (e.g. bertopic stack)
Semantic class guidance¶
Class |
Use when |
|---|---|
|
Behaviour expected to match TX on shared fixture shapes |
|
Speaker assumptions removed, eligibility policy substituted, chronology via order/date |
|
Algorithmic replacement (e.g. |
Evidence (renderable citations)¶
Evidence must include enough information to render and validate the cited passage — not merely an opaque page back-pointer.
Each evidence item:
Field |
Required |
Notes |
|---|---|---|
|
yes |
Must exist in the input document used for this |
|
when citing a span |
Unit-local half-open offsets per analysis-document.md |
|
yes when displaying text |
Exact substring from the cited unit/page text at record time |
|
yes |
Fingerprint of the document the quote was taken from |
|
yes |
Validated page or page_span form for navigation |
source_ref alone is insufficient when spans exist. Parent artifact refs must include parent module_id, parent cache_identity, and parent outcome.
Stale citations after text edits¶
Evidence is valid only while
evidence[].content_fingerprintequals the current analysis document fingerprint for the samesplit_profile/granularity_versionAfter edit / reorder / include-exclude / splitter change, stale evidence must not be displayed against newer text (UI shows unavailable/stale — does not highlight mismatched offsets)
Reuse of a published result after identity change is already forbidden by cache identity; open views must re-resolve evidence before render
Corpus-size and edge-case degradation¶
Map to named outcomes, not uncaught exceptions. Refusal vs empty-success is contract-owned:
Situation |
Outcome / capability |
|---|---|
Zero units / empty notebook after omission of blank/excluded pages |
|
Zero eligible units after |
|
One unit where module requires multi-unit corpus (e.g. topic shift, similarity matrix) |
|
Single-unit topic modelling |
|
Tiny vocabulary / no tokens for a lexical metric |
Prefer |
Very short pages only |
Follow eligibility when required; otherwise module notes + table below |
All-blank OCR (all pages omitted) |
|
NER finds no entities |
|
Consumer needs entities/topics and parent payload is empty |
|
Optional extra missing (BERTopic, embeddings package, transformer extra) |
|
Ollama or model weights missing |
|
Model/algorithm requires more samples than available |
|
Execution exception / crash |
attempt |
Minimum-input defaults (core set)¶
Shared 1.1 tokenizer for lexical metrics unless a module documents otherwise: maximal runs matching TX TOKEN_RE (letters with optional internal '/’/-); casefold for types; sentence splits on .?! followed by whitespace or EOS.
Float metrics in canonical payloads round to 6 decimal places for goldens.
wordclouds baseline (wordclouds_tokens_v1 / wordclouds_payload_v1)¶
Normative for wordclouds baseline mode (enrichment_mode: "baseline"). Sole analytical input is AnalysisDocument.text (never units[] tokenization).
Rule |
Policy |
|---|---|
Base tokens |
Shared 1.1 |
Stopwords |
Pinned list id |
Stem/lemma |
None |
Numbers / punctuation |
Not tokens (except internal apostrophe/hyphen inside |
Eligible token |
Survives tokenize + stopword filter |
Success payload |
|
Zero eligible tokens |
Non-empty |
Enrichment |
Baseline never consumes optional parent |
Compatibility is judged on analytical payload semantics; rendered pixels / PNG bit identity are non-contractual.
Module |
|
|
Notes |
|---|---|---|---|
|
zero emitted units |
≥1 unit |
zero sub-metric counts allowed |
|
|
|
MTLD only if |
|
|
otherwise |
non-finite scores → |
|
empty document or zero eligible tokens after |
≥1 eligible token |
baseline only in wordclouds baseline mode; see section above |
|
empty document |
possibly empty labels |
|
|
parents / empty join |
per parents |
hard parents |
|
eligibility / algorithm mins |
Language foundations payloads¶
Module |
Payload id |
Notes |
|---|---|---|
|
|
|
|
|
Per-unit |
|
|
Lexicon |
Chronology for sentiment/NER timelines uses unit order (+ optional date). Do not invent wall-clock timestamps. Language foundations modules are ungated relative to notebook_eligibility_v1.
Topics & similarity payloads¶
Module |
Payload id |
Notes |
|---|---|---|
|
|
Eligibility required; seed-bucket topics; baseline ignores optional |
|
|
Ungated; BoW TF-IDF cosine |
|
|
Ungated; consecutive cosine drops vs unit |
|
|
Eligibility required; optional extra — missing/unconfigured → |
Module |
|
|
Notes |
|---|---|---|---|
|
|
≥2 units |
|
|
empty document |
ranked list (maybe length 1) |
|
LLM suite |
empty / unavailable model |
abstain rules |
see LLM section |
Emotion & salience payloads¶
Module |
Payload id |
Notes |
|---|---|---|
|
|
Ungated; lexicon |
|
|
Neighbor window by |
|
|
Optional transformer extra → |
|
|
Hard parents |
|
|
Salience fork (no momentum); optional soft |
LLM evidence, cache identity contribution, and refusal¶
Applies to llm_summary, llm_action_items, llm_custom_qa, narrative_summary:
Unsupported answers abstain — do not fabricate citations or evidence
Evidence must resolve to current compatible units/spans under the current content fingerprint and split profile
Stale evidence after relevant text or splitting changes is not reusable
Bounded input: deterministic chunking / section aggregation; forbid dumping an unbounded whole-notebook string when it exceeds the configured max context policy (policy id is part of cache identity)
Frozen LLM policy ids:
chunking_policy_id:notebook_chunks_units_v1(pack units byorderup to a token budget; oversized units are deterministically sub-split with span provenance; never silently truncated)reduction_policy_id:notebook_map_reduce_v1(bound total prompt context; map/reduce when chunks exceed total budget)grounding_strategy_id:ground_doc_chunks_v1(document chunks) orground_highlights_summary_v1(narrative_summary)
Cache identity must include (via analysis-run-storage
llmobject): resolved model digest, prompt/template version, generation settings, grounding strategy id, question text when applicable, input/dependency identities, chunking policy idRecorded test doubles must exercise the same result validation and abstention path as live Ollama (no separate “stub success” shape)
Synthesis & LLM payloads¶
Module |
Payload id |
Notes |
|---|---|---|
|
|
Eligibility required |
|
|
Hard parents |
|
|
Eligibility required; seed-bucket topics (see topics & similarity) |
|
|
See topics & similarity |
|
|
See topics & similarity |
|
|
See topics & similarity |
|
|
Eligibility; prefer |
|
|
Hard parent |
|
|
Hard parents |
|
|
Optional Ollama; |
|
|
Optional Ollama |
|
|
Grounded |
|
|
Hard parent |
Derived Analyse health (non-durable)¶
AnalysisHealth is computed for UI surfaces from published envelopes + planned cache identities + notebook content_revision. It is not a persisted authority; publish authority remains published.json + cache identity.
Field |
Notes |
|---|---|
|
Notebook content identity (project-on-disk.md) |
|
Per-module |
|
|
|
Optional batch coordinator status |
Aggregate order: running → interrupted → any stale → all unavailable/missing → any failed → any degraded capability (unavailable_* / insufficient_data / skipped_not_applicable) → healthy.
Overview / Themes / Mood / Moments / Summaries must answer “is this current and healthy?” from this shared derivation (or a scope of it). Ask notebook is ad-hoc and does not update batch health.