Skip to content

🧹 chore: post-0151 cleanup — dead validation duplicate, ADR-0014 scope, goformat codegen drift - #188

Merged
konih merged 6 commits into
mainfrom
chore/post-0151-cleanup
Aug 7, 2026
Merged

🧹 chore: post-0151 cleanup — dead validation duplicate, ADR-0014 scope, goformat codegen drift#188
konih merged 6 commits into
mainfrom
chore/post-0151-cleanup

Conversation

@konih

@konih konih commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Why

Post-v0.15.1 cleanup: the four follow-ups recorded against PR #186 and Phase 8e that need no
operator decision. No behaviour change ships in this PR — the one code deletion is unreachable,
and the one behaviour description that changes was wrong about what already ships.

What changed

:fire: Drop dead ValidateQueueManagerConnectionDelete — the bare variant lost its only
caller when the v1alpha1 webhook was deleted in 8e-8b; the live webhook calls the byte-identical
...DeleteV1Beta1. It survived only through its own tests.

Deviation from the recorded follow-up, which said "delete it + its redundant tests": deleting all
five tests would have dropped two assertions that the V1Beta1 suite does not carry — the
no-dependents → allow branch, and the multi-kind formatDependents detail assertion. Those two
tests are retargeted onto ...DeleteV1Beta1 instead; only the three per-kind tests are deleted,
as TestValidateQueueManagerConnectionDeleteWithV1Beta1Dependents already exercises all five
dependent kinds.

:memo: Correct the ADR-0014 carve-out scopefail() returns TerminalRetryInterval for
every non-transient QMC error, but ADR-0014, the --terminal-retry-interval help string and the
code comment all described it as auth-only. This corrects the record to match shipped behaviour;
the behaviour is unchanged and deliberate (a QMC's inputs — Secret, endpoint, TLS material — are
all mutable, so no terminal QMC state is known to be permanent).

Also fills the OPERATOR_RUNTIME.md flags table, which listed none of the --*-interval tuning
flags nor --mq-request-timeout.

:wrench: Exclude generated files from goformat — gofmt/goimports were rewriting the
controller-gen deepcopy and mockery mocks, so task format produced codegen drift that task verify
then flagged. This bit PR #186 twice, each time costing a restore commit. Detection is by the
standard // Code generated ... DO NOT EDIT. header scanned across the file preamble (controller-gen
emits it on line 7, under a build tag and licence block) rather than by hardcoded path, so new
generators are covered without editing the script.

:memo: Runbook note on bootstrap-ordering ERROR logs — REQ-REL-2026-08 made a missing QMC or
Secret return the error rather than wait silently on the watch, so applying a directory in one shot
(the normal GitOps case) emits rate-limited Reconciler error lines until the referenced object
appears. Documents that this is the retry backstop rather than an incident, and when it is
actionable.

What to review

  • The test retargeting in internal/validation/queuemanagerconnection_test.go — specifically that
    no assertion was lost relative to what the three deleted tests covered.
  • Whether the ADR-0014 "Scope" paragraph is the wording you want on the record, since it widens the
    documented contract to match code rather than narrowing code to match the ADR.
  • hack/goformat.sh preamble scan — sed -n '1,/^package /p'.

Test plan

Full local gate matrix, all green on 3aa70f8:

Gate Result
task test:run pass — internal 92.7% (floor 90), api 92.5% (floor 75)
task lint (golangci + go-arch-lint) 0 issues / no warnings
task verify (codegen, CRD fragments, samples) ok
task format:check clean
task lint:shell clean
task lint:markdown 0 errors, 90 files
task scrub:tree ok, 548 files

goformat exclusion verified end-to-end: appended deliberately mis-formatted Go to
zz_generated.deepcopy.go, ran the script, confirmed the file was left untouched, then restored it.
Coverage was the specific risk here (deleting covered code plus its tests) and both floors hold.

Risks

Low. The deleted function is unreachable, the format change only narrows what gets rewritten, and
the rest is prose. The one thing worth a second pair of eyes is the ADR scope paragraph, which is a
statement about the contract rather than about code.

Out of scope

  • F1 / R2 — e2e exercising mqweb outage → recovery self-heal within one retry interval. Real
    test work, not cleanup.
  • TESTQ — characterising AUTH-14 watch-recovery latency / bounded resync backstop.
  • REL-4 — CRD printer column (public-CRD surface, LGTM-gated).
  • P3 v1alpha1 doc residue — already fixed by docs: align docs with v1beta1-only API #185; the INBOX entry was stale.

Tip

Review commit-by-commit — the four commits are independent and each stands alone.

Review note: this branch has had no independent reviewer. Gates and the coverage check are
machine-verified as above, but the code review is self-review only.

konih added 4 commits August 7, 2026 09:58
…e duplicate

The bare variant lost its only caller when the v1alpha1 webhook was deleted
(Phase 8e-8b); the webhook calls ...DeleteV1Beta1, which is byte-identical.
Kept alive only by its own tests.

