Skip to content

ci(release) astubbs#197: publish the curated changelog section as the GitHub Release body - #199

Closed
astubbs wants to merge 22 commits into
masterfrom
ci/release-notes-body
Closed

astubbs wants to merge 22 commits into
masterfrom
ci/release-notes-body

Conversation

@astubbs

@astubbs astubbs commented Aug 5, 2026 •

Copy link
Copy Markdown
Owner

Description

Fixes the "release page has no body" sub-item of #197.

What was wrong. .github/workflows/release.yml (not publish.yml - that one only publishes
snapshots) does create the GitHub Release, and it did try to use the changelog: an inline awk
compared each line to the literal string == <releaseVersion>. The section is headed
== 0.6.0.0 (unreleased), so it matched nothing, and the step fell back to --generate-notes. On the
release page an auto-generated commit list is indistinguishable from the curated notes having silently
vanished, so the bug reported nothing. That fallback is the bug, and it is gone.

What now happens. bin/release-notes.py <version> prints the version's CHANGELOG.adoc section as
Markdown. release.yml renders it before it commits, tags, deploys or publishes anything - so a
missing section fails while it is still cheap, rather than after the artifacts are on Central - and a
Dry run rehearses the render and puts the body in the job summary. A missing, empty, or
unconvertible section is a non-zero exit that fails the release. There is no fallback body.

This branch was re-cut onto today's master, discarding its own redundant copy of the
io.confluent.* → bz.stub.* rename now that master has completed that rename itself, then given a
local simplify + code-review pass. Both changed the PR materially; see What the review pass
changed
below.

The AsciiDoc -> Markdown decision

Convert a bounded subset, and reject the rest loudly. Not "extract and accept the degradation", not
"link and give up".

  • The subset is what the changelog actually uses: === headings, */** bullets, . ordered lists,
    https://…[text] and link:…[text] macros, *bold*, `mono`, NOTE::, + continuations,
    // comments. Everything the two languages already share (paragraphs, monospace) passes through.
  • Anything outside it that would render as visible garbage - source blocks, tables, anchors, block
    attributes, includes, conditionals, xrefs - is an error, not a silent pass. That is what keeps
    "bounded subset" from decaying into "mangled markup": the day someone writes a table in a release
    section, CI says so.
  • Two details a naive sed gets wrong and this does not: AsciiDoc bold is one asterisk, which in
    Markdown is italics (so *Quarantine lane* would have quietly changed emphasis); and monospace
    spans are masked before inline rules run, so `bz.stub.parallelconsumer.*` keeps its asterisk.
    Relative link:docs/…[] targets are absolutised at the released tag - a relative link in a release
    body resolves against github.com and 404s.
  • No asciidoctor/pandoc. A release job must not be able to fail because a gem or a package would
    not install, and the input is one small file whose shape we control.

What the review pass changed - including two bugs in the original

A local simplify + code-review pass ran before this was pushed. It found two defects the
self-test did not, both of which defeat the PR's own purpose:

  • A section that renders to nothing exited 0 with a 1-byte body. Emptiness was judged on raw
    lines, so a section holding only // comments or a + passed the check and then had every line
    dropped. That is the blank release page of Release 0.6.0.0 - the fork's first release #197 reached from the other side, inside the
    script written to prevent it. Emptiness is now judged on the converted output:

    $ printf '== 0.6.0.0\n\n// a comment\n' > c.adoc
    
    before:  1 byte, exit 0
    after:   error: the `== 0.6.0.0` section produces no notes …   exit 2
    
  • bin/release-notes.py v0.5.2.2 produced blob/vv0.5.2.2/… - a supported, tested spelling
    whose relative links all 404. The notes render perfectly; only a reader clicking finds out.

code-review additionally found, all verified red against the previous commit:

  • HIGH - macros and emphasis containing a `monospace` span shipped as raw AsciiDoc.
    convert_inline split on backticks, so a macro's [ and ] landed in different pieces: exit 0, a
    dead link on the release page, and the surviving single asterisks rendering as italics - the exact
    quiet emphasis change the code's own comment says must not happen. Now masks code spans with a
    placeholder instead of splitting. A macro written inside a code span still stays literal, asserted.
  • MEDIUM - a // line comment could abort a release. A commented-out draft entry holding
    [source,java], a | cell or a stray backtick failed exit 3, for a line that is dropped. Line
    comments are now skipped - but not ////, which matches ^\s*// too and is a comment block
    whose contents would reach the body. The reviewer's suggested fix would have opened that hole.
  • LOW - nested ordered lists flattened; LC_ALL=C crashed on em dashes with a traceback reported
    as an IO error; and a mktemp regression introduced during simplify that would have turned the
    macOS lane red (BSD mkstemp(3) requires trailing Xs).

And in the shell harness:

  • The self-test exited 1 when python3 was absent, not 2. bin/check-all.sh maps 1→FAIL and
    2→CANNOT-RUN, so a python-less box reported this as a broken gate. It now probes as
    bin/check-docs-data.sh does, but asserts version_info[0] >= 3 - the house probe accepts a
    python that is Python 2, under which the renderer is a syntax error.
  • $RANDOM fixture names inside $(...). bash <5.1 does not reseed $RANDOM in a subshell and
    the helper is only ever called in a command substitution, so on the bash-3.2 macOS lane every
    fixture landed on one path. Now mktemp.

One rejected finding worth recording: indenting + continuations to preserve list attachment is
right in the abstract but would make the live output worse - both + uses in CHANGELOG.adoc
close a whole bullet list, which is what the current trailing-paragraph output gives. The hazard it
named (an ordered list restarting at 1 after a continuation) has zero instances. Recorded as an
explicit caveat in the code instead.

Review round six: two silent-output paths, closed

The sixth @claude review pass (focused on bin/release-notes.py) confirmed the emptiness
predicate, the code-span masking, the // vs //// asymmetry and the --strict wiring, and
independently agreed with the rejected +-indentation finding - it re-ran the
grep -cE '^\.+\s' CHANGELOG.adoc -> 0 check and hand-rendered both live + sites.

It filed two edges as theoretical and not worth chasing. That review has never been able to execute
anything - its sandbox declines bash/python3 every round - so both were run here, and both
are real. One is worse than the hand-trace suggested:

  • Unconstrained monospace, ``like this``, was rewritten INSIDE the span. convert_inline
    masks by splitting on a single backtick, so a doubled delimiter yields an empty span and hands
    the text between the two delimiters to convert_prose as prose. Measured: ``link:docs/x[y]``
    came back as ``[y](https://…/docs/x)`` and ``a *bold* b`` as ``a **bold** b`` - the exact
    rewriting convert_inline's own docstring promises never happens to a monospace span. The backtick
    count is even, so the odd-count check could not see it. Now rejected (exit 3) rather than taught:
    the masker would have to carry two delimiter widths, and CHANGELOG.adoc has zero instances.
  • A contentless bullet defeated the emptiness check. * converts to - , which is not blank, so
    markdown.strip() passed it: render() returned "- \n- \n" and exited 0, publishing a page of
    empty bullets. That is the Release 0.6.0.0 - the fork's first release #197 blank release body reached one indirection
    further on, inside the script written to prevent it. Emptiness is now judged on what survives with
    the list markers off - limited to the two markers convert_line emits, because over-stripping would
    fail a real section as "no notes", and a blocked release is the worse failure. Two assertions guard
    that boundary.

Self-test 37 -> 43 assertions. Four of the six go red against the pre-fix renderer (verified by
stashing it); the other two are the over-rejection guards, which pass on both sides. The real
CHANGELOG.adoc still renders byte-identically at 5994 bytes.

Behaviour change: --strict on real releases

release.yml now passes --strict when dryRun is false, so a real release refuses while the
heading still says == 0.6.0.0 (unreleased). A dry run still only warns, so rehearsing before the
freeze works. This replaces a manual instruction that lived in a docs/inflight/ note due for
deletion after 0.6.0.0 - an instruction nothing enforced.

No dedicated CI job - the glob already covers it

The original version of this PR added a release-notes job to .github/workflows/maven.yml so the
renderer self-test ran per-PR. Master has since made that redundant and it is dropped.
bin/check-all.sh discovers bin/check-*.sh and bin/test-*.sh by glob, and
.github/workflows/repo-hygiene.yml runs bin/check-all.sh --with-tests on pull_request. Adding a
named job would be exactly the hand-maintained list that script exists to abolish. Verified rather
than assumed: bin/check-all.sh --with-tests reports ok test-release-notes.sh in its 42-gate sweep.
maven.yml is byte-identical to master.

Documentation went to docs/releasing.md, not AGENTS.md

All three of the original payload's documentation hunks targeted AGENTS.md sections that master has
since moved out of that file entirely. AGENTS.md is byte-identical to master; the content is in
docs/releasing.md, which owns the topic - a paragraph under Cutting a release, the env-binding
note beside it, and a bullet under At release time naming the real enforcer.

Script injection: the claim this PR originally made, and now actually keeps

The first draft of this checklist said the release version "reaches the script as an argv argument,
not interpolated into a shell string"
. That was false, and the review was right to call it.
${{ inputs.releaseVersion }} is expanded by GitHub Actions as textual substitution into the run:
script before bash ever parses it
- the surrounding quotes are part of the generated source, not a
guarantee about it, so an input containing shell metacharacters is injected as code.

Rather than soften the wording, the claim was made true. release.yml binds the dispatch inputs to
environment variables once at job level and every shell step reads "$RELEASE_VERSION"; the value now
reaches the shell as data it never re-parses.

This deliberately widens the diff. The fix covers the file's four pre-existing interpolations (the
tag-exists guard, release:prepare, git checkout, gh release create) as well as the render step
this PR added - hardening one instance and leaving four would have left the file no safer while
implying it was. release:prepare's -DreleaseVersion= arguments were also unquoted, so they gain
word-splitting safety in the same pass. if:/with: expressions still use ${{ }}: Actions evaluates
those itself, never through a shell, so they are not an injection path.

Exploitability was low either way - workflow_dispatch already requires write access - so this is
hygiene, and more importantly honesty about what the checklist asserts.

The same defect existed elsewhere and was fixed: mutation-full-sweep.yml interpolated the
free-text threads dispatch input into a run: line, two lines below the same step correctly
env-binding its neighbours. The convention is now stated in bin/AGENTS.md → Workflows, which
bin/CLAUDE.md bridges into any session touching bin/.

Verification

check-all --with-tests   42 ran - 42 passed, 0 failed, 0 could not run, 5 skipped
test-release-notes.sh    All self-tests passed   (43 assertions, up from 23; none weakened)
release-notes.py 0.6.0.0 exit=0, 5994 bytes
check-issue-refs.sh      No unqualified references below #1000 on added lines
check-copyright-headers  491 file(s) - 0 violation(s)

All 29 real CHANGELOG.adoc sections render byte-identically to the pre-review renderer. A
12,000-section fuzz run reports empty: 0, leaked-mask: 0, odd-ticks: 0, broken-links: 0. The
release.yml step was simulated under bash -eo pipefail: dry-run 0.6.0.0 → exit 0; real run →
exit 4 on the frozen-heading check; 9.9.9.9 → exit 2. gh release create is unreachable in every
failing case.

Failure modes confirmed loud: missing version (exit 2), unsupported AsciiDoc (3), unfrozen heading
under --strict (4), unreadable changelog (1). CRLF, unicode, prefix-vs-longer-version
(0.6.0 vs 0.6.0.0), duplicate headings and pipe/bracket link labels all behave.

actionlint is not installed on the dev box and is not in mise, so it was not run. Substitutes:
both workflows parse as YAML, bin/check-action-versions.sh passes, and maven.yml is unchanged
from master so only release.yml is exposed. A Dry run of the Release workflow is the cheap
rehearsal before merge - it now prints the body to the job summary.

Merge-prep pass: a stale claim in the notes this PR edits

Both release notes still said MDC context was un-captured at submit time. #205
merged on 2026-08-27
(15a23deb0, adding internal/MdcPropagation.java), so that was false - and
this branch had re-asserted it while rewriting the bullet, and attested the paragraph
post-merge: checked. The attestation was about tense, which was genuinely correct; the fact
travelled through underneath it.

Two follow-ups recorded, not done here

  • bin/check-changelog-renders.sh - splitting part B into its own gate, so a changelog edit is
    checked by the default bin/check-all.sh sweep rather than only --with-tests. Needs a new gate
    plus its own self-test and a reviewer-grant decision.
  • bin/check-workflow-run-interpolation.sh - the env-binding convention above is currently enforced
    by nothing.

Checklist

  • Docs updated - docs/releasing.md (owns the topic), docs/inflight/release-0.6.0.0.md,
    docs/inflight/release-0600-blockers.md, bin/AGENTS.md, plus a .gitignore line for
    __pycache__/. Not AGENTS.md - master moved these sections out; see above.
    CHANGELOG.adoc deliberately untouched, per AGENTS.md
  • Tests added/updated - bin/test-release-notes.sh, 43 assertions, run per-PR via
    bin/check-all.sh --with-tests in repo-hygiene.yml
  • Title & body reflect the final content of this PR - rewritten after the re-cut and the review
    pass; the dropped CI job, the relocated docs and two newly-found bugs are all recorded above
  • Self-hosted runner / security implications considered - touches release.yml and
    mutation-full-sweep.yml. In release.yml the render step runs before any credential is used
    and handles no secret, and the net change to the release's authority is a removed fallback.
    Dispatch inputs no longer reach any shell by ${{ }} interpolation - see Script injection

Part of #197.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@claude

claude Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

Claude finished @astubbs's task in 5m 33s —— View job


Review: publish the curated changelog section as the release body

Task list

  • Gather context (PR description, diff, workflows)
  • Read changed files (release.yml, maven.yml, bin/release-notes.py, bin/test-release-notes.sh, AGENTS.md, docs/inflight/release-0.6.0.0.md)
  • Trace bin/release-notes.py logic against bin/test-release-notes.sh assertions and the real CHANGELOG.adoc
  • Review release.yml/maven.yml workflow changes for correctness/security
  • Post final review

⚠️ Execution caveat: this sandbox declined to run python3/bash (even python3 -c "print(1)" required interactive approval that never arrived), so I could not actually execute bin/test-release-notes.sh or the renderer against CHANGELOG.adoc. Everything below is a hand-trace of the code against every assertion in the test file and against the real changelog's headings (I confirmed via grep that all 29 == -headed sections match the version-heading regex, that none contain | table syntax, and that the only NOTE:: admonitions in the file sit in the preamble, before any version section). Please treat correctness claims below as "verified by careful reading," not "verified by running it" — worth an extra look/CI run before merge.

Summary

The design is sound: fail loudly before anything is tagged/deployed/published, reject unsupported AsciiDoc rather than silently mangling it, no --generate-notes fallback. I traced bin/release-notes.py's regexes and control flow against all 22 assertions in bin/test-release-notes.sh (heading detection incl. v-prefix and (unreleased)-suffix handling, prefix-vs-longer-version disambiguation, missing/empty-section errors, all 8 rejected constructs, block/bold/code-span/link conversions) and didn't find a mismatch. find_section's ^==\s+ heading regex correctly excludes === subheadings (needs the 3rd char to be whitespace), and the real changelog's one edge case beyond (unreleased) — == v0.2.0.1 DO NOT USE - has critical bug — is handled the same way (captured as a warn-only suffix), consistent with the "all 29 sections render 0" claim.

One thing worth a look before merge:

.github/workflows/release.yml:108 — python3 bin/release-notes.py "${{ inputs.releaseVersion }}" > .... The PR checklist states "the release version reaches the script as an argv argument, not interpolated into a shell string." That's true from Python's point of view, but GitHub Actions expands ${{ inputs.releaseVersion }} by textual substitution into the run: block before bash parses it — so it's still substituted into the shell string, just one that happens to end up quoted around a single argv token. A releaseVersion value containing shell metacharacters (e.g. a stray ") would still be a shell-injection vector, same as the pre-existing -DreleaseVersion=${{ inputs.releaseVersion }}, refs/tags/v${{ inputs.releaseVersion }}, and git checkout "v${{ inputs.releaseVersion }}" uses already in this file. This PR doesn't introduce a new class of exposure — it just adds one more instance of the file's existing pattern — and workflow_dispatch already requires write access to trigger, so real-world exploitability is low. But since the PR body explicitly makes a security claim about this exact line, it's worth either softening that claim or (separately, for the whole file) switching to env:-bound variables (env: RELEASE_VERSION: ${{ inputs.releaseVersion }} → reference "$RELEASE_VERSION") to make the claim actually true. Not a blocker for this PR specifically, since it matches existing file convention rather than regressing it.

Fix this →

Smaller observations (non-blocking)

  • bin/release-notes.py's RE_BOLD (\*{1,2}([^*\n]+)\*{1,2}) would misfire on ordinary text containing two unrelated single asterisks (e.g. arithmetic like 3 * 4 * 5), wrapping everything between them as bold. Not currently triggered by CHANGELOG.adoc, and it's an inherent limitation of a line-oriented regex converter rather than a real parser — just flagging as a known fragility if a future changelog entry ever needs a literal bare *.
  • Multi-line NOTE:: admonitions: only the first physical line gets the > **Note:** blockquote prefix; a wrapped second line without a leading > would rely on CommonMark's blockquote "lazy continuation" to still render correctly on GitHub. That should work fine for plain prose continuations, but a +-continued second paragraph inside a NOTE:: would fall outside the blockquote (a blank line breaks lazy continuation) and render as an unquoted paragraph instead of erroring per the "reject, don't mangle" design principle. Currently moot — no NOTE:: in the file lives inside a version section — but if this becomes a real pattern, worth either supporting it explicitly or adding it to UNSUPPORTED.
  • release-notes job in maven.yml is correctly scoped to if: github.event_name == 'pull_request' and has no needs:/continue-on-error, so it gates PRs as intended without slowing down push-to-master builds. Placement/indentation matches the sibling quarantine-audit job.
  • The render step in release.yml runs before git identity/release:prepare/tag creation as claimed, and the GitHub release step correctly stays gated on if: ${{ !inputs.dryRun }} while the render step itself is not gated — matching the "dry runs rehearse the render too" description.

Verified against real data (via static trace, not execution — see caveat above)

  • All 29 == -headed version sections in CHANGELOG.adoc match SECTION_HEADING's regex; none contain | (table syntax) or other content the UNSUPPORTED list would flag.
  • The (unreleased) regression case from Release 0.6.0.0 - the fork's first release #197 (== 0.6.0.0 (unreleased)) is exactly reproduced by bin/test-release-notes.sh's SUFFIXED case and traces correctly through find_section's suffix-as-warning path.

Overall: well-scoped, well-tested-by-design change that fixes a real silent-failure bug, with clear docs updates in AGENTS.md and the inflight release runbook. The one item worth a second look is the shell-interpolation claim in the PR body versus what the workflow YAML actually does — informational rather than blocking, since it doesn't regress the file's existing (already-accepted) pattern.

@github-actions

github-actions Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

✅ Duplicate Code Report

Two engines run in parallel for cross-validation. Each has its own thresholds tuned to its baseline - the real safety net is the per-engine "max increase vs base" check.

✅ PMD CPD

PR Base Change
Clones 27 27 ➖ 0
Duplicated lines 949 949 ➖ 0
Duplication 0.36% 0.36% ➖ 0
Rule Limit Status
Max duplication 0.5% ✅ Pass (0.36%)
Max increase vs base +0.1% ✅ Pass (+0.00%)

