Pular para o conteúdo

O que é um caso

Um caso é a unidade de prática no Fito: um repositório que a pessoa que aprende bifurca, trabalha e devolve como um pull request. Esta página descreve do que um caso é feito, antes de você construir qualquer parte dele.

Leia se você vai criar um caso. Ela cobre o formato do artefato e as palavras que os comandos de criação usam. Ela não cobre os comandos em si — cada um tem a sua própria página — e não cobre jogar um caso, que é Abrir e trabalhar um caso.

Um caso vive no próprio repositório git, na sua conta ou na sua organização. O Fito nunca o hospeda. O que o Fito guarda é a URL https, a versão e o conhecimento que o caso afirma ensinar.

Três tipos de ref vivem nesse repositório, e eles têm durações diferentes:

Ref O que é Duração
main O ramo de desenvolvimento. Onde você edita Seu, sempre
vX.Y.Z Um ramo e uma tag, criados na publicação Congelados para sempre
case/solution-vX.Y.Z A solução exemplar daquela versão Congelados para sempre

Quem aprende clona o vX.Y.Z congelado, então o que a pessoa recebe nunca se move sob os pés dela. Quando você corrige um caso, você cria refs congelados novos ao lado dos antigos; você nunca reescreve um.

A identidade do caso é um UUID que o backend atribui no registro. Ela não está escrita em lugar nenhum do repositório, e é o <id> da URL /cases/<id> do caso.

O código desse repositório existe em dois estados, e você constrói os dois.

Estado Onde vive O que é
Inicial O ramo congelado vX.Y.Z O que quem aprende recebe
Solução case/solution-vX.Y.Z O exemplo resolvido, para quem avalia

O que cada estado contém decorre do tipo do caso. Um estado inicial diagnostic carrega o defeito, e a solução dele repara. Um implementation carrega a lacuna, e a solução preenche. Um tutorial pode usar o mesmo código nos dois, e ainda assim nomeia um ramo de solução.

.case/ é igual nos dois. Ele descreve o caso, não um ramo, então a pasta no ramo da solução precisa ser igual à que quem aprende recebe. O passo de publicação confere isso e reconcilia os dois antes de enviar, então uma divergência é pega em vez de publicada — mas é mais fácil nunca criar uma.

É também por isso que starter_state/known_state.yaml não tem campo branch: um arquivo que descreve todos os refs nunca conseguiria nomear um ramo certo.

Todo caso declara um type, e o tipo determina o que o caso precisa conter. O validador estrutural cobra essa regra.

Tipo O que quem aprende faz O que o tipo exige
diagnostic Encontra e repara um defeito starter_state/known_state.yaml traz failing_tests ou known_errors
implementation Constrói uma funcionalidade task/deliverables.yaml inclui uma entrada code_change
tutorial Segue passos guiados pelo código task/steps.md existe, e failing_tests não pode aparecer

.case/ é o contrato. Ele fica ao lado do código do próprio projeto, e descreve o caso em todos os refs.

Quatorze arquivos são sempre obrigatórios:

Arquivo O que carrega
manifest.yaml Título, tipo, versão, status, duração, idioma, tags, autoria e como uma solução é entregue
artifacts.yaml Os arquivos do projeto que importam, cada um com um papel
learning_objectives.yaml O que o caso desenvolve
prerequisites.yaml O que quem aprende já precisa ter
rubric.yaml Os critérios contra os quais o trabalho é avaliado
solution.yaml O ramo exemplar e quem pode vê-lo
situation/situation.yaml A lista de documentos narrativos
situation/01_intro.md A situação em que quem aprende cai
task/objective.md A declaração única do objetivo
task/deliverables.yaml As saídas esperadas
starter_state/description.md A condição inicial, em prosa
starter_state/known_state.yaml A condição inicial, legível por máquina
solution/notes.md A abordagem pretendida — para quem avalia, nunca para quem aprende
solution/notes-template.md O rascunho em branco dessas mesmas seções

Outros quatro são condicionais ou opcionais:

  • task/steps.md — obrigatório num tutorial, e só nele.
  • quiz.yaml — opcional. Um caso pode trazer perguntas ao lado da rubrica.
  • task/constraints.md — opcional. Regras dentro das quais quem aprende precisa trabalhar.
  • Outros documentos de situação — um chamado, um e-mail, um log — cada um listado em situation/situation.yaml com o seu format.
  • acceptable_solutions em solution.yaml — outros ramos que também resolvem o caso, cada um com um id e uma descrição opcional.

