# Tasks — SDD CLI (TUI)

## Backlog

---

### T-01 — Adicionar dependências ratatui e crossterm ao Cargo.toml

**Objetivo:** incluir `ratatui 0.29` e `crossterm 0.28` como deps de produção, medir acréscimo de binário com `cargo bloat --release` e confirmar gate ≤+5MB.

**Arquivos:** `Cargo.toml`, `Cargo.lock`. **Origem:** RNF-04, RT-04, RT-05. **Tipo:** Sequencial — pré-requisito de toda a TUI.

**Prompt de execução:** Adicione `ratatui = "0.29"` e `crossterm = "0.28"` em `[dependencies]`; `ratatui` também em `[dev-dependencies]` (TestBackend). Garanta `[profile.release] strip = true`. Rode `cargo build --release` e `cargo bloat --release --crates`; registre o delta. Se > 5 MB, retorne erro.

---

### T-02 — Criar esqueleto do módulo `src/tui/` com submódulos

**Objetivo:** estrutura de arquivos do layout da Tech Spec + `mod tui;` em `main.rs`.

**Arquivos:** `src/main.rs` (`mod tui;`), `src/tui/{mod,app,stage,orchestration,event,ui,markdown,runner,loader,editor,persist}.rs`. **Origem:** Tech Spec §Estrutura. **Tipo:** Sequencial — depende de T-01.

**Prompt de execução:** Crie `src/tui/` com os 11 arquivos, cada um com comentário de escopo. Adicione `mod tui;` em `main.rs` após os demais `mod`. `cargo check` sem erros. Sem implementação funcional.

---

### T-03 — Adicionar `Command::Tui(TuiArgs)` no enum e braço em `run()`

**Objetivo:** registrar `sdd tui` no dispatch sem alterar braços existentes.

**Arquivos:** `src/main.rs` (enum `Command` :124, `run()` :444), `src/tui/mod.rs`. **Origem:** RF-01, RNF-05. **Tipo:** Sequencial — depende de T-02.

**Prompt de execução:** Defina `pub struct TuiArgs { pub root: Option<PathBuf> }` e `pub fn run(_a: TuiArgs) -> anyhow::Result<()> { Ok(()) }`. Adicione `Tui(crate::tui::TuiArgs)` ao enum (`#[command(name="tui")]`) e o braço em `run()`. Não toque nos demais braços. `cargo test` verde.

---

### T-04 — Detecção de TTY e degradação

**Objetivo:** guarda de TTY em `run()` antes de qualquer render; sem TTY ou `TERM=dumb` → stderr + exit 1.

**Arquivos:** `src/tui/mod.rs`. **Origem:** RF-11, CA-RF11, RNF-03. **Tipo:** Sequencial — depende de T-03.

**Prompt de execução:** Detecte TTY com `crossterm::tty::IsTty` + `TERM=dumb`. Em falha: stderr "sdd tui requer terminal interativo. Use sdd idea, sdd prd, ..." e `bail!`. Detecção injetável (trait/flag) para teste sem terminal.

---

### T-05 — Setup/teardown do terminal com guard RAII

**Objetivo:** raw mode + alternate screen com `Drop` que garante teardown em panic.

**Arquivos:** `src/tui/mod.rs`. **Origem:** RT-01. **Tipo:** Sequencial — depende de T-04.

**Prompt de execução:** `struct TerminalGuard` com `new()` (enable raw + EnterAlternateScreen) e `Drop` (disable + LeaveAlternateScreen). Panic hook via `set_hook` restaura antes de imprimir. Instancie em `run()` após o TTY-check. Teste: `Drop` não entra em panic.

---

### T-06 — Structs `App`/`Screen`/`Stage` e event loop básico

**Objetivo:** modelo de estado completo + loop `poll`/`update`/`render`.

**Arquivos:** `src/tui/{app,event,mod,ui}.rs`. **Origem:** RF-10, Tech Spec §Componentes/§Dados. **Tipo:** Sequencial — depende de T-05.

