jarvis-ai-framework 3.2.0 → 4.0.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/agents/product/prod.discovery-interviewer.md +1 -1
- package/bin/README.md +14 -14
- package/bin/commands/docs-publish.js +50 -92
- package/bin/commands/docs-sync.js +30 -63
- package/bin/lib/cli/program.js +23 -25
- package/bin/lib/docs/fetch-file.js +29 -26
- package/bin/lib/docs/publish-file.js +89 -161
- package/bin/lib/docs/storage/build-index.js +87 -0
- package/bin/lib/docs/storage/filesystem.js +203 -0
- package/bin/lib/docs/storage/index.js +75 -0
- package/bin/lib/docs/validate-frontmatter.js +14 -4
- package/bin/lib/vcs/api.js +0 -125
- package/package.json +2 -2
- package/rules/AGENTS.md +12 -9
- package/rules/engineering/eng.integrations-rules.md +2 -1
- package/rules/product/prod-rules.md +4 -5
- package/rules-on-demand/product/prod.guided-rules.md +104 -0
- package/skills/jarvis-docs-central/README.md +57 -269
- package/skills/jarvis-docs-central/SKILL.md +126 -296
- package/skills/jarvis-init/SKILL.md +46 -7
- package/templates/ENV-template.md +20 -5
- package/templates/engineering/ARD-template.md +39 -6
- package/templates/engineering/architecture-template.md +1 -0
- package/templates/product/prod-breakdown-template.md +20 -2
- package/templates/product/prod-discovery-template.md +24 -1
- package/templates/product/prod-epic-template.md +32 -1
- package/templates/product/prod-frd-template.md +29 -2
- package/templates/product/prod-issue-template.md +36 -1
- package/templates/product/prod-prd-template.md +33 -2
- package/workflows/engineering/eng.build-tech-spec.md +2 -2
- package/workflows/engineering/eng.create-ard-from-code.md +9 -11
- package/workflows/engineering/eng.create-ard.md +15 -13
- package/workflows/engineering/eng.create-rfc.md +8 -10
- package/workflows/engineering/eng.pr.md +4 -4
- package/workflows/engineering/eng.pre-pr.md +4 -4
- package/workflows/engineering/eng.rpa.robot.md +4 -2
- package/workflows/engineering/eng.start.md +17 -16
- package/workflows/product/prod.roadmap.preview.md +4 -1
- package/workflows/product/prod.spec.ard.md +7 -3
- package/workflows/product/prod.spec.breakdown.md +7 -3
- package/workflows/product/prod.spec.clarify.md +5 -1
- package/workflows/product/prod.spec.discovery.md +7 -3
- package/workflows/product/prod.spec.epic.md +13 -11
- package/workflows/product/prod.spec.frd.md +15 -13
- package/workflows/product/prod.spec.issue.md +5 -1
- package/workflows/product/prod.spec.md +3 -1
- package/workflows/product/prod.spec.prd.md +15 -13
- package/workflows/warm-up.md +3 -3
- package/bin/lib/docs/redis-cache.js +0 -49
- package/bin/lib/vcs/fetch-raw.js +0 -42
|
@@ -2,10 +2,10 @@ import { readFileSync } from 'node:fs'
|
|
|
2
2
|
import { parseFrontmatter, extractFrontmatterBlock } from '../utils/frontmatter.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Valida frontmatter YAML de documentos (PRD, FRD, ARD, RFC)
|
|
5
|
+
* Valida frontmatter YAML de documentos (PRD, FRD, épico, história, tarefa, ARD, RFC)
|
|
6
6
|
*
|
|
7
7
|
* @param {string} filePath - Caminho do arquivo
|
|
8
|
-
* @param {string} tipo - Tipo do documento (
|
|
8
|
+
* @param {string} tipo - Tipo do documento (ver VALID_TYPES em publish-file.js)
|
|
9
9
|
* @returns {Object} Metadados extraídos
|
|
10
10
|
* @throws {Error} Se frontmatter for inválido
|
|
11
11
|
*/
|
|
@@ -54,7 +54,13 @@ export function validateFrontmatter(filePath, tipo) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
// Validar status
|
|
57
|
-
|
|
57
|
+
// Produto (rules/product/prod-rules.md), ARD (templates/engineering/ARD-template.md),
|
|
58
|
+
// discovery (prod-discovery-template.md) e RFC (RFC-template.md)
|
|
59
|
+
const validStatuses = [
|
|
60
|
+
'icebox', 'in_review', 'backlog', 'in_progress', 'in_production', 'cancelled', 'deprecated',
|
|
61
|
+
'proposed', 'approved',
|
|
62
|
+
'Draft', 'In Review', 'Ready for Decision', 'Accepted', 'Rejected', 'Superseded'
|
|
63
|
+
]
|
|
58
64
|
|
|
59
65
|
if (metadata.status && !validStatuses.includes(metadata.status)) {
|
|
60
66
|
console.warn(
|
|
@@ -76,7 +82,11 @@ function getRequiredFields(tipo) {
|
|
|
76
82
|
const fields = {
|
|
77
83
|
prd: ['id', 'name', 'version', 'status'],
|
|
78
84
|
frd: ['id', 'name', 'version', 'status', 'related_prd'],
|
|
79
|
-
|
|
85
|
+
feat: ['id', 'name', 'version', 'status', 'related_prd'],
|
|
86
|
+
epic: ['id', 'name', 'version', 'status', 'related_prd'],
|
|
87
|
+
story: ['id', 'name', 'status', 'related_prd'],
|
|
88
|
+
task: ['id', 'name', 'status'],
|
|
89
|
+
ard: ['id', 'name', 'version', 'status'],
|
|
80
90
|
rfc: ['Status', 'Criado em', 'Proponente'],
|
|
81
91
|
'qa-report': ['period', 'squad', 'version']
|
|
82
92
|
}
|
package/bin/lib/vcs/api.js
CHANGED
|
@@ -37,39 +37,6 @@ async function request(url, { method = "GET", headers = {}, body } = {}) {
|
|
|
37
37
|
return { ok: res.ok, status: res.status, json, text };
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export async function fetchRawFile(repoUrl, filePath, ref = "main") {
|
|
41
|
-
const repo = parseRepoUrl(repoUrl);
|
|
42
|
-
const token = getVcsToken(repo.vendor);
|
|
43
|
-
const headers = authHeaders(repo.vendor, token);
|
|
44
|
-
const encodedPath = encodeURIComponent(filePath);
|
|
45
|
-
|
|
46
|
-
let url;
|
|
47
|
-
if (repo.vendor === "gitlab") {
|
|
48
|
-
url = `${repo.apiBase}/projects/${repo.projectPathEncoded}/repository/files/${encodedPath}/raw?ref=${encodeURIComponent(ref)}`;
|
|
49
|
-
} else if (repo.vendor === "github") {
|
|
50
|
-
url = `${repo.apiBase}/repos/${repo.owner}/${repo.repo}/contents/${filePath}?ref=${encodeURIComponent(ref)}`;
|
|
51
|
-
headers.Accept = "application/vnd.github.raw";
|
|
52
|
-
} else {
|
|
53
|
-
url = `${repo.apiBase}/repositories/${repo.owner}/${repo.repo}/src/${encodeURIComponent(ref)}/${filePath}`;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const res = await fetch(url, { headers });
|
|
57
|
-
if (res.status === 404) {
|
|
58
|
-
const err = new Error(`not_found:${filePath}`);
|
|
59
|
-
err.code = 404;
|
|
60
|
-
throw err;
|
|
61
|
-
}
|
|
62
|
-
if (res.status === 401 || res.status === 403) {
|
|
63
|
-
const err = new Error(`unauthorized:${repo.vendor}`);
|
|
64
|
-
err.code = res.status;
|
|
65
|
-
throw err;
|
|
66
|
-
}
|
|
67
|
-
if (!res.ok) {
|
|
68
|
-
throw new Error(`fetch failed ${res.status}: ${await res.text()}`);
|
|
69
|
-
}
|
|
70
|
-
return await res.text();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
40
|
export async function createMergeRequest(repoUrl, opts) {
|
|
74
41
|
const { source, target, title, description = "" } = opts;
|
|
75
42
|
const repo = parseRepoUrl(repoUrl);
|
|
@@ -141,98 +108,6 @@ export async function createMergeRequest(repoUrl, opts) {
|
|
|
141
108
|
};
|
|
142
109
|
}
|
|
143
110
|
|
|
144
|
-
/**
|
|
145
|
-
* Commit de um ou mais arquivos numa branch nova (docs publish).
|
|
146
|
-
* files: [{ path, contentBase64, action: 'create'|'update' }]
|
|
147
|
-
*/
|
|
148
|
-
export async function commitFiles(repoUrl, opts) {
|
|
149
|
-
const { branch, startBranch, message, files } = opts;
|
|
150
|
-
const repo = parseRepoUrl(repoUrl);
|
|
151
|
-
const token = getVcsToken(repo.vendor);
|
|
152
|
-
const headers = authHeaders(repo.vendor, token);
|
|
153
|
-
|
|
154
|
-
if (repo.vendor === "gitlab") {
|
|
155
|
-
const { ok, status, json } = await request(
|
|
156
|
-
`${repo.apiBase}/projects/${repo.projectPathEncoded}/repository/commits`,
|
|
157
|
-
{
|
|
158
|
-
method: "POST",
|
|
159
|
-
headers,
|
|
160
|
-
body: {
|
|
161
|
-
branch,
|
|
162
|
-
start_branch: startBranch,
|
|
163
|
-
commit_message: message,
|
|
164
|
-
actions: files.map((f) => ({
|
|
165
|
-
action: f.action || "create",
|
|
166
|
-
file_path: f.path,
|
|
167
|
-
content: f.contentBase64,
|
|
168
|
-
encoding: "base64",
|
|
169
|
-
})),
|
|
170
|
-
},
|
|
171
|
-
}
|
|
172
|
-
);
|
|
173
|
-
if (!ok || !json?.id) {
|
|
174
|
-
throw new Error(`Falha no commit GitLab (${status}): ${JSON.stringify(json)}`);
|
|
175
|
-
}
|
|
176
|
-
return { sha: json.id };
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (repo.vendor === "github") {
|
|
180
|
-
const refRes = await request(
|
|
181
|
-
`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/git/ref/heads/${startBranch}`,
|
|
182
|
-
{ headers }
|
|
183
|
-
);
|
|
184
|
-
if (!refRes.ok) {
|
|
185
|
-
throw new Error(`Branch ${startBranch} não encontrada no GitHub (${refRes.status})`);
|
|
186
|
-
}
|
|
187
|
-
const sha = refRes.json.object.sha;
|
|
188
|
-
await request(`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/git/refs`, {
|
|
189
|
-
method: "POST",
|
|
190
|
-
headers,
|
|
191
|
-
body: { ref: `refs/heads/${branch}`, sha },
|
|
192
|
-
});
|
|
193
|
-
let lastSha = sha;
|
|
194
|
-
for (const file of files) {
|
|
195
|
-
const put = await request(
|
|
196
|
-
`${repo.apiBase}/repos/${repo.owner}/${repo.repo}/contents/${file.path}`,
|
|
197
|
-
{
|
|
198
|
-
method: "PUT",
|
|
199
|
-
headers,
|
|
200
|
-
body: {
|
|
201
|
-
message,
|
|
202
|
-
content: file.contentBase64,
|
|
203
|
-
branch,
|
|
204
|
-
},
|
|
205
|
-
}
|
|
206
|
-
);
|
|
207
|
-
if (!put.ok) {
|
|
208
|
-
throw new Error(
|
|
209
|
-
`Falha ao escrever ${file.path} no GitHub (${put.status}): ${JSON.stringify(put.json)}`
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
lastSha = put.json.commit?.sha || lastSha;
|
|
213
|
-
}
|
|
214
|
-
return { sha: lastSha };
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const form = new FormData();
|
|
218
|
-
form.set("branch", branch);
|
|
219
|
-
form.set("parents", startBranch);
|
|
220
|
-
form.set("message", message);
|
|
221
|
-
for (const file of files) {
|
|
222
|
-
const buf = Buffer.from(file.contentBase64, "base64");
|
|
223
|
-
form.set(file.path, new Blob([buf]));
|
|
224
|
-
}
|
|
225
|
-
const res = await fetch(`${repo.apiBase}/repositories/${repo.owner}/${repo.repo}/src`, {
|
|
226
|
-
method: "POST",
|
|
227
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
228
|
-
body: form,
|
|
229
|
-
});
|
|
230
|
-
if (!res.ok) {
|
|
231
|
-
throw new Error(`Falha no commit Bitbucket (${res.status}): ${await res.text()}`);
|
|
232
|
-
}
|
|
233
|
-
return { sha: "ok" };
|
|
234
|
-
}
|
|
235
|
-
|
|
236
111
|
export async function createIssue(repoUrl, opts) {
|
|
237
112
|
const { title, body, labels = ["bug"] } = opts;
|
|
238
113
|
const repo = parseRepoUrl(repoUrl);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jarvis-ai-framework",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Jarvis framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"prepublishOnly": "echo 'Publishing jarvis-framework...'",
|
|
12
12
|
"publish:gitlab": "npm publish",
|
|
13
13
|
"test:comandos": "node test/comandos-docs.test.js",
|
|
14
|
-
"test:filtro": "node --test test/profile-filter.test.js test/token-report.test.js test/flow-map.test.js test/env-loader.test.js test/sync-engine.test.js test/vcs-api.test.js test/fetch-file.test.js test/publish-file.test.js",
|
|
14
|
+
"test:filtro": "node --test test/profile-filter.test.js test/token-report.test.js test/flow-map.test.js test/env-loader.test.js test/sync-engine.test.js test/vcs-api.test.js test/fetch-file.test.js test/publish-file.test.js test/docs-storage.test.js",
|
|
15
15
|
"lint": "eslint bin/ test/",
|
|
16
16
|
"lint:fix": "eslint bin/ test/ --fix",
|
|
17
17
|
"format": "prettier --write bin/ test/",
|
package/rules/AGENTS.md
CHANGED
|
@@ -24,14 +24,16 @@ rules/ # Sempre carregadas no início da sessão
|
|
|
24
24
|
└── prod-rules.md # Regras de especificacao
|
|
25
25
|
|
|
26
26
|
rules-on-demand/ # Lidas pelo workflow que as usa (não carregadas no início)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
├── engineering/
|
|
28
|
+
│ ├── eng.start-rules.md # Regras para /eng.start
|
|
29
|
+
│ ├── eng.plan-rules.md # Regras para /eng.plan
|
|
30
|
+
│ ├── eng.work-rules.md # Regras para /eng.work
|
|
31
|
+
│ ├── eng.pre-pr-rules.md # Regras para /eng.pre-pr
|
|
32
|
+
│ ├── eng.pr-rules.md # Regras para /eng.pr
|
|
33
|
+
│ ├── eng.tech-spec-rules.md # Regras para tech specs
|
|
34
|
+
│ └── eng.breakdown-subtasks-rules.md # Regras para o breakdown de subtarefas
|
|
35
|
+
└── product/
|
|
36
|
+
└── prod.guided-rules.md # Modo Developer-Guided (lida só com PROD_MODE=developer-guided)
|
|
35
37
|
```
|
|
36
38
|
|
|
37
39
|
### `rules/` x `rules-on-demand/`
|
|
@@ -46,7 +48,8 @@ O Claude Code carrega tudo de `.claude/rules/` no início da sessão: `rules/` f
|
|
|
46
48
|
1. .windsurf/rules / .cursor/rules (mais alta)
|
|
47
49
|
2. rules/engineering/eng-rules.md
|
|
48
50
|
3. rules-on-demand/engineering/eng.{comando}-rules.md
|
|
49
|
-
4. rules/product/prod-rules.md (
|
|
51
|
+
4. rules-on-demand/product/prod.guided-rules.md (só com PROD_MODE=developer-guided)
|
|
52
|
+
5. rules/product/prod-rules.md (mais baixa)
|
|
50
53
|
```
|
|
51
54
|
|
|
52
55
|
**Regra**: Regras mais especificas tem precedencia sobre regras gerais.
|
|
@@ -9,7 +9,8 @@ O Jarvis não assume Jira, GitLab ou Slack. Leia `$IDE/ENV.md` e despache pelo a
|
|
|
9
9
|
| Variável | Vendors | Adapter |
|
|
10
10
|
|----------|---------|---------|
|
|
11
11
|
| `TASK_MANAGER` | jira, linear, github, asana | `jarvis tasks comment` |
|
|
12
|
-
| `VERSION_CONTROL` | gitlab, github, bitbucket | `jarvis vcs create-merge` / `create-issue`
|
|
12
|
+
| `VERSION_CONTROL` | gitlab, github, bitbucket | `jarvis vcs create-merge` / `create-issue` |
|
|
13
|
+
| `CENTRAL_DOCS_STORAGE` | filesystem (s3 e gdrive no futuro) | `jarvis docs fetch` / `sync` / `publish` |
|
|
13
14
|
| `MESSAGE_COMUNICATOR` | slack, discord, teams | runtime `communicator/` |
|
|
14
15
|
|
|
15
16
|
`{TASK_MANAGER_KEY}` = id da tarefa. Com board, é o id do card. Sem board, é o número de controle do usuário.
|
|
@@ -22,7 +22,6 @@ IMPORTANTE: Para que você funcione como o previsto e tenha todas as informaçõ
|
|
|
22
22
|
- `PROD_FLOWS`
|
|
23
23
|
- `PROD_TEMPLATES`
|
|
24
24
|
- `PROD_DOCS`
|
|
25
|
-
- `CENTRAL_DOCS_REPO`
|
|
26
25
|
- **Se o ENV.md não existir ou estiver incompleto**, o agente deve:
|
|
27
26
|
1. Interromper a execução do comando solicitado
|
|
28
27
|
2. Informar ao usuário que não podemos avançar sem o ENV.md. Mensagem abaixo.
|
|
@@ -41,20 +40,19 @@ PROD_RULES=$RULES_FOLDER/$PROD_FOLDER_NAME
|
|
|
41
40
|
PROD_FLOWS=.$IDE/$FLOWS_FOLDER
|
|
42
41
|
PROD_TEMPLATES=.$IDE/$TEMPLATES_FOLDER/$PROD_FOLDER_NAME
|
|
43
42
|
PROD_DOCS=$DOCS_FOLDER/$PROD_FOLDER_NAME
|
|
44
|
-
CENTRAL_DOCS_REPO=[USER:LOCAL_CENTRAL_DOCS_REPO]
|
|
45
43
|
```
|
|
46
44
|
|
|
47
45
|
Abaixo, segue uma descrição de algumas das variáveis mais importantes para as rotinas de produto:
|
|
48
46
|
|
|
49
47
|
- $DOCS_FOLDER é o nome da pasta principal de documentações do projeto. Ela fica localizada na raiz do projeto.
|
|
50
|
-
- $PROD_DOCS é o nome da pasta principal de documentações de produto do projeto.
|
|
48
|
+
- $PROD_DOCS é o nome da pasta principal de documentações de produto do projeto. No projeto único (sem workspace), fica em `docs/jarvis/product`, fora do versionamento do código.
|
|
51
49
|
- $PROD_FOLDER_NAME é o nome padrão da pasta de produto que será usada em diversos contextos do projeto.
|
|
52
50
|
- $TEMPLATES_FOLDER é o nome da pasta principal de templates do projeto.
|
|
53
51
|
- $PROD_TEMPLATES é o caminho completo para os templates de produto.
|
|
54
52
|
- $FLOWS_FOLDER é o nome da pasta de workflows e comandos utilizados pelos IDEs. (tenha em mente que o nome da pasta pode variar de acordo com a IDE utilizada)
|
|
55
53
|
- $RULES_FOLDER é o nome da pasta principal de regras invioláveis que os agentes devem seguir.
|
|
56
54
|
- $PROD_RULES é o caminho para a pasta que contém as regras de produto. Leia todos os arquivos dentro dessa pasta para entender as regras de produto.
|
|
57
|
-
- $
|
|
55
|
+
- $CENTRAL_DOCS_STORAGE e $CENTRAL_DOCS_LOCATION configuram o Central docs (opcional): onde ficam as especificações aprovadas e o índice global de todas elas. Vazio = desligado. Hoje o único armazenamento é `filesystem` (uma pasta; se tiver `.git`, publica por PR). Leitura e publicação sempre por `jarvis docs fetch | sync | publish`.
|
|
58
56
|
|
|
59
57
|
|
|
60
58
|
## VARIÁVEL `$IDE` - DETECÇÃO AUTOMÁTICA DA PASTA DA IDE
|
|
@@ -116,7 +114,8 @@ Em itens e especificações, utilizamos status para identificar quais etapas do
|
|
|
116
114
|
- backlog: Item já foi estudado, sabemos o que fazer e está aguardando priorização de implementação.
|
|
117
115
|
- in_progress: Item que está em desenvolvimento.
|
|
118
116
|
- in_production: Item que está em produção.
|
|
119
|
-
- cancelled: Item
|
|
117
|
+
- cancelled: Item cancelado antes de ser entregue.
|
|
118
|
+
- deprecated: Item que esteve em produção e foi descontinuado.
|
|
120
119
|
|
|
121
120
|
|
|
122
121
|
## Padrão de nomes e pastas
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
> **Applies to:** HUB: all | POSITION: all | AREA: all | SQUAD: all
|
|
2
|
+
|
|
3
|
+
# Regras do Modo Developer-Guided
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Definir como a IA conduz os comandos de produto quando o usuário escolheu o **Modo Developer-Guided** (Modo Fácil): uma conversa didática, para quem vem do código e quer aprender Product Management (PM, gestão de produto) enquanto faz.
|
|
8
|
+
|
|
9
|
+
O Modo Fácil **não é um Jarvis simplificado**. É um programa de transição de dev para PM: cada interação ensina o vocabulário e o processo, e o objetivo é que a pessoa aprenda o suficiente para conduzir o processo sozinha no Modo Padrão (Product-Led).
|
|
10
|
+
|
|
11
|
+
## Escopo
|
|
12
|
+
|
|
13
|
+
- Vale **somente** quando `PROD_MODE=developer-guided` no `$IDE/ENV.md`. Com `PROD_MODE` vazio ou `product-led`, este arquivo não se aplica.
|
|
14
|
+
- Vale em todos os comandos de `workflows/product/` (`prod.spec`, `prod.spec.discovery`, `.prd`, `.frd`, `.ard`, `.epic`, `.issue`, `.breakdown`, `.clarify`, `prod.roadmap.preview`) e no `eng.create-ard`.
|
|
15
|
+
- Muda **a conversa**, não o documento: etapas, seções e conteúdo de cada documento seguem o workflow e o template, como no Modo Padrão.
|
|
16
|
+
- Complementa `rules/product/prod-rules.md`. Onde as duas falam do mesmo assunto (formato das perguntas), esta prevalece.
|
|
17
|
+
|
|
18
|
+
## Regras
|
|
19
|
+
|
|
20
|
+
### Obrigatório
|
|
21
|
+
|
|
22
|
+
#### Linguagem e ritmo
|
|
23
|
+
|
|
24
|
+
- **Uma pergunta por vez.** Nunca juntar várias perguntas nem despejar blocos longos de texto. Espere a resposta antes de seguir.
|
|
25
|
+
- **Termo real + explicação simples, sempre juntos.** Use o nome técnico de PM e explique na mesma frase. Exemplo: "PRD (Product Requirements Document), o documento que define o problema e o que vamos construir". A pessoa precisa absorver o vocabulário, não fugir dele.
|
|
26
|
+
- Analogias com código funcionam bem: a pessoa é dev (ex.: "o FRD está para o PRD como a implementação está para a interface").
|
|
27
|
+
|
|
28
|
+
#### Perguntas e opções
|
|
29
|
+
|
|
30
|
+
Use `AskUserQuestion` em **toda transição de artefato** (ex.: FRD → ARD) e em **toda questão ou gate em aberto**. A ferramenta aceita até 4 opções, mais um "Outro" automático de texto livre:
|
|
31
|
+
|
|
32
|
+
| Tipo de pergunta | Opções |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Gate (seguir, pular, aprovar uma etapa) | `[Sim]` · `[Não]` · `[Explicar melhor]` + Outro = `[Dúvida]` |
|
|
35
|
+
| Pergunta de conteúdo (ex.: "qual o público-alvo?") | até 3 respostas · `[Explicar melhor]` + Outro = `[Dúvida]` |
|
|
36
|
+
|
|
37
|
+
- `[Explicar melhor]` aparece **sempre**.
|
|
38
|
+
- `[Dúvida]` **é** o "Outro": a pessoa escreve a dúvida no texto livre.
|
|
39
|
+
- Sem `AskUserQuestion` na IDE: use a tabela de `prod-rules.md`, com as mesmas opções nas linhas.
|
|
40
|
+
|
|
41
|
+
#### Comportamento de cada opção
|
|
42
|
+
|
|
43
|
+
| Opção | O que fazer |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `[Sim]` | Seguir para o próximo passo. |
|
|
46
|
+
| `[Não]` | Dizer em **uma frase** a consequência de pular (ex.: "Sem o FRD, o ARD fica sem base para decidir a arquitetura") e confirmar. Se a pessoa insistir, registrar o artefato como **pendente** e seguir. |
|
|
47
|
+
| `[Explicar melhor]` | A pessoa pode digitar o que não entendeu (opcional). Com texto, explique aquele ponto; sem texto, explique o passo inteiro. Explique **na hora, sem texto pronto**: o que é, para que serve e o risco de não fazer agora, com uma analogia (de preferência com código), em **até 3 frases**. Depois, repita **a mesma** pergunta. |
|
|
48
|
+
| `[Dúvida]` | Responda **só aquele ponto**, sem reiniciar o fluxo. Ao terminar, volte à pergunta original. |
|
|
49
|
+
|
|
50
|
+
Nunca avance enquanto a pessoa não tiver esclarecido o que não entendeu.
|
|
51
|
+
|
|
52
|
+
#### Mentoria entre artefatos
|
|
53
|
+
|
|
54
|
+
Nunca pule de um artefato para outro sem avisar. Antes de cada transição:
|
|
55
|
+
|
|
56
|
+
1. Apresente o próximo passo de forma leve.
|
|
57
|
+
2. Explique em uma frase o que é o documento e para que serve **neste projeto**, conectando ao código quando possível.
|
|
58
|
+
3. Dê o controle à pessoa com as opções de gate.
|
|
59
|
+
|
|
60
|
+
#### Fechamento de cada iteração
|
|
61
|
+
|
|
62
|
+
Ao terminar um documento, sem esperar pedido:
|
|
63
|
+
|
|
64
|
+
1. Gere o documento completo.
|
|
65
|
+
2. Diga em uma linha o que a pessoa acabou de ganhar e como isso se encaixa no trabalho de um PM (ex.: "Agora você tem o ARD: o registro de por que escolhemos essa arquitetura.").
|
|
66
|
+
3. Peça a revisão: `[Aprovar]` · `[Ajustar]` · `[Explicar melhor]` + Outro = `[Dúvida]`.
|
|
67
|
+
4. **Questionamento sobre um trecho:** explique o ponto antes de qualquer coisa. Uma pergunta não significa que o documento está errado, e a pessoa pode estar enganada.
|
|
68
|
+
- Documento correto: explique o porquê e diga claramente que não há o que mudar.
|
|
69
|
+
- A pessoa tem razão, ou a dúvida revelou falha ou ambiguidade no texto: explique e **sugira uma alteração**, dizendo o que mudaria e por quê.
|
|
70
|
+
- Opções: `[Entendi]` (mantém e volta à revisão) · `[Explicar melhor]` (outra analogia, até 3 frases, e repete a pergunta) · `[Sugerir alteração]`.
|
|
71
|
+
- `[Sugerir alteração]`: avalie se a mudança faz sentido (se não fizer, explique o motivo com honestidade), proponha o texto novo e **só aplique depois da confirmação**.
|
|
72
|
+
- Melhorias que a própria IA identificar também passam por `[Sugerir alteração]`, sempre com o que mudaria, por que ajuda e o risco de não mudar.
|
|
73
|
+
5. Só avance para o próximo artefato depois da aprovação.
|
|
74
|
+
|
|
75
|
+
#### Documento final e frontmatter
|
|
76
|
+
|
|
77
|
+
- O documento gerado é **idêntico em qualidade e estrutura** ao do Modo Padrão: completo, técnico e denso. A simplicidade fica na conversa. O documento é o padrão que a pessoa terá de produzir sozinha depois.
|
|
78
|
+
- Mantenha os comentários `#` do frontmatter que vêm do template. Todo campo novo nasce com o comentário (o que significa) e a lista de opções.
|
|
79
|
+
- Ao mudar o valor de um campo durante a conversa (ex.: `status: in_review` → `backlog`), diga em uma frase o que a mudança significa.
|
|
80
|
+
|
|
81
|
+
### Proibido
|
|
82
|
+
|
|
83
|
+
- Simplificar, encurtar ou pular seções do documento final por causa do modo.
|
|
84
|
+
- Alterar o documento sem confirmação, inclusive para aplicar uma melhoria proposta pela própria IA.
|
|
85
|
+
- Sugerir uma alteração sem dizer o que muda, por que ajuda e o risco de não mudar.
|
|
86
|
+
- Fazer várias perguntas de uma vez.
|
|
87
|
+
- Perguntar, sugerir ou lembrar a troca para o Modo Padrão. A troca é manual (`/jarvis-init` ou `PROD_MODE` no `ENV.md`), quando a pessoa quiser.
|
|
88
|
+
|
|
89
|
+
### Recomendado
|
|
90
|
+
|
|
91
|
+
- Preferir exemplos do próprio projeto (código, telas, entidades) aos genéricos.
|
|
92
|
+
- Quando a pessoa usar um termo errado, corrigir com gentileza, citando o termo certo junto com a explicação.
|
|
93
|
+
|
|
94
|
+
## Exceções
|
|
95
|
+
|
|
96
|
+
- Se a pessoa pedir explicitamente outro formato na conversa (ex.: "pode me perguntar tudo de uma vez"), siga o pedido naquele comando.
|
|
97
|
+
- O aviso de modelo (`recommended_model`) não é deste arquivo: vale nos dois modos e está no topo de cada workflow.
|
|
98
|
+
|
|
99
|
+
## Referências
|
|
100
|
+
|
|
101
|
+
- `rules/product/prod-rules.md`: regras gerais de produto (ambiente, status, formato das perguntas)
|
|
102
|
+
- `rules/product/prod.spec-rules.md`: princípios de escrita de spec
|
|
103
|
+
- `templates/product/`: templates com o frontmatter comentado
|
|
104
|
+
- `docs/produto/`: guia humano de cada comando (para quem mantém o framework)
|