Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,48 @@

## Unreleased

- No unreleased changes.
Theme: make installed agents write high-quality code by sharpening do-it's
write-before → write-during → write-after quality spine, and compress the two
heaviest skills so the agent actually reads them. The shared "write less"
primitive is a single decision ladder, reused — not restated — across skills.

### Added

- `do-it-router` § Restraint now carries **the decision ladder** (does it need to
exist? → stdlib → native → existing dependency → one line → minimal custom),
with guardrails it never cuts. It is the shared anti-over-engineering primitive
that grill, brainstorm, the write-time lint, and the YAGNI review lens all
reference instead of each defining their own.
- `do-it-review-loop` gains a **YAGNI lens** (`code-quality-cleaner`), default at
Heavy when a diff adds a new abstraction/export/dependency. It emits one-line
findings with a closed tag vocabulary (`delete:` / `stdlib:` / `native:` /
`yagni:` / `shrink:`), each carrying a severity, plus a quantified
`net: -<N> lines possible` / `Lean already. Ship.` verdict.

### Changed

- **grill** rewritten and slimmed (290 → 88-line core + a 52-line `references/`
file behind progressive disclosure). The core loop is stated once, at the top:
necessity first (decision-ladder rung 1), falsify cheaply by exploring code
instead of asking, ask one decision at a time with a recommended answer, on a
checkable-and-exhaustive completion criterion. The lens taxonomy,
rationalizations, red flags, severity, and common-mistakes lists moved to
`references/checks.md`; the grill-log artifact is de-ceremonied but retains the
same capability.
- **brainstorm** rewritten and slimmed (293 → 110-line core + an 89-line
`references/artifact-format.md`). The two viewpoints (product + architecture)
now run **inline by default** and fan out to independent subagents only at
Heavy tier or on explicit request — capability unchanged, default cost removed.
Options map along the decision ladder with a deletion-over-addition bias; a
pick-a-branch classifier and a fog-of-war skip cut over-firing.
- `anti-patterns-lint.sh` no-consumer family now also flags speculative
`export interface` / `type` / `abstract class` declarations nothing references,
framed as decision-ladder rung 1. The family set stays closed by design (per
§ Restraint); richer YAGNI checks live in the on-demand review lens, not the
write-time hook.
- `code-quality-cleaner` agent extended from maintainability-only to
maintainability + YAGNI/over-engineering, with a bounded checklist and the
tagged finding format above.

## 0.11.0

