@guilhermefsousa/open-spec-kit 0.0.5 → 0.0.7
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/package.json +1 -1
- package/src/commands/doctor.js +14 -3
- package/src/commands/init.js +32 -42
- package/src/commands/validate.js +1 -1
- package/src/utils/http.js +1 -1
- package/templates/agents/agents/spec-hub.agent.md +4 -1
- package/templates/agents/rules/hub_structure.instructions.md +4 -1
- package/templates/agents/rules/ownership.instructions.md +19 -9
- package/templates/agents/skills/dev-orchestrator/SKILL.md +55 -5
- package/templates/agents/skills/discovery/SKILL.md +19 -4
- package/templates/agents/skills/setup-project/SKILL.md +39 -5
- package/templates/agents/skills/specifying-features/SKILL.md +54 -12
package/package.json
CHANGED
package/src/commands/doctor.js
CHANGED
|
@@ -67,7 +67,10 @@ export async function doctorCommand() {
|
|
|
67
67
|
if (agents.includes('claude')) {
|
|
68
68
|
try {
|
|
69
69
|
claudeMcpContent = await readFile(join(cwd, '.mcp.json'), 'utf-8');
|
|
70
|
-
if (claudeMcpContent.includes('SEU-TOKEN') || claudeMcpContent.includes('SEU-DOMINIO')
|
|
70
|
+
if (claudeMcpContent.includes('SEU-TOKEN') || claudeMcpContent.includes('SEU-DOMINIO')
|
|
71
|
+
|| claudeMcpContent.includes('seu-token-aqui') || claudeMcpContent.includes('seu-dominio')
|
|
72
|
+
|| claudeMcpContent.includes('seu-email') || claudeMcpContent.includes('${CONFLUENCE_URL}')
|
|
73
|
+
|| claudeMcpContent.includes('${CONFLUENCE_API_TOKEN}')) {
|
|
71
74
|
console.log(chalk.yellow(' ⚠ .mcp.json (Claude) existe mas tem placeholders'));
|
|
72
75
|
fail++;
|
|
73
76
|
} else {
|
|
@@ -93,8 +96,16 @@ export async function doctorCommand() {
|
|
|
93
96
|
if (agents.includes('copilot')) {
|
|
94
97
|
try {
|
|
95
98
|
copilotMcpContent = await readFile(join(cwd, '.vscode/mcp.json'), 'utf-8');
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
if (copilotMcpContent.includes('SEU-TOKEN') || copilotMcpContent.includes('SEU-DOMINIO')
|
|
100
|
+
|| copilotMcpContent.includes('seu-token-aqui') || copilotMcpContent.includes('seu-dominio')
|
|
101
|
+
|| copilotMcpContent.includes('seu-email') || copilotMcpContent.includes('${CONFLUENCE_URL}')
|
|
102
|
+
|| copilotMcpContent.includes('${CONFLUENCE_API_TOKEN}')) {
|
|
103
|
+
console.log(chalk.yellow(' ⚠ .vscode/mcp.json (Copilot) existe mas tem placeholders'));
|
|
104
|
+
fail++;
|
|
105
|
+
} else {
|
|
106
|
+
console.log(chalk.green(' ✓ .vscode/mcp.json (Copilot) configurado'));
|
|
107
|
+
pass++;
|
|
108
|
+
}
|
|
98
109
|
} catch {
|
|
99
110
|
console.log(chalk.red(' ✗ .vscode/mcp.json (Copilot) ausente'));
|
|
100
111
|
fail++;
|
package/src/commands/init.js
CHANGED
|
@@ -103,7 +103,7 @@ function deriveSigla(projectName) {
|
|
|
103
103
|
.filter(w => !skip.has(w.toLowerCase()))
|
|
104
104
|
.map(w => w[0].toUpperCase())
|
|
105
105
|
.join('');
|
|
106
|
-
return letters.slice(0, 4) || projectName.slice(0, 3).toUpperCase();
|
|
106
|
+
return (letters.slice(0, 4) || projectName.trim().slice(0, 3).toUpperCase()).trim();
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
// ──────────────────────────────────────────────────────
|
|
@@ -342,15 +342,7 @@ Thumbs.db
|
|
|
342
342
|
*.swp
|
|
343
343
|
`;
|
|
344
344
|
|
|
345
|
-
|
|
346
|
-
content += `
|
|
347
|
-
# VS Code (exceto MCP config compartilhada)
|
|
348
|
-
.vscode/*
|
|
349
|
-
!.vscode/mcp.json
|
|
350
|
-
`;
|
|
351
|
-
} else {
|
|
352
|
-
content += '\n.vscode/\n';
|
|
353
|
-
}
|
|
345
|
+
content += '\n.vscode/\n';
|
|
354
346
|
|
|
355
347
|
return content;
|
|
356
348
|
}
|
|
@@ -391,53 +383,38 @@ FIGMA_API_KEY=seu-figma-api-key
|
|
|
391
383
|
return content;
|
|
392
384
|
}
|
|
393
385
|
|
|
394
|
-
function
|
|
386
|
+
function buildMcpServers(config, { stdio = false } = {}) {
|
|
395
387
|
const runner = detectMcpRunner();
|
|
396
|
-
const
|
|
397
|
-
...runner.prefix,
|
|
398
|
-
'--confluence-url', '${CONFLUENCE_URL}',
|
|
399
|
-
'--confluence-username', '${CONFLUENCE_USERNAME}',
|
|
400
|
-
'--confluence-token', '${CONFLUENCE_API_TOKEN}'
|
|
401
|
-
];
|
|
388
|
+
const base = stdio ? { type: 'stdio' } : {};
|
|
402
389
|
const servers = {
|
|
403
390
|
confluence: {
|
|
391
|
+
...base,
|
|
404
392
|
command: runner.command,
|
|
405
|
-
args:
|
|
393
|
+
args: [
|
|
394
|
+
...runner.prefix,
|
|
395
|
+
'--confluence-url', config.confluenceUrl,
|
|
396
|
+
'--confluence-username', config.confluenceUser,
|
|
397
|
+
'--confluence-token', config.confluenceToken
|
|
398
|
+
],
|
|
406
399
|
}
|
|
407
400
|
};
|
|
408
401
|
if (config.hasFigma && config.figmaFileUrl) {
|
|
409
402
|
const npx = detectNpxRunner();
|
|
410
403
|
servers.figma = {
|
|
404
|
+
...base,
|
|
411
405
|
command: npx.command,
|
|
412
|
-
args: [...npx.prefix, FIGMA_MCP_PACKAGE, '--figma-api-key',
|
|
406
|
+
args: [...npx.prefix, FIGMA_MCP_PACKAGE, '--figma-api-key', config.figmaToken]
|
|
413
407
|
};
|
|
414
408
|
}
|
|
415
|
-
return
|
|
409
|
+
return servers;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function generateClaudeMcp(config) {
|
|
413
|
+
return JSON.stringify({ mcpServers: buildMcpServers(config) }, null, 2) + '\n';
|
|
416
414
|
}
|
|
417
415
|
|
|
418
416
|
function generateCopilotMcp(config) {
|
|
419
|
-
|
|
420
|
-
const confluenceArgs = [
|
|
421
|
-
...runner.prefix,
|
|
422
|
-
'--env-file', '.env',
|
|
423
|
-
'--no-confluence-ssl-verify'
|
|
424
|
-
];
|
|
425
|
-
const servers = {
|
|
426
|
-
confluence: {
|
|
427
|
-
type: 'stdio',
|
|
428
|
-
command: runner.command,
|
|
429
|
-
args: confluenceArgs,
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
if (config.hasFigma && config.figmaFileUrl) {
|
|
433
|
-
const npx = detectNpxRunner();
|
|
434
|
-
servers.figma = {
|
|
435
|
-
type: 'stdio',
|
|
436
|
-
command: npx.command,
|
|
437
|
-
args: [...npx.prefix, FIGMA_MCP_PACKAGE, '--figma-api-key', '${input:figma-api-key}']
|
|
438
|
-
};
|
|
439
|
-
}
|
|
440
|
-
return JSON.stringify({ servers }, null, 2) + '\n';
|
|
417
|
+
return JSON.stringify({ servers: buildMcpServers(config, { stdio: true }) }, null, 2) + '\n';
|
|
441
418
|
}
|
|
442
419
|
|
|
443
420
|
function generateArchitectureSkeleton(config) {
|
|
@@ -982,3 +959,16 @@ export async function initCommand() {
|
|
|
982
959
|
process.exit(1);
|
|
983
960
|
}
|
|
984
961
|
}
|
|
962
|
+
|
|
963
|
+
// Exported for testing — pure functions with no side effects
|
|
964
|
+
export {
|
|
965
|
+
stripHtml,
|
|
966
|
+
detectTechInText,
|
|
967
|
+
detectRepoNames,
|
|
968
|
+
deriveSigla,
|
|
969
|
+
generateProjectsYml,
|
|
970
|
+
generateEnvFile,
|
|
971
|
+
generateEnvExample,
|
|
972
|
+
generateGitignore,
|
|
973
|
+
generateArchitectureSkeleton,
|
|
974
|
+
};
|
package/src/commands/validate.js
CHANGED
|
@@ -24,7 +24,7 @@ import * as rules from '../schemas/spec.schema.js';
|
|
|
24
24
|
function parseBrief(content) {
|
|
25
25
|
const sections = parseSections(content);
|
|
26
26
|
return {
|
|
27
|
-
lineCount: content.split(
|
|
27
|
+
lineCount: content.split(/\r?\n/).length,
|
|
28
28
|
hasProblema: !!findSection(sections, /problema|contexto|visão\s*geral|overview|background|objetivo\s+do\s+produto|situação\s*atual|descri[çc][aã]o|identifica[çc][aã]o/i),
|
|
29
29
|
hasForaDeEscopo: !!findSection(sections, /fora\s+de\s+escopo/i),
|
|
30
30
|
reqIds: content.match(/REQ-\w+/g) || [],
|
package/src/utils/http.js
CHANGED
|
@@ -63,7 +63,7 @@ const SSL_ERROR_CODES = new Set([
|
|
|
63
63
|
]);
|
|
64
64
|
|
|
65
65
|
export function isSslError(err) {
|
|
66
|
-
return err.status === 0 && (
|
|
66
|
+
return err.status === 0 && !!(
|
|
67
67
|
SSL_ERROR_CODES.has(err.code) ||
|
|
68
68
|
SSL_ERROR_CODES.has(err.message) ||
|
|
69
69
|
(err.message && SSL_ERROR_CODES.has(err.message.split(':').pop()?.trim()))
|
|
@@ -84,13 +84,16 @@ specs/NNN-nome/
|
|
|
84
84
|
links.md ← PRs + link da feature page
|
|
85
85
|
audit-report.md ← resultado do self-review do /spec
|
|
86
86
|
conformance-report.json ← validação pós-implementação do /dev
|
|
87
|
+
conformance-history.log ← histórico de validações (append por run)
|
|
88
|
+
openapi.yaml ← stub OpenAPI 3.0 (opcional, se REST endpoints)
|
|
87
89
|
```
|
|
88
90
|
|
|
89
91
|
## Validation checklist
|
|
90
92
|
|
|
91
93
|
- [ ] Brief máx 1 página
|
|
92
94
|
- [ ] Todo cenário tem Given/When/Then
|
|
93
|
-
- [ ] Cenários de falha cobertos
|
|
95
|
+
- [ ] Cenários de falha cobertos (401, 403, input validation 400)
|
|
96
|
+
- [ ] Cenários de NFR cobertos (se PRD tem Requisitos Não-Funcionais)
|
|
94
97
|
- [ ] Tasks agrupadas por repo (per projects.yml)
|
|
95
98
|
- [ ] Dependências explícitas
|
|
96
99
|
- [ ] Cada task = 1 PR
|
|
@@ -24,7 +24,8 @@ applyTo: '**/*.md'
|
|
|
24
24
|
|
|
25
25
|
1. Created: spec directory with brief + scenarios + contracts + tasks
|
|
26
26
|
2. In progress: tasks are checked off, links.md tracks PRs
|
|
27
|
-
3.
|
|
27
|
+
3. Post-merge sync: if implementation diverged intentionally from spec, /dev updates contracts.md and scenarios.md to match reality (Phase D.1.5)
|
|
28
|
+
4. Done: all tasks checked, spec directory stays (it IS the history)
|
|
28
29
|
|
|
29
30
|
Specs are NOT archived or moved. The spec directory with checked tasks IS the record.
|
|
30
31
|
|
|
@@ -39,6 +40,8 @@ Specs are NOT archived or moved. The spec directory with checked tasks IS the re
|
|
|
39
40
|
| PR tracking | `specs/<spec>/links.md` |
|
|
40
41
|
| Spec quality audit | `specs/<spec>/audit-report.md` |
|
|
41
42
|
| Implementation conformance | `specs/<spec>/conformance-report.json` |
|
|
43
|
+
| Conformance history | `specs/<spec>/conformance-history.log` |
|
|
44
|
+
| OpenAPI stub (optional) | `specs/<spec>/openapi.yaml` |
|
|
42
45
|
| Architecture overview | `docs/architecture.md` |
|
|
43
46
|
| Architecture decisions | `docs/decisions/ADR-NNN.md` |
|
|
44
47
|
| Lessons learned | `docs/lessons/NNN-title.md` |
|
|
@@ -6,7 +6,7 @@ applyTo: '**/*.md'
|
|
|
6
6
|
|
|
7
7
|
# Rule: Artifact Ownership (RACI)
|
|
8
8
|
|
|
9
|
-
Every artifact in this project has exactly **one Owner** (creates it) and
|
|
9
|
+
Every artifact in this project has exactly **one Owner** (creates it) and one or more designated **Updaters** (can modify it after creation under specific conditions). Other skills may **Read** or **Validate**, but never **Write**.
|
|
10
10
|
|
|
11
11
|
This rule exists to prevent the "duplicate responsibility" anti-pattern where multiple skills update the same artifact with no clear authority, causing drift and conflicts.
|
|
12
12
|
|
|
@@ -16,8 +16,8 @@ This rule exists to prevent the "duplicate responsibility" anti-pattern where mu
|
|
|
16
16
|
|----------|----------------|---------|---------|------------|
|
|
17
17
|
| Demandas/ labels | /setup | — | /discovery | — |
|
|
18
18
|
| Visão do Produto | /setup | — | all | — |
|
|
19
|
-
|
|
|
20
|
-
| DD (Design Document) | /spec (via `design-doc` agent
|
|
19
|
+
| Glossário | /setup | /discovery (exit gate), /dev (post-merge only) | /spec | /spec (read-only validate) |
|
|
20
|
+
| DD (Design Document) | /spec (via `design-doc` agent) | /dev (post-merge, via `design-doc` agent) | — | — |
|
|
21
21
|
| Domínio/Regras | /setup | /dev (post-merge only) | /discovery, /spec | — |
|
|
22
22
|
| Domínio/Fluxos | /setup | /dev (post-merge only) | /discovery | — |
|
|
23
23
|
| Domínio/Tabelas | /setup | — | /discovery | — |
|
|
@@ -27,25 +27,35 @@ This rule exists to prevent the "duplicate responsibility" anti-pattern where mu
|
|
|
27
27
|
| Feature labels | each skill at its transition | — | all | — |
|
|
28
28
|
| Arquivados/ | /setup | — | — | — |
|
|
29
29
|
|
|
30
|
+
**Glossário conflict rule**: if /dev (post-merge) needs to update a term that /discovery defined, /dev's update wins — it reflects implemented reality. /dev adds a note: "Atualizado pós-merge: {reason}".
|
|
31
|
+
|
|
32
|
+
**DD update coordination**: /spec updates the DD FIRST (during spec phase), /dev updates AFTER MERGE (during Phase D). If /dev needs to change something /spec wrote, /dev overwrites with implemented reality (code is source of truth post-merge). No locking needed — the sequential workflow prevents simultaneous updates.
|
|
33
|
+
|
|
30
34
|
## Local Artifacts
|
|
31
35
|
|
|
32
36
|
| Artifact | Owner (creates) | Updater | Readers | Validators |
|
|
33
37
|
|----------|----------------|---------|---------|------------|
|
|
34
38
|
| `projects.yml` | /setup | /spec (adds planned repos), /dev (repo URLs + status) | all | — |
|
|
35
|
-
| `docs/architecture.md` | /setup | /discovery (resolves decisions) | /spec, /dev | /spec (validates no blockers) |
|
|
39
|
+
| `docs/architecture.md` | /setup | /discovery (resolves decisions), /dev (adds resolved decisions post-merge) | /spec, /dev | /spec (validates no blockers) |
|
|
36
40
|
| `docs/lessons/` | /dev | /dev | all | — |
|
|
37
41
|
| `docs/decisions/` | manual / spec-agent | — | all | — |
|
|
42
|
+
| `docs/pending-confluence-updates.md` | any skill (on MCP failure) | any skill (on retry) | all | — |
|
|
38
43
|
| `specs/NNN/brief.md` | /spec | — | /dev | — |
|
|
39
|
-
| `specs/NNN/scenarios.md` | /spec | — | /dev | — |
|
|
40
|
-
| `specs/NNN/contracts.md` | /spec | — | /dev | — |
|
|
44
|
+
| `specs/NNN/scenarios.md` | /spec | /dev (post-merge sync D.1.5 — only if conformance report shows intentional divergence) | /dev | — |
|
|
45
|
+
| `specs/NNN/contracts.md` | /spec | /dev (post-merge sync D.1.5 — only if conformance report shows intentional divergence) | /dev | — |
|
|
41
46
|
| `specs/NNN/tasks.md` | /spec | — | /dev | — |
|
|
42
47
|
| `specs/NNN/links.md` | /spec (template) | /dev (MR links) | — | — |
|
|
43
48
|
| `specs/NNN/audit-report.md` | /spec (self-review) | — | /dev (reads before Phase B, blocks if ❌) | — |
|
|
44
|
-
| `specs/NNN/
|
|
49
|
+
| `specs/NNN/openapi.yaml` | /spec (optional, if REST endpoints) | /dev (may extend) | — | — |
|
|
50
|
+
| `specs/NNN/conformance-report.json` | /dev (Phase C.3) | /dev (overwrites per run) | CI Guard | — |
|
|
51
|
+
| `specs/NNN/conformance-history.log` | /dev (Phase C.3) | /dev (appends per run) | — | — |
|
|
52
|
+
| `CHANGELOG.md` (impl repo) | /dev (Phase D.4.5) | /dev | all | — |
|
|
53
|
+
|
|
54
|
+
**Conformance versioning**: `conformance-report.json` is overwritten on each /dev run. To preserve history, /dev appends a summary line to `specs/NNN/conformance-history.log`: `{timestamp} | {result} | {matching}/{total} endpoints | {matching}/{total} fields`
|
|
45
55
|
|
|
46
56
|
## Key Rules
|
|
47
57
|
|
|
48
|
-
1. **One
|
|
58
|
+
1. **One Owner per artifact** — each artifact has exactly one Owner that creates it. Updaters are explicitly designated in the matrix above with conditions (e.g., "post-merge only"). If a skill writes to an artifact where it is not listed as Owner or Updater, it is wrong.
|
|
49
59
|
|
|
50
60
|
2. **Validate ≠ Update** — /spec validates the Glossário (checks all terms are present) but does NOT add terms. If terms are missing, it stops and asks the dev to re-run /discovery.
|
|
51
61
|
|
|
@@ -111,7 +121,7 @@ The `docs/architecture.md` "Decisões em Aberto" table uses this schema:
|
|
|
111
121
|
|
|
112
122
|
Status values: `aberta`, `resolvida — [decisão tomada]`
|
|
113
123
|
|
|
114
|
-
|
|
124
|
+
/discovery updates this column during its exit gate. /dev may also add resolved decisions post-merge (Phase D.4) when new decisions are discovered during implementation. /spec validates that no `aberta` decision blocks /dev.
|
|
115
125
|
|
|
116
126
|
## links.md PR Table Format
|
|
117
127
|
|
|
@@ -58,7 +58,7 @@ Read from `projects.yml` → `agents` section:
|
|
|
58
58
|
|
|
59
59
|
| Role | Config key | If null or missing |
|
|
60
60
|
|------|-----------|-------------------|
|
|
61
|
-
| Security scan | `agents.security` | Skip scan, add note to MR: "Security scan manual
|
|
61
|
+
| Security scan | `agents.security` | Skip scan, add note to MR: "Security scan manual necessário" |
|
|
62
62
|
| Code review | `agents.code_review` | Skip pre-review, notify dev |
|
|
63
63
|
| Design document | `agents.design_doc` | Update DD directly no Confluence (read → append → update) |
|
|
64
64
|
|
|
@@ -75,12 +75,12 @@ Read from `projects.yml` → `agents` section:
|
|
|
75
75
|
- Dependencies between groups
|
|
76
76
|
- Parallelizable groups (marked `[P]`)
|
|
77
77
|
- Execution order
|
|
78
|
-
|
|
78
|
+
4. **Check if repos exist** — for each repo referenced in tasks.md:
|
|
79
79
|
- Look up the repo in `projects.yml`
|
|
80
80
|
- If `status: active` and `url` is filled → repo exists, skip
|
|
81
81
|
- If `status: planned` and `url` is null → **create the repo** (see Phase A.1 below)
|
|
82
82
|
- If the repo is NOT declared in projects.yml → stop and ask the dev
|
|
83
|
-
|
|
83
|
+
5. Create GitLab/GitHub Issues (1 per task) via API or terminal:
|
|
84
84
|
- Title: `[NNN] task description`
|
|
85
85
|
- Labels: `spec`, `NNN-feature-name`
|
|
86
86
|
- Assign to the repo's issue board
|
|
@@ -256,6 +256,12 @@ The orchestrator extracts response type field names from contracts.md and asks t
|
|
|
256
256
|
|
|
257
257
|
This artifact enables CI Guard (see below) and provides audit trail for compliance.
|
|
258
258
|
|
|
259
|
+
Also append a summary line to `specs/NNN-name/conformance-history.log` (create if it doesn't exist):
|
|
260
|
+
```
|
|
261
|
+
{timestamp} | {result} | {matching}/{total} endpoints | {matching}/{total} fields
|
|
262
|
+
```
|
|
263
|
+
This preserves history across multiple /dev runs.
|
|
264
|
+
|
|
259
265
|
C.4. **Run extension hooks** (if any)
|
|
260
266
|
|
|
261
267
|
If the spec repo has a `hooks/pre-merge/` directory with executable scripts, run each one in alphabetical order. Each script receives two arguments: `<spec-dir>` and `<repo-dir>`.
|
|
@@ -315,6 +321,17 @@ If the code reviewer (human or agent) rejects the MR:
|
|
|
315
321
|
After the dev merges the MR:
|
|
316
322
|
|
|
317
323
|
D.1. Update `specs/NNN-name/links.md` with merged MR link
|
|
324
|
+
|
|
325
|
+
D.1.5. **Sync spec with implementation reality**
|
|
326
|
+
If the conformance report (Phase C.3) detected INTENTIONAL divergences (spec was wrong, implementation corrected it), update the LOCAL spec files to match what was actually implemented:
|
|
327
|
+
- `contracts.md`: fix endpoint paths, response fields, or types that diverged
|
|
328
|
+
- `scenarios.md`: update Given/When/Then if behavior changed
|
|
329
|
+
- Commit: `fix(NNN): sync spec with implementation — {summary of changes}`
|
|
330
|
+
|
|
331
|
+
This ensures specs remain the source of truth for FUTURE features that reference them. Without this update, /discovery and /spec for next features read stale contracts.
|
|
332
|
+
|
|
333
|
+
If conformance report shows NO divergences → skip (specs already match).
|
|
334
|
+
|
|
318
335
|
D.2. Move VCS Issue → `done`
|
|
319
336
|
D.3. **Update living docs on Confluence** (via MCP):
|
|
320
337
|
|
|
@@ -336,7 +353,13 @@ D.3. **Update living docs on Confluence** (via MCP):
|
|
|
336
353
|
- Notify the dev with message: "Confluence indisponível — atualizações salvas em docs/pending-confluence-updates.md. Execute manualmente quando o Confluence voltar."
|
|
337
354
|
- On the next /dev execution, check if `docs/pending-confluence-updates.md` exists and attempt to apply pending updates
|
|
338
355
|
|
|
339
|
-
D.4.
|
|
356
|
+
D.4. **Post-implementation discoveries:**
|
|
357
|
+
|
|
358
|
+
If implementation revealed:
|
|
359
|
+
- a) A SURPRISE (unexpected behavior, edge case) → save to `docs/lessons/NNN-title.md` with template below
|
|
360
|
+
- b) A NEW ARCHITECTURE DECISION (chose a pattern, discovered a constraint) → add to `docs/architecture.md` "Decisões em Aberto" table with Status: `resolvida — [decisão tomada durante implementação de {SIGLA}-NNN]`. This ensures architecture.md reflects decisions made during /dev, not just during /discovery.
|
|
361
|
+
|
|
362
|
+
Lessons template:
|
|
340
363
|
```
|
|
341
364
|
## O que aconteceu
|
|
342
365
|
[description]
|
|
@@ -345,6 +368,26 @@ D.4. If something surprised during implementation → generate `docs/lessons/NNN
|
|
|
345
368
|
## Como evitar
|
|
346
369
|
[what to do differently next time]
|
|
347
370
|
```
|
|
371
|
+
D.4.5. **Update CHANGELOG.md**
|
|
372
|
+
|
|
373
|
+
In the MAIN repo (first repo in projects.yml), create or update `CHANGELOG.md` with an entry for this feature:
|
|
374
|
+
|
|
375
|
+
```markdown
|
|
376
|
+
## [{SIGLA}-NNN] Feature Name — YYYY-MM-DD
|
|
377
|
+
|
|
378
|
+
### Adicionado
|
|
379
|
+
- {list new endpoints from conformance report}
|
|
380
|
+
- {list new entities from contracts.md}
|
|
381
|
+
|
|
382
|
+
### Alterado
|
|
383
|
+
- {list modified entities/endpoints, if evolution feature}
|
|
384
|
+
|
|
385
|
+
### Observações
|
|
386
|
+
- {any "A CONFIRMAR" items still pending}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
If `CHANGELOG.md` doesn't exist, create it with header: `# Changelog` and a reference to [Keep a Changelog](https://keepachangelog.com/).
|
|
390
|
+
|
|
348
391
|
D.5. Notify Google Chat (rich card format):
|
|
349
392
|
```bash
|
|
350
393
|
./scripts/notify-gchat.sh --card \
|
|
@@ -387,6 +430,7 @@ E.3. Validate the API (orchestrator does via curl):
|
|
|
387
430
|
- Health check (`GET /health` → 200)
|
|
388
431
|
- Minimum flow: register → login → 1 authenticated CRUD operation
|
|
389
432
|
- Verify CORS (front origin must be accepted)
|
|
433
|
+
- If the spec has NFR scenarios (performance targets): run a basic load smoke test against the critical endpoint (e.g., `hey -n 100 -c 10 {url}` or equivalent) and verify the p95 response time meets the target. If load testing tooling is not available, log: "NFR validation manual necessária — tooling de load test não disponível."
|
|
390
434
|
|
|
391
435
|
E.4. Validate the frontend (orchestrator checks):
|
|
392
436
|
- Build passes (stack agent executes the build)
|
|
@@ -534,6 +578,9 @@ BUNDLE_SIZE=$(du -sk "$2/dist/assets/" | cut -f1)
|
|
|
534
578
|
|
|
535
579
|
## Validation checklist
|
|
536
580
|
|
|
581
|
+
- [ ] Audit-report.md read and evaluated (no ❌ items)
|
|
582
|
+
- [ ] Repos auto-created if `status: planned` (Phase A.1)
|
|
583
|
+
- [ ] Feature label changed to `em-dev` on Confluence
|
|
537
584
|
- [ ] Correct coding agent selected per stack
|
|
538
585
|
- [ ] VCS Issues created (1 per task)
|
|
539
586
|
- [ ] Tests generated before implementation (TDD)
|
|
@@ -541,7 +588,7 @@ BUNDLE_SIZE=$(du -sk "$2/dist/assets/" | cut -f1)
|
|
|
541
588
|
- [ ] All tests pass
|
|
542
589
|
- [ ] **Commit GREEN** (`feat(NNN): all tests pass [GREEN]`) done after all tests pass
|
|
543
590
|
- [ ] Conformance check passed (endpoints + response fields match contracts.md)
|
|
544
|
-
- [ ] Conformance report saved (`specs/NNN/conformance-report.json`)
|
|
591
|
+
- [ ] Conformance report saved (`specs/NNN/conformance-report.json`) + history appended to `conformance-history.log`
|
|
545
592
|
- [ ] Extension hooks passed (if any in `hooks/pre-merge/`)
|
|
546
593
|
- [ ] Security scan passed
|
|
547
594
|
- [ ] MR created with spec references
|
|
@@ -549,6 +596,9 @@ BUNDLE_SIZE=$(du -sk "$2/dist/assets/" | cut -f1)
|
|
|
549
596
|
- [ ] MR rejected loop handled (if applicable — fix, re-test, re-check conformance)
|
|
550
597
|
- [ ] links.md updated with MR links
|
|
551
598
|
- [ ] Living docs updated on Confluence (DD, Dominio, Glossario)
|
|
599
|
+
- [ ] Spec synced with implementation if intentional divergences (Phase D.1.5)
|
|
600
|
+
- [ ] Architecture.md updated with new decisions if discovered during implementation (Phase D.4)
|
|
601
|
+
- [ ] CHANGELOG.md updated in main repo (Phase D.4.5)
|
|
552
602
|
- [ ] Feature label → `done` on Confluence
|
|
553
603
|
- [ ] Lessons saved if applicable
|
|
554
604
|
- [ ] GChat notifications sent at each transition
|
|
@@ -47,9 +47,13 @@ If NO argument was passed (user ran `/discovery` without a feature name):
|
|
|
47
47
|
|
|
48
48
|
Bloqueadas:
|
|
49
49
|
- 🚀 TFB-002 - Conferência (depende de TFB-001)
|
|
50
|
+
|
|
51
|
+
Caminho crítico recomendado: TFB-000 → TFB-001 → TFB-003 → TFB-002
|
|
52
|
+
(002 depende de 001; 003 pode ser paralela com 001)
|
|
50
53
|
```
|
|
51
|
-
6.
|
|
52
|
-
7.
|
|
54
|
+
6. **Suggest execution order**: analyze the dependency graph from all features' "Depende de" fields and suggest the order that minimizes blocked time. This is a SUGGESTION — the dev chooses the final order.
|
|
55
|
+
7. Ask: "Qual feature deseja trabalhar?"
|
|
56
|
+
8. Proceed with the chosen feature.
|
|
53
57
|
|
|
54
58
|
If argument WAS passed (e.g., `/discovery TFB-001`):
|
|
55
59
|
- Locate the corresponding feature page and proceed normally.
|
|
@@ -69,7 +73,7 @@ Read these files FIRST:
|
|
|
69
73
|
### 1. Compile all information
|
|
70
74
|
|
|
71
75
|
From Confluence (via MCP), read:
|
|
72
|
-
- The feature page in `Features/` (demand extracted by /setup)
|
|
76
|
+
- The feature page in `Features/` (demand extracted by /setup). Read the metadata table — especially the "Seções do PO" field, which tells you exactly which PO document sections are relevant for this feature. Use this to focus your gap analysis.
|
|
73
77
|
- `Dominio/` — business rules, flows, reference tables, integrations
|
|
74
78
|
- `Visao do Produto` — product scope and success metrics
|
|
75
79
|
- Previous Q&A rounds on the feature page (if any)
|
|
@@ -178,9 +182,12 @@ Covered / Partial / Missing.
|
|
|
178
182
|
| SECURITY | Sensitive data? Auth requirements? Redaction needed? |
|
|
179
183
|
| PERFORMANCE | SLAs? Expected load? Rate limits? |
|
|
180
184
|
| UX | Error messages? Empty states? (if frontend) |
|
|
185
|
+
| TECHNOLOGY | Stack in projects.yml compatible with requirements? WebSocket needed but no support? Background jobs needed but no worker declared? Auth mechanism defined? DB supports required queries (full-text search, JSONB, geo)? |
|
|
181
186
|
|
|
182
187
|
**Special rule — PERFORMANCE**: this category can NEVER be marked as "Covered" without at least one question about: data limits (how many records per entity?), response SLA (max acceptable response time per endpoint), or expected throughput (requests/second, concurrent users). If the PO demand does not mention performance, ASK — absence of a performance requirement does not mean "no requirement", it means "undocumented implicit requirement".
|
|
183
188
|
|
|
189
|
+
**Special rule — TECHNOLOGY**: this category can NEVER be marked as "Covered" without verifying: (1) all repos in projects.yml have a stack declared, (2) the declared stack supports all feature requirements (WebSocket, background jobs, full-text search, etc.), (3) the auth mechanism is defined. Absence of technology constraints does not mean the stack is fine — it means the constraint is implicit.
|
|
190
|
+
|
|
184
191
|
For each category marked Partial or Missing, generate a candidate question.
|
|
185
192
|
|
|
186
193
|
**Prioritize:** Impact (High/Medium/Low) x Blocks spec? (Yes/No).
|
|
@@ -272,7 +279,7 @@ After documenting technical decisions, **return to step 6** and re-evaluate: if
|
|
|
272
279
|
|
|
273
280
|
**IF no gaps remain (or all answered):**
|
|
274
281
|
|
|
275
|
-
Generate the PRD on the feature page in Confluence:
|
|
282
|
+
Generate the PRD on the feature page in Confluence. **IMPORTANT: APPEND the PRD section BELOW the existing metadata table and Escopo section created by /setup — do NOT replace or remove them.**
|
|
276
283
|
|
|
277
284
|
```
|
|
278
285
|
## PRD
|
|
@@ -297,6 +304,14 @@ Generate the PRD on the feature page in Confluence:
|
|
|
297
304
|
### Decisões tomadas
|
|
298
305
|
- Duvida N.1: [decision] — Justificativa: [why]
|
|
299
306
|
- ...
|
|
307
|
+
|
|
308
|
+
### Requisitos Não-Funcionais (se aplicável)
|
|
309
|
+
- **Performance**: [target, e.g., "GET /bills < 200ms p95, 100 req/s"]
|
|
310
|
+
- **Disponibilidade**: [target, e.g., "99.9% uptime"]
|
|
311
|
+
- **Escalabilidade**: [constraints, e.g., "suportar 10k faturas/mês"]
|
|
312
|
+
|
|
313
|
+
_Include this section only if the gap analysis identified PERFORMANCE or TECHNOLOGY
|
|
314
|
+
gaps with concrete targets. If no NFRs were identified, omit entirely._
|
|
300
315
|
```
|
|
301
316
|
|
|
302
317
|
Then:
|
|
@@ -165,6 +165,7 @@ Must contain these sections:
|
|
|
165
165
|
- **Premissas**: assumptions stated in the PO docs (copy them, don't summarize)
|
|
166
166
|
- **Escopo da v1**: what's in
|
|
167
167
|
- **Fora de escopo**: what's explicitly out
|
|
168
|
+
- **Riscos e dependências críticas**: external systems without defined contracts, teams/knowledge dependencies, technical unknowns. If PO docs mention integration with an external system but no contract or API is defined, register as risk. If PO mentions a technology the team has no experience with, register as risk. If no risks identified, write "Nenhum risco crítico identificado nos documentos do PO."
|
|
168
169
|
- **Metricas de sucesso**: if the PO defined metrics, use them. If not, write "Metricas de negocio — A CONFIRMAR. Nao definidas pelo PO." Do NOT invent metrics. Do NOT use functional test criteria as metrics.
|
|
169
170
|
- **Restricoes**: mandatory tech, environment, compliance constraints
|
|
170
171
|
|
|
@@ -296,10 +297,31 @@ All subsequent features ({SIGLA}-001 onwards) have an implicit dependency on {SI
|
|
|
296
297
|
|
|
297
298
|
**Reminder: feature pages are children of `{SIGLA} — Features` (which is a child of `ROOT_ID`). Do NOT create features inside `Demandas/`.**
|
|
298
299
|
|
|
299
|
-
|
|
300
|
+
**Follow this feature identification algorithm — both phases are mandatory:**
|
|
301
|
+
|
|
302
|
+
**Phase A — Map PO sections to feature candidates:**
|
|
303
|
+
1. Read each PO document in `Demandas/`
|
|
304
|
+
2. Identify every NUMBERED SECTION or HEADING that describes a distinct user capability (look for: "Objetivo:", "Como [persona]...", numbered items "0.", "1.", "2.", or distinct headings with acceptance criteria)
|
|
305
|
+
3. One section with a distinct objective = one feature candidate
|
|
306
|
+
4. Record for each candidate: source reference (e.g., "Regra de Negocio §2"), title, number of acceptance criteria
|
|
307
|
+
5. If a document has NO numbered sections (free-form text), identify capabilities by change of theme, persona, or objective — each distinct capability = one candidate
|
|
308
|
+
|
|
309
|
+
**Phase B — Cross-cutting concern sweep:**
|
|
310
|
+
After listing business features from Phase A, scan ALL PO documents AND architecture docs for these triggers. If found AND no Phase A candidate already covers the concern explicitly, CREATE a dedicated feature:
|
|
311
|
+
|
|
312
|
+
| Trigger keywords in input docs | Feature to create |
|
|
313
|
+
|-------------------------------|-------------------|
|
|
314
|
+
| SSO, JWT, OAuth, roles, permissões, autorização, autenticação, LGPD, rate limit | {SIGLA}-NNN - Autenticação e Autorização |
|
|
315
|
+
| automático, SLA, prazo, timeout, scheduled, job, cron, fechamento automático | {SIGLA}-NNN - Processos Automáticos e SLA |
|
|
316
|
+
|
|
317
|
+
General principle: any capability mentioned in the PO that is NOT tied to a specific user screen or flow but affects multiple features should be evaluated as a potential cross-cutting feature.
|
|
318
|
+
|
|
319
|
+
If the concern IS already an explicit PO section (identified in Phase A as its own candidate), do NOT create a duplicate.
|
|
320
|
+
|
|
321
|
+
**After identifying all features, create a page for EACH.** For each feature:
|
|
300
322
|
|
|
301
323
|
1. Create a child page under `{SIGLA} — Features` with title: `🚀 {SIGLA}-NNN - Feature name` (numbering sequential: 001, 002, ...). E.g., `🚀 FT-001 - Cadastro e Autenticação`, `🚀 TD-003 - Gerenciamento de Tarefas`
|
|
302
|
-
2. Content MUST
|
|
324
|
+
2. Content MUST follow this template (in pt-BR):
|
|
303
325
|
```
|
|
304
326
|
| Campo | Valor |
|
|
305
327
|
|-------|-------|
|
|
@@ -307,8 +329,11 @@ Analyze the PO documents in `Demandas/` and identify distinct features/capabilit
|
|
|
307
329
|
| Depende de | {SIGLA}-000 (e outras se houver, separadas por vírgula) |
|
|
308
330
|
| Complexidade | baixa / média / alta |
|
|
309
331
|
| Repos envolvidos | {quais repos participam} |
|
|
332
|
+
| Seções do PO | {source sections, e.g., "Regra de Negocio §2, §7; DefinicoesTecnicas §2.2"} |
|
|
333
|
+
|
|
334
|
+
## Escopo
|
|
335
|
+
{bullet list of what this feature includes — extracted from PO docs, not invented}
|
|
310
336
|
```
|
|
311
|
-
After the table: 1-2 paragraphs extracted from PO documents describing what the feature does.
|
|
312
337
|
3. Add label `em-discovery` (ready for /discovery to process)
|
|
313
338
|
|
|
314
339
|
If the PO documents describe a SINGLE monolithic system without clear feature boundaries, create ONE feature page covering the full scope and note: "Feature única — considerar quebra em sub-features durante /discovery."
|
|
@@ -356,7 +381,7 @@ In the local spec repo:
|
|
|
356
381
|
| # | Decisao | Impacto | Bloqueia | Status |
|
|
357
382
|
|---|---------|---------|----------|--------|
|
|
358
383
|
| 1 | Worker separado ou parte da API? | Alto — define repos e CI | /spec | aberta |
|
|
359
|
-
| 2 | Valores do enum de Status |
|
|
384
|
+
| 2 | Valores do enum de Status | Médio — afeta model e validação | /dev | aberta |
|
|
360
385
|
```
|
|
361
386
|
|
|
362
387
|
Status values: `aberta`, `resolvida — [decisão tomada]`. The /discovery updates this column when resolving decisions (exit gate).
|
|
@@ -384,6 +409,8 @@ Before closing the loop, the agent MUST do a self-review:
|
|
|
384
409
|
- Did I invent anything that isn't in the PO documents?
|
|
385
410
|
3. **Fix any gaps found** by updating the pages
|
|
386
411
|
4. **Report** what was added/fixed in the self-review
|
|
412
|
+
5. **Feature coverage**: for EACH numbered section or distinct capability in the PO documents, verify it is covered by at least one feature page. If uncovered → create a feature or add the scope to an existing one. Report: "Cobertura de features: {N}/{total} seções do PO cobertas."
|
|
413
|
+
6. **Cross-cutting check**: if PO/architecture docs mention auth keywords (SSO, JWT, OAuth, roles, permissões, autorização, autenticação, LGPD, rate limit) → verify a feature covers auth implementation. If they mention automation keywords (automático, SLA, prazo, timeout, scheduled, job, cron, fechamento automático) → verify a feature covers it. If missing → create the dedicated feature. Use the same trigger keywords from Phase B.
|
|
387
414
|
|
|
388
415
|
### 6. Close the loop
|
|
389
416
|
|
|
@@ -434,6 +461,7 @@ The output is considered good when:
|
|
|
434
461
|
- **Architecture.md**: has an "open decisions" table ranked by impact
|
|
435
462
|
- **projects.yml**: has all detected repos declared (not commented), with stack and status
|
|
436
463
|
- **Self-review**: was performed, gaps were found and fixed (or confirmed none exist)
|
|
464
|
+
- **Features**: every numbered section/capability in the PO documents is covered by at least one feature. Cross-cutting concerns (auth, automated processes) have dedicated features when triggered by keywords in the input. Feature pages include Escopo and Seções do PO fields.
|
|
437
465
|
|
|
438
466
|
## Validation checklist
|
|
439
467
|
|
|
@@ -443,7 +471,7 @@ The output is considered good when:
|
|
|
443
471
|
- [ ] Demand label transition: (none/novo) → processando → processado
|
|
444
472
|
|
|
445
473
|
### Content generated
|
|
446
|
-
- [ ] Visao do Produto: all required sections present (O que é, Para quem, Por que existe, Premissas, Escopo da v1, Fora de escopo, Métricas de sucesso, Restrições)
|
|
474
|
+
- [ ] Visao do Produto: all required sections present (O que é, Para quem, Por que existe, Premissas, Escopo da v1, Fora de escopo, Riscos e dependências críticas, Métricas de sucesso, Restrições)
|
|
447
475
|
- [ ] Glossario: covers all domain terms from PRD (verified by re-read)
|
|
448
476
|
- [ ] Regras: all rules have ID + Fonte (PRD section) + Verificavel
|
|
449
477
|
- [ ] Fluxos: all flows have happy path + exceptions + Mermaid flowchart TD
|
|
@@ -451,15 +479,21 @@ The output is considered good when:
|
|
|
451
479
|
- [ ] Integracoes: all events have producer + consumer + expected payload
|
|
452
480
|
- [ ] {SIGLA} — Features parent page created
|
|
453
481
|
- [ ] Initial feature pages created under {SIGLA} — Features (with label `em-discovery`)
|
|
482
|
+
- [ ] Every PO section covered by at least one feature (verified in self-review)
|
|
483
|
+
- [ ] Cross-cutting features created when PO mentions auth/SSO/JWT or SLA/automático keywords
|
|
484
|
+
- [ ] Feature pages have: Seções do PO field + Escopo section
|
|
454
485
|
- [ ] {SIGLA} — Arquivados parent page created
|
|
455
486
|
|
|
456
487
|
### Spec repo updated
|
|
457
488
|
- [ ] projects.yml filled with all detected repos (status: planned, not commented)
|
|
458
489
|
- [ ] docs/architecture.md draft with Mermaid diagrams (flowchart, erDiagram) and open decisions table
|
|
490
|
+
- [ ] `docs/lessons/` and `docs/decisions/` directories created
|
|
459
491
|
|
|
460
492
|
### Quality gates
|
|
461
493
|
- [ ] Self-review performed (re-read PRD vs. output)
|
|
494
|
+
- [ ] Figma context read and incorporated (if configured)
|
|
462
495
|
- [ ] No business context was invented
|
|
463
496
|
- [ ] All ambiguities marked "A CONFIRMAR" with explanation
|
|
464
497
|
- [ ] Unreadable attachments listed as "NAO PROCESSADO"
|
|
465
498
|
- [ ] Demand label changed to `processado` (verified)
|
|
499
|
+
- [ ] GChat notification sent (if webhook configured)
|
|
@@ -43,6 +43,13 @@ Read these files FIRST:
|
|
|
43
43
|
- **Reuse** shared types (ErrorResponse, PaginatedResponse) by reference
|
|
44
44
|
- If the new feature MODIFIES behavior of an existing endpoint, document the change explicitly in brief.md: "Modifica GET /api/contas para incluir campo `saldoAtual` no response"
|
|
45
45
|
|
|
46
|
+
**Figma freshness check (if Figma configured):**
|
|
47
|
+
If `projects.yml` has `figma.file_url` and Figma MCP is available:
|
|
48
|
+
1. Read `get_metadata()` for the feature's frames
|
|
49
|
+
2. Compare key elements (screen count, form fields) against what /discovery captured in the PRD
|
|
50
|
+
3. If significant changes detected (new screens, removed fields) → WARN: "Design no Figma mudou desde o /discovery. Diferenças: {list}. Continuar com o design atual ou re-executar /discovery?"
|
|
51
|
+
4. If no changes or Figma unavailable → proceed silently
|
|
52
|
+
|
|
46
53
|
## Inputs
|
|
47
54
|
|
|
48
55
|
- Approved PRD on Confluence (label `prd-aprovado`) — read via MCP
|
|
@@ -63,7 +70,7 @@ Read these files FIRST:
|
|
|
63
70
|
### 1. Read PRD from Confluence
|
|
64
71
|
|
|
65
72
|
From Confluence (via MCP), read the approved PRD on the feature page.
|
|
66
|
-
Extract: requirements, decisions, scope, out of scope, assumptions.
|
|
73
|
+
Extract: requirements, decisions, scope, out of scope, assumptions, and NFRs (if the PRD has a "Requisitos Não-Funcionais" section).
|
|
67
74
|
|
|
68
75
|
### 2. Identify features in the PRD
|
|
69
76
|
|
|
@@ -123,11 +130,16 @@ Numbering is sequential: find the highest existing number in `specs/` and increm
|
|
|
123
130
|
- Every REQ-NNN from the PRD MUST have at least one scenario covering it
|
|
124
131
|
- If a REQ has no scenario, either the REQ is unverifiable (fix the PRD) or a scenario is missing (add it)
|
|
125
132
|
- **Cross-check with business rules**: read `Domínio/Regras` on Confluence and verify that every RN referenced in the scenarios exists. If a scenario contradicts an RN, flag it as error.
|
|
126
|
-
- **Mandatory
|
|
133
|
+
- **Mandatory security scenarios**: if the feature has ANY authenticated endpoint, include:
|
|
134
|
+
- At least 1 scenario: request WITHOUT token → expected 401 NAO_AUTORIZADO
|
|
135
|
+
- At least 1 scenario: request with WRONG role → expected 403 ACESSO_NEGADO
|
|
136
|
+
- At least 1 scenario per endpoint accepting user input: malformed/malicious input → expected 400 with validation error (NOT 500)
|
|
137
|
+
If feature has NO authenticated endpoints, skip auth scenarios.
|
|
127
138
|
- **Mandatory pagination scenarios**: if ANY endpoint uses explicit pagination (PaginatedResponse, page/pageSize params, or similar envelope), include scenarios for:
|
|
128
139
|
- Default pagination (no params → uses defaults)
|
|
129
140
|
- Last page (partial results)
|
|
130
141
|
- Invalid page values (page ≤ 0, pageSize > max) — expected: 400 or clamped to defaults
|
|
142
|
+
- **NFR scenarios (if PRD has "Requisitos Não-Funcionais")**: for each measurable NFR target (e.g., "GET /bills < 200ms p95"), create at least one CT-NNN-XX scenario with a concrete Given/When/Then. Example: `Given 50 concurrent users, When GET /api/v1/bills with filters, Then p95 response time < 200ms`. If the NFR is not measurable in a test (e.g., "99.9% uptime"), include it in brief.md under "Restrições" instead. Add NFR-related tasks to tasks.md (e.g., "add response time middleware", "configure rate limiting").
|
|
131
143
|
- **No unresolved markers (MANDATORY)**: specs MUST NOT contain any of these markers anywhere — including inside code blocks and code examples:
|
|
132
144
|
`MOCKADO`, `TODO`, `A CONFIRMAR`, `TBD`, `FIXME`, `PLACEHOLDER`, `TKTK`
|
|
133
145
|
If any assumption is not validated, go back to /discovery to resolve it.
|
|
@@ -154,9 +166,9 @@ Numbering is sequential: find the highest existing number in `specs/` and increm
|
|
|
154
166
|
| UpdatedAt | DateTime | Sim | Data de última atualização |
|
|
155
167
|
```
|
|
156
168
|
5. **Error codes**: every error code specific to this feature, as constants/enum
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
169
|
+
6. **Validation rules** (as a top-level `##` section, NOT nested inside a per-stack section): every field validation (required, format, max length, valid values)
|
|
170
|
+
7. **Response examples**: at least one success example and one error example per endpoint, with HTTP status code
|
|
171
|
+
8. **Shared types**: if this feature DEFINES types that other features will reuse (ex: ErrorResponse, PaginatedResponse), mark them in a `## Tipos compartilhados` section. If this feature USES types from another feature, REFERENCE them ("Ver contracts.md da feature NNN") — do NOT copy the full definition. If extending a type, define only the extension.
|
|
160
172
|
|
|
161
173
|
Additional structural rule: **editável entities MUST have both `CriadoEm` and `AtualizadoEm` fields**. If an entity can be modified via PUT/PATCH, it needs `AtualizadoEm` for auditability.
|
|
162
174
|
|
|
@@ -175,6 +187,11 @@ Additional rules:
|
|
|
175
187
|
- **Dependency between blocks**: if a repo block REQUIRES another block to be COMPLETED first, declare explicitly with `> Dependency: todo-api block must be completed before starting`
|
|
176
188
|
- Each task = 1 PR
|
|
177
189
|
- Reference REQ-NNN from scenarios
|
|
190
|
+
- **Size estimate**: each task line should include a size indicator (P/M/G):
|
|
191
|
+
- P (pequeno): < 2h, single file change, well-understood pattern
|
|
192
|
+
- M (médio): 2-8h, multiple files, may need investigation
|
|
193
|
+
- G (grande): > 8h, complex logic, new patterns, integration work
|
|
194
|
+
- Format: `- [ ] [P] T-NNN-REPO-XX: description (REQ-NNN)`
|
|
178
195
|
- **Feature grande**: if the PRD has more than 15 behaviors/requirements or spans 4+ repos, /discovery should have flagged it already. If it arrived here approved, proceed without questioning. Just note in brief.md: "Feature com {N} requisitos — escopo aprovado pelo PO."
|
|
179
196
|
|
|
180
197
|
#### links.md
|
|
@@ -202,7 +219,18 @@ Confirm you generated all **5 files** for this feature:
|
|
|
202
219
|
|
|
203
220
|
If any file is missing, **create it now** before continuing.
|
|
204
221
|
|
|
222
|
+
#### Optional: OpenAPI stub (if API endpoints exist)
|
|
223
|
+
|
|
224
|
+
If contracts.md defines REST endpoints, generate a minimal OpenAPI 3.0 stub file at `specs/NNN-name/openapi.yaml` containing:
|
|
225
|
+
- paths (from endpoint table: method + route)
|
|
226
|
+
- request/response schemas (from contract types)
|
|
227
|
+
- auth scheme (if authenticated endpoints: bearerAuth)
|
|
228
|
+
|
|
229
|
+
This is a STUB — /dev may extend it during implementation. Mark as draft: `info.description: "Auto-generated from contracts.md — draft"`
|
|
205
230
|
|
|
231
|
+
If the feature has no REST endpoints (e.g., worker-only feature), skip this step.
|
|
232
|
+
|
|
233
|
+
### 4. Self-review and audit
|
|
206
234
|
|
|
207
235
|
Before generating the DD or closing the loop, run ALL checks below. Fix any failures, then generate the audit report.
|
|
208
236
|
|
|
@@ -215,9 +243,11 @@ Before generating the DD or closing the loop, run ALL checks below. Fix any fail
|
|
|
215
243
|
- Response type defined
|
|
216
244
|
- At least one success example and one error example
|
|
217
245
|
- Error codes cover all failure scenarios
|
|
218
|
-
4. **Auth consistency**: if feature has authenticated endpoints, confirm
|
|
219
|
-
5. **
|
|
220
|
-
6. **
|
|
246
|
+
4. **Auth consistency**: if feature has authenticated endpoints, confirm CTs exist for: "sem token → 401", "role errado → 403"
|
|
247
|
+
5. **Input validation**: for each endpoint accepting user input, confirm at least one CT for "input malformado → 400" exists
|
|
248
|
+
6. **Pagination consistency**: if any endpoint returns lists, confirm pagination scenarios exist
|
|
249
|
+
7. **Cross-feature types**: if contracts.md defines a type that already exists in another feature's contracts.md, replace with a reference
|
|
250
|
+
8. **NFR coverage**: if the PRD has a "Requisitos Não-Funcionais" section, confirm each measurable NFR has at least one CT scenario. Non-measurable NFRs should appear in brief.md "Restrições"
|
|
221
251
|
|
|
222
252
|
If ANY check fails, fix the spec files BEFORE proceeding. Report what was fixed.
|
|
223
253
|
|
|
@@ -231,9 +261,11 @@ If ANY check fails, fix the spec files BEFORE proceeding. Report what was fixed.
|
|
|
231
261
|
| 1 | REQ → Scenarios | ✅ 12/12 | All REQs have ≥1 scenario |
|
|
232
262
|
| 2 | RN → Scenarios | ✅ 8/8 | All RNs have ≥1 scenario |
|
|
233
263
|
| 3 | Endpoints → Contracts | ✅ 6/6 | All endpoints have request/response/errors |
|
|
234
|
-
| 4 | Auth (401
|
|
235
|
-
| 5 |
|
|
236
|
-
| 6 |
|
|
264
|
+
| 4 | Auth (401 + 403 scenarios) | ✅ 2/2 | CT-NNN-XX (401), CT-NNN-YY (403) |
|
|
265
|
+
| 5 | Input validation (400 scenarios) | ✅ 3/3 | One per input endpoint |
|
|
266
|
+
| 6 | Pagination scenarios | ✅ 2/2 | CT-NNN-XX, CT-NNN-YY |
|
|
267
|
+
| 7 | Cross-feature types | ✅ OK | References only, no redefinitions |
|
|
268
|
+
| 8 | NFR coverage | ✅ 2/2 | Each measurable NFR has CT scenario |
|
|
237
269
|
|
|
238
270
|
**Generated**: YYYY-MM-DD
|
|
239
271
|
**Fixed during review**: (list what was added/corrected, or "none")
|
|
@@ -345,8 +377,10 @@ If a Confluence operation fails mid-flow (updating DD, changing labels, reading
|
|
|
345
377
|
- [ ] Every scenario has Given/When/Then
|
|
346
378
|
- [ ] Happy path covered for every endpoint/behavior
|
|
347
379
|
- [ ] Failure scenarios covered (validation errors, not found, ownership)
|
|
348
|
-
- [ ] Auth
|
|
380
|
+
- [ ] Auth scenarios (401 without token + 403 wrong role) present if feature has authenticated endpoints
|
|
381
|
+
- [ ] Input validation scenarios (malformed input → 400) present for each endpoint accepting user input
|
|
349
382
|
- [ ] Pagination scenarios present if any endpoint returns paginated lists
|
|
383
|
+
- [ ] NFR scenarios present if PRD has "Requisitos Não-Funcionais" section (each measurable target has a CT)
|
|
350
384
|
- [ ] Edge cases covered (boundary values, empty results, duplicates)
|
|
351
385
|
|
|
352
386
|
### Contracts quality
|
|
@@ -362,9 +396,17 @@ If a Confluence operation fails mid-flow (updating DD, changing labels, reading
|
|
|
362
396
|
- [ ] Each task = 1 PR
|
|
363
397
|
- [ ] links.md has correct Confluence page link
|
|
364
398
|
|
|
399
|
+
### Artifacts
|
|
400
|
+
- [ ] `audit-report.md` generated with all checks passing
|
|
401
|
+
- [ ] `openapi.yaml` generated (if feature has REST endpoints)
|
|
402
|
+
- [ ] Figma freshness check performed (if configured)
|
|
403
|
+
|
|
365
404
|
### Integration
|
|
366
405
|
- [ ] DD updated on Confluence
|
|
406
|
+
- [ ] Glossary validated on Confluence (all PRD terms present)
|
|
407
|
+
- [ ] All open decisions in architecture.md resolved (no blockers for /dev)
|
|
367
408
|
- [ ] Feature label updated on Confluence → `em-spec`
|
|
409
|
+
- [ ] All spec files committed and pushed
|
|
368
410
|
- [ ] GChat notification sent
|
|
369
411
|
- [ ] Lessons from docs/lessons/ applied
|
|
370
412
|
|