Repository navigation
refactor(software-writer)!: less error surface, more agent judgment - #60
Merged
Merged
Conversation
SKILL.md now owns the numeric style targets as the inline default of `docs.style`, and the pointer-bullet rules in Step 3. writing-style.md drops the targets, the Flesch-Kincaid sentence, the numbers section and the rejections table. pointer-file.md drops the bullet rules SKILL.md owns, its WRONG/CORRECT pairs and its rationalizations table. surface-shapes.md reduces the Limitations example, the C4 floor and the changelog discipline to one line each.
Step 6 has one preservation value: a comment that matches `comments.preserve_patterns` and existed before the edit is skipped, with no consistency check, no probe, no classification and no edit. Step 5 checks the line only against the footguns a project registers in `code.footgun_additions` and passes when none are registered, so the stack references drop their footgun catalogs and keep only the documentation sources with their query form and the doc-comment convention. The caller-fallback rule in Step 3 is cut to its two rules plus the published-surface sentence, and the Step 6 workaround clauses are gone. comments.md and primitives.md lose their worked examples, banned-pattern blocks and the passages that restated Step 6. BREAKING CHANGE: `comments.exemption_markers` is retired. Move its markers into `comments.preserve_patterns`, which now leaves a matching pre-existing comment untouched.
Step 1 no longer checks a framework version pin, and each framework reference holds one line naming its table construct, so the pins, isolation sections, doubles, helpers and error-path idioms are gone from the twelve framework files. SKILL.md drops the DAMP three-occurrence rule, the naming-order rule and the over-mocking rationale, and points at the reference that owns each moved rule: the arrange-data sources in data.md, the CLI-output rules in shape.md, the leak vectors and hermetic rule in independence.md, and the guard-clause procedure in behavior.md. The four universal references lose their worked examples, the DAMP thresholds, the fixture-scope and flag/skip tables, and the per-framework non-deterministic-call tables, and the load sentences list only what each reference keeps.
The bash definition patterns searched only `*.sh` and `*.bash`, so `.bats` files and extensionless scripts with a `sh` or `bash` shebang were never enumerated, and the TypeScript patterns skipped `.mts` and `.cts`. Step 2 now detects bash and Python from shebang lines as well as extensions, and the bash and Python tool references build the file list from `git ls-files`, with one exclude pathspec per `sweep.exclude` entry and only regular files passed to the first-line test, because BSD awk aborts the run on a listed file that is missing from the working tree. A Path scope covers the tracked files under the named paths, and the report names the untracked ones as not swept. The tool references keep their Run, Never-pass and isolated-form lines plus one findings line per tool naming which entries are dead-code findings. The Test handling and Limits lines are gone, and the PHPStan core section merges into the shipmonk section.
EXTENSION.md drops the `comments.exemption_markers` row, states that `comments.preserve_patterns` skips a matching pre-existing comment in Step 6, and names `code.footgun_additions` as the only footgun source, since the stack references no longer carry a footgun catalog or a doc-tool query table. The setup skill asks only for preserved markers or patterns. The READMEs and AGENTS.md describe only content the skill files now hold. The `[Unreleased]` changelog section states the net change against 2.4.0. Entries for content this change removes are deleted, and the exemption-marker retirement carries its migration step.
The Go, TypeScript and PHP definition patterns still walked untracked files and ignored `sweep.exclude`, so they now run over the same tracked-file list as bash and Python. Every stack applies a directory entry as `':(exclude,glob)**/<entry>/**'`, which also matches nested directories, and the generated-header entry keeps its files out of the ledger and out of the tool evidence. A tool finding outside the listed files no longer becomes a row, an executable Python script gets no `file` row, and the report names the untracked files a Path scope leaves unswept. The Run lines regain the vulture configuration, deadcode library and Psalm `findUnusedCode` notes. The writing-code Step 4 diamond names removed references, replaced implementations and changed signatures, which the old skip sentence covered. The writing-docs number rule applies outside the `docs.style` default again, and the companion-file rule names `AGENTS.md` as the only owner. writing-tests checks every preservation indicator, and data.md no longer contradicts its committed-fixture source.
writing-code Step 2 consults a stack source "with the query form it gives", but the restored TypeScript, Python and PHP sources named no place to read. Each now names the file, the field or the page to open at the pinned version, and the TypeScript implementation source defers to the package's `main` or `exports` field instead of naming an output directory. A Path sweep no longer reports untracked files inside `sweep.exclude` paths as not swept.
Step 6 skipped a pre-existing comment matching `comments.preserve_patterns` with no edit at all. That overrode the rule to delete a why-comment together with the code it describes, and left the comment above code the edit had removed. The skip now keeps such a comment unchanged unless the edit deletes the code it describes.
The reduction cut the Step 6 clause that a workaround whose trigger is gone, or whose removal criterion a run shows met, is neither a contradiction nor a refuted claim. Without it, "a claim a run refutes is corrected" reads as an instruction to rewrite or drop such a workaround. The clause and its two digraph labels are back.
The `sweep.exclude` row in EXTENSION.md repeated the literal git exclude pathspecs that each sweeping-dead-code tool reference states next to its file-list command. No sweep step reads EXTENSION.md, so the row now states what an entry excludes, and the pathspec form stays in the tool references, where the command uses it.
The Claude manifest described writing-tests as a workflow "with stack-specific idioms". Each framework reference now holds a single table-construct line, so the description named content the skill no longer has.
The sweep's file-list commands gave wrong results on real repositories. macOS awk aborts on a first line that is not valid UTF-8, so the shebang filter now runs under `LC_ALL=C`. grep read a tracked file named `-n.sh` as an option, so every definition search now ends with `--`. The Python tool lines passed an undefined `<paths>` that skipped extensionless scripts. They now take the listed files. The ShellCheck findings line drops its per-code glosses (#56). Duplicate statements are removed: the untracked-files clause in sweep report item 1, a repeated pointer sentence in writing-tests Step 6, the non-deterministic-inputs section of `independence.md`, and the restated assertion-scope line in `behavior.md`. `comments.md` no longer deletes a comment that is only a pointer, which contradicted the rule that keeps a bare spec or ticket citation.
The ShellCheck, vulture and ruff Run lines passed the listed files through `xargs -0` with no `--`, so a tracked file named `-n.sh` or `-n.py` was read as an option and the tool exited without findings. They now end their options with `--`. pylint rejects `--` and reads a dash-named file the same way, so its Run line passes each listed file with a `./` prefix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #48
Fixes #51
Fixes #55
Fixes #56
Fixes #57
Supersedes #59.
Summary
The four
software-writerskills keep their workflow steps and gates. Their text is cut to what one content rule admits. The behavior changes are listed under Changes.comments.exemption_markersis retired; this is the one breaking change.Why
This PR does not aim to reduce the text an agent loads. It has two goals: a smaller error surface, and more room for the implementing agent's own judgment.
Error surface. Each sentence in a skill file can be wrong, go out of date, or disagree with another copy of the same rule. #49 and #54 fixed defects by adding detail, and #51 then reported wording defects in lines #49 added. #55 exists because
comments.preserve_patternsandcomments.exemption_markersoverlapped; this PR retirescomments.exemption_markers. Version pins, footgun catalogs and per-framework API facts are the content most likely to go stale, and they are removed. Rules that writing-tests and writing-docs restated betweenSKILL.mdand their references now live in one file.Room for judgment. Footgun catalogs, version pins, worked examples and fixed thresholds such as the DAMP limits told the agent what to do in cases it can decide from the project's code and installed versions. They are removed. Step 5 of writing-code checks only the footguns a project registers in
code.footgun_additions, and each writing-tests framework reference keeps one line naming its table construct. The workflow steps and gates stay, and they remain the main constraint on the agent.The test for each block was "Is it relevant to a step, and what happens without it?", not "Is it true?". A true block that no step needs was cut. A block stayed when a step cannot run without it, when removing it would lead the agent to a wrong result, or when it prevents a failure recorded in real use. For that reason each dead-code tool reference keeps one findings line: the sweep turns an unmatched finding in a listed file into a ledger row.
sweeping-dead-code moves partly the other way. Fixing #48 and #57 needed a tracked-file list per stack, so its five tool references gained literal
git ls-filescommands. They are new prescription and new text that can be wrong.Neither goal is measured. No benchmark backs this PR.
#59 fixes #48 in the bash reference text that this PR rewrites. This PR carries the same file set, so #59 is superseded.
Changes
writing-code
comments.preserve_patternsis the only preservation value. Step 6 skips a matching comment that existed before the edit entirely: no consistency check, no probe, no classification, no edit. Such a comment is deleted only together with the code it describes.comments.exemption_markersis no longer read.code.footgun_additions.references/comments.mdkeeps the classification table, the load-bearing list and the comment shapes; examples and restatements of Step 6 are gone.writing-tests
independence.md,shape.md,behavior.md);SKILL.mdpoints at the owner.behavior.md.writing-docs
docs.stylestates its default inline: sentences of at most 25 words averaging 12-17, paragraphs of at most 4 sentences, predominantly active voice. The rule on keeping numbers sits outside the default, so a project that overridesdocs.stylekeeps it.SKILL.mdowns the pointer-bullet rules;pointer-file.mdno longer restates them.pointer-file.mdkeeps the companion-file rule (AGENTS.mdowns the content,CLAUDE.mdis a one-line include), andSKILL.mdpoints to it.sweeping-dead-code
.sh,.bashand.batsfiles and from extensionless files with ashorbashshebang (software-writer: sweeping-dead-code bash definition search skips .bats files and extensionless shell scripts #48). Python covers extensionless files with apythonshebang, and TypeScript covers.mtsand.cts(software-writer: sweeping-dead-code skips .mts/.cts files and extensionless Python scripts #57).git ls-files. A directorysweep.excludeentry applies as':(exclude,glob)**/<entry>/**', which matches the directory at any depth. An entry that is not a path, such as the generated-header default, excludes its files from the whole sweep.filerow.Extension contract, setup skill and docs
EXTENSION.mddrops thecomments.exemption_markersrow and statescode.footgun_additionsas the only footgun source. Every named value a skill cites has a row, and every row is cited.software-writer-extension-setupasks only forcomments.preserve_patterns.AGENTS.md, the root README row and the Claudeplugin.jsondescription name only behavior the reduced text has. No version field changes.[Unreleased]section states the net change against 2.4.0 and a migration note.Breaking change
A project that assigned
comments.exemption_markersin awriting-codeextension file moves those markers intocomments.preserve_patterns. The old name is ignored without a warning, and the setup skill's re-sync mode does not flag it.Left open
inject-extension.shreports a non-regular extension file as "not readable") and software-writer-extension-setup: verify Claude Code delivery requirements #40 (verify the Claude Code delivery requirements of the setup skill) concern the hooks and the setup skill, not skill text..batsfiles, unless production code sources or runs it. This is the intended definition for helper scripts beside the tests. An entry script such asinstall.shbesideinstall.batsis misclassified by it; that case belongs with software-writer: sweeping-dead-code reports helpers defined in test files as test-only #58.#[DataProvider]without noting that PHPUnit 9 uses the@dataProviderannotation (software-writer: writing-tests PHPUnit reference names only the #[DataProvider] attribute #61).