jarvis-ai-framework 5.2.0 → 5.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/AGENTS.md +1 -0
- package/README.md +14 -1
- package/bin/commands/init.js +149 -2
- package/bin/commands/tokens.js +9 -3
- package/bin/lib/cli/program.js +14 -2
- package/bin/lib/core/docs-migrate.js +259 -0
- package/bin/lib/core/env-upgrade.js +84 -0
- package/bin/lib/core/profile-filter.js +15 -3
- package/bin/lib/core/sync-engine.js +5 -3
- package/bin/lib/core/token-report.js +1 -0
- package/bin/lib/docs/storage/build-index.js +2 -1
- package/bin/lib/vcs/api.js +13 -1
- package/bin/lib/vcs/create-issue.js +17 -3
- package/package.json +2 -2
- package/rules/AGENTS.md +4 -1
- package/rules/artifact-style-rules.md +53 -0
- package/rules/product/prod-rules.md +4 -2
- package/rules/product/prod.spec-rules.md +2 -2
- package/rules-on-demand/engineering/eng.plan-rules.md +1 -1
- package/rules-on-demand/engineering/eng.pr-rules.md +4 -3
- package/rules-on-demand/engineering/eng.start-rules.md +2 -2
- package/rules-on-demand/engineering/eng.transitions-rules.md +58 -0
- package/rules-on-demand/engineering/eng.work-rules.md +9 -3
- package/skills/eng-global-pr/SKILL.md +3 -1
- package/skills/eng-global-task-comment/SKILL.md +2 -0
- package/skills/jarvis-docs-central/SKILL.md +1 -1
- package/skills/jarvis-init/SKILL.md +54 -17
- package/skills/jarvis-report-issue/SKILL.md +64 -9
- package/templates/ENV-template.md +10 -0
- package/templates/engineering/architecture-template.md +2 -1
- package/templates/engineering/plan-template.md +2 -0
- package/templates/product/prod-epic-template.md +1 -1
- package/templates/product/prod-frd-template.md +1 -1
- package/templates/product/prod-issue-template.md +1 -1
- package/templates/product/prod-prd-template.md +1 -1
- package/workflows/engineering/eng.plan.md +2 -1
- package/workflows/engineering/eng.pr.md +39 -6
- package/workflows/engineering/eng.pre-pr.md +2 -1
- package/workflows/engineering/eng.spec-consolidate.md +3 -1
- package/workflows/engineering/eng.start.md +8 -2
- package/workflows/engineering/eng.work.md +22 -5
- package/workflows/product/prod.spec.discovery.md +2 -2
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* `rules/AGENTS.md`: ao mudar uma, mude as três.
|
|
8
8
|
*
|
|
9
9
|
* Regras:
|
|
10
|
-
* - Os
|
|
10
|
+
* - Os eixos (HUB, POSITION, AREA, SQUAD e o opcional ARTIFACT_STYLE) são combinados com AND.
|
|
11
|
+
* - ARTIFACT_STYLE (5º campo, opcional): ausente no bloco = `all`; perfil sem valor =
|
|
12
|
+
* `ai-generated`. Sem coringa: FULLCYCLE e GENERALIST não o satisfazem (é escolha da pessoa).
|
|
11
13
|
* - `all` casa qualquer valor; listas são separadas por vírgula.
|
|
12
14
|
* - FULLCYCLE (HUB) satisfaz qualquer HUB.
|
|
13
15
|
* - GENERALIST (POSITION) satisfaz qualquer POSITION e qualquer AREA.
|
|
@@ -20,8 +22,11 @@
|
|
|
20
22
|
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
21
23
|
import { join, relative, sep } from "node:path";
|
|
22
24
|
|
|
25
|
+
// SQUAD para no próximo `|`: o 5º campo (ARTIFACT_STYLE) é opcional.
|
|
23
26
|
const APPLIES_TO_RE =
|
|
24
|
-
/> \*\*Applies to:\*\* HUB: ([^|]+)\| POSITION: ([^|]+)\| AREA: ([^|]+)\| SQUAD: (
|
|
27
|
+
/> \*\*Applies to:\*\* HUB: ([^|]+)\| POSITION: ([^|]+)\| AREA: ([^|]+)\| SQUAD: ([^|\n]+)(?:\| ARTIFACT_STYLE: ([^|\n]+))?/;
|
|
28
|
+
|
|
29
|
+
const DEFAULT_ARTIFACT_STYLE = "ai-generated";
|
|
25
30
|
|
|
26
31
|
/**
|
|
27
32
|
* @typedef {Object} AppliesTo
|
|
@@ -29,6 +34,7 @@ const APPLIES_TO_RE =
|
|
|
29
34
|
* @property {string} POSITION
|
|
30
35
|
* @property {string} AREA
|
|
31
36
|
* @property {string} SQUAD
|
|
37
|
+
* @property {string} ARTIFACT_STYLE - `all` quando o bloco não traz o campo
|
|
32
38
|
*/
|
|
33
39
|
|
|
34
40
|
/**
|
|
@@ -37,6 +43,7 @@ const APPLIES_TO_RE =
|
|
|
37
43
|
* @property {string} POSITION
|
|
38
44
|
* @property {string} AREA
|
|
39
45
|
* @property {string} SQUAD
|
|
46
|
+
* @property {string} [ARTIFACT_STYLE] - vazio = `ai-generated`
|
|
40
47
|
*/
|
|
41
48
|
|
|
42
49
|
/**
|
|
@@ -52,6 +59,7 @@ export function parseAppliesTo(content) {
|
|
|
52
59
|
POSITION: match[2].trim(),
|
|
53
60
|
AREA: match[3].trim(),
|
|
54
61
|
SQUAD: match[4].trim(),
|
|
62
|
+
ARTIFACT_STYLE: (match[5] || "all").trim(),
|
|
55
63
|
};
|
|
56
64
|
}
|
|
57
65
|
|
|
@@ -76,7 +84,11 @@ export function matchesProfile(appliesTo, profile) {
|
|
|
76
84
|
const position = generalist || axisMatches(appliesTo.POSITION, profile.POSITION);
|
|
77
85
|
const area = generalist || axisMatches(appliesTo.AREA, profile.AREA);
|
|
78
86
|
const squad = axisMatches(appliesTo.SQUAD, profile.SQUAD);
|
|
79
|
-
|
|
87
|
+
const style = axisMatches(
|
|
88
|
+
appliesTo.ARTIFACT_STYLE || "all",
|
|
89
|
+
profile.ARTIFACT_STYLE || DEFAULT_ARTIFACT_STYLE
|
|
90
|
+
);
|
|
91
|
+
return hub && position && area && squad && style;
|
|
80
92
|
}
|
|
81
93
|
|
|
82
94
|
function walkMarkdown(dir) {
|
|
@@ -149,7 +149,7 @@ export function syncAssets(targetDir, ide, opts = {}) {
|
|
|
149
149
|
|
|
150
150
|
// RTK: detectar e reconciliar RTK_ENABLED + rtk-rules.md
|
|
151
151
|
if (!opts.dryRun) {
|
|
152
|
-
const rtkResult = reconcileRtk(ideDir, targetDir, ide);
|
|
152
|
+
const rtkResult = reconcileRtk(ideDir, targetDir, ide, { keepEnvValues: opts.keepEnvValues });
|
|
153
153
|
if (rtkResult) result.copied.push(rtkResult);
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -191,9 +191,11 @@ export function syncAssets(targetDir, ide, opts = {}) {
|
|
|
191
191
|
* Detecta RTK no PATH e reconcilia RTK_ENABLED no ENV.md + rtk-rules.md na IDE.
|
|
192
192
|
* - RTK encontrado → RTK_ENABLED=true no ENV.md, mantém rule
|
|
193
193
|
* - RTK não encontrado → remove rtk-rules.md da IDE, mantém RTK_ENABLED=false
|
|
194
|
+
* - `keepEnvValues` (jarvis init --upgrade): não troca RTK_ENABLED=false por true, porque o
|
|
195
|
+
* upgrade só acrescenta chaves novas; acrescentar RTK_ENABLED quando ela não existe continua valendo
|
|
194
196
|
* @returns {string|null} mensagem de log ou null se nenhuma ação
|
|
195
197
|
*/
|
|
196
|
-
function reconcileRtk(ideDir, targetDir, ide) {
|
|
198
|
+
function reconcileRtk(ideDir, targetDir, ide, { keepEnvValues = false } = {}) {
|
|
197
199
|
const rtkRulePath = join(ideDir, "rules", "rtk-rules.md");
|
|
198
200
|
const envPath = join(ideDir, "ENV.md");
|
|
199
201
|
const hasRtk = (() => {
|
|
@@ -209,7 +211,7 @@ function reconcileRtk(ideDir, targetDir, ide) {
|
|
|
209
211
|
// Ativar RTK_ENABLED no ENV.md se existir e estiver false
|
|
210
212
|
if (existsSync(envPath)) {
|
|
211
213
|
let env = readFileSync(envPath, "utf-8");
|
|
212
|
-
if (env.includes("RTK_ENABLED=false")) {
|
|
214
|
+
if (env.includes("RTK_ENABLED=false") && !keepEnvValues) {
|
|
213
215
|
env = env.replace("RTK_ENABLED=false", "RTK_ENABLED=true");
|
|
214
216
|
writeFileSync(envPath, env, "utf-8");
|
|
215
217
|
return "(rtk) detectado — RTK_ENABLED=true no ENV.md";
|
|
@@ -91,6 +91,7 @@ export function buildReport(root, profile, opts = {}) {
|
|
|
91
91
|
POSITION: profile.POSITION,
|
|
92
92
|
AREA: profile.AREA,
|
|
93
93
|
SQUAD: profile.SQUAD,
|
|
94
|
+
ARTIFACT_STYLE: profile.ARTIFACT_STYLE || "ai-generated",
|
|
94
95
|
},
|
|
95
96
|
rtkEnabled,
|
|
96
97
|
estimate: `tokens = bytes ÷ ${BYTES_PER_TOKEN} (estimativa)`,
|
|
@@ -53,7 +53,8 @@ export function renderIndex(root, squad) {
|
|
|
53
53
|
const areaDir = join(root, squad, area);
|
|
54
54
|
const files = walkFiles(areaDir).filter((f) => {
|
|
55
55
|
const name = f.split(sep).pop();
|
|
56
|
-
|
|
56
|
+
// {nome}.public.md (versão humanizada, ARTIFACT_STYLE=human-generated) não entra no índice
|
|
57
|
+
return name.startsWith(prefix) && name.endsWith(".md") && !name.endsWith(".public.md");
|
|
57
58
|
});
|
|
58
59
|
out.push(`## ${area}`, "", `> ${title}`, "");
|
|
59
60
|
if (files.length === 0) {
|
package/bin/lib/vcs/api.js
CHANGED
|
@@ -108,6 +108,14 @@ export async function createMergeRequest(repoUrl, opts) {
|
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
// Tipos de issue do Bitbucket (campo `kind`; ele não tem labels livres).
|
|
112
|
+
const BITBUCKET_KINDS = ["bug", "enhancement", "proposal", "task"];
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @param {string} repoUrl
|
|
116
|
+
* @param {{ title: string, body: string, labels?: string[] }} opts - `labels` padrão: ["bug"].
|
|
117
|
+
* No Bitbucket, a primeira label vira o `kind` quando é um tipo válido; senão, `bug`.
|
|
118
|
+
*/
|
|
111
119
|
export async function createIssue(repoUrl, opts) {
|
|
112
120
|
const { title, body, labels = ["bug"] } = opts;
|
|
113
121
|
const repo = parseRepoUrl(repoUrl);
|
|
@@ -149,7 +157,11 @@ export async function createIssue(repoUrl, opts) {
|
|
|
149
157
|
{
|
|
150
158
|
method: "POST",
|
|
151
159
|
headers,
|
|
152
|
-
body: {
|
|
160
|
+
body: {
|
|
161
|
+
title,
|
|
162
|
+
content: { raw: body },
|
|
163
|
+
kind: BITBUCKET_KINDS.includes(labels[0]) ? labels[0] : "bug",
|
|
164
|
+
},
|
|
153
165
|
}
|
|
154
166
|
);
|
|
155
167
|
if (!ok || !json?.links?.html?.href) {
|
|
@@ -9,11 +9,25 @@ import { createIssue, parseRepoUrl } from "./api.js";
|
|
|
9
9
|
* @param {string} options.repo - URL ou `org/repo` do repositório
|
|
10
10
|
* @param {string} options.title - Título da issue
|
|
11
11
|
* @param {string} options.bodyFile - Path de um arquivo com o corpo em markdown
|
|
12
|
+
* @param {string} [options.labels] - Labels separadas por vírgula (padrão: bug)
|
|
12
13
|
*/
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* "enhancement, documentation" → ["enhancement", "documentation"]; vazio → undefined (padrão: bug).
|
|
16
|
+
* @param {string} [raw]
|
|
17
|
+
* @returns {string[] | undefined}
|
|
18
|
+
*/
|
|
19
|
+
export function parseLabels(raw) {
|
|
20
|
+
const list = String(raw || "")
|
|
21
|
+
.split(",")
|
|
22
|
+
.map((l) => l.trim())
|
|
23
|
+
.filter(Boolean);
|
|
24
|
+
return list.length ? list : undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function runCreateIssue({ repo, title, bodyFile, labels }) {
|
|
14
28
|
if (!title || !bodyFile || !repo) {
|
|
15
29
|
console.error(
|
|
16
|
-
"Uso: jarvis vcs create-issue --repo <url-ou-path> --title <titulo> --body-file <path>"
|
|
30
|
+
"Uso: jarvis vcs create-issue --repo <url-ou-path> --title <titulo> --body-file <path> [--label <labels>]"
|
|
17
31
|
);
|
|
18
32
|
process.exit(1);
|
|
19
33
|
}
|
|
@@ -33,7 +47,7 @@ export async function runCreateIssue({ repo, title, bodyFile }) {
|
|
|
33
47
|
const body = existsSync(bodyFile) ? readFileSync(bodyFile, "utf-8") : "";
|
|
34
48
|
|
|
35
49
|
try {
|
|
36
|
-
const result = await createIssue(repoUrl, { title, body });
|
|
50
|
+
const result = await createIssue(repoUrl, { title, body, labels: parseLabels(labels) });
|
|
37
51
|
parseRepoUrl(repoUrl);
|
|
38
52
|
console.log(`✅ Issue aberto: ${result.url}`);
|
|
39
53
|
console.log(JSON.stringify(result));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jarvis-ai-framework",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.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 test/docs-storage.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 test/env-upgrade.test.js test/docs-migrate.test.js test/init-upgrade.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
|
@@ -75,6 +75,8 @@ Cada arquivo de rule declara para quais perfis se aplica via bloco `applies_to`,
|
|
|
75
75
|
> **Applies to:** HUB: {valor ou all} | POSITION: {valor ou all} | AREA: {valor ou all} | SQUAD: {valor ou all}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
Campo opcional no fim: `| ARTIFACT_STYLE: {ai-generated, human-generated ou all}` (ausente = `all`).
|
|
79
|
+
|
|
78
80
|
**Eixos de filtragem:**
|
|
79
81
|
|
|
80
82
|
| Eixo | Exemplos de valor | `all` significa |
|
|
@@ -83,13 +85,14 @@ Cada arquivo de rule declara para quais perfis se aplica via bloco `applies_to`,
|
|
|
83
85
|
| POSITION | TECH LEAD, PM, QA-ENGINEER, SENIOR, GENERALIST | qualquer cargo |
|
|
84
86
|
| AREA | ENGINEERING, PRODUCT | qualquer área |
|
|
85
87
|
| SQUAD | CORE | qualquer squad |
|
|
88
|
+
| ARTIFACT_STYLE (opcional) | ai-generated, human-generated | qualquer estilo (ENV vazio = `ai-generated`; sem coringa) |
|
|
86
89
|
|
|
87
90
|
**Regras:**
|
|
88
91
|
- Uma rule é aplicada se **todos** os eixos forem satisfeitos (AND, não OR)
|
|
89
92
|
- Arquivos sem bloco `applies_to` são considerados **universais** — copiados para qualquer perfil
|
|
90
93
|
- `rules/AGENTS.md` nunca é filtrado — sempre copiado
|
|
91
94
|
|
|
92
|
-
**Quem faz a filtragem:** o skill `/jarvis-init` (Passo
|
|
95
|
+
**Quem faz a filtragem:** o skill `/jarvis-init` (Passo 8 — Profile-Aware Rules Sync). Ao criar, atualizar ou fazer upgrade do ENV.md, copia para `$IDE/rules/` apenas as rules que batem com o perfil (HUB + POSITION + AREA + SQUAD + ARTIFACT_STYLE) e deleta as que não batem mais.
|
|
93
96
|
|
|
94
97
|
**Ao criar uma nova rule**, definir o bloco `applies_to` é obrigatório. Sem ele, a rule é tratada como universal — o que pode ser indesejado para rules domain-specific.
|
|
95
98
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
> **Applies to:** HUB: all | POSITION: all | AREA: all | SQUAD: all | ARTIFACT_STYLE: human-generated
|
|
2
|
+
|
|
3
|
+
# Artifact Style Rules (human-generated)
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Com `ARTIFACT_STYLE=human-generated` no `ENV.md`, nada do que o Jarvis publica leva marca de IA, e todo documento gerado oferece uma versão humanizada para repassar a clientes ou stakeholders.
|
|
8
|
+
|
|
9
|
+
## Escopo
|
|
10
|
+
|
|
11
|
+
Esta rule só é copiada para `$IDE/rules/` quando o perfil tem `ARTIFACT_STYLE=human-generated` (eixo do `Applies to`, Passo 8 do `/jarvis-init`). Vale para todo comando e para pedidos fora de workflow.
|
|
12
|
+
|
|
13
|
+
## Regras
|
|
14
|
+
|
|
15
|
+
### Obrigatório
|
|
16
|
+
|
|
17
|
+
1. **Publicado pelo Jarvis: sempre sem marcas, sem perguntar.**
|
|
18
|
+
- Vale para: mensagem de commit, título e descrição do PR/MR, comentário no card, issue aberta (ex.: `jarvis-report-issue`).
|
|
19
|
+
- Esta rule **prevalece** sobre instruções de atribuição da IDE: não inclua `Co-Authored-By` de ferramenta nem "Generated with …".
|
|
20
|
+
- Antes do push, o `eng.pr` confere e limpa o que a IDE tiver posto (Fase 3 do `eng.pr`).
|
|
21
|
+
2. **Documento gerado: grava o padrão e pergunta.**
|
|
22
|
+
- Vale para todo `.md` que um comando grava, inclusive os de sessão: PRD, FRD, épico, história, discovery, ARD, RFC, tech spec, Central docs, `architecture.md`, `plan.md`, `context.md`, `daily.md` (e a linha de timesheet), `gate-checklist.md`, `pull-request.md`.
|
|
23
|
+
- Depois de gravar o documento padrão (como hoje), pergunte com `AskUserQuestion`: **"Quer a versão humanizada deste documento?"** (**Não**, padrão / **Sim**).
|
|
24
|
+
- Com Sim, grave `{nome}.public.md` **ao lado** do original, passando no checklist abaixo. O original continua como fonte da verdade.
|
|
25
|
+
- Central docs (`feature-*`, `delivery-*`): o `.public.md` fica ao lado da consolidação, na sessão, e **não** é publicado.
|
|
26
|
+
3. **Checklist "sem marcas de IA"** (versão humanizada e tudo o que é publicado). Não pode ter:
|
|
27
|
+
- `Co-Authored-By` de ferramenta, "Generated with …" ou links para a ferramenta;
|
|
28
|
+
- menções a IA, Claude ou outros modelos, assistente, agente, sub-agente ou Advisor;
|
|
29
|
+
- `recommended_model` nem comentários de frontmatter dirigidos à IA;
|
|
30
|
+
- "Reportado por: IA" ou qualquer autoria atribuída à ferramenta.
|
|
31
|
+
4. **Estilo da versão humanizada:** texto corrido de pessoa para pessoa. Parágrafos onde cabe parágrafo; lista só quando há itens; sem emojis de status em excesso; sem fórmulas como "Em resumo", "Vale ressaltar". Mantenha o conteúdo, as decisões e os links úteis ao leitor (issue, PR, card).
|
|
32
|
+
|
|
33
|
+
### Proibido
|
|
34
|
+
|
|
35
|
+
- Alterar o documento original para gerar a versão humanizada.
|
|
36
|
+
- Publicar commit, PR, comentário ou issue com qualquer item do checklist.
|
|
37
|
+
- Reescrever commits já enviados ao remoto.
|
|
38
|
+
- Contar `{nome}.public.md` na sequência de IDs (`prd-{id}`, `discovery-{id}`…) ou incluí-lo em índices.
|
|
39
|
+
|
|
40
|
+
### Recomendado
|
|
41
|
+
|
|
42
|
+
- Com vários documentos gerados no mesmo comando, uma pergunta só, listando os documentos.
|
|
43
|
+
|
|
44
|
+
## Exceções
|
|
45
|
+
|
|
46
|
+
- Com `ARTIFACT_STYLE=ai-generated` (ou vazio), esta rule não existe na sessão e nada muda.
|
|
47
|
+
|
|
48
|
+
## Referências
|
|
49
|
+
|
|
50
|
+
- `templates/ENV-template.md` (`ARTIFACT_STYLE`)
|
|
51
|
+
- `skills/jarvis-init/SKILL.md` (Pergunta 9 e Passo 8)
|
|
52
|
+
- `workflows/engineering/eng.pr.md` (conferência antes do push)
|
|
53
|
+
- `rules/AGENTS.md` (eixo `ARTIFACT_STYLE` do `Applies to`)
|
|
@@ -40,12 +40,14 @@ PROD_RULES=$RULES_FOLDER/$PROD_FOLDER_NAME
|
|
|
40
40
|
PROD_FLOWS=.$IDE/$FLOWS_FOLDER
|
|
41
41
|
PROD_TEMPLATES=.$IDE/$TEMPLATES_FOLDER/$PROD_FOLDER_NAME
|
|
42
42
|
PROD_DOCS=$DOCS_FOLDER/jarvis/$PROD_FOLDER_NAME
|
|
43
|
+
DISCOVERIES_DOCS=$DOCS_FOLDER/jarvis/discoveries
|
|
43
44
|
```
|
|
44
45
|
|
|
45
46
|
Abaixo, segue uma descrição de algumas das variáveis mais importantes para as rotinas de produto:
|
|
46
47
|
|
|
47
48
|
- $DOCS_FOLDER é o nome da pasta principal de documentações do projeto. Ela fica localizada na raiz do projeto.
|
|
48
|
-
- $PROD_DOCS é a pasta dos documentos de produto gerados pelos comandos (PRD, FRD, épicos, histórias
|
|
49
|
+
- $PROD_DOCS é a pasta dos documentos de produto gerados pelos comandos (PRD, FRD, épicos, histórias): `$JARVIS_DOCS/product` (`docs/jarvis/product`), nos dois modos de trabalho e fora do versionamento do código. Os de engenharia ficam em `$ENG_DOCS` (`docs/jarvis/engineering`).
|
|
50
|
+
- $DISCOVERIES_DOCS é a pasta dos discoveries: `$JARVIS_DOCS/discoveries` (`docs/jarvis/discoveries`), fora de `product/`. ENV sem a variável: use `$PROD_DOCS/discoveries` se essa pasta existir, senão `$JARVIS_DOCS/discoveries`, e avise para rodar `jarvis init --upgrade`.
|
|
49
51
|
- $PROD_FOLDER_NAME é o nome padrão da pasta de produto que será usada em diversos contextos do projeto.
|
|
50
52
|
- $TEMPLATES_FOLDER é o nome da pasta principal de templates do projeto.
|
|
51
53
|
- $PROD_TEMPLATES é o caminho completo para os templates de produto.
|
|
@@ -126,7 +128,7 @@ Dentro das pastas do projeto, os caminhos de pastas e o nome dos arquivos finais
|
|
|
126
128
|
- Documento de Requisitos Funcionais: `$PROD_DOCS/prd-{id}-{nome-do-pai}/frd-{id}-{nome}.md`
|
|
127
129
|
- Épico: `$PROD_DOCS/prd-{id}-{nome-do-pai}/issues/epic-{id}-{nome}.md`
|
|
128
130
|
- História / tarefa: `$PROD_DOCS/prd-{id}-{nome-do-pai}/issues/{story|task}-{id}-{nome}.md`
|
|
129
|
-
- Discovery (rascunho de uma ideia, anterior ao PRD): `$
|
|
131
|
+
- Discovery (rascunho de uma ideia, anterior ao PRD): `$DISCOVERIES_DOCS/discovery-{id}-{nome}.md`. Usa `status` (`in_review` enquanto o rascunho existe; `cancelled` se o veredito for não seguir) e `verdict` (vazio durante a entrevista, `proceed`, `investigate_more` ou `do_not_proceed`). O veredito é uma recomendação; um PRD, FRD, épico ou issue criado depois prevalece como fonte da verdade.
|
|
130
132
|
|
|
131
133
|
O ID deve ser iterado nos novos arquivos seguindo a sequência existente.
|
|
132
134
|
|
|
@@ -147,14 +147,14 @@ A terminologia inconsistente cria confusão. "Cliente" vs "Usuário" vs "Cliente
|
|
|
147
147
|
|
|
148
148
|
### Princípio: Discovery como insumo
|
|
149
149
|
|
|
150
|
-
**Princípio**: O discovery (`$
|
|
150
|
+
**Princípio**: O discovery (`$DISCOVERIES_DOCS/discovery-{id}-{nome}.md`) é um rascunho de suposições. Ele pode servir de contexto para um PRD, FRD, épico ou issue, mas nunca é obrigatório e nunca é tratado como verdade.
|
|
151
151
|
|
|
152
152
|
**O discovery é opcional**:
|
|
153
153
|
- Sem discovery apontado, siga o fluxo do comando normalmente, sem procurar na pasta `discoveries/` e sem perguntar nada sobre discovery. Ter arquivos nessa pasta não tem relação com o comando.
|
|
154
154
|
- Exemplos: `/prod.spec.prd já sei o que quero` segue o fluxo de sempre; `/prod.spec.prd discovery-002` carrega o discovery.
|
|
155
155
|
|
|
156
156
|
**Como apontar e achar o discovery**:
|
|
157
|
-
- O usuário aponta por caminho, nome ou id (como `discovery-002`); procure em `$
|
|
157
|
+
- O usuário aponta por caminho, nome ou id (como `discovery-002`); procure em `$DISCOVERIES_DOCS/`.
|
|
158
158
|
- Se o arquivo não existir: informe, liste os discoveries da pasta e pergunte qual usar, ou se o usuário prefere seguir sem discovery.
|
|
159
159
|
- Se a pasta `discoveries/` não existir: siga sem discovery e não crie a pasta.
|
|
160
160
|
- Se mais de um arquivo casar com o que o usuário apontou: pergunte qual usar, sem escolher sozinho.
|
|
@@ -261,7 +261,7 @@ Cada fase pode ter uma seção `### Comentários:` para:
|
|
|
261
261
|
- ✅ Detalhar cada tarefa com contexto
|
|
262
262
|
- ✅ Indicar dependências (sequencial/paralelo)
|
|
263
263
|
- ✅ Usar os emojis de status corretamente
|
|
264
|
-
- ✅ Validar o plano com o humano antes de prosseguir
|
|
264
|
+
- ✅ Validar o plano com o humano antes de prosseguir (pergunta "Aprovar o plan.md?" de `eng.transitions-rules.md`)
|
|
265
265
|
- ✅ Escrever tudo em português (pt-BR)
|
|
266
266
|
|
|
267
267
|
---
|
|
@@ -271,6 +271,7 @@ O MR deve seguir o template em `$IDE/templates/engineering/PR-template.md`:
|
|
|
271
271
|
- ❌ Commitar arquivos de configuração local
|
|
272
272
|
- ❌ Commitar credenciais ou tokens
|
|
273
273
|
- ❌ Mencionar AI/Claude no PR
|
|
274
|
+
- ❌ Com `ARTIFACT_STYLE=human-generated`: push de commit ou PR com marca de IA ou da IDE (`Co-Authored-By` de ferramenta, "Generated with …") — conferir antes (Fase 3.0 do `eng.pr`)
|
|
274
275
|
- ❌ [!IMPORTANT] PUSH DIRETO PARA `main`/`dev`
|
|
275
276
|
|
|
276
277
|
### ✅ SEMPRE FAÇA
|
|
@@ -322,7 +323,7 @@ Antes de considerar o PR completo:
|
|
|
322
323
|
- [ ] Card do Jira movido para "In Review"
|
|
323
324
|
- [ ] Comentários de code review processados
|
|
324
325
|
- [ ] `pull-request.md` aprovado na sessão (e publicado, se o usuário respondeu Sim)
|
|
325
|
-
- [ ]
|
|
326
|
+
- [ ] Pergunta "O PR já foi aprovado e mergeado?" no fim (Sim → `/eng.spec-consolidate`)
|
|
326
327
|
- [ ] `daily.md` gerado ou atualizado e aprovado (só com PR aberto), com a linha de timesheet na mensagem final
|
|
327
328
|
|
|
328
329
|
---
|
|
@@ -330,8 +331,8 @@ Antes de considerar o PR completo:
|
|
|
330
331
|
## Sessão e publicação
|
|
331
332
|
|
|
332
333
|
- O texto do PR fica em **`$SESSIONS_DIR/eng/{TASK_MANAGER_KEY}/pull-request.md`**, aprovado pelo usuário.
|
|
333
|
-
- **Publicar (push + MR/PR) só com o Sim** do `AskUserQuestion` "Publicar o PR agora?". Com Não, o arquivo fica na sessão e nada é enviado.
|
|
334
|
-
- **A sessão nunca é apagada por este comando:** o `/eng.spec-consolidate`, que roda
|
|
334
|
+
- **Publicar (push + MR/PR) só com o Sim** do `AskUserQuestion` "Publicar o PR agora?", ou com a escolha "Publicar direto e validar no PR" da Fase 0 (`eng.transitions-rules.md`). Com Não, o arquivo fica na sessão e nada é enviado.
|
|
335
|
+
- **A sessão nunca é apagada por este comando:** o `/eng.spec-consolidate`, que roda depois do merge, precisa do `architecture.md`, do `plan.md`, do `gate-checklist.md` e do `pull-request.md`. A pessoa apaga à mão quando quiser.
|
|
335
336
|
|
|
336
337
|
## daily.md (registro do esforço)
|
|
337
338
|
|
|
@@ -42,7 +42,7 @@ O workflow **só é considerado completo** após:
|
|
|
42
42
|
|
|
43
43
|
1. O `architecture.md` estar preenchido
|
|
44
44
|
2. O usuário revisar o documento
|
|
45
|
-
3. O usuário **aprovar explicitamente** para prosseguir
|
|
45
|
+
3. O usuário **aprovar explicitamente** para prosseguir — sem Advisor, pela pergunta de transição "Aprovar o architecture.md?" (`eng.transitions-rules.md`)
|
|
46
46
|
|
|
47
47
|
**Exceção (Advisor):** se o usuário escolheu usar o Advisor no início do `eng.start`, as questões em aberto são decididas pela sugestão dele e o gate segue a autonomia do `context.md`: com `autonomia: alta` o `start` apresenta o resumo e segue para o `eng.plan` sem aguardar; com `média` ou `baixa`, a aprovação explícita continua obrigatória.
|
|
48
48
|
|
|
@@ -92,7 +92,7 @@ O workflow **só é considerado completo** após:
|
|
|
92
92
|
7. **Aguardar aprovação**
|
|
93
93
|
- Se aprovado → Informar próximos passos
|
|
94
94
|
- Se rejeitado → Iterar no documento
|
|
95
|
-
- NUNCA prosseguir
|
|
95
|
+
- NUNCA prosseguir sem a resposta: "Aprovar e seguir para o `/eng.plan`" (pergunta de transição, `eng.transitions-rules.md`) é a aprovação para seguir; a exceção do Advisor continua valendo
|
|
96
96
|
|
|
97
97
|
---
|
|
98
98
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
> **Applies to:** HUB: all | POSITION: all | AREA: ENGINEERING | SQUAD: all
|
|
2
|
+
|
|
3
|
+
# Regras das transições do ciclo de engenharia
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Dar fluidez ao ciclo `eng.start → eng.plan → eng.work → eng.pre-pr → eng.pr → eng.spec-consolidate` com perguntas nos pontos de início e de transição, sem mudar nada para quem prefere o fluxo de sempre.
|
|
8
|
+
|
|
9
|
+
## Escopo
|
|
10
|
+
|
|
11
|
+
Lida pelos workflows `eng.start`, `eng.plan`, `eng.work`, `eng.pre-pr` e `eng.pr` (cada um manda ler este arquivo). Vale para as perguntas da tabela "Transições" abaixo.
|
|
12
|
+
|
|
13
|
+
## Regras
|
|
14
|
+
|
|
15
|
+
### Obrigatório
|
|
16
|
+
|
|
17
|
+
1. **A opção padrão mantém o fluxo atual.** É a primeira (ou a marcada como padrão) e diz o que acontece, com "(como hoje)" ou o nome do fluxo. **Nunca** se chama "Ignorar": quem a escolhe não pula nada, segue o fluxo de sempre e interage com o documento como sempre fez.
|
|
18
|
+
2. **Formato:** `AskUserQuestion`, uma pergunta por decisão, no máximo 4 opções. Sem `AskUserQuestion`, use a tabela de opções de `prod-rules.md`.
|
|
19
|
+
3. **A resposta é a aprovação.** "Aprovar e seguir" ou "Aprovar e parar aqui" valem como a aprovação explícita que as rules de cada comando exigem. Sem uma dessas respostas, nada avança.
|
|
20
|
+
4. **Seguir para o próximo comando:** se a IDE permite chamar outro comando (no Claude Code, pelo Skill tool), chame-o com o mesmo `{TASK_MANAGER_KEY}`; senão, mostre o comando pronto para colar.
|
|
21
|
+
5. **Limites que nenhuma escolha dispensa:** `MAX_AI_EXECUTION_PERCENTAGE`, testes e lint passando, e a parada em questão nova em aberto.
|
|
22
|
+
|
|
23
|
+
### Proibido
|
|
24
|
+
|
|
25
|
+
- Pergunta nova sem a opção que mantém o fluxo atual.
|
|
26
|
+
- Avançar para o próximo comando sem a resposta do usuário.
|
|
27
|
+
- Usar a escolha de um comando para contornar o `MAX_AI_EXECUTION_PERCENTAGE`.
|
|
28
|
+
|
|
29
|
+
### Transições
|
|
30
|
+
|
|
31
|
+
| Comando | Quando | Pergunta | Opções (padrão primeiro) |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| `eng.start` | Início, só **sem Advisor** | "Como tratar as questões em aberto que surgirem?" | Tratar no architecture.md (como hoje) · Uma a uma, assim que surgirem |
|
|
34
|
+
| `eng.start` | Fim, só **sem Advisor** | "Aprovar o architecture.md?" | Aprovar e parar aqui (como hoje) · Aprovar e seguir para o `/eng.plan` · Ajustar o documento |
|
|
35
|
+
| `eng.plan` | Fim | "Aprovar o plan.md?" | Aprovar e parar aqui (como hoje) · Aprovar e seguir para o `/eng.work` · Ajustar o plano |
|
|
36
|
+
| `eng.work` | Início | Execução | Fase a fase, com aprovação (como hoje) · Todas de uma vez ("N de M tarefas", pelo limite) |
|
|
37
|
+
| `eng.work` | Início | Commits | Um por fase (como hoje) · Um commit só ao final |
|
|
38
|
+
| `eng.work` | Início | Depois do work | Sugerir o `/eng.pre-pr` (como hoje) · Rodar o `/eng.pre-pr` na sequência · Ir direto para o `/eng.pr` · Parar aqui |
|
|
39
|
+
| `eng.pre-pr` | Fim | "Seguir para o `/eng.pr`?" | Parar aqui para ajustar (como hoje) · Seguir para o `/eng.pr` |
|
|
40
|
+
| `eng.pr` | Início | "Como validar o PR?" | Revisar o texto e confirmar a publicação aqui (como hoje) · Publicar direto e validar no PR |
|
|
41
|
+
| `eng.pr` | Fim | "O PR já foi aprovado e mergeado?" | Ainda não (como hoje) · Sim, rodar o `/eng.spec-consolidate` |
|
|
42
|
+
|
|
43
|
+
**Com Advisor**, o `eng.start` não ganha pergunta nova: o Advisor decide as questões em aberto e o gate do fim segue a autonomia do `context.md`, como já estava.
|
|
44
|
+
|
|
45
|
+
### Recomendado
|
|
46
|
+
|
|
47
|
+
- Mostre, na própria opção, o que muda na prática (ex.: "Todas de uma vez (6 de 6 tarefas)").
|
|
48
|
+
- No `eng.work`, grave as escolhas no cabeçalho do `plan.md`; numa retomada, pergunte uma vez se mantém.
|
|
49
|
+
|
|
50
|
+
## Exceções
|
|
51
|
+
|
|
52
|
+
- O usuário pode dar as escolhas em texto livre ("faça todas as fases, um commit, direto ao PR"); valem como as respostas das perguntas correspondentes. É o "Escape Hatch" de `eng-rules.md` ("o usuário pode sempre fazer override de qualquer regra contextual com instrução explícita").
|
|
53
|
+
|
|
54
|
+
## Referências
|
|
55
|
+
|
|
56
|
+
- `workflows/engineering/eng.{start,plan,work,pre-pr,pr}.md`
|
|
57
|
+
- `rules/engineering/eng-rules.md` (`MAX_AI_EXECUTION_PERCENTAGE`)
|
|
58
|
+
- `rules/product/prod-rules.md` (formato sem `AskUserQuestion`)
|
|
@@ -73,7 +73,7 @@ O `work` é **estritamente proibido** de:
|
|
|
73
73
|
| Fazer `git push` | Escrever código |
|
|
74
74
|
| Criar Pull Requests | Criar/modificar arquivos de código |
|
|
75
75
|
| Usar `git add .` | `git add` de arquivos específicos da fase |
|
|
76
|
-
| Commitar sem aprovação do usuário na fase | Commitar ao final da fase validada, com testes passando
|
|
76
|
+
| Commitar sem aprovação do usuário na fase | Commitar ao final da fase validada (ou ao final, com "Um commit só"), com testes passando |
|
|
77
77
|
| Commitar com testes falhando | Executar testes locais |
|
|
78
78
|
| Mover cards no Jira | Ler arquivos da sessão |
|
|
79
79
|
| Fazer merge de branches | Atualizar `plan.md` com progresso |
|
|
@@ -81,6 +81,8 @@ O `work` é **estritamente proibido** de:
|
|
|
81
81
|
|
|
82
82
|
O commit segue o formato do workflow (`{TASK_MANAGER_KEY} {tipo}({escopo}): {descrição}`, com `Refs:`). Push e PR são responsabilidade do `eng.pr`.
|
|
83
83
|
|
|
84
|
+
**Escolhas do início** (`eng.transitions-rules.md`, Fase 1.3 do workflow): execução, commits e o que vem depois. Com "Todas de uma vez", a escolha é a aprovação das fases; com "Um commit só ao final", o commit é um só, depois da última fase; com "Ir direto para o `/eng.pr`", o work termina chamando o `/eng.pr` (que faz o push e o PR, não o work).
|
|
85
|
+
|
|
84
86
|
### 2. Escopo de Atuação
|
|
85
87
|
|
|
86
88
|
O `work` atua **exclusivamente** em:
|
|
@@ -222,12 +224,14 @@ Ao concluir uma fase, adicione na seção `### Comentários:`:
|
|
|
222
224
|
|
|
223
225
|
### Pontos de Pausa Obrigatórios
|
|
224
226
|
|
|
225
|
-
|
|
227
|
+
Com **"Fase a fase, com aprovação (como hoje)"**, o workflow **DEVE pausar e aguardar confirmação**:
|
|
226
228
|
|
|
227
229
|
1. ✋ **Antes de iniciar qualquer fase**
|
|
228
230
|
2. ✋ **Após completar implementação** (antes de atualizar plan.md)
|
|
229
231
|
3. ✋ **Antes de iniciar próxima fase**
|
|
230
232
|
|
|
233
|
+
Com **"Todas de uma vez"**, essas pausas não acontecem. **Em qualquer escolha**, o workflow para no limite do `MAX_AI_EXECUTION_PERCENTAGE`, com um teste falhando e diante de uma questão nova em aberto.
|
|
234
|
+
|
|
231
235
|
### Comunicação
|
|
232
236
|
|
|
233
237
|
- Seja claro sobre o que foi feito
|
|
@@ -291,10 +295,12 @@ Ao finalizar **TODAS as fases** do `plan.md`, informe:
|
|
|
291
295
|
2. Execute os testes completos
|
|
292
296
|
3. Quando estiver pronto, use `eng.pr` para criar o Pull Request
|
|
293
297
|
|
|
294
|
-
⚠️ Este workflow commita por fase, mas NÃO faz push nem PR.
|
|
298
|
+
⚠️ Este workflow commita (por fase ou ao final), mas NÃO faz push nem PR.
|
|
295
299
|
Use `eng.pr` quando estiver pronto para submeter.
|
|
296
300
|
```
|
|
297
301
|
|
|
302
|
+
Depois, siga a escolha **Depois do work** da Fase 1.3 (sugerir o `/eng.pre-pr`, chamá-lo, chamar o `/eng.pr` ou parar).
|
|
303
|
+
|
|
298
304
|
---
|
|
299
305
|
|
|
300
306
|
## Checklist de Conclusão de Fase
|
|
@@ -152,6 +152,8 @@ git add {arquivo1} {arquivo2} ...
|
|
|
152
152
|
Refs: {TASK_MANAGER_KEY}
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
+
Com `ARTIFACT_STYLE=human-generated`: sem `Co-Authored-By` de ferramenta nem "Generated with …", mesmo que a IDE peça (`rules/artifact-style-rules.md`).
|
|
156
|
+
|
|
155
157
|
**Tipos permitidos:**
|
|
156
158
|
|
|
157
159
|
| Tipo | Uso |
|
|
@@ -207,7 +209,7 @@ Usar template oficial em `$IDE/templates/engineering/PR-template.md`.
|
|
|
207
209
|
- **Branch origem**: `{NOME_DA_BRANCH}`
|
|
208
210
|
- **Branch destino**: Conforme solicitado (ex: `develop`)
|
|
209
211
|
|
|
210
|
-
> ⚠️ **IMPORTANTE**: Não mencione AI, Claude ou assistentes no MR.
|
|
212
|
+
> ⚠️ **IMPORTANTE**: Não mencione AI, Claude ou assistentes no MR. Com `ARTIFACT_STYLE=human-generated`, também sem "Generated with …" nem link da ferramenta.
|
|
211
213
|
|
|
212
214
|
### 6. Atualizar o card (`TASK_MANAGER`)
|
|
213
215
|
|
|
@@ -28,6 +28,8 @@ Ler `TASK_MANAGER`, `TASK_MANAGER_URL_BASE`, `TOKEN_TASK_MANAGER` e `USER` do `$
|
|
|
28
28
|
|
|
29
29
|
Se `TASK_MANAGER` estiver vazio, ausente ou ainda for a lista `[jira, linear, github, asana]` → **encerrar em silêncio** (freelance, sem board). Não pedir token. Não falhar o workflow.
|
|
30
30
|
|
|
31
|
+
Com `ARTIFACT_STYLE=human-generated`, o comentário sai sem marcas de IA (`rules/artifact-style-rules.md`).
|
|
32
|
+
|
|
31
33
|
### 1. MCP (só Jira)
|
|
32
34
|
|
|
33
35
|
Se `TASK_MANAGER=jira` e o MCP Atlassian estiver disponível:
|
|
@@ -24,7 +24,7 @@ Integrar os comandos do framework com o **Central docs**: o registro do que **de
|
|
|
24
24
|
| Documentos de trabalho | PRD, FRD, épicos, histórias, ARD, RFC, QA, swagger, robôs, C4: o que se pretende e se discute | `docs/jarvis/` (`$PROD_DOCS`, `$ENG_DOCS`), fora do versionamento |
|
|
25
25
|
| **Central docs** | O que foi implementado: um documento **completo e autossuficiente** por funcionalidade (estado atual) e um **registro por entrega** (PR, commits, autores) | Pasta do Central docs (adaptador) |
|
|
26
26
|
|
|
27
|
-
Quem escreve no Central docs é o **`/eng.spec-consolidate`** (agente `eng.docs-consolidator`),
|
|
27
|
+
Quem escreve no Central docs é o **`/eng.spec-consolidate`** (agente `eng.docs-consolidator`), depois do merge do PR. Os documentos de trabalho nunca são publicados lá.
|
|
28
28
|
|
|
29
29
|
**Modos deste skill:**
|
|
30
30
|
- buscar o que já foi implementado (Modo 1);
|