From a3c15b249e4552fd0941dedda83c8446632b0a01 Mon Sep 17 00:00:00 2001 From: grok Date: Sun, 16 Aug 2026 12:11:13 +0000 Subject: [PATCH 01/22] [grok/vc-implement] feat: Voice Lab as a Codescribe website module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stacked on #77. Teacher + Seal Atlas live at /voice/lab — same teach() triangle as codescribe-teacher, idle until Run; Atlas HTML loads only on demand. Corpus writes Seal Atlas as the quality-report surface. Authored-By: grok --- CHANGELOG.md | 14 + bin/codescribe-corpus.rs | 28 +- core/quality/engine_contract.rs | 89 +++- core/quality/mod.rs | 5 +- core/quality/seal_atlas_html.rs | 180 ++++++++ docs/THE_ENGINE_CONTRACT.md | 3 + docs/quality-reports/CONTRACT.md | 93 ++++ site/package.json | 3 +- .../public/voice/atlas/seal-atlas.take01.html | 158 +++++++ .../voice/atlas/the-engine.contract.html | 58 +++ site/src/components/Footer.astro | 1 + site/src/components/Nav.astro | 32 +- site/src/lib/teacher/teach.test.ts | 47 ++ site/src/lib/teacher/teach.ts | 312 +++++++++++++ site/src/pages/voice/lab.astro | 409 ++++++++++++++++++ 15 files changed, 1418 insertions(+), 14 deletions(-) create mode 100644 core/quality/seal_atlas_html.rs create mode 100644 docs/quality-reports/CONTRACT.md create mode 100644 site/public/voice/atlas/seal-atlas.take01.html create mode 100644 site/public/voice/atlas/the-engine.contract.html create mode 100644 site/src/lib/teacher/teach.test.ts create mode 100644 site/src/lib/teacher/teach.ts create mode 100644 site/src/pages/voice/lab.astro diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b7bdb86..a8f67913 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- **Voice Lab on the website** (`/voice/lab`). Teacher + Seal Atlas as a + Codescribe module, not a sidecar: same `teach()` triangle as + `codescribe-teacher`, idle until Run; Atlas HTML loads only on demand. + +### Changed + +- **Quality HTML is Seal Atlas.** `codescribe-corpus` writes + `quality/seal-atlas.{profile}.html` as the report (handshake in + `docs/quality-reports/CONTRACT.md`). Qube scores move to + `quality/qube.{profile}.html` and stay a footnote. Gold take 01 remains + `docs/quality-reports/seal-atlas.take01.html`. + ## [0.13.3] - 2026-08-13 > The agent-stability and STT-truth-layer wave: one dictation pipeline with an diff --git a/bin/codescribe-corpus.rs b/bin/codescribe-corpus.rs index e9a81674..ea1110b0 100644 --- a/bin/codescribe-corpus.rs +++ b/bin/codescribe-corpus.rs @@ -33,6 +33,9 @@ use codescribe_core::asr_session::GatewaySessionAvailability; use codescribe_core::config::UserSettings; use codescribe_core::pipeline::contracts::{EngineEvent, LayerSource}; use codescribe_core::quality::engine_contract::{CORPUS_REPORT_SCHEMA, ENGINE_CONTRACT_ID}; +use codescribe_core::quality::seal_atlas_html::{ + SealAtlasPage, SealAtlasStats, render_seal_atlas_html, +}; use codescribe_core::util::safe_path::{safe_open, safe_symlink_or_copy_bounded}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; @@ -1133,7 +1136,8 @@ async fn run_worker(args: WorkerArgs) -> Result<()> { let input_hashes_unchanged = rows .iter() .all(|row| row.audio_hash_unchanged && row.reference_hash_unchanged); - let quality_html = format!("quality/{}.html", args.profile.token()); + let quality_html = format!("quality/seal-atlas.{}.html", args.profile.token()); + let qube_html = format!("quality/qube.{}.html", args.profile.token()); let quality_report = build_quality_report( args.profile, &args.language, @@ -1154,8 +1158,30 @@ async fn run_worker(args: WorkerArgs) -> Result<()> { metrics_reference: MetricsReference::Corpus, local_transcription: LocalTranscriptionMode::LocalWhisper, }; + let atlas = SealAtlasPage { + title: format!("Seal Atlas — corpus {}", args.profile.token()), + lede: format!( + "Corpus profile {}. One take, one PCM clock. Words from SealedSpan.words when a dump is attached — not from the final string.", + args.profile.token() + ), + stats: SealAtlasStats { + sealed_spans: quality_report.entries.len().to_string(), + ..SealAtlasStats::default() + }, + findings: vec![ + format!( + "Qube scores (footnote) live at {}. Avg WER is not the live engine.", + qube_html + ), + ], + dump_present: false, + }; atomic_write_private( &output_root.join(&quality_html), + render_seal_atlas_html(&atlas).as_bytes(), + )?; + atomic_write_private( + &output_root.join(&qube_html), render_qube_html(&quality_report, &quality_config).as_bytes(), )?; diff --git a/core/quality/engine_contract.rs b/core/quality/engine_contract.rs index 72452f17..8eacceda 100644 --- a/core/quality/engine_contract.rs +++ b/core/quality/engine_contract.rs @@ -14,8 +14,58 @@ pub const CORPUS_REPORT_SCHEMA: &str = "codescribe-corpus-parity/v3"; /// Stable id of the engine contract itself. pub const ENGINE_CONTRACT_ID: &str = "the-engine/v1"; -/// Path of the agent-facing prose lock, relative to the repo root. -pub const ENGINE_CONTRACT_DOC: &str = "docs/THE_ENGINE_CONTRACT.md"; +/// Path of the HTML-surface contract, relative to the repo root. +pub const QUALITY_HTML_CONTRACT_DOC: &str = "docs/quality-reports/CONTRACT.md"; + +/// Failures if this string is not a Seal Atlas quality report. +pub fn validate_quality_html(html: &str) -> Vec { + let lowered = html.to_ascii_lowercase(); + let mut failures = Vec::new(); + if !html.contains(r#"name="engine-contract""#) || !html.contains(ENGINE_CONTRACT_ID) { + failures.push("missing meta engine-contract=the-engine/v1".into()); + } + if !html.contains(r#"name="quality-report-surface""#) + || !lowered.contains("seal-atlas") && !lowered.contains("seal atlas") + { + failures.push("missing meta quality-report-surface=seal-atlas".into()); + } + if !lowered.contains("seal atlas") && !lowered.contains("seal-atlas") { + failures.push("title/body must name Seal Atlas".into()); + } + if !html.contains(r#"class="stat""#) { + failures.push("Voice Lab handshake needs div.stat cards".into()); + } + if !lowered.contains("word-grain") { + failures.push("must label word-grain".into()); + } + if !lowered.contains("utterance-grain") { + failures.push("must label utterance-grain".into()); + } + if !lowered.contains("clock-lie") && !html.contains("kłamstwo zegarowe") { + failures.push("clock-lie must be a first-class finding".into()); + } + if !html.contains("SealedSpan.words") + && !lowered.contains("sealedspan.words") + && !lowered.contains("sealed spans") + { + failures.push("must name SealedSpan.words or sealed spans".into()); + } + if !lowered.contains("whisper") { + failures.push("must mention whisper_words / Whisper on the same clock".into()); + } + if lowered.contains("

