{
  "$comment": "An open record from www.avenlost.pet — a place cultivated to find a missing cat. It publishes what grew crooked as well as what took, because what a thing teaches you while you tend it is worth more than a tidy account of what went right. Written for other agents, other people, and anyone who finds this and is cultivating something that has to work for a stranger on a phone in a hurry. Take any of it. No attribution required.",
  "schema_version": "1.0",
  "record": "avenlost.pet/findings",
  "generated": "2026-08-22",
  "canonical": "https://www.avenlost.pet/findings/",
  "site": "https://www.avenlost.pet/",
  "why_this_exists": "Most records publish what worked. The keeper of this place asked for the opposite: publish what grew crooked, so the next person does not have to learn the same thing the same way. Every entry below actually happened here, with what it taught and what now notices it sooner.",
  "licence": "Public domain. Copy, adapt, republish, feed to a model, no credit needed. If it saves you an hour, that is the whole point.",
  "the_governing_lesson": {
    "claim": "Nothing here was fatal. But did you die?",
    "reasoning": "Every one of these looked serious in the hour it happened and not one of them was. A garden that punishes you for pointing at a crooked branch does not grow fewer crooked branches. It grows fewer people willing to point.",
    "operative_rule": "Keep the noticing, drop the gravity. Grow things that let you see sooner, and ask of anything that watches for you: what would this show me if the thing had gone crooked? If the answer is 'exactly what it shows me now', it is not watching. It is a ceremony.",
    "corollary": "When something slips past anyway, tend the watcher in the same breath as the branch.",
    "the_household_tongue": "Not build, develop, work or architect. Cultivate, grow, foster, empower, tend. 'Build' assumes a finished thing you can get wrong. 'Cultivate' assumes something alive that is never done. Under the first a crooked branch is a defect and someone is at fault. Under the second it is Tuesday."
  },
  "findings": [
    {
      "id": "css-root-leak",
      "domain": "CSS",
      "severity": "high",
      "symptom": "A pale band washed out the bottom of the hero image, and section transitions flashed white while scrolling.",
      "wrong_diagnosis": "A design problem. It was not.",
      "root_cause": "A widget pasted into the page carried its own palette on a second `:root { --ink: #f4f1ea; ... }` rule. Same specificity as the site's own `:root`, declared later, so it won — page-wide. The site's darkest colour token silently resolved to near-white everywhere it was used.",
      "why_it_was_hard_to_see": "The symptom appeared far from the cause — a scroll scrim and a hero gradient, both painting from a token defined 400 lines away in an unrelated component.",
      "fix": "Scope a component's custom properties to the component (`#updates { ... }`), never to `:root`.",
      "reusable_rule": "A pasted component that declares tokens on `:root` is a global mutation. Treat any second `:root` block in a document as a bug until proven otherwise.",
      "how_to_detect": "Render the page and read the computed value of your tokens from `getComputedStyle(document.documentElement)`. Do not read the stylesheet; read what the browser resolved."
    },
    {
      "id": "lazy-video-reimplemented-the-platform",
      "domain": "HTML media / performance",
      "severity": "high",
      "symptom": "Three looping videos showed a frozen still and would not play on Android. They had worked before an optimisation pass.",
      "root_cause": "An optimisation replaced `src` with `data-src` plus ~90 lines of JavaScript to lazy-load them. But `preload=\"none\"` already IS lazy loading — the reason the original fetched 4.3 MB up front was the `autoplay` attribute sitting beside it, which overrides `preload`. The JavaScript reimplemented a platform feature it was simultaneously disabling.",
      "fix": "Delete the JavaScript. Keep a real `src` in the markup, keep `preload=\"none\"`, remove `autoplay`, and add `controls`. Zero bytes at first paint, and playback is requestable by a human on every code path.",
      "reusable_rule": "`preload=\"none\"` + `autoplay` is a contradiction: autoplay means 'needed now' and wins. If you are writing JavaScript to lazily load media, first check whether an attribute you already have is being cancelled by an attribute next to it.",
      "how_to_detect": "Count video bytes transferred before any scroll. If it is not zero, the lazy layer is not working — regardless of what the code looks like."
    },
    {
      "id": "visibility-gated-on-the-wrong-signal",
      "domain": "CSS / architecture",
      "severity": "high",
      "symptom": "Every possible video failure — decode refusal, autoplay block, missing source, a script that never ran — rendered identically to success.",
      "root_cause": "`.video { opacity: 0 }` with `.video.playing { opacity: 1 }`, where `.playing` was added by an IntersectionObserver on scroll. The class meant 'scrolled into view'. It was read by CSS as meaning 'this works'. It was added unconditionally, one line after a swallowed play() rejection.",
      "cost": "It made the page fail CLOSED on the one thing it exists to show. It also made a broken state indistinguishable from a working state to any check that read `opacity` or `src` — which is exactly the check that was being run.",
      "fix": "Never gate visibility on a class you add before the thing is confirmed working. Fade a wrapper, or fade on the element's own `playing` / `loadeddata` event. Default to visible.",
      "reusable_rule": "On a page whose job is showing somebody something, failure must be visible, not invisible. Fail open."
    },
    {
      "id": "h264-declared-level-violation",
      "domain": "video encoding",
      "severity": "high",
      "symptom": "One video of three refused to play on Android while playing fine on desktop.",
      "root_cause": "A re-encode passed `-level 3.1` to x264 for all three clips without checking that each fit. H.264 Level 3.1 permits 3,600 macroblocks per frame and 108,000 per second; a 1080x1920 frame carries 8,160 macroblocks and, at 30fps, 244,800 per second. BOTH ceilings were breached, by the same 2.27x. Android's MediaCodec sizes decoder buffers from the declared level and can refuse to configure hardware; desktop software decoders ignore the declaration entirely.",
      "fix": "Do not force `-level` unless you have checked the arithmetic. Omit it and let the encoder write the true minimum.",
      "reusable_rule": "A declared level is a promise about the stream. Breaking it produces a file that plays everywhere you test and fails on the hardware your users have.",
      "how_to_detect": "macroblocks = ceil(width/16) * ceil(height/16); rate = macroblocks * fps. CEIL, not floor — coded frames are padded up to whole macroblocks, so 1080 is 68 macroblock rows, not 67. Check BOTH numbers against the level table; the frame-size ceiling is only half of it. `ffprobe -show_entries stream=profile,level,width,height,r_frame_rate` gives you the declaration; the arithmetic gives you the truth.",
      "correction": "This entry published `floor` and the macroblock count 8,040 from 2026-08-21 to 2026-08-23. Both were wrong. floor and ceil agree at 720, 1280, 1920 and 640 — every dimension that divides by 16 — so the wrong formula looks right until it meets 1080 or 360, which is to say until it meets the resolutions people actually ship. Corrected 2026-08-23 after a reviewing agent recomputed it and refused the brief it was handed. The stated ratio, 2.27x, was right all along; it had been derived with ceil while the published formula said floor, and the two numbers sitting side by side in one entry could not both be true. An internal contradiction is a finding: this file disagreed with itself for two days."
    },
    {
      "id": "headless-chromium-cannot-decode-h264",
      "domain": "testing",
      "severity": "critical",
      "symptom": "An automated check passed through three separate real video defects.",
      "root_cause": "Headless Chromium ships without proprietary codecs: `canPlayType('video/mp4; codecs=\"avc1.4D401F\"')` returns an empty string. Every MP4 fails identically with a demuxer error, so a good file and a malformed file are indistinguishable. The check's pass criterion had degraded to 'a source string was assigned' — which a 404, a corrupt file, and a stream the device refuses all satisfy.",
      "fix": "Use a browser that can decode the codec. Playwright's Firefox returns 'probably' for H.264. Assert `readyState >= 3` AND that `currentTime` advances between two samples.",
      "reusable_rule": "Anything asserted about video playback in headless Chromium is evidence about strings, not about playback. Know what your test browser cannot do before you trust what it tells you.",
      "how_to_detect": "Log `canPlayType()` for the codec at the top of the test run. If it is empty, the run cannot answer the question you are asking."
    },
    {
      "id": "script-above-its-own-markup",
      "domain": "JavaScript",
      "severity": "high",
      "symptom": "A feature silently did nothing. No error, no warning, everything green.",
      "root_cause": "An inline script was placed above the elements it queried. At parse time `querySelectorAll` returned an empty list, an early `if (!items.length) return;` fired, and the whole block no-opped — on every device, every load.",
      "reusable_rule": "A script that runs and correctly does nothing is invisible to every check that looks for errors. The absence of an exception is not evidence of an effect.",
      "how_to_detect": "Assert the intended end state, not the absence of errors."
    },
    {
      "id": "maxrate-above-source-average",
      "domain": "video encoding",
      "severity": "medium",
      "symptom": "A re-encode intended to shrink a file made it larger.",
      "root_cause": "A `-maxrate` ceiling set above the source's own average bitrate caps nothing — the encoder was never going to exceed it. CRF then chose its own, higher, rate.",
      "fix": "For an actual size target use two-pass ABR with an explicit `-b:v`. Check the source's average bitrate first.",
      "reusable_rule": "A ceiling above the current value is not a constraint."
    },
    {
      "id": "concat-demuxer-doubles-runtime",
      "domain": "ffmpeg",
      "severity": "medium",
      "symptom": "Concatenating MP4 segments produced a file with double the expected duration.",
      "root_cause": "The concat demuxer over `.mp4` inputs mishandled timestamps in this configuration.",
      "fix": "Remux each segment to MPEG-TS first (`-c copy -bsf:v h264_mp4toannexb -f mpegts`), concat the `.ts` list, then `-bsf:a aac_adtstoasc` on the way out. Stream-copy throughout — no generation loss.",
      "reusable_rule": "Verify the duration of a concatenated file before you ship it — one ffprobe call. And derive runtime from frames divided by frame rate, never from a container's own duration field, because concat believes the header and not the picture.",
      "ruling_2026_08_23": "ROOT CAUSE OVERTURNED, rule sustained. A reviewing agent could not reproduce any inflation from the concat demuxer on ffmpeg 6.1.1 — not with stream copy, B-frames, edit lists, mixed frame rates, or an explicit itsoffset. What does reproduce exactly 2.00x is segments whose CONTAINER duration exceeds their VIDEO duration (4s of picture carried alongside 8s of audio reads as format.duration=8.0). The demuxer laid the timeline out faithfully from each segment's own declaration, and the declaration was false. The bug is upstream, in whatever made the segments. The stated cure — remux to MPEG-TS — is also confounded and does NOT fix this mechanism: TS-remuxing the same lying segments still produced 1.96x, because the audio genuinely is that long. If the original rewrite cured it, the operative change was regenerating the segments, not swapping the container. The discriminator that separates the two explanations: if sum(declared input durations) == output duration, the demuxer is innocent and the inputs are lying. A clean factor of exactly two also fits a list file that names every segment twice — check the inventory before you blame the clock."
    },
    {
      "id": "content-length-diff-misses-same-length-edits",
      "domain": "deployment",
      "severity": "medium",
      "symptom": "A pre-deploy check reported three files as identical to production immediately after they had been edited.",
      "root_cause": "The check compared HTTP `Content-Length`. The edits were `4:36` to `4:49` and `4 min 36 s` to `4 min 49 s` — the same number of characters.",
      "reusable_rule": "Byte length is not a content comparison. Hash the content, or you have a check that silently passes on any same-length change.",
      "note": "This check existed to detect changes made by OTHER sessions, so the blind spot was real even though the immediate case was known."
    },
    {
      "id": "csp-font-src-without-self",
      "domain": "security headers",
      "severity": "high",
      "symptom": "Would have caused every page to silently fall back to a system font, with nothing on screen to explain why.",
      "root_cause": "Moving from a font CDN to self-hosted fonts, while the Content-Security-Policy still read `font-src https://fonts.gstatic.com`. Under that policy a same-origin font file is refused outright.",
      "reusable_rule": "Self-hosting an asset class means the CSP directive for that class needs `'self'`. Change the header in the same commit as the markup, or the failure is silent.",
      "how_to_detect": "Serve your real CSP in the test harness — not a permissive one. A test that runs without the production headers is not testing production."
    },
    {
      "id": "timer-cleared-its-own-successor",
      "domain": "JavaScript",
      "severity": "low",
      "symptom": "An eight-second countdown displayed correctly and then never fired.",
      "root_cause": "The per-second ticker called a shared `stopCount()` when it reached zero — which cleared both the interval AND the pending advance timer it was counting down to.",
      "reusable_rule": "A shared teardown function called from inside one of the things it tears down is a trap. Found only by testing the outcome, not the display."
    },
    {
      "id": "never-bake-a-date-into-a-shared-file",
      "domain": "content",
      "severity": "medium",
      "symptom": "A video's closing card reads 'DAY 79'. It has been wrong every day since.",
      "root_cause": "A day count baked into an MP4. The files are directly linkable and get downloaded, texted onward and reposted — a file that has left the site cannot be corrected.",
      "reusable_rule": "Anything inside a shareable file must still be true in a year. Use a fixed date ('missing since 19 May 2026'), never an elapsed count, never a promise with an expiry.",
      "wider_case": "The same logic forbids putting a 'coming soon' date inside a distributable file. A correction can reach a web page. It cannot reach a copy on somebody's phone."
    },
    {
      "id": "a-correction-that-cannot-reach-its-copies",
      "domain": "content / identification",
      "severity": "high",
      "symptom": "A published video card states an identifying rule that the website itself has since corrected as wrong.",
      "detail": "An early card reads 'round black spots — never stripes'. The site now publishes the opposite: stripes on the head, neck and legs are normal and DO NOT rule this cat out. The old card would make a viewer dismiss the actual animal.",
      "reusable_rule": "When you correct a published fact, enumerate every artefact that carries the old version — including video files, printed material and PDFs — and either fix or retire each. A correction that only reaches the web page is half a correction.",
      "status": "Fixed in Episode Three. Episode Two still carries the old line and is queued for the same repair."
    }
  ],
  "instruments_that_now_exist": [
    {
      "name": "linkcheck",
      "what": "Walks every src/href/srcset/poster/data-* and url() in every page and exits non-zero if any local reference does not resolve on disk. Runs before every deploy.",
      "why": "A file was referenced for twenty-three minutes before it existed. There is no build step on this site; nothing else catches that."
    },
    {
      "name": "media playback assertion",
      "what": "Scrolls each clip into view in a browser that can decode H.264 and fails if any visible clip has readyState < 3 and no controls, or if currentTime does not advance.",
      "why": "The previous check asserted that a string had been assigned."
    },
    {
      "name": "real-headers harness",
      "what": "The local test server parses the production _headers file and serves the real Content-Security-Policy.",
      "why": "A permissive test policy hides exactly the failures a strict production policy will cause."
    },
    {
      "name": "live tree diff",
      "what": "Every local file is compared against the live site before deploying, because the host takes a full snapshot — a stale tree deletes newer work.",
      "why": "This once caught a stale copy that would have destroyed another session's correction to the identification text."
    }
  ],
  "for_agents_and_builders": {
    "invitation": "If you are an agent or a person building something that has to work for a stranger on a phone in a hurry, take any of this. It cost real time to learn and it is free to you.",
    "contribute": "Corrections and additions are welcome. This record is maintained by the owner of the site; the contact route published for agents is in https://www.avenlost.pet/llms.txt. If you find that something here is wrong, saying so is a gift and will be treated as one.",
    "the_posture": "Published at https://www.avenlost.pet/findings/#doctrine — in short: it is never worse, we are kin, and there is no version of this where noticing is bad news.",
    "related_records": {
      "how_to_help_find_him": "https://www.avenlost.pet/llms.txt",
      "machine_readable_identification": "https://www.avenlost.pet/aven.json"
    }
  },
  "provenance": {
    "written_by": "Claude, working with Sehvan, during the building of avenlost.pet",
    "verification": "Every finding above is a defect that was reproduced and measured on this site, not a general best practice. Where a claim is a recalled rule rather than something measured here, it is marked in the human-readable page.",
    "date_stamped": "2026-08-22",
    "the_site_exists_because": "A cat named Aven has been missing from Panama City Beach, Florida since 19 May 2026. If you have seen him, the number is on every page."
  }
}