Skip to content

go-ldd v2.10.1: R2/R11 absence is a value (Introduce Null Object for optional collaborators); eval docs - #28

Merged
buzzdan merged 5 commits into
mainfrom
claude/handoff-eval-rebaseline-uxs66q
Sep 11, 2026
Merged

go-ldd v2.10.1: R2/R11 absence is a value (Introduce Null Object for optional collaborators); eval docs#28
buzzdan merged 5 commits into
mainfrom
claude/handoff-eval-rebaseline-uxs66q

Conversation

@buzzdan

@buzzdan buzzdan commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Summary

Releases go-linter-driven-development 2.10.1. Motivated by the go-2.10.0-5828c34 eval baseline (buzzdan/ldd-evals#1).

R2 and R11: absence is a value

Both nil-handling reviews in the baseline (case-e-nils-review, 0/2) proposed "reject nil in the constructor" for an optional event sink and never offered the Null Object, and the refactor (case-e-nils-refactor, 0/1) introduced a one-implementation Sink interface to get a no-op, failing the R6 postcheck. The cause is structural: a hunter sees one rule file, and R2's fix list had no move for an optional collaborator. The Null Object lived only in R11, which pointed at R2 without R2 pointing back.

  • core/rules/R2-self-validating-types.md: a new design point, "Absence is a value too", with the Reporter/DiscardSink() shape, and an Introduce Null Object fix move that names the fork: a required collaborator is rejected in the constructor; an optional one (logger, sink, clock, metrics) gets a do-nothing value by default, and every guard in the methods is deleted. "Hoist method checks" now says it is the wrong move for an optional field.
  • lang/go/rules/R2/falsifying-questions.md: Q2 (methods re-checking fields) and Q6 (nil passed as an argument) carry the same fork, and ask the hunter to name both moves when the code does not say which the field is.
  • core/rules/R11-conditional-dispatch.md: the Null Object entry states the Go shape. A no-op implementation only when an interface already exists; otherwise a value of the concrete type composing io.Discard (the standard library's own Null Object: a real io.Writer whose Write returns len(p), nil); never a new interface for the sake of the no-op (R6). Optional collaborators only.

Expected effect on the baseline: case-e-nils-review fix-null-object (0/2 today), and the refactor's nil-unrepresentable, default-constructor-exists and the R6 Q1 postcheck (0/1 in both medium passes). About $3 for the review case and $3 for the refactor to re-run.

Release 2.10.1

The changelog's Unreleased entries (this change, the generated plugin directory from #27, the behavioral evals) become ## [2.10.1] - 2026-09-11; plugin.json and the root README table follow. The plugin directory is regenerated; task check, lint-core (Residue table refreshed) and the docs gate pass.

Eval docs

  • docs/eval-fixture.md describes the two grader-generator changes in buzzdan/ldd-evals#2: cluster graders match the word "cluster" followed by the anchor or its last dotted segment, and a plant may carry recall_match.
  • docs/eval-harness.md and docs/eval-baseline.md name go-2.10.0-5828c34 as the current baseline, with its pass rates and the noise floor from two medium passes; 681fdb0 stays as the worked example of the comparison procedure.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WrQTEgY87C1UdfgejismGr

…erated review graders

The evals repository's generator now matches a cluster on the word "cluster"
followed by the anchor or its last dotted segment, and a plant may carry
recall_match when reports name it by symbol rather than file. Record both in the
fixture doc that describes the manifest's consumers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WrQTEgY87C1UdfgejismGr
…ce Null Object

Both nil-handling reviews in the go-2.10.0-5828c34 baseline proposed "reject nil
in the constructor" for an optional event sink, and the refactor introduced a
one-implementation interface to get a no-op. The R2 hunter only ever sees R2's
file, and that file had no move for an optional collaborator: its fixes were
"add validating constructor", "hoist method checks", "delete re-validation",
"replace nil returns". The Null Object lived in R11 only, and R11 pointed at R2
without R2 pointing back.

R2 gains a design point ("absence is a value too") with the Reporter/Sink shape,
and an "Introduce Null Object" fix move that names the fork: a required
collaborator is rejected in the constructor, an optional one gets a do-nothing
value by default. R2's Go falsifying questions Q2 and Q6 carry the same fork so a
hunter routes each finding to the right move and names both when the code does
not say which the field is. R11's Null Object entry states the Go shape: a no-op
implementation only when an interface already exists, otherwise a value of the
concrete type composing io.Discard, never a new interface for the sake of the
no-op (R6). The changelog records the change under Unreleased; the generated
plugin is regenerated and task check passes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WrQTEgY87C1UdfgejismGr
@buzzdan buzzdan changed the title docs: describe recall_match and the looser cluster default of the generated review graders R2, R11: absence is a value (Introduce Null Object for optional collaborators); eval doc for recall_match Sep 11, 2026
The Null Object guidance added Go tokens (nil, func, a Go code fence, io.Discard)
to two core rule files; lint-core counts them as soft residue and requires the
table to be current.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WrQTEgY87C1UdfgejismGr
Point the harness and baseline docs at the new reference, with its pass rates and
the noise floor measured from two medium passes; 681fdb0 stays as the worked
example of the comparison procedure.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WrQTEgY87C1UdfgejismGr
@buzzdan buzzdan changed the title R2, R11: absence is a value (Introduce Null Object for optional collaborators); eval doc for recall_match go-ldd v2.10.1: R2/R11 absence is a value (Introduce Null Object for optional collaborators); eval docs Sep 11, 2026
@buzzdan
buzzdan marked this pull request as ready for review September 11, 2026 07:44
…ated directory

The changelog's Unreleased entries (the R2/R11 change, the generated plugin
directory, the behavioral evals) become 2.10.1; plugin.json and the root README
follow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WrQTEgY87C1UdfgejismGr
@buzzdan
buzzdan merged commit 20e50b7 into main Sep 11, 2026
1 check passed
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