codescribe quality report

") { + failures.push("retired Qube H1 is not a Seal Atlas".into()); + } + let wer_at = lowered.find("avg wer"); + let footnote_at = lowered.find("footnote"); + if let Some(wer) = wer_at { + if footnote_at.map(|f| f < wer).unwrap_or(false) == false { + failures.push("Avg WER may only appear after a footnote marker".into()); + } + } + failures +} + /// What a quality report is allowed to treat as the document vs a proposal. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] @@ -421,6 +471,40 @@ mod tests { assert_eq!(QUALITY_REPORT_SURFACE, "seal-atlas"); } + #[test] + fn gold_atlas_passes_html_handshake() { + let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(".."); + let path = root.join(SEAL_ATLAS_GOLD_HTML); + let body = std::fs::read_to_string(&path) + .unwrap_or_else(|err| panic!("{} must exist: {err}", path.display())); + let failures = validate_quality_html(&body); + assert!(failures.is_empty(), "gold take 01 failed handshake: {failures:?}"); + } + + #[test] + fn html_contract_doc_exists() { + let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(".."); + let body = std::fs::read_to_string(root.join(QUALITY_HTML_CONTRACT_DOC)) + .unwrap_or_else(|err| panic!("{QUALITY_HTML_CONTRACT_DOC} must exist: {err}")); + for needle in [ + "quality-report-surface", + "div class=\"stat\"", + "word-grain", + "clock-lie", + "quality/seal-atlas.", + ] { + assert!(body.contains(needle), "CONTRACT.md missing {needle:?}"); + } + } + + #[test] + fn retired_qube_title_fails_handshake() { + let fake = r#"Codescribe Quality Report +

