Skip to content

docs(gate): land corpus lessons and add non-blocking rewrite report - #200

Open
cuioss-oliver wants to merge 10 commits into
mainfrom
feature/plan-v02-17-lessons-into-source
Open

docs(gate): land corpus lessons and add non-blocking rewrite report#200
cuioss-oliver wants to merge 10 commits into
mainfrom
feature/plan-v02-17-lessons-into-source

Conversation

@cuioss-oliver

@cuioss-oliver cuioss-oliver commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Lands the twelve repository source lessons drained from the api-sheriff-roadmap corpus into the
narrowest document or gate whose reader is the person about to make the mistake. One new
operator-approved page receives the build-gate cluster, five existing documents receive the rest,
and the one mechanism that can be enforced rather than merely stated becomes a non-gating
OpenRewrite dirty-tree report job in CI.

The change is subtractive as well as additive: lessons found already present in repository source at
HEAD are recorded as already-covered rather than restated, and where a rule was substantially
present already, only the missing members of its enumerated class were added — not a second copy of
the rule.

Changes

New page (the one approved new document)

  • doc/development/build-gate-discipline.adoc — the build-gate cluster: the quality gate's
    rewriting behaviour and its operational consequences, the single build-invocation rule, and the
    two surviving halves of the fixed-point lesson together with the recorded discard verdict for the
    half that did not survive verification.
  • doc/development/README.adoc — one row in the == Contents table for the new page. The table
    indexes every page in the directory, so omitting the row would silently misrepresent the set.

Existing documents

  • CLAUDE.md — three always-on statements only, integrated into the Pre-Commit Process section
    beside the existing -Werror prose rather than appended blind: the general gate-mutation rule,
    the class statement it belongs to, and the one-line declared-versus-asserted discriminator.
  • doc/development/declared-limit-assertion-coverage.adoc — the declared-versus-asserted rules
    behind the coverage matrix, folded into the page that already owns that subject.
  • doc/development/sonar-quality-gate.adoc — the unowned-duplicated-state rule about line-number
    cross-references.
  • demo-client/doc/playwright-suite.adoc — the browser-policy rule completed to its full enumerated
    class.
  • .claude/skills/run-integration-tests/SKILL.md — the two owed pointers: the compose --no-deps
    cross-reference, and a pointer to the browser-policy boundary (the rule itself stays in the
    Playwright doc, since this skill's subject is the integration-tests stack, not demo-client).

CI

  • .github/workflows/maven.yml — a new rewrite-report job that runs the rewriting gate and
    reports the resulting dirty tree plus the OpenRewrite recipe attribution. It is deliberately
    non-gating, patterned on the existing supply-chain-scan job, including the
    exit-code: 0-not-continue-on-error distinction that keeps a broken tool red while suppressing
    the verdict. No CI lane ran the rewriting gate before this PR, so this job is what first brings
    the OpenRewrite mutation under CI observation.

Test Plan

  • Quality gate passed (verify -Ppre-commit) green at 6a8100a, tree clean post-gate
  • Full verify passed at the same HEAD
  • Pre-submission self-review clean (6 candidates examined, none matched)
  • rewrite-report job observed on this PR's first CI run (the job is new and has never executed)

Related Issues

None.


Generated by plan-finalize skill

Intent

The problem. Twelve hard-won lessons lived only in a drained lessons corpus. A lesson nobody
reads changes no behaviour: the person about to re-make the mistake reads CLAUDE.md, a
doc/development/ page, or a CI failure — never the corpus. Landing them is what turns recorded
experience into something that actually intercepts the next occurrence.

The chosen approach. Each rule goes into the narrowest document whose reader is the person at
risk, and nowhere else — stated once, cross-referenced elsewhere, never restated. Where a lesson can
be enforced rather than merely written down, it is enforced: the OpenRewrite dirty-tree finding
becomes a real CI job instead of a paragraph. Every premise was re-probed at HEAD before landing, so
two lessons already satisfied by repository source are recorded as already-covered instead of
duplicated, one refuted claim is discarded with the verdict recorded, and no landed text carries a
file:line anchor — that anchor style is itself one of the lessons being landed, and this plan
found a live instance of it going stale mid-flight.

The new CI job is deliberately non-gating. main is not the formatter's fixed point today, so a
blocking form would be red on every run and would be disabled within a week; a report that is always
visible and never blocks is the form that survives. It follows the existing

[Intent truncated — 1373 of 2155 characters shown; full outline in the plan workspace]

Summary by CodeRabbit

  • Documentation

    • Expanded development guidance for build-gate behavior, including file mutations, incremental builds, formatting, rewrites, and change attribution.
    • Added guidance for validating configuration behavior, declared-limit coverage, and SonarCloud quality-gate scope.
    • Clarified browser-only control coverage and when to use Playwright versus API-based integration tests.
    • Updated contributor documentation indexes and coverage references.
  • CI

    • Added a non-blocking rewrite report that records automated changes and recipe attribution while still reporting tooling failures.

cuioss-oliver and others added 9 commits August 9, 2026 14:50
Create doc/development/build-gate-discipline.adoc as a peer of the Sonar
quality-gate policy. It records the three mechanisms in this repository that
mutate the working tree while the gate exits 0 -- OpenRewrite's import-group
churn (and its poisoning of the change-ledger freshness stamp), the pre-commit
formatter's non-idempotency, and the SimplifyTestThrows reversion reached via
JUnit5BestPractices -- the three consequences a contributor acts on, the revert
rule with the objection to it and the standing fixed-point debt, the
recipe-scoping trap, the non-gating rewrite-report job that reports all of it,
the incremental-build rule, and the recorded discard of the
fully-qualified-refspec fix.

Add the matching row to the contributor guide's Contents table.

Co-Authored-By: Claude <noreply@anthropic.com>
Add one section to the declared-limit assertion-coverage note carrying the
three rules that motivate the matrix: the deletion discriminator (a parsed,
schema-validated key with no production consumer is a silent security no-op,
tested by asking whether deleting the key would turn anything red, with the
note's own inert TLS protocol-floor row as the worked instance); that wiring an
inert key is a behavioural flip for every consumer, so the first failing test
is a sample of the dependant set rather than the whole of it, and a new
assertion extends SingleSourceTlsContractTest instead of splitting the contract
across a second file; and that an opt-in runtime feature needs a
deployment-activation test, with TlsEdgeActivationWiringTest as the reference
shape.

The three marked blocks DescriptorInventoryWiringTest parses as its expected
inventory are untouched; the integration-tests module suite is green.

Co-Authored-By: Claude <noreply@anthropic.com>
Add one section to the Sonar quality-gate policy stating the two rules that
answer the same question from opposite ends. A cosmetic sweep must stay out of
the interior of uncovered branches, because Sonar's new-code window is the diff
rather than its semantics -- a pure rename inside an uncovered catch block
drags pre-existing uncovered lines into the pull request's coverage
measurement. A finding inside the scanned surface but outside the declared
write-boundary is dispositioned taken_into_account and reported as a named
follow-up, never silently absorbed, because the widening is invisible in a gate
result that only ever gets greener.

Close with the page's own hygiene rule: cross-references here name documents
and rules, never file:line anchors. The four-anchor deferral table that belongs
here by subject is deliberately not landed -- its anchors no longer resolve and
one now points at a comment recording the finding as fixed, so it is recorded
as an omission with its reason rather than restored as a stale list.

Co-Authored-By: Claude <noreply@anthropic.com>
… pointers

The Playwright doc already carries the browser-policy rule and its
generalisation; only the enumerated class was short. Add the two members it
omitted -- cookie partitioning, and the navigation context a response arrives
in (top-level redirect GET versus cross-site form POST) -- and state that this
suite is the only gate in the repository covering that class. The navigation
member is the one the page's own worked defect turned on, so the list now
matches the story it sits under.

Give the run-integration-tests skill the two cross-references it was missing:
that a green RestAssured run here is not evidence about that class, and that a
trimmed bring-up already has a working script rather than needing a Compose
profile. Both are pointers -- each rule stays in the document that owns it.

Co-Authored-By: Claude <noreply@anthropic.com>
CLAUDE.md is the scarcest surface in the repository, so only statements that
apply to most work earn a line here. Three do, and each cross-references its
detail page rather than restating it.

Beside the -Werror prose in the Pre-Commit Process, where a reader already has
the build gate in mind: a successful build is not evidence that work happened,
and a gate that exits 0 can still have changed your files -- so a review-bot
suggestion is verified by surviving the gate rather than by being implemented,
and unrelated churn is reverted rather than committed. The mechanisms, the
operational consequences and the recipe-scoping trap stay in
doc/development/build-gate-discipline.adoc.

With the testing standards: a configuration key that parses is not a
configuration key that acts, discriminated by asking whether deleting the key
would turn any test red. The worked instance stays in
doc/development/declared-limit-assertion-coverage.adoc.

Co-Authored-By: Claude <noreply@anthropic.com>
Three mechanisms in this repository mutate the working tree while the gate
exits 0, and all three are invisible in the build result by construction. Add a
rewrite-report job to the Maven workflow that runs the rewriting gate and
prints, into the job summary, the post-gate git status --porcelain listing and
every "Changes have been made to <file> by:" block with its recipe chain.

The job is patterned on supply-chain-scan: no needs:, hardened runner, checkout
without persisted credentials, and deliberately non-gating on its own verdict.
It carries no continue-on-error, so a genuine Maven or tooling failure still
turns the check red; only the dirty verdict is suppressed, and it is suppressed
structurally -- no step asserts cleanliness, so there is no failing path to
mask. shell: bash is load-bearing on both run steps: it selects pipefail, and
without it the tee would swallow a Maven failure.

-Ppre-commit is load-bearing too, and the leading comment says so: the recipe
list that reaches all three mechanisms is the pre-commit profile's
activeRecipes override, and without the profile the goal reports
"Using active recipe(s) []" and exonerates OpenRewrite for free. The same
comment records why this lane is deliberately not the positively-phrased
fitness function ADR-0030 prescribes, and the condition under which it could
become one.

The job commits nothing and pushes nothing; the mutated tree lives only in the
runner.

Co-Authored-By: Claude <noreply@anthropic.com>
The page asserted that main is not at the OpenRewrite recipes' fixed point and recorded reaching it as unpaid debt. A whole-reactor verify -Ppre-commit run drives rewrite:run with the full pre-commit recipe list in every module, produces zero 'Changes have been made to' attributions and leaves the tree clean, so the premise was false. Restate every fixed-point passage as the current observed state plus the drift risk: the fixed point is a property of the tree at a point in time, lost silently the moment a change the recipes want to rewrite lands. The three mechanisms, the three operational consequences and the revert rule are unchanged; the revert rule's reasoning is re-grounded on that drift risk rather than on standing debt.
The job stays a report, not a gate; only its leading comment changes. The old rationale claimed a fail-on-dirty assertion would be red on every run for as long as main is not the formatter's fixed point, which is false - the tree is observed clean at the active recipes' fixed point. The real reason to stay non-gating is that the observation is not a guarantee: a hard gate would block every pull request from the moment any drift lands, including the ones that did not cause it. The comment now also names the condition under which the ADR-0030 fitness-function shape becomes the right call.
The rewrite-report job's ADR-0030 divergence comment restated, near-verbatim,
the argument already carried by doc/development/build-gate-discipline.adoc
while its own header comment declares that adoc as the home for the story.
Collapse it to what is genuinely site-unique: the ADR-0030 summary, the
divergence flag, the one-clause reason, the pointer, and the prohibition
against converting the job into a hard gate. Comments only, no behaviour
change.

Also correct doc/development/README.adoc's "twelve-file descriptor surface"
to thirteen. The page it describes states thirteen and that count is
machine-checked by DescriptorInventoryWiringTest, so the README line was
provably stale.

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

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request documents browser-control coverage, adds non-gating OpenRewrite reporting to Maven CI, and expands contributor guidance for build gates, configuration assertions, and SonarCloud scope.

Changes

Browser-Control Test Coverage

Layer / File(s) Summary
Browser-control coverage guidance
.claude/skills/run-integration-tests/SKILL.md, demo-client/doc/playwright-suite.adoc
The documentation distinguishes RestAssured coverage from browser-enforced controls and identifies Playwright as the repository gate for those controls.

Build-Gate Reporting and Discipline

Layer / File(s) Summary
OpenRewrite workflow reporting
.github/workflows/maven.yml
The Maven workflow runs the pre-commit OpenRewrite gate and publishes working-tree status and recipe attribution while preserving tooling failures.
Build-gate operating rules
doc/development/build-gate-discipline.adoc, CLAUDE.md, doc/development/README.adoc
Contributor guidance covers gate-induced mutations, recipe scoping, dirty-tree attribution, incremental compilation, guard interpretation, and related documentation links.

Coverage and Scope Policies

Layer / File(s) Summary
Configuration effectiveness checks
doc/development/declared-limit-assertion-coverage.adoc, CLAUDE.md, doc/development/README.adoc
The documentation requires behavioral configuration assertions and defines wiring and deployment activation checks.
SonarCloud scope and coverage rules
doc/development/sonar-quality-gate.adoc
The policy documents uncovered-branch coverage effects, declared write boundaries, named follow-ups, and stable references.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the documentation updates and the addition of the non-blocking OpenRewrite report job.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@cuioss-review-bot

Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 No relevant tests
🔒 No security concerns identified
⚡ No major issues detected

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The awk-based extraction of recipe attribution from rewrite-run.log in the rewrite-report job is tightly coupled to the current OpenRewrite/Maven log format; consider making the parsing more robust (e.g., anchoring on explicit markers or using a machine-readable output mode if available) to avoid breakage on minor log format changes.
  • The new rewrite-report job runs rewrite:run on every workflow invocation, adding a non-trivial Maven execution; consider scoping this job to specific branches or events (e.g., pull_request only, or main-protected branches) to keep CI time under control while still getting the intended visibility.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The awk-based extraction of recipe attribution from `rewrite-run.log` in the `rewrite-report` job is tightly coupled to the current OpenRewrite/Maven log format; consider making the parsing more robust (e.g., anchoring on explicit markers or using a machine-readable output mode if available) to avoid breakage on minor log format changes.
- The new `rewrite-report` job runs `rewrite:run` on every workflow invocation, adding a non-trivial Maven execution; consider scoping this job to specific branches or events (e.g., `pull_request` only, or main-protected branches) to keep CI time under control while still getting the intended visibility.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

The rewrite-report job died on its first CI run with

    No plugin found for prefix 'rewrite'

after Maven Central answered 429 for org.openrewrite.maven/maven-metadata.xml.
Resolving a goal PREFIX requires that metadata fetch even though the plugin is
declared in the pre-commit profile, so the job carried a network dependency it
does not otherwise need and never reached the gate at all.

Invoke org.openrewrite.maven:rewrite-maven-plugin:run by full coordinates
instead. The version still resolves from the profile's own plugin declaration,
and no prefix metadata is fetched.

Verified locally: the run reports the full 19-recipe active list (not the
empty-recipe false negative the profile omission produces), exits 0, and leaves
the tree clean.

The job stays non-gating for the DIRTY VERDICT only; a genuine tooling failure
turning it red is the designed behaviour, and this run was exactly that.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: cuioss/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 346a03d1-fdb4-44b1-abe1-8519148ecdb6

📥 Commits

Reviewing files that changed from the base of the PR and between e343404 and e7a5c7c.

📒 Files selected for processing (8)
  • .claude/skills/run-integration-tests/SKILL.md
  • .github/workflows/maven.yml
  • CLAUDE.md
  • demo-client/doc/playwright-suite.adoc
  • doc/development/README.adoc
  • doc/development/build-gate-discipline.adoc
  • doc/development/declared-limit-assertion-coverage.adoc
  • doc/development/sonar-quality-gate.adoc

Comment thread .github/workflows/maven.yml
Comment thread .github/workflows/maven.yml
Comment thread CLAUDE.md
Comment thread demo-client/doc/playwright-suite.adoc
Comment thread doc/development/declared-limit-assertion-coverage.adoc
Comment thread doc/development/sonar-quality-gate.adoc
Comment thread doc/development/sonar-quality-gate.adoc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant