@aperant/framework 0.7.0 → 0.7.4

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.
Files changed (151) hide show
  1. package/CHANGELOG.md +205 -0
  2. package/agents/apt-planner.md +12 -0
  3. package/agents/apt-pr-review-fixer.md +13 -9
  4. package/bin/apt-tools.mjs +7 -0
  5. package/dist/cli/ci-watch/stop-matrix.d.mts.map +1 -1
  6. package/dist/cli/ci-watch/stop-matrix.mjs +16 -0
  7. package/dist/cli/ci-watch/stop-matrix.mjs.map +1 -1
  8. package/dist/cli/commands/ci-watch.d.mts +11 -0
  9. package/dist/cli/commands/ci-watch.d.mts.map +1 -1
  10. package/dist/cli/commands/ci-watch.mjs +108 -2
  11. package/dist/cli/commands/ci-watch.mjs.map +1 -1
  12. package/dist/cli/commands/features-audit.d.mts +24 -0
  13. package/dist/cli/commands/features-audit.d.mts.map +1 -1
  14. package/dist/cli/commands/features-audit.mjs +159 -5
  15. package/dist/cli/commands/features-audit.mjs.map +1 -1
  16. package/dist/cli/commands/health-check.d.mts +16 -0
  17. package/dist/cli/commands/health-check.d.mts.map +1 -1
  18. package/dist/cli/commands/health-check.mjs +118 -2
  19. package/dist/cli/commands/health-check.mjs.map +1 -1
  20. package/dist/cli/commands/init.d.mts +9 -0
  21. package/dist/cli/commands/init.d.mts.map +1 -1
  22. package/dist/cli/commands/init.mjs +49 -4
  23. package/dist/cli/commands/init.mjs.map +1 -1
  24. package/dist/cli/commands/modes.d.mts.map +1 -1
  25. package/dist/cli/commands/modes.mjs +11 -0
  26. package/dist/cli/commands/modes.mjs.map +1 -1
  27. package/dist/cli/commands/pr-review-audit-fixer.d.mts +13 -0
  28. package/dist/cli/commands/pr-review-audit-fixer.d.mts.map +1 -1
  29. package/dist/cli/commands/pr-review-audit-fixer.mjs +18 -5
  30. package/dist/cli/commands/pr-review-audit-fixer.mjs.map +1 -1
  31. package/dist/cli/commands/task.d.mts.map +1 -1
  32. package/dist/cli/commands/task.mjs +84 -5
  33. package/dist/cli/commands/task.mjs.map +1 -1
  34. package/dist/cli/commands/validate-evidence.d.mts +24 -2
  35. package/dist/cli/commands/validate-evidence.d.mts.map +1 -1
  36. package/dist/cli/commands/validate-evidence.mjs +154 -17
  37. package/dist/cli/commands/validate-evidence.mjs.map +1 -1
  38. package/dist/cli/commands/vitest-doctor.d.mts +2 -0
  39. package/dist/cli/commands/vitest-doctor.d.mts.map +1 -0
  40. package/dist/cli/commands/vitest-doctor.mjs +168 -0
  41. package/dist/cli/commands/vitest-doctor.mjs.map +1 -0
  42. package/dist/cli/config/gitignore-drift.d.mts +23 -1
  43. package/dist/cli/config/gitignore-drift.d.mts.map +1 -1
  44. package/dist/cli/config/gitignore-drift.mjs +81 -3
  45. package/dist/cli/config/gitignore-drift.mjs.map +1 -1
  46. package/dist/cli/config/load.d.mts +56 -2
  47. package/dist/cli/config/load.d.mts.map +1 -1
  48. package/dist/cli/config/load.mjs +192 -2
  49. package/dist/cli/config/load.mjs.map +1 -1
  50. package/dist/cli/consistency/parse-review.mjs +7 -0
  51. package/dist/cli/consistency/parse-review.mjs.map +1 -1
  52. package/dist/cli/dispatch.d.mts.map +1 -1
  53. package/dist/cli/dispatch.mjs +24 -2
  54. package/dist/cli/dispatch.mjs.map +1 -1
  55. package/dist/cli/gate/gates/gitignore-in-sync.d.mts +1 -1
  56. package/dist/cli/gate/gates/gitignore-in-sync.d.mts.map +1 -1
  57. package/dist/cli/gate/gates/gitignore-in-sync.mjs +5 -2
  58. package/dist/cli/gate/gates/gitignore-in-sync.mjs.map +1 -1
  59. package/dist/cli/gate/gates/review-clean.d.mts +5 -1
  60. package/dist/cli/gate/gates/review-clean.d.mts.map +1 -1
  61. package/dist/cli/gate/gates/review-clean.mjs +23 -18
  62. package/dist/cli/gate/gates/review-clean.mjs.map +1 -1
  63. package/dist/cli/gate/gates/verify-approved.d.mts +49 -1
  64. package/dist/cli/gate/gates/verify-approved.d.mts.map +1 -1
  65. package/dist/cli/gate/gates/verify-approved.mjs +93 -14
  66. package/dist/cli/gate/gates/verify-approved.mjs.map +1 -1
  67. package/dist/cli/help.d.mts.map +1 -1
  68. package/dist/cli/help.mjs +7 -2
  69. package/dist/cli/help.mjs.map +1 -1
  70. package/dist/cli/install/runtime-detect.d.mts +13 -0
  71. package/dist/cli/install/runtime-detect.d.mts.map +1 -1
  72. package/dist/cli/install/runtime-detect.mjs +9 -0
  73. package/dist/cli/install/runtime-detect.mjs.map +1 -1
  74. package/dist/cli/task/index-md.d.mts.map +1 -1
  75. package/dist/cli/task/index-md.mjs +14 -2
  76. package/dist/cli/task/index-md.mjs.map +1 -1
  77. package/dist/plugin/.claude-plugin/plugin.json +11 -2
  78. package/dist/plugin/agents/apt-improver.md +99 -0
  79. package/dist/plugin/agents/apt-planner.md +127 -10
  80. package/dist/plugin/agents/apt-pr-review-fixer.md +13 -9
  81. package/dist/plugin/skills/apt/SKILL.md +1 -0
  82. package/dist/plugin/skills/apt-close-task/SKILL.md +63 -1
  83. package/dist/plugin/skills/apt-debug/SKILL.md +39 -6
  84. package/dist/plugin/skills/apt-debug/appendices/diagnose-discipline.md +119 -0
  85. package/dist/plugin/skills/apt-diagram/SKILL.md +378 -0
  86. package/dist/plugin/skills/apt-diagram/appendices/design-discipline.md +97 -0
  87. package/dist/plugin/skills/apt-discuss/SKILL.md +72 -5
  88. package/dist/plugin/skills/apt-discuss/appendices/grill-discipline.md +104 -0
  89. package/dist/plugin/skills/apt-discuss/appendices/zoom-out-helper.md +79 -0
  90. package/dist/plugin/skills/apt-execute/SKILL.md +57 -5
  91. package/dist/plugin/skills/apt-execute/appendices/tdd-mode.md +107 -0
  92. package/dist/plugin/skills/apt-improve/DEEPENING.md +84 -0
  93. package/dist/plugin/skills/apt-improve/INTERFACE-DESIGN.md +97 -0
  94. package/dist/plugin/skills/apt-improve/LANGUAGE.md +104 -0
  95. package/dist/plugin/skills/apt-improve/SKILL.md +141 -0
  96. package/dist/plugin/skills/apt-plan/SKILL.md +171 -4
  97. package/dist/plugin/skills/apt-plan/adapters/conductor.md +98 -0
  98. package/dist/plugin/skills/apt-pr-review/SKILL.md +57 -18
  99. package/dist/plugin/skills/apt-prototype/LOGIC.md +109 -0
  100. package/dist/plugin/skills/apt-prototype/SKILL.md +143 -0
  101. package/dist/plugin/skills/apt-prototype/UI.md +90 -0
  102. package/dist/plugin/skills/apt-quick/SKILL.md +49 -8
  103. package/dist/plugin/skills/apt-release-notes/SKILL.md +193 -0
  104. package/dist/plugin/skills/apt-release-notes/appendices/persona-voice.md +59 -0
  105. package/dist/plugin/skills/apt-review/SKILL.md +2 -0
  106. package/dist/plugin/skills/apt-run/SKILL.md +32 -4
  107. package/dist/plugin/skills/apt-setup/SKILL.md +308 -6
  108. package/dist/plugin/skills/apt-ship/SKILL.md +122 -1
  109. package/dist/plugin/skills/apt-spar/SKILL.md +315 -0
  110. package/dist/plugin/skills/apt-triage/AGENT-BRIEF.md +84 -0
  111. package/dist/plugin/skills/apt-triage/OUT-OF-SCOPE.md +75 -0
  112. package/dist/plugin/skills/apt-triage/SKILL.md +169 -0
  113. package/dist/plugin/skills/apt-update/SKILL.md +77 -10
  114. package/dist/plugin/skills/apt-verify/SKILL.md +3 -0
  115. package/dist/plugin/skills/apt-verify-proof/SKILL.md +10 -5
  116. package/dist/plugin/skills/apt-watch-ci/SKILL.md +166 -0
  117. package/dist/plugin/skills/apt-zoom-out/SKILL.md +130 -0
  118. package/package.json +1 -1
  119. package/prompts/conductor-framework-context.md +63 -0
  120. package/prompts/conductor-system.md +11 -0
  121. package/skills/apt-close-task/SKILL.md +1 -0
  122. package/skills/apt-discuss/SKILL.md +47 -5
  123. package/skills/apt-execute/SKILL.md +9 -0
  124. package/skills/apt-plan/SKILL.md +12 -0
  125. package/skills/apt-pr-review/SKILL.md +19 -3
  126. package/skills/apt-quick/SKILL.md +19 -8
  127. package/skills/apt-researcher.md +1 -0
  128. package/skills/apt-setup/SKILL.md +33 -2
  129. package/skills/apt-verify-proof/SKILL.md +7 -5
  130. package/src/cli/ci-watch/stop-matrix.mjs +17 -0
  131. package/src/cli/commands/ci-watch.mjs +113 -2
  132. package/src/cli/commands/features-audit.mjs +164 -5
  133. package/src/cli/commands/health-check.mjs +115 -2
  134. package/src/cli/commands/init.mjs +52 -4
  135. package/src/cli/commands/modes.mjs +11 -0
  136. package/src/cli/commands/pr-review-audit-fixer.mjs +18 -5
  137. package/src/cli/commands/task.mjs +83 -5
  138. package/src/cli/commands/validate-evidence.mjs +158 -17
  139. package/src/cli/commands/vitest-doctor.mjs +173 -0
  140. package/src/cli/config/gitignore-drift.mjs +74 -3
  141. package/src/cli/config/load.mjs +188 -2
  142. package/src/cli/consistency/parse-review.mjs +6 -0
  143. package/src/cli/dispatch.mjs +23 -2
  144. package/src/cli/gate/gates/gitignore-in-sync.mjs +5 -2
  145. package/src/cli/gate/gates/review-clean.mjs +24 -19
  146. package/src/cli/gate/gates/verify-approved.mjs +97 -14
  147. package/src/cli/help.mjs +7 -2
  148. package/src/cli/install/runtime-detect.mjs +9 -0
  149. package/src/cli/task/index-md.mjs +15 -2
  150. package/templates/config.json +2 -7
  151. 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|standard|complex",
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`.