fix/forgejo-central-ci #30

Merged
faicel merged 10 commits from fix/forgejo-central-ci into dev 2026-09-04 22:19:41 +00:00
Owner
No description provided.
New core::ota module, fully additive (no SigilEvent/SigilError/FrameType
changes), off by default and never implied:

- Shared tier (ota alone): wire codec for command ids 0x10..0x18 under the
  0x7F product envelope, manifest_digest_input/manifest_digest single
  source of truth, local OtaError taxonomy, hand-written golden vectors.
- Receive half (sensor,ota): OtaStorage sink trait, TrailerRecord bootable
  marker, OtaReceiver with contiguous chunks, incremental SHA-256,
  erase-once block bookkeeping, ECDSA-gated finalize via SecureElement,
  STATUS projection, ABORT, idle timeout.
- Send half (gateway,ota): OtaImageSource trait, OtaSender stop-and-wait
  engine with digest preflight, bounded resends, cumulative-ACK progress,
  STATUS-driven resume, REBOOT gated on completion.
- Interop suite drives both engines through the real codec under loss.

Feature-matrix gate extended with ota/sensor,ota/gateway,ota; embedded
cross-checks extended to thumbv6m sensor,ota and armv7 gateway,ota;
empty-set diagnostic accepts the ota-only tooling tier; version 1.2.0;
CHANGELOG, README, CLAUDE.md updated.
Architecture-audit remediation:
- Erase-once bitmap commits each block only after its erase succeeds;
  failed erases retry verbatim while committed blocks are never re-erased
  (shared-block staged bytes survive fault/retry episodes).
- Storage integration errors become runtime errors instead of panics:
  zero granularity rejected at BEGIN/chunk/finalize; trailer erase range
  computed by a single checked helper shared by validation and write, with
  BEGIN enforcing disjointness from the image window (aligned start >=
  staging_cap) before any flash access.
- Sender correlates replies to the ACTIVE manifest: ACK_READY must echo
  the negotiated chunk_len and STATUS must carry matching version+length,
  else they are inert. The receiver's Idle STATUS projection retains the
  dropped session identity so legitimate resume-after-expiry still works.
- Sender validates source len() against the signed length before hashing.
- OtaError is #[non_exhaustive] from day one; closed v1 wire enums
  documented. ota feature no longer pulls heapless; OtaStorage drops the
  unused read() method (readback belongs to host bootloaders).
- Strict rustdoc gate added to scripts/test.sh; broken intra-doc links
  fixed via root re-exports; wording corrections.
aligned_trailer_range now verifies start + span with checked arithmetic,
so a trailer block at the top of the 32-bit flash space is rejected at
BEGIN with the standard integration error instead of wrapping. Boundary
test included.
Performance-audit remediation:
- Sender poll() resends the already-staged in-flight chunk without any
  OtaImageSource read; the image parameter is dropped from poll(). A
  counting-source test proves zero reads on resend and exactly one read
  when advancing to the next sequence.
- New dual-role-gated type_size_bounds suite pins measured host sizes of
  OtaSender/OtaReceiver/BeginFrame/TrailerRecord behind explicit approved
  caps, per the crate-wide footprint contract.
- SAMD21 linked-footprint and stack high-water measurement is recorded as
  an explicit handoff requirement for the firmware integration project.
Security-audit remediation:
- Manifest v2: sigil-ota-v2 domain now binds product_id (u16 LE) into the
  signed digest, so images validly signed for another product sharing the
  factory root are rejected at verification.
- Anti-rollback: OtaReceiverConfig::min_acceptable_version refuses strictly
  older signed versions at BEGIN with new wire verdict VERSION_REJECTED(6);
  equality remains a valid repair; the durable floor is host-owned.
- Manifest authentication moved to BEGIN (before any staging flash access):
  invalid signatures never open a session or spend erase/write cycles;
  FINALIZE keeps verifying the staged-bytes hash against the authenticated
  manifest.
- Absolute per-session lifetime ceiling bounds identical-BEGIN pinning
  (ExpiredAbsoluteLifetime); idle refresh alone can no longer hold a session.
- Literal golden vectors (manifest input, digest image SHA, compressed
  P-256 key, real r||s signature) generated deterministically and verified
  against the independent p256 implementation; ACK_FINAL VersionRejected
  frame vector added.
- Host authorization requirements documented (one receiver per authorized
  gateway; admission budgets stay host policy). p256 dev-dep gains the
  ecdsa feature for the conformance check only.
Closes the remaining security-audit finding (MAJOR, uncertain scope):
manifest v2 now signs product_id AND the hardware profile byte that
install factory certificates already attest, making OTA images fully
target-bound even when several boards share one factory root. Manifest
input grows to 56 bytes; receiver config gains hardware_profile_id;
frozen P-256 literals and the deterministic generator were regenerated;
CLAUDE.md documents the compatibility invariant.
Replace the inline tag/publish/check logic in .forgejo/workflows with thin
callers to the shared faicel/central_ci reusable workflows (rust_crate_checks,
create_tag_on_dev, create_tag_on_main, publish_on_tag, validate_flow), aligned
with the model already used by lis2dh12. Delete the local
_rust-crate-checks.yml gate. Every caller passes
test_command: bash scripts/test.sh; the feature clippy matrix (all features,
sensor, gateway) moves into that script so CI lint coverage is unchanged.
Add scripts/deny-check.sh as the local dependency-policy wrapper. Document
the thin-caller model and the owner-accepted mutable central_ci@main ref risk
in .forgejo/README.md.
Fail-fast: a lint-only regression now surfaces in minutes instead of after
the multi-minute locked feature-matrix test run. Zero effect on green runs;
no gate added, removed, or weakened.
[1.2.1] - 2026-09-05
All checks were successful
Run checks on feature branches / rust-crate-checks (push) Successful in 1m43s
Run checks on feature branches / checks (push) Successful in 0s
Validate branch flow / validate-flow (pull_request_target) Successful in 2s
Validate branch flow / validate (pull_request_target) Successful in 0s
fa3a6c53b5
- Update README.md
 - Migrate the Forgejo CI workflows
Merge branch 'dev' into fix/forgejo-central-ci
All checks were successful
Validate branch flow / validate-flow (pull_request_target) Successful in 2s
Validate branch flow / validate (pull_request_target) Successful in 0s
Run checks on feature branches / rust-crate-checks (push) Successful in 1m39s
Run checks on feature branches / checks (push) Successful in 0s
14f22b3c26
faicel deleted branch fix/forgejo-central-ci 2026-09-04 22:19:41 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
homeiot/sigil!30
No description provided.