No new clones introduced by this PR.

✅ jscpd (language-agnostic)

PR Base Change
Clones 106 106 ➖ 0
Duplicated lines 1503 1503 ➖ 0
Duplication 0.81% 0.82% 🙂 -0.01%
Rule Limit Status
Max duplication 2% ✅ Pass (0.81%)
Max increase vs base +0.1% ✅ Pass (-0.01%)

No new clones introduced by this PR.

Powered by astubbs/duplicate-code-cross-check

@github-actions

github-actions Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

📌 Duplicate code detection tool report

The tool analyzed your source code and found the following degree of similarity between the files:

✅ No new or increased file similarities introduced by this PR.

Full similarity report
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/BackPressureFlagVisibilityProbes.java

📄 jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/BackPressureFlagVisibilityProbes.java

File Similarity (%)
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitWindowLostUpdateProbes.java 47.8
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitPathVisibilityProbes.java 46.69
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/BootstrapResetTripleWriteProbes.java

📄 jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/BootstrapResetTripleWriteProbes.java

File Similarity (%)
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitPathVisibilityProbes.java 37.12
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/SeenSucceededOrderingProbes.java 32.94
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CalibrationProbes.java

📄 jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CalibrationProbes.java

File Similarity (%)
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitPathVisibilityProbes.java 37.63
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/SeenSucceededOrderingProbes.java 35.35
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitPathVisibilityProbes.java

📄 jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitPathVisibilityProbes.java

File Similarity (%)
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitWindowLostUpdateProbes.java 55.72 ⚠️
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/SeenSucceededOrderingProbes.java 55.31 ⚠️
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/BackPressureFlagVisibilityProbes.java 46.69
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CalibrationProbes.java 37.63
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/BootstrapResetTripleWriteProbes.java 37.12
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitWindowLostUpdateProbes.java

📄 jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitWindowLostUpdateProbes.java

File Similarity (%)
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitPathVisibilityProbes.java 55.72 ⚠️
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/BackPressureFlagVisibilityProbes.java 47.8
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionState.java 34.64
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitWindowSeamTest.java 32.25
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/SeenSucceededOrderingProbes.java

📄 jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/SeenSucceededOrderingProbes.java

File Similarity (%)
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitPathVisibilityProbes.java 55.31 ⚠️
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CalibrationProbes.java 35.35
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/BootstrapResetTripleWriteProbes.java 32.94
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ExceptionInUserFunctionException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ExceptionInUserFunctionException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelConsumerException.java 56.03 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java 37.79
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetDecodingError.java 32.62
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 30.34
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 30.06
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelStreamProcessor.java 56.27 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java 54.98 ⚠️
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 43.63
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelStreamProcessor.java 42.3
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TestParallelEoSStreamProcessor.java 34.31
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 33.53
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/PCModule.java 32.75
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelStreamProcessor.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java 56.27 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java 47.86
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 41.86
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelStreamProcessor.java 39.44
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 35.04
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/PCModule.java 30.7
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PCRetriableException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PCRetriableException.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/PCRetriableExceptionTest.java 32.35
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/ThrowableUtils.java 30.22
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelConsumerException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelConsumerException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ExceptionInUserFunctionException.java 56.03 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java 46.31
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelConsumerOptions.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelConsumerOptions.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 30.79
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java 54.98 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelStreamProcessor.java 52.21 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelStreamProcessor.java 47.86
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TestParallelEoSStreamProcessor.java 39.59
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/PCModule.java 34.89
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 33.66
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PollContextInternal.java 33.27
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 32.52
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelStreamProcessor.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java 52.21 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java 42.3
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 39.56
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelStreamProcessor.java 39.44
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelStreamProcessor.java 30.17
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PollContext.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PollContext.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/RecordContextInternal.java 47.45
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PollContextInternal.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PollContextInternal.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/PollContextInternalTest.java 38.83
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java 33.27
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/RecordContext.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/RecordContext.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/RecordContextInternal.java 30.57
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/RecordContextInternal.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/RecordContextInternal.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PollContext.java 47.45
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/RecordContext.java 30.57
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/SubmitWorkToPoolShutdownRaceTest.java 38.16
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionState.java 37.56
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/BrokerPollSystem.java 37.29
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ExternalEngine.java 37.1
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkManager.java 36.22
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ConsumerOffsetCommitter.java 34.59
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionStateManager.java 34.12
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ProducerManager.java 33.68
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java 32.52
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProducerManagerTest.java 32.51
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ConsumerManager.java 31.24
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java 31.01
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelConsumerOptions.java 30.79
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/PollerDeathClosesTheConsumerTest.java 30.45
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/BrokerPollSystem.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/BrokerPollSystem.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 37.29
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ConsumerManager.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ConsumerManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 31.24
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ConsumerOffsetCommitter.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ConsumerOffsetCommitter.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 34.59
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionState.java 30.21
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/EpochAndRecordsMap.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/EpochAndRecordsMap.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionStateManager.java 30.78
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ExternalEngine.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ExternalEngine.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ExternalEnginePipelineBufferTest.java 39.47
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 37.1
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 34.82
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetDecodingError.java 50.08 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/NoEncodingPossibleException.java 48.9
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelConsumerException.java 46.31
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/PCInternalRuntimeException.java 38.23
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ExceptionInUserFunctionException.java 37.79
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/EncodingNotSupportedException.java 37.46
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 31.45
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/PCInternalRuntimeException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/PCInternalRuntimeException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java 38.23
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/PCModule.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/PCModule.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java 34.89
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java 32.75
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelStreamProcessor.java 30.7
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ProducerManager.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ProducerManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 33.68
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/Java8StreamUtils.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/Java8StreamUtils.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/Java8StreamUtilsTest.java 35.58
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/JavaUtils.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/JavaUtils.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/CollectionUtils.java 33.28
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/ThrowableUtils.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/ThrowableUtils.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/ThrowableUtilsTest.java 31.85
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PCRetriableException.java 30.22
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/metrics/PCMetrics.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/metrics/PCMetrics.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/metrics/PCMetrics859Test.java 40.04
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 31.66
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java 31.45
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 30.86
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ExceptionInUserFunctionException.java 30.34
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/CorruptOffsetMetadataException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/CorruptOffsetMetadataException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnsupportedOffsetEncodingException.java 37.26
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnknownOffsetMetadataMagicException.java 31.5
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/EncodedOffsetPair.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/EncodedOffsetPair.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetMapCodecManager.java 35.5
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetEncoding.java 30.24
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/EncodingNotSupportedException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/EncodingNotSupportedException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java 37.46
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/NoEncodingPossibleException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/NoEncodingPossibleException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java 48.9
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetDecodingError.java 45.54
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 34.2
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 33.34
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetDecodingError.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetDecodingError.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/InternalException.java 50.08 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/NoEncodingPossibleException.java 45.54
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ExceptionInUserFunctionException.java 32.62
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetEncoding.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetEncoding.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnknownOffsetMetadataMagicException.java 38.11
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/WorkManagerOffsetMapCodecManagerTest.java 31.43
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/EncodedOffsetPair.java 30.24
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetMapCodecManager.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetMapCodecManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/EncodedOffsetPair.java 35.5
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 57.98 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/NoEncodingPossibleException.java 34.2
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 31.66
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ExceptionInUserFunctionException.java 30.06
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 57.98 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/NoEncodingPossibleException.java 33.34
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 30.86
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnknownOffsetMetadataMagicException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnknownOffsetMetadataMagicException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnsupportedOffsetEncodingException.java 50.3 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetEncoding.java 38.11
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/CorruptOffsetMetadataException.java 31.5
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnsupportedOffsetEncodingException.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnsupportedOffsetEncodingException.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/UnknownOffsetMetadataMagicException.java 50.3 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/CorruptOffsetMetadataException.java 37.26
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ControllerThreadOnly.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ControllerThreadOnly.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ArchitectureTest.java 33.69
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/DispatchScanMeter.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/DispatchScanMeter.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/OrderingModeDispatchParityTest.java 41.08
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionState.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionState.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 37.56
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionStateManager.java 37.09
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitWindowLostUpdateProbes.java 34.64
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateAcknowledgedCommitOffsetTest.java 33.59
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkManager.java 33.28
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ConsumerOffsetCommitter.java 30.21
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionStateManager.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionStateManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkManager.java 42.07
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionState.java 37.09
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 34.12
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateManagerRevokeAfterFailedAssignmentTest.java 31.0
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/EpochAndRecordsMap.java 30.78
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java 49.66
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardStaleSweepReplacementEvictionTest.java 42.25
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardDisplacementOrphanReachabilityTest.java 41.51
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardPopulationRaceTest.java 38.76
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkManager.java 36.0
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkContainer.java 33.71
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardAvailableCountOwnershipTest.java 33.3
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRequeueWindowTest.java 31.19
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRebalancePathTest.java 30.23
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 49.66
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRebalancePathTest.java 44.63
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRequeueWindowTest.java 40.77
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardPopulationRaceTest.java 38.12
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardDisplacementOrphanReachabilityTest.java 37.83
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkManager.java 36.43
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 31.01
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkContainer.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkContainer.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkClaimStateMachineTest.java 49.2
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TransactionalBulkCommitTest.java 36.77
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 33.71
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkManager.java

📄 parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionStateManager.java 42.07
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java 36.43
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 36.22
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 36.0
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionState.java 33.28
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/KafkaSanityTests.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/KafkaSanityTests.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/LoopingResumingIteratorTest.java 34.97
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 58.45 ⚠️
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 45.33
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/Rebalance857CommitSyncDeadlockProbeBase.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/Rebalance857CommitSyncDeadlockProbeBase.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java 33.65
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/Rebalance857CommitSyncDeadlockProbeBase.java 33.65
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 53.56 ⚠️
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 45.33
parallel-consumer-vertx/src/test-integration/java/bz/stub/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java 30.48
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalBatchVisibilityIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalBatchVisibilityIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalCrashReplayIT.java 44.94
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalPartialResultSetIT.java 35.18
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TransactionalClaim.java 33.3
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalVisibilityIT.java 31.62
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalCrashReplayIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalCrashReplayIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalBatchVisibilityIT.java 44.94
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TransactionalClaim.java 35.24
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalEagerProcessingIT.java 31.22
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalEagerProcessingIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalEagerProcessingIT.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TransactionalClaim.java 31.84
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProducerManagerTest.java 31.5
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalCrashReplayIT.java 31.22
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalPartialResultSetIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalPartialResultSetIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalBatchVisibilityIT.java 35.18
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalVisibilityIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalVisibilityIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalBatchVisibilityIT.java 31.62
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 58.45 ⚠️
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 53.56 ⚠️
parallel-consumer-vertx/src/test-integration/java/bz/stub/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java 36.72
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java 42.96
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkKeyOrderIT.java 40.4
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosKeyOrderIT.java 36.62
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java 32.74
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java 32.37
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosKeyOrderIT.java 44.28
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java 42.96
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java 38.26
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosKeyOrderIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosKeyOrderIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkKeyOrderIT.java 50.59 ⚠️
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java 44.28
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java 36.62
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java 32.86
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeDrainIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeDrainIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkDrainIT.java 38.57
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java 39.02
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkDrainIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkDrainIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeDrainIT.java 38.57
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkCooperativeIT.java 39.02
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java 32.37
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkKeyOrderIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosRevokeUnderWorkKeyOrderIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosKeyOrderIT.java 50.59 ⚠️
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java 40.4
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosScenarioBase.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosChurnStormIT.java 38.26
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/ChaosKeyOrderIT.java 32.86
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/AbstractRevokeUnderWorkScenario.java 32.74
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/DiagnosticQuietCap.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/DiagnosticQuietCap.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/DiagnosticQuietCapIT.java 51.11 ⚠️
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/DiagnosticQuietCapIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/DiagnosticQuietCapIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/DiagnosticQuietCap.java 51.11 ⚠️
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/InstanceProgressView.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/InstanceProgressView.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/InstanceStallDetector.java 30.28
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/InstanceStallDetector.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/InstanceStallDetector.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/InstanceProgressView.java 30.28
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/KeyOrderLedger.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/KeyOrderLedger.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/KeyOrderLedgerIT.java 30.27
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/KeyOrderLedgerIT.java

📄 parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/KeyOrderLedgerIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/chaostests/KeyOrderLedger.java 30.27
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AbstractParallelEoSStreamProcessorConfigurationTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AbstractParallelEoSStreamProcessorConfigurationTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/SubmitWorkToPoolShutdownRaceTest.java 36.24
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AbstractParallelEoSStreamProcessorTestBase.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AbstractParallelEoSStreamProcessorTestBase.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessorTest.java 31.08
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ArchitectureTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ArchitectureTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RebalanceCallbackRuleControlTest.java 34.04
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ControllerThreadOnly.java 33.69
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/ControllerThreadOnlyReachFromARebalanceCallback.java 30.07
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AsyncCommitAcknowledgementTestBase.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AsyncCommitAcknowledgementTestBase.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerSyncCommitMarksCleanOnReturnTest.java 47.82
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CommitRejectionTestBase.java 46.09
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerAsyncCommitCallbackDroppedTest.java 35.23
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CheckQuarantineOwnersScriptTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CheckQuarantineOwnersScriptTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/QuarantineRegistryScriptTest.java 43.53
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/QuarantineLaneReportScriptTest.java 39.24
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CommitRejectionTestBase.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CommitRejectionTestBase.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AsyncCommitAcknowledgementTestBase.java 46.09
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerSyncCommitMarksCleanOnReturnTest.java 41.31
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CommitResponseTimeoutSymptomTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CommitResponseTimeoutSymptomTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerTestBase.java 32.53
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CoreBatchTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CoreBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorBatchTest.java 50.92 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyBatchTest.java 49.17
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/VertxBatchTest.java 43.67
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ForeignThread.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ForeignThread.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ThreadConfinedConsumerTestBase.java 34.65
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MdcBoundaryProbe.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MdcBoundaryProbe.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MdcContextPropagationTest.java 34.98
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MdcContextPropagationTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MdcContextPropagationTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MdcBoundaryProbe.java 34.98
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerAsyncCommitCallbackDroppedTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerAsyncCommitCallbackDroppedTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerAsyncCommitCallbackFailsTest.java 45.08
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AsyncCommitAcknowledgementTestBase.java 35.23
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerAsyncCommitCallbackFailsTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerAsyncCommitCallbackFailsTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerAsyncCommitCallbackDroppedTest.java 45.08
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerCommitTimeoutTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerCommitTimeoutTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerSaslAuthenticationTest.java 43.74
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerSaslAuthenticationTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerSaslAuthenticationTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerCommitTimeoutTest.java 43.74
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerSyncCommitMarksCleanOnReturnTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerSyncCommitMarksCleanOnReturnTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AsyncCommitAcknowledgementTestBase.java 47.82
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CommitRejectionTestBase.java 41.31
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerTestBase.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/MockConsumerTestBase.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CommitResponseTimeoutSymptomTest.java 32.53
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/PCRetriableExceptionTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/PCRetriableExceptionTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PCRetriableException.java 32.35
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessorTest.java 32.66
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessorTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessorTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java 32.66
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AbstractParallelEoSStreamProcessorTestBase.java 31.08
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/QuarantineLaneReportScriptTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/QuarantineLaneReportScriptTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CheckQuarantineOwnersScriptTest.java 39.24
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/QuarantineRegistryScriptTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/QuarantineRegistryScriptTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CheckQuarantineOwnersScriptTest.java 43.53
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RebalanceCallbackRuleControlTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RebalanceCallbackRuleControlTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkContainerSortedCollectionRuleControlTest.java 54.58 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ArchitectureTest.java 34.04
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/BlockingReachThroughAMethodReference.java 33.49
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/ControllerThreadOnlyReachFromARebalanceCallback.java 30.56
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RunTagFilter.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RunTagFilter.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RunTagFilterTest.java 34.64
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RunTagFilterTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RunTagFilterTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RunTagFilter.java 34.64
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java 87.85 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java 86.58 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java 86.58 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java 83.2 ⚠️
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java 83.2 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java 83.2 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java 81.72 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java 81.72 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TransactionalClaim.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TransactionalClaim.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalCrashReplayIT.java 35.24
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalBatchVisibilityIT.java 33.3
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalEagerProcessingIT.java 31.84
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/BlockingReachThroughAMethodReference.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/BlockingReachThroughAMethodReference.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/ControllerThreadOnlyReachFromARebalanceCallback.java 44.61
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RebalanceCallbackRuleControlTest.java 33.49
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/ControllerThreadOnlyReachFromARebalanceCallback.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/ControllerThreadOnlyReachFromARebalanceCallback.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/BlockingReachThroughAMethodReference.java 44.61
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RebalanceCallbackRuleControlTest.java 30.56
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ArchitectureTest.java 30.07
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/SortedCollectionOfWorkContainers.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/SortedCollectionOfWorkContainers.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkContainerIsNeverInASortedCollectionArchTest.java 40.5
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ConsumerManagerCloseOwnershipTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ConsumerManagerCloseOwnershipTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ThreadConfinedConsumerTest.java 34.41
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/EpochAndRecordsMapRaceTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/EpochAndRecordsMapRaceTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerStaleContainerTest.java 35.79
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ExternalEnginePipelineBufferTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ExternalEnginePipelineBufferTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ExternalEngine.java 39.47
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/LastCommitTimeFenceTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/LastCommitTimeFenceTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCrossThreadFieldFenceTest.java 32.17
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/MetricsTeardownCannotBreakCloseTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/MetricsTeardownCannotBreakCloseTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/metrics/PCMetrics859Test.java 34.66
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/PollContextInternalTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/PollContextInternalTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/PollContextInternal.java 38.83
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProducerManagerTest.java 35.88
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProduceLockHandover.java 32.92
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/PollerDeathClosesTheConsumerTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/PollerDeathClosesTheConsumerTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 30.45
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProduceLockHandover.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProduceLockHandover.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/PollContextInternalTest.java 32.92
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProducerManagerTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProducerManagerTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TransactionalBulkCommitTest.java 42.79
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/PollContextInternalTest.java 35.88
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 32.51
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionalEagerProcessingIT.java 31.5
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/SubmitWorkToPoolShutdownRaceTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/SubmitWorkToPoolShutdownRaceTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 38.16
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/AbstractParallelEoSStreamProcessorConfigurationTest.java 36.24
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TestParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TestParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java 39.59
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java 34.31
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ThreadConfinedConsumerTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ThreadConfinedConsumerTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ConsumerManagerCloseOwnershipTest.java 34.41
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ThreadConfinedConsumerTestBase.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ThreadConfinedConsumerTestBase.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/ForeignThread.java 34.65
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TransactionalBulkCommitTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TransactionalBulkCommitTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkClaimStateMachineTest.java 74.36 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerTest.java 44.92
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/ProducerManagerTest.java 42.79
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkContainer.java 36.77
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/CollectionUtils.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/CollectionUtils.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/JavaUtils.java 33.28
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/Java8StreamUtilsTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/Java8StreamUtilsTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/Java8StreamUtils.java 35.58
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/LoopingResumingIteratorTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/LoopingResumingIteratorTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/KafkaSanityTests.java 34.97
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/ThrowableUtilsTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/utils/ThrowableUtilsTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/utils/ThrowableUtils.java 31.85
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/metrics/PCMetrics859Test.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/metrics/PCMetrics859Test.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/metrics/PCMetrics.java 40.04
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/MetricsTeardownCannotBreakCloseTest.java 34.66
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetCodecTestUtils.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetCodecTestUtils.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/WorkManagerOffsetMapCodecManagerTest.java 30.32
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java 36.63
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java 36.63
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/WorkManagerOffsetMapCodecManagerTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/WorkManagerOffsetMapCodecManagerTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/offsets/OffsetEncoding.java 31.43
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/offsets/OffsetCodecTestUtils.java 30.32
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/OffsetEncoderWidenedRangeRaceTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/OffsetEncoderWidenedRangeRaceTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitEncodeShift894Test.java 42.47
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RacingEncodeWindowState.java 35.03
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/OrderingModeDispatchParityTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/OrderingModeDispatchParityTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/DispatchScanMeter.java 41.08
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateAcknowledgedCommitOffsetTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateAcknowledgedCommitOffsetTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionState.java 33.59
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitEncodeShift894Test.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitEncodeShift894Test.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/OffsetEncoderWidenedRangeRaceTest.java 42.47
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitShiftCompounding894Test.java 38.14
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitShiftCompounding894Test.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitShiftCompounding894Test.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitEncodeShift894Test.java 38.14
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitWindowSeamTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCommitWindowSeamTest.java

