@dtlabs/ai-toolkit 0.1.7 → 0.2.1
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/.claude/agents/define-feature.md +1 -0
- package/.claude/agents/dependency-injection-refactoring.md +1 -0
- package/.claude/agents/dependency-supply-chain-security.md +1 -0
- package/.claude/agents/developer-backend.md +1 -0
- package/.claude/agents/developer-frontend.md +1 -0
- package/.claude/agents/developer-testing.md +1 -0
- package/.claude/agents/domain-model-refactoring.md +1 -0
- package/.claude/agents/god-class-decomposition.md +1 -0
- package/.claude/agents/init-agents-md.md +1 -0
- package/.claude/agents/install-toolkit.md +134 -3
- package/.claude/agents/intervention-documentation-standard.md +1 -0
- package/.claude/agents/review-solution.md +1 -0
- package/.claude/agents/security-hardening.md +1 -0
- package/.claude/agents/validate-feature-docs.md +2 -0
- package/.claude/settings.json +5 -0
- package/.claude/skills/assess-codebase/SKILL.md +139 -60
- package/.claude/skills/implement-feature/SKILL.md +208 -26
- package/.claude/workflows/am-phase1.js +304 -0
- package/.claude/workflows/am-phase2.js +166 -0
- package/.claude/workflows/pm-phase1.js +164 -0
- package/.claude/workflows/pm-phase2.js +108 -0
- package/.claude/workflows/pm-phase3.js +309 -0
- package/CHANGELOG.md +29 -0
- package/README.md +26 -0
- package/bin/cli.js +64 -5
- package/docs/token-optimization-backlog.md +115 -0
- package/docs/token-optimization.md +274 -0
- package/package.json +1 -1
- package/.claude/agents/assessment-manager.md +0 -672
- package/.claude/agents/project-manager.md +0 -309
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
name: 'pm-phase3',
|
|
3
|
+
description: 'Feature delivery phase 3: implementation loop (developer agents + review-solution per US, max 2 rework cycles, git commit per US) → remediation → PR → Feature Registry → Token-Estimate actuals → Effort-Estimate actuals.',
|
|
4
|
+
phases: [
|
|
5
|
+
{ title: 'Implementation', detail: 'Dispatch developer agents per work breakdown, review per US' },
|
|
6
|
+
{ title: 'Remediation', detail: 'Fix OPEN issues from Issues Register' },
|
|
7
|
+
{ title: 'PR', detail: 'Push branch, create PR, update registry' },
|
|
8
|
+
{ title: 'Actuals', detail: 'Write Token-Estimate and Effort-Estimate actuals' },
|
|
9
|
+
],
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// args: "<path-to-feature.md> --branch feature/FTR-NNN-slug"
|
|
13
|
+
const argStr = typeof args === 'string' ? args : ''
|
|
14
|
+
const featurePath = argStr.trim().split(/\s+/)[0]
|
|
15
|
+
const branchMatch = argStr.match(/--branch\s+(\S+)/)
|
|
16
|
+
const branch = branchMatch ? branchMatch[1] : null
|
|
17
|
+
|
|
18
|
+
// ── Implementation ────────────────────────────────────────────────────────────
|
|
19
|
+
phase('Implementation')
|
|
20
|
+
|
|
21
|
+
log(`Starting implementation for ${featurePath}${branch ? ` on branch ${branch}` : ''}`)
|
|
22
|
+
|
|
23
|
+
const tokenLedger = []
|
|
24
|
+
const escalations = []
|
|
25
|
+
|
|
26
|
+
// Read the Work Breakdown and execute implementation
|
|
27
|
+
// A single orchestration agent handles the full implementation loop:
|
|
28
|
+
// parse WB → per-phase dispatch → review per US → rework (max 2 cycles) → commit per US
|
|
29
|
+
// It uses sub-tool calls (Read, Bash, etc.) to do git work and reads the WB itself.
|
|
30
|
+
// It does NOT spawn further subagents — it reads files and calls Bash for git commands.
|
|
31
|
+
|
|
32
|
+
const IMPL_SCHEMA = {
|
|
33
|
+
type: 'object',
|
|
34
|
+
properties: {
|
|
35
|
+
prefix: { type: 'string' },
|
|
36
|
+
phases_done: { type: 'number' },
|
|
37
|
+
us_passed: { type: 'array', items: { type: 'string' } },
|
|
38
|
+
us_escalated: { type: 'array', items: { type: 'string' } },
|
|
39
|
+
issues_path: { type: 'string' },
|
|
40
|
+
issues_open: { type: 'number' },
|
|
41
|
+
},
|
|
42
|
+
required: ['prefix', 'phases_done'],
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const beforeImpl = budget.spent()
|
|
46
|
+
|
|
47
|
+
const implResult = await agent(
|
|
48
|
+
`You are the implementation orchestrator for the feature delivery pipeline.
|
|
49
|
+
|
|
50
|
+
Feature path: ${featurePath}
|
|
51
|
+
Branch: ${branch || '(already checked out)'}
|
|
52
|
+
|
|
53
|
+
Your job:
|
|
54
|
+
|
|
55
|
+
1. Read {PREFIX}-Work-Breakdown.md (same directory as feature.md).
|
|
56
|
+
Extract all phases, tasks, domains, and User Story groupings from Section 4.
|
|
57
|
+
|
|
58
|
+
2. For each phase in order:
|
|
59
|
+
a. Identify tasks grouped by User Story (US-XX) or INFRA.
|
|
60
|
+
b. For each group, spawn the correct developer agent:
|
|
61
|
+
- DB/BE/INFRA tasks → subagent_type: developer-backend
|
|
62
|
+
- FE tasks → subagent_type: developer-frontend
|
|
63
|
+
- TEST tasks → subagent_type: developer-testing
|
|
64
|
+
Prompt: "${featurePath} <comma-separated task IDs>"
|
|
65
|
+
Independent groups within a phase can be dispatched in parallel (multiple Agent calls in same response).
|
|
66
|
+
c. When ALL tasks for a User Story are done → spawn review-solution:
|
|
67
|
+
subagent_type: review-solution, prompt: "${featurePath} --scope <US-ID>"
|
|
68
|
+
- PASS (no CRITICAL): git add -A && git commit -m "feat({PREFIX}): implement {US-ID} — {title}"
|
|
69
|
+
Log WARNING/INFO findings to {PREFIX}-Issues.md.
|
|
70
|
+
- FAIL (CRITICAL): rework — re-dispatch the developer agent with the review findings appended to the prompt.
|
|
71
|
+
Max 2 rework cycles. After 2 failed cycles → escalate (add to escalations list).
|
|
72
|
+
INFRA tasks: reviewed as a group, commit: "feat({PREFIX}): implement shared infrastructure (INFRA)"
|
|
73
|
+
|
|
74
|
+
3. After all phases complete:
|
|
75
|
+
- Read {PREFIX}-Issues.md if it exists. Count OPEN items.
|
|
76
|
+
- Report: prefix, phases_done, us_passed (list of US IDs that passed), us_escalated (list that escalated), issues_path, issues_open.
|
|
77
|
+
|
|
78
|
+
IMPORTANT RULES:
|
|
79
|
+
- Never use run_in_background: true when spawning agents.
|
|
80
|
+
- Track escalations: if a US fails review after 2 rework cycles, add its ID to us_escalated and continue.
|
|
81
|
+
- Partial failures are acceptable — continue with remaining phases.
|
|
82
|
+
- All git commands via Bash tool.
|
|
83
|
+
- Commit message format: feat({PREFIX}): implement {US-ID} — {US title}`,
|
|
84
|
+
{
|
|
85
|
+
label: 'implementation-orchestrator',
|
|
86
|
+
phase: 'Implementation',
|
|
87
|
+
schema: IMPL_SCHEMA,
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
const implTokens = budget.spent() - beforeImpl
|
|
92
|
+
tokenLedger.push({ agent: 'implementation-orchestrator', model: 'sonnet', phase_delta_tokens: implTokens })
|
|
93
|
+
log(`Implementation done — ${implResult.phases_done} phases, ${(implResult.us_passed || []).length} US passed, ${(implResult.us_escalated || []).length} escalated`)
|
|
94
|
+
log(`Phase delta: ${implTokens} tokens`)
|
|
95
|
+
|
|
96
|
+
if (implResult.us_escalated?.length) {
|
|
97
|
+
for (const usId of implResult.us_escalated) {
|
|
98
|
+
escalations.push({ usId, reason: 'CRITICAL review finding unresolved after 2 rework cycles' })
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const prefix = implResult.prefix
|
|
103
|
+
const issuesPath = implResult.issues_path || ''
|
|
104
|
+
|
|
105
|
+
// ── Remediation ───────────────────────────────────────────────────────────────
|
|
106
|
+
phase('Remediation')
|
|
107
|
+
|
|
108
|
+
const REM_SCHEMA = {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
issues_fixed: { type: 'number' },
|
|
112
|
+
issues_deferred: { type: 'number' },
|
|
113
|
+
},
|
|
114
|
+
required: ['issues_fixed', 'issues_deferred'],
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let issuesFixed = 0
|
|
118
|
+
let issuesDeferred = 0
|
|
119
|
+
|
|
120
|
+
if (implResult.issues_open > 0 && issuesPath) {
|
|
121
|
+
log(`Remediation: ${implResult.issues_open} OPEN issues`)
|
|
122
|
+
const beforeRem = budget.spent()
|
|
123
|
+
|
|
124
|
+
const remResult = await agent(
|
|
125
|
+
`You are a remediation agent for the feature delivery pipeline.
|
|
126
|
+
|
|
127
|
+
Read the Issues Register at: ${issuesPath}
|
|
128
|
+
|
|
129
|
+
For each OPEN issue:
|
|
130
|
+
- If severity is INFO: mark it DEFERRED immediately (update the Status column to DEFERRED). Do not dispatch a developer agent.
|
|
131
|
+
- If severity is WARNING: dispatch the appropriate developer agent (developer-backend for most cases) with the issue description. Then spawn review-solution to verify the fix. Max 1 retry per issue. If unresolved after 1 retry, mark DEFERRED.
|
|
132
|
+
|
|
133
|
+
After processing all issues, return:
|
|
134
|
+
{ "issues_fixed": N, "issues_deferred": N }
|
|
135
|
+
|
|
136
|
+
Update the Issues Register Status column in place for each resolved/deferred issue.`,
|
|
137
|
+
{
|
|
138
|
+
label: 'remediation',
|
|
139
|
+
phase: 'Remediation',
|
|
140
|
+
schema: REM_SCHEMA,
|
|
141
|
+
}
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
const remTokens = budget.spent() - beforeRem
|
|
145
|
+
tokenLedger.push({ agent: 'remediation', model: 'sonnet', phase_delta_tokens: remTokens })
|
|
146
|
+
issuesFixed = remResult.issues_fixed || 0
|
|
147
|
+
issuesDeferred = remResult.issues_deferred || 0
|
|
148
|
+
log(`Remediation done — fixed: ${issuesFixed}, deferred: ${issuesDeferred} | phase delta: ${remTokens} tokens`)
|
|
149
|
+
} else {
|
|
150
|
+
log('Remediation: no OPEN issues — skipped')
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ── PR ────────────────────────────────────────────────────────────────────────
|
|
154
|
+
phase('PR')
|
|
155
|
+
|
|
156
|
+
const PR_SCHEMA = {
|
|
157
|
+
type: 'object',
|
|
158
|
+
properties: {
|
|
159
|
+
pr_url: { type: 'string' },
|
|
160
|
+
registry_updated: { type: 'boolean' },
|
|
161
|
+
},
|
|
162
|
+
required: ['pr_url'],
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const beforePR = budget.spent()
|
|
166
|
+
|
|
167
|
+
const prResult = await agent(
|
|
168
|
+
`You are the PR and registry agent for the feature delivery pipeline.
|
|
169
|
+
|
|
170
|
+
Feature path: ${featurePath}
|
|
171
|
+
Branch: ${branch || 'current branch'}
|
|
172
|
+
Prefix: ${prefix}
|
|
173
|
+
Issues fixed: ${issuesFixed}, deferred: ${issuesDeferred}
|
|
174
|
+
|
|
175
|
+
Your tasks:
|
|
176
|
+
|
|
177
|
+
1. If there are remediation fixes, commit them:
|
|
178
|
+
git add -A
|
|
179
|
+
git commit -m "fix(${prefix}): remediate review issues"
|
|
180
|
+
|
|
181
|
+
2. Push the branch:
|
|
182
|
+
git push -u origin ${branch || 'HEAD'}
|
|
183
|
+
|
|
184
|
+
3. Create a PR targeting develop:
|
|
185
|
+
gh pr create \\
|
|
186
|
+
--title "feat(${prefix}): <Feature Title from feature.md>" \\
|
|
187
|
+
--base develop \\
|
|
188
|
+
--body "## Summary
|
|
189
|
+
- Implements <Feature Title> (<N> User Stories, <N> tasks)
|
|
190
|
+
- Source docs: ${prefix}-Requirements.md, ${prefix}-Tech-Spec.md
|
|
191
|
+
|
|
192
|
+
## Implementation
|
|
193
|
+
- Architect review: all US passed
|
|
194
|
+
- Issues Register: ${issuesFixed} fixed, ${issuesDeferred} deferred → see ${prefix}-Issues.md
|
|
195
|
+
|
|
196
|
+
## Test plan
|
|
197
|
+
- [ ] Build passes
|
|
198
|
+
- [ ] Tests pass
|
|
199
|
+
- [ ] Manual smoke test of key flows"
|
|
200
|
+
|
|
201
|
+
4. Update the Feature Registry (internal_docs/features/REGISTRY.md):
|
|
202
|
+
Find or append the entry for ${prefix}. Set Status to "completed".
|
|
203
|
+
|
|
204
|
+
Return { "pr_url": "<url>", "registry_updated": true/false }.
|
|
205
|
+
If the PR creation fails, return { "pr_url": "(PR creation failed)", "registry_updated": false }.`,
|
|
206
|
+
{
|
|
207
|
+
label: 'pr-and-registry',
|
|
208
|
+
phase: 'PR',
|
|
209
|
+
schema: PR_SCHEMA,
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
const prTokens = budget.spent() - beforePR
|
|
214
|
+
tokenLedger.push({ agent: 'pr-and-registry', model: 'sonnet', phase_delta_tokens: prTokens })
|
|
215
|
+
log(`PR done: ${prResult.pr_url} | phase delta: ${prTokens} tokens`)
|
|
216
|
+
|
|
217
|
+
// ── Actuals ───────────────────────────────────────────────────────────────────
|
|
218
|
+
phase('Actuals')
|
|
219
|
+
|
|
220
|
+
// Compute proportional distribution of phase tokens across logical agents
|
|
221
|
+
// Phase tokens are exact (budget.spent() deltas); per-agent breakdown is proportional.
|
|
222
|
+
// This is documented in the Token-Estimate file with a disclaimer.
|
|
223
|
+
const totalImplTokens = tokenLedger.reduce((s, e) => s + (e.phase_delta_tokens || 0), 0)
|
|
224
|
+
|
|
225
|
+
const ACTUALS_SCHEMA = {
|
|
226
|
+
type: 'object',
|
|
227
|
+
properties: {
|
|
228
|
+
token_estimate_path: { type: 'string' },
|
|
229
|
+
effort_estimate_path: { type: 'string' },
|
|
230
|
+
},
|
|
231
|
+
required: [],
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const beforeActuals = budget.spent()
|
|
235
|
+
|
|
236
|
+
await agent(
|
|
237
|
+
`You are the actuals recorder for the feature delivery pipeline.
|
|
238
|
+
|
|
239
|
+
Feature path: ${featurePath}
|
|
240
|
+
Prefix: ${prefix}
|
|
241
|
+
|
|
242
|
+
Token ledger (phase-level measurements):
|
|
243
|
+
${JSON.stringify(tokenLedger, null, 2)}
|
|
244
|
+
|
|
245
|
+
Total tokens consumed by pm-phase3 workflow (all phases combined): ${totalImplTokens} (exact, from budget tracking)
|
|
246
|
+
|
|
247
|
+
TASK 1 — Update Token-Estimate.md:
|
|
248
|
+
Find ${prefix}-Token-Estimate.md in the feature directory.
|
|
249
|
+
If it doesn't exist, create it with the structure from docs/procedures/token-estimation.md.
|
|
250
|
+
|
|
251
|
+
Append this section at the end:
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Actuals vs Estimate
|
|
256
|
+
|
|
257
|
+
> ⚠️ Per-agent values are proportional distributions of the phase total.
|
|
258
|
+
> Phase totals (pm-phase3 total: ${totalImplTokens} tokens) are exact measurements.
|
|
259
|
+
> Individual agent breakdown is estimated proportionally.
|
|
260
|
+
|
|
261
|
+
| Agent | Task / Scope | Model | Phase delta tokens | Notes |
|
|
262
|
+
|-------|-------------|-------|-------------------|-------|
|
|
263
|
+
${tokenLedger.map(e => `| ${e.agent} | — | ${e.model} | ${e.phase_delta_tokens} | exact phase delta |`).join('\n')}
|
|
264
|
+
|
|
265
|
+
## Grand Total (pm-phase3)
|
|
266
|
+
|
|
267
|
+
| Metric | Value |
|
|
268
|
+
|--------|-------|
|
|
269
|
+
| Total tokens (pm-phase3) | ${totalImplTokens} (exact) |
|
|
270
|
+
| Implementation phases | ${implResult.phases_done} |
|
|
271
|
+
| US passed | ${(implResult.us_passed || []).join(', ') || 'N/A'} |
|
|
272
|
+
| US escalated | ${(implResult.us_escalated || []).join(', ') || 'none'} |
|
|
273
|
+
|
|
274
|
+
TASK 2 — Append actuals to Effort-Estimate.md:
|
|
275
|
+
Find ${prefix}-Effort-Estimate.md in the feature directory.
|
|
276
|
+
Append:
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Actuals vs Estimate
|
|
281
|
+
|
|
282
|
+
| Metric | Estimated | Actual |
|
|
283
|
+
|--------|-----------|--------|
|
|
284
|
+
| Implementation phases | ${implResult.phases_done} | ${implResult.phases_done} |
|
|
285
|
+
| Issues fixed | — | ${issuesFixed} |
|
|
286
|
+
| Issues deferred | — | ${issuesDeferred} |
|
|
287
|
+
|
|
288
|
+
Return { "token_estimate_path": "<path>", "effort_estimate_path": "<path>" }.`,
|
|
289
|
+
{
|
|
290
|
+
label: 'write-actuals',
|
|
291
|
+
phase: 'Actuals',
|
|
292
|
+
schema: ACTUALS_SCHEMA,
|
|
293
|
+
}
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
const actualsTokens = budget.spent() - beforeActuals
|
|
297
|
+
tokenLedger.push({ agent: 'write-actuals', model: 'sonnet', phase_delta_tokens: actualsTokens })
|
|
298
|
+
log(`Actuals written | phase delta: ${actualsTokens} tokens`)
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
pr_url: prResult.pr_url,
|
|
302
|
+
token_ledger: tokenLedger,
|
|
303
|
+
issues_summary: {
|
|
304
|
+
escalations: escalations.length,
|
|
305
|
+
escalation_details: escalations,
|
|
306
|
+
issues_fixed: issuesFixed,
|
|
307
|
+
issues_deferred: issuesDeferred,
|
|
308
|
+
},
|
|
309
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
1
|
## 0.1.4 (2026-07-21)
|
|
2
|
+
## [0.2.1](https://github.com/dtlab-tech/ai-toolkit/compare/v0.2.0...v0.2.1) (2026-07-27)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* validate-feature-docs always writes report; fix false-positive gap detection ([68caf3e](https://github.com/dtlab-tech/ai-toolkit/commit/68caf3e25214bcb219df1654c4b3ede5cc42eb3b))
|
|
8
|
+
* validate-feature-docs always writes report; fix false-positive gap detection in pm-phase1 ([d99fdb3](https://github.com/dtlab-tech/ai-toolkit/commit/d99fdb39be1663539bd0ed7e6ca4facc2c53fd76))
|
|
9
|
+
|
|
10
|
+
## [0.2.0](https://github.com/dtlab-tech/ai-toolkit/compare/v0.1.7...v0.2.0) (2026-07-27)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **FTR-007:** explicit per-agent model assignment ([853eb0f](https://github.com/dtlab-tech/ai-toolkit/commit/853eb0f956a9a1aa64dedac7100fb1ad9eab4b08))
|
|
16
|
+
* **FTR-007:** implement US-01 — explicit per-agent model assignment ([0fe5fba](https://github.com/dtlab-tech/ai-toolkit/commit/0fe5fba9b25dc261e840d99d97105dec7c0c9318))
|
|
17
|
+
* **FTR-008:** compact instructions block for ~/.claude/CLAUDE.md ([738df59](https://github.com/dtlab-tech/ai-toolkit/commit/738df597e2da3edc04de68462f0e4555b232941d))
|
|
18
|
+
* **FTR-008:** implement compact instructions block ([0dab04d](https://github.com/dtlab-tech/ai-toolkit/commit/0dab04d9c14392866c9046eee9e7052a2beac586))
|
|
19
|
+
* **FTR-009:** implement shared infrastructure (INFRA) ([31bceb9](https://github.com/dtlab-tech/ai-toolkit/commit/31bceb9788a1f403eea3f2971b87959fa9e33f97))
|
|
20
|
+
* **FTR-009:** implement US-01 — Feature Delivery Workflow Scripts ([7f6dd7d](https://github.com/dtlab-tech/ai-toolkit/commit/7f6dd7da8280d9bc6b5b9922bf7f751c1837f8ad))
|
|
21
|
+
* **FTR-009:** implement US-02 — Assessment Workflow Scripts ([7b1e668](https://github.com/dtlab-tech/ai-toolkit/commit/7b1e668217f89ef16011fbe253a8e4bfb5714d0c))
|
|
22
|
+
* **FTR-009:** rewrite orchestrators as Workflow scripts ([7f63b20](https://github.com/dtlab-tech/ai-toolkit/commit/7f63b209e6f4826115c74189847f68d77dc16ac1))
|
|
23
|
+
* release develop → main (FTR-007, FTR-008, FTR-009) ([66c9e05](https://github.com/dtlab-tech/ai-toolkit/commit/66c9e05dde12be03f2c3d2a13eea112103fd6a20))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* **FTR-009:** remediate review issues; update registry ([6aaeeb0](https://github.com/dtlab-tech/ai-toolkit/commit/6aaeeb0465b4d2003e61f33f7c6d0641bc477f9c))
|
|
29
|
+
* **FTR-009:** rewrite all 5 workflow scripts with correct Workflow SDK API ([2c6da04](https://github.com/dtlab-tech/ai-toolkit/commit/2c6da041c07a1c233678cd0d64dfeaf66f0674a5))
|
|
30
|
+
|
|
2
31
|
## 0.1.7 (2026-07-23)
|
|
3
32
|
|
|
4
33
|
|
package/README.md
CHANGED
|
@@ -65,6 +65,32 @@ The toolkit ships **generic agents** that work with any project. Each agent read
|
|
|
65
65
|
|
|
66
66
|
Generic procedures live in `docs/procedures/`. Projects can override any of them by placing a file with the same name at their own `docs/procedures/`. Agents check the project first, then fall back to the toolkit.
|
|
67
67
|
|
|
68
|
+
## Required configuration — subagent spawn depth
|
|
69
|
+
|
|
70
|
+
> ⚠️ **This setting is not optional for the orchestrated pipelines.** Without it, `/implement-feature` and `/assess-codebase` silently degrade.
|
|
71
|
+
|
|
72
|
+
The toolkit is built on a **two-level agent hierarchy**: an orchestrator (`project-manager` or `assessment-manager`) is spawned as a subagent, and it in turn spawns the specialized worker agents (developers, reviewers, assessors), each on its own role-appropriate model with an isolated context.
|
|
73
|
+
|
|
74
|
+
Since Claude Code **v2.1.217, a subagent cannot spawn further subagents by default** (spawn depth is capped at 1, an intentional guard against unbounded recursive fan-out and cost). Under that default, when an orchestrator runs as a subagent it has **no `Agent` tool** — so instead of delegating, it executes every worker's task *inline, in its own context, on its own model*. The consequences:
|
|
75
|
+
|
|
76
|
+
- **Per-agent model assignment stops taking effect** — the `haiku`/`sonnet`/`opus` mapping on each agent is never applied, because those agents are never actually spawned. Everything runs on the orchestrator's model.
|
|
77
|
+
- **Context isolation is lost** — one long orchestrator context replaces the intended per-agent isolation.
|
|
78
|
+
- **Per-agent token telemetry disappears** — no per-agent `<usage>` blocks are emitted, so `*-Token-Estimate.md` records only an aggregate orchestrator total.
|
|
79
|
+
|
|
80
|
+
To let the toolkit work as designed, raise the allowed depth to **2** (main loop → orchestrator → workers). This repo already sets it in [`.claude/settings.json`](.claude/settings.json):
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"env": {
|
|
85
|
+
"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "2"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**When you install the toolkit into another project, you must add this setting yourself.** The installers (`npx @dtlabs/ai-toolkit`, `ai-toolkit --global`, and the `/install-toolkit` agent) **never copy or edit any `settings.json`** — that file is user-owned, and merging it automatically would risk clobbering your existing configuration. Instead, each installer **checks** whether `CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH` is set to `2`+ in the destination and, if it is missing, prints the exact snippet to add (to `.claude/settings.json` for one project, or `~/.claude/settings.json` for all projects). After adding it, restart Claude Code so the variable is loaded.
|
|
91
|
+
|
|
92
|
+
The orchestrator agents already omit the `tools:` frontmatter field, so they inherit the `Agent` tool automatically once the depth allows it — no per-agent changes are needed.
|
|
93
|
+
|
|
68
94
|
## Documentation
|
|
69
95
|
|
|
70
96
|
- [Quick Reference](docs/reference.md) — cheatsheet of every skill, command, agent, and procedure
|
package/bin/cli.js
CHANGED
|
@@ -40,10 +40,18 @@ function banner() {
|
|
|
40
40
|
|
|
41
41
|
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
42
42
|
|
|
43
|
+
// User-owned config that must NEVER be copied into a destination. We only verify
|
|
44
|
+
// and advise on these — copying would clobber the user's existing settings.
|
|
45
|
+
const NEVER_COPY = new Set(['settings.json', 'settings.local.json']);
|
|
46
|
+
|
|
43
47
|
function fileHash(filePath) {
|
|
44
48
|
return crypto.createHash('md5').update(fs.readFileSync(filePath)).digest('hex');
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
function readJsonSafe(filePath) {
|
|
52
|
+
try { return JSON.parse(fs.readFileSync(filePath, 'utf8')); } catch { return null; }
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
function ensureDir(filePath) {
|
|
48
56
|
const dir = path.dirname(filePath);
|
|
49
57
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
@@ -67,10 +75,12 @@ function expandMappings(mappings) {
|
|
|
67
75
|
if (!fs.existsSync(src)) continue;
|
|
68
76
|
if (fs.statSync(src).isDirectory()) {
|
|
69
77
|
for (const entry of walkDir(src)) {
|
|
78
|
+
if (NEVER_COPY.has(path.basename(entry))) continue; // never clobber user config
|
|
70
79
|
const rel = path.relative(src, entry);
|
|
71
80
|
files.push({ src: entry, dest: path.join(dest, rel) });
|
|
72
81
|
}
|
|
73
82
|
} else {
|
|
83
|
+
if (NEVER_COPY.has(path.basename(src))) continue;
|
|
74
84
|
files.push({ src, dest });
|
|
75
85
|
}
|
|
76
86
|
}
|
|
@@ -262,6 +272,52 @@ async function askMattPocock() {
|
|
|
262
272
|
else console.log(` ${clr('gray', 'Skipped.')}\n`);
|
|
263
273
|
}
|
|
264
274
|
|
|
275
|
+
// ── subagent spawn-depth check (verify & advise only — never write) ────────────
|
|
276
|
+
|
|
277
|
+
const SPAWN_DEPTH_VAR = 'CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH';
|
|
278
|
+
|
|
279
|
+
// Report whether the spawn-depth prerequisite is satisfied for a destination,
|
|
280
|
+
// checking both project-level and local-override settings files. Purely advisory:
|
|
281
|
+
// this NEVER creates or modifies any settings file.
|
|
282
|
+
function checkSpawnDepth(destRoot) {
|
|
283
|
+
const candidates = [
|
|
284
|
+
path.join(destRoot, '.claude', 'settings.json'),
|
|
285
|
+
path.join(destRoot, '.claude', 'settings.local.json'),
|
|
286
|
+
];
|
|
287
|
+
|
|
288
|
+
console.log(divider());
|
|
289
|
+
console.log(bold(' Subagent spawn depth (required for orchestrated pipelines)'));
|
|
290
|
+
console.log(divider());
|
|
291
|
+
|
|
292
|
+
for (const file of candidates) {
|
|
293
|
+
if (!fs.existsSync(file)) continue;
|
|
294
|
+
const json = readJsonSafe(file);
|
|
295
|
+
const value = json && json.env && json.env[SPAWN_DEPTH_VAR];
|
|
296
|
+
if (value !== undefined && Number(value) >= 2) {
|
|
297
|
+
console.log(` ${clr('green', '✔')} ${SPAWN_DEPTH_VAR}=${value} found in ${dim(path.relative(process.cwd(), file))}`);
|
|
298
|
+
console.log(` ${dim('Orchestrators can spawn worker subagents — pipelines will run as designed.')}\n`);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
console.log(` ${clr('yellow', '⚠')} ${SPAWN_DEPTH_VAR} is not set to 2+ in this project.`);
|
|
304
|
+
console.log(` ${dim('Without it, /implement-feature and /assess-codebase run every worker inline')}`);
|
|
305
|
+
console.log(` ${dim('on the orchestrator model: per-agent model assignment, context isolation,')}`);
|
|
306
|
+
console.log(` ${dim('and per-agent token telemetry are all lost.')}`);
|
|
307
|
+
console.log();
|
|
308
|
+
console.log(` ${bold('Action required')} — add this to ${clr('cyan', '.claude/settings.json')} (project)`);
|
|
309
|
+
console.log(` or ${clr('cyan', '~/.claude/settings.json')} (all projects). We do not edit it for you,`);
|
|
310
|
+
console.log(` ${dim('to avoid clobbering your existing configuration:')}`);
|
|
311
|
+
console.log();
|
|
312
|
+
console.log(clr('gray', ' {'));
|
|
313
|
+
console.log(clr('gray', ' "env": {'));
|
|
314
|
+
console.log(clr('gray', ` "${SPAWN_DEPTH_VAR}": "2"`));
|
|
315
|
+
console.log(clr('gray', ' }'));
|
|
316
|
+
console.log(clr('gray', ' }'));
|
|
317
|
+
console.log();
|
|
318
|
+
console.log(` ${dim('Then restart Claude Code so the variable is loaded.')}\n`);
|
|
319
|
+
}
|
|
320
|
+
|
|
265
321
|
// ── entry points ──────────────────────────────────────────────────────────────
|
|
266
322
|
|
|
267
323
|
async function installLocal(targetDir, force) {
|
|
@@ -277,6 +333,7 @@ async function installLocal(targetDir, force) {
|
|
|
277
333
|
await runInstall(`local project`, mappings, force);
|
|
278
334
|
writeInstalledVersion(targetDir);
|
|
279
335
|
console.log(` ${clr('green', '✔')} ${bold('Install complete.')}\n`);
|
|
336
|
+
checkSpawnDepth(targetDir);
|
|
280
337
|
await askMattPocock();
|
|
281
338
|
console.log(divider());
|
|
282
339
|
console.log(`\n ${bold('Next steps:')}`);
|
|
@@ -293,15 +350,17 @@ async function installGlobal(force) {
|
|
|
293
350
|
console.log(` ${clr('cyan', '▸')} Target: ${bold(target)} ${clr('gray', '(global Claude folder)')}\n`);
|
|
294
351
|
await checkVersion(target, force);
|
|
295
352
|
const mappings = [
|
|
296
|
-
{ src: path.join(packageRoot, '.claude', 'agents'),
|
|
297
|
-
{ src: path.join(packageRoot, '.claude', 'skills'),
|
|
298
|
-
{ src: path.join(packageRoot, '.claude', 'commands'),
|
|
299
|
-
{ src: path.join(packageRoot, '
|
|
300
|
-
{ src: path.join(packageRoot, '
|
|
353
|
+
{ src: path.join(packageRoot, '.claude', 'agents'), dest: path.join(target, 'agents') },
|
|
354
|
+
{ src: path.join(packageRoot, '.claude', 'skills'), dest: path.join(target, 'skills') },
|
|
355
|
+
{ src: path.join(packageRoot, '.claude', 'commands'), dest: path.join(target, 'commands') },
|
|
356
|
+
{ src: path.join(packageRoot, '.claude', 'workflows'), dest: path.join(target, 'workflows') },
|
|
357
|
+
{ src: path.join(packageRoot, 'docs'), dest: path.join(target, 'docs') },
|
|
358
|
+
{ src: path.join(packageRoot, 'CLAUDE.md'), dest: path.join(target, 'CLAUDE.md') },
|
|
301
359
|
];
|
|
302
360
|
await runInstall('global Claude folder', mappings, force);
|
|
303
361
|
writeInstalledVersion(target);
|
|
304
362
|
console.log(` ${clr('green', '✔')} ${bold('Global install complete.')}\n`);
|
|
363
|
+
checkSpawnDepth(homedir);
|
|
305
364
|
await askMattPocock();
|
|
306
365
|
console.log(divider());
|
|
307
366
|
console.log(`\n ${bold('Next steps:')}`);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Token Optimization — Backlog di feature atomiche
|
|
2
|
+
|
|
3
|
+
> Deriva da `docs/token-optimization.md`. Data: 2026-07-24.
|
|
4
|
+
> Ogni voce è **atomica**: implementabile e verificabile in isolamento.
|
|
5
|
+
> "Criticità" = priorità di ottimizzazione (impatto/rischio), NON severità di difetto.
|
|
6
|
+
> Nessun intervento è un bug attivo → nessun `CRITICAL`.
|
|
7
|
+
> Sequenza consigliata = ordine degli ID.
|
|
8
|
+
|
|
9
|
+
## Quadro sintetico
|
|
10
|
+
|
|
11
|
+
| ID | Intervento | Criticità | Sforzo | Rischio | File toccati | Dipende da |
|
|
12
|
+
|----|-----------|-----------|--------|---------|--------------|-----------|
|
|
13
|
+
| OPT-01 ✅ | `model:` esplicito su ogni agent (→ FTR-007, PR #20) | **HIGH** | Basso | Basso | 15 agent (frontmatter) | — |
|
|
14
|
+
| OPT-02 | Deduplicare CLAUDE.md globale vs progetto | **HIGH** | Minimo | Zero | `~/.claude/CLAUDE.md` | — |
|
|
15
|
+
| OPT-03 | Blocco "Compact instructions" in CLAUDE.md | MEDIUM | Minimo | Zero | `CLAUDE.md` (progetto) | — |
|
|
16
|
+
| OPT-04 | Spostare i cataloghi da CLAUDE.md a reference.md | MEDIUM | Basso | Basso | `CLAUDE.md`, `docs/reference.md` | — |
|
|
17
|
+
| OPT-05 | Procedure on-demand — assessment-manager | MEDIUM | Medio | Basso | `assessment-manager.md` | — |
|
|
18
|
+
| OPT-06 | Procedure on-demand — project-manager | MEDIUM | Medio | Basso | `project-manager.md` | — |
|
|
19
|
+
| OPT-07 | Resource-budget testuale negli assessment agent | MEDIUM | Basso | Basso | 3+ assessment agent | — |
|
|
20
|
+
| OPT-08 | Summary/full split negli output di assessment | **HIGH** | Alto | Medio | assessment agents + int-doc + manager | OPT-07 |
|
|
21
|
+
| OPT-09 | Estrarre calcolo deterministico da assessment-manager | **HIGH** | Alto | Medio | `assessment-manager.md` + nuovo script | — |
|
|
22
|
+
| OPT-10 | generic-software-assessment → ruolo triage | MEDIUM | Medio | Medio | `generic-software-assessment.md` + manager | OPT-08 |
|
|
23
|
+
| OPT-11 | Delegation policy negli orchestratori | LOW | Basso | Basso | 2 orchestratori | — |
|
|
24
|
+
| OPT-12 | Hook di filtro output verboso (opzionale) | LOW | Basso | Basso | `settings.json` + script hook | — |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Feature atomiche
|
|
29
|
+
|
|
30
|
+
### OPT-01 — `model:` esplicito su ogni agent
|
|
31
|
+
- **Criticità:** HIGH · **Sforzo:** Basso · **Rischio:** Basso
|
|
32
|
+
- **Obiettivo:** ogni agent dichiara il modello adatto al suo ruolo, così nessuno eredita Opus per default.
|
|
33
|
+
- **Scope (solo frontmatter):** aggiungere `model:` ai 15 agent che ne sono privi. Mappatura:
|
|
34
|
+
- `sonnet`: `assessment-manager`, `project-manager`, `developer-backend`, `developer-frontend`, `developer-testing`, `god-class-decomposition`, `domain-model-refactoring`, `dependency-injection-refactoring`, `security-hardening`, `dependency-supply-chain-security`, `define-feature`, `init-agents-md`, `install-toolkit`, `intervention-documentation-standard`
|
|
35
|
+
- `opus`: `review-solution` (unico ruolo con giudizio architetturale profondo)
|
|
36
|
+
- **Fuori scope:** i 7 agent già `haiku` restano invariati.
|
|
37
|
+
- **Criteri di accettazione:** `grep -L "^model:" .claude/agents/*.md` non restituisce nulla; ogni valore ∈ {haiku, sonnet, opus}.
|
|
38
|
+
- **Dipendenze:** nessuna.
|
|
39
|
+
|
|
40
|
+
### OPT-02 — Deduplicare CLAUDE.md globale vs progetto
|
|
41
|
+
- **Criticità:** HIGH · **Sforzo:** Minimo · **Rischio:** Zero
|
|
42
|
+
- **Obiettivo:** eliminare il duplicato caricato a ogni sessione; il `CLAUDE.md` di progetto resta la fonte unica del catalogo toolkit.
|
|
43
|
+
- **Scope:** ridurre `~/.claude/CLAUDE.md` alle sole preferenze cross-progetto (lingua, stile, convenzioni personali). Rimuovere il catalogo toolkit duplicato.
|
|
44
|
+
- **Criteri di accettazione:** `diff ~/.claude/CLAUDE.md ./CLAUDE.md` NON è più identico; il globale non contiene più le tabelle Skills/Commands/Agents; il Gate Protocol resta accessibile (nel progetto).
|
|
45
|
+
- **Dipendenze:** nessuna. ⚠️ File utente globale — confermare con l'utente prima di modificare.
|
|
46
|
+
|
|
47
|
+
### OPT-03 — Blocco "Compact instructions" in CLAUDE.md
|
|
48
|
+
- **Criticità:** MEDIUM · **Sforzo:** Minimo · **Rischio:** Zero
|
|
49
|
+
- **Obiettivo:** guidare l'auto-compaction a preservare ciò che conta (decisioni, file, finding IDs) e scartare rumore.
|
|
50
|
+
- **Scope:** aggiungere al `CLAUDE.md` di progetto una sezione `# Compact instructions` (preserva: obiettivo corrente, decisioni confermate, risposte utente, file modificati, errori aperti, finding/artifact IDs; scarta: risultati grep grezzi, output tool riusciti, spiegazioni ripetute, piani superati).
|
|
51
|
+
- **Criteri di accettazione:** la sezione esiste in `CLAUDE.md`; nessun'altra modifica.
|
|
52
|
+
- **Dipendenze:** nessuna. (Coordinare con OPT-04 se si tocca lo stesso file.)
|
|
53
|
+
|
|
54
|
+
### OPT-04 — Spostare i cataloghi da CLAUDE.md a reference.md
|
|
55
|
+
- **Criticità:** MEDIUM · **Sforzo:** Basso · **Rischio:** Basso
|
|
56
|
+
- **Obiettivo:** CLAUDE.md sotto ~200 righe, solo essenziali operativi; il catalogo di scoperta vive in reference.md.
|
|
57
|
+
- **Scope:** spostare le tabelle Skills / Commands / Agents / Procedures in `docs/reference.md`. In `CLAUDE.md` restano: Dependencies, How it works, override procedure, **Gate Protocol**. Aggiungere in CLAUDE.md un puntatore a reference.md.
|
|
58
|
+
- **Criteri di accettazione:** `CLAUDE.md` < 200 righe; nessuna tabella-catalogo persa (presente in reference.md); Gate Protocol ancora in CLAUDE.md.
|
|
59
|
+
- **Dipendenze:** nessuna.
|
|
60
|
+
|
|
61
|
+
### OPT-05 — Procedure on-demand (assessment-manager)
|
|
62
|
+
- **Criticità:** MEDIUM · **Sforzo:** Medio · **Rischio:** Basso
|
|
63
|
+
- **Obiettivo:** leggere ogni procedura nella fase in cui serve, non tutte all'avvio.
|
|
64
|
+
- **Scope:** in `assessment-manager.md`, spostare le istruzioni "read at startup" così che `token-estimation.md`/`pricing.md` si leggano in Phase 3-4, `assessment-findings-gate.md` in Phase 5, ecc.
|
|
65
|
+
- **Criteri di accettazione:** nessuna procedura letta prima della fase che la usa; il comportamento delle fasi resta invariato.
|
|
66
|
+
- **Dipendenze:** nessuna. (Se si fa OPT-09, `token-estimation.md` sparisce del tutto dal contesto LLM.)
|
|
67
|
+
|
|
68
|
+
### OPT-06 — Procedure on-demand (project-manager)
|
|
69
|
+
- **Criticità:** MEDIUM · **Sforzo:** Medio · **Rischio:** Basso
|
|
70
|
+
- **Obiettivo:** stesso principio di OPT-05 applicato al `project-manager` (che legge ancora più procedure).
|
|
71
|
+
- **Scope:** riorganizzare `project-manager.md` per caricare ogni procedura alla fase pertinente (PR-procedure alla fase PR, ecc.).
|
|
72
|
+
- **Criteri di accettazione:** nessuna procedura caricata anticipatamente; pipeline invariata.
|
|
73
|
+
- **Dipendenze:** nessuna.
|
|
74
|
+
|
|
75
|
+
### OPT-07 — Resource-budget testuale negli assessment agent
|
|
76
|
+
- **Criticità:** MEDIUM · **Sforzo:** Basso · **Rischio:** Basso
|
|
77
|
+
- **Obiettivo:** limiti di lettura/output come **istruzioni nel prompt** (NON frontmatter — `budget:` non è supportato dall'harness).
|
|
78
|
+
- **Scope:** aggiungere una sezione `## Resource budget` in prosa agli assessment agent (es. "Inspect at most ~25 files; ≤2 evidence snippets per finding; stop when evidence is sufficient — do not explore to increase coverage").
|
|
79
|
+
- **Criteri di accettazione:** la sezione è testo del prompt, non YAML; presente in `generic-software-assessment`, `layered-architecture-assessment`, `concurrency-safety-assessment`.
|
|
80
|
+
- **Dipendenze:** nessuna.
|
|
81
|
+
|
|
82
|
+
### OPT-08 — Summary/full split negli output di assessment
|
|
83
|
+
- **Criticità:** HIGH · **Sforzo:** Alto · **Rischio:** Medio
|
|
84
|
+
- **Obiettivo:** l'orchestratore legge un **summary compatto**, non il documento intero. Il guadagno reale (non il formato JSON in sé).
|
|
85
|
+
- **Scope:** ogni assessment agent produce `{PREFIX}-{area}.full.md` (dettagli) + `{PREFIX}-{area}.summary` (conteggi per severità, finding IDs, path del full). `assessment-manager` e `intervention-documentation-standard` consumano il summary; il full si apre solo per i finding accettati.
|
|
86
|
+
- **Criteri di accettazione:** ogni agent scrive entrambi i file; il manager non legge i `.full` in Phase 3; l'int-doc apre i full solo per i finding selezionati.
|
|
87
|
+
- **Dipendenze:** OPT-07 (budget di output coerente).
|
|
88
|
+
|
|
89
|
+
### OPT-09 — Estrarre calcolo deterministico da assessment-manager
|
|
90
|
+
- **Criticità:** HIGH · **Sforzo:** Alto · **Rischio:** Medio
|
|
91
|
+
- **Obiettivo:** togliere dal prompt ~3.500 parole di pseudo-codice (calcolo token/effort, registry write) che un LLM esegue in modo costoso e fragile.
|
|
92
|
+
- **Scope:** spostare Token-Estimate / Effort-Estimate / registry-write in uno script (`scripts/estimate.*`) invocato via Bash; il prompt dell'agent si riduce a "esegui lo script con questi input e verifica l'output".
|
|
93
|
+
- **Criteri di accettazione:** i tre file prodotti sono identici (per input noti) a prima; `assessment-manager.md` perde le sezioni di calcolo passo-passo; nessun errore aritmetico possibile lato LLM.
|
|
94
|
+
- **Dipendenze:** nessuna hard; sinergica con OPT-05.
|
|
95
|
+
|
|
96
|
+
### OPT-10 — generic-software-assessment → ruolo triage
|
|
97
|
+
- **Criticità:** MEDIUM · **Sforzo:** Medio · **Rischio:** Medio
|
|
98
|
+
- **Obiettivo:** evitare che il generic duplichi il lavoro degli specialisti (layer, security, concurrency) sullo stesso codebase.
|
|
99
|
+
- **Scope:** trasformare `generic-software-assessment` in triage: scansione superficiale che decide quali specialisti attivare e copre solo le aree non coperte (Opzione A della gap analysis).
|
|
100
|
+
- **Criteri di accettazione:** il generic non riesamina aree già coperte da uno specialista attivo; l'output indica gli specialisti raccomandati.
|
|
101
|
+
- **Dipendenze:** meglio dopo OPT-08 (contratto di output stabile).
|
|
102
|
+
|
|
103
|
+
### OPT-11 — Delegation policy negli orchestratori
|
|
104
|
+
- **Criticità:** LOW · **Sforzo:** Basso · **Rischio:** Basso
|
|
105
|
+
- **Obiettivo:** regola esplicita "delega un subagent solo se serve" (task indipendente/parallelo, output voluminoso, riuso multiplo); non delegare ciò che una grep/read risolve.
|
|
106
|
+
- **Scope:** aggiungere una sezione `## Delegation policy` a `assessment-manager` e `project-manager`.
|
|
107
|
+
- **Criteri di accettazione:** entrambi gli orchestratori contengono i criteri delega/non-delega.
|
|
108
|
+
- **Dipendenze:** nessuna.
|
|
109
|
+
|
|
110
|
+
### OPT-12 — Hook di filtro output verboso (opzionale)
|
|
111
|
+
- **Criticità:** LOW · **Sforzo:** Basso · **Rischio:** Basso
|
|
112
|
+
- **Obiettivo:** filtrare output verbosi (build/test/log) prima che entrino nel contesto.
|
|
113
|
+
- **Scope:** `PreToolUse` su Bash in `settings.json` + script che riduce l'output di test/build alle sole righe rilevanti.
|
|
114
|
+
- **Criteri di accettazione:** l'hook appare in `/hooks`; un comando di test mostra solo failures.
|
|
115
|
+
- **Dipendenze:** nessuna. Fare solo se gli assessment inizieranno a lanciare build/test.
|