<a id="ch-04"></a>

## Capítulo 4 — Replicação das linhas de base e piloto

<!-- open-cyber-academy:lesson-figures:start ch-04 -->
### Mapa da aula

Aula 04 publicada. Mapa, exemplo, EX021.

```mermaid
flowchart TD
  N0["4.1 Reprodução, replicação, robustez"]
  N1["4.2 Reproduzindo um cálculo de modelo: o modelo insu"]
  N2["4.3 A discrepância do GridWater-Sim sintética"]
  N3["4.4 Verificando um simulador"]
  N4["4.5 Replicando uma linha de base de detecção: artefa"]
  N5["4.6 Obtendo os parâmetros"]
  N6["4.7 O piloto"]
  N7["Síntese do capítulo"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Exemplo resolvido"]
  EX --> Q["Exercício EX021"]
```

### Desenho lógico

```mermaid
flowchart LR
  N0["4.1 Reprodução, replicação, robustez"]
  N1["4.2 Reproduzindo um cálculo de modelo: o modelo insu"]
  N2["4.3 A discrepância do GridWater-Sim sintética"]
  N3["4.4 Verificando um simulador"]
  N4["4.5 Replicando uma linha de base de detecção: artefa"]
  N5["4.6 Obtendo os parâmetros"]
  N6["4.7 O piloto"]
  N7["Síntese do capítulo"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX021"]
```

```text
[4.1 Reprodução, replicação, robustez]
    |
    v
[4.2 Reproduzindo um cálculo de modelo: o modelo insu]
    |
    v
[4.3 A discrepância do GridWater-Sim sintética]
    |
    v
[4.4 Verificando um simulador]
    |
    v
[4.5 Replicando uma linha de base de detecção: artefa]
    |
    v
[4.6 Obtendo os parâmetros]
    |
    v
[4.7 O piloto]
    |
    v
[Síntese do capítulo]
    |
    v
[Exemplo resolvido] --> [Exercício EX021]
```
<!-- open-cyber-academy:lesson-figures:end ch-04 -->


### Objetivos de aprendizagem e conexão

Ao fim deste capítulo, o estudante será capaz de:

1. Distinguir reprodução, replicação e verificações de robustez, e escolher qual delas uma linha de base exige.
2. Reproduzir um cálculo de modelo publicado, declarar uma tolerância com antecedência, diagnosticar uma discrepância e escrever um registro de reprodução.
3. Verificar um simulador com invariantes, testes unitários e uma implementação independente antes de confiar em qualquer comparação que ele produza.
4. Reconhecer artefatos do protocolo de avaliação — ajuste por pontos, vazamento temporal, características específicas do testbed — que inflam as linhas de base de detecção.
5. Obter parâmetros do modelo junto a especialistas e documentá-los com incerteza explícita.
6. Desenhar um piloto delimitado cujo propósito seja a viabilidade, com critérios de prosseguir/não prosseguir, e explicar por que um piloto não deve ser usado para estimar o tamanho do efeito.

O Capítulo 3 fixou as hipóteses, as linhas de base e as condições de falha. Antes que o estudo principal possa comparar DEP com SILO, CRITFLAG e ORACLE, é preciso mostrar que cada número de que essas comparações dependem significa o que alega.

### 4.1 Reprodução, replicação, robustez