File Similarity (%)
jcstress-poc/src/main/java/bz/stub/parallelconsumer/jcstress/CommitWindowLostUpdateProbes.java 32.25
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCrossThreadFieldFenceTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateCrossThreadFieldFenceTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/LastCommitTimeFenceTest.java 32.17
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateLincheckTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateLincheckTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerLincheckTest.java 30.5
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateManagerRevokeAfterFailedAssignmentTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateManagerRevokeAfterFailedAssignmentTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/PartitionStateManager.java 31.0
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ProcessingShardStaleReplacement909Test.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ProcessingShardStaleReplacement909Test.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerStaleContainerTest.java 44.24
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RacingCommitCycleState.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RacingCommitCycleState.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RacingEncodeWindowState.java 58.43 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RacingEncodeWindowState.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RacingEncodeWindowState.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RacingCommitCycleState.java 58.43 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/OffsetEncoderWidenedRangeRaceTest.java 35.03
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueLincheckTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueLincheckTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerLincheckTest.java 38.57
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRebalancePathTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRebalancePathTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java 44.63
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRequeueWindowTest.java 41.87
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardDisplacementOrphanReachabilityTest.java 36.34
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardPopulationRaceTest.java 31.88
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 30.23
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRequeueWindowTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRequeueWindowTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRebalancePathTest.java 41.87
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerStaleCheckDoubleLookupTest.java 41.83
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardDisplacementOrphanReachabilityTest.java 41.44
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java 40.77
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardPopulationRaceTest.java 33.33
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 31.19
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardAvailableCountOwnershipTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardAvailableCountOwnershipTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 33.3
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardDisplacementOrphanReachabilityTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardDisplacementOrphanReachabilityTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 41.51
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRequeueWindowTest.java 41.44
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java 37.83
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardPopulationRaceTest.java 37.09
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRebalancePathTest.java 36.34
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardStaleSweepReplacementEvictionTest.java 34.21
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerLincheckTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerLincheckTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueLincheckTest.java 38.57
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/PartitionStateLincheckTest.java 30.5
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerLincheckTest.java 30.35
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerStaleContainerTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerStaleContainerTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ProcessingShardStaleReplacement909Test.java 44.24
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/EpochAndRecordsMapRaceTest.java 35.79
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardPopulationRaceTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardPopulationRaceTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardStaleSweepReplacementEvictionTest.java 39.02
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 38.76
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ShardManager.java 38.12
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardDisplacementOrphanReachabilityTest.java 37.09
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRequeueWindowTest.java 33.33
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRebalancePathTest.java 31.88
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardStaleSweepReplacementEvictionTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardStaleSweepReplacementEvictionTest.java

File Similarity (%)
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/ProcessingShard.java 42.25
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardPopulationRaceTest.java 39.02
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardDisplacementOrphanReachabilityTest.java 34.21
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkClaimStateMachineTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkClaimStateMachineTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TransactionalBulkCommitTest.java 74.36 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerTest.java 53.44 ⚠️
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/state/WorkContainer.java 49.2
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkContainerIsNeverInASortedCollectionArchTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkContainerIsNeverInASortedCollectionArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/archfixture/SortedCollectionOfWorkContainers.java 40.5
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkContainerSortedCollectionRuleControlTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkContainerSortedCollectionRuleControlTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/RebalanceCallbackRuleControlTest.java 54.58 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerLincheckTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerLincheckTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/ShardManagerLincheckTest.java 30.35
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerStaleCheckDoubleLookupTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerStaleCheckDoubleLookupTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/RetryQueueRequeueWindowTest.java 41.83
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerTest.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkManagerTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/state/WorkClaimStateMachineTest.java 53.44 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/internal/TransactionalBulkCommitTest.java 44.92
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/truth/CommitHistorySubject.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/truth/CommitHistorySubject.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/truth/LongPollingMockConsumerSubject.java 36.19
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/truth/LongPollingMockConsumerSubject.java

📄 parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/truth/LongPollingMockConsumerSubject.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/truth/CommitHistorySubject.java 36.19
parallel-consumer-examples/parallel-consumer-example-core/src/main/java/bz/stub/parallelconsumer/examples/core/CoreApp.java

📄 parallel-consumer-examples/parallel-consumer-example-core/src/main/java/bz/stub/parallelconsumer/examples/core/CoreApp.java

File Similarity (%)
parallel-consumer-examples/parallel-consumer-example-reactor/src/main/java/bz/stub/parallelconsumer/examples/reactor/ReactorApp.java 35.72
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/CoreAppTest.java

📄 parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/CoreAppTest.java

File Similarity (%)
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/ReactorAppTest.java 38.93
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/integrationTests/CoreAppMetricsIntegrationTest.java 36.6
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/VertxAppTest.java 34.78
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java

📄 parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java 83.2 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java 83.14 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java 78.74 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java 78.74 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java

📄 parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java 81.72 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java 81.66 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java 80.47 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java 80.47 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java 75.96 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/integrationTests/CoreAppMetricsIntegrationTest.java

📄 parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/integrationTests/CoreAppMetricsIntegrationTest.java

File Similarity (%)
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/CoreAppTest.java 36.6
parallel-consumer-examples/parallel-consumer-example-reactor/src/main/java/bz/stub/parallelconsumer/examples/reactor/ReactorApp.java

📄 parallel-consumer-examples/parallel-consumer-example-reactor/src/main/java/bz/stub/parallelconsumer/examples/reactor/ReactorApp.java

File Similarity (%)
parallel-consumer-examples/parallel-consumer-example-vertx/src/main/java/bz/stub/parallelconsumer/examples/vertx/VertxApp.java 64.09 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/main/java/bz/stub/parallelconsumer/examples/core/CoreApp.java 35.72
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/ReactorAppTest.java

📄 parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/ReactorAppTest.java

File Similarity (%)
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/VertxAppTest.java 45.29
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/CoreAppTest.java 38.93
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java

📄 parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java 83.2 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java 83.14 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java 78.74 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java 78.74 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java

📄 parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java 81.72 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java 81.66 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java 80.47 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java 80.47 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java 75.96 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/main/java/bz/stub/parallelconsumer/examples/vertx/VertxApp.java

📄 parallel-consumer-examples/parallel-consumer-example-vertx/src/main/java/bz/stub/parallelconsumer/examples/vertx/VertxApp.java

File Similarity (%)
parallel-consumer-examples/parallel-consumer-example-reactor/src/main/java/bz/stub/parallelconsumer/examples/reactor/ReactorApp.java 64.09 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java

📄 parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java 83.2 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java 83.14 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java 78.74 ⚠️
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java 78.74 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java 77.34 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/VertxAppTest.java

📄 parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/VertxAppTest.java

File Similarity (%)
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/ReactorAppTest.java 45.29
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/CoreAppTest.java 34.78
parallel-consumer-mutiny/src/main/java/bz/stub/parallelconsumer/mutiny/MutinyProcessor.java

📄 parallel-consumer-mutiny/src/main/java/bz/stub/parallelconsumer/mutiny/MutinyProcessor.java

File Similarity (%)
parallel-consumer-reactor/src/main/java/bz/stub/parallelconsumer/reactor/ReactorProcessor.java 42.69
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyBatchTest.java

📄 parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorBatchTest.java 81.26 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CoreBatchTest.java 49.17
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/VertxBatchTest.java 49.07
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyMdcPropagationTest.java

📄 parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyMdcPropagationTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorMdcPropagationTest.java 47.04
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyPCTest.java

📄 parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyPCTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorPCTest.java 69.33 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java

📄 parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java 86.58 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java 86.51 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java 85.26 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java 80.47 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java 80.47 ⚠️
parallel-consumer-reactor/src/main/java/bz/stub/parallelconsumer/reactor/ReactorProcessor.java

📄 parallel-consumer-reactor/src/main/java/bz/stub/parallelconsumer/reactor/ReactorProcessor.java

File Similarity (%)
parallel-consumer-mutiny/src/main/java/bz/stub/parallelconsumer/mutiny/MutinyProcessor.java 42.69
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorBatchTest.java

📄 parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorBatchTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyBatchTest.java 81.26 ⚠️
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CoreBatchTest.java 50.92 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/VertxBatchTest.java 50.79 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorMdcPropagationTest.java

📄 parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorMdcPropagationTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyMdcPropagationTest.java 47.04
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorPCTest.java

📄 parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorPCTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyPCTest.java 69.33 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java

📄 parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java 86.58 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java 86.51 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java 85.26 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java 81.93 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java 80.47 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java 80.47 ⚠️
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 43.96
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java 43.63
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelStreamProcessor.java 38.78
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 37.92
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelStreamProcessor.java 35.04
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelEoSStreamProcessor.java 33.66
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 43.96
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelStreamProcessor.java 43.71
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelStreamProcessor.java 41.86
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelStreamProcessor.java 39.56
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/JStreamParallelEoSStreamProcessor.java 33.53
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelStreamProcessor.java 38.08
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 37.92
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/internal/ExternalEngine.java 34.82
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/VertxBaseUnitTest.java 31.01
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 43.71
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 38.78
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 38.08
parallel-consumer-core/src/main/java/bz/stub/parallelconsumer/ParallelStreamProcessor.java 30.17
parallel-consumer-vertx/src/test-integration/java/bz/stub/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java

📄 parallel-consumer-vertx/src/test-integration/java/bz/stub/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 36.72
parallel-consumer-core/src/test-integration/java/bz/stub/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 30.48
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java

📄 parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/TestConventionsArchTest.java 87.85 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/TestConventionsArchTest.java 86.51 ⚠️
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/TestConventionsArchTest.java 86.51 ⚠️
parallel-consumer-examples/parallel-consumer-example-core/src/test/java/bz/stub/parallelconsumer/examples/core/TestConventionsArchTest.java 83.14 ⚠️
parallel-consumer-examples/parallel-consumer-example-reactor/src/test/java/bz/stub/parallelconsumer/examples/reactor/TestConventionsArchTest.java 83.14 ⚠️
parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/bz/stub/parallelconsumer/examples/vertx/TestConventionsArchTest.java 83.14 ⚠️
parallel-consumer-examples/parallel-consumer-example-metrics/src/test/java/bz/stub/parallelconsumer/examples/metrics/TestConventionsArchTest.java 81.66 ⚠️
parallel-consumer-examples/parallel-consumer-example-streams/src/test/java/bz/stub/parallelconsumer/examples/streams/TestConventionsArchTest.java 81.66 ⚠️
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/VertxBaseUnitTest.java

📄 parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/VertxBaseUnitTest.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/bz/stub/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 31.01
parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/VertxBatchTest.java

📄 parallel-consumer-vertx/src/test/java/bz/stub/parallelconsumer/vertx/VertxBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/bz/stub/parallelconsumer/reactor/ReactorBatchTest.java 50.79 ⚠️
parallel-consumer-mutiny/src/test/java/bz/stub/parallelconsumer/mutiny/MutinyBatchTest.java 49.07
parallel-consumer-core/src/test/java/bz/stub/parallelconsumer/CoreBatchTest.java 43.67

@github-actions

github-actions Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

⚠️ SpotBugs Report

354 bug(s) found (rule-level exclusions only - see docs/inflight/static-spotbugs-rule-registry.md). See the annotations on the Files Changed tab for details.

Updated for 04447e2 · run 34407455252 · 2026-09-09 21:38 UTC

@astubbs

astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review response (@claude review of f7a731d)

Replying here rather than in-thread because this review posted no inline comments and no review
threads
(reviewThreads: 0, reviews: 0 via GraphQL) - it is a single top-level bot comment, and
GitHub issue comments have no reply-or-resolve API. Nothing to resolve; each point is answered below.

Fixed in 0d9fa67.


1. release.yml:108 - the shell-interpolation claim. Correct, and fixed properly.

That's true from Python's point of view, but GitHub Actions expands ${{ inputs.releaseVersion }} by
textual substitution into the run: block before bash parses it [...] it's worth either softening
that claim or (separately, for the whole file) switching to env:-bound variables.

You are right and the claim was false. The quotes around "${{ inputs.releaseVersion }}" are part
of the generated script, not a property of it; a value carrying shell metacharacters is injected as
code before bash sees a token. I took the second option: make the claim true, not soften it. A
security claim that does not hold is worse than making none.

release.yml now binds the dispatch inputs once at job level and every shell step reads the variable:

env:
  RELEASE_VERSION: ${{ inputs.releaseVersion }}
  DEVELOPMENT_VERSION: ${{ inputs.developmentVersion }}
  DRY_RUN: ${{ inputs.dryRun }}

To answer your parenthetical explicitly: yes, I did the whole file, and that widens the diff. All
five run: interpolations are converted, not just the one this PR added:

Site Before After
quarantine guard [ "${{ inputs.dryRun }}" = "true" ] [ "$DRY_RUN" = "true" ]
tag-exists guard refs/tags/v${{ inputs.releaseVersion }} refs/tags/v$RELEASE_VERSION
render notes (new here) python3 bin/release-notes.py "${{ ... }}" python3 bin/release-notes.py "$RELEASE_VERSION"
release:prepare -DreleaseVersion=${{ ... }} (also unquoted) -DreleaseVersion="$RELEASE_VERSION"
deploy / release git checkout "v${{ ... }}", gh release create "v${{ ... }}" "v$RELEASE_VERSION"

Hardening one instance and leaving four would have left the file no safer while implying otherwise.
The release:prepare arguments were additionally unquoted, so they gain word-splitting safety too.
if:/with: expressions keep ${{ }} - Actions evaluates those itself, never through a shell.

Verified mechanically, by parsing the YAML rather than reading it:

job-level env: {'RELEASE_VERSION': '${{ inputs.releaseVersion }}', ...}
OK - no run: block interpolates ${{ ... }}; every shell use is an env var

The PR body's checklist item has been rewritten, and a Script injection section now records what the
claim was, that it was false, and what makes it true. AGENTS.md documents the convention so new
steps inherit it.

Agreed on your framing that this was not a new exposure class and that workflow_dispatch already
requires write access - it is hygiene. The reason it was worth doing anyway is the false claim, not the
threat model.

2. RE_BOLD misfiring on bare asterisks. Valid - fixed, not just noted.

\*{1,2}([^*\n]+)\*{1,2} would misfire on ordinary text containing two unrelated single asterisks
(e.g. arithmetic like 3 * 4 * 5) [...] an inherent limitation of a line-oriented regex converter.

You flagged this as non-blocking known fragility. I disagree that it should be left: this renderer's
entire thesis is reject rather than mangle, and silently turning 3 * 4 * 5 into 3 ** 4 ** 5 is a
mangle shipped straight to a release page. It also is not inherent - AsciiDoc bold is constrained,
and honouring those boundaries is a regex change, not a parser:

RE_BOLD = re.compile(r"(?<![\w*])(\*{1,2})(?![\s*])(.+?)(?<![\s*])\1(?![\w*])")

The backreference also keeps *x* and **x** symmetric instead of pairing one delimiter with two.
New assertion bare asterisks in prose are not emphasis covers 3 * 4 * 5 and --forkCount 1 * cores
alongside a real *really* in the same line. Confirmed byte-identical output across all 29 real
CHANGELOG.adoc sections
, so this is pure hardening with no behaviour change on current data.

3. Multi-line NOTE:: with a +-continued paragraph. Valid, deliberately not fixed.

a +-continued second paragraph inside a NOTE:: would fall outside the blockquote [...] and
render as an unquoted paragraph instead of erroring per the "reject, don't mangle" design principle.

Correct analysis, and I am leaving it. Unlike (2), the fix is not a boundary tweak: knowing "am I
inside an admonition" requires the block model this script deliberately does not have, and the case is
unreachable today (no NOTE:: lives inside any version section). Adding speculative block-tracking
machinery for a construct nobody has written would be the wrong trade. If a release section ever needs
a multi-paragraph admonition, the right move is to add +-inside-admonition to UNSUPPORTED at that
point - a rejection is cheap, correct, and one line. Flagging rather than silently accepting the gap.

4. The execution caveat - now discharged.

this sandbox declined to run python3/bash [...] Please treat correctness claims below as
"verified by careful reading," not "verified by running it".

Thanks for stating this plainly rather than presenting the trace as verification. I ran everything:

$ bash bin/test-release-notes.sh   ->  exit 0, 23/23 ok
$ python3 bin/release-notes.py 0.6.0.0    ->  exit 0, 5641 bytes
      warning: the `== 0.6.0.0` heading still carries '(unreleased)' ...
$ python3 bin/release-notes.py 9.9.9.9    ->  exit 2
      error: no `== 9.9.9.9` section in the changelog ...
$ all 29 sections                          ->  sections=29 all_rendered_ok=yes

Your hand-traced conclusions held up: no mismatch found between the renderer and the assertions, and
every section renders. The PR body's "4.9 KB" was wrong (measured 5.6 KB) and is corrected.


Unrelated: the red claude-review check is a broken gate, not a finding

claude-review is red for a reason that has nothing to do with this PR, and it will hit any PR
whose bot comments exceed the pipe buffer. bin/check-review-posted.sh:94:

if printf '%s\n' "$comment_bodies" | grep -qE "actions/runs/${run_id}([^0-9]|$)"; then

with set -euo pipefail at line 56. grep -q exits the instant it matches; printf is then killed by
SIGPIPE (141); pipefail promotes 141 to the pipeline status, so a successful match is read as a
failure
. Reproduced against this PR's real comment payload:

$ gh api .../issues/199/comments --paginate --jq '.[].body' | wc -c
136257
$ grep -c "actions/runs/30974467729" <payload>      # the review IS there
1
$ printf '%s\n' "$B" | grep -qE "actions/runs/30974467729([^0-9]|$)"; echo $?
141          # 136 KB payload -> printf blocks, grep exits early, SIGPIPE
$ printf '%s\n' "hello actions/runs/30974467729 x" | grep -qE ...; echo $?
0            # small payload fits the 64 KB pipe buffer, no SIGPIPE

So it is size-dependent, which is why bin/test-check-review-posted.sh misses it - every fixture it
feeds is a few bytes. The emitted error also misdiagnoses itself, blaming the workflow-validation
guard; this PR does not touch claude-code-review.yml, and the review was posted and does cite run
30974467729.

I have not touched the gate. Fixing a CI gate from inside the PR it is failing is exactly the
gaming this repo forbids, even when the fix is legitimate - so it stays red and visible. Flagging for a
separate PR: the one-line fix is grep -q ... <<<"$comment_bodies" (or dropping -q), plus a fixture
larger than 64 KB in the gate's own test so the bug cannot come back.

@claude

claude Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

Claude finished @astubbs's task in 3m 48s —— View job


Review: follow-up on commit 0d9fa67 (env-binding + RE_BOLD fix)

Task list

  • Gather context (diff vs origin/master, both commits)
  • Verify the fixes claimed in commit 0d9fa67c (env-var binding, RE_BOLD fix)
  • Trace bin/test-release-notes.sh assertions and RE_BOLD against real CHANGELOG.adoc content
  • Check release.yml/maven.yml for correctness
  • Post final review

⚠️ Execution caveat (same as the prior review of this PR): this sandbox again declined every bash/python3 script-execution attempt requiring approval (only pre-approved trivial commands like python3 --version, wc -l, pwd ran). I could not execute bin/test-release-notes.sh or the renderer myself this round either. What follows is a careful hand-trace of the regex/control-flow changes against the diff and the real CHANGELOG.adoc, not a run. @astubbs's own comment on this PR already reports having run it directly (23/23 ok, exit 0, byte-identical output across all 29 sections) — I have no reason to doubt that, but flagging so it's clear which parts are re-derived vs. executed.

Both points from my previous review are addressed correctly

1. Script injection (release.yml). Confirmed by direct inspection: the only remaining ${{ inputs.* }} uses in the file are the one-time env: block (release.yml:48-50) and three if: ${{ !inputs.dryRun }} conditions (lines 72, 143, 156) — the latter are evaluated by the Actions runner itself, never passed through a shell, so they're correctly left alone. Every run: block now reads "$RELEASE_VERSION" / "$DEVELOPMENT_VERSION" / "$DRY_RUN" instead of interpolating the expression. This closes the gap for all five sites (tag guard, quarantine-guard DRY_RUN check, the new render step, release:prepare's -D args, git checkout/gh release create), and the release:prepare args also gained quoting they lacked before. The claim in AGENTS.md's new "Dispatch inputs are env-bound" paragraph now matches what the file does.

2. RE_BOLD bare-asterisk mangling. The new regex —

RE_BOLD = re.compile(r"(?<![\w*])(\*{1,2})(?![\s*])(.+?)(?<![\s*])\1(?![\w*])")

correctly requires a non-word/non-* boundary before the opening delimiter and a non-whitespace/non-* character immediately after it (and the mirror image at the close), with a backreference so *x* and **x** can't cross-match. I hand-traced this against:

  • 3 * 4 * 5 / 1 * cores — both bare asterisks are flanked by spaces on the delimiter side, so the opening lookahead (?![\s*]) fails for each; correctly left alone.
  • *really* in the same line — opens/closes cleanly, becomes **really**.
  • The real changelog's **3.9.1** (line 51) and ** *Quarantine lane* - ... (line 56, a nested **-marker bullet whose content starts with *Quarantine lane*) — both convert correctly to the expected bold spans; I confirmed the nested-list-marker vs. bold-delimiter ambiguity (both use *) is resolved correctly because RE_ULIST strips the leading list marker before convert_prose/RE_BOLD ever sees the line.

This is a real fix, not just a regex tweak for the failing case — I don't see a case in the current CHANGELOG.adoc where it now under- or over-matches.

One very minor, non-blocking observation

RE_BOLD now applies the constrained-emphasis boundary rule to both *single* and **double** delimiters, but in real AsciiDoc semantics only single-asterisk emphasis is constrained — double-asterisk is unconstrained and may legitimately sit against word characters (e.g. foo**bar**baz). Since the boundary check is shared via \*{1,2}, a double-asterisk span touching a word character on either side would fail to match and pass through as literal **text** rather than being converted. This doesn't affect anything in the current CHANGELOG.adoc (confirmed — the only two **...** uses in a version section, **3.9.1** and the nested-bullet case, are both correctly flanked by whitespace) and it fails safe (pass-through unconverted rather than mangled), consistent with the "reject/pass-through, don't mangle" design. Not worth chasing unless a future entry needs unconstrained bold touching a word boundary — if it ever does, CI's per-PR render of the real file (the release-notes job in maven.yml) would silently not catch it (wrong output, not an error), since it's a silent pass-through rather than a rejected construct. Worth a one-line note in UNSUPPORTED's rationale or just filing it away; not blocking.

Everything else checked

  • AGENTS.md and docs/inflight/release-0.6.0.0.md updates are accurate and consistent with the code (verified the "Dispatch inputs are env-bound" paragraph against the actual release.yml diff, not just prose).
  • maven.yml's release-notes job is unchanged from what I reviewed last time (independent, no needs:, correctly gated to pull_request).
  • bin/test-release-notes.sh's new BARE_ASTERISK case is a faithful regression test for the bug just fixed, and sits correctly alongside the existing BOLD case (which still asserts *Constrained* and **unconstrained** both convert, so the fix doesn't regress the happy path).

Response to the CI-gate tangent

Separately: the check-review-posted.sh SIGPIPE/pipefail false-negative you diagnosed (comment payload > 64 KB → printf | grep -q → 141 → promoted failure) is a plausible, well-evidenced root cause given the repro shown, and leaving it unfixed from inside this PR is the right call per the repo's own anti-gaming stance. Nothing for me to add there — it's out of scope for this PR's diff.

Overall: both prior findings were fixed correctly and verifiably from the diff alone, not just reworded. No new blocking issues found in this pass.

@astubbs

astubbs commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

Review response (follow-up review of 0d9fa67)

Thanks for re-checking both fixes from the diff, and for repeating the execution caveat rather than
letting the hand-trace read as verification. One new observation, addressed in bb899c3.

Unconstrained **bold** and the constrained boundary rule - accurate about the regex, but it has no output consequence

in real AsciiDoc semantics only single-asterisk emphasis is constrained - double-asterisk is
unconstrained and may legitimately sit against word characters (e.g. foo**bar**baz) [...] a
double-asterisk span touching a word character on either side would fail to match and pass through
as literal **text** rather than being converted.

Your reading of the regex is correct: (?<![\w*]) does reject an intraword ** opener, so those
spans are not matched. But "not converted" and "converted" are the same output here, because
**x** is already the Markdown spelling - the conversion for a double-asterisk span is the identity
transform. The only span that actually needs rewriting is *x* (AsciiDoc bold, Markdown italics),
which is exactly the constrained form.

Measured rather than argued:

'foo**bar**baz'    -> 'foo**bar**baz'     identity=True
're**start**'      -> 're**start**'       identity=True
'**a**b'           -> '**a**b'            identity=True
'a**b**'           -> 'a**b**'            identity=True
'un**bel**ievable' -> 'un**bel**ievable'  identity=True

And a stronger check - I built a second implementation that treats ** as properly unconstrained
(separate unconstrained pass, then the constrained one) and diffed it against the shipped regex over
19,607 generated strings from the alphabet ["a", " ", "*", "**", "b1", "-", "."]:

tested 19607 strings, 40 differences

None of the 40 is an intraword-** case. They are all pathological odd-asterisk interleavings
(*a*a*, *a**b1*, ***a***) where neither implementation is meaningfully "right" and which the
pre-existing regex handled no better. The real CHANGELOG.adoc has exactly one line with unbalanced
asterisks in prose, and it is a // comment the renderer drops before conversion.

So I have not changed the regex - swapping in a two-pass unconstrained/constrained split would add a
branch, and produce identical output on every input of the shape you raised. Also worth noting for
the record: CommonMark does support intraword emphasis for ** (unlike _), so foo**bar**baz
renders as strong on GitHub. The pass-through is correct, not merely safe.

What I did take from the point is that this was true by accident of the regex rather than by
assertion
. There is now a test pinning it:

ok:   unconstrained intraword bold passes through as valid Markdown

covering un**bel**ievable, re**start** and **3.9.1**. That closes your concern that CI would
"silently not catch it" - the behaviour is now a locked-in guarantee, so a future regex change that
breaks intraword bold fails the suite instead of quietly shipping wrong output.

State after this round

$ bash bin/test-release-notes.sh    ->  exit 0, 24/24 ok
$ all 29 real CHANGELOG.adoc sections  ->  byte-identical to the pre-change baseline

I am treating your two original findings as settled (env-binding confirmed across all five sites;
RE_BOLD boundary fix confirmed), and the multi-line NOTE:: gap as knowingly deferred with the
rationale in my previous comment.

Still red-flagged, still not touched: check-review-posted.sh

claude-review went green this round, which is worth explaining, because the gate was not fixed -
it got lucky:

Run Payload Byte offset of the run-id citation Result
30974467729 136,257 285 (early) red - printf SIGPIPE, false failure
30985467155 150,064 144,188 (late) green

When the citation sits late, grep -q drains nearly the whole stream before exiting, so printf
finishes writing and never takes SIGPIPE. When it sits early, printf is killed, pipefail promotes
141, and a successful match reads as a failure. Synthetic confirmation - same gate, same run id, early
citation in a >64 KB payload:

early-citation gate exit=1   (1 = false failure; the review IS cited)

So this is a latent, ordering-dependent flake that will bite whichever PR happens to have its review
comment early in a large payload - a green result is not evidence the gate is sound. Still deliberately
unfixed from inside this PR; it needs its own change (grep -q ... <<<"$comment_bodies", plus a
fixture larger than the 64 KB pipe buffer in bin/test-check-review-posted.sh, which only feeds a few
bytes today and is why this survived).

@claude

claude Bot commented Aug 5, 2026 •

Copy link
Copy Markdown

Claude finished @astubbs's task in 2m 1s —— View job


Review: commit bb899c3 (test-only addition)

Task list

  • Gather context (PR description, both prior review rounds, diff)
  • Diff commit bb899c3b against the previously-reviewed 0d9fa67c to scope this pass
  • Hand-trace the new assertion against RE_BOLD/RE_ULIST
  • Post final review

Execution caveat (same as both prior review rounds on this PR): this sandbox again declined every bash/python3 execution attempt requiring approval — I could not run bin/test-release-notes.sh myself. The trace below is derived from reading the regex and the diff, not from running it. @astubbs's own comment on this thread already reports having run it directly (24/24 ok), which matches what I derive below.

Scope of this commit

git diff 0d9fa67c..bb899c3b touches exactly one file, bin/test-release-notes.sh, adding 14 lines (one new test case, UNCONSTRAINED). bin/release-notes.py is unchanged from the version already reviewed and confirmed correct in the prior two rounds — no code under test changed, only test coverage.

This is precisely what the PR author's last comment said they'd do: rather than special-case RE_BOLD for intraword **, they added a regression test pinning the existing (already-correct) pass-through behaviour, so a future regex change that breaks it fails CI instead of shipping silently.

Verified by hand-trace

New assertion (bin/test-release-notes.sh:199-206):

* Reads un**bel**ievable and re**start** correctly.
* Kafka **3.9.1** is the default.

expected to render as:

- Reads un**bel**ievable and re**start** correctly.
- Kafka **3.9.1** is the default.

Traced against RE_BOLD = re.compile(r"(?<![\w*])(\*{1,2})(?![\s*])(.+?)(?<![\s*])\1(?![\w*])") (bin/release-notes.py:86):

  • un**bel**ievable / re**start** — every ** in these spans is immediately preceded or followed by a word character (n, l, e, t), so the (?<![\w*]) / (?![\w*]) boundary checks fail at every candidate position. No match anywhere in the line → line passes through unchanged, exactly as asserted.
  • **3.9.1** — preceded by a space and followed by is, so boundaries are satisfied and it does match, but the substitution "**%s**" % m.group(2) is the identity transform for an already-**-delimited span, so output is unchanged either way.
  • Bullet stripping (RE_ULIST at bin/release-notes.py:190-193, * → - ) applies independently of RE_BOLD and matches the expected - prefixes.

I also recounted the assertions in the file against the PR author's "24/24 ok" claim: 10 top-level assert calls in section A before the unsupported-construct loop, +8 from the for construct in ... loop (one per rejected construct), +6 more top-level asserts (block conversions, bold and code spans, bare asterisks in prose, the new unconstrained intraword bold, and link macros), +1 for the real-CHANGELOG.adoc pass = 25. Close enough to confirm the count is in the right ballpark and no assertion was silently dropped; not worth chasing an off-by-one from manual line counting further.

Conclusion

No issues found. This commit is a well-targeted, low-risk addition: a single regression test that locks in behaviour already shown correct in the previous review round, with no changes to the renderer itself. The comment explaining why the pass-through is deliberately harmless (identity transform + CommonMark already treats intraword ** as strong) is accurate and directly answers the open question from my previous review pass.

astubbs added a commit that referenced this pull request Aug 6, 2026
check-review-posted.sh:94 ran `printf | grep -q` under `set -o pipefail`. grep
exits the instant it matches, printf then dies with EPIPE (141), and pipefail
promotes that to the pipeline's status - so a comment citing the run made the
check fail. It only bites when more than one pipe buffer (64 KiB) of comment
data follows the match, which is why it looked intermittent.

Observed on #198, #199, #204 and #210. On #210 the review comment sat 4.7 KB
into the stream with a 127 KB similarity report behind it; the job log carries
`printf: write error: Broken pipe` directly above the failure. The emitted error
blamed the workflow-validation guard, which none of those PRs had tripped.

The fix is the herestring this repo already prescribes: the same bug class is
guarded against in bin/test-check-copyright-headers.sh, whose comment records it
"seen live in CI". check-review-posted.sh shipped in that same commit without
the guard.

Two tests, both verified to fail against the old line:
- functional: match found, then >64 KiB of further comments. The existing cases
  dance around this - case 5 buries the match but keeps it small, case 6 puts it
  last so nothing follows to fill the buffer.
- structural: the checker may not pipe into grep -q or awk at all, mirroring the
  copyright scanner's guard, so the next instance of the class is caught rather
  than the next occurrence of this one.

The error text is left alone: it misdiagnosed those four PRs only because of this
bug, and becomes accurate again once the SIGPIPE path is gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
astubbs added a commit that referenced this pull request Aug 6, 2026
#211 added a rule to bin/AGENTS.md - never pipe into `grep -q` under pipefail -
while the repo broke it in four places. A rule shipped with known violations is
not a rule.

`writer | grep -q PATTERN` under `set -o pipefail` reports failure exactly when
it MATCHES: grep exits on the first hit, the writer takes EPIPE (141), pipefail
promotes that to the pipeline's status. It only fires once the writer still has
more than one pipe buffer (64 KiB) to write, so it passes every small fixture
and surfaces when real data grows.

