@aperant/framework 0.7.0 → 0.7.3
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 +180 -0
- package/agents/apt-planner.md +12 -0
- package/agents/apt-pr-review-fixer.md +13 -9
- package/bin/apt-tools.mjs +7 -0
- package/dist/cli/ci-watch/stop-matrix.d.mts.map +1 -1
- package/dist/cli/ci-watch/stop-matrix.mjs +16 -0
- package/dist/cli/ci-watch/stop-matrix.mjs.map +1 -1
- package/dist/cli/commands/ci-watch.d.mts +11 -0
- package/dist/cli/commands/ci-watch.d.mts.map +1 -1
- package/dist/cli/commands/ci-watch.mjs +108 -2
- package/dist/cli/commands/ci-watch.mjs.map +1 -1
- package/dist/cli/commands/features-audit.d.mts +24 -0
- package/dist/cli/commands/features-audit.d.mts.map +1 -1
- package/dist/cli/commands/features-audit.mjs +159 -5
- package/dist/cli/commands/features-audit.mjs.map +1 -1
- package/dist/cli/commands/health-check.d.mts +16 -0
- package/dist/cli/commands/health-check.d.mts.map +1 -1
- package/dist/cli/commands/health-check.mjs +118 -2
- package/dist/cli/commands/health-check.mjs.map +1 -1
- package/dist/cli/commands/init.d.mts +9 -0
- package/dist/cli/commands/init.d.mts.map +1 -1
- package/dist/cli/commands/init.mjs +49 -4
- package/dist/cli/commands/init.mjs.map +1 -1
- package/dist/cli/commands/modes.d.mts.map +1 -1
- package/dist/cli/commands/modes.mjs +11 -0
- package/dist/cli/commands/modes.mjs.map +1 -1
- package/dist/cli/commands/pr-review-audit-fixer.d.mts +13 -0
- package/dist/cli/commands/pr-review-audit-fixer.d.mts.map +1 -1
- package/dist/cli/commands/pr-review-audit-fixer.mjs +18 -5
- package/dist/cli/commands/pr-review-audit-fixer.mjs.map +1 -1
- package/dist/cli/commands/task.d.mts.map +1 -1
- package/dist/cli/commands/task.mjs +84 -5
- package/dist/cli/commands/task.mjs.map +1 -1
- package/dist/cli/commands/validate-evidence.d.mts +24 -2
- package/dist/cli/commands/validate-evidence.d.mts.map +1 -1
- package/dist/cli/commands/validate-evidence.mjs +154 -17
- package/dist/cli/commands/validate-evidence.mjs.map +1 -1
- package/dist/cli/commands/vitest-doctor.d.mts +2 -0
- package/dist/cli/commands/vitest-doctor.d.mts.map +1 -0
- package/dist/cli/commands/vitest-doctor.mjs +168 -0
- package/dist/cli/commands/vitest-doctor.mjs.map +1 -0
- package/dist/cli/config/gitignore-drift.d.mts +23 -1
- package/dist/cli/config/gitignore-drift.d.mts.map +1 -1
- package/dist/cli/config/gitignore-drift.mjs +81 -3
- package/dist/cli/config/gitignore-drift.mjs.map +1 -1
- package/dist/cli/config/load.d.mts +56 -2
- package/dist/cli/config/load.d.mts.map +1 -1
- package/dist/cli/config/load.mjs +192 -2
- package/dist/cli/config/load.mjs.map +1 -1
- package/dist/cli/consistency/parse-review.mjs +7 -0
- package/dist/cli/consistency/parse-review.mjs.map +1 -1
- package/dist/cli/dispatch.d.mts.map +1 -1
- package/dist/cli/dispatch.mjs +24 -2
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/gate/gates/gitignore-in-sync.d.mts +1 -1
- package/dist/cli/gate/gates/gitignore-in-sync.d.mts.map +1 -1
- package/dist/cli/gate/gates/gitignore-in-sync.mjs +5 -2
- package/dist/cli/gate/gates/gitignore-in-sync.mjs.map +1 -1
- package/dist/cli/gate/gates/review-clean.d.mts +5 -1
- package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
- package/dist/cli/gate/gates/review-clean.mjs +23 -18
- package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
- package/dist/cli/gate/gates/verify-approved.d.mts +49 -1
- package/dist/cli/gate/gates/verify-approved.d.mts.map +1 -1
- package/dist/cli/gate/gates/verify-approved.mjs +93 -14
- package/dist/cli/gate/gates/verify-approved.mjs.map +1 -1
- package/dist/cli/help.d.mts.map +1 -1
- package/dist/cli/help.mjs +7 -2
- package/dist/cli/help.mjs.map +1 -1
- package/dist/cli/install/runtime-detect.d.mts +13 -0
- package/dist/cli/install/runtime-detect.d.mts.map +1 -1
- package/dist/cli/install/runtime-detect.mjs +9 -0
- package/dist/cli/install/runtime-detect.mjs.map +1 -1
- package/dist/cli/task/index-md.d.mts.map +1 -1
- package/dist/cli/task/index-md.mjs +14 -2
- package/dist/cli/task/index-md.mjs.map +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +11 -2
- package/dist/plugin/agents/apt-improver.md +99 -0
- package/dist/plugin/agents/apt-planner.md +127 -10
- package/dist/plugin/agents/apt-pr-review-fixer.md +13 -9
- package/dist/plugin/skills/apt/SKILL.md +1 -0
- package/dist/plugin/skills/apt-close-task/SKILL.md +63 -1
- package/dist/plugin/skills/apt-debug/SKILL.md +39 -6
- package/dist/plugin/skills/apt-debug/appendices/diagnose-discipline.md +119 -0
- package/dist/plugin/skills/apt-diagram/SKILL.md +378 -0
- package/dist/plugin/skills/apt-diagram/appendices/design-discipline.md +97 -0
- package/dist/plugin/skills/apt-discuss/SKILL.md +72 -5
- package/dist/plugin/skills/apt-discuss/appendices/grill-discipline.md +104 -0
- package/dist/plugin/skills/apt-discuss/appendices/zoom-out-helper.md +79 -0
- package/dist/plugin/skills/apt-execute/SKILL.md +57 -5
- package/dist/plugin/skills/apt-execute/appendices/tdd-mode.md +107 -0
- package/dist/plugin/skills/apt-improve/DEEPENING.md +84 -0
- package/dist/plugin/skills/apt-improve/INTERFACE-DESIGN.md +97 -0
- package/dist/plugin/skills/apt-improve/LANGUAGE.md +104 -0
- package/dist/plugin/skills/apt-improve/SKILL.md +141 -0
- package/dist/plugin/skills/apt-plan/SKILL.md +171 -4
- package/dist/plugin/skills/apt-plan/adapters/conductor.md +98 -0
- package/dist/plugin/skills/apt-pr-review/SKILL.md +57 -18
- package/dist/plugin/skills/apt-prototype/LOGIC.md +109 -0
- package/dist/plugin/skills/apt-prototype/SKILL.md +143 -0
- package/dist/plugin/skills/apt-prototype/UI.md +90 -0
- package/dist/plugin/skills/apt-quick/SKILL.md +49 -8
- package/dist/plugin/skills/apt-release-notes/SKILL.md +193 -0
- package/dist/plugin/skills/apt-release-notes/appendices/persona-voice.md +59 -0
- package/dist/plugin/skills/apt-review/SKILL.md +2 -0
- package/dist/plugin/skills/apt-run/SKILL.md +32 -4
- package/dist/plugin/skills/apt-setup/SKILL.md +308 -6
- package/dist/plugin/skills/apt-ship/SKILL.md +122 -1
- package/dist/plugin/skills/apt-spar/SKILL.md +315 -0
- package/dist/plugin/skills/apt-triage/AGENT-BRIEF.md +84 -0
- package/dist/plugin/skills/apt-triage/OUT-OF-SCOPE.md +75 -0
- package/dist/plugin/skills/apt-triage/SKILL.md +169 -0
- package/dist/plugin/skills/apt-update/SKILL.md +77 -10
- package/dist/plugin/skills/apt-verify/SKILL.md +3 -0
- package/dist/plugin/skills/apt-verify-proof/SKILL.md +10 -5
- package/dist/plugin/skills/apt-watch-ci/SKILL.md +166 -0
- package/dist/plugin/skills/apt-zoom-out/SKILL.md +130 -0
- package/package.json +133 -133
- package/prompts/conductor-framework-context.md +63 -0
- package/prompts/conductor-system.md +11 -0
- package/skills/apt-close-task/SKILL.md +1 -0
- package/skills/apt-discuss/SKILL.md +47 -5
- package/skills/apt-execute/SKILL.md +9 -0
- package/skills/apt-plan/SKILL.md +12 -0
- package/skills/apt-pr-review/SKILL.md +11 -2
- package/skills/apt-quick/SKILL.md +19 -8
- package/skills/apt-researcher.md +1 -0
- package/skills/apt-setup/SKILL.md +33 -2
- package/skills/apt-verify-proof/SKILL.md +7 -5
- package/src/cli/ci-watch/stop-matrix.mjs +17 -0
- package/src/cli/commands/ci-watch.mjs +113 -2
- package/src/cli/commands/features-audit.mjs +164 -5
- package/src/cli/commands/health-check.mjs +115 -2
- package/src/cli/commands/init.mjs +52 -4
- package/src/cli/commands/modes.mjs +11 -0
- package/src/cli/commands/pr-review-audit-fixer.mjs +18 -5
- package/src/cli/commands/task.mjs +83 -5
- package/src/cli/commands/validate-evidence.mjs +158 -17
- package/src/cli/commands/vitest-doctor.mjs +173 -0
- package/src/cli/config/gitignore-drift.mjs +74 -3
- package/src/cli/config/load.mjs +188 -2
- package/src/cli/consistency/parse-review.mjs +6 -0
- package/src/cli/dispatch.mjs +23 -2
- package/src/cli/gate/gates/gitignore-in-sync.mjs +5 -2
- package/src/cli/gate/gates/review-clean.mjs +24 -19
- package/src/cli/gate/gates/verify-approved.mjs +97 -14
- package/src/cli/help.mjs +7 -2
- package/src/cli/install/runtime-detect.mjs +9 -0
- package/src/cli/task/index-md.mjs +15 -2
- package/templates/config.json +2 -7
- package/workflows/verify-proof.md +8 -3
|
@@ -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*.
|
|
@@ -99,6 +99,18 @@ For STANDARD and COMPLEX tasks:
|
|
|
99
99
|
- Test files that will need updates
|
|
100
100
|
- Configuration that may need changes
|
|
101
101
|
|
|
102
|
+
### 4.4. React state guidance — sync-store vs render-committed ref (BUG-025-planner)
|
|
103
|
+
|
|
104
|
+
When a planned event handler fires a flush/persist immediately after mutating a Zustand/Jotai/refs-stored store, the spec MUST recommend reading from `store.getState()` (or the equivalent direct-read primitive) on the synchronous path, NOT from a `useRef`-populated-by-`useEffect`.
|
|
105
|
+
|
|
106
|
+
Why: refs populated via `useEffect` lag the store by exactly one render cycle. A handler that mutates the store and immediately reads the ref sees the pre-mutation value, silently corrupting persists and order-of-operations contracts. Reference pattern: `apps/desktop/src/renderer/src/App.tsx::runUpsertForIds` (post-fix commit `4c263856`).
|
|
107
|
+
|
|
108
|
+
Investigation checklist when the task touches a Zustand/Jotai store or any handler that does flush-after-mutate:
|
|
109
|
+
|
|
110
|
+
- Grep for `useRef(` references that cache store state (e.g. `const fooRef = useRef(foo)` populated by `useEffect(() => { fooRef.current = foo }, [foo])`).
|
|
111
|
+
- If the spec or planned subtasks read from such a ref on a synchronous path that ALSO mutates the store, recommend `store.getState()` (or `useFooStore.getState()`) as the read primitive.
|
|
112
|
+
- Note the caveat explicitly in the spec's Implementation Decisions section so the executor doesn't silently revert it.
|
|
113
|
+
|
|
102
114
|
### 4.5. Consume design.md (C24)
|
|
103
115
|
|
|
104
116
|
If `{task_dir}/design.md` exists (emitted by a prior `/apt:design` run), load it before decomposing subtasks:
|
|
@@ -110,7 +122,17 @@ If `{task_dir}/design.md` exists (emitted by a prior `/apt:design` run), load it
|
|
|
110
122
|
|
|
111
123
|
## 5. Write Specification
|
|
112
124
|
|
|
113
|
-
Create `spec.md` in the task directory (`{task_dir}` passed from the router, e.g. `.aperant/tasks/{task-id}/spec.md`)
|
|
125
|
+
Create `spec.md` in the task directory (`{task_dir}` passed from the router, e.g. `.aperant/tasks/{task-id}/spec.md`).
|
|
126
|
+
|
|
127
|
+
**Content format branches on track (Fast Path Guarantee — Pocock adoption ID-05):**
|
|
128
|
+
|
|
129
|
+
### 5.A. QUICK track — legacy 4-section format (hard-exempt from PRD upgrade)
|
|
130
|
+
|
|
131
|
+
When `track === "QUICK"` (the `apt:classify` rubric routed this as a one-shot
|
|
132
|
+
task) OR the complexity is `SIMPLE`, write the existing minimal 4-section
|
|
133
|
+
spec. Do NOT promote to PRD shape. The QUICK path is a constraint, not a
|
|
134
|
+
toggle — the user opted into one-shot speed; PRD ceremony would violate
|
|
135
|
+
that contract.
|
|
114
136
|
|
|
115
137
|
```markdown
|
|
116
138
|
# Task: {task description}
|
|
@@ -131,6 +153,79 @@ Create `spec.md` in the task directory (`{task_dir}` passed from the router, e.g
|
|
|
131
153
|
{What this task explicitly does NOT cover}
|
|
132
154
|
```
|
|
133
155
|
|
|
156
|
+
### 5.B. STANDARD / DEEP / COMPLEX tracks — PRD-shaped spec.md
|
|
157
|
+
|
|
158
|
+
When `track ∈ {"STANDARD", "DEEP"}` OR complexity is `STANDARD` or
|
|
159
|
+
`COMPLEX`, write a PRD-shaped spec.md so the artifact survives the task
|
|
160
|
+
and is committable as a second-consumer document. Section ordering is
|
|
161
|
+
**load-bearing** — downstream tooling (`apt-tools coverage-check`,
|
|
162
|
+
`apt-tools consistency check`) reads sections by header.
|
|
163
|
+
|
|
164
|
+
```markdown
|
|
165
|
+
# Spec: {task title}
|
|
166
|
+
|
|
167
|
+
**Task ID:** {task-id}
|
|
168
|
+
**Track:** {STANDARD | DEEP}
|
|
169
|
+
**Scope:** {framework | desktop | web | core | ui | backend | docs}
|
|
170
|
+
|
|
171
|
+
## Problem Statement
|
|
172
|
+
|
|
173
|
+
{What pain are we solving? Cite empirical evidence, prior decisions, or
|
|
174
|
+
codebase artifacts where possible. State what's broken or missing today.}
|
|
175
|
+
|
|
176
|
+
## Solution
|
|
177
|
+
|
|
178
|
+
{One paragraph: the chosen approach. Then a bulleted net delta of what
|
|
179
|
+
ships: new files, modified files, new flags, new config, new skills.}
|
|
180
|
+
|
|
181
|
+
## User Stories
|
|
182
|
+
|
|
183
|
+
{One story per user value slice. Format: "**US-NN (persona).** As a
|
|
184
|
+
{persona}, when I {trigger}, I want {behavior} so I can {outcome}."
|
|
185
|
+
Stories map 1:1 onto subtasks in implementation_plan.json.}
|
|
186
|
+
|
|
187
|
+
## Implementation Decisions
|
|
188
|
+
|
|
189
|
+
{Load-bearing principles carried forward into every subtask. Format:
|
|
190
|
+
"### ID-NN: {decision title}" + rationale + practical consequence. Each
|
|
191
|
+
ID-NN is referenced from subtask descriptions where relevant.}
|
|
192
|
+
|
|
193
|
+
## Testing Decisions
|
|
194
|
+
|
|
195
|
+
{One block per test family: "### TD-NN: {test family name}" + what's
|
|
196
|
+
covered + which subtask owns the test file. Critical: Fast Path Guarantee
|
|
197
|
+
regression tests (QUICK-exempt assertions) MUST be enumerated here.}
|
|
198
|
+
|
|
199
|
+
## Out of Scope
|
|
200
|
+
|
|
201
|
+
{Explicit non-goals. Each bullet names what is deferred + where it
|
|
202
|
+
belongs (parallel track, v2 follow-up, separate task).}
|
|
203
|
+
|
|
204
|
+
## Further Notes
|
|
205
|
+
|
|
206
|
+
{Sequencing rationale, risk surface, dependencies on other parts of the
|
|
207
|
+
codebase, files-affected preview, and any other context the executor
|
|
208
|
+
needs but that doesn't fit the seven primary sections.}
|
|
209
|
+
|
|
210
|
+
### Acceptance Criteria
|
|
211
|
+
|
|
212
|
+
{Cross-cutting AC1..ACN list — each acceptance criterion gets a stable
|
|
213
|
+
ID. Subtasks reference these IDs via their per-subtask
|
|
214
|
+
`acceptance_criteria` field (see Section 6). This list IS the
|
|
215
|
+
plan-coverage-check input.}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Constraint — do NOT interview the user.** The PRD is synthesized from
|
|
219
|
+
the task description + codebase investigation + AGENTS.md, not from a
|
|
220
|
+
clarifying interview. If a section truly cannot be filled, write
|
|
221
|
+
`{TBD — needs user input}` so the gap is visible; do NOT pause for
|
|
222
|
+
clarification (that's `apt:discuss`'s job, not the planner's).
|
|
223
|
+
|
|
224
|
+
**Section ordering is mandatory.** `apt-tools coverage-check validate`
|
|
225
|
+
greps `## Acceptance Criteria` for AC IDs; `apt-tools consistency check`
|
|
226
|
+
greps `## Solution` and `## User Stories`. Renaming or reordering these
|
|
227
|
+
breaks downstream tooling.
|
|
228
|
+
|
|
134
229
|
### 5.1. Design Reference section (C24 — when design.md exists)
|
|
135
230
|
|
|
136
231
|
When `{task_dir}/design.md` exists, `spec.md` MUST include a `## Design Reference` section **directly below `## Requirements`**. The section cites the design artifact by relative path and enumerates which screens and components the subtasks cover. Shape:
|
|
@@ -212,35 +307,95 @@ When `status: warn` (non-blocking enforcement) and the user is in **auto mode**
|
|
|
212
307
|
|
|
213
308
|
## 6. Create Implementation Plan
|
|
214
309
|
|
|
215
|
-
Create `implementation_plan.json` in the task directory (`{task_dir}/implementation_plan.json`)
|
|
310
|
+
Create `implementation_plan.json` in the task directory (`{task_dir}/implementation_plan.json`).
|
|
311
|
+
|
|
312
|
+
**Subtask schema branches on track (Pocock adoption ID-05 — Fast Path Guarantee).**
|
|
313
|
+
|
|
314
|
+
### 6.A. QUICK track / SIMPLE complexity — legacy flat subtask schema
|
|
216
315
|
|
|
217
316
|
```json
|
|
218
317
|
{
|
|
219
318
|
"task": "{task description}",
|
|
220
|
-
"complexity": "simple
|
|
319
|
+
"complexity": "simple",
|
|
221
320
|
"spec": "spec.md",
|
|
321
|
+
"subtasks": [
|
|
322
|
+
{
|
|
323
|
+
"id": "1",
|
|
324
|
+
"title": "{subtask title}",
|
|
325
|
+
"description": "{what to do — concrete, not vague}",
|
|
326
|
+
"files": ["path/to/file1.ts", "path/to/file2.ts"],
|
|
327
|
+
"dependencies": [],
|
|
328
|
+
"status": "pending",
|
|
329
|
+
"verification": "{command or check to verify completion}"
|
|
330
|
+
}
|
|
331
|
+
]
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
QUICK subtasks omit `hitl`, `afk`, `acceptance_criteria`, and `user_value`
|
|
336
|
+
fields. The one-shot path doesn't need user-value framing or per-subtask
|
|
337
|
+
HITL gates.
|
|
338
|
+
|
|
339
|
+
### 6.B. STANDARD / DEEP / COMPLEX — vertical-slice subtask schema
|
|
340
|
+
|
|
341
|
+
```json
|
|
342
|
+
{
|
|
343
|
+
"task": "{task description}",
|
|
344
|
+
"complexity": "standard|complex",
|
|
345
|
+
"spec": "spec.md",
|
|
346
|
+
"vertical_slice_schema_version": "1",
|
|
222
347
|
"declared_persona_tier": "primary",
|
|
223
348
|
"declared_personas": ["mobile-dev"],
|
|
224
349
|
"tier_confidence": "high",
|
|
225
350
|
"subtasks": [
|
|
226
351
|
{
|
|
227
352
|
"id": "1",
|
|
228
|
-
"title": "{subtask title}",
|
|
353
|
+
"title": "{subtask title — user-value framing, not 'add UI'}",
|
|
229
354
|
"description": "{what to do — concrete, not vague}",
|
|
230
355
|
"files": ["path/to/file1.ts", "path/to/file2.ts"],
|
|
356
|
+
"acceptance_criteria": ["AC1", "AC3"],
|
|
231
357
|
"dependencies": [],
|
|
232
358
|
"status": "pending",
|
|
359
|
+
"hitl": "required | review | none",
|
|
360
|
+
"afk": "safe | unsafe",
|
|
361
|
+
"user_value": "{one-line user-value framing — who benefits, how}",
|
|
233
362
|
"verification": "{command or check to verify completion}"
|
|
234
363
|
}
|
|
235
364
|
]
|
|
236
365
|
}
|
|
237
366
|
```
|
|
238
367
|
|
|
368
|
+
**Mandatory STANDARD/DEEP fields (per subtask):**
|
|
369
|
+
|
|
370
|
+
- `hitl` — `"required" | "review" | "none"`. `required` means a human MUST
|
|
371
|
+
approve the subtask before proceeding (autonomy 1 always pauses;
|
|
372
|
+
autonomy 2 batches recommendations; autonomy 3 escalates only on
|
|
373
|
+
conflict). `review` means the human reviews the diff after the agent
|
|
374
|
+
ships it (post-hoc, not blocking). `none` means agent-only.
|
|
375
|
+
- `afk` — `"safe" | "unsafe"`. `safe` means the agent may proceed
|
|
376
|
+
unattended without supervision. `unsafe` means the agent should pause
|
|
377
|
+
at the start of this subtask if no human is present (autonomy < 3).
|
|
378
|
+
- `acceptance_criteria` — `string[]` of id-refs (`"AC1"`, `"AC3"`, …)
|
|
379
|
+
into the spec.md `## Acceptance Criteria` section. Every AC in spec.md
|
|
380
|
+
MUST be referenced by at least one subtask (gate G8 consistency-check
|
|
381
|
+
enforces this on ship).
|
|
382
|
+
- `user_value` — one-line framing of WHO benefits and HOW. Prevents
|
|
383
|
+
horizontal slicing ("add UI" / "add backend") — every subtask must be
|
|
384
|
+
a vertical user-shippable slice with a defensible value framing.
|
|
385
|
+
|
|
386
|
+
**Plan-level fields for STANDARD/DEEP:**
|
|
387
|
+
|
|
388
|
+
- `vertical_slice_schema_version` — `"1"` (current). Stable across the
|
|
389
|
+
v1 schema window; bumped when the subtask shape changes incompatibly.
|
|
390
|
+
Plans without this field are treated as legacy flat schema.
|
|
391
|
+
|
|
239
392
|
Reference `prompts/planner.md` for subtask decomposition patterns:
|
|
240
393
|
- Each subtask should be completable in one focused session
|
|
241
394
|
- Dependencies must form a DAG (no circular deps)
|
|
242
395
|
- Verification must be automated (test command, grep check, type check)
|
|
243
396
|
- Files list must be exhaustive — every file the subtask touches
|
|
397
|
+
- Subtask title MUST frame user value, not file scope (e.g., "Solo
|
|
398
|
+
dogfooder gets PRD-shaped spec on STANDARD", NOT "edit apt-plan SKILL.md")
|
|
244
399
|
|
|
245
400
|
**Framework-scope doc-sync rule (C33).** When `task.scope === "framework"` AND any subtask's `files` intersect `packages/framework/src/cli/**`, the plan MUST end with a subtask whose title contains `Doc sync` (case-insensitive) and whose `files` list includes at least one of `packages/framework/skills/apt-*/SKILL.md`, `packages/framework/agents/apt-*.md`, `packages/framework/templates/agents-*.md`, or `CLAUDE.md`. The detailed rule and rationale live in `packages/framework/agents/apt-planner.md` §5.1; the planner agent appends this subtask automatically when it would otherwise be missing. Smoke-drain emits a warn-only signal for plans that violate the rule.
|
|
246
401
|
|
|
@@ -273,6 +428,18 @@ The coverage check ensures every acceptance criterion has at least one subtask w
|
|
|
273
428
|
node packages/framework/bin/apt-tools.mjs commit "plan: create implementation plan for {task}" --files spec.md implementation_plan.json
|
|
274
429
|
```
|
|
275
430
|
|
|
431
|
+
## 8a. Runtime-context adapters
|
|
432
|
+
|
|
433
|
+
If `APERANT_TERMINAL_ID` is set (you are running under the Aperant
|
|
434
|
+
Conductor — a master-orchestrator agent inside the Aperant app), see
|
|
435
|
+
`adapters/conductor.md` for the plan-review handshake convention
|
|
436
|
+
(`proceed` / `abort` / `[Conductor realignment]` stdin strings) the
|
|
437
|
+
Conductor's drawer uses post-commit. The `artifact.ready{kind:'plan'}`
|
|
438
|
+
signal itself is now emitted automatically by the `apt-tools commit`
|
|
439
|
+
postcondition — no manual emit step required. Native invocations
|
|
440
|
+
(Claude Code, Gemini, OpenCode, Codex with no Conductor context) can
|
|
441
|
+
skip the adapter entirely and proceed to Section 9.
|
|
442
|
+
|
|
276
443
|
## 9. Report
|
|
277
444
|
|
|
278
445
|
Output a summary:
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# apt-plan adapter — Aperant Conductor
|
|
2
|
+
|
|
3
|
+
This adapter is **only loaded** when the planner runs under the Aperant
|
|
4
|
+
Conductor (a master-orchestrator agent inside the Aperant desktop / web
|
|
5
|
+
app). Native invocations of `/apt:plan` (from plain Claude Code, Gemini
|
|
6
|
+
CLI, OpenCode, or Codex) IGNORE this file entirely — the framework
|
|
7
|
+
behavior in `SKILL.md` is the source of truth for them.
|
|
8
|
+
|
|
9
|
+
## When to load this adapter
|
|
10
|
+
|
|
11
|
+
Detect Conductor context by env var:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
[ -n "$APERANT_TERMINAL_ID" ]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The Conductor injects `APERANT_TERMINAL_ID` into every PTY it spawns.
|
|
18
|
+
If the var is unset, you are NOT under the Conductor — stop reading.
|
|
19
|
+
|
|
20
|
+
## What changes under the Conductor
|
|
21
|
+
|
|
22
|
+
The planner's filesystem outputs (`spec.md`, `implementation_plan.json`)
|
|
23
|
+
are unchanged. The ADDITION is one extra step after Section 8 (Persist
|
|
24
|
+
State) of `SKILL.md`:
|
|
25
|
+
|
|
26
|
+
### Plan-Ready Signal (framework-owned, no action required)
|
|
27
|
+
|
|
28
|
+
The `artifact.ready{kind:'plan'}` signal is emitted **automatically** by
|
|
29
|
+
the framework's `apt-tools commit` postcondition. When the planner
|
|
30
|
+
commits `spec.md` + `implementation_plan.json` via the standard:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
node packages/framework/bin/apt-tools.mjs commit "plan: ..." \
|
|
34
|
+
--files spec.md implementation_plan.json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
…and the process is running under a Conductor PTY (env
|
|
38
|
+
`APERANT_TERMINAL_ID` is set), `apt-tools commit` auto-emits a fully-
|
|
39
|
+
formed `artifact.ready` envelope to `.aperant/events/{today}.jsonl`.
|
|
40
|
+
The envelope carries the `task_id`, plan path, sha256 hash, and the
|
|
41
|
+
auto-stamped `terminal_id`.
|
|
42
|
+
|
|
43
|
+
This replaces the earlier markdown-discipline emit step. The earlier
|
|
44
|
+
step was correctly skipped on QUICK / SIMPLE classified tasks (Fast
|
|
45
|
+
Path Guarantee, Pocock adoption ID-05) — moving the emit to a
|
|
46
|
+
framework postcondition makes it work uniformly across QUICK, STANDARD,
|
|
47
|
+
DEEP, and COMPLEX without violating the Fast Path Guarantee.
|
|
48
|
+
|
|
49
|
+
**Planner authors don't need to do anything.** As long as you call
|
|
50
|
+
`apt-tools commit` to land your plan artifacts, the Conductor will
|
|
51
|
+
see `artifact.ready` and the drawer's PlanReadyCard will auto-promote.
|
|
52
|
+
|
|
53
|
+
If the planner does NOT use `apt-tools commit` (it lands the plan via
|
|
54
|
+
raw `git commit` or `git add`), the auto-emit will not fire. In that
|
|
55
|
+
case the Conductor falls back to filesystem polling of the task dir
|
|
56
|
+
(slightly higher latency, same outcome).
|
|
57
|
+
|
|
58
|
+
### Plan-review handshake (Step 6 + 7 of Conductor v2)
|
|
59
|
+
|
|
60
|
+
After emitting `artifact.ready{kind:'plan'}` the planner SHOULD pause at
|
|
61
|
+
an idle prompt and listen for ONE of three Conductor-driven inputs:
|
|
62
|
+
|
|
63
|
+
- `proceed\r` — the human (via the PlanReadyCard's **Approve** button)
|
|
64
|
+
approves the plan. Continue to `/apt:execute` as you would in the
|
|
65
|
+
normal flow.
|
|
66
|
+
- `abort\r` — the human rejected. Abandon this plan; do not start
|
|
67
|
+
execution. Optionally exit the session cleanly.
|
|
68
|
+
- `[Conductor realignment] <note>\r` — the human pressed **Realign**.
|
|
69
|
+
Treat the `<note>` as additional planning context: re-open spec.md /
|
|
70
|
+
implementation_plan.json, address the note's gaps, commit a new
|
|
71
|
+
revision, and emit a fresh `artifact.ready{kind:'plan'}` (with the
|
|
72
|
+
same task_id but a NEW request_id — the drawer keys cards on
|
|
73
|
+
request_id, so re-using it would suppress the new card). The
|
|
74
|
+
realignment loop can repeat; after attempt_n >= 3 the Conductor may
|
|
75
|
+
decide to respawn the terminal entirely.
|
|
76
|
+
|
|
77
|
+
These exact strings are pinned by the Conductor's `ConductorContextHost`
|
|
78
|
+
handlers (`packages/ui/src/sections/conductor/ConductorContextHost.tsx`).
|
|
79
|
+
Native CLI invocations of `/apt:plan` (no `APERANT_TERMINAL_ID`) skip
|
|
80
|
+
this handshake and follow the normal report → `/apt:execute` flow.
|
|
81
|
+
|
|
82
|
+
## Why this lives in an adapter (not in SKILL.md)
|
|
83
|
+
|
|
84
|
+
The Aperant Framework is consumed by multiple CLIs (Claude Code, Gemini,
|
|
85
|
+
OpenCode, Codex) and by the Aperant app itself. The vast majority of
|
|
86
|
+
`/apt:plan` invocations come from native CLIs — those should not see
|
|
87
|
+
or execute Conductor-specific machinery. By isolating the Conductor's
|
|
88
|
+
event-emit obligations to this adapter, the public skill stays minimal
|
|
89
|
+
and the framework remains CLI-agnostic. The pattern mirrors
|
|
90
|
+
`appendices/` (reasoning-stance loaders) but with a different semantic:
|
|
91
|
+
**runtime-context loader** — load when the runtime environment matches.
|
|
92
|
+
|
|
93
|
+
## Adding more adapters
|
|
94
|
+
|
|
95
|
+
Future runtime contexts (e.g. a hypothetical CI runner, another
|
|
96
|
+
orchestrator) can add `adapters/{context}.md` files using the same
|
|
97
|
+
pattern: detect via env or filesystem signal, document the additional
|
|
98
|
+
obligations, and add a one-line conditional reference in `SKILL.md`.
|