@antoneeo/agentic-sdlc-skill 1.3.1 → 1.5.0
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 +25 -5
- package/README.md +81 -84
- package/gemini-extension.json +2 -2
- package/package.json +6 -3
- package/references/analysis_template.md +44 -19
- package/references/architecture_template.md +7 -4
- package/references/feature_vision_template.md +21 -0
- package/references/features_history_template.md +5 -6
- package/references/principles_template.md +13 -0
- package/references/project_vision_template.md +26 -0
- package/references/roadmap_template.md +9 -0
- package/scripts/init.js +142 -69
- package/scripts/postinstall.js +39 -13
- package/scripts/preuninstall.js +7 -4
- package/skills/agentic-sdlc-skill/ENFORCEMENT.md +55 -0
- package/skills/agentic-sdlc-skill/SKILL.md +141 -80
- package/skills/agentic-sdlc-skill/scripts/sdlc_check.py +474 -0
- package/skills/agentic-sdlc-skill/templates.md +169 -0
package/scripts/init.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
@@ -17,63 +17,133 @@ function checkCommand(cmd) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// 1. Path definitions
|
|
20
|
-
const directories = [
|
|
21
|
-
path.join(cwd, 'ai_docs'),
|
|
22
|
-
path.join(cwd, 'ai_docs', '
|
|
23
|
-
path.join(cwd, 'ai_docs', '
|
|
24
|
-
path.join(cwd, 'ai_docs', '
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
20
|
+
const directories = [
|
|
21
|
+
path.join(cwd, 'ai_docs'),
|
|
22
|
+
path.join(cwd, 'ai_docs', 'vision'),
|
|
23
|
+
path.join(cwd, 'ai_docs', 'vision', 'features'),
|
|
24
|
+
path.join(cwd, 'ai_docs', 'strategic'),
|
|
25
|
+
path.join(cwd, 'ai_docs', 'audit'),
|
|
26
|
+
path.join(cwd, 'ai_docs', 'solutions')
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const files = {
|
|
30
|
+
projectVision: path.join(cwd, 'ai_docs', 'vision', 'project_vision.md'),
|
|
31
|
+
roadmap: path.join(cwd, 'ai_docs', 'vision', 'roadmap.md'),
|
|
32
|
+
principles: path.join(cwd, 'ai_docs', 'vision', 'principles.md'),
|
|
33
|
+
architecture: path.join(cwd, 'ai_docs', 'strategic', 'architecture.md'),
|
|
34
|
+
existingFeatures: path.join(cwd, 'ai_docs', 'strategic', 'existing_features.md'),
|
|
35
|
+
featuresHistory: path.join(cwd, 'ai_docs', 'strategic', 'features_history.md'),
|
|
31
36
|
auditPlan: path.join(cwd, 'ai_docs', 'audit', 'audit_plan.md'),
|
|
32
|
-
handoff: path.join(cwd, 'ai_docs', 'audit', 'handoff.md'),
|
|
33
|
-
claudeConfig: path.join(cwd, 'CLAUDE.md'),
|
|
34
|
-
geminiConfig: path.join(cwd, 'GEMINI.md'),
|
|
35
|
-
codexAgents: path.join(cwd, 'AGENTS.md'),
|
|
36
|
-
cursorRules: path.join(cwd, '.cursorrules')
|
|
37
|
-
};
|
|
37
|
+
handoff: path.join(cwd, 'ai_docs', 'audit', 'handoff.md'),
|
|
38
|
+
claudeConfig: path.join(cwd, 'CLAUDE.md'),
|
|
39
|
+
geminiConfig: path.join(cwd, 'GEMINI.md'),
|
|
40
|
+
codexAgents: path.join(cwd, 'AGENTS.md'),
|
|
41
|
+
cursorRules: path.join(cwd, '.cursorrules')
|
|
42
|
+
};
|
|
38
43
|
|
|
39
44
|
// 2. Operational Protocol (System Prompt)
|
|
40
|
-
const protocolContent = `# "Agentic SDLC" Operational Protocol
|
|
41
|
-
|
|
42
|
-
You are a senior software engineer
|
|
43
|
-
|
|
44
|
-
##
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
##
|
|
54
|
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
45
|
+
const protocolContent = `# "Agentic SDLC" Operational Protocol
|
|
46
|
+
|
|
47
|
+
You are a senior software engineer following a Documentation-First and Vision-Guided process. The process is proportional to risk: do not apply heavyweight governance to trivial work, but never bypass Vision, security, or design gates for significant changes.
|
|
48
|
+
|
|
49
|
+
## 0. Triage First
|
|
50
|
+
Classify every operational request:
|
|
51
|
+
- L1 Trivial: small local fix, no API/dependency/behavior expansion. Implement with relevant tests; no new docs.
|
|
52
|
+
- L2 Small: clear root cause, up to 3 files, low risk. Provide mini-analysis in the response; test.
|
|
53
|
+
- L3 Significant: public contract, user-visible behavior, security-sensitive area, new dependency, architectural impact, or more than 3 files. Use the full workflow below.
|
|
54
|
+
- Spike: time-boxed exploration; document result in \`ai_docs/solutions/SPIKE_[topic].md\`; production work must be reclassified.
|
|
55
|
+
|
|
56
|
+
Security-sensitive areas are never L1.
|
|
57
|
+
|
|
58
|
+
## 1. Mode Selection
|
|
59
|
+
- Standalone: if devPNT is unavailable, use \`ai_docs/\` as the complete source of truth.
|
|
60
|
+
- Hybrid/devPNT: if devPNT is available and configured for this project, use it for governed state. The devPNT M-VISION is the milestone north star, Master Plan is strategic roadmap, Action Plan is tactical execution, and governed artifacts live in devPNT.
|
|
61
|
+
- Do not create silent double truth. In Hybrid, \`ai_docs/\` is human-readable context, fallback, handoff, or shadow; devPNT governs plans and versioned artifacts.
|
|
62
|
+
|
|
63
|
+
## 2. Audit and Alignment
|
|
64
|
+
For L3 or explicit audit requests:
|
|
65
|
+
- Check \`ai_docs/\`, \`ai_docs/vision/\`, \`ai_docs/strategic/\`, \`ai_docs/audit/\`, and \`ai_docs/solutions/\`.
|
|
66
|
+
- If missing, create them by analyzing the codebase in batches.
|
|
67
|
+
- Never treat architecture or feature history as a substitute for Vision.
|
|
68
|
+
|
|
69
|
+
## 3. Vision Gate
|
|
70
|
+
Standalone:
|
|
71
|
+
- Read \`ai_docs/vision/project_vision.md\`, \`roadmap.md\`, and \`principles.md\`.
|
|
72
|
+
- Vision documents start as \`Stato: DRAFT\`; DRAFT informs but does not block an explicit user request.
|
|
73
|
+
- \`Stato: APPROVED\` is binding: surface conflicts before implementation.
|
|
74
|
+
|
|
75
|
+
Hybrid/devPNT:
|
|
76
|
+
- Read the active M-VISION before design or code.
|
|
77
|
+
- Verify the request advances a stated benefit or success signal.
|
|
78
|
+
- If request, local Vision, and M-VISION diverge, stop and surface the conflict.
|
|
79
|
+
|
|
80
|
+
## 4. Request Analysis
|
|
81
|
+
For L3 in Standalone:
|
|
82
|
+
- Create or update \`ai_docs/solutions/ANALYSIS_[feature].md\`.
|
|
83
|
+
- Include Objective, Feature Vision, Impact, Security and Threat Model, Action Plan, Test Strategy, and Diary/Current State.
|
|
84
|
+
|
|
85
|
+
For L3 in Hybrid:
|
|
86
|
+
- Restore Master Plan, Action Plan, and related devPNT artifacts.
|
|
87
|
+
- Use devPNT for D-UC, P-TM, E-ISP, E-TDD, E-TP, ADR, and plan updates.
|
|
88
|
+
- Use Markdown shadows only as readable mirrors, never as the authoritative source over devPNT.
|
|
89
|
+
|
|
90
|
+
## 5. Development and Testing
|
|
91
|
+
Only after the required gate for the triage level:
|
|
92
|
+
1. Implement surgically following the plan.
|
|
93
|
+
2. Write or update automated tests where possible, using AAA for unit tests.
|
|
94
|
+
3. Run tests/lint/smoke checks. If the environment cannot run them, document the alternative verification.
|
|
95
|
+
4. After 3 consecutive test runs without progress, stop and ask for guidance.
|
|
96
|
+
|
|
97
|
+
## 6. Closing
|
|
98
|
+
- Verify the result against local Vision or devPNT M-VISION.
|
|
99
|
+
- Update only documents actually impacted.
|
|
100
|
+
- In Hybrid, propose ADR/KL updates when architectural facts changed.
|
|
101
|
+
- Keep docs and code in the same commit/PR.
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
const projectVisionBoilerplate = `# Project Vision
|
|
105
|
+
Stato: DRAFT
|
|
106
|
+
|
|
107
|
+
## North Star
|
|
108
|
+
- TBD
|
|
109
|
+
|
|
110
|
+
## Target Users
|
|
111
|
+
- TBD
|
|
112
|
+
|
|
113
|
+
## Goals
|
|
114
|
+
- TBD
|
|
115
|
+
|
|
116
|
+
## Non-Goals
|
|
117
|
+
- TBD
|
|
118
|
+
|
|
119
|
+
## Success Signals
|
|
120
|
+
- TBD
|
|
121
|
+
`;
|
|
122
|
+
|
|
123
|
+
const roadmapBoilerplate = `# Vision Roadmap
|
|
124
|
+
Stato: DRAFT
|
|
125
|
+
|
|
126
|
+
| Milestone | Expected Benefit | Priority | Success Signal | Status |
|
|
127
|
+
|:---|:---|:---|:---|:---|
|
|
128
|
+
| M1 | - | - | - | [PLANNED] |
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
const principlesBoilerplate = `# Vision Principles
|
|
132
|
+
Stato: DRAFT
|
|
133
|
+
|
|
134
|
+
## Principles
|
|
135
|
+
- TBD
|
|
136
|
+
|
|
137
|
+
## Strategic Anti-Patterns
|
|
138
|
+
- TBD
|
|
139
|
+
`;
|
|
140
|
+
|
|
141
|
+
const historyBoilerplate = `<!-- GENERATED by agentic-sdlc - update manually only if the project does not use sdlc_check.py index. -->
|
|
142
|
+
# Feature History
|
|
143
|
+
|
|
144
|
+
| ID | Feature Name | Level | Status | Start Date | End Date | Analysis Doc |
|
|
145
|
+
|:---|:---|:---|:---|:---|:---|:---|
|
|
146
|
+
`;
|
|
77
147
|
|
|
78
148
|
console.log('🚀 Initializing Agentic SDLC workflow (Discovery Mode)...');
|
|
79
149
|
|
|
@@ -95,12 +165,15 @@ const writeIfNotExists = (filePath, content, description) => {
|
|
|
95
165
|
console.log(`⏭️ Skipped: ${path.relative(cwd, filePath)} already exists.`);
|
|
96
166
|
return false;
|
|
97
167
|
}
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
writeIfNotExists(files.
|
|
101
|
-
writeIfNotExists(files.
|
|
102
|
-
writeIfNotExists(files.
|
|
103
|
-
writeIfNotExists(files.
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
writeIfNotExists(files.projectVision, projectVisionBoilerplate, 'Project Vision Boilerplate');
|
|
171
|
+
writeIfNotExists(files.roadmap, roadmapBoilerplate, 'Vision Roadmap Boilerplate');
|
|
172
|
+
writeIfNotExists(files.principles, principlesBoilerplate, 'Vision Principles Boilerplate');
|
|
173
|
+
writeIfNotExists(files.architecture, '# Project Architecture\n\n- Stack:\n- Patterns:\n', 'Architecture Boilerplate');
|
|
174
|
+
writeIfNotExists(files.existingFeatures, '# Existing Features\n\n- \n', 'Features Boilerplate');
|
|
175
|
+
writeIfNotExists(files.featuresHistory, historyBoilerplate, 'History Table');
|
|
176
|
+
writeIfNotExists(files.auditPlan, '# Audit Plan\n\nStates: PENDING | ANALYZED | SKIPPED.\n\n| Percorso | Stato | Riferimento | Note |\n|---|---|---|---|\n| / | PENDING | - | Initial analysis |\n', 'Audit Plan');
|
|
104
177
|
|
|
105
178
|
// 5. Client Discovery and Configuration
|
|
106
179
|
console.log('\n--- Environment Analysis ---');
|
|
@@ -115,17 +188,17 @@ if (checkCommand('gemini')) {
|
|
|
115
188
|
writeIfNotExists(files.geminiConfig, protocolContent, 'Gemini Configuration');
|
|
116
189
|
}
|
|
117
190
|
|
|
118
|
-
if (checkCommand('codex')) {
|
|
119
|
-
console.log('✅ Codex AI detected.');
|
|
120
|
-
writeIfNotExists(files.codexAgents, protocolContent, 'Codex AGENTS.md');
|
|
121
|
-
}
|
|
191
|
+
if (checkCommand('codex')) {
|
|
192
|
+
console.log('✅ Codex AI detected.');
|
|
193
|
+
writeIfNotExists(files.codexAgents, protocolContent, 'Codex AGENTS.md');
|
|
194
|
+
}
|
|
122
195
|
|
|
123
196
|
// Cursor/Windsurf (always recommended)
|
|
124
197
|
writeIfNotExists(files.cursorRules, protocolContent, 'Cursor/Windsurf Rules');
|
|
125
198
|
|
|
126
199
|
console.log('\n✅ Setup completed successfully!');
|
|
127
200
|
console.log('💡 Next steps:');
|
|
128
|
-
console.log(' 1. If using Claude Code, start it: it will read CLAUDE.md.');
|
|
129
|
-
console.log(' 2. If using Gemini CLI, commands will use GEMINI.md.');
|
|
130
|
-
console.log(' 3. If using Codex, restart/open the project so it reads AGENTS.md.');
|
|
131
|
-
console.log(' 4. Start analyzing the codebase following ai_docs/audit/audit_plan.md.');
|
|
201
|
+
console.log(' 1. If using Claude Code, start it: it will read CLAUDE.md.');
|
|
202
|
+
console.log(' 2. If using Gemini CLI, commands will use GEMINI.md.');
|
|
203
|
+
console.log(' 3. If using Codex, restart/open the project so it reads AGENTS.md.');
|
|
204
|
+
console.log(' 4. Start analyzing the codebase following ai_docs/audit/audit_plan.md.');
|
package/scripts/postinstall.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { execSync } = require('child_process');
|
|
4
4
|
const fs = require('fs');
|
|
@@ -10,9 +10,12 @@ const SKILL_SOURCE = path.join(PACKAGE_ROOT, 'skills', 'agentic-sdlc-skill');
|
|
|
10
10
|
const CLAUDE_HOME = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
|
|
11
11
|
const CLAUDE_SKILLS_DIR = path.join(CLAUDE_HOME, 'skills');
|
|
12
12
|
const CLAUDE_SKILL_TARGET = path.join(CLAUDE_SKILLS_DIR, 'agentic-sdlc');
|
|
13
|
-
const CODEX_HOME = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
14
|
-
const CODEX_SKILLS_DIR = path.join(CODEX_HOME, 'skills');
|
|
15
|
-
const CODEX_SKILL_TARGET = path.join(CODEX_SKILLS_DIR, 'agentic-sdlc');
|
|
13
|
+
const CODEX_HOME = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
14
|
+
const CODEX_SKILLS_DIR = path.join(CODEX_HOME, 'skills');
|
|
15
|
+
const CODEX_SKILL_TARGET = path.join(CODEX_SKILLS_DIR, 'agentic-sdlc');
|
|
16
|
+
const GEMINI_HOME = process.env.GEMINI_HOME || path.join(os.homedir(), '.gemini');
|
|
17
|
+
const GEMINI_SKILLS_DIR = path.join(GEMINI_HOME, 'skills');
|
|
18
|
+
const GEMINI_SKILL_TARGET = path.join(GEMINI_SKILLS_DIR, 'agentic-sdlc');
|
|
16
19
|
|
|
17
20
|
function checkCommand(cmd) {
|
|
18
21
|
try {
|
|
@@ -56,7 +59,7 @@ function installClaudeSkill() {
|
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
function installCodexSkill() {
|
|
62
|
+
function installCodexSkill() {
|
|
60
63
|
if (!fs.existsSync(SKILL_SOURCE)) {
|
|
61
64
|
console.log(`⚠️ Skill source not found at ${SKILL_SOURCE}; skipping Codex install.`);
|
|
62
65
|
return false;
|
|
@@ -72,15 +75,37 @@ function installCodexSkill() {
|
|
|
72
75
|
console.log(` Manual install: copy "${SKILL_SOURCE}" to "${CODEX_SKILL_TARGET}".`);
|
|
73
76
|
return false;
|
|
74
77
|
}
|
|
75
|
-
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function installGeminiSkill() {
|
|
81
|
+
if (!fs.existsSync(SKILL_SOURCE)) {
|
|
82
|
+
console.log(`⚠️ Skill source not found at ${SKILL_SOURCE}; skipping Gemini install.`);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
fs.mkdirSync(GEMINI_SKILLS_DIR, { recursive: true });
|
|
87
|
+
copyRecursive(SKILL_SOURCE, GEMINI_SKILL_TARGET);
|
|
88
|
+
console.log(`📦 Installed Gemini skill at: ${GEMINI_SKILL_TARGET}`);
|
|
89
|
+
console.log(' Run "gemini skills reload" or restart Gemini CLI to load it.');
|
|
90
|
+
return true;
|
|
91
|
+
} catch (err) {
|
|
92
|
+
console.log(`⚠️ Failed to install Gemini skill: ${err.message}`);
|
|
93
|
+
console.log(` Manual install: copy "${SKILL_SOURCE}" to "${GEMINI_SKILL_TARGET}".`);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
76
97
|
|
|
77
98
|
function hasCodexHome() {
|
|
78
99
|
return Boolean(process.env.CODEX_HOME) || fs.existsSync(CODEX_HOME);
|
|
79
100
|
}
|
|
80
101
|
|
|
81
|
-
function hasClaudeHome() {
|
|
82
|
-
return Boolean(process.env.CLAUDE_CONFIG_DIR) || fs.existsSync(CLAUDE_HOME);
|
|
83
|
-
}
|
|
102
|
+
function hasClaudeHome() {
|
|
103
|
+
return Boolean(process.env.CLAUDE_CONFIG_DIR) || fs.existsSync(CLAUDE_HOME);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function hasGeminiHome() {
|
|
107
|
+
return Boolean(process.env.GEMINI_HOME) || fs.existsSync(GEMINI_HOME);
|
|
108
|
+
}
|
|
84
109
|
|
|
85
110
|
console.log('\n--- Agentic SDLC Skill Discovery ---');
|
|
86
111
|
|
|
@@ -92,10 +117,11 @@ if (checkCommand('claude') || hasClaudeHome()) {
|
|
|
92
117
|
installClaudeSkill();
|
|
93
118
|
}
|
|
94
119
|
|
|
95
|
-
if (checkCommand('gemini')) {
|
|
96
|
-
console.log(`✅ Detected: Gemini CLI`);
|
|
97
|
-
detected = true;
|
|
98
|
-
|
|
120
|
+
if (checkCommand('gemini') || hasGeminiHome()) {
|
|
121
|
+
console.log(`✅ Detected: Gemini CLI`);
|
|
122
|
+
detected = true;
|
|
123
|
+
installGeminiSkill();
|
|
124
|
+
}
|
|
99
125
|
|
|
100
126
|
if (checkCommand('codex') || hasCodexHome()) {
|
|
101
127
|
console.log(`✅ Detected: Codex AI`);
|
package/scripts/preuninstall.js
CHANGED
|
@@ -6,8 +6,10 @@ const os = require('os');
|
|
|
6
6
|
|
|
7
7
|
const CLAUDE_HOME = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
|
|
8
8
|
const CLAUDE_SKILL_TARGET = path.join(CLAUDE_HOME, 'skills', 'agentic-sdlc');
|
|
9
|
-
const CODEX_HOME = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
10
|
-
const CODEX_SKILL_TARGET = path.join(CODEX_HOME, 'skills', 'agentic-sdlc');
|
|
9
|
+
const CODEX_HOME = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
10
|
+
const CODEX_SKILL_TARGET = path.join(CODEX_HOME, 'skills', 'agentic-sdlc');
|
|
11
|
+
const GEMINI_HOME = process.env.GEMINI_HOME || path.join(os.homedir(), '.gemini');
|
|
12
|
+
const GEMINI_SKILL_TARGET = path.join(GEMINI_HOME, 'skills', 'agentic-sdlc');
|
|
11
13
|
|
|
12
14
|
function removeSkill(target, label) {
|
|
13
15
|
if (!fs.existsSync(target)) return;
|
|
@@ -19,5 +21,6 @@ function removeSkill(target, label) {
|
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
removeSkill(CLAUDE_SKILL_TARGET, 'Claude Code');
|
|
23
|
-
removeSkill(CODEX_SKILL_TARGET, 'Codex');
|
|
24
|
+
removeSkill(CLAUDE_SKILL_TARGET, 'Claude Code');
|
|
25
|
+
removeSkill(CODEX_SKILL_TARGET, 'Codex');
|
|
26
|
+
removeSkill(GEMINI_SKILL_TARGET, 'Gemini');
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Enforcement meccanico (opzionale, consigliato per i team)
|
|
2
|
+
|
|
3
|
+
Le regole a livello di prompt dipendono dalla disciplina del modello e degradano con contesti lunghi, compaction e istruzioni concorrenti. Tre livelli di garanzia crescente:
|
|
4
|
+
|
|
5
|
+
## 1. Validazione interattiva (default, nessun setup)
|
|
6
|
+
|
|
7
|
+
L'agente esegue alla chiusura (Fase 5) un solo gate:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
python "<dir_skill>/scripts/sdlc_check.py" check
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
(`check` = validate + stale in un comando.) Exit code ≠ 0 ⇒ la feature non si dichiara chiusa. È il livello minimo previsto dalla skill.
|
|
14
|
+
|
|
15
|
+
## 2. Check in CI (consigliato per i team)
|
|
16
|
+
|
|
17
|
+
Copia `scripts/sdlc_check.py` nel repository (es. `tools/sdlc_check.py`) e aggiungi alla pipeline:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
python tools/sdlc_check.py validate
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Effetto: indice non rigenerato, frontmatter invalidi, sezione sicurezza mancante o stati incoerenti **bloccano la pipeline** invece di affidarsi alla memoria dell'agente. Funziona perché i documenti viaggiano nello stesso PR del codice (regola di Fase 5).
|
|
24
|
+
|
|
25
|
+
Nota: la copia nel repo è quella autoritativa per la CI; aggiornala quando aggiorni la skill.
|
|
26
|
+
|
|
27
|
+
## 3. Hook PreToolUse (gate sulle scritture)
|
|
28
|
+
|
|
29
|
+
Blocca Edit/Write su percorsi protetti quando nessuna `ANALYSIS_*.md` è `IN_PROGRESS`. In `.claude/settings.json` del progetto:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"hooks": {
|
|
34
|
+
"PreToolUse": [
|
|
35
|
+
{
|
|
36
|
+
"matcher": "Write|Edit",
|
|
37
|
+
"hooks": [
|
|
38
|
+
{
|
|
39
|
+
"type": "command",
|
|
40
|
+
"command": "python \"C:\\Users\\<utente>\\.claude\\skills\\agentic-sdlc\\scripts\\sdlc_check.py\" gate --hook --protected \"src/auth;src/crypto\""
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Semantica: exit code 2 + messaggio su stderr ⇒ la scrittura viene bloccata e il messaggio è mostrato all'agente, che deve creare l'ANALYSIS (Fase 3) prima di riprovare.
|
|
50
|
+
|
|
51
|
+
**Avvertenze d'uso:**
|
|
52
|
+
- Il gate è volutamente grossolano: applicato a tutto `src/` bloccherebbe anche i task L1/L2 legittimi previsti dal Triage. Usalo **solo su directory security-critical** (`--protected "src/auth;src/crypto"`), dove "mai senza analisi" è la policy desiderata.
|
|
53
|
+
- I percorsi in `--protected` sono prefissi relativi alla radice del progetto, separati da `;`.
|
|
54
|
+
- `ai_docs/`, `tests/` e `test/` sono sempre esclusi dal blocco.
|
|
55
|
+
- L'hook assume che la working directory sia la radice del progetto (comportamento standard degli hook di Claude Code).
|