aidd-lint: tier-2 prose-smell charter #107

Closed
opened 2026-07-23 11:31:28 +00:00 by jared · 2 comments
Owner

Context

Tier 2 of the aidd-lint system (see mapping ticket): prose smells with no structural signature that deterministic cops can reach. Closed catalog of three, each with name / definition / exemplar / prescribed fix:

  1. rationale-in-the-imperative-position -- a short step that explains why instead of saying do. (Borderline exemplar kept in mine-lints step 1: "so it isn't anchored to what cops already catch" -- retained because it changes execution order; the charter entry must include this counter-example.)
  2. misplaced-pre-emption -- a tool-failure warning not adjacent to the tool call it guards; moved to a reference file it is read only after the failure it exists to prevent. Exemplar: the root-.rubocop.yml and tea-hang warnings deliberately kept inline at their steps in c6a4177.
  3. duplicated-authority -- prose restating what a template, reference file, or Ruby gate already enforces (cross-file; the deterministic duplication cop only sees within one file). Exemplar: pre-c6a4177 step 4 restating the ticket template's consistency check.

Judge: single-shot haiku/sonnet pass over a changed file, charter file supplied verbatim in the prompt, output in the same offense format as the deterministic cops. The judge may NOT invent smells outside the catalog. Also serves as the anti-gaming backstop for step-bulk (fat step split into thin steps that are still gate logic).

Acceptance criteria

  • Charter doc (3 entries, counter-examples included) living beside the linter.
  • Judge prompt + wrapper producing file:line: <smell-name>: <one-line finding> lines.
  • Closed-catalog enforcement: output naming a smell not in the charter is discarded and logged.
  • Run against pre-c6a4177 mine-lints/SKILL.md (git show 5ea6bbf) flags at least 2 of the 3 smells; against current HEAD is clean or advisory-only.

Non-goals

  • No autofix. Advisory severity only.
  • Not a general style critique -- the catalog is the whole scope.

Verify

The two-commit A/B in acceptance criteria, plus one run on a file outside os-sdlc to confirm no os-sdlc-specific assumptions.

## Context Tier 2 of the aidd-lint system (see mapping ticket): prose smells with no structural signature that deterministic cops can reach. Closed catalog of three, each with name / definition / exemplar / prescribed fix: 1. **rationale-in-the-imperative-position** -- a short step that explains why instead of saying do. (Borderline exemplar kept in mine-lints step 1: "so it isn't anchored to what cops already catch" -- retained because it changes execution order; the charter entry must include this counter-example.) 2. **misplaced-pre-emption** -- a tool-failure warning not adjacent to the tool call it guards; moved to a reference file it is read only after the failure it exists to prevent. Exemplar: the root-.rubocop.yml and tea-hang warnings deliberately kept inline at their steps in c6a4177. 3. **duplicated-authority** -- prose restating what a template, reference file, or Ruby gate already enforces (cross-file; the deterministic duplication cop only sees within one file). Exemplar: pre-c6a4177 step 4 restating the ticket template's consistency check. Judge: single-shot haiku/sonnet pass over a changed file, charter file supplied verbatim in the prompt, output in the same offense format as the deterministic cops. The judge may NOT invent smells outside the catalog. Also serves as the anti-gaming backstop for step-bulk (fat step split into thin steps that are still gate logic). ## Acceptance criteria - Charter doc (3 entries, counter-examples included) living beside the linter. - Judge prompt + wrapper producing `file:line: <smell-name>: <one-line finding>` lines. - Closed-catalog enforcement: output naming a smell not in the charter is discarded and logged. - Run against pre-c6a4177 `mine-lints/SKILL.md` (git show 5ea6bbf) flags at least 2 of the 3 smells; against current HEAD is clean or advisory-only. ## Non-goals - No autofix. Advisory severity only. - Not a general style critique -- the catalog is the whole scope. ## Verify The two-commit A/B in acceptance criteria, plus one run on a file outside os-sdlc to confirm no os-sdlc-specific assumptions.
Author
Owner

Implemented on branch aidd-lint/tier-2 (uncommitted, pending review). Tier2::Judge behind bin/aidd-lint --tier2, charter at references/tier2-charter.md, judge prompt asset, shared PathReferenceScanner (dead-reference cop refactored onto it), injectable claude -p invoker with visible invoker_failed + logged catalog/range discards, single-run eval harness. ADR-0060.

Acceptance amendment (evidence-driven): a catalog-validation mining pass over 3 files unrelated to c6a4177 confirmed only duplicated-authority recurs (at 3 scales: cross-plugin, within-file paraphrase, frontmatter-vs-body); rationale-in-the-imperative and misplaced-pre-emption found no clean instances and are marked status: provisional in the charter. Live haiku A/B: pre-c6a4177 fixture flagged duplicated-authority on the template consistency-check restatement (the ticket's exemplar); HEAD clean on run 1; closed catalog held in all runs; pinned counter-example never flagged. Original >=2-of-3 bar therefore amended to 1-of-3 — recorded in ADR-0060 and the charter. Cross-file authority resolution shipped (validation showed it's where the confirmed smell lives); unreferenced-Ruby-gate blind spot recorded as accepted limit.

Open: queue-drain wiring (nothing consumes the Tier-2 queue yet; --tier2 is manual). Full suite 151 runs / 316 assertions green incl. #108's tests + opus review fixes.

Implemented on branch aidd-lint/tier-2 (uncommitted, pending review). Tier2::Judge behind `bin/aidd-lint --tier2`, charter at references/tier2-charter.md, judge prompt asset, shared PathReferenceScanner (dead-reference cop refactored onto it), injectable claude -p invoker with visible invoker_failed + logged catalog/range discards, single-run eval harness. ADR-0060. Acceptance amendment (evidence-driven): a catalog-validation mining pass over 3 files unrelated to c6a4177 confirmed only duplicated-authority recurs (at 3 scales: cross-plugin, within-file paraphrase, frontmatter-vs-body); rationale-in-the-imperative and misplaced-pre-emption found no clean instances and are marked status: provisional in the charter. Live haiku A/B: pre-c6a4177 fixture flagged duplicated-authority on the template consistency-check restatement (the ticket's exemplar); HEAD clean on run 1; closed catalog held in all runs; pinned counter-example never flagged. Original >=2-of-3 bar therefore amended to 1-of-3 — recorded in ADR-0060 and the charter. Cross-file authority resolution shipped (validation showed it's where the confirmed smell lives); unreferenced-Ruby-gate blind spot recorded as accepted limit. Open: queue-drain wiring (nothing consumes the Tier-2 queue yet; --tier2 is manual). Full suite 151 runs / 316 assertions green incl. #108's tests + opus review fixes.
Author
Owner

Reviewed and merged to main in 41240a8 (2026-07-23).

Reviewed and merged to main in 41240a8 (2026-07-23).
jared closed this issue 2026-07-23 17:49:49 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#107
No description provided.