Retarget the two tests carrying assertions the V1Beta1 suite lacks — the
no-dependents allow branch and the multi-kind detail formatting — onto
...DeleteV1Beta1 rather than deleting them, so no assertion is lost. The
three per-kind tests (Topic/Channel/auth) are dropped as redundant with
TestValidateQueueManagerConnectionDeleteWithV1Beta1Dependents, which
exercises all five dependent kinds.
…interval flags

fail() returns TerminalRetryInterval for every non-transient QMC error, but
ADR-0014, the --terminal-retry-interval help string and the code comment all
described it as an auth-only carve-out. Correct the record to match shipped
behaviour — the behaviour itself is unchanged and intentional, since a QMC's
inputs (Secret, endpoint, TLS material) are all mutable.

Also fill the OPERATOR_RUNTIME.md flags table, which listed none of the
--*-interval tuning flags nor --mq-request-timeout.
gofmt and goimports were rewriting controller-gen deepcopy and mockery mocks,
so a run of `task format` produced codegen drift that `task verify` then
flagged — twice during the v0.15.1 fix lane, each costing a restore commit.

Detect generated files by the standard "// Code generated ... DO NOT EDIT."
header scanned across the file preamble (controller-gen emits it on line 7,
below a build tag and license block) rather than by hardcoded path, so new
generators are covered automatically. Drops the now-dead v1alpha1 golines
exemption.
REQ-REL-2026-08 made workload reconciles return the error when the referenced
QueueManagerConnection or Secret is missing, instead of waiting silently on the
watch. Applying a directory in one shot (the normal GitOps case) therefore emits
rate-limited Reconciler ERROR lines until the referenced object appears.

Document that this is the deliberate retry backstop rather than an incident, and
when it is genuinely actionable, so operators do not alert on a bare ERROR-rate
threshold.
@codecov

codecov Bot commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@konih

konih commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

F2 verified end-to-end against task format (not just hack/goformat.sh).

task format runs two commands — the script and golangci-lint run --fix ./... — so the script fix alone would not have closed this. Appended deliberately mis-formatted Go to both generated files, ran task format, and confirmed neither was rewritten and nothing else in the tree was touched:

File Result
api/v1beta1/zz_generated.deepcopy.go preserved
test/mocks/mqadmin/admin_mock.go preserved

.golangci.yaml already covers the second command independently (generated: lax plus explicit zz_generated\..*\.go$ excludes at lines 106/127/141/144), so no config change was needed — but that was assumed rather than checked in the original push, hence this confirmation.

Tree restored clean afterwards.

@konih

konih commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

Independent review — APPROVE

Reviewed diff-only by a reviewer that did not author the branch. No P0 or P1 survived adversarial re-check.

Verified (claims that held):

  • UnreachabilityValidateQueueManagerConnectionDelete is genuinely dead; the only live caller path (internal/webhook/v1beta1/queuemanagerconnection_webhook.go:48) uses ...DeleteV1Beta1. .renovate/ and .worktrees/ correctly excluded.
  • The retargeting was necessary, not redundant — both pre-existing live-function tests (validation_test.go:364, queuemanagerconnection_test.go:256) assert only len(errs) == 0, so neither covered the len(dependents) == 0 → nil allow branch nor any errs[0].Detail content. The two retargeted tests add exactly those. The Channel/ChannelAuthRule/AuthorityRecord branches from the three deleted tests remain covered by DeleteWithV1Beta1Dependents.
  • Flags table — all five added rows match cmd/main.go names and defaults exactly (5m/10m, 15s, 30s, 2m, 30s).
  • ADR scope — the widened wording does not contradict the existing "does not apply to workload reconcilers" statement.
  • The log sample is not fabricatedConnectionNotFoundError.Error() plus the k8s NotFound cause and group messaging.mkurator.dev reproduce the quoted string character-for-character.
  • hack/goformat.sh — passes bash -n, detects both real generated files, and dropping the api/v1alpha1/*_types.go golines exemption is safe (package no longer exists).

P2 — docs/OPERATOR_RUNTIME.md bootstrap-ordering section is half wrong

The new section claims applying "a QMC before its credentials Secret" makes that reconcile return the error and emit rate-limited Reconciler error lines. False for the QMC half. A missing credentials Secret surfaces as *mqadmin.SecretNotFoundError (internal/adapter/mqrest/factory.go:495), which is neither ErrTransient nor ErrTerminal; the QMC reconciler routes it through fail(), which ends at queuemanagerconnection_controller.go:154 returning RequeueAfter with a nil error — so controller-runtime logs nothing, and fail() has no log call of its own. The operator sees a Warning Event (SecretNotFound) plus Ready=False, not an ERROR line.

The workload-CR half is correct (setSyncedError's default: branch, reconcile_shared.go:191-192). Being fixed in this PR.

P3 (recorded, not blocking)

  1. hack/goformat.sh:16-19sed | grep -q under pipefail can propagate SIGPIPE (141) and misreport a generated file as not-generated. Reproduced only with a synthetic ~200k-line preamble; both real generated files detect correctly. Latent robustness nit.
  2. Taskfile.yml:203format:check's git checkout -- api/*/zz_generated.deepcopy.go test/mocks/ is now dead weight and a footgun (silently discards uncommitted changes to those paths). Pre-existing, left in place deliberately as a belt-and-braces net.
  3. docs/adr/0014-*.md:45 — "whenever the error is not ErrTransient" has one exception: a failed status update returns wrapped statusErr and gets controller-runtime backoff instead of the 2m backstop. Being tightened in this PR.

