Skip to content

refactor(software-writer)!: less error surface, more agent judgment - #60

Merged
SpiGAndromeda merged 13 commits into
mainfrom
refactor/software-writer-reduce-content
Nov 5, 2026
Merged

SpiGAndromeda merged 13 commits into
mainfrom
refactor/software-writer-reduce-content

Conversation

@SpiGAndromeda

@SpiGAndromeda SpiGAndromeda commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #48
Fixes #51
Fixes #55
Fixes #56
Fixes #57

Supersedes #59.

Summary

The four software-writer skills 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_markers is 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_patterns and comments.exemption_markers overlapped; this PR retires comments.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 between SKILL.md and 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-files commands. 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_patterns is 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_markers is no longer read.
  • Step 5 is now "Footgun check" and reads only code.footgun_additions.
  • Step 3's caller-fallback rule is two sentences plus the report for a fallback on a published surface.
  • The diamond before Step 4 asks whether the edit adds a dependency or export, removes a call or reference, replaces an implementation, or changes a signature. It replaces the Step 4 skip sentence.
  • references/comments.md keeps the classification table, the load-bearing list and the comment shapes; examples and restatements of Step 6 are gone.
  • Each stack reference holds its documentation sources with a query form, and one doc-comment convention line.

writing-tests

  • The Step 1 version-pin check is gone, together with the pins in the framework references.
  • The leak vectors, the CLI-output rules and the guard-clause procedure each live in one reference (independence.md, shape.md, behavior.md); SKILL.md points at the owner.
  • Step 6 runs the preservation check against the indicator table in behavior.md.
  • Each of the 12 framework references is one table-construct line.

writing-docs

  • docs.style states 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 overrides docs.style keeps it.
  • SKILL.md owns the pointer-bullet rules; pointer-file.md no longer restates them. pointer-file.md keeps the companion-file rule (AGENTS.md owns the content, CLAUDE.md is a one-line include), and SKILL.md points to it.

sweeping-dead-code

Extension contract, setup skill and docs

  • EXTENSION.md drops the comments.exemption_markers row and states code.footgun_additions as the only footgun source. Every named value a skill cites has a row, and every row is cited.
  • software-writer-extension-setup asks only for comments.preserve_patterns.
  • The plugin README, AGENTS.md, the root README row and the Claude plugin.json description name only behavior the reduced text has. No version field changes.
  • The CHANGELOG [Unreleased] section states the net change against 2.4.0 and a migration note.

Breaking change

A project that assigned comments.exemption_markers in a writing-code extension file moves those markers into comments.preserve_patterns. The old name is ignored without a warning, and the setup skill's re-sync mode does not flag it.

Left open

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.
@SpiGAndromeda SpiGAndromeda changed the title refactor(software-writer)!: reduce skill content to what a step consumes refactor(software-writer)!: less error surface, more agent judgment Nov 5, 2026
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.
@SpiGAndromeda
SpiGAndromeda merged commit 4a79308 into main Nov 5, 2026
8 checks passed
@SpiGAndromeda
SpiGAndromeda deleted the refactor/software-writer-reduce-content branch November 5, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment