<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pipeline Spec-Driven · Da Ideia à Produção</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,300;0,6..72,400;0,6..72,500;0,6..72,600;1,6..72,400&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
/* ============================================================
PALETA — o canvas fica monocromático (tinta + papel) e as
cores entram só como SINAL: cada sistema tem a sua, o store
local tem cor própria, e os checkpoints humanos têm a cor de alerta.
============================================================ */
:root{
--ink:#0a0e16; /* canvas profundo */
--ink-2:#0f141f; /* superfície de card */
--ink-3:#151c2a; /* card elevado */
--line:rgba(255,255,255,.08);
--line-2:rgba(255,255,255,.16);
--paper:#eae6dc; /* corpo de texto, branco quente */
--paper-dim:#9aa4b6; /* secundário */
--paper-faint:#5e6678; /* terciário */
--entry:#b39ddb; /* Entrada / ideia (violeta) */
--confluence:#34d3b0; /* Confluence — documentos */
--jira:#fb7a8e; /* Jira — itens de trabalho */
--bitbucket:#5fa8f5; /* Bitbucket — código */
--local:#c6d76a; /* docs/<orquestracao> — fallback local */
--gate:#f5b740; /* Checkpoint humano — sinal */
--radius:10px;
--maxw:1180px;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
background:var(--ink);
color:var(--paper);
font-family:"Newsreader",Georgia,serif;
font-size:18px;
line-height:1.72;
font-weight:300;
-webkit-font-smoothing:antialiased;
overflow-x:hidden;
}
/* Grade de blueprint fixa atrás de tudo */
body::before{
content:"";
position:fixed;inset:0;
background-image:
linear-gradient(var(--line) 1px,transparent 1px),
linear-gradient(90deg,var(--line) 1px,transparent 1px);
background-size:42px 42px;
-webkit-mask-image:radial-gradient(ellipse 90% 70% at 50% 0%,#000 30%,transparent 90%);
mask-image:radial-gradient(ellipse 90% 70% at 50% 0%,#000 30%,transparent 90%);
opacity:.5;
pointer-events:none;
z-index:0;
}
.wrap{position:relative;z-index:1;max-width:var(--maxw);margin:0 auto;padding:0 28px}
/* ----- vocabulário tipográfico ----- */
.mono{font-family:"IBM Plex Mono",monospace;font-weight:500}
.tag{
font-family:"IBM Plex Mono",monospace;
font-size:11px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;
display:inline-flex;align-items:center;gap:7px;
}
.tag::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor;box-shadow:0 0 9px currentColor}
.c-entry{color:var(--entry)} .c-conf{color:var(--confluence)}
.c-jira{color:var(--jira)} .c-bit{color:var(--bitbucket)}
.c-local{color:var(--local)} .c-gate{color:var(--gate)}
h1,h2,h3{font-weight:400;line-height:1.12;letter-spacing:-.01em}
h2{font-size:clamp(28px,4.2vw,44px);margin-bottom:14px}
h3{font-size:22px}
.lede{font-size:clamp(19px,2.2vw,23px);color:var(--paper-dim);max-width:62ch;font-weight:300}
.eyebrow{
font-family:"IBM Plex Mono",monospace;font-size:12px;letter-spacing:.22em;
text-transform:uppercase;color:var(--paper-faint);margin-bottom:18px;display:block;
}
em{font-style:italic;color:var(--paper)}
strong{font-weight:500;color:#fff}
.em-conf{font-style:normal;color:var(--confluence)}
.em-jira{font-style:normal;color:var(--jira)}
.em-bit{font-style:normal;color:var(--bitbucket)}
.em-gate{font-style:normal;color:var(--gate)}
code{font-family:"IBM Plex Mono",monospace;font-size:.82em;background:var(--ink-3);
border:1px solid var(--line);border-radius:5px;padding:2px 6px;color:#cdd6e6}
section{padding:84px 0;border-top:1px solid var(--line)}
.sec-head{margin-bottom:46px;max-width:70ch}
/* ============================================================
HERO — sequência de "boot" com revelações escalonadas
============================================================ */
.hero{padding:120px 0 96px;border-top:none}
.hero .status{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:34px}
.pill{
font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.1em;
border:1px solid var(--line-2);border-radius:30px;padding:6px 13px;color:var(--paper-dim);
display:inline-flex;align-items:center;gap:8px;
}
.blink{width:7px;height:7px;border-radius:50%;background:var(--confluence);
box-shadow:0 0 8px var(--confluence);animation:blink 1.8s ease-in-out infinite}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.25}}
.hero h1{font-size:clamp(40px,7vw,82px);letter-spacing:-.025em;margin:6px 0 26px;max-width:16ch}
.hero h1 .glow{color:var(--gate)}
.hero .lede{font-size:clamp(20px,2.6vw,27px);max-width:60ch}
.hero .scroll-hint{margin-top:60px;font-family:"IBM Plex Mono",monospace;font-size:12px;
letter-spacing:.18em;color:var(--paper-faint);display:flex;align-items:center;gap:12px}
.hero .scroll-hint .bar{height:1px;width:60px;background:var(--line-2)}
/* revelação escalonada no load */
.reveal{opacity:0;transform:translateY(22px);animation:rise .9s cubic-bezier(.2,.7,.2,1) forwards}
@keyframes rise{to{opacity:1;transform:none}}
.d1{animation-delay:.05s}.d2{animation-delay:.18s}.d3{animation-delay:.32s}
.d4{animation-delay:.46s}.d5{animation-delay:.6s}.d6{animation-delay:.74s}
/* ============================================================
CALLOUT — a grande ideia
============================================================ */
.idea-card{
background:linear-gradient(180deg,var(--ink-3),var(--ink-2));
border:1px solid var(--line-2);border-radius:16px;padding:46px 48px;position:relative;overflow:hidden;
}
.idea-card::after{content:"";position:absolute;top:0;left:0;width:4px;height:100%;background:var(--gate)}
.idea-card .big{font-size:clamp(24px,3.4vw,34px);line-height:1.32;font-weight:400;max-width:30ch}
.idea-card p{color:var(--paper-dim);margin-top:22px;max-width:70ch}
/* ============================================================
PIPELINE INTERATIVO — o coração da página
============================================================ */
.rail{display:grid;grid-template-columns:repeat(8,1fr);gap:10px;margin-bottom:14px}
@media(max-width:900px){.rail{grid-template-columns:repeat(2,1fr)}}
@media(max-width:480px){.rail{grid-template-columns:1fr}}
.stage{
background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius);
padding:18px 15px 16px;cursor:pointer;position:relative;text-align:left;
transition:transform .25s cubic-bezier(.2,.7,.2,1),border-color .25s,background .25s;
display:flex;flex-direction:column;gap:10px;min-height:148px;
}
.stage:hover{transform:translateY(-5px);border-color:var(--line-2);background:var(--ink-3)}
.stage:focus-visible{outline:2px solid var(--gate);outline-offset:2px}
.stage.active{border-color:var(--accent);background:var(--ink-3)}
.stage.active::before{content:"";position:absolute;left:0;top:14px;bottom:14px;width:3px;
border-radius:3px;background:var(--accent)}
.stage .num{font-family:"IBM Plex Mono",monospace;font-size:12px;color:var(--paper-faint);letter-spacing:.1em}
.stage .nm{font-size:18px;font-weight:400;line-height:1.15;color:var(--paper)}
.stage .sys{display:flex;flex-wrap:wrap;gap:5px;margin-top:auto}
.chip{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;
border:1px solid currentColor;border-radius:4px;padding:2px 5px;opacity:.85}
.gate-flag{position:absolute;top:-9px;right:10px;font-family:"IBM Plex Mono",monospace;font-size:9px;
letter-spacing:.08em;background:var(--gate);color:#2a1d00;border-radius:4px;padding:2px 6px;font-weight:600;
box-shadow:0 0 14px rgba(245,183,64,.4)}
/* trilho de progresso sob os cards */
.progress{height:2px;background:var(--line);border-radius:2px;margin:0 2px 30px;position:relative}
.progress .fill{position:absolute;left:0;top:0;height:100%;border-radius:2px;background:var(--accent,var(--paper-faint));
transition:width .4s ease,background .4s;width:14%}
/* dossiê do estágio selecionado */
.dossier{
background:var(--ink-2);border:1px solid var(--line-2);border-radius:16px;
padding:38px 42px;display:grid;grid-template-columns:1fr 300px;gap:42px;min-height:230px;
}
@media(max-width:820px){.dossier{grid-template-columns:1fr;padding:30px 26px;gap:26px}}
.dossier .d-num{font-family:"IBM Plex Mono",monospace;font-size:13px;letter-spacing:.16em;
color:var(--accent);margin-bottom:10px}
.dossier h3{font-size:30px;margin-bottom:16px}
.dossier .d-body{font-size:18px;color:var(--paper);max-width:60ch}
.dossier .d-body .hl{color:var(--accent);font-style:normal}
.meta{border-left:1px solid var(--line);padding-left:26px;display:flex;flex-direction:column;gap:20px}
@media(max-width:820px){.meta{border-left:none;border-top:1px solid var(--line);padding-left:0;padding-top:24px}}
.meta .row .k{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.16em;
text-transform:uppercase;color:var(--paper-faint);display:block;margin-bottom:5px}
.meta .row .v{font-size:16px;color:var(--paper);line-height:1.4}
.meta .v.accent{color:var(--accent)}
/* ============================================================
MAPEAMENTO POR SISTEMA — onde cada artefato "mora"
============================================================ */
.principle{background:var(--ink-3);border:1px solid var(--line);border-left:3px solid var(--gate);
border-radius:0 var(--radius) var(--radius) 0;padding:22px 26px;margin-bottom:40px;max-width:78ch}
.principle .mono{color:var(--gate);font-size:12px;letter-spacing:.12em;text-transform:uppercase;display:block;margin-bottom:8px}
.sys-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
@media(max-width:980px){.sys-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){.sys-grid{grid-template-columns:1fr}}
.sys-col{background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius);
padding:28px 26px;border-top:3px solid var(--accent)}
.sys-col h3{display:flex;align-items:center;gap:11px;font-size:21px;margin-bottom:6px}
.sys-col .role{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.1em;
text-transform:uppercase;color:var(--accent);margin-bottom:16px;display:block}
.sys-col p{font-size:16px;color:var(--paper-dim);line-height:1.6}
.sys-col ul{list-style:none;margin-top:16px;display:flex;flex-direction:column;gap:9px}
.sys-col li{font-size:15px;color:var(--paper);padding-left:18px;position:relative;line-height:1.45}
.sys-col li::before{content:"›";position:absolute;left:0;color:var(--accent);font-family:"IBM Plex Mono",monospace}
/* ============================================================
ARQUITETURA — 6 componentes expansíveis
============================================================ */
.comp-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
@media(max-width:780px){.comp-grid{grid-template-columns:1fr}}
.comp{background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius);
overflow:hidden;transition:border-color .25s}
.comp:hover{border-color:var(--line-2)}
.comp.open{border-color:var(--line-2)}
.comp-head{padding:24px 26px;cursor:pointer;display:flex;align-items:flex-start;gap:18px}
.comp-head:focus-visible{outline:2px solid var(--gate);outline-offset:-2px}
.comp-idx{font-family:"IBM Plex Mono",monospace;font-size:13px;color:var(--paper-faint);
border:1px solid var(--line-2);border-radius:7px;width:34px;height:34px;flex:0 0 34px;
display:flex;align-items:center;justify-content:center}
.comp-head .t{flex:1}
.comp-head h3{font-size:20px;margin-bottom:3px}
.comp-head .sub{font-style:italic;color:var(--paper-dim);font-size:15.5px}
.comp-toggle{font-family:"IBM Plex Mono",monospace;font-size:20px;color:var(--paper-faint);
transition:transform .3s;line-height:1;margin-top:4px}
.comp.open .comp-toggle{transform:rotate(45deg);color:var(--gate)}
.comp-body{max-height:0;overflow:hidden;transition:max-height .42s cubic-bezier(.2,.7,.2,1)}
.comp-body .inner{padding:0 26px 26px;color:var(--paper-dim);font-size:16.5px}
.comp-body .inner p{margin-bottom:0}
.comp-body .inner .why{margin-top:14px;background:var(--ink-3);border-radius:8px;padding:14px 16px;
border-left:2px solid var(--accent);font-size:15px;color:var(--paper)}
.comp-body .inner .why b{color:var(--accent);font-weight:500}
/* ============================================================
AGENT TEAMS / AUTOMATIONS — plano de controle
============================================================ */
.control-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:8px}
@media(max-width:900px){.control-grid{grid-template-columns:1fr}}
.control-card{
background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius);
padding:26px 24px;position:relative;overflow:hidden;border-top:3px solid var(--accent);
}
.control-card .cc-label{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.14em;
text-transform:uppercase;color:var(--accent);display:block;margin-bottom:12px}
.control-card h3{font-size:21px;margin-bottom:10px}
.control-card p{font-size:16px;color:var(--paper-dim);line-height:1.58}
.control-card ul{list-style:none;margin-top:16px;display:flex;flex-direction:column;gap:8px}
.control-card li{font-size:14.5px;color:var(--paper);line-height:1.45;padding-left:18px;position:relative}
.control-card li::before{content:"›";position:absolute;left:0;color:var(--accent);font-family:"IBM Plex Mono",monospace}
.decision-band{
margin-top:22px;background:var(--ink-3);border:1px solid var(--line-2);border-left:3px solid var(--gate);
border-radius:0 var(--radius) var(--radius) 0;padding:24px 26px;display:grid;grid-template-columns:180px 1fr;gap:24px;
}
@media(max-width:760px){.decision-band{grid-template-columns:1fr;gap:12px}}
.decision-band .db-k{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.14em;
text-transform:uppercase;color:var(--gate)}
.decision-band p{color:var(--paper);font-size:16.5px;line-height:1.6}
.lane{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}
.lane span{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.08em;text-transform:uppercase;
border:1px solid var(--line-2);border-radius:4px;padding:4px 7px;color:var(--paper-dim)}
/* ============================================================
CHECKPOINT — fluxo do portão humano
============================================================ */
.flow{display:grid;grid-template-columns:repeat(6,1fr);gap:0;margin-top:8px}
@media(max-width:900px){.flow{grid-template-columns:1fr;gap:14px}}
.step{position:relative;padding:24px 18px 24px 0}
@media(max-width:900px){.step{padding:0 0 0 40px}}
.step .s-num{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--gate);
border:1px solid var(--gate);border-radius:50%;width:30px;height:30px;display:flex;
align-items:center;justify-content:center;margin-bottom:14px;background:var(--ink)}
@media(max-width:900px){.step .s-num{position:absolute;left:0;top:0}}
.step::after{content:"";position:absolute;top:14px;left:30px;right:0;height:1px;
background:linear-gradient(90deg,var(--gate),var(--line));opacity:.5}
.step:last-child::after{display:none}
@media(max-width:900px){.step::after{top:30px;left:14px;bottom:-14px;right:auto;width:1px;height:auto}}
.step .s-t{font-family:"IBM Plex Mono",monospace;font-size:13px;color:var(--paper);font-weight:500;margin-bottom:6px}
.step .s-d{font-size:14.5px;color:var(--paper-dim);line-height:1.5}
/* ============================================================
BUILD vs BUY
============================================================ */
.bb-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:8px}
@media(max-width:760px){.bb-grid{grid-template-columns:1fr}}
.bb{border-radius:var(--radius);padding:30px 30px;border:1px solid var(--line)}
.bb.buy{background:var(--ink-2)}
.bb.build{background:linear-gradient(180deg,var(--ink-3),var(--ink-2));border-color:var(--line-2)}
.bb h3{font-size:19px;margin-bottom:16px;display:flex;align-items:center;gap:10px}
.bb h3 .mono{font-size:11px;letter-spacing:.12em}
.bb.buy h3 .mono{color:var(--confluence)} .bb.build h3 .mono{color:var(--gate)}
.bb ul{list-style:none;display:flex;flex-direction:column;gap:13px}
.bb li{font-size:16px;color:var(--paper);padding-left:24px;position:relative;line-height:1.5}
.bb.buy li::before{content:"✓";position:absolute;left:0;color:var(--confluence);font-family:"IBM Plex Mono",monospace}
.bb.build li::before{content:"›";position:absolute;left:0;color:var(--gate);font-family:"IBM Plex Mono",monospace;font-weight:600}
.bb li small{display:block;color:var(--paper-dim);font-size:13.5px;margin-top:2px}
/* ============================================================
ROADMAP — timeline em fases
============================================================ */
.timeline{position:relative;padding-left:40px}
.timeline::before{content:"";position:absolute;left:14px;top:8px;bottom:8px;width:2px;
background:linear-gradient(180deg,var(--entry),var(--confluence),var(--jira),var(--bitbucket),var(--gate))}
.phase{position:relative;padding:0 0 38px}
.phase:last-child{padding-bottom:0}
.phase .dot{position:absolute;left:-33px;top:3px;width:16px;height:16px;border-radius:50%;
background:var(--ink);border:3px solid var(--accent);box-shadow:0 0 12px -2px var(--accent)}
.phase .ph-tag{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.16em;
text-transform:uppercase;color:var(--accent);margin-bottom:5px;display:block}
.phase h3{font-size:21px;margin-bottom:8px}
.phase p{font-size:16.5px;color:var(--paper-dim);max-width:74ch;line-height:1.6}
.phase .risk{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.08em;
border:1px solid var(--line-2);border-radius:5px;padding:3px 9px;color:var(--paper-faint);
display:inline-block;margin-top:12px}
/* ============================================================
FECHAMENTO
============================================================ */
.closing{text-align:center;padding:110px 0}
.closing .eyebrow{margin:0 auto 22px}
.closing .contract{font-size:clamp(30px,5.6vw,60px);font-weight:300;line-height:1.18;
letter-spacing:-.02em;max-width:18ch;margin:0 auto}
.closing .contract .a{color:var(--gate)}.closing .contract .b{color:var(--confluence)}
.closing p{color:var(--paper-dim);max-width:58ch;margin:28px auto 0;font-size:18px}
footer{border-top:1px solid var(--line);padding:40px 0;text-align:center}
footer .mono{font-size:12px;letter-spacing:.14em;color:var(--paper-faint);text-transform:uppercase}
/* ============================================================
BDD DENTRO DO SDD — camadas da spec, notações e a espinha
============================================================ */
/* pilha de camadas da spec */
.spec-stack{position:relative;border:1px dashed var(--line-2);border-radius:14px;
padding:42px 22px 22px;display:flex;flex-direction:column;gap:11px;max-width:720px}
.spec-stack .ss-cap{position:absolute;top:15px;left:24px;font-family:"IBM Plex Mono",monospace;
font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-faint)}
.spec-layer{background:var(--ink-2);border:1px solid var(--line);border-radius:9px;padding:16px 22px}
.spec-layer .sl-t{font-size:17px;color:var(--paper);line-height:1.2}
.spec-layer .sl-s{font-family:"IBM Plex Mono",monospace;font-size:12px;color:var(--paper-dim);
margin-top:5px;letter-spacing:.02em}
.spec-layer.bdd{border-color:var(--confluence);background:var(--ink-3);position:relative;padding:20px 22px;
box-shadow:0 0 0 1px var(--confluence) inset,0 0 28px -10px var(--confluence)}
.spec-layer.bdd .sl-t{color:#fff}
.spec-layer.bdd .sl-s{color:var(--confluence)}
.spec-layer.bdd .sl-flag{position:absolute;top:-9px;right:18px;font-family:"IBM Plex Mono",monospace;
font-size:9px;letter-spacing:.1em;text-transform:uppercase;background:var(--confluence);color:#04342c;
padding:2px 8px;border-radius:4px;font-weight:600}
.spec-layer.out{border-color:rgba(95,168,245,.4)}
.spec-layer.out .sl-s{color:var(--bitbucket)}
/* notações: Gherkin × EARS */
.notations{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-top:30px}
@media(max-width:760px){.notations{grid-template-columns:1fr}}
.note-card{background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.note-card .nc-head{padding:18px 22px 12px;display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.note-card .nc-head .lbl{font-family:"IBM Plex Mono",monospace;font-size:13px;font-weight:600;letter-spacing:.05em}
.note-card .nc-head .role{font-style:italic;color:var(--paper-dim);font-size:14px}
.note-card.gherkin .lbl{color:var(--confluence)}
.note-card.ears .lbl{color:var(--gate)}
.code-panel{font-family:"IBM Plex Mono",monospace;font-size:12.5px;line-height:1.8;margin:0;
padding:8px 22px 20px;color:#cdd6e6;white-space:pre-wrap;border-top:1px solid var(--line)}
.code-panel .cmt{color:var(--paper-faint)}
.code-panel .g-kw{color:var(--confluence);font-weight:500}
.code-panel .e-kw{color:var(--gate);font-weight:600}
.notations-tie{text-align:center;font-family:"IBM Plex Mono",monospace;font-size:11px;
letter-spacing:.1em;color:var(--paper-faint);margin-top:16px}
/* a espinha de comportamento atravessando o pipeline */
.spine-track{display:flex;align-items:center;margin:16px 0 26px;flex-wrap:wrap;gap:4px 0}
.sp-pill{font-family:"IBM Plex Mono",monospace;font-size:12px;border:1px solid var(--line-2);
border-radius:20px;padding:6px 13px;color:var(--paper-faint);background:var(--ink-2)}
.sp-pill.on{color:var(--paper);border-color:var(--confluence)}
.sp-pill.gate{color:#2a1d00;background:var(--gate);border-color:var(--gate);font-weight:600;
box-shadow:0 0 16px -4px var(--gate)}
.sp-link{height:1px;flex:1;min-width:12px;background:var(--line-2)}
.sp-cards{display:grid;grid-template-columns:repeat(6,1fr);gap:12px}
@media(max-width:860px){.sp-cards{grid-template-columns:repeat(2,1fr)}}
@media(max-width:480px){.sp-cards{grid-template-columns:1fr}}
.sp-card{background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius);padding:18px 16px}
.sp-card.payoff{border-color:var(--gate);background:var(--ink-3)}
.sp-card .sp-stage{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.12em;
color:var(--paper-faint);display:block;margin-bottom:9px}
.sp-card.payoff .sp-stage{color:var(--gate)}
.sp-card h4{font-size:16px;font-weight:400;color:var(--paper);margin-bottom:6px;line-height:1.2}
.sp-card p{font-size:14px;color:var(--paper-dim);line-height:1.5}
/* respeita quem prefere menos movimento */
@media(prefers-reduced-motion:reduce){
.reveal{animation:none;opacity:1;transform:none}
.blink{animation:none}
*{transition-duration:.01ms !important}
}
</style>
</head>
<body>
<!-- ====================== HERO ====================== -->
<header class="hero">
<div class="wrap">
<div class="status reveal d1">
<span class="pill"><span class="blink"></span>SISTEMA · ORQUESTRAÇÃO DE SDLC</span>
<span class="pill">JIRA</span>
<span class="pill">BITBUCKET</span>
<span class="pill">CONFLUENCE</span>
<span class="pill">PROJECT DISCOVERY</span>
<span class="pill">ARTIFACT STORE LOCAL</span>
<span class="pill">AGENT TEAMS</span>
<span class="pill">AUTOMATIONS</span>
</div>
<span class="eyebrow reveal d2">Spec-Driven Development · arquitetura de referência</span>
<h1 class="reveal d3">Da <span class="glow">ideia</span> à produção, orquestrada por agentes.</h1>
<p class="lede reveal d4">Um pre-flight de projeto e oito etapas que transformam uma frase em linguagem natural em código revisado em produção — com Refinamento quando a feature pede grooming, humanos assinando embaixo nos pontos que importam, e artefatos salvos em <code>docs/<orquestracao></code> quando as integrações ainda não estão completas.</p>
<div class="scroll-hint reveal d5"><span class="bar"></span> role para percorrer o fluxo</div>
</div>
</header>
<!-- ====================== A GRANDE IDEIA ====================== -->
<section>
<div class="wrap">
<div class="idea-card">
<p class="big">Isto não é "uma sequência de chamadas de IA". É uma <strong>máquina de estados durável</strong> — onde a unidade que percorre o pipeline é uma <em>feature</em>, e cada etapa a transforma de um artefato no próximo.</p>
<p>Por que essa distinção decide tudo? Porque você pediu <span class="em-gate">checkpoints em pontos críticos</span>. Quando o agente gera o PRD e espera a aprovação de um PM, esse PM pode levar três dias para responder. Um script comum estoura, perde o estado e obriga a refazer tudo. Uma máquina de estados durável <strong>persiste o estado da feature, pausa indefinidamente no portão e só retoma quando recebe o sinal de aprovação.</strong> É a diferença entre o que funciona na demo e o que sobrevive ao mundo real.</p>
</div>
</div>
</section>
<!-- ====================== PRE-FLIGHT ====================== -->
<section id="preflight">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">00 · Antes da primeira feature</span>
<h2>Adapte a pipeline ao projeto</h2>
<p class="lede">Para funcionar bem em qualquer repositório, a pipeline começa entendendo onde está: stack, comandos, CI, paths, sistemas, riscos e regras de quando aumentar o rigor.</p>
</div>
<div class="control-grid">
<div class="control-card" style="--accent:var(--confluence)">
<span class="cc-label">Config</span>
<h3>sdd.config.yaml</h3>
<p>Declara stack, sistemas, paths, comandos, adapters, artifact store e políticas de qualidade. É o contrato local que evita o agente inventar como o projeto funciona.</p>
<ul>
<li>Paths de código, testes, docs e migrations</li>
<li>Comandos de lint, typecheck, test e build</li>
<li>Fallback em docs/<orquestracao></li>
<li>Políticas de risco e checkpoints</li>
</ul>
</div>
<div class="control-card" style="--accent:var(--bitbucket)">
<span class="cc-label">Discovery</span>
<h3>Project Discovery</h3>
<p>Mapeia o codebase real antes da primeira feature brownfield: arquitetura, padrões, CI, comandos confiáveis e riscos recorrentes do projeto.</p>
<ul>
<li>Onboarding técnico do repositório</li>
<li>Memória inicial para próximos agentes</li>
<li>Regras locais de execução e review</li>
</ul>
</div>
<div class="control-card" style="--accent:var(--gate)">
<span class="cc-label">Risco</span>
<h3>Risk Classification</h3>
<p>Classifica cada feature antes da Ideia virar plano. O risco decide Refinement, Agent Teams, reviewers, deploy checkpoint e evidências mínimas.</p>
<ul>
<li>Low, medium, high ou critical</li>
<li>Security, data, migration, infra e performance</li>
<li>Gates proporcionais ao impacto</li>
</ul>
</div>
</div>
</div>
</section>
<!-- ====================== PIPELINE INTERATIVO ====================== -->
<section id="pipeline">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">01 · O fluxo</span>
<h2>As oito etapas</h2>
<p class="lede">Clique em qualquer etapa para abrir seu dossiê: o que ela faz, qual sistema é o dono do artefato, qual agente atua, qual arquivo local é salvo e se existe um portão humano. O Refinamento é opcional, mas aparece formalmente no trilho para não sumir do planejamento.</p>
</div>
<div class="rail" id="rail"><!-- cards injetados via JS --></div>
<div class="progress"><div class="fill" id="progress-fill"></div></div>
<div class="dossier" id="dossier"><!-- conteúdo injetado via JS --></div>
</div>
</section>
<!-- ====================== BDD DENTRO DO SDD ====================== -->
<section id="comportamento">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">02 · O contrato executável</span>
<h2>O BDD vive dentro do SDD</h2>
<p class="lede">BDD e SDD não competem. O SDD é o continente; o BDD é a <em>camada de comportamento</em> da spec — a parte que diz, de forma testável, o que conta como "certo". É ela que dá dentes ao Review.</p>
</div>
<!-- as camadas de uma spec -->
<h3 style="margin-bottom:18px">As camadas de uma spec</h3>
<div class="spec-stack">
<span class="ss-cap">A spec · o contrato</span>
<div class="spec-layer"><div class="sl-t">História de usuário</div><div class="sl-s">por quê — As a… I want…</div></div>
<div class="spec-layer bdd">
<span class="sl-flag">camada BDD</span>
<div class="sl-t">Comportamento + critérios de aceite</div>
<div class="sl-s">o quê, testável · executa como portão de validação</div>
</div>
<div class="spec-layer"><div class="sl-t">Arquitetura (TechSpec)</div><div class="sl-s">como — decisões e riscos</div></div>
<div class="spec-layer out"><div class="sl-t">Testes + código gerados</div><div class="sl-s">a saída, validável pela camada de cima</div></div>
</div>
<!-- Gherkin × EARS -->
<h3 style="margin:46px 0 6px">Duas notações, complementares</h3>
<p style="color:var(--paper-dim);max-width:74ch">O <strong>EARS</strong> afirma a regra de forma rigorosa; o <strong>Gherkin</strong> dá o exemplo concreto que a prova. A mesma exigência, por dois ângulos:</p>
<div class="notations">
<div class="note-card gherkin">
<div class="nc-head"><span class="lbl">GHERKIN</span><span class="role">o exemplo executável</span></div>
<pre class="code-panel"><span class="cmt"># roda no CI via Cucumber e família</span>
<span class="g-kw">Funcionalidade:</span> Bloqueio por tentativas
<span class="g-kw">Cenário:</span> Conta bloqueia após 3 erros
<span class="g-kw">Dado</span> um usuário com login válido
<span class="g-kw">Quando</span> ele erra a senha 3 vezes
<span class="g-kw">Então</span> a conta é bloqueada por 15 min
<span class="g-kw">E</span> um e-mail de alerta é enviado</pre>
</div>
<div class="note-card ears">
<div class="nc-head"><span class="lbl">EARS</span><span class="role">a regra rigorosa</span></div>
<pre class="code-panel"><span class="cmt"># requisito inequívoco na spec</span>
Quando o usuário erra a senha 3
vezes consecutivas, o sistema
<span class="e-kw">DEVE</span> bloquear a conta por 15 min
e <span class="e-kw">DEVE</span> enviar um e-mail de
alerta ao titular.</pre>
</div>
</div>
<p class="notations-tie">EARS diz a regra ⇄ Gherkin prova com o exemplo</p>
<!-- a espinha de comportamento no pipeline -->
<h3 style="margin:52px 0 4px">A espinha de comportamento, etapa por etapa</h3>
<p style="color:var(--paper-dim);max-width:74ch">O comportamento não fica numa etapa só — ele atravessa o pipeline inteiro, do nascimento da história até virar documentação viva.</p>
<div class="spine-track">
<span class="sp-pill">01</span><span class="sp-link"></span>
<span class="sp-pill on">02</span><span class="sp-link"></span>
<span class="sp-pill">03</span><span class="sp-link"></span>
<span class="sp-pill on">04</span><span class="sp-link"></span>
<span class="sp-pill on">05</span><span class="sp-link"></span>
<span class="sp-pill gate">06</span><span class="sp-link"></span>
<span class="sp-pill on">07</span><span class="sp-link"></span>
<span class="sp-pill on">08</span>
</div>
<div class="sp-cards">
<div class="sp-card"><span class="sp-stage">ETAPA 02</span><h4>Histórias nascem</h4><p>As histórias de usuário são o ponto de partida do comportamento.</p></div>
<div class="sp-card"><span class="sp-stage">ETAPA 04</span><h4>Critérios escritos</h4><p>Gherkin/EARS no campo de Critérios de Aceite da story no Jira — apps como Xray e Zephyr guardam isso nativamente.</p></div>
<div class="sp-card"><span class="sp-stage">ETAPA 05</span><h4>Pronto para engenharia</h4><p>O Refinement consolida subtasks, DoD, estimativas e flags sem duplicar a Tech Spec.</p></div>
<div class="sp-card payoff"><span class="sp-stage">ETAPA 06 · o ganho</span><h4>Portão executável</h4><p>O Bitbucket Pipelines roda os cenários. Verde = o comportamento bate com a spec.</p></div>
<div class="sp-card"><span class="sp-stage">ETAPA 07</span><h4>Review contra spec</h4><p>A revisão compara código, testes e evidências com os critérios aprovados antes do merge.</p></div>
<div class="sp-card"><span class="sp-stage">ETAPA 08</span><h4>Documentação viva</h4><p>Cenários executáveis e decisões aprovadas alimentam a memória comportamental.</p></div>
</div>
<!-- o porquê: o portão de validação -->
<div class="idea-card" style="margin-top:48px">
<p class="big">A IA gera código vulnerável em <strong>10% a 42%</strong> dos casos. O que pega isso de forma determinística não é mais IA revisando IA — são <strong>critérios de aceite executáveis</strong>.</p>
<p>Sem eles, o Review é uma revisão mole e infinita, sem critério objetivo de "pronto". Com Gherkin/EARS, ele ganha um portão binário de passa/não-passa ancorado em comportamento definido pelo negócio — e o checkpoint humano do merge passa a decidir com <em>evidência</em>, não com opinião.</p>
</div>
<!-- a disciplina dos Três Amigos -->
<div class="principle" style="margin-top:24px">
<span class="mono">A regra que torna isso seguro</span>
O comportamento precisa cruzar um <strong>checkpoint humano antes</strong> de o agente codar. Senão a mesma IA escreve o cenário, escreve o código e confere a própria prova — e o "verde" não significa nada. O antídoto vem do próprio BDD, dos <em>Três Amigos</em> (negócio, dev e QA): humanos aprovam o comportamento a montante, o agente implementa a jusante. Autoria do comportamento separada da autoria do código.
</div>
</div>
</section>
<!-- ====================== MAPEAMENTO POR SISTEMA ====================== -->
<section id="mapeamento">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">03 · Onde cada coisa mora</span>
<h2>Divida por artefato, não por etapa</h2>
<p class="lede">O instinto é dividir por etapa ("1 a 4 é Jira"). O jeito mais limpo é dividir por <em>tipo de artefato</em> e deixar cada um no sistema onde os humanos naturalmente colaboram com ele — mantendo um fallback local no repositório.</p>
</div>
<div class="principle">
<span class="mono">Regra de ouro</span>
Mantenha cada artefato no sistema onde os humanos colaboram com ele — e <strong>nunca duplique entre sistemas externos, apenas conecte com links</strong>. Se a integração ainda não existe, o arquivo em <code>docs/<orquestracao></code> é a fonte canônica.
</div>
<div class="sys-grid">
<div class="sys-col" style="--accent:var(--confluence)">
<h3><span class="tag c-conf"></span>Confluence</h3>
<span class="role">Conteúdo · documentos vivos</span>
<p>O lar do que é texto rico: PRD, TechSpec, decision records. Versionamento, comentários, diagramas — tudo o que humanos leem e discutem.</p>
<ul><li>O documento do PRD</li><li>A TechSpec e seus diagramas</li><li>A memória legível por humanos</li></ul>
</div>
<div class="sys-col" style="--accent:var(--jira)">
<h3><span class="tag c-jira"></span>Jira</h3>
<span class="role">Estado · itens de trabalho</span>
<p>O dono do <em>estado</em>: o épico que rastreia o PRD, as tasks decompostas, e o status que avança conforme o trabalho caminha.</p>
<ul><li>O épico (rastreia o PRD)</li><li>Uma issue por task</li><li>O status: To Do → In Review → Done</li></ul>
</div>
<div class="sys-col" style="--accent:var(--bitbucket)">
<h3><span class="tag c-bit"></span>Bitbucket</h3>
<span class="role">Código · execução e review</span>
<p>Onde o código vive e a entrega acontece: branches, pull requests e os portões de qualidade via Pipelines (CI).</p>
<ul><li>Branch e Pull Request</li><li>Code review e merge</li><li>CI / Pipelines como gate</li></ul>
</div>
<div class="sys-col" style="--accent:var(--local)">
<h3><span class="tag c-local"></span>docs/<orquestração></h3>
<span class="role">Fallback · artefatos locais</span>
<p>O mínimo obrigatório para qualquer projeto: uma pasta por orquestração com todos os artefatos aprovados/registrados e o mapa de rastreabilidade.</p>
<ul><li>00 a 08 por etapa</li><li>traceability-map.yaml</li><li>Fonte canônica quando não há Jira/Confluence</li></ul>
</div>
</div>
<p style="margin-top:34px;color:var(--paper-dim);max-width:74ch">
É por isso que o PRD e a TechSpec tocam <em>dois</em> sistemas cada um: o <span class="em-conf">documento</span> mora no Confluence, o <span class="em-jira">item que o rastreia</span> mora no Jira, ligados por um link. O <span style="color:var(--local)">store local</span> guarda a cópia mínima auditável quando essa cadeia ainda não está completa.
</p>
</div>
</section>
<!-- ====================== ARQUITETURA / 6 COMPONENTES ====================== -->
<section id="arquitetura">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">04 · A anatomia</span>
<h2>Seis componentes</h2>
<p class="lede">Pense numa linha de montagem: o produto avança de estação em estação sendo transformado, inspetores assinam embaixo, e algo controla a esteira e lembra onde cada peça está. Seu sistema tem seis peças análogas. Clique para abrir cada uma.</p>
</div>
<div class="comp-grid" id="comp-grid"><!-- injetado via JS --></div>
</div>
</section>
<!-- ====================== AGENT TEAMS / AUTOMATIONS ====================== -->
<section id="agentteams">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">05 · O plano de controle</span>
<h2>Subagents, Agent Teams e automações</h2>
<p class="lede">A pipeline não precisa escolher entre “um agente faz tudo” e “vários agentes brigam pelo mesmo arquivo”. O controle define quando delegar, quando paralelizar e quando pausar para um evento externo.</p>
</div>
<div class="control-grid">
<div class="control-card" style="--accent:var(--confluence)">
<span class="cc-label">Subagents</span>
<h3>O caminho padrão</h3>
<p>Cada etapa continua tendo um dono claro: PRD, TechSpec, Tasks, Refinement, Execution, Review e Memory. Subagents são o encaixe natural para papéis especializados com contexto e saída previsíveis.</p>
<ul>
<li>Um artefato principal por etapa</li>
<li>Prompts e skills específicos por papel</li>
<li>Menor risco de conflito entre agentes</li>
</ul>
</div>
<div class="control-card" style="--accent:var(--bitbucket)">
<span class="cc-label">Agent Teams</span>
<h3>Paralelo quando há separação real</h3>
<p>Use equipes quando a tarefa admite lanes independentes: arquitetura, segurança, contratos, testes, frontend, backend e performance. O agente principal sintetiza, não delega a decisão final.</p>
<ul>
<li>TechSpec com revisores especialistas</li>
<li>Execução por ownership de arquivos</li>
<li>Review paralelo antes do gate de merge</li>
</ul>
</div>
<div class="control-card" style="--accent:var(--gate)">
<span class="cc-label">Automations</span>
<h3>Eventos, hooks e tarefas agendadas</h3>
<p>Automação não é uma nona etapa. É o plano de fundo que acorda a pipeline, aplica guardrails locais, registra trilha de auditoria e retoma workflows quando Jira, Slack ou Bitbucket emitem sinais.</p>
<ul>
<li>Webhooks e Channels para eventos reais</li>
<li>Hooks para validação determinística local</li>
<li>Scheduled tasks só para varreduras temporárias</li>
</ul>
</div>
</div>
<div class="decision-band">
<span class="db-k">Regra de roteamento</span>
<p><strong>Subagent por padrão.</strong> Agent Team apenas quando houver trabalho realmente paralelo, ownership explícito e contrato de saída por lane. Hooks bloqueiam violações locais; checkpoints humanos continuam decidindo PRD, TechSpec, Refinement de risco, merge e deploy.</p>
</div>
<div class="lane" aria-label="Lanes possíveis para Agent Teams">
<span>architecture</span><span>security</span><span>data contracts</span><span>QA</span><span>frontend</span><span>backend</span><span>tests</span><span>performance</span>
</div>
</div>
</section>
<!-- ====================== FLUXO DO CHECKPOINT ====================== -->
<section id="checkpoint">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">06 · O ponto crítico</span>
<h2>Como um checkpoint funciona, por dentro</h2>
<p class="lede">O segredo de "autônomo com checkpoints" está aqui: o workflow durável precisa <em>pausar e esperar um evento externo</em> que pode demorar dias.</p>
</div>
<div class="flow">
<div class="step"><div class="s-num">1</div><div class="s-t">Chega ao gate</div><div class="s-d">O workflow termina a etapa e alcança um portão crítico.</div></div>
<div class="step"><div class="s-num">2</div><div class="s-t">Persiste o estado</div><div class="s-d">Salva tudo em docs/<orquestracao> e no sistema externo quando existir.</div></div>
<div class="step"><div class="s-num">3</div><div class="s-t">Posta o artefato</div><div class="s-d">Manda o PRD/PR para revisão com o link local e externo.</div></div>
<div class="step"><div class="s-num">4</div><div class="s-t">Aguarda o sinal</div><div class="s-d">Pausa indefinidamente. Sem timeout, sem desperdício.</div></div>
<div class="step"><div class="s-num">5</div><div class="s-t">Sinal chega</div><div class="s-d">Um webhook (transição no Jira ou clique no Slack) avisa.</div></div>
<div class="step"><div class="s-num">6</div><div class="s-t">Retoma</div><div class="s-d">O workflow continua exatamente de onde parou.</div></div>
</div>
<p style="margin-top:40px;color:var(--paper-dim);max-width:76ch">
Os portões que eu marcaria como <span class="em-gate">críticos</span>: depois do <strong>PRD</strong> ("é isto que queremos construir?"), depois do <strong>TechSpec</strong> ("a arquitetura faz sentido?"), depois do <strong>Refinement</strong> quando houver risco, flags, migração ou dependência externa, <strong>sempre antes do merge</strong> (a aprovação do review) e <strong>antes do deploy</strong>. A decomposição em tasks pode rodar automática, com conferência por amostragem.
</p>
</div>
</section>
<!-- ====================== BUILD vs BUY ====================== -->
<section id="buildbuy">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">07 · Honestidade de engenharia</span>
<h2>Construir versus montar</h2>
<p class="lede">Para uso interno, uma fração enorme disto já existe pronta. A pergunta certa não é "como construo as 8 etapas do zero?", e sim "qual é a <em>cola</em> que eu preciso construir?".</p>
</div>
<div class="bb-grid">
<div class="bb buy">
<h3><span class="mono">JÁ EXISTE</span> Monte a partir disto</h3>
<ul>
<li>Rovo gera PRDs no Confluence<small>e os quebra em épicos e issues no Jira</small></li>
<li>Rovo Dev transforma issues em código<small>o agente de execução nativo da plataforma</small></li>
<li>Bitbucket: code review + Pipelines<small>os portões de CI já estão prontos</small></li>
<li>GitHub Spec Kit dá o scaffolding<small>model-agnostic, funciona com o Claude Code</small></li>
</ul>
</div>
<div class="bb build">
<h3><span class="mono">A COLA</span> Isto você constrói</h3>
<ul>
<li>O orquestrador durável<small>o cérebro com os portões — o calcanhar de Aquiles de quem improvisa</small></li>
<li>A camada de memória<small>o que torna os agentes bons no <em>seu</em> codebase específico</small></li>
<li>O artifact store local<small>docs/<orquestracao> como fallback universal de artefatos aprovados</small></li>
<li>A lógica de rastreabilidade<small>os links que ligam código ↔ task ↔ spec ↔ PRD ↔ ideia</small></li>
</ul>
</div>
</div>
<p style="margin-top:30px;color:var(--paper-dim);max-width:74ch">
Reinventar um agente gerador de PRD, quando o Rovo já faz isso dentro do <em>seu próprio</em> Confluence, seria desperdício. Monte o que existe; construa só o que é seu.
</p>
</div>
</section>
<!-- ====================== ROADMAP ====================== -->
<section id="roadmap">
<div class="wrap">
<div class="sec-head">
<span class="eyebrow">08 · O caminho</span>
<h2>Em fases, sem ferver o oceano</h2>
<p class="lede">"Da ideia à produção" é um escopo gigante. Você quer autonomia com checkpoints como <em>destino</em>, não como ponto de partida — então construa em fases que vão conquistando confiança.</p>
</div>
<div class="timeline">
<div class="phase" style="--accent:var(--entry)">
<span class="dot"></span><span class="ph-tag">Fase 0 · fundação</span>
<h3>Conexões de leitura</h3>
<p>Prove o básico via MCP/API: consigo ler uma issue do Jira, um repositório do Bitbucket e uma página do Confluence? Nada mais.</p>
<span class="risk">risco: nenhum</span>
</div>
<div class="phase" style="--accent:var(--confluence)">
<span class="dot"></span><span class="ph-tag">Fase 1 · planejamento</span>
<h3>Copiloto de planejamento (etapas 2–5)</h3>
<p>PRD → TechSpec → Tasks → Refinement, com aprovação humana nos gates críticos. Nenhum código é escrito, nenhuma produção é tocada — risco zero e valor imediato no dia um.</p>
<span class="risk">risco: baixo · valor: alto</span>
</div>
<div class="phase" style="--accent:var(--jira)">
<span class="dot"></span><span class="ph-tag">Fase 2 · execução</span>
<h3>Execução + Review (etapas 6–7) em sandbox</h3>
<p>Ligue os agentes de código num repositório de testes, com tasks pequenas e bem-escopadas. Aprove <em>todo</em> PR no começo — aqui é onde o risco real entra.</p>
<span class="risk">risco: médio · ambiente isolado</span>
</div>
<div class="phase" style="--accent:var(--bitbucket)">
<span class="dot"></span><span class="ph-tag">Fase 3 · loop fechado</span>
<h3>Memória (etapa 8)</h3>
<p>Persista o contexto, as decisões e os learnings para que o próximo ciclo já nasça mais inteligente. É o que fecha o ciclo e melhora tudo o que veio antes.</p>
<span class="risk">habilita ganhos compostos</span>
</div>
<div class="phase" style="--accent:var(--gate)">
<span class="dot"></span><span class="ph-tag">Fase 4 · autonomia conquistada</span>
<h3>Relaxe os checkpoints</h3>
<p>Mova os portões de "todo passo" para "só os críticos", conforme a confiança se acumula. É assim que você <strong>conquista</strong> a autonomia em vez de declará-la no dia um.</p>
<span class="risk">o destino, não a largada</span>
</div>
</div>
</div>
</section>
<!-- ====================== FECHAMENTO ====================== -->
<section class="closing">
<div class="wrap">
<span class="eyebrow">o princípio que amarra tudo</span>
<p class="contract">A spec é o <span class="a">contrato</span>.<br>A rastreabilidade é o <span class="b">produto</span>.</p>
<p>Quando o código diverge da spec, isso é um defeito a ser pego no review — não um detalhe. E quando cada artefato aponta de volta para sua origem, você ganha um sistema auditável que alimenta a própria memória.</p>
</div>
</section>
<footer>
<div class="wrap"><span class="mono">arquitetura de referência · jira × bitbucket × confluence × docs/<orquestracao> · spec-driven + behavior-driven development</span></div>
</footer>
<script>
/* ============================================================
DADOS DO PIPELINE
Cada estágio carrega: cor de destaque, sistemas (chips),
se tem portão humano, e o texto do dossiê.
============================================================ */
const STAGES = [
{ id:1, name:"Ideia", accent:"var(--entry)",
chips:[{t:"Entrada",c:"c-entry"}], gate:null,
artifact:"Descrição em linguagem natural",
local:"01-idea.md",
agent:"— (humano)",
desc:`O ponto de entrada. Pode ser uma issue de tipo customizado no Jira, uma mensagem no Slack ou um formulário. Captura a <span class="hl">intenção</span> em linguagem natural — com contexto de negócio, restrições e critérios de sucesso.` },
{ id:2, name:"PRD", accent:"var(--confluence)",
chips:[{t:"Confluence",c:"c-conf"},{t:"Jira",c:"c-jira"}], gate:"PRD",
artifact:"Documento de Requisitos",
local:"02-prd.md",
agent:"Claude (Sonnet)",
desc:`A IA gera o PRD a partir da ideia. O <span class="hl">documento</span> vive no Confluence; o item de trabalho que o rastreia — o épico — vive no Jira. É o <strong>primeiro portão crítico</strong>: "isto é o que queremos construir?".` },
{ id:3, name:"TechSpec", accent:"var(--confluence)",
chips:[{t:"Confluence",c:"c-conf"},{t:"Bitbucket",c:"c-bit"}], gate:"SPEC",
artifact:"Arquitetura · riscos · plano",
local:"03-techspec.md",
agent:"Claude (Opus) · Team opcional",
desc:`O agente <span class="hl">lê o codebase existente</span> via Bitbucket para ancorar a spec na realidade, propõe a arquitetura e identifica os riscos. Quando o escopo é amplo, um Agent Team revisa arquitetura, segurança, contratos de dados e QA antes da síntese final. Segundo portão crítico.` },
{ id:4, name:"Tasks", accent:"var(--jira)",
chips:[{t:"Jira",c:"c-jira"}], gate:"opcional",
artifact:"Issues independentes",
local:"04-tasks.md",
agent:"Claude (Sonnet)",
desc:`A spec é decomposta em <span class="hl">unidades de trabalho executáveis de forma independente</span>. Uma issue por unidade, cada uma com contexto suficiente para ser executada sozinha. O portão aqui é opcional — uma conferência por amostragem basta.` },
{ id:5, name:"Refinamento", accent:"var(--gate)",
chips:[{t:"Jira",c:"c-jira"},{t:"Confluence",c:"c-conf"}], gate:"opcional",
artifact:"Documento de grooming",
local:"05-refinement.md",
agent:"Claude (Sonnet)",
desc:`Condensa o backlog num <span class="hl">guia macro acionável</span>: resumo, solução proposta, pontos de observação, checklist, subtasks com estimativa, Definition of Done e flags/configurações. É opcional para features triviais, mas deve registrar quando foi dispensado.` },
{ id:6, name:"Execução", accent:"var(--bitbucket)",
chips:[{t:"Bitbucket",c:"c-bit"},{t:"Jira",c:"c-jira"}], gate:null,
artifact:"Branch + Pull Request",
local:"06-execution.md",
agent:"Claude Code / Rovo Dev · Team opcional",
desc:`Agentes com <span class="hl">contexto completo do codebase</span> pegam uma task, escrevem o código, criam a branch e abrem o PR. Agent Teams entram só quando frontend, backend e testes têm ownership separado. A issue caminha no Jira: In Progress → In Review.` },
{ id:7, name:"Review", accent:"var(--bitbucket)",
chips:[{t:"Bitbucket",c:"c-bit"},{t:"Jira",c:"c-jira"}], gate:"MERGE",
artifact:"PR aprovado · merge",
local:"07-review.md",
agent:"Agent Team + Pipelines",
desc:`Code review automatizado no PR, portões de qualidade via CI (Pipelines) e <span class="hl">validação contra a spec</span> — não só lint. Revisores de segurança, performance, testes, arquitetura e contratos atuam em paralelo antes do gate de merge e do deploy.` },
{ id:8, name:"Memória", accent:"var(--gate)",
chips:[{t:"Confluence",c:"c-conf"},{t:"Jira",c:"c-jira"},{t:"Bitbucket",c:"c-bit"}], gate:null,
artifact:"Contexto compactado · decisões",
local:"08-memory.md",
agent:"Claude (compactação)",
desc:`Depois de shipar, captura learnings, decisões e contexto para que as tarefas futuras já <span class="hl">nasçam informadas</span>. Vive no Confluence (decision records), num store vetorial para RAG e nos links de rastreabilidade. Para projetos que já existem, é aqui que o codebase é ingerido.` },
];
const rail = document.getElementById('rail');
const dossier = document.getElementById('dossier');
const progressFill = document.getElementById('progress-fill');
/* monta os cards do trilho */
STAGES.forEach(s=>{
const el = document.createElement('div');
el.className='stage';
el.tabIndex=0;
el.setAttribute('role','button');
el.setAttribute('aria-label',`Etapa ${s.id}: ${s.name}`);
el.style.setProperty('--accent', s.accent);
el.dataset.id = s.id;
el.innerHTML = `
${s.gate ? `<span class="gate-flag">⚷ ${s.gate}</span>` : ``}
<span class="num">${String(s.id).padStart(2,'0')}</span>
<span class="nm">${s.name}</span>
<span class="sys">${s.chips.map(c=>`<span class="chip ${c.c}">${c.t}</span>`).join('')}</span>`;
el.addEventListener('click',()=>select(s.id));
el.addEventListener('keydown',e=>{ if(e.key==='Enter'||e.key===' '){e.preventDefault();select(s.id);} });
rail.appendChild(el);
});
/* renderiza o dossiê do estágio escolhido */
function select(id){
const s = STAGES.find(x=>x.id===id);
document.querySelectorAll('.stage').forEach(c=>c.classList.toggle('active', +c.dataset.id===id));
dossier.style.setProperty('--accent', s.accent);
// barra de progresso acompanha a posição no fluxo
progressFill.style.width = (id/STAGES.length*100)+'%';
progressFill.style.background = s.accent;
dossier.innerHTML = `
<div>
<div class="d-num">ETAPA ${String(s.id).padStart(2,'0')} / 08</div>
<h3>${s.name}</h3>
<p class="d-body">${s.desc}</p>
</div>
<div class="meta">
<div class="row"><span class="k">Artefato</span><span class="v">${s.artifact}</span></div>
<div class="row"><span class="k">Arquivo local</span><span class="v">docs/<orquestracao>/${s.local}</span></div>
<div class="row"><span class="k">Agente</span><span class="v">${s.agent}</span></div>
<div class="row"><span class="k">Portão humano</span><span class="v ${s.gate?'accent':''}">${s.gate ? 'Sim · '+s.gate : 'Não'}</span></div>
<div class="row"><span class="k">Sistemas</span><span class="v">${s.chips.map(c=>c.t).join(' · ')}</span></div>
</div>`;
}
select(1); // abre na etapa 1
/* ============================================================
COMPONENTES DA ARQUITETURA (acordeão)
============================================================ */
const COMPONENTS = [
{ t:"Orquestrador", sub:"a esteira inteligente · o cérebro",
body:`Mantém a máquina de estados: sabe que a feature X está parada esperando aprovação há dois dias e retoma quando o sinal chega. A ferramenta desenhada para isso é um motor de execução durável como o <code>Temporal</code> — ele persiste estado, sobrevive a reinícios e tem o conceito nativo de "esperar por um sinal humano".`,
why:`<b>A decisão mais consequente do projeto.</b> Alternativas: Postgres + fila (você reescreve à mão o que o Temporal dá de graça) ou Forge + Automation da Atlassian (menos infra, mais amarração à plataforma).` },
{ t:"Camada de Agentes", sub:"os trabalhadores de cada estação",
body:`Nem todo agente é igual. Subagents dão um dono claro para PRD, TechSpec, Tasks, Refinement, Execution, Review e Memory. Agent Teams entram como especialização paralela quando há lanes independentes — arquitetura, segurança, contratos, QA, frontend, backend ou testes.`,
why:`Para execução, o <b>Claude Code</b> foi feito para "agente com contexto completo do codebase". A alternativa nativa é o <b>Rovo Dev</b>, que transforma itens do Jira em código. O orquestrador decide quando delegar sequencialmente e quando compor uma equipe.` },
{ t:"Camada de Integração", sub:"os trilhos entre o cérebro e os sistemas",
body:`Há duas direções, e é fácil esquecer uma. <strong>Saindo</strong> do orquestrador para os sistemas: APIs REST ou servidores <code>MCP</code>. <strong>Voltando</strong> dos sistemas ao orquestrador: Channels, webhooks e callbacks de checkpoint.`,
why:`Sem <b>eventos</b>, o orquestrador fica cego — teria que ficar perguntando "já aconteceu? já aconteceu?". Webhooks avisam "PR aberto", "issue mudou", "humano aprovou"; scheduled tasks entram só quando não existe evento confiável.` },
{ t:"Camada de Contexto e Memória", sub:"o onboarding do agente",
body:`O coração da <em>qualidade</em>. O agente tem janela de contexto finita — não lê o repositório inteiro toda vez. Assim como você não entrega só um ticket a um dev novo (você dá os docs de arquitetura, as convenções, as armadilhas), esta camada dá esse onboarding: RAG sobre codebase + docs, Postgres para a linhagem das specs, Confluence como camada legível.`,
why:`Para um projeto que <b>já existe</b> (brownfield), ingerir o codebase aqui é o primeiro passo obrigatório — é o que separa "orquestrar projeto novo" de "orquestrar projeto existente".` },
{ t:"Checkpoints Humanos", sub:"os inspetores da linha",
body:`Tecnicamente: o workflow chega ao gate, persiste o estado, posta o artefato e <strong>espera um sinal externo</strong>. Na sua stack, o sinal chega de duas formas naturais — uma transição de workflow no Jira ou um botão clicável numa mensagem do Slack.`,
why:`Você já tem o conector do Slack, então <b>aprovação por Slack é quase de graça</b>. Críticos: pós-PRD, pós-TechSpec, pré-merge e pré-deploy.` },
{ t:"Governança e Observabilidade", sub:"o que constrói a confiança",
body:`Parece opcional para uso interno, mas é o que te deixa relaxar a autonomia depois. Você precisa de trilha de auditoria, rastreamento de custo, links de rastreabilidade, hooks locais e task gates que bloqueiam saídas sem origem, DoD ou evidência.`,
why:`A rastreabilidade <b>não é burocracia</b>: é exatamente o que alimenta a memória e o que permite auditar uma decisão meses depois. Hooks e automations tornam essa disciplina executável.` },
];
const cg = document.getElementById('comp-grid');
COMPONENTS.forEach((c,i)=>{
const el = document.createElement('div');
el.className='comp';
el.innerHTML = `
<div class="comp-head" role="button" tabindex="0" aria-expanded="false">
<span class="comp-idx">${i+1}</span>
<span class="t"><h3>${c.t}</h3><span class="sub">${c.sub}</span></span>
<span class="comp-toggle">+</span>
</div>
<div class="comp-body"><div class="inner">
<p>${c.body}</p>
<div class="why">${c.why}</div>
</div></div>`;
const head = el.querySelector('.comp-head');
const bodyEl = el.querySelector('.comp-body');
const toggle = ()=>{
const open = el.classList.toggle('open');
head.setAttribute('aria-expanded', open);
bodyEl.style.maxHeight = open ? bodyEl.scrollHeight + 'px' : '0px';
};
head.addEventListener('click', toggle);
head.addEventListener('keydown', e=>{ if(e.key==='Enter'||e.key===' '){e.preventDefault();toggle();} });
cg.appendChild(el);
});
/* revelação suave ao rolar — leve, só para dar vida */
const io = new IntersectionObserver((entries)=>{
entries.forEach(en=>{ if(en.isIntersecting){ en.target.style.opacity=1; en.target.style.transform='none'; io.unobserve(en.target);} });
},{threshold:.12});
document.querySelectorAll('section .sec-head, .idea-card, .dossier, .timeline, .bb-grid, .flow, .sys-grid, .comp-grid, .control-grid, .decision-band, .spec-stack, .notations, .sp-cards').forEach(el=>{
el.style.opacity=0; el.style.transform='translateY(20px)';
el.style.transition='opacity .8s cubic-bezier(.2,.7,.2,1), transform .8s cubic-bezier(.2,.7,.2,1)';
io.observe(el);
});
</script>
</body>
</html>