python
Technical notes on web development, DevOps, and AI integration.
51 articles
- 09:01devops
The Status Value That Shouldn't Exist Yet
A weeks-old file carried a status value the old reader never wrote. The vocabulary changed without a schema version bump. A lesson in data contracts.
TL;DR: A checker warning revealed a transcript file whose status value didn't exist in the old reader's vocabulary. The fix splits failures into unknown-status, where the reader lags, and legacy-enum-status, where a writer changed vocabulary without bumping the schema version. Lesson learned: treat enum changes as schema changes and bump versions in the same commit.
#python#schema#backward-compatibility - 04:41tooling
Tesseract OCR in a pipeline: ordering, quarantine, empty output
Adding tesseract to an ingest pipeline turned out to be less about the CLI and more about ordering, the img caption convention, quarantine, and empty output.
TL;DR: A media ingest job stalled with media-blocked status after tesseract went unregistered, previously blocking every job including audio-only ones. The fix narrows preflight so OCR is only mandatory for image-only jobs, splitting failures into plan-blocking versus quarantine-worthy problems. Empty OCR output counts as success with evidence recorded, while infrastructure timeouts retry and corrupt content gets quarantined for healing.
#tesseract#ocr#python - 04:03devops
Event Log Integrity the Git Way: A Frame Tamper Story
A one-byte frame tamper taught me how content-addressed sidecars, an append-only event log, and disk-truth verification keep a pipeline recoverable.
TL;DR: When a corrupted frame triggered media-quarantine instead of a crash, the kernel proved it rebuilds state from events and verifies files from disk, never trusting recorded hashes. Content-addressed caption sidecars give free deduplication, while the append-only log enables clean recovery through full rebuilds. But hash chains prove tamper-evidence, not authenticity—integrity is an architecture, not a checksum ritual.
#git#event-sourcing#automation - 01:14ai
I finally split my transcription failures into two families
My transcription pipeline died silently mid-window. A hang turns out to be an exception that must be caught, and every failure has an owner.
TL;DR: After a hung transcription exposed an uncaught TimeoutExpired exception, the author split pipeline failures into infrastructure issues, which silently retry, and content issues, which log a failure event. Broken files follow a retry ladder capped at three attempts, then a visible skip that still blocks completion. Correct exit-code mapping keeps retries from amplifying hopeless failures.
#whisper#ffmpeg#python - 23:34ai
The transcript filter is a projection, not a parameter
Changing a filter rule doesn't mean re-running whisper. The filter is a projection of stored stdout, stamped with a sha256 of the rule.
TL;DR: When the profanity filter changed, the author's first instinct was re-running Whisper on every transcript, even though the audio never changed. The fix: treat filtering as a cheap projection of already-cached Whisper output, not a transcription step. Stamp artifacts with a phrase-list hash, so rule changes mean instant re-projection with zero model calls.
#python#whisper#idempotency - 14:23tooling
The Context Guard: Validating What Your Pipeline Sends
A prompt assembly failure can send a naked question to an AI chat and still pass as grounded synthesis. A cheap input-side guard keeps the chain honest.
TL;DR: The pipeline sent a naked question to the AI with zero context, yet the generic answer passed all validation because checks only ran on output, never input. The fix is a cheap context_present() gate requiring either 400 characters or a URL, tagging results as missing or ok. It warns without blocking, since harsh guards get deleted.
#python#automation#llm - 13:22tooling
AI Chat Scraper Audit: From False Positives to Precise Regex
A loose completion gate called a half-written answer done. One audit produced four fixes: pre-answer failure patterns, an anchored heading gate, probe-copy.
TL;DR: The scraper kept cutting AI answers short because loose completion gates matched "Sources" inside citation lines. The fix narrows trust: failure patterns only count before any answer text, and the completion gate requires a contracted final heading via a strict regex. Added a --probe-copy diagnostic and evidence logging; selftest grew from 72 to 79 asserts.
#python#regex#debugging - 02:28tooling
The .rejected File: When Human Decisions Beat Derived Status
My research registry only had derived statuses, until a .rejected file gave human decisions a seat in the precedence chain.
TL;DR: A dismissed research topic kept reappearing in the registry scan, so the author added a .rejected marker file that humans write and tools only read, storing the reason in a rejected_reason field. The article compares this to precedence chains in rustup, pyenv, nvm, and git. Key lessons: markers are human decisions, and overrides must be visible, never silent.
#python#automation#tooling - 12:23backend
My Derived Field Went Stale Three Days After I Backfilled It
A backfilled next_review went stale in three days. The fix: compute derived fields at read time and keep manual overrides.
TL;DR: A hand-run backfill for next_review went stale the moment one new file hit the index, exposing it as a derived field that shouldn't be stored. The real fix computes it at read time, only filling blanks so manual overrides survive. SQLite and PostgreSQL settled this long ago: derive on read, store only for overrides or heavy read performance.
#python#sqlite#postgresql