Commit Graph
28 Commits
Author SHA1 Message Date
BFE EngineeringandClaude Fable 5 2756de0b46 review: iteration-1 fixes across CI, bridge, VM harness, and docs
CI/pipeline:
- KERNEL_TARBALL passed as a YAML env literal '~' was never tilde-expanded
  and would have failed every hosted kernel-build dispatch; the path is now
  exported from the shell. Verified reproducible before the fix.
- Every job gets timeout-minutes; boot smoke uses timeout -k so a wedged
  qemu is SIGKILLed instead of holding the job.
- Tarball fetch + fail-closed sha256 verification deduplicated into
  build/fetch-kernel-tarball.sh (with curl retries), used by build-kernel.sh
  and both CI jobs. busybox fetch gains retries too.
- ccache layer for kernel-build (cache keyed on defconfig+patches) recovers
  the incremental-compile speed the ephemeral-runner move cost.
- build-kernel.sh now asserts every fragment option survived olddefconfig —
  merge_config -m pastes text and Kconfig silently drops unmet symbols.

rs485-bridge:
- pending-buffer cap (2x max RTU ADU) instead of unbounded growth;
  explicit accept-loop error handling with backoff instead of .flatten();
  per-arm inline bounds instead of the string-keyed lookup whose default
  would have mis-bounded a future get-input; control-socket cleanup errors
  surfaced; flag-shaped values rejected in arg parsing; doc example uses a
  private mktemp dir. Test timing margins widened for contended runners
  (gap 25->120ms, 60x margin on the split-frame test).

VM harness:
- stage-1/stage-2 boot scripts share one validated slot parser and one
  by-name populator (qemu/rootfs/etc/warden-lib.sh) — the duplicated
  parser had already diverged on validation; userdata/oem mount failures
  now fail fast with a greppable sentinel; udhcpc fallback keys off the
  interface actually having an address; switch_root applet guarded.
- boot-smoke delegates the qemu invocation to run.sh (machine shape lives
  in ONE place); run.sh port 0 disables a hostfwd.
- mkimage: unknown partition names fail at build time; DISK_END is a max,
  not last-entry; --state keys validated as filenames.
- portal-scenario: mock readiness is asserted (no silent fall-through),
  hostfwd port collisions retried, mount-failure sentinel fails fast.
- ui-shot: fixed sleeps replaced with bounded screendump polling; the
  repaint assertion is real and documented as such. qmp.py loses its
  module-global and gains argv validation.

Docs/scrub: bench-host paths and the site AP name removed from six more
port docs and two evidence tables; path-bearing build artifacts (.elf,
.map) untracked (the 154-byte firmware .bin is path-free and stays);
ADR-0003 marked visibility-superseded by ADR-0007; stale section
cross-reference fixed; flare-edge noted as private for outside readers;
stale root-level review report removed per the new workspace rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HUayid7W5w7jBdb9Rrj1K
2026-08-30 08:19:17 -06:00
BFE EngineeringandClaude Fable 5 5155224594 public-readiness: scrub internal details, split licensing, hosted kernel-build
Preparing the repo to go public (ADR-0007):

- CI: kernel-build moves from the self-hosted runner to ubuntu-latest
  (installs its own cross toolchain + qemu, caches the pristine tarball).
  On a public repo a registered self-hosted runner is reachable from
  approved fork-PR workflows — i.e. arbitrary code on private
  infrastructure — and the build never actually needed the SDK host.
  ADR-0004 marked superseded-in-part; docs/ci-cd.md rewritten (site
  specifics now live only in the private deployment log).
- Licensing: LICENSE gains the GPL-2.0 carve-out for patches/ and the
  kernel source excerpts (Linux derivatives; per-driver provenance was
  already tracked in PROVENANCE.md); patches/README.md states it too.
- Scrubbed from the tip: bench-unit dev credentials and its gadget IP
  (m2-boot notes), the site AP SSID+BSSID and a neighboring AP's BSSID
  and the device WLAN MAC (wifi bring-up evidence — BSSIDs are
  geolocatable), the runner mesh IP. NOTE: these remain in git history;
  decision on a pre-publication history rewrite is separate.
- Emoji cleanup across 21 tracked files (kernel port docs, review report,
  enforce-mcdc.sh) per repo text conventions: status marks became
  [x]/[wip]/[ ]/OK plain text.
- "[maintainer]-gated" process phrasing normalized to "maintainer-gated"
  (attributions in dated evidence docs kept).

