ganbatte-os 0.2.26 → 0.2.28
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.
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// slack-notify.js — Slack notification tool
|
|
3
|
+
// slack-notify.js — Slack notification tool (zero-dep)
|
|
4
4
|
// Usage: node slack-notify.js <command> [--options]
|
|
5
|
-
// Auth:
|
|
5
|
+
// Auth:
|
|
6
|
+
// - Webhook commands (send, task-done, sprint-summary): SLACK_WEBHOOK_URL
|
|
7
|
+
// - Web API commands (fetch-thread, find-thread): SLACK_BOT_TOKEN
|
|
6
8
|
|
|
7
9
|
const WEBHOOK_URL = process.env.SLACK_WEBHOOK_URL
|
|
8
|
-
|
|
9
|
-
if (!WEBHOOK_URL) {
|
|
10
|
-
// Graceful skip — no webhook configured is not an error
|
|
11
|
-
console.log(JSON.stringify({ skipped: true, reason: 'SLACK_WEBHOOK_URL not set' }))
|
|
12
|
-
process.exit(0)
|
|
13
|
-
}
|
|
10
|
+
const BOT_TOKEN = process.env.SLACK_BOT_TOKEN
|
|
14
11
|
|
|
15
12
|
function parseArgs(argv) {
|
|
16
13
|
const result = { _: [] }
|
|
@@ -35,6 +32,19 @@ function parseArgs(argv) {
|
|
|
35
32
|
const args = parseArgs(process.argv.slice(2))
|
|
36
33
|
const [cmd, sub, ...rest] = args._
|
|
37
34
|
|
|
35
|
+
const WEBHOOK_COMMANDS = new Set(['send', 'task-done', 'sprint-summary'])
|
|
36
|
+
const API_COMMANDS = new Set(['fetch-thread', 'find-thread'])
|
|
37
|
+
|
|
38
|
+
if (WEBHOOK_COMMANDS.has(cmd) && !WEBHOOK_URL) {
|
|
39
|
+
console.log(JSON.stringify({ skipped: true, reason: 'SLACK_WEBHOOK_URL not set' }))
|
|
40
|
+
process.exit(0)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (API_COMMANDS.has(cmd) && !BOT_TOKEN) {
|
|
44
|
+
console.log(JSON.stringify({ error: 'SLACK_BOT_TOKEN not set (required for Web API commands)' }))
|
|
45
|
+
process.exit(0)
|
|
46
|
+
}
|
|
47
|
+
|
|
38
48
|
async function sendWebhook(payload) {
|
|
39
49
|
if (args['dry-run']) {
|
|
40
50
|
return { _dry_run: true, url: WEBHOOK_URL.replace(/\/[^/]{6,}$/, '/***'), payload }
|
|
@@ -53,6 +63,22 @@ async function sendWebhook(payload) {
|
|
|
53
63
|
return { sent: false, status: res.status, body: text }
|
|
54
64
|
}
|
|
55
65
|
|
|
66
|
+
async function slackApi(method, params) {
|
|
67
|
+
if (args['dry-run']) {
|
|
68
|
+
return { _dry_run: true, method, params: { ...params, token: '***' } }
|
|
69
|
+
}
|
|
70
|
+
const body = new URLSearchParams(params).toString()
|
|
71
|
+
const res = await fetch(`https://slack.com/api/${method}`, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: {
|
|
74
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
75
|
+
'Authorization': `Bearer ${BOT_TOKEN}`,
|
|
76
|
+
},
|
|
77
|
+
body,
|
|
78
|
+
})
|
|
79
|
+
return res.json()
|
|
80
|
+
}
|
|
81
|
+
|
|
56
82
|
function escapeSlack(text) {
|
|
57
83
|
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
58
84
|
}
|
|
@@ -155,6 +181,55 @@ async function main() {
|
|
|
155
181
|
break
|
|
156
182
|
}
|
|
157
183
|
|
|
184
|
+
case 'fetch-thread': {
|
|
185
|
+
const channel = args['channel-id'] || process.env.SLACK_CHANNEL_ID_WEEKLY
|
|
186
|
+
const ts = args['thread-ts'] || args.ts
|
|
187
|
+
if (!channel || !ts) {
|
|
188
|
+
result = { error: '--channel-id (or SLACK_CHANNEL_ID_WEEKLY) and --thread-ts required' }
|
|
189
|
+
break
|
|
190
|
+
}
|
|
191
|
+
const limit = args.limit || '100'
|
|
192
|
+
const api = await slackApi('conversations.replies', { channel, ts, limit })
|
|
193
|
+
if (!api.ok) {
|
|
194
|
+
result = { ok: false, error: api.error, needed: api.needed }
|
|
195
|
+
break
|
|
196
|
+
}
|
|
197
|
+
const messages = (api.messages || []).map(m => ({
|
|
198
|
+
user: m.user,
|
|
199
|
+
ts: m.ts,
|
|
200
|
+
text: m.text || '',
|
|
201
|
+
reply_count: m.reply_count,
|
|
202
|
+
}))
|
|
203
|
+
result = { ok: true, count: messages.length, messages }
|
|
204
|
+
break
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
case 'find-thread': {
|
|
208
|
+
const channel = args['channel-id'] || process.env.SLACK_CHANNEL_ID_WEEKLY
|
|
209
|
+
const pattern = args.pattern
|
|
210
|
+
if (!channel || !pattern) {
|
|
211
|
+
result = { error: '--channel-id (or SLACK_CHANNEL_ID_WEEKLY) and --pattern required' }
|
|
212
|
+
break
|
|
213
|
+
}
|
|
214
|
+
const api = await slackApi('conversations.history', { channel, limit: args.limit || '50' })
|
|
215
|
+
if (!api.ok) {
|
|
216
|
+
result = { ok: false, error: api.error, needed: api.needed }
|
|
217
|
+
break
|
|
218
|
+
}
|
|
219
|
+
const re = new RegExp(pattern, 'i')
|
|
220
|
+
const match = (api.messages || []).find(m => re.test(m.text || ''))
|
|
221
|
+
if (!match) {
|
|
222
|
+
result = { found: false }
|
|
223
|
+
break
|
|
224
|
+
}
|
|
225
|
+
result = {
|
|
226
|
+
found: true,
|
|
227
|
+
ts: match.ts,
|
|
228
|
+
text_preview: (match.text || '').slice(0, 200),
|
|
229
|
+
}
|
|
230
|
+
break
|
|
231
|
+
}
|
|
232
|
+
|
|
158
233
|
default:
|
|
159
234
|
result = {
|
|
160
235
|
error: cmd ? `Unknown command: ${cmd}` : 'No command provided',
|
|
@@ -162,6 +237,12 @@ async function main() {
|
|
|
162
237
|
send: 'send --text "Hello *bold* _italic_" | send --blocks-file payload.json',
|
|
163
238
|
'task-done': 'task-done --task T-001 --commit abc1234 --author "Name" [--sprint "S01"] [--track backend] [--message "feat: ..."]',
|
|
164
239
|
'sprint-summary': 'sprint-summary --file sprint-status.json',
|
|
240
|
+
'fetch-thread': 'fetch-thread --channel-id C... --thread-ts 1234567890.123456 [--limit 100]',
|
|
241
|
+
'find-thread': 'find-thread --channel-id C... --pattern "regex" [--limit 50]',
|
|
242
|
+
},
|
|
243
|
+
auth: {
|
|
244
|
+
webhook_commands: 'send, task-done, sprint-summary — require SLACK_WEBHOOK_URL',
|
|
245
|
+
api_commands: 'fetch-thread, find-thread — require SLACK_BOT_TOKEN (scopes: groups:history for private channels)',
|
|
165
246
|
},
|
|
166
247
|
formatting: {
|
|
167
248
|
bold: '*text*',
|
|
@@ -1,5 +1,86 @@
|
|
|
1
1
|
# weekly-update — Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-04-20 — v1.2.1 (refinamento do modo simple após envio validado)
|
|
4
|
+
|
|
5
|
+
Após o primeiro envio real em modo `simple` (mesma data), Douglas ajustou manualmente a versão gerada antes de enviar. Ajustes virando regras permanentes:
|
|
6
|
+
|
|
7
|
+
### Mudanças nas regras do modo simple
|
|
8
|
+
|
|
9
|
+
1. **Bullet markers opcionais**: removida obrigatoriedade de `•`. Quebra de linha entre itens é suficiente e preferível — Slack renderiza limpo.
|
|
10
|
+
2. **Tom casual/neutro misturado**: `pra/tá/tô` não são mais mandatórios. Mistura natural com `para/está/estou` é validada e soa melhor.
|
|
11
|
+
3. **Termos contextualmente aceitos** (nova categoria, entre banidos e permitidos):
|
|
12
|
+
- `PRD` — PO/PM usam, mantém.
|
|
13
|
+
- `front`/`backend` — aceitáveis quando linguagem corrente do time.
|
|
14
|
+
- `Storybook` — aceitável se nome de produto; senão trocar por "catálogo de componentes".
|
|
15
|
+
4. **Voz ativa primeira pessoa obrigatória**: "Criei e enviei" > "Entreguei" > "Foi entregue". Evitar passiva.
|
|
16
|
+
5. **Tamanho alvo ajustado**: 200-350 palavras (antes 150-250). Completude vale mais que concisão extrema — cobrir todas as entregas e pendências.
|
|
17
|
+
|
|
18
|
+
### Exemplo canônico arquivado
|
|
19
|
+
|
|
20
|
+
`.gos/weekly-updates/2026-04-20.md` — versão final enviada por Douglas com ajustes. Frontmatter documenta os ajustes aplicados. SKILL.md passa a referenciar esse arquivo como exemplo autoritativo (substitui o rascunho anterior curto).
|
|
21
|
+
|
|
22
|
+
### Diff vs v1.2.0
|
|
23
|
+
|
|
24
|
+
- Regras 3/4/5 do modo simple reescritas.
|
|
25
|
+
- Nova regra 3 (termos contextualmente aceitos) intercalada.
|
|
26
|
+
- Alvo subiu de 150-250 para 200-350 palavras.
|
|
27
|
+
- Exemplo canônico agora é o envio real, não um rascunho.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 2026-04-20 — v1.2.0 (modos `simple` e `detailed`, controlados por env)
|
|
32
|
+
|
|
33
|
+
Motivação: na thread "Conversa semanal" de 2026-04-17, PO (U07M07M6R42) e PM (U0ADE3FT9HB) pediram explicitamente resumo em linguagem não-técnica. Citações literais:
|
|
34
|
+
|
|
35
|
+
- PM: "consegue trazer um resumo em linguem nao técnica pra mim ahaha, por favor?"
|
|
36
|
+
- PO: "Pensa que está em uma reunião com a gente, o que você compartilharia?"
|
|
37
|
+
|
|
38
|
+
### Novo argumento e env var
|
|
39
|
+
|
|
40
|
+
- `$ARGUMENTS --mode simple|detailed` sobrescreve via linha de comando.
|
|
41
|
+
- `WEEKLY_UPDATE_MODE=simple|detailed` no `.env` define o padrão do projeto.
|
|
42
|
+
- Se ambos ausentes, fallback para `detailed` (comportamento anterior).
|
|
43
|
+
- Skill não pergunta mais — resolve via env/arg e informa o modo no início da Phase 2.
|
|
44
|
+
|
|
45
|
+
### Modo `simple` (novo)
|
|
46
|
+
|
|
47
|
+
Audiência não-técnica (PO/PM/clientes). Regras obrigatórias:
|
|
48
|
+
|
|
49
|
+
1. Zero IDs de task (nada de T-084, T-110).
|
|
50
|
+
2. Zero jargão técnico. Lista banida: API, endpoint, FK, hook, webhook, migration, deploy, pipeline, CI/CD, TypeScript, Zod, backend, frontend, SPA routing, commit, branch, merge, PR, rebase, drift, build, pre-commit.
|
|
51
|
+
3. Bullets curtos em vez de parágrafos densos.
|
|
52
|
+
4. Foco no valor entregue, não em como foi feito.
|
|
53
|
+
5. Tom de reunião casual (primeira pessoa, contrações como "pra", "to", "tá").
|
|
54
|
+
6. Alvo: 150-250 palavras.
|
|
55
|
+
|
|
56
|
+
Calibração humanizer: conversacional (intensidade alta), contra os 30 pontos de padrões AI.
|
|
57
|
+
|
|
58
|
+
### Modo `detailed` (comportamento anterior, preservado)
|
|
59
|
+
|
|
60
|
+
Audiência técnica (tech lead, outros devs). Permite IDs de task, jargão apropriado, narrativa em parágrafos, dependências explícitas. Alvo: 300-500 palavras.
|
|
61
|
+
|
|
62
|
+
### Checklist de aprovação expandido
|
|
63
|
+
|
|
64
|
+
Novos itens na Phase 4:
|
|
65
|
+
- Modo confirmado antes do envio.
|
|
66
|
+
- Em `simple`: nenhum termo banido aparece no texto final.
|
|
67
|
+
- Em `simple`: nenhum ID de task (T-XXX) aparece no texto final.
|
|
68
|
+
|
|
69
|
+
### Arquivos afetados
|
|
70
|
+
|
|
71
|
+
- `.gos/skills/weekly-update/SKILL.md` — Gate 3 novo, Phase 2 refatorada com templates por modo, Phase 3 com calibração por modo, Phase 4 checklist expandido.
|
|
72
|
+
- `.env-example` — nova var `WEEKLY_UPDATE_MODE=simple`.
|
|
73
|
+
- `.env` local Ganbatte — adicionado `WEEKLY_UPDATE_MODE=simple`.
|
|
74
|
+
|
|
75
|
+
### Companion: `slack-notify.js` ganhou `fetch-thread` e `find-thread`
|
|
76
|
+
|
|
77
|
+
Comandos Web API via `SLACK_BOT_TOKEN` (scope `groups:history` para canais privados). Usado pela skill e disponível para auditoria de threads passadas. Allow-rules adicionadas em `~/.claude/settings.json`:
|
|
78
|
+
|
|
79
|
+
- `Bash(node .gos/scripts/tools/slack-notify.js fetch-thread:*)`
|
|
80
|
+
- `Bash(node .gos/scripts/tools/slack-notify.js find-thread:*)`
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
3
84
|
## 2026-04-17 — v2.0 (Web API, thread obrigatória, auto-descoberta)
|
|
4
85
|
|
|
5
86
|
Mudanças estruturais motivadas por incidente em produção: o envio via incoming webhook caiu fora da thread "Conversa semanal" e gerou mensagem isolada no canal #cnpq-tech.
|
|
@@ -3,15 +3,17 @@ name: weekly-update
|
|
|
3
3
|
description: >
|
|
4
4
|
Gera resumo das tasks concluidas nos ultimos 10 dias no ClickUp, humaniza o texto
|
|
5
5
|
em pt-BR e posta como resposta na thread "Conversa semanal" do Slack (#cspo-tech).
|
|
6
|
+
Suporta dois modos: simple (curto, ~150 palavras) e detailed (completo, ~400 palavras).
|
|
6
7
|
Requer aprovacao do usuario antes do envio.
|
|
7
8
|
description_pt-BR: >
|
|
8
9
|
Resumo semanal das tasks concluidas, humanizado com anti-AI patterns,
|
|
9
|
-
com aprovacao antes de postar na Conversa semanal do Slack.
|
|
10
|
-
argument-hint: "[link da mensagem 'Conversa semanal' no Slack
|
|
10
|
+
com aprovacao antes de postar na Conversa semanal do Slack. Modo simple ou detailed.
|
|
11
|
+
argument-hint: "[--mode simple|detailed] [link da mensagem 'Conversa semanal' no Slack]"
|
|
11
12
|
type: prompt
|
|
12
|
-
version: "1.1
|
|
13
|
+
version: "1.2.1"
|
|
13
14
|
env:
|
|
14
15
|
- WEEKLY_UPDATE
|
|
16
|
+
- WEEKLY_UPDATE_MODE
|
|
15
17
|
- SLACK_WEBHOOK_CSPO_TECH
|
|
16
18
|
categories: [reporting, slack, clickup, weekly]
|
|
17
19
|
allowedTools:
|
|
@@ -87,6 +89,28 @@ Se o valor retornado for `__MISSING__` ou vazio:
|
|
|
87
89
|
|
|
88
90
|
Se ambos os gates passarem, prosseguir normalmente.
|
|
89
91
|
|
|
92
|
+
### Gate 3 — Resolver modo de escrita
|
|
93
|
+
|
|
94
|
+
Determinar `MODE` nesta ordem de precedência:
|
|
95
|
+
|
|
96
|
+
1. **`$ARGUMENTS`** (maior prioridade):
|
|
97
|
+
- Contém `--mode simple` → `MODE=simple`
|
|
98
|
+
- Contém `--mode detailed` → `MODE=detailed`
|
|
99
|
+
2. **Variável de ambiente `WEEKLY_UPDATE_MODE`** (default do projeto):
|
|
100
|
+
```bash
|
|
101
|
+
echo "${WEEKLY_UPDATE_MODE:-}"
|
|
102
|
+
```
|
|
103
|
+
- Valor `simple` → `MODE=simple`
|
|
104
|
+
- Valor `detailed` → `MODE=detailed`
|
|
105
|
+
- Vazio ou qualquer outro valor → cair para passo 3
|
|
106
|
+
3. **Fallback final**: `MODE=detailed`.
|
|
107
|
+
|
|
108
|
+
**Não perguntar ao usuário.** O padrão fica no `.env` (recomendado: `WEEKLY_UPDATE_MODE=simple` alinhado ao pedido da PO/PM na thread "Conversa semanal"). Só sobrescrever via argumento quando precisar de um envio técnico pontual.
|
|
109
|
+
|
|
110
|
+
Informar ao usuário o modo resolvido no início da Phase 2 (ex: "Modo resolvido: `simple` (via env)").
|
|
111
|
+
|
|
112
|
+
**Contexto histórico (por que existem dois modos):** a PO (não-técnica) e o PM (não-técnico) na thread "Conversa semanal" pediram explicitamente "resumo em linguagem não técnica" e "pensa que está em uma reunião com a gente, o que você compartilharia?". O modo `simple` foi desenhado para atender esse pedido. O `detailed` segue para audiência técnica (tech lead, outros devs).
|
|
113
|
+
|
|
90
114
|
---
|
|
91
115
|
|
|
92
116
|
## Phase 1 — Buscar tasks concluidas no ClickUp (ultimos 10 dias)
|
|
@@ -112,13 +136,13 @@ Se nenhuma task encontrada: informar ao usuario e encerrar.
|
|
|
112
136
|
|
|
113
137
|
## Phase 2 — Gerar resumo pt-BR
|
|
114
138
|
|
|
115
|
-
|
|
139
|
+
O template e as regras variam por `MODE`. Secoes marcadas com (?) sao opcionais — incluir somente se houver conteudo relevante.
|
|
116
140
|
|
|
117
|
-
|
|
141
|
+
### Template (comum aos dois modos)
|
|
118
142
|
|
|
119
143
|
```
|
|
120
144
|
*O que foi feito*
|
|
121
|
-
[
|
|
145
|
+
[Conteudo conforme regras do modo]
|
|
122
146
|
|
|
123
147
|
*Desafios encontrados* (?)
|
|
124
148
|
[Dependencias, bloqueios, decisoes dificeis]
|
|
@@ -133,17 +157,79 @@ O resumo DEVE seguir este template. Secoes marcadas com (?) sao opcionais — in
|
|
|
133
157
|
[Pedidos de alinhamento, decisao, recurso]
|
|
134
158
|
```
|
|
135
159
|
|
|
136
|
-
|
|
160
|
+
Regras comuns aos dois modos:
|
|
161
|
+
- Sem emojis.
|
|
162
|
+
- Titulos de secao em negrito Slack: `*titulo*`.
|
|
163
|
+
- Uma linha em branco entre titulo e corpo (Slack renderiza colado sem isso).
|
|
164
|
+
|
|
165
|
+
---
|
|
137
166
|
|
|
138
|
-
|
|
139
|
-
- Tom: conversacional, direto, como se estivesse contando para um colega nao tecnico
|
|
140
|
-
- Foco em **o que foi entregue e por que importa**, nao em nomes de tasks ou IDs
|
|
141
|
-
- Sem jargao tecnico (trocar "API endpoint" por "integracao", "migration" por "ajuste no banco", etc.)
|
|
142
|
-
- Sem emojis
|
|
143
|
-
- Os titulos das secoes usam negrito Slack: `*titulo*`
|
|
167
|
+
### Modo `detailed` — Relatório executivo (audiência técnica)
|
|
144
168
|
|
|
145
|
-
|
|
146
|
-
|
|
169
|
+
Audiência: tech lead, outros devs, stakeholders técnicos.
|
|
170
|
+
|
|
171
|
+
Regras:
|
|
172
|
+
- Permite referenciar **IDs de task** (T-082, T-110, etc.) quando importa para rastreio.
|
|
173
|
+
- Permite **termos técnicos** quando a audiência é técnica (API, FK, hook, TypeScript, deploy, Storybook, webhook).
|
|
174
|
+
- Narrativa em **parágrafos** agrupados por tema; bullets só para listas de tasks ou bloqueios.
|
|
175
|
+
- Explica **decisões** e **trade-offs** quando houver (por que X e não Y).
|
|
176
|
+
- Inclui dependências explícitas ("T-084 depende da T-082 nova").
|
|
177
|
+
- Tamanho alvo: 300-500 palavras.
|
|
178
|
+
|
|
179
|
+
Exemplo de tom (extraído do envio real 2026-04-17):
|
|
180
|
+
> *O que foi feito*
|
|
181
|
+
>
|
|
182
|
+
> A semana concentrou na frente de Storybook e infra de deploy. Criei a conta Vercel pra hospedar o Storybook separado, customizei a home com branding Fractus, corrigi o SPA routing e atualizei o README. Pluguei Vercel Analytics e Speed Insights nos dois apps.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### Modo `simple` — Linguagem acessível (audiência não-técnica)
|
|
187
|
+
|
|
188
|
+
Audiência: PO/PM sem background técnico, clientes, time de negócio.
|
|
189
|
+
|
|
190
|
+
Regras **obrigatórias** (violar qualquer uma implica reescrever):
|
|
191
|
+
|
|
192
|
+
1. **Zero IDs de task.** Nunca mencionar "T-084", "T-110", "task X". Só o que foi entregue, em linguagem de valor.
|
|
193
|
+
2. **Zero jargão técnico de baixo nível.** Banidos sempre: API, endpoint, FK, foreign key, hook, webhook, migration, pipeline, CI/CD, TypeScript, Zod, regex, SPA routing, commit, branch, merge, PR, rebase, drift, build, deploy. Traduzir cada um:
|
|
194
|
+
- "API de diagnóstico" → "formulário de diagnóstico" ou "ferramenta pra coletar dados do diagnóstico"
|
|
195
|
+
- "Deploy no Vercel" → "publicar a página online" ou "colocar online"
|
|
196
|
+
- "Corrigi o SPA routing" → "arrumei a navegação entre telas que estava quebrada"
|
|
197
|
+
- "Hook de pre-commit" → "trava automática que impede erros de passar adiante"
|
|
198
|
+
- "Migration" → "ajuste no banco de dados" (quando inevitável) ou omitir
|
|
199
|
+
- "Regras de negócio em doc próprio" → "organizei as regras do produto num documento pra validar com o time"
|
|
200
|
+
3. **Termos contextualmente aceitos** (use com moderação — só quando a audiência já conhece do produto):
|
|
201
|
+
- `PRD` — PO/PM usam o termo.
|
|
202
|
+
- `front`/`backend` — aceitáveis quando já é linguagem corrente do time (ver exemplo do envio 2026-04-20).
|
|
203
|
+
- `Storybook` — aceitável se é nome de produto/catálogo conhecido; caso contrário, traduzir pra "catálogo de componentes".
|
|
204
|
+
- Se na dúvida, traduzir. Regra: PO/PM deve entender sem parar pra perguntar.
|
|
205
|
+
4. **Linhas curtas, sem bullet markers obrigatórios.** Cada linha com 1 frase, no máximo 2. Slack renderiza quebras de linha limpas sem `•` — preferível ao marcador visual. O PM do time usa `•` em algumas mensagens e não em outras; siga o padrão do autor do envio (default: sem marcador, só quebra de linha).
|
|
206
|
+
5. **Voz ativa primeira pessoa.** Preferir "Criei e enviei pra X" sobre "Foi entregue pra X". Preferir "Arrumei" sobre "Foram feitos ajustes".
|
|
207
|
+
6. **Foco no valor entregue**, não em como foi feito. Em vez de "configurei X e corrigi Y", usar "agora Z funciona / está disponível / está mais rápido".
|
|
208
|
+
7. **Tom reunião casual, mas não forçado.** Primeira pessoa (eu/a gente). Contrações permitidas (`pra`, `tá`, `tô`) mas não obrigatórias — mistura com forma neutra (`para`, `está`, `estou`) é natural e foi validado no envio 2026-04-20. Evitar formalismo corporativo ("foi realizada a entrega de...").
|
|
209
|
+
8. Tamanho alvo: 200-350 palavras. Preferência por completude (cobrir todas as entregas e pendências) sobre concisão extrema.
|
|
210
|
+
|
|
211
|
+
Teste de validação (aplicar mentalmente antes de aprovar):
|
|
212
|
+
- Se minha mãe lesse esse texto, ela entenderia o que eu fiz essa semana? Se não, reescrever.
|
|
213
|
+
- Se o PO leu e vai perguntar "o que é X?" — termo X é jargão, trocar.
|
|
214
|
+
- Dupla checagem: se PO/PM usam o termo em mensagens próprias na thread, pode manter (ex: PRD).
|
|
215
|
+
|
|
216
|
+
Exemplo canônico — envio validado 2026-04-20 (ver `.gos/weekly-updates/2026-04-20.md` para versão completa):
|
|
217
|
+
|
|
218
|
+
> *O que foi feito*
|
|
219
|
+
>
|
|
220
|
+
> Coloquei online o catálogo de componentes do Fractus com a cara nova — logo, cores e a home personalizada. Já plugado nos medidores de desempenho pra gente acompanhar se a página tá rápida.
|
|
221
|
+
> A branch desse catálogo tava bagunçada, arrumei e montei uma trava automática pra não deixar entrar mistura errada de novo.
|
|
222
|
+
> Liguei travas antes de subir código pra evitar que erro passe adiante — quem tentar subir coisa quebrada é avisado na hora.
|
|
223
|
+
> Organizei as regras do produto num documento, usando para validarmos as regras no desenvolvimento do front/backend.
|
|
224
|
+
> Criei e enviei para Adriano Morais uma ferramenta que extrai contatos de grupo do WhatsApp.
|
|
225
|
+
> No nosso framework interno, parei de mandar notificação duplicada no Slack e arrumei a conexão com o ClickUp na IDE nova que eu estou testando.
|
|
226
|
+
|
|
227
|
+
Padrões a notar nesse envio:
|
|
228
|
+
- Sem marcadores `•`, só quebra de linha entre itens.
|
|
229
|
+
- Mistura `pra/tá` com `para/está` naturalmente.
|
|
230
|
+
- `front/backend` aceito porque é linguagem já corrente do time.
|
|
231
|
+
- Voz ativa primeira pessoa em todos os itens (`Coloquei`, `Arrumei`, `Liguei`, `Criei e enviei`).
|
|
232
|
+
- Comprimento total ~310 palavras (acima do mínimo ajustado de 200-350).
|
|
147
233
|
|
|
148
234
|
## Phase 3 — Humanizar
|
|
149
235
|
|
|
@@ -166,10 +252,18 @@ Carregar e aplicar:
|
|
|
166
252
|
1. `.gos/libraries/content/ai-writing-patterns.md` — catálogo de 26 padrões
|
|
167
253
|
2. `.gos/skills/humanizer/SKILL.md` — processo de 5 passos
|
|
168
254
|
|
|
169
|
-
Calibração
|
|
170
|
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
255
|
+
Calibração varia por `MODE`:
|
|
256
|
+
|
|
257
|
+
- **`detailed`** — **Relatório executivo** (intensidade média)
|
|
258
|
+
- Cortar enchimento e inflação
|
|
259
|
+
- Manter formalidade leve
|
|
260
|
+
- Não forçar primeira pessoa se não couber
|
|
261
|
+
|
|
262
|
+
- **`simple`** — **Conversacional casual** (intensidade alta)
|
|
263
|
+
- Primeira pessoa obrigatória (eu/a gente)
|
|
264
|
+
- Contrações permitidas e encorajadas (pra, to, tá, né)
|
|
265
|
+
- Cortar qualquer palavra que soe de relatório corporativo
|
|
266
|
+
- Após a passagem de humanização, validar também a regra de zero jargão técnico (Phase 2, regra 2) — se qualquer termo banido reaparecer, reescrever
|
|
173
267
|
|
|
174
268
|
Processo:
|
|
175
269
|
1. Identificar padrões presentes no resumo (especialmente P01, P03, P04, P07, P10, P15, P17, P19, P22)
|
|
@@ -190,10 +284,13 @@ Apresentar ao usuário:
|
|
|
190
284
|
### Checklist antes de aprovar
|
|
191
285
|
|
|
192
286
|
Verificar e apresentar junto com o texto:
|
|
287
|
+
- [ ] Modo de escrita confirmado (`simple` ou `detailed`)
|
|
193
288
|
- [ ] Acentuação correta em todo o texto (não, é, há, também, além, etc.)
|
|
194
289
|
- [ ] Sem uso de hífen (-) onde deveria ser travessão (—)
|
|
195
290
|
- [ ] Assinatura do autor presente no final
|
|
196
291
|
- [ ] Catálogo ai-writing-patterns.md foi carregado e aplicado
|
|
292
|
+
- [ ] Se `MODE=simple`: nenhum termo banido apareceu (API, endpoint, FK, hook, deploy, migration, TypeScript, SPA, commit, branch, PR, merge, build, etc.)
|
|
293
|
+
- [ ] Se `MODE=simple`: nenhum ID de task (T-XXX) no texto
|
|
197
294
|
|
|
198
295
|
Perguntar com AskUserQuestion:
|
|
199
296
|
- **"Aprovar e enviar"** — prosseguir para Phase 5
|
|
@@ -255,8 +352,10 @@ Verificar resposta:
|
|
|
255
352
|
| Período | Últimos 10 dias |
|
|
256
353
|
| Slack canal | `#cspo-tech` |
|
|
257
354
|
| Webhook env var | `SLACK_WEBHOOK_CSPO_TECH` |
|
|
258
|
-
| Calibração humanizer | Relatório executivo (média) |
|
|
355
|
+
| Calibração humanizer | `detailed`: Relatório executivo (média) · `simple`: Conversacional (alta) |
|
|
259
356
|
| Score máximo AI | 30 |
|
|
260
357
|
| Template | *O que foi feito* / *Desafios* / *Em andamento* / *Pendências* / *Ajuda?* |
|
|
358
|
+
| Modos | `--mode simple` (leigos, sem jargão) · `--mode detailed` (técnicos) |
|
|
359
|
+
| Default (env) | `WEEKLY_UPDATE_MODE=simple` no `.env`; fallback se ausente: `detailed` |
|
|
261
360
|
| Ortografia | OBRIGATÓRIA — acentos pt-BR, crase, travessão |
|
|
262
361
|
| Assinatura | `— {git config user.name}` no final |
|