Resumo
- O
draft-ietf-jmap-object-history-00acrescenta versões anteriores e destruídas aoFoo/get, mas permite condensar atualizações rápidas, remover versões em qualquer ordem e descartar histórico silenciosamente sob pressão de armazenamento. - Um retrato recuperado ajuda a restaurar dados. Ele não identifica ator, pedido, decisão de autorização nem efeito posterior; até
hasMoreHistory: falseé incapaz de certificar que o histórico está completo.
Um catálogo de contatos pode trazer de volta o telefone removido ontem. Uma caixa postal pode mostrar a mensagem como estava imediatamente antes da exclusão. É uma função útil: torna reversível um erro e evita que cada cliente invente seu próprio arquivo paralelo.
Os mesmos campos, porém, podem transmitir uma certeza que o protocolo não oferece. Um ID constante, um número de versão e um horário de substituição viram facilmente uma linha do tempo elegante. Nenhum deles diz quem agiu, qual cliente enviou a mutação, qual regra autorizou a operação ou se a consequência posterior aconteceu.
Essa é a fronteira decisiva do JMAP Object History, enviado em nome do grupo de trabalho em 15 de setembro. A proposta torna consultável um estado antigo. Ela não transforma um depósito de recuperação em livro de auditoria.
O protocolo devolve estados retidos, não eventos
O núcleo do JMAP define uma família de métodos para cada tipo de objeto: Foo/get, Foo/changes, Foo/set, Foo/query e Foo/queryChanges. A sincronização do estado atual já faz parte da arquitetura. Foo/changes informa quais IDs mudaram entre estados, mas não entrega os valores anteriores.
A capability urn:ietf:params:jmap:object-history amplia Foo/get. Com includeReplaced: true, representações substituídas aparecem ao lado do objeto vigente. Com includeDestroyed: true, é possível pedir objetos que deixaram de existir. Se os dois forem usados, o servidor pode devolver todas as versões ainda retidas de um objeto destruído.
Cada versão conserva o mesmo ID. objectHistory.version estabelece a ordem dentro da resposta. objectHistory.replaced registra quando aquela representação foi substituída por atualização ou destruição; null marca o objeto vivo.
São coordenadas de estado, não a proveniência de um acontecimento. O horário de substituição não informa quando a versão nasceu. O número não nomeia uma transação. Nenhum campo traz ator, sessão, dispositivo, corpo do pedido, política aplicada, aprovação, motivo, notificação ou efeito externo.
Dois retratos vizinhos permitem calcular a diferença de valores. Não demonstram que uma única ação atômica causou essa diferença.
O meio ausente talvez nunca tenha sido registrado
O texto permite explicitamente que o servidor reúna várias atualizações rápidas em uma só versão. Se um número de telefone for alterado três vezes em pouco tempo, talvez reste apenas o valor anterior e o posterior ao intervalo. Não é obrigatório criar uma linha histórica para cada ação.
Também é permitido podar versões antigas em qualquer ordem. Lacunas na sequência são válidas, e o cliente não pode presumir que o histórico seja contínuo ou completo. Uma ausência admite duas explicações: uma versão separada nunca foi criada, ou foi criada e eliminada depois.
Até o número é fraco entre consultas. O servidor deve procurar consistência, mas o cliente não pode depender dela. A finalidade principal é ordenar versões do mesmo objeto em uma resposta. Tratá-lo como ID durável de evento de auditoria exigiria uma propriedade que a proposta deliberadamente não promete.
Isso dá honestidade econômica ao desenho. Também torna inválida a pergunta “mostre tudo o que aconteceu” quando não existe um sistema de eventos separado.
hasMoreHistory é orientação de busca, não certificado de completude
historyLimit limita o total de entradas e pede as versões mais recentes. Se o limite for alcançado para qualquer ID solicitado, hasMoreHistory: true informa que há material retido mais antigo naquele momento. Numa resposta com vários objetos, não revela qual deles tem continuação; cada um precisa ser consultado separadamente.
O valor verdadeiro é transitório. A proposta avisa que as entradas antigas podem ser eliminadas antes da próxima chamada. A marca descreve disponibilidade instantânea, não reserva os dados.
O valor falso é ainda menos conclusivo. Normalmente significa que todo o histórico retido para aqueles IDs foi devolvido. Mesmo assim, o servidor pode responder falso quando há mais histórico se for caro demais determiná-lo. E falso não quer dizer que toda mudança foi capturada, que nada foi podado ou que toda representação ainda existente foi encontrada.
Um painel que converta falso em “auditoria completa” inverte o contrato. O rótulo defensável é mais limitado: nenhum histórico retido adicional foi informado nesta resposta.
Duração nula não quer dizer retenção eterna
Uma conta que anuncia a capability expõe maxHistoryDuration. Um número é a idade máxima, em segundos após a substituição, depois da qual uma versão pode ter sido descartada. Null indica que o servidor não impõe limite baseado em tempo.
Null não significa permanente. A seção de segurança reconhece pressão de armazenamento e autoriza o descarte silencioso ao atingir os limites. Tempo é um controle de retenção; espaço total é outro. Um tipo pode até oferecer a interface e não manter versão anterior alguma. Ainda assim, devolve o objeto atual com objectHistory e pode chamar todos os objetos correntes de versão 1.
Portanto, a capability prova a existência de uma interface, não de um acervo probatório mínimo. Aquisição e conformidade precisam fixar retenção mínima, aviso de exclusão, exportação, integridade e preservação legal em contratos próprios.
Recuperação e responsabilização precisam de recibos diferentes
Para recuperação, a superfície é bem desenhada. Um cliente pode perguntar a Email/changes quais IDs foram destruídos, passar esses IDs a Email/get, solicitar objetos excluídos e apresentar os últimos valores anteriores à remoção. O usuário recupera conteúdo sem o protocolo fingir que ele continua ativo.
Para responsabilização, faltam colunas. Um recibo robusto precisa ligar ator autenticado e sessão, cliente e dispositivo de origem, corpo exato da mutação, token de estado condicional, versão e decisão da política de autorização, transação aceita pelo servidor, hashes anterior e posterior, ID durável do evento, entrega de notificação e resultado observado.
O histórico pode oferecer uma representação anterior ou posterior. Não preenche o restante. Inferir o autor a partir do dono do objeto é inseguro. Inferir autoridade a partir da mudança visível ignora a política aplicada. Inferir efeito externo a partir de um valor armazenado confunde aceitação no plano de controle com execução e observação.
Quando houver dever de prestar contas, a arquitetura deve unir retratos de recuperação a um registro append-only. Não deve fingir que um único depósito cumpre dois contratos incompatíveis.
Acesso histórico não é apenas o acesso de hoje
O passado introduz um problema de autorização. Quem não pode ler o objeto atual não pode ler seu histórico. Se as permissões mudaram ao longo do tempo, o servidor deve entregar apenas as versões que o solicitante teria tido direito de ler naquela época.
A regra impede que um leitor recém-autorizado veja valores anteriores ao seu direito de acesso. Também exige que o servidor retenha contexto histórico suficiente para decidir. Uma lista de controle atual pode não conseguir reconstruir a resposta correta.
O JMAP Sharing já separa principais, permissão pretendida e acesso efetivo. Object History acrescenta tempo: o direito de inspecionar uma versão antiga depende de um direito antigo, não apenas do mapa shareWith atual. A versão devolvida evidencia que o servidor decidiu revelá-la, mas não documenta por completo essa decisão sem um registro independente.
Às vezes, o histórico correto é incompleto de propósito
Uma cópia antiga pode revelar justamente a informação que alguém quis remover. Um telefone apagado de um contato pode permanecer na história. Por isso o texto recomenda uma capacidade administrativa de purgar o histórico de objetos específicos por privacidade ou conformidade.
Não é uma falha a esconder. Recuperação, responsabilização, apagamento e custo de armazenamento apontam para direções diferentes. Para cada classe de dados, é preciso declarar qual objetivo prevalece, quem pode autorizar a purga, se um recibo resistente a adulteração permanece e quais fatos independentes sobrevivem depois que o conteúdo é removido.
Prometer “histórico imutável” sobre uma interface feita para permitir exclusão seria perigoso. Desligar a recuperação por ela não ser um livro forense seria igualmente ruim. A solução é separar os depósitos e publicar seus limites.
Adoção pelo grupo de trabalho não é implantação
O documento de setembro é quase idêntico ao rascunho individual de março. O corpo do protocolo não ganhou nova evidência. A mudança relevante é que a proposta agora leva o nome do grupo JMAP.
O Datatracker o classifica como WG Document em I-D Exists. Não há area director responsável, shepherd ou telechat informados. O resumo deixa vazio o intended status, enquanto o cabeçalho do rascunho diz Standards Track. Continua sendo Internet-Draft, não RFC, e as fontes congeladas não comprovam implementação ativa nem política de retenção em serviço identificado.
Essa fronteira de maturidade reforça a lição operacional. Um registro coordena o vocabulário entre implementações. Só evidência de execução mostra quais versões foram capturadas, condensadas ou podadas, quem tinha autorização e se a restauração funcionou.
Fontes
- Registro do JMAP Object History no Datatracker
- Histórico de revisões do JMAP Object History
- JMAP Object History, revisão 00 do grupo de trabalho
- JMAP Object History, revisão individual 00
- RFC 8620: The JSON Meta Application Protocol
- RFC 8621: JMAP for Mail
- RFC 9610: JMAP for Contacts
- RFC 9670: JMAP Sharing
- Parâmetros JMAP da IANA
- RFC 2119: Key Words for Requirement Levels
- RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words
- Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption
- Running-Code Primacy
Briefing para membros
Contexto aprofundado do perfil
Faça login com o nível de assinatura correto para desbloquear o briefing completo e as notas das fontes.
Apenas para Strategic Circle
Strategic Circle
Aberto a todos os leitores. Desbloqueie Briefings de perfil após se inscrever e fazer login.
Junte-se ao Strategic CircleSomente para Leadership Alliance
Leadership Alliance
Para proprietários e gestores qualificados de ativos de PI; faça login para desbloquear os briefings da Leadership Alliance.
Junte-se ao Leadership Alliance