**Prompt de execução:** Defina structs/enums da Tech Spec §Dados em `app.rs`. Mapeie `KeyEvent→Action` em `event.rs` (Quit, Confirm, Back, Up, Down, Approve, Regenerate, Edit, Help). Loop `poll(100ms)`→`update`→`render` em `mod.rs`; `q` e `Ctrl+C` setam `should_quit`. `sdd tui` abre e fecha sem panic.

---

### T-07 — `orchestration.rs`: scan de `docs/` e parse do traceability-map

**Objetivo:** ler orquestrações, parsear `traceability-map.yaml`, montar `Orchestration`/`StageState`.

**Arquivos:** `src/tui/orchestration.rs`, `src/tui/app.rs`. **Origem:** RF-02, RF-04, CA-RF02, RN-02, RN-04. **Tipo:** Paralela (Fase 2) — depende de T-06.

**Prompt de execução:** `pub fn scan_orchestrations(root: &Path) -> Vec<Orchestration>` lista dirs de `docs/`, lê YAML com `serde_yaml` (campos `artifacts.<stage>.{state,file,approved_at}`); ausência → `unknown`. Testes com `tempfile`: YAML completo, ausente, `state` desconhecido.

---

### T-08 — Tela OrchestrationList com atalhos base

**Objetivo:** lista com seleção (↑/↓/j/k) e ações (Enter, `n`, `q`).

**Arquivos:** `src/tui/ui.rs`, `src/tui/app.rs`. **Origem:** RF-02, RF-10, CA-RF02. **Tipo:** Sequencial — depende de T-07.

**Prompt de execução:** `render_orchestration_list` com `List`+`ListState` (nome, estado, etapa). Reducer: Up/Down move `selected`, Confirm→StageBoard, Quit. Snapshot test `TestBackend` com 3 orquestrações.

---

### T-09 — NewOrchestration: input de texto e `sdd init`

**Objetivo:** criar orquestração via campo de texto + subprocesso `sdd init`.

**Arquivos:** `src/tui/{app,ui,runner}.rs`. **Origem:** RF-03, RN-03, §Segurança. **Tipo:** Sequencial — depende de T-08.

**Prompt de execução:** `Action::Char/Backspace`; reducer de `NewOrchestration`. `run_init(root, idea)` via `current_exe()`+args vetorizados (nunca `sh -c`). Erro→ErrorPanel. Teste de args corretos.

---

### T-10 — `stage.rs`: máquina de estados e navegação/bloqueio

**Objetivo:** regras de navegação; bloqueio de etapas futuras sem aprovação das obrigatórias.

**Arquivos:** `src/tui/stage.rs`, `src/tui/app.rs`. **Origem:** RF-04, CA-RF08, RN-04, RN-08. **Tipo:** Paralela (Fase 2) — depende de T-06.

**Prompt de execução:** `can_navigate(stages, target) -> Result<(),String>`. Obrigatórias: Idea, Prd, Techspec, Tasks, Execution, Review, Memory; Refinement opcional; reversa sempre livre. Testes: Techspec com Prd pending→erro "Aprovação do PRD obrigatória"; Execution com Refinement skipped→ok; Idea aprovada→ok.

---

### T-11 — StageBoard: painel de progresso

**Objetivo:** painel das 9 etapas com ícones de estado + navegação, integrando T-10.

**Arquivos:** `src/tui/ui.rs`, `src/tui/app.rs`. **Origem:** RF-04, CA-RF08, RF-10. **Tipo:** Sequencial — depende de T-10.

**Prompt de execução:** `render_stage_board` com `List` e ícones (○ pending, ● in_progress, ✓ approved, ⊘ skipped, ? unknown); highlight da corrente; `approved_at` nas aprovadas. Enter em etapa bloqueada → mensagem inline no rodapé. Snapshot test.

---

### T-12 — `loader.rs`: spinner com threshold 200ms

**Objetivo:** loader braille; operações <200ms não renderizam spinner.

**Arquivos:** `src/tui/loader.rs`. **Origem:** RF-05, CA-RF05, RNF-01. **Tipo:** Paralela (Fase 2) — depende de T-06.

**Prompt de execução:** `Loader { armed_at, frame, label }` com `arm/disarm/tick/is_visible/current_frame` (braille `⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏`). Testes: <200ms→invisível; `armed_at = now-250ms`→visível (sem `sleep`).

---

### T-13 — `runner.rs`: execução de etapa em thread + canal mpsc

**Objetivo:** subcomandos `sdd <stage>` em thread com `mpsc`, loop continua animando spinner.

**Arquivos:** `src/tui/runner.rs`, `src/tui/app.rs` (`StageResult`). **Origem:** RF-06, RN-06, RT-02, §Execução/§Segurança. **Tipo:** Sequencial — depende de T-12 e T-11.

**Prompt de execução:** `spawn_stage(stage, name, root, input) -> Receiver<StageResult>` via `thread::spawn`+`channel`. Mapa `Stage→subcomando` espelha `STAGE_FILES` (main.rs:70). `current_exe()`, args `[sub, "--name", name, "--root", root]`+input; `stdin: null`. Loop usa `try_recv`. Teste: args vetorizados, sem `sh -c`.

---

### T-14 — `markdown.rs`: parser do subconjunto → `ratatui::text::Text`

**Objetivo:** converter o subset Markdown dos artefatos sem crate externa.

**Arquivos:** `src/tui/markdown.rs`. **Origem:** RF-07, RT-08, §Performance. **Tipo:** Paralela (Fase 2) — depende de T-06.

**Prompt de execução:** `parse(&str) -> Text<'static>` linha-a-linha: `#` bold/cabeçalho; `-`/`*` listas `• `; ` ``` ` code; `**bold**`; `|col|` tabela; resto texto plano (sem panic). Testes com fixtures (prd/techspec): contagem de `Line` e presença de `Modifier::BOLD`.

---

### T-15 — Viewer com scroll

**Objetivo:** tela de visualização com scroll, integrando T-14; converte conteúdo uma vez.

**Arquivos:** `src/tui/ui.rs`, `src/tui/app.rs`. **Origem:** RF-07, RNF-02. **Tipo:** Sequencial — depende de T-14 e T-13.

**Prompt de execução:** `render_viewer` com `Paragraph::scroll((scroll,0))` em `Block`. Ao entrar no Viewer, `markdown::parse` uma vez e guarda o `Text`. Up/Down scroll; `a`→Checkpoint; `Esc`→StageBoard. Snapshot tests em 40/80/120 cols.

---

### T-16 — `editor.rs`: ciclo suspender/restaurar `$EDITOR`

**Objetivo:** suspender terminal, abrir `$EDITOR` com artefato, restaurar ao fechar.

**Arquivos:** `src/tui/editor.rs`. **Origem:** RF-08, R-07, §Suspender/§Segurança. **Tipo:** Paralela (Fase 2) — depende de T-05.

**Prompt de execução:** `open_editor(path)`: disable raw + LeaveAlternateScreen → `Command::new($EDITOR|vi).arg(path).status()` → EnterAlternateScreen + enable raw + redraw. Path como arg separado (sem `sh -c`). Exit não-zero→erro. Teste: path nunca embutido em shell string.

---

### T-17 — `write_atomic` + refatoração de `save_artifact`/`write_stage_content`

**Objetivo:** `write_atomic` (write-then-rename) e migrar `fs::write` não-atômico do harness.

**Arquivos:** `src/tui/persist.rs`, `src/main.rs` (:1182, :1996). **Origem:** RNF-06, RT-06, CA-RF09, RNF-05, §Segurança. **Tipo:** Sequencial — depende de T-02; antes de T-18. **⚠ Impacta o harness — exige testes de não-regressão explícitos.**

**Prompt de execução:** `write_atomic(path, content)` escreve em `.tmp` no mesmo dir + `fs::rename`. Substitua `fs::write` em `save_artifact` (~1182) e `write_stage_content` (~1996). Mantenha assinaturas/comportamento externo. `cargo test` completo. Testes: escrita normal; `.tmp` órfão não corrompe alvo; dir inexistente→erro.

---

### T-18 — Checkpoint: Aprovar / Regenerar / Editar via `sdd artifact save`

**Objetivo:** fluxo de checkpoint com persistência via subprocesso (sem reimplementar YAML).

**Arquivos:** `src/tui/{app,persist,ui}.rs`. **Origem:** RF-08, RF-09, CA-RF08/09, RN-07/08/09/11. **Tipo:** Sequencial — depende de T-17 e T-16.

**Prompt de execução:** `approve_via_artifact_save(exe, name, stage, file, root)` via `Command` com args vetorizados (`artifact save --name --stage --file --state approved --force`). Reducer `Checkpoint`: `a`→approve, `r`→Running (sem sobrescrever), `e`→`open_editor`+reapresenta. UI com `[a]provar [r]egerar [e]ditar`. Teste de args exatos.

---

### T-19 — Refinement condicional: prompt skip/run e estado skipped

**Objetivo:** perguntar executar/pular Refinement; registrar `skipped`.

**Arquivos:** `src/tui/{app,ui,stage}.rs`. **Origem:** RF-14, RN-08, §Fluxo. **Tipo:** Sequencial — depende de T-18 e T-11.

**Prompt de execução:** `Screen::RefinementPrompt`; StageBoard ao selecionar Refinement vai para o prompt: `r`→Running{Refinement}, `s`→`approve_via_artifact_save(state="skipped")`→StageBoard relendo. UI do painel. Teste: `can_navigate` aceita Skipped como cumprida.

---

### T-20 — Painel de erro e recuperação

**Objetivo:** exibir stderr em exit não-zero com "Tentar novamente"/"Editar configuração".

**Arquivos:** `src/tui/{app,ui}.rs`. **Origem:** RF-13, CA-RF13, RN-11. **Tipo:** Sequencial — depende de T-13 e T-16.

**Prompt de execução:** `StageResult.exit_code != 0` → `Screen::ErrorPanel{stage,stderr}`. Reducer: `r`→Running, `e`→`open_editor("sdd.config.yaml")`. `render_error_panel` (stderr máx 20 linhas, wrap, ações no rodapé). Nunca dispara escrita (RN-11). Snapshot + teste de não-escrita.

---

### T-21 — Tela de ajuda contextual `?`

**Objetivo:** ajuda com atalhos do contexto atual, via `?`.

**Arquivos:** `src/tui/{app,ui,event}.rs`. **Origem:** RF-12, RF-10. **Tipo:** Paralela — depende de T-11.

**Prompt de execução:** `Screen::Help{return_to: Box<Screen>}`; `?` em qualquer tela→Help; `Esc`/`q`→`*return_to`. `render_help` com tabela contextual (`Screen→Vec<(atalho,desc)>`). Snapshot test a partir de StageBoard.

---

### T-22 — Tela de resumo final pós-Memory

**Objetivo:** resumo com nome, slug, caminhos e timestamps após Memory.

**Arquivos:** `src/tui/{app,ui}.rs`. **Origem:** RF-15. **Tipo:** Paralela — depende de T-18.

**Prompt de execução:** Após Memory aprovada → `Screen::Summary`. `render_summary` com `Table` dos `stages` (arquivo, estado, approved_at). `q`→should_quit. Snapshot test.

---

### T-23 — Telemetria: `log_jsonl` em `.sdd/tui-events.jsonl`

**Objetivo:** emitir eventos locais reusando `log_jsonl` (main.rs:3937).

**Arquivos:** `src/tui/{app,mod}.rs`. **Origem:** §Observabilidade, RT-01. **Tipo:** Paralela — depende de T-18.

**Prompt de execução:** Torne `log_jsonl` `pub(crate)`. Emita `tui_open`/`tui_close` (mod.rs) e `orchestration_selected`/`stage_started`/`stage_finished`/`checkpoint_decision`/`tui_error` nos reducers. Aplique `runtime::redaction` ao stderr antes de logar. Teste: `tui_error` não loga stderr bruto com segredo.

---

### T-24 — Testes unitários, render e não-regressão

**Objetivo:** consolidar cobertura (unit, TestBackend, inferência do gate, não-regressão).

**Arquivos:** `src/tui/*.rs` (tests), `src/main.rs` (tests). **Origem:** CA-RF02/05/08/09/11, CA-RNF05, RT-03, §Testes. **Tipo:** Sequencial — depende de T-04, T-07, T-10, T-12, T-14, T-17.

**Prompt de execução:** Complete testes faltantes. Inferência: `04-tasks.md` sintético → `infer_artifact` retorna `"tasks"`. Não-regressão: invocar `sdd idea --help`/`sdd prd --help` e verificar stdout/exit. Degradação: `run` com `is_tty=false`→erro sem raw mode. Render 40/80/120 cols. `cargo test` zero falhas.

---

### T-25 — Validação manual de terminais e benchmark de inicialização

**Objetivo:** matriz iTerm2/Terminal.app/alacritty/kitty/tmux + `time sdd tui` < 1s. **Gate de release.**

**Arquivos:** nenhum (validação manual; registrar em `docs/<slug>/validation-matrix.md`). **Origem:** RNF-01/02/03, RT-01. **Tipo:** Sequencial — depende de T-24.

**Prompt de execução:** Por terminal: abrir, redimensionar, executar etapa + `$EDITOR`, `kill -9` durante etapa (terminal restaurado?). Medir `time sdd tui` (macOS+Linux). Registrar. Panic/corrupção → bloqueia merge.

---

## Dependências

| Task | Depende de |
|---|---|
| T-01 | — |
| T-02 | T-01 |
| T-03 | T-02 |
| T-04 | T-03 |
| T-05 | T-04 |
| T-06 | T-05 |
| T-07 | T-06 |
| T-08 | T-07 |
| T-09 | T-08 |
| T-10 | T-06 |
| T-11 | T-10 |
| T-12 | T-06 |
| T-13 | T-12, T-11 |
| T-14 | T-06 |
| T-15 | T-14, T-13 |
| T-16 | T-05 |
| T-17 | T-02 |
| T-18 | T-17, T-16 |
| T-19 | T-18, T-11 |
| T-20 | T-13, T-16 |
| T-21 | T-11 |
| T-22 | T-18 |
| T-23 | T-18 |
| T-24 | T-04, T-07, T-10, T-12, T-14, T-17 |
| T-25 | T-24 |

**Candidatas a Agent Team paralelo (Fase 2, após T-06):** T-07, T-10, T-12, T-14, T-16, T-17 — sem conflito de arquivo entre si.

---

## Critérios de aceite

Cenários Gherkin por task (reaproveitam CA-RF do PRD). Destaques:

### T-03 — Não-regressão
```gherkin
Cenário: sdd tui reconhecido
  Dado o binário com Command::Tui
  Quando executa "sdd tui --help"
  Então clap exibe a descrição sem erro
Cenário: Subcomandos existentes intactos
  Quando "sdd idea --help"/"sdd prd --help" são invocados
  Então stdout e exit code são idênticos ao baseline pré-TUI
```

### T-04 — Degradação sem TTY
```gherkin
Cenário: Terminal sem TTY
  Dado stdout redirecionado para arquivo/pipe
  Quando executa "sdd tui"
  Então não inicia, mensagem no stderr, exit 1, sem entrar em raw mode
```

### T-07 — Parse do traceability-map
```gherkin
Cenário: Orquestração sem traceability-map.yaml
  Dado um diretório em docs/ sem o arquivo
  Quando a tela é exibida
  Então a orquestração é listada com estado "unknown"
```

### T-10 — Navegação/bloqueio
```gherkin
Cenário: Bloquear avanço sem aprovar etapa obrigatória
  Dado PRD pending
  Quando tenta ir para Tech Spec
  Então bloqueia com "Aprovação do PRD obrigatória"
Cenário: Refinement skipped libera Execution
  Dado Refinement skipped
  Quando tenta ir para Execution
  Então a navegação é permitida
```

### T-12 — Loader threshold
```gherkin
Cenário: Operação rápida não pisca loader
  Dado uma operação de filesystem
  Quando conclui em < 200ms
  Então o spinner não é exibido
```

### T-13 — Runner sem shell
```gherkin
Cenário: Subcomando executado sem shell
  Quando spawn_stage é chamado
  Então usa current_exe() e args vetorizados, nunca sh -c
```

### T-17 — Escrita atômica + não-regressão
```gherkin
Cenário: Escrita atômica
  Dado que o usuário aprovou um artefato
  Quando o processo é interrompido durante a gravação
  Então o artefato anterior permanece intacto, sem arquivo corrompido
Cenário: Subcomandos intactos após refatoração
  Quando os subcomandos existentes são invocados
  Então stdout/stderr/exit são idênticos ao comportamento anterior
```

### T-18 — Checkpoint
```gherkin
Cenário: Aprovar PRD
  Quando pressiona "a"
  Então "sdd artifact save --state approved --force" é invocado
  E o traceability-map recebe state: approved e approved_at
  E a TUI avança
Cenário: Regenerar sem sobrescrever
  Quando pressiona "r"
  Então a etapa é re-executada e o arquivo não é sobrescrito até nova aprovação
```

### T-23 — Telemetria segura
```gherkin
Cenário: stderr não vaza segredos
  Dado stderr com padrão de segredo
  Quando tui_error é emitido
  Então o campo no JSONL contém valor redactado
```

### T-25 — Validação manual
```gherkin
Cenário: Abertura rápida
  Quando "time sdd tui" em macOS
  Então primeira tela útil < 1 segundo
Cenário: Sem panic em terminais suportados
  Quando o fluxo completo roda (resize + $EDITOR) em cada terminal da matriz
  Então nenhum panic e o terminal é restaurado
```

---

## Ordem sugerida

```
FASE 1 — Fundação (sequencial)
  T-01 → T-02 → T-03 → T-04 → T-05 → T-06

FASE 2 — Componentes paralelos (após T-06; T-16/T-17 dependem de T-05/T-02)
  T-07 (orchestration) · T-10 (stage) · T-12 (loader) · T-14 (markdown) · T-16 (editor) · T-17 (write_atomic)

FASE 3 — UI sequencial
  T-07→T-08→T-09  |  T-10→T-11→T-21  |  T-12→T-13→T-20  |  T-14→T-15  |  T-17→T-18

  ▶ CHECKPOINT DE REFINEMENT RECOMENDADO AQUI (risco medium)
    revisar T-13 (runner), T-17 (write_atomic compartilhado), T-18 (checkpoint) antes de integrar

FASE 4 — Integração e telas finais (após T-18+T-20)
  T-18→T-19 (Refinement) · T-18→T-22 (Summary) · T-18→T-23 (Telemetria)

FASE 5 — Validação e release
  T-24 (testes consolidados) → T-25 (validação manual — gate de release)
```

---

## Rastreabilidade

| Campo | Valor |
|---|---|
| Orquestração | `criar-um-cli-poderoso-...-sdd-cli` |
| Origem (Tech Spec) | `03-techspec.md` — Plano de implementação (25 itens), §Arquitetura/§Dados/§Segurança/§Testes |
| Origem (PRD) | `02-prd.md` — RF-01..RF-15, RNF-01..RNF-08, CA-RF* |
| Risco | `00-risk-classification.md` — medium (external_dependency) → Refinement recomendado antes da Execução |
| Código ancorado | `src/main.rs` (:70, :124, :444, :985, :1061, :1140, :1182, :1742, :1969, :1996, :3937, :4034); `Cargo.toml`; `src/runtime/redaction.rs` |
| Próximo artefato | `05-refinement.md` (recomendado) ou `06-execution.md` |