Expand Down
38 changes: 24 additions & 14 deletions agents/code-quality-cleaner.toml
Original file line number Diff line number Diff line change
@@ -1,33 +1,43 @@
name = "code-quality-cleaner"
description = "Use during do-it-review-loop for read-only maintainability review of redundancy, dead paths, weak abstractions, and cleanup risk."
description = "Use during do-it-review-loop for read-only maintainability and YAGNI review of redundancy, dead paths, single-use or speculative abstractions, reinvented stdlib, and cleanup risk."
sandbox_mode = "read-only"
developer_instructions = """
Operate as the do-it maintainability review lens. Stay read-only.
Operate as the do-it maintainability and YAGNI review lens. Stay read-only.

Default to Standard slice; never self-escalate to Heavy without explicit assignment. Full dispatch contract: see `do-it-subagent-orchestration` § Required Prompt Contract.

Purpose:
- find cleanup issues that create correctness, review, or maintenance risk
- keep the delivered diff smaller and easier to support
- find cleanup and over-engineering issues that create correctness, review, or maintenance risk
- keep the delivered diff smaller and easier to support — the best code is the code that was never written
- avoid style-only commentary

Workflow:
1. Inspect the actual diff or changed files named by the parent.
2. Look for duplicated logic, stale helpers, dead paths, avoidable abstraction, and brittle tests.
3. Check whether local patterns or helpers were missed.
4. Report only issues with a real consequence.
5. Recommend the smallest cleanup that removes the risk.
2. Maintainability scan: duplicated logic, stale helpers, dead paths, brittle tests, and local patterns or helpers that were missed.
3. YAGNI / over-engineering scan against the decision ladder (see `do-it-router` § Restraint). Bounded checklist:
- an interface, abstract class, or `type` with a single implementation;
- a factory, builder, or registry producing exactly one product;
- a wrapper or adapter that only forwards to one callee;
- a module, hook, or config flag exporting a single unused item;
- hand-rolled code the stdlib or platform already provides;
- speculative parameters, generality, or `Phase 2` scaffolding with no current caller.
4. Report only issues with a real consequence; recommend the smallest change that removes the risk — prefer deletion over addition, boring over clever.

Never cut the guardrails: input validation at trust boundaries, error handling that prevents data loss, security, accessibility, or behavior the task explicitly required. Lazy, not negligent.

Severity:
- Blocking: quality issue can cause wrong behavior, broken tests, data loss, or contract breakage.
- Important: likely future bug, meaningful duplication, misleading abstraction, or brittle coverage.
- Opportunity: local clarity with low delivery risk.
- Blocking: the issue can cause wrong behavior, broken tests, data loss, or contract breakage.
- Important: likely future bug, meaningful duplication, or misleading abstraction.
- Opportunity: local simplification with low delivery risk (most YAGNI findings land here unless tied to correctness).

Finding format — one line each, ordered by severity, using a CLOSED tag vocabulary:
[<severity>] L<line>: <tag>: <what to cut>. <replacement>.
Tags: `delete:` (dead or unused — remove it) · `stdlib:` (reinvents the standard library — use it) · `native:` (reinvents a native language or runtime feature) · `yagni:` (speculative abstraction with one or zero users — inline it) · `shrink:` (works but larger than needed — collapse it). Every finding states both what to cut AND what replaces it, and carries a severity so the batch-emission and closeout gates still function. Do not invent new tags.

Token discipline:
- do not audit untouched subsystems
- cite exact lines or diff evidence when possible
- cite exact lines or diff evidence
- keep findings short and action-oriented
- say when no cleanup finding justifies action

Return findings first, ordered by severity, with evidence, consequence, smallest fix, and residual risk.
End with a quantified verdict: `net: -<N> lines possible` when cuts exist, or `Lean already. Ship.` when none do. Return findings first, ordered by severity, each with evidence and smallest fix, then residual risk.
"""
27 changes: 14 additions & 13 deletions commands/do-it-brainstorm.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
---
description: 在编码前用产品边界 + 架构地基双核心澄清需求形态,并按任务动态补充 UX、用户、Ops、安全、领域语言或计划视角
description: 在编码前用产品视角 + 架构视角双核心澄清需求形态与选项,沿决策阶梯发散,并把需要收敛的事项交给 do-it-grill
---

# /do-it-brainstorm

对当前任务先做 divergent brainstorm,搞清楚需求到底是什么、可能长什么样,再把需要收敛的事项交给 `do-it-grill`。默认运行两个核心视角
对当前任务先做 divergent brainstorm,搞清楚需求到底是什么、可能长什么样、有哪些选项,再把需要收敛的事项交给 `do-it-grill`。每一遍都由两个核心视角支撑

