<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>byASB — field notes</title>
    <link>https://byasb.com/notes/</link>
    <description>A running, dated record of what shipped on byasb.com and the work behind it.</description>
    <atom:link href="https://byasb.com/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Per-frame normalisation quietly destroys the comparison you needed</title>
      <link>https://byasb.com/writing/fod-false-alarms/</link>
      <guid isPermaLink="false">2026-08-31-per-frame-normalisation-quietly-destroys-the-comparison-you-needed</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>Rescaling each frame's heatmap to span 0–1 looks harmless and is usually one line. But the output no longer answers "how anomalous is this frame" — it answers "which part of this frame is most anomalous relative to the rest of this frame." An empty surface with faint sensor noise gets stretched until its loudest noise pixel reads 1.0. The comparison that mattered — this frame against a known-clear reference — was thrown away before the model was consulted. Normalise against a fixed reference instead.</description>
    </item>
    <item>
      <title>OR-logic adds your false-positive rates; AND-logic multiplies them down</title>
      <link>https://byasb.com/writing/fod-false-alarms/</link>
      <guid isPermaLink="false">2026-08-31-or-logic-adds-your-false-positive-rates-and-logic-multiplies-them-down</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>If any single indicator firing is enough to declare a detection, the false-positive rates of your indicators sum. With several noisy signals, noise wins. Requiring all of them — size AND peak AND not-glare AND persistence — makes those rates multiply instead, which drives them toward zero as long as the conditions are close to independent. On a charging pad, a glint bright enough to pass the size check usually fails the glare check, and one that survives both usually fails persistence because it moves with the light source.</description>
    </item>
    <item>
      <title>Anomaly models on reflective surfaces learn your target's features as background</title>
      <link>https://byasb.com/writing/fod-false-alarms/</link>
      <guid isPermaLink="false">2026-08-31-anomaly-models-on-reflective-surfaces-learn-your-target-s-features-as-background</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>A glossy surface spends the whole dataset-collection period mirroring whatever is above it — car undersides, ceiling lights, general workshop brightness. Those reflections are large, soft-edged and bright, and they appear in most frames labelled normal. The model correctly learns that large soft bright shapes are the expected state. Then a human hand — large, soft-edged, bright — scores as background, while a small dark bolt scores high. The model was not broken. It answered the question the data asked it.</description>
    </item>
    <item>
      <title>You can read the camera and the runtime off a screenshot</title>
      <link>https://byasb.com/writing/fod-false-alarms/</link>
      <guid isPermaLink="false">2026-08-31-you-can-read-the-camera-and-the-runtime-off-a-screenshot</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>A magenta cast across the frame means a NoIR sensor — infrared cut filter removed, so the red channel picks up near-IR it would normally reject. The window chrome around the image identifies the runtime; OpenCV's highgui has a distinctive one. Timestamps moving across successive frames give you the loop rate. On one job that produced Raspberry Pi, Camera Module 3 NoIR, Python on OpenCV, and roughly 1.5 FPS — before reading a line of source. Worth doing early: it rules out every fix the hardware can't actually run.</description>
    </item>
    <item>
      <title>Failing in both directions at once is an architecture signal, not a tuning one</title>
      <link>https://byasb.com/hire/rescue/</link>
      <guid isPermaLink="false">2026-08-31-failing-in-both-directions-at-once-is-an-architecture-signal-not-a-tuning-one</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>A threshold is a single operating point on a curve, so moving it trades one error type for the other. If a detector is simultaneously missing real objects and firing on nothing, there is no point on that curve where you are fine — you are only choosing which way to fail. That is the cheapest diagnostic I know: ask whether both failure modes are present. If they are, stop tuning and go look at how the decision is assembled.</description>
    </item>
    <item>
      <title>Three schematic faults worth checking before you write the firmware</title>
      <link>https://byasb.com/work/energy-meter-firmware/</link>
      <guid isPermaLink="false">2026-08-31-three-schematic-faults-worth-checking-before-you-write-the-firmware</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>From a three-phase energy meter review, all found on paper: an ADuM4151 isolator with channel C wired in the reverse direction, which kills the CF1 output entirely. An oscillator marked 24.567 MHz where 24.576 was intended — a transposed digit, giving a 0.037% systematic over-read that firmware can correct for rather than requiring a respin. And a boot-strap conflict where GPIO12 serves as MISO while also acting as the VDD_SDIO strap, remedied at the efuse level. Reading the schematic first is cheaper than debugging the board it produces.</description>
    </item>
    <item>
      <title>Auditability is structural — you cannot retrofit events you never recorded</title>
      <link>https://byasb.com/writing/telehealth-certification/</link>
      <guid isPermaLink="false">2026-08-31-auditability-is-structural-you-cannot-retrofit-events-you-never-recorded</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>Most application code stores current state and updates in place, because that is what every framework tutorial shows. When a regulator asks for a reconstructable history, the events needed to build one were never written down — not lost, never created. No migration recovers them. That makes retrofitting an audit trail a data-layer rewrite, and everything above the data layer moves with it. In a regulated build, decide what constitutes an event and what is immutable before you draw a single screen.</description>
    </item>
    <item>
      <title>Consent is a versioned event, not a boolean on a profile</title>
      <link>https://byasb.com/writing/telehealth-certification/</link>
      <guid isPermaLink="false">2026-08-31-consent-is-a-versioned-event-not-a-boolean-on-a-profile</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>You will eventually be asked what a specific person agreed to on a specific date — and the wording will have changed since. A flag on the user record cannot answer that. Store consent as an event carrying the version of the text that was shown, the timestamp, and the identity and standing of whoever captured it. The same rule applies to clinical actions generally: bind identity and authority at the moment of the action, because looking it up later gives you today's answer to a question about last year.</description>
    </item>
    <item>
      <title>Retention policy, not camera count, decides edge versus central</title>
      <link>https://byasb.com/tools/video-analytics-tco/</link>
      <guid isPermaLink="false">2026-08-31-retention-policy-not-camera-count-decides-edge-versus-central</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>Per-camera edge inference nearly always looks worse on the capex line, and teams stop there. The number that actually moves the comparison is how long you keep footage and whether you keep all of it. Continuous archival plus sustained upstream bandwidth for every stream compounds every month; event-triggered retention does not. Price three years of both before choosing an architecture — on a 1,400-camera model the answer inverts somewhere in the retention period, not at some threshold camera count.</description>
    </item>
    <item>
      <title>An offline alarm is a queue, a retry, and an escalation — in that order</title>
      <link>https://byasb.com/work/humanitarian-duty-of-care/</link>
      <guid isPermaLink="false">2026-08-31-an-offline-alarm-is-a-queue-a-retry-and-an-escalation-in-that-order</guid>
      <pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate>
      <description>For a panic alarm used by staff deployed into places with no coverage, "send" cannot mean an HTTP call. It means: write the alert to a local durable queue immediately, acknowledge to the user that it is held, retry on every connectivity event rather than on a timer, and escalate through a separate channel once delivered. The user-facing part matters as much as the transport — someone pressing that button needs to know it was captured, not that a request is pending.</description>
    </item>
  </channel>
</rss>
