@aperant/framework 0.6.3 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/README.md +64 -10
- package/agents/apt-improver.md +99 -0
- package/agents/apt-planner.md +115 -10
- package/dist/__test-helpers/run-cmd.d.mts +4 -2
- package/dist/__test-helpers/run-cmd.d.mts.map +1 -1
- package/dist/__test-helpers/run-cmd.mjs +56 -15
- package/dist/__test-helpers/run-cmd.mjs.map +1 -1
- package/dist/cli/artifacts/classification.d.mts.map +1 -1
- package/dist/cli/artifacts/classification.mjs +10 -0
- package/dist/cli/artifacts/classification.mjs.map +1 -1
- package/dist/cli/ci-watch/lock.d.mts +53 -0
- package/dist/cli/ci-watch/lock.d.mts.map +1 -0
- package/dist/cli/ci-watch/lock.mjs +172 -0
- package/dist/cli/ci-watch/lock.mjs.map +1 -0
- package/dist/cli/ci-watch/state.d.mts +36 -0
- package/dist/cli/ci-watch/state.d.mts.map +1 -0
- package/dist/cli/ci-watch/state.mjs +103 -0
- package/dist/cli/ci-watch/state.mjs.map +1 -0
- package/dist/cli/ci-watch/stop-matrix.d.mts +58 -0
- package/dist/cli/ci-watch/stop-matrix.d.mts.map +1 -0
- package/dist/cli/ci-watch/stop-matrix.mjs +164 -0
- package/dist/cli/ci-watch/stop-matrix.mjs.map +1 -0
- package/dist/cli/cli-wrappers/ci-watch.d.mts +2 -0
- package/dist/cli/cli-wrappers/ci-watch.d.mts.map +1 -0
- package/dist/cli/cli-wrappers/ci-watch.mjs +9 -0
- package/dist/cli/cli-wrappers/ci-watch.mjs.map +1 -0
- package/dist/cli/commands/adr.d.mts +5 -0
- package/dist/cli/commands/adr.d.mts.map +1 -0
- package/dist/cli/commands/adr.mjs +228 -0
- package/dist/cli/commands/adr.mjs.map +1 -0
- package/dist/cli/commands/ci-watch.d.mts +7 -0
- package/dist/cli/commands/ci-watch.d.mts.map +1 -0
- package/dist/cli/commands/ci-watch.mjs +465 -0
- package/dist/cli/commands/ci-watch.mjs.map +1 -0
- package/dist/cli/commands/context.d.mts +7 -0
- package/dist/cli/commands/context.d.mts.map +1 -0
- package/dist/cli/commands/context.mjs +224 -0
- package/dist/cli/commands/context.mjs.map +1 -0
- package/dist/cli/commands/event.d.mts.map +1 -1
- package/dist/cli/commands/event.mjs +59 -24
- package/dist/cli/commands/event.mjs.map +1 -1
- package/dist/cli/commands/host-detect.d.mts +1 -1
- package/dist/cli/commands/host-detect.d.mts.map +1 -1
- package/dist/cli/commands/host-detect.mjs +30 -3
- package/dist/cli/commands/host-detect.mjs.map +1 -1
- package/dist/cli/commands/init.d.mts.map +1 -1
- package/dist/cli/commands/init.mjs +73 -5
- package/dist/cli/commands/init.mjs.map +1 -1
- package/dist/cli/commands/modes.d.mts +13 -0
- package/dist/cli/commands/modes.d.mts.map +1 -0
- package/dist/cli/commands/modes.mjs +220 -0
- package/dist/cli/commands/modes.mjs.map +1 -0
- package/dist/cli/commands/pr-review-audit-fixer.d.mts +41 -2
- package/dist/cli/commands/pr-review-audit-fixer.d.mts.map +1 -1
- package/dist/cli/commands/pr-review-audit-fixer.mjs +91 -14
- package/dist/cli/commands/pr-review-audit-fixer.mjs.map +1 -1
- package/dist/cli/commands/route.d.mts.map +1 -1
- package/dist/cli/commands/route.mjs +11 -2
- package/dist/cli/commands/route.mjs.map +1 -1
- package/dist/cli/commands/task.d.mts.map +1 -1
- package/dist/cli/commands/task.mjs +136 -6
- package/dist/cli/commands/task.mjs.map +1 -1
- package/dist/cli/commands/tokens.d.mts.map +1 -1
- package/dist/cli/commands/tokens.mjs +150 -6
- package/dist/cli/commands/tokens.mjs.map +1 -1
- package/dist/cli/commands/triage.d.mts +8 -0
- package/dist/cli/commands/triage.d.mts.map +1 -0
- package/dist/cli/commands/triage.mjs +259 -0
- package/dist/cli/commands/triage.mjs.map +1 -0
- package/dist/cli/config/post-merge-sweep.d.mts +18 -0
- package/dist/cli/config/post-merge-sweep.d.mts.map +1 -1
- package/dist/cli/config/post-merge-sweep.mjs +48 -3
- package/dist/cli/config/post-merge-sweep.mjs.map +1 -1
- package/dist/cli/consistency/registry.d.mts +11 -0
- package/dist/cli/consistency/registry.d.mts.map +1 -1
- package/dist/cli/consistency/registry.mjs +13 -0
- package/dist/cli/consistency/registry.mjs.map +1 -1
- package/dist/cli/coordination/agent-identity.d.mts +9 -0
- package/dist/cli/coordination/agent-identity.d.mts.map +1 -1
- package/dist/cli/coordination/agent-identity.mjs +11 -0
- package/dist/cli/coordination/agent-identity.mjs.map +1 -1
- package/dist/cli/coordination/event-log.d.mts +27 -0
- package/dist/cli/coordination/event-log.d.mts.map +1 -1
- package/dist/cli/coordination/event-log.mjs +72 -2
- package/dist/cli/coordination/event-log.mjs.map +1 -1
- package/dist/cli/design/frontmatter-schema.d.mts +3 -3
- package/dist/cli/design/frontmatter-schema.d.mts.map +1 -1
- package/dist/cli/design/frontmatter-schema.mjs +3 -1
- package/dist/cli/design/frontmatter-schema.mjs.map +1 -1
- package/dist/cli/dispatch.d.mts.map +1 -1
- package/dist/cli/dispatch.mjs +14 -1
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/gate/registry.d.mts +11 -0
- package/dist/cli/gate/registry.d.mts.map +1 -1
- package/dist/cli/gate/registry.mjs +13 -0
- package/dist/cli/gate/registry.mjs.map +1 -1
- package/dist/cli/help.d.mts.map +1 -1
- package/dist/cli/help.mjs +1 -0
- package/dist/cli/help.mjs.map +1 -1
- package/dist/cli/host/detect.d.mts +1 -0
- package/dist/cli/host/detect.d.mts.map +1 -1
- package/dist/cli/host/detect.mjs +5 -0
- package/dist/cli/host/detect.mjs.map +1 -1
- package/dist/cli/route/envelope.d.mts +68 -4
- package/dist/cli/route/envelope.d.mts.map +1 -1
- package/dist/cli/route/envelope.mjs +140 -103
- package/dist/cli/route/envelope.mjs.map +1 -1
- package/dist/cli/route/skill-discover.d.mts +11 -0
- package/dist/cli/route/skill-discover.d.mts.map +1 -1
- package/dist/cli/route/skill-discover.mjs +46 -1
- package/dist/cli/route/skill-discover.mjs.map +1 -1
- package/dist/cli/skill-author/contract.d.mts +20 -0
- package/dist/cli/skill-author/contract.d.mts.map +1 -1
- package/dist/cli/skill-author/contract.mjs +27 -0
- package/dist/cli/skill-author/contract.mjs.map +1 -1
- package/dist/cli/skill-author/skill-template.d.mts.map +1 -1
- package/dist/cli/skill-author/skill-template.mjs +4 -3
- package/dist/cli/skill-author/skill-template.mjs.map +1 -1
- package/dist/cli/task/worktree-cleanup.d.mts +9 -1
- package/dist/cli/task/worktree-cleanup.d.mts.map +1 -1
- package/dist/cli/task/worktree-cleanup.mjs +190 -9
- package/dist/cli/task/worktree-cleanup.mjs.map +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/agents/apt-planner.md +1 -1
- package/dist/plugin/skills/apt/SKILL.md +111 -5
- package/dist/plugin/skills/apt-author-skill/SKILL.md +11 -0
- package/dist/plugin/skills/apt-bootstrap/SKILL.md +1 -0
- package/dist/plugin/skills/apt-classify/SKILL.md +1 -0
- package/dist/plugin/skills/apt-close-task/SKILL.md +1 -0
- package/dist/plugin/skills/apt-create-docs/SKILL.md +1 -0
- package/dist/plugin/skills/apt-debug/SKILL.md +2 -0
- package/dist/plugin/skills/apt-design/SKILL.md +2 -0
- package/dist/plugin/skills/apt-discuss/SKILL.md +2 -0
- package/dist/plugin/skills/apt-docs/SKILL.md +2 -0
- package/dist/plugin/skills/apt-execute/SKILL.md +1 -0
- package/dist/plugin/skills/apt-mockup/SKILL.md +2 -0
- package/dist/plugin/skills/apt-pause/SKILL.md +1 -0
- package/dist/plugin/skills/apt-personas/SKILL.md +1 -0
- package/dist/plugin/skills/apt-plan/SKILL.md +2 -0
- package/dist/plugin/skills/apt-pr-review/SKILL.md +1 -0
- package/dist/plugin/skills/apt-quick/SKILL.md +2 -0
- package/dist/plugin/skills/apt-resume/SKILL.md +1 -0
- package/dist/plugin/skills/apt-review/SKILL.md +1 -0
- package/dist/plugin/skills/apt-roadmap/SKILL.md +1 -0
- package/dist/plugin/skills/apt-roundtable/SKILL.md +2 -0
- package/dist/plugin/skills/apt-run/SKILL.md +1 -0
- package/dist/plugin/skills/apt-scan/SKILL.md +1 -0
- package/dist/plugin/skills/apt-setup/SKILL.md +1 -0
- package/dist/plugin/skills/apt-ship/SKILL.md +6 -5
- package/dist/plugin/skills/apt-stress-test/SKILL.md +1 -0
- package/dist/plugin/skills/apt-terminal/SKILL.md +1 -0
- package/dist/plugin/skills/apt-update/SKILL.md +5 -0
- package/dist/plugin/skills/apt-verify/SKILL.md +1 -0
- package/dist/plugin/skills/apt-verify-proof/SKILL.md +1 -0
- package/dist/types/config.d.ts +85 -0
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +125 -122
- package/prompts/coder.md +2 -0
- package/prompts/planner.md +12 -0
- package/prompts/spec_writer.md +9 -0
- package/skills/apt/SKILL.md +112 -5
- package/skills/apt-author-skill/SKILL.md +11 -0
- package/skills/apt-bootstrap/SKILL.md +1 -0
- package/skills/apt-classify/SKILL.md +1 -0
- package/skills/apt-close-task/SKILL.md +33 -1
- package/skills/apt-create-docs/SKILL.md +1 -0
- package/skills/apt-debug/SKILL.md +41 -6
- package/skills/apt-debug/appendices/diagnose-discipline.md +119 -0
- package/skills/apt-design/SKILL.md +2 -0
- package/skills/apt-diagram/SKILL.md +342 -0
- package/skills/apt-diagram/appendices/design-discipline.md +97 -0
- package/skills/apt-discuss/SKILL.md +27 -0
- package/skills/apt-discuss/appendices/grill-discipline.md +104 -0
- package/skills/apt-discuss/appendices/zoom-out-helper.md +79 -0
- package/skills/apt-docs/SKILL.md +2 -0
- package/skills/apt-execute/SKILL.md +49 -5
- package/skills/apt-execute/appendices/tdd-mode.md +107 -0
- package/skills/apt-improve/DEEPENING.md +84 -0
- package/skills/apt-improve/INTERFACE-DESIGN.md +97 -0
- package/skills/apt-improve/LANGUAGE.md +104 -0
- package/skills/apt-improve/SKILL.md +141 -0
- package/skills/apt-mockup/SKILL.md +2 -0
- package/skills/apt-pause/SKILL.md +1 -0
- package/skills/apt-personas/SKILL.md +1 -0
- package/skills/apt-plan/SKILL.md +149 -4
- package/skills/apt-planner.md +42 -1
- package/skills/apt-pr-review/SKILL.md +47 -16
- package/skills/apt-prototype/LOGIC.md +109 -0
- package/skills/apt-prototype/SKILL.md +143 -0
- package/skills/apt-prototype/UI.md +90 -0
- package/skills/apt-quick/SKILL.md +32 -0
- package/skills/apt-resume/SKILL.md +1 -0
- package/skills/apt-review/SKILL.md +3 -0
- package/skills/apt-roadmap/SKILL.md +1 -0
- package/skills/apt-roundtable/SKILL.md +2 -0
- package/skills/apt-run/SKILL.md +33 -4
- package/skills/apt-scan/SKILL.md +1 -0
- package/skills/apt-setup/SKILL.md +129 -2
- package/skills/apt-ship/SKILL.md +52 -4
- package/skills/apt-stress-test/SKILL.md +1 -0
- package/skills/apt-terminal/SKILL.md +1 -0
- package/skills/apt-triage/AGENT-BRIEF.md +84 -0
- package/skills/apt-triage/OUT-OF-SCOPE.md +75 -0
- package/skills/apt-triage/SKILL.md +169 -0
- package/skills/apt-update/SKILL.md +3 -0
- package/skills/apt-verify/SKILL.md +4 -0
- package/skills/apt-verify-proof/SKILL.md +4 -0
- package/skills/apt-watch-ci/SKILL.md +163 -0
- package/skills/apt-zoom-out/SKILL.md +130 -0
- package/src/cli/artifacts/classification.mjs +10 -0
- package/src/cli/ci-watch/lock.mjs +178 -0
- package/src/cli/ci-watch/state.mjs +103 -0
- package/src/cli/ci-watch/stop-matrix.mjs +181 -0
- package/src/cli/cli-wrappers/ci-watch.mjs +9 -0
- package/src/cli/commands/adr.mjs +243 -0
- package/src/cli/commands/ci-watch.mjs +503 -0
- package/src/cli/commands/context.mjs +244 -0
- package/src/cli/commands/event.mjs +63 -24
- package/src/cli/commands/host-detect.mjs +33 -7
- package/src/cli/commands/init.mjs +83 -5
- package/src/cli/commands/modes.mjs +215 -0
- package/src/cli/commands/pr-review-audit-fixer.mjs +95 -16
- package/src/cli/commands/route.mjs +11 -2
- package/src/cli/commands/task.mjs +152 -18
- package/src/cli/commands/tokens.mjs +157 -6
- package/src/cli/commands/triage.mjs +277 -0
- package/src/cli/config/post-merge-sweep.mjs +49 -3
- package/src/cli/consistency/registry.mjs +14 -0
- package/src/cli/coordination/agent-identity.mjs +12 -0
- package/src/cli/coordination/event-log.mjs +73 -2
- package/src/cli/design/frontmatter-schema.mjs +3 -1
- package/src/cli/dispatch.mjs +15 -1
- package/src/cli/gate/registry.mjs +14 -0
- package/src/cli/help.mjs +1 -0
- package/src/cli/host/detect.mjs +5 -0
- package/src/cli/route/envelope.mjs +140 -106
- package/src/cli/route/skill-discover.mjs +46 -1
- package/src/cli/skill-author/contract.mjs +29 -0
- package/src/cli/skill-author/skill-template.mjs +4 -3
- package/src/cli/task/worktree-cleanup.mjs +191 -9
- package/templates/adr-format.md +56 -0
- package/templates/config.json +4 -0
- package/templates/context-format.md +34 -0
|
@@ -9,16 +9,20 @@ user_invocable: true
|
|
|
9
9
|
internal: false
|
|
10
10
|
spawns_agent: true
|
|
11
11
|
agent_name: "apt-executor"
|
|
12
|
+
task_context: require-existing
|
|
12
13
|
default_execution_mode: auto
|
|
13
14
|
execution_modes:
|
|
14
15
|
- auto
|
|
15
16
|
- step
|
|
16
17
|
allowed-tools: "Read, Write, Edit, Bash, Grep, Glob"
|
|
17
|
-
argument-hint: "apt:execute [--continue]"
|
|
18
|
+
argument-hint: "apt:execute [--continue] [--subtask <id>] [--parallel] [--wave <N>] [--tdd] [--no-tdd]"
|
|
18
19
|
gates:
|
|
19
20
|
- constitution-read
|
|
20
21
|
- constitution-coverage
|
|
21
22
|
- plan-exists
|
|
23
|
+
config_keys:
|
|
24
|
+
- coding.tdd_default
|
|
25
|
+
- tdd.iron_law
|
|
22
26
|
---
|
|
23
27
|
<objective>
|
|
24
28
|
Read an implementation plan, iterate through subtasks, implement each one with atomic commits, and track progress. Supports both sequential (default) and wave-parallel execution modes.
|
|
@@ -78,6 +82,8 @@ When `/apt:execute` spawns ANY subagent (executor, wave workers, post-subtask re
|
|
|
78
82
|
| `--subtask <id>` | Jump to a specific subtask (skip dependency check — user override) |
|
|
79
83
|
| `--parallel` | Force wave-parallel mode even if `parallelization.enabled` is false in config |
|
|
80
84
|
| `--wave <N>` | Execute only wave N (implies wave mode). Useful for pacing or quota management |
|
|
85
|
+
| `--tdd` | Activate the vertical-tracer-bullet TDD discipline for this run (gates `<tdd_iron_law>`). Inverse of `--no-tdd`. Hard-exempt on QUICK tasks per Fast Path Guarantee (ID-05). |
|
|
86
|
+
| `--no-tdd` | Deactivate TDD even if `coding.tdd_default: true` is set in config. |
|
|
81
87
|
</arguments>
|
|
82
88
|
|
|
83
89
|
<process>
|
|
@@ -133,6 +139,44 @@ Before loading context, determine execution mode:
|
|
|
133
139
|
|
|
134
140
|
4. **If Sequential Mode:** proceed to Section 1 below (existing behavior, unchanged).
|
|
135
141
|
|
|
142
|
+
### 0a.1. TDD Discipline Detection (Pocock adoption AC3)
|
|
143
|
+
|
|
144
|
+
Compute whether the vertical-tracer-bullet TDD discipline is active for
|
|
145
|
+
this run. The `<tdd_iron_law>` block in Section 3c is gated on this
|
|
146
|
+
boolean. Three inputs combine; QUICK is hard-exempt regardless.
|
|
147
|
+
|
|
148
|
+
1. **Read config:** `coding.tdd_default` from `.aperant/config.json`
|
|
149
|
+
(default `false` when absent).
|
|
150
|
+
2. **Read flags:** `--tdd` (force-enable) and `--no-tdd` (force-disable)
|
|
151
|
+
on the command line.
|
|
152
|
+
3. **Read task track** from `apt-tools task get . --id {task-id}` →
|
|
153
|
+
`task.track`. (If unset, fall back to `complexity` field on
|
|
154
|
+
`implementation_plan.json`: `simple` → QUICK, otherwise STANDARD.)
|
|
155
|
+
|
|
156
|
+
Compute `tdd_active` as:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
if track === "QUICK":
|
|
160
|
+
tdd_active = false # Fast Path Guarantee — ID-05, hard-exempt
|
|
161
|
+
elif --no-tdd flag:
|
|
162
|
+
tdd_active = false # explicit user override
|
|
163
|
+
elif --tdd flag:
|
|
164
|
+
tdd_active = true # explicit user opt-in
|
|
165
|
+
else:
|
|
166
|
+
tdd_active = coding.tdd_default || legacy config.tdd.iron_law === true
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Carry `tdd_active` forward to Section 3c. When `tdd_active === false`,
|
|
170
|
+
the iron-law block is skipped entirely and execute behaves identically
|
|
171
|
+
to the pre-Pocock single-commit flow. When `tdd_active === true`, the
|
|
172
|
+
red-green-refactor sequence is mandatory and audited by gate G9.
|
|
173
|
+
|
|
174
|
+
**The QUICK exemption is a constraint, not a toggle.** A user who passes
|
|
175
|
+
`--tdd` on a QUICK-routed task gets `tdd_active = false` and a one-line
|
|
176
|
+
note in the run report: "TDD requested but skipped — QUICK Fast Path
|
|
177
|
+
Guarantee (ID-05)". The Pocock appendix
|
|
178
|
+
`appendices/tdd-mode.md` carries the rationale.
|
|
179
|
+
|
|
136
180
|
## 1. Load Context
|
|
137
181
|
|
|
138
182
|
1. Read `AGENTS.md` if it exists — extract coding conventions, test requirements, style rules
|
|
@@ -235,11 +279,11 @@ Follow `subtask.description` to implement the changes. Rules:
|
|
|
235
279
|
- Add/update tests if the subtask modifies testable behavior
|
|
236
280
|
- Reference `prompts/coder.md` for coding methodology and environment awareness
|
|
237
281
|
|
|
238
|
-
<tdd_iron_law enabled_when="
|
|
282
|
+
<tdd_iron_law enabled_when="tdd_active === true">
|
|
239
283
|
|
|
240
|
-
**TDD Iron Law — conditional flow.** This block activates ONLY when
|
|
284
|
+
**TDD Iron Law — conditional flow.** This block activates ONLY when `tdd_active === true` (computed in Section 0a.1 from `coding.tdd_default` config, the `--tdd` / `--no-tdd` flags, and the task track). When `tdd_active === false` — including all QUICK-routed tasks regardless of flag or config (Fast Path Guarantee, ID-05) — skip this block entirely and use the single-commit flow above. The legacy `config.tdd.iron_law` config key continues to work and is rolled into `tdd_active` as a backward-compat alias.
|
|
241
285
|
|
|
242
|
-
When
|
|
286
|
+
When the iron law is on, 3c/3d/3e collapses into a strict red-green-refactor sequence with **two commits per subtask**:
|
|
243
287
|
|
|
244
288
|
1. **Write the failing test first.** Identify or create the test file in `subtask.files` (look for `*.test.*` / `*.spec.*`). Add the test that describes the behavior you are about to implement. Do NOT touch implementation files yet.
|
|
245
289
|
2. **Commit the red test.**
|
|
@@ -255,7 +299,7 @@ When `tdd.iron_law` is on, 3c/3d/3e collapses into a strict red-green-refactor s
|
|
|
255
299
|
```
|
|
256
300
|
The audit gate `tdd-iron-law` (G9) fires during `/apt:verify` and asserts this commit order per subtask — a `feat(...)` commit that precedes the matching `test(...)` commit on the same file set is a blocking failure.
|
|
257
301
|
|
|
258
|
-
**Rationalizations to reject** (do NOT take any of these shortcuts when `
|
|
302
|
+
**Rationalizations to reject** (do NOT take any of these shortcuts when `tdd_active` is on):
|
|
259
303
|
|
|
260
304
|
| Rationalization | Counter-rule |
|
|
261
305
|
|---|---|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Adapted from Matt Pocock's MIT-licensed skill suite:
|
|
3
|
+
https://github.com/mattpocock/skills/blob/main/skills/engineering/tdd
|
|
4
|
+
Licensed under MIT. Modifications: ported as an apt:execute appendix
|
|
5
|
+
gated by `tdd_active` (config.coding.tdd_default || --tdd flag) and
|
|
6
|
+
made QUICK-exempt per Aperant's Fast Path Guarantee (ID-05).
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# TDD Mode — Vertical Tracer-Bullet Discipline (apt:execute appendix)
|
|
10
|
+
|
|
11
|
+
This appendix loads into `apt:execute`'s context when `tdd_active === true`
|
|
12
|
+
(see SKILL.md §0a.1). It carries the vertical-tracer-bullet discipline
|
|
13
|
+
Pocock's `tdd` skill captured. The audit gate G9 (`tdd-iron-law`) enforces
|
|
14
|
+
the commit order; this prose explains the **why**.
|
|
15
|
+
|
|
16
|
+
## Why vertical tracer bullets, not horizontal layers
|
|
17
|
+
|
|
18
|
+
A "vertical slice" of TDD means: for each subtask, write one failing
|
|
19
|
+
test that describes the **smallest end-to-end behavior change the user
|
|
20
|
+
will care about**, then implement only enough to make it green.
|
|
21
|
+
Horizontal TDD ("write all the data-layer tests first, then all the
|
|
22
|
+
service tests, then all the UI tests") accumulates dead inventory and
|
|
23
|
+
hides whether the slice actually delivers user value.
|
|
24
|
+
|
|
25
|
+
Concretely:
|
|
26
|
+
|
|
27
|
+
- A vertical-slice subtask titled "Solo dogfooder gets a PRD-shaped
|
|
28
|
+
spec on STANDARD" should commit one `test(plan): STANDARD emits PRD
|
|
29
|
+
shape` red test first — exercising the user-visible behavior — then
|
|
30
|
+
one `feat(plan): branch spec.md on track` green commit. Two commits.
|
|
31
|
+
Done.
|
|
32
|
+
- A horizontal-slice subtask titled "edit apt-plan SKILL.md" gets you a
|
|
33
|
+
test that pins prose, not a test that pins user value. The G9 audit
|
|
34
|
+
will pass technically but the discipline failed.
|
|
35
|
+
|
|
36
|
+
The vertical-slice subtask schema (`user_value` field, mandatory on
|
|
37
|
+
STANDARD/DEEP per AC2) is **upstream** of this discipline — TDD bites
|
|
38
|
+
hardest when the subtask was already framed as user value, not file
|
|
39
|
+
scope.
|
|
40
|
+
|
|
41
|
+
## The five rules of vertical tracer bullets
|
|
42
|
+
|
|
43
|
+
These five rules are the load-bearing discipline; ignoring any one of
|
|
44
|
+
them collapses TDD back into ceremony.
|
|
45
|
+
|
|
46
|
+
1. **Write the failing test from the spec, not from the implementation
|
|
47
|
+
you're about to write.** If you write the test after you mentally
|
|
48
|
+
draft the implementation, the test only pins what you wrote —
|
|
49
|
+
not what the spec required. Read the relevant `acceptance_criteria`
|
|
50
|
+
id-ref, then write a test that fails because that AC isn't met yet.
|
|
51
|
+
|
|
52
|
+
2. **Verify the test fails for the *right reason*.** A `ReferenceError`
|
|
53
|
+
because the function doesn't exist yet is not the same as the
|
|
54
|
+
assertion failing on a value mismatch. The G9 audit treats any
|
|
55
|
+
non-zero exit as RED, but the discipline demands you check the
|
|
56
|
+
failure mode is "behavior wrong", not "code shape wrong".
|
|
57
|
+
|
|
58
|
+
3. **Implement the minimum to turn the test green.** No speculative
|
|
59
|
+
abstractions. No "while I'm here, I'll refactor X." The vertical
|
|
60
|
+
slice is one test + one minimum impl. Refactor lives in a follow-up
|
|
61
|
+
subtask with its own test.
|
|
62
|
+
|
|
63
|
+
4. **Commit the test before the implementation.** This is the iron-law
|
|
64
|
+
commit order audit gate G9 enforces. A `feat(...)` commit that
|
|
65
|
+
precedes the matching `test(...)` commit on the same file set is a
|
|
66
|
+
blocking failure at `/apt:verify`.
|
|
67
|
+
|
|
68
|
+
5. **Don't grow the test surface to cover edge cases the spec didn't
|
|
69
|
+
list.** Edge cases are subtasks of their own (with their own AC
|
|
70
|
+
id-refs). The vertical-slice rule applies recursively: each edge
|
|
71
|
+
case is a new tracer bullet through the whole stack, not a wider
|
|
72
|
+
suite of tests for the same slice.
|
|
73
|
+
|
|
74
|
+
## Fast Path Guarantee — QUICK is hard-exempt
|
|
75
|
+
|
|
76
|
+
`tdd_active` is forced `false` when the task's track is `"QUICK"`,
|
|
77
|
+
regardless of flag or config. The rationale: QUICK is the one-shot
|
|
78
|
+
fast path for trivial fixes (typo, copy change, single-line config
|
|
79
|
+
update). Forcing TDD ceremony on those tasks violates the Fast Path
|
|
80
|
+
Guarantee (ID-05) — the user opted into speed, not discipline. If a
|
|
81
|
+
QUICK-routed task genuinely needs TDD, the right move is to re-route
|
|
82
|
+
it as STANDARD via `/apt:plan` (which the router will do for any task
|
|
83
|
+
with >1 file or >30 words of description).
|
|
84
|
+
|
|
85
|
+
The skill body emits a one-line note in the run report when `--tdd`
|
|
86
|
+
was passed on a QUICK task: "TDD requested but skipped — QUICK Fast
|
|
87
|
+
Path Guarantee (ID-05)". This is intentional surface — the user sees
|
|
88
|
+
that their flag was overridden by the constraint.
|
|
89
|
+
|
|
90
|
+
## Backward-compat alias
|
|
91
|
+
|
|
92
|
+
The legacy `config.tdd.iron_law` key continues to enable TDD for
|
|
93
|
+
projects that adopted Aperant before the Pocock content-format
|
|
94
|
+
upgrade. The new computation rolls it into `tdd_active`:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
tdd_active = (
|
|
98
|
+
(--tdd flag) ||
|
|
99
|
+
(coding.tdd_default === true) ||
|
|
100
|
+
(config.tdd.iron_law === true)
|
|
101
|
+
)
|
|
102
|
+
&& (track !== "QUICK")
|
|
103
|
+
&& !(--no-tdd flag)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The two config keys (`coding.tdd_default` and `tdd.iron_law`) coexist
|
|
107
|
+
without conflict; either set to `true` enables TDD by default.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Adapted from Matt Pocock's MIT-licensed skill suite:
|
|
3
|
+
https://github.com/mattpocock/skills/blob/main/skills/engineering/improve-codebase-architecture/DEEPENING.md
|
|
4
|
+
Licensed under MIT. Modifications: scoped to Aperant's apt:improve
|
|
5
|
+
Phase-1 explore step and aligned with the deletion-test priority
|
|
6
|
+
rubric in Phase 2.
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# DEEPENING — Domain-modeling depth lens
|
|
10
|
+
|
|
11
|
+
This lens asks: **does this area model the domain at the right depth?**
|
|
12
|
+
Are the abstractions earning their keep, or are they shallow wrappers
|
|
13
|
+
hiding nothing?
|
|
14
|
+
|
|
15
|
+
The discipline is to **find abstractions that have failed to deepen** —
|
|
16
|
+
classes, modules, or types that started as a single-use convenience and
|
|
17
|
+
never grew into something that captures domain meaning.
|
|
18
|
+
|
|
19
|
+
## What "deep" means
|
|
20
|
+
|
|
21
|
+
A deep abstraction:
|
|
22
|
+
|
|
23
|
+
- Has a name that maps to a domain concept the user / business cares
|
|
24
|
+
about
|
|
25
|
+
- Encapsulates more behavior than its interface suggests (you can call
|
|
26
|
+
one method and trust it to handle multiple internal concerns)
|
|
27
|
+
- Reads naturally in client code without the reader needing to know
|
|
28
|
+
the abstraction's internals
|
|
29
|
+
|
|
30
|
+
A shallow abstraction:
|
|
31
|
+
|
|
32
|
+
- Has a name that mirrors implementation detail rather than domain
|
|
33
|
+
concept (e.g., `DataManager`, `Helper`, `Utils`)
|
|
34
|
+
- Encapsulates almost no behavior — the interface is wider than the
|
|
35
|
+
internals (mostly pass-through)
|
|
36
|
+
- Reads as noise in client code; the reader has to look inside the
|
|
37
|
+
abstraction to know what it does
|
|
38
|
+
|
|
39
|
+
## Red flags this lens surfaces
|
|
40
|
+
|
|
41
|
+
- **Anemic types** — types that are bags of fields with no methods, OR
|
|
42
|
+
classes with methods that just return fields.
|
|
43
|
+
- **Pass-through wrappers** — `class FooService { constructor(api) { this.api = api } create(x) { return this.api.create(x) } }` adds nothing.
|
|
44
|
+
- **Single-call-site abstractions** — extracted "for reuse" but only
|
|
45
|
+
called from one place. Inline them.
|
|
46
|
+
- **God objects** — abstractions that grew too deep AND too wide,
|
|
47
|
+
collecting unrelated responsibilities. Different problem, same lens.
|
|
48
|
+
|
|
49
|
+
## Apply in Phase 1
|
|
50
|
+
|
|
51
|
+
When the explore step scans the named area:
|
|
52
|
+
|
|
53
|
+
1. For each module / class / type, ask: "what domain concept does this
|
|
54
|
+
model?"
|
|
55
|
+
2. If the answer is "none — it's an implementation detail dressed up as
|
|
56
|
+
a concept", flag it as a candidate.
|
|
57
|
+
3. Note in the inventory: `{File}:{Symbol} — shallow ({reason})`. The
|
|
58
|
+
deletion test in Phase 2 will rank these.
|
|
59
|
+
|
|
60
|
+
## What this lens does NOT cover
|
|
61
|
+
|
|
62
|
+
- Boundary shape between modules → see `INTERFACE-DESIGN.md`
|
|
63
|
+
- Naming consistency within / across modules → see `LANGUAGE.md`
|
|
64
|
+
|
|
65
|
+
DEEPENING is about whether each abstraction is the right size. The
|
|
66
|
+
sibling lenses are about whether the gaps between them are well-shaped
|
|
67
|
+
and whether the language is consistent.
|
|
68
|
+
|
|
69
|
+
## Deletion test (Phase 2 prep)
|
|
70
|
+
|
|
71
|
+
For each candidate this lens flags, the Phase-2 deletion test asks:
|
|
72
|
+
|
|
73
|
+
> If I deleted `{Symbol}` and inlined its body at every call site, what
|
|
74
|
+
> domain meaning would be lost?
|
|
75
|
+
|
|
76
|
+
If the answer is "nothing — it was just a name on a syntactic shape",
|
|
77
|
+
the deletion test passes and the candidate is high-priority for refactor
|
|
78
|
+
(remove the abstraction; the area gets shallower in surface area but
|
|
79
|
+
deeper in meaning per remaining concept).
|
|
80
|
+
|
|
81
|
+
If the answer is "we'd lose the {domain concept} as a first-class
|
|
82
|
+
thing in the code", the deletion test fails — the abstraction was
|
|
83
|
+
earning its keep, just maybe at the wrong depth. Re-scope to a sibling
|
|
84
|
+
lens.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Adapted from Matt Pocock's MIT-licensed skill suite:
|
|
3
|
+
https://github.com/mattpocock/skills/blob/main/skills/engineering/improve-codebase-architecture/INTERFACE-DESIGN.md
|
|
4
|
+
Licensed under MIT. Modifications: scoped to Aperant's apt:improve
|
|
5
|
+
Phase-1 explore step and aligned with apt:review Pass 4's boundary
|
|
6
|
+
audit semantics (this lens is proactive; Pass 4 is reactive).
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# INTERFACE-DESIGN — Boundary-shape lens
|
|
10
|
+
|
|
11
|
+
This lens asks: **are the boundaries between modules well-shaped?** Are
|
|
12
|
+
there feature-envy patterns? Hidden coupling? Async leakage? Boundary
|
|
13
|
+
violations the reactive `apt:review` Pass 4 audit would catch if a diff
|
|
14
|
+
crossed them, but which currently exist statically and nobody is
|
|
15
|
+
auditing?
|
|
16
|
+
|
|
17
|
+
## Red flags this lens surfaces
|
|
18
|
+
|
|
19
|
+
### Feature envy
|
|
20
|
+
A method in module A spends most of its time reading fields from
|
|
21
|
+
module B's types. The behavior wants to live in B but the import
|
|
22
|
+
direction made it land in A. Symptom: lots of `b.x`, `b.y`, `b.z`
|
|
23
|
+
accesses in A's methods.
|
|
24
|
+
|
|
25
|
+
### Hidden coupling
|
|
26
|
+
Module A imports module B by accident — not because B's exported
|
|
27
|
+
surface is being used, but because B re-exports something A actually
|
|
28
|
+
wanted from a third place. Symptom: `import { foo } from './b'` where
|
|
29
|
+
`foo` is defined in C and B is just a passthrough.
|
|
30
|
+
|
|
31
|
+
### Async leakage
|
|
32
|
+
A function in A returns a Promise, but the work it kicks off settles
|
|
33
|
+
asynchronously somewhere else (timer, event handler, background job).
|
|
34
|
+
The caller can `await` the Promise and think they're done, but the
|
|
35
|
+
real work is still in flight. Symptom: tests pass synchronously but
|
|
36
|
+
real-world behavior is racy.
|
|
37
|
+
|
|
38
|
+
### Wide-then-narrow interfaces
|
|
39
|
+
Module A exports 30 functions, but only 3 are called externally. The
|
|
40
|
+
other 27 are accidental surface. Symptom: `index.ts` exports `*`.
|
|
41
|
+
|
|
42
|
+
### Pass-through importers
|
|
43
|
+
Module A exports `foo` which it imports from B and re-exports
|
|
44
|
+
unchanged. Adds a hop with no value. Symptom: A's body contains
|
|
45
|
+
`export { foo } from './b'` and nothing else for that symbol.
|
|
46
|
+
|
|
47
|
+
### Dependency direction violations
|
|
48
|
+
Per Aperant's import-direction convention (`packages/` never imports
|
|
49
|
+
from `cloud/`), this lens flags any backward import. The static lint
|
|
50
|
+
catches some of these; this lens catches the rest (e.g., implicit type
|
|
51
|
+
re-exports that leak `cloud/` types into `packages/`).
|
|
52
|
+
|
|
53
|
+
## Apply in Phase 1
|
|
54
|
+
|
|
55
|
+
When the explore step scans the named area:
|
|
56
|
+
|
|
57
|
+
1. For each module boundary (file-level or directory-level), identify
|
|
58
|
+
the explicit imports + exports.
|
|
59
|
+
2. Look for the 6 red flags above.
|
|
60
|
+
3. Note in the inventory: `{Module A} ↔ {Module B} — {red-flag name}
|
|
61
|
+
({one-line evidence})`.
|
|
62
|
+
|
|
63
|
+
## Distinguishing this from DEEPENING and LANGUAGE
|
|
64
|
+
|
|
65
|
+
| Lens | Question |
|
|
66
|
+
|---|---|
|
|
67
|
+
| **DEEPENING** | Does each abstraction earn its keep at its current depth? |
|
|
68
|
+
| **INTERFACE-DESIGN** | Are the gaps between abstractions well-shaped? |
|
|
69
|
+
| **LANGUAGE** | Does the codebase use the same word for the same thing? |
|
|
70
|
+
|
|
71
|
+
A red flag in one lens often surfaces in another, but the lens is the
|
|
72
|
+
diagnostic angle. A god-object problem is DEEPENING (the abstraction
|
|
73
|
+
is too deep AND too wide); a feature-envy problem is INTERFACE-DESIGN
|
|
74
|
+
(the boundary is in the wrong place).
|
|
75
|
+
|
|
76
|
+
## Deletion test (Phase 2 prep)
|
|
77
|
+
|
|
78
|
+
For each candidate this lens flags, the Phase-2 deletion test asks:
|
|
79
|
+
|
|
80
|
+
> If I moved this code across the boundary it currently sits behind
|
|
81
|
+
> (or removed the boundary entirely), what would break?
|
|
82
|
+
|
|
83
|
+
If the answer is "nothing important — the boundary was an accident",
|
|
84
|
+
the deletion test passes and the candidate is high-priority for
|
|
85
|
+
refactor (move the code; the boundary disappears).
|
|
86
|
+
|
|
87
|
+
If the answer is "we'd lose the ability to test / mock / version this
|
|
88
|
+
slice independently", the deletion test fails — the boundary was
|
|
89
|
+
earning its keep, even if the shape is awkward. Re-scope to "reshape"
|
|
90
|
+
rather than "remove".
|
|
91
|
+
|
|
92
|
+
## What this lens does NOT cover
|
|
93
|
+
|
|
94
|
+
- Whether the abstractions on either side of the boundary are deep
|
|
95
|
+
enough → see `DEEPENING.md`
|
|
96
|
+
- Whether the boundary's types and method names use the codebase's
|
|
97
|
+
domain language → see `LANGUAGE.md`
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Adapted from Matt Pocock's MIT-licensed skill suite:
|
|
3
|
+
https://github.com/mattpocock/skills/blob/main/skills/engineering/improve-codebase-architecture/LANGUAGE.md
|
|
4
|
+
Licensed under MIT. Modifications: scoped to Aperant's apt:improve
|
|
5
|
+
Phase-1 explore step and aligned with CONTEXT.md's aliases-to-avoid
|
|
6
|
+
field — this lens reads that field to catch term conflations.
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# LANGUAGE — Naming-consistency lens
|
|
10
|
+
|
|
11
|
+
This lens asks: **does the codebase use the same word for the same
|
|
12
|
+
thing?** Do field names match domain language? Is CONTEXT.md's
|
|
13
|
+
"aliases to avoid" list violated anywhere?
|
|
14
|
+
|
|
15
|
+
Naming inconsistency is invisible until you trip over it. A reader who
|
|
16
|
+
hits `userId` in one file and `user_id` in another, or `account` in
|
|
17
|
+
the UI and `customer` in the backend, has to mentally translate
|
|
18
|
+
between vocabularies — and that translation cost accumulates across
|
|
19
|
+
every code review and every onboarding.
|
|
20
|
+
|
|
21
|
+
## Red flags this lens surfaces
|
|
22
|
+
|
|
23
|
+
### Same concept, two names
|
|
24
|
+
The codebase has `user`, `account`, and `customer` referring to the
|
|
25
|
+
same entity in different layers. Pick one and rename. CONTEXT.md's
|
|
26
|
+
"aliases to avoid" field is the canonical place to record which name
|
|
27
|
+
won.
|
|
28
|
+
|
|
29
|
+
### Same name, two concepts
|
|
30
|
+
The codebase has two distinct `Session` types — one for an auth
|
|
31
|
+
session and one for a chat session. Disambiguate with a domain prefix
|
|
32
|
+
(`AuthSession`, `ChatSession`) so a reader doesn't have to import the
|
|
33
|
+
right one based on file location.
|
|
34
|
+
|
|
35
|
+
### Field-name drift across layers
|
|
36
|
+
The backend stores `created_at`, the API returns `createdAt`, the UI
|
|
37
|
+
displays `Date created`. The serialization layer becomes a translation
|
|
38
|
+
graveyard. Standardize across all three layers.
|
|
39
|
+
|
|
40
|
+
### Implementation-detail names
|
|
41
|
+
Field or symbol names that describe *how* something is stored or
|
|
42
|
+
computed rather than *what* it represents. `is_processed_boolean` vs
|
|
43
|
+
`is_processed`. `temp_holder_arr` vs `pending_items`.
|
|
44
|
+
|
|
45
|
+
### CONTEXT.md violations
|
|
46
|
+
If `CONTEXT.md` declares "Plan thread" with aliases-to-avoid: "Plan
|
|
47
|
+
session, plan chat", any code in the area that calls it a "plan
|
|
48
|
+
session" or "plan chat" is a violation. Grep CONTEXT.md aliases as
|
|
49
|
+
part of this lens.
|
|
50
|
+
|
|
51
|
+
## Apply in Phase 1
|
|
52
|
+
|
|
53
|
+
When the explore step scans the named area:
|
|
54
|
+
|
|
55
|
+
1. Read `CONTEXT.md` (if present) — every term-block's `Aliases to
|
|
56
|
+
avoid` field becomes a grep target.
|
|
57
|
+
2. Grep the area for each alias. Each hit is a candidate.
|
|
58
|
+
3. Look for the 4 other red flags above by inspection.
|
|
59
|
+
4. Note in the inventory: `{File}:{Line} — uses {wrong-term} for
|
|
60
|
+
{canonical-term} ({CONTEXT.md reference if applicable})`.
|
|
61
|
+
|
|
62
|
+
## Apply in Phase 3 (deepening loop)
|
|
63
|
+
|
|
64
|
+
When the user picks a LANGUAGE candidate, the deepening loop should
|
|
65
|
+
write the canonical decision into CONTEXT.md via `apt-tools context
|
|
66
|
+
write`:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
apt-tools context write . \
|
|
70
|
+
--term "{canonical}" \
|
|
71
|
+
--definition "{one-line}" \
|
|
72
|
+
--aliases-to-avoid "{loser1}, {loser2}"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This is the cycle: LANGUAGE lens surfaces conflations → user picks the
|
|
76
|
+
canonical term → CONTEXT.md upserts the term-block → future LANGUAGE
|
|
77
|
+
passes use CONTEXT.md as the grep source.
|
|
78
|
+
|
|
79
|
+
## Distinguishing this from DEEPENING and INTERFACE-DESIGN
|
|
80
|
+
|
|
81
|
+
A symbol can have a perfectly good name and still be the wrong depth
|
|
82
|
+
(DEEPENING) or sit behind the wrong boundary (INTERFACE-DESIGN).
|
|
83
|
+
LANGUAGE is orthogonal — it asks "regardless of where this lives or
|
|
84
|
+
how big it is, does its name match the codebase's vocabulary?"
|
|
85
|
+
|
|
86
|
+
## Deletion test (Phase 2 prep)
|
|
87
|
+
|
|
88
|
+
The deletion test for LANGUAGE candidates is unusual: deleting the
|
|
89
|
+
*wrong* name doesn't help unless you replace it with the right one. So
|
|
90
|
+
the Phase-2 priority rubric for LANGUAGE candidates is:
|
|
91
|
+
|
|
92
|
+
> Number of call sites that read with friction × cost of rename
|
|
93
|
+
> divided by ergonomic gain.
|
|
94
|
+
|
|
95
|
+
High-call-site, cheap-rename, real-confusion candidates are
|
|
96
|
+
high-priority. One-off conflations that aren't blocking anyone are
|
|
97
|
+
low-priority — record them in CONTEXT.md and move on.
|
|
98
|
+
|
|
99
|
+
## What this lens does NOT cover
|
|
100
|
+
|
|
101
|
+
- Abstraction depth → `DEEPENING.md`
|
|
102
|
+
- Boundary shape → `INTERFACE-DESIGN.md`
|
|
103
|
+
|
|
104
|
+
LANGUAGE is read-only of the symbol's *name*, not its *shape*.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apt:improve
|
|
3
|
+
description: "Proactive refactor discovery — scan a named area through DEEPENING / INTERFACE-DESIGN / LANGUAGE lenses, present top candidates, deepen via grill loop."
|
|
4
|
+
apt-skill-version: {{APT_VERSION}}
|
|
5
|
+
stage: plan
|
|
6
|
+
intent: investigate
|
|
7
|
+
when_to_use: "The user feels code has rotted and wants a refactor surface (not a feature). Triggers: 'this part of the codebase needs work', 'I want to refactor X but don't know where to start', 'show me what's worth refactoring in Y'."
|
|
8
|
+
user_invocable: true
|
|
9
|
+
internal: false
|
|
10
|
+
spawns_agent: true
|
|
11
|
+
agent_name: "apt-improver"
|
|
12
|
+
task_context: create-new
|
|
13
|
+
default_track: DEEP
|
|
14
|
+
default_execution_mode: step
|
|
15
|
+
execution_modes:
|
|
16
|
+
- auto
|
|
17
|
+
- step
|
|
18
|
+
allowed-tools: "Read, Grep, Glob, Bash"
|
|
19
|
+
argument-hint: "apt:improve [area-name]"
|
|
20
|
+
gates: []
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Improve — Proactive Refactor Discovery
|
|
24
|
+
|
|
25
|
+
Open question #2 in the Pocock adoption spec was answered concretely:
|
|
26
|
+
`apt:review` Pass 4 (architecture) is strictly **reactive** — it audits
|
|
27
|
+
the current diff for boundary violations. The work-intent "look at this
|
|
28
|
+
codebase and tell me what to refactor proactively" has no home today
|
|
29
|
+
(users retrofit it onto `apt:discuss --brainstorm` or `/apt:roundtable`,
|
|
30
|
+
both scope-mismatched). This skill is that home.
|
|
31
|
+
|
|
32
|
+
**Pocock adoption attribution.** 3-phase workflow + DEEPENING /
|
|
33
|
+
INTERFACE-DESIGN / LANGUAGE lenses ported from Matt Pocock's MIT-licensed
|
|
34
|
+
`improve-codebase-architecture` skill. Aperant-specific: spawns the
|
|
35
|
+
`apt-improver` agent and references `apt-discuss/appendices/grill-discipline.md`
|
|
36
|
+
as the canonical source for the autonomy-aware deepening loop rather than
|
|
37
|
+
re-stating the policy here.
|
|
38
|
+
|
|
39
|
+
## When to Use
|
|
40
|
+
|
|
41
|
+
- Feeling that an area of the codebase has rotted but unsure where to
|
|
42
|
+
start (proactive discovery)
|
|
43
|
+
- Before a multi-task refactor cycle, to surface the highest-leverage
|
|
44
|
+
candidates first
|
|
45
|
+
- After a feature has bedded in and the user wants to consolidate
|
|
46
|
+
|
|
47
|
+
## When NOT to Use
|
|
48
|
+
|
|
49
|
+
- Auditing a current diff for boundary violations — that's `/apt:review`
|
|
50
|
+
Pass 4 (reactive)
|
|
51
|
+
- Locking a specific refactor decision — use `/apt:discuss` instead
|
|
52
|
+
- Renaming or restructuring without proactive discovery — use
|
|
53
|
+
`/apt:plan` directly
|
|
54
|
+
|
|
55
|
+
## 3-Phase workflow
|
|
56
|
+
|
|
57
|
+
### Phase 1 — Explore (scan a named area for candidate refactors)
|
|
58
|
+
|
|
59
|
+
Sub-agent `apt-improver` reads:
|
|
60
|
+
|
|
61
|
+
- The named area (a noun phrase like "sparring engine", "feature
|
|
62
|
+
registry", "auth flow")
|
|
63
|
+
- `CONTEXT.md` term-blocks matching the area (if present)
|
|
64
|
+
- Relevant files via Glob/Grep
|
|
65
|
+
|
|
66
|
+
It applies three lenses, each described in its own sub-file:
|
|
67
|
+
|
|
68
|
+
- **DEEPENING** (`DEEPENING.md`) — does this area model the domain at
|
|
69
|
+
the right depth? Are abstractions earning their keep, or are they
|
|
70
|
+
shallow wrappers hiding nothing?
|
|
71
|
+
- **INTERFACE-DESIGN** (`INTERFACE-DESIGN.md`) — are the boundaries
|
|
72
|
+
between modules well-shaped? Are there feature-envy patterns? Hidden
|
|
73
|
+
coupling? Async leakage?
|
|
74
|
+
- **LANGUAGE** (`LANGUAGE.md`) — does the codebase use the same word
|
|
75
|
+
for the same thing? Do field names match domain language? Is
|
|
76
|
+
CONTEXT.md's "aliases to avoid" list violated anywhere?
|
|
77
|
+
|
|
78
|
+
Output: a Phase-1 inventory of **candidate refactors** with one-line
|
|
79
|
+
diagnoses per candidate.
|
|
80
|
+
|
|
81
|
+
### Phase 2 — Present candidates (top 3-5 with deletion-test rationale)
|
|
82
|
+
|
|
83
|
+
The skill body filters the Phase-1 inventory down to 3-5 candidates
|
|
84
|
+
using the **deletion test**: for each candidate, ask "if I deleted this
|
|
85
|
+
abstraction, what would break?" If the answer is "nothing important",
|
|
86
|
+
the candidate is high-priority (the abstraction was paying no rent).
|
|
87
|
+
|
|
88
|
+
Output to the user:
|
|
89
|
+
|
|
90
|
+
```markdown
|
|
91
|
+
## Refactor candidates for {area}
|
|
92
|
+
|
|
93
|
+
1. **{Candidate title}** — {one-line diagnosis}.
|
|
94
|
+
Deletion test: {what breaks if removed} → {priority: high/med/low}.
|
|
95
|
+
|
|
96
|
+
2. ...
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Phase 3 — Deepen via grill loop (autonomy-aware)
|
|
100
|
+
|
|
101
|
+
The user picks one or more candidates. For each picked candidate, the
|
|
102
|
+
skill enters a deepening loop. **This loop references
|
|
103
|
+
`apt-discuss/appendices/grill-discipline.md` as the canonical source**
|
|
104
|
+
for autonomy-aware degradation:
|
|
105
|
+
|
|
106
|
+
- Autonomy 1: ask the user about every load-bearing design question
|
|
107
|
+
- Autonomy 2: batch-recommend per decision, user reviews at end
|
|
108
|
+
- Autonomy 3: auto-lock with the 3 escalation triggers (conflict with
|
|
109
|
+
prior locked decision; critical-path file touched; no defensible
|
|
110
|
+
default)
|
|
111
|
+
|
|
112
|
+
The deepening loop produces a concrete refactor plan (which becomes
|
|
113
|
+
`/apt:plan`'s input on a subsequent invocation).
|
|
114
|
+
|
|
115
|
+
## Sub-files (MIT-attributed)
|
|
116
|
+
|
|
117
|
+
- `DEEPENING.md` — domain-modeling depth lens
|
|
118
|
+
- `INTERFACE-DESIGN.md` — boundary-shape lens
|
|
119
|
+
- `LANGUAGE.md` — naming-consistency lens
|
|
120
|
+
|
|
121
|
+
All three are ported from Matt Pocock's improve-codebase-architecture
|
|
122
|
+
skill with MIT attribution per AC15.
|
|
123
|
+
|
|
124
|
+
## Agent spawned
|
|
125
|
+
|
|
126
|
+
`apt-improver` (definition at `packages/framework/agents/apt-improver.md`)
|
|
127
|
+
runs Phase 1 — the codebase scan. Phases 2 and 3 run inline in the
|
|
128
|
+
parent agent (no separate sub-agent) because they require user
|
|
129
|
+
interaction for the candidate filter + the deepening loop.
|
|
130
|
+
|
|
131
|
+
## Output contract
|
|
132
|
+
|
|
133
|
+
- Phase 1 outputs a candidate inventory to stdout (not persisted).
|
|
134
|
+
- Phase 2 outputs the top 3-5 to stdout for user selection.
|
|
135
|
+
- Phase 3 (deepening loop) writes locked decisions to
|
|
136
|
+
`.aperant/context/notes/{task-id}.md` via `apt-tools context write`
|
|
137
|
+
and `apt-tools adr write` (the latter only when Nygard's 3-gate
|
|
138
|
+
filter passes — most refactor decisions are reversible and stay in
|
|
139
|
+
context-notes).
|
|
140
|
+
- The skill does NOT emit an implementation plan — that's `/apt:plan`'s
|
|
141
|
+
job. apt:improve produces *what to refactor*; apt:plan produces *how*.
|