docs: sequence a behavior-changing case - #65
Conversation
Two instructions in it could not be followed as written. The title rule asked for 50 characters or fewer, and the squash subject is the title with ` (#N)` appended -- this repository allows squash and nothing else, with `squash_merge_commit_title: COMMIT_OR_PR_TITLE`. So a contributor who used the whole budget landed a longer subject on `main`. Fourteen subjects there exceed 50 and six of them are inside it before the number, which is the failure this describes. `gitlint` holds the bound on every local commit and never sees a merged subject, so the template is the only place it can be kept. The answer-key note points at both tier readmes for how to produce one. Only the CLI tier's says: generate by running the tool, never by hand. The transform tier's readme said nothing about it, and that is the half with no regeneration command at all, so it is where hand-writing a key is likeliest and where the rule was missing. The rule now sits in that readme too, which makes the pointer true rather than narrowing it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The template now says the squash subject is the title with the number appended, and asks for 50 characters or fewer once it is on. This file still asked for 50 on the title alone and said to write pull request titles the same way as commit subjects, so a contributor following it lands an over-limit subject -- the failure the template change exists to remove. The code span drops the leading space the template uses, because markdownlint MD038 rejects it outside an HTML comment. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The transform tier tells you to produce the key by running the tool, and the template asks a behavior-changing case to have failed first. Read in order those cannot both hold: a key generated from the current tool equals current behavior, so the case passes by construction. The order is what differs, not the rule. Write the intended key, watch it fail, change both implementations, then run the tool and confirm it agrees. What ships is still the tool's output. Editing a key to make a test pass moves the key to meet the implementation; this moves the implementation to meet the key. Both docs carry the rule, so both say it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can commit Qodo's fix in one click with committable suggestions (GitHub & GitLab) |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #65 +/- ##
=======================================
Coverage 87.40% 87.40%
=======================================
Files 3 3
Lines 691 691
=======================================
Hits 604 604
Misses 87 87 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
PR Summary by QodoClarify corpus workflow for behavior-changing cases
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
…behavior-changes # Conflicts: # .github/pull_request_template.md # CONTRIBUTING.md # corpus/README.md
The rule reads the same in fewer words. "runs that in the other order" becomes "reverses that order", the tool the case first fails against is left to the sequence rather than named, and the gerund pair closing the CONTRIBUTING sentence becomes a plain clause. Two clauses go entirely: that the hand-written key exists only long enough to fail, which the procedure above it already shows, and the "that is the opposite of" frame in front of the distinction, which the distinction states on its own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The changes are documentation-only and consistently reconcile previously conflicting contributor instructions without introducing code or harness risk.
Pull request overview
This PR updates contributor documentation to clarify the correct sequence for writing behavior-changing transform-tier corpus cases (specifically, cases that change what gets joined) so “write failing case first” and “generate keys from tool output” can both be followed coherently.
Changes:
- Clarifies that join-changing cases should be drafted by writing the intended
expected.mdfirst, confirming the case fails, then updating implementations and regenerating to verify the tool matches the intended output. - Aligns this sequencing guidance across both
corpus/README.mdandCONTRIBUTING.mdto avoid contradictory instructions.
File summaries
| File | Description |
|---|---|
| corpus/README.md | Adds an explicit exception/sequence for join-changing cases to reconcile “generate expected output” with “fail-first” discipline. |
| CONTRIBUTING.md | Extends the same sequencing guidance into the contributing workflow narrative so contributor-facing docs remain consistent. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
What changes, and why
The transform tier's two rules cannot both be followed in the order they are given.
corpus/README.mdsays to produceexpected.mdby running the tool overinput.mdrather than by writing it out, and.github/pull_request_template.md:17asks a case that changes what gets joined to have been "written first and failed first". A key generated from the current tool equals current behavior, so a case built that way passes by construction and pins the behavior the change is meant to replace.The contradiction is older than the wording that exposed it.
CONTRIBUTING.md:31("write the failing case, watch it fail, then implement") andCONTRIBUTING.md:35("produce those two files by running the tool and reading the diff") have sat four lines apart onmaincarrying it. #47 mirrored the answer-key rule into the tier that lacked it, which is what made the gap visible in a second place.What differs is the order, not the rule. For a case that changes what gets joined: write the intended key, watch it fail against the current tool, change both implementations, then run the tool again and confirm its output is what you wrote. What ships is still the tool's output, and the hand-written key exists only long enough to fail. That is the opposite of editing a key to make a test pass — there the key moves to meet the implementation, here the implementation moves to meet the key, and the regeneration is what checks that the intent and the implementation agree.
Both documents carry the rule, so both state the sequence.
This is stacked on #47 because the
corpus/README.mdsentence it qualifies is added there. GitHub retargets this tomainwhen #47 merges.Corpus
The corpus is the specification, and both implementations answer to it. Tick what applies.
corpus/pins the new behavior. The case was written first and failed first.Documentation of how to write a case. No case, key or harness changes.
Checks
make checkpasses, ormake testdoes and this touches no Rust.make tidyis green, andunwrap-markdown-prose-py --fail-on-changeleaves both files alone. Documentation only, no Rust.🤖 Generated with Claude Code