Semana 1, dia 2. Percorra o ensino e o marco resolvido antes de tentar os exercícios indicados. Compare o seu artefato com a resolução final só depois.
1.2a Comportamento normal de reserva e invariantes de serviço
O que significa um serviço funcionar corretamente?
A prontidão para incidentes é mais fácil de discutir quando a organização consegue explicar o que o serviço promete a usuários legítimos. Uma página web pode responder enquanto a função por trás dela está errada. Num serviço de sala de estudo, um frequentador pode ver uma confirmação e não obter uma sala válida, ou ver um cancelamento enquanto a sala permanece indisponível para outra pessoa. Essas situações têm causas operacionais diferentes, mas ilustram um problema comum de preparação: saber que o software está alcançável não basta para especificar um resultado de negócio correto.
O capítulo 01 atual identifica a aplicação de reservas, o serviço de identidade da equipe, a base de dados, a cópia de segurança e a central de atendimento. Esse mapa de serviço nomeia componentes e donos. O contrato D1 de prontidão de evidência pergunta qual fonte poderia registrar um evento relevante, o que os campos significam e se a equipe conseguiria recuperá-lo com responsabilidade. A pergunta separada desenvolvida aqui é: Que condição observável significaria que o serviço de reserva atendeu a um requisito de negócio definido?
Uma linha de base de comportamento é uma descrição documentada de operação aceitável numa versão e num contexto especificados. Pode identificar quais estados de reserva são válidos, quando uma sala está ocupada, se um cancelamento libera um horário, como tempos sobrepostos são tratados e o que deve acontecer com um pedido inválido. O dono da regra precisa estar claro. Quem responde não deve inventar a política de reserva durante um incidente só para fazer uma teoria preferida caber nos dados.
Isto se relaciona a identificar serviços importantes e as consequências deles para o risco organizacional. O NIST Cybersecurity Framework 2.0 organiza a gestão contínua de risco de cibersegurança, e o NIST SP 800-61 Revision 3 integra a preparação de resposta a incidentes com essas atividades de gestão de risco. Nenhuma das fontes prescreve as regras de reserva deste exemplo. As regras são deliberadamente fictícias, mas a disciplina de definir e testar um resultado de serviço é reutilizável.
No nível introdutório, quem estuda deve fazer três perguntas: Que tarefa legítima o usuário espera concluir? Que resultado seria inaceitável mesmo com a aplicação ainda alcançável? Quais condições precisam ser especificadas antes de julgarmos esse resultado? Uma resposta clara é mais útil do que um indicador verde de saúde sem explicação.
Trace a jornada do usuário legítimo antes de imaginar um atacante
Uma linha de base útil de comportamento começa com uma jornada normal de usuário. Num serviço hipotético da Harbor Library, um frequentador escolhe uma sala e um horário, envia um pedido, recebe uma resposta aceita ou rejeitada e mais tarde consulta a reserva resultante. Um membro autorizado da equipe pode mover ou cancelar essa reserva. A tabela canônica R1–R8 não especifica pontos de extremidade reais, regras de transação da base nem o fluxo completo de aprovação da organização, portanto esta jornada é um modelo de ensino proposto, não uma implementação verificada.
Divida a jornada proposta em resultados pequenos:
Tabela da aula; deslize para ver todas as colunas →
| Intenção do usuário | Resultado esperado sob uma política aprovada | Comportamento negativo que vale testar |
|---|---|---|
| Procurar um horário | Os horários disponíveis seguem as regras aceitas de ocupação da sala | Um horário ocupado e confirmado aparece como livre |
| Pedir uma reserva | Um pedido permitido e sem conflito recebe um resultado consistente | Uma reserva em conflito aparece como aceita |
| Alterar uma reserva | Só o objeto pedido e permitido muda | A reserva ou a sala errada muda |
| Cancelar uma reserva | O estado é registrado e a ocupação é atualizada sob a política | Uma sala cancelada permanece bloqueada sem justificativa |
| Revisar uma reserva | A visão reflete a reserva correta e as regras relevantes de atualização | Uma reserva obsoleta ou sem relação é exibida |
A tabela não estabelece que qualquer desses erros ocorreu no caso canônico. Descreve as perguntas que um ensaio aprovado pelo responsável poderia testar antes de um incidente. Os critérios de comportamento devem ser definidos em palavras que um trabalhador da recepção consiga entender. Se o requisito não pode ser explicado sem o nome de um framework de programação ou de um produto de base de dados, pode estar preso demais ao detalhe de implementação para expressar a promessa real ao usuário.
Note também que os resultados positivo e negativo são diferentes. Mostrar que uma reserva ordinária tem sucesso não mostra que uma sobreposição inválida será rejeitada. Mostrar que um cancelamento devolve uma resposta de sucesso não mostra que a sala correta ficou disponível. A prontidão exige um conjunto pequeno de perguntas independentes, não uma demonstração vagamente bem-sucedida.
A jornada deve incluir os seus limites: o tipo de sala pretendido, o período de tempo testado, os papéis permitidos e o que conta como reserva concluída. Uma biblioteca pode ter salas compartilhadas ou reservas provisórias, mas essas capacidades não estão especificadas no exercício. Quem estuda não deve assumi-las só para explicar um problema observado.
Converta expectativas vagas em invariantes testáveis
Um invariante é uma propriedade que deve permanecer verdadeira sempre que as condições declaradas se aplicam. Para uma sala de estudo simplificada de ocupação única, uma regra plausível é que duas reservas confirmadas não devem ocupar intervalos de tempo sobrepostos na mesma sala. Uma segunda regra pode ser que uma reserva cancelada não ocupa o horário antigo. Uma terceira pode exigir que todo intervalo aceito termine depois de começar.
Um invariante só é útil com um contrato completo:
- Escopo: Quais salas, estados, representação de tempo e versão da aplicação a regra cobre?
- Pré-condições: O que precisa ser verdadeiro antes de aplicar a regra?
- Comportamento esperado: Quais valores são válidos e quais devem falhar?
- Verificação: Que resultado demonstraria conformidade para as entradas selecionadas?
- Significado da falha: O que se pode concluir quando a verificação falha, e o que permanece incerto?
Para a peça de ensino BSL1, o escopo é estreito de propósito: um dia fictício, salas de ocupação única, dois estados reconhecidos e seis objetos sintéticos de reserva. Outros significados de estado e regras de compartilhamento de sala não são inventados em silêncio. O invariante se aplica só a este modelo.
Uma regra testável é melhor do que “o sistema não deve cometer erros”. Por exemplo: “Sob a regra de ocupação única, nenhuma duas linhas confirmadas com a mesma sala podem ter intervalos de tempo semiabertos que se intersectem.” A regra especifica tanto os objetos quanto a condição. Também fornece um falseador: um par corretamente interpretado de intervalos confirmados, da mesma sala e sobrepostos, violaria a política declarada.
Esse achado ainda não identificaria a causa. Poderia resultar de um defeito de programação, de uma ação administrativa, de uma condição de corrida, de um erro de dados de teste ou de uso indevido. O invariante trata da consistência do estado de negócio. Um achado de incidente de segurança exige uma investigação separada de autorização, mecanismo e impacto.
Essa separação permite ao analista declarar um problema técnico útil sem alegar mais do que a evidência sustenta: “O modelo fornecido contém uma sobreposição que viola a regra declarada de ocupação” é defensável para a peça; “o atacante roubou uma conta da equipe e corrompeu as reservas” não é.
Os limites de tempo fazem parte da semântica do serviço
Reservas de sala são compromissos baseados em tempo. Se uma reserva usa a Room A das 09:00 às 10:00 e outra usa a sala das 10:00 às 11:00, os limites de tempo se encontram, mas não necessariamente conflitam. Se a primeira termina às 10:30, a segunda a sobrepõe. Uma política precisa especificar como trata inícios e fins.
O laboratório BSL1 usa intervalos semiabertos, em que o início está incluído e o fim está excluído. Em notação matemática isto é [início, fim). Sob esta convenção de ensino, uma reserva 09:00–10:00 não conflita com uma reserva 10:00–11:00. Uma reserva 09:00–10:30 conflita com uma reserva 10:00–11:00. Uma linha que começa e termina às 11:00 tem duração zero e é inválida.
A condição de sobreposição para dois intervalos válidos é: o primeiro começa antes de o segundo terminar e o segundo começa antes de o primeiro terminar. Comparar só se os horários de início são iguais perde intervalos sobrepostos com inícios diferentes. Tratar ambos os extremos como inclusivos cria relatos falsos de conflito para reservas adjacentes sob a convenção declarada.
Esses detalhes importam na operação. Um limite de tempo inválido pode criar um defeito de agenda visível ao usuário enquanto a aplicação está tecnicamente responsiva. Uma discrepância pode resultar de erros ordinários de implementação, de uma política incorreta ou de um fuso incompatível, e não de comportamento malicioso deliberado.
Uma aplicação real também precisaria definir horário de funcionamento, fusos, transições de horário de verão e reservas que cruzam a data. O laboratório inicial evita de propósito essas dimensões extras ao usar um dia fictício fixo com horários HH:MM. Isso evita implicar que um analisador curto de ensino seja uma implementação de agenda de produção.
Mantenha também o horário da reserva distinto do horário da evidência do incidente. R1 e R3 contêm carimbos de evento de fonte usados para entender o caso canônico. Os intervalos de sala do BSL1 descrevem horários em que um cliente poderia ocupar um espaço. Um tipo de tempo não substitui o outro. Um evento de fonte às 08:43 não significa que a reserva alterada estava marcada para 08:43.
O estado de uma reserva muda a interpretação do intervalo
Considere dois registros para a mesma sala e o mesmo horário. Se ambos estão confirmados, a política simplificada vê um conflito. Se um está cancelado, o registro cancelado já não ocupa o horário sob esta regra. Contar toda linha histórica como ativa produziria falsos positivos; tratar todo estado desconhecido como inofensivo poderia esconder conflitos reais.
BSL1 reconhece exatamente dois estados: CONFIRMED e CANCELLED. Reservas confirmadas participam das comparações de ocupação; reservas canceladas não participam. Outros valores não são mapeados automaticamente. Se uma mudança de sistema introduz um estado novo, o responsável pelo serviço deve explicar como ele afeta a ocupação, e o verificador deve ser atualizado sob um contrato versionado antes de se confiar num resultado.
Uma mudança de estado pode ser legítima ou não autorizada. O fato de o estado cancelado liberar uma sala não prova que o cancelamento foi aprovado. Também não estabelece que o usuário foi notificado ou que a auditoria histórica está completa. Isso exige testes e evidência separados. O R4 canônico original registra um cancelamento de B18, mas não contém um estado-alvo aprovado pelo responsável e não estabelece o comportamento atual de ocupação de B18.
A regra de estado é, portanto, um auxílio de preparação. Permite a uma equipe articular qual estado estaria correto se as condições aprovadas fossem conhecidas. Não pode transformar um evento impresso da aplicação num resultado de negócio verificado.
Uma pergunta útil de controle é: “Se a entrada de estado muda enquanto sala e horário permanecem constantes, qual resultado deve mudar?” A variante negativa posterior do BSL1 altera um item cancelado para confirmado e, com isso, introduz outra sobreposição. Isso mostra que o modelo é sensível ao campo de estado, em vez de gravar uma resposta preferida.
A aprovação de uma regra de negócio precisa ser versionada
O significado de uma reserva correta pode mudar. Uma biblioteca pode introduzir salas compartilhadas, alterar o horário de funcionamento, permitir retenções temporárias ou mudar o comportamento de cancelamento. Nessa situação, um teste que aplicou corretamente a regra do ano passado pode estar errado para o serviço aprovado de hoje.
Cada linha de base deve, portanto, carregar uma pequena versão de livro de regras e premissas aprovadas pelo responsável. Campos sugeridos incluem: versão, dono, data de vigência, funções afetadas, estados aceitos, categorias de sala, interpretação de tempo, amostras de entradas permitidas e proibidas, versão de implementação testada e um gatilho de revisão. Esses campos definem o comportamento correto de negócio; não substituem os campos de log de D1 nem a matriz de autorização da resposta a incidentes.
Imagine uma versão de linha de base que proíbe toda sobreposição na mesma sala. Uma versão futura pode distinguir salas de ocupação única de um espaço de estudo compartilhado. Uma colisão na sala compartilhada poderia então ser permitida segundo uma regra recém-aprovada. O processo responsável é reter ambas as versões, registrar por que a política mudou e retestar a regra nova de propósito.
Não reescreva a história aplicando uma política futura a uma decisão mais antiga sem dizê-lo. Um teste deve relatar qual versão conferiu e se essa versão se aplicava à operação examinada.
No registro canônico da Harbor Library, R6 mostra apenas que o treinamento da recepção estava agendado. Não fornece uma versão completa e aprovada de regra de reserva para B17 e B18. Quem estuda pode pedir a especificação de negócio relevante ao responsável pelo serviço, mas não pode afirmar que as regras do BSL1 já estavam ativas no ambiente fictício real da Harbor Library.
Quem começa deve entender a distinção entre “o programa está errado” e “a nossa expectativa documentada está errada”. Elas levam a passos seguintes diferentes. Corrigir o programa sem confirmar a política pode criar um erro novo; revisar uma política só para desculpar uma falha inexplicada pode ocultar um problema. Um contrato aprovado e um teste reproduzível ajudam um revisor a identificar qual premissa exige correção.
Violações de linha de base não provam comprometimento cibernético
Um alerta de segurança e um invariante de negócio falho podem aparecer juntos ou separados. Nenhum explica o outro automaticamente.
Suponha que um verificador isolado encontre duas reservas confirmadas sobrepostas na Room B. O resultado sustenta uma afirmação sobre essa peça sob a política escolhida. Não mostra que uma credencial da equipe foi roubada. Explicações possíveis incluem um defeito de lógica, uma importação malformada, um erro administrativo manual, um livro de regras desatualizado ou uma mudança intencional não autorizada. Cada explicação exigiria o próprio discriminador.
Por outro lado, uma sessão de conta não autorizada pode existir enquanto todo invariante de reserva ainda passa. Uma pessoa pode ver um registro não autorizado sem alterar uma reserva. Assim, a ausência de um problema de estado de negócio não prova a ausência de um problema de segurança.
Isto importa no primeiro marco de resposta. Um analista que observa uma entrada suspeita pode ser tentado a rotular qualquer erro posterior de reserva como obra do atacante. Mas proximidade temporal não é prova causal. R1 relata uma entrada bem-sucedida de desk-a, R3 e R4 relatam mudanças de reserva, e R5 registra uma preocupação de frequentador. Às 09:05, essas observações sustentam investigação; não fornecem uma explicação autenticada nem uma comparação de estado atual contra uma linha de base aprovada e completa.
Use um vocabulário de quatro níveis:
- Requisito especificado: o responsável pelo serviço definiu uma regra para um escopo declarado.
- Peça avaliada: um programa controlado aplicou essa regra a entradas de ensino selecionadas.
- Discrepância operacional verificada: uma comparação separada, autorizada e confiável, mostra que um serviço ao vivo não atendeu à regra aplicável.
- Mecanismo de segurança estabelecido: uma investigação independente liga a discrepância a uma causa não autorizada.
BSL1 alcança só o segundo nível. R1–R8 não provam o terceiro nem o quarto por associação com BSL1. Manter essas alegações separadas ajuda a equipe de resposta a investigar prontamente uma falha genuína de serviço sem acusar automaticamente um usuário nem minimizar uma preocupação possível de segurança.
Testes positivos, testes negativos e condições de controle
Um ensaio útil de prontidão não deve simplesmente buscar um resultado verde. Deve mostrar que entrada válida é aceita e que entrada inválida é rejeitada sob condições conhecidas.
O exemplo positivo do BSL1 consiste em reservas adjacentes. Uma reserva confirmada da Room A termina às 10:00, e outra reserva confirmada da Room A começa às 10:00. Sob a convenção semiaberta, o par não se sobrepõe.
O exemplo negativo primário contém reservas confirmadas da Room B para 09:00–10:00 e 09:30–10:30. Como os intervalos se intersectam, o verificador deve sinalizar um conflito.
Um segundo exemplo negativo é uma reserva confirmada com início e fim ambos às 11:00. A sala em si pode estar disponível, mas a reserva tem duração inválida. O teste de sobreposição não deve ser a única regra de aceitação.
O controle de cancelamento verifica uma premissa diferente. Um registro cancelado da Room A 09:00–10:00 é ignorado para ocupação ativa. Numa variante separada, mudar só esse estado para confirmado faz com que ele conflite com a reserva ativa existente. O teste revela por que o significado do estado é essencial.
Um terceiro teste de sensibilidade remove uma linha sobreposta de uma entrada de trabalho. O verificador agora relata menos problemas. Isso não significa que o sistema subjacente foi reparado; significa que o verificador já não vê todo objeto relevante. Num caso real, este é o risco de uma exportação filtrada ou incompleta do estado atual.
Cada um desses resultados precisa de uma limitação de escopo. Uma comparação bem-sucedida de intervalos adjacentes não diz nada sobre toda sala ou todo dia. Uma sobreposição sinalizada não é um impacto medido sobre frequentadores. Uma sobreposição ausente numa entrada incompleta não é prova de uma agenda segura.
Distinga falha de contrato, falha de entrada e ausência de fonte
Quando um verificador devolve um problema, quem estuda deve classificar que tipo de problema é.
Uma falha de contrato ocorre quando uma entrada interpretável viola a regra de negócio declarada — por exemplo, duas reservas válidas e confirmadas se sobrepõem na mesma sala de ocupação única.
Uma falha de qualidade da entrada ocorre quando os dados fornecidos não podem ser interpretados sob o contrato. Um intervalo de comprimento zero, um identificador de reserva duplicado ou um estado desconhecido não é necessariamente a mesma falha que uma reserva dupla. Pode refletir dados de teste malformados, um defeito do exportador ou um problema da aplicação a montante.
Uma limitação de cobertura ocorre quando registros relevantes estão ausentes do quadro de teste fornecido. Se uma linha sobreposta é omitida, o verificador pode relatar ausência de conflito apesar de a população maior permanecer inalterada. Isto não é uma demonstração de que a regra passou no escopo completo pretendido.
Essas categorias devem permanecer visíveis no resultado. Caso contrário, a equipe pode investigar o comportamento da aplicação quando na verdade precisa de uma verificação aprovada de qualidade da fonte, ou pode descartar um conflito genuíno como erro de exportador sem evidência.
O fato de uma asserção em Python ter sucesso não autentica a fonte da entrada. Para BSL1, isto é aceitável porque a peça é sintética de propósito. Uma comparação real aprovada pelo responsável exigiria, além disso, uma fonte declarada, seleção completa, carimbos de tempo, permissões de acesso e uma visão autoritativa do estado atual. Essas são perguntas separadas de evidência, cobertas por outros capítulos da edição inglesa e por D1; o laboratório de linha de base não as duplica.
Quem é novo deve conseguir explicar o resultado numa frase: “Nos dados BSL1 fornecidos, o verificador encontrou um conflito ativo de sala e uma duração inválida; as alegações mais amplas de correção limitam-se às seis linhas sintéticas e à política declarada.”
Uma interpretação errada e uma correta, em contraste
Plausível, mas incorreta:
“R1 mostra que o atacante entrou. R3 e R4 mostram que o atacante mudou reservas. O nosso teste novo de reserva encontrou uma reserva dupla; portanto a Harbor Library sofreu um ataque confirmado que danificou a agenda.”
Isto funde conjuntos de dados sem relação e faz alegações causais sem suporte. R1 contém um rótulo de conta, não uma identidade humana verificada. R3/R4 registram operações sem estabelecer a autorização delas. O teste BSL1 usa objetos da série S sem relação com o caso da série R. Não pode ser tratado como evidência nova sobre B17 ou B18.
Interpretação defensável de sala:
“No marco fictício das 09:05, R1–R8 justificam perguntar se as mudanças registradas de B17/B18 foram aprovadas e se o sintoma relatado pelo frequentador corresponde à agenda autoritativa. O operador, o escopo completo do treinamento e a correção atual do estado de negócio permanecem sem resolução. À parte, a peça BSL1 demonstra como definir e conferir dois invariantes de reserva em objetos inventados; essas verificações não fazem achado algum sobre o incidente da Harbor Library.”
A interpretação melhor identifica uma próxima pergunta válida e preserva a fronteira da fonte. Também evita dizer que uma ausência de achados BSL1 inocentaria a conta ou provaria que não houve exposição de dados. Um invariante de negócio é uma parte útil da prontidão, não um detector universal de segurança.
A edição atualizada oficial do NIST SP 800-34 Rev. 1 trata de avaliar sistemas e operações para requisitos e prioridades de contingência. Não define a política de reserva da Harbor Library nem confirma qualquer evento da série R. A aplicação de ensino aqui é que uma organização se beneficia de entender resultados críticos de serviço antes de uma interrupção, em vez de inventar um teste de correção só depois que algo parece suspeito.
Torne a linha de base portátil através de uma mudança de serviço
Uma regra deve permanecer compreensível quando o software ou a hospedagem muda. A frase “a consulta à base devolveu zero linhas” depende de uma implementação e de uma seleção particulares. A frase “duas reservas confirmadas de ocupação única não devem se sobrepor na mesma sala” expressa uma expectativa de negócio que pode ser avaliada por caminhos de teste autorizados diferentes.
Essa portabilidade sustenta a prontidão para incidentes. Se um serviço migra de um monólito para componentes separados, as fontes de log podem mudar. A promessa central de negócio pode permanecer estável. Uma linha de base de comportamento dá ao responsável pelo serviço um modo de reconhecer se a migração ainda produz resultados aceitáveis; D1 precisa ser atualizado à parte para identificar onde a evidência pode agora ser coletada.
Portabilidade não significa universalidade. Uma versão posterior do serviço pode alterar legitimamente a política. A regra precisa, portanto, de versão, escopo e histórico de mudança. Um bom teste pode relatar tanto o resultado esperado da política antiga quanto o resultado novo proposto, sem apagar o registro anterior de aceitação.
Considere uma atualização fictícia de software que muda a representação de reservas canceladas. Se uma linha de base passa de repente a sinalizar conflitos, a equipe deve primeiro conferir se entradas canceladas estão sendo contadas incorretamente como ativas ou se o significado efetivo do estado mudou. Essa é uma pergunta sobre alinhamento de contrato e de teste, ainda não um achado de comprometimento.
O responsável pelo serviço deve definir o resultado pretendido para o usuário e aprovar mudanças no significado. A equipe técnica pode expressar e ensaiar a regra em código. A equipe de resposta a incidentes pode mais tarde usar a regra aprovada como referência ao investigar uma falha relatada de serviço. Nenhum desses papéis ganha autoridade para inspecionar dados reais de frequentadores só porque existe um programa de demonstração.
Um modelo de relatório para quem estuda no primeiro mês
Depois de um ensaio de linha de base, quem estuda deve produzir um relatório de contrato, não um relatório de incidente. O documento deve identificar a versão da regra, os identificadores de entrada, a ocupação de sala assumida, a semântica de estado, a convenção de intervalo, os resultados esperados positivos e negativos, a saída executada ou raciocinada, e as alegações exatas que a verificação não pode estabelecer.
Um relatório claro pode afirmar:
“BSL1-v1 aplica-se a seis linhas fictícias de reserva de um dia. O verificador testa a validade do intervalo e sobreposições na mesma sala entre reservas confirmadas, sob limites de tempo semiabertos. Encontra S03/S04 em conflito e S06 inválido. Uma variante independente de mudança de estado acrescenta um conflito S01/S05; omitir S04 de uma entrada copiada remove um conflito detectado sem provar reparo do serviço. Nenhum estado real de reserva, usuário, conta, fonte de log ou serviço de produção foi testado.”
Este é um artefato útil porque outra pessoa que estuda pode reproduzir toda classificação relevante a partir da entrada declarada. Também impede que a falha de um requisito de brinquedo se torne uma alegação sem suporte de incidente no mundo real.
Para quem começa, o resultado aceito não é matemática complicada nem uma avaliação abrangente de segurança da aplicação. É uma explicação que liga expectativa de negócio → premissas declaradas → comparação reproduzível → conclusão restringida. O estágio curricular seguinte pode então ensinar como um analista de resposta a incidentes obtém observações confiáveis e as separa de hipóteses.
Este relatório complementa, em vez de substituir, o contrato existente D1 de prontidão de evidência, o laboratório de revisão de alegações R1–R8 e a passagem do caso. As ferramentas respondem a perguntas diferentes, e um pacote maduro de prontidão mantém essas fronteiras explícitas.
Síntese da seção: a preparação começa com uma promessa explícita
O mapa de serviço diz quais sistemas podem importar. A linha de base de comportamento diz o que o serviço legítimo deve alcançar. O plano de prontidão de evidência diz quais fontes autorizadas poderiam mais tarde sustentar ou contestar uma alegação. O registro de decisão do caso afirma o que a equipe de fato sabe e qual próxima ação exige aprovação. São artefatos complementares com propósitos distintos.
Para a Harbor Library, um invariante sobre ocupação confirmada de sala oferece um exemplo prático de comportamento normal. Não estabelece que B17/B18 foram modificadas de forma incorreta, nem fornece um ator humano, uma lista autorizada de tarefas, um resultado de restauração ou uma conclusão de transferência de dados. O juízo canônico das 09:05 ainda se apoia só em R1–R8.
Um estudante sólido do primeiro mês deve terminar capaz de explicar por que uma reserva adjacente permitida passa, por que um par confirmado sobreposto falha, por que o cancelamento muda a ocupação, por que entradas incompletas podem esconder um conflito, e por que nenhum desses resultados de peça, sozinho, prova um incidente de segurança. Isso é conhecimento substantivo adicional de prontidão, não uma recontagem do caso do incidente.
Laboratório offline BSL1 — invariantes de reserva
Meta: Reproduzir uma verificação determinística de invariante de negócio para um conjunto fictício pequeno de reservas e, em seguida, demonstrar como uma mudança de estado ou uma entrada ausente altera o que o verificador pode relatar.
Ambiente: biblioteca padrão do Python 3, só memória. Sem criação de arquivo, pedidos de rede, autenticação, registros pessoais ou mudanças de produção.
Classificação da peça: Os identificadores S01–S06 são objetos inventados de treinamento BSL1 e não têm relação com as reservas canônicas B17–B20 da Harbor Library nem com R1–R8.
Regras: Reservas confirmadas ocupam o intervalo da sala; reservas canceladas não ocupam. Os intervalos de reserva são semiabertos [início, fim), o fim precisa ser estritamente posterior ao início, e sobreposições confirmadas simultâneas na mesma sala são proibidas sob esta política de brinquedo de ocupação única.
Tabela da aula; deslize para ver todas as colunas →
| ID | Sala | Início | Fim | Estado |
|---|---|---|---|---|
| S01 | Room A | 09:00 | 10:00 | CONFIRMED |
| S02 | Room A | 10:00 | 11:00 | CONFIRMED |
| S03 | Room B | 09:00 | 10:00 | CONFIRMED |
| S04 | Room B | 09:30 | 10:30 | CONFIRMED |
| S05 | Room A | 09:00 | 10:00 | CANCELLED |
| S06 | Room C | 11:00 | 11:00 | CONFIRMED |
Antes de executar, preveja os achados de base. Explique por que S01 e S02 não se sobrepõem, e por que S05 não ocupa o horário da sala. Em seguida, preveja o resultado quando só S05 muda para confirmado e quando S04 é omitido de propósito de uma cópia de trabalho incompleta.
Programa reproduzível em Python 3
from itertools import combinations
BOOKINGS = [
("S01", "Room A", "09:00", "10:00", "CONFIRMED"),
("S02", "Room A", "10:00", "11:00", "CONFIRMED"),
("S03", "Room B", "09:00", "10:00", "CONFIRMED"),
("S04", "Room B", "09:30", "10:30", "CONFIRMED"),
("S05", "Room A", "09:00", "10:00", "CANCELLED"),
("S06", "Room C", "11:00", "11:00", "CONFIRMED"),
]
def minute(text):
hours, minutes = map(int, text.split(":"))
if not (0 <= hours < 24 and 0 <= minutes < 60):
raise ValueError("invalid clock field")
return hours * 60 + minutes
def overlaps(a, b):
return (
minute(a[2]) < minute(b[3])
and minute(b[2]) < minute(a[3])
)
def inspect(rows):
if len({r[0] for r in rows}) != len(rows):
raise ValueError("duplicate booking ID")
issues = []
for row_id, room, start, end, status in rows:
if status not in {"CONFIRMED", "CANCELLED"}:
issues.append(f"UNKNOWN_STATUS {row_id}")
if minute(start) >= minute(end):
issues.append(f"INVALID_INTERVAL {row_id}")
active = [
row for row in rows
if (
row[4] == "CONFIRMED"
and minute(row[2]) < minute(row[3])
)
]
for first, second in combinations(active, 2):
if first[1] == second[1] and overlaps(first, second):
issues.append(f"CONFLICT {first[0]}/{second[0]}")
return sorted(issues)
baseline = inspect(BOOKINGS)
for issue in baseline:
print("BASE", issue)
print("BASE_COUNT", len(baseline))
print(
"BOUNDARY_S01_S02",
"OVERLAP" if overlaps(BOOKINGS[0], BOOKINGS[1])
else "NO_OVERLAP",
)
print(
"CANCELLED_S05",
"NOT_OCCUPYING"
if BOOKINGS[4][4] == "CANCELLED"
else "OCCUPYING",
)
# Controlled status-change variant: S05 only.
variant = [
(*row[:4], "CONFIRMED") if row[0] == "S05" else row
for row in BOOKINGS
]
changed = inspect(variant)
for issue in changed:
print("VARIANT", issue)
print("VARIANT_COUNT", len(changed))
# Incomplete-input negative control: omit S04 only.
incomplete = [row for row in BOOKINGS if row[0] != "S04"]
missing = inspect(incomplete)
for issue in missing:
print("INCOMPLETE", issue)
print("INCOMPLETE_COUNT", len(missing))
assert baseline == ["CONFLICT S03/S04", "INVALID_INTERVAL S06"]
assert len(changed) == 3
assert len(missing) == 1
Compare o resultado impresso e os limites com a resolução BSL1 no apêndice final. As seis entradas da série S são uma peça separada de preparação, nunca evidência do caso para R1–R8.
Unidade de revisão da semana 1, número 2 — Não transformar uma entrada vazia numa agenda limpa
Objetivo e comportamento observado
Explique como rejeitar um quadro de ensaio incompleto ou ininterpretável, preservando os achados originais da regra de reserva. Esta unidade estende o BSL1; não muda a convenção de intervalo semiaberto, os significados de estado confirmado/cancelado nem a peça S01–S06.
No programa original, inspect([]) devolve []. Isto é consistente com conferir pares numa sequência vazia: não há pares conflitantes fornecidos. Não é uma demonstração de um quadro saudável de seis reservas. Do mesmo modo, minute("9:00") devolve 540 porque o analisador converte as duas peças numéricas; não impõe uma representação de hora com dois dígitos. A linha de base original usa cadeias bem formadas, portanto os resultados existentes não são invalidados por essas sondas.
A guarda proposta torna explícito o contrato adicional do ensaio. Os identificadores esperados precisam ser um conjunto congelado não vazio; cada linha precisa conter cinco cadeias não vazias; os campos de relógio precisam usar exatamente dois dígitos ASCII, dois-pontos e dois dígitos ASCII, com intervalos válidos de hora e minuto; os estados precisam ter os dois significados definidos; os identificadores precisam ser únicos e coincidir exatamente com o quadro declarado.
São convenções locais de ensino, não requisitos universais para APIs reais de reserva. Um serviço real pode usar legitimamente listas JSON, outros modelos de estado ou uma representação diferente de carimbo de tempo. Precisa da própria interpretação documentada. A documentação de expressões regulares do Python explica a correspondência da cadeia inteira; não prescreve o nosso contrato de tempo ou de reserva.
Por que o achado de duração precisa sobreviver
S06 tem horários de início e fim iguais. Ambos os campos são interpretáveis sob o contrato de relógio. O invariante original, portanto, ainda relata INVALID_INTERVAL S06; a guarda não repara em silêncio o horário de fim, não descarta a linha nem a reinterpreta como cancelamento. Admissão da entrada e achados da regra de negócio permanecem separados.
A mesma distinção se aplica a um quadro completo que contém um conflito genuíno modelado. Uma boa guarda precisa admitir as linhas interpretáveis e deixar a regra original relatar o conflito. Rejeitar toda entrada problemática impediria quem estuda de ver a condição de negócio que o laboratório foi desenhado para ensinar.
Extensão reproduzível do BSL1
Rode primeiro a listagem original completa do BSL1 numa sessão nova. Preveja cinco linhas novas antes de rodar a extensão seguinte. O resultado é condicional ao quadro esperado fornecido; nem a igualdade de identificadores nem a sintaxe estrita autenticam uma fonte.
# Run after the complete BSL1 listing, in the same Python session.
import re
W1_BSL_EXPECTED = frozenset({"S01", "S02", "S03", "S04", "S05", "S06"})
def w1_inspect_scoped(rows, expected_ids=W1_BSL_EXPECTED):
if type(expected_ids) is not frozenset or not expected_ids:
raise ValueError("INVALID_EXPECTED_SCOPE")
if any(type(item) is not str or not item.strip() for item in expected_ids):
raise ValueError("INVALID_EXPECTED_SCOPE")
if type(rows) not in (list, tuple) or not rows:
raise ValueError("EMPTY_OR_INVALID_INPUT")
ids = []
for row in rows:
if type(row) not in (list, tuple) or len(row) != 5:
raise ValueError("INVALID_ROW_SHAPE")
if any(type(item) is not str or not item.strip() for item in row):
raise ValueError("INVALID_FIELD_TYPE")
row_id, room, start, end, status = row
ids.append(row_id)
for text in (start, end):
if re.fullmatch(r"[0-9]{2}:[0-9]{2}", text) is None:
raise ValueError("CLOCK_FORMAT")
minute(text) # Reuse BSL1's hour/minute range check.
if status not in {"CONFIRMED", "CANCELLED"}:
raise ValueError("UNKNOWN_STATUS")
if len(ids) != len(set(ids)):
raise ValueError("DUPLICATE_ID")
if frozenset(ids) != expected_ids:
raise ValueError("COVERAGE_MISMATCH")
return inspect(rows) # Preserve BSL1's overlap/duration findings.
def w1_show_bsl(label, rows, expected_ids=W1_BSL_EXPECTED):
try:
issues = w1_inspect_scoped(rows, expected_ids)
except ValueError as error:
print(label, "INPUT_REJECTED", str(error))
else:
print(label, "EVALUATED", ";".join(issues) if issues else "NO_FINDINGS_IN_SCOPE")
w1_bad_clock = [
(row[0], row[1], "9:00", row[3], row[4]) if row[0] == "S01" else row
for row in BOOKINGS
]
w1_show_bsl("W1_BASE", BOOKINGS)
w1_show_bsl("W1_EMPTY", [])
w1_show_bsl("W1_MISSING_S04", [r for r in BOOKINGS if r[0] != "S04"])
w1_show_bsl("W1_BAD_CLOCK", w1_bad_clock)
w1_show_bsl("W1_NARROW_SCOPE", [BOOKINGS[0]], frozenset({"S01"}))
A última chamada declara de propósito um quadro diferente, de um objeto. Não é uma versão reparada do teste de seis objetos. Mantenha esses dois relatórios separados. Retenha também as demonstrações originais de sensibilidade do BSL1 à mudança de estado e à linha omitida: elas ensinam o que o modelo sem guarda vê, enquanto esta extensão ensina se um resultado responde a um quadro pré-declarado.
Prática suplementar W1-R2
Objetivo: diagnosticar entrada vazia, ausente e malformada sem suprimir achados válidos de invariante. Entradas: as seis linhas originais do BSL1 e as cinco chamadas acima. Artefato exigido: a saída de cinco linhas, uma explicação de cinco linhas sobre admissão versus resultado de invariante, e um pedido de fonte proposto para o caso de S04 ausente. Restrições: preserve S06 inalterado; não modifique o BOOKINGS original; não redefina o quadro de seis objetos para obter um resultado verde. Explique se conferir identificadores prova coleta autêntica ou completa no mundo real.
Avaliação: um ponto para cada um: achados de linha de base inalterados, rejeição de entrada vazia, rejeição de linha ausente, explicação do relógio estrito, e resultado de uma linha corretamente limitado. Alegações de autenticação da fonte ou de reparo do serviço precisam ser corrigidas. Os EX002, EX005 e EX010 originais mantêm os requisitos de duas linhas, quatro linhas e duas frases; este artefato suplementar não é inserido nesses campos exigidos. Resolução.
Rubrica: 3 = cinco pontos da fonte: linha de base inalterada, rejeição do vazio, rejeição da linha ausente, relógio estrito e resultado de uma linha limitado;; 2 = a maior parte desses pontos, com uma omissão de limite;; 1 = responde, mas omite fonte, limite ou a distinção entre admissão e invariante;; 0 = nenhum.
Síntese da revisão
“Nenhum achado nas linhas fornecidas” não é a mesma alegação que “a entrada pretendida estava completa”, e nenhuma das duas é um achado universal de segurança do serviço.
Marco resolvido
Uma chamada de edição bem-sucedida não é prova de que o estado da reserva atende à regra aprovada pelo responsável. Na peça BSL1, compare primeiro o estado final da reserva com o invariante declarado; depois teste à parte a variante controlada de mudança de estado. Nenhum dos resultados se torna um fato de incidente da série R.
Prática — Aula 02
EX002 — As duas primeiras perguntas
Objetivo: escolher verificações que poderiam mudar a decisão de restrição. Entradas: R1–R6 e as tabelas de serviço e de autoridade. Saída: duas linhas com uma pergunta precisa, o fato que a torna relevante, o custodiante ou a pessoa autorizada a quem perguntar, e como qualquer das respostas muda a decisão. Uma pergunta precisa testar a explicação do treinamento; a outra precisa testar quem usou a conta ou se as edições continuam. Registre pedidos em vez de dizer que a entrevista ou a revisão de log já ocorreu. Uma nota 2 exige discriminadores diferentes e um caminho nomeado de aprovação para qualquer coleta nova de identidade.
Extensão de linha de base de comportamento: Na pergunta de treinamento, especifique qual comportamento aprovado pelo responsável para B17/B18 precisa ser conferido além da entrada de calendário de R6. Na pergunta de conta, separe um discriminador de fonte da pergunta ainda aberta de contrato de negócio. Os resultados da série S do BSL1 não são evidência sobre B17/B18.
Resolução: EX002 no apêndice final.
Rubrica: 3 = nota 2 da fonte: duas linhas com discriminadores diferentes, caminho nomeado de aprovação para coleta nova de identidade, e a série S fora da evidência de B17/B18;; 2 = as duas linhas existem, mas falta um discriminador ou o caminho de aprovação;; 1 = responde à pergunta, mas omite fonte, limite, autoridade ou teste exigido;; 0 = nenhum.
EX005 — Linha do tempo
Objetivo: preservar a ordem dos eventos sem transformar sequência em causação. Entradas: R1, R3, R4 e R5. Saída: uma tabela UTC de quatro linhas com identificador do registro, fonte, hora e evento observado, seguida de uma frase de ordenação e de uma frase separada de causalidade sem suporte. Mantenha a hora de abertura do caso, 09:00, fora da tabela de eventos. Uma nota 2 ordena os quatro eventos corretamente e explica por que a precedência, sozinha, não identifica o ator humano nem prova por que a visão do frequentador mudou.
Extensão: Acrescente uma nota separada de marco case opened 09:00; decision 09:05; available R1–R8. Explique por que os horários de abertura do caso e de decisão não devem ser inseridos na cronologia de quatro linhas de eventos de fonte como se fossem eventos de fonte.
Para crédito completo: Uma resposta de 2 pontos preserva a cronologia e rejeita atribuição humana e causalidade sem suporte.
Resolução: EX005 no apêndice final.
Rubrica: 3 = nota 2 da fonte: quatro eventos na ordem correta, frase de ordenação, frase de causalidade sem suporte, e 09:00 fora da tabela de eventos de fonte;; 2 = a ordem está correta, mas falta o limite de causalidade ou de ator;; 1 = responde à pergunta, mas omite fonte, limite ou a separação entre ordem e causa;; 0 = nenhum.
EX010 — Rascunho de comunicação
Objetivo: comunicar uma ação útil sem atribuição prematura. Entradas: R1–R8 e o estado de abertura às 09:00, antes da decisão das 09:05. Saída: exatamente duas frases para um público interno de responsável pelo serviço: a primeira declara sinais observados de serviço e incerteza; a segunda nomeia uma próxima verificação proposta, o dono dela e o marco esperado de decisão às 09:05. Não diga que preservação, entrevista ou restrição já foi aprovada ou executada. Uma nota 2 fornece um ponteiro de fonte e uma distinção inequívoca entre trabalho planejado e trabalho concluído.
Extensão de linha de base de comportamento: Mantenha exatamente duas frases no marco de abertura das 09:00. Distinga os registros de edição R3/R4 e o relato de frequentador R5 de um estado de negócio incorreto verificado; nomeie uma verificação proposta, pelo responsável pelo serviço, do comportamento esperado, antes da decisão das 09:05.
Resolução: EX010 no apêndice final.
Rubrica: 3 = nota 2 da fonte: exatamente duas frases, ponteiro de fonte, e distinção inequívoca entre trabalho planejado e concluído no marco das 09:00;; 2 = as duas frases existem, mas a distinção entre proposta e execução fica ambígua;; 1 = responde à pergunta, mas omite fonte, limite ou trata trabalho planejado como feito;; 0 = nenhum.