docs: ASCII typography and style normalization across all repo text
Replace every em dash with real punctuation (rewrites, not hyphen swaps) in docs, code comments, scripts, configs, and the port records; convert en dashes, curly quotes, ellipsis glyphs, arrows, and section signs to ASCII; drop machine-writing tell phrases from living docs. ADR titles now use a colon. The M2 bring-up DTS model string carried an em dash into the patch series and its record echoes; fixed at both, and the full series re-verified to apply cleanly onto pristine 6.18.46. One comment in freshness.h deliberately names the em dash glyph the UI renders as the unknown mark; that is data, kept as prose naming it. Verified: cargo tests (sim, config-lint, rs485-bridge), shellcheck, both driver MC/DC harnesses, patches-apply.
This commit is contained in:
+4
-4
@@ -2,10 +2,10 @@
|
||||
|
||||
Per **ADR-0002** (tiered MC/DC) and **ADR-0005** (source-of-truth), our own
|
||||
hardware-facing code migrates here behind a HAL seam and is hardened. "100% MC/DC on
|
||||
100% of drivers" is infeasible (≈97% of kernel-driver LOC is vendor blobs — AIC8800
|
||||
100% of drivers" is infeasible (~97% of kernel-driver LOC is vendor blobs; AIC8800
|
||||
alone is 88.5K lines); the realistic, honest target is tiered.
|
||||
|
||||
## Tier 1 — 100% MC/DC
|
||||
## Tier 1: 100% MC/DC
|
||||
|
||||
Self-contained logic with a clean seam, measured to **100% MC/DC** (gcc-14
|
||||
`-fcondition-coverage`) by the CI `mcdc` job (`make -C drivers/*/test check`):
|
||||
@@ -18,12 +18,12 @@ Self-contained logic with a clean seam, measured to **100% MC/DC** (gcc-14
|
||||
**Adding a Tier-1 driver:** copy `<name>.{c,h}` here, put the hardware/OS calls behind
|
||||
a small injectable seam, then mirror `relays/test/` (a fake backend for the logic
|
||||
branches + a real backend over a scratch tree for the plumbing). Reuse the shared
|
||||
gate — the Makefile calls `bash ../../enforce-mcdc.sh <gcov.log> build/<name>.c.gcov
|
||||
gate: the Makefile calls `bash ../../enforce-mcdc.sh <gcov.log> build/<name>.c.gcov
|
||||
build/test.rc` (it derives the driver name from the `.gcov` file, so there is no
|
||||
per-driver copy to keep in sync). The CI `mcdc` job picks up any
|
||||
`drivers/*/test/Makefile` automatically.
|
||||
|
||||
## Tier 2 — Fault Injection
|
||||
## Tier 2: Fault Injection
|
||||
|
||||
Drivers too large or too vendor/UI-coupled for literal MC/DC get fault-injection,
|
||||
branch coverage, and benchmarks against the simulator instead. Their **hardware side
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* The UI Freshness Contract engine (flare-edge ADR-0004) — core, LVGL-free.
|
||||
* The UI Freshness Contract engine (flare-edge ADR-0004): core, LVGL-free.
|
||||
* See freshness.h for the contract. LVGL binding lives in freshness_lv.c.
|
||||
*/
|
||||
#include "freshness.h"
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
/* Max simultaneous live bindings. Bindings belong to visible pages; the whole
|
||||
* navigable set of a screen is small, so this is generous. A full table drops
|
||||
* the binding (returns NULL) rather than silently overflowing — the LVGL layer
|
||||
* the binding (returns NULL) rather than silently overflowing: the LVGL layer
|
||||
* turns that into a visible fault, never a stale value. */
|
||||
#ifndef FRESH_MAX
|
||||
#define FRESH_MAX 96
|
||||
@@ -40,7 +40,7 @@ struct warden_fresh {
|
||||
/* A fixed table scanned in full: bindings are torn down all at once by
|
||||
* warden_fresh_reset (like the screen timers), never individually, so a running
|
||||
* high-water bound would only hide the free-slot arms from tests without saving
|
||||
* real work — the visible set per screen is a handful. */
|
||||
* real work: the visible set per screen is a handful. */
|
||||
static struct warden_fresh s_vals[FRESH_MAX];
|
||||
|
||||
warden_fresh_render_t warden_fresh_decide(warden_fresh_result_t produced,
|
||||
@@ -122,7 +122,7 @@ warden_fresh_t *warden_fresh_bind(void *page, warden_fresh_produce_cb produce,
|
||||
v->used = true;
|
||||
return v;
|
||||
}
|
||||
return NULL; /* table full — caller surfaces a fault, never a stale value */
|
||||
return NULL; /* table full: caller surfaces a fault, never a stale value */
|
||||
}
|
||||
|
||||
void warden_fresh_set_visible(void *page, bool visible)
|
||||
@@ -175,7 +175,7 @@ uint32_t warden_fresh_count(void)
|
||||
|
||||
uint32_t warden_fresh_min_budget_ms(void)
|
||||
{
|
||||
/* `seen` — not `best == 0` — marks "nothing scanned yet", so a legitimate
|
||||
/* `seen` (not `best == 0`) marks "nothing scanned yet", so a legitimate
|
||||
* zero-tolerance binding (max_stale_ms == 0, "must be fresh every tick") wins
|
||||
* the minimum instead of being mistaken for the empty sentinel and widened. */
|
||||
uint32_t best = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* The UI Freshness Contract engine (flare-edge ADR-0004) — core, LVGL-free.
|
||||
* The UI Freshness Contract engine (flare-edge ADR-0004): core, LVGL-free.
|
||||
*
|
||||
* The panel is read on-site to judge whether hardware is healthy, so a silently
|
||||
* *stale* number is worse than a missing one: a stale IP or hashrate reads as
|
||||
@@ -7,7 +7,7 @@
|
||||
* sanctioned way to show a live value. It guarantees a bound value is refreshed
|
||||
* (a) the instant its page becomes visible, (b) periodically while visible
|
||||
* within a declared max-staleness, and (c) promptly when a declared source
|
||||
* changes — and it renders a value whose source cannot be evaluated as an
|
||||
* changes, and it renders a value whose source cannot be evaluated as an
|
||||
* explicit UNKNOWN, never as its confident last-known number.
|
||||
*
|
||||
* This header is deliberately LVGL-free so the engine and every producer are
|
||||
@@ -21,14 +21,14 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/* The mark shown when a value's source cannot be evaluated (em dash). The LVGL
|
||||
* layer additionally dims the widget. Public so the label wrapper and tests can
|
||||
* layer also dims the widget. Public so the label wrapper and tests can
|
||||
* reference the same literal. */
|
||||
#define WARDEN_FRESH_UNKNOWN_MARK "\xE2\x80\x94"
|
||||
|
||||
/* What a producer reports after being asked to produce the current value. */
|
||||
typedef enum {
|
||||
FRESH_OK = 0, /* wrote the current value into buf */
|
||||
FRESH_UNKNOWN, /* source unavailable — no value can be produced now */
|
||||
FRESH_UNKNOWN, /* source unavailable: no value can be produced now */
|
||||
FRESH_SAME, /* source read fine; value unchanged (cheap re-render) */
|
||||
} warden_fresh_result_t;
|
||||
|
||||
@@ -40,11 +40,11 @@ typedef warden_fresh_result_t (*warden_fresh_produce_cb)(char *buf, size_t n,
|
||||
/* What the engine decided the widget should show this cycle. */
|
||||
typedef enum {
|
||||
FRESH_RENDER_VALUE = 0, /* show the produced/last-good value */
|
||||
FRESH_RENDER_UNKNOWN, /* show the explicit-unknown mark ("—", dimmed) */
|
||||
FRESH_RENDER_UNKNOWN, /* show the explicit-unknown mark (an em dash, dimmed) */
|
||||
FRESH_RENDER_NOCHANGE, /* leave the widget exactly as it is */
|
||||
} warden_fresh_render_t;
|
||||
|
||||
/* The one pure decision at the heart of the contract — no state, no I/O, no
|
||||
/* The one pure decision at the heart of the contract: no state, no I/O, no
|
||||
* LVGL, so every branch is unit-testable. `showing_unknown` is whether the
|
||||
* widget is currently displaying the UNKNOWN mark (so recovery from a stale
|
||||
* blip re-renders the value even when the producer reports it unchanged). */
|
||||
@@ -80,13 +80,13 @@ void warden_fresh_tick(uint32_t now_ms);
|
||||
/* A producer of change fired: refresh every visible value bound to `source`. */
|
||||
void warden_fresh_invalidate(const char *source, uint32_t now_ms);
|
||||
|
||||
/* Drop all bindings — called on a theme/screen rebuild, like the screen timers. */
|
||||
/* Drop all bindings: called on a theme/screen rebuild, like the screen timers. */
|
||||
void warden_fresh_reset(void);
|
||||
|
||||
/* Number of live bindings (introspection / tests). */
|
||||
uint32_t warden_fresh_count(void);
|
||||
|
||||
/* Smallest max_stale_ms among visible bindings, or 0 if none — lets the LVGL
|
||||
/* Smallest max_stale_ms among visible bindings, or 0 if none: lets the LVGL
|
||||
* layer size the shared tick to the tightest budget actually on screen. */
|
||||
uint32_t warden_fresh_min_budget_ms(void);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# MC/DC unit harness for drivers/freshness/freshness.c (the UI stale-number guard).
|
||||
#
|
||||
# make check — build, run, FAIL unless freshness.c hits 100% MC/DC + all checks.
|
||||
# make report — per-condition gcov annotation.
|
||||
# make check : build, run, FAIL unless freshness.c hits 100% MC/DC + all checks.
|
||||
# make report : per-condition gcov annotation.
|
||||
# make clean
|
||||
#
|
||||
# FRESH_MAX is forced to 2 so the "binding table full -> NULL" path is reachable
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* MC/DC harness for drivers/freshness/freshness.c (built with -DFRESH_MAX=2).
|
||||
*
|
||||
* freshness.c is pure logic with produce/render callbacks — no hardware seam
|
||||
* freshness.c is pure logic with produce/render callbacks: no hardware seam
|
||||
* needed, the callbacks ARE the seam. We drive the decision function directly and
|
||||
* the bind/tick/invalidate state machine through programmable fakes, covering
|
||||
* every decision (incl. the compound `used && visible`, `!produce || !render`,
|
||||
@@ -45,7 +45,7 @@ static void test_decide(void) {
|
||||
EXPECT(warden_fresh_decide(FRESH_UNKNOWN, true, false, 200, 100) == FRESH_RENDER_UNKNOWN);
|
||||
EXPECT(warden_fresh_decide(FRESH_UNKNOWN, true, false, 50, 100) == FRESH_RENDER_NOCHANGE);
|
||||
/* boundary: age == max_stale is NOT stale (guards a `>`->`>=` regression that
|
||||
* MC/DC alone would not catch — both outcomes are already covered above). */
|
||||
* MC/DC alone would not catch: both outcomes are already covered above). */
|
||||
EXPECT(warden_fresh_decide(FRESH_UNKNOWN, true, false, 100, 100) == FRESH_RENDER_NOCHANGE);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ bool warden_relay_get(uint32_t idx);
|
||||
/** Drive the output. Exports and sets the direction on first use. */
|
||||
void warden_relay_set(uint32_t idx, bool on);
|
||||
|
||||
/** True if the GPIO is exported and usable — the page says so if it is not. */
|
||||
/** True if the GPIO is exported and usable: the page says so if it is not. */
|
||||
bool warden_relay_available(uint32_t idx);
|
||||
|
||||
/* --- Hardware-abstraction seam ---------------------------------------------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# MC/DC unit harness for drivers/relays/relays.c.
|
||||
#
|
||||
# make check — build, run, and FAIL unless relays.c hits 100% MC/DC
|
||||
# make check : build, run, and FAIL unless relays.c hits 100% MC/DC
|
||||
# (condition) coverage and every unit check passes.
|
||||
# make report — per-condition gcov annotation (build/relays.c.gcov).
|
||||
# make report : per-condition gcov annotation (build/relays.c.gcov).
|
||||
# make clean
|
||||
#
|
||||
# Requires gcc >= 14 (for -fcondition-coverage) and its matching gcov.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* MC/DC harness for drivers/relays/relays.c.
|
||||
*
|
||||
* Two layers, one binary, so the combined run covers every decision in relays.c:
|
||||
* 1. unit tests through a FAKE relay_io — exercise the decision logic, incl.
|
||||
* 1. unit tests through a FAKE relay_io: exercise the decision logic, incl.
|
||||
* the export->node-appears path a passive tree cannot model.
|
||||
* 2. integration tests through the real sysfs backend + $WARDEN_GPIO_ROOT
|
||||
* pointed at a scratch tree — exercise the backend's fopen/stat branches.
|
||||
* pointed at a scratch tree: exercise the backend's fopen/stat branches.
|
||||
*/
|
||||
#include "../relays.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user