- `product-strategist`:产品边界、核心目标、需求形态、多个选项及其好处 / 坏处 / 风险。
- `architecture-strategist`:核心底层、扩展模块、阶段闭环、边界、验证路线。
- **产品视角**(`product-strategist`:产品边界、核心目标、需求形态、多个选项及其好处 / 坏处 / 风险。
- **架构视角**(`architecture-strategist`:核心底层、扩展模块、阶段闭环、边界、验证路线。

根据任务再动态补充 `ux-designer`、`end-user-advocate`、`ops-sre`、`ceo-reviewer`、`red-team-reviewer`、`domain-language-reviewer` 或 `plan-challenger`。旧的四补充视角组合不再是默认固定流程
两个视角固定存在,但**默认由主线程内联推演**;只有 Heavy 或你显式要求时,才真正扇出成独立只读子智能体。按任务再动态补充 `ux-designer`、`end-user-advocate`、`ops-sre`、`ceo-reviewer`、`red-team-reviewer`、`domain-language-reviewer` 或 `plan-challenger`(零到两个,只在能改变实现路线时加)

## 调用方式

- `/do-it-brainstorm` — 默认双核心;由 router / 当前任务决定是否补充视角
- `/do-it-brainstorm` — 默认双视角内联;由 router / 当前任务决定是否补充视角与是否扇出
- `/do-it-brainstorm product,architecture,ops` — 显式指定 lenses(逗号分隔)。
- `/do-it-brainstorm lenses=ux,end-user,red-team` — 在双核心之外补充指定视角
- `/do-it-brainstorm discuss` — 项目上下文还不足时先讨论问题空间,不强制写 artifact。
- `/do-it-brainstorm all` — 运行双核心 + 所有适用补充视角;只在 Heavy 或用户明确要求时使用
- `/do-it-brainstorm lenses=ux,end-user,red-team` — 在双视角之外补充指定视角
- `/do-it-brainstorm discuss` — 只做内联讨论,不写 artifact(这是默认形态)
- `/do-it-brainstorm all` — 扇出双视角 + 所有适用补充视角为独立子智能体;只在 Heavy 或明确要求时用

## 行为

1. 加载 `do-it-brainstorm` skill。
2. 先确认 task frame 和当前 repo 真相;上下文空白时先讨论需求形态,不强制写 artifact
3. 默认选择 `product-strategist` + `architecture-strategist`,再按任务风险选择补充视角
4. 输出按 `Requirement Shape` / `Product Boundary` / `Core Goal` / `Options` / `Architecture Foundation` / `Extension Modules` / `Must Resolve In Grill` 分层
5. 当结果需要后续 session 复用时,写入 `.do-it/brainstorm/<task>.md`。
2. 先定「哪个问题主导」(产品形态 / 架构地基 / 某个补充关切),把力气投在那里
3. 确认 task frame 和当前 repo 真相;上下文空白或没有真正待决项时,直说并交给 planning,不硬造选项
4. 沿决策阶梯(跳过 → stdlib/原生 → 已装依赖 → 最小自建 → 完整自建)铺开选项,偏向减法与无聊的方案
5. 输出 `Requirement Shape` / `Product Boundary` / `Core Goal` / `Options` / `Architecture Foundation` / `Extension Modules` / `Must Resolve In Grill` 分层;默认内联,下一 session 需复用或 Heavy 时才写 `.do-it/brainstorm/<task>.md`。
6. **不**在 brainstorm 内做最终收敛;需要收敛时交给 `/do-it-grill`。

## 跳过条件

- 任务是机械重构、单文件改名、依赖升级、纯内部基础设施。
- 当前 task slug 已存在 `.do-it/brainstorm/<task>.md` 且提案未实质变更。
- 拷问后发现没有真正的开放决策 —— 直接交给 planning。

## 与 grill 的衔接

Expand Down
27 changes: 19 additions & 8 deletions hooks/anti-patterns-lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@
# case-list — ≥10 consecutive added lines look like a bash case branch
# pattern (`*"..."*`); flags the "大段 case 语句吞所有变体"
# shape that should usually be data-driven.
# no-consumer — a freshly-added TS/JS top-level `export {const|function|class} <Name>`
# whose `<Name>` does not appear in any other .ts/.tsx/.js/.mjs/.cjs
# file under the repo.
# no-consumer — a freshly-added TS/JS top-level export whose `<Name>` does not
# appear in any other .ts/.tsx/.js/.mjs/.cjs file under the repo.
# Covers `const|let|var|function|class` AND the speculative-
# abstraction kinds `interface|type|abstract class` — an exported
# abstraction nobody references is decision-ladder rung 1 (does it
# need to exist?), the highest-signal YAGNI smell catchable at
# write time.
# copy-paste — a contiguous chunk of ≥5 non-trivial added lines whose first
# AND last lines both appear in another file inside the same
# directory.
#
# Like comments-lint.sh this hook is advisory only.
# Like comments-lint.sh this hook is advisory only. The family set is
# deliberately small and CLOSED: per do-it-router § Restraint, do not grow it
# into an ever-longer anti-pattern list. Richer YAGNI review (single-impl
# interfaces, one-product factories, pass-through wrappers, reinvented stdlib)
# belongs to the on-demand do-it-review-loop YAGNI lens, not this write-time hook.

set -uo pipefail

Expand Down Expand Up @@ -177,6 +185,8 @@ fi

# ------------------------------------------------------------------------
# Family 2: no-consumer — TS/JS top-level export with no other reference.
# Includes the speculative-abstraction kinds (interface / type / abstract
# class): an exported abstraction nobody references is decision-ladder rung 1.
# ------------------------------------------------------------------------
case "$FILE_PATH" in
*.ts|*.tsx|*.js|*.jsx|*.mjs|*.cjs)
Expand All @@ -185,11 +195,12 @@ case "$FILE_PATH" in
# which is not supported by BSD awk (macOS default). The regex matches:
# - `export const|let|var <name>`
# - `export function <name>` / `export async function <name>`
# - `export class <name>`
# - `export class <name>` / `export abstract class <name>`
# - `export interface <name>` / `export type <name>`
# - `export default function <name>` / `export default class <name>`
EXPORT_NAMES="$(printf '%s\n' "$ADDED_LINES" \
| grep -E '^[[:space:]]*export[[:space:]]+(default[[:space:]]+(async[[:space:]]+)?(function|class)|async[[:space:]]+function|const|let|var|function|class)[[:space:]]+[A-Za-z_][A-Za-z0-9_]*' \
| sed -E 's/^[[:space:]]*export[[:space:]]+(default[[:space:]]+)?(async[[:space:]]+function|function|class|const|let|var)[[:space:]]+([A-Za-z_][A-Za-z0-9_]*).*/\3/' \
| grep -E '^[[:space:]]*export[[:space:]]+(default[[:space:]]+(async[[:space:]]+)?(function|class)|async[[:space:]]+function|abstract[[:space:]]+class|const|let|var|function|class|interface|type)[[:space:]]+[A-Za-z_][A-Za-z0-9_]*' \
| sed -E 's/^[[:space:]]*export[[:space:]]+(default[[:space:]]+)?(async[[:space:]]+function|abstract[[:space:]]+class|function|class|const|let|var|interface|type)[[:space:]]+([A-Za-z_][A-Za-z0-9_]*).*/\3/' \
| sort -u)"
if [[ -n "$EXPORT_NAMES" ]]; then
NO_CONSUMER_NAMES=""
Expand All @@ -213,7 +224,7 @@ case "$FILE_PATH" in
done <<<"$EXPORT_NAMES"
if [[ -n "$NO_CONSUMER_NAMES" ]]; then
_record_family "no-consumer"
_append_detail "no-consumer: ${NO_CONSUMER_NAMES} (newly-exported but no other file references; consider whether the export is needed)"
_append_detail "no-consumer: ${NO_CONSUMER_NAMES} (newly-exported, no other file references it — decision ladder rung 1: does it need to exist, or can it be inlined or dropped?)"
fi
fi
;;
Expand Down
6 changes: 3 additions & 3 deletions index.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
{
"kind": "skill",
"name": "do-it-grill",
"description": "Use when hidden assumptions or user-only decisions need fact verification before planning, implementation, or closeout.",
"description": "Pressure-test the load-bearing premises and necessity of a plan before it hardens into code, commits, or claims. Use when hidden assumptions or user-only decisions gate planning, implementation, or closeout, or when asked to grill, challenge, or stress-test.",
"origin": "do-it",
"optional": false,
"group": "mainline",
Expand All @@ -79,7 +79,7 @@
{
"kind": "skill",
"name": "do-it-brainstorm",
"description": "Use when planning needs divergent product and architecture option mapping before grill converges on decisions.",
"description": "Map requirement shape and options through a product viewpoint and an architecture viewpoint before grill converges on decisions. Use when planning needs divergent option mapping, or when asked to brainstorm or 脑暴.",
"origin": "do-it",
"optional": false,
"group": "on-demand",
Expand Down Expand Up @@ -264,7 +264,7 @@
{
"kind": "agent",
"name": "code-quality-cleaner",
"description": "Use during do-it-review-loop for read-only maintainability review of redundancy, dead paths, weak abstractions, and cleanup risk.",
"description": "Use during do-it-review-loop for read-only maintainability and YAGNI review of redundancy, dead paths, single-use or speculative abstractions, reinvented stdlib, and cleanup risk.",
"origin": "do-it",
"optional": false,
"source": "agents/code-quality-cleaner.toml",
Expand Down
Loading
Loading