Files
mathiasandClaude Opus 5 489b4bb2a1
CI / Lint / Test / Vet (push) Successful in 37s
CI / Build & Import (push) Failing after 5s
CI / Deploy via GitOps (push) Skipped
chore(spike): recover the /bygge toolchain from tmpfs (#28)
analyze_srt.py, build_page.py and transcode.yaml produced the /bygge
prototype. They were sitting in a session scratchpad on tmpfs, one reboot
from gone, while spike issues #29-#31 were written as if they had to be
built from scratch.

Committed as found, defects documented rather than fixed: max_tokens=6000
truncates anything past ~6 minutes of audio, the page title is hardcoded,
and the schema still carries fields no consumer renders.

The four-check validator is the part worth keeping — the coverage-gap and
Swedish-number-grounding checks catch errors that timestamp and citation
checks structurally cannot.

Real transcripts and analyses stay out: this repo is public and the
recordings are a named person discussing a client's project. Only the
synthetic fixture is committed, which exercises all four checks with no
model call.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BeAp5LTscnz2W7Ubt4eJ6m
2026-08-13 11:37:03 +02:00

73 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# spike-media — the `/bygge` toolchain, recovered
Throwaway spike tooling for #28 (upload → transcript → takeaways). Committed
because it was found in `tmpfs` one reboot from gone, not because it is finished.
Nothing here is wired into tapir. No database, no HTTP handler, no ADR.
## What produced `/bygge`
The prototype at `tapir.d-ma.be/bygge` was **not** hand-built, which the epic and
the first round of spike issues both got wrong. It came from these three scripts:
```
IMG_1233.mov --transcode.yaml--> IMG_1233.web.mp4 (k3s Job, h264, +faststart)
IMG_1233.wav --whisper---------> IMG_1233.sv.srt (interactive — the one manual step)
IMG_1233.sv.srt --analyze_srt.py--> analys.json (berget/mistral-medium, temperature=0)
analys.json + video --build_page.py--> page HTML
```
The reference analysis was produced by **`berget/mistral-medium`** — a mid-tier
cloud model, not a frontier one. That matters when judging what a local model
has to clear: the bar is mistral-medium, and it should be re-run as the control
arm rather than excluded.
## The validator is the valuable part
`analyze_srt.py` grades its own output on four checks. Two of them catch classes
of error that timestamp- and citation-checking cannot:
| Check | Catches |
|---|---|
| citation exact / **partial** / absent | Paraphrase presented as a quote. Three tiers, because `alternativ` citations legitimately stitch non-contiguous passages — a strict substring test fails the reference output. |
| `TALET … FINNS INTE I CITATET` | A wrong number carried by a *verbatim* citation and a *real* timestamp. Converts Swedish number-words to digits first. It caught `45×230` where the transcript said `220`. |
| `TACKNINGSLUCKA` | Spans of the clip no section covers. **The recall term** — without it an empty analysis scores perfectly on every other check. |
| timestamp exists in the SRT | Fabricated seek targets. Near-solved: 74/75 on the reference, because the model copies the cue starts it was handed. |
## Known defects — read before running
- **`max_tokens: 6000` is too low.** The 4-minute reference analysis is ~4,700
output tokens, i.e. ~78% of budget. A 10-minute clip truncates for every model,
and truncation reads as a JSON-discipline failure if you are not counting
tokens. Record `finish_reason` and separate `truncated` from `malformed`.
- **`build_page.py` hardcodes the title** (`"Jonas genomgång av tillbyggnad"`).
- **The schema carries fields nothing renders** — `projekt.sammanfattning`,
`projekt.skede`, `avsnitt.bildtid`, `avsnitt.bildmotiv`, `material[]`,
`oklart[]` — left over from an earlier still-frame/markdown output that
`build_page.py` replaced. They are paid for in output tokens on every run.
- **Speaker attribution is inferred, not diarized.** The output attributes
statements by name from an SRT with no speaker labels. All four checks above
are blind to a misattribution.
- **The web encode does not downscale.** The source is 720×1280; `-preset
veryfast -crf 24` on handheld motion is what makes it ~5 Mbps, not the
resolution. The lever is the preset.
## Fixtures
`fixtures/fake.sv.srt` + `fixtures/fake.analys.json` — a synthetic 7-cue Swedish
construction walkthrough with planted numbers. No real people, no real project.
It exercises the parser and all four validator checks **without a model call**,
which is what makes it usable in a test.
## Why the real artifacts are not here
**This repo is public.** The prototype's transcript and analysis are a verbatim
recording of a named person discussing a client's building project — private
third-party content, and exactly the class of data #28 calls out as the reason
uploaded transcripts cannot live in the shared `transcripts` table.
So `IMG_1233.sv.srt`, `payload.json` and the model-comparison runs stay out of
git here. That leaves `/bygge` without a versioned source of truth, which is a
real gap and a decision for #28: a private repo, an encrypted blob, or accepting
that the reference artifacts live outside version control.