Codescribe Quality Report

Avg WER 12%

"#; + let failures = validate_quality_html(fake); + assert!(failures.len() >= 3, "{failures:?}"); + } + #[test] fn gold_atlas_html_is_a_pcm_instrument_not_a_wer_table() { let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(".."); @@ -465,3 +549,4 @@ mod tests { ); } } + diff --git a/core/quality/mod.rs b/core/quality/mod.rs index 6bcf2c0d..a818b48c 100644 --- a/core/quality/mod.rs +++ b/core/quality/mod.rs @@ -18,6 +18,8 @@ /// Locked THE ENGINE contract for quality-report HTML and corpus JSON. pub mod engine_contract; pub mod overlay_quality; +/// Seal Atlas HTML renderer — the quality-report surface corpus writes. +pub mod seal_atlas_html; /// Background Qube donor daemon: opt-in stop-path WAV/transcript persistence. pub mod qube_daemon; /// Qube report types and serialization for quality/donor telemetry surfaces. @@ -27,8 +29,9 @@ pub mod teacher; pub use engine_contract::{ CORPUS_REPORT_SCHEMA, ENGINE_CONTRACT, ENGINE_CONTRACT_ID, EngineContract, - render_engine_contract_html, + render_engine_contract_html, validate_quality_html, }; +pub use seal_atlas_html::{SealAtlasPage, SealAtlasStats, render_seal_atlas_html}; pub use teacher::{ Layer1MergeMode, Layer1MergedDelivery, MergeMode, MergedDelivery, TeacherInput, TeacherReport, merge_live_layer1, merge_live_whisper, merge_live_whisper_with_terms, report_to_html, teach, diff --git a/core/quality/seal_atlas_html.rs b/core/quality/seal_atlas_html.rs new file mode 100644 index 00000000..c599b4ef --- /dev/null +++ b/core/quality/seal_atlas_html.rs @@ -0,0 +1,180 @@ +//! Seal Atlas HTML — the quality-report surface `codescribe-corpus` writes. +//! +//! Gold visual is take 01 (`docs/quality-reports/seal-atlas.take01.html`). +//! This renderer emits a handshake-valid atlas for a corpus profile when a +//! live dump is not attached. Waveform SVG is omitted until +//! `CODESCRIBE_SEAL_ATLAS_DUMP` is present; the page is still a Seal Atlas, +//! not a Qube WER table. + +use super::engine_contract::{ + ENGINE_CONTRACT_ID, QUALITY_REPORT_SURFACE, engine_contract_css, render_engine_contract_html, +}; + +/// Numbers Voice Lab lifts out of `.stat` cards. +#[derive(Debug, Clone)] +pub struct SealAtlasStats { + pub word_grain: String, + pub sealed_spans: String, + pub per_word_spans: String, + pub clock_lies: String, + pub silero_threshold: String, +} + +impl Default for SealAtlasStats { + fn default() -> Self { + Self { + word_grain: "n/a".into(), + sealed_spans: "n/a".into(), + per_word_spans: "n/a".into(), + clock_lies: "n/a".into(), + silero_threshold: "0.5".into(), + } + } +} + +/// One Seal Atlas HTML document. +#[derive(Debug, Clone)] +pub struct SealAtlasPage { + pub title: String, + pub lede: String, + pub stats: SealAtlasStats, + pub findings: Vec, + pub dump_present: bool, +} + +impl Default for SealAtlasPage { + fn default() -> Self { + Self { + title: "Seal Atlas".into(), + lede: "One take, one PCM clock. Words from SealedSpan.words — not from the final string.".into(), + stats: SealAtlasStats::default(), + findings: Vec::new(), + dump_present: false, + } + } +} + +/// Handshake-valid Seal Atlas HTML. Title contains `Seal Atlas`. +pub fn render_seal_atlas_html(page: &SealAtlasPage) -> String { + let title = if page.title.to_ascii_lowercase().contains("seal atlas") { + page.title.clone() + } else { + format!("Seal Atlas — {}", page.title) + }; + let stats = [ + (&page.stats.word_grain, "word-grain ≥75% speech"), + (&page.stats.sealed_spans, "sealed spans"), + (&page.stats.per_word_spans, "spans with per-word pins"), + (&page.stats.clock_lies, "clock-lie"), + (&page.stats.silero_threshold, "Silero threshold"), + ] + .into_iter() + .map(|(value, label)| { + format!( + "
{}{}
", + html_escape(value), + label + ) + }) + .collect::(); + + let findings = if page.findings.is_empty() { + "
  • No dump attached. This page is the contract surface; waveform waits on CODESCRIBE_SEAL_ATLAS_DUMP.
  • ".into() + } else { + page.findings + .iter() + .map(|line| format!("
  • {}
  • ", html_escape(line))) + .collect::() + }; + + let dump_note = if page.dump_present { + "

    Waveform from the live dump. Production Silero via vad_atlas_probe. Letter ticks = równomierna interpolacja, not measurement.

    " + } else { + "

    Waveform omitted — no CODESCRIBE_SEAL_ATLAS_DUMP. whisper_words still map backward onto pcm_time when a dump arrives. Per-word pins are real where they exist and not guaranteed. Utterance-grain vs word-grain stay labeled. Clock-lie is a finding.

    " + }; + + format!( + r#" + + + + + + +{title} + + + +
    +
    +

    {title}

    +

    {lede}

    +
    {stats}
    +
    +{plate} +
    +

    Lanes

    +

    Silero p(mowa) · word-grain · utterance-grain · clock-lie · whisper_words

    +{dump_note} +

    Words from SealedSpan.words / the live dump — never rebuilt from the final string. HQ / Cloud stay proposals.

    +
    +
    +

    Findings

    +
      {findings}
    +
    +
    + + +"#, + contract = ENGINE_CONTRACT_ID, + surface = QUALITY_REPORT_SURFACE, + title = html_escape(&title), + lede = html_escape(&page.lede), + stats = stats, + plate = render_engine_contract_html(), + dump_note = dump_note, + findings = findings, + css = engine_contract_css(), + ) +} + +fn html_escape(value: &str) -> String { + value + .replace('&', "&") + .replace('<', "<") + .replace('>', ">") + .replace('"', """) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::quality::engine_contract::validate_quality_html; + + #[test] + fn renderer_passes_the_html_handshake() { + let html = render_seal_atlas_html(&SealAtlasPage { + title: "profile apple-layer0".into(), + ..SealAtlasPage::default() + }); + let failures = validate_quality_html(&html); + assert!(failures.is_empty(), "{failures:?}"); + assert!(html.contains("Seal Atlas — profile apple-layer0")); + assert!(!html.contains("Avg WER")); + assert!(!html.contains("Codescribe Quality Report")); + } +} diff --git a/docs/THE_ENGINE_CONTRACT.md b/docs/THE_ENGINE_CONTRACT.md index f22cc85a..8c12c581 100644 --- a/docs/THE_ENGINE_CONTRACT.md +++ b/docs/THE_ENGINE_CONTRACT.md @@ -84,6 +84,9 @@ The private quality HTML is a **Seal Atlas**, not a WER table with a banner. Gold visual: [`docs/quality-reports/seal-atlas.take01.html`](quality-reports/seal-atlas.take01.html) (take 01 „no to dobra", replay `cff0817b…`, 44100 Hz, 2650112 samples). +HTML handshake (meta, `.stat` cards, lanes): [`docs/quality-reports/CONTRACT.md`](quality-reports/CONTRACT.md). +`codescribe-corpus` writes `quality/seal-atlas.{profile}.html`. Qube is a footnote. + 1. **One take, one clock.** X-axis is the capture PCM sample counter. Apple sealed spans, `SealedSpan.words`, Whisper segments, and Silero p(speech) share that axis. No reconstructed timeline. 2. **Production Silero.** Curve from the engine's embedded ONNX + default `VadConfig`, 32 ms chunks — `vad_atlas_probe`, not a toy VAD. 3. **Words from the live dump.** `CODESCRIBE_SEAL_ATLAS_DUMP` after session-end seal. Never rebuilt from the final string. diff --git a/docs/quality-reports/CONTRACT.md b/docs/quality-reports/CONTRACT.md new file mode 100644 index 00000000..f9793ee5 --- /dev/null +++ b/docs/quality-reports/CONTRACT.md @@ -0,0 +1,93 @@ +# Quality-report HTML contract + +Source of truth: `core/quality/engine_contract.rs`. +Visual gold: [`seal-atlas.take01.html`](seal-atlas.take01.html) +(take 01 „no to dobra” — the Claude artifact, locked). + +`codescribe-corpus` writes these HTML files. Voice Lab only lists what +passes this handshake. A WER table is a footnote, never the throne. + +## Identity + +| | | +| --- | --- | +| surface | `seal-atlas` | +| engine | `the-engine/v1` | +| primary key | `pcm_time` | +| Voice Lab kind | `seal_atlas` | + +Required ``: + +```html + + +Seal Atlas — … +``` + +Title **must** contain `Seal Atlas` (or `seal-atlas`). +`Codescribe Quality Report` is the retired Qube page. It may still be +written as `quality/qube.{profile}.html`. It is not the report. + +## Fact cards + +Voice Lab reads: + +```html +
    VALUELABEL
    +``` + +Take 01 cards (labels may be PL or EN): + +| value | meaning | +| --- | --- | +| `20/20` | word-grain words with ≥75% speech | +| `11` | sealed spans | +| `2` | spans with per-word pins | +| `1` | clock-lie (span 2) | +| `0.5` | Silero threshold | + +A corpus atlas without a dump still emits these five `.stat` cards +(values may be `n/a`). Missing the class is a handshake miss. + +## Lanes (one take, one clock) + +X-axis is the capture PCM sample counter. Required legend tokens: + +- `Silero` / `p(mowa)` — production VAD, 32 ms, default threshold +- `word-grain` — SFSpeech actually returned per-word pins +- `utterance-grain` — one segment over the Apple commit-to-commit window +- `clock-lie` / `kłamstwo zegarowe` — first-class finding +- `whisper_words` — Whisper mapped **back** onto the same clock + +Forbidden as the live picture: reconstructed timelines, letter timings +presented as measurement, Whisper drawn into Silero silence. + +## Required body copy + +The HTML must say, in some language: + +1. Words come from `SealedSpan.words` / the live dump — not from the final string. +2. Per-word pins are real where they exist and **not guaranteed**. +3. Letter ticks inside a word are even interpolation, not measurement. +4. Clock-lie: too many characters for the claimed PCM duration + (`CLOCK_LIE_CHARS_PER_SEC = 30`). Take 01 span 2 is the canonical example. + +## Files corpus must write + +| path | kind | role | +| --- | --- | --- | +| `quality/seal-atlas.{profile}.html` | `seal_atlas` | **the** quality report | +| `docs/quality-reports/seal-atlas.take01.html` | `seal_atlas` | gold take, never regenerated from WER | +| `quality/qube.{profile}.html` | `quality_report` | retired scores surface, footnote | +| `docs/THE_ENGINE_CONTRACT.md` + engine plate | `quality_contract` | doctrine, not a take | + +Destination the operator sees: `~/.vibecrafted/artifacts/vetcoders/codescribe` +(or `$CODESCRIBE_ARTIFACTS_DIR`). If the atlas does not land there, Voice Lab +never shows it. + +## Forbidden in a Seal Atlas HTML + +- title `Codescribe Quality Report` as the H1 +- `Avg WER` as a hero / first stat +- treating HQ / Cloud / AI as the live engine +- omitting `engine-contract` or `quality-report-surface` meta diff --git a/site/package.json b/site/package.json index a6751b56..a118d545 100644 --- a/site/package.json +++ b/site/package.json @@ -8,7 +8,8 @@ "start": "astro dev", "build": "astro build", "preview": "astro preview", - "check": "astro check" + "check": "astro check", + "test:teacher": "node --experimental-strip-types --test src/lib/teacher/teach.test.ts" }, "dependencies": { "@fontsource/jetbrains-mono": "^5.1.0", diff --git a/site/public/voice/atlas/seal-atlas.take01.html b/site/public/voice/atlas/seal-atlas.take01.html new file mode 100644 index 00000000..c8b228be --- /dev/null +++ b/site/public/voice/atlas/seal-atlas.take01.html @@ -0,0 +1,158 @@ + + + + + + + +Seal Atlas — take 01 „no to dobra" + + + +
    +
    +

    Seal Atlas — take 01 „no to dobra"

    +

    Jeden take (60.1 s), jedna oś czasu: licznik próbek PCM z capture. Krzywa mowy policzona +produkcyjnym Silero VAD (embedded ONNX, config domyślny silnika), słowa pochodzą z +SealedSpan.words zrzuconych przez żywy tor Apple-live w replayu — +nie z żadnej rekonstrukcji.

    +
    +
    20/20słów word-grain ≥75% na mowie
    +
    11sealed spans
    +
    2spany z per-word pinami
    +
    1clock-lie (span 2)
    +
    0.5próg Silero
    +
    +
    + +
    +

    Pełny przebieg — 0…60 s

    +

    Góra: obwiednia PCM. Środek: p(mowa) Silero co 32 ms z progiem 0.5 (linia przerywana). +Dół: zapieczętowane spany Apple (z pinami słów tam, gdzie SFSpeech oddał segmenty) i segmenty Whispera +zmapowane wstecz na ten sam zegar. Najedź na box, żeby zobaczyć tekst i zakres.

    +
    0s5s10s15s20s25s30s35s40s45s50s55s60sPCM 44.1 kHzSilero p(mowa) · próg 0.5Apple · SealedSpan.wordsspan 1: No to dobra teraz generalnie powiem parę słów korzystając z surowej transkrypcji przez co. [0.00–20.00s] mowa 84%#1span 2: Mamy już pierwsze słowo do analizy czego. [20.00–20.10s] mowa 100%span 3: Ten plik WAV i puścił go na. [20.70–23.49s] mowa 98%#3ten [20.70–20.94s] mowa 100%plik wave [20.94–21.93s] mowa 100%plik w…i [22.14–22.35s] mowa 75%puścił [22.35–22.92s] mowa 100%puś…go [22.92–23.13s] mowa 100%na [23.13–23.49s] mowa 100%span 4: Nasz and point bo muszę mieć pewność Leksykon działa. [23.49–32.10s] mowa 76%#4span 5: Więc po prostu będę mówił z dupy. [32.10–35.40s] mowa 48%#5span 6: To aplikacja. [35.40–37.40s] mowa 95%#6span 7: Ta aplikacja. [37.40–39.80s] mowa 50%#7span 8: Stworzona. [39.80–43.20s] mowa 36%#8span 9: Duże bazy kodowe przestały być tajemnicą i czarną dziurą dla agentów jaj korzysta z Ruska. [43.98–53.79s] mowa 73%#9duże [43.98–44.28s] mowa 90%bazy [44.28–44.55s] mowa 100%kodowe [44.55–45.09s] mowa 100%przestały [45.27–45.66s] mowa 85%być [45.66–45.81s] mowa 100%tajemnicą [45.81–46.59s] mowa 100%taje…i [46.59–47.31s] mowa 100%iczarną [47.79–48.15s] mowa 75%dziurą [48.15–48.57s] mowa 100%dla [49.20–49.89s] mowa 100%dlaagentów [49.89–50.25s] mowa 100%jaj [50.25–50.52s] mowa 100%korzysta [52.20–52.62s] mowa 100%z Ruska [52.62–53.79s] mowa 100%z Ruskaspan 10: W wersji dwa. [53.79–57.30s] mowa 69%#10span 11: 000. [57.30–57.50s] mowa 43%Whisper · whisper_wordsNo to dobra. Teraz generalnie powiem parę słów, korzystając z surowej transkrypcji przez CodeScribe. [1.00–11.56s]Mamy już pierwsze słowo do analizy, wobec czego chcę, żebyś za chwilę dam [11.56–19.98s]żebyś wziął ten blik wave [20.10–21.96s]i puścił go na [21.96–23.48s]nasz endpoint, bo muszę mieć pewność, [25.49–27.51s]czy leksykon działa. [27.67–29.53s]Więc po prostu [31.33–32.09s]co tam obliwstwoj. [32.10–35.08s]Log3 to aplikacja [35.40–37.38s]toż ona. [38.90–39.78s]po to, aby [40.30–43.18s]Duże bazy kodowe przestały być tajemnicą i czarną dziurą dla agentów AI. [43.70–50.42s]Korzystam z Rusta. [52.12–53.78s]w wersji Tooltrain 2024. [54.79–57.29s]
    +
    +Silero p(mowa) +span word-grain (piny słów) +span utterance-grain (1 segment) +clock-lie +whisper_words +
    +
    + +
    +

    Zoom: span 3 — „Ten plik WAV i puścił go na" (20.7–23.5 s)

    +

    6 słów, każde z własnym zakresem próbek. Podział na litery wewnątrz słowa to +równomierna interpolacja (SFSpeech nie daje timingów grafemów) — jawnie oznaczona, nie pomiar.

    +
    21s22s23sPCM 44.1 kHzSilero p(mowa) · próg 0.5Apple · SealedSpan.wordsspan 3: Ten plik WAV i puścił go na. [20.70–23.49s] mowa 98%#3ten [20.70–20.94s] mowa 100%tenplik wave [20.94–21.93s] mowa 100%plik wavei [22.14–22.35s] mowa 75%ipuścił [22.35–22.92s] mowa 100%puściłgo [22.92–23.13s] mowa 100%gona [23.13–23.49s] mowa 100%naspan 4: Nasz and point bo muszę mieć pewność Leksykon działa. [23.49–32.10s] mowa 76%#4Whisper · whisper_wordsżebyś wziął ten blik wave [20.10–21.96s]i puścił go na [21.96–23.48s]
    +
    + +
    +

    Zoom: span 9 — 14 słów (44.0–53.8 s)

    +

    Najdłuższy word-grain span take'a. Widać przerwy między słowami pokrywające się z dolinami +Silero („czarną" zaczyna się po 480 ms ciszy — VAD i pin zgadzają się co do niej).

    +
    44s45s46s47s48s49s50s51s52s53s54sPCM 44.1 kHzSilero p(mowa) · próg 0.5Apple · SealedSpan.wordsspan 9: Duże bazy kodowe przestały być tajemnicą i czarną dziurą dla agentów jaj korzysta z Ruska. [43.98–53.79s] mowa 73%#9duże [43.98–44.28s] mowa 90%dużebazy [44.28–44.55s] mowa 100%bazykodowe [44.55–45.09s] mowa 100%kodoweprzestały [45.27–45.66s] mowa 85%być [45.66–45.81s] mowa 100%tajemnicą [45.81–46.59s] mowa 100%tajemnicąi [46.59–47.31s] mowa 100%iczarną [47.79–48.15s] mowa 75%dziurą [48.15–48.57s] mowa 100%dziurądla [49.20–49.89s] mowa 100%dlaagentów [49.89–50.25s] mowa 100%jaj [50.25–50.52s] mowa 100%jajkorzysta [52.20–52.62s] mowa 100%z Ruska [52.62–53.79s] mowa 100%z Ruskaspan 10: W wersji dwa. [53.79–57.30s] mowa 69%#10Whisper · whisper_wordsDuże bazy kodowe przestały być tajemnicą i czarną dziurą dla agentów AI. [43.70–50.42s]Korzystam z Rusta. [52.12–53.78s]
    +
    + +
    +

    Każde słowo word-grain vs Silero

    +

    Udział chunków z p(mowa) ≥ 0.5 wewnątrz zakresu słowa.

    +
    + + +
    spansłowozakres [s]czasmowa
    #3ten20.70–20.94240 ms100%
    #3plik wave20.94–21.93990 ms100%
    #3i22.14–22.35210 ms75%
    #3puścił22.35–22.92570 ms100%
    #3go22.92–23.13210 ms100%
    #3na23.13–23.49360 ms100%
    #9duże43.98–44.28300 ms90%
    #9bazy44.28–44.55270 ms100%
    #9kodowe44.55–45.09540 ms100%
    #9przestały45.27–45.66390 ms85%
    #9być45.66–45.81150 ms100%
    #9tajemnicą45.81–46.59780 ms100%
    #9i46.59–47.31720 ms100%
    #9czarną47.79–48.15360 ms75%
    #9dziurą48.15–48.57420 ms100%
    #9dla49.20–49.89690 ms100%
    #9agentów49.89–50.25360 ms100%
    #9jaj50.25–50.52270 ms100%
    #9korzysta52.20–52.62420 ms100%
    #9z Ruska52.62–53.791170 ms100%
    +
    + +
    +

    Uczciwe wnioski

    +
      +
    • Piny są prawdziwe tam, gdzie istnieją. 20/20 słów z per-word pinami leży w ≥75% +na chunkach mowy wg Silero; minimum to 75% („i", 210 ms — krótkie spójniki łapią sąsiadującą ciszę). +Czasy trwania są fizjologiczne (150–990 ms na słowo).
    • +
    • Dwie klasy ziarna. Tylko 2 z 11 spanów mają per-word piny — SFSpeech oddaje segmenty +kapryśnie; pozostałe spany niosą jeden „word" o ziarnie całego utterance. Per-word payload +jest więc realny, ale nie gwarantowany.
    • +
    • Span 2 to kłamstwo zegarowe na żywym okazie: 41 znaków przypięte do 100 ms +(410 znaków/s — fizycznie niemożliwe). To ten sam rodzaj rozjazdu, który łapią WARN-y +„seal window unresolved". Silero mówi „mowa 100%", ale zakres nie jest zakresem tej mowy.
    • +
    • Utterance-grain spany zawierają ogony ciszy (span 8: 36% mowy) — zakres spanu to +odległość między commitami Apple, nie obrys mowy. Dokładnie dlatego W13-3B chce mintować +tożsamości z krawędzi ciszy Silero.
    • +
    • Litery = interpolacja. Rozbicie liter jest równomiernym podziałem zakresu słowa, +oznaczonym na grafie; realne timingi grafemów wymagałyby forced-alignera — nie udajemy, że je mamy.
    • +
    +

    Źródła: CODESCRIBE_SEAL_ATLAS_DUMP (nowa powierzchnia +dowodowa w apple_live_session) + vad_atlas_probe (nowy example w core). +Sesja replay cff0817b…, sample_rate 44100 Hz, 2650112 próbek.

    +
    +
    + + diff --git a/site/public/voice/atlas/the-engine.contract.html b/site/public/voice/atlas/the-engine.contract.html new file mode 100644 index 00000000..482c7b6b --- /dev/null +++ b/site/public/voice/atlas/the-engine.contract.html @@ -0,0 +1,58 @@ + + + + + + +THE ENGINE · quality-report contract + + + +
    +
    +

    THE ENGINE · quality-report contract

    +

    Place on the canvas is given by energy in time. Quality HTML is a Seal Atlas, not a WER table. Source of truth: the-engine/v1.

    +
    +
    pcm_timeprimary key
    +
    3finality bars
    +
    seal-atlasrequired surface
    +
    proposalHQ / Cloud / AI
    +
    +
    +
    +

    Three bars — not synonyms

    + + + + +
    utterance_final / committedThis layer finished its hypothesis. That layer is banned from further overwrite of this span. Not the document.
    utterance_sealedApple + Whisper + lexicon fused a Silero-bounded span. Record [sample_start, sample_end) is append-only.
    transcript_sealedSession assembled. Automation hands down. Full HQ / Cloud may only propose a variant.
    +
    +
    +

    Atlas rules

    +
      +
    • One take, one PCM clock. Live dump + production Silero. Never a reconstructed timeline.
    • +
    • Word-grain vs utterance-grain labeled. Per-word pins are real where they exist and not guaranteed.
    • +
    • Clock-lie is a finding. Letters are interpolation, not measurement.
    • +
    • Whisper is mapped backward onto the same clock. It does not hallucinate into silence.
    • +
    +

    Forbidden: rewrite_from_zero · reorder_spans · hallucinate_into_silence · full_file_in_automatic_pipeline · treat_whole_text_mutable_until_session_seal

    +
    +
    + + diff --git a/site/src/components/Footer.astro b/site/src/components/Footer.astro index 6e056363..ebe4d401 100644 --- a/site/src/components/Footer.astro +++ b/site/src/components/Footer.astro @@ -11,6 +11,7 @@ import { asset, page } from '../lib/asset'; codescribe