---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v1.43
secao: 90
titulo: "OFFLINE E FALHA DE REDE · **`estável`** (2026-08-24, F7.7-P5, duas decisões dele no gate) · OF1–OF9"
sequencia: 96 de 98
bytes_do_corpo: 10423
md5_do_corpo: ff509cad3d35ef0eb9176d85517cff12
gerado_por: 06-validacao/geradores/gen-camada-ia.py
nota: fatia GERADA — o corpo abaixo é byte a byte o trecho do canônico; edite o canônico, nunca esta fatia. Canônico inteiro em https://ds.seed.eng.br/01-canonicos/seed-componentes.md
---
## 90. OFFLINE E FALHA DE REDE · **`estável`** (2026-08-24, F7.7-P5, duas decisões dele no gate) · OF1–OF9

**O que esta seção é.** O contrato do que a interface mostra quando a rede falha
— e do que ela **não** faz. Ela fecha a primeira das três linhas que o
`mapa-cobertura-ds.md` §6.1 marcava **❌ AUSENTE** desde a F7.1. Evidência
completa em `09-pesquisa/leitura-f77-estados-ausentes.md`.

**Medido antes de escrever:** **0 de 40** artefatos do acervo têm qualquer estado
de rede. A única menção de conexão que existe é uma linha de erro genérico do
§25/Z1 no `banco-feedback.html` (*"Verifique a conexão e tente de novo…"*), que é
estado de **erro**, não estado de **rede**. E o canal de anúncio já existe:
**9 das 16 telas** têm `aria-live="polite"`. Faltava o que dizer nele.

### 90.1 OF1 — offline NUNCA se declara por flag

`navigator.onLine` devolvendo `true` **não garante** acesso à internet: a
heurística do sistema considera "online" quem está numa LAN sem saída, e no
Windows o status depende de alcançar um servidor da Microsoft, o que firewall e
VPN bloqueiam com a internet funcionando. A recomendação da MDN é normativa aqui:
*não desabilite recursos com base no status online; apenas ofereça dicas.*

**A regra:**

- **`false` é confiável** (se o navegador diz que está offline, está) e pode
  ADIANTAR a dica;
- **`true` não é evidência de nada** e nunca serve para reabilitar sozinho;
- **o estado de falha se conclui de uma REQUISIÇÃO QUE FALHOU**, e se for para
  insistir, se confirma por batida (*heartbeat*).

⚠ **Proibido:** desabilitar controle porque a flag disse offline. Isso trava a
interface de quem usa VPN — e a nossa gente de campo usa VPN.

### 90.2 OF2 — são DOIS estados, não um (decisão dele: (a))

| Estado | Quando | O que a tela diz, na forma da §89 |
|---|---|---|
| **Sem conexão** (do lado de quem usa) | o dispositivo não alcança a rede | *"Você está sem conexão."* + o que ainda é possível |
| **Sistema indisponível** (do nosso lado) | a rede está boa e o servidor não responde ou devolve erro | *"Não foi possível alcançar o sistema."* + o que fazer |

**Por que dois e não um.** É o que a diretriz de UX offline manda (*deixe claro
se o problema é do nosso lado ou do lado de quem usa*) e é a **continuação
direta da MC3**, que ele decidiu na §89: voz impessoal, com "nós" reservado para
quando a falha é da SEED. Um estado único culparia a rede do cliente por uma
queda nossa — e o produto emite documento com ART, onde essa distinção importa.

**Custo declarado, e ele é do produto:** exige que a camada de dados informe qual
falha ocorreu. Sem essa informação, a interface cai no estado **Sistema
indisponível**, nunca no "sem conexão" — errar para o lado de assumir a falha é
coerente com a MC3.

Distinção verbal obrigatória (§89.3): **"não é possível"** (regra permanente) ×
**"não foi possível"** (esta tentativa falhou). Falha de rede é sempre a segunda.

### 90.3 OF3 — o estado crítico é PERSISTENTE; a recuperação é TRANSITÓRIA

- Enquanto a falha dura, o aviso **fica**: faixa na borda superior da região
  afetada, ou do `app` quando a falha é global. Não é toast, não some sozinho.
- Quando a conexão volta, o aviso **sai** e a volta é anunciada por **toast**
  (§17), que some. Voltar ao normal não merece ocupação permanente.

### 90.4 OF4 — o aviso diz o estado E o que ainda é possível

Nunca só o estado. A faixa tem, sempre: **o que aconteceu** · **o que continua
possível** · **uma ação** (tentar de novo, quando faz sentido). Faixa que só
anuncia a desgraça transfere o problema sem transferir a saída — é a mesma
doença que a MC5 corrige no diálogo destrutivo.

### 90.5 OF5 — nunca bloquear

**Proibido:** modal de carregamento que impede navegação, e requisição que
bloqueia conteúdo já carregado. A pessoa continua lendo, navegando e preenchendo.
O que falha é o **envio**, não a interface.

### 90.6 OF6 — o item NÃO ENVIADO tem marca própria

O que a pessoa fez e não saiu ainda **aparece como tal**, no próprio item, com
**forma + texto** (nunca só cor — OF8): marca de pendência e o rótulo
*"Não enviado"*. Três estados possíveis por item: **enviado** (sem marca) ·
**não enviado** (marca de pendência) · **falhou** (marca de erro + ação de tentar
de novo).

⭐ **Esta é a peça que a decisão (c) dele manda especificar AGORA**, mesmo sem
fila: a marcação é idêntica com ou sem fila, então especificá-la hoje é trabalho
que não se repete amanhã.

### 90.7 OF7 — a mudança de estado é ANUNCIADA