As [National Academies (2019)](https://doi.org/10.17226/25303) distinguem a **reprodutibilidade** — obter resultados consistentes usando os mesmos dados de entrada, passos computacionais, métodos e condições de análise — da **replicabilidade** — obter resultados consistentes entre estudos voltados à mesma pergunta, cada um com seus próprios dados. Uma terceira atividade, muitas vezes chamada de verificação de **robustez**, varia as escolhas analíticas sobre os mesmos dados. As teses sobre infraestrutura precisam das três:

| Atividade | Exemplo do Cascade Study | Contra o que protege |
|---|---|---|
| Reprodução | Reexecutar um cálculo de inoperabilidade publicado com a matriz publicada | Leitura errada das convenções; erros de codificação na linha de base |
| Replicação | Construir Port Halvard de forma independente e testar se o resultado de Riverbend se sustenta | Constatações específicas do contexto ou do modelo |
| Robustez | Variar pesos, reservas, passo de tempo, horizonte | Resultados que dependem de uma escolha arbitrária |

### 4.2 Reproduzindo um cálculo de modelo: o modelo insumo-produto de inoperabilidade

#### 4.2.1 O modelo

O modelo insumo-produto de inoperabilidade de Haimes e Jiang ([2001](https://doi.org/10.1061/(ASCE)1076-0342(2001)7:1(1))) adapta a economia de insumo-produto de Leontief à infraestrutura. Cada setor *i* tem uma inoperabilidade *q_i* entre 0 (plenamente operável) e 1 (plenamente inoperável). O equilíbrio após uma perturbação inicial *c\** é *q* = *A\*q* + *c\**, portanto *q* = (*I* − *A\**)⁻¹ *c\**. O elemento *A\*_ij* é a inoperabilidade transmitida ao setor *i* por unidade de inoperabilidade do setor *j*. A convenção importa: a linha é o setor *receptor*, a coluna o setor *fornecedor*. Artigos e softwares diferem na notação, e alguns derivam *A\** das tabelas econômicas de insumo-produto por passos de normalização que são fáceis de errar sutilmente.

#### 4.2.2 Laboratório de reprodução

Um artigo "publicado" sintético relata que, após uma perturbação que torna a energia 50% inoperável, a água atinge uma inoperabilidade de equilíbrio de 0,236 num modelo de três setores. Declare com antecedência uma tolerância de ± 0,005 (arredondamento na publicação) e então reproduza:

```python
# Lab 4a - reproducing an inoperability input-output (IIM) result (offline, standard library only)
# q = (I - A*)^-1 c*. Convention: A*[i][j] = inoperability contributed to sector i per unit inoperability of sector j.
def solve(a, c):
    n = len(c)
    m = [[(1.0 if i == j else 0.0) - a[i][j] for j in range(n)] + [c[i]] for i in range(n)]
    for col in range(n):
        piv = max(range(col, n), key=lambda r: abs(m[r][col]))
        m[col], m[piv] = m[piv], m[col]
        for r in range(n):
            if r != col:
                f = m[r][col] / m[col][col]
                m[r] = [x - f * y for x, y in zip(m[r], m[col])]
    return [m[i][n] / m[i][i] for i in range(n)]
sectors = ["power", "water", "telecom"]
A = [[0.00, 0.05, 0.10],   # power depends a little on water (cooling) and telecom (SCADA comms)
     [0.40, 0.00, 0.15],   # water depends strongly on power
     [0.30, 0.02, 0.00]]   # telecom depends on power
c = [0.50, 0.00, 0.00]    # initial perturbation: power 50% inoperable
q = solve(A, c)
print("convention A* (row = receiving sector):", [round(x, 3) for x in q])
At = [list(r) for r in zip(*A)]
qt = solve(At, c)
print("transposed by mistake:               ", [round(x, 3) for x in qt])
```

Saída esperada:

```text
convention A* (row = receiving sector): [0.528, 0.236, 0.163]
transposed by mistake:                [0.528, 0.028, 0.057]
```

Com a convenção correta, a reprodução confere (água 0,236). Com a matriz transposta — um erro que não produz aviso, nem falha, e gera um vetor de aparência plausível —, a inoperabilidade da água cai quase uma ordem de grandeza, e a *classificação* dos setores muda: as telecomunicações agora parecem mais afetadas do que a água. O próprio valor da energia coincide nos dois casos, e é exatamente isso que torna o erro perigoso: um replicador que verifique apenas o setor perturbado declararia sucesso.

#### 4.2.3 O registro de reprodução

Um registro de reprodução anota: o valor-alvo e sua fonte (página, tabela); a tolerância, fixada *antes* da execução; o ambiente de software (versão da linguagem, sistema operacional); os insumos e sua procedência; a saída exata; as discrepâncias e seu diagnóstico; e a decisão (reproduzido, reproduzido após correção, não reproduzido). Quando a convenção dos autores originais for ambígua, escreva para eles; registre a correspondência. Uma não reprodução é um resultado, e não um constrangimento, e pertence à tese.

#### 4.2.4 O que um IIM reproduzido pode e não pode sustentar

Reproduzir o cálculo mostra apenas que a aritmética foi compreendida. O IIM continua linear e baseado em equilíbrio: ele não modela reservas, temporização nem ordem de restauração, e seus coeficientes costumam ser derivados de fluxos econômicos, e não de dependências de engenharia. No Cascade Study, ele serve como **verificação cruzada em nível setorial** — os setores que o IIM classifica como mais afetados correspondem aos serviços que o modelo de reservas mostra falhando? —, e não como concorrente do modelo de restauração.

### 4.3 A discrepância do GridWater-Sim (sintética)

O benchmark sintético GridWater-Sim relata, para uma configuração semelhante a Riverbend, uma perda ponderada média de serviços críticos sob a restauração pelos clientes que a reimplementação do candidato não conseguiu reproduzir dentro da tolerância declarada com antecedência. O diagnóstico seguiu a ordem que mais frequentemente encontra a causa:

1. **Insumos.** Foram usadas as mesmas distribuições de parâmetros? A documentação do benchmark dava as distribuições triangulares como (low, mode, high); o `random.triangular` do Python recebe (low, high, mode). Trocar mode e high desloca a média silenciosamente.
2. **Semântica.** "Restaurado" significa reenergizado ou serviço retomado? O GridWater-Sim aplicava um atraso de reinício de uma hora apenas à água; a reimplementação o aplicava a todos os serviços.
3. **Numérica.** O benchmark avançava o tempo em passos fixos; a reimplementação calculava os intervalos exatos de interrupção. Passos fixos introduzem um erro de discretização que depende do passo e de onde os esgotamentos das reservas caem dentro de um passo.
4. **Aleatoriedade.** As sementes e a ordem dos sorteios eram idênticas? A ordem dos sorteios importa: sortear as durações antes das reservas numa implementação e depois na outra produz conjuntos de cenários diferentes a partir da mesma semente.

Depois de alinhar (1) e (2), a diferença restante ficou dentro da tolerância e diminuiu com passos de tempo menores, confirmando (3). A tese registra o benchmark como *reproduzido após a correção de uma ambiguidade na ordem dos parâmetros*, relata os valores original e corrigido e adota a implementação por intervalos exatos, mantendo a versão por passos de tempo como verificação independente.

### 4.4 Verificando um simulador

A verificação pergunta se o modelo está implementado corretamente; a validação pergunta se ele representa o sistema real de forma adequada ao seu propósito ([Sargent, 2013](https://doi.org/10.1057/jos.2012.20)). A verificação vem primeiro, porque validar uma implementação defeituosa não tem sentido.

**Invariantes** que qualquer simulador de restauração correto precisa satisfazer:

- Se toda reserva exceder o horizonte, a perda ponderada de serviços críticos é zero sob qualquer ordenação.
- Duas políticas que produzem a mesma ordem produzem resultados idênticos com sorteios idênticos.
- A perda do oráculo é menor ou igual à perda de qualquer política em qualquer sorteio.
- Aumentar uma reserva, mantendo todo o resto fixo, nunca aumenta a perda.
- Os clientes-hora sob a regra de Smith são menores ou iguais aos de qualquer outra ordenação quando as durações de restauração são iguais.
- A perda e os clientes-hora são não negativos e limitados por peso × horizonte e clientes × horizonte.

Os **testes unitários** verificam os menores componentes: a aritmética de intervalos para um único serviço; o efeito de uma dependência com uma reserva local; a atribuição de equipes com duas equipes. Os **testes entre implementações** comparam duas implementações escritas de forma independente sobre sorteios fixos. Os **testes de condições extremas** usam reservas zero, durações zero e um único alimentador. Mantenha os testes no arquivo (Capítulo 7); um revisor que pode executá-los confia mais nas comparações do que um que precisa aceitá-las por fé.

### 4.5 Replicando uma linha de base de detecção: artefatos da avaliação

Embora o Cascade Study não proponha um detector, sua análise do tempo até o impacto depende de quando uma perturbação é reconhecida, e o candidato precisa ser capaz de julgar as linhas de base de detecção relatadas para infraestrutura. Os mecanismos comuns de inflação são escolhas da avaliação, e não propriedades do modelo.

#### 4.5.1 Ajuste por pontos

[Kim et al. (2022)](https://ojs.aaai.org/index.php/AAAI/article/view/20680) mostraram que o ajuste por pontos (point adjustment, PA) — contar um segmento anômalo inteiro como detectado quando qualquer ponto nele é sinalizado — pode fazer pontuações aleatórias parecerem excelentes. O laboratório a seguir reproduz o efeito em rótulos sintéticos:

```python
# Lab 4b - how point adjustment (PA) inflates detection scores (offline, standard library only)
import random
random.seed(42)
N = 2000
labels = [0] * N
for start, length in [(300, 60), (900, 120), (1500, 80)]:
    for t in range(start, start + length):
        labels[t] = 1
scores = [random.random() for _ in range(N)]          # a detector that knows nothing
thr = sorted(scores)[int(0.97 * N)]                    # alarm on the top 3% of scores
pred = [1 if s > thr else 0 for s in scores]
def f1(p, y):
    tp = sum(1 for a, b in zip(p, y) if a and b)
    fp = sum(1 for a, b in zip(p, y) if a and not b)
    fn = sum(1 for a, b in zip(p, y) if b and not a)
    prec = tp / (tp + fp) if tp + fp else 0.0
    rec = tp / (tp + fn) if tp + fn else 0.0
    return round(2 * prec * rec / (prec + rec), 3) if prec + rec else 0.0
def segments(y):
    segs, t = [], 0
    while t < len(y):
        if y[t]:
            s = t
            while t < len(y) and y[t]:
                t += 1
            segs.append((s, t))
        else:
            t += 1
    return segs
def adjust(p, y, k=0.0):
    q = list(p)
    for s, e in segments(y):
        hit = sum(p[s:e]) / (e - s)
        if hit > k:
            for t in range(s, e):
                q[t] = 1
    return q
print("point-wise F1           :", f1(pred, labels))
print("F1 after PA             :", f1(adjust(pred, labels), labels))
print("F1 after PA%K (K = 0.20):", f1(adjust(pred, labels, 0.20), labels))
print("segments hit by >=1 alarm:", sum(1 for s, e in segments(labels) if any(pred[s:e])), "of", len(segments(labels)))
```

Saída esperada:

```text
point-wise F1           : 0.05
F1 after PA             : 0.911
F1 after PA%K (K = 0.20): 0.05
segments hit by >=1 alarm: 3 of 3
```

Um detector sem nenhuma informação alcança 0,911 após o PA porque cada segmento longo contém, por acaso, pelo menos um dos 3% de alarmes aleatórios. O PA%K com K = 20% elimina a inflação aqui. Para a pesquisa em IC, a lição vai além: nenhuma das métricas diz *quando* o primeiro alarme verdadeiro ocorreu em relação ao início do segmento, que é o que importa para as reservas. Uma métrica relevante para a consequência é a **latência de detecção relativa ao tempo até o impacto** — a fração de incidentes detectados antes que a reserva do primeiro serviço dependente se esgote.

#### 4.5.2 Outros artefatos

- **Vazamento temporal.** Divisões aleatórias de séries temporais em treino/teste permitem que um modelo aprenda com o futuro. Use divisões ordenadas no tempo que imitem a implantação.
- **Características específicas do testbed.** Um detector pode aprender assinaturas das ferramentas de injeção de ataques do testbed ou de seus sensores específicos, em vez dos ataques.
- **Cobertura do conjunto de ataques.** Os ataques de um conjunto de dados foram escolhidos por quem o construiu; o desempenho neles diz pouco sobre outras classes de ataques ([Arp et al., 2022](https://www.usenix.org/conference/usenixsecurity22/presentation/arp)).
- **Taxas de base.** Uma taxa de falsos positivos que parece pequena num conjunto de dados balanceado pode sobrecarregar os operadores em taxas de base realistas ([Sommer and Paxson, 2010](https://doi.org/10.1109/SP.2010.25)).

### 4.6 Obtendo os parâmetros

As reservas, as durações de restauração e os pesos do modelo vêm de pessoas. A elicitação estruturada com especialistas — preparar os especialistas, pedir quantis em vez de valores únicos, devolver as distribuições implícitas e registrar as justificativas — reduz a ancoragem e o excesso de confiança ([O'Hagan et al., 2006](https://doi.org/10.1002/0470033312)). Para o Cascade Study (sintético):

| Parâmetro | Obtido junto a | Forma | Documentação |
|---|---|---|---|
| Duração da restauração de um alimentador | Três despachantes da REC | Mínimo, mais provável e máximo para manobras manuais sem SCADA | Justificativa por valor; divergências registradas |
| Reserva das telecomunicações | Engenheiro de instalações da operadora | Autonomia das baterias sob a carga medida, horas de combustível do gerador | Pressuposto de carga declarado |
| Reserva da água | Gerente de operações da RWA | Autonomia do gerador mais o rebaixamento do armazenamento até a pressão mínima | Pressuposto de demanda (estação) declarado |
| Reserva do hospital | Diretor de instalações | Combustível disponível na carga típica; horas de água no local | Exigências normativas e estoque real distinguidos |
| Pesos | Painel de gestão de emergências | Comparações pareadas convertidas em pesos | Obtidos antes de qualquer simulação; assinados e datados |

As distribuições triangulares são uma escolha pragmática para elicitações de três pontos; elas não são derivadas da física. O Capítulo 6 testa se as conclusões dependem da família de distribuições.

### 4.7 O piloto

#### 4.7.1 Para que serve um piloto

Um piloto testa a **viabilidade**: se os procedimentos, os materiais, a temporização, os fluxos de dados e os instrumentos funcionam. Ele não é um pequeno estudo principal. Os tamanhos de efeito estimados a partir de pilotos são imprecisos demais para planejar tamanhos de amostra ou sustentar alegações ([Leon, Davis and Kraemer, 2011](https://doi.org/10.1016/j.jpsychires.2010.10.008)). O piloto do Cascade Study teve duas vertentes:

1. **Piloto de simulação.** Executar as quatro políticas em 50 sorteios para verificar se o código, o registro e as invariantes funcionam, se o tempo de execução permite o número planejado de sorteios e se a censura em 72 horas é rara. Os *resultados* do piloto (diferenças entre as políticas) são registrados como exploratórios e não são interpretados.
2. **Piloto do exercício de mesa.** Três operadores (participantes sintéticos P01–P03, não elegíveis para o estudo principal) percorreram um cenário de 40 minutos com e sem uma exibição do tempo até o impacto. Perguntas: Eles entendem a exibição? O cenário revela o desfecho cedo demais? Quanto tempo leva cada decisão? O processo de consentimento e de devolutiva funciona?

#### 4.7.2 Critérios de prosseguir/não prosseguir (declarados com antecedência)

| Critério | Limiar | Resultado do piloto (sintético) | Decisão |
|---|---|---|---|
| Os testes de invariantes passam | Todos | Todos | Prosseguir |
| Censura em 72 h | < 1% dos serviço-sorteios | 0% | Prosseguir |
| Tempo de execução para 500 sorteios, incluindo o oráculo | < 1 hora | Minutos | Prosseguir |
| Os participantes leem a exibição corretamente | ≥ 2 de 3 | 3 de 3 após uma mudança de redação | Prosseguir com revisão |
| O cenário revela o desfecho prematuramente | Não | Sim — um inject mencionava "desvio do hospital" | Revisar o inject; repilotar um participante |
| Duração da sessão | ≤ 60 min | 55 min | Prosseguir |

Toda revisão é registrada no registro de desvios com a data e a confirmação de que não existiam dados do estudo principal.

### 4.8 Exemplo resolvido: o piloto que mudou o cenário

No piloto do exercício de mesa, P02 perguntou por que a reserva do gerador do hospital aparecia como 26 horas quando "todo mundo sabe que a água acaba primeiro". O candidato tinha exibido apenas as reservas diretas de energia. A exibição foi revisada para mostrar o **tempo efetivo até o impacto** (o mínimo sobre todos os caminhos, como no Laboratório 3) ao lado das reservas diretas, com o caminho mostrado. Isso mudou o instrumento — um resultado legítimo de piloto — e levantou uma questão metodológica para o estudo principal: a comparação entre "com exibição" e "sem exibição" passou a testar a exibição do tempo efetivo até o impacto, e não apenas qualquer informação de criticidade. As hipóteses do exercício de mesa foram refinadas de acordo, *antes* do estudo principal, e a mudança foi pré-registrada como uma emenda.

### 4.9 Erros comuns e limites

- Declarar uma reprodução bem-sucedida depois de verificar uma única saída.
- Definir as tolerâncias depois de ver a discrepância.
- Tratar o código do benchmark como a especificação quando ele discorda de seu artigo, ou vice-versa, sem registrar qual foi seguido.
- Validar um simulador antes de verificá-lo.
- Relatar o F1 com ajuste por pontos para detecção em infraestrutura sem a latência relativa à consequência.
- Pedir números únicos aos especialistas e tratá-los como certos.
- Usar os tamanhos de efeito do piloto para planejar ou para alegar.

- Verificar apenas o setor perturbado numa reprodução, como com a energia na matriz de inoperabilidade transposta, que coincide sob as duas convenções.
- Presumir que a ordem dos parâmetros de uma biblioteca corresponde à notação do artigo, como com a distribuição triangular no caso do GridWater-Sim.
- Interpretar as diferenças entre as políticas num piloto, quando o propósito do piloto é a viabilidade e seus resultados são registrados como exploratórios.
- Mudar um instrumento do exercício de mesa após o piloto sem registrar a mudança no registro de desvios.

### Exercícios — capítulo 4

**EX021 — Registro de reprodução.** *Objetivo:* documentar uma tentativa de reprodução. *Insumos:* Laboratório 4a. *Restrições:* executar off-line; tolerância de ± 0,005 fixada antes da execução. *Passos:* (1) registrar o alvo (água 0,236); (2) executar primeiro a matriz transposta e registrar a discrepância; (3) diagnosticar usando a convenção da matriz; (4) executar a convenção correta; (5) escrever a entrada do registro com os detalhes do ambiente. *Evidência esperada:* registro de reprodução. *Rubrica:* 3 = saídas exatas, diagnóstico da convenção, ambiente registrado, observa que a energia coincide nas duas execuções; 2 = falta um elemento; 1 = sem diagnóstico; 0 = não executado.

**EX022 — Análise de perturbações no IIM.** *Objetivo:* usar um modelo reproduzido para uma alegação delimitada. *Insumos:* Laboratório 4a com a convenção correta. *Restrições:* off-line. *Passos:* (1) calcular *q* para as perturbações energia 0,5 e telecomunicações 0,5 separadamente; (2) calcular *q* para as duas juntas; (3) verificar se o resultado conjunto é igual à soma dos resultados separados e explicar por quê; (4) declarar uma alegação que o modelo sustenta e uma que ele não pode sustentar. *Evidência esperada:* três vetores e um parágrafo. *Rubrica:* 3 = vetores corretos, linearidade (superposição) explicada, alegação limitada à inoperabilidade de equilíbrio sem temporização; 2 = vetores corretos, explicação rala; 1 = erros; 0 = nada.

**EX023 — A armadilha da ordem dos parâmetros.** *Objetivo:* detectar um erro silencioso de entrada. *Insumos:* uma distribuição documentada como (low = 4, mode = 8, high = 12). *Restrições:* usar o `random.triangular(low, high, mode)` do Python. *Passos:* (1) calcular a média teórica, (low + mode + high) / 3, para a chamada correta `triangular(4, 12, 8)`; (2) estimar a média da chamada errada `triangular(4, 8, 12)` a partir de 100.000 sorteios com semente e registrar o mínimo e o máximo; explicar o que a chamada errada realmente amostra; declarar qual teste a teria detectado. *Evidência esperada:* duas médias e uma explicação. *Rubrica:* 3 = média correta 8,0; a chamada errada trata 8 como *high* e 12 como *mode*, então a fórmula do CPython retorna 4 + 4·√(2u) para *u* uniforme — valores em [4, ≈ 9,66] com média ≈ 7,77, que nem sequer é uma distribuição triangular; uma verificação da média sozinha é fraca, enquanto verificar se o máximo amostral se aproxima de 12 e traçar um histograma detecta o erro; 2 = erro identificado, teste fraco; 1 = erro não percebido; 0 = nada.

**EX024 — Testes de invariantes.** *Objetivo:* escrever testes de verificação. *Insumos:* as invariantes de §4.4 e o simulador que você vai conhecer no Capítulo 5 (Laboratório 5), ou o seu próprio. *Restrições:* pelo menos quatro invariantes como asserções executáveis. *Passos:* (1) escolher pelo menos quatro invariantes de §4.4; (2) escrever cada uma como uma asserção executável; (3) executar as asserções sobre sorteios fixos; (4) introduzir deliberadamente um defeito, como remover o atraso de reinício de um serviço, e mostrar qual teste falha. *Evidência esperada:* código dos testes e saída antes e depois do defeito. *Rubrica:* 3 = quatro ou mais invariantes significativas, o defeito detectado, explicação do porquê; 2 = os testes rodam, mas o defeito não é detectado; 1 = testes triviais; 0 = nada.

**EX025 — Métrica de detecção relativa à latência.** *Objetivo:* definir uma métrica de detecção relevante para a consequência. *Insumos:* Laboratório 4b e os valores de tempo até o impacto do Laboratório 3 (o primeiro impacto crítico em 2 h para o SCADA da água, 8 h para as telecomunicações). *Restrições:* definir a métrica formalmente. *Passos:* (1) definir "detectado antes do impacto" para um segmento com início conhecido e tempo até o impacto conhecido; (2) calculá-lo para o detector aleatório, tratando cada passo de tempo como 6 minutos e tomando o tempo até o impacto como 2 h para todo segmento; (3) comparar com os valores de F1. *Evidência esperada:* definição, fração calculada, parágrafo. *Rubrica:* 3 = definição sólida e cálculo correto a partir do índice do primeiro alarme em cada segmento, com o contraste com o PA explicado; 2 = definição boa, erro de cálculo; 1 = vaga; 0 = nada.

**EX026 — Plano do piloto.** *Objetivo:* desenhar um piloto de viabilidade. *Insumos:* seu próprio estudo dos exercícios anteriores. *Restrições:* pelo menos seis critérios de prosseguir/não prosseguir com limiares; declaração explícita do que não será estimado. *Passos:* (1) listar as perguntas de viabilidade do piloto; (2) definir limiares declarados com antecedência; (3) definir o que acontece em caso de "não prosseguir" para cada um; (4) definir quem pode participar e por que os participantes do piloto são excluídos do estudo principal. *Evidência esperada:* plano do piloto. *Rubrica:* 3 = critérios mensuráveis, apenas de viabilidade, exclusão justificada, processo de revisão registrado; 2 = um critério vago; 1 = piloto usado para estimar o efeito; 0 = nada.

### Síntese do capítulo

Antes de comparar métodos, garanta que os números significam o que alegam. Reproduza as linhas de base com uma tolerância fixada com antecedência, verifique mais de uma saída e registre as convenções — uma matriz transposta produziu uma resposta plausível e errada que coincidia justamente no valor que um replicador apressado verificaria. Diagnostique as discrepâncias pelos insumos, pela semântica, pela numérica e pela aleatoriedade. Verifique os simuladores com invariantes, testes unitários e uma implementação independente antes de validá-los. Trate com desconfiança as linhas de base de detecção que dependem do ajuste por pontos, de divisões aleatórias ou de um único testbed, e prefira, para a infraestrutura, a latência relativa ao tempo até o impacto. Obtenha os parâmetros com incerteza e procedência. Use o piloto para ajustar os procedimentos e os instrumentos, nunca para estimar efeitos.

<!-- open-cyber-academy:chapter-navigation:start ch-04 -->
### Continue estudando — capítulo 04 de 08

[← Capítulo 03](#ch-03) · [Índice de capítulos do curso](../SUBJECTS.md) · [Capítulo 05 →](#ch-05)

Siga para a próxima lição escrita.
<!-- open-cyber-academy:chapter-navigation:end -->

## Worked answers

<a id="answer-ex021"></a>
**EX021 — Registro de reprodução.** Alvo: água 0,236 (artigo sintético, Tabela 2). Tolerância de ± 0,005 fixada antes da execução. Execução 1 (matriz transposta): `[0.528, 0.028, 0.057]` — a água difere em 0,208, fora da tolerância; a energia confere. Diagnóstico: o artigo define *A\*_ij* como o efeito de *j* sobre *i*; o arquivo de entrada foi lido por colunas. Execução 2 (convenção correta): `[0.528, 0.236, 0.163]` — reproduzido. Ambiente: versão do Python, sistema operacional, data. Decisão: reproduzido após a correção de um erro de convenção no nosso tratamento da entrada. Observação: a energia coincidir nas duas execuções mostra por que verificar uma única saída é insuficiente.

<a id="answer-ex022"></a>
**EX022 — Análise de perturbações no IIM.** Energia 0,5 sozinha: `[0.528, 0.236, 0.163]`. Telecomunicações 0,5 sozinhas: `[0.057, 0.101, 0.519]`. As duas: `[0.585, 0.336, 0.682]`, que é igual à soma dos dois vetores separados (salvo arredondamento), porque o IIM é linear: *q* = (*I* − *A\**)⁻¹ *c\** e a inversa se distribui sobre a soma das perturbações. Alegação sustentada: "neste modelo linear de equilíbrio, uma perturbação combinada de energia e telecomunicações eleva a inoperabilidade da água a cerca de 0,34". Não sustentada: qualquer coisa sobre temporização, reservas, limiares ou ordem de restauração — e qualquer alegação de que uma inoperabilidade acima de 1 tem significado (modelos lineares podem exceder os limites físicos para perturbações grandes).

<a id="answer-ex023"></a>
**EX023 — A armadilha da ordem dos parâmetros.** Chamada correta `triangular(4, 12, 8)`: média (4 + 8 + 12) / 3 = 8,0. A chamada errada `triangular(4, 8, 12)` passa high = 8 e mode = 12; o CPython calcula *c* = (12 − 4)/(8 − 4) = 2 e retorna 4 + 4·√(2*u*), então os valores vão de 4 a cerca de 9,66 e a média é cerca de 7,77 (uma execução com semente de 100.000 sorteios deu mínimo 4,02, máximo 9,66, média 7,77). A saída não é uma distribuição triangular e excede o "high" documentado de 8, sem nunca chegar a 12. Uma verificação da média sozinha (7,77 contra 8,0) é facilmente descartada como ruído; uma verificação da faixa contra os limites documentados e um histograma revelam o erro imediatamente.

<a id="answer-ex024"></a>
**EX024 — Testes de invariantes.** Exemplos de asserções usando o Laboratório 5: (1) com todas as reservas acima de 72 h, a perda de toda política é 0; (2) `evaluate` com ordens idênticas dá resultados idênticos; (3) ORACLE ≤ cada política em cada sorteio; (4) aumentar a reserva de um serviço em 1 h nunca aumenta a perda sobre sorteios fixos; (5) com durações iguais, os clientes-hora de SILO ≤ os de toda permutação. Remover o atraso de reinício de um serviço *não* é detectado por nenhuma dessas invariantes — isso reduz as perdas de todas as políticas de forma consistente. Ele é detectado por um **teste unitário** sobre um único serviço: alimentador restaurado em 5 h, reserva de 2 h → intervalo de interrupção esperado (2, 6). A nota máxima tira a lição: as invariantes testam a estrutura, os testes unitários testam a semântica; você precisa dos dois.

<a id="answer-ex025"></a>
**EX025 — Métrica de detecção relativa à latência.** Definição: para cada segmento anômalo *k* com início *s_k*, primeiro alarme *a_k* (o primeiro índice sinalizado no segmento) e tempo até o impacto *T_k*, o segmento é "detectado antes do impacto" se *a_k* existir e (*a_k* − *s_k*) × Δ*t* < *T_k*. Com Δ*t* = 6 min e *T* = 2 h (20 passos): o primeiro alarme do segmento 1 está no deslocamento de 21 passos (2,1 h) → não; o do segmento 2 no deslocamento 0 → sim; o do segmento 3 no deslocamento de 29 passos (2,9 h) → não. Fração detectada antes do impacto = 1/3. Contraste: PA-F1 0,911, F1 por pontos 0,05, PA%K 0,05. A métrica de latência mostra que um detector sem nenhuma informação vence a reserva apenas por acaso — uma informação que o PA-F1 esconde por completo.

<a id="answer-ex026"></a>
**EX026 — Plano do piloto.** Um plano forte lista as perguntas de viabilidade (taxa de recrutamento, compreensão dos materiais, duração das sessões, captura de dados, tempo de execução, testes de invariantes), define limiares como em §4.7.2, especifica as respostas de "não prosseguir" (revisar e repilotar; mudar a via de recrutamento; reduzir o escopo), exclui os participantes do piloto do estudo principal porque eles já viram os materiais e suas escolhas estariam contaminadas, e declara explicitamente que nenhum tamanho de efeito será estimado nem relatado como evidência.