O visibility do solution.yaml decide quando quem aprende pode ver o exemplar: never, post_completion ou always. A geração propõe post_completion a não ser que você escolha outro.

Quatro desses arquivos nomeiam componentes de conhecimento (knowledge components), cada um com um nível de Bloom:

  • learning_objectives.yaml — o que o caso desenvolve. Pelo menos uma entrada, e pelo menos uma delas com weight: primary.
  • prerequisites.yaml — o que quem aprende já deveria ter. Cada entrada é mandatory: true ou false.
  • rubric.yaml — todo critério está ancorado em um componente, e todo objetivo de aprendizagem está ancorado por pelo menos um critério.
  • quiz.yaml — cada pergunta nomeia um ou mais.

Uma referência é escrita inteira, na forma <type>:<technology-slug>.<component-slug>, por exemplo concept:javalin.handler. Os três tipos são concept, execution-fact e usage-scenario.

Juntas, elas formam o conjunto de referências do caso: os pares de componente e nível de Bloom, sem repetição. É o que o backend resolve quando você publica, e é o que congela.

Essa regra é o motivo de escolher as referências ser a parte mais lenta de desenhar um caso, e de isso acontecer antes de qualquer coisa ser escrita.

Um critério da rubrica ou uma pergunta do quiz atendidos com nota 2 ou 3 registram o seu próprio nível de Bloom como a proficiência registrada para o componente que nomeiam, e os selos de pré-requisito na capa de um caso leem essas mesmas proficiências. Então um critério apontado para um pré-requisito deixa o caso conceder o pré-requisito que pediu a quem aprende para já trazer, e o próximo caso que precisa daquele componente lê You have this com base num caso que o exigia.

Três regras valem, e são cobradas em lugares diferentes:

  • Todo objetivo de aprendizagem é pontuado por pelo menos um critério da rubrica. O validador rejeita uma árvore que quebra isso, então você descobre antes de publicar. Uma pergunta do quiz não satisfaz a regra, porque o quiz é opcional.
  • Todo objetivo de aprendizagem é alcançável no seu próprio nível. Pelo menos um desses critérios declara o nível de Bloom do objetivo ou um mais alto, porque um critério não registra mais do que o nível que declara. Um critério APPLICATION cobre um objetivo COMPREHENSION, então um mesmo componente pode ser avaliado em duas profundidades. O validador também rejeita uma árvore que quebra isso.
  • Todo critério e toda pergunta nomeiam um objetivo de aprendizagem. Aqui o validador aceita o que poderia rejeitar — um critério apontado para um pré-requisito, ou para um componente que o caso não referencia em nenhum outro lugar. Em vez disso, /fito-case-design faz a comparação por você e reporta cada falta em Open questions na proposta, para você decidir.

A terceira é um aviso, e não uma recusa, porque a checagem estrutural também roda quando alguém abre um caso — e um caso já publicado assim precisa continuar abrindo.

Tudo sob solution/ é para quem avalia. Quem aprende é informado pela situação, pela tarefa, pelas restrições, pelas entregas, pelos artefatos e pelos objetivos de aprendizagem — nunca pelas notas da solução.

Dois arquivos alcançam mais longe do que parecem:

  • learning_objectives.yaml alimenta a página pública do catálogo, que qualquer pessoa pode ler antes de se inscrever.
  • prerequisites.yaml e os arquivos de tarefa são lidos para quem aprende no briefing.

Por isso a prosa desses arquivos carrega uma regra.

Uma descrição pode dizer o que está quebrado e o que quem aprende vai conseguir fazer. Ela não pode dizer a jogada que repara aquilo.

O teste é uma única pergunta:

Alguém que leu só esta descrição, e nada mais do caso, conseguiria aplicar a correção?

Se sim, reescreva.

  • ✗ “Rastreie uma requisição que falha pela cadeia ordenada de handlers, identifique o before-handler que a interrompe antes do roteamento e aplique uma correção idiomática.” — isso entrega o diagnóstico.
  • ✓ “Rastreie uma requisição que falha pela cadeia ordenada de handlers e repare a composição que a quebra.” — o mesmo objetivo, com o diagnóstico deixado para quem aprende.

Casos tutorial estão isentos. Os passos deles são o método, então não há o que esconder. A rubrica também está isenta: um nível de pontuação não consegue descrever uma resposta exemplar sem nomear o que aquela resposta faz, e a rubrica nunca é lida para quem aprende.

Nada confere essa regra. Ela é sustentada pelos comandos de criação e pela sua revisão.