docs: require PR template and complete-file batches in maintenance flows
Maintenance task commands now fill .github/PULL_REQUEST_TEMPLATE.md section by section instead of inventing their own headings, and follow-up tasks keep the description true for the final HEAD while preserving hand-added content. Raise the anti-slop batch window to 60-120 findings and require each selected file to be finished: remaining findings need an individual specific reason, shared root causes count once, and difficulty alone no longer justifies a skip. A half-fixed file otherwise returns as a second pull request over the same code. Add the maintenance-review command, which reviews every open anti-slop and react-doctor pull request and fixes the findings directly rather than commenting, without merging or approving.
This commit is contained in:
@@ -17,7 +17,7 @@ If the output is not empty, stop immediately and report that the worktree has un
|
|||||||
|
|
||||||
Then run:
|
Then run:
|
||||||
|
|
||||||
`bun run deslop -- next-batch --min-issues 25 --max-issues 60`
|
`bun run deslop -- next-batch --min-issues 60 --max-issues 120`
|
||||||
|
|
||||||
Use the command output as the source of truth for this task scope.
|
Use the command output as the source of truth for this task scope.
|
||||||
|
|
||||||
@@ -282,7 +282,20 @@ Before moving to the next finding, check all four:
|
|||||||
|
|
||||||
Handle findings deliberately instead of skipping them: for parsing work, add the smallest schema that covers the fields actually used; for contract changes, follow call sites with search and update them; for tests, prefer real seams over widened fixtures.
|
Handle findings deliberately instead of skipping them: for parsing work, add the smallest schema that covers the fields actually used; for contract changes, follow call sites with search and update them; for tests, prefer real seams over widened fixtures.
|
||||||
|
|
||||||
Skip a finding only when the fix would require broad architectural changes, unclear behavior changes, or changes outside the selected batch scope. If skipped, mention it in the PR body.
|
## Finish the file
|
||||||
|
|
||||||
|
A selected file is finished when it has zero anti-slop findings for the enabled rules, or when every remaining finding has an individual, specific reason to stay.
|
||||||
|
|
||||||
|
This matters beyond tidiness. A file left half-fixed will be selected again by a later batch, producing a second pull request over the same file, with its own template, its own review, and its own merge. Every finding you defer costs the repository owner a future review cycle. Treat "I fixed the easy half" as an incomplete task, not a delivery.
|
||||||
|
|
||||||
|
So, before you consider a selected file done:
|
||||||
|
|
||||||
|
- Re-run `bun run deslop -- file <path>` and read what is left.
|
||||||
|
- If findings remain, they must be the genuinely hard ones, and you must be able to explain each one specifically. "Requires a broader refactor" is only acceptable when you name the refactor, the module boundary it crosses, and why doing it here would make the change unreviewable.
|
||||||
|
- A group of findings sharing one root cause counts as one reason, and that root cause is usually worth fixing. If eleven findings in a file all come from one untyped parser, fixing that parser is the point of the batch, not a reason to skip.
|
||||||
|
- Leaving more than roughly a quarter of a file's findings behind means you have not finished. Either finish them or explain, per group, why the file was a bad selection in the first place.
|
||||||
|
|
||||||
|
Skip a finding only when the fix would require unclear behavior changes, or a change so large it would stop the pull request from being reviewable. Difficulty alone is not a reason. If skipped, give the specific reason in the PR body under `## Non-goals`.
|
||||||
|
|
||||||
Hard prohibitions. Each of these makes the lint output greener while making the code worse, and each is grounds for rejecting the whole PR:
|
Hard prohibitions. Each of these makes the lint output greener while making the code worse, and each is grounds for rejecting the whole PR:
|
||||||
- Do not disable, downgrade, or ignore anti-slop rules, in configuration or with inline comments.
|
- Do not disable, downgrade, or ignore anti-slop rules, in configuration or with inline comments.
|
||||||
@@ -323,17 +336,20 @@ Validation and delivery:
|
|||||||
- Create exactly one PR with `gh pr create` using the exact printed `PR title`.
|
- Create exactly one PR with `gh pr create` using the exact printed `PR title`.
|
||||||
- After the PR is created, switch back to `main` and pull the latest remote changes again.
|
- After the PR is created, switch back to `main` and pull the latest remote changes again.
|
||||||
|
|
||||||
PR requirements:
|
PR requirements. The repository has a mandatory pull request template at `.github/PULL_REQUEST_TEMPLATE.md`, and `AGENTS.md` requires it to be completed with concrete evidence for the final PR HEAD. Read the template and `CONTRIBUTING.md` before writing the description. Use every template heading, in the template's order, and do not invent replacement headings. Fill each section as follows.
|
||||||
|
|
||||||
- Use the exact printed `PR title`.
|
- Use the exact printed `PR title`.
|
||||||
- Include the `Run ID`, `Batch name`, and `Branch name`.
|
- `## Intent`: state that this is an unattended maintenance batch, name the `Run ID`, `Batch name`, and `Branch name`, and say what behavior changes. When nothing observable changes, say so explicitly rather than leaving it implied.
|
||||||
- Include selected files.
|
- `## Non-goals`: the findings left unfixed in the selected files, findings elsewhere in the repository, and any refactor you deliberately did not start. Give the reason for each, not just the count.
|
||||||
- Include findings fixed according to `check-batch`.
|
- `## Affected surfaces`: the packages, runtimes, user-visible states, and persisted or external contracts the diff reaches. Name every runtime the changed code runs in, and explain why an apparently applicable runtime is unaffected.
|
||||||
- Include remaining findings in selected files.
|
- `## Repository guidance`: fill the table. List the `AGENTS.md` rules you followed, every project skill that matched the change, required skill references you read, and the nearest `README.md` or `DOCUMENTATION.md` for the touched modules. For each row explain why it applies and how the change complies. Do not list filenames without explanation.
|
||||||
- Include validation results for `check-batch` and every package-scoped type-check, lint, and test command you ran, naming the packages.
|
- `## Validation`: fill the table with the exact commands you ran and their results, including `check-batch` and every package-scoped type-check, lint, and test command, naming the packages. Record failures honestly, including pre-existing failures unrelated to this PR, and say which checks you did not run. Do not claim runtime behavior from type-check or lint alone.
|
||||||
- Include a `Manual testing recommendations` section with focused checks for the changed behavior, based on the selected files and actual edits. Type-contract changes can alter runtime behavior at call sites, so name the affected surfaces concretely.
|
- `## Visual evidence`: these PRs usually have no visible change, so explain concretely why the diff cannot affect rendered behavior. If anything user-visible did change, attach before/after evidence for the affected states.
|
||||||
- Include any skipped findings and why.
|
- `## Risks and failure behavior`: cover what breaks if a change is wrong, how to roll it back, and any compatibility, data, performance, or cross-runtime concern. This is where every behavior-affecting decision belongs: each parsing decision you introduced and what now happens on invalid input, each `// SAFETY:` comment you added with the invariant it documents, and any change to whether an object key is present. State "None identified" only with a concrete reason.
|
||||||
- Include any `// SAFETY:` comment you added, with the invariant it documents.
|
|
||||||
- Include every parsing decision you introduced: what schema was added, and what now happens when input fails to parse. Reviewers must be able to see where behavior changed without reading the whole diff.
|
Add a `## Manual testing recommendations` section after the template sections, with focused checks for the changed behavior, based on the selected files and actual edits. Type-contract changes can alter runtime behavior at call sites, so name the affected surfaces concretely.
|
||||||
|
|
||||||
|
Also state, inside `## Intent`, the selected files and how many findings `check-batch` reports as fixed and remaining.
|
||||||
|
|
||||||
Constraints:
|
Constraints:
|
||||||
- Keep the PR small and reviewable.
|
- Keep the PR small and reviewable.
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ Delivery:
|
|||||||
- Reply to addressed review comments using `gh`.
|
- Reply to addressed review comments using `gh`.
|
||||||
- For each specific review comment you addressed, reply with what was changed and the follow-up commit hash.
|
- For each specific review comment you addressed, reply with what was changed and the follow-up commit hash.
|
||||||
- If the feedback was a general PR comment, add one general PR comment summarizing what was addressed, commit hashes, and validation results.
|
- If the feedback was a general PR comment, add one general PR comment summarizing what was addressed, commit hashes, and validation results.
|
||||||
|
- Update the PR description so it stays true for the final HEAD: refresh `## Validation` with the checks you re-ran, and move any new behavior change into `## Risks and failure behavior`. Keep every heading of `.github/PULL_REQUEST_TEMPLATE.md` intact, and preserve content the repository owner added by hand, including screenshots. Read the live description before editing and merge into it rather than overwriting.
|
||||||
- If a comment is intentionally not addressed, reply with a concise reason.
|
- If a comment is intentionally not addressed, reply with a concise reason.
|
||||||
- Do not release the batch while its PR is still open and awaiting review. The claim is what keeps parallel batches off these files.
|
- Do not release the batch while its PR is still open and awaiting review. The claim is what keeps parallel batches off these files.
|
||||||
- Release the batch only once its PR has been merged or closed: `bun run deslop -- release --run <run-id>`.
|
- Release the batch only once its PR has been merged or closed: `bun run deslop -- release --run <run-id>`.
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ If a check fails for a reason unrelated to this PR, verify that claim by checkin
|
|||||||
|
|
||||||
- Commit your fixes with concise messages describing what was actually wrong.
|
- Commit your fixes with concise messages describing what was actually wrong.
|
||||||
- Push to the PR branch. Never force-push.
|
- Push to the PR branch. Never force-push.
|
||||||
- Update the PR description so it describes the final state: what the batch did, what you corrected and why, every behavior change with the decision you made, every remaining skipped finding with its reason, and the exact validation commands you ran with their results.
|
- Update the PR description so it describes the final state, using every heading of `.github/PULL_REQUEST_TEMPLATE.md` in the template's order. `## Intent` covers what the batch did and what you corrected; `## Non-goals` covers what you deliberately left alone; `## Affected surfaces` must reflect the final diff, including files you added beyond the batch scope; `## Repository guidance` must list the rules, skills, and module documentation that applied to your own edits, not only the batch's; `## Validation` must contain the exact commands you re-ran and their results; `## Risks and failure behavior` must carry every behavior change you accepted or introduced. A description that still describes only the batch's original work is incomplete.
|
||||||
- Preserve any content the repository owner added to the description by hand, including screenshots. Read the live description before editing it and merge your changes into it rather than overwriting.
|
- Preserve any content the repository owner added to the description by hand, including screenshots. Read the live description before editing it and merge your changes into it rather than overwriting.
|
||||||
- Add one PR comment summarizing your review pass, so the history shows what was examined and what was changed.
|
- Add one PR comment summarizing your review pass, so the history shows what was examined and what was changed.
|
||||||
- Do not merge, do not close, do not approve, and do not request review.
|
- Do not merge, do not close, do not approve, and do not request review.
|
||||||
|
|||||||
@@ -33,7 +33,10 @@ Workflow:
|
|||||||
- Fix as many diagnostics as practical in the selected files. Your default should be to fix selected diagnostics, not to skip them.
|
- Fix as many diagnostics as practical in the selected files. Your default should be to fix selected diagnostics, not to skip them.
|
||||||
- Prefer direct, behavior-preserving fixes: missing effect cleanup, mutable effect dependencies, accessibility issues with semantic fixes, local performance improvements, Tailwind shorthand replacements, component extraction when the boundary is clear, dead-code removal after verifying no references, and reducer or derived-state cleanup when the state relationship is local and clear.
|
- Prefer direct, behavior-preserving fixes: missing effect cleanup, mutable effect dependencies, accessibility issues with semantic fixes, local performance improvements, Tailwind shorthand replacements, component extraction when the boundary is clear, dead-code removal after verifying no references, and reducer or derived-state cleanup when the state relationship is local and clear.
|
||||||
- Handle larger diagnostics deliberately instead of skipping them: for component splits, extract the smallest coherent subcomponent that reduces the diagnostic while preserving props/state flow; for dead code, verify references with search before deleting exports, types, or files; for state architecture issues, prefer the smallest local reducer or derived-state simplification that preserves behavior; for render-function extraction, extract only stable render helpers that do not depend on large implicit closure state, or pass explicit props; for behavior-sensitive diagnostics, read the surrounding code first and preserve existing runtime behavior.
|
- Handle larger diagnostics deliberately instead of skipping them: for component splits, extract the smallest coherent subcomponent that reduces the diagnostic while preserving props/state flow; for dead code, verify references with search before deleting exports, types, or files; for state architecture issues, prefer the smallest local reducer or derived-state simplification that preserves behavior; for render-function extraction, extract only stable render helpers that do not depend on large implicit closure state, or pass explicit props; for behavior-sensitive diagnostics, read the surrounding code first and preserve existing runtime behavior.
|
||||||
- Skip a diagnostic only when the fix would require broad architectural changes, unclear behavior changes, or changes outside the selected batch scope. If skipped, mention it in the PR body.
|
- Finish each selected file. A file is finished when it has zero React Doctor diagnostics, or when every remaining diagnostic has an individual, specific reason to stay. A half-fixed file will be selected again later and cost a second pull request, a second review, and a second merge over the same code.
|
||||||
|
- Before considering a file done, re-run `bun run doctor -- file <path>` and read what is left. Leaving more than roughly a quarter of a file's diagnostics behind means you have not finished.
|
||||||
|
- A group of diagnostics sharing one root cause counts as one reason, and that root cause is usually worth fixing rather than deferring.
|
||||||
|
- Skip a diagnostic only when the fix would require unclear behavior changes, or a change so large it would stop the pull request from being reviewable. Difficulty alone is not a reason. If skipped, give the specific reason in the PR body under `## Non-goals`.
|
||||||
- Do not suppress React Doctor diagnostics unless there is a clear false positive.
|
- Do not suppress React Doctor diagnostics unless there is a clear false positive.
|
||||||
- If a listed diagnostic requires changes outside the selected files, make only the minimal required supporting change. Do not expand the cleanup scope.
|
- If a listed diagnostic requires changes outside the selected files, make only the minimal required supporting change. Do not expand the cleanup scope.
|
||||||
|
|
||||||
@@ -59,15 +62,20 @@ Validation and delivery:
|
|||||||
- Create exactly one PR with `gh pr create` using the exact printed `PR title`.
|
- Create exactly one PR with `gh pr create` using the exact printed `PR title`.
|
||||||
- After the PR is created, switch back to `main` and pull the latest remote changes again.
|
- After the PR is created, switch back to `main` and pull the latest remote changes again.
|
||||||
|
|
||||||
PR requirements:
|
PR requirements. The repository has a mandatory pull request template at `.github/PULL_REQUEST_TEMPLATE.md`, and `AGENTS.md` requires it to be completed with concrete evidence for the final PR HEAD. Read the template and `CONTRIBUTING.md` before writing the description. Use every template heading, in the template's order, and do not invent replacement headings. Fill each section as follows.
|
||||||
|
|
||||||
- Use the exact printed `PR title`.
|
- Use the exact printed `PR title`.
|
||||||
- Include the `Run ID`, `Batch name`, and `Branch name`.
|
- `## Intent`: state that this is an unattended maintenance batch, name the `Run ID`, `Batch name`, and `Branch name`, and say what behavior changes. When nothing observable changes, say so explicitly rather than leaving it implied.
|
||||||
- Include selected files.
|
- `## Non-goals`: the diagnostics left unfixed in the selected files, diagnostics elsewhere in the repository, and any refactor you deliberately did not start. Give the reason for each, not just the count.
|
||||||
- Include diagnostics fixed according to `check-batch`.
|
- `## Affected surfaces`: the packages, runtimes, user-visible states, and persisted or external contracts the diff reaches. Name every runtime the changed code runs in, and explain why an apparently applicable runtime is unaffected.
|
||||||
- Include remaining diagnostics in selected files.
|
- `## Repository guidance`: fill the table. List the `AGENTS.md` rules you followed, every project skill that matched the change, required skill references you read, and the nearest `README.md` or `DOCUMENTATION.md` for the touched modules. For each row explain why it applies and how the change complies. Do not list filenames without explanation.
|
||||||
- Include validation results for every package-scoped type-check, lint, and test command you ran, naming the packages.
|
- `## Validation`: fill the table with the exact commands you ran and their results, including `check-batch` and every package-scoped type-check, lint, and test command, naming the packages. Record failures honestly, including pre-existing failures unrelated to this PR, and say which checks you did not run. Do not claim runtime behavior from type-check or lint alone.
|
||||||
- Include a `Manual testing recommendations` section with focused checks for the changed behavior. Base it on the selected files and actual edits, for example checking affected dropdowns, keyboard navigation, model/agent selection, settings controls, or mobile/desktop variants.
|
- `## Visual evidence`: these PRs usually have no visible change, so explain concretely why the diff cannot affect rendered behavior. If anything user-visible did change, attach before/after evidence for the affected states.
|
||||||
- Include any skipped diagnostics and why.
|
- `## Risks and failure behavior`: cover what breaks if a change is wrong, how to roll it back, and any compatibility, data, performance, or cross-runtime concern. State "None identified" only with a concrete reason.
|
||||||
|
|
||||||
|
Add a `## Manual testing recommendations` section after the template sections, with focused checks for the changed behavior. Base it on the selected files and actual edits, for example checking affected dropdowns, keyboard navigation, model or agent selection, settings controls, and mobile or desktop variants.
|
||||||
|
|
||||||
|
Also state, inside `## Intent`, the selected files and how many diagnostics `check-batch` reports as fixed and remaining.
|
||||||
|
|
||||||
Constraints:
|
Constraints:
|
||||||
- Keep the PR small and reviewable.
|
- Keep the PR small and reviewable.
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ Delivery:
|
|||||||
- Reply to addressed review comments using `gh`.
|
- Reply to addressed review comments using `gh`.
|
||||||
- For each specific review comment you addressed, reply with what was changed and the follow-up commit hash.
|
- For each specific review comment you addressed, reply with what was changed and the follow-up commit hash.
|
||||||
- If the feedback was a general PR comment, add one general PR comment summarizing what was addressed, commit hashes, and validation results.
|
- If the feedback was a general PR comment, add one general PR comment summarizing what was addressed, commit hashes, and validation results.
|
||||||
|
- Update the PR description so it stays true for the final HEAD: refresh `## Validation` with the checks you re-ran, and move any new behavior change into `## Risks and failure behavior`. Keep every heading of `.github/PULL_REQUEST_TEMPLATE.md` intact, and preserve content the repository owner added by hand, including screenshots. Read the live description before editing and merge into it rather than overwriting.
|
||||||
- If a comment is intentionally not addressed, reply with a concise reason.
|
- If a comment is intentionally not addressed, reply with a concise reason.
|
||||||
- Do not release the batch while its PR is still open and awaiting review. The claim is what keeps parallel batches off these files.
|
- Do not release the batch while its PR is still open and awaiting review. The claim is what keeps parallel batches off these files.
|
||||||
- Release the batch only once its PR has been merged or closed: `bun run doctor -- release --run <run-id>`.
|
- Release the batch only once its PR has been merged or closed: `bun run doctor -- release --run <run-id>`.
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const NOISY_RULES = new Set(["no-runtime-typeof", "require-safety-comment-for-ty
|
|||||||
function usage(exitCode = 0) {
|
function usage(exitCode = 0) {
|
||||||
const out = exitCode === 0 ? console.log : console.error;
|
const out = exitCode === 0 ? console.log : console.error;
|
||||||
out(`Usage:
|
out(`Usage:
|
||||||
bun run deslop -- next-batch [--min-issues 25] [--max-issues 60] [--max-files 4]
|
bun run deslop -- next-batch [--min-issues 60] [--max-issues 120] [--max-files 4]
|
||||||
[--max-active ${DEFAULT_MAX_ACTIVE}] [--claim-ttl ${DEFAULT_CLAIM_TTL_DAYS}] [--include-noisy]
|
[--max-active ${DEFAULT_MAX_ACTIVE}] [--claim-ttl ${DEFAULT_CLAIM_TTL_DAYS}] [--include-noisy]
|
||||||
bun run deslop -- check-batch --run <run-id>
|
bun run deslop -- check-batch --run <run-id>
|
||||||
bun run deslop -- active [--claim-ttl ${DEFAULT_CLAIM_TTL_DAYS}]
|
bun run deslop -- active [--claim-ttl ${DEFAULT_CLAIM_TTL_DAYS}]
|
||||||
@@ -62,7 +62,7 @@ pipeline. Claims are shared across clones by default. A batch stays active until
|
|||||||
it is released.
|
it is released.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
bun run deslop -- next-batch --min-issues 25 --max-issues 60
|
bun run deslop -- next-batch --min-issues 60 --max-issues 120
|
||||||
bun run deslop -- file packages/ui/src/lib/settings/metadata.ts
|
bun run deslop -- file packages/ui/src/lib/settings/metadata.ts
|
||||||
bun run deslop -- check-batch --run 2026-08-16T10-12-44Z
|
bun run deslop -- check-batch --run 2026-08-16T10-12-44Z
|
||||||
bun run deslop -- release --run 2026-08-16T10-12-44Z`);
|
bun run deslop -- release --run 2026-08-16T10-12-44Z`);
|
||||||
@@ -311,8 +311,8 @@ function printReportHeader(report) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function commandNextBatch(args) {
|
function commandNextBatch(args) {
|
||||||
const minIssues = asPositiveInt(args["min-issues"], 25, "min-issues");
|
const minIssues = asPositiveInt(args["min-issues"], 60, "min-issues");
|
||||||
const maxIssues = asPositiveInt(args["max-issues"], 60, "max-issues");
|
const maxIssues = asPositiveInt(args["max-issues"], 120, "max-issues");
|
||||||
const maxFiles = asPositiveInt(args["max-files"], 4, "max-files");
|
const maxFiles = asPositiveInt(args["max-files"], 4, "max-files");
|
||||||
if (minIssues > maxIssues) throw new Error("--min-issues cannot be greater than --max-issues.");
|
if (minIssues > maxIssues) throw new Error("--min-issues cannot be greater than --max-issues.");
|
||||||
const maxActive = asPositiveInt(args["max-active"], DEFAULT_MAX_ACTIVE, "max-active");
|
const maxActive = asPositiveInt(args["max-active"], DEFAULT_MAX_ACTIVE, "max-active");
|
||||||
|
|||||||
Reference in New Issue
Block a user