Verified: zero emojis tracked; scrub grep clean; patches carry no internal
references; ci.yml parses; shellcheck unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HUayid7W5w7jBdb9Rrj1K
2026-08-30 07:25:57 -06:00
BFE EngineeringandClaude Fable 5 c7e06514ad qemu: RS485 bridge to sim, portal E2E scenario, CI wiring
Phase 3 of the device sim, all verified on QEMU 10.0.11:

- qemu/rs485-bridge/: std-only crate bridging a QEMU serial chardev (unix
  socket) to warden_sim::ModbusSlave — gap-based RTU framing (CRC failures
  degrade to real-slave silence), line-protocol control socket for register
  seeding and fault injection (drop/exception/clear), bounds-checked so a
  scenario typo answers err instead of panicking the bus. 7 unit tests,
  bench in the sim_bench pattern. Verified end-to-end: guest master frame
  on /dev/ttyS4 (pci-serial) answered from the sim slave, CRC-correct.
- virt machine gains highmem=off: the 32-bit non-LPAE kernel cannot reach
  virt's default 40-bit PCIe ECAM (pci-host-generic EOVERFLOW); with it the
  full PCI set probes (16550A ttyS0, i6300esb).
- Watchdog scenario verified: guest arms /dev/watchdog, no petting, i6300esb
  resets the VM ~30s later (first environment where this arm is testable).
- qemu/tests/portal-scenario.sh: the real static-musl warden-flared inside
  the VM against flare-edge's mock portal on the host — authenticated
  check-in, firmware desired-state pull, and download of a real signed
  tier-1 .wfw offer, asserted from the portal log. Found and filed
  flare-edge#106 (fatal SIGBUS in the HPMCU boot-loaded probe on
  non-RV1106 memory maps); runs against a flared built from the
  qemu-vm-support fix branch.
- stage-2 init: WARDEN_FLARE_INSECURE=1 + WARDEN_HPMCU=0 (documented VM
  deviations), firmware-version stamp, newline-terminated state seeds.
- CI: rs485-bridge joins the test loop and bench job; new qemu-tools job
  (shellcheck + initramfs + disk image on hosted runners); kernel-build
  gains a fail-closed qemu boot-smoke step. All qemu scripts shellcheck-clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HUayid7W5w7jBdb9Rrj1K
2026-08-29 19:59:44 -06:00
BFE Engineering 0833d61bfa ci: automatic artifact GC for kernel builds (account-wide storage)
Mirror flare-edge's artifact GC so the shared Actions storage quota can't fill
from either repo. A new prune-artifacts job (ubuntu, gh + built-in token,
actions:write) runs before the kernel-build upload and deletes older
kernel-rv1106 artifacts beyond the newest 3; kernel-build needs it. retention-days
14 -> 5 as the backstop. Best-effort so it never blocks a build. Completes the
account-wide auto-clear (an over-quota once blocked ALL runs, not just uploads).
2026-08-26 10:44:48 -06:00
github-actions[bot] 3764d1d7e8 ci: update loc/tests/coverage badges [skip ci] 2026-08-26 00:10:48 +00:00
github-actions[bot] 40a61b5e62 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 23:17:26 +00:00
BFE EngineeringandClaude Opus 4.8 a804a35e08 ci: kernel-build artifact upload is best-effort (storage-quota resilience)
The kernel build itself is the gate; uploading the zImage/dtb can fail on an
account-wide GitHub artifact-storage-quota hit unrelated to the build. Mark the
upload continue-on-error so a good build isn't red-X'd by it. Outputs also remain
on the self-hosted runner host.

Verified: kernel-build compiled the RV1106 6.18.46 kernel end-to-end on
bfe-mpc-0640 (zImage 8.25 MB + rv1106-warden.dtb 37 KB); the patch series applied
(issue #1 fix confirmed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 17:16:36 -06:00
BFE EngineeringandClaude Opus 4.8 5e1b02ba60 kernel-build: apply patches outside the checkout + fail-loud sentinel (#1)
The kernel-build job set WORK inside the repo checkout, so build-kernel.sh's
`git apply` ran from a subdirectory of the warden-sdk git repo — where git apply
silently ignores out-of-subdir paths and exits 0 without applying anything. The
build then failed at the (never-created) rv1106-warden.dtb target, and the
unconditional `echo "applied"` had masked it.

- ci.yml: WORK -> ${{ runner.temp }}/kbuild-out (outside the checkout); artifact
  paths follow.
- build-kernel.sh: the patch loop now fails loudly instead of echoing on silent
  failure, and a post-apply sentinel assert (rv1106-warden.dts must exist) makes a
  silent no-op impossible to ship — the regression guard for this class.

Refs #1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 16:55:46 -06:00
github-actions[bot] cb26739164 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 22:28:04 +00:00
BFE EngineeringandClaude Opus 4.8 5a9432b8bc ci: self-provision python + cross toolchain in kernel-build job
Make the self-hosted kernel-build runnable with zero manual toolchain/python setup
on the runner host (docs/ci-cd.md steps 3-4 move into the workflow):

- build/build-kernel.sh: honor a caller-provided CROSS_COMPILE (default stays the
  Luckfox uclibc prefix). The kernel is freestanding, so a generic arm cross
  compiler links it.
- kernel-build job: set CROSS_COMPILE=arm-linux-gnueabihf- (Debian
  gcc-arm-linux-gnueabihf, already on 0640) instead of depending on the ephemeral
  SDK checkout path; symlink python->python3 into $RUNNER_TEMP/bin on $GITHUB_PATH
  for the bare-`python` SDK quirk.
- docs/ci-cd.md: only steps 1-2 (systemd service + cgroup cap) still need 0640 sudo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 16:27:21 -06:00
BFE EngineeringandClaude Opus 4.8 4f060db1b1 ci: make main the canonical branch (badges guard, docs)
Point the badges job's branch guard at refs/heads/main and update the README /
ci-cd docs to name main as the canonical branch, ahead of establishing main from
bringup as the SDK's first main commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 16:18:36 -06:00
github-actions[bot] 620a21928d ci: update loc/tests/coverage badges [skip ci] 2026-08-25 22:06:24 +00:00
github-actions[bot] aa47a537c2 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 22:02:56 +00:00
github-actions[bot] c23de76ccc ci: update loc/tests/coverage badges [skip ci] 2026-08-25 21:49:36 +00:00
BFE EngineeringandClaude Opus 4.8 4ee4dfcf88 review: fix review findings (correctness, hardening, doc-accuracy)
First recursive code-review-harness pass over the authored SDK code (sim/,
config-lint, flowgen, drivers/{relays,freshness}, build/, ci.yml). Four parallel
dimension reviewers; all findings at every severity corrected per workspace rule.

Correctness / reliability:
- freshness.c min_budget_ms: use a `seen` flag, not `best==0`, as the empty
  sentinel — a zero-tolerance (max_stale_ms==0) binding was silently widened to a
  looser neighbour's budget. Regression test added; still 66/66 MC/DC.
- config-lint parse_reserved_ranges: match `reg` as a whole property token (ident
  boundary before, `=` after) so `reg-names` / a `region-*` label no longer
  mis-parses into a bogus reserved range.
- config-lint loader check: fail closed — flag any loader with a LOAD_ADDR that is
  not a known-safe boot component, instead of only known MCU names, so a future
  coprocessor ("Rtos"/"Bl32") can't slip past the 0x40000-brick gate.
- build-kernel.sh: sha256 verification is now mandatory (refuse to build if the pin
  is missing) and the mktemp scratch tree is removed on exit (trap), while a
  caller-provided WORK is left intact for CI artifact upload.

Test quality:
- freshness: added the age==max_stale boundary case and a clock-wraparound
  (now < last_ok) fail-safe-to-UNKNOWN test.
- relays: unsetenv(WARDEN_GPIO_ROOT) at main() so the NULL-env arm is hermetic.

Security / CI:
- ci.yml: top-level `permissions: contents: read` (badges overrides to write);
  pin taiki-e/install-action to commit SHA (v2.86.7).

Maintainability / docs:
- drivers/enforce-mcdc.sh: one shared, name-derived gate replaces the two
  copy-pasted per-driver scripts; Makefiles call ../../enforce-mcdc.sh.
- docs/architecture.md: §3/§4/§6/§7 rewritten to match reality — NPU/RGA models,
  config-lint, and the relays+freshness MC/DC harnesses are done; kernel §6 now
  reflects the 5.10->6.18.46 forward-port (ADR-0001), not the superseded plan44/6.6.
- README: status blurb + layout table corrected (kernel/, .github/; stale ci/ and
  patches/ descriptions fixed). hpmcu "8 tests" -> 7 in docs.
- freshness.{c,h}: ADR reference points at flare-edge ADR-0004 (warden-sdk's
  ADR-0004 is the CI runner — number collision).
- normalize rustfmt drift across sim/ + config-lint.

All green: sim 37 tests, config-lint 8 tests, both drivers 100% MC/DC (relays
40/40, freshness 66/66), clippy clean under -D warnings, gitleaks clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 15:48:52 -06:00
github-actions[bot] 75ff711e43 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 21:23:54 +00:00
github-actions[bot] c7c1c70219 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 21:19:41 +00:00
github-actions[bot] e07db1d87e ci: update loc/tests/coverage badges [skip ci] 2026-08-25 20:32:29 +00:00
BFE EngineeringandClaude Opus 4.8 289ce7f42f ci: self-hosted warden-sdk runner registered + docs/ci-cd.md (P5)
Registered a 3rd repo-scoped runner on bfe-mpc-0640 (label warden-sdk,
bfe-mpc-0640-warden-sdk) per ADR-0004. It is offline pending the sudo-gated steps
(service install + CPUQuota/MemoryMax cgroup cap + toolchain/python provisioning),
documented in docs/ci-cd.md as a [maintainer] handoff. kernel-build stays dispatch-gated
and passes JOBS=4 as a belt-and-braces resource bound.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 14:31:29 -06:00
github-actions[bot] 9621af6ab0 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 20:27:07 +00:00
BFE EngineeringandClaude Opus 4.8 f2a9c0a32c kernel: RV1106 6.18.46 patch series + hermetic build wrapper (P1)
- patches/: the pristine-6.18.46 -> WardenOS delta as a 13-patch, subsystem-split
  series (223 files, ~136K lines: clk, pinctrl, DTs/mach, usb-phy, VOP/panel/rgb,
  mailbox, pvtm, rknpu, rga, aic8800 wifi, audio codec, thermal/rtc/adc/gmac/touch).
  Verified: every patch applies cleanly onto pristine (git apply --check), the full
  series reproduces the hardware-verified tree, and the applied source configures +
  builds the warden dtb + rockchip DRM drivers (rc=0).
- build/build-kernel.sh: fetch+verify pristine (sha256-pinned) -> apply series ->
  warden_defconfig -> zImage + rv1106-warden.dtb. build/warden_defconfig captured.
- CI: `patches-apply` (GitHub-hosted, cached tarball) enforces the series applies;
  `kernel-build` (self-hosted warden-sdk runner, dispatch-gated until registered)
  runs the full build and uploads the image.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 14:26:04 -06:00
github-actions[bot] c7ff63b3f6 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 20:16:15 +00:00
BFE EngineeringandClaude Opus 4.8 6fcfb80e5a bench: dependency-free sim micro-benchmarks + CI bench job (P4)
benches/sim_bench.rs (harness=false, zero deps): fixed-iteration ns/op timing for
hpmcu_tick, cru_poll, modbus_read_holding, rga_improcess, membus_poke_peek. Human
timings to stdout, one JSON trend line per bench to stderr for CI capture. New CI
`bench` job smoke-runs them. Regression-vs-history gating is future work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 14:15:22 -06:00
github-actions[bot] a6b60c2484 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 20:13:02 +00:00
github-actions[bot] d27bb7151d ci: update loc/tests/coverage badges [skip ci] 2026-08-25 20:02:27 +00:00
BFE EngineeringandClaude Opus 4.8 1752dea7b6 drivers/relays: hardened + 100% MC/DC (Tier-1, first driver)
Bring relays.c into warden-sdk/drivers/ behind a relay_io seam (ADR-0005): the
sysfs plumbing is an injectable backend, the gpio root is $WARDEN_GPIO_ROOT-
overridable. Host harness (drivers/relays/test/) reaches 100% MC/DC (40/40
conditions, 100% lines) by combining fake-io unit tests (logic branches incl.
export->node-appears) with real-sysfs integration tests over a scratch tree
(backend fopen/stat branches). CI `mcdc` job enforces 100% across drivers/*/test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 14:01:29 -06:00
github-actions[bot] d4acc9f3b3 ci: update loc/tests/coverage badges [skip ci] 2026-08-25 19:54:49 +00:00
BFE EngineeringandClaude Opus 4.8 1d3298a408 ci: GitHub Actions pipeline — cargo test + llvm-cov + badges (P5 host-testable jobs)
test job runs cargo test across sim + config-lint and cargo-llvm-cov line coverage
on the sim crate; badges job renders loc/tests/coverage shields on push to bringup
([skip ci] + paths-ignore loop guard). mcdc/bench/kernel-build jobs land with
P2/P4/P1. README carries the CI + badge row.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017wB8KB3MMQztRDXCMCkPrf
2026-08-25 13:48:22 -06:00