Gate matrix trusted as reported; go build ./... and go test ./internal/validation/ re-run independently and pass.

konih added 2 commits August 7, 2026 10:39
Independent review caught the runbook section asserting that a QMC applied
before its credentials Secret emits rate-limited Reconciler ERROR lines. It does
not: a missing Secret surfaces as SecretNotFoundError, which is neither
transient nor terminal, so fail() sets Ready=False, emits a SecretNotFound
Warning Event and returns RequeueAfter with a nil error — controller-runtime
logs nothing. Only the workload-CR ordering produces the ERROR lines.

Split the section so each ordering states its own observable signal, and point
operators at the condition and Event for the QMC case rather than the log
stream.

Also tighten the ADR-0014 scope paragraph: the TerminalRetryInterval path is
taken when the error is non-transient *and the status update succeeds* — a
failed status update returns that error and gets controller-runtime backoff.
Follow-up review found the same wrong claim one layer up: the error-classification
table still stated categorically that unclassified errors (incl. missing
connection/Secret) return the error to controller-runtime and log at ERROR. True
for workload reconcilers, false for the QMC — fail() returns RequeueAfter with a
nil error, so nothing is logged.

Scope the row per reconciler the way the Terminal and Transient rows already do,
and split the follow-on sentence so the Secret case points at the condition and
Event instead of the log.

Swept the rest of the doc set for the same claim: ADR-0014's principle bullets and
the INSTALL_AND_USE condition reference are both framed around Synced (the
workload condition), so they are already workload-scoped and correct.
@sonarqubecloud

sonarqubecloud Bot commented Aug 7, 2026

Copy link
Copy Markdown

@konih

konih commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator Author

Independent review round 3 — APPROVE (head 756d131)

Three independent review rounds, each on a fresh reviewer that saw only the diff. No P0, P1, or P2 outstanding.

Round Head Verdict Raised
1 3aa70f8 APPROVE 1×P2 (bootstrap-ordering prose wrong for the QMC path), 3×P3
2 cbe6641 APPROVE 1×P2 residual (same claim, unfixed in the table above)
3 756d131 APPROVE 2×P3 wording nits

What round 3 verified against source

  • Unclassified row, workload half — matches setSyncedError (reconcile_shared.go:184-211): unclassified falls to the default: branch and returns the error, so controller-runtime emits the ERROR.
  • Unclassified row, QMC half — matches fail() (queuemanagerconnection_controller.go:132-154): Ready=False via setCondition, Warning Event via recordReconcileWarning (which classifies SecretNotFoundError to reason SecretNotFound, events.go:43-46), and RequeueAfter: TerminalRetryInterval() with a nil error. fail() contains no logger.Error, so "no ERROR line" holds.
  • The watch claim is real — all five workload controllers (Queue, Topic, Channel, ChannelAuthRule, AuthorityRecord) wire SetupWithManager through setupMQObjectController, which registers the QMC watch with connectionWatchPredicates.
  • Anchor resolves#expected-error-logs-during-bootstrap-ordering matches the unique heading under default toc slugify.
  • No contradictions elsewhere — ADR-0014's amendment bullets are explicitly prefixed "for workload reconcilers (setSyncedError)"; INSTALL_AND_USE.md:536,770 are framed on Synced (workload-only; QMC uses Ready). Neither is categorical.

P3 nits — recorded, deliberately not fixed

  1. docs/OPERATOR_RUNTIME.md:204 — "QMC: fail() treats any non-transient error the same way" can read as "same as the workload behaviour just described", which the following clause then contradicts; the intended referent is the Terminal row. Behaviour described after it is accurate.
  2. docs/OPERATOR_RUNTIME.md:207-211 — the QMC half is described as retrying "on the 2m backstop", omitting its symmetric fast path (the Secret watch, queuemanagerconnection_controller.go:162-166). Not wrong — the linked section immediately below states the watch re-enqueues within seconds and the requeue is the fallback — but asymmetrically incomplete.

Stopping the polish here deliberately: both are wording nits on the same sentence, and another fix round would invalidate this APPROVE and cost a fourth review for no correctness gain. Logged to the INBOX instead.


Ready for maintainer merge. Note for the record: the branch was authored by the same session that coordinated these reviews, so the reviewers — not the author — are the gate. No reviewer approved its own work, and no APPROVE was carried across a change.

@konih
konih merged commit bba0e1b into main Aug 7, 2026
22 checks passed
@konih
konih deleted the chore/post-0151-cleanup branch August 7, 2026 12:10
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.

2 participants