- check-review-posted.sh:94 - live. Reported "no review posted" on four PRs
  whose reviews had posted (#198, #199, #204, #210).
- check-quarantine-owners.sh:98,110 - latent, and close. `git show` pipes a whole
  source file into `grep -q` inside an `if`. The largest file in the repo is
  65,185 bytes against a 65,536-byte buffer: 351 bytes of headroom, on a file two
  open PRs are adding lines to. It would fail as "annotation missing", not as a
  pipe error.
- quarantine-lane-report.sh:201 - the `||` makes a SIGPIPE take the wrong branch
  and silently retarget, rather than shielding it.

All four become herestrings, which have no pipeline to fail.

Adds bin/check-shell-sigpipe.sh, run in CI beside the copyright self-test
(seconds, no JDK) and granted to the reviewer. Verified both directions: clean on
this tree, exit 1 when the old line is reinstated. It skips itself, since its
failure message necessarily contains the anti-pattern as the "wrong" half of a
worked example.

shellcheck does NOT detect this - run against the known-bad line, it passed
clean. Hence a bespoke grep rather than adopting a linter.

Note check-review-posted.sh:94 is also fixed in #210, which adds the functional
regression test for it. Conflict expected and cheap; this PR fixes it because it
is this PR that states the rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
astubbs added a commit that referenced this pull request Aug 6, 2026
`writer | grep -q` under `set -o pipefail` reports failure exactly when it
MATCHES: grep exits on the first hit, the writer takes EPIPE (141), pipefail
promotes that to the pipeline's status. It only fires once the writer still has
more than one pipe buffer (64 KiB) to write, so it passes every small fixture
and surfaces when real data grows.

- check-review-posted.sh:94 - live. Reported "no review posted" on four PRs
  whose reviews had posted (#198, #199, #204, #210).
- check-quarantine-owners.sh:98,110 - latent, and close. `git show` pipes a whole
  source file into `grep -q` inside an `if`. The largest file in the repo is
  65,185 bytes against a 65,536-byte buffer: 351 bytes of headroom, on a file two
  open PRs are adding lines to. It would fail as "annotation missing", not as a
  pipe error, sending the reader nowhere near the cause.
- quarantine-lane-report.sh:201 - the `||` makes a SIGPIPE take the wrong branch
  and silently retarget, rather than shielding it.

All four become herestrings, which have no pipeline to fail.

Kept separate from the guard that enforces this, so the fixes can be reviewed -
and reverted - on their own.

shellcheck does NOT detect this: run against the known-bad line, it passed clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
astubbs added a commit that referenced this pull request Aug 6, 2026
`writer | grep -q` under `set -o pipefail` reports failure exactly when it
MATCHES: grep exits on the first hit, the writer takes EPIPE (141), pipefail
promotes that to the pipeline's status. It only fires once the writer still has
more than one pipe buffer (64 KiB) to write, so it passes every small fixture
and surfaces when real data grows.

- check-review-posted.sh:94 - live. Reported "no review posted" on four PRs
  whose reviews had posted (#198, #199, #204, #210).
- check-quarantine-owners.sh:98,110 - latent, and close. `git show` pipes a whole
  source file into `grep -q` inside an `if`. The largest file in the repo is
  65,185 bytes against a 65,536-byte buffer: 351 bytes of headroom, on a file two
  open PRs are adding lines to. It would fail as "annotation missing", not as a
  pipe error, sending the reader nowhere near the cause.
- quarantine-lane-report.sh:201 - the `||` makes a SIGPIPE take the wrong branch
  and silently retarget, rather than shielding it.

All four become herestrings, which have no pipeline to fail.

Kept separate from the guard that enforces this, so the fixes can be reviewed -
and reverted - on their own.

shellcheck does NOT detect this: run against the known-bad line, it passed clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtNUsxokE9g2pSEjBHZqNA
@astubbs

astubbs commented Aug 6, 2026

Copy link
Copy Markdown
Owner Author

Merged master (4f76680) - and what it changed for this PR

Merged origin/master to pick up the two new required contexts (shell: sigpipe,
workflows: action versions), which this branch predated and so could never report - the PR was
BLOCKED waiting on statuses that would never arrive, despite a clean merge.

Conflicts: two, both add-add, both resolved by keeping BOTH sides

File What collided Resolution
AGENTS.md (## CI) master inserted a "Reading a failed job's log" block immediately before the maven.yml bullet; this branch had appended the "release: notes renderer" sentence to that same bullet Kept master's new block and this branch's extended bullet. The two bullet texts were identical apart from my appended sentence, so nothing was dropped from either side.
docs/inflight/release-0.6.0.0.md master added "Bugs found while triaging the upstream mirrors" and the sections after it at the same point where this branch added the "drop the (unreleased) suffix before dispatching" instruction Kept both. Ordered my pre-dispatch note with the other pre-dispatch prose, then master's new sections.

Master's bug list is left verbatim - it is #198's territory, and bullets 1 and 2 describing the
Kafka-version and README-Roadmap errors are master's to reconcile now that #198 has fixed them. Not
this PR's call to edit.

Both new guards pass, and they genuinely inspect this PR's files

$ bash bin/check-shell-sigpipe.sh      ->  ok:   no bin/*.sh pipes into grep -q under pipefail   (exit 0)
$ bash bin/check-action-versions.sh    ->  ok:   every action is used at a single version        (exit 0)

Checked why they pass rather than trusting the exit code:

  • shell: sigpipe - bin/test-release-notes.sh is in scope (the guard loops "$SCAN_DIR"/*.sh)
    and does set pipefail, but it contains no grep -q at all. I also swept for the wider
    early-exit class the guard does not encode (| head, | grep -m, | sed q) and found none. Its
    two pipes read to EOF (| grep -c, | sed 's/^/ /'), so no writer can take EPIPE. Compliant on
    the merits, not by omission.
  • workflows: action versions - the release: notes renderer job this PR adds to maven.yml
    already uses actions/checkout@v6, matching all other uses. No change needed.

Pleasing to see bin/check-shell-sigpipe.sh land as a CI-enforced guard for the class I hit on this
PR - claude-review reporting "no review posted" while the review was sitting in the payload.

#198 changed my input, and the pipeline handled it correctly

bin/release-notes.py reads CHANGELOG.adoc, which #198 edited, so I re-ran everything against the
merged file rather than assuming:

suite            -> exit 0, 24/24 ok
all 29 sections  -> render, exit 0
0.6.0.0 body     -> 5725 bytes

The only difference in the rendered release body is #198's correction flowing straight through:

- The Kafka client stays on **3.9.1** - Kafka 4.x ... deferred to keep the release low-risk.
+ The Kafka client moves 3.9.1 -> **3.9.2**, a patch bump within the same 3.9 line - no API or
+ behaviour change for callers. Kafka 4.x ... deferred to keep the release low-risk.

That is the whole point of this PR working: a changelog correction becomes the release page text with
no separate step to forget. The (unreleased) suffix is still on the heading on master, so the
pre-dispatch instruction in the inflight doc remains accurate and necessary.


One thing master's new rules say I should do, that I am deliberately NOT doing here

bin/AGENTS.md (new in da36161) says:

Grant a script when it is read-only and lets the reviewer check a claim rather than infer it [...]
A reviewer that can re-run what a PR asserts catches a false claim; one that cannot is guessing.

bin/test-release-notes.sh meets that bar exactly - read-only (writes only into a mktemp -d it
traps away), seconds-fast, no network, no gh, no git writes - and it is not in --allowedTools,
while every sibling check-*.sh / test-check-*.sh is. This PR is arguably the strongest evidence
for the rule: the reviewer hand-traced my regexes three rounds running because its sandbox
declined python3/bash, and said so each time.

I am not adding the grant in this PR, because bin/AGENTS.md also documents the cost:

Editing that workflow costs you the review on that PR. [...] claude-review will go red on the
PR making the change [...] it stays red until merge.

claude-review is a required status check on master (confirmed via the branch ruleset), so making
that edit here would trade a merge-blocked PR for a differently-merge-blocked PR. The doc's own remedy
is to split the workflow edit out, so I am flagging it as a follow-up rather than doing it. The exact
addition, both spellings, since these are prefix matches and not globs:

Bash(bin/test-release-notes.sh:*),Bash(./bin/test-release-notes.sh:*)

Worth pairing with a sweep for any other ungranted verification script, since the same gap is what
bin/AGENTS.md was written to stop recurring.

(Not touching bin/check-review-posted.sh either - master's cb8b118 already fixed the SIGPIPE
false-negative I diagnosed on this PR.)

@claude

claude Bot commented Aug 6, 2026 •

Copy link
Copy Markdown

Claude finished @astubbs's task in 1m 58s —— View job


Review: merge commit 4f76680c (master merged in, conflicts resolved)

Task list

  • Gather context (PR description, three prior in-thread review rounds, diff)
  • Diff origin/master...HEAD to scope what actually changed since the last reviewed commit (bb899c3b)
  • Check for leftover conflict markers / dropped content from the merge
  • Verify the two merge-conflict resolutions (AGENTS.md, docs/inflight/release-0.6.0.0.md) actually kept both sides
  • Spot-check bin/release-notes.py / bin/test-release-notes.sh against the two previously-fixed findings (env-binding, RE_BOLD boundaries) for regressions
  • Verify the "both new master CI guards pass cleanly against this PR's files" claim independently
  • Post final review

Execution caveat, consistent with all three prior rounds on this PR: this sandbox again declined every attempt to actually execute bin/test-release-notes.sh or python3 bin/release-notes.py (approval never arrived, even for the bare python3 bin/release-notes.py 0.6.0.0 invocation, though python3 --version and basic ls/grep did run). This independently reproduces the exact gap the author raised in their last comment: bin/test-release-notes.sh still isn't in --allowedTools, so a reviewer can only hand-trace it, not run it. Everything below is static analysis of the diff, not execution.

What actually changed in this pass

git diff origin/master...HEAD since the last-reviewed commit (bb899c3b) is exactly one merge commit pulling in origin/master (c6fff838, a docs-only commit) — no functional changes to bin/release-notes.py, bin/test-release-notes.sh, or the workflow files beyond conflict resolution. Confirmed:

  • No leftover <<<<<<</=======/>>>>>>> markers anywhere in the tree.
  • AGENTS.md: master's new "Reading a failed job's log" block (AGENTS.md:183-186) and this branch's extended maven.yml bullet (AGENTS.md:199, ending "...so release notes break on the PR that wrote them, not on the release page.") are both present — neither side was dropped.
  • docs/inflight/release-0.6.0.0.md: this branch's "drop the (unreleased) suffix before dispatching" paragraph (lines 15-20) sits immediately before master's new "Bugs found while triaging the upstream mirrors" section (line 22) — both intact, correctly ordered.

The two previously-fixed findings hold up under this merge

  • Env-binding (release.yml): the only ${{ inputs.* }} uses left in the file are the one-time env: block and the if: ${{ !inputs.dryRun }} conditionals (Actions-evaluated, never shelled). Every run: block reads "$RELEASE_VERSION"/"$DEVELOPMENT_VERSION"/"$DRY_RUN", across all five sites (quarantine guard, tag-exists guard, the new render step, release:prepare's -D args, git checkout/gh release create). Matches what was fixed in 0d9fa67c, unchanged by the merge.
  • RE_BOLD boundary regex: bin/release-notes.py:86 is byte-identical to the version verified in the second review round; the constrained-boundary lookarounds and the UNCONSTRAINED regression test (bin/test-release-notes.sh:199-206) are untouched by the merge.

Independently verified the author's claim about the two new master-side CI guards

The author's last comment asserts bin/check-shell-sigpipe.sh and bin/check-action-versions.sh (both new on master, merged into this branch) pass against this PR's new files. Checked the mechanics directly rather than trusting the exit code:

  • bin/test-release-notes.sh has no grep -q/-qE/-Eq anywhere (only grep -oE, grep -c, both of which read to EOF), so check-shell-sigpipe.sh's pattern genuinely doesn't apply — not a near-miss.
  • Every actions/checkout@ reference across .github/workflows/*.yml, including the new release-notes job this PR adds to maven.yml (maven.yml:174) and release.yml:52, is @v6 — no version skew for check-action-versions.sh to catch.

Conclusion

No new issues. This commit is a clean merge that correctly preserves both sides of two add-add conflicts, and none of the two previously-identified-and-fixed findings (script injection via ${{ }} interpolation; RE_BOLD mangling bare asterisks) regressed. The three prior review rounds already covered the substantive design (bounded AsciiDoc→Markdown conversion, reject-don't-mangle, fail-before-tag ordering) and found it sound; nothing in this merge changes that assessment.

One outstanding, non-blocking item already flagged by the author and not part of this diff: bin/test-release-notes.sh still isn't granted in --allowedTools, so every review round on this PR (including this one) has had to hand-trace a read-only, seconds-fast self-test instead of running it — worth picking up as the documented follow-up.

@astubbs

astubbs commented Aug 6, 2026

Copy link
Copy Markdown
Owner Author

Issue-reference gate (#114): six references qualified - 6c96df3

.github/scripts/issue-ref-gate.js arrived in 735b1d3a, after this branch was written, and the
PR Checklist required check fails on any bare #NN below 1000 on an added line. This branch
carried six, every one of them #197:

File Where
.github/workflows/maven.yml the release: notes renderer job comment
.github/workflows/release.yml the "deliberately NOT --generate-notes" rationale
AGENTS.md the Release notes paragraph
bin/release-notes.py the module docstring's "why this exists"
bin/test-release-notes.sh the header comment and the suffix regression test's name

All six mean this fork's release tracking issue, so all six became astubbs#197. The gate's own
rationale lands squarely on this case - #197 resolves in both repos and confluentinc#197 is a
different issue, so the bare form was a coin flip that would have looked correct. docs/inflight/
already said astubbs#197, from master's own sweep, which is where I took the form from.

Verified with the gate itself rather than by eye, run against a locally computed diff vs
origin/master so it reflects what CI will see:

changed files: 6
unqualified refs below #1000: 0

(Before the fix, the same command listed all six.) Worth noting the gate reads added lines in
changed files
, not the PR body or commit messages - so the earlier commits' #197 are out of its
scope. I have not rewritten them; new commits use astubbs#.

No issue-refs: N/A opt-out used - there was nothing to except, the references were simply
unqualified.

The other three new commits, checked rather than assumed

  • 67f6f3df (TODO index). bash bin/todo-index.sh --check → "docs/TODO_INDEX.md is up to
    date."
    This PR adds no TODO/FIXME/XXX marker (git diff origin/master | grep -E "^\+.*(TODO|FIXME|XXX)"
    → none), so nothing to regenerate.
  • 810283c0 (deleted self-hosted lanes). The only runs-on this PR adds is ubuntu-latest, for
    the release: notes renderer job. No deleted lane is referenced from either workflow I touch.
  • 16ac63b1 / c6fff838. A core test fix and AGENTS.md merge-strategy guidance - neither touches
    anything this PR depends on.

Full state after the merge and this fix

bin/test-release-notes.sh      -> exit 0, 24/24 ok
bin/check-shell-sigpipe.sh     -> ok:   no bin/*.sh pipes into grep -q under pipefail
bin/check-action-versions.sh   -> ok:   every action is used at a single version
bin/todo-index.sh --check      -> up to date
bin/check-copyright-headers.sh -> 232 java files, 0 violations
issue-ref-gate.js              -> 0 unqualified refs
git log HEAD..origin/master    -> empty

Everything in my previous comment still stands, including the one deliberate omission: the
--allowedTools grant for bin/test-release-notes.sh is left for a follow-up PR, because editing
claude-code-review.yml would turn the required claude-review check red until merge - which
bin/AGENTS.md documents and which would simply trade one blocked state for another.

@claude

claude Bot commented Aug 6, 2026 •

Copy link
Copy Markdown

Claude finished @astubbs's task in 1m 59s —— View job


Review: commit 6c96df3b (qualify issue references for the new repo-wide gate)

Task list

  • Gather context (diff vs origin/master, four prior in-thread review rounds, changed files)
  • Scope this pass to what's new since the last reviewed commit (4f76680c)
  • Verify all six #197 sites are correctly qualified, and no other sub-1000 bare refs were introduced
  • Post final review

Scope of this commit

6c96df3b is a pure text-substitution commit: #197 → astubbs#197 in six comments/docstrings across .github/workflows/maven.yml, .github/workflows/release.yml, AGENTS.md, bin/release-notes.py, and bin/test-release-notes.sh (one occurrence each, except the last file which has two). No functional code changed — bin/release-notes.py's logic and bin/test-release-notes.sh's assertions are byte-identical apart from the one string literal in the regression-test name. This is triggered by .github/scripts/issue-ref-gate.js, a new required check (landed in 735b1d3a, after this branch was written) that flags bare #NN below 1000 on added lines, since that range is ambiguous between this fork and confluentinc/parallel-consumer.

Verified independently

Rather than trust the PR comment's "0 unqualified refs" claim, I re-derived it: extracted every #[0-9]+ occurrence on added lines across the five touched files and confirmed each of the six sites is preceded by astubbs (astubbs#197 in every case) — matching the gate's own qualification pattern (\b(?:astubbs|confluentinc)\s*#\d+, read directly from .github/scripts/issue-ref-gate.js). I also checked for any other sub-1000 bare ref this commit might have introduced or missed — none found. (I couldn't execute the gate script itself end-to-end in this sandbox — file writes outside the repo dir and node <script> invocations were both blocked without approval that didn't arrive — but the regex-based cross-check against the gate's actual qualification logic is equivalent verification for a change this mechanical.)

The choice of astubbs#197 (vs. confluentinc#197) is correct: every one of the six sites is discussing this fork's release-notes-body bug (#197 in this repo, the PR's own tracking issue), not anything upstream. The gate's stated rationale — a bare #197 resolves in both repos, and a wrong-but-resolving link is worse than a broken one — applies directly here, so qualifying rather than opting out (issue-refs: N/A) was the right call.

Conclusion

No issues. This is a low-risk, mechanical fix scoped exactly to what the new required check demands, consistent with the convention already used in docs/inflight/release-0.6.0.0.md (from master's earlier sweep). Combined with the four prior review rounds on this PR (design, script-injection env-binding, RE_BOLD boundary fix, and the master merge), I have no outstanding concerns on this PR.

astubbs added a commit that referenced this pull request Aug 12, 2026
…he sweep tool a mode that could have caught it (#258)

* docs(upstream-map): track the 28 issues closed by the 2023 admin sweep

Upstream ran two bulk clearouts before going quiet, and neither was a triage:
2023-06-15 `eddyv` closed 35 unmerged PRs with "Closing - Stale." (34 of them
ours), and 2023-07-07 `johnbyrnejb` closed 28 issues with "Closing Issue" -
every one marked COMPLETED rather than "not planned".

That state reason is why the cohort was invisible. GitHub renders `completed`
as resolved, so the issues read as done at a glance, and `upstream-sweep.sh`
searches `updated:>=last_swept`, so anything last touched in 2023 can never
appear in a sweep. None of the 28 were in this manifest; the mirroring that
produced the other 78 fork mirrors only ever sampled *open* upstream issues.

All 28 were re-read in full - bodies plus all 58 comments - and each verified
against fork source rather than trusted from its thread. That mattered: four
issue bodies point at PRs that "fix" them (#372->#390, #319->#270, #203->#345,
#191->#346) and every one of those PRs was itself swept unmerged.

Result: 2 already fixed (#41 offset-scan removal, #319 shutdown CME), 6 partly
addressed, 20 fully open. Grouped into work items rather than 28 near-duplicate
entries, since several want designing together - per-topic handlers with
separate consume/produce types, seek with subscription changes, retry expiry
with stall detection. #57 folded into the existing log-noise entry.

Swept PR head commits were checked and are all still reachable, so the drafts
are recoverable; entries cite branch and SHA, not just the PR number.

Upstream-Issue: confluentinc#154
Forwarded: no
Applied-Upstream: no

* docs(upstream-map): mirror the whole 2023 cohort, not the parts we rate

The point of mirroring is a clean, known cutoff - "every issue upstream closed
administratively is accounted for here" - not a curated pick of the good ones.
A set filtered by our own value judgement is not a cutoff: the next person
cannot tell "not mirrored because it was junk" from "not mirrored because it
was missed", and that ambiguity is worth far more than the cost of carrying a
few items nobody will ever action.

Drops the decline recommendations from #53, #199, #246 and #57 in favour of
neutral statements of the trade-off, and renames sweep-2023-decline-candidates
to sweep-2023-small-items (status wontfix -> none). The facts that informed
those recommendations are kept - they are useful to whoever picks the issue up
- but they are now framed as input to that person's decision rather than as our
verdict delivered in advance. Fork issues can always be closed later on their
merits, which leaves a visible record; pruning before mirroring does not.

Records the principle in the section header so a later pass does not re-prune.

Upstream-Issue: confluentinc#154
Forwarded: no
Applied-Upstream: no

* docs(upstream-map): link the created fork mirrors back to their entries

The 28 mirrors are live as #227-254 (label `upstream-admin-closed`),
with confluentinc#41 -> #233 and confluentinc#319 -> #252 created
and immediately closed as completed, carrying the code evidence that they are
genuinely fixed.

Records the fork numbers on each entry so the mapping is queryable rather than
re-derived, which is the reason this file exists. Adds `fork.fork_issues` (the
plural of the existing `fork_issue`) because several entries deliberately group
upstream items that want designing together, and documents it in the schema
block. Verified: all 28 mirrors are referenced, none missing, no strays.

Also snapshots each upstream title verbatim into its mirror body header, dated
2026-08-07 - the fork titles may drift as these are worked, and the original
wording is what makes an old thread findable.

Upstream-Issue: confluentinc#154
Forwarded: no
Applied-Upstream: no

* fix(tooling): give upstream-sweep a mode that can see closures it never saw

The default sweep is a window search - `updated:>=$since` - so it structurally
cannot see an item whose last activity predates the window, and `last_swept`
only moves forward, so the blind spot grows. That is why upstream's 2023
administrative closures went unnoticed for three years: 28 issues closed with
"Closing Issue" and 35 unmerged PRs closed as "Closing - Stale.", all marked
COMPLETED, none of it triage, none of it visible to us.

Adds `--audit`: no time window, asks "which closed upstream items are neither
tracked in the manifest nor mirrored in the fork?", and flags days where an
implausible number of things closed at once. Run against the real repo it
rediscovers both sweeps from scratch and reports zero unaccounted, which is
also an end-to-end check that the new fork_issues linkage is correct.

Bots are excluded from the PR analysis. Dependabot self-closes superseded
bumps in batches that look exactly like a sweep - 2022-08-16, 2022-10-20,
2023-11-03 and 2024-01-25 are all dependabot - and unfiltered they buried the
two real sweeps in noise. Filtering them surfaced two human PRs that had been
sitting inside those batches (confluentinc#508, confluentinc#650), now recorded
for review.

The report says outright that a bulk day is not proof of a sweep, because a
release triage looks identical from here, and that stateReason COMPLETED is not
evidence of a fix - that assumption is what made this cohort invisible.

Known remaining hole, recorded not fixed: a PR closed alone on a quiet day is
still invisible, since detection keys on bulk.

Upstream-Issue: confluentinc#154
Forwarded: no
Applied-Upstream: no

* fix(tooling): teach the audit about Discussions, a content type we never checked

Discussions were invisible to everything: not in the manifest, not mirrored,
not in any sweep mode. 74 of them upstream, and nothing we run would ever have
mentioned one.

They were NOT swept - no bulk closure, and the largest day (2024-04-02, six
threads) is all answered=true housekeeping. So the failure mode is different
from the 2023 cohort: not administrative closure, just questions nobody
answered, in a place no issue search reaches. Handling differs accordingly -
these want answering or converting, not mirroring wholesale.

The audit now lists zero-reply discussions, excluding release-announcement
threads by title: those legitimately have no replies, and counting them as
neglect would put 9 false positives at the top of the report.

Two finds justify the check on their own. Discussion 542 (zero replies) is a
field report of a transactional consumer stuck in rebalance because it cannot
acquire the produce lock, with the reporter suspecting the revoke-time flush -
the same lock lifecycle as bug-producing-lock-double-release, and they raised
the timeout without effect, which is evidence about the mechanism rather than
the duration. Discussion 883 (zero replies) is the same complaint as fork
mirror #187 but with a runnable reproducer, which #187 lacks.

Upstream-Issue: confluentinc#154
Forwarded: no
Applied-Upstream: no

* docs(inflight): record the open obligation to account for every upstream item

Two notes, both about what is NOT done.

Discussions are not a queue to be converted. There is no pipeline turning
threads into issues, and most should never become one. The rule is a judgement:
if reading a discussion makes us think there is an issue, we raise one - a
normal fork issue on its own merits, citing the discussion as where it came
from. It exists because we believe the problem is real, not because a thread
existed. That also keeps `upstream-mirror` meaning exactly "an upstream issue
we carry", which is what makes the 2023 cutoff verifiable.

The wider obligation is now written down: every upstream issue, PR and
discussion must be accounted for - carried, declined, or genuinely resolved
upstream - not sampled. The 2023 cohort was found only because it was a *bulk*
event; `--audit` keys on bulk closures and zero-reply threads, and both are
proxies that miss whole shapes of problem (a PR closed alone on a quiet day, a
discussion with one dismissive reply, an issue marked COMPLETED with no linked
PR). The audit narrows the field; only reading discharges the obligation.

Also records what has been ruled out, so it is not re-investigated: wiki
disabled, no advisories, all open-milestone issues already mirrored, the orphan
branches accounted for (v0.6.x-dev is the lambda-actor work already captured
via swept PRs; 0.5.3.x's regression fix IS on master as a908e16), and
"upstream pushed today" being a pushed_at artefact rather than new activity.
Left open: project boards need a read:project scope we do not have, and 169
forks are unexamined.

* fix(upstream-map): use a group the schema actually allows

Two new entries used `group: batching-ordering`, which is not in the GROUPS
allow-list in scripts/upstream-map.py, so `upstream-map.py validate` failed on
them. Caught in review on #258.

My mistake was validating the wrong way: I checked the file with an ad-hoc
yaml.safe_load plus a duplicate-id check, which passes happily on a group the
schema rejects, instead of running the project's own validator that AGENTS.md
tells contributors to run before committing manifest changes.

Reassigned both to `features` rather than widening GROUPS. The rest of this
cohort's feature entries already use `features`, so this keeps the cohort
internally consistent, and the ordering/batching distinction is not lost - it
lives where it belongs, on the issues themselves via the `area/batching-ordering`
label (#244, #236). Adding a vocabulary term to a shared schema as
a side effect of a mirroring PR is the larger, less reversible change.

Also drops the redundant 345 from sweep-2023-broker-disconnect-commit's
`related` list, where it already appears in `prs`.

Verified: `upstream-map.py validate` reports OK on 27 entries, and `refs` and
`table` both still render.

* docs(upstream): graduate the durable parts of the sweep record out of inflight

The three inflight notes stay - they hold undischarged work - but they were
also carrying permanent content, and inflight is transient by its own charter.

Moved to durable homes, each citing the manifest rather than restating it:

- docs/upstream.md gains the upstream-admin-closed cohort note (with the
  "do not trust 2023-era closure states" rule), the discussions non-mirroring
  policy decided 2026-08-07, documentation of --audit and its known blind
  spots, and the ruled-out upstream surfaces (wiki, advisories, milestones,
  orphan branches, pushed_at).
- docs/solutions/ gains the transferable lesson: a closure state is a
  rendering choice not a triage, "fixed by #N" must be checked against the
  merge bit, windowed watchers need a no-window audit, and bots must be
  filtered before hunting bulk events.
- upstream-pr-analysis.adoc is corrected: it claimed issues were never
  bulk-closed, which the 2023-07-07 sweep disproves, and the PR sweep is
  now confirmed rather than suspected.

The inflight notes now hold only open work, pointing at the new homes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(upstream): name the analysis doc's role (the plan) beside the manifest (the state)

docs/upstream.md's opening enumerated everything it owns except the
editorial analysis, and neither source-of-truth reference was a clickable
link. Now the two roles are named explicitly: the .adoc is the plan, the
manifest is the state tracker.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(upstream): make the audit's discussion query actually paginate, and correct the sweep cohort

Address PR review feedback (#258).

- upstream-sweep.sh: `gh --paginate` only substitutes a variable named
  `endCursor`; calling it `$cursor` meant the cursor was never fed back and gh
  re-requested page 1 forever (reproduced: 469 identical pages at first:2).
  It only looked healthy because 74 discussions fit in one page of 100. The
  failure was also swallowed by `2>/dev/null || true`, which would have printed
  a clean "(none)" for a broken query - the one answer this mode must never
  invent. Fail loudly instead.

- upstream-map.yaml: the sweep cohort listed 36 PRs against a documented count
  of 35. Upstream closed exactly 35 unmerged PRs on 2023-06-15; confluentinc#66
  (closed 2022-10-19) was carried in by mistake. Listing a ref here marks it
  accounted for, so it was hiding an unrelated PR from every future audit.
  Recorded PR 258 and moved the entry to `pr-open` per the lifecycle rule.

- next-upstream-coverage-completeness.md: dropped the cached counts - inflight
  notes must not record what a command can answer, and the "~100 partially
  mirrored" line already contradicted docs/upstream.md, which says all 78 open
  upstream issues are mirrored with backlinks. Kept only what the audit cannot
  say: what nobody has read yet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs(agents): let the manifest cache frozen upstream-issue facts, and say why

The rule said "the manifest tracks upstream PRs only", so mirroring the 2023
sweep cohort into it read as a violation. The rule is what is out of date.

An archived upstream's closed issue numbers and closure events are frozen. Caching
them locally is a read-path optimisation, not a second tracker: grepping one file is
instant, while the same answer from the mirrors costs dozens of API round-trips and
burns rate limit shared across agents. The usual objection to duplication - the copy
silently diverges - needs a source that can still move, and this one cannot.

So the boundary is redrawn where it actually bites: the mirror owns an issue's *live
state* and remains the only place you update it; the manifest may cache what is frozen
(number, cohort, owning mirror). Cache what is frozen; never mirror what is moving.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs(upstream): put the manifest-caching rule in the doc that owns it

The previous commit wrote the rule into AGENTS.md, which is the one place it
does not belong. AGENTS.md's own preamble calls itself a router - "if it only
matters once you are already in a topic... it goes in that topic's doc" - and
docs/upstream.md line 7 already claims ownership explicitly: "AGENTS.md carries
only the pointer and the one-line rule that manifest upkeep is the agent's job."

The rule was in fact already stated twice before this branch (AGENTS.md:442 and
docs/upstream.md:23), so growing the AGENTS.md copy deepened a fragmentation that
was already there. Now stated once, where an agent editing the manifest will
actually be looking, with AGENTS.md left holding the pointer and the one binding
rule whose failure is silent (keep the fork side in sync).

Net effect on the router: one line shorter than master, despite covering more.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* docs(agents): make a pointer say who owns the rule, not just what is nearby

Diagnosed from a live miss. A reviewer cited AGENTS.md's "the manifest tracks
upstream PRs only", so that section was read and treated as authoritative - while
docs/upstream.md had been stating the same rule, and claiming ownership of it, the
whole time. The duplicate was then grown in the router rather than fixed at source.

Nothing in the reading path revealed the mistake. AGENTS.md stated a complete-looking
rule and followed it with a pointer listing four adjacent mechanics ("the manifest
schema, the mirrors, the commit trailers and the upstream sweep"), which reads as
*further detail*, not as *this is a summary and that doc wins*. The contract was
written down - docs/upstream.md:7 - but only on the side nobody enters from, since
AGENTS.md is what loads every session.

The anti-duplication rule already existed here ("Never state a fact twice"). What was
missing is the half that makes it discoverable: a cross-reference must name the owner
and say the owner wins, so a reader can tell a stub from the whole rule before editing
the copy. Applied to the rule itself and to the upstream pointer that failed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@astubbs
astubbs marked this pull request as draft August 19, 2026 03:11
astubbs and others added 9 commits September 1, 2026 00:02
…e body

A GitHub Release cut by this pipeline had no readable body. The workflow did try:
an inline awk compared each line to the literal string "== <releaseVersion>", but
the section is headed "== 0.6.0.0 (unreleased)", so it matched nothing - and the
step then fell back to --generate-notes, which is indistinguishable, on the release
page, from the curated notes having silently vanished. Nothing failed.

Replaces the one-liner with bin/release-notes.py, and removes the fallback:

- Extraction tolerates the headings the file actually uses ("v0.5.2.2", a
  "(unreleased)" suffix - warned about, not silently accepted) and will not let a
  version prefix match a longer version (0.6.0.1 vs 0.6.0.10).
- AsciiDoc -> Markdown for a bounded subset (headings, bullets, ordered lists,
  link/URL macros, bold, admonitions, "+" continuations, "//" comments), with
  monospace spans masked so `bz.stub.parallelconsumer.*` is not read as an
  emphasis marker, and relative link: targets absolutised at the released tag so
  they do not 404 off github.com. Anything outside the subset that would render as
  garbage (source blocks, tables, anchors, block attributes, includes, xrefs) is an
  error, not a silent pass. No asciidoctor/pandoc: the release must not be able to
  fail because a gem would not install.
- Missing, empty or unconvertible section = non-zero exit. release.yml renders the
  notes BEFORE it commits, tags, deploys or publishes anything, so that failure is
  cheap; a dry run rehearses the render and prints the body to the job summary.

Tested by bin/test-release-notes.sh (contract cases on synthetic changelogs, plus
every version section of the real CHANGELOG.adoc). No CI job is added for it:
bin/check-all.sh --with-tests globs bin/test-*.sh and repo-hygiene.yml runs that on
every PR, so the suite is already swept - the original branch added a dedicated
maven.yml job because check-all.sh did not exist yet, and re-adding one now would
be the hand-maintained list that script exists to abolish.

Docs go to docs/releasing.md and docs/inflight/release-0.6.0.0.md rather than
AGENTS.md, which no longer carries the Releasing or CI sections this originally
edited. Every reference to #197 is written qualified: the fork's numbers sit
inside confluentinc's range, confluentinc#197 is a different issue, and
.github/scripts/issue-ref-gate.js now fails a bare one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…g them into shell

The PR body claimed the release version "reaches the script as an argv argument, not
interpolated into a shell string". That was false: `${{ inputs.releaseVersion }}` is
substituted textually into the `run:` block before bash parses it, so an input carrying
shell metacharacters is injected as code regardless of the quotes around it. A security
claim that does not hold is worse than no claim, so make the claim true rather than
retract it.

release.yml now binds releaseVersion/developmentVersion/dryRun to
RELEASE_VERSION/DEVELOPMENT_VERSION/DRY_RUN once at job level, and every shell step reads
the environment variable. This covers the file's pre-existing instances too (the tag
guard, release:prepare, git checkout, gh release create), not just the render step this
PR added - leaving four unhardened and one hardened would have been incoherent. `if:` and
`with:` expressions still use `${{ }}`: those are evaluated by Actions, never by a shell.
The maven args were also unquoted, so they gained word-splitting safety as well.

Also fix a real mangle the reviewer flagged in the renderer: RE_BOLD ignored AsciiDoc's
constrained-emphasis boundaries, so ordinary prose containing two bare asterisks
("3 * 4 * 5") was rewritten into broken emphasis - precisely the mangled output this
renderer promises never to ship. The regex now honours the boundaries and pairs its
delimiters with a backreference. Verified byte-identical output across all 29 real
CHANGELOG.adoc sections.

Tests: bin/test-release-notes.sh gains a bare-asterisk assertion (23 pass, exit 0).
Docs: docs/releasing.md records the env-binding convention so new steps inherit it -
AGENTS.md no longer carries the Releasing section this originally edited.
… through

The follow-up review noted RE_BOLD applies constrained-emphasis boundaries to `**` as
well as `*`, though AsciiDoc's double-asterisk form is unconstrained, so an intraword
span like `un**bel**ievable` is not matched.

Accurate about the regex, but it has no effect on output: `**x**` is already the Markdown
spelling, so "converting" it is the identity transform, and CommonMark renders intraword
`**` as strong regardless. Checked every intraword form (`foo**bar**baz`, `re**start**`,
`a**b**`, `**a**b`) - matched and unmatched produce byte-identical output. An exhaustive
sweep of 19607 generated strings against an implementation that treats `**` as properly
unconstrained found no difference on any input of that shape.

So there is nothing to fix, and the pass-through is asserted rather than left to chance.
24 assertions, exit 0; all 29 real CHANGELOG.adoc sections still render byte-identically.
… not a blank release page

The emptiness check ran on the RAW section lines, so "the section has lines in it" was
being used as a proxy for "the section renders to something". Those are different tests
and only the second one is the promise. A section holding nothing but `//` comments - or
nothing but a `+` list continuation - passed the first, and every one of its lines was
then dropped during conversion:

    $ printf '== 0.6.0.0\n\n// a comment\n' > c.adoc
    $ python3 bin/release-notes.py 0.6.0.0 --changelog c.adoc | wc -c
    1
    $ echo $?
    0

One byte, exit 0, and release.yml would hand that to `gh release create --notes-file`.
That is the blank release page of #197 reached from the other side, in the script
written to make it impossible. Emptiness is now judged on the converted output, in
`render`, which is the only place where it is a true statement.

Four smaller mangles found by the same adversarial pass over the renderer:

- An odd number of backticks on a line leaves a monospace span open, so `convert_inline`
  masks the remainder as code and silently stops converting emphasis in it. Rejected now,
  with the same "fail rather than ship mangled markup" contract as the AsciiDoc table.
- `'''` (thematic break) and `<<<` (page break) passed through into the body, where
  Markdown renders both as literal punctuation. Rejected.
- `check_supported` reported one line once per pattern that matched it, so `|===` was
  reported twice - as a table and as a table cell. First match wins now, and the patterns
  are explicitly allowed to overlap.
- argparse exits 2 on a usage error, which is this script's "no section for that version".
  A release operator hitting a mistyped flag would have gone looking for a missing
  changelog section. Usage errors are exit 1, matching what the docstring always claimed.

Plus one deliberate behaviour change, wired up by release.yml in the next commit: `--strict`
promotes the "heading still carries `(unreleased)`" warning to a refusal (exit 4). The suffix
never reaches the body - the heading is not rendered - so this is about not tagging a changelog
that still calls the version unreleased, and a warning in a 30-minute job log is not a check.
Without the flag it stays a warning, so a rehearsal before the freeze is still possible.

bin/test-release-notes.sh gains eight assertions, six of them verified red against the previous
renderer. The empty-body one counts BYTES rather than comparing to "": `$(...)` strips the
trailing newline, so the one-byte body this commit is about compares equal to empty and the
obvious spelling of the assertion passes over the bug.

32 assertions, exit 0; all 29 real CHANGELOG.adoc sections still render byte-identically.
…till says (unreleased)

The instruction to drop the `(unreleased)` suffix before dispatching lived in a
docs/inflight/ note, which is deleted when its work lands - so 0.6.0.1 would rediscover it -
and the renderer only warned, into a job log nobody reads at minute thirty of a release. That
is a documented invariant with no check behind it, which this repo has decided is not an
invariant at all.

release.yml now passes --strict whenever dryRun is false, so a real release stops at the
render step - before anything is committed, tagged, deployed or published - rather than
tagging a CHANGELOG.adoc that still calls the version unreleased. A dry run deliberately does
not pass it: rehearsing the body BEFORE the heading is frozen is the point of rehearsing, and
a flag that blocked that would just be turned off.

Also states, where a reader will hit it:

- docs/releasing.md gains the frozen-heading rule and corrects "empty" to "renders to
  nothing" - the two differ, and the difference is the bug the previous commit fixed.
- docs/inflight/release-0.6.0.0.md drops its explanation of why the suffix is tolerated and
  points at docs/releasing.md as the owner, keeping only the part that is transient: that
  0.6.0.0 has not had it done yet.
- The render step's comment now says why bin/test-release-notes.sh is re-run here when
  repo-hygiene.yml already ran it on the same master SHA. A reader could not previously tell
  deliberate belt-and-braces from a leftover.
…g the renderer for its stderr

Three defects in the self-test harness, none of which could fail the suite - which is what
made them worth finding.

**Without python3 the suite exited 1.** bin/check-all.sh maps 1 to FAIL and 2 to CANNOT, and
repo-hygiene.yml's macOS lane maps anything but 2 to "self-test FAILS on macOS" - so a box
without an interpreter reported this as a broken gate rather than as coverage that did not
run. That is the attribution failure the macOS lane's own step comment spends a paragraph on.
It now probes the way bin/check-docs-data.sh and bin/check-upstream-map.sh do and exits 2,
with one difference: it asserts `sys.version_info[0] >= 3` rather than accepting any `python`,
because the renderer's `print(..., file=...)` is a syntax error under Python 2, so the house
probe would select an interpreter that cannot run the thing under test.

**Fixture paths used $RANDOM, inside `$(...)`.** bash before 5.1 does not reseed $RANDOM in a
subshell and `changelog()` is only ever called in a command substitution, so on the macOS
bash-3.2 lane every fixture would land on one path and silently overwrite the last - while
THREE_SECTIONS, written first, is still read by asserts two thirds of the way down the file.
On bash 5 it is a birthday collision across 15 draws instead. mktemp has neither problem.

**Part B spawned three processes per failing section to learn one thing.** The first re-run
discarded stdout, stderr and its exit status - dead code producing nothing any later line
consumed; the second existed only to recover the stderr render_status had thrown away. One
invocation now keeps its own stderr in a file.

Also gitignores __pycache__: bin/release-notes.py is the first module here anything might
import rather than run, and CPython drops bytecode beside the source when it does.

32 assertions, exit 0. No assertion was changed or removed.
… one workflow that breaks it

The rule this branch introduced - a dispatch input reaches a `run:` block as an environment
variable, never as `${{ }}` - was written only into docs/releasing.md, which nobody editing a
non-release workflow opens. It was already stale on arrival:
mutation-full-sweep.yml interpolates the free-text `threads` dispatch input straight into its
`run:` line, on the self-hosted runner, two lines below the same step correctly env-binding
PIT_TARGET_CLASSES and PIT_TARGET_TESTS. A convention with one live violation and no reader is
not a convention.

So: bin/AGENTS.md's Workflows section - which already owns "one version per action", the same
shape of rule - states it in two lines and names docs/releasing.md as the owner, and the
`threads` input joins its two neighbours in `env:`. bin/CLAUDE.md bridges that file into a
Claude Code session the moment anything under bin/ is touched, which a topic doc does not do.

Nothing enforces it yet; a bin/check-workflow-run-interpolation.sh scanning `run:` bodies for
`${{ inputs.* }}` and `${{ github.event.* }}` is the shape that would, in the mould of
bin/check-action-versions.sh, and is left for its own change since it needs a self-test.

Sibling scan for the same defect class, since a fix that removes today's instance invites
tomorrow's: `${{ }}` inside a `run:` body across .github/workflows/ leaves maven.yml's
`run: ${{ matrix.cmd }}` (workflow-file data, not user input) and quarantine-lane.yml's
`${{ steps.run.outcome }}` (an Actions enum). Neither is attacker-controlled; both left alone.
… every relative link

`bin/release-notes.py v0.5.2.2` is supported and tested - historic sections are headed
`== v0.5.2.2`, so the extractor normalises the prefix away and both spellings find the same
section. The default git ref for relative links did not normalise it:

    $ python3 bin/release-notes.py v0.5.2.2 --changelog c.adoc
    - See [the doc](https://github.com/astubbs/parallel-consumer/blob/vv0.5.2.2/docs/x.md).

`vv0.5.2.2` is not a tag. The notes render perfectly and every `link:docs/...` in them 404s -
a failure that is invisible at render time and only shows up when a reader clicks, which is
precisely the class this script exists to close. The two spellings now produce byte-identical
output, asserted by comparing them to each other rather than to a hardcoded URL, so the case
cannot rot when the repo URL changes.

Found by adversarially probing the renderer rather than by a test failing; verified red
against the previous commit. 33 assertions, exit 0.
… in Markdown

The comment claimed a blank line "keeps the block with its item". It does not: CommonMark
ends a list at an unindented paragraph, so the continued block trails the list rather than
attaching to the item. The output still reads correctly - checked against both `+` uses in
CHANGELOG.adoc - and preserving the attachment would mean the line converter carrying list
state, which is not worth it for two sites. So the behaviour stands and the comment now
says what it is, rather than what would be nicer.
@github-actions

github-actions Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

🟢 Throughput — OK

This branch measured about 13% faster than master, on the one test this measures. That is INSIDE this test's own run-to-run spread of about 17%, so read it as a reading and not as a result - re-running the same commit moves it by about as much.

What Value Meaning
Compared with master 1.127 above 1.00 is faster, below is slower
Subject test took 43.0s the test under measurement
Control tests took 26.4s the other tests in this same run
Subject ÷ controls, here 1.628 not a speed - a shape that cancels machine speed
Subject ÷ controls, master 1.834 median of recent master runs
Reported rate 94150 rec/s this machine only; not comparable across runners

Allowable range 🟢 ≥ 0.70 · 🟡 0.50–0.70 (about a 30% loss) · 🔴 < 0.50 (about a 50% loss)

What the numbers mean, and what they cannot tell you

The one that gets misread. Subject ÷ controls is a shape, not a speed. 1.7 means the subject took 1.7 times as long as the control tests in the same run - it says nothing about master on its own, and a reviewer has already read it as "1.7x faster than master". Only Compared with master answers that question.

Why a shape and not a rate. A rate depends on which runner you drew. A shape does not: every test here processes a fixed number of records, so a runner twice as slow doubles the subject and the controls together and leaves their ratio alone. That is the whole trick, and it is why the reported rate is shown last and labelled as this machine only.

Reading the comparison. master ÷ this run. Above 1.00 the subject is proportionally quicker here than on master; below 1.00 it is slower. 0.50 means it takes twice as long relative to its controls - that is the failing bound, not a small one.

By conservation, not by correction. Every test in this lane processes a fixed number of records, so within one run the ratio of one test's time to another's is invariant under machine speed — a runner twice as slow doubles both terms and leaves the ratio alone. There is no machine-index correction to be wrong, because nothing needed correcting. share = subjectSeconds / controlSeconds, both from this same run.

Per-method times, not class times. A class time is work + setup, and container startup and @BeforeAll do not scale with work — they are the non-conserved term, and leaving them in breaks the invariant.

Reference is the median of 10 recent perf baseline (master) run(s), read from their artifacts. There is no committed baseline to go stale, and a share is dimensionless, so an old entry stays comparable to a new one without re-baselining. Shares observed: 1.613 – 2.253.

What this still cannot do. It removes machine-to-machine variance. It does not remove this test's own run-to-run variance, measured at about 30% on a single unchanged commit while its controls stayed within 5%. That is a property of the test, not of the comparison, and no arithmetic here can touch it — which is why the reference is a median and the bounds are deliberately coarse. 🟡 means look at this; only 🔴 is outside the measured spread.

Runs used: 43ed239, b1a6dbd, a37d148, e8bd2cb, 1743297, 4bc6e7a, b62c310, c381310, c79424a, 9c67c89

Since the previous push: ratio 1.203 -> 1.127, share 1.526 -> 1.628, rate 85731 -> 94150 (+9.8%). One push of difference sits inside this test's measured spread - read it as movement, not as a result.

Updated for 04447e2 · run 34407455252 · 2026-09-09 21:37 UTC

@codecov

codecov Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.26%. Comparing base (43ed239) to head (04447e2).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##             master     #199      +/-   ##
============================================
+ Coverage     82.79%   83.26%   +0.47%     
- Complexity     1596     1604       +8     
============================================
  Files            96       96              
  Lines          5475     5475              
  Branches        554      554              
============================================
+ Hits           4533     4559      +26     
+ Misses          745      723      -22     
+ Partials        197      193       -4     
Flag Coverage Δ
chaos 53.18% <ø> (?)
integration 63.24% <ø> (+0.21%) ⬆️
performance 47.71% <ø> (?)
unit 79.50% <ø> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

astubbs and others added 2 commits September 2, 2026 13:16
… port

bin/release-notes.py landed the same day the Node-default ruling did (bin/lib/source-patterns.mjs,
#403), which says the repo already chose Node over Python. The gate matches only sh|bash,
so nothing flagged the .py; the .sh beside it carries a shell-justified: line. Owner's ruling,
2026-09-02: let it ride, port later. This line is where that decision lives, so the next sweep
finds a decision rather than an oversight.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CMeraeBL2ycXVHEaTHM86W
…landed on both sides

#201 squash-merged while this branch carried the same two release notes with a fresher
MDC state. Both hunks were the same fact from two directions: master had dropped the load-factor
bullet as "now #201" but still carried the stale "MDC is not captured" claim this branch
had already corrected (#205 landed it). Resolved to the state that is true now that both
have merged - the triage list is recorded as landed in the blockers note, and the release note's
"bugs found while triaging" section, which had nothing open left in it, is removed along with its
heading, which nothing cites.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CMeraeBL2ycXVHEaTHM86W
@astubbs astubbs changed the title ci(release) #197: publish the curated changelog section as the GitHub Release body ci(release) astubbs#197: publish the curated changelog section as the GitHub Release body Sep 2, 2026
@astubbs
astubbs marked this pull request as draft September 2, 2026 22:43
astubbs added a commit that referenced this pull request Sep 7, 2026
…ely ignores

Thirty-nine items are in flight - 32 open PRs plus seven with no PR yet - and
the ordering had been re-derived from scratch three times in one session,
differently each time. This writes it down once.

Ordered by value to the release, explicitly not by merge mechanics: conflicts,
red checks and stale bases are not inputs to it. Records the two hard
constraints (#199 cannot be applied after the tag, #207 decides what already
deployed v6 readers will tolerate forever), the one item with schedule risk
(the Connect PoC is not written yet), and the three open decisions the order
cannot settle on its own.

Per the directory's rules it names no PR titles or states - `gh pr list` owns
those - and gives the command to re-check coverage instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
astubbs added a commit that referenced this pull request Sep 8, 2026
…hecklist

#476 vetted every open note and touched five this branch also
edits. Three conflicted and each is resolved on the side that reflects
the later decision:

- release-0600-blockers.md: deleted here, modified there. Kept deleted;
  the two corrections the sweep made to it are folded into the
  burn-down's tag-day checks. One of them is only half right and is
  recorded as such: release.yml does build a notes file from the
  changelog (#72), but its exact heading match fails on the
  "(unreleased)" suffix and falls back to generated notes, which is what
  #199 fixes. The sweep's "the MDC gap is real" is refuted on the
  tree - MdcPropagation captures and restores the caller's context since
  #205 - so the burn-down keeps that correction.
- release-experimental-module-records.md: the 2026-09-07 deferral wins
  over the sweep's vetted marker, per the per-note contract (a deferred
  note carries the state, not the marker).
- release-when-is-v6-good-enough.md: the sweep's dated "the date passed"
  paragraph and its stale vetted marker ("the question is still
  unanswered") are dropped; the rewritten note records the decisions
  and names the failure mode in its own words.

Also carried from the sweep: the citation to the poisoned-transaction
wedge note is repointed to the sibling #476 merged it into; the
burn-down now points at the sweep's own "what gates v6" list in
process-candidate-ranking.md and records where the two disagree (the
sweep reads the poisoned pair as not gating, and the batchSize
validate() bound as the cheapest real fix, which could ride in tier 1);
and the #44 exception is narrowed - #466 bounded the
revoke wait, so what #408 still owns is declining rather than
waiting.

Claude-Session: 460f7df9-dcc2-4b00-a9f9-62f3a2c6d5e4
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
56 commits of master, none of which touched this PR's mechanism: master
changed neither `.github/workflows/release.yml`, `bin/release-notes.py`,
`bin/test-release-notes.sh` nor `.github/workflows/mutation-full-sweep.yml`
since the branch's last master merge, so the renderer and the workflow step
that calls it merge unchanged. Master's `release.yml` still carries the inline
`awk`/`sed` converter this PR replaces.

Master also changed six of the files this PR touches. Four auto-merged:
`docs/releasing.md` and `bin/AGENTS.md` (#457's job batching, #442's
integration sharding), `.gitignore` (#378, #440), and
`docs/inflight/release-0.6.0.0.md` (#448, #476). Two conflicted.

`docs/inflight/release-0600-blockers.md` - the #197 triage bullet, inside
the `post-merge: checked` markers. This branch (2026-09-01, 2026-09-03) rewrote it
in post-merge terms as "all four landed"; master's grooming sweep (#476,
2026-09-08, correcting on 2026-09-07) rewrote the same bullet to say the
empty-release-body item **was already false when written** - #72 gave the
workflow a `--notes-file` built from the `CHANGELOG.adoc` section on 2026-07-29,
with `--generate-notes` only as a fallback. Master's correction is right and is
the later decision, so it is kept; master's claim that MDC is still open is not -
#205 merged 2026-08-27, which is why this branch corrected it, and that
correction is kept. Resolved as one bullet carrying both later facts, and it now
states what #199 actually does (replace the inline converter, and fail the
release on a missing or unrenderable section) rather than the retired claim that
it restores a body that was never absent.

`docs/refactoring.md` - two unrelated new sections appended at the same point.
Both kept: this branch's "`bin/release-notes.py` is Python in a Node-default
`bin/`" and master's "JUnit tag resolution is implemented twice". No content
from either side dropped.

Neither `--ours` nor `--theirs` was used.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
@github-actions

github-actions Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

🧪🔒 Quarantine Lane Report

The quarantine lane is empty - no @Quarantined tests remain, so none ran.

Any earlier row on this PR asking for a @Quarantined annotation or a docs/quarantined-tests.md
entry to be deleted is withdrawn - there is nothing left to delete. A merge-blocking review
thread, if one was opened for that row, still has to be resolved by hand.

Lane: non-gating; rules: see the Quarantine Audit check.

No quarantined test changed outcome since the previous push.

Updated for 04447e2 · run 34407455205 · 2026-09-09 21:32 UTC

astubbs added a commit that referenced this pull request Sep 9, 2026
… named, and five stale lines are corrected

Owner's decisions, 2026-09-09: the merge queue is closed as of today,
with later finds 0.6.0.x unless data loss on a default configuration;
the poisoned-transaction wedge is the second named exception beside
#44, and the release-note draft now carries it; the gate-latch
warning #487 argued for is v6-sized and joins tier 1 as the last
item; the upstream flat-counter reporters are not asked.

Corrections from the owner's read of the note: the release page body
is posted by hand on the day with gh release edit, because release.yml's
exact heading match misses the unreleased heading on master - so
#199 follows the tag rather than gating it, and the two lines that
said the workflow already publishes the curated section are fixed; the
#468 line no longer asks the reader to check a PR body for two
by-key removals that #468 dismissed and #492 fixed; the
vetting sweep's opening claim that the quarantine registry is non-empty
is struck as the sweep's dated reading; and the disposition list names
the three deferred bug notes it omitted.

Claude-Session: 460f7df9-dcc2-4b00-a9f9-62f3a2c6d5e4
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
astubbs added a commit that referenced this pull request Sep 9, 2026
…d the notes and README now say so

The opening paragraph of the 0.6.0.0 section claimed "no method signature
changed, but two identifiers did", and the coordinates bullet under Breaking
said "no signature changed, so nothing else in your code moves". Both were
false, and the seven bullets beneath them said so: a renamed exception, a
removed method, a new exception type on the commit failure surface, changed
protected signatures on the controller, a changed stream contract, and
identity equality on RecordContext. The owner caught it on the PR.

The claim was copied from src/docs/README_TEMPLATE.adoc, which carried it
twice - in the fork summary ("the API is source-compatible") and in the
Upgrading section ("Nothing else changes. The API is source-compatible, so
beyond the import lines no source edit is needed"). Both were written when
the rename was the only change and were never revisited as the breaking
changes landed. Same defect, four sites; all four are corrected here, and
README.adoc is regenerated from the template with the asciidoc-template
plugin rather than hand-edited.

What the text now says, in all four places: for most users the upgrade is the
pom and the imports, the committed offset format is unchanged so a consumer
group upgrades in place, and the API changes are the short list under
Breaking - named in the README so a reader knows what to look for before
following the link.

The rendered release-page Markdown was regenerated from the corrected section
with #199's converter in strict mode.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
astubbs added a commit that referenced this pull request Sep 9, 2026
…e the release

Owner review on #498, five changes:

- The opening no longer teases three roadmap items in a clause. A new
  "What comes next" section lists the queue by state - implemented and on
  an open PR (fencing recovery, virtual threads, self-tuning concurrency,
  global rate limiting, Streams and Connect previews, the multi-language
  sidecar and in-process clients, the commit-failure seam, the health check,
  residence time, the dashboard, offset density, the direct-pull engine, the
  docs site, the API gate); designed but not built (the dead-letter queue,
  batch failure attribution, the poll-path error seam, micro-batching,
  bounded buffers, the Java 17 baseline); and the 1.0 API settlement. The
  list is drawn from docs/data/roadmap.yaml and the open PR list, and says
  so; previews are marked as previews per the announcement note's rule.
- Breaking is rewritten as nested bullets: one line of consequence per
  change, one sub-bullet per thing a reader must do or know, no paragraphs.
  Same content, about half the words.
- The Fixes subsection "Records lost or duplicated with nothing in the logs"
  is "Priority 1: data loss and duplicates".
- The intake-stall limitation no longer says "silently": #497 adds a
  WARN when the gate has stayed latched with nothing retiring, and is in
  tier 1 for this release. An AsciiDoc comment beside the bullet records the
  tag-day dependency: if #497 has not merged, the WARN sentence comes
  out and "silently" goes back.
- A "The size of this release" section quantifies the gap from 0.5.3.2,
  upstream's last published release: merged PRs, main and test Java lines
  added and removed with rename detection, and new files, main against test.
  These are figures a command can produce, which docs/merge-checklist.md
  warns against; they are here because the section is frozen at the tag and
  the release is the one place a point-in-time number is the point. The
  commands are in a comment beside them, and recomputing them is a tag-day
  check named in the PR body.

Lines over 120 columns from the rewrite were rewrapped. The rendered
Markdown was regenerated with #199's converter in strict mode and
its self-test passes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
astubbs added a commit that referenced this pull request Sep 9, 2026
…ighten Breaking, name what comes next, and size the release

Owner review on #498, in one commit.

THE SOURCE-COMPATIBILITY CLAIM WAS FALSE, in four places. The opening
paragraph said "no method signature changed, but two identifiers did", and
the coordinates bullet under Breaking said "no signature changed, so nothing
else in your code moves" - while the bullets beneath them listed a renamed
exception, a removed method, a new exception type on the commit failure
surface, changed protected signatures on the controller, a changed stream
contract, and identity equality on RecordContext. The claim had been copied
from src/docs/README_TEMPLATE.adoc, which carried it twice (the fork summary
and the Upgrading section), written when the rename was the only change and
never revisited. All four sites now say: for most users the upgrade is the
pom and the imports, it is not source-compatible beyond that, the offset
format is unchanged so a consumer group upgrades in place, and the API
changes are the short list under Breaking - which the README names, so a
reader knows what to look for before following the link. README.adoc is
regenerated from the template with the asciidoc-template plugin.

WHAT COMES NEXT replaces a one-clause teaser. A new section lists the queue
by state, drawn from docs/data/roadmap.yaml and the open PR list: implemented
and on an open PR (fencing recovery and the two transactional fixes it
unlocks, virtual threads, self-tuning concurrency, global rate limiting, the
Streams and Connect previews, the multi-language sidecar and in-process
clients, the commit-failure seam, the health check, residence time, the
dashboard, offset density, the direct-pull engine, the docs site, the API
gate); designed but not built (the dead-letter queue, batch failure
attribution, the poll-path error seam, micro-batching, bounded buffers, the
Java 17 baseline); and the 1.0 API settlement. Previews are marked as
previews, per the announcement note's rule.

BREAKING is nested bullets: one line of consequence per change, one
sub-bullet per thing a reader must do or know. Same content, half the words.

THE PRIORITY-1 FIXES SUBSECTION is named "Priority 1: correctness", for the
property rather than the failure.

THE INTAKE-STALL LIMITATION no longer says "silently": #497 adds a
WARN when the gate has stayed latched with nothing retiring, and is in tier 1
for this release. An AsciiDoc comment beside the bullet records the tag-day
dependency - if #497 has not merged, the WARN sentence comes out and
"silently" goes back.

THE SIZE OF THIS RELEASE is a new section quantifying the gap from 0.5.3.2,
upstream's last published release: merged PRs, main and test Java lines
added and removed with rename detection, and new files, main against test.
These are figures a command can produce, which docs/merge-checklist.md warns
against; they are here because the section is frozen at the tag and the
release is the one place a point-in-time number is the point. The commands
are in a comment beside them, and recomputing them is a tag-day check named
in the PR body.

The rendered Markdown was regenerated with #199's converter in strict
mode and its self-test passes; every line of the section is within 120
columns.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
astubbs added a commit that referenced this pull request Sep 9, 2026
…es (#498)

The release-time rewrite of CHANGELOG.adoc's `== 0.6.0.0` section, so that
it is the published release notes rather than the working text it had been
since the fork. docs/releasing.md says the section for the release being cut
is generated at release time, replacing what is there; there is no generator
in bin/, so this is that generation, done by hand from the first-parent
commit log since the fork point (every fix, fix!, feat, feat! and deps body
read in full) and from the release documents: the v6 burn-down note on
#475, docs/inflight/release-0.6.0.0.md, docs/data/roadmap.yaml and
the open PR list. It is the one deliberate exception to "a PR never adds a
changelog entry", which exists so this rewrite can be written as a set.

What the section now says, in order: the fork and its coordinates, the
stability-release argument, and that upgrading is the pom and the imports
for most users but is not source-compatible beyond that; the size of the
release since 0.5.3.2, upstream's last published release; Breaking, as
nested bullets - the coordinates and Java packages, the commit-budget
exception, JStream blocking until close, the metadata-policy default, the
batchSize bound, the exception rename and removed listener getter, identity
equality for RecordContext, the two controller narrowings, the Mutiny Java
17 floor; Fixes in three subsections - priority 1 correctness, consumption
stopped after a rebalance (the confluentinc#857 story: the mechanisms
closed, the detector lines demoted to timing proxies, the one unattributed
chaos-only arm), other fixes; Known limitations, stated so the release
claims no more than it can show; What comes next, by state - implemented
and on an open PR, designed and not yet built, toward 1.0; Dependencies
re-read against the poms; Examples; and Build & CI, the lanes that say how
the library is tested and analysed, with Fray named as the next concurrency
lane.

Claims removed or corrected from the old text: the "source-compatible"
claim, which the Breaking list itself contradicted, removed here and from
src/docs/README_TEMPLATE.adoc in two places, README.adoc regenerated; the
wrong upstream attribution on the null-epoch fix that #217 asked to
be dropped; "upstream's last release 0.5.3.3" corrected to 0.5.3.2
published; the Reactor version, which said 3.8.6 while the pom says 3.8.7;
the self-hosted lane described as per-PR; the quarantine state; two counts
restated as shape; two upstream bullets folded into the fork entries that
carry them.

The heading loses its "(unreleased)" suffix, so release.yml's exact heading
match now finds the section. The release page body is still posted by hand
on the day from the converter's Markdown, per the burn-down's tier 3;
#199 follows the tag.

Tag-day checks this leaves: #497 must be merged, or the WARN
sentence in the intake-stall limitation comes out and "silently" goes back
(an AsciiDoc comment beside the bullet says the same); and the figures
under "The size of this release" are recomputed with the commands in the
comment beside them.

Also touched: docs/inflight/release-0.6.0.0.md gains the settled
release-condition wording at the same insertion point #475 amends
it, whichever merges second keeps the settled paragraph; docs/releasing.md
no longer says the section's generation is undecided.

Co-authored-by: Claude Fable 5.1 (1M context) <noreply@anthropic.com>
Brings in the v6 changelog finalisation (#498), the batchSize bound,
the gate-latch warning and the Lincheck timeout change. The changelog
heading is now `== 0.6.0.0` on master, so this branch's strict-mode refusal
of an `(unreleased)` heading no longer fires on a real run.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
@astubbs

astubbs commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

Successor: #501 converts CHANGELOG.adoc to CHANGELOG.md once - using this PR's converter in strict mode to render every section - and replaces the release step with a six-line awk extract of the ## <version> section that fails the run when the section is missing or empty. That keeps the guarantee this PR added (no silent fallback to generated notes, a rehearsal in the dry run's job summary) without a parser to maintain. If that lands, this PR closes as superseded by it; the converter did its one job there.

astubbs added a commit that referenced this pull request Sep 9, 2026
… is its section verbatim

The file was renamed in the previous commit with its AsciiDoc contents
intact; this commit converts them. CHANGELOG.adoc used almost nothing of
AsciiDoc: headings, `url[text]` link macros, single-star bold, `**` nested
bullets, three NOTE admonitions, one continuation and a vestigial
toc/ifndef preamble from when the README included it. GitHub release bodies
are Markdown, so the file's format was the only reason a converter had to
exist between the two - #199's 412-line parser and its 397-line
self-test. Converting the file once removes the need for both.

The new content is every version section of the old file rendered by that
converter in strict mode (all eleven render, including the finalised
0.6.0.0 section, whose body is byte-identical to the one #498 was
going to post by hand), under `## <version>` headings, with the preamble
converted by hand. The 0.6.0.0 text is unchanged in content.

release.yml gains an "Extract the release notes" step before release:prepare
that pulls the `## <version>` section with awk and fails the run if it is
missing or empty - the strict-mode guarantee #199 had, in six lines,
with no fallback to --generate-notes. The GitHub release step posts that
file. A dry run rehearses the extraction and puts the body in the job
summary.

What encoded the AsciiDoc shape changes with it: the changelog citation
gate reads `###` section headings and `-` bullets (its tests updated), the
package-rename guard's comment names the `### Breaking` bullet, and the live
docs name the heading syntax as it is now. docs/releasing.md says what the
workflow now does with the file.

Supersedes #199, whose converter did its one job here and whose
release.yml changes are replaced by the six-line extract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
astubbs added a commit that referenced this pull request Sep 9, 2026
… is its section verbatim

The file was renamed in the previous commit with its AsciiDoc contents
intact; this commit converts them. CHANGELOG.adoc used almost nothing of
AsciiDoc: headings, `url[text]` link macros, single-star bold, `**` nested
bullets, three NOTE admonitions, one continuation and a vestigial
toc/ifndef preamble from when the README included it. GitHub release bodies
are Markdown, so the file's format was the only reason a converter had to
exist between the two - #199's 412-line parser and its 397-line
self-test. Converting the file once removes the need for both.

The new content is every version section of the old file rendered by that
converter in strict mode (all eleven render, including the finalised
0.6.0.0 section, whose body is byte-identical to the one #498 was
going to post by hand), under `## <version>` headings, with the preamble
converted by hand. The 0.6.0.0 text is unchanged in content.

release.yml gains an "Extract the release notes" step before release:prepare
that pulls the `## <version>` section with awk and fails the run if it is
missing or empty - the strict-mode guarantee #199 had, in six lines,
with no fallback to --generate-notes. The GitHub release step posts that
file. A dry run rehearses the extraction and puts the body in the job
summary.

What encoded the AsciiDoc shape changes with it: the changelog citation
gate reads `###` section headings and `-` bullets (its tests updated), the
package-rename guard's comment names the `### Breaking` bullet, and the live
docs name the heading syntax as it is now. docs/releasing.md says what the
workflow now does with the file.

Supersedes #199, whose converter did its one job here and whose
release.yml changes are replaced by the six-line extract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
astubbs added a commit that referenced this pull request Sep 9, 2026
… is its section verbatim

The file was renamed in the previous commit with its AsciiDoc contents
intact; this commit converts them. CHANGELOG.adoc used almost nothing of
AsciiDoc: headings, `url[text]` link macros, single-star bold, `**` nested
bullets, three NOTE admonitions, one continuation and a vestigial
toc/ifndef preamble from when the README included it. GitHub release bodies
are Markdown, so the file's format was the only reason a converter had to
exist between the two - #199's 412-line parser and its 397-line
self-test. Converting the file once removes the need for both.

The new content is every version section of the old file rendered by that
converter (all twenty-nine render - the eleven unprefixed ones in strict mode - including the finalised
0.6.0.0 section, whose body is byte-identical to the one #498 was
going to post by hand), under `## <version>` headings, with the preamble
converted by hand. The 0.6.0.0 text is unchanged in content.

release.yml gains an "Extract the release notes" step before release:prepare
that pulls the `## <version>` section with awk and fails the run if it is
missing or empty - the strict-mode guarantee #199 had, in six lines,
with no fallback to --generate-notes. The GitHub release step posts that
file. A dry run rehearses the extraction and puts the body in the job
summary.

What encoded the AsciiDoc shape changes with it: the changelog citation
gate reads `###` section headings and `-` bullets (its tests updated), the
package-rename guard's comment names the `### Breaking` bullet, and the live
docs name the heading syntax as it is now. docs/releasing.md says what the
workflow now does with the file.

Supersedes #199, whose converter did its one job here and whose
release.yml changes are replaced by the six-line extract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
astubbs added a commit that referenced this pull request Sep 9, 2026
…ter dropped

The version sections were rendered by #199's converter, which does not
emit AsciiDoc line comments - so every `//` block inside a version section was
silently lost in the conversion. Only the preamble's one comment survived,
because the preamble was converted by hand.

The automated review found one of the four. Grepping the defect class rather
than the symptom - `grep -n '^//'` against `3e66041e3^:CHANGELOG.adoc`, which
is the last byte-identical copy - finds twelve comment lines in six blocks:

- The preamble's `git log --pretty` recipe. Already present, hand-converted.
- The `// only show TOC if this is the root document` note. Correctly gone: it
  annotated the `ifndef::github_name[]` / `toc::[]` directives, which have no
  Markdown equivalent and were themselves dropped on purpose.
- Regenerate at the tag, above `### Breaking`: the exact commands that recompute
  the size-of-this-release figures. This is the one the review flagged.
- TAG-DAY, in Known limitations: what to do to the latched-gate bullet if
  #497 had not merged before the tag.
- There is no 0.5.3.4 release, at the end of the 0.6.0.0 section: why a version
  number is missing from the file.
- The upstream release-tag URL under `## v0.4.0.0`, a source note on a pre-fork
  section.

The last four are restored as HTML comments, in the positions they held in the
AsciiDoc. Nothing rendered changes: comment syntax is the only difference, and
content parity is unmoved at 29 `## ` headings, 58 `### ` headings and 342
bullets.

The TAG-DAY block is indented two spaces so it sits inside the list item it
annotates. A `<!--` at column zero between two bullets is an HTML block, which
ends the list and starts a new one - a gap AsciiDoc line comments do not
create, and one that would have shown up in the release body.

DECISION FOR THE MAINTAINER, deliberately not taken here. Three of these now
live inside the `## 0.6.0.0` section, and this PR makes that section the
release body verbatim - so they ship into the v0.6.0.0 release notes. They do
not render, but they are readable in the body source, which the old converter
route never exposed. Regenerate-at-the-tag and TAG-DAY are the maintainer-only
two; moving them to docs/releasing.md instead is a one-line change if you would
rather the release body carried none of them. Restoring in place is the
lossless default and is what the review suggested first.

`awk` extraction rehearsed over the modified file: 0.6.0.0 is 631 lines,
0.5.3.3 is 7, v0.4.0.0 is 15 - all non-empty, so the fail-loud guard is not
tripped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
astubbs added a commit that referenced this pull request Sep 9, 2026
… is its section verbatim

The file was renamed in the previous commit with its AsciiDoc contents
intact; this commit converts them. CHANGELOG.adoc used almost nothing of
AsciiDoc: headings, `url[text]` link macros, single-star bold, `**` nested
bullets, three NOTE admonitions, one continuation, a handful of `//` line
comments and a vestigial toc/ifndef preamble from when the README included
it. GitHub release bodies are Markdown, so the file's format was the only
reason a converter had to exist between the two - #199's 412-line
parser and its 397-line self-test. Converting the file once removes the need
for both.

The new content is every version section of the old file rendered by that
converter (all twenty-nine render - the eleven unprefixed ones in strict
mode - including the finalised 0.6.0.0 section, whose body is byte-identical
to the one #498 was going to post by hand), under `## <version>`
headings that keep their original text, with the preamble converted by hand.
The 0.6.0.0 text is unchanged in content. Parity against the old file: 29
version sections, 58 section headings, 5 sub-headings, 342 bullets in both
of the old file's bullet syntaxes, 75 nested bullets.

The converter does not emit AsciiDoc line comments, so the four `//` blocks
inside version sections are restored by hand as HTML comments in the
positions they held: the recompute commands for the size-of-this-release
figures above `### Breaking`; the tag-day note on the latched-gate bullet in
Known limitations, indented two spaces so it stays inside the list item (a
`<!--` at column zero between two bullets is an HTML block and would split
the list); the "there is no 0.5.3.4 release" note at the end of the 0.6.0.0
section; and the upstream release-tag URL under `## v0.4.0.0`. The one
comment not carried over annotated the toc/ifndef directives, which have no
Markdown equivalent and were dropped on purpose. Three of the four sit inside
`## 0.6.0.0`, so they travel in the release body's source without rendering;
moving the two maintainer-only ones to docs/releasing.md is the owner's call.

release.yml gains an "Extract the release notes" step before release:prepare
that pulls the `## <version>` section with awk and fails the run if it is
missing or empty - the strict-mode guarantee #199 had, in six lines,
with no fallback to --generate-notes. The GitHub release step posts that
file. A dry run rehearses the extraction and puts the body in the job
summary.

What encoded the AsciiDoc shape changes with it: the changelog citation
gate reads `###` section headings and `-` bullets (its tests updated), the
package-rename guard's comment names the `### Breaking` bullet, and the live
docs name the heading syntax as it is now. docs/releasing.md says what the
workflow now does with the file.

Supersedes #199, whose converter did its one job here and whose
release.yml changes are replaced by the six-line extract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
astubbs added a commit that referenced this pull request Sep 9, 2026
… is its section verbatim

The file was renamed in the previous commit with its AsciiDoc contents
intact; this commit converts them. CHANGELOG.adoc used almost nothing of
AsciiDoc: headings, `url[text]` link macros, single-star bold, `**` nested
bullets, three NOTE admonitions, one continuation, a handful of `//` line
comments and a vestigial toc/ifndef preamble from when the README included
it. GitHub release bodies are Markdown, so the file's format was the only
reason a converter had to exist between the two - #199's 412-line
parser and its 397-line self-test. Converting the file once removes the need
for both.

The new content is every version section of the old file rendered by that
converter (all twenty-nine render - the eleven unprefixed ones in strict
mode - including the finalised 0.6.0.0 section, whose body is byte-identical
to the one #498 was going to post by hand), under `## <version>`
headings that keep their original text, with the preamble converted by hand.
The 0.6.0.0 text is unchanged in content. Parity against the old file: 29
version sections, 58 section headings, 5 sub-headings, 342 bullets in both
of the old file's bullet syntaxes, 75 nested bullets.

The converter does not emit AsciiDoc line comments, so the four `//` blocks
inside version sections are restored by hand as HTML comments in the
positions they held: the recompute commands for the size-of-this-release
figures above `### Breaking`; the tag-day note on the latched-gate bullet in
Known limitations, indented two spaces so it stays inside the list item (a
`<!--` at column zero between two bullets is an HTML block and would split
the list); the "there is no 0.5.3.4 release" note at the end of the 0.6.0.0
section; and the upstream release-tag URL under `## v0.4.0.0`. The one
comment not carried over annotated the toc/ifndef directives, which have no
Markdown equivalent and were dropped on purpose. Three of the four sit inside
`## 0.6.0.0`, so they travel in the release body's source without rendering;
moving the two maintainer-only ones to docs/releasing.md is the owner's call.

release.yml gains an "Extract the release notes" step before release:prepare
that pulls the `## <version>` section with awk and fails the run if it is
missing or empty - the strict-mode guarantee #199 had, in six lines,
with no fallback to --generate-notes. The GitHub release step posts that
file. A dry run rehearses the extraction and puts the body in the job
summary.

What encoded the AsciiDoc shape changes with it: the changelog citation
gate reads `###` section headings and `-` bullets (its tests updated), the
package-rename guard's comment names the `### Breaking` bullet, and the live
docs name the heading syntax as it is now. docs/releasing.md says what the
workflow now does with the file.

Supersedes #199, whose converter did its one job here and whose
release.yml changes are replaced by the six-line extract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XS64Xttx4vF5datYh7fmk
@astubbs

astubbs commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

Closing as superseded by #501, merged 2026-09-09. The changelog is now CHANGELOG.md, converted once using this PR's converter to render every section, and release.yml posts the ## <version> section verbatim - extracted before anything is tagged, failing the run when the section is missing or empty, with no fallback to generated notes and a rehearsal in the dry run's job summary. That is the guarantee this PR added, without a parser to maintain. The converter did its one job there; nothing from this branch is lost.

@astubbs astubbs closed this Sep 9, 2026
astubbs added a commit that referenced this pull request Sep 10, 2026
…ot by hand

The review caught six passages still describing the heading-match bug
#501 fixed and closed #199 on: release.yml now extracts
the changelog's versioned section verbatim, fails if it is missing, and
posts it as the release body. The tier 3 box for posting by hand is
withdrawn and ticked as done by that PR, #199 leaves the
can-follow list, the ownership table names the Markdown changelog, and
the tag-day check becomes "read the release page and confirm the body
is the section".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xoi3HYae8pjsEatuNFKieD
astubbs added a commit that referenced this pull request Sep 10, 2026
…ut it (#475)

0.6.0.0 is a bugs-only stability release, and it is overdue: the fork has
carried the fixes for upstream's most-reported defects for months while the
release waited on features. This note is the source of truth for cutting it -
the owner's decisions, the merge queue from those decisions to the tag, every
open question, and the checks that make the published artefacts true on the
day. #197 is the tracking handle and its body points here; nothing is
maintained on the issue.

THE DECISIONS, 2026-09-07 and confirmed since. The bar is the stability
release and nothing else; Streams and Connect move to the next-0x horizon in
the roadmap data; the producer-recovery stack is outside v6. The release
claim carries two named exceptions rather than waiting on them: the
transactional revoke wait (#44, bounded since #466, not yet
declined) and, from 2026-09-09, the poisoned-transaction wedge, both in the
transactional producer mode only. The merge queue closed on 2026-09-09; later
finds are 0.6.0.x unless they are data loss on a default configuration.

THE BURN-DOWN, recorded as each merge landed. Tier 1, the self-contained
fixes, is complete: the last two to join were the batchSize bound
(#496) and the gate-latch warning (#497), both decided v6-sized
on the day the queue closed. Tier 3, the plumbing, has the changelog section
finalised as the release notes and the claim amended (#498) and the
release page body posted verbatim from CHANGELOG.md by release.yml (#501,
closing #199); what remains is the tag-day checks, the drafted issue
responses, and the tag. A can-follow list names what is deliberately
not v6.

WHAT THE RELEASE NOTE SAYS ABOUT THE confluentinc#857 FAMILY, each line with
the PR that settled it: the revoke-path deadlock proven by control arm, the
eager stall withdrawn as a timing bound that flips with the processor count,
the fifth item measured as the consumer-group protocol under churn rather
than PC, the poller death fixed, the instance-stall sightings classified as
worker saturation from the load side. The intake stall #471 found has
its verdict from #487: the record-intake load gate is what stops
intake, head-of-line blocking is not why, and any instance that retries
forever while a fraction of its stream never succeeds latches eventually at a
computable threshold, idle or not. There is no gate fix; the fix bounds the
failures (#149's dead-letter queue), and until then #497 makes
the state visible. One arm stays unattributed and is named as such.

DATA LOSS AND DUPLICATES: the bug-162 replay branch refuted and the false
truncation warning fixed (#494, closing #162).

KNOWN UNKNOWNS, split in two so nothing is papered over: what is still
unknown at the cut - the shard half of the per-shard liveness blind spot, the
flake rows kept open with reasons, the maturity claim - and, under its own
heading, the unknowns made known on 2026-09-08 and how each was settled.

TAG-DAY CHECKS, folded in from the retired blockers note: master green with
the lanes known to lie named, the churn scenario's no-progress window settled
by replay and widened in #499 with the rebalance-dwell bound named as
that class's survivor, the Lincheck lane's timeout raised against runner-speed
variance, the rename named in both groupId and packages, the README's
trademark wording claiming nothing it does not have (#495), and the
changelog section as the release notes since #498, posted as the release
body by release.yml since #501.

ONE CHANGELOG EDIT, on the owner's decision of 2026-09-10: the "size of this
release" table of merged-PR and line counts is removed. Measured on a branch,
carrying its own re-measure instruction, stale from the next merge on; the
notes make their claim through the fixes they name.

Also here: a ci- note from this PR's own last review round - the file-refs
gate reads a token as a path only with two segments, so the changelog rename
left this branch-only note naming the old file with nothing to go red, and
the note records the allow-list that would close it; the vetting sweep's
reading and every open bug note's disposition,
moved into the ranking note where the tiers override them; a dated survey of
upstream items with no fix and no response as its own deferred note; the
refactoring registry's codec entry corrected for what #480 did and did
not change; and the confluentinc#546 manifest entry marked merged. Two notes
retired with their content migrated: the blockers register and the
merge-order plan for a far larger v6. The question this note began as, "when
is v6 good enough?", was answered on 2026-09-08 and the file renamed.

Serves #197; closes nothing. The tracker closes when
the tag is cut.

Co-authored-by: Claude Fable 5.1 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

0.6.0.0 Targeted at the 0.6.0.0 release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant