Skip to content

Pin the live buffer's two cost claims as assertions - #923

Merged
jeremy merged 2 commits into
mainfrom
pin-cost-claims
Sep 18, 2026
Merged

jeremy merged 2 commits into
mainfrom
pin-cost-claims

Conversation

@jeremy

@jeremy jeremy commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

Follow-on to #921, same treatment for the two remaining cost claims in the event-feed package's capacity comments.

The claims

  1. MaxCapacity: "The live buffer grows to its capacity lazily and pays only for the events it admits."
  2. DefaultLiveBufferCapacity: "deliberately decoupled from the dedupe capacity — only event-bearing frames are buffered."

Both justify a published constraint by naming a cost or an independence. Neither was measured.

TestLiveBufferPaysOnlyForTheEventsItAdmits

Bytes (runtime.MemStats.TotalAlloc), not testing.AllocsPerRun's count, for the reason #921 paid for: make([]Event, 0, capacity) is one allocation whether the capacity is 1 or a million, so a count is identical in exactly the case that must fail. TestSustainedOverflowRetainsTheBacking next to it counts allocations because its claim is about how many happen; this claim is about how big one is.

Capacity and admitted count vary independently — a grid over admitted ∈ {0, 1, 16, 1000} × capacity ∈ {n, n+1, 10n, 10 000, MaxCapacity} — because a diagonal cannot tell "pays for its capacity" from "pays for what it admits", which is the entire claim. Every cell is compared against the smallest capacity that still holds the admitted events, so a fixed-size allocation added to newLiveBuffer moves all the cells together and stays green. The rising floor across admitted counts is the other half: the cost does move, with the events, which is what makes the invariance an observation rather than a measurement of nothing.

Events are built outside the measured region and carry no strings, so the only allocations inside it are the liveBuffer struct and append's growth of the store. The grid never overflows — a drop would charge the measurement for add's dropped-ids slices instead of the store.

TestLiveBufferCapacityIsDecoupledFromTheDedupeCapacity

Behavior rather than bytes, and the choice is not arbitrary — it follows from the first test. Because the live buffer's cost does not move with its own capacity, a byte grid over the two capacities would stay green under newLiveBuffer(cfg.dedupeCapacity, …), which is the single most likely way to break this claim. Bytes are the wrong instrument here.

What is observable is which capacity bounds which population: the buffer drops at its own configured capacity and the LRU evicts at its own, each while the other is set somewhere else. Sampled off the diagonal in both orderings (64/3, 3/64, 1/8, 8/1) plus the shipped defaults — and the defaults cell is labelled in the table as the one that discriminates nothing, since DefaultLiveBufferCapacity and DefaultDedupeCapacity are the same number.

What this test cannot reach, stated rather than papered over

Writing DefaultLiveBufferCapacity = DefaultDedupeCapacity would make the two constants formally coupled and leave every observation in the test unchanged — verified, it passes under that mutation — because untyped constants carry no evidence of where they came from. That half of the claim is a statement about intent and stays a comment. The half that is mechanical — that nothing in the wiring derives, swaps or clamps one by the other — is what the test holds.

Mutation checks

Each mutation applied to loop.go, built, both tests run, reverted. T1 = pays-only-for-admitted, T2 = decoupled.

# mutation T1 T2
M1 newLiveBuffer → events: make([]Event, 0, capacity) FAIL pass
M2 newLiveBuffer → events: make([]Event, 0, capacity/2+1) (half-sized, still eager) FAIL pass
M3 dedupe-shaped eager index map sized by capacity in newLiveBuffer FAIL pass
M4 grow to capacity on the first add rather than in the constructor FAIL pass
M5 control: a fixed-size (capacity-independent) allocation in newLiveBuffer pass pass
N1 newLoop hands the dedupe capacity to the live buffer pass FAIL
N2 newLoop hands the live buffer capacity to the dedupe pass FAIL
N3 newLoop clamps the live buffer by the dedupe capacity pass FAIL
N4 newLoop clamps the dedupe by the live buffer capacity pass FAIL
N5 DefaultLiveBufferCapacity = DefaultDedupeCapacity pass pass — the documented limit above

M5 is the control that matters for the byte test: an unrelated allocation must not break it, or the test would become a tripwire on every edit to newLiveBuffer. M1–M4 are four different eager-allocation shapes, including the exact one that exists in dedupe.go today.

Gates

go build ./..., go vet ./..., go test ./... -race -count=1, make go-lint (0 issues). The two new tests also pass -race -count=5.


Summary by cubic

Adds two tests pinning the event-feed capacity comments' two cost claims: the live buffer pays only for events admitted, and its capacity is decoupled from the dedupe capacity. Also expands those comments to describe the dedupe LRU as a bounded per-lane window and reference the tests.

Tests

  • TestLiveBufferPaysOnlyForTheEventsItAdmits measures bytes across a grid of capacity × admitted count, so cost must not move with capacity and must move with admitted events; bytes rather than allocation count, since make([]Event, 0, capacity) is one allocation at any size.
  • TestLiveBufferCapacityIsDecoupledFromTheDedupeCapacity asserts which capacity bounds which population rather than bytes, because the first test shows cost doesn't move with capacity, so a byte grid would stay green under newLiveBuffer(cfg.dedupeCapacity).
  • Mutation-checked: nine targeted mutations fail, the fixed-size control passes, and the one mutation coupling the two default constants still passes — untyped constants carry no derivation evidence, so that half stays a comment.

Written for commit e5f337f. Summary will update on new commits.

Review in cubic

The MaxCapacity comment says the live buffer grows to its capacity lazily
and pays only for the events it admits, and DefaultLiveBufferCapacity says
it is deliberately decoupled from the dedupe capacity. Both are measurable,
and neither was measured.

TestLiveBufferPaysOnlyForTheEventsItAdmits measures bytes, not allocation
count: make([]Event, 0, capacity) is one allocation at any size, so a count
is identical in exactly the case that must fail. Capacity and admitted count
vary independently, because a diagonal cannot tell "pays for its capacity"
from "pays for what it admits".

TestLiveBufferCapacityIsDecoupledFromTheDedupeCapacity asserts behavior
rather than bytes, and the reason is the first test: the live buffer's cost
does not move with its own capacity, so a byte grid would stay green under
newLiveBuffer(cfg.dedupeCapacity). What is observable is which capacity
bounds which population, sampled off the diagonal in both orderings — the
shipped defaults are the same number, so the equal cell discriminates
nothing.
Copilot AI balanced review requested due to automatic review settings September 18, 2026 06:26
@github-actions github-actions Bot added the go label Sep 18, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-18T06:31:53.665827Z e5f337f Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@jeremy

jeremy commented Sep 18, 2026

Copy link
Copy Markdown
Member Author

@codex review

Copilot AI 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.

🟡 Changes recommended

The updated public documentation inaccurately describes the bounded, lane-specific dedupe LRU.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds assertions that live-buffer allocation depends on admitted events and that live-buffer and dedupe capacities remain independently wired.

Changes:

  • Adds allocation and capacity-decoupling tests.
  • Links capacity documentation to those tests.

[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

File summaries
File Description
go/pkg/basecamp/eventfeed/connector.go Documents capacity rationale and associated assertions.
go/pkg/basecamp/eventfeed/buffer_test.go Tests lazy allocation and independent capacity wiring.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread go/pkg/basecamp/eventfeed/connector.go Outdated
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: de5b5cdae6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@jeremy

jeremy commented Sep 18, 2026

Copy link
Copy Markdown
Member Author

Fixed in e5f337f. The clause now reads "the dedupe LRU is a window over the lane's most recent deliveries that every delivery path records into: poll page, drain and streaming alike" — bounded, per-lane, and the contrast with the buffer (only event-bearing frames) is the part that carries the decoupling.

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: e5f337f308

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copilot AI 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.

🟢 Approved

The assertions accurately exercise the documented allocation and independent-capacity invariants without unresolved issues.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@jeremy

jeremy commented Sep 18, 2026

Copy link
Copy Markdown
Member Author

Review threads: 1 resolved (1 fixed, 0 declined).

@jeremy
jeremy enabled auto-merge (squash) September 18, 2026 06:34
@jeremy
jeremy merged commit 819f5e7 into main Sep 18, 2026
51 checks passed
@jeremy
jeremy deleted the pin-cost-claims branch September 18, 2026 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants