Skip to content

Plan: Capture Vec<u8> migration baselines for the default codec path (10.2.1) - #654

Draft
leynos wants to merge 3 commits into
mainfrom
10-2-1-capture-baselines
Draft

Plan: Capture Vec<u8> migration baselines for the default codec path (10.2.1)#654
leynos wants to merge 3 commits into
mainfrom
10-2-1-capture-baselines

Conversation

@leynos

@leynos leynos commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Summary

Draft ExecPlan for roadmap item 10.2.1 — capture allocation, copied-byte,
throughput, and latency baselines for inbound decode, middleware pass-through,
request hooks, and outbound encode on the default codec path.

Plan document:
docs/execplans/10-2-1-capture-baselines.md

This PR is documentation only. No Rust source, tests, build configuration,
or dependency manifests are touched. The plan requires approval before
implementation begins.

The central design decision

The plan separates two kinds of artefact:

  • Invariants — statements such as "outbound encode performs at least one
    payload-sized allocation" — are asserted by tests. They survive a dependency
    bump and invert exactly when item 11.1.2 lands.
  • Measurements — the concrete counts, bytes, and nanoseconds — are recorded
    with a full environment stamp and are explicitly not asserted.

The reason is .github/dependabot.yml: Cargo updates run daily with
auto-merge configured. Allocation counts are properties of bincode, bytes,
tokio-util, libstd, and the toolchain as much as of wireframe, so a
committed figure would have gone red on bot PRs until re-blessing became
reflex — destroying the before-and-after comparability that items 10.2.2,
11.2.3, and 13.2.1 need.

Substantive finding: the roadmap names the wrong copy

Reviewers should look at this first, because it changes what item 11.1.2 must
do. The roadmap and ADR-010 describe "the final default-path Vec<u8> copy
between serialization and FrameCodec::wrap_payload". That phrase names two
operations that do not copy, and misses two costs that do.

Free on the default codec:

  • LengthDelimitedFrameCodec::wrap_payload (src/codec.rs:283) is the
    identity function; type Frame = Bytes (:262).
  • Bytes::from(Vec<u8>) (src/app/outbound_encoding.rs:36) takes ownership of
    the vector's buffer.

Not free:

  1. Serializer::serialize returns Vec<u8> (src/serializer.rs:67-71), so
    bincode allocates a vector and copies the payload into it. This is
    what item 11.1.2 can remove.
  2. Bytes::from(Vec<u8>) heap-allocates a 24-byte Shared control block when
    len != capacity (bytes-1.12.1/src/bytes.rs:947-967) — the normal case,
    because bincode grows its output amortized.
  3. LengthDelimitedEncoder::encode (src/codec.rs:248-257) delegates to
    tokio_util, which copies the payload again into the Framed write
    buffer. This is outside encode_message_frame, and item 11.1.2 cannot
    remove it.

A baseline scoped to encode_message_frame would therefore record roughly half
the outbound payload traffic, and item 10.2.2 would set thresholds against it.
The plan measures the framed encoder as a fifth row and ships a correction to
docs/roadmap.md:475-477 and :491-492 plus ADR-010 as its first, standalone
commit.

Review process

A six-lens design review (structural integrity, alternatives, measurement
validity, interface contracts, operational failure modes, long-term viability)
returned revise on the first draft. Every finding below was verified
against the code before being acted on.

Dropped from the draft:

  • The Verus proof and Kani harness. docs/roadmap.md:583-718 is a
    dedicated formal-verification phase; item 15.1.4 adds make kani/make verus, 15.3.1 adds the first Kani harnesses, and 15.5.2 adds the verus/
    proof modules the draft proposed to occupy. The machinery was also aimed at
    counter arithmetic, whereas this instrument's realistic failure mode is
    misattribution. Property tests and a seeded-fault control attack that
    directly.
  • The insta gate over live measurements, in favour of a snapshot over fixed
    synthetic rows that tests the renderer's format only.
  • The hand-transcribed baseline table, in favour of a generated document region.

Defects fixed (each would have failed to compile or measured the wrong thing):

Defect Evidence
Decode shim unreachable across a module boundary parse_envelope is a bare private fn at src/app/inbound_handler.rs:74
Hooks attributed to the wrong type, and unreachable without a transport invoke_before_send_hooks is on WireframeClient at src/client/messaging.rs:335
Outbound shim leaks a private type through a public signature EncodedFrame is pub(crate) at src/app/outbound_encoding.rs:18
Middleware stage had no seam and would be re-implemented src/app/frame_handling/response.rs:41-55
wireframe_testing cannot see test-support wireframe_testing/Cargo.toml:16 enables only testkit
Report sort has no Ord to sort by Stage and PayloadClass derive neither

Caption: defects found by the design review and verified against the code.

Two false premises in the draft were also corrected: CI does not run
make test (.github/workflows/ci.yml runs check-fmt, lint,
markdownlint, nixie, and test-workflow-contracts, with Rust tests
reaching CI only via a coverage action), and Cargo.toml:15 sets
default-members = ["."], so make test would not build wireframe_testing's
tests either. All invariant tests therefore live in the root crate's tests/.

The plan also reuses the repository's existing pointer-identity idiom for
zero-copy assertions (src/codec/tests.rs:63-71, :195-232, :236-245)
rather than inventing a new one.

Scope tightened from six milestones to five, and the tolerance from 32 files
and 2,500 lines to 20 and 1,400 — matching the completed 9.6.1 plan.

Validation

make markdownlint (including the typos en-GB-oxendict chain) and make nixie
both pass. No Rust gates were run because no Rust changed.

Follow-ups recorded, not actioned

  • src/app/codec_driver.rs:1-12 documents that the frame pipeline applies
    protocol before_send hooks, but no such invocation was located in
    FramePipeline::process (:56-71). To be confirmed in Stage A; an issue if
    it is a genuine defect.
  • docs/repository-layout.md is referenced by AGENTS.md:41-43, the
    documentation style guide, and the roadmap, but does not exist.

References

🤖 Generated with Claude Code

Summary by Sourcery

Add a reviewed execution plan for establishing migration baselines on the default codec path.

Enhancements:

  • Add a detailed execution plan for capturing default codec path allocation, copied-byte, throughput, and latency baselines while separating durable invariants from environment-dependent measurements.
  • Document the corrected outbound data-flow analysis, including serializer allocation, framed encoder copying, and the scope of the planned measurements.
  • Define staged implementation, validation, reporting, provenance, and review requirements for future baseline instrumentation.

Documentation:

  • Add the draft roadmap execution plan at docs/execplans/10-2-1-capture-baselines.md.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Warning

Your free Security trial is over. An organization admin can activate billing to continue.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ae06ff51-5f67-410a-8065-ce64815ec9a4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds a detailed execution plan document for roadmap item 10.2.1, defining how to capture allocation, copied-byte, throughput, and latency baselines on the default codec path, including clarified copy locations, measurement strategy, instrumentation design, verification plan, and milestone breakdown — with no code changes yet.

Flow diagram for invariant and measurement outputs

flowchart TD
    Start[Run default-path probe]
    Warmup[Warm-up iteration]
    Scope[Measure scoped production work]
    Validate{Allocator installed and no thread escape?}
    Invariants[Assert stable invariants]
    Numbers[Record environment-stamped measurements]
    Render[Render generated Markdown region]
    End[Baseline document]

    Start --> Warmup --> Scope --> Validate
    Validate -->|No| Error[Reject measurement]
    Validate -->|Yes| Invariants --> Render
    Validate -->|Yes| Numbers --> Render
    Render --> End
Loading

File-Level Changes

Change Details Files
Introduces a comprehensive ExecPlan document for roadmap item 10.2.1 that specifies how to baseline allocations, copied bytes, throughput, and latency on the default codec path, and corrects earlier misunderstandings about where Vec copies and allocations occur.
  • Adds a long-form execution plan describing context, goals, scope, and constraints for measuring the default codec path (inbound decode, middleware, hooks, outbound encode, framed encoder).
  • Clarifies the actual locations of payload copies and allocations (serializer Vec, Bytes::from control block, framed encoder) and documents corrections needed in roadmap and ADR-010 wording.
  • Defines an allocation and copy measurement strategy using a thread-local probe allocator and Valgrind DHAT copy mode, separating asserted invariants from non-asserted numeric measurements.
  • Spells out a verification plan (V-1..V-6) with property tests, seeded-fault controls, snapshot tests for report formatting, and reproducibility checks for copied-byte capture.
  • Details milestones (EP-M1..EP-M5) for implementing instrumentation, production seams, probes, invariant tests, generated baseline document, copied-byte and timing benchmarks, and related ADR and docs updates.
  • Records risks, tolerances, decision log, surprises, and progress tracking for the planned implementation, emphasizing feature-gating and no changes to public default surfaces until later code work.
docs/execplans/10-2-1-capture-baselines.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

codescene-access[bot]

This comment was marked as outdated.

leynos and others added 3 commits August 23, 2026 05:09
Add `docs/execplans/10-2-1-capture-baselines.md`, a draft execution plan
for capturing allocation, copied-byte, throughput, and latency baselines
across inbound decode, middleware pass-through, request hooks, and
outbound encode on the default codec path.

The draft records the reconnaissance behind the design, notably that the
"final default-path copy" named by the roadmap and ADR-010 is not where
the phrase suggests: `LengthDelimitedFrameCodec::wrap_payload` is the
identity function and `Bytes::from(Vec<u8>)` takes ownership without
copying, so the cost lies in the `Vec<u8>` that `Serializer::serialize`
must materialize.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rework the baseline plan so it asserts invariants and merely records
measurements, rather than committing absolute numbers to tests. Cargo
Dependabot runs daily with auto-merge, and allocation counts are
properties of bincode, bytes, tokio-util, and the toolchain as much as
of wireframe, so a committed figure would have become a rubber stamp.

Drop the proposed Verus proof and Kani harness. Roadmap section 15 owns
prover bring-up, including the `verus/` entry point that revision 1
proposed to occupy, and the machinery was aimed at counter arithmetic
when the instrument's realistic failure mode is misattribution.

Fix six defects that would not have compiled or would have measured the
wrong thing: `parse_envelope` is private to its module; the before-send
hooks live on `WireframeClient`, not `RequestHooks`, and need a
transport to reach; the outbound shim would have leaked `pub(crate)`
`EncodedFrame` through a public signature; the middleware stage had no
seam and would have been re-implemented; `wireframe_testing` enables
only `testkit` and cannot see `test-support`; and `Stage` and
`PayloadClass` lack the `Ord` the report's sort requires.

Correct three claims about the default path. `Bytes::from(Vec<u8>)`
allocates a control block even though it does not copy;
`LengthDelimitedEncoder::encode` performs a second payload-sized copy
that item 11.1.2 cannot remove; and middleware pass-through boxes a
future per call, so it is not allocation-free.

Also record that CI does not run `make test`, that `default-members`
excludes `wireframe_testing` from it, and add an escape detector and an
installation check to the instrument, whose two silent failure modes
both report the zero that also signals success.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rebasing onto main brought commit a31c01a, which upgraded Criterion from
0.5.1 to 0.8.2 and migrated the existing benches off the deprecated
`criterion::black_box` re-export, together with serde, serde_json, and
futures bumps.

Update the plan's timing milestone to import `black_box` from
`std::hint`, and record the upgrade as decision D-12. The API the plan
relies on -- `iter_custom`, `Throughput::Bytes`, `Throughput::Elements`,
and `BenchmarkId` -- is unchanged across the upgrade.

Note the churn itself in `Surprises and discoveries`: four
dependency-affecting commits reached main inside a single day, which is
the cadence decision D-6 anticipates and the reason the plan asserts
invariants rather than committed allocation figures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@leynos
leynos force-pushed the 10-2-1-capture-baselines branch from b14f0f8 to f8fc5cf Compare August 23, 2026 03:11
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No quality gates enabled for this code.

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