Entrada e saída do estado de falha vão à região `aria-live="polite"` que a tela
já tem (§1.13-b). **Nunca `assertive`**: perda de rede não interrompe o que a
pessoa está fazendo — a faixa persistente já carrega a informação para quem vê, e
o anúncio educado basta para quem ouve.

### 90.8 OF8 — nunca só cor

Estado de rede se marca por **linguagem + forma + cor**, os três. Regra herdada
da SC 1.4.1 e já praticada no §25/Z1.

### 90.9 OF9 — fronteira do design system

O DS fecha o **contrato visível**. **Não** são desta seção: service worker,
sincronização em segundo plano, IndexedDB, resolução de ordem de envio e política
de repetição. Isso é produto.

**Pendência `OF-P1` — a FILA de ações offline.** Decisão dele: (c) — o aviso e a
marcação fecham agora; a fila entra depois, **com a obrigação escrita ANTES de
alguém implementá-la**:

> Qualquer fila que sobreviva ao fechamento da aba grava, **no dispositivo**, o
> que a operação carrega — número de unidade consumidora, documento, endereço,
> valor de fatura. Isso é tratamento de dado pessoal **fora do servidor** e puxa
> LGPD: **base legal declarada · limite de retenção · cifragem em repouso ·
> limpeza no encerramento de sessão**. A fila não nasce sem essas quatro.

E a razão de ela existir um dia é local: **a SEED trabalha onde não há sinal** —
subestação, sala de painéis, canteiro e usina em zona rural de MG, ES e BA são
exatamente os lugares onde a coleta acontece. Offline aqui não é borda exótica, é
condição de trabalho.

### 90.10 OF10 — os estados de SINCRONIZAÇÃO (emenda de 2026-08-24, tarde)

**Por que esta cláusula nasceu.** A §90 foi escrita com a fila como *hipótese*
(OF-P1). No mesmo dia ele informou que ela é **decisão tomada**, verbatim:

> *"vamos criar um app para poder comunicar com o ERP para os funcionários
> poderem fazer cadastro off-line de certas coisas para poder depois sincronizar
> quando tiver internet (…) por exemplo, OS, a equipe de campo sincroniza o app e
> tem a OS que precisa trabalhar, pode preencher as infos offline sem problema e
> sincronizar quando tiver internet, o mesmo ocorre com sistema de ponto."*

Isso **não contradiz** a decisão (c) do gate — ela guardou exatamente a peça que
os dois mundos compartilham. Mas revela **três estados que a §90 não tinha**,
porque ela foi escrita para o caso "a rede caiu no meio do uso", e o app é o caso
"a rede não estava lá desde o começo, e por projeto".

**OF10-a — o item tem QUATRO estados, não dois.**

| Estado | O que significa | Marca |
|---|---|---|
| **enviado** | está no servidor | sem marca |
| **não enviado** | existe só no dispositivo, esperando rede | marca de pendência + rótulo |
| **sincronizando** | está subindo agora | marca de progresso, no item |
| **falhou** | tentou e não subiu | marca de erro + ação de tentar de novo |

O estado **sincronizando** é do ITEM, não só da tela: quem tem 40 apontamentos
subindo precisa ver quais já foram.

**OF10-b — a sincronização é um EVENTO COM RESULTADO, e o resultado fica.**
Terminada a sincronização, a interface diz **quantos subiram, quantos falharam e
o que fazer com os que falharam**. Esse resultado **não some sozinho**: permanece
até a pessoa reconhecê-lo. Sincronização que termina em silêncio é a forma mais
cara de perder trabalho, porque ninguém fica sabendo.

**OF10-c — antes de sair do local, dá para saber o que não subiu.** O resumo do
pendente é alcançável **sem procurar** — a equipe de campo decide se pode ir
embora com base nele. É o mesmo princípio da OF4 (dizer o que ainda é possível),
aplicado ao momento em que a decisão é irreversível: sair do canteiro.

**OF10-d — nunca "sincronizado" otimista.** Item só sai de *não enviado* quando o
servidor **confirmou**. Marcar como enviado ao despachar é mentir sobre o dado.

### 90.11 OF-P1 deixa de ser hipótese — e o ponto tem exigência PRÓPRIA

A pendência **OF-P1** se mantém aberta como trabalho de produto, mas muda de
natureza: **a fila vai existir**, então as quatro obrigações da §90.9 (base legal
declarada · limite de retenção · cifragem em repouso · limpeza no encerramento de
sessão) deixam de ser cautela e passam a ser **requisito de projeto**.

⚠ **E o registro de PONTO tem regra própria, acima da LGPD.** A **Portaria MTP
671/2021** criou o **REP-P** (registrador eletrônico de ponto por programa) e
**admite expressamente a marcação offline com sincronização posterior** — logo o
plano dele é suportado pela norma. Mas o REP-P vem com exigências que **são de
desenho, não só de backend**:

- **criptografia de no mínimo 128 bits na transmissão E no armazenamento** — o
  que transforma "cifragem em repouso" de recomendação em obrigação;
- **comprovante de registro ao trabalhador a cada marcação**, impresso ou em PDF,
  com assinatura no padrão **PAdES** — isto é uma PEÇA, e ela não existe no
  inventário;
- **o registro não se altera** — o que significa que a marcação de ponto **não
  entra no regime de conflito da §91**: ela não é editável, é apenas
  transmitida.

**Pendência nova `PT-P1`:** o comprovante de registro de ponto do trabalhador é
peça a especificar (família Interna do inventário), e a conformidade ao REP-P é
**[não conferido]** por esta sessão — precisa de quem responde por folha e
jurídico na SEED. O design system desenha a peça; ele não atesta conformidade
trabalhista.

---

