Skip to content

fix: saturating engine telemetry and ACK sequence validity (layer 4) - #55

Merged
petesramek merged 2 commits into
petesramek-payload-type-safetyfrom
petesramek-stats-ack-validity
Oct 28, 2026
Merged

petesramek merged 2 commits into
petesramek-payload-type-safetyfrom
petesramek-stats-ack-validity

Conversation

@petesramek

Copy link
Copy Markdown
Owner

Description

Layer 4 of the TinyLink remediation sequence (stacked on layer 3, petesramek-payload-type-safety). Replaces every direct ++_stats.* in the engine with the saturating Stats::increment(TelemetryEvent) API, and adds tracking of whether a valid application sequence has been received so sendAck() cannot acknowledge a frame that was never accepted.

Closes #

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactor / code quality improvement
  • CI / build / tooling change

Changes

Files: src/TinyLink.h, test/test_tinylink/test_main.cpp, CHANGELOG.md.

  • All 14 direct counter increments now call _stats.increment(TelemetryEvent::X) (PacketReceived, CobsDecodeFailed, ChecksumMismatch, PacketLengthMismatch, PayloadSizeMismatch, PacketEncodeFailed, CobsEncodeFailed, InterByteTimeout, AckTimeout, ReceiveOverflow, UnexpectedMessageType, UnexpectedSequence, InvalidAckResult, InvalidHandshake). Counters saturate at UINT32_MAX.
  • New private _hasReceivedSequence. Set when an application frame is accepted; sendAck() returns false without writing while it is unset.
  • Stays valid across callback delivery, read(), flush().
  • Invalidated by: construction, reset(), begin(), a valid peer handshake Request (peer restart; the old frame is stale), and an unsupported-version handshake (Incompatible).
  • Rejected frames (before connection, wrong payload size) do not validate the sequence.

Public behavior changes

  • sendAck() now returns false (nothing written) until an application frame is accepted, and again after the invalidating transitions above.
  • Counters no longer wrap (previously unreachable in practice, now guaranteed).

Checklist

  • I have read the Contributing Guidelines.
  • My branch is up-to-date with the target branch.
  • My changes compile without errors or warnings on the affected platform(s).
  • I have added or updated tests to cover my changes.
  • All existing tests pass (pio test -e native).
  • I have updated relevant documentation (README, inline comments, etc.).
  • My commit messages follow the Conventional Commits format. (first commit does not; second does)
  • I have added a CHANGELOG.md entry under [Unreleased].

Testing Done

pio test -e native on Windows: 121 test cases, 121 succeeded (111 existing + 10 new).

New tests: testEngineCountersSaturateAtMaximumInsteadOfWrapping, testSendAckReturnsFalseBeforeAnyApplicationFrameIsAccepted, testRejectedApplicationFramesDoNotValidateAckSequence, testAckSequenceRemainsValidAfterCallbackDelivery, ...AfterRead, ...AfterFlush, testResetInvalidatesAckSequence, testBeginInvalidatesAckSequence, testPeerHandshakeRequestInvalidatesAckSequence, testIncompatibleHandshakeInvalidatesAckSequence. Construction is covered by the first. Existing testSendAckPropagatesFailedAndPartialWrites and testClosedTransportRejectsWritesAndDoesNotBlockRecovery now accept an application frame first so they still exercise write failures.

Assumptions and limitations

  • Lifecycle decision: only transitions that end or restart the current session invalidate the sequence (begin(), peer handshake request, Incompatible). A handshake Response, ACK timeout and log frames do not.
  • The saturation test preloads counters through a test-only friend struct TinyLinkStatsAccess declared in TinyLink; no public/private state is exposed to users. It drives 12 of 14 events through the engine; PacketEncodeFailed and CobsEncodeFailed are unreachable with valid payload sizes, so they rely on the shared Stats::increment mapping (covered in test_stats).
  • CI compile checks for non-native platforms were not run locally.

petesramek and others added 2 commits October 28, 2026 13:46
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@petesramek
petesramek added this pull request to stack #61 October 28, 2026 14:42
@petesramek
petesramek merged commit 1966e1e into remedation Oct 28, 2026
4 checks passed
petesramek added a commit that referenced this pull request Oct 28, 2026
#62)

* status.h replaced with ackresult

* ackmessage rewritten

* updated ackmessage

* added telemetryevent.h

* updated stats.h

* updated stats.h

* updated messagetype.h

* updated version.h

* updated handshakemessage.h

* update logmessage.h

* update loglevel

* updated state.h

* updated fletche16.h

* update cobscodec.h

* updated packet.h

* removed packed.h

* rtemoved duplicate code

* updated tinylink.h

* updated adapters

* removed plan folder

* added skills

* removed tests

* test: add native Fletcher-16 suite (#32)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* test: add comprehensive TinyLink native suite (#33)

* test: add native Fletcher-16 suite

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* test: add comprehensive TinyLink native suite

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* test: cover remaining native components (#34)

* test: add native Fletcher-16 suite

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* test: add comprehensive TinyLink native suite

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* test: cover remaining native components

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* readme

* switch prompt and result order

* merged src structure with large project flat structure issue.

* updated model

* feat(adapter): report transport write results (#52)

Add a shared result type and propagate accepted-byte counts from all built-in adapters. Expand native adapter stubs and tests for complete, partial, failed, and zero-length writes.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* feat(engine): handle transport write results (#53)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* feat(engine): require trivially copyable payloads (#54)

Enforce trivially copyable payload types on all toolchains including AVR, document opaque-byte portability limits, and add compile-contract checks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* fix: saturating engine telemetry and ACK sequence validity (layer 4) (#55)

* Saturate engine telemetry and validate ACK sequence

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* docs: changelog for stats saturation and ACK validity

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* fix(lifecycle): recover from transport loss (#56)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* test(adapters): cover POSIX adapter with PTYs (#57)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* test: organize suites by responsibility and split TinyLink tests (#58)

Move suites to test/suites, isolate platform stubs under test/support/stubs, and split the TinyLink suite into behavior files. All 142 registrations preserved.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* test: document infrastructure and improve loop assertion diagnostics (#59)

* test: document infrastructure and improve loop assertion diagnostics

Document test helpers, platform stubs, compile-contract probes and capacity
assumptions. Loop-based assertions now report the failing index, length or
value via TEST_ASSERT_*_MESSAGE and a diag() helper.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* build(test): enforce strict native warnings and add sanitizer CI (#60)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* removed cod etesting skill

* bumped version to 0.5.0

* fix: reconcile remedation merge with main duplicates (#63)

Restore the verified stacked implementation (src, tests, tools, CI) where the
main merge left duplicate TinyWriteResult/test files and broken TinyLink.h.
Drop duplicate README write-result section and obsolete scripts/ probe.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@petesramek
petesramek deleted the petesramek-stats-ack-validity branch October 28, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant