Tradução automática, não revista por um falante nativo. O inglês é a referência.

ProjetoEditar no GitHubFonte: CHANGELOG.md

Registo de alterações

Todas as alterações relevantes ao Kshana estão documentadas aqui.

O formato baseia-se em Keep a Changelog e este projeto segue o Semantic Versioning. Enquanto o projeto estiver antes da 1.0, o esquema público de cenários/resultados ainda pode mudar; as alterações incompatíveis são assinaladas explicitamente.

Por lançar#

[0.40.0] - 2026-10-29#

A 0,40 acrescenta a cadeia da missão de classe Artemis e o seu segmento lunar, uma etiqueta de evidência em cada figura e tabela que uma execução escreve, ingestão e ajuste de relógios medidos, uma verificação de envio de parceiros de dados, uma região estimada de emissor a partir de relatos ADS-B ou AIS, a nova campanha de benchmark da 0,40, e a linha de comandos, os relatórios e o Studio em dezassete idiomas além do inglês (os documentos de máquina permanecem em inglês). A matriz de verificação cresce de 388 para 401 linhas: 176 VALIDATED (inalterado), 221 MODELLED (eram 208) e 4 PARTNER. Nenhuma linha foi promovida a VALIDATED. Os tipos de cenário crescem de 87 para 92. Todo limiar que uma comparação com pré-registo não atingiu está declarado abaixo e permanece fixado; nenhum foi relaxado. A declaração consultiva permanece inalterada: o Kshana é um software de caráter consultivo, não um equipamento de navegação homologado e não uma certificação; o operador continua a ser responsável.

Limites conhecidos#

  • As execuções em outros idiomas levam cerca do dobro do tempo, porque o cenário é executado duas vezes (uma em inglês para os ficheiros de máquina, outra no idioma escolhido para a pessoa).
  • Algumas frases do Studio são montadas a partir de fragmentos e podem não ter artigos em idiomas com género gramatical.
  • As traduções são traduções automáticas que nenhum falante nativo revisou; o inglês é a referência.

Adicionado#

  • Dezassete idiomas além do inglês para o texto do motor destinado às pessoas e para o site e o Studio: nl, pl, pt-BR, pt-PT, fi, sv, da, nb, cs, uk, ru, de, fr, es, et, ja, zh-Hans (--lang, KSHANA_LANG, as variáveis de configuração regional; lang nas chamadas da biblioteca, de Python, de WebAssembly e de MCP). Mensagens e erros da linha de comandos, resumos de execução, textos de gráficos, report.html, descrições dos tipos de cenário e as declarações consultivas estão traduzidos; os documentos de máquina (JSON, CSV, códigos de erro, a matriz de verificação) permanecem em inglês, e uma execução em outro idioma executa o cenário uma vez em inglês para os ficheiros de máquina e uma vez no idioma escolhido para a pessoa (docs/i18n.md). As traduções são traduções automáticas, não revistas por falantes nativos; o inglês é a referência; o REVIEW.md de cada idioma lista o que um revisor deve verificar primeiro, e as páginas do site trazem um aviso a indicá-lo. As palavras de veredito, os níveis de evidência e o âmbito consultivo ("não homologado", "não uma certificação", "o operador continua a ser responsável") são mantidos em todos os idiomas.
  • kshana interference-map locate: uma região estimada de emissor a partir de relatos ADS-B ou AIS. Uma posterior sobre onde pode estar uma fonte de relatos de posição degradados (linha de vista de rádio num raio terrestre de 4/3, altura da antena e potência do emissor marginalizadas, aeronaves afetadas a puxar e aeronaves não afetadas com linha de vista a empurrar em sentido contrário), escrita como regiões a 50, 90 e 95%, um centroide com a respetiva elipse de incerteza (nunca um ponto isolado), sessões no tempo (início, fim, duração, área afetada, aeronaves distintas acima do mínimo de publicação), um perfil por hora do dia e horas por dia, com fusão opcional de uma solução TDOA de geolocation. Saídas: GeoJSON, resumo em JSON, CSV de sessões e uma figura SVG, cada uma com a licença, a atribuição, o id do método, as hipóteses, os limites e a sua etiqueta de evidência. Biblioteca interference_map::api::emitter_regions_from_*, Python e WebAssembly interference_emitter_regions. MODELLED (linha VM-bc70cb57 do registo; a matriz tem agora 401 linhas, 176 VALIDATED, 221 MODELLED, 4 PARTNER); calibrada apenas com dados sintéticos, com a comparação com os locais de emissores do Jammertest 2025 fixada antecipadamente e executada uma vez: ADS-B e AIS ambos NOT ASSESSABLE (poucas sessões programadas nos dados abertos), portanto a linha permanece MODELLED (docs/emitter-region/RESULTS.md). Formulação neutra, apenas agregados; a publicação de regiões de emissores no observatório público permanece desativada. Há um exemplo sintético em examples/emitter-region/ (docs/INTERFERENCE-MAP.md).
  • Registos de relógio medidos. src/clock_log.rs lê um registo de relógio medido numa única série de fase: oito formatos (RINEX clock, TimeLab, TICC, linuxptp ptp4l, phc2sys e ts2phc, seguimento e estatísticas do chrony), cada um um subconjunto documentado; qualquer coisa fora dele é recusada com um erro que nomeia o que foi encontrado. É usado por telecom-timing ([series.clock_log]) e pelo tipo de cenário de relógio ([clock_log], que acrescenta um bloco measured com o SHA-256 do registo e as ADEV, TDEV e MTIE sobrepostas), com o cenário incluído clock-measured-log (docs/CLOCK-LOG-FORMATS.md). Comparado com o allantools em dados públicos reais face a limiares fixados antecipadamente: a primeira execução não atingiu B1 (5 de 11 casos, todos com carimbos de tempo TICC mantidos como f64), B2, B3 (7 de 24 casos) e B4 (a versão do cabeçalho não era verificada); após as correções B1, B3 e B4 são atingidos e B2 é atingido, exceto por um par de MTIE, que está fixado e não é um defeito do motor (o allantools 2024,6 remove a frequência média antes de integrar; face ao seu MTIE em modo de fase, o motor concorda dentro de 1e-10). A linha permanece MODELLED (tests/fixtures/clock_log_real/RESULTS.md).
  • Um holdover conduzido por uma série medida ajustada: o [clock_fit] do tipo de cenário de relógio ajusta o ruído de uma série medida e conduz o holdover a partir dele (src/clock_fit.rs, cenário incluído clock-fitted-log). Comparação com pré-registo: F1(b), F3 e F4 atingidos; F1(a) (recuperar o FM de passeio aleatório registado) NOT MET nos registos C3 (não identificável por construção) e em dois de três registos C4 (FM de passeio aleatório absorvido pelo FM de cintilação e pela deriva); F2 (identificação do ruído face ao allantools) atingido em onze de doze registos e D3 e NOT MET em D2 como registado (atingido em condições equivalentes). Todas as falhas estão fixadas (tests/clock_fit_known_noise.rs); o bloco fitted e o holdover conduzido por ele permanecem MODELLED (tests/fixtures/clock_fit/RESULTS.md).
  • A nova campanha de benchmark da 0,40, com pré-registo e assinatura do responsável antes de qualquer execução: A3 (EXPLORATORY, a AUC de bootstrap agrupado por pasta de agc_k_sigma, quantil de 2,5 % 0,8502 contra 0,80), D3 (EXPLORATORY, três de cinco detetores excedem uma lacuna de otimismo de 0,05 na escala 0,25), R3 (AUC 1,0) e R4 (P_fa 0,0, P_d 1,0): todos MET, todos MODELLED. A2, D1 e R1 não foram tocados e permanecem NOT MET; nada aqui os encerra (xval/bench/RESULTS-0.40.md, Bench).
  • kshana partner check <submission.toml>: verifica o formato e os metadados de um envio de parceiro de dados (kshana.partner-submission/1: dispositivo, ficheiro de dados e SHA-256, como foi obtido, as linhas MODELLED às quais é oferecido, licença, declarações) e lê os dados com os leitores de registo de relógio ou de IMU do próprio motor. Não pontua nada e não valida nada. Há um exemplo sintético em examples/partner-submission/.
  • docs/PARTNER-DATA.md: que linhas MODELLED do registo poderiam ser promovidas por dados medidos, os formatos aceites, como um envio é verificado, pontuado face a um limiar fixado antecipadamente e creditado, e o que PARTNER e VALIDATED significam cada um; uma nota de divulgação em rascunho para o responsável em docs/drafts/PARTNER-OUTREACH.md (nada é enviado).
  • Segundas campanhas para os limiares não atingidos de gnss-ssv e lunar-infrastructure, executadas conforme o pré-registo (xval/gnss-ssv/PREREGISTRATION-v2.md, xval/lunar-infra/PREREGISTRATION-v2.md; assinadas antes de qualquer execução). Toda falha original permanece NOT MET e fixada. gnss-ssv: o controlo reproduz a execução 1 célula por célula; cinco ablações de leitura única trazem 2 das 78 células não atingidas para dentro da tolerância (EXPLORATORY, sem limiar); o novo limiar S7b (um formato de transmissão com atenuação e piso ajustado em painéis Classic IIR) é NOT MET nos painéis IIR-M em 3,83 a 3,95 dB contra 3 dB; a campanha de receção publicada reservada não foi executada (nenhuma fonte fixada) (xval/gnss-ssv/RESULTS-v2.md). lunar-infrastructure: os novos limiares C3a, C3b (um limite de deteção de cerca de 3e-9 m/s2), Q3a, Q3b (uma CDF normal precisa elimina a diferença de 1.7e-6) e G3'' são atingidos como limiares próprios, e G3' com priores ilustrativos é atingido e etiquetado como EXPLORATORY (xval/lunar-infra/RESULTS-v2.md). Tudo permanece MODELLED. Novos itens públicos: kshana::lambda::{erfc_accurate, normal_cdf_accurate, bootstrap_success_rate_accurate}.
  • Uma etiqueta de evidência em cada figura e tabela que uma execução escreve. O JSON de resultado tem uma chave evidence, o SVG do gráfico tem um elemento de metadados e uma linha sob o gráfico, e a tabela CSV tem linhas de comentário # evidence:: o nível (VALIDATED, MODELLED ou PARTNER, o mais fraco das linhas) e os ids das linhas da matriz de verificação em que a execução assenta. Linhas e estados são lidos da matriz, não escritos à mão; os ids são estáveis (VM- e oito dígitos hexadecimais, uma nova coluna ID em docs/VERIFICATION-MATRIX.md, uma lista congelada em tests/fixtures/evidence_ids.txt). Também em receiver-trust, jammertest score, iq acquire/sweep/track/monitor, no relatório de exposição de rota e, dentro do config.json assinado, em todo pacote de evidências (config_version 1,1; kshana evidence verify indica o nível; pacotes feitos antes da 0,40 são verificados sem alteração). tests/evidence_labels_doc_sync.rs falha se uma figura não tem etiqueta, se uma etiqueta discorda da matriz ou se um novo escritor de ficheiros não está etiquetado nem listado com um motivo. As saídas que não trazem etiqueta estão listadas em docs/SURFACES.md. Os três gráficos de demonstração do README foram renderizados de novo com a etiqueta (retirá-lo restaura os bytes antigos; docs/revisions/STUDIO15-evidence-label-0.40.md). Nenhuma afirmação mudou.
  • O tipo de cenário mission-thread (scenarios/mission-thread-artemis-class.toml, docs/MISSION-THREAD.md): o orçamento de erro de navegação e temporização de uma cadeia de fases do lançamento à reentrada, com todo número MODELLED e toda entrada declarada. Oito tipos de fase: launch-ascent, leo-rendezvous (covariância relativa de Clohessy-Wiltshire ao longo de excertos de sensor, janela de acoplagem), tli-and-cruise (propagação de Cowell com uma matriz de transição de estado por diferenças finitas, erro de queima, atualizações gnss-ssv e de seguimento em solo, a Lua a partir de um recorte opcional do kernel DE440), entry (sigma do ângulo de trajetória, probabilidade do corredor, desaceleração máxima nas extremos do corredor, área de aterragem) e os quatro tipos lunares. Regras de transferência (carry, inflate, reacquire), conversões de referencial e de escala de tempo como linhas próprias do orçamento, uma sobreposição opcional da rede terrestre que define o ciclo de seguimento de cada fase, a margem face aos requisitos declarados e o elo mais fraco. O exemplo segue a sequência de uma apresentação pública de conceito de operações da NASA com números ILLUSTRATIVE: um exemplo de ponta a ponta de classe Artemis em 11 fases, segmentos terrestre e lunar. A propagação cislunar foi comparada com a trajetória pública da Artemis I ao longo de um arco de 72 h face a um limiar fixado em xval/mission-thread/PREREGISTRATION.md antes da execução: NOT MET (45,3 km e 0,25 m/s contra 5 km e 0,05 m/s). O diagnóstico situa a falha em cinco pequenos eventos impulsivos na referência; entre eles o modelo de forças reproduz os estados horários com mediana de 0,4 m. A linha permanece MODELLED (xval/mission-thread/RESULTS.md).
  • O segmento lunar da cadeia da missão de classe Artemis: quatro tipos de cenário, cada um também um tipo de fase da interface mission-thread (src/mission_thread/lunar/), todos MODELLED.
    • lunar-orbit-rendezvous: navegação relativa até à acoplagem numa órbita polar circular de 100 km ou numa órbita polar elíptica de 100 km por 3000 km (scenarios/lunar-orbit-rendezvous.toml, ...-elfo.toml). Uma estimativa de Gauss-Newton em lote ao longo do arco funde uma solução absoluta por veículo a partir de um conjunto ilustrativo de relés de classe LCNS, um erro persistente do sinal no espaço (comum aos dois veículos e independente) e uma distância por enlace cruzado, sob o modelo de forças lunares da biblioteca. Indica a posição e a velocidade relativas nos eixos locais do alvo, a disponibilidade da solução, o erro de estimação normalizado quadrático médio face ao valor esperado, o custo de ignorar os harmónicos da gravidade, os modelos terminais de sensor relativo ao lado do valor só de sinais e a covariância 6x6 transferida.
    • lunar-descent: o orçamento de dispersão de aterragem num local polar sul (scenarios/lunar-descent.toml; lunar-descent-lola.toml lê o DEM do LOLA a partir de um checkout): um modelo de erro inercial de cinco estados por eixo, uma solução AFS (isolada ou diferencial, usando o resíduo do enlace de correção de lunar-differential-pnt), uma solução relativa ao terreno (o correlacionador terrain-nav sobre o seu relevo sintético, ou o limite de Cramer-Rao da correlação com o DEM do LOLA) e o tempo lunar por meio do relógio do veículo (lunar-time-offset). Informa a elipse de aterragem de 3 sigma, cada combinação de auxílios e uma calibração de Monte Carlo da elipse.
    • lunar-surface: disponibilidade de posicionamento e temporização por local e estação (scenarios/lunar-surface.toml; lunar-surface-terrain.toml acrescenta o horizonte do LOLA por traçado de raios): o valor de posicionamento de local único é igual, bit a bit, ao de moonlight-service-volume; o que varia com a estação é a visibilidade da Terra e do Sol obtida das efemérides analíticas.
    • lunar-ascent: a ascensão até à órbita de encontro e a covariância de posição e velocidade levada de volta à órbita (scenarios/lunar-ascent.toml), com a dispersão no corte do motor indicada ao lado.
    • docs/MISSION-THREAD-LUNAR.md; o pré-registo, as suas alterações e todos os resultados, inclusive as falhas, em xval/mission-thread-lunar/.

Evidências#

  • Fixado antecipadamente em xval/mission-thread-lunar/PREREGISTRATION.md antes de qualquer execução, com seis alterações datadas (cada uma feita antes da obtenção dos dados, exceto a Alteração 6, que corrige um erro aritmético numa contagem de estados após a obtenção e antes de qualquer resultado de A2; toda emenda está divulgada no ficheiro). Nenhum limiar foi relaxado.
  • A1 (o propagador face à trajetória reconstruída do LRO do JPL Horizons, 24 h): MET, uma diferença 3-D máxima de 33 m contra um limiar de 500 m e uma diferença radial RMS de 2,4 m contra 60 m.
  • A2 (o mesmo propagador face à NRHO do CAPSTONE ao longo de uma revolução de 6,5 dias): NOT MET, uma diferença de posição final de 136,8 km contra um limiar de 25 km e uma diferença de raio de periapsia osculador de 28,4 km contra 10 km. A linha permanece MODELLED, e a falha está fixada por tests/mission_thread_lunar_oracles.rs.
  • B1 (a consistência da estimativa do encontro com o seu próprio modelo) é MET no quarto projeto de estimador, NEES médio de 5,85 a 5,93 contra um intervalo de [5,2, 6,8]; os três projetos anteriores, um filtro de Kalman estendido em três variantes, não a atingiram. Uma quinta alteração, feita depois de o cenário de 2 h incluído ter levado 4 de 50 tentativas a um mínimo local (NEES médio 1e9), executa o ajuste de Gauss-Newton sobre um arco crescente com redução de passo; B1 não muda com ela e os cenários incluídos dão 6,51 e 6,33. O histórico está em xval/mission-thread-lunar/RESULTS.md.
  • Nada aqui é VALIDATED: as linhas de referência independente testam o propagador partilhado, e não um filtro de navegação, um sinal ou um orçamento.

[0.39.0] - 2026-10-22#

Sem novas funcionalidades: uma correção de linha de comandos, atualizações de dependências nas ferramentas de validação cruzada e documentação. Os resultados do motor são inalterados face à 0.38.0.

Corrigido#

  • A linha de comandos termina silenciosamente com o estado 141 quando a sua saída padrão é fechada (kshana kinds | head), em vez de entrar em pânico com "failed printing to stdout: Broken pipe". 141 é 128 mais SIGPIPE, o estado que uma shell comunica para yes | head. Só é tratado um pipe fechado: um disco cheio ou qualquer outro erro de escrita continua a comunicar-se, e um fluxo em direto que escreva num socket fechado continua a receber o seu erro de escrita. tests/cli_closed_pipe.rs fecha o leitor antes de o programa arrancar, pelo que a primeira escrita falha em todas as execuções.

Segurança#

Uma atualização de dependência na biblioteca distribuída (a primeira entrada), o restante nas ferramentas de validação cruzada (xval/).

  • p256, p384 e p521 0,13 para 0,14 (com elliptic-curve 0.14.3, ecdsa 0.17.0 e crypto-bigint 0.5.5 para 0.7.10; também a dependência direta crypto-bigint, agora 0,7) resolvem RUSTSEC-2026-0387, uma variabilidade de tempo de execução em crypto-bigint 0.5.5. O Kshana usa estes crates apenas para verificar assinaturas públicas (a chave raiz Galileo OSNMA e os tokens de carimbo temporal RFC 3161) e só assina em testes com chaves descartáveis, pelo que a exposição prática era nula; a atualização remove o aviso sem uma entrada de exclusão. Os ficheiros de bloqueio da biblioteca e do MCP mudam ambos; nenhum resultado de verificação muda (os testes de vetores de OSNMA e de carimbo temporal passam sem alteração).
  • A versão mínima suportada do Rust é agora 1,88 (exigida pela correção do RUSTSEC-2026-0387).
  • memmap2 0.9.10 para 0.9.11 (RUSTSEC-2026-0186) nos ficheiros de bloqueio da verificação cruzada ANISE (xval/anise-lunar-od, xval/anise-mars-od); os ficheiros de bloqueio voltam também a sincronizar a dependência de caminho kshana do repositório.
  • pillow 12.3.0 para 13.0.0 e certifi 2026.7.22 para 2026.10.19 nas fixações do ambiente de referências independentes (xval/oracles/requirements.lock, requirements.frozen.txt): as versões corrigidas para oito avisos do pillow e um aviso do certifi.

Documentação#

  • docs/BENCH.md, o README e este ficheiro listam todos os limiares do kshana-bench que são NOT MET, tal como registados em xval/bench/RESULTS-v2.md: A2 (agc_k_sigma AUC 0,766 contra pelo menos 0,80 na partição de teste), D1 (maior diferença 0,0301) e tarefa (b) R1 (transportado, não executado de novo). Nenhum limiar foi afrouxado.
  • Revisão de completude do README: uma lista de conteúdos; os tipos de cenário arquivados por famílias, cada um com uma página em docs/kinds/by-kind/ (a descrição e os campos do motor, as entradas e os resultados de uma execução de exemplo, as linhas do registo e as referências independentes, as limitações que o relatório da execução indica e o gráfico que o motor escreve), uma folha de contactos por família, todos indexados por docs/KINDS.md; todos os comandos em docs/COMMANDS.md; todas as superfícies, comandos de plugin, skills e páginas do Studio em docs/ALL-SURFACES.md; todos os domínios de capacidade em docs/CAPABILITY-DOMAINS.md; diagramas Mermaid incorporados (visão geral do sistema, superfícies, laço interno, confiança do recetor, ida e volta de laboratório, Studio, fluxo de testes e lançamento, mapa de módulos, distribuição). Escrito por tools/gen_kinds_index.py, tools/gen_readme_blocks.py e tools/gen_figures_038.py; auditado por tools/readme_audit.py; protegido por tests/readme_completeness_doc_sync.rs, que também fixa a descrição e os campos de cada entrada ao motor.
  • tools/render-diagram-chromium.sh: renderiza um diagrama Mermaid para SVG e PNG em Linux e atualiza o registo de renderização.
  • README: as figuras de utilizadores espaciais e lunares usavam caminhos relativos a docs/, pelo que não carregavam a partir do README; uma ligação apontava para ../../docs/JAMMERTEST.md.
  • Removidos dois ficheiros de gráficos desatualizados, copiados à mão (docs/assets/clock-ensemble-band.svg, sweep-clock-stability.svg), que nenhuma página usava e que já não correspondiam ao motor; docs/KINDS.md contém os gráficos atuais.

[0.38.0] - 2026-10-19#

Adicionado#

  • GNSS para além da constelação (gnss-ssv). Um novo tipo de cenário para veículos espaciais acima, em redor e para além das órbitas GNSS (docs/SSV.md): disponibilidade de um e de quatro sinais, durações de interrupção, C/N0, DOP e ligações de lóbulo principal face a lóbulos laterais para GPS, GLONASS, Galileo, BDS, QZSS e NavIC numa casca ou ao longo de trajetórias LEO, MEO, GEO, HEO e de transferência lunar; diagramas de emissão do folheto, paramétricos ou fornecidos pelo utilizador; um modelo de ionosfera, plasmasfera e atmosfera por raio rasante; um projeto de recetor de sinal fraco; um filtro de Kalman estendido GNSS a bordo para HEO e transferência lunar; e navegação relativa de formação. Comparado com o folheto do Space Service Volume do ICG sob um pré-registo versionado antes da execução: as constantes de potência mínima radiada e o limiar lunar concordam, os outros limiares não são atingidos sob a leitura pré-registada (quase todos por causa do ângulo de feixe GLONASS inconsistente do folheto), e o substituto paramétrico de lóbulos laterais não reproduz os diagramas de painel GPS medidos. Tudo continua MODELLED (xval/gnss-ssv/RESULTS.md).
  • Órbita e superfície lunares como infraestrutura de navegação e geodésica (lunar-infrastructure). Um novo tipo de cenário com cinco estudos selecionados por study (docs/LUNAR-INFRASTRUCTURE.md): consistência de uma determinação de órbita GNSS terrestre a bordo numa órbita de halo quase retilínea face a uma determinação independente de distância e taxa de distância a partir do solo; fase da portadora com dupla diferença conjunta de estação à superfície e orbitador, com fixação de inteiros LAMBDA; informação de Fisher do datum lunar de sete parâmetros com e sem medições de distância entre orbitador e superfície; desvios inter-técnicas de GNSS, VLBI e medição laser face à ligação local; e sensibilidade a h2, k2, l2 e à libração física. MODELLED, com entradas ILLUSTRATIVE: a numérica é verificada face a programas independentes em numpy e scipy, e nada é comparado com uma medição de uma grandeza lunar. Os limiares foram fixados em xval/lunar-infra/PREREGISTRATION.md e em duas alterações divulgadas. Três são NOT MET e cada uma está fixada por um teste que afirma a falha: C3 (um erro de força injetado não é detetado à taxa pré-registada), Q3 (a taxa de sucesso por bootstrap difere da referência independente numpy em 1.7e-6 contra um limiar de 1e-9, devido à aproximação da CDF normal do LAMBDA) e a metade do traço de G3 (acrescentar uma família de medições de distância nem sempre reduz o traço da pseudo-inversa). Os restantes são atingidos (xval/lunar-infra/RESULTS.md).
  • Um sexto artigo na tabela de Investigação. "Cislunar navigation is an observability problem: arc-length thresholds, Gramian conditioning, and the Doppler lever" (arXiv:2610,23871, eess.SP) mostra que a diluição de precisão é indefinida para seguimento cislunar só por distância e usa em vez disso o Gramiano de observabilidade em quatro órbitas retrógradas distantes planas: só por distância tem característica 2 de 4 num instante e precisa de um arco de cerca de 2,09 h, a taxa de distância (Doppler) dá característica 4 instantaneamente, e coestimar uma estação com estados de satélites e relógios continua com défice de característica de um sem uma observável interferométrica externa. Os seus números são regenerados pelo tipo de cenário cislunar-observability (kshana scenarios/cislunar-observability.toml); cislunar-arc-recovery testa o limiar com um estimador independente. O cartão de investigação do README, os READMEs de crates, npm e PyPI e o gerador incluem-no.
  • O árbitro neutro, tornado mensurável. kshana jammertest import lê o catálogo de ensaios e o plano de transmissão do Jammertest da NPRA publicados como verdade programada (identificadores do catálogo mantidos) e kshana jammertest score pontua um registo de recetor face a ele por ensaio (latência de deteção, alarmes em falta, falsos alarmes, tempo de recuperação), opcionalmente como pacote de evidências assinado (docs/JAMMERTEST.md). Os limiares de pontuação foram pré-registados antes de qualquer execução pontuada (xval/jammertest-score/). No conjunto de dados JammerTest 2024 (obtido, nunca incorporado) a regra de dados mínimos pré-registada falhou tanto na primeira execução como na revisão do tratamento de dados, pelo que nenhum limiar é avaliável e nada é reclamado; ambas as execuções estão registadas e fixadas. MODELLED: o calendário são as janelas registadas do conjunto de dados, não horas de emissão registadas. O conjunto NMEA da SimulaMet de 2025 não é adaptado (nenhuma licença indicada na sua página).
  • Os indicadores do próprio recetor, ao lado dos do Kshana. UBX-NAV-STATUS spoofDetState e UBX-SEC-SIG são lidos para self_report em cada época, e a comparação receiver_self_report no resultado coloca-os face aos monitores do Kshana (ambos, só o recetor, só o Kshana, nenhum); não emite nenhum alarme e não altera nenhuma pontuação. Juntam-se-lhes um leitor Septentrio SBF (PVTGeodetic, MeasEpoch, RFStatus, só de leitura, sobre a biblioteca sbf-tools de licença MIT) e receiver-trust live --serial (um fluxo NMEA série ou USB, só de leitura; nunca escreve num recetor).
  • Temporização e segurança de hardware (docs/TIMING-HIL.md, docs/HARDWARE-SAFETY.md). O tipo de cenário holdover-test pontua um ensaio de holdover de um sistema de temporização (GNSS retirado pelo operador, holdover, recuperação) a partir de um registo de erro de tempo medido, face às máscaras ITU-T de tabelas públicas. clock_log lê registos do linuxptp (ptp4l, phc2sys, ts2phc) e do chrony (tracking, statistics). iq scene --format sdrx escreve metadados ION GNSS SDR e iq monitor --follow monitoriza uma gravação SigMF enquanto cresce (só receção). compliance-report passa a incluir o Foundational PNT Profile da NIST IR 8323r1 (15 linhas parafraseadas, fornece elementos de prova em apoio de). Um pacote de evidências pode registar a lab-attestation do operador no seu manifesto assinado, nunca verificada; as etapas de hardware 0 a 4 e as notas legais estão em HARDWARE-SAFETY.md (a aguardar revisão jurídica). Não existe nenhum caminho de transmissão de qualquer tipo.
  • kshana-bench v1 (kshana bench, bench/SPEC.md, docs/BENCH.md): tarefas, partições e métricas fixas para deteção de interferência GNSS em registos de recetor (JammerTest 2024) e IQ, previsão de holdover de temporização (relógios IGS) e a diferença de otimismo fora da distribuição; manifestos de partição com somas de controlo fixadas e scripts de obtenção (sem dados incorporados), um conjunto reservado por compromisso e revelação, um esquema de ficheiro de resultados e uma página estática de classificação. Linhas de base sob limiares pré-registados em xval/bench/PREREGISTRATION.md: limiares do pontuador atingidos, C1 a C3 atingidos, D2 atingido; A2 NOT MET (agc_k_sigma AUC 0,766 contra pelo menos 0,80 na partição de teste), D1 NOT MET (maior diferença 0,0301) e tarefa (b) R1 NOT MET (transportado, não executado de novo), cada um fixado (xval/bench/RESULTS-v2.md). Todas as pontuações são MODELLED. Python bench_score, bench_leaderboard; WebAssembly o mesmo; MCP score_benchmark, render_leaderboard.
  • Observatório de interferência (kshana interference-map daily, sensitivity, docs/observatory/METHOD.md): um GeoJSON diário reproduzível, PNG e JSON de relatório de incidentes com três estados (degradado, não degradado, não observado), um atraso mínimo de 24 h, células de 0,5 graus ou mais grosseiras, nenhuma causa atribuída e dados do OpenSky recusados; um estudo de sensibilidade dos parâmetros pré-registados; um catálogo retrospetivo de 30 dias do Báltico a partir de adsb.lol.
  • Entradas de máquina e de sensores para receiver-trust (docs/MACHINE-INPUTS.md). Novos valores de [log] format, todos só de leitura, MODELLED, com conjuntos de dados de ensaio escritos internamente e sem dados incorporados: rtklib-pos (ficheiros de solução .pos do RTKLIB), novatel (BESTPOS OEM7 ASCII e binário, C/No de RANGE e RXSTATUS; o indicador de jammer do recetor passa a ser o self_report da época, confrontado com os alarmes do Kshana pela comparação receiver-self-report), rtcm3 (C/N0 MSM4 e MSM7 para GPS, GLONASS, Galileo, SBAS, QZSS, BeiDou e NavIC; disposições das tabelas pyrtcm de licença BSD, cujo aviso está em NOTICE, não da norma RTCM) e gnss-sdr (mensagens do Monitor e do monitor PVT do GNSS-SDR como linhas JSON, retransmitidas por integrations/gnss-sdr/relay.py).
  • Registos IMU como segundo sensor. [log.imu] (csv ou euroc) integra a taxa de guinada do giroscópio no rumo que o monitor heading-course lê; inline em todas as superfícies e transportado através dos pacotes de evidências. kshana imu-fit (Python imu_fit, WebAssembly imu_fit, MCP fit_imu_log, plugin /kshana-fit-imu, uma ação JetBrains) ajusta os parâmetros do acelerómetro e do giroscópio dos cenários hybrid e fusion a partir de um registo estacionário por desvio de Allan e imprime uma tabela [accel_classical] com o SHA-256 do registo na sua proveniência.
  • Integrações: um pacote ROS 2 (integrations/ros2/kshana_trust: NavSatFix e ublox_ubx_msgs à entrada, tópicos de confiança à saída; a sua ponte sem ROS é testada contra o motor real, o próprio nó não foi executado num grafo ROS em funcionamento), uma ponte gnss_lib_py (integrations/gnss_lib_py, dependência MIT, opcional) e um retransmissor GNSS-SDR.
  • Exportador MQTT do Home Assistant para telemetria de confiança: kshana trust-telemetry --print-mqtt e --mqtt-tcp <host:port> (mensagens de descoberta e um documento de estado JSON; só publicação, sem credenciais nem TLS), e format = "mqtt" como texto em Python, WebAssembly e MCP.
  • Sete linhas MODELLED do registo para o que antecede. Nada aqui é VALIDATED: não foi lida nenhuma captura de um recetor real, estação de base, IMU, execução do GNSS-SDR, grafo ROS ou broker MQTT.
  • Margem da ligação ótica ao longo do tempo. O tipo de cenário optical-atmosphere aceita uma tabela opcional [timeseries] (duration_h, step_s, seed) e passa então a escrever também, por local, uma realização com semente do modelo de local indicado ao longo do tempo: episódios de nuvens, uma coluna de água líquida por episódio, uma amostra de cintilação gama-gama por passo e, a partir delas, a margem da ligação, os desvanecimentos por nuvens e por cintilação e o indicador de ligação ativa, com a disponibilidade realizada, a fração de nuvens, o número de interrupções e a interrupção mais longa. MODELLED (uma extração do modelo, não do clima; sem referência independente externa). Sem a tabela o resultado é o documento da 0,37. Os dois cenários óticos incluídos trazem a tabela (336 h, 600 s, semente 37). Limiares pré-registados em xval/optical-atmosphere/PREREGISTRATION-timeseries.md antes da primeira execução.
  • Especificação das condições de ensaio e a ida e volta de laboratório. kshana.test-conditions/1 é publicado como docs/spec/TEST-CONDITIONS.md com um esquema JSON e passa a incluir recording.kind = "receiver-log". kshana bench-export também escreve <base>.conditions.json. kshana evidence round-trip constrói um pacote assinado que liga a soma de controlo do cenário, a das condições indicadas, a do registo do recetor e a pontuação face aos eventos indicados, e recusa condições que discordem dos eventos de pontuação. Exemplo trabalhado com gps-sdr-sim a escrever apenas um ficheiro; a reprodução é da responsabilidade do operador e nunca é automatizada. Python evidence_round_trip, MCP create_round_trip_pack, plugin /kshana-evidence-pack.
  • Pacotes de normas (kshana standards-pack, standards/): os perfis de ensaio do referencial DHS Resilient PNT para os níveis 1 a 4, os níveis de exatidão e a avaliação de integridade da IMO MSC.1/Circ.1575, e monitorizar, avaliar e mitigar do Apêndice F do ICAO Doc 9849, cada um um conjunto de cenários pontuados face a limiares indicados antes da execução, com as linhas de compliance-report para as quais fornecem elementos de prova em apoio. As falhas estão registadas e fixadas: DHS L4-T1 e os quatro ensaios de exatidão da IMO. O próprio Doc 9849 não foi lido (pago); o pacote ICAO segue a apresentação do próprio Plano de Mitigação de RFI do ICAO. compliance-report passa a ter uma secção de standards-pack. Tudo MODELLED.
  • LunaNet Augmented Forward Signal (docs/LUNANET-AFS.md): códigos Gold AFS-I e Weil AFS-Q para PRN 1 a 210, sinais lunanet-afs-i e lunanet-afs-q em kshana iq, o código SB1 BCH, CRC-24Q e entrelaçador, e kshana lunanet-afs-check (spec, symbols, generate), fixado ao LNIS V5 Applicable Document 1 Volume A (LSIS-AFS V1.0, 29 de janeiro de 2025). Códigos VALIDATED face às tabelas impressas do documento (que este assinala como TBC); uma coluna terciária impressa (PRN 147) é provavelmente uma gralha e a falha está fixada. A codificação LDPC das subtramas 2 a 4 não está implementada.
  • Cadernos do curso (notebooks/course/): jamming, spoofing, holdover, integridade, OSNMA e mapa de interferência, cada um com exercícios.
  • Estudo de URA máximo da Etapa 3 do ARAIM do WG-C UE-EUA (xval/araim-m3/, src/bin/gen_araim_m3_study.rs), que substitui o plano retirado da "Table A-3"; MODELLED com desvios indicados.
  • Rascunhos para decisão do responsável em docs/drafts/: artigo JOSS, alteração da carta do TSC, processo de registo de referências independentes e uma proposta de divisão de LICENSES/. Nada ali está adotado.
  • Vistas do Studio para as funcionalidades da 0,38 (kshana.dev/studio/). Repetição da ponte (duas execuções sintéticas num só relógio: trajetória, pontuação de confiança, os satélites que o registo ouve e o veredicto, com os indicadores do próprio recetor ao lado dos alarmes do Kshana); PNT ótico (os dois cenários optical-atmosphere, com uma realização com semente opcional de [timeseries], MODELLED); Ensaio de holdover (o resultado de holdover-test medido face às máscaras ITU-T, desenhado a partir do próprio record.series do resultado); um visualizador do observatório de interferência que abre os ficheiros que o utilizador produziu e não inclui nenhum; na página Ferramentas, um pontuador do Jammertest, um ajuste IMU e o MQTT como formato de telemetria; e em Confiança um seletor de formato de registo (RTKLIB .pos, NovAtel OEM7, RTCM 3, GNSS-SDR, Septentrio SBF) com um ficheiro IMU opcional. Cada vista lê ficheiros no navegador e não envia nada; cada valor mantém a etiqueta que o registo lhe atribui e cada uma traz a declaração consultiva. A página /benchmark do sítio mostra o fragmento kshana bench leaderboard.

Corrigido#

  • Questão #36: camadas de fixação exata ao byte. As camadas de fixação exata ao byte só são executadas num anfitrião declarado como linha de base (KSHANA_EXACT_PINS=1, definido por scripts/gate.sh), não em todos os Mac com chip Apple, porque a biblioteca matemática da Apple difere entre versões do macOS; a camada portátil é executada em todo o lado, e tests/exact_pin_gate_guard.rs impede que uma camada exata ao byte volte a ser condicionada apenas pela plataforma. As próprias comparações com as referências independentes passam no macOS. Nenhum literal foi retomado e nenhuma tolerância foi alterada. scripts/oracle-triage.sh e docs/LOCAL-ORACLE-TESTS.md explicam como triar uma diferença; .github/workflows/oracle-macos.yml é um diagnóstico manual e semanal, não uma barreira.
  • CodeQL: um padrão não ancorado no auxiliar trust-open do Studio passa agora a corresponder ao cabeçalho inteiro (web/studio/lib/trust-open.mjs).
  • CI: disco do executor. A tarefa check compila os perfis de desenvolvimento e de teste sem informação de depuração, pelo que a ligação já não enche o disco.
  • Guardas de código-fonte. Todo o ficheiro de código-fonte que contém conjuntos de dados de teste com fixações declara o âmbito das suas fixações, e os testes que escrevem ficheiros temporários usam um caminho único por chamada, pelo que as execuções paralelas não podem colidir.
  • docs/SCENARIOS.md é regenerado para o campo opcional timeseries de optical-atmosphere.
  • Plugin JetBrains: sem uso de API da plataforma obsoleta ou programada para remoção. O IntelliJ Plugin Verifier (verifyPlugin) face à compilação 263 do IntelliJ IDEA (2026,3: 263.6800.24 e 263.7031.23) encontrou uma chamada obsoleta, FileEditorManager.openFile, em Insert Example; passa agora a abrir o novo ficheiro com OpenFileDescriptor. O plugin é compatível com 2024,3 (a versão since-build, inalterada) e com ambas as compilações 263, sem avisos. A CI executa agora verifyPlugin e falha perante problemas de compatibilidade e perante qualquer uso de API programada para remoção.

[0.37.0] - 2026-10-17#

Adicionado#

  • PNT ótico através da atmosfera (tipo de cenário optical-atmosphere, docs/OPTICAL-ATMOSPHERE.md, nota de projeto docs/design/optical-atmosphere-0.37.md). Para uma ligação ótica e um conjunto de locais em terra, reporta a perda em céu limpo dependente do comprimento de onda e da elevação, o estado de turbulência de Hufnagel-Valley (variância de Rytov, índice de cintilação, desvanecimentos gama-gama, média de abertura), a disponibilidade face à margem da ligação a partir de um clima de nuvens indicado, a margem necessária para disponibilidades-alvo e o teto que nenhuma margem ultrapassa, a distribuição das durações de interrupção, o erro de temporização e de alcance por interrupção através do modelo de holdover do relógio, a diversidade de locais correlacionada com a distância e os ganhos hipotéticos de uma mudança de comprimento de onda, de uma abertura maior, da redução de cintilação por ótica adaptativa e de margem adicional. optical_linkbudget passa a ter um orçamento sensível à atmosfera; sem ele, a sua saída é idêntica bit a bit à da 0,36 (limiar A5). Dois cenários incluídos trazem climas de nuvens ILLUSTRATIVE. MODELLED: três linhas do registo. A numérica satisfaz os limiares A1 a A6 pré-registados em xval/optical-atmosphere/PREREGISTRATION.md face a um programa independente em mpmath; isso verifica a implementação das fórmulas indicadas, não a atmosfera, e nenhum registo de disponibilidade medida foi comparado, pelo que nenhuma linha é VALIDATED. O limiar A4 foi falhado inicialmente por 3e-9 porque a CDF normal em uso era uma aproximação de 1.5e-7; a CDF foi substituída e o limiar mantido como registado. As compilações nativa e WebAssembly devolvem documentos idênticos byte a byte para ambos os cenários incluídos (A7, executado no commit de integração da 0.37.0).

[0.36.0] - 2026-10-16#

Adicionado#

  • ROC de deteção dos monitores IQ (PRO-32, docs/design/DETECTION-ROC.md). Uma campanha com monitores guarda o máximo de cada estatística de teste sobre janelas de eventos indicados (positivas) e sobre janelas em mosaico fora dos eventos (negativas, roc_window_s). O relatório agrega-as por tipo de alarme numa ROC com a sua AUC e o ponto de funcionamento no limiar configurado, como roc.json e uma secção do relatório. Em campanhas sintéticas, a verificação do nível de acaso é satisfeita. O limiar de AUC do C/N0 (0,95) não é atingido (0,79), porque as janelas negativas imediatamente a seguir a um evento herdam o decaimento do CUSUM a partir da deteção; isto fica registado. MODELLED.

  • Monitores IQ na campanha de repetição em laboratório (PRO-31, docs/design/MONITORS-IN-CAMPAIGN.md). Uma tabela opcional [monitors] num ficheiro de campanha executa os monitores IQ na passagem única do executor: potência e espetral após cada cadeia de front-end, e C/N0, SQM e bloqueio por canal seguido. Os seus alarmes são pontuados face aos eventos indicados: detetado ou em falta, tempo até à deteção e falsos alarmes por hora de exposição. Indica-se o valor de falso alarme em forma fechada de cada teste, incluindo um novo valor gaussiano bilateral para os testes SQM (2Q(k)). Sem a tabela nada muda. Em campanhas sintéticas, os limiares de falso alarme de potência e SQM e o de falso alarme de C/N0 são atingidos; 18 de 18 atenuações são detetadas, mas o limite do tempo até à deteção, abaixo de uma amostra do detetor por construção, não é atingido e fica registado. MODELLED; linha do registo "IQ monitors scored in lab-replay campaigns".

  • Ajuste de laboratório a partir de campanhas IQ, seguimento (tests/iq_labfit_followup.rs, tarefa de CI labfit-iq-followup). Testa as duas hipóteses que a §13,6 de docs/design/LABFIT-FROM-IQ.md deixou em aberto, face a limiares pré-registados em 1e532f84. Acrescenta duas campanhas sintéticas: S, com um J/S em degraus (semente 2026_1014), e R, uma rampa nova (semente 2026_1015). Os resultados estão em docs/design/evidence/labfit-followup/RESULTS.md.

    • S1 atingido: com cada nível de J/S mantido, δ_eff é recuperado dentro de +0,185 dB. O erro de −1,1 dB das campanhas em rampa é atraso do estimador.
    • S2 não atingido, fixado por um teste que afirma a falha: (d) tal como escrito na campanha em degraus verifica-se para o modelo do laço de seguimento (0,45 dB) mas não para o empírico (6,42 dB).
    • R1 atingido: na campanha em rampa nova, (d) com o produto do tempo de permanência de queda ajustado pela taxa de rampa de cada evento acrescentado fica dentro de 1 dB para ambos os modelos.
    • As falhas de (a′) e (d) replicam-se em R.
    • Uma campanha pode agora indicar o seu J/S como um perfil step no ambiente de teste.
    • Nenhum veredicto da §13 muda, e a linha do registo continua MODELLED.
  • Captura inicial do FLL limitada, opcional (DS-LOOP-05): uma nova chave de projeto de laço [design.carrier] fll_pull_in_max_s (s), em Rust LoopConfig::fll_pull_in_max_s. Com fll_assist = "pull-in" força a passagem de FLL para PLL passado esse tempo, seja qual for o PLI. Não definida por omissão e, nesse caso, fora da soma de controlo do projeto; o projeto predefinido e a sua soma de controlo não mudam.

    • Verificado face a limiares pré-registados em 58789af0, em verdade injetada. O controlo é atingido: o valor predefinido nunca passa o controlo em 9 de 10 sementes a 33 dB-Hz.
    • Não atingido: com um limite de 1,0 s, 16 de 20 execuções mantêm o bloqueio a 33 dB-Hz e 8 de 20 a 31 dB-Hz; as restantes alternam entre passagens forçadas e o regresso do FLL. O jitter de fase é 1,8× o do PLL isolado a 33 dB-Hz.
    • O patamar de captura inicial de ~35 dB-Hz continua a ser o limite documentado do valor predefinido.
    • MODELLED; linha do registo "Capped FLL pull-in below the default design's FLL-to-PLL hand-over floor (opt-in)".
  • Histerese de aquisição e quantizador do front-end no tipo de cenário jamming (CAP-06c): duas secções opcionais para um cenário jamming.

    • [acquisition]: acquisition_threshold_dbhz (dB-Hz, igual ou superior ao limiar de seguimento) e reacquisition_delay_s (s, por omissão 0). Um satélite é adquirido no limiar de aquisição ou acima dele, depois de ter estado não adquirido durante o atraso. É mantido enquanto estiver no limiar de seguimento ou acima dele. Saídas: epochs[].sats[].acquired (verdadeiro/falso), epochs[].acquired (contagem) e fom.availability_acquired (1).
    • [front_end]: adc_bits (1 a 16) e bandwidth_mhz (MHz, por omissão o dobro da taxa de chip). Produz um bloco front_end: agc_gain_reduction_db (dB, 10·log10(1 + J/N)), quantiser_loss_db (dB, retirada ao C/N0 efetivo de cada ligação) e loss_model. A perda é a de entrada gaussiana, assinalada como não válida para jammers CW, de banda estreita e de varrimento.
    • Sem as secções, todas as saídas são idênticas byte a byte.
    • Verificado face a limiares pré-registados em 70c72fcc. A perda do quantizador fica dentro de 0,0007 dB de um Monte Carlo independente, e a leitura do AGC dentro de 0,012 dB do laço de AGC da camada IQ.
    • As execuções de histerese registadas foram pouco informativas (todas as ligações perdidas), pelo que esse limiar é NOT MET. Um conjunto suplementar de execuções registado em 37793290 satisfaz-o: cada indicador é igual a um recálculo independente, e 732 de 1824 ligações mostram a histerese.
    • Resultado: com um jammer CW, um ADC de 1 bit perde cerca de 5 dB mais do que o valor gaussiano.
    • MODELLED; linha do registo "Acquisition hysteresis and the front-end quantiser in the jamming kind against independent recomputations".
  • Sombra de terreno sobre o jammer no tipo de cenário jamming (CAP-06b): uma secção opcional [terrain] num cenário jamming com um jammer. Campos:

    • dem_hgt: uma tesela SRTM .hgt, relativa ao diretório de trabalho;
    • samples_per_side, ll_lat_deg e ll_lon_deg (graus): o tamanho e o canto da tesela;
    • geoid_undulation_m (m, por omissão 0), k_factor (por omissão 4/3) e profile_step_m (m, por omissão 30).

    O motor amostra o perfil de terreno em círculo máximo entre o jammer e o recetor e encontra o gume de faca dominante. A potência recebida do jammer, e portanto cada J/S, é reduzida pela perda de gume de faca único da ITU-R P.526-15 §4,1.

    • O resultado passa a ter um bloco jammer_terrain: nu_max (1), diffraction_loss_db (dB), obstacle_distance_m (m), obstacle_terrain_m (m), path_length_m (m) e profile_points (contagem).
    • Sem a secção, todas as saídas são idênticas byte a byte.
    • Verificado face a limiares e a dez posições pré-registados em 92cd2bfd, na tesela SRTM real versionada do Vale da Morte, face a um recálculo independente em numpy. Todos atingidos: pior diferença 1.6e-10 em ν e na perda (limiar 1e-9), a perda monótona na altura do jammer, e a perda a reduzir o J/S exatamente do seu valor.
    • MODELLED; linha do registo "Terrain shadowing of the jammer in the jamming kind against an independent numpy recomputation on a real SRTM tile".
  • Ganhos de antena CRPA no tipo de cenário jamming (CAP-06a): uma secção opcional [crpa] num cenário jamming. Campos: elements_enu_m (posições dos elementos em este-norte-cima local, m), weighting ("null-steering" ou "mvdr") e bandwidth_mhz (largura de banda de ruído do MVDR, MHz, por omissão o dobro da taxa de chip).

    • Cada canal forma um feixe sem distorção na direção do seu satélite. O ruído da ligação é escalado por ‖w‖² e o jammer por |wᴴa_j|² antes da equação de C/N0 anti-jam existente.
    • Cada ligação passa a ter um bloco crpa: array_noise_gain_db (dB) e jammer_gain_db (dB).
    • Sem a secção, todas as saídas são idênticas byte a byte.
    • Uma secção inválida (uma lista de elementos vazia, uma ponderação desconhecida, uma largura de banda não positiva) é um erro, através de kshana e api::run_toml tal como de jamming::run_jamming.
    • Verificado face a limiares pré-registados em 08d83b4d. Atingidos: aditividade (após uma correção: a primeira compilação acrescentou as novas unidades à tabela de unidades de cada execução de jamming); um elemento não é um agrupamento; ganho de ruído e C/N0 efetivo face a um recálculo independente em numpy dentro de 1e-9 dB; o MVDR tende para o nulo com JNR elevado.
    • Não atingido: o ganho do jammer do MVDR em 194 de 456 ligações com a matemática portátil da 0,36 (202 com matemática do anfitrião; docs/revisions/STUDIO15-batch4-rebaseline.md) (pior 1.7e-6 dB). Os resíduos de −100 a −188 dB estão abaixo da resolução do float64 nesse limiar, e o numpy discorda de si próprio na mesma ordem de grandeza.
    • MODELLED; linha do registo "CRPA antenna gains in the jamming kind against an independent numpy recomputation".
  • Motor de seguimento IQ face ao GNSS-SDR 0.0.19 (PRO-33): kshana iq track e o GNSS-SDR seguem as mesmas gravações independentes em numpy de GPS L1 C/A a 30 a 45 dB-Hz.

    • Limiares pré-registados em 48edd4a5. A calibração registada falhou numa passagem errada do GNSS-SDR (F3), pelo que a Emenda 1 (1e4288c4) acrescenta aos dois recetores um FLL apenas de captura inicial, versionado antes de qualquer gravação de teste.
    • Atingidos: o jitter de portadora e de código e o Doppler concordam dentro de 5 % em todos os C/N0.
    • Não atingidos: o C/N0 NWPR do motor lê 2,3–7,1 dB abaixo do SNV do GNSS-SDR (F4, um limite conhecido do estimador; o M2M4 está a 0,06 dB da verdade); os indicadores de bloqueio diferem por definição (F5); um desacordo de deslize a 30 dB-Hz (F6).
    • MODELLED; linha do registo "IQ tracking engine against GNSS-SDR 0.0.19 on independent recordings".
  • Duas linhas VALIDATED para códigos da camada IQ (DS-GIQ-06b, PRO-39).

    • BeiDou B1I. Todos os 63 códigos primários B1I coincidem, chip a chip, com o gerador independente do GNSS-SDR v0.0.19 (limiar pré-registado em 911106d1). Apenas a saída desse programa está versionada: os códigos PRN B1I que o ICD público define, como prefixo e soma de controlo.
    • GPS L1C. Todos os 126 códigos L1CP/L1CD e 63 sobreposições L1CO coincidem com as colunas de verificação que a IS-GPS-800J imprime, e a sequência de Legendre calculada coincide com a sua Tabela 6.2-1 (limiares pré-registados em fe372e26).
    • Linhas: "BeiDou B1I primary ranging codes against an independent generator" e "GPS L1C ranging and overlay codes against the IS-GPS-800J printed check columns".
  • Bandas GLONASS, BeiDou e Galileo E6 no modelo de espetro (CAP-12, sinais): novos nomes de banda glonass-l1of e glonass-l2of (qualquer canal FDMA como glonass-l1of-k<K>, K = −7 a 6), beidou-b1i, beidou-b1c, beidou-b2a, beidou-b3i e galileo-e6. Cada uma traz a portadora, a modulação e a potência mínima recebida do seu ICD. São opcionais por nome: o conjunto de bandas predefinido e todas as saídas existentes não mudam.

    • Verificado face a limiares pré-registados em 5806f28b: os valores do ICD, os nulos, o composto B1C e o caminho C/N0 são atingidos.
    • Dois limiares não foram atingidos. O limiar de área unitária era inatingível tal como escrito (F1). As formas de onda B1I e B1C da camada IQ só coincidem com o modelo em média de banda, devido aos espetros de riscas irregulares dos seus códigos (F2).
    • MODELLED; linha do registo "Spectrum model: GLONASS, BeiDou and Galileo E6 bands (opt-in)".
  • Opção CFAR de média de células na aquisição IQ (PRO-37): iq::acq::ca_cfar e ca_cfar_cells decidem numa grelha de aquisição comparando cada célula com a média de células de referência na sua linha de Doppler. O limiar vem da probabilidade de falso alarme CA-CFAR em forma fechada para M blocos não coerentes (ca_cfar_pfa, ca_cfar_alpha), pelo que a decisão não depende da normalização da potência das amostras. É opcional; o detetor predefinido e todas as saídas existentes não mudam.

    • Verificado face a limiares pré-registados em 3724aefa: a forma fechada face a Monte Carlo (18 de 18 casos), e uma taxa de projeto de 1 % medida em 0,97–1,01 % em ruído gaussiano e em ruído quantizado a 2 bits.
    • Um limiar não foi atingido: num sinal de 2 bits sem ruído, 1,28 % das células fora do pico excedem o limiar, nos lóbulos laterais de correlação do código (resultado F1).
    • MODELLED; linha do registo "Cell-averaging CFAR option in IQ acquisition".
  • Modelo de cintilação face a dados medidos (PRO-34): o modelo de cintilação de Cornell do canal IQ foi comparado com intensidade e fase GPS L1 medidas a 50 Hz numa noite de cintilação equatorial (registo Zenodo 16941224, INGV, Malindi, CC BY 4,0), sob limiares pré-registados em b6ccb499. Atingidos: a distribuição da intensidade e a cintilação de fase ligada ao S4. Não atingido: o modelo desvanece 2,4 vezes mais frequentemente abaixo de −10 dB e 3,5 vezes mais tempo (resultado F1). O processamento registado lê a fase enrolada do modelo (resultado F2); o resultado de fase mantém-se com ela desenrolada. scripts/fetch_scint_malindi.sh obtém os dados. A linha continua MODELLED: "IQ ionospheric scintillation channel (Cornell model) against measured 50 Hz GPS L1 scintillation".

  • Leitor de amostras LuGRE corrigido (MR-09): realdata::lugre::parse_iqs_sdrx lê um lote IQ LuGRE com I no nibble alto e os níveis mid-rise 2v + 1 (SdrLayout::mid_rise), que retiram a média de −½ que os inteiros em complemento para dois simples trazem em I e Q. run_acq.py --corrected dá ao GNSS-SDR a mesma leitura. O leitor ION genérico e todas as saídas existentes não mudam: 149 resultados de cenário e um estudo são idênticos byte a byte antes e depois, e os resultados LuGRE fixados leem-se como registados (xval/lugre-reader/RESULTS.md). Nenhuma linha do registo muda.

  • Seguimento BOC(1 1) opcional (CAP-07 (a)): LoopConfig::boc reescala os discriminadores do DLL para o pico principal do BOC(1 1) em seno e acrescenta um monitor bump-jump (correladores muito adiantado e muito atrasado a ±0,5 chip, contadores ascendentes/descendentes, N = 8) que afasta o NCO de código de um pico lateral; Channel::bump_jumps lista os saltos. Desligado por omissão, e todas as saídas existentes não mudam. Verificado face a limiares pré-registados em 6b68f6cc num sinal BeiDou B1C sintético: um arranque em pico lateral que fica a 0,55 chip sem a opção é puxado para o pico principal por um salto aos 0,08 s com ela, e não se viu nenhum salto falso a partir do pico principal. Um limiar não foi atingido: a grelha de testes unitários da escala chega a fora do intervalo linear dos discriminadores (resultado F1 em docs/design/evidence/boc-bump-jump/RESULTS.md). MODELLED; linha do registo "BOC(1 1) tracking: DLL scaling and bump-jump ambiguity resolution (opt-in)".

  • Ajuste de laboratório a partir de campanhas IQ (B7.1, docs/design/LABFIT-FROM-IQ.md). O [input] campaign = "<out-dir>" de um cenário labfit ajusta uma pasta de saída de kshana iq campaign na CLI (kshana iq labfit), em Python (kshana.iq_labfit) e na ferramenta labfit do MCP (apenas pastas dentro do seu diretório de trabalho). Ajusta uma unidade por sinal, projeto de laço, cadeia de front-end e tipo de jammer:

    • o modelo de C/N0 face a J/S indicado, com censura;
    • o limiar de seguimento, diretamente e em forma fechada;
    • os modelos de bloqueio do laço de seguimento e empírico, acoplados através do modelo de C/N0, com os seus tempos de permanência;
    • um bootstrap de agrupamentos com semente sobre as gravações, intervalos de previsão de 90 % e conjuntos reservados deixando uma gravação de fora;
    • uma tabela [validation] pré-registada, com soma de controlo, com PASS/FAIL por limiar.

    O relatório é kshana.labfit-iq/1 em JSON, CSV e Markdown, com um bloco de unidades. Q_eff não é identificável a partir de dados de C/N0 sem uma medição de potência independente. É indicado, nunca ajustado, e o parâmetro ajustado é delta_eff = delta - 10 log10 Q (alteração de projeto de 2026-10-12). Um tipo de jammer desconhecido assume o Q indicado mais prejudicial (cw, 1). Em campanhas sintéticas a partir das cenas do próprio Kshana, o limiar de cobertura do conjunto reservado (c) passa. Os limiares (a') e (b') de delta_eff (0 de 50 campanhas cobertas) e o limiar de seguimento em forma fechada (d) não são atingidos: ficam registados com os seus valores. MODELLED; linha do registo "Calibration of the open receiver's C/N0 and lock models to IQ campaign results, with stated prediction error". O caminho labfit de registo de recetor e as suas saídas não mudam.

  • solar-system num kernel da JPL (CAP-31): planetary_kernel_path toma cada corpo que o SPK contém (com de440s: Mercúrio, Vénus, a Terra, a Lua) do kernel, etiqueta KERNEL, e acrescenta um bloco kernel apenas quando definido. Nova linha, VALIDATED face ao SPICE (pré-registada f8e946ea; pior 3.3e-5 m, 1.0e-11 m/s). O relatório predefinido não muda.

  • Porkchop na efeméride DE440 (CAP-20b): maneuver::porkchop_kernel varre C3 e V∞ de chegada em estados heliocêntricos de um SPK DE440. Nova linha, VALIDATED face a estados do SPICE

    • pykep 3.0.1 (pré-registada 2d857fb1; Terra a Marte 2026-2028, 304 células, pior 2.6e-14, a mesma célula de C3 mínimo).
  • Macromodelo não gravitacional do LRO: NOT MET (DS-LRO-10, pré-registado e82047e2). lunar_od::LunarMacroModel (opcional através de LunarForceModel::macro_model): radiação solar direta em placa plana com a sombra da Lua, um painel que segue o Sol, e albedo lunar e infravermelho térmico; LunarMacroModel::lro_generic é uma aproximação genérica de LRO etiquetada, a partir de factos publicados (sem placas do corpo: a tabela de placas não pôde ser obtida). No arco de 4 h do LRO, deixa o RMS reduzido-dinâmico em 6,668 m e o dinâmico em 11,94 m, com um fator de radiação inverosímil (cerca de +21 / −22), pelo que os três limiares são falhados. O resultado está fixado por um teste, e nenhuma saída predefinida muda (docs/design/evidence/ds-lro-10-macro-model/RESULTS.md). O SRP lunar de bala de canhão opcional usa agora a sombra cónica da Lua em vez da da Terra (forces::conical_shadow_body).

  • OD lunar: maré sólida k2 opcional e relatividade selenocêntrica (DS-LRO-11), desligadas por omissão (LunarForceModel::lunar_tide, ::relativity); um seletor KSHANA_LRO_DEGREE para a validação cruzada com o ANISE (DS-LRO-04); um conjunto de dados de ensaio de arco de 24 h do LRO e um ajuste de arco longo apenas informativo (DS-LRO-09). As execuções informativas estão registadas em docs/design/evidence/ds-lro-09-11-longer-arc/RESULTS.md; nenhum número publicado muda.

  • NRHO CR3BP 9:2 face ao CAPSTONE (CAP-29d): nova linha MODELLED que mede a NRHO circular restrita do motor face à órbita voada do CAPSTONE (JPL Horizons, março de 2023; pré-registada 4e868170): período 1,07 %, apolune 0,05 %, perilune 4,1 % a partir das médias do CAPSTONE, dentro dos limiares registados de 3 / 5 / 20 %. Uma medição, não uma validação.

  • Estados rotativos CR3BP para ICRF centrado na Lua (RM-34, FUT-06): cr3bp::to_moon_centred_icrf / from_moon_centred_icrf / to_moon_centred_icrf_de440 mapeiam um estado rotativo adimensional Terra-Lua para a linha Terra-Lua instantânea da DE440, incluindo a taxa fora do plano do referencial. Nova linha, VALIDATED face a um referencial de dois vetores do SPICE (pré-registada 2313eb1b, alterada antes de qualquer execução d5ef79b3; 72 casos, pior 1.8e-7 m e 1.2e-9 m/s).

  • Membros de famílias CR3BP face à API de Órbitas Periódicas de Três Corpos do JPL: NOT MET (RM-35, pré-registado a9074f65). cr3bp_family (correção de halo, NRHO e DRO, índice de estabilidade da monodromia, continuação por pseudo-comprimento de arco) coincide com 54 de 58 membros da API em todos os limiares (estado, período e Jacobi dentro de 1e-10 em todos os casos). Um índice de estabilidade de halo L1 (9.5e-2) e três fechos de DRO pequenas (1.5e-8 a 3.3e-8 contra 1e-8) falham, pelo que o módulo é #[doc(hidden)] e nenhuma linha o reclama. Resultados: docs/design/evidence/cr3bp-families/RESULTS.md.

  • Orientação e ambiente lunares DE440 opcionais (FUT-05, DS-LRO-08; predefinições inalteradas): lunar_frame::try_icrf_to_moon_pa_de440, lunar::try_mci_to_mcmf_de440 / try_mcmf_to_mci_de440 (ancoradas à época, eixos principais DE440) e lunar_od::De440LunarEnvironment (orientação de eixos principais DE440 incorporada mais o Sol e a Lua geocêntricos de um SPK DE440 fornecido pelo utilizador). Face ao ANISE (pré-registado ea537710): orientação dentro de 3.5e-7 rad e ajustes do LRO dentro de 1 mm, mas o ramo da efeméride falhou o seu limiar (Sol 30,7 m, Lua 1,1 m, um desvio de tempo de ~1 ms do lado do ANISE), pelo que não é uma linha validada. Resultados: docs/design/evidence/fut05-de440-lunar-env/RESULTS.md.

  • Datum da campanha do referencial lunar, limiar NumPy escalado pela condição: NOT MET (pré-registado b887eb05; continua MODELLED). O passo 0 exclui o recurso à pseudo-inversa como causa da diferença de 0,30 com as estações estimadas; o NumPy concorda dentro do limiar em seis de oito cenários, mas stations_estimated falha-o (6.8e-6 contra 5.9e-7), e na data nova 2026-12-01 uma baliza do polo sul não observada torna a informação da baliza deficiente em característica, o que a referência independente inalterada não consegue avaliar. Resultados: docs/design/evidence/mr05-lunar-datum-cond/RESULTS.md.

  • Datum do referencial lunar a partir de uma campanha de observação real (Lua analítica) VALIDATED em pontos normais EDC novos de 2025 (pré-registado 31f5283 antes de qualquer um ser obtido): a referência independente SPICE e NumPy inalterada concorda na contabilidade, nas características e no acoplamento nulo, e dentro de 1.11e-3 nos sigmas (limiar 1e-2), 8.95e-4 na condição e 1.79e-3 nas razões transversal/longitudinal (limiar 2e-2). Apenas uma verificação de biblioteca do cálculo da covariância; os limiares não discriminam modelos da Lua. Resultados: docs/design/evidence/mr06-llr-analytic-fresh/RESULTS.md.

  • Orientação IAU dos corpos e GM dos catorze corpos do sistema solar acrescentados, separados da linha "Physical constants of every solar-system body" para uma linha VALIDATED (pré-registada 154bc54): Body::iau_rotation_et concorda com o pxform do SPICE em pck00011 dentro de 1e-9 rad em 574 matrizes nas épocas originais e em 574 em 41 épocas novas nunca comparadas antes (pior Fobos 1.38e-10 rad), e Body::mu é igual a gm_de440 para os catorze corpos. O resto da linha original (J2, raio médio, o relatório) continua MODELLED. Resultados: docs/design/evidence/mr08-body-orientation/RESULTS.md.

  • Lambert de várias revoluções (maneuver::lambert_multirev): todas as soluções com até três revoluções, ambos os ramos. Nova linha do registo, VALIDATED face ao pykep 3.0.1 (pré-registada a75de851; 382 casos, 1058 soluções, pior diferença de velocidade 1.6e-13 contra 1e-8). A guarda interna de aterragem de Kepler encontrou uma limitação de maneuver::kepler_universal num arco com e = 0,994; está registada em docs/design/evidence/lambert-multirev/RESULTS.md.

  • Pressão de radiação solar de caixa-asas e ECOM2 (DS-PA-14), opcional. srp_boxwing: um modelo de caixa-asas de placas planas com as tabelas Galileo FOC/IOV dos metadados de satélites do GSC, em guinada GNSS nominal, com derivadas parciais do fator de radiação e por painel, e o modelo empírico ECOM2 com as suas derivadas parciais. Selecionado com ForceModel::box_wing_srp / PreciseForceModel::box_wing_srp (campos srp_boxwing, por omissão None: o caminho de bala de canhão e todos os valores de referência não mudam); com um conjunto de caixa-asas, cr é o seu fator de radiação. Comparado com o Orekit 12,2 sob um pré-registo (xval/srp-boxwing-orekit/): todos os limiares atingidos, cerca de 1e-15 relativo; VALIDATED como avaliação de modelo, a previsão de SRP do Galileo continua MODELLED.

  • Sombra de SRP com Terra achatada e escurecimento de limbo solar (FUT-09, RM-11). Novo módulo srp_shadow: oblate_conical_shadow (elipsoide ocultante WGS-84), limb_darkened_shadow (lei de Eddington) e ShadowModel, selecionado com ForceModel::srp_shadow (por omissão: a sombra cónica esférica existente, inalterada); forces::srp_accel_with_lit_fraction. A sombra achatada concorda com a razão de iluminação do Orekit 12,2 dentro de 7.4e-9 em 2400 geometrias (VALIDATED, xval/srp-oblate-shadow-orekit/); o escurecimento de limbo não tem referência independente externa (MODELLED).

  • Termosfera NRLMSISE-00 (FUT-08, RM-10, DS-PA-13). nrlmsise00: uma adaptação de gtd7 e gtd7d (comutadores, modos de Ap diário e de matriz ap de 3 horas) da versão em C de domínio público do Fortran do NRL. É idêntica bit a bit a essa adaptação em C e fica dentro de 1.9e-6 relativo do pymsis 0.13.0 (Fortran do NRL, precisão simples) numa grelha de 720 pontos, e reproduz os 17 casos de teste publicados (VALIDATED; xval/nrlmsise00-pymsis/). Isto valida a adaptação, não a exatidão do modelo face à densidade medida.

  • Nível opcional de densidade de arrasto NRLMSISE-00. forces::DensityModel::{Exponential, Nrlmsise00 { f107a, f107, ap }}, forces::drag_accel_with_density, density_at e propagator::ForceModel::drag_density. O modelo exponencial estático continua a ser o predefinido, bit a bit. A meteorologia espacial é constante por modelo. VALIDATED ao nível da órbita face ao arrasto NRLMSISE-00 do próprio Orekit 12,2 ao longo de 24 h (pior 0,03 m contra até 142 km de deslocamento por arrasto; xval/drag-tier-orekit/).

  • Sol e Lua DE440 opcionais no propagador de Cowell (RM-33, FUT-10). propagator::ForceModel::with_ephemeris aceita qualquer EphemerisProvider (por exemplo, um KernelEphemeris DE440) para os termos de terceiro corpo e de SRP; recusa um fornecedor que não consiga servir a época, conta os recursos à série analítica e está desligado por omissão. EphemerisProvider::relative_position_jd2 mantém precisão em duas partes. Face ao Orekit 12,2 no seu próprio leitor DE440, as órbitas de 24 h concordam até 0,017 m; o limiar pré-registado de posição do Sol/Lua foi falhado (6,4 m / 0,24 m; o SPICE mostra a mesma diferença), pelo que MODELLED (xval/propagator-de440-orekit/).

  • Maré atmosférica S1 opcional (DS-PA-03). tides::atmospheric_tide_s1 e s1_air_tide_acceleration (Biancale & Bode 2006, GFZ STR06/01 Tabela 1 modelo N1, graus 2–6), ativadas com air_tide_s1() em propagator::ForceModel e precise_od::PreciseForceModel; desligadas por omissão. MODELLED (coeficientes reverificados face à tabela publicada; sem referência independente externa para o efeito da força).

  • Determinação de órbita em lote com taxa de distância e azimute/elevação e máscara de elevação (RM-36, FUT-13). orbit_determination::determine_orbit_batch_tracking, simulate_tracking, predict_tracking, propagate_with_stm (STM variacional com derivadas parciais analíticas de dois corpos + J2), is_visible, measurement_with_partials; batch_ls::gauss_newton_analytic. O caminho só por distância não muda. Comparado com os mínimos quadrados em lote do Orekit 12,2 em 8 cenários pré-registados: todos os limiares atingidos exceto a concordância de estado sem ruído (≤ 1 cm), falhada em 2 de 4 cenários a 1,46 e 1,74 cm com o kshana a 1e-8 m da verdade; registado, MODELLED.

  • Ponderação de exatidão SP3 (DS-PA-06). sp3::parse_sp3_accuracy e Sp3Accuracy::position_sigma_m mapeiam os códigos de exatidão do cabeçalho e de cada registo para sigmas de observação; uma variante do ajuste Galileo ponderada por SP3 (RMS 3D de Nível 2 de 0,035 m contra 0,070 m sem ponderação) é acrescentada ao lado das execuções registadas inalteradas. MODELLED.

  • Tarefa de despacho de arco completo do Swarm-A (DS-PA-08) em .github/workflows/agency-od-validation.yml.

  • Gravidade planetária a partir de tabelas SHADR do PDS (CAP-30, parte de CAP-31). SphericalHarmonicField::from_shadr (src/gravity_pds.rs) lê o Mars GMM-3 (g/o 120) e o GRAIL GL0660B (g/o 660); Body::with_gravity_field associa qualquer campo carregado (predefinições inalteradas). Estão incluídos recortes de grau 20 (NASA PDS, domínio público; tests/fixtures/planetary_gravity/NOTICE.md); os ficheiros completos são obtidos por xval/planetary-gravity-pyshtools/fetch_data.sh. VALIDATED face ao pyshtools 4.14.1 (dentro de 4e-15 da gravidade total a g/o 120 em toda a esfera, 5e-14 a g/o 660 para |lat| ≤ 60°); a ligação ao referencial do corpo continua MODELLED (o referencial nativo de cada campo não é o referencial IAU usado).

  • Gravidade de grau elevado até ao grau 2190 (RM-14, FUT-07). SphericalHarmonicField::acceleration_hf / potential_hf (coluna progressiva modificada de Holmes–Featherstone, sem subexcedência, sem singularidade polar), prepare_high_degree, um carregador ICGEM em fluxo from_gfc_file / from_gfc_reader (verificações de norma e de grau máximo, sistema de marés registado, termos variáveis no tempo rejeitados) e scripts/fetch_egm2008.sh (EGM2008 completo, SHA-256 fixado, não incluído; testes condicionados por KSHANA_EGM2008_GFC). propagator::FieldEvaluator seleciona-o no opcional Geopotential. Concorda com o Orekit 12,2 até 7.3e-17 m/s² até ao grau 2190, e uma órbita de 24 h 200×200 concorda até 0,13 m. MODELLED: o pyshtools falhou o limiar pré-registado junto ao polo (atribuído ao pyshtools) e o controlo de sensibilidade de grau 70 da órbita falhou (0,73 m < 1 m); ambos estão registados em xval/.

  • Integrador DOP853 (FUT-11). integrator::integrate_dop853, integrate_dop853_checked, integrate_dop853_dense (saída densa de 7.ª ordem), dop853_step, dop853_initial_step, com uma guarda de passo que falha de forma segura; propagator::Integrator::Dop853, propagate_dop853, propagate_dop853_checked. O controlador predefinido não muda. VALIDATED face ao SciPy 1.18.1 solve_ivp(method="DOP853"): passos isolados dentro de 5.6e-15, sequências de passos coincidentes, estados finais dentro de 1.6e-12 (xval/dop853-scipy/).

  • Resolvedor robusto de Kepler (FUT-12). Novo módulo kepler: solve_kepler_markley (arranque de Markley 1995, resíduo sem cancelamento) para todos os 0 ≤ e < 1, envolvido por propagator::solve_kepler_robust. VALIDATED face a raízes mpmath de 50 dígitos até 0,9 ε·|E| até e = 0,999999 (xval/kepler-mpmath/).

  • Gravidade terrestre tesseral opcional no propagador de Cowell (RM-09). propagator::ForceModel passa a ter geopotential: Option<Geopotential> (with_geopotential, with_egm2008(nmax)). Avalia um SphericalHarmonicField (EGM2008 incluído até grau/ordem 70, ou qualquer .gfc ICGEM) num referencial fixo à Terra alcançado pelo ângulo de rotação da Terra (EarthFixedFrame::Era) ou pela cadeia GCRS-ITRS CIO (EarthFixedFrame::Cio). Por omissão None: nenhuma saída existente muda. VALIDATED face ao Holmes–Featherstone do Orekit 12,2 ao longo de 24 h (6 casos, pior 0,036 m), com os limiares pré-registados em xval/cowell-tesseral-orekit/PREREGISTRATION.md.

  • Datas julianas em duas partes através da rotação da Terra no caminho da órbita: jd2::gmst82, cio::gcrs_to_itrs_matrix_jd2, frames::teme_to_itrf_jd2 / itrf_to_teme_jd2, orbit::Propagator::position_in_frame_jd2 e own_jd2_utc, conversões From entre jd2::Jd2 e timescales::TwoPartJd, e um two_part_jd = true opcional para o cenário ephemeris (ECEF, traço no solo e vista de estação; desligado e inalterado por omissão, e a chave fica fora da soma de controlo do cenário quando desligada). Nova linha do registo, VALIDATED face ao pyerfa gmst82/c2t06a (pré-registada b10475ee; 40 datas: GMST idêntico bit a bit, matriz dentro de 2.7e-14, rotação em passos de 1 µs dentro de 1.1e-14 rad, onde o caminho de f64 único as falha). A época do modelo de forças de Cowell continua em f64 único; a razão está na sua documentação.

  • Previsão de EOP para além da tabela (EopSeries::with_ls_ar_prediction, EopSeries::last_mjd): uma extensão opcional de uma série de orientação da Terra do IERS pelo preditor LS+AR emitido na sua última linha, de modo que os argumentos de referencial de uma época posterior seguem a previsão em vez de ficarem fixos na última linha. As respostas dentro da tabela são idênticas bit a bit (testado); a série continua a fixar-se, a menos que isto seja chamado. A exatidão da previsão continua a ser o resultado LS+AR existente face ao Bulletin A (MODELLED).

  • Desvios do polo celeste dX, dY na cadeia CIO (cio::gcrs_to_cirs_matrix_with_offsets), e verificações diretas de vetores ERFA de precession_matrix, teme_to_gcrs_matrix e da nova função. Nova linha do registo, VALIDATED face ao pyerfa (pré-registada 979c1e39; 40 épocas 1950–2100: precessão e CIO idênticas bit a bit, TEME→GCRS dentro de 1.1e-10 rad, o efeito previsto da série de dois termos da equação dos equinócios). As funções existentes não mudam.

  • UTC anterior a 1972 no caminho de tempo em duas partes (timescales::tai_minus_utc_on_date, e Jd2::from_utc_calendar, jd2::utc_to_tai e jd2::tai_to_utc a partir de 1960-01-01): a era da taxa em deriva ("segundo de borracha"), com a tabela de deriva do SOFA, degraus fracionários de fim de dia e a conversão da fração do dia de UTC para SI. Nova linha do registo, VALIDATED face ao pyerfa dtf2d/utctai/taiutc (pré-registada 23c40661; 117 instantes 1960–1971, pior 2.9e-11 s contra um limiar de 1 µs). Todos os resultados de 1972 em diante são idênticos bit a bit (soma de controlo fixada antes da alteração). Antes de 1960, TAI − UTC é 0, como no SOFA. O timescales::tai_minus_utc de f64 único não muda.

  • Relógio de satélite GLONASS difundido (GlonassEphemeris::sv_clock_bias_s): −τn + γn·(t − tb) a partir do registo RINEX, num tempo lido no relógio do satélite (duas iterações de ponto fixo, a convenção do RTKLIB). Os −τn e γn lidos não eram usados anteriormente. Nova linha do registo "GLONASS broadcast satellite clock and broadcast-orbit propagation", VALIDATED face ao RTKLIB 2.4.2-p13 geph2clk/geph2pos (pré-registada e099c42a; 292 casos num ficheiro de difusão real de 2013: diferença de relógio 0 s, pior posição 1,1 mm contra um limiar de 1 cm). Função de biblioteca; nenhuma saída de cenário muda. Não é aplicada nenhuma transformação PZ-90.11 → ITRF, e o módulo di-lo.

  • Solução de tempo PPP face ao relógio de estação do IGS (0,36, FUT-19): o relógio do recetor do filtro PPP float em WTZR concorda com o relógio combinado final do IGS para a estação até 0,075 ns (desvio-padrão) com um desvio constante de −0,66 ns nas duas horas convergidas. Os limiares foram pré-registados em xval/ppp-time/. VALIDATED (nova linha do registo). Novo conjunto de dados de ensaio igs_2025055_WTZR_05m_0006.clk, os registos de relógio de estação do ficheiro de relógios finais do IGS já usado para os relógios dos satélites.

  • Paridade do PPP com o gLAB (0,36, WP-07, RM-31): o gLAB 6.0.0 foi executado sobre as mesmas entradas WTZR como ferramenta separada (núcleo Apache-2.0; soma de controlo da descarga verificada face à lista publicada), com a linha de comandos de uma alteração processual versionada antes da execução. Na sua primeira execução registada, o PPP float do Kshana e o do gLAB concordam dentro de 0,05 m em 240 de 240 épocas e até 5,0 mm na última. O limiar de SPP foi falhado (mediana 1,187 m contra 0,50 m) e fica registado como resultado: as próprias soluções SPP do gLAB e do RTKLIB diferem entre si em 0,852 m. A regra registada deixa por isso os ramos das duas ferramentas como não atingidos no seu conjunto, embora a paridade do PPP se verifique.

  • Leitura de navegação RINEX 4 (0,36, WP-07, PRO-41): rinex::parse_nav lê ficheiros de navegação RINEX 4.00-4.02 (> EPH GPS LNAV, Galileo I/NAV e F/NAV, BeiDou D1/D2, QZSS LNAV; outros registos saltados até ao cabeçalho de registo seguinte), e parse_nav_with aceita opções. VALIDATED face ao ficheiro RINEX 3 fundido do IGS do mesmo dia: todos os campos descodificados idênticos e 0 m em posição. A leitura de RINEX 2/3 não muda.

  • Posições difundidas BeiDou GEO (opcional): NavParseOptions::include_beidou_geo e RinexEphemeris::sv_position_ecef_bds_geo (BDS ICD, inclinação de −5 graus). parse_nav continua a saltar os GEO. MODELLED: a comparação pré-registada com uma órbita precisa está condicionada pelos dados e ainda não foi executada.

  • Ficheiros de observação RINEX 4: um ficheiro de observação MGEX RINEX 4,00 real é lido nos testes (MODELLED, aderência à norma do formato).

  • RTK com LAMBDA em RINEX real (0,36, WP-07 ★): rtk_real::run_rtk, duplas diferenças de linha de base curta de código e fase GPS de dupla frequência com um filtro de Kalman float e fixação de inteiros LAMBDA (teste de razão). VALIDATED nas estações IGS WTZR e WTZZ (a 1,4 m uma da outra) face à sua linha de base ITRF2020 sob limiares pré-registados: fixado em todas as épocas após os primeiros dez minutos, erro de linha de base com mediana de 4,5 mm e percentil 95 de 5,5 mm.

  • Paridade do PPP de dados reais com o RTKLIB (RM-31): xval/ppp-parity/run.sh e tests/ppp_parity_glab_rtklib.rs com limiares pré-registados. O PPP do RTKLIB v2.4.2-p13 sobre as mesmas entradas WTZR concorda com o Kshana dentro de 5 cm em todas as épocas das duas últimas horas (9,7 mm no fim) no terceiro registo; as duas primeiras execuções, registadas como resultados, tinham a maré sólida desligada e a antena do recetor no espaço de base do RTKLIB. O limiar de paridade de ponto único foi falhado (mediana de 1,09 m contra 0,5 m). O ramo do gLAB não foi executado (condicionado pelos dados).

  • Codificadores de mensagens de navegação para além do LNAV (0,36, WP-07, PRO-40): gnss_navmsg codifica GPS CNAV (tipos de mensagem 10, 11, 30; CRC-24Q; codificação contínua de taxa 1/2 K=7), Galileo I/NAV (tipos de palavra 1-5 em páginas nominais par/ímpar; entrelaçador 30x8; sincronização 0101100000) e Galileo F/NAV (tipos de página 1-4; entrelaçador 61x8; sincronização 101101110000), com descodificadores de teste. MODELLED: idas e voltas e respostas conhecidas do ICD; uma verificação pré-registada de que as efemérides Galileo difundidas ficam na grelha de LSB do codificador manteve-se (pior 3.6e-3 LSB) mas falhou o seu limiar de número de satélites (15 de 20), registado. Os codificadores são funções de biblioteca; a ligação às cenas não faz parte desta alteração.

  • Leitor de ficheiros IONEX (0,36, WP-07): ionex::parse_ionex_file com IonexFile, IonexHeader, IonexEpoch, IonexFileMap e IonexTimeInterp: um leitor IONEX 1,0 estrito de colunas fixas, com épocas contadas a partir do dia do primeiro mapa, 9999 lido como em falta, mapas de RMS e as interpolações temporais do formato por vizinho mais próximo, consecutiva e de mapa rodado; TEC oblíquo à altura da camada do cabeçalho. Verificado num mapa sintético versionado e, condicionado pelos dados (obtido no momento do teste com um SHA-256 fixado, não incorporado), num recorte de um GIM real do CODE: todos os nós exatos; a interpolação coincide com uma referência de fórmula até 4e-13 TECU. O iontec do RTKLIB concorda até 3.6e-13 TECU em 6885 pontos (B6 pré-registado). VALIDATED com evidência condicionada pelos dados (decisão do responsável, 2026-10-13): o teste falha com qualquer mapa que não seja o fixado por SHA.

  • Suavização de portadora de Hatch (0,36, WP-07): hatch::HatchFilter e pvt::assemble_epoch_precise_smoothed, a forma sem divergência (livre de ionosfera) na montagem precisa de ponto único. MODELLED com um resultado registado: na estação IGS WTZR reduz o erro mediano de ponto único de 1,55 m para 1,12 m e o percentil 95 de 3,47 m para 3,21 m, aquém da redução de 40 % pré-registada (o erro restante é do tipo desvio, não ruído).

  • PPP float em RINEX real (0,36, WP-07): ppp_real::run_ppp, um filtro de posicionamento preciso de ponto estático float em código e fase GPS de dupla frequência reais com produtos finais do IGS (desvios e variações de antena, maré da Terra sólida, wind-up de fase, atraso de Shapiro, atraso húmido estimado, deteção de saltos de ciclo), com parse_antex_receiver. VALIDATED na estação IGS WTZR reservada face à sua coordenada ITRF2020 sob limiares pré-registados: após 6 h o erro é de 1,5 mm na horizontal e 2,9 cm na vertical, e todas as épocas das últimas duas horas ficam dentro de 10 cm.

  • Interpolação de relógio preciso SP3 (0,36, WP-07): Sp3File::clock_s e clock_nodes interpolam linearmente os relógios de satélite SP3 tabelados entre os dois nós válidos que os delimitam (marcador de relógio inválido saltado), e ClockRinex::from_sp3 alimenta com eles PreciseProducts, pelo que a cadeia precisa funciona só com um SP3. VALIDATED face aos relógios finais de 30 s do IGS de 2025-02-24 sob limiares pré-registados: 32 satélites GPS, RMS no ponto médio 0,121 ns (limiar 0,15 ns), percentil 95 0,265 ns (limiar 0,30 ns).

  • RAIM ao lado das figuras de mérito de holdover do relógio (CAP-05b): uma secção opcional [integrity] no tipo de cenário clock reporta um bloco integrity_fom separado (RAIM instantâneo num céu predefinido a partir de um local indicado: veredicto por época e níveis de proteção, disponibilidade; indisponível enquanto o GNSS é negado, nunca extrapolado). As figuras de holdover não mudam; sem a secção a saída é idêntica byte a byte. MODELLED.

  • Limiares de receiver-trust calibrados no JammerTest 2024 (CAP-13): uma calibração pré-registada dos monitores de queda de C/N0, de AGC e de indicador de jamming no conjunto de dados público JammerTest 2024 (obtido em tempo de execução, nunca incorporado; examples/jammertest_trust_calibration.rs), distribuída apenas como o [monitors] profile = "jammertest-2024-calibrated" opcional (1,5 dB, 3,5 sigma, 29). Conjunto reservado: os limiares de AGC, de indicador de jamming e de união passam; o limiar de falsos alarmes de C/N0 falha (0,023 contra 0,02), pelo que a linha é MODELLED (xval/jammertest-trust/RESULTS.md). As predefinições e as saídas sem o perfil não mudam.

  • Hipóteses de falha ARAIM com vários satélites (CAP-05a): a regra de subconjuntos do ADD v4.2 generalizada para além de pares (add_v42_subset_plan, add_v42_protection_levels_to_order; a ordem 2 é exatamente o caminho existente verificado pelo MAAST) e um RAIM avançado opcional sobre essas hipóteses (araim_subset_raim), que reporta o subconjunto de maior separação quando é detetada uma falha. As distribuições a priori que exigem subconjuntos mais profundos são recusadas, nunca truncadas. MODELLED.

  • Linha de horizonte em receiver trust (FUT-01): uma sessão receiver-trust pode indicar uma [skyline]; os satélites atrás dela perdem-se para o céu (sky-blocked, behind_skyline, open_fraction) e as suas perdas são classificadas como geometry, nunca environment; sem uma, o recurso à lacuna de azimute e todas as saídas ficam como antes. O gerador de formação de equipas ganha um evento natural-degradation (um céu bloqueado, não interferência) e o cenário scenarios/training/fjord-natural-degradation.toml. O Monte Carlo de UERE x DOP ganha as duas geometrias de linha de horizonte mascarada da nota de projeto, pré-registadas isoladamente: todas as 26 verificações passam.

  • Verificação de marca temporal RFC 3161 (CAP-14): kshana::evidence::tsa::verify_token verifica, offline, a assinatura de um token de marca temporal (RSA PKCS#1 v1.5, RSA-PSS, ECDSA P-256 e P-384), a sua ligação ao certificado de assinatura ESS, a utilização timeStamping do signatário e a sua cadeia até uma âncora fiável no genTime do token; kshana evidence verify --tsa-ca <anchors.pem> aplica-a ao timestamp.tsr de um pacote (opcional; sem ela o relatório não muda). VALIDATED, de forma estreita: todos os 27 casos autogerados concordam com o OpenSSL 3.0.13 quanto ao veredicto e ao genTime, numa comparação pré-registada antes de o verificador ser escrito. A revogação não é verificada.

  • Níveis de verificação por valor para todos os tipos (RM-04): o resultado de cada tipo de cenário termina agora com um bloco figure_tiers que nomeia os seus valores principais, a linha da matriz de verificação que é responsável por cada um e o nível lido dessa linha (os valores a que nenhuma linha corresponde são listados como sem nível). O bloco é acrescentado após a execução e, retirado, repõe o documento anterior byte a byte (api::without_figure_tiers). lunar-station-coverage não tem figure_tiers até uma nova previsão datada substituir a congelada; leo-ppp, solar-system, sweep e sweep-nd não têm valor principal escalar, e lunar-attack-surface escreve JSON compacto. Os membros de campanhas mantêm os seus documentos sem nível.

  • Predefinição quântica quantum-cai-coast (CAP-08c): um cenário inercial incluído em que um acelerómetro de interferómetro de átomos frios, especificado pela física do seu interferómetro ([accel_quantum.cai] com um nível de vibração da plataforma indicado), segue por inércia face a um acelerómetro de quartzo de grau de navegação durante uma interrupção de GNSS de 110 minutos. MODELLED.

  • Graus de liberdade equivalentes exatos de Greenhall (CAP-03): allan::edf_greenhall, o algoritmo completo de Greenhall e Riley (2003) (ordens de diferença 1 a 3, expoentes de ruído +2 a -4, com e sem sobreposição, modificado e não modificado, com as tabelas de J grande), com envoltórios ADEV, MDEV e HDEV. VALIDATED numa comparação pré-registada com o allantools 2024,6: 4 876 pontos de grelha dentro de 6.0e-13 relativo; o allantools falha em mais 32 pontos, que ficam registados sem valor de referência independente. Os intervalos de confiança de assurance::uncertainty não mudam bit a bit.

  • Termos de erro do interferómetro de átomos frios (RM-26/27/28): ruído de fase do laser Raman (com o termo de atraso de retrorreflexão), o desvio por curvatura da frente de onda de uma nuvem térmica (desfocagem pura, com um raio de deteção) e a resolução da ambiguidade de franjas (assistida por sensor clássico e com dois tempos de interrogação), como funções de biblioteca em src/inertial/cai_error_terms.rs, cada forma fechada verificada por quadratura ou Monte Carlo. MODELLED; ainda não acessíveis a partir de um tipo de cenário (docs/QUANTUM-MODELS.md).

  • Formatos de registo de relógio (RM-03): src/clock_log.rs lê ficheiros de relógio RINEX, registos ASCII de fase ou frequência ao estilo TimeLab e registos de contador TAPR TICC para uma única série de fase normalizada (tau0 indicado ou encontrado, lacunas contadas, uma política de lacunas). Opcional: uma série de temporização de telecomunicações pode nomear um registo ([series.clock_log]), e a tabela [clock_log] de um cenário de relógio acrescenta um bloco measured (ADEV, TDEV, MTIE). Sem a tabela, ambos os tipos de cenário são idênticos byte a byte (docs/CLOCK-LOG-FORMATS.md). Uma comparação pré-registada em três registos sintéticos satisfez os seus limiares de fase e de ligação; os estimadores concordam com o allantools dentro de 2.5e-14 sempre que este avalia, e este não avalia o ponto de MTIE do registo inteiro (registado). MODELLED.

  • Máscaras de deriva da sincronização de frequência (RM-01): o tipo de cenário telecom-timing passa a ter sete máscaras de geração de deriva MTIE e TDEV a temperatura constante, ITU-T G.811 PRC, G.812 Tipos I a III, G.8262 EEC Opções 1 e 2 e G.8262.1 eEEC, com as partes em lei de potência que as tabelas escrevem, e o cenário de referência scenarios/telecom-synce-eec.toml (um OCXO em funcionamento livre face às máscaras EEC: falha aos 1 000 s, onde um laço tem de fazer o trabalho). Cada linha foi relida face ao texto do itu.int; a G.812 (06/2004) foi substituída por uma edição 08/2026 pré-publicada que não pôde ser lida. MODELLED (uma transcrição); as máscaras e saídas existentes não mudam.

  • Orientação sobre a distribuição a priori do filtro para o tipo de cenário gnss-ins (0,36, WP-09, resultado de RM-21): a distribuição a priori predefinida do filtro do pacote adequa-se a uma IMU de grau tático. Com uma IMU de grau de navegação, a predefinição pode tornar a deriva fundida pior do que um INS livre: 52 m contra 11 m num perfil de aeronave de 70 m/s. Defina [imu_*.filter_prior] para corresponder ao grau do sensor, como fazem os novos pacotes marítimo, ferroviário e de aviação. Nenhum cenário incluído combina uma IMU de grau de navegação com a distribuição a priori predefinida: todos os que usam a predefinição têm desvios residuais de acelerómetro de pelo menos 0,015 m/s². Apenas documentação; nenhuma saída muda.

  • Exportação para test bench verificada com os leitores do próprio simulador (0,36, WP-09, CAP-16): os ficheiros de movimento de kshana bench-export de 8 cenários incluídos foram relidos pelos leitores de NMEA, de latitude/longitude/altura e de movimento fixo à Terra do gps-sdr-sim (MIT, commit 28ca29a6, usado como ferramenta separada através de xval/testbench-gpssdrsim/; nenhuma função de sinal é chamada). Devolvem a trajetória exportada até 1,2 mm, 0,15 mm e exatamente. RESULTADO: o leitor de movimento fixo à Terra desse simulador não consegue aceitar o CSV de largura total, porque o seu buffer de linha de 100 caracteres divide cada linha. docs/TEST-BENCH.md indica agora os cortes de coluna a usar e o limite de 300 s do simulador. VALIDATED (nova linha do registo); os bytes da exportação não mudam.

  • GNSS/INS no conjunto de dados KF-GINS (0,36, WP-09, FUT-17): carregadores e executor de fusion::kfgins e o modelo de medição com braço de alavanca no EKF em laço fechado. No conjunto de dados de demonstração KF-GINS (obtido no momento do teste, não incorporado), o RMS horizontal do Kshana face à trajetória de referência é 1,09 cm contra os 1,11 cm do próprio KF-GINS, e todos os limiares pré-registados se verificaram. VALIDATED com evidência condicionada pelos dados (decisão do responsável, 2026-10-13): o conjunto de dados é obtido com SHA-256 fixados e o caminho de reprodução está em xval/kfgins/PREREGISTRATION.md.

  • Filtro PNT acoplado no pacote de fusão (0,36, WP-09, FUT-16): o tipo de cenário fusion aceita uma tabela opcional [coupled] que executa um filtro empilhado sobre pseudodistâncias com um estado de desvio de acelerómetro (fusion::coupled::CoupledPntBiasFilter), e fusion::coupled::CoupledPnt3d é a versão 3-D de 8 estados. Novo cenário incluído fusion-pnt-coupled: com acelerómetros com desvio, o modo acoplado mantém a posição do conjunto quântico a 18,7 m (percentil 95) com integridade total, onde os filtros desacoplados chegam a 430 m. Sem a tabela, fusion e hybrid não mudam (fixado); hybrid recusa a tabela. MODELLED.

  • Pacotes GNSS/INS marítimo, ferroviário e de aviação (0,36, WP-09, RM-21): cenários incluídos gnss-ins-maritime, gnss-ins-rail e gnss-ins-aviation sobre a biblioteca de trajetórias, e uma tabela opcional [tight] para o tipo de cenário gnss-ins que funde pseudodistâncias de uma constelação SGP4 Walker (todos os satélites quando nominal, os poucos mais altos quando degradada). No pacote ferroviário, o acoplamento forte mantém a solução de grau de navegação a 5,3 m através de um desmonte e de um túnel, contra 12,9 m com acoplamento fraco. Sem [tight], o pacote não muda (fixado). MODELLED.

  • Acoplamento forte de fase da portadora (0,36, WP-09, RM-25 / FUT-17): fusion::carrier_tc, um EKF de estado de erro com um relógio de recetor de dois estados explícito e ambiguidades de portadora float, conduzido por uma constelação SGP4 Walker com correções Klobuchar e Saastamoinen no laço de medição, deteção de saltos por portadora diferenciada no tempo e reinicialização de ambiguidades, e uma execução só com código sobre as mesmas medições para comparação. MODELLED: num percurso em figure-8, a solução de portadora é de 2,5 cm contra 47 cm só com código, e NIS/NEES são consistentes entre sementes.

  • Biblioteca de trajetórias GNSS/INS (0,36, WP-09, RM-24): o tipo de cenário gnss-ins aceita uma tabela opcional [trajectory] com profile = "straight" | "figure8" | "stop_go" | "aircraft" | "uas" | "csv". Os perfis comandam taxas de Euler e aceleração ao longo da trajetória a partir do estado verdadeiro e derivam a IMU verdadeira da cinemática de corpo rígido (curvas coordenadas, subidas, Coriolis); csv importa uma trajetória verdadeira (t, lat, lon, alt, vn, ve, vd, roll, pitch, yaw) e resolve a IMU que a reproduz. Sem a tabela, o pacote voa o seu percurso histórico, bit a bit (fixado). MODELLED.

  • Teselas DEM em latitude/longitude para o horizonte lunar: [terrain] dem_tile_path lê uma tesela de texto realdata::lola_dem (alturas acima da esfera média numa grelha de latitude/longitude) em vez da dem_path estereográfica polar, tanto para lunar-station-coverage como para moonlight-service-volume; o relatório repete a tesela (terrain.dem_tile, com o seu SHA-256). realdata::lola_dem está agora ligado à marcha de raios do horizonte. Uma tesela reamostrada a partir do recorte incluído dá à estação o horizonte do recorte até 0,22 graus. MODELLED.

  • Terreno no local de exportação do volume de serviço: com uma secção terrain, cada linha da exportação de geometria por satélite de moonlight-service-volume traz clears_terrain (o satélite está acima da máscara plana e do horizonte do local de exportação no seu azimute), o relatório traz o horizonte do local (export_site_terrain) e o CSV de execução ganha a coluna. Sem terreno, a exportação não muda. MODELLED.

  • Campos principais fornecidos pelo motor (0,36, STUDIO-06): kshana::api::HEADLINE_FIELDS, field_importance_json() e o field_importance() do WebAssembly indicam, para doze tipos de cenário, quais os campos de um cenário que respondem à sua pergunta, os melhores primeiro, como caminhos com pontos (jammers[].eirp_dbw). O Studio lê-os antes da sua própria ordenação. Apenas metadados de apresentação: o motor nunca os lê, nenhum ficheiro de cenário precisa deles, nenhum resultado depende deles. tests/field_importance.rs falha se um tipo de cenário não for despachável ou se um caminho não se encontrar em nenhum dos cenários incluídos desse tipo (apanhou dois caminhos que os identificadores achatados do Studio tinham escrito sem os parênteses retos da matriz).

  • Tabela de tipo de cenário para módulo fornecida pelo motor (0,36, STUDIO-05): kshana::api::KIND_MODULES, kind_modules_json() e o kind_modules() do WebAssembly indicam, para cada tipo de cenário cujas linhas da matriz de verificação nomeiam outro módulo que não o seu, os nomes dos módulos. O mapa de capacidades do Studio usava a sua própria cópia escrita à mão; tests/kind_modules.rs falha se um tipo de cenário da tabela não for despachável ou se um módulo não aparecer em nenhuma linha da matriz. Nenhuma saída mudou.

  • Execução IQ curta na compilação para navegador (0,36): iq_signals() e iq_run_short(fs_hz, duration_s, signal, ids, dopplers_hz, cn0_dbhz, seed) no módulo WebAssembly constroem uma cena sintética, adquirem cada satélite e seguem os adquiridos, tudo em memória, limitado a 0,25 s, 1 000 000 amostras e 8 satélites. O construtor de cenas e a pesquisa de sinais por nome saíram de iq::cli, só nativo (para iq::scene::synthetic e iq::signals::by_name), de modo que ambas as compilações os partilham; a saída da linha de comandos não muda. O teste nativo e web/smoke.mjs comparam o mesmo pedido com um único valor de referência (tests/fixtures/iq_short_golden.json), byte a byte: desde a alteração de matemática portátil (STUDIO-15, abaixo), a compilação para navegador e a compilação nativa dão os mesmos bits.

  • APIs tipadas em Python e TypeScript (CAP-34): kshana.pyi tipa os vocabulários fechados (ScenarioKind, todos os nomes de tipo de cenário; ErrorKind; ProvenanceClass) e os dicionários KindMeta e FieldUnit; scenario_kinds() e error_kind() devolvem-nos. O pacote WebAssembly acrescenta run_typed (uma execução como objeto RunOutput tipado com o documento analisado como data) e scenario_kinds (o KindMeta[] analisado), e o seu kshana.d.ts traz o mesmo vocabulário; error_kind é tipado como ErrorKind | "". tests/typed_api_sync.rs mantém ambas as listas iguais às do motor.

  • Unidades para cada coluna de sweep-nd (FUT-28): um resultado sweep-nd traz agora key_units e metric_units, a unidade de cada chave varrida e de cada métrica registada, lida da tabela de unidades do próprio pacote varrido. Um eixo pode declarar unit para uma chave que o pacote não repete; uma unidade declarada que contradiga a do pacote é recusada, e uma unidade que nenhum dos dois indique é null, nunca adivinhada. points[].coords[] e points[].metrics[] estão descritos, pelo que todos os 76 tipos de cenário estão agora totalmente cobertos pela barreira de unidades de campo (teto de tipos de cenário por cobrir 1 -> 0).

  • Matrizes NumPy a partir de RunOutput (FUT-26): o RunOutput do Python passa a ter array(path), columns(path) e series(), que devolvem numpy.ndarray para uma lista numérica, as colunas numéricas de uma lista de registos, ou todas as séries de registos do documento. Cada matriz é igual a numpy.asarray dos mesmos valores de data() (dtype e bits). O NumPy só é importado quando uma delas é chamada e fica fora dos requisitos de execução. Tipado em kshana.pyi e verificado pelo stubtest.

  • Otimizador de campanhas (CAP-32): a nova secção opcional [optimize] do tipo de cenário campaign pesquisa de uma a três chaves de cenário dentro de limites indicados o melhor valor de uma métrica: minimizar, maximizar ou atingir um alvo. Pesquisa de forma exaustiva numa grelha, ou com um simplex de Nelder–Mead determinístico e limitado. Cada avaliação é uma execução real do tipo de cenário nomeado e está listada no trace do resultado. Exemplo: scenarios/campaign-optimize-link-budget.toml. Os limiares foram pré-registados (docs/design/evidence/cap32-optimize/):

    • a função de Rosenbrock é satisfeita (f* = 1.7e-20);
    • uma resolução de alvo 1-D em forma fechada é satisfeita (6e-15 relativo);
    • a grelha é igual bit a bit a uma força bruta independente;
    • o simplex faz pelo menos tão bem como uma grelha de 41 × 41 em 177 execuções.

    O limiar 1-D da ronda 1 fica registado como NOT MET, porque a caixa pré-registada excluía a solução. MODELLED; linha do registo "Bounded optimisation of one metric over campaign parameters". Aditivo: as campanhas sem a secção não mudam.

  • Conjuntos de calibração (CAP-10): três verificações de semente única repetidas em 200 sementes independentes face a limiares pré-registados, em docs/CALIBRATION-ENSEMBLES.md (gerado por gen_calibration_ensembles; valores por semente em docs/data/calibration-ensembles.csv).

    • O intervalo bootstrap de 95 % do Monte Carlo da campanha cobre a média verdadeira em 192 de 200 conjuntos, e a sua verificação do qui-quadrado passa em 196.
    • A tolerância de percentil de semente única passa em apenas 183 de 200: NOT MET, como previsto. É um limiar de cerca de 2 sigmas, registado e não afrouxado.
    • As calibrações de ADEV de FM branca passam em todas as sementes, com o seu pior erro muito dentro da tolerância.

    MODELLED.

  • Tipos de cenário incorporados através do trait Scenario (FUT-27, em curso): o trait BuiltinKind (api::BuiltinKind, com um gancho de nível por valor e append_figure_tiers), e os primeiros tipos de cenário passados para ele (inertial, spoof, passes, link-budget, jamming). A saída não muda: um manifesto de todo o catálogo com o SHA-256 de cada saída é idêntico antes e depois (tests/scenario_output_manifest.rs).

  • Verificação sem obtenção no Playground (RM-07): tests/playground_no_fetch.rs verifica três coisas:

    • todos os cenários da biblioteca do Studio estão no pacote do navegador;
    • o pacote é idêntico byte a byte a scenarios/;
    • todos os cenários do navegador são executados a partir de um diretório de trabalho vazio.
  • Mapas Alt-PNT: campo gravítico real, Monte Carlo de erro de mapa, SRTM em resolução total (0,36, WP-10). O tipo de cenário gravity-map aceita um [reference] opcional: uma anomalia gravítica sintetizada a partir dos coeficientes EGM2008 incluídos (ou de um ficheiro ICGEM .gfc através de gfc_path, apenas em compilações nativas). Essa síntese coincide com o Serviço de Cálculo do ICGEM até cerca de 1e-8 mGal em 794 nós em duas regiões, face a limiares pré-registados de 0,005 mGal RMS e 0,02 mGal máx. (VALIDATED; linha do registo "Gravity-anomaly synthesis from a spherical-harmonic model"). O novo cenário incluído gps-denied-gravity-nav-egm2008 executa o teste de referência de 60 minutos nesse campo real de grau 70. Resultado pré-registado: erro de correspondência 3106 m, pelo que o limiar de < 500 m é NOT MET, como previsto (o grau 70 é demasiado suave), e a redução de dez vezes na deriva é MET (MODELLED). Uma tabela opcional [map_error_mc] repete o teste de referência sobre erros de mapa com semente e correlação gaussiana e reporta a distribuição do erro de correspondência (cenário incluído gravity-map-error-mc). Exploratório e não pré-registado: com um erro de mapa de 2 mGal correlacionado ao longo de 0,2 graus (a dimensão que o próprio sigma do correlacionador orça), 1 de 20 realizações fica dentro de 500 m (mediana 2,9 km, p95 14,7 km), contra 144 m com um mapa perfeito. A posição inferior a 500 m do teste de referência sintético pressupõe que o mapa é exato. Sem nenhuma das opções, o documento é idêntico byte a byte ao de versões anteriores. combined-altpnt aceita um [magnetic_grid] opcional (csv_path, column) que lê o canal magnético de um CSV no formato EMAG2v3. O EMAG2 não é incorporado porque os seus termos não são explícitos: tools/fetch_emag2_tile.py obtém-no com um SHA-256 fixado e recorta uma caixa. Não se reclama nenhum resultado de navegação na grelha EMAG2 real. Estimação conjunta de mapa (SLAM de terreno, RM-18): altpnt::sequential::run_sequential_trn_on_map faz voar o navegador sequencial de terreno sobre um mapa guardado que difere da verdade, quer confiando nele, quer estimando uma correção de mapa por célula com um filtro Rao-Blackwellizado ao estilo FastSLAM. Pré-registado face ao SITAN de mapa conhecido com um erro de mapa correlacionado de 15 m em 20 sementes: um ganho médio de 1,5 %, melhor em 10 de 20, pelo que ambos os limiares de melhoria são NOT MET (10 % e 12 de 20), sem prejuízo num mapa perfeito (MET). Uma única passagem sem revisitas não permite aprender o mapa (xval/terrain-slam-rbpf/, MODELLED). Os documentos de terrain-slam são idênticos byte a byte. Os testes de SRTM real passam agora a ser executados na CI em dois recortes de resolução total versionados; todos os limiares pré-registados são atingidos, com o nó mais próximo igual ao do GDAL 3.8.4 em 8 de 8 pontos (xval/srtm-ungate/).

  • Interoperabilidade, WP-08 (0,36; cada item pré-registado e versionado isoladamente antes da execução da sua referência independente, cada um uma nova linha VALIDATED do registo, exceto o item de telemetria, que alarga uma linha existente):

    • Mensagens de Dados de Órbita CCSDS (src/odm.rs): OPM 3.0/2.0, OMM 3.0/2.0 e OCM 3,0 (blocos TRAJ, PHYS, COV, MAN, USER) escritas e lidas em KVN e NDM/XML, e uma OMM de precisão total a partir de um conjunto de elementos SGP4 (OmmMessage::from_omm_file); a saída de OmmFile::to_omm_kvn não muda. Face ao Orekit 13.1.8 nos dois sentidos: 27 de 30 mensagens do Kshana são analisadas no Orekit e o Kshana lê todas as escritas pelo Orekit, valores dentro de 1e-14 relativo e épocas dentro de 1e-9 s; quatro resultados fixados (o Orekit exige ELEMENT_SET_NO, recusa COMMENT em parâmetros definidos pelo utilizador em XML, não escreve BTERM sem BSTAR e lê épocas relativas de OCM em TDB em segundos SI). O META_START do escritor OMM antigo é recusado pelo Orekit (registado). Linha "CCSDS Orbit Data Messages (OPM, OMM, OCM)".
    • Mensagens de Dados de Atitude CCSDS (src/adm.rs, src/ndm_xml.rs): AEM 2.0/1.0 e APM 2,0 em KVN e XML face ao Orekit 13.1.8, todos os limiares atingidos; o escritor APM do Orekit recusa uma manobra sem MAN_DELTA_MASS (fixado). Linha "CCSDS Attitude Data Messages (AEM, APM)".
    • Exportação SPK do SPICE (src/spk_writer.rs): escritor e leitor de SPK dos tipos 9 e 13 e exportação de OEM para SPK; face ao CSPICE N0067, os kernels são idênticos byte a byte aos do SPICE e avaliam-se de forma idêntica bit a bit. Linha "SPICE SPK export (types 9 and 13)".
    • SPK do SPICE dos tipos 3 e 21 (src/spk_writer.rs): segmentos do tipo 3 (Chebyshev) e do tipo 21 (linhas de diferenças estendidas) escritos a partir de registos dados e avaliados como o SPICE o faz; face ao CSPICE N0067, os kernels são idênticos byte a byte aos do SPICE e todas as avaliações concordam bit a bit nos dois sentidos. Linha "SPICE SPK types 3 and 21 (Chebyshev, extended difference lines)".
    • Extensões de Space Packet (src/space_packet.rs): cabeçalho secundário com códigos de tempo CUC/CDS, controlo de erros de pacote, segmentação e verificações de fluxo, face ao ccsdspy 2.0.1, spacepackets-rs 0.18.0, spacepackets-py 0.32.0 e ao crc_hqx do CPython, zero divergências. Linha "CCSDS Space Packet secondary header, packet error control and segmentation".
    • Esquema de telemetria 1,3 através de consumidores reais: a exposição Prometheus e o JSON OTLP/HTTP de um fluxo sintético de esquema 1.3, incluindo a série de geometria e a etiqueta class, lidos exatamente pelo prometheus_client e pelo proto OTLP, aceites pelo promtool 3.5.0 check metrics sem nenhum problema de lint e passados sem alteração pelo OpenTelemetry Collector contrib 0.135.0 (condicionado pelos dados: ferramentas obtidas com SHA-256 fixados, saídas versionadas).
  • Determinação de órbita de Marte, execução 2 (0,36, WP-14, CAP-30): mars_od::fit_damped escala a matriz normal pela sua diagonal e amortece o passo (Levenberg-Marquardt), depois de o ajuste de Gauss-Newton registado ter falhado numa matriz cuja diagonal bruta abrange oito ordens de grandeza. Registada em separado (xval/mro-od/PREREGISTRATION-RUN2.md, mesmo arco, limiares e edição). Nas passagens do MRO pontuadas, a órbita fica a 0,36 km RMS (0,53 km no máximo) da reconstrução de navegação do MRO, limiares atingidos. O Doppler pós-ajuste é de 48,6 mHz contra o limiar de 30 mHz, não atingido (resultado fixado). Uma alteração apenas de pontuação, R2-A1, está divulgada em docs/revisions. A linha continua MODELLED.

  • Modelo de Doppler de 2 vias com rampa de Marte e determinação de órbita (0,36, WP-14, parte de CAP-30, fase 2): mars_od prevê o Doppler de 2 vias em banda X com rampa da DSN a partir de tabelas de rampa ODF (tempo de luz, Shapiro, troposfera, tempo de estação, estações da DSN através da cadeia CIO e EOP do IERS) e ajusta um orbitador de Marte (GMM-3, terceiros corpos, SRP, arrasto). naif_kernel lê SPK do tipo 1 (verificado face ao CSPICE) e gravity_sh::from_shadr lê campos SHADR do PDS. Pré-registado face à reconstrução de navegação do MRO em passagens reais do MRO (condicionado pelos dados, scripts/fetch_mro_od.sh, CI mensal): o Doppler previsto coincide com as observações até 12,5 mHz (limiar 30 mHz, atingido); o ajuste de órbita registado falhou no arco pontuado e não produziu nenhuma órbita (resultado fixado). A linha continua MODELLED.

  • Leitor de Orbit Data File da DSN (0,36, WP-14, parte de CAP-30): odf::parse_odf lê ODF TRK-2-18. Num ODF real do Mars Reconnaissance Orbiter (NASA PDS, incorporado), o leitor coincide com o número de registos, as posições de grupo, as estações e os tempos da etiqueta do PDS, e todos os seus tipos de dados são conhecidos. A tabela de fim de ficheiro da etiqueta tem uma linha a menos do que o ficheiro, uma inconsistência da etiqueta registada como resultado. MODELLED. A determinação de órbita com estes dados ainda não está feita.

  • Orçamento TWSTFT e estabilidade da transferência de tempo: o tipo de cenário time-transfer-budget (0,36, WP-14, FUT-19).

    • Equação de duas vias: twstft_budget resolve-a para T_A − T_B com atrasos de equipamento das estações, a assimetria ionosférica ascendente/descendente em banda Ku, a diferença de atraso do transponder e os termos de Sagnac, e recupera o modelo direto até 1e-15 s.
    • Orçamento de incerteza: combinado em quadratura, com o TDEV da ligação como termo de tipo A.
    • Ruído da ligação: a série de duas vias passa a ter um patamar de ruído de fase flicker, uma não reciprocidade diurna e um resíduo constante de reciprocidade. O pacote timetransfer de jitter branco não muda.
    • Série real: a estabilidade de séries fornecidas do BIPM Circular T, CSV MJD,ns ou de relógios de estação do IGS.

    MODELLED. Novo cenário incluído time-transfer-budget. A solução de tempo PPP é VALIDATED em separado face ao relógio de estação do IGS no ramo de dados reais de GNSS.

  • Aquecimento de reentrada, radiometria EO e perdas de ascensão (0,36, WP-14, CAP-28): três novos tipos de cenário.

    • entry-heating: uma reentrada de massa pontual com 3-DoF sobre uma Terra ou um Marte em rotação, com aquecimento no ponto de estagnação de Sutton-Graves.
    • eo-radiometry: SNR do gerador de imagens, MTF em Nyquist, resposta relativa de arestas e NIIRS GIQE 4.
    • ascent-losses: uma ascensão por viragem gravitacional em vários estágios com perdas de gravidade, de arrasto, de direção e de contrapressão, verificada pela identidade exata de dv ideal menos perdas.

    A desaceleração máxima da reentrada foi verificada face ao valor nominal publicado da Stardust sob um limiar pré-registado: 35,44 g contra 33,4 g (+6,1 %, limiar 10 %). Essa linha é VALIDATED. O aquecimento, a radiometria e a ascensão são MODELLED. Também novos: reentry::us76_pressure, os cenários incluídos entry-heating-stardust, eo-radiometry e ascent-losses, e docs/ENTRY-EO-ASCENT.md.

  • Controlo de atitude com rodas de reação: o tipo de cenário aocs (0,36, WP-14, CAP-21). Uma manobra de apontamento inercial de um corpo rígido com três ou mais rodas de reação equilibradas sob realimentação MRP, com binários de roda de norma mínima limitados ao limite de cada motor (aocs). Também pode fechar o laço sobre um EKF multiplicativo a partir de um giroscópio e de um seguidor de estrelas simulados (aocs_mekf). O laço de estado verdadeiro foi comparado com o Basilisk 2.9.1 em três casos pré-registados antes de o código existir (três rodas ortogonais, uma pirâmide de quatro rodas, um caso de saturação). Todas as componentes MRP, taxas do corpo, velocidades de roda e binários de motor concordaram em todas as amostras, no pior caso 2.4e-14 em sigma e 2.9e-11 rad/s na velocidade da roda. Esta linha é VALIDATED; o MEKF é MODELLED (consistência NEES). Novos cenários incluídos aocs-slew e aocs-slew-mekf, e docs/AOCS.md.

  • Planeamento de contactos com a estação terrestre e ACM DVB-S2 (0,36, WP-14, CAP-22/23): dois novos tipos de cenário. acm-link indica, para um satélite sobre uma estação, o Es/N0 de cada passagem e o MODCOD DVB-S2 escolhido ao longo dela (limiares da Tabela 13 da ETSI EN 302 307-1 mais uma margem). Indica também o volume de dados que o ACM transporta face à linha de base de codificação constante. contact-schedule faz o mesmo para vários satélites sobre várias estações e constrói um plano de contactos sem conflitos (viragem da antena, uma estação por satélite, entrega ponderada por prioridade limitada ao atraso acumulado de cada um). Apresenta um plano guloso de valor marginal, uma linha de base por ordem de chegada e o ótimo exato em conjuntos pequenos, com a diferença de otimalidade do plano guloso. As janelas de acesso provêm do previsor de passagens aparentes VALIDATED. Novos cenários incluídos acm-link e contact-schedule (dados de entrada ilustrativos) e docs/CONTACT-SCHEDULING.md. MODELLED (duas novas linhas do registo).

  • Posicionamento Doppler com Starlink face a uma experiência publicada (0,36, WP-14, parte de CAP-11, MODELLED). Trata-se de uma comparação por aproximação, fixada antecipadamente, entre o modo Doppler de leo-pvt com a predefinição starlink-sop e os percentis do conjunto de dados 3 de "Unveiling Starlink for PNT" (NAVIGATION 72(1), 2025, doi:10.33012/navi.685). O modelo usou 3 satélites (uma máscara de 47 graus escolhida por uma regra fixa), sem auxílio de altura e com um sigma Doppler de 30 Hz, ao longo de 200 sementes. O seu erro 3-D no percentil 90 é de 92,2 m a 20 s e de 870 m a 8 s, face aos 2 m e 10 m publicados, pelo que os dois limiares de fator dois são NOT MET. O modelo é pessimista, e não otimista como previsto: três satélites fixos dão muito menos diversidade geométrica do que os 63 satélites da experiência ao longo de 10 minutos com mudança de canal a cada 15 s. Ambas as falhas são afirmadas em teste (tests/starlink_doppler_published_proxy.rs).

  • Otimizador de transferências impulsivas sobre DE440 (0,36, WP-14, CAP-20c/d): maneuver::optimise_transfer_kernel determina as datas de partida e de chegada de uma transferência balística de dois impulsos e de uma só revolução que minimizam o C3 de partida ou o V-infinito de chegada dentro do Tipo I ou do Tipo II. Pesquisa uma grelha de 2 dias e refina depois com Nelder-Mead 2-D, sobre estados heliocêntricos do kernel DE440; assenta em porkchop_kernel. A comparação foi fixada antecipadamente (bf0439e8) face a um otimizador independente com SPICE + pykep 3.0.1 + SciPy 1.18.1 na oportunidade Terra-Marte de 2026: as quatro otimizações concordam até 8.7e-13 em termos relativos, com datas a menos de 1e-5 dia (VALIDATED, nova linha do registo). Como referência publicada secundária, o NASA/TM-2010-216764 (o manual Terra-Marte 2026-2045) é reproduzido para o C3 mínimo do Tipo II (9,182 vs 9,144) e para o V-infinito de chegada mínimo do Tipo II (2,564 vs 2,565). O C3 mínimo do Tipo I não é reproduzido: 10,535 vs 11,11 (-5.18 %), sendo que a referência independente da biblioteca concorda com o Kshana. Essa falha está registada e é afirmada em teste.

  • Estudo da estação de referência lunar (0,36, motivado por material publicado sobre uma estação de referência planeada para o polo sul lunar; fontes em docs/LUNAR-REFERENCE-STATION.md): o tipo lunar-station-coverage, uma varredura de Monte Carlo do modelo de PNT diferencial lunar sobre uma grelha de utilizadores polar sul e um dia de épocas, que dá, por ponto e para a região, o percentil do erro corrigido e não corrigido, a disponibilidade com os motivos, a cobertura face a um limiar declarado, os níveis de proteção, o raio de cobertura por azimute e o orçamento da ligação de correções. Reduz-se exatamente a lunar-differential-pnt num só ponto, época e ensaio; a sua aritmética foi recalculada com numpy sob um limiar fixado antecipadamente (posições e percentis atingidos; as correções da estação falharam o seu por arredondamento de dupla precisão, registado). MODELLED; linha do registo "Lunar reference-station coverage and accuracy map". Sem afiliação nem aval de qualquer agência; nenhuma afirmação sobre o desempenho de qualquer sistema real.

  • Previsão fixada antecipadamente: cobertura da estação de referência lunar (não é uma validação; MODELLED). docs/predictions/lunar-reference-station.md congela, no commit c05dac1d, os resultados de lunar-station-coverage sob os pressupostos declarados publicamente, com hashes SHA-256 dos dados de entrada e dos resultados e um protocolo de pontuação fixado desde já (fator 2 para exatidões e níveis de proteção, 10 pontos percentuais para disponibilidade e cobertura; um pressuposto alterado dá origem a uma nova previsão datada, nunca a uma edição; uma falha é publicada com tanto destaque como um acerto). Todos os valores são dominados pelo conjunto de elementos, não publicado, da constelação de quatro satélites, que é ILLUSTRATIVE, e di-lo. tests/prediction_frozen.rs protege-a; docs/VALIDATION.md ganha uma secção "Pre-registered predictions". Sem linha no registo.

  • Extensões da estação de referência lunar (0,36; as limitações 2 e 3 do estudo da estação e o estilo de solução das fontes), todas opcionais em lunar-station-coverage e ausentes por predefinição, pelo que todos os documentos existentes, incluindo a previsão congelada, permanecem inalterados: [receiver] (multipercurso a + b exp(-el / el0) no utilizador e na estação, o da estação opcionalmente de Gauss-Markov ao longo das épocas, ruído de código DLL a partir do C/N0, enviesamentos entre canais; valores ILLUSTRATIVE na Lua); orbit_err_growth_m_per_s (crescimento linear do erro de órbita difundido ao longo da latência de correção, ILLUSTRATIVE); [solution] (restrição de altura, um mínimo de três satélites com ela, uma janela de utilizador estático ao longo das épocas). Dois adendas à comparação com as afirmações publicadas, cada um fixado antecipadamente isoladamente antes da sua execução, ficam ao lado da execução registada sem edição: K5 com crescimento falha a todas as taxas; com o estilo de solução das fontes, K1 a K5 falham e K6 passa (1 de 6), com o erro 3-D corrigido no p95 de R300 a descer de 280,6 m para 2,11 m. MODELLED; três linhas do registo.

  • Máscaras de horizonte do terreno lunar (0,36; a primeira limitação do estudo da estação de referência lunar): uma secção opcional [terrain] em lunar-station-coverage (a estação e cada ponto de utilizador) e em moonlight-service-volume (cada ponto da grelha) dá a cada local um horizonte dependente do azimute no formato de tabela de linha do horizonte de 0,36, a partir de um perfil declarado e identificado com a sua fonte (station_horizon, user_horizon) e/ou de um traçado de raios sobre um DEM polar (dem_path) ao longo de círculos máximos da esfera lunar com curvatura exata. Inclui um recorte de 0,98 MB do DEM polar sul LRO LOLA LDEM_75S_240M, de domínio público, reamostrado por média de blocos 5 x 5 para 1200 m (data/lunar-dem/, com o respetivo NOTICE, SHA-256 e scripts/make_lola_south_polar_crop.py), e o cenário scenarios/lunar-station-coverage-terrain.toml, apenas do repositório. Verificado face a horizontes em forma fechada (esfera nua, cratera num planalto, cone rasterizado); MODELLED, linha do registo "Lunar terrain horizon masks from a stated profile or a polar DEM". Sem a secção, todos os documentos, incluindo o bloco de unidades, são idênticos byte a byte.

  • Confiança com consciência da geometria (nota de projeto de geometria de 0,36, secção 4). Cada época de receiver-trust, estática ou de embarcação, em lote ou em tempo real, traz a sua geometria de satélites: good, degraded (motivos few-satellites, high-pdop, high-hdop e, a título informativo, sky-blocked) ou unknown quando o registo não dá geometria de satélites, com HDOP, PDOP, VDOP e os satélites usados. É derivada das elevações e dos azimutes que o recetor comunica (NMEA GSV, UBX NAV-SAT) através do kernel orbit::dop existente, ou obtida de NMEA GSA. Cada época traz também uma etiqueta, good, fair ou poor, sempre comunicada e nunca pontuada, e uma nota com o HDOP, o PDOP, o VDOP, o número de satélites e a perda de sinal por extenso. A pontuação de uma embarcação ganha um monitor geometry que não deduz nada, a menos que a geometria seja fraca (HDOP acima de 4, PDOP acima de 6 ou menos de 5 satélites usados), subindo depois em rampa até um limite de 15 pontos; a geometria sozinha atinge no máximo a banda degradada, nunca a de não confiável (sem alarme). Cada dedução recebe uma classe, geometry, environment ou inconsistency, para que um céu fraco não seja lido como um ataque. loss-of-lock é geometry quando os satélites perdidos estavam todos abaixo de 15 graus no seu último relato; uma dedução por geometria fraca é inconsistency quando o HDOP declarado pelo recetor discorda do céu que ele próprio declara em mais de max(1,0, 25 % do HDOP derivado), pelo que um céu fraco forjado não consegue comprar a etiqueta. Uma nova tabela [geometry] indica cada limiar com a sua proveniência (HDOP 4, PDOP 6, pelo menos 5 usados, sigma_UERE 1,5 m, uma tolerância de HDOP de max(1,0, 25 % do HDOP derivado), sendo os 25 % uma escolha representativa para recetores com relógios por constelação ou soluções por subconjunto, 15 graus; os valores da IEC 61108-1 e do GPS SPS tal como citados, a verificar face ao texto das normas). A perda total de sinal não é rotulada como céu: quando há satélites à vista que não são seguidos e o DOP dos satélites à vista é bom (e os não seguidos não estão confinados a uma metade do horizonte), a época traz signal_loss e a dedução de geometria é environment. Um HDOP ou PDOP declarado de 99 ou mais, a qualidade GGA 0 e o modo GSA 1 são lidos como ausência de posição, e não como DOP. O limite (cap_points 15), o fim da rampa (full_ratio 1,5) e o piso (floor, por predefinição o degraded_min da pontuação) estão em [geometry], tal como os bons níveis da etiqueta (HDOP 2, PDOP 3, 6 satélites, representativos); o limite em vigor é min(cap_points, 100 - floor), pelo que uma tabela [score] que aumente degraded_min (incluindo uma de 0,35) reduz o limite em vez de ser recusada, e um piso abaixo de degraded_min é recusado. MODELLED; software de caráter consultivo, não um equipamento de navegação homologado (IEC 61108, IEC 61162): o operador continua a ser responsável pela navegação da embarcação.

  • A geometria chega a todas as superfícies: o JSON de resultados (epochs[].geometry, class em cada dedução, geometry_model, geometry_summary), as linhas JSON em tempo real (esquema 1,3), os receiver_trust em Python e WebAssembly, assess_vessel_log e receiver_trust_replay, as ferramentas MCP assess_*, os pacotes de evidências (epochs.json, config.json, uma faixa de geometria na página de resumo) e trust-telemetry (Prometheus kshana_trust_geometry* e uma etiqueta class em kshana_trust_reason_active, OTLP kshana.geometry.*, campos personalizados CEF cs6 (estado e classes da geometria), cfp3 (HDOP) e cfp4 (PDOP), verificados com os dois analisadores CEF de referência independente, e LEEF geoStatus, geoHdop, geoClass). A etiqueta de geometria também é exportada, acrescentada depois de todas as séries e campos anteriores e apenas para entradas que a tragam: Prometheus kshana_trust_geometry_label{label} e kshana_trust_geometry_vdop, OTLP kshana.geometry.label e kshana.geometry.vdop, LEEF geoLabel, geoPdop, geoVdop, geoUsed, e CEF um terceiro campo cs6 (a etiqueta) e cn1 (satélites usados); o VDOP não está no CEF (os campos personalizados de vírgula flutuante estão ocupados). Os dois analisadores CEF de referência independente leem de volta os casos de etiqueta tal como escritos (emenda 5: 176 linhas, 172 analisadas por pycef, 176 por Logstash). Um HDOP declarado que o céu declarado não explica é assinalado em cada época e contado (geometry_summary.hdop_mismatch, uma linha na página de resumo das evidências), e só é pontuado quando a geometria é fraca. A perda de sinal é exportada por si, uma vez que o estado da geometria permanece degraded enquanto ela se mantém: Prometheus kshana_trust_geometry_signal_loss, OTLP kshana.geometry.signal_loss, LEEF geoSignalLoss=1; em CEF surge como a classe environment em cs6.

  • orbit::dop_cofactor: o fator de covariância (HᵀH)⁻¹ por detrás de orbit::dop, extraído deste com a mesma aritmética.

  • Linha do registo "Position error from geometry: RMS error = sigma_UERE x DOP" (MODELLED, consistência interna): um Monte Carlo com sementes da solução de mínimos quadrados do motor nas 8 geometrias DOP coincidentes com gnss_lib_py, face ao fator de covariância do kernel DOP validado, com tolerâncias fixadas antecipadamente antes da primeira execução e dois controlos negativos que falham como exigido; a par, uma verificação anterior sobre quatro céus escolhidos à mão, com intervalos de confiança de qui-quadrado, comunicada tal como foi executada, antes do pré-registo.

  • Máscaras de linha do horizonte dependentes do azimute (src/skyline.rs, docs/SKYLINE.md, ponto 1 da nota de projeto): um corte de elevação que depende do azimute, o máximo ponto a ponto de tabelas (cada uma interpolada por si, com fecho em 360°), um desfiladeiro urbano em forma fechada (com extremidades abertas opcionais), setores de arestas vivas e um perfil de terreno com a curvatura da Terra; o corte efetivo é max(mask_deg, skyline). Quatro predefinições REPRESENTATIVE com proveniência declarada (city-street, harbour-approach, fjord, container-terminal), substituíveis campo a campo. Uma secção opcional [skyline] em gnss-sim, jamming, leo-pvt (todos os modos, incluindo a varredura polar), leo-pass e nos ficheiros de treino nmea-scenario, e em orbit e integrity através de um novo utilizador em local terrestre, user_site = { lat_deg, lon_deg, height_m } (ângulos de observação geodésicos sobre a Terra em rotação, com a vertical geodésica para a separação horizontal e vertical do ARAIM; cada amostra é um instante absoluto, epoch + t, para o qual os conjuntos de elementos, as efemérides difundidas e os ficheiros SP3 são avançados a partir das suas próprias épocas, datadas a partir da época de satélite mais recente quando não é declarada nenhuma epoch; um user em órbita recusa uma linha do horizonte). Os resultados ganham skyline { source, open_fraction, provenance } e, por amostra, masked_by_skyline. Sem a secção, todos os cenários são idênticos byte a byte a 0.35.0, verificado face a resumos criptográficos do commit da versão. Seis exemplos incluídos: orbit-urban-canyon-skyline, integrity-harbour-approach, gnss-sim-container-terminal-skyline, jamming-harbour-approach-skyline, leo-pvt-fjord-skyline e a campanha leo-vertical-autonomous-vehicle-skyline (o desfiladeiro do veículo autónomo como corte plano e como rua; a campanha existente permanece inalterada). MODELLED.

  • Funções de geometria do céu (src/geometry.rs, ponto 2 da nota de projeto): sky_geometry (satélites visíveis e mascarados a partir de um local, de um instante e de predefinições de constelação, conjuntos de elementos de duas linhas (tle, no máximo 4 MiB, propagados pelo SGP4 do motor até uma epoch UTC) ou satélites indicados; sky_source e sky_statement dizem se o céu é representativo ou o céu que os conjuntos de elementos dão nessa época, e não uma medição; tle_skipped lista cada linha não usada com o seu motivo; limites de entrada de 2000 satélites acima do horizonte, verificados antes de construir uma tabela de sistema, e de 16 relógios de recetor; os cinco DOP; o cofator e a covariância ENU com um relógio por sistema ou um em comum; a elipse de erro horizontal a um sigma e com uma confiança declarada), sky_monte_carlo (erros de mínimos quadrados com sementes, no máximo 5000), skyline_presets, skyline_profile e skyplot_svg. orbit::dop_cov expõe a covariância por detrás de orbit::dop, que passa a ser a sua redução (os escalares validados não se alteram). Superfícies: kshana sky e kshana skyline, funções Python e WASM com os mesmos nomes, e a ferramenta MCP sky_geometry (40 ferramentas), e o notebook notebooks/geometry.ipynb (com o seu espelho .md; executado por tests/python/test_notebooks.py). Cada resultado traz a etiqueta MODELLED, a declaração do modelo de erro e o aviso consultivo.

  • Registo: cinco linhas de linha do horizonte e de geometria do céu. VALIDATED, cada uma numa comparação fixada antecipadamente antes de a sua referência independente ser executada: Azimuth-dependent skyline mask: visible set, azimuth and elevation, and DOP under the mask face ao Orekit 12,2 (TopocentricFrame, ElevationMask) e ao gnss_lib_py 1.0.4 (get_dop), com a pior diferença de ângulo de observação e de máscara de 1.1e-12° contra 1e-9°, conjuntos visíveis idênticos, DOP 3.3e-13 em termos relativos (xval/orekit-skyline/); Horizontal error ellipse and per-system cofactor from the geometry covariance face a numpy linalg.inv e linalg.eigh (P2 padrão), 270 casos, eixos 5.1e-13 em termos relativos (xval/numpy-ellipse/). MODELLED: as reduções de desfiladeiro, setor e terreno; as predefinições; a composição da geometria do céu (céu predefinido, nuvem de Monte Carlo).

  • Com as linhas de confiança por geometria, de linha do horizonte e da estação de referência lunar, o registo tem 274 linhas: 134 validadas, 136 modeladas, 4 de parceiro.

  • Estação de referência lunar: laboratório de tempo da estação (MODELLED). Um bloco opcional [time_lab] em lunar-time-budget (src/lunar_time_lab.rs). Modela um relógio de estação (por predefinição da classe miniRAFS, qualquer classe nomeada, ou um cartão de dispositivo ajustado a pontos de estabilidade declarados) governado para LTC, depois em funcionamento livre ou reajustado a cada N segundos. Emite a curva de erro de tempo x(t), o tempo até 1, 10 e 100 ns (bissecção a par da forma fechada) e o termo dominante por horizonte, tudo com unidades. O resíduo de governação é ILLUSTRATIVE. A taxa de LTC não é rederivada e mantém a sua própria linha VALIDATED. O objetivo ao nível do nanossegundo do material público de Lunar PNT do ICG WG-B (junho de 2024) é citado como declaração da fonte, e não como afirmação. A ordenação dos relógios ótico < PHM < RAFS < miniRAFS mantém-se de 1 s a 7e5 s, e o teste fixa o cruzamento das curvas de PHM e RAFS perto de 7.5e5 s. Esse cruzamento é uma propriedade dos modelos de relógio de um só tipo de ruído (FM de cintilação pura contra FM de ruído branco puro), e não um resultado físico. Sem o bloco, o relatório, a sua tabela e o seu resumo permanecem inalterados. Exemplo: scenarios/lunar-station-time-lab.toml. Acrescenta uma linha ao registo, etiquetada MODELLED.

  • Estação de referência lunar: geodesia da estação (MODELLED). Dados de entrada opcionais extra_reflectors e extra_beacons em lunar-llr-datum acrescentam um bloco station_geodesy. A informação de datum das cinco matrizes, proveniente do recorte arquivado de medição de distância por laser, é combinada com o que um retrorrefletor acrescentado e uma baliza VLBI acrescentada, em locais declarados, contribuiriam. O refletor é medido nas épocas arquivadas em que o consegue ver, com os respetivos pesos arquivados. A baliza usa a rede e o calendário de lunar-frame-campaign, com as estações fixas. O bloco dá cada 1-sigma de Helmert antes e depois, e a sua razão. São limites de Cramer-Rao para um conjunto reduzido de parâmetros, sobre um calendário e um local ILLUSTRATIVE. Dados de entrada ausentes ou vazios deixam o relatório idêntico byte a byte. Exemplos: scenarios/lunar-station-geodesy-baseline.toml e -with-station.toml. Acrescenta uma linha ao registo, etiquetada MODELLED.

  • Estação de referência lunar: comparação com afirmações publicadas (MODELLED). Cada afirmação numérica em cinco fontes públicas é listada com a sua formulação exata, página e pressupostos declarados, e classificada como comparável, parcialmente comparável ou não comparável (tests/fixtures/lunar_station_published/CLAIMS.md; fontes com URL, data de obtenção, SHA-256 e licença em tests/fixtures/lunar_station/SOURCES.md). As afirmações parcialmente comparáveis foram pontuadas segundo seis limiares unilaterais fixados antecipadamente antes da execução (PREREGISTRATION.md, revisão 2, 05bf9a19): 1 de 6 afirmações dentro do limiar fixado antecipadamente (pré-registado 05bf9a19). A cobertura é de 0,00 contra >= 0,95 nos dois círculos polares sul, e o p95 corrigido é de 280,6 m contra <= 1,5 m. A causa são os elementos orbitais dos satélites, que nenhuma fonte publica: nos elementos ILLUSTRATIVE incluídos no código, quatro satélites estão em vista comum em 8 % das épocas, com geometria quase singular. A execução não reproduz as afirmações com esses elementos e não é prova de que as afirmações estejam erradas. Fixado em tests/lunar_station_published_oracle.rs. Uma linha do registo, etiquetada MODELLED com a conclusão.

  • Estação de referência lunar: preparação de dados de ficheiros de relógio. realdata::clk::rinex_clock_series indica agora o sistema de tempo das suas épocas. É o valor de TIME SYSTEM ID ou, quando este não está declarado, o valor por predefinição do sistema de satélites do cabeçalho. O resultado diz também se o sistema foi declarado. A função recusa um sistema de tempo desconhecido (uma escala de tempo lunar, por exemplo), um ficheiro de sistemas mistos sem declaração e ficheiros que discordam entre si, em vez de os ler como tempo GPS. Inclui um ficheiro de teste sintético de relógio de estação. Não é definido nenhum formato de ficheiro de correções, porque não existe nenhum público.

Alterado#

  • A documentação dos módulos fusion::ukf, fusion::tightly_coupled e fusion::gnss_ins_ekf já não designa como trabalho futuro o navegador com filtro de Kalman unscented (UKF) de 17 estados, o acoplamento forte com INS completo e o estado de relógio explícito; remetem para hybrid_ukf, tightly_coupled17 e carrier_tc.

  • O RINEX 4 já não é recusado (0,36, WP-07): um ficheiro de navegação RINEX 4 era rejeitado de propósito; agora é lido (ver Acrescentado). Nos ficheiros de observação da versão 4 e posteriores, as etiquetas do cabeçalho são reconhecidas apenas nas colunas 61-80, para que os novos registos de texto livre não possam passar por etiquetas.

  • ionex::parse_ionex lê ficheiros IONEX reais (0,36, WP-07): um registo completo de 16 valores preenche as colunas 61-80, que o leitor tomava por uma etiqueta, pelo que devolvia None em todos os ficheiros IONEX reais. Agora lê como valores um registo cujo campo de etiqueta é numérico. Nenhuma saída fornecida o usava.

  • Potências recebidas de Galileo E1 e E5a segundo o OS SIS ICD Issue 2,1 (revisão, 2026-10-14). As bandas de espetro galileo-e1 e galileo-e5a, e as vítimas GNSS de sinais LEO que delas retiram a sua potência, passam a usar as potências recebidas mínimas da Tabela 12 do Galileo OS SIS ICD Issue 2,1: −157,25 dBW (era −157,0) e −155,25 dBW (era −155,0).

    • Mudam nove resultados de cenários: os exemplos de espetro, a campanha de espetro, três verticais de resiliência LEO e três projetos de sinal LEO. O C/N0 efetivo muda −0,25 dB e o J/S +0,25 dB nestas bandas.
    • Cada valor alterado (1766, antigo → novo) está listado em docs/revisions/CAP12-galileo-icd21-power-changes.md e no respetivo CSV, com as tabelas da documentação que mudaram. Nenhuma linha do registo muda de estado.
    • Segunda parte, no mesmo dia: as vítimas de sinais LEO galileo-e5b (−155,0 → −155,25 dBW, E5b da Tabela 12) e galileo-e5-altboc (−152,0 → −152,24 dBW). O ICD não tem uma linha de E5 de banda completa, pelo que o valor AltBOC é a soma de potências dos totais E5a e E5b da Tabela 12, construída como o valor antigo. Mudam três resultados de projeto de sinal LEO (64 valores: estas potências recebidas e a degradação do C/N0 de LEO para GNSS nas duas vítimas), listados na mesma revisão (§5) e no mesmo CSV. Nada mais muda.
  • Correção da maré atmosférica S2 (tides::atmospheric_tide). Os harmónicos de pressão do ar S2 de Ray (2001) são coeficientes de P_nm não normalizado com atrasos de fase em cosseno; eram usados como totalmente normalizados e com o atraso como avanço em seno do IERS. Entram agora divididos por N_nm com ε = 90° − ψ; o novo tides::s2_air_waves reproduz o modelo A2 da Tabela 5 do GFZ STR06/01 para todas as 21 ondas (pior 0,0005 cm, 0,05°; VALIDATED). Só mudam as saídas com marés ativadas: o ajuste CI de Galileo 0,132 → 0,133 m, as componentes de Swarm-A em 1–2 mm (fixado antecipadamente em xval/s2-air-tide-fix/).

  • Apenas documentação: propagator::solve_kepler_checked, orbit::solve_kepler e ephem::solve_kepler ficam documentados como solucionadores legados, numericamente inalterados, com remissão para kepler::solve_kepler_markley.

  • Estado da ronda 3 de D9 (utck_bound). A Circular T 465 do BIPM saiu em 2026-10-12. A pontuação prospetiva fixada antecipadamente continua por executar: a edição 465 contém cerca de 285 valores de teste e a regra de paragem exige 1000, ou seja, cerca das edições 465–468. A execução precisa também dos ficheiros por laboratório de 2026-09-30 arquivados, porque o BIPM entretanto reescreveu 87 dos 113. A linha do registo e o cabeçalho do teste di-lo; o teste, os seus limiares e a sua divisão não mudam.

  • Revisão da verdade da documentação (0,36). Roteiro, linhas de capacidades, linhas de estado de documentos de projeto e comentários de módulos alinhados com o código; sem alterações de saída. Os itens já construídos mas ainda listados como em aberto ficam agora marcados como concluídos: as verificações de máscara ITU-T, o cenário de holdover de 24 h e a ingestão de registos de relógio (temporização de telecomunicações), os guias de arranque do primeiro minuto, Lense–Thirring e a verificação cruzada do propagador com o Orekit, a cadeia GCRS com ITRF preciso, os hashes de referência e entre plataformas, a proveniência, o ARAIM de falhas múltiplas (ADD v4.2), o FDE de satélite único, a biblioteca CRPA, o limite de ambiguidade de franja do CAI, o dimensionamento de ruas de cobertura e a vista de órbita 3-D, a dinâmica de atitude de corpo rígido, o escritor de OMM e o leitor de kernels NAIF, a libração lunar DE440, a frase de significado da execução no recreio, PositioningFom, o navegador fortemente acoplado de 17 estados e o tipo de mapa de gravidade. As linhas indicam também com precisão o que continua em aberto (por exemplo o JD de duas partes em orbit::Propagator, o leitor src/ionex.rs face a um produto real e a exclusão de vários satélites em raim). O docs/design/evidence/cn0-m2m4/RESULTS.md em falta é escrito a partir de uma execução nova dos seus testes (M1–M4 passam), e o rascunho de validação IQ voltado para parceiros tem as contagens atuais do registo.

  • Os códigos de memória do Galileo E1 deixam de ser incluídos. data/galileo-os-sis-icd/C7_E1B.txt e C8_E1C.txt (Anexo C.7/C.8 do ICD) são removidos do repositório e dos pacotes. Os termos do ICD (citados em LICENSING.md) permitem que um utilizador guarde os códigos com a fonte reconhecida e os use num produto, mas só permitem a redistribuição para fins não comerciais, e o Kshana é também oferecido ao abrigo de uma licença comercial. galileo::e1b_table / e1c_table passam a devolver um Result e a ler a cópia do próprio utilizador a partir de KSHANA_GALILEO_E1B / KSHANA_GALILEO_E1C ou, numa cópia de trabalho do código-fonte, a partir de data/galileo-os-sis-icd/, onde o novo scripts/fetch_galileo_e1_codes.sh os extrai do PDF do ICD (com verificação de hash). galileo::E1B_TABLE_TEXT / E1C_TABLE_TEXT são removidos. Sem as tabelas, os sinais Galileo E1 (galileo-e1b, galileo-e1c) devolvem um erro que indica como as fornecer, e os testes de E1 são ignorados com uma mensagem. Com as tabelas presentes, todas as saídas de E1 permanecem inalteradas. Nenhum cenário, resultado de referência ou saída de espetro usa as tabelas de códigos. Os ficheiros de teste de E5a dos Anexos C.3/C.4 (a referência independente de LFSR em tests/iq_signals.rs) são tratados da mesma forma: obtidos pelo mesmo script, ignorados pelo git, e o teste é ignorado sem eles.

  • Matemática portátil em todo o lado (0,36, STUDIO-15): todas as funções transcendentes f64 da biblioteca, e os amostradores normal, gama e exponencial de rand_distr, passam a calcular através da libm em Rust puro (portable_math::PortableFloat, portable_distr), pelo que uma compilação nativa e a compilação WebAssembly devolvem JSON de resultados idêntico byte a byte para todos os 141 cenários incluídos e para a execução curta de IQ. O custo é que os últimos bits dos resultados calculados com a biblioteca matemática do anfitrião se alteraram: 98 dos 141 cenários incluídos mudaram, 43 não; 5 mudaram em mais de 1e-3 no seu maior campo, e os restantes em menos. Cada valor alterado está listado, antigo -> novo, em docs/revisions/STUDIO15-portable-math-rebaseline.md (com um CSV de todos os 136 127 números alterados); nenhum limiar, tolerância ou valor-limite mudou. Números publicados que mudaram: disponibilidade de europa-surface-pnt com a distância à Terra 0,719 -> 0,713 e erro RMS 86,147 -> 86,499 m (uma época no limite da disponibilidade passa a resolver-se da mesma forma em toda a parte; imprimia 0,725 / 85,800 m em macOS arm64); erro de estação de lunar-joint-od-clock 3,541350 -> 3,536885 m com VLBI e 2183,558 -> 2184,021 m sem ele; paper/crossover/inertial.json, oito valores de vibration_psd em 3 unidades na última casa (erratum no relatório técnico); o documento cislunar-observability publicado em grandezas ao nível do piso de arredondamento (oito valores para além de seis algarismos significativos, até 6.8e-5 em termos relativos; nenhuma ordenação nem limiar mudou). Os hashes fixados das proteções de identidade byte a byte (skyline_scenarios, geometry_corpus_identity, geometry_trust_no_change) são rebaseados para uma linha de base designada "0,36 portable", mantendo-se os valores de 0.35.0 como registo histórico; a previsão congelada da estação de referência lunar não foi tocada e a sua reexecução portátil fica guardada a seu lado (docs/predictions/*.portable-0.36.json). tests/lunar_joint_od_numpy_oracle.rs (a linha validada de OD conjunta lunar): ficheiros de teste reexportados e comparação com numpy repetida com numpy 2.4.6, a versão registada, com script e limiar inalterados; as seis redes passam (docs/revisions/STUDIO15-lunar-joint-od-oracle-rerecord.md). O trabalho dos lotes 2-3 integrado depois de STUDIO-15 também usa matemática portátil (457 pontos de chamada em 62 ficheiros); o que isso alterou está em docs/revisions/STUDIO15-batch4-rebaseline.md: 12 cenários incluídos (maior alteração relativa 5.2e-8, nenhum valor impresso muda), 28 linhas de proteção de linha do horizonte revalidadas, o resumo criptográfico M2M4 de iq_campaign, os hashes de referência legados de gnss-ins, o sigma de datum da baliza não observada (632,3769 -> 632,3772 m), e duas conclusões registadas (fechos de DRO no CR3BP; CRPA A3, 194 de 456 ligações). O edf exato de Greenhall mantém o seu limiar validado com um logaritmo de precisão dupla-dupla no seu kernel (docs/revisions/STUDIO15-greenhall-edf-portable.md), e a referência independente do test bench gps-sdr-sim foi reexecutada nas exportações NMEA alteradas, com todos os limiares a manter-se (docs/revisions/STUDIO15-testbench-gpssdrsim-rerun.md).

  • README: a linha do conjunto lunar indica o nível de evidência de cada parte (dizia que todas eram MODELLED).

  • realdata::clk::rinex_clock_series devolve RinexClockSeries (série, registo de grelha, sistema de tempo, se foi declarado, tipo de registo) em vez de um par (PhaseSeries, GriddingLog). Passa a recorrer a registos de recetor/estação (AR) com o nome pedido quando não há registos de satélite (AS).

  • Nenhuma pontuação muda, a menos que a geometria seja fraca; a etiqueta é sempre comunicada. Com geometria boa ou razoável (incluindo um céu aberto só com GPS de 8 satélites) ou com geometria desconhecida (o monitor não é executado), todas as pontuações são como em 0,35: tests/geometry_trust_no_change.rs fixa as saídas das duas sessões de exemplo e tests/geometry_corpus_identity.rs cada corpus NMEA de embarcação submetido (também como céu aberto só com GPS) e os cenários de formação de tripulações aos bytes de 0.35.0, depois de removidas as chaves acrescentadas; nos dois cenários de formação em que a interferência torna a geometria fraca, as épocas fracas diferem apenas pela dedução de geometria. Um registo com geometria fraca perde até 15 pontos que não perdia em 0,35. As restantes alterações previstas são todas acréscimos: as chaves acima no JSON de resultados e nos pacotes de evidências (score_model.weights não muda); o esquema de linhas JSON em tempo real passa de 1,2 para 1,3 (geometry acrescentado, class em cada dedução); o resumo do excerto ganha geometry; a telemetria ganha séries de geometria, campos e a etiqueta class apenas para entradas que os tragam, pelo que um fluxo ou resultado de 0,35 é apresentado byte a byte como antes. geometry é o 17.º nome de monitor; é listado em último lugar em monitors_run quando decidiu (uma embarcação cujo registo dá a geometria; uma lista de 0,35 mantém a sua ordem e a contagem de monitores do resumo sobe uma unidade) e não tem entrada em [score.weights] (definir uma é recusado: a sua dedução é definida em [geometry]).

  • tests/fixtures/dop/NOTICE indicava a licença do gnss_lib_py como Apache-2.0; a versão 1.0.4 é MIT.

  • O leitor NMEA passa a ler GSA (um GSA curto é ignorado, não contado como saltado) e mantém as elevações e os azimutes de GSV, incluindo para satélites listados sem sinal; o leitor UBX mantém a elevação e o azimute de NAV-SAT. O C/N0 é lido exatamente como antes.

  • Alteração de resultado: os interferidores de banda larga e de varrimento passam a usar Q = 2. A equação antiinterferência usa o ajuste de espetro alargado Q de manual para estes interferidores, onde usava 1. Q = 2 é ruído branco sobre o lóbulo principal com a potência do sinal na banda normalizada; está fixado nos testes à forma fechada de navsignal.

    • Inalterado: os interferidores CW e de banda estreita (Q = 1), um tipo de interferidor não reconhecido (Q = 1, o valor mais danoso) e q_override.
    • Efeito: onde atua um interferidor de banda larga ou de varrimento, o C/N0 efetivo sobe até 3,0103 dB, os limiares de J/S derivados sobem 3,0103 dB e os raios de negação em espaço livre encolhem por um fator de 0,7071.
    • Cenários incluídos alterados: mudam 12 de 144, todos como fixado antecipadamente (xval/jammer-q/PREREGISTRATION.md, resultados em xval/jammer-q/RESULTS.md):
      • jamming-demo: C/N0 +3,01 dB;
      • jamming-harbour-approach-skyline: min_tracking 6 → 7;
      • lunar-jamming: satélites perdidos 26 → 0, distância mediana de perda de bloqueio 27,4 → 19,4 km;
      • tracking-loop: raio de negação por dinâmica do laço 75,2 → 53,2 km;
      • e as campanhas e verificações cruzadas de espetro que os contêm.
    • Consumidores afetados: os tipos jamming, lunar-jamming, tracking-loop e impairment-eval, o jamming_kind_cross_check dos tipos de espetro, a curva de referência MODELLED da campanha de IQ e o Q predefinido de labfit, e a exportação de cenas de interoperabilidade.
  • Extensão JetBrains: nenhuma API de plataforma obsoleta ou marcada para remoção. Os cinco diálogos de escolha usam um pequeno DialogWrapper com uma lista pendente em vez do obsoleto Messages.showChooseDialog; os seletores de um só ficheiro usam o construtor de FileChooserDescriptor em vez do obsoleto FileChooserDescriptorFactory.createSingleFileDescriptor(); a animação abre com BrowserUtil.browse(Path) em vez de browse(File), que a plataforma 2026,3 marca para remoção. O Since-build mantém-se em 243. O IntelliJ Plugin Verifier reporta Compatible, sem utilização obsoleta ou marcada para remoção, face a 2024,3 (IC-243.21565.193), 2025,2 (IC-252.23892.409), 2026.2.3 (IU-262.10968.63) e 2026,3 EAP (IU-263.6259.32); verifyPlugin verifica 2024,3 por predefinição e qualquer lista indicada em KSHANA_VERIFY_IDES.

  • gnss_sim::run_gnss_sim e jamming::run_jamming devolvem Result: uma secção [skyline] inválida é um erro quando chamada diretamente, como já era através de api::run_toml, em vez de um regresso silencioso à máscara plana. Quebra de compatibilidade para quem chama estas duas funções em Rust.

Corrigido#

  • Pontuador da campanha: um falso bloqueio real do seguidor nunca era contado (iq::campaign). A verificação de falso bloqueio do seguidor move um canal de LOCKED para LOST quando dispara. O pontuador marcava, em vez disso, a atualização seguinte do canal, que já estava desbloqueada e por isso nunca era contada. Um evento false-lock comunicado a partir de LOCKED é agora um episódio no seu instante, na execução e em cada evento declarado que o contenha. Um encontrado durante a captura, ou repetido por um canal já em LOST, não é um novo episódio. Um novo teste provoca um falso bloqueio real: uma portadora GPS L1 C/A legítima com um salto de 1/(2T) enquanto bloqueada (tests/iq_campaign_false_lock.rs).

    • Na campanha de referência de tests/iq_campaign.rs, só muda o PRN 11 de ramp/agc-3bit (episódios de falso bloqueio 0 → 1, 426 e 437 por hora bloqueada).
    • Os DIGESTs das suas células são fixados de novo.
    • A fixação dos resultados pontuados, fixada antecipadamente, mantém-se ativa e continua a reproduzir-se exatamente: no seu hash, apenas esses seis campos, alterados por esta correção feita após o registo, são remapeados para os seus valores anteriores à correção. Os valores corrigidos são fixados à parte.
    • Nenhum limiar foi alterado e nenhuma linha, valor ou número web VALIDATED mudou.
  • lunar-frame-campaign: uma baliza sem observação passa a ser comunicada (encontrado por MR-05). O relatório ganha unobserved_beacons e warning apenas quando alguma baliza não tem observação, e então os sigmas das balizas observadas provêm da sua própria informação em vez de serem todos nulos. O datum não muda, e nenhuma saída por predefinição, incluída ou publicada se altera (docs/revisions/BEACON-unobserved-cell-changes.md).

  • Referencial lunar de eixos principais (lunar_frame::icrf_to_moon_pa, usado por lunar_od e pelo ajuste do LRO): o desvio entre o referencial de Terra média e o de eixos principais da DE421, de moon_080317.tf, era aplicado no sentido errado e com a ordem de Euler errada, pelo que o referencial PA analítico ficava a cerca de 208″ do PA em vez de coincidir com ele. Passa a ser transcrito como o Frames Required Reading do SPICE o define e concorda com pxform('MOON_ME','MOON_PA') do SPICE até 2.6e-16 rad; o referencial PA analítico fica a 6″ a 8″ do PA da DE440 (fixado antecipadamente e1ead19b, refixado be33382e depois de a primeira alteração proposta falhar o limiar de 1e-12; docs/design/evidence/fut05b-me-pa-offset-sign/). Números publicados que mudam: o ajuste do LRO (tests/agency_lro.rs) com sobreposição bruta 53,8 → 39,9 m, dinâmico 12,6 → 12,05 m, dinâmico reduzido 6,65 → 6,67 m (limiares inalterados). A pilha analítica concorda agora com a validação cruzada ANISE de nível DE (12,0 / 6,67 m) nos dois níveis; a diferença anterior no nível dinâmico era este erro.

  • O servidor MCP recusa [terrain] dem_hgt (seguimento de CAP-06b). O caminho do mosaico de terreno do tipo de interferência está agora em inline_only::FILE_SOURCE_KEYS. Uma superfície em linha recusa um cenário que o indique, com uma mensagem que não contém o caminho nem um erro do sistema operativo. O teste de proteção de fontes de ficheiro assinala agora também os campos que terminam em _hgt.

  • Jd2::from_parts com uma parte fracionária do dia perdia a fração nas conversões de UTC, TAI, UT1 e rotação da Terra (uma hora de parte do dia deixava a Terra 15° errada); a parte do dia é agora normalizada para um inteiro. Nenhum chamador do motor foi afetado: todos passam um dia inteiro, e todas as saídas fornecidas são idênticas bit a bit.

Planeado#

  • A geometria a partir de uma linha do horizonte declarada (ponto 1 de 0,36, já no motor como src/skyline.rs): sky-blocked e open_fraction a partir da linha do horizonte quando a entrada a fornece (a lacuna de azimute como alternativa), um evento de degradação natural (fiorde ou terminal) em nmea-scenario, e as duas geometrias mascaradas da nota de projeto na linha sigma_UERE x DOP, fixadas antecipadamente como adenda.
  • Geometria para registos RINEX com navegação (a partir da posição do próprio motor) e registos Android (a partir das linhas Status); ambos leem hoje unknown. Geometria em $PKSHT (versão 1 inalterada em 0,36) e nas integrações com Signal K e OpenCPN.
  • Uma lacuna preexistente, não introduzida em 0,36: quando o campo SNR de todos os satélites está vazio, não dispara nenhuma dedução de loss-of-lock nem de C/N0; a perda total de sinal só é visível através de signal_loss do monitor de geometria (classe environment). Está prevista uma dedução para este caso.
  • Um fluxo de esquema 1,3 nas referências independentes externas de telemetria (o analisador de formato de texto do Prometheus e o recolhedor OTLP), que hoje cobrem apenas fluxos 1,2.
  • Uma obstrução bilateral (um desfiladeiro ou um fiorde estreito) é lida como perda de sinal e não como céu bloqueado até a linha do horizonte ser integrada.

[0.35.0] - 2026-10-12#

Uma passagem que nomeia clientes de IA de terceiros é omitida aqui; consta de CHANGELOG.md no GitHub.

Verificador de Galileo OSNMA#

  • Novo módulo kshana::osnma e kshana osnma verify <input>: um verificador aberto, em Rust puro, do lado do recetor para o Galileo OSNMA. Lê páginas I/NAV e comunica, por satélite e época, se os dados de navegação estão autenticados, com um motivo para cada falha ou atraso: leitura de HKROOT e MACK, remontagem de DSM-KROOT e DSM-PKR, verificação de Merkle da chave pública, verificação da cadeia de chaves TESLA, verificação de MACSEQ e de etiquetas para ADKD 0, 4 e 12 incluindo autenticação cruzada, e um resultado com a forma de $PKSOS para o monitor de confiança do recetor. A saída traz um aviso consultivo de que o estado não é um serviço de integridade de navegação. docs/OSNMA.md indica o que é e o que não é verificado, o requisito de tempo, e que o Kshana não concede quaisquer direitos ao abrigo dos direitos de propriedade intelectual do ICD OSNMA da UE (os utilizadores baseiam-se na autorização do Anexo E do ICD). Implementado face ao SIS ICD Issue 1,1 e às Receiver Guidelines Issue 1,3. As páginas têm verificação CRC e um fluxo de bytes UBX-RXM-SFRBX da u-blox pode ser lido diretamente (--format ubx). Os testes por predefinição usam dados sintéticos e testes de resposta conhecida de primitivas publicadas; um teste opcional lê uma cópia descarregada localmente dos vetores oficiais. Após revisão independente, o verificador obtém o seu tempo apenas de chaves TESLA verificadas (uma subtrama de futuro distante falsificada já não pode apagar uma falha), deixa uma autenticação expirar e acompanhar o IODnav em uso, respeita as mensagens de alerta verificadas (cuja folha de Merkle passa a incluir o campo aleatório NPK) e o estado NMA "don't use", mantém as etiquetas fictícias fora do estado do satélite, mantém as cadeias por CID com revogação e renovação, verifica o hash de preenchimento de KROOT, e limita os comprimentos de trama UBX e o trabalho de verificação TESLA. Um satélite só é lido como autenticado enquanto os dados mais recentes de efemérides e de relógio que envia forem, bit a bit, os dados que foram autenticados (e não apenas sob o mesmo IODnav), um estado ou revogação do cabeçalho NMA não autenticado só conta quando dois satélites concordam ou um KROOT verificado o transporta, um KROOT mais antigo reproduzido não pode substituir uma cadeia, e um fluxo de chaves parado é comunicado.

Acrescentado (canais do servidor MCP)#

    Uma passagem que nomeia clientes de IA de terceiros é omitida aqui; consta de CHANGELOG.md no GitHub.

  • kshana-mcp --http <addr>, HTTP em streaming, alojado pelo próprio utilizador. Loopback por predefinição; um endereço que não seja loopback exige --allow-remote e um token de portador em KSHANA_MCP_HTTP_TOKEN; nenhuma ferramenta lê ou escreve um caminho (as ferramentas de ficheiros IQ estão desativadas); limites de tamanho de pedido, tempo e concorrência; sem cabeçalho CORS; verificações de Host e Origin. O Kshana não aloja nenhum ponto de acesso (docs/deploy/mcp-http.md, com modelos para Docker, Fly.io e Cloud Run).

Acrescentado (superfícies)#

  • osnma_verify em Python e WebAssembly. O verificador por detrás de kshana osnma verify sobre bytes em memória, devolvendo o JSON que --json imprime (aviso consultivo no seu campo advisory; apenas estado de autenticação, não um serviço de integridade de navegação). As mesmas recusas que na linha de comandos. Não está no MCP: a entrada é um fluxo bruto longo do recetor, mais bem servido pela CLI e pelo Python. docs/SURFACES.md e docs/OSNMA.md di-lo.

  • trust_telemetry em WebAssembly, Python e MCP, com um comando de extensão e uma ação JetBrains. Apresenta um fluxo de confiança ou um resultado de receiver-trust como texto Prometheus, linhas syslog CEF ou LEEF ou uma carga JSON OTLP, com os codificadores que kshana trust-telemetry usa (kshana::surface::trust_telemetry); sem socket e sem relógio. Extensão: /kshana-trust-telemetry e a competência trust-telemetry. JetBrains: Render Trust Telemetry. As funcionalidades wasm e python e o servidor MCP passam também a ativar otlp, que não acrescenta nenhum crate.

  • Varrimento de paridade. Ações JetBrains Validate Scenario, List Scenario Kinds e Assess Receiver Stream; kshana --help passa a listar receiver-trust evidence, evidence, trust-telemetry e nmea-scenario; o notebook compliance-and-test-bench (mapeamento de compliance e exportação de test bench); e cada célula "CLI only" do JetBrains que restava em docs/SURFACES.md é agora um N/A explícito com o seu motivo.

  • Uma passagem que nomeia clientes de IA de terceiros é omitida aqui; consta de CHANGELOG.md no GitHub.

Acrescentado (pacotes de evidências)#

  • kshana receiver-trust evidence e kshana evidence verify: pacotes de evidências assinados e verificáveis para um evento de confiança GNSS. Um pacote reúne o excerto bruto do registo e o SHA-256 do registo completo, a configuração com todos os limiares, os resultados e motivos por época, a versão do motor, um manifesto encadeado por hashes e um resumo HTML autónomo, assinados com Ed25519 (uma chave de kshana evidence keygen ou um ficheiro próprio; as chaves nunca são guardadas num pacote e *.evidence-key é ignorado pelo git). verify verifica todos os hashes, a cadeia e a assinatura e indica exatamente o que falha; com --pubkey fixa o signatário. Pode ser anexado um token RFC 3161, que é lido e associado ao manifesto (a assinatura da própria autoridade não é verificada por esta compilação; openssl ts -verify trata disso). O excerto do registo são os bytes exatos da janela quando o leitor comunica intervalos de origem (NMEA, UBX, RINEX 3, Android) e, caso contrário, o registo completo, e o manifesto diz qual dos casos. A criação e a verificação são funções públicas puras (kshana::evidence) que compilam para wasm32. Os pacotes declaram que são um registo técnico, e não um parecer jurídico. As novas dependências são a árvore de ed25519-dalek (BSD-3-Clause e Apache-2.0/MIT, funcionalidades mínimas) e um zeroize direto (já nessa árvore) para apagar o material de chaves. Ver docs/EVIDENCE-PACKS.md.

Acrescentado (telemetria de confiança)#

  • kshana trust-telemetry: a confiança GNSS como fonte de telemetria de segurança. Lê o fluxo de confiança por época (linhas JSON: pontuação 0-100, banda, motivos) ou um resultado em lote de receiver-trust e alimenta um ponto de acesso Prometheus /metrics (localhost por predefinição), eventos syslog em CEF ou LEEF dentro de um envelope RFC 5424 (UDP ou TCP) e, atrás da funcionalidade otlp desativada por predefinição, exportação JSON OTLP/HTTP. A entrega corre em threads de trabalho com limites de tempo de ligação e de escrita, recuo de religação limitado e um contador kshana_trust_syslog_send_failures_total, pelo que um recolhedor morto ou bloqueado não consegue bloquear a avaliação em tempo real nem congelar /metrics; as etiquetas de motivo são limitadas a 64 séries. Sem novas dependências. Há um painel Grafana de exemplo em deploy/grafana/. Os nomes das métricas, as etiquetas e o mapeamento de campos CEF/LEEF estão em docs/TRUST-TELEMETRY.md. O formato do fluxo está isolado em src/telemetry/sample.rs.

Adicionado#

  • Confiança marítima: uma pontuação de confiança em tempo real de 0-100 para a posição de uma embarcação em movimento, a partir do NMEA 0183 que o recetor já emite, com uma barreira opcional. kshana receiver-trust aceita uma tabela [platform] (kind = "static" ou "vessel", a velocidade máxima, a aceleração e a taxa de viragem da embarcação, a altura da antena acima da linha de água e um sensor de rumo opcional; cada valor por predefinição está documentado com o seu motivo). Para uma embarcação, o monitor estático de salto de posição, que mede a distância à média de calibração e está errado num navio em movimento, é substituído por monitores causais de plataforma móvel: consistência cinemática da posição face à velocidade e ao rumo comunicados e face aos limites da embarcação, rumo do giroscópio face ao rumo sobre o fundo, odómetro de velocidade face à velocidade sobre o fundo, altitude da antena face à altura declarada acima da linha de água, colapso e subida conjunta da dispersão de C/N0 face à linha de base de calibração, e consistência temporal (também face ao relógio deste computador, em modo em tempo real). Lê também um estado de autenticação comunicado, global ou por satélite (apenas um estado comunicado: sem criptografia OSNMA). Cada limiar é declarado numa tabela [maritime] antes da execução. Cada época recebe depois uma pontuação de 0 a 100 por um mapeamento determinista e fixado antecipadamente (sem aprendizagem, nada ajustado a eventos; os pesos, os limites das bandas e as evidências constam numa tabela [score]), mapeada nos estados de confiança existentes, com os monitores que deduziram e os seus pontos. Os cenários estáticos não mudam e têm o mesmo hash que antes. kshana receiver-trust live <session.toml> lê stdin, um ficheiro em acréscimo, TCP ou UDP e escreve uma linha JSON por época e uma frase proprietária $PKSHT; com --gate deixa o fluxo passar inalterado enquanto a posição é de confiança e marca a posição como inválida (qualidade GGA 0, estado RMC e GLL V, modo GNS e VTG N) enquanto não é. A barreira está desativada a menos que seja pedida; --listen tcp:<port> serve o fluxo filtrado a qualquer número de clientes TCP (loopback por predefinição, um cliente lento é largado em vez de bloquear os outros). Este é um software de caráter consultivo, não um equipamento de navegação homologado (IEC 61108, IEC 61162); o operador continua a ser responsável. examples/maritime-trust/ é um registo sintético de Tallinn a Helsínquia, escrito apenas como texto, com um desvio de posição a meio do trajeto durante o qual o recetor continua a comunicar uma posição válida; a sua saída esperada está fixada por um teste. Guia: docs/MARITIME-TRUST.md. As verificações não conseguem ver um falsificador cuja posição seja consistente com tudo o que está no barramento; o guia di-lo.

Mapa de interferência#

  • kshana interference-map e kshana route-exposure: um retrato público de onde aeronaves e navios comunicaram dados de navegação degradados, e de quanto de uma rota é afetado. Os dados de entrada são ficheiros CSV locais feitos a partir de dados ADS-B (adsb.lol, ODbL 1,0) e AIS (NOAA MarineCadastre, Kystverket sob NLOD 2,0) com licença aberta; cada ficheiro de saída é uma fonte e um dia UTC de GeoJSON, com o método, os seus limiares, a licença dos dados, a atribuição e o enviesamento de cobertura da fonte. O método ADS-B agrega NIC e NACp numa grelha fixa e considera uma célula degradada com base na proporção de aeronaves distintas, com salvaguardas para equipamento que nunca comunica exatidão, baixa altitude e causas de área alargada. O método AIS executa cinco detetores: posições em terra (face a uma linha de costa fornecida pelo utilizador), trajetos circulares, saltos implausíveis, velocidades implausíveis e muitas embarcações numa só posição. Os limiares são constantes fixadas antecipadamente de uma versão de método designada. Apenas agregados: os identificadores são tratados por hash em memória e nunca escritos, e as células com menos de 5 aeronaves ou embarcações distintas não são publicadas. Uma célula degradada não é uma constatação de interferência. Os comandos por predefinição não usam rede; um auxiliar opcional fetch-land --allow-network descarrega polígonos de terra do Natural Earth de um endereço fixado por commit e só guarda o ficheiro se o seu SHA-256 coincidir. A entrada ADS-B é um CSV ou diretamente os ficheiros de histórico readsb do adsb.lol (nova dependência: flate2 com o seu motor em Rust puro, para gzip). Ambos os métodos estão na versão 2: uma chamada de degradado ou anómalo exige pelo menos 5 aeronaves ou embarcações (o mínimo de publicação), toda a contagem por célula abaixo de 5 é retida como null, e um dia cujo fundo não pode ser estimado retém as suas chamadas. Os ficheiros de saída têm o nome <source>-<dataset>-<date>.geojson e nunca são sobrescritos; a entrada é lida em fluxo linha a linha; a exposição de rota trata o antimeridiano. Os testes usam apenas dados sintéticos. Ver docs/INTERFERENCE-MAP.md e a revisão de licenças em docs/data/INTERFERENCE-DATA-SOURCES.md.

Acrescentado (fluxos de formação)#

  • kshana nmea-scenario: NMEA 0183 de ponte sintético para formação de tripulações no reconhecimento de interferência e de spoofing GNSS. A partir de um TOML de cenário, escreve um ficheiro ou transmite por TCP ou UDP (unicast ou broadcast; em tempo real, acelerado ou o mais depressa possível) o conjunto completo de ponte GGA, RMC, VTG, GSV, GSA, GNS, ZDA, HDT e VBW para o trajeto de uma embarcação com limites de taxa de viragem, aceleração e corrente, com geometria de satélites a partir das constelações nominais do próprio motor. Eventos programados numa linha temporal: interferência, desvio de posição (uma posição válida que se afasta), spoofing de tempo e um atraso de repetição, cada um com rampas de início e de recuperação. Um registo do instrutor (JSON e texto) regista o que foi injetado e quando, com o trajeto verdadeiro face ao comunicado. Uma biblioteca em scenarios/training/ (interferência em mar aberto, desvio costeiro, spoofing de tempo na aproximação ao porto, combinado) traz notas para o formador. A saída tem somas de verificação válidas e é determinista por semente; os testes fixam um excerto de referência por cenário e leem cada frase com o leitor NMEA de receiver-trust. Apenas texto: sem saída de RF, IQ ou forma de onda; os fluxos destinam-se a formação e ensaio e nunca devem ser ligados aos sistemas de navegação em funcionamento de uma embarcação. Ver docs/NMEA-TRAINING.md.

Integrações marítimas (0.35.0, linha de trabalho B)#

  • Extensão Signal K (integrations/signalk/, não publicada no npm): executa ou liga-se a kshana receiver-trust live (a entrada NMEA do próprio servidor, argumentos de entrada personalizados, uma fonte TCP de linhas JSON, ou as frases $PKSHT de um fluxo com barreira), publica a pontuação de confiança, a banda, os motivos, os alarmes e o estado da barreira em navigation.gnss.kshana.* (incluindo a posição comunicada pelo recetor como contexto, nunca navigation.position), e emite uma notificação Signal K (warn em degradado, alarm em não confiável, com limiares de retenção, de limpeza e de obsolescência, todos no esquema de configuração). Sem dependências npm. Testado sobre saída sintética gravada.
  • OpenCPN: o NMEA em modo de barreira é servido diretamente por kshana receiver-trust live --gate --listen tcp:10110 (recomendado); um retransmissor TCP sem dependências (integrations/opencpn/nmea-tcp-relay.mjs) é a alternativa opcional. Em qualquer dos casos, o OpenCPN vê uma posição inválida quando a confiança colapsa e $PKSHT na sua janela de depuração NMEA; os testes reproduzem o fluxo sintético com barreira através de um socket TCP real e verificam o que um consumidor recebe. Uma extensão nativa de painel de pontuação (integrations/opencpn/plugin/, API de extensões 1,18, CMake) lê $PKSHT do próprio fluxo NMEA do OpenCPN e alerta na banda de não confiável; compila, a sua lógica tem testes unitários e foi executada dentro do OpenCPN 5.8.4 sob um ecrã virtual (evidências e um script de reprodução em integrations/opencpn/evidence/); não está empacotada para o gestor de extensões.
  • Construção de referência (deploy/reference-build/): lista genérica de peças, configuração do sistema operativo, unidades systemd para o monitor consultivo e para a barreira opcional (verificadas com systemd-analyze verify por check-units.sh), uma opção de contentor, ligação ao Signal K.
  • A extensão Signal K aceita o esquema JSON em tempo real 1,2 (uma chave position e depois uma chave advisory acrescentadas; as chaves acrescentadas desconhecidas são ignoradas), verificado sobre saída real de 1,2 e face a um signalk-server real.
  • Correções da revisão: as unidades systemd reiniciam sempre e correm em ambiente isolado (sem shell, sem rede onde não é necessária), um excerto de logrotate, check-units.sh falha perante qualquer constatação; o contentor executa a barreira a partir de variáveis de ambiente, com verificação de saúde e imagens de base fixadas por resumo; metadados de pontuação do Signal K, a notificação obsoleta é substituída quando os dados retomam, os erros de processos filhos são mantidos e os encerramentos escalam, inputArgs inseguros são recusados, e a notificação está em notifications.navigation.gnss.kshana.trust; o retransmissor limita uma linha parcial retida; os analisadores de $PKSHT rejeitam pontuações fora de 0 a 100; uma verificação de ligações da documentação; um fluxo de trabalho de CI (marine-integrations.yml) que executa tudo isto, incluindo o binário real de ponta a ponta.
  • docs/MARINE-INTEGRATIONS.md. Software de caráter consultivo, não um equipamento homologado; o operador continua a ser responsável. Apenas software: nada transmite, e não é afirmado nenhum valor de deteção ou de falso alarme.

Acrescentado: mapeamento de compliance e exportação para test bench#

  • docs/compliance/ e kshana compliance-report. Um mapeamento das saídas do Kshana para cinco referenciais e normas de resiliência (o US DHS Resilient PNT Conformance Framework v2.0, as orientações da IMO para navios, as orientações da EASA para a aviação, o artigo 21 da NIS2, a EN 16803, uma norma paga citada por parte e pelos poucos números de cláusula visíveis no texto do catálogo), uma tabela por referencial: a referência, o que pede na nossa paráfrase, as saídas que fornecem elementos de prova em apoio dele, e a lacuna. Ficam registadas as versões das fontes, os URL e o que foi e não foi lido. kshana compliance-report <result.json>... preenche o mapeamento a partir das execuções indicadas e marca cada linha como evidenced, partly-evidenced, not-evidenced ou out-of-scope, em Markdown e JSON, com a lacuna mantida em todas as linhas. A formulação é "fornece elementos de prova em apoio de"; nada é classificado nem aprovado. Os testes usam execuções sintéticas e falham quando uma tabela submetida se afasta do código.
  • kshana bench-export <scenario.toml>. Escreve o movimento do veículo e os eventos de um cenário gnss-ins, jamming ou gnss-sim para um simulador GNSS de laboratório: um CSV de movimento do utilizador com referenciais documentados e um ficheiro auxiliar de metadados, GGA/RMC NMEA 0183, texto de pontos de passagem, e os eventos como CSV e como blocos receiver-trust [[events]] (src/interop/testbench.rs). Apenas movimento e eventos: nenhum sinal é escrito. Cada ficheiro é lido de volta em tests/interop_testbench.rs e comparado dentro da sua tolerância declarada. docs/TEST-BENCH.md dá o método para reproduzir a exportação através de um simulador e pontuar o registo do recetor com kshana receiver-trust.
  • O que conta como evidência. Um resultado só conta para uma capacidade quando traz os campos que o seu tipo escreve; uma etiqueta de tipo, por si só, não conta para nada. Tipos desconhecidos, um resultado que discorda do seu cenário irmão, hashes não hexadecimais e contagens de confiança do recetor malformadas são listados como não usados, com o motivo. O relatório escapa as células de Markdown e não pode entrar em pânico com um hash não ASCII. compliance::run_from_text e assess_texts recebem textos, não caminhos.
  • Exportação para test bench. --epoch tem verificação de intervalo (UtcEpoch::parse_iso); o ficheiro de pontos de passagem verifica cada intervalo e o comando diz porquê quando um é deixado de fora; a documentação indica que o rumo de gnss-ins é a guinada do corpo e não o rumo sobre o fundo, os campos de substituição de GGA, e a própria variação de altura do cenário. bench-export e compliance-report constam do texto de utilização.
  • fusion::pack::truth_trajectory expõe o histórico de estados verdadeiros do perfil de condução de gnss-ins (o mesmo passo que a verdade do próprio tipo usa), e UtcEpoch ganha campos de data e hora NMEA.

Validação do mapa de interferência#

  • A semântica de descodificação e a geometria do mapa de interferência são verificadas face a implementações independentes sobre dados de entrada sintéticos. Os significados dos códigos NIC e NACp face à descodificação com pyModeS de tramas ADS-B sintéticas, os valores de não disponível do AIS face à descodificação com pyais de frases AIVDM sintéticas, a atribuição de células da grelha face a shapely, o comprimento de rota por estado de célula face a shapely e GeographicLib, e a mascaragem de interior face a shapely e pyproj, cada um com uma tolerância fixada antes da primeira comparação (tests/fixtures/interference_map_ref/PREREGISTRATION.md). Isto valida a forma como os códigos e os valores dos campos são lidos e a geometria, não que uma célula assinalada seja interferência. O leitor de polígonos de terra fecha agora um anel que não repete o primeiro vértice, que antes lia sem a sua última aresta. A documentação indica os limiares de baixa exatidão de NACp e NIC como o limite que cada código representa (NACp 6 é um limite de EPU de 556 m, NIC 5 um limite de contenção de 1 NM).

Acrescentado (validação dos formatos de telemetria e dos pacotes de evidências)#

  • Verificações externas da criptografia dos pacotes de evidências, do verificador de pacotes e dos formatos de transmissão da telemetria. Os vetores de teste Ed25519 da secção 7,1 da RFC 8032 (1, 2, 3 e 1024) e os exemplos SHA-256 da FIPS 180-4 passam pelas próprias funções de assinatura, verificação e hash do pacote, com igualdade exata. Um verificador escrito em Python apenas a partir da secção normativa de docs/EVIDENCE-PACKS.md (hashlib e cryptography) concorda com o verificador em Rust em 71 pacotes íntegros e adulterados: veredicto, conjunto de falhas, veredicto da assinatura e ambas as cabeças da cadeia. A nossa exposição Prometheus é lida pelo analisador do cliente oficial em Python e o nosso JSON OTLP pela mensagem oficial opentelemetry-proto, de forma estrita, e ambos concordam com o estado a partir do qual foram feitos. CEF e LEEF não têm validador aberto independente e continuam modelados. docs/EVIDENCE-PACKS.md ganhou o formato normativo do pacote e o procedimento de verificação a partir dos quais o verificador clean-room foi escrito; VerifyReport ganhou signature_valid. Referências independentes e ficheiros de teste: scripts/gen_ed25519_rfc8032_ref.py, scripts/gen_evidence_pack_ref.py com scripts/evidence_verify_cleanroom.py, scripts/gen_telemetry_formats_ref.py; testes evidence_crypto_reference, evidence_pack_reference e telemetry_formats_reference. A CI não precisa de Python.

Acrescentado (validação dos eventos CEF)#

  • Os eventos CEF da telemetria são lidos de volta corretamente por dois analisadores independentes de código aberto. pycef 1,11 e o codec CEF do Logstash (logstash-codec-cef 6.2.7 no Logstash 8.15.3) analisam 157 linhas CEF (cada mudança de banda e cada época do fluxo de telemetria submetido, mais texto adversarial com =, barras invertidas, barras verticais, quebras de linha, tabulações e texto multibyte) e recuperam cada campo do cabeçalho, a gravidade, o conjunto exato de chaves da extensão e cada valor exatamente. O codec do Logstash lê também quatro linhas cujo texto de cabeçalho exige escape, o que pycef não consegue. O limiar foi registado antes de qualquer dos analisadores ser executado (tests/cef_reference.rs); ficheiros de teste em tests/fixtures/cef/, scripts de referência independente scripts/gen_cef_ref.py e scripts/gen_cef_logstash_ref.py; a CI não precisa de Python nem de Logstash. O LEEF não tem analisador aberto mantido e continua modelado. Os eventos CEF passam a trazer a pontuação de confiança e o desvio de época nos campos personalizados de vírgula flutuante do dicionário CEF (cfp1, cfp2) em vez dos campos inteiros cn1 e cn2, que não serviam para nenhum dos valores; o CEF é novo nesta versão, pelo que nada do que foi distribuído muda.

Alterado#

  • MCP: assess_receiver_log aceita o registo como text ou base64; a entrada da ferramenta é limitada a 4 MiB.
  • O gráfico de interferência também retira as suas cores da paleta. src/jamming.rs era o único módulo que a revisão da paleta Observatory deixou com as suas próprias cores enquanto o trabalho do Q de interferidores era integrado; o seu *.chart.svg (os cenários jamming, maritime-strait-jamming e outros do tipo jamming) lê agora src/palette.rs, e a lista de exceções em tests/palette_sync.rs está vazia. Apenas cores e tipo de letra: os gráficos jamming-demo e maritime-strait-jamming são iguais às suas representações gravadas anteriormente depois de normalizadas a cor, font-family e o rodapé de versão. Nenhum valor representado mudou. As cópias gravadas do Studio em web/studio/recorded/ foram regravadas nas retransposições de 0.33.0 e 0.34.0 (apenas o carimbo de versão): ainda trazem a cor antiga do gráfico de interferência, e adotam a cor da paleta na próxima retransposição.

Corrigido#

  • O limite de 3 sigma do conjunto de relógios cobre agora o piso de cintilação, e a verificação de saúde do filtro vê-o. Com um flicker_floor, o relógio verdadeiro trazia FM de cintilação mas o filtro de dois estados que fornece o limite de integridade não, pelo que a cobertura de 3 sigma do cenário clock-ensemble fornecido era 0,41 (clássico) e 0,33 (quântico), e a verificação NIS/NEES, que tirava a sua verdade do modelo do próprio filtro, comunicava valores idênticos com e sem o piso. O limite é agora a variância de dois estados mais a variância exata da fase de cintilação acumulada desde a última sincronização, calculada a partir do mesmo banco que o relógio verdadeiro usa; a verificação NIS/NEES tira a sua verdade do modelo alargado com esse banco e executa o filtro alargado correspondente (e o filtro de dois estados face à verdade de cintilação comunica consistent = false). Alteração de saída, apenas para relógios com um flicker_floor não nulo: integrity em clock-ensemble passa de 0,40866 / 0,33026 para 0,99970 / 1,0 (clássico / quântico) e o NIS/NEES de filter_health passa a incluir a cintilação; o erro de temporização, holdover_s e timing_p95_ns não mudam, e os cenários sem piso são idênticos byte a byte. scenarios/orbit-gnss-challenged.toml (tipo orbit, semente 7, pisos 1e-16 / 2e-11) também muda: fom.integrity clássico de 0,7734 para 1,0 e quântico de 0,9796 para 1,0, e o NIS/NEES de filter_health e as suas bandas mudam. O seu filter_health.consistent quântico passa de true para false: um evento de amostragem do conjunto de cintilação de 16 sementes por 60 passos (NIS 0,8815 face a uma banda de [0,9125, 1,0914]), e não um defeito. A banda é de 95 %, pelo que cerca de 5 % das sementes assinalam um filtro correspondente por construção (40 sementes novas deste cenário: quântico 1 e clássico 2 assinalados); a 64 por 200, a mesma semente fica dentro da banda para ambos os relógios (NIS 0,990 e 1,001). Seguimento conhecido: o tipo fusion tem a mesma lacuna (integridade clássica 0,80 com um piso); o tipo hybrid mantém-se acima de 0,99.

[0.34.1] - 2026-10-10#

Segurança#

  • Entrada do servidor MCP reforçada. As ferramentas de cenário do servidor MCP aceitam agora apenas conteúdo em linha e recusam campos de fonte de ficheiro; o tamanho da entrada é limitado. Aviso consultivo: GHSA-8wpf-hqg5-6xjr.

[0.34.0] - 2026-10-09#

Reprodução em laboratório: um motor de seguimento, monitores de deteção e um executor de campanhas para gravações IQ de GNSS, com os desenhos de laço, estimadores de C/N0 e pontuações que os acompanham. Classe de evidência: tudo o que se segue é MODELLED ou verificado quanto à consistência interna face a formas fechadas e a simulação com sementes; nada disto acrescenta uma linha VALIDATED, e o registo de verificação não muda (251 linhas: 124 validadas, 123 modeladas, 4 de parceiro). É uma camada de análise de software: nada aqui sintetiza uma forma de onda de interferidor ou de spoofer, e nada transmite.

Adicionado#

  • Reprodução em laboratório: condições de teste, executor de campanhas e pontuação (0.34.0). kshana iq campaign <campaign.toml> reproduz gravações × cadeias de front end × desenhos de laço (kshana.loop-design/1) e pontua cada célula face a um ficheiro de condições de teste por gravação (kshana.test-conditions/1, TOML ou JSON). Esse ficheiro declara o que um laboratório sabe sobre a gravação: os satélites esperados e, para cada evento, a sua etiqueta de tipo, início e fim, satélites afetados e o perfil declarado de J/S ou de potência do interferidor. São apenas metadados. As pontuações por satélite, para a execução completa e por evento, são:

    • disponibilidade, tempo até à perda de bloqueio e o J/S declarado na perda;
    • tempo de reaquisição, a partir do fim do evento e a partir da perda;
    • degradação medida do C/N0 por intervalo de J/S declarado;
    • episódios de falso bloqueio por hora bloqueada (o indicador do seguidor, ou o Doppler face a um ficheiro auxiliar de verdade);
    • jitter do discriminador PLL e DLL.

    Junto a cada curva de degradação medida, é desenhada uma referência analítica de separação espetral (jamming::effective_cn0_dbhz com o Q do tipo) e rotulada MODELLED onde quer que apareça.

    As células correm em paralelo através da máquina de estados de bloqueio da sessão de seguimento, e cada uma é escrita atomicamente sob uma chave de hash de conteúdo. A chave abrange o SHA-256 da gravação, os hashes da condição, do front end, do desenho, da execução e da pontuação, o data_class exigido (synthetic | client-confidential) e a versão do motor. Com run.epochs definido, o fluxo kshana.track-epoch/1 e os eventos de bloqueio de cada célula são também mantidos, com o nome da chave da célula e incluídos por hash na célula. cell_key e report::digest são públicos, para que um consumidor possa voltar a derivar cada chave e o resumo. Uma nova execução salta, por isso, as células concluídas, e as saídas nunca dependem do número de trabalhadores. A execução escreve scorecard.csv/.json, um report.html autónomo e um DIGEST. Os limiares de sucesso/falha ([scoring.bars], substituíveis por gravação) são aplicados quando o relatório é construído.

    • [scoring] cn0_estimator = "m2m4" | "nwpr" (por predefinição "m2m4", parte do hash de pontuação) escolhe o C/N0 por detrás do C/N0 comunicado e da curva de degradação. Ambas as estimativas são sempre pontuadas e comunicadas (medianas da execução completa e da linha de base, e por intervalo de J/S), e a célula e a folha de pontuação registam o estimador. O NWPR lê baixo cerca de 8 dB × Bn·T sob o próprio jitter do laço; o M2M4 não.

    Também novo:

    • kshana iq campaign report <dir> reconstrói as folhas de pontuação, o relatório e o resumo a partir das células;
    • kshana iq conditions <file> verifica um ficheiro de condições de teste face ao seu esquema;
    • events_from_sigmf = true importa como eventos as anotações kshana:test_event de uma gravação SigMF;
    • O Python ganha iq_test_conditions, iq_campaign e iq_campaign_report;
    • kshana-mcp ganha iq_campaign, que é incremental e retomável dentro do orçamento de amostras por chamada, com todos os ficheiros confinados ao diretório de trabalho, e iq_campaign_status.

    Testes: tests/iq_campaign.rs executa uma campanha sintética de 3 gravações × 2 front ends × 2 desenhos. As suas cenas trazem perfis de C/N0 declarados, e cobre:

    • cada métrica verificada face à verdade injetada;
    • retoma após uma execução parcial com um só trabalhador e uma célula corrompida, idêntica byte a byte a uma execução ininterrupta com quatro trabalhadores;
    • ficheiros de épocas por célula;
    • uma regressão de reaquisição de três satélites durante 20 s: com reacquire ligado, todos os canais voltam em 2 s após uma lacuna de 2 s; o resultado com reacquire desligado está fixado;
    • limiares reavaliados sem voltar a executar;
    • a CLI;
    • verificações de débito e de memória em modo de lançamento, ignoradas por predefinição, incluindo uma gravação de 4 GB (5,45× o tempo real, memória de pico 2 MB acima do RSS inicial; medições numa só máquina, não limiares).

    Apenas software: nada transmite, e nenhuma forma de onda de interferência ou de spoofing é sintetizada. Notas de projeto e de construção: docs/design/LAB-CAMPAIGN.md.

  • Motor de seguimento para reprodução em laboratório (0.34.0: B3.1, B3.2, B3.3, B6.1).

    • Ficheiros de desenho de laço: TOML kshana.loop-design/1 (docs/design/LOOP-DESIGN-TOML.md; analisador iq::track::design). Um ou mais desenhos nomeados definem cada campo do laço:

      • tipo de portadora (PLL, FLL ou PLL assistido por FLL), ordens e larguras de banda;
      • discriminadores PLL/FLL/DLL e auxílio da portadora;
      • espaçamento e integração;
      • limiares de bloqueio e janelas de C/N0, e sincronização de bits;
      • a máquina de estados de bloqueio;
      • a aquisição de passagem ("auto" ou explícita).

      Os desenhos podem usar extends entre si. As chaves desconhecidas são recusadas. Cada desenho resolvido tem um hash SHA-256 sobre uma forma JSON canónica (chaves ordenadas a todos os níveis, formatação numérica fixa), pelo que o hash não depende da ordem dos campos; todas as saídas o registam. Superfícies:

      • kshana iq track --design <file> [--design-name], em que as opções explícitas substituem o desenho e ficam registadas;
      • kshana iq sweep --design <file>, que executa todos os desenhos do ficheiro;
      • Python iq_track(design=, design_name=, reacquire=), iq_loop_designs;
      • MCP iq_track design/design_name.
    • C/N0 M2M4 (EpochOutput.cn0_m2m4_dbhz, a coluna cn0_m2m4_dbhz da época de seguimento depois de cn0_beaulieu_dbhz; dicionários de época em Python). A estimativa de segundo e quarto momentos sobre as mesmas janelas que o NWPR, apenas a partir da potência imediata: o NWPR lê baixo sob o próprio jitter da portadora do laço (cerca de 8 dB × Bn_PLL·T) e o M2M4 não. Em GPS L2C CM (20 ms, nominal 40 dB-Hz, PLL de 1 a 10 Hz) lê 39,93 dB-Hz em todas as larguras de banda, enquanto o NWPR desce de 39,55 para 38,22; em L1 C/A a 45 dB-Hz lê 45,34. O NWPR e todas as outras saídas não mudam (uma fixação bit a bit). O registo binário continua com 184 bytes (o valor ocupa o float reservado e o bit de indicador 6).

    • Derivações extra de correlador (multicorrelador / SQM). [design.integration] extra_taps_chips = [..] (desvios em chips a partir do imediato, positivos adiantados; no máximo 16, cada um dentro de ±2) correlaciona réplicas extra a par de E/P/L e devolve-as como EpochOutput.extra ((offset, value) pela ordem do desenho). Os laços nunca as usam. A chave é omitida do JSON canónico quando vazia, pelo que o hash do desenho por predefinição e todas as saídas sem derivações não mudam (kshana.track-epoch/1 mantém-se; o CSV/JSONL/binário sem derivações é idêntico bit a bit). Com derivações: colunas CSV/JSONL e um registo binário de 184 + 16 × taps bytes cujo cabeçalho transporta extra_taps_chips, para que um leitor antigo recuse o ficheiro em vez de o interpretar mal. --extra-taps (CLI), extra_taps (Python) e extra_taps_chips (MCP iq_track). Os desenhos de uma execução têm de concordar quanto às derivações.

    • Canais paralelos (iq track / iq sweep --threads <N|auto>; Rust TrackSession::with_threads). Os canais de cada bloco correm em até N threads (std::thread::scope; wasm32 continua em série). A correlação e a máquina de estados de bloqueio de um canal só tocam nesse canal; as suas épocas e eventos são colocados em memória intermédia e escritos nos destinos pela ordem dos canais, pelo que a saída (CSV, JSONL, binário, eventos, resumo) é idêntica byte a byte à execução em série para qualquer N. O valor por predefinição continua a ser 1 thread. Medido numa gravação de 12 canais, 4 s, 4,092 MHz em 4 núcleos: 19,5 s em série, 11,5 s com 2 threads, 6,3 s com 4 (3,1×; a aquisição inicial é em série).

    • Exportação da superfície de aquisição (kshana.acq-surface/1; iq::acq_surface, docs/design/ACQ-SURFACE.md). iq acquire --surface <path> (um PRN; CSV, JSON ou binário), iq_acq_surface em Python e iq_acquire surface_out em MCP escrevem toda a superfície de potência de correlação Doppler × fase do código que a pesquisa calcula (as suas células são as de acquire, bit a bit) com o pico e dois refinamentos de Doppler fino: uma estimativa parabólica e uma pesquisa fina de 1/16 de intervalo (≈5 Hz a 4 ms coerentes, face a intervalos de 167 Hz). O próprio acquire e todos os valores por predefinição não mudam.

    • Saída de épocas em fluxo (kshana.track-epoch/1; iq::track::sink). Cada atualização do laço traz:

      • os correladores adiantado/imediato/atrasado;
      • as três saídas dos discriminadores;
      • os estados dos NCO de PLL/FLL/DLL e a fase da portadora;
      • o PLI e os indicadores de bloqueio;
      • ambas as estimativas de C/N0 e os bits;
      • o estado de bloqueio.

      É escrita à medida que acontece, como CSV, JSON Lines ou uma forma binária com versão, com leitores em Rust (BinaryEpochReader) e em Python (iq_read_epochs).

      • iq track ganha --epochs, --events e --summary (kshana.track-summary/1), e iq sweep ganha --epochs e --events. O MCP iq_track ganha epochs_out/events_out e constrói a sua resposta a partir do resumo de memória limitada.
      • A memória dinâmica de uma execução já não cresce com o comprimento da gravação: tests/iq_track_memory.rs mede-a com um alocador contador (6× o comprimento, o mesmo pico com uma diferença de 64 KiB), com um controlo que mostra que o caminho em memória cresce.
      • A saída em fluxo é idêntica bit a bit à reprodução em memória.
    • Máquina de estados de bloqueio (iq::track::lock, TrackSession): captura → bloqueado → perdido → reaquisição → captura, ou retirado quando uma perda ultrapassa reacq_window_s (por predefinição 30 s). As pesquisas falhadas são repetidas a cada reacq_interval_s (0,1 s), a intervalos regulares, pelo que o calendário de repetições acrescenta no máximo 0,1 s a um tempo de reaquisição medido. Um recuo opcional (reacq_max_interval_s acima de reacq_interval_s) está desativado por predefinição, e max_reacq_attempts é um limite opcional (0, nenhum, por predefinição). Uma interrupção de 2 s em três PRN a 4,092 MS/s termina agora com todos os canais reaquiridos e bloqueados. Com um orçamento de 3 tentativas, todos os canais foram retirados a menos de 0,2 s da perda.

      • Os limiares (loss_dwell_s, pull_in_max_s, a janela Doppler de reaquisição) provêm do desenho. Cada transição é um evento com o seu motivo.
      • A verificação de falso bloqueio compara o Doppler seguido com o seu alias de ±1/(2T) do FLL/PLL. Apanha o falso bloqueio que o PR #38 mediu (−2400 Hz seguido a 500 Hz de distância). Com a reaquisição ativada, o canal termina bloqueado no Doppler injetado.
      • Uma lacuna de sinal de 0,8 s é declarada como perdida e reaquirida a menos de 0,3 s do regresso do sinal.
      • --summary final_state (e a coluna da tabela) é o estado depois da última transição, pelo que um canal retirado depois da sua última atualização do laço indica RETIRED.
      • Assistência do FLL apenas durante a captura ([design.carrier] fll_assist = "pull-in", a predefinição; "always" mantém o comportamento anterior bit a bit). O FLL passa o controlo ao PLL quando o PLI suavizado se mantém igual ou acima de fll_off_pli (0,8) durante fll_gate_dwell_s (0,1 s), e regressa quando desce abaixo de fll_on_pli (0,6). Se ficasse ligado, o caminho do FLL de 10 Hz quebrava o bloqueio de fase abaixo de cerca de 38 dB-Hz em sinais limpos: a 35 dB-Hz a fração de bloqueio de fase era de 10–16 %, com um erro de fase verdadeiro de 38–41°. Com a barreira, a predefinição mantém 100 % a 35 dB-Hz com 4,5°, o mesmo que um PLL sozinho. A captura a partir de um erro de passagem de 100 Hz não muda. Evidência com limiares fixados antecipadamente: docs/design/evidence/carrier-lock/. Os laços por predefinição deixam, por isso, de ser idênticos bit a bit às execuções anteriores do desenho por predefinição. Use fll_assist = "always" para as reproduzir. Limite conhecido: a 35 dB-Hz a passagem de controlo ocorre 1,9–2,6 s depois do início do seguimento, e a 33 dB-Hz o FLL de 10 Hz mantém o PLI abaixo do limiar de passagem de controlo, pelo que a captura nunca termina.
      • Novas chaves de desenho de laço e API, listadas:
        • [design.carrier]: fll_assist, fll_off_pli, fll_on_pli, fll_gate_dwell_s;
        • [design.lock]: reacq_window_s, reacq_interval_s, reacq_max_interval_s, com max_reacq_attempts alterado de um valor por predefinição de 3 para um limite opcional (por predefinição 0);
        • Rust: LoopConfig.fll_assist (FllAssist, FllGate), LoopCore::set_fll_enabled, EpochOutput.fll_active, ChannelSummary.final_state.
      • O hash do desenho incide sobre uma forma JSON canónica, e o hash do desenho incorporado por predefinição é 33261cd171a53803a6c262686e878e01f37d902a93d5918c20a44297b8ef8e80 (fixado por um teste).
      • Notas de compatibilidade das saídas:
        • a tabela de iq track tem uma coluna final_state no fim;
        • o CSV de iq sweep tem uma coluna design_hash no fim, e o seu JSON tem design_hash e warnings;
        • o mean_cn0_dbhz da varredura é agora a média de todas as atualizações que têm uma estimativa NWPR (resumo de memória limitada), e já não da segunda metade da execução.
      • A reaquisição está desativada no desenho incorporado por predefinição, onde a máquina de estados apenas observa e os laços correm bit a bit como correm sem ela. (Os próprios laços por predefinição mudaram, no entanto: ver a assistência do FLL acima.) Ative-a por desenho ([design.lock] reacquire = true), com --reacquire ou com reacquire=True.
      • Um aviso commensurate_sampling: quando fs está a menos de 1e-6 de um múltiplo de metade da taxa de chip (iq::track::commensurate_samples_per_chip), iq track/iq sweep (saída, --summary, JSON de varredura), a resposta de iq_track do MCP e o resultado de iq_track em Python avisam que o jitter e o enviesamento do laço de código não são representativos. A causa de fundo está documentada com limiares fixados antecipadamente em docs/design/evidence/dll-jitter/. Com exatamente 2 amostras por chip e espaçamento de 0.5 chip, a curva S do DLL é um único degrau e o laço oscila: ≈ 0,09 chip de erro de código RMS (≈ 26 m) a 45 dB-Hz, face a ≈ 0,004 chip a uma taxa incomensurável. O C/N0 NWPR cerca de 2 dB baixo a essa taxa tem a mesma causa. Com exatamente 0 Hz de Doppler de código e 4 amostras por chip, o código nunca atravessa a zona morta de ±0.21 chip, pelo que um enviesamento de fase de código de até cerca de 0,2 chip pode persistir sem aparecer no jitter (medido: um espaçamento de 0.5 chip dá 2,0× o erro de código do controlo, com uma média de +0,011 chip; um espaçamento de 0.25 chip dá +0,125 chip); o aviso cobre a taxa.
      • Limite conhecido: o desenho por predefinição não passa o controlo de FLL para PLL abaixo de cerca de 35 dB-Hz (um piso de captura de ~35 dB-Hz; ver a assistência do FLL acima e docs/design/evidence/carrier-lock/).
      • Uma pesquisa de falso bloqueio ou de reaquisição que não pode correr (uma taxa sem um número inteiro de amostras por período de código) já não interrompe o seguimento.
      • Testes: tests/iq_track_engine.rs, tests/iq_cli.rs, iq::track::design::tests, tests/python e o ciclo completo de IQ do MCP.
  • Perfis de C/N0 em cenas sintéticas (0.34.0). iq::channel::cn0_profile programa um C/N0 variável no tempo por satélite nas próprias cenas do Kshana, como desvios em dB relativos ao C/N0 da cena. Formas: degrau, rampa, linear por troços e desvanecimentos de Rice tipo cintilação, com sementes, com um S4 declarado e um tempo de decorrelação. São aplicadas através do gancho de canal da cena já existente (Cn0ProfileChannel, compondo com os efeitos de ionosfera, troposfera, cintilação e multipercurso), sem alteração ao núcleo da cena. O cn0_dbhz do ficheiro auxiliar de verdade acompanha o perfil.

    • Superfícies: kshana iq scene … --cn0-profile <toml> e kshana.iq_scene(…, cn0_profile="<toml>").
    • Para que serve: os laços, os monitores e a pontuação de campanhas podem ser testados sob esforço face a uma verdade conhecida. Altera apenas a intensidade dos sinais legítimos.
    • Verificações (tests/iq_cn0_profile.rs). Limiares: intensidade média do desvanecimento a menos de 5 % de 1, S4 a menos de 8 % do alvo (com S4 = 0,3, 0,7 e 1), correlação de intensidade acima de 0,9 a 0,05 τ e abaixo de 0,05 a 5 τ; verdade exatamente o C/N0 declarado mais o perfil; uma queda do C/N0 NWPR seguido a menos de 0,7 dB de um degrau de 6 dB. Medido: S4 a menos de 1,3 % do alvo, e uma queda seguida de 6,26 dB.
  • Monitores de deteção no caminho IQ (0.34.0 "Reprodução em laboratório"). Novo módulo iq::monitor, comando kshana iq monitor e ligação kshana.iq_monitor(path, ...). Observam uma gravação e comunicam séries temporais e eventos assinalados (instantes de início, de alarme e de fim, pico, limiar). Apenas detetam e medem; nada aqui gera um sinal.

    • Potência total / AGC: potência por bloco e o ganho que um AGC ideal aplicaria; assinala subidas e quedas.
    • Espetro pré-correlação: PSD de Welch por bloco face a uma linha de base aprendida. O limiar de excesso provém de um alvo de falso alarme. Também curtose complexa e um detetor de impulsos. O detetor de impulsos conta as amostras acima de um limiar em cada bloco e levanta um evento quando a cauda superior binomial exata dessa contagem é inferior a pulse_pfa (por predefinição 1e-4 por bloco), e não quando uma pontuação z ultrapassa um limite: com as pequenas contagens esperadas de blocos curtos, uma única amostra já são vários sigmas.
    • C/N0 por canal: dois detetores de mudança CUSUM unilaterais (queda e subida), alimentados com estimativas independentes (o passo é definido a partir da janela de C/N0 do laço).
    • SQM a partir dos correladores: delta (I_E − I_L)/I_P e razão (I_E + I_L)/(2 I_P), mais testes de assimetria a partir de correladores extra quando um canal os fornece.
    • Série de indicadores de bloqueio: PLI e um indicador de bloqueio de frequência a partir de imediatos sucessivos, como sinais em bruto. As decisões de bloqueio e de perda de bloqueio ficam com a máquina de estados de bloqueio do motor de seguimento.

    Uma única passagem em fluxo (iq::monitor::run::run_monitors) executa tudo, com um ficheiro de definições TOML/JSON (MonitorConfig); o executor de campanhas usa o mesmo ponto de entrada. Tudo MODELLED. Cada estatística é verificada face à sua forma fechada por simulação com sementes (tests/iq_monitor.rs):

    • excedências da potência de bloco face à cauda Gama;
    • média da curtose 2 e dispersão 2/√N;
    • fração de impulsos e^{−t};
    • comprimentos de corrida do CUSUM face à aproximação de Siegmund (medidos 330 e 8,46 amostras face a 338 e 8,34);
    • o indicador de bloqueio de fase face à média de fase de Rice;
    • num sinal C/A seguido, as dispersões do delta e da razão do SQM ficam a cerca de 6 % das formas fechadas de primeira ordem (medido 5,97 %; limiar do teste 12 %).

    A fórmula de falso alarme do excesso espetral é uma aproximação; a taxa medida foi 1,3× a fórmula. De ponta a ponta, os monitores assinalam:

    • um degrau de C/N0 de 6 dB (instante da mudança dentro de uma estimativa);
    • um caminho refletido que surge a meio da gravação (teste da razão);
    • uma interrupção de sinal (o PLI cai de 0,999 para −0,3 e o FLI de 0,93 para 0,03 durante ela);
    • um tom de banda estreita e amostras esparsas de grande amplitude (testes espetral, de impulsos e de curtose). São dados de entrada genéricos de teste de DSP, não modelos de interferência.

Alterado#

  • iq track/iq sweep fazem o fluxo através da nova sessão (ver Acrescentado).
    • --csv mantém as suas colunas de 0,32 mas passa a ser feito em fluxo, pelo que as linhas de vários canais se intercalam por ordem temporal em vez de agrupadas por canal. --json mantém a sua forma de 0,32 e continua a guardar todas as épocas em memória: use --epochs para gravações longas.
    • iq sweep mede o jitter sobre as atualizações da segunda metade da duração da execução (antes, a segunda metade do número de atualizações), e o seu CSV/JSON ganha uma coluna design_hash.
    • A tabela de seguimento ganha uma coluna final_state.
    • O texto de utilização já não afirma que iq track aceita as opções do front end; só iq acquire as aplica.
    • Em Python, acq_noncoherent e doppler_max de iq_track passam a ter por predefinição None (os valores do desenho, 1 e 5000 Hz no desenho incorporado). As suas épocas ganham os correladores adiantado/atrasado, carrier_phase_cycles, bit_edge, bit e state, e o resultado ganha design e events.

Corrigido#

  • O passo de aquisição por predefinição já não entrega ao seguimento do Galileo E1 um resíduo que o FLL não consegue captar. O passo 2 / (3 · N · T_code) deixa até 1 / (3 · N · T_code) de erro Doppler na passagem de controlo, mas o FLL de dois quadrantes por predefinição só capta 1 / (4 T_track). Para todos os códigos de 4 ms ou mais (N = 1), incluindo o Galileo E1-B e E1-C, o resíduo (83,3 Hz a 4 ms) ficava fora da captura de 62,5 Hz e o seguimento tinha falso bloqueio a +125 Hz, com um indicador de bloqueio de fase de 0,97 que o escondia. O passo por predefinição fica agora também limitado a 0.2 / T_track (kshana::iq::acq::default_step_hz), 0,8 da captura, pelo que a passagem de controlo se mantém dentro dela mesmo quando o intervalo vizinho vence. (0,4 foi tentado primeiro: teve falso bloqueio em 1 execução em 42 no E1-B, e uma pesquisa coerente de 1 ms de GPS L1 C/A escolheu um intervalo a 350 Hz e bloqueou a +500 Hz; 0,25 e 0,2 não tiveram nenhum nas mesmas execuções.) Custo: o Galileo E1-B/E1-C passa de intervalos de 166,7 Hz para 50 Hz, 201 intervalos em ±5 kHz em vez de 61; os códigos de 1 ms (166,7 Hz, N = 4) não mudam. "auto" num desenho de laço significa isto; um doppler_step_hz ou --doppler-step explícito é usado como escrito, e iq acquire (sem passagem de controlo para o seguimento) mantém o passo de manual. O cabeçalho da época e --summary registam agora o passo resolvido e as larguras de banda do laço de cada canal (resolved). O hash do desenho por predefinição não muda. Alteração de saída: as deteções em códigos de 4 ms e mais longos podem cair noutros intervalos de Doppler.

  • O GPS L2C CM (atualização do laço de 20 ms) mantém o bloqueio com o desenho por predefinição. O PLL de 15 Hz e o FLL de 10 Hz por predefinição têm Bn · T de 0,3 e 0,2 com T = 20 ms, e o laço perdia o bloqueio mesmo a partir de um arranque perfeito (PLI −0,08, M2M4 15,8 dB-Hz). A nova chave de desenho carrier.bn_t_max (por predefinição 0,1) limita as larguras de banda de ruído do PLL e do FLL a bn_t_max / T quando o tempo de atualização do laço é superior a 4 ms (Design::loop_config_for): 5 Hz e 5 Hz a 20 ms, 10 Hz e 10 Hz aos 10 ms do BeiDou B1C; os códigos de 1 ms e 4 ms mantêm 15 e 10 Hz. Aplica-se também a larguras de banda explícitas; bn_t_max = 0 desativa-a. A chave é omitida da forma canónica no seu valor por predefinição, pelo que o hash por predefinição não muda; um desenho que defina qualquer outro valor tem um hash diferente. A 45 dB-Hz, o L2C CM dá agora PLI 0,996, erro Doppler de 0,00 Hz e M2M4 42,71 dB-Hz. Ponto em aberto conhecido: o C/N0 NWPR lê 1,76 dB abaixo aí (e 2,45 dB abaixo no B1C a 10 ms), pelo que o T5 da matriz para o L2C continua a ser uma constatação ignorada.

  • docs/assets/clock-ensemble-band.svg regenerado: a figura submetida estava desatualizada face ao seu próprio cenário (uma alteração de dados, não um redesenho). O gráfico foi desenhado em 2026-06-02 a partir de scenarios/clock-ensemble.toml; dois dias depois, 67fed19e definiu os pisos de FM de cintilação nesse cenário (quântico flicker_floor = 1e-16, CSAC flicker_floor = 2e-11) e a figura nunca foi redesenhada. Mostrava a execução anterior aos pisos: eixo y de 0 a 47 ns, p95 de interrupção por execução do CSAC de 10,5 a 47,6 ns (média 25,2 ns), holdover clássico de 4050 s em média. O cenário tal como é fornecido (e como o tutorial e o resumo da CLI já indicam) dá um eixo y de 0 a 407 ns, p95 por execução do CSAC de 40,8 a 374,0 ns (média 167,0 ns), holdover clássico de 844 s [220 a 2130 s]; a linha de especificação de 20 ns fica nos mesmos 20 ns num eixo cerca de nove vezes mais alto. O motor não mudou: o motor atual sobre o ficheiro de cenário de junho reproduz exatamente o eixo da figura antiga. A figura não é referenciada a partir do README nem da documentação.

Limitações conhecidas#

  • O C/N0 NWPR lê baixo com C/N0·T por imediato elevado, e o BOC(1 1) a 5 MS/s perde cerca de 1 dB. O NWPR não tem enviesamento em imediatos ideais, mas o próprio jitter do PLL do laço custa cerca de 8 dB × Bn·T ajustados (uma cena, quatro pontos: −0.24/−0.44/−0.77/−1,58 dB a 1/2.5/5/10 Hz e 20 ms; cerca de −1 dB com o bn_t_max = 0.1 por predefinição); o M2M4 é insensível. Os dados do BeiDou B1C a 5 MS/s perdem também cerca de 1 dB de potência do imediato por limitação de banda (use 10 MS/s ou mais). Nenhum dos casos é um defeito do estimador; as linhas T5 da matriz de sinais para o GPS L2C e o BeiDou B1C continuam a ser constatações ignoradas, com estas causas.

[0.33.1] - 2026-10-08#

Segurança#

  • Texto de gráficos e adoção de gráficos pelo Studio reforçados. O texto que um cenário leva para um gráfico gerado é agora escapado de forma consistente por uma rotina partilhada, e o Studio adota apenas marcação de desenho de um gráfico. Os parâmetros de endereço do Studio, as pesquisas indexadas por tipo e as obtenções de cenários ficam restritos a valores conhecidos. Os gráficos incluídos, os resultados gravados e os números publicados não mudam. Recomenda-se a atualização a quem abre ficheiros de cenário de origens não fiáveis no Studio ou incorpora gráficos gerados em páginas web. Aviso consultivo: GHSA-h25h-cg9f-v2cg.

[0.33.0] - 2026-10-08#

Documentação#

  • O âmbito de interferência e de spoofing da camada IQ, indicado com rigor. As entradas de 0.31.0 e 0.32.0 abaixo dizem que a camada IQ acrescenta "sem síntese de formas de onda de interferência ou de spoofing". Isso é verdade para a própria camada IQ (iq::scene gera apenas sinais GNSS legítimos), mas lia-se como uma afirmação sobre todo o motor, e não é uma: desde 0.29.0 a secção [iq] do tipo spectrum escreve um instantâneo SigMF do seu modelo analítico com os interferidores configurados (interferidores de tipo ruído intervalo a intervalo, tons e chirps como formas de onda), e spoof_capture soma em memória uma réplica de sinal autêntico e uma de spoofer para testar a captura do laço (o compósito nunca é escrito). O motor também tem um recetor GNSS por software desde 0.20.0 (sdr: aquisição e seguimento; desde 0.31.0 também iq::acq e iq::track). Nada no Kshana transmite nem comanda hardware de rádio. A linha de estado do README, docs/POSITIONING.md, docs/SPECTRUM.md e as notas de projeto do IQ di-lo agora; as entradas já publicadas ficam como foram publicadas. Nenhum comportamento muda.
  • Limitação conhecida: amostragem comensurável. A uma taxa de amostragem que é um múltiplo inteiro ou semi-inteiro da taxa de chip, as amostras ficam nas mesmas fases de chip em todos os chips, e o discriminador de código passa a ser uma escada. Num sinal sintético GPS L1 C/A a 45 dB-Hz com espaçamento de 0.5 chip, 2,046 MHz (2 amostras/chip) dá ≈ 0,09 chip (≈ 26 m) de erro de código RMS e um enviesamento de −0,09 chip, face a ≈ 0,003 chip a uma taxa incomensurável. O C/N0 NWPR lê ≈ 2,4 dB abaixo aí. A 4,092 MHz depende do espaçamento e do Doppler de código. Com 0,5 chip é inofensivo a 1500 Hz de Doppler mas 2× com um enviesamento de 0,011 chip a 0 Hz, e com 0,25 ou 0,1 chip é 8–10× o erro de código. O seguimento da portadora não é afetado. docs/design/iq-notes/receiver.md tem as medições.

Adicionado#

  • Camada IQ de GNSS no servidor MCP (Fase B.1). kshana-mcp ganha seis ferramentas que comandam a camada kshana iq a partir de um agente: iq_signals (os nomes de sinais aceites e a configuração IQ), iq_info (descrever uma gravação), iq_scene (gerar uma cena de perfil declarado ou de efemérides difundidas, com o canal opcional ao nível do sinal), iq_acquire (aquisição por FFT, opcionalmente atrás de estágios de front end), iq_track (adquirir e depois o banco DLL/PLL/FLL) e iq_frontend (passa-banda, rejeita-banda, supressão, excisão, AGC, quantificador). As amostras IQ nunca atravessam o protocolo: cada ferramenta recebe caminhos de ficheiros dentro de um diretório de trabalho definido por KSHANA_MCP_IQ_DIR (se não estiver definido, as ferramentas de ficheiros IQ ficam desativadas e todas as outras ferramentas não são afetadas), recusa caminhos que resolvam para fora dele e saídas que já existam, a menos que overwrite esteja definido, impõe um orçamento de amostras por chamada (KSHANA_MCP_IQ_MAX_SAMPLES, por predefinição 50 000 000) antes de qualquer trabalho, recusa argumentos desconhecidos e responde com um resumo JSON compacto (deteções, C/N0, estado de bloqueio e cada ficheiro escrito com o seu número de bytes). A saída por época vai apenas para ficheiros que o chamador nomeia. As ferramentas executam o mesmo caminho de código que a CLI através de uma nova interface pública, kshana::iq::cli::execute, que devolve a mensagem da CLI em vez de a imprimir (o stdout é o canal JSON-RPC do MCP); iq::cli::build_code e iq::cli::signal_names passam também a ser públicos. Apenas software e aditivo: a camada IQ não acrescenta síntese de interferência nem de spoofer, nada é alguma vez transmitido, e não há novas dependências. server.json declara as duas variáveis de ambiente. Os testes de ciclo completo em mcp/kshana-mcp/tests/iq_round_trip.rs geram uma cena curta de dois satélites e verificam a aquisição face ao próprio ficheiro auxiliar de verdade da cena, o bloqueio do seguimento e o C/N0, o front end, a saída SigMF, o orçamento, o confinamento de caminhos e o estado desativado.

  • A camada IQ de GNSS no registo de validação. Uma verificação cruzada fixada antecipadamente com o gps-sdr-sim (um gerador independente de banda de base GPS L1 C/A, MIT, commit 28ca29a6) passa a fazer parte do conjunto de testes sempre ativo (tests/iq_gpssdrsim_cross_generator.rs). A sua saída de referência submetida (tests/fixtures/iq_gpssdrsim_cross_generator/: 20 ms de I/Q de 8 bits do próprio gps-sdr-sim, a sua listagem de canais e o estado do canal por detrás dela, a partir de um arnês ligado à mesma compilação) é regenerada por scripts/gen_iq_gpssdrsim_ref.sh. Nada, no momento do teste, precisa de rede nem da ferramenta externa. São acrescentadas duas linhas ao registo (251 linhas: 124 validadas, 123 modeladas, 4 de parceiro):

    • Geometria do sinal de cenas IQ de GNSS face a um gerador independente de banda de base: Validado. A verdade da cena (conjunto visível, pseudodistância, fase do código, Doppler, ângulos de observação) para uma cena de efemérides difundidas coincide com o estado de canal do gps-sdr-sim nos 11 canais: pior caso 1,6 mm, 5.5e-6 chip, 7.4e-5 Hz, 4e-9 graus, face a limiares de 0,05 m, 2e-4 chip, 0,02 Hz e 1e-4 graus fixados antes da execução.
    • Aquisição IQ de GNSS sobre amostras I/Q geradas de forma independente: Modelado, com uma constatação. iq::acq encontra todos os satélites simulados nas amostras do gps-sdr-sim dentro dos limiares registados (fase do código a menos de 0,195 chip, Doppler a menos de 72 Hz). O limiar registado "nenhum outro PRN detetado" falha, porém: na saída sem ruído do gps-sdr-sim, o limiar de ruído gaussiano é ultrapassado pela correlação cruzada dos outros satélites para todos os 21 PRN ausentes. O teste estrito é mantido, ignorado com a constatação, e um teste fixado regista-a. Nenhum código do motor nem API pública muda. As amostras I/Q não são comparadas amostra a amostra: a tabela de senos inteiros, os ganhos, a fase inicial nula da portadora e os campos LNAV truncados do gps-sdr-sim não são grandezas em que um recetor precise de concordar. A comparação é feita nas observáveis que um recetor mede.

Alterado#

  • iq track passa o controlo a partir de uma aquisição de ≈4 ms por predefinição (alteração de comportamento). A aquisição que inicializa cada canal de seguimento integra agora ceil(4 ms / T_code) períodos de código de forma coerente em vez de um, em que T_code é o período completo do código (primário vezes o comprimento secundário num código em camadas, a unidade sobre a qual a aquisição integra). Os códigos de 1 ms sem camadas (GPS L1 C/A, BeiDou B1I, GLONASS L1OF) pesquisam agora 4 períodos (4 ms), pelo que o passo Doppler por predefinição 2 / (3 · N · T_code) é de ~167 Hz em vez de ~667 Hz. Todos os códigos cujo período completo já é de 4 ms ou mais mantêm 1 período: Galileo E1-B (4 ms), BeiDou B1C (10 ms), e os códigos em camadas GPS L5-I/L5-Q, Galileo E5a-I/E5a-Q e E1-C (10 a 100 ms com os seus códigos de sobreposição), e o GPS L2C. Todos os sinais integram, por isso, pelo menos ~4 ms. Uma pesquisa de um só período podia passar um canal a até ~333 Hz de distância, fora da captura do FLL, e este seguia então um falso bloqueio a ~500 Hz de distância enquanto comunicava um seguimento limpo. Numa varredura com sementes de 180 canais GPS L1 C/A (Doppler em ±5 kHz, 38 a 47 dB-Hz, metade com dados de navegação; docs/design/evidence/iq-track-acq-default/, reexecutável) os falsos bloqueios descem de 27 em 180 para 1 em 180 e as aquisições falhadas de 102 para 11, por ~40 ms mais de pesquisa por PRN em GPS L1 (11 → 52 ms). O único falso bloqueio residual está a 38 dB-Hz, a 36 Hz de distância. Todas as superfícies concordam: kshana iq track e kshana iq sweep (--acq-coherent), kshana.iq_track em Python (acq_coherent=None é agora automático; ficheiro de stub atualizado) e a ferramenta iq_track do MCP. Os utilizadores que dependiam do comportamento antigo por predefinição podem passar acq_coherent=1 (--acq-coherent 1). O próprio valor por predefinição de --coherent de kshana iq acquire continua a ser 1. Novos iq::acq::auto_coherent_periods e iq::acq::AUTO_COHERENT_S públicos; teste de regressão tests/iq_cli.rs::track_default_handoff_does_not_false_lock_where_one_period_did.
  • Todos os gráficos gerados seguem agora o tema Observatory do sítio: os bytes de todos os gráficos mudam. Esta é uma revisão deliberada das figuras publicadas, apenas de cores e tipos de letra; nenhum valor representado, coordenada ou etiqueta mudou. O *.chart.svg de cada cenário (e, por isso, as exportações de gráficos do Studio e os gráficos de demonstração do README), o HTML do relatório de execução (*.report.html), a animação da linha temporal (--animate), as páginas HTML de resultados de cenários e de estudos, o resumo de validação e as figuras e diagramas da documentação usavam a paleta escura quente de julho (fundo #0c0b08, dourado #e0bd84) e um tema de relatório em papel quente. Passam agora a retirar todas as cores e tipos de letra de um único módulo, src/palette.rs, que espelha web/theme.css: os gráficos são desenhados em escuro de instrumento sobre o fundo Observatory (#060A14) na pilha tipográfica Geist; o relatório, o leitor de animação e as páginas de resultados seguem a preferência de claro/escuro do espectador com os tokens claros e escuros do Observatory. Os seis domínios de falha mantêm uma cor cada (interferência coral, spoofing magenta, temporização azul, órbitas ciano, integridade lima, navegação âmbar), e os níveis de evidência leem-se validado lima, modelado âmbar, parceiro magenta. As rampas de cascata mantêm a sua ordenação percetual (inferno), reancoradas no novo fundo.
    • tests/palette_sync.rs prende o módulo a web/theme.css nos dois temas, verifica que docs/assets/palette.json e docs/diagrams/mermaid-config.json (ambos gerados a partir do módulo, para as ferramentas de figuras em Python e para o mermaid-cli) estão atualizados, e falha se um literal de cor hexadecimal aparecer em src/ fora da paleta.
    • tests/published_figures_still_reproduce.rs ganha um terceiro diagnóstico, "só se moveram cores e tipos de letra", para que uma revisão da paleta se distinga de um valor representado que se moveu. Cada gráfico do README reconstruído foi verificado como igual ao seu antecessor sob esse normalizador.
    • tools/gen_validation_figures.py lê a paleta e passa também a gerar as três figuras de resultados do README que não tinham gerador submetido (domain-coverage-map, scenario-fom, sgp4-regime-bars), com elementos de texto reais, a partir de web/capabilities.json, do resultado de clock-holdover e de tests/fixtures/sgp4_comparison.md. tools/gen_readme_assets.py lê a mesma paleta, o que corrige o seu desvio do tema claro face ao sítio. Os valores de sgp4-regime-bars são a coluna de pior caso kshana↔ref desse ficheiro de teste (7.31e-9, 8.05e-9, 8.18e-9 e 4.12e-6 km), inalterados face à figura do Matplotlib, e tests/figures_doc_sync.rs falha agora se a figura submetida e o ficheiro de teste discordarem.
  • docs/assets/figures/domain-coverage-map atualizado para os dados atuais (uma alteração de dados, não um redesenho). A figura indicava 28 capacidades em 8 domínios (11 validadas, 17 modeladas), desatualizada face à sua própria fonte declarada; desenhada agora pelo seu novo gerador a partir de web/capabilities.json, indica 46 capacidades em 8 domínios (17 validadas, 29 modeladas).

Corrigido#

  • O Q do interferidor CW/de banda estreita é agora 1,0, e não 1,5. O valor de manual para um tom sobre a portadora é 1 (um tom mantém o pico espetral do sinal, κ = T_c, Q = 1/(R_c κ)); o antigo 1,5 fazia um tom menos danoso do que ruído de banda larga com o mesmo J/S. Alteração de saída: cerca de −1,8 dB de C/N0 efetivo sob interferidores CW/de banda estreita com J/S elevado nos tipos jamming, lunar-jamming e de interoperabilidade (o tom do exemplo spectrum incluído: 17,98 dB-Hz da tabela, era 19,74). O Q de banda larga mantém-se em 1,0 (conservador, cerca de 3 dB abaixo do ~2 de manual) até à revisão de 0,34. Defina q_override para manter o antigo 1,5.

  • A saída inteira de kshana iq scene usa o intervalo inteiro. Com ruído de potência unitária e uma escala de escrita de 1, as cenas ci8/ci16 saíam como cerca de {-1, 0, 1} e as cenas de 2 bits tinham os seus limiares a 2,8 sigma. Os formatos inteiros são agora escalados de modo a que o RMS esperado por componente seja um quarto da escala completa (31,75 LSB em ci8, 8191,75 em ci16) ou 2 LSB em 2 bits. A escala e o número de elementos cortados são impressos e escritos no ficheiro auxiliar. A saída em vírgula flutuante não muda.

  • Oito fixações de ficheiros de teste em sete ficheiros de teste já não falham no macOS por diferenças no último bit (parte da questão #36). As fixações que verificam que o motor ainda constrói os dados de entrada submetidos de uma referência independente (jacobianos, uma tabela de estados, azimutes de lançamento) comparavam bit a bit e falhavam no macOS arm64 em 2 a alguns milhares de unidades na última casa. Passam a comparar a menos de 1e-12 de uma escala retirada do ficheiro de teste; inteiros, chaves e comprimentos continuam a comparar-se exatamente, e um teste de mutação mostra que uma alteração relativa de 1e-6 continua a falhar. A fixação do azimute de lançamento compara sin az e o ramo ascendente/descendente em vez do próprio azimute, porque asin amplifica um ulp do seu argumento para cerca de 3e-9 rad quando uma inclinação é igual à colatitude de um local. Nenhuma tolerância de referência independente nem limiar fixado antecipadamente mudou. Dois testes (OD conjunta lunar, observabilidade lunar) não estão cobertos: no macOS as suas próprias comparações fixadas antecipadamente movem-se, e isso fica para um seguimento.

  • kshana iq track e kshana iq sweep aplicam as opções do front end. O texto de utilização anunciava --bandpass/--notch/--blank/--excise/--agc/--bits em track, mas track e sweep nunca construíam a cadeia: as opções eram ignoradas em silêncio, e uma sem valor, como --notch, engolia a opção seguinte. Ambos os comandos passam a interpretá-las como iq acquire faz e a colocar uma cadeia de front end nova à frente da passagem de aquisição e da passagem de seguimento. A saída é igual à de executar o comando sobre o ficheiro que iq frontend escreve com as mesmas opções.

  • Os dados da cena IQ são colocados por sinal. kshana iq scene --data (e NavData::Seeded) colocavam bits de 50 bit/s em todos os sinais, incluindo os pilotos, e à taxa LNAV do GPS no Galileo e no BeiDou. Os dados seguem agora a temporização de símbolo própria de cada sinal, indicada pelo novo SpreadingCode::data_modulation() (DataModulation, definido por cada construtor em iq::signals). Isso são 10 ms em L5-I5, 4 ms em E1-B, 2 ms em BeiDou B1I GEO (D2), e bits de 20 ms com um meandro de 10 ms em GLONASS L1OF. Os dados são recusados em pilotos, em GPS L2C como um único fluxo CM/CL, e NavData::Lnav em qualquer coisa que não seja L1 C/A. Os códigos personalizados mantêm por predefinição a temporização de 20 ms anterior. Uma Scene programática que pedisse NavData::Lnav num código que não fosse L1 C/A, ou NavData::Seeded num piloto, gerava em silêncio e agora devolve um erro na primeira leitura.

  • Os canais GLONASS L1OF são adquiridos e seguidos na sua própria portadora FDMA. iq::acq::acquire e os canais de seguimento misturavam cada código para baixo apenas a partir de if_hz. Numa gravação GLONASS de vários canais, uma pesquisa pelo canal +3 encontrava, por isso, o sinal do canal 0 (todos os canais partilham um código de medição de distância) e nunca procurava 1,6875 MHz mais acima. Ambos usam agora SampleSpec::baseband_hz(carrier) = if_hz + (carrier − center_hz). O termo da portadora é zero em qualquer gravação centrada na portadora do próprio sinal e é omitido quando o centro é desconhecido, pelo que o processamento CDMA não muda. Se contornou o comportamento antigo incorporando carrier − center no if_hz do ficheiro auxiliar, retire esse termo: o desvio é agora aplicado a partir da portadora e do centro, pelo que mantê-lo aplica-o duas vezes. Limitação conhecida, inalterada aqui: uma cena GLONASS identifica cada satélite pelo seu canal de frequência k, e o identificador de satélite u32 faz o envolvimento de um canal negativo. O ficheiro auxiliar de verdade escreve k = -7 como sat_id 4294967289 (k + 2^32). Leia-o de volta como k com uma conversão i32.

[0.32.0] - 2026-10-05#

Adicionado#

  • Camada IQ de GNSS na CLI e em Python (0.32.0 Fase A). O módulo iq existente pode agora ser usado sem escrever Rust. Cinco novos comandos kshana iq juntam-se ao grupo de tratamento de dados: scene gera uma longa cena IQ de vários satélites para um ficheiro com um ficheiro auxiliar de verdade; acquire executa a aquisição por FFT de um ou mais PRN sobre uma gravação e comunica cada deteção (PRN, Doppler, fase do código, estatística, limiar); track adquire e depois executa o banco DLL/PLL/FLL sobre uma gravação e emite saída de seguimento por época (CSV/JSON) com larguras de banda de laço, tempo de integração e espaçamento de correladores configuráveis; sweep reproduz uma gravação através de vários desenhos de laço e comunica o jitter e as métricas de bloqueio resultantes por desenho; e labfit ajusta o modelo de perda de bloqueio do laço de seguimento a uma linha temporal de confiança do recetor. O mesmo núcleo é exposto em Python (kshana.iq_scene, iq_acquire, iq_track, iq_labfit, iq_signals), devolvendo listas e dicionários compatíveis com NumPy. Apenas software e aditivo: sem novas dependências, sem transmissão, sem síntese de formas de onda de interferência ou de spoofing; o motor, a aquisição, o seguimento e os desenhos de laço são os do próprio crate, pelo que quem chama a CLI ou o Python obtém os mesmos bits que os testes em Rust. Novo módulo iq::cli; o próprio ficheiro auxiliar de verdade da cena é a referência independente em tests/iq_cli.rs (a aquisição recupera cada fase de código e Doppler injetados, o seguimento converge para o Doppler injetado). Nenhuma contagem publicada de tipos de cenário nem linha da matriz de verificação muda.
  • Capacidades restantes da biblioteca IQ de GNSS na CLI iq e em Python (0.32.0 Fase A.2). Assenta na Fase A, expondo o resto da camada iq sem escrever Rust:
    • Canal de propagação em iq scene (e em iq_scene de Python): uma ionosfera de primeira ordem (--iono-stec/--iono-vtec ou --iono-klobuchar), a troposfera de Saastamoinen/Niell (--tropo), o modelo de cintilação de Cornell (--s4, --scint-tau0, --sigma-phi), multipercurso especular no solo (--multipath-height/--multipath-ground), o canal móvel terrestre de três estados (--land-mobile) e um bloco sem linha de vista (--nlos) aplicam-se a todos os satélites através de uma nova ponte interna ao crate (iq::channel::SceneChannelAdapter) que converte os caminhos absolutos dos modelos de canal na forma de excesso sobre a geometria da cena.
    • Saída SigMF em iq scene (--format sigmf): escreve as amostras como um par .sigmf-data/.sigmf-meta com uma captura e anotações por satélite; acquire/track já leem SigMF, pelo que uma cena faz o ciclo completo.
    • DSP do front end: um novo comando iq frontend <in> <out> e as mesmas opções em acquire/track (--bandpass, --notch, --blank, --excise, --agc, --bits 1/2/3/8/14) executam os estágios de iq::frontend (FIR passa-banda, rejeita-banda adaptativo, supressão de impulsos, excisão no domínio da frequência, AGC, quantificador); espelhado em Python como iq_frontend.
    • Cenas de efemérides difundidas: iq scene --nav <rinex_nav> --rx-pos lat,lon,alt (com --start/--window/--prn) coloca cada satélite GPS saudável na sua geometria difundida verdadeira usando o leitor RINEX do motor, pelo que o ficheiro auxiliar de verdade traz a distância, o Doppler e a fase do código reais por satélite; espelhado em Python como iq_scene_broadcast. Apenas software e aditivo: sem novas dependências, sem transmissão, sem síntese de formas de onda de interferência ou de spoofing (os efeitos de propagação do canal atuam apenas sobre o sinal legítimo). Cada afirmação numérica é testada face a uma referência independente (forma fechada ou verdade injetada) nos testes unitários de canal/front end e em tests/iq_cli.rs.

[0.31.0] - 2026-10-04#

Adicionado#

  • Camada IQ de GNSS: simulação ao nível do sinal e processamento de recetor por software. Um novo módulo iq leva o Kshana de um front end L1 C/A de um só satélite e blocos curtos a uma camada completa ao nível do sinal, acessível a partir do grupo de comandos kshana iq. Gera cenas IQ em bruto longas e de vários satélites com um ficheiro auxiliar de verdade por época (iq::scene); aplica a propagação ao nível do sinal — ionosfera com divergência código-portadora, troposfera, cintilação de amplitude e de fase (modelo de Cornell), multipercurso de Fresnel e um canal móvel terrestre de três estados, com ausência de linha de vista (iq::channel); adquire e segue com aquisição por FFT e um banco DLL/PLL/FLL multicanal, reproduzindo uma gravação através de muitos desenhos de laço (iq::acq, iq::track); modela o front end — filtragem FIR/IIR, quantificação de 1 a 14 bits, AGC, rejeita-banda, supressão de impulsos e excisão no domínio da frequência (iq::frontend); processa em fluxo grandes conjuntos de dados gravados com memória limitada — formatos int8/int16/float32/2 bits empacotados e FI real, SigMF de vários ficheiros, reamostragem, um inventário de conjuntos de dados com SHA-256 por ficheiro e um executor em lote (iq::io); acrescenta códigos de espalhamento para GPS L5/L2C, Galileo E1 (CBOC, códigos de memória reais do ICD) e E5a, BeiDou B1C/B1I e GLONASS L1OF, cada um verificado face ao seu documento de controlo de interface (iq::signals); e ajusta o modelo de perda de bloqueio do laço de seguimento ao comportamento observado de um recetor real em execuções de laboratório, com erro de conjunto reservado deixando uma execução de fora e extrapolação rotulada como previsão (iq::labfit). Cada afirmação numérica é testada face a uma referência independente (uma tabela do ICD, uma forma fechada, ou um recetor independente a recuperar a verdade injetada); os modelos físicos de canal e de laço continuam MODELLED. Trata-se apenas de uma camada de software: escreve ficheiros IQ para recetores por software e não sintetiza formas de onda de interferência ou de spoofing nem comanda hardware de rádio. Nenhuma contagem publicada de tipos de cenário nem linha da matriz de verificação muda. Projeto: docs/design/GNSS-IQ-PLAN.md.
  • Confiança no recetor: avaliar um registo real de recetor GNSS. kshana receiver-trust <scenario.toml> lê um registo u-blox UBX, RINEX 3 (com um ficheiro de navegação difundido opcional), Android GnssLogger ou NMEA 0183 para uma única linha temporal com marcas de tempo e executa sobre ela monitores de confiança: queda da densidade de potência da portadora em relação ao ruído (C/N0), perda de bloqueio, controlo automático de ganho (AGC), o indicador de interferência da u-blox, salto de posição e, com RINEX e navegação, a solução de posição de ponto único do próprio motor com monitorização autónoma da integridade pelo recetor (RAIM) por paridade e o monitor auxiliado pelo relógio. Cada época é nominal, degradada ou não confiável, e o resultado diz quando e porquê. Os eventos e as quedas de C/N0 previstas declarados no cenário são pontuados face a tolerâncias declaradas no mesmo ficheiro: detetado, tardio ou falhado, e concordam ou discordam. As saídas são o JSON de resultados, um CSV por época e um gráfico; o resultado traz o SHA-256 do registo e todos os limiares. Também acessível a partir de Python (kshana.receiver_trust), do pacote WebAssembly (receiver_trust, registos em linha) e da nova ferramenta assess_receiver_log do servidor Model Context Protocol (MCP). Guia: docs/RECEIVER-TRUST.md; exemplo: examples/receiver-trust/. Nos registos de spoofing do JammerTest 2024, o caminho do motor reproduz o primeiro alarme da cadeia de referência independente fixada antecipadamente em cada início publicado (tests/receiver_trust_jammertest.rs). Os monitores continuam MODELLED; nenhuma linha da matriz de verificação muda.

0.30.0 - 2026-10-03#

Uma versão menor. As rondas de validação 2 e os pacotes da vaga 1 levam a matriz de verificação de 223 linhas (93 VALIDATED) em 0.29.3 para 249 linhas (123 VALIDATED, 122 MODELLED, 4 PARTNER); cada promoção foi verificada face a uma referência independente com uma tolerância fixada antes da execução, e cada discordância é publicada como constatação. Novidades: um leitor nativo de kernels NAIF e um caminho DE440, um caminho único e validado de propagação e tempo de SGP4 para ITRS, uma biblioteca de relógios medidos, um gerador de referência LunaNet AFS, solucionadores de precisão alargada e de informação em raiz quadrada, e processamento IQ lunar real sobre dados LuGRE. Os números publicados que mudaram estão listados como revisões abaixo.

Vinte e sete linhas da matriz de verificação passam a VALIDATED depois de uma referência independente ter concordado dentro de uma tolerância fixada antes da primeira comparação (a regra de promoção em docs/VALIDATION.md): dez numa primeira ronda de validação e dezassete numa segunda. Cinquenta e uma linhas MODELLED foram submetidas a uma referência independente externa na primeira ronda e as restantes linhas encaminháveis na segunda; cada discordância é registada abaixo como constatação, em vez de ser ajustada até desaparecer. Três linhas foram divididas para que uma parte validada não carregue um resto não validado, o que leva a matriz de 223 para 226 linhas; os pacotes de validação incorporados desde então levam-na para 249. As contagens são lidas de docs/VERIFICATION-MATRIX.md gerado.

0.29.0 após a ronda 1 Por lançar
Linhas da matriz de verificação 223 223 249
das quais VALIDATED face a uma referência independente externa 83 93 123
das quais MODELLED 136 126 122
das quais PARTNER 4 4 4
Abreviaturas usadas nesta entrada
Abreviatura Significado
ADD, ARAIM, MAAST Airborne Design Document (do ARAIM); monitorização autónoma avançada da integridade pelo recetor; a Matlab Algorithm Availability Simulation Tool da Universidade de Stanford
ADEV, VRW, ARW desvio de Allan; passeio aleatório de velocidade; passeio aleatório de ângulo
ANISE, SPICE, NAIF, PCK um conjunto de ferramentas de astrodinâmica de código aberto (Nyx Space); o conjunto de ferramentas Spacecraft, Planet, Instrument, C-matrix, Events da NASA, do seu Navigation and Ancillary Information Facility; kernel de constantes planetárias
BCRS, TDB, TT Sistema de Referência Celeste Baricêntrico; Tempo Dinâmico Baricêntrico; Tempo Terrestre
BIPM, UTC(k) Bureau Internacional de Pesos e Medidas; a realização do Tempo Universal Coordenado por um laboratório
CCSDS, OEM, LTC, TCL Consultative Committee for Space Data Systems; Orbit Ephemeris Message; sistemas de tempo lunares escritos no campo TIME_SYSTEM da mensagem
CRLB limite inferior de Cramér–Rao
CW movimento relativo de Clohessy–Wiltshire
DE440 Development Ephemeris 440 do Jet Propulsion Laboratory
DOP, PDOP diluição da precisão; diluição da precisão de posição
EKF, UKF, INS, GNSS, IMU filtro de Kalman estendido; filtro de Kalman unscented (UKF); sistema de navegação inercial; sistema global de navegação por satélite; unidade de medição inercial
EMT, VPL, HPL limiar efetivo do monitor; nível de proteção vertical e horizontal
EOP, IERS, PCC, MAE parâmetros de orientação da Terra; International Earth Rotation and Reference Systems Service; Prediction Comparison Campaign; erro absoluto médio
ERFA, SOFA Essential Routines for Fundamental Astronomy; Standards of Fundamental Astronomy
GMAT a General Mission Analysis Tool da NASA
NTN, SSB rede não terrestre (3GPP); bloco de sinal de sincronização
IGS, ILRS, ITRF2020 International GNSS Service; International Laser Ranging Service; International Terrestrial Reference Frame 2020
ILS, LAMBDA mínimos quadrados inteiros; Least-squares AMBiguity Decorrelation Adjustment
ISB enviesamento entre sistemas
LEO órbita terrestre baixa
MHSS, PL, TPL separação de soluções por múltiplas hipóteses; nível de proteção; nível de proteção de temporização
PSD, IQ, SigMF densidade espetral de potência; amostras em fase e em quadratura; Signal Metadata Format
QPN ruído de projeção quântica
RAIM monitorização autónoma da integridade pelo recetor
SBAS, WAAS, DFMC, GEO sistema de aumento baseado em satélites; o Wide Area Augmentation System dos EUA; dupla frequência e multiconstelação; um satélite SBAS geoestacionário
RMS, SISRE raiz do valor quadrático médio; erro de distância do sinal no espaço
RTKLIB uma biblioteca de posicionamento GNSS de código aberto
TCXO oscilador de cristal com compensação de temperatura
VLBI interferometria de linha de base muito longa

Validado#

Cada linha abaixo nomeia o seu tipo de referência independente (Biblioteca: uma biblioteca independente de terceiros que calcula uma grandeza definida de forma única; Medido: dados reais medidos; P2: uma biblioteca numérica independente que recalcula uma grandeza de álgebra linear sobre entradas submetidas), a referência independente, a tolerância fixada antes da execução e o resultado. Cada promoção foi repetida por um segundo revisor, que regenerou o ficheiro de teste byte a byte e mostrou que uma mutação deliberada do motor faz o teste ficar vermelho.

  • Fusão de sensores GNSS/INS (Biblioteca), limitada ao EKF de estado de erro de 15 estados com acoplamento fraco: NaveGo v1.4 (LGPL-3.0, executado sob GNU Octave) na sua própria condução real com IMU/GNSS Ekinox. O RMS horizontal, vertical e de inovação de posição do Kshana são 0,912, 0,940 e 0,861 dos do NaveGo (limiar 1,2) e a sua inovação normalizada média é 0,395 (limiar 1,5). O GNSS está presente durante toda a condução, pelo que nenhuma interrupção é testada. O filtro de Kalman unscented (UKF) fortemente acoplado e o filtro de relógio acoplado ficam fora da afirmação.
  • Atitude de 3 graus de liberdade e orçamento de erro de apontamento (Biblioteca), limitado ao pico do binário de gradiente gravítico: Basilisk 2.9.1 GravityGradientEffector, 40 casos, a menos de 1e-12 em termos relativos (pior 2.1e-15). O orçamento de apontamento RSS é uma soma de números fornecidos pelo chamador e fica fora dele.
  • Geometria conjunta lunar de comunicações e navegação (Biblioteca), limitada à colocação do local, azimute, elevação e distância: ANISE 0.10.2, 768 amostras, a menos de 1e-6 graus e 1 mm (pior 2.2e-12 graus e 5.6e-9 m). O parâmetro de exatidão de medição de distância é um dado de projeto fora da afirmação.
  • Dinâmica de atitude de corpo rígido sem binário (Biblioteca): o cubo de nave Basilisk 2.9.1, 1e4 s em duas inércias gerais, quaternião e taxas a menos de 1e-9 (pior 3.3e-11 e 3.4e-12 rad/s).
  • Resolução de ambiguidades inteiras da fase da portadora GNSS (LAMBDA) (Biblioteca), limitada à solução ILS e às suas duas melhores normas: RTKLIB v2.4.2-p13 lambda(), 300 covariâncias, 0 discordâncias inteiras, normas a menos de 1e-9 em termos relativos (pior 5.6e-13). A taxa de sucesso por bootstrap continua apenas verificada internamente.
  • PL de temporização composto, MHSS escalar (P2): numpy 2.3.5 e scipy 1.18.1 sobre 300 entradas submetidas, PL a menos de 1e-9 em termos relativos (pior 1.2e-10), subconjunto condutor idêntico.
  • Branqueamento de modo comum por GLS e a identidade de Mahalanobis (P2): LAPACK do numpy 2.3.5 sobre 201 covariâncias submetidas, a menos de 1e-12 em termos relativos (pior 7.9e-16); números de condição até 19,3.
  • Fornecedor de orientação lunar de eixos principais DE440 (Biblioteca): pxform do SPICE sobre o PCK binário em 2 000 épocas fora dos nós, a menos de 1.7e-5 rad (pior 1.7e-6 rad, cerca de 3 m à superfície), depois da correção listada em "Corrigido".
  • Entrada e saída de gravações SigMF, e espetros de Welch (Biblioteca), limitado à leitura e escrita de SigMF e a welch_psd: signal.welch do scipy 1.18.1 a menos de 1e-12 em termos relativos por intervalo (pior 6.0e-14); gravações do sigmf-python 1.13.0 descodificadas de forma idêntica bit a bit; os metadados do crate válidos face ao esquema SigMF v1.2.6. A síntese IQ e as suas comparações de modelo ficam fora dele.
  • Ajustador de efemérides difundidas LEO e SISRE face ao intervalo de ajuste (Medido), limitado ao ajuste kepleriano de 16 parâmetros e ao seu SISRE só de órbita: órbitas precisas ITSG do TU Graz de quatro satélites face às estatísticas de Liu et al. 2025, componentes a menos de 1.5x (0,804 a 1,087) e SISRE a menos de 1.5x (0,716 a 0,809).

Constatações#

A referência independente discordou destas linhas, pelo que continuam MODELLED. Cada constatação é também escrita no texto da referência independente da linha (e, por isso, em docs/MODELLED-RATIONALE.md), com um teste que a fixa.

  • Estimação do estado do relógio de bordo: em relógios IGS retidos de 11 satélites GPS Block IIF, o filtro de três estados é consistente um passo à frente mas demasiado confiante a uma hora em 9 de 11 (os termos periódicos e de cintilação não estão no modelo).
  • Deteção de spoofing: no JammerTest 2024 nenhum monitor ao nível das observáveis deu alarme a menos de 10 s de qualquer dos 8 inícios publicados, e três janelas anteriores ao início tiveram falsos alarmes.
  • Nível de proteção de temporização sob spoofing: o erro de tempo não detetado medido excede o TPL em 3 de 8 inícios detetados (1.9x a 5.3x); uma calibração de relógio de 60 s não cobre a deriva do TCXO do recetor.
  • Janela de lançamento e geometria de ascensão: face ao Orekit 12,2 a geometria concorda até ao arredondamento, mas a velocidade do local por rotação da Terra falha 1e-6 em termos relativos a 62,9 graus de latitude (1.12e-6, o movimento polar que o modelo esférico omite). Ronda 2: a velocidade com polo verdadeiro e com época concorda, a velocidade por predefinição sem época continua a falhar (ver abaixo).
  • Corredor de reentrada balística (Allen–Eggers): a desaceleração de pico prevista para a reentrada da Stardust é de 61,8 g face aos 32,89 g reconstruídos (+88 %, tolerância 15 %).
  • Erro conjunto de UT1 e de movimento polar: face à fórmula de exatidão impressa em 178 edições do IERS Bulletin A, o polo concorda a menos de 1.5x mas o UT1 não (0,48 a 10 dias, 1,59 a 40 dias). Superado na ronda 2: a linha é agora VALIDATED (ver abaixo).
  • Dados de entrada de orientação da Terra por predefinição, offline: o astropy confirma a contagem das linhas, mas as 12 linhas que o crate designa como previsões do Bulletin A estão assinaladas como medidas (I), e não como previstas (P). Os valores de concordância da linha do previsor operacional eram, por isso, face a linhas medidas. Superado na ronda 2: o motor classifica as linhas pelo indicador e a linha é VALIDATED.
  • Erro de previsão de orientação da Terra de estilo operacional: o erro de UT1 do previsor é de 2.4x a 12.6x o do Bulletin A a 1 a 10 dias e de 5,32 ms a 10 dias, fora do intervalo de 0,36 a 3,13 ms da 2.ª EOP PCC.
  • VLBI geodésico lunar: face aos tempos de luz do ANISE através da DE440, nenhum atraso fica a menos de 1 ps; a maior diferença é de 24 µs, sobretudo devido ao centro analítico da Lua (cerca de 200 km da DE440). Ronda 2: o caminho por kernel é VALIDATED numa linha própria; este caminho analítico continua MODELLED.
  • Exportação de interoperabilidade lunar: o Orekit 12,2 recusa os sistemas de tempo LTC e TCL, pelo que a troca dos ficheiros OEM lunares com um segundo leitor não está estabelecida.
  • Movimento relativo de Clohessy–Wiltshire: face ao movimento não linear do Orekit a 100 m, a diferença é de 1,2 a 6,3 mm, acima de 1 mm; escala como o termo de segunda ordem omitido, pelo que a tolerância fixada antecipadamente ficava abaixo do erro de linearização. Superado na ronda 2: a correção de segunda ordem é VALIDATED face ao mesmo limiar.
  • Crescimento do erro de deriva INS/TRN: face a um Monte Carlo inercial livre do NaveGo, as leis de crescimento mantêm-se a menos de 5 % até 600 s e sobrestimam para além disso (2.2x a 8x a uma hora), porque omitem a realimentação de Schuler. Superado na ronda 2: o modelo de erro de Schuler é VALIDATED.
  • Volume de serviço lunar a partir da geometria real da constelação: 4 de 12 estatísticas de disponibilidade publicadas diferem em mais de 2 pontos percentuais (até 22,5).
  • Sobrelimite do enviesamento de rastreabilidade heterogénea de UTC(k): em 105 024 linhas do BIPM, o sobrelimite é excedido em 50,8 % das linhas; a incerteza publicada limita a medição do desvio pelo BIPM, e não o próprio desvio.
  • Classificação do espaço nulo do datum lunar: na geometria publicada de cinco refletores, a correlação é de -0.78 contra -0.97, e o CRLB da origem é 96 a 98 % inferior ao do artigo.
  • Substrato de geometria do datum de LLR lunar: face a 192 pontos normais lunares do ILRS de 2024, o RMS do resíduo unidirecional era de 96 m com a interpolação de orientação anterior e é de 22,7 m após a correção abaixo, ainda acima do limiar de 10 m (coordenadas de estação arredondadas, sem movimento polar). A série de orientação satura em silêncio fora de 2024-2025. Ronda 2: o modelo de distância medida é VALIDATED numa linha própria (2,81 m); a série cobre agora 2014-2030 e dá erro fora desse intervalo.
  • Acoplamento da taxa do relógio relativista ao referencial: o termo de autopotencial está 3.18e-4 acima do valor publicado (tolerância 1e-4); o artigo avalia um potencial diferente, pelo que não existe valor publicado desta forma fechada. Superado na ronda 2: o potencial equatorial de grau 2 é VALIDATED face ao mesmo artigo.
  • Constantes físicas de todos os corpos do sistema solar: 12 de 84 constantes dos corpos acrescentados diferem de NAIF pck00011 e gm_de440 (elementos mais antigos dos satélites de Marte; outras soluções de GM para Urano, Neptuno e Plutão). Ronda 2: as constantes seguem agora o NAIF (uma transcrição, não contada), e a orientação calculada concorda com o SPICE; a linha continua MODELLED.
  • Modelos de efemérides LEO selecionáveis: o ajuste de 22 parâmetros deixa 1.71x e 1.86x o erro ao longo da trajetória publicado em arcos de 20 min, acima de 1.5x. Superado na ronda 2: o modelo e o ajuste de 22 parâmetros são VALIDATED numa linha própria.
  • Posicionamento conjunto GNSS e LEO: o enviesamento entre sistemas concorda com o RTKLIB, mas 93,2 % das épocas ficam a menos de 3 m do ITRF2020, contra 95 %; o próprio RTKLIB atinge 88,2 % nos dados (93,6 % após a correção do atraso de grupo da ronda 2).
  • Cegueira de integridade em modo comum e mapas de cobertura e DOP: ambas as comparações passaram mas foram recusadas na revisão porque um motor deliberadamente errado também passa nelas (a primeira só verifica uma identidade interna; os pisos publicados da segunda não conseguem ver um PDOP duplicado). Ronda 2: a cegueira de integridade em modo comum é VALIDATED em entradas com paridade; os mapas de cobertura continuam uma constatação (ver abaixo).

Ronda de validação 2#

A segunda ronda tomou todas as linhas que a primeira deixou encaminháveis, com novos pré-registos submetidos antes de qualquer ficheiro de teste ser obtido ou de qualquer referência independente ser executada, um segundo revisor adversarial que repetiu cada comparação e uma mutação deliberada do motor que tem de fazer cada teste ficar vermelho. O responsável aceitou a formulação corrigida da linha do limite fora de Omega em 2026-10-02 antes de esta ser promovida (o seu texto antigo contradizia o código).

Promovidas a VALIDATED (17). Tipo de referência independente entre parênteses; tolerância fixada antes da execução.

  • Acoplamento da taxa do relógio relativista ao referencial (Referência): L_m de Ashby e Patla 2024 a menos de 2.8e-6 (limiar 1e-4) a partir do potencial equatorial de grau 2 dos dois campos que o artigo cita; gravidade de grau 350 do pyshtools para a entrada radial (8.3e-5); velocidade lunar DE441 (2.5e-3).
  • Dados de entrada de orientação da Terra por predefinição, offline (Biblioteca): o astropy 8.0.1 e o IERS Bulletin A n.º 039 confirmam as 30 linhas finais, 54 rápidas e 90 previstas do extrato recortado de novo.
  • Erro conjunto de UT1 e de movimento polar (Biblioteca): as rotações completas do astropy e do pyerfa reproduzem a tabela conjunta (UT1 e polo a menos de 6e-16, a combinação a menos de 1.9e-7); os erros realizados do IERS Annual Report 2019 dão razões de 1,001 a 1,100.
  • Pegada e cobertura de carga útil de observação da Terra (Biblioteca): Orekit 12,2 e GeographicLib 2,1 em todos os limiares fixados antecipadamente, com a regressão nodal de J2 agora no espaçamento dos nós.
  • Movimento relativo de Clohessy–Wiltshire (Biblioteca): com uma correção de segunda ordem em forma fechada, a menos de 1.2e-7 m do movimento não linear do Orekit contra 1e-3 m; a matriz linear sozinha continua caracterizada (1,2 a 6,3 mm).
  • Pontaria no plano B e assistência gravitacional por cónicas ajustadas (Biblioteca): plano B, assíntotas, C3 e elementos heliocêntricos do GMAT R2026a; sbpy 0.6.0 e Kasuga e Jewitt 2019 para o parâmetro de Tisserand.
  • Crescimento do erro de deriva INS/TRN (Biblioteca): um modelo de erro de Schuler de nove estados a menos de 5 % das execuções de deriva corrigidas do NaveGo em todos os 48 pontos (pior 3,70 %).
  • Cegueira de integridade em modo comum (P2): lstsq do numpy em 1464 entradas com paridade a menos de 1e-12 (pior 1.06e-14).
  • OD e relógio lunares conjuntos multitécnica (P2): o numpy recalcula cada passo de Gauss-Newton, sigma e erro de estação em seis redes (a menos de 2.4e-11) após uma correção da resolução por QR.
  • Covariância das coordenadas de estação do VLBI lunar (Biblioteca): um jacobiano construído com o SPICE reproduz o calendário, o espetro, os sigmas e o espaço nulo a menos de 1 % e 0,1 graus; numpy até 2e-13.
  • Limite do modo comum indetetável com resíduo fora de Omega (P2, formulação corrigida por decisão do responsável): LAPACK do numpy em 256 casos a menos de 1e-12, seis infinitos exatos.
  • Classificação do espaço nulo invariante à base (P2): interseção de subespaços com SciPy e NumPy em 72 matrizes construídas, inteiros exatos, norma do projetor a menos de 6.0e-15.
  • Serviços ionosféricos de frequência única e de UTC de uma mensagem de navegação LEO (Biblioteca): GNSSTk 15.3.1 para Klobuchar, Az e a deriva de UTC; ERFA para os três casos de segundo intercalar.
  • Limite de posicionamento por rede não terrestre 5G (P1): limites de SSB único de Bachl, Lei e Nabeel 2026 a menos de meio algarismo impresso; numpy para as covariâncias da solução de posição.
  • Modelo de distância medida de LLR (Medido, nova linha separada do substrato do datum de LLR): 192 pontos normais lunares do ILRS com 2,81 m de RMS contra um limiar de 10 m, com o tempo de luz baricêntrico do IERS 2010; as componentes abaixo do limiar não são resolvidas uma a uma, e a linha di-lo.
  • VLBI geodésico lunar, caminho por kernel (Biblioteca, nova linha separada da linha do VLBI lunar): tempos de luz do SPICE convergidos a menos de 1 ps e derivadas parciais a menos de 1e-6 em épocas próximas de J2000; o caminho analítico por predefinição continua MODELLED.
  • Modelo de efemérides LEO de 22 parâmetros de Liu et al. 2025 e o seu ajuste (Medido, nova linha separada da linha dos modelos selecionáveis): órbitas precisas reais a menos de 1.5x das estatísticas publicadas nos dias do artigo e em dias retidos (0,683 a 1,186); a convenção de escala de n_dot é transcrita e não é validada por esta comparação, e a regra de paragem é a regra de convergência de parâmetros do Kshana, e não a regra de variação do RMS do artigo. O polinómio ATOMIC e a tabela de cinco altitudes continuam MODELLED.

Linhas VALIDATED existentes com novo suporte (sem alteração da contagem).

  • Posições dos planetas a partir dos elementos de Standish do JPL e tempo de luz entre corpos do sistema solar: os limiares a posteriori de duas vezes o nominal são substituídos por comparações fixadas antecipadamente com o JPL Horizons DE441 (RMS no máximo o valor da Tabela 8.10.1 do Explanatory Supplement, pior 0,778, incluídas a divisão da Terra e a rotação ICRF; tempos de luz a menos de 1e-6 s do Horizons em posições DE441, pior 6.7e-9 s). As suas marcas "limite fixado após a comparação" são removidas.
  • Integridade (RAIM/ARAIM/SBAS): a linha já não assenta em verificações de plausibilidade. Passa a dizer: a separação de soluções por múltiplas hipóteses do ARAIM do ADD v4.2 concorda com o Stanford MAAST para o ARAIM 2 em 270 casos reais (pior diferença de VPL 2.2e-3 m contra 0,05 m); a deteção e exclusão RAIM instantânea concordam com raim_fde do RTKLIB em 2016 de 2016 decisões, com o nível de proteção de declive a menos de 2.7e-12 m; os níveis de proteção L1 do SBAS DO-229E concordam com o Stanford MAAST em difusões WAAS reais (2868 pares a menos de 1.6e-5 m). Indica com clareza que as funções de sigma uniforme raim::araim_raim e raim::araim_dual_raim NÃO são aderentes à norma do ADD (diferenças de VPL/HPL com entradas coincidentes de 0.75/4.04 m e 0.39/1.93 m, uma constatação), que a comparação SBAS DFMC L5 é uma constatação (308 pares sem GEO à vista são protegidos pelo Kshana e não pelo MAAST) e que raim::solution_separation_raim não tem comparação externa. A sua marca própria é removida.
  • Ajustador de efemérides difundidas LEO: a órbita verdadeira integrada é acrescentada à parte validada (Orekit 12,2 a menos de 4,55 mm em 6 h, limiar 2 cm); os polinómios de correção, o ajuste de relógio e o compromisso do período de atualização continuam modelados.

Constatações e linhas bloqueadas (continuam MODELLED). O texto da referência independente de cada linha traz a constatação e o seu teste fixado.

  • Modulação de sinais de navegação (Betz 2001, Hein 2006): os espetros e as correlações concordam; os lóbulos laterais de 24 MHz e todos os enviesamentos de multipercurso (11 a 15 % baixos) não, causa por esclarecer.
  • Geolocalização TDOA/FDOA: os limites coincidem com os de Ho e Chan e de Ho e Xu, e com o código dos autores a menos de 3e-12; os fatores de Ottawa impressos a partir de um Monte Carlo diferem em 1,3 % e 4,4 %.
  • GNSS da Terra à distância lunar: as médias no zénite do GENESIS concordam com Montenbruck et al. 2023 em 5 de 6; as médias no nadir são 1,0 a 2,4 satélites mais altas.
  • Mapas de cobertura e DOP: os projetos para a Terra concordam com o Orekit, o gnss_lib_py e o numpy em todos os limiares; os projetos para a Lua e Marte excedem 1e-9 apenas em células quase singulares.
  • Posicionamento GNSS conjunto: frequência dupla 79,9 % e produtos precisos 94,2 % a menos de 3 m contra 95 % (RTKLIB 67,9 % e 94,1 %); a diferença de ISB com produtos precisos deve-se ao RTKLIB ignorar os desvios das antenas.
  • Laços de seguimento (GNSS-SDR 0.0.19): concordam de 35 a 45 dB-Hz; a 30 dB-Hz PLL +21 %, DLL -32 %, limiares +1,5 dB; tempos de deslize de 0,5 a 2 décadas mais curtos.
  • Volume de serviço lunar (Orekit e Hipparchus): 155 de 160 valores concordam; o requisito da pior amostra falha na geometria quase singular do LNCSS B.
  • Sensor inercial quântico: o piso só de QPN fica 21 a 31 % abaixo do ruído medido de Gauguet 2009 (limiar 30 %, falhado por 0,5 pontos).
  • Predefinições de osciladores: as unidades medidas excedem as predefinições de holdover do rubídio, de curto prazo do césio e de pior unidade do CSAC; a predefinição de OCXO não tem registo medido.
  • Densidade da meteorologia espacial: o Jacchia 1971 fica a menos de um fator 2 das densidades de acelerómetros no máximo solar, mas cerca de 1.7x demasiado denso no mínimo de 2008.
  • TEC oblíquo sem geometria: 33 de 36 arcos a menos de 3 TECU do mapa CODE (pior 6,84).
  • Deteção de spoofing e TPL face ao registo oficial do JammerTest 2024: 4 de 10 inícios detetados a tempo; o TPL é excedido em 4 de 10.
  • Filtro de relógio em relógios IGS novos: dois de 11 satélites falham o critério da soma das inovações.
  • Previsor de EOP por mínimos quadrados mais autorregressivo: UT1 1,73 a 2.11x o Bulletin A a 2 a 10 dias.
  • Sobrelimite do desvio realizado de UTC(k): excedência agregada 0,0333 contra 1e-2.
  • Datum do referencial lunar a partir de uma campanha: o ramo SPICE concorda; o ramo P2 com estações estimadas falha 1e-9 num problema de condição 2.1e8.
  • Datum do referencial lunar a partir de LLR real: 15 de 16 valores concordam com o SPICE; o sigma da translação em z é 1,03 % alto contra 1 %.
  • Reentrada (Allen-Eggers): a solução de massa pontual concorda com reconstruções de agências (apenas uma verificação cruzada); a comparação com o acelerómetro está bloqueada à espera de uma fonte legível do Hayabusa2.
  • Máscaras ITU-T: os valores de exemplo impressos concordam; os limites de classe da G.8273.2 não têm nenhum (bloqueado).
  • Geometria da janela de lançamento: a velocidade do local com polo verdadeiro e com época concorda com o Orekit (4.9e-8); a velocidade por predefinição sem época continua a falhar (1.12e-6). Não promovida; seguimento pendente.
  • Constantes físicas de todos os corpos: agora 0 de 84 diferem do NAIF (uma transcrição), e a orientação calculada concorda com o SPICE até 1.4e-10 rad. Não promovida; seguimento pendente.
  • Bloqueadas por uma decisão de âmbito do responsável, cada uma com a respetiva comparação concordante submetida: observabilidade absoluta de estações lunares, DOP de balizas à superfície, a exportação fora do eixo, potência de deteção entre modalidades, a estatística de consistência em modo comum e cobertura LEO polar.
  • Bloqueadas por dados: orçamento de erro de transferência de tempo (precisa de uma redução com dados reais), C/N0 do JammerTest (posição da antena e divisão de potência não documentadas).

Revisões (números publicados que mudaram, antigo -> novo).

  • Os níveis de proteção de snapshot_raim estão agora no nível local geodésico em vez do radial: até 0,31 m de HPL e 0,14 m de VPL em ABMF (16 graus N); nenhum resultado de referência mudou, mas o resumo registado do tutorial de gnss-sim passa de HPL médio 22,1 m / VPL 40,0 m para 22,2 m / 39,9 m (docs/tutorials/scenarios/gnss-sim.toml).
  • Valores por predefinição do acoplamento de taxa do referencial lunar: d_alpha/d_scale 3.139807e-11 -> 3.138801e-11; d_alpha/d_radial 1.807187e-17 -> 1.806185e-17 por metro.
  • Execução de EOP por predefinição offline (realtime-frame-eop, células listadas em docs/revisions/M035-default-eop-recut-cell-changes.md): predicted_rows 12 -> 90; piso do polo 0,06776 -> 0,05550 mas; eop_term_m 14,01601 -> 14,01583; total_m 20,09759 -> 20,09746; total_time_ns 67,03834 -> 67,03790; as linhas da Tabela 2 de tests/golden/realtime-frame-eop.csv; concordância do previsor operacional 0.256/0.695/1.252/3.885 ms -> 0.133/0.421/0.839/2.786 ms.
  • docs/LEO-NAVMSG.md liu22 SISRE órbita/com relógio: 60 s 0.011/0.046 -> 0.014/0.046 cm; 300 s 0.068/0.139 -> 0.074/0.142 cm; 600 s 0.269/0.299 -> 0.258/0.290 cm.
  • Tabela de altitudes de Liu, Kshana (razão): GRACE-A 5,40 (0,61) -> 4,25 (0,48); GRACE-C 4,12 (0,66) -> 2,87 (0,46); Sentinel-2A 2,95 (1,03) -> 2,20 (0,77); HY-2A 2,38 (1,13) -> 1,25 (0,59); Sentinel-6A 0,70 (0,94) -> 0,51 (0,67).
  • Escala de nDot da mensagem de navegação LEO 2^-60 -> 2^-58 (não fixada antecipadamente, divulgada; fora da comparação de ajuste); o CRC da trama de amostra liu22 0x62373A -> 0xDED99C.
  • Tabela de verificação de docs/LEO-NAVMSG.md: a linha de Liu e ATOMIC dividida numa linha VALIDATED de 22 parâmetros e numa linha MODELLED de ATOMIC e de cinco altitudes.
  • Texto da linha de orientação lunar de eixos principais DE440: intervalo 2024-2025 / 731 linhas -> 2014-2030 / 6 209 linhas; "satura em silêncio" -> erro fora do seu intervalo.
  • Cenário eo-coverage: equatorial_ground_track_spacing_km 2756,37 -> 2752,17 km; novos campos inclination_deg (98,19) e nodal_period_min (98,893).
  • constellation-multi-gnss-coverage (o relógio de referência de TDOP/GDOP é agora a constelação de numeração mais baixa à vista): GDOP global máx. 2,2236 -> 2,1205, média 1,122 -> 1,131, mediana 1,115 -> 1,125, p90 1,255 -> 1,265, p95 1,305 -> 1,315, p99 1,41 -> 1,42, e o mapa de GDOP por célula; mean_visible_by_constellation somado como inteiros (cerca de 1e-12 em termos relativos, invisível a 4 casas decimais).
  • Posição GNSS conjunta de frequência única após a correção do atraso de grupo difundido: 93,2 % -> 93,6 % a menos de 3 m; mediana de ISB -0.351 -> -0.114 ns.
  • tracking-loop jitter_table log10_mean_time_to_cycle_slip_s (laço de Costas SNR rho/4): no limiar de 25,47 dB-Hz 11,58 -> 2,10; a 25 dB-Hz 9,55 -> 1,60; a 22 dB-Hz 2,24 -> -0.14.
  • ins-trn-coast: todas as saídas mudam com o modelo de erro de Schuler; o pico de TRN do cenário fornecido 52,932679 -> 44,711834 m (tests/conflict_resilience_architecture_guard.rs).
  • Relatório de lunar-vlbi: nova chave geometry_path ("analytic" na execução por predefinição, nenhum valor numérico mudou); novos campos opcionais planetary_kernel_path, earth_orientation_kernel_path e moon_orientation_kernel_path, com epoch_partials no caminho por kernel; a descrição do tipo é reescrita. A referência independente do caminho por kernel da linha de verificação é o SPICE (0,06 ps); o ANISE (0,12 ps) passa a ser uma verificação cruzada da avaliação do kernel.
  • Constantes de corpos: GM de Fobos 7.087e5 -> 7.087546066894452e5; Deimos 9.62e4 -> 9.615569648120313e4; Urano 5.7939506103e15 -> 5.793951256527211e15; Neptuno 6.83509997e15 -> 6.835103145462294e15; Plutão 8.69326e11 -> 8.696138177608748e11 (m^3/s^2); raio equatorial de Fobos 13,1 -> 13,0 km; polo e meridiano de referência de Fobos e Deimos a partir de pck00011; o prime_meridian_deg do sistema solar inclui agora os termos quadrático e periódicos.
  • europa-surface-pnt (body-pnt em Europa), a partir da orientação completa de Europa de pck00011 (7cfd66b4; a orientação concorda com o pxform do SPICE até 1.4e-10 rad), que move o módulo de aterragem no espaço inercial: disponibilidade só com retransmissores / com a distância à Terra 0,485 / 0,725 -> 0,480 / 0,719 (83 -> 82 de 171 épocas só com retransmissores), PDOP mediano 5,266 -> 5,360, erro RMS da solução de posição 129,516 / 100,983 m -> 112,742 / 86,147 m, sigma formal mediano 5,266 / 4,272 m -> 5,360 / 4,239 m. A tabela em docs/SOLAR-SYSTEM.md e a fixação em mcp/kshana-mcp/tests/round_trip.rs acompanham; mars-orbit-pnt não muda.
  • space-weather (f107 180, f107a 165, kp 4), com o fator calibrado substituído pelo de Jacchia 1971: activity_density_kg_m3 a 300/400/500/600/800 km 2.602e-11 -> 3.608e-11, 4.176e-12 -> 6.929e-12, 8.136e-13 -> 1.618e-12, 1.769e-13 -> 4.189e-13, 1.544e-14 -> 3.781e-14; activity_factor 1.076/1.121/1.168/1.216/1.320 -> 1.492/1.860/2.322/2.881/3.232; reference_exospheric_temperature_k removido, mean_exospheric_temperature_k acrescentado (1186,7 K); tests/space_weather_reference.rs: a oscilação do ciclo solar a 800 km é agora 10.4x (NRLMSISE-00 13.6x) e a asserção de altitude acompanha a subida do NRLMSISE até 500 km e a descida a 800 km.
  • ntn-5g-positioning toa_median_sigma_3d_m: NR 5 MHz 2,0903959 -> 2,0903962 m; NB 200 kHz 25,938613 -> 25,938839 m (texto do resumo inalterado em 2,09 / 25,94 m).
  • lunar-joint-od-clock (resolução por QR): with_vlbi.station_pos_err_m 3,541344 -> 3,541350 m; without_vlbi.station_pos_err_m 2183,119 -> 2183,558 m.
  • docs/field-units-schema.json reemitido para os campos novos e removidos acima.

Pacotes de validação#

D12, precisão alargada e um solucionador de raiz quadrada (duas novas linhas VALIDATED: 226 -> 228 linhas, 110 -> 112 validadas).

Parte 1, referência independente de precisão alargada:

  • Datum do referencial lunar com as estações estimadas: uma referência independente mpmath de precisão alargada de 50 dígitos (fixada antecipadamente 804662d5, limiares escalados pela condição a partir de uma fórmula de erro retrógrado a priori) concorda numa nova data de campanha (2026-03-18) e no cenário original de 2024-01-01; nova linha VALIDATED sob P2. Resolve a anterior disputa de precisão dupla: os sigmas de datum do motor estão desviados até 9.7e-6, as vias de inversa e de valores próprios do NumPy até 6.2e-6, e as suas vias de Cholesky e QR cerca de 1e-8. O motor está dentro do seu limite de erro mas cerca de mil vezes menos exato do que uma via de fatorização.
  • Ambiente da referência independente: mpmath 1.3.0 acrescentado.
  • Revisões: nenhuma. Nenhum ficheiro de referência nem figura publicada muda; a linha "Lunar frame datum from an observing campaign" continua MODELLED (decisão do fundador de 2026-10-02, opção A: não toma emprestado o estado da linha separada); o seu texto de testes cita o novo teste e a sua constatação.

Parte 2, solucionador de datum de informação em raiz quadrada:

  • Novo solucionador opcional de informação em raiz quadrada (linalg_sr; solver = "srif" no cenário lunar-frame-campaign): QR de Householder, marginalização através do fator triangular, um SVD de Jacobi para o espetro, e produtos compensados apenas a partir de operações corretamente arredondadas. Face à referência independente de 50 dígitos (fixada antecipadamente b41908c9), os seus sigmas de datum concordam até 3e-13 numa nova data (2026-06-09); nas entradas de 2026-03-18 e 2024-01-01 o solucionador por predefinição está desviado até 1e-5. Nova linha VALIDATED sob P2. O solucionador por predefinição e a sua saída não mudam. Os limiares fixados antecipadamente só atestam erros acima de cerca de 2e-7 em termos relativos: rejeitam o solucionador por predefinição mas não um sinal de Householder invertido, um produto escalar não compensado ou uma inversa final espetral, e a linha di-lo.
  • Caminhos opcionais de raiz quadrada a par dos valores por predefinição inalterados: fim::crlb_srif, batch_ls::gauss_newton_srif, orbit_determination::determine_orbit_batch_srif, lunar_combination::formal_covariance_srif, precise_od::fit_srif e cislunar_srif::srif_cross_validation_sqrt, sobre os novos linalg_sr::weighted_lstsq e covariance_from_sqrt_information. Cada um concorda com o seu valor por predefinição onde ambos são exatos (uma verificação interna, sem linha; não é afirmada nenhuma validação para eles). precise_od::fit delega agora numa rotina partilhada; a sua saída e a saída por predefinição de todos os cenários não mudam.
  • Decisões de característica nas campanhas de referencial lunar: uma verificação de precisão alargada fixada antecipadamente ao longo de 40 dias confirma todas as decisões decidíveis de bloco de estação e de Helmert de característica completa. O limite a priori não consegue garantir os 20 dias de Helmert com deficiência de característica; em aritmética exata, o seu defeito é geométrico, com o limiar de 1e-9 dentro do intervalo natural das razões de valores próprios da campanha. Sem linha.
  • A afirmação da linha da campanha de precisão alargada é restringida a "dentro do limite de pior caso", e a sua verificação da direção mais fraca com estações fixas mede agora um ângulo real (6.6e-16 rad; o comparador mudou de acos para uma corda, o limiar não).
  • Revisões: nenhuma. Nenhum ficheiro de referência nem figura publicada muda; a linha "Lunar frame datum from an observing campaign" não muda e continua MODELLED (decisão do fundador de 2026-10-02, opção A).

D4, espinha dorsal de efemérides de kernel JPL, fase 1 (quatro novas linhas VALIDATED: 228 -> 232 linhas, 112 -> 116 validadas).

  • O leitor de kernels NAIF tem uma linha própria. naif_kernel (contentor DAF, SPK tipo 2, PCK binário tipo 2) concorda com o SPICE Toolkit (CSPICE N0067 até spiceypy 8.2.0) e com o ANISE 0.10.6 em todos os 600 estados DE440 e 200 rotações de orientação lunar de uma grelha aleatória extraída a partir do hash do próprio commit de pré-registo (abcd9133), dentro de limiares derivados previamente da avaliação de Chebyshev em dupla precisão (pior caso 0,6 % do limiar, 1.95e-3 m). A linha afirma que o motor lê corretamente os kernels JPL, não que a DE440 ou a série analítica sejam exatas (tests/naif_reader_spice_oracle.rs).
  • ephem_provider::KernelEphemeris: posições DE440 (ou de qualquer SPK de tipo 2) através do leitor do próprio motor, com épocas TDB em duas partes e o SHA-256 do kernel guardado para os relatórios; nunca substitui o baricentro de um sistema por um planeta. LunisolarSource permite que um percurso de geometria escolha a série analítica (a predefinição) ou um kernel.
  • Lua por kernel opcional para lunar-llr-datum e lunar-vlbi-fim: uma chave planetary_kernel_path lê o centro geocêntrico da Lua a partir do kernel; nada mais muda, e o relatório ganha um bloco moon_ephemeris que nomeia o kernel e o respetivo SHA-256. Sem a chave, ambos os relatórios são idênticos byte a byte aos anteriores.
  • Covariância de um ponto da superfície lunar no percurso por kernel (nova linha VALIDATED): com todas as estações fixas e o farol na Lua DE440, a covariância do farol concorda com um jacobiano de tempo de luz do SPICE (pior caso 1.7e-3 face a um limiar de 1 %) e com uma inversa do NumPy (4e-14 face a 1e-9), pré-registado em 4a51256 (tests/lunar_vlbi_surface_point_spice_oracle.rs). A linha do percurso analítico continua MODELLED: na Lua analítica, o seu menor sigma do farol fica 3,9 % abaixo da referência independente.
  • Datum do referencial lunar a partir de uma campanha real, centro da Lua por kernel (nova linha VALIDATED): em 447 pontos normais de 2019-Q2 nunca vistos, pré-registado em 830d945a antes de qualquer um ter sido obtido, a covariância do datum no percurso por kernel concorda com a referência independente inalterada do SPICE e do NumPy dentro de 7.6e-5 face a limiares de 1 % e 2 % (tests/validate_llr_datum_kernel_moon_fresh.rs). O fundador decidiu que esta linha só é promovida com pontos novos; o diagnóstico com dados já vistos (c51f8b2) é uma constatação, não uma evidência. O limiar não discrimina modelos da Lua: a Lua analítica também passa na mesma fatia (pior caso 3.8e-3), a mutação planeada (a Lua por kernel uma hora atrasada) não foi detetada e, na dobra, um centro da Lua errado em cerca de 4 650 km (a Lua tomada em torno do baricentro Terra-Lua) também passou. A linha afirma a covariância nesse percurso, não o centro da Lua, e di-lo.
  • Posições do Sol, da Lua, de Mercúrio e de Vénus a partir da DE440 em épocas UTC (nova linha VALIDATED): KernelEphemeris::relative_position_utc concorda com o Skyfield 1,54 em 600 posições entre 1973 e 2026, pior caso 2,96 m, dentro de um limiar pré-registado (0bfafe6d) definido pela série TDB − TT de dois termos (tests/kernel_ephemeris_skyfield_oracle.rs). As posições dos planetas passam a ter agora esta nova linha de kernel; a linha Standish e a linha das luas planetárias ficam inalteradas, e as luas aguardam um cenário que precise delas (decisão do fundador).
  • Constatações: a única falha da comparação do datum LLR (sigma da translação em z de 1,025 % face a 1 %) desce para 0,049 % quando apenas o centro da Lua é lido da DE440, com dados já vistos (tests/validate_llr_datum_kernel_moon.rs); na fatia nova de 2019 a Lua analítica também passa, pelo que a falha de 2015 era marginal para a geometria desse trimestre. As linhas analíticas "Lunar frame datum from a REAL observing campaign" e "Lunar-surface-point coordinate covariance … kept distinct from the Earth-station one" continuam MODELLED; os textos das suas referências independentes passam a apontar para as linhas do percurso por kernel.
  • lunar_ephemeris deixa de dizer que o motor não tem leitor de kernels binários; aponta para a linha do leitor e explica por que razão os kernels de veículos espaciais (tipos 13 e 21) continuam a vir do Horizons.
  • Revisões: nenhuma. Nenhum ficheiro de referência, valor publicado ou valor de teste existente muda; os relatórios analíticos lunar-llr-datum, lunar-vlbi-fim e lunar-vlbi-fim com todas as estações fixas são idênticos byte a byte aos anteriores (prefixos SHA-256 do resultado 9927aac2, cf1d2671, 25c357e4).

D9, biblioteca de relógios medidos "Clock Atlas" (três novas linhas, uma VALIDATED: 232 -> 235 linhas, 116 -> 117 validadas).

  • Biblioteca de relógios medidos (clock_library). Cartões de dispositivo (modulação de fase branca, de frequência branca, flicker e de passeio aleatório, uma deriva linear de frequência e, opcionalmente, termos de fase de uma a quatro por revolução) ajustados a um registo de relógio medido com nome e avaliados em dados reservados; variâncias de Allan e de Hadamard com tratamento de lacunas; um detetor de condicionamento que regista todas as lacunas, valores atípicos de fase, saltos de fase, rajadas e saltos de frequência e nada sabe de limites de ficheiro ou de dia; conversão de um cartão para o modelo de ruído de temporização de slot, o modelo de relógio de Kalman estendido e os níveis de ruído do monitor de spoofing. Leitores para ficheiros de relógio RINEX e IGS, ficheiros por laboratório do BIPM e a Secção 1 da Circular T (realdata::clk); um limite de envelhecimento hierárquico agregado para UTC(k) (utck_bound, ainda não avaliado).
  • Identificação de ruído por autocorrelação de atraso 1 (allan::lag1_noise_id, Riley e Greenhall 2004), nova linha VALIDATED (Biblioteca): concorda com o allantools 2024,6 autocorr_noise_id em 140 casos, inteiros idênticos, pior diferença 9.6e-13 face a um limiar de 1e-9 (pré-registado 2ec76864; tests/clock_library_lag1_noise_id_allantools.rs).
  • Cartões de dispositivo medidos com previsão em dados reservados, nova linha MODELLED (uma constatação): ajuste num terço, previsão do desvio de Allan dos outros dois terços dentro de um fator de 1,5 (pré-registado 2ec76864). GPS Block IIF numa janela IGS nova (2026-03-01 a 14): 10 de 11; o G27 é otimista à escala de duas horas (pior fator 1,510). Césio (dentro, 1,070), OCXO (fora, 2,348) e estrôncio (dentro) são comunicados, não cegos. O cartão do recetor JammerTest e os cartões do maser Galileo e do Deep Space Atomic Clock estão bloqueados. Uma classe de modelo de TCXO de recetor ZED-F9P em 12 estações estáticas de Wroclaw (Zenodo 6488497) falha: 1 de 11 estações cegas numa nova execução corrigida e divulgada (tests/clock_library_device_cards_oracle.rs, tests/clock_library_f9p_cards_oracle.rs).
  • Cartões GPS Block IIF com termos por revolução, nova linha MODELLED (uma constatação): numa segunda janela nova (2026-04-01 a 14), 9 de 11 dentro do limiar; o G03 (1,947) e o G25 (1,581) são otimistas porque os seus registos reservados são mais ruidosos do que os terços de ajuste; retirar os termos periódicos falha nos 11 (pré-registado fb475550; tests/clock_library_periodic_cards_oracle.rs).
  • M002, estimação do estado do relógio de bordo, ronda 3 (uma constatação, continua MODELLED): depois do detetor de condicionamento congelado, o filtro estendido da ronda 2, com afinação e critérios inalterados, satisfaz (a) e (c) em todos os 11 satélites pela primeira vez; (b) falha no G09 (0,894) e no G26 (0,876) (pré-registado fb475550; tests/clock_state_ext_igs_conditioned_oracle.rs).
  • M010, deteção de spoofing, rondas 3 a 4b (continua MODELLED): ronda 3 bloqueada (167 épocas de treino das outras sessões da unidade JammerTest face a 3600); com um cartão de classe de modelo ZED-F9P (rondas 4 e 4b) o monitor de relógio gera zero falsos alarmes antes do início em todos os 10 inícios registados (ronda 2: 86) e 6 de 10 inícios são detetados em 10 s (ronda 2: 4); os mesmos quatro continuam atrasados (tests/clock_library_tcxo_card_jammertest_oracle.rs).
  • M083, sobrelimite de UTC(k), ronda 3: pré-registado de forma prospetiva (fb475550) em emissões da Circular T a partir de 465, ainda não executado (tests/utck_bound_prospective_oracle.rs).
  • Ambiente da referência independente: o registo ZED-F9P de Wroclaw fica sujeito a transferência de dados em $KSHANA_ORACLES/data/wroclaw_f9p (CC BY 4,0, cerca de 1,5 GB); os ficheiros de teste de relógio IGS estão incluídos no repositório (produtos IGS, com atribuição).
  • Revisões: nenhuma. Nenhum ficheiro de referência, valor publicado ou valor de teste existente muda; a M001 (reancoragem de holdover) não é aplicada porque nenhuma classe de relógio foi promovida.

D8, um percurso validado de propagação, referencial e tempo (três novas linhas VALIDATED e M131 promovida: 235 -> 238 linhas, validadas 117 -> 121).

Os tipos de cenário de órbita terrestre que tinham os seus próprios modelos de dois corpos, de J2 secular ou apenas de tempo sideral partilham agora um único percurso: conjuntos de elementos SGP4/SDP4 com datas julianas em duas partes, levados para o GCRS e o ITRS (International Terrestrial Reference System) através da cadeia IAU (International Astronomical Union) 2006/2000A, com parâmetros de orientação da Terra opcionais.

  • Novos sgp4::MeanElementSet, sgp4::SgpOrbit, sgp4::Eop, sgp4::teme_to_itrs_matrix[_eop] e sgp4::gcrs_to_itrs_matrix[_eop]; Sgp4::new_at e Sgp4::propagate_at aceitam épocas em duas partes. Novos jd2::Jd2::from_utc_calendar (convenção SOFA dtf2d para dias com segundo intercalar), jd2::utc_to_tai, tai_to_utc, utc_to_ut1 (através do TAI, como o SOFA utcut1), tai_to_tt e um jd2::earth_rotation_angle em duas partes.
  • O modo polar de leo-pvt propaga por SGP4 em 2026-01-01T00:00:00 UTC na cadeia IAU (leo_fusion::polar::latitude_sweep_at aceita qualquer época); o gerador Walker SGP4 roda para o referencial fixo à Terra através da cadeia IAU.
  • O tipo de cenário passes executa um novo preditor de passagens aparentes (passes::predict_passes_apparent, apparent_look_angles): SGP4 na cadeia IAU, refração ITU-R P.834-9 e o tempo de luz da ligação descendente (novos interruptores refraction e light_time, ativos por predefinição), parâmetros de orientação da Terra (ut1_minus_utc_s, xp_arcsec, yp_arcsec, predefinição 0), cruzamentos resolvidos até 1e-7 s e a culminação por pesquisa de secção áurea. O passes::predict_passes geométrico fica inalterado.
  • tests/no_private_models.rs impede que os núcleos de geometria, tempo e propagação do pacote tenham uma propagação kepleriana própria, taxas de J2 seculares ou uma rotação apenas por tempo sideral; os escalões rápidos com nome e a física que é o objeto de uma linha são exceções fundamentadas.
  • Nova linha VALIDATED "Two-part Julian dates and leap seconds on the Earth-orbit time path": pyerfa 2.0.1.5 dtf2d/utctai/taiutc em 224 instantes em torno de todos os 27 segundos intercalares, dentro de 1e-6 s (pré-registado e947e69d); pior caso 1.9e-11 s.
  • Nova linha VALIDATED "One Earth-orbit path": posições TEME de 232 conjuntos de elementos face ao python-sgp4 2,24 (o SGP4 de referência de Vallado) dentro de 6.1e-8 m (limiar de 1 cm), e as rotações GCRS -> ITRS e TEME -> ITRS face ao ERFA c2t06a, pnm06a e ee06a dentro de 2.9e-6 mas e 0,41 mas (limiares de 0,1 e 2 mas), com parâmetros de orientação da Terra (pré-registado 72ea9eb0). Divulgado: a primeira execução falhou em 2016-12-31T23:59:59,5 por um segundo de rotação; o UT1 foi obtido a partir da data juliana quase-UTC num dia com segundo intercalar, o motor passa agora pelo TAI, e a segunda execução concorda com os limiares inalterados.
  • M131 "LEO coverage and dilution of precision for polar and Arctic users against MEO GNSS" passa a VALIDATED: o Orekit 13.1.8 recebe os estados GCRS do motor, roda-os e calcula a visibilidade e o DOP (NumPy para grupos de vários relógios); posições dentro de 6.8e-5 m (limiar de 0,2 m), contagens de satélites à vista idênticas em 4040/4040 amostras, DOP mediano dentro de 2.3e-11 em termos relativos.
  • Nova linha VALIDATED "Apparent ground-station pass prediction with refraction and light time": o Orekit 13.1.8 a propagar os mesmos conjuntos de elementos num TEME construído por si segundo a definição indicada, com refração ITU-R P.834 e o seu modelo de medição de tempo de luz, em 60 casos em estações ao nível do mar: 1210 passagens, cruzamentos dentro de 3.4e-6 s (limiar de 5 ms), elevação máxima dentro de 5.5e-7 deg, direção aparente dentro de 8.8e-7 deg (limiar de 1e-4 deg).
  • Constatações, mantidas fixas: as primeiras comparações de alegação completa de ponta a ponta com o Orekit falharam os limiares de posição e de direção, não por causa do motor mas porque o SDP4 do Orekit 13.1.8 afasta-se do SGP4 de referência em órbitas de espaço profundo circulares (e = 0) (até 67 m) e o seu TEME predefinido é construído sobre a nutação IERS 1996 (IAU 1980), a cerca de 72 milissegundos de arco da cadeia IAU 2006/2000A (2,7 m em LEO). O coeficiente ITU-R P.834 de h*theta0^2 no Orekit é 0,011380 onde a Recomendação imprime 0,01380; a comparação é ao nível do mar, onde o termo se anula, e a diferença acima dele fica fixada.
  • "Ground-station pass prediction (ground segment)" continua VALIDATED com a sua alegação restringida ao passes::predict_passes geométrico; o tipo de cenário passes pertence à nova linha.
  • Ambiente da referência independente: Orekit 13.1.8 com Hipparchus 4.0.3, pyerfa 2.0.1.5, python-sgp4 2,24 (xval/d8-orekit13/setup.sh).
  • Revisões: scenarios/passes.toml incluído, acesso total 1675 s -> 1659 s (cinco passagens como antes; melhor elevação máxima 73,25 deg -> 70,08 deg), e todas as saídas de passes mudam com o novo percurso (a linha impressa em docs/examples/multi-tool-pipeline.md e a entrada passes de docs/CAPABILITY.md passam a dizê-lo); polar-arctic-leo-coverage incluído, VDOP GNSS no equador 1,19669 -> 1,19710, a 89,9 deg 1,50645 -> 1,50590, VDOP fundido a 89,9 deg 1,14388 -> 1,14250 (os valores publicados com duas casas decimais 1,20, 1,51 e 1,14 ficam inalterados). Nenhum ficheiro de referência muda.
  • Ainda não encaminhados: leo_pass, os modos doppler, conjunto e de temporização de leo-pvt e a órbita de referência de leo_navmsg (os seus modelos estão em leo_link::geometry e leo_fusion::geom), e os projetos terrestres em constellation-design (um escalão rápido de dois corpos com nome).

D6, gerador de referência LunaNet AFS, LSIS V1.0 (quatro novas linhas, duas VALIDATED: 238 -> 242 linhas, validadas 121 -> 123).

  • Gerador de referência LunaNet Augmented Forward Signal (AFS) (lunar_afs), fixado ao LunaNet Signal-In-Space Recommended Standard (LSIS) V1.0 de 29 de janeiro de 2025 e a nomear essa versão em todas as saídas: a portadora de 2492,028 MHz; o canal de dados AFS-I BPSK(1) a 500 símbolos por segundo com o seu código Gold de 2046 chips; o piloto AFS-Q BPSK(5) com os seus códigos primário Weil de 10230 chips, secundário de 4 chips e terciário de 1500 chips; a trama de identificador 0 (padrão de sincronização, subtrama 1 BCH (51, 8), CRC-24, subtramas 2 a 4 LDPC de taxa um meio, entrelaçador de blocos de 60 por 98) com um descodificador exaustivo da subtrama 1 e um descodificador LDPC min-sum escrito apenas a partir da matriz de verificação de paridade; e síntese de IQ em banda de base com etiquetas de referência escritas como gravação SigMF. Os códigos são gerados a partir dos registos de deslocamento e das construções de Legendre/Weil da norma. Nada copiado da norma é redistribuído (ela não tem termos de reutilização): os índices primários do AFS-Q provêm da IS-GPS-800J, e o que apenas os anexos da norma definem (atrasos G2 do AFS-I, códigos terciários, submatrizes LDPC) é lido em tempo de execução a partir de uma cache local que xval/lunar-afs/fetch_lsis.sh preenche a partir do PDF alojado pela NASA, com cada ficheiro verificado face a um SHA-256 fixado (lunar_afs::lsis). O modelo é uma referência de aderência à norma, não um modelo de canal, de propagação ou de balanço de ligação.
  • sigmf::meta_to_json_with_extensions e sigmf::annotation_extension_fields: uma gravação pode transportar campos de extensão com espaço de nomes declarados em core:extensions.
  • Nova linha VALIDATED "LunaNet AFS baseband rendering against an independent generator, given its channel state": face ao LANS-AFS-SIM (BSD-2-Clause, commit 480c6bf3, compilação de banda S), zero discrepâncias de chips nos códigos dos PRN 1 a 210, zero discrepâncias de símbolos nas três tramas da execução, e uma correlação complexa normalizada de 0,999990 em 23,9 s das suas próprias amostras (pior bloco de 2 ms 0,999948), dentro de limiares fixados antes da comparação (pré-registado 986ac280). Aciona o renderizador com o estado de canal do próprio simulador e não abrange a repartição de potência a partir da densidade portadora-ruído nem a escrita em SigMF e em 8 bits.
  • Nova linha VALIDATED "LunaNet AFS frame channel coding, FID 0": as tramas de 6000 símbolos são iguais às do LANS-AFS-SIM símbolo a símbolo (pré-registado 986ac280); o código da subtrama 1 reproduz o exemplo trabalhado da Figura 8 do LSIS e o CRC-24 o valor de verificação do catálogo CRC-24/LTE-A.
  • Ambas as linhas promovidas dependem de dados da cache LSIS: o seu teste de referência independente é ignorado com um aviso até que xval/lunar-afs/fetch_lsis.sh tenha sido executado.
  • Constatação (nova linha MODELLED), "LunaNet AFS spreading-code generation": de 2 937 232 chips e bits gerados e comparados com as tabelas da norma e os ficheiros do Anexo 3, um difere, os "últimos 24 chips" que a Tabela E-5 imprime para o PRN terciário 147, que duplica a célula do PRN 151, enquanto o próprio ficheiro do Anexo 3 da norma concorda com o gerador. O critério de zero discrepâncias não é satisfeito.
  • Constatação (nova linha MODELLED), "LunaNet AFS closed-loop decodability": três execuções pré-registadas face ao PocketSDR-AFS; a terceira satisfez integralmente os limiares de seguimento e de descodificação, mas não a sua salvaguarda de que uma compilação do recetor apenas com impressão reproduz o registo da compilação fixada, porque duas execuções do recetor não modificado já diferem nos seus registos de aquisição.
  • Corrigido: a portadora predefinida de lunar_service (export_antenna.carrier_hz), lunar_jamming e attack_surface era um valor arredondado de 2,4 GHz; é agora a portadora AFS LSIS-020, 2492,028 MHz. Com a predefinição antiga, a perda em espaço livre estava subestimada em 0,327 dB.
  • Revisões: nenhuma. Todos os cenários incluídos indicam a sua portadora, e os resultados de todos os 138 ficheiros de cenário são idênticos byte a byte aos do main anterior.

D7, IQ lunar real e GPS LNAV (sete novas linhas, nenhuma VALIDATED: 242 -> 249 linhas, validadas 123 sem alteração).

  • portable_math::FftPlan: uma transformada rápida de Fourier (FFT) de base mista cuja saída tem os mesmos bits em todas as plataformas; um SHA-256 fixado das transformadas de 8000 e 24000 pontos passa em x86_64 e em wasm32-wasip1 (executor em xval/portable-fft-wasm/).

  • acquisition: pesquisa paralela de fase de código em IQ amostrado (pcps_acquire, pcps_grid) com dobragem coerente, acumulação não coerente, um limiar de qui-quadrado para uma probabilidade de falso alarme em toda a pesquisa e uma estatística de média por célula para ruído de banda limitada; refine, prompt_series com Doppler de código, e os estimadores de densidade portadora-ruído (C/N0) M2M4 e de pico da grelha.

  • gps_lnav: um codificador da mensagem de navegação legada (LNAV) da IS-GPS-200 para as subtramas 1 a 3, com a paridade da Tabela 20-XIV e um descodificador de campos.

  • realdata::ion_sdr: um leitor do ION GNSS SDR Metadata Standard (.sdrx) e dos seus ficheiros de amostras, com to_mid_rise para níveis em complemento para dois.

  • realdata::lugre: o cabeçalho de lote IQS do LuGRE (Lunar GNSS Receiver Experiment), a telemetria RAW, ACQ e NAV e os ficheiros CLK, e uma verificação que lista onde os metadados de .sdrx contradizem o cabeçalho binário.

  • antenna::GainPattern2D e, em earth_gnss_lunar, o referencial do corpo com orientação por guinada, os ângulos de azimute de transmissão e fora do nadir, e transmit_side_db para C/N0 relativo com diagramas medidos.

  • Codificação da mensagem de navegação GPS LNAV (nova linha, continua MODELLED após a pós-verificação do integrador): no ficheiro de difusão IGS de 2 de março de 2025, analisado e descodificado pelo RTKLIB v2.4.2-p13, todas as 960 palavras passam a paridade, todas as 96 subtramas são descodificadas e todos os 608 inteiros difundidos são iguais aos do Kshana (tests/gps_lnav_rtklib_integer_oracle.rs), mas o pré-registo (d4d9eb9d) chegou ao ramo público dois segundos depois do commit que contém o resultado, pelo que a ordem "registado antes de o ficheiro ser obtido" não pode ser demonstrada e a linha não é promovida.

  • realdata::ion_sdr preenche as palavras a partir do bit mais significativo (I no nibble alto de um byte LuGRE; a leitura anterior produzia o sinal conjugado), mantém a leitura antiga como SdrLayout::fill_lsb_first e lê amostras mais largas do que uma palavra.

  • acquisition::refine_doppler_coherent: refinamento Doppler coerente em fase (0,2 Hz RMS a 30 dB-Hz em 200 ms em simulação).

  • GPS L1 C/A face ao gps-sdr-sim: chips e bit de paridade exatos ao bit; 230 de 1152 campos LNAV diferem em uma unidade porque o gps-sdr-sim trunca onde o inteiro difundido exige arredondamento.

  • LNAV descodificado pelo RTKLIB: toda a paridade e todas as subtramas passam e todos os parâmetros estão a menos de meio quantum; 41 valores escalados diferem em algumas unidades da última casa através da constante decimal 2^-43 do RTKLIB, acima do limiar registado.

  • Aquisição LuGRE face ao GNSS-SDR 0.0.19: 266 de 266 decisões concordam, 250 localizadas na mesma célula; a maioria dos positivos são artefactos de uma média de −0,5 nos níveis de 4 bits em bruto; a vertente de C/N0 não teve dados de voo contemporâneos. Dois lotes (OP5, OP12) foram excluídos por erro: os seus metadados concordam com os cabeçalhos, mas o leitor então não conseguia ler uma amostra mais larga do que uma palavra.

  • Aquisição LuGRE face ao Doppler previsto pela órbita: com a decisão pela potência da amostra, todas as pesquisas cruzam em ruído de banda limitada; com a decisão por média por célula, os pares mais fortes concordam em módulo com o sinal invertido, o que mostra que a ordem I/Q registada é o conjugado dos dados.

  • Aquisição cega nos lotes da superfície lunar: quatro lotes adquirem cada um um satélite (previsto visível, sem falso alarme a 1e-7), nenhum adquire dois, pelo que o limiar da diferença de Doppler não tem nenhum par para avaliar.

  • C/N0 relativo à distância lunar (M039 reformulada): 15 registos Block IIR/IIR-M e um par, poucos demais para o limiar registado.

  • Revisões: nenhuma; nenhum número publicado, ficheiro de referência ou valor da documentação mudou.

  • A linha M039 "Earth-GNSS at lunar distance" reformula a sua alegação à distância lunar como o C/N0 relativo entre satélites numa época mais a visibilidade (não se alega o C/N0 absoluto); continua MODELLED. O NOTICE de nível superior contém a atribuição CC BY 4,0 do LuGRE.

Corrigido#

  • A orientação dos eixos principais lunares da DE440 é agora interpolada ao longo da geodésica entre nós diários. A interpolação anterior, elemento a elemento, tinha um erro de até 2.0e-4 rad (340 m na superfície lunar) perto dos pontos de quarto de cada dia, e não os "cerca de 14 m" que a linha indicava. Os seus utilizadores (geometria de telemetria laser lunar, datum lunar, observabilidade de falhas lunares) recebem a orientação corrigida.
  • Correções do motor da ronda 2, cada uma executada de novo face à sua tolerância pré-registada inalterada: a versão IERS de uma linha EOP é lida a partir das suas flags I/P e não de um bloco Bulletin B em branco; snapshot_raim usa o nível local geodésico; o acoplamento do referencial de taxa lunar usa o raio equatorial, o J2 e a rotação; o ajuste liu22 parte de correções nulas sem priors e usa a taxa de movimento médio do artigo; o espaçamento dos nós EO inclui a regressão nodal de J2; o tempo de salto de ciclo de Costas usa rho/4; a solução conjunta aplica o atraso de grupo difundido do par; a resolução conjunta lunar usa um passo QR; o limite NTN é avaliado na posição verdadeira; a referência de relógio do projeto de constelação é a constelação mais baixa à vista; a série de orientação DE440 abrange 2014-2030 e dá erro fora desse intervalo em vez de truncar.

Adicionado#

  • leo_navmsg::truth::TruthOrbit::from_ecef_states, uma órbita de referência construída a partir de estados tabelados fixos à Terra, usada pela comparação do ajustador de órbita real.
  • Os ficheiros de teste e os ficheiros de dados das comparações acima, cada um com o seu gerador e um NOTICE.md que indica a fonte, a licença, a data de obtenção e o SHA-256.
  • Ronda 2: araim_reference::add_v42_protection_levels e _ecef (deteção de falhas ADD v4.2, a seguir o Stanford MAAST para o ARAIM 2, aviso BSD-3 no código-fonte); raim::snapshot_raim_fde; cw_dynamics::second_order_correction e propagate_second_order; o modelo de erro INS de nove estados inertial::coast::ErrorDynamics; derivadas parciais de lunar_vlbi::KernelGeometry e as entradas de lunar-vlbi do percurso por kernel; naif_kernel, um leitor de kernels SPK de tipo 2 e PCK binários; lunar_llr_geometry::llr_bcrs_one_way_m com estações ITRF2020; densidade de Jacchia 1971; solar_system::link_on sobre qualquer fornecedor de efemérides; launch::site_rotation_speed_at; eo_payload::j2_nodal_period e ground_track_spacing_equator_j2; batch_ls::gauss_newton_qr; precise_products (leitores de relógio RINEX, ANTEX e DCB).

[0.29.3] - 2026-10-01#

Uma versão de correção sobre a 0.29.2. O Kshana Studio é reconstruído em torno de duas vistas: uma vista Simples, que responde primeiro e explica em palavras simples, e uma vista Avançada com o painel completo. Acompanham-na duas pequenas correções em kshana.dev. O motor não muda: todos os cenários incluídos dão um resultado idêntico byte a byte ao da 0.29.2, exceto a marca de versão.

Alterado#

  • O Kshana Studio tem uma vista Simples. É a vista em que o Studio abre.
    • A resposta vem primeiro: um cenário abre no seu resultado, indicado numa frase simples. Cada cenário incluído tem a sua própria frase, escrita para aquilo que esse cenário mede.
    • São mostradas no máximo cinco definições, as que mais alteram a resposta. As restantes ficam em "Definições avançadas", recolhidas até serem abertas.
    • "Como isto é calculado" explica o método em poucas linhas, e "Para investigadores" apresenta os valores do próprio motor, o ficheiro do cenário e as evidências por trás do resultado.
  • O painel completo é a vista Avançada. Todos os painéis, gráficos, exportações e relatórios do Studio anterior estão lá.
  • Um interruptor alterna entre as duas vistas e mantém o ponto em que se estava. O cenário, a vista em que se estava e quaisquer definições editadas transitam consigo. O Studio lembra-se da última vista utilizada. As ligações do site e da documentação abrem a vista Simples; uma ligação com view=advanced abre a vista Avançada, e todas as ligações anteriores do Studio continuam a abrir o mesmo cenário e a mesma vista.
  • Uma primeira vista mais rápida em ligações lentas. A resposta registada de um cenário é desenhada antes de o resto do Studio carregar, pelo que, numa ligação móvel lenta, a resposta aparece em cerca de dois segundos em vez de cerca de nove.
  • Melhor pesquisa. Uma pesquisa lista agora primeiro os cenários cuja área ou título corresponde às palavras, antes dos cenários que apenas as mencionam no nome do ficheiro ou no texto.

Corrigido#

  • O globo da página inicial deixa de ficar em branco com o movimento reduzido ativo. Com a definição do sistema para movimento reduzido ativa, redimensionar a janela podia deixar o globo principal vazio até a página ser deslocada. O globo é agora redesenhado no mesmo fotograma do redimensionamento.
  • A consola de banda L da página inicial explica a sua banda vazia. Em "Watch a jammer take the band", o painel GPS L5 / Galileo E5a ficava escuro durante todo o minuto, o que parecia uma avaria. Nenhum jammer transmite nessa banda neste cenário, e os sinais dos satélites ficam abaixo do piso de ruído, pelo que nada ali se eleva acima dele. Uma etiqueta discreta di-lo agora em qualquer troço de painel sem nada acima do piso (o painel L5 / E5a e o painel L2C antes de o seu jammer de ruído começar), com o C/N0 e o estado de bloqueio de cada banda da mesma execução. Só é colocada onde nada está acima do piso, pelo que nunca cobre energia de jammer.

0.29.2 - 2026-10-01#

Uma versão de correção sobre a 0.29.1. Remove código duplicado nos módulos de mensagem de navegação LEO, de fusão e de espetro, acrescenta um tema claro a kshana.dev, move o Kshana Studio para o seu próprio endereço, torna o site legível por motores de pesquisa e por assistentes de IA, corrige várias pequenas coisas no Studio e permite que as versões npm sejam publicadas sem um token guardado. Nenhuma saída do motor muda: todos os cenários incluídos dão um resultado idêntico byte a byte ao da 0.29.1, exceto a marca de versão.

Adicionado#

  • Um tema claro para kshana.dev. Todas as páginas podem ser lidas em modo claro ou escuro. O site segue a definição do sistema do leitor e tem um interruptor para a alterar.
  • Os motores de pesquisa e os assistentes de IA conseguem ler o site. Cada página tem agora o seu próprio título, descrição, endereço canónico, etiquetas de cartão social e dados estruturados schema.org, e texto simples para as secções que um script desenha. O site publica robots.txt, um sitemap.xml com a data da última alteração de cada página, llms.txt e llms-full.txt (um guia curto e um guia completo em texto simples para assistentes de IA), e uma chave IndexNow para que uma publicação possa indicar aos motores de pesquisa o que mudou.
  • As versões npm podem ser publicadas sem um token guardado. A tarefa npm executa agora Node 24 e npm 11.5.1 ou posterior, que suportam a publicação fidedigna do npm: o npm troca a identidade GitHub da tarefa de versão por uma credencial de curta duração. O segredo NPM_TOKEN continua a funcionar e é usado enquanto estiver definido, pelo que nada muda até a publicação fidedigna ser ativada para o pacote em npmjs.com. docs/RELEASING.md enumera os passos.

Alterado#

  • O título da página inicial é legível sobre o globo. Uma sombra suave fica agora por trás do título e do seu texto, esbatendo as linhas de órbita e os pontos de satélite do globo animado onde o cruzam.

  • O Kshana Studio tem o seu próprio endereço: https://kshana.dev/studio/. Todas as ligações do site e da documentação apontam para lá. O endereço antigo, /playground/, continua a funcionar e reencaminha para o novo, mantendo na ligação o cenário, a vista e as restantes definições.

  • Correções do Studio. O ficheiro do motor é descarregado uma vez em vez de duas. Enquanto é descarregado, o Studio mostra de imediato o resultado registado do cenário, identificado como registado, em vez de um ecrã vazio. Num telemóvel, o cabeçalho é uma única linha compacta. Os valores principais são dispostos dois por linha, pelo que nenhum fica escondido fora do lado do ecrã. As etiquetas dos campos usam as palavras do próprio cenário, com o nome do campo a seu lado, e a pesquisa encontra campos por qualquer um deles.

  • Menos código duplicado. A tabela de unidades da mensagem de navegação LEO escrevia as mesmas dez linhas de estatísticas SISRE para quatro resumos de ajuste. Uma macro escreve-as agora uma só vez. Os dois gráficos em cascata de espetro partilham um eixo de tempo, uma barra de cor e um painel de barra de C/N0. A subamostragem da grelha principal reutiliza downsample_grid, e o integral de Simpson reutiliza navsignal::simpson. Os dois pontos de entrada do tipo de cenário de passagem LEO partilham um passo de configuração. leo_link::geometry importa os auxiliares vetoriais de leo_fusion::geom em vez de os copiar. O relatório avançado importa o escape de HTML do relatório da API em vez de o copiar. Cada um dos 139 ficheiros de cenário em scenarios/ foi executado na 0.29.1 e com este código, e todos os ficheiros de saída são idênticos byte a byte.

  • As tabelas de unidades de leo-navmsg e leo-pvt têm os seus próprios ficheiros. Saíram de módulos que também contêm lógica, para src/leo_navmsg/units.rs e src/leo_fusion/pvt_units.rs. PVT_UNITS mantém o seu caminho público. Apenas estes dois ficheiros de tabelas se juntam às isenções de deteção de copiar e colar para catálogos declarativos em sonar-project.properties, que tests/sonar_cpd_exclusions_are_justified.rs verifica.

Corrigido#

  • O emblema de CI do README mostra o resultado dos pushes para main. O emblema contava execuções de todos os eventos em main, pelo que podia indicar "failing" enquanto todas as execuções de push estavam verdes; agora pede apenas execuções de push (event=push).

0.29.1 - 2026-10-01#

Uma versão de correção sobre a 0.29.0: o valor de cobertura medido, a linha com o nome do projeto em kshana.dev, uma tarefa de cobertura mais rápida e um README renovado. Nenhuma saída do motor muda: todos os cenários dão o mesmo resultado que na 0.29.0.

Revisões de números publicados#

  • Cobertura de linhas: ~96 % → ~95 %. A tarefa de cobertura voltou a medir o código da 0.29.0 publicada (commit db796dd, execução de CI 36809850252, 2026-10-01): 95.35 %, 55 970 de 58 697 linhas de src/. O valor publicado era 95,63 % (37 697 de 39 419 linhas), medido em b1d350d antes da 0.28.0; arredondava para ~96 %. O novo valor arredonda para ~95 %, pelo que todas as superfícies que tests/coverage_figure_doc_sync.rs fixa mudam em conjunto: docs/COVERAGE.md, o emblema do README, a linha de evidências e a tabela de CI, os emblemas do crates.io, do PyPI e do npm, o relatório técnico e a página de cobertura de kshana.dev. O mínimo de 85 % mantém-se.

Adicionado#

  • A linha com o nome em kshana.dev. "Kshana · क्षण · the precise instant" abre agora o cabeçalho principal da página inicial e fica sob a marca no rodapé de todas as páginas. O kshana.dev continua a não fazer qualquer pedido a outro anfitrião: o devanágari é um subconjunto Noto Sans Devanagari alojado no próprio site, com as três letras de क्षण (1 692 bytes, web/fonts/, com o texto da sua SIL Open Font License e o seu SHA-256 em web/fonts/FONTS.json). web/tools/fetch_third_party.py aprendeu a guardar um subconjunto text= do Google Fonts com um nome de ficheiro endereçado por conteúdo.

Alterado#

  • As ligações do site aterram onde apontam, em endereços limpos. Uma ligação para uma secção coloca agora essa secção logo abaixo do cabeçalho, num telemóvel e num computador de secretária: uma ligação para um setor de Missions abre esse setor com o seu painel no topo; as ligações de Capabilities e de Editions mantêm o seu lugar enquanto os gráficos acima delas são desenhados; Editions deixa de acrescentar um segundo desvio de cabeçalho; e uma ligação para uma parte recolhida de uma página da documentação abre-a. Todas as páginas são ligadas pelo seu endereço limpo (/evidence#research, /docs/changelog, / para a página inicial), e as ligações canónicas, o mapa do site e os redirecionamentos dos endereços antigos indicam os mesmos; os endereços .html continuam a funcionar. A secção Research tem a sua própria ligação no cabeçalho, entre Evidence e Developers, e no rodapé. A documentação deixa de mostrar o roteiro (ROADMAP.md continua no repositório): o grupo Project é Changelog, Licensing, Security, Contributing, Governance e Code of conduct, e o Glossary passou para Get started.
  • A tarefa de cobertura é mais rápida. Na 0.29.0 demorou 143 minutos, face a uns saudáveis 91 a
    1. O fuzzer tests/property.rs, a causa da última vez, ocupou 4 deles. O corpus incluído passou de 74 para 139 cenários, e três binários de teste percorriam-no todo, um ficheiro de cada vez (determinism duas vezes, advanced_report e animation uma vez): 37 minutos no total sob instrumentação de cobertura, face a 3 na 0.27.2. Agora partilham tests/support/corpus.rs, que executa o trabalho por cenário em todos os núcleos e devolve os resultados por ordem; todos os cenários e todas as asserções se mantêm. Num portátil arm64, compilação de depuração: determinism demora 143 s em 14 núcleos face a 612 s com KSHANA_CORPUS_THREADS=1 (o antigo percurso em série).
  • O README, renovado. Abre com a mesma linha de nome do site; as capturas de ecrã do Studio foram refeitas a partir do Studio da 0.29.1, com uma nova do Studio num telemóvel e da sua barra de passos inferior; uma nova faixa "The site" mostra três páginas de kshana.dev da compilação da 0.29.1 (tools/capture_site_shots.mjs, compostas por tools/readme_shots.py e registadas em docs/assets/readme/site/SHOTS.json); o valor de cobertura indica ~95 %; e o texto alternativo da figura de investigação, que repetia o da figura de arquitetura, descreve agora os artigos. Os emblemas do cabeçalho são mais pequenos e mais curtos (18 px de altura; "~95%", "83/223", "quality", "AGPL-3.0", "zenodo.20528627"), pelo que os onze cabem em duas linhas; todas as ligações e todos os textos alternativos mantêm o seu significado completo.
  • A tarefa da imagem de contentor passa a ter 90 minutos. Em v0.29.0, a compilação linux/arm64 emulada da imagem kshana-mcp atingiu o antigo limite de 45 minutos ao compilar o seu último crate, pelo que a imagem, a entrada no registo MCP e a verificação do canal não foram publicadas. O limite é agora de 90 minutos; a imagem não muda.
  • Oito literais de vírgula flutuante reagrupados em src/ephem.rs e src/sgp4.rs (0.323_273_64 → 0.323_273_640): o SonarQube Cloud lia um último grupo de _64 ou _32 como um sufixo f64 ou f32 em falta (regra S7454). Os valores são os mesmos números, pelo que todos os resultados ficam inalterados.

0.29.0 - 2026-10-01#

Doze novos tipos de cenário e três novas formas de ler uma execução. O motor passa a abranger o espetro de radiofrequência, todo o sistema solar, constelações em torno de qualquer corpo, campanhas que encadeiam cenários numa só missão e posicionamento, navegação e temporização (PNT) a partir da órbita terrestre baixa (LEO), do sinal à solução de posição. Cada execução pode também ser escrita como uma animação, um relatório completo e um conjunto de ficheiros de interoperabilidade para outras ferramentas.

Em torno do motor: um kshana.dev redesenhado (um site de várias páginas e um novo painel Kshana Studio que executa todas as capacidades no navegador), um README reescrito, catorze ferramentas no servidor do Model Context Protocol (MCP), uma compilação para navegador que dá os mesmos números que a nativa e uma página pública para o Kshana Pro.

0.28.0 0.29.0
Tipos de cenário 63 75
Ficheiros de cenário (mais um manifesto de conjunto) 77 138, dos quais 132 estão incluídos para kshana example
Linhas da matriz de verificação 174 223
das quais VALIDATED face a uma referência independente externa 66 83
dos quais MODELLED (modelo declarado, verificado quanto à consistência interna) 104 136
dos quais PARTNER (requer equipamento ou dados de um parceiro) 4 4

De onde vem o crescimento:

Área Tipos de cenário Ficheiros de cenário Linhas da matriz (validadas + modeladas)
Espetro 1 1 3 (1 + 2)
Sistema solar e posicionamento em torno de qualquer corpo 2 3 6 (2 + 4)
Projeto de constelações 1 3 3 (2 + 1)
Campanhas 1 5 3 (0 + 3)
Cenários marítimos, rodoviários e ferroviários 0 5 0
Animação, relatórios, exportações de interoperabilidade 0 0 0
Projetos de sinal LEO e o espetro multibanda 1 4 4 (2 + 2)
Passagem LEO e balanço de ligação 1 6 9 (6 + 3)
Mensagem de navegação LEO 1 5 9 (3 + 6)
Posicionamento, temporização e fusão em LEO 3 8 8 (1 + 7)
Cadeia LEO de ponta a ponta 1 3 1 (0 + 1)
Cenários LEO de resiliência, de área de foco e de utilizador final 0 18 3 (0 + 3)
Total acrescentado 12 61 49 (17 + 32)

A capacidade LEO é independente de qualquer sistema: funciona com parâmetros genéricos e declarados e não precisa de nenhum sistema com nome. Os sistemas com nome são predefinições opcionais, cada uma no seu próprio ficheiro com a sua fonte pública. Uma predefinição, o Celeste IOD (demonstração em órbita), usa valores apresentados no workshop LEO-PNT do ESA NAVISP, 2026 (ESA é a Agência Espacial Europeia; NAVISP é o seu Programa de Apoio e Inovação em Navegação); vive num só ficheiro, src/celeste_iod.rs, com os seus cinco cenários só de repositório, pelo que pode ser retida sem uma alteração ao código-fonte, e nenhum dos seus valores do workshop é repetido neste registo de alterações.

Leia "Revisões de números publicados" antes de atualizar. Uma saída do motor muda (as colunas de referencial inercial do tipo de cenário ephemeris, após a correção de um sinal na matriz de nutação), e a auditoria da documentação corrigiu valores que documentos anteriores tinham impresso.

Abreviaturas usadas nesta entrada

Estados: VALIDATED significa verificado face a uma referência externa independente (uma tabela publicada, o software de outro grupo ou dados medidos); MODELLED significa um modelo declarado verificado apenas quanto à consistência interna; PARTNER significa que a verificação requer equipamento ou dados de um parceiro.

Abreviatura Significado
3GPP, 5G, NTN 3rd Generation Partnership Project; rede móvel de quinta geração; rede não terrestre
AD, BC eras do calendário (anno Domini, antes de Cristo)
AIAA American Institute of Aeronautics and Astronautics
AltBOC, BOC, BPSK, MBOC portadora de desvio binário alternativa; portadora de desvio binário; modulação por deslocamento de fase binária; portadora de desvio binário multiplexada (modulações de sinal)
ATOMIC Autonomous Time and Orbit Determination for Microsatellite Constellations (um modelo de efemérides LEO publicado)
C/A, L1, L2, L2C, L5 código de aquisição grosseira e os nomes das portadoras e dos sinais civis do Global Positioning System
C/N0 relação portadora-densidade de ruído
CIO Celestial Intermediate Origin
CLI interface de linha de comandos
CRC-24Q verificação de redundância cíclica de 24 bits (polinómio da Qualcomm)
CSAC relógio atómico à escala de chip
CSS, HTML, SVG, XML Cascading Style Sheets; HyperText Markup Language; Scalable Vector Graphics; Extensible Markup Language
CSV, JSON, PDF, TOML, URL valores separados por vírgulas; JavaScript Object Notation; Portable Document Format; Tom's Obvious Minimal Language; localizador uniforme de recursos
CW onda contínua
CZML, KML, GeoJSON Cesium Language; Keyhole Markup Language; Geographic JSON (formatos de mapa e de globo)
DE441 Development Ephemeris 441 do Jet Propulsion Laboratory
DOI identificador digital de objeto
DOP, GDOP, PDOP, HDOP, VDOP diluição da precisão: geométrica, de posição, horizontal, vertical
E1, E5, E5a, E5b nomes de sinais do Galileo
E3F o nome de uma posição na tabela da constelação do Global Positioning System
ECEF centrado na Terra e fixo à Terra
EE equação dos equinócios
EGM2008 Earth Gravitational Model 2008
EIRP potência isotrópica radiada equivalente
ERFA, SOFA Essential Routines for Fundamental Astronomy; Standards of Fundamental Astronomy (bibliotecas de astronomia de referência)
ESA, NAVISP Agência Espacial Europeia; o seu Programa de Apoio e Inovação em Navegação
FDMA acesso múltiplo por divisão de frequência
GCRF, GCRS Geocentric Celestial Reference Frame; Geocentric Celestial Reference System
GLONASS o sistema global de navegação por satélite da Rússia
GNSS, GPS sistema global de navegação por satélite; Global Positioning System
IAU União Astronómica Internacional
ICD, OS SIS ICD, OS SDD documento de controlo de interface; Galileo Open Service Signal-In-Space Interface Control Document; Galileo Open Service Service Definition Document
ICRF International Celestial Reference Frame
IMO Organização Marítima Internacional
INS, MEMS sistema de navegação inercial; sistema microeletromecânico
IOD demonstração em órbita
IQ em fase e em quadratura
IS-GPS-200 a especificação de interface do Global Positioning System
ISS Estação Espacial Internacional
ITRF, ITRS, PEF, TEME International Terrestrial Reference Frame; International Terrestrial Reference System; pseudo fixo à Terra; equador verdadeiro, equinócio médio (referenciais)
ITU, ITU-R União Internacional das Telecomunicações; o seu Setor das Radiocomunicações
J/S relação jammer-sinal
J2 to J6, J2000 harmónicas zonais do campo gravítico; a época 2000-01-01 12:00
JPL Jet Propulsion Laboratory
LEO, MEO órbita terrestre baixa; órbita terrestre média
MBSE engenharia de sistemas baseada em modelos
NEES erro de estimação normalizado ao quadrado
NeQuick-G o modelo de ionosfera do Galileo
OEM, SP3, TLE Orbit Ephemeris Message; Standard Product 3 (órbitas precisas); conjunto de elementos de duas linhas
PNT, PPP posicionamento, navegação e temporização; posicionamento preciso de pontos
PSD, SSC densidade espetral de potência; coeficiente de separação espetral
RAIM, SQM monitorização autónoma da integridade pelo recetor; monitorização da qualidade do sinal
RINEX, RTCM Receiver Independent Exchange Format; Radio Technical Commission for Maritime Services
RMS raiz do valor quadrático médio
RTKLIB uma biblioteca de código aberto de posicionamento GNSS, usada aqui como referência independente
SGP4 Simplified General Perturbations 4 (o modelo orbital dos conjuntos de elementos de duas linhas)
SHA-256 Secure Hash Algorithm, 256 bits
SigMF Signal Metadata Format
SISRE erro de alcance do sinal no espaço
SPS PS Standard Positioning Service Performance Standard
SRTM Shuttle Radar Topography Mission
STK Systems Tool Kit (o seu formato de ficheiro de efemérides .e)
STL Satellite Time and Location
SVID identificador de veículo espacial
T/P/F o total de satélites, planos e faseamento de uma constelação Walker
TEC conteúdo eletrónico total
UHF ultra-alta frequência
UTC Tempo Universal Coordenado
WGS 84 World Geodetic System 1984
X1, X5 nomes de sinais do sistema Xona Pulsar

Revisões de números publicados#

Um número publicado que mude é uma revisão e fica registado, nunca corrigido em silêncio. Esta versão traz uma revisão a uma saída do motor e várias a valores impressos na documentação.

Saída do motor

  • A redução TEME→GCRS rodava em 2·Δψ: a matriz de nutação tinha o sinal de Δψ invertido. nutation::numat construía Rx(−(ε̄+Δε))·Rz(Δψ)·Rx(ε̄) onde o iauNumat do SOFA constrói Rx(−(ε̄+Δε))·Rz(−Δψ)·Rx(ε̄), pelo que nutation_matrix, nutation_matrix_2000a, teme_to_gcrs e gcrs_to_teme rodavam o dobro da nutação em longitude, cerca de 25 segundos de arco. Todas as verificações da cadeia eram testes de propriedades (rotação própria, ida e volta, uma contribuição de nutação não nula) que um erro de sinal satisfaz; o teste de Vallado de ponta a ponta cobria TEME→PEF, TEME→ITRF e GCRS→ITRS, mas não TEME→GCRS. No exemplo de Vallado (AIAA 2006-6753, 2004-04-06), a cadeia falhava o GCRF publicado em 1 145 m; agora fica a 0,11 m dele, e a matriz é igual ao numat do ERFA a 1e-14. tests/frame_reference_vectors.rs::teme_to_gcrs_matches_vallado_gcrf e nutation::tests::nutation_matrix_matches_erfa_numat falham ambos com o sinal antigo. O teste de consistência do CIO (Celestial Intermediate Origin) em src/cio.rs tinha atribuído a discordância resultante de ~130 m a "≈ 2·EE"; o resíduo é agora de 5 cm e o seu limite foi apertado de 250 m para 1 m. Isto altera números publicados, registados aqui como uma revisão: as colunas gcrs_r_m e gcrs_v_m_s do tipo de cenário ephemeris (cerca de 0,8–1,0 km para o cenário ISS (International Space Station) incluído; as suas colunas TEME, fixas à Terra, de traço no solo, de ângulos de visada e de Doppler não mudam), e Propagator::position_in_frame / state_gcrs para os referenciais GCRS e ITRS. Nenhuma linha de resumo, gráfico ou hash de referência de nenhum cenário incluído lê estas colunas. As novas exportações de interoperabilidade usam a cadeia corrigida: a posição CZML do primeiro satélite orbit-sgp4-gps concorda com uma redução ERFA do mesmo TLE (propagado pelo pacote Python sgp4) a 2,3 cm.
  • O tipo de cenário leo-navmsg, nativamente e na compilação para navegador. O tipo de cenário calcula agora todas as funções transcendentes através de uma única biblioteca matemática portável, pelo que a sua trama tem os mesmos bytes em todas as plataformas e em todas as compilações (em Fixed). Todos os valores de leo-navmsg mudam com isso, assim como a fase navmsg de leo-pnt-chain. O tipo de cenário é novo nesta versão, pelo que nada de uma versão anterior muda, mas mudam valores impressos antes da correção: o valor de verificação de docs/LEO-NAVMSG.md para o cenário de codificação e descodificação era 0x110315 e é 0x19105F, e o seu SISRE da mensagem descodificada é 0,129 cm. Em kshana.dev, o cartão de Missions para leo-navmsg-fit-interval-trade mostrava um pior erro de alcance de 1,6 mm com um ajuste de 60 s e 40,3 mm com um ajuste de 900 s; o site é agora construído a partir do motor desta versão e mostra 1,8 mm e 46,6 mm.
  • O mapa da pegada de jamming em kshana.dev (Missions). Cada uma das suas 875 células é uma execução de maritime-strait-jamming em que apenas muda a posição do recetor. As células são agora calculadas a partir das mesmas coordenadas com três casas decimais que a ligação "abrir esta execução" da célula entrega ao Kshana Studio, pelo que uma célula mostra exatamente o que a sua ligação reproduz. A relação média jammer-sinal (J/S) de 30 células muda em 0,1 dB, para cima ou para baixo; a disponibilidade de seguimento de nenhuma célula muda. O motor dá resultados idênticos para todas as células na 0.28.0 e na 0.29.0.
  • Reamostragem com semente no pacote WebAssembly (WASM). A compilação para navegador extraía índices de bootstrap e de permutação diferentes dos da compilação nativa a partir da mesma semente (em Fixed). O intervalo quantum-anomaly-detect da área sob a curva no navegador era [0.9901265, 0.9938305] e é agora o nativo [0.99035875, 0.993861]. Nenhum número nativo muda.

Valores impressos na documentação

A documentação foi auditada palavra a palavra face a execuções do motor desta versão. Quando um valor impresso não coincidia com a execução, o documento foi corrigido, e cada correção está aqui listada, antigo → novo. Em todos os casos abaixo a saída do motor não mudou; o documento tinha-a lido mal, arredondado mal ou ficado desatualizado.

  • Auditoria da documentação das páginas de espetro, constelação, campanha, animação, relatório e interoperabilidade, e um novo docs/SOLAR-SYSTEM.md. Todos os valores foram executados de novo com este motor. Dois números publicados mudam: docs/CONSTELLATION-DESIGN.md indicava o teste de cobertura de 5 000 satélites como "cerca de 0,13 s numa compilação de depuração"; isso não se reproduziu (1,24 s num portátil sobrecarregado), pelo que a página indica agora a parcela do pré-filtro que o teste imprime (9,9 % de 19 440 000 testes de pares) e os 0,14 s do binário de lançamento para o leo-pnt-mega-shell incluído. A mesma página indicava o cruzamento do E3F como "desviado 0,050 deg"; nenhum teste imprime esse valor, pelo que a página indica agora apenas o limiar de 0,06 deg que o teste impõe e a derivação de 7,30 face a 7,36 deg que está por trás dele. Nenhuma saída do motor muda.
  • Documentos LEO-PNT: valores publicados revistos (executados de novo no motor desta versão). Compromisso de bandas em docs/LEO-SIGNAL.md: o atraso ionosférico de primeira ordem de generic-s é 3,24 m (estava impresso 3,25 m) e o de generic-c-wide é 0,77 m (era 0,78 m). Codificação e descodificação em docs/LEO-NAVMSG.md: o SISRE da mensagem descodificada estava impresso como 0,119 cm quando a execução dava 0,122 cm; a página imprime agora 0,129 cm, o valor após a correção de independência de plataforma em Fixed, abaixo. Passagem LEO face a GNSS em docs/LEO-PASS.md: menos 32 dB de perda em espaço livre no pico da passagem (era "26 a 32 dB"). Quanto aos valores de sinal e de passagem, a saída do motor não mudou; os documentos tinham-na lido mal ou arredondado mal.
  • Tutoriais, o exemplo de pipeline trabalhado e o comando /kshana-run, auditados face ao motor desta versão. Revisões de valores publicados, antigo → novo: os tipos de cenário que escrevem <scenario>.table.csv são seis, não quatro (faltavam leo-navmsg e telecom-timing; docs/tutorials/README.md, commands/kshana-run.md); o cruzamento ½bT² de átomos frios no Tutorial 3 é 18 443 s, não 18 440 s; o erro de ida e volta de oem-interop em docs/examples/multi-tool-pipeline.md é o valor medido de 4.88e-7 km, não "~1e-7 km"; a banda de holdover do CSAC no Tutorial 2 é a de 2000–3200 s que o teste afirma, não "~2600–4400 s"; o Tutorial 1 cita as linhas SP3 e o bloco de geometria com a precisão com que o motor os escreve. Nenhuma saída do motor mudou.
  • Páginas de validação, quântica, SGP4, animação, alegações e integridade. docs/VALIDATION.md: o limiar imposto sobre o desvio de Allan simulado a um segundo de um relógio de ruído de frequência branco é 20 % (estava impresso 25 %; o limiar de 25 % é o da curva a 1, 10 e 100 s); a linha do passeio aleatório de velocidade indica agora o seu limiar imposto de 20 % ao lado dos cerca de 12 % observados; e a disponibilidade do relógio atómico à escala de chip em orbit-gnss-challenged é cerca de 0,73 (estava impresso cerca de 0,83). docs/QUANTUM.md: o ruído por disparo limitado por vibração no exemplo trabalhado de átomos frios da página é cerca de 46 vezes o seu piso de ruído de disparo (estava "~45×"; recalculado 46,49), e o intervalo "1–50 µg/√Hz" para dispositivos em campo, que contradizia um dispositivo que a própria página cita, é substituído pelos valores publicados dos dois dispositivos citados. docs/SGP4-VALIDATION.md: a pior diferença de posição é 4,12 mm (estava "≈ 4 mm"), com o satélite identificado. docs/ANIMATION.md: o exemplo do codificador de vídeo lia os fotogramas de 24 fotogramas por segundo a 12; agora usa 24, a taxa que o manifesto de fotogramas indica. docs/CLAIMS-VS-REALITY.md: o modelo de jamming tem 10 testes (eram 8), e o "2,97 m face a 48,8 m" do filtro acoplado é substituído pelo que o seu teste afirma (o erro de posição acoplado abaixo de 0,6 vezes o desacoplado, ganhando em pelo menos 90 de 100 ensaios). docs/INTEGRITY.md: a marca "Today" indicava v0.22.0; agora indica esta versão, e duas capacidades construídas entretanto (o modo de falha à escala da constelação e a mensagem de suporte de integridade) saem da sua lista de lacunas.

Adicionado#

Espetro

  • Tipo de cenário spectrum: um modelo de espetro de banda L e cascata (src/spectrum.rs, src/sigmf.rs, docs/SPECTRUM.md). Toda a banda L do GNSS como uma única densidade espetral de potência (PSD): GPS L1 de aquisição grosseira (C/A) e L2 civil (L2C) (BPSK(1)), Galileo E1 (portadora de desvio binário multiplexada, MBOC(6,1,1/11), ou BOC(1 1)), GPS L5 e Galileo E5a (BPSK(10)), um piso de ruído kT com um fator de ruído do recetor, e jammers de onda contínua (CW), de banda estreita, de varrimento (chirp) e de ruído adaptado numa cronologia programada. Cada jammer é avaliado por banda pelo seu coeficiente de separação espetral (SSC), dando a relação jammer-sinal (J/S) e a densidade portadora-ruído (C/N0) efetiva por banda e por linha. O gráfico é uma cascata SVG com barras de C/N0; o result.json contém a grelha com média de blocos em potência. [iq] opcional desenha o modelo como amostras IQ, escreve e lê uma gravação Signal Metadata Format (SigMF) (cf32_le, ci16_le) e compara uma estimativa de Welch com o modelo; [recording] opcional estima um ficheiro SigMF real. Exemplo incluído scenarios/l-band-waterfall-jamming.toml: um chirp apanha o L1 C/A e o E1 aos 10 s, um tom CW na portadora L1 mantém o C/A em 17,98 dB-Hz depois de o chirp parar enquanto o E1, cujo espetro tem um nulo aí, recupera; o L5 e o E5a ficam intocados.
    • Nova linha VALIDATED: as PSD e os SSC dos sinais, face ao lóbulo principal de BPSK(n) de 2n x 1,023 MHz, aos lóbulos de BOC(1 1) centrados em +/-1.023 MHz, às formas fechadas de Parseval por trás dos SSC publicados de -61.8 / -64.8 / -67.8 dB/Hz, e ao Q = 1 (CW) e 1,5 (adaptado) dos manuais. O máximo da PSD de BOC(1 1) está em +/-0.759 MHz, não no centro do lóbulo; o teste fixa ambos.
    • Duas novas linhas MODELLED: a cascata e a cronologia de C/N0, que se reduzem exatamente à cadeia do tipo de cenário jamming (verificadas em cruzamento em todos os relatórios), e o codec SigMF e o estimador de Welch. Nenhuma gravação de terceiros está no repositório.
    • navsignal: uma variante MBOC e spectral_separation_coeff_offset.
    • O relatório imprime o C/N0 que a tabela Q representativa do tipo de cenário jamming daria, ao lado do derivado do espetro; para um tom CW na portadora C/A diferem em 1,8 dB. Três novas linhas da matriz: uma validada (espetros de sinal e coeficientes de separação espetral) e duas modeladas.

Sistema solar

  • Efemérides do sistema solar e posicionamento em torno de qualquer corpo. Dois novos tipos de cenário.
    • solar-system: o Sol, os oito planetas, Plutão, a Lua, Fobos, Deimos, Io, Europa, Ganimedes, Calisto e Titã numa época: posição e velocidade heliocêntricas no International Celestial Reference Frame (ICRF), parâmetro gravitacional, raios, J2 (a segunda harmónica zonal) quando publicado, rotação sideral, o polo e o meridiano de origem da União Astronómica Internacional (IAU), uma trajetória orbital ao longo de uma revolução, e o tempo de luz, o alcance de ida e de ida e volta, o atraso de Shapiro solar e a separação do Sol a partir de um corpo observador e para qualquer ligação adicional. Os planetas provêm dos elementos keplerianos do Jet Propulsion Laboratory (JPL) de Standish e Williams (Tabela 1, 1800 AD a 2050 AD; Tabelas 2a/2b, 3000 BC a 3000 AD); as luas, dos elementos médios do JPL com a taxa de rotação síncrona da IAU, e Titã, do modelo de rotação da IAU. Exemplo: scenarios/solar-system-tour.toml.
    • body-pnt: um orbitador ou um módulo de aterragem à superfície em torno de qualquer um desses corpos, a navegar com pseudo-distâncias de uma constelação Walker em torno do corpo e com um alcance de ida e volta sem relógio a partir da Terra; diluição da precisão, incerteza formal e soluções de posição por mínimos quadrados com semente, com e sem a ligação à Terra. Exemplos: scenarios/mars-orbit-pnt.toml, scenarios/europa-surface-pnt.toml.
    • Body passa a incluir Mercúrio, Vénus, Júpiter, Saturno, Úrano, Neptuno, Plutão e as sete luas, uma pesquisa por nome e um registo físico; AnalyticSolarSystem dá qualquer corpo relativamente a qualquer outro através da interface EphemerisProvider já existente.
    • VALIDATED face ao JPL Horizons (Development Ephemeris DE441; ficheiros de teste e consultas em tests/fixtures/solar_system/): Mercúrio a Saturno e a Terra a partir da Tabela 1 dentro do dobro do erro nominal indicado (pior caso 1,87 vezes), todos os oito planetas a partir das Tabelas 2a/2b (pior caso 1,71 vezes), e o tempo de luz da Terra a Marte e a Júpiter. MODELLED: Úrano e Neptuno a partir da Tabela 1, que excedem o erro indicado face à DE441 (2,0 e 5,2 vezes), Plutão, as luas, as constantes dos corpos e os resultados de body-pnt.
    • Constatação: a série lunar de Montenbruck & Gill em src/ephem.rs já está referida ao equinócio J2000 pelo seu próprio termo de precessão (0,05 graus face ao Horizons), pelo que é usada sem uma rotação de precessão adicional. Seis novas linhas da matriz: duas validadas (posições dos planetas, tempo de luz) e quatro modeladas.

Constelações em torno de qualquer corpo

  • Projeto de constelações em escala (tipo de cenário constellation-design, src/constellation.rs). Padrões Walker delta e Walker estrela (T/P/F), listas explícitas de elementos e projetos de várias camadas, várias constelações por execução, em torno da Terra, da Lua, de Marte ou de qualquer outro planeta, de Plutão ou de uma lua importante, a partir das constantes dos corpos acrescentadas pelo tipo de cenário solar-system. Predefinições a partir de elementos nominais publicados: a linha de base do Global Positioning System (GPS) e a constelação expansível de 24 posições (Standard Positioning Service Performance Standard, SPS PS, 2020), o Galileo Walker 24/3/1 (Open Service Service Definition Document, edição 1,1), a órbita terrestre média do BeiDou Walker 24/3/1 mais satélites geoestacionários e geossíncronos inclinados (Open Service Performance Standard 3,0) e o GLONASS 24/3/1 (Interface Control Document 5,1). Cobertura e diluição da precisão (DOP) numa grelha de latitude/longitude: satélites à vista, GDOP, PDOP, HDOP e VDOP (geométrica, de posição, horizontal, vertical) e disponibilidade por célula, a nível global e no pior local, com um relógio de recetor por constelação. Um pré-filtro de visibilidade (semiângulo de cobertura mais uma banda de latitude subsatélite, exato num corpo esférico) executa 5 000 satélites numa grelha de 10 deg em cerca de 0,13 s numa compilação de depuração.
    • VALIDATED: o gerador Walker reproduz a Tabela 23 do SDD do Galileo OS e a fórmula de posições do ICD do GLONASS; a predefinição GPS reproduz a coluna de cruzamento do equador do SPS PS (35 de 36 locais dentro de 0,0108 deg; E3F dentro de 0,06 deg, sendo a própria linha da tabela inconsistente); a distribuição global de HDOP da linha de base GPS concorda com o Apêndice B do SPS PS (mediana 0,940 face a 0,94, 95 % 1,255 face a 1,25, média 0,965 face a 0,96; limiar 0,03).
    • MODELLED: projetos arbitrários, outros corpos, os nós de fase e geossíncronos inclinados do BeiDou, órbitas de dois corpos com J2 opcional, apenas geometria.
    • Cenários: constellation-multi-gnss-coverage (102 satélites, disponibilidade 100 %, PDOP mediano 0,95, 31,0 à vista acima de 10 deg), leo-pnt-mega-shell (5 000 satélites, disponibilidade 99,22 % com PDOP de 3 ou menos acima de 20 deg, 0 % nas calotas polares, o pré-filtro mantém 11,5 % dos testes de pares), lunar-relay-constellation (14 satélites em torno da Lua, disponibilidade 21,33 % no total e máxima sobre a região polar sul). Os três estão incluídos para kshana example. Notas: docs/CONSTELLATION-DESIGN.md. Três novas linhas da matriz: duas validadas (gerador Walker e predefinições GNSS, DOP global do GPS) e uma modelada.
  • Uma campanha conduzida pelo modelo de espetro, e constelações em torno de qualquer corpo. scenarios/campaign-spectrum-holdover-integrity.toml encadeia o tipo de cenário spectrum com um holdover de relógio e um monitor de integridade (um chirp apanha o L1 C/A e o E1; um tom CW mantém então o C/A em baixo enquanto o E1 recupera e o recetor recua para um céu apenas Galileo), fixado face ao exemplo de cascata autónomo em tests/campaign_composition_reference.rs. constellation-design resolve agora o seu corpo central através de Body::by_name, pelo que uma constelação pode ser colocada em torno de qualquer planeta, de Plutão ou de uma lua importante com as constantes que o tipo de cenário solar-system usa.

Campanhas

  • Campanhas: muitos cenários compostos numa só execução. Um novo tipo de cenário campaign (src/campaign.rs, documentado em docs/CAMPAIGNS.md) executa membros de tipos de cenário existentes através do mesmo despacho da linha de comandos e lê números dos seus resultados. Quatro secções, em qualquer combinação:
    • [[phases]]: uma missão encadeada numa só cronologia. As predefinições por tipo de cenário leem o erro de tempo do relógio face ao seu limite de guarda, a relação média efetiva portadora-densidade de ruído (C/N0) face ao piso de seguimento, o nível de proteção vertical face ao limite de alerta, o erro de posição, os satélites em seguimento e as sinalizações de alarme, mantidos numa grelha comum com fronteiras de fase e eventos. O estado é transmitido por carry, handoff e end_at.
    • [sweep]: de uma a três chaves com pontos de qualquer tipo de cenário, opcionalmente com um conjunto com semente em cada nó.
    • [monte_carlo]: realização k com semente base + k, com média, dispersão, percentis e um intervalo de confiança bootstrap de 95% com semente fixa.
    • [compose]: valores partilhados ligados a vários membros, com um resumo combinado do melhor e do pior caso. Cada resultado contém um hash de campanha e um resumo criptográfico de todos os resultados dos membros. Quatro cenários incluídos: campaign-jam-spoof-holdover-integrity (nominal, jamming, spoofing terminado na deteção do monitor de relógio aos 370 s, holdover a transportar o desvio de 37,0 ns do spoofing com uma unidade inercial em navegação por estima, um alarme de integridade, recuperação), campaign-sweep-jammer-power, campaign-shared-jammer-sea-road e campaign-monte-carlo-clock-holdover. tests/campaign_composition_reference.rs fixa as identidades da composição: uma campanha de uma só fase reproduz a execução autónoma bit a bit em três tipos de cenário, um conjunto com semente fixa é estável byte a byte e, num relógio de ruído de frequência branco, a média do conjunto fica dentro do intervalo comunicado, com a dispersão dentro do intervalo qui-quadrado de sqrt(q_wf * tau) = 16,459 ns. Três novas linhas modeladas da matriz.

Animação

  • Exportação de animação (--animate svg|html|frames|all, src/animation.rs, docs/ANIMATION.md). Qualquer execução cujo resultado contenha uma série temporal pode agora ser escrita como um ficheiro Scalable Vector Graphics (SVG) animado (keyframes de Cascading Style Sheets, sem script: os traços desenham-se atrás de um cursor de tempo em movimento), um único leitor HyperText Markup Language (HTML) autónomo (reproduzir e pausar, deslocar, velocidade, todos os painéis num cursor sincronizado, marcadores de eventos que saltam ao clicar; sem recursos externos) ou uma sequência numerada de fotogramas SVG com um manifest.json que indica os fotogramas por segundo, a duração e os tempos dos fotogramas para um codificador de vídeo. Uma campanha é reproduzida como as suas fases com os seus alarmes marcados; uma execução de espetro anima a sua cascata linha a linha. O leitor respeita prefers-color-scheme, e com prefers-reduced-motion tanto o SVG como o leitor mostram a imagem final em vez de se moverem. --animate-fps e --animate-duration definem a reprodução; kshana::api::animate_toml e kshana::animation::animate_result são os pontos de entrada da biblioteca, e result.json ganha um bloco animation apenas quando --animate é executado. A saída é uma função pura do resultado e das opções, idêntica byte a byte numa nova execução, sem marca temporal. Um tipo de cenário sem eixo temporal amostrado é recusado com "no time series to animate" e nada é escrito. O exportador desenha as amostras da própria execução e não acrescenta nenhum número, pelo que é MODELLED (consistência interna) e não tem linha na matriz de verificação; nenhum número publicado muda. Testes: tests/animation.rs (determinismo, contagem de fotogramas, nenhum endereço externo, XML bem formado, o caminho de movimento reduzido e todos os cenários incluídos com uma série temporal a animar-se).

Relatórios

  • Relatórios avançados de execução (src/advanced_report.rs, docs/REPORTS.md). Cada execução da interface de linha de comandos (CLI) escreve agora <scenario>.report.html, um relatório HyperText Markup Language (HTML) imprimível, e <scenario>.report.json, o mesmo conteúdo como documento JavaScript Object Notation (JSON) legível por máquina. Secções: um resumo executivo; todas as entradas do cenário com a sua unidade, lida do esquema de unidades dos campos (o bloco units do resultado), ou então do sufixo do nome do campo, ou então indicada como não indicada; os resultados com o gráfico da execução, todos os escalares e um resumo de cada coluna numérica; para uma campanha, a tabela de nós do varrimento, a média de Monte Carlo, o desvio-padrão, os percentis 5.º / 50.º / 95.º e o intervalo de confiança bootstrap com um histograma por métrica, a tabela de fases da cadeia, ou os membros e o resumo combinado da composição (e a grelha de uma execução sweep ou sweep-nd); uma cronologia de eventos; a etiqueta VALIDATED / MODELLED / PARTNER, a referência independente e as evidências de teste de cada linha da matriz de verificação que os tipos de cenário da execução exercitam, lidas da matriz através de uma correspondência entre tipo de cenário e linha (uma linha que avalia um caminho de entrada, como o caminho Simplified General Perturbations 4 (SGP4) de orbit ou o caminho de registo medido de slot-timing, só é listada quando a execução seguiu esse caminho, e a linha do leitor da Shuttle Radar Topography Mission (SRTM) não é listada para nenhum tipo de cenário, dado que nenhum campo de cenário lê um mosaico SRTM); as declarações de não modelado e os pressupostos, cada um citado com a sua fonte; e um registo de reprodutibilidade (versão do motor, o commit de origem quando a compilação define KSHANA_GIT_COMMIT, resumos Secure Hash Algorithm de 256 bits (SHA-256) do ficheiro do cenário e do documento de resultado, semente, plataforma e o comando exato). O relatório não lê nenhum relógio: o mesmo cenário, a mesma semente e a mesma compilação do motor dão um relatório idêntico byte a byte, e a única marca temporal que pode mostrar é a que --study-name já escreve. Uma folha de estilo de impressão ajusta-se a A4 e US Letter, repete os cabeçalhos das tabelas e mantém linhas e figuras inteiras entre páginas; um ficheiro Portable Document Format (PDF) é feito com o "Guardar como PDF" do navegador. Não existe a opção --report pdf, porque desenhar os gráficos num PDF exigiria uma dependência nova e pesada. Testes: tests/advanced_report.rs comunica todos os cenários incluídos (nenhuma secção vazia, nenhum texto provisório, etiquetas iguais às da matriz, o resumo do cenário igual ao do ficheiro, idêntico byte a byte numa nova execução) e tests/advanced_report_cli.rs executa de novo o comando registado num diretório novo e exige um result.json idêntico byte a byte. Nenhum número publicado muda, e as contagens de tipos de cenário, de ficheiros de cenário e de linhas da matriz ficam inalteradas.
  • O relatório, a animação e as exportações funcionam em conjunto. O relatório avançado ganha uma secção "Animação e exportações": o desenho animado da execução incorporado como imagem inerte (ou o motivo de não existir), ligações para os ficheiros de animação e de exportação escritos a seu lado, e cada formato de interoperabilidade com a indicação de se se aplica, porque não, e a sua especificação; report.json contém o mesmo bloco companions. O leitor de animação HTML lista os ficheiros de exportação escritos a seu lado. A interface de linha de comandos (CLI) passa a gerar as exportações antes de escrever o relatório, para que ambos possam nomear os ficheiros.

Exportações de interoperabilidade

  • Exportações e importações de interoperabilidade (--export, src/interop/, docs/INTEROP.md). kshana <scenario.toml> --export <format> escreve a geometria do cenário como CZML (a Cesium Language), KML (Keyhole Markup Language 2,2, uma norma do Open Geospatial Consortium, com trajetórias gx:Track com marcas temporais), GeoJSON (Internet Engineering Task Force Request for Comments 7946) e efemérides Ansys STK (Systems Tool Kit) .e (EphemerisTimePosVel, metros, um ficheiro por objeto em movimento), e o instantâneo IQ (em fase e em quadratura) sintetizado do tipo de cenário spectrum como um par SigMF (Signal Metadata Format) através do src/sigmf.rs existente. --export all escreve todos os formatos aplicáveis e imprime porque os restantes não se aplicam; --export list comunica sem executar. Os objetos em movimento são escritos no Geocentric Celestial Reference System (CZML INERTIAL, STK ICRF) e em longitude, latitude e altura WGS 84 (World Geodetic System 1984) fixas à Terra (KML, GeoJSON); os locais fixos em CZML são FIXED. O tipo de cenário jamming acrescenta duas pegadas de jammer a partir das suas próprias equações de ligação. --import-route <file.geojson> escreve um LineString GeoJSON nas entradas de trajetória de terrain-nav, terrain-slam, gravity-map e combined-altpnt. As exportações são deterministas ao byte e não contêm marca temporal. tests/interop_formats.rs valida todas as exportações face à sua especificação publicada, compara os estados de satélite exportados com os do próprio motor a 1 mm e executa todos os cenários incluídos por todos os formatos, cada um a exportar ou a indicar porque não (a tabela em docs/INTEROP.md). Nenhum número publicado muda: a síntese IQ do tipo de cenário spectrum passou para uma função partilhada e o seu documento de resultado é idêntico byte a byte, e PassesScenario ganha propagator() e epoch_calendar() usados pela sua própria execução. As contagens de tipos de cenário, de ficheiros de cenário e de linhas da matriz de verificação ficam inalteradas. Um cenário de órbita ou de integridade sem epoch é datado pelos dados dos próprios satélites: t = 0 é a época mais antiga entre as de TLE (conjunto de elementos de duas linhas), de efemérides de difusão ou de SP3 (Standard Product 3), e cada um desses satélites é rodado para o GCRS e para os referenciais fixos à Terra no seu próprio instante; 2000-01-01T00:00:00Z só é usado quando nenhum satélite tem época. As exportações SP3 e OEM (Orbit Ephemeris Message) mantêm a sua etiqueta de 2000-01-01. Para o suportar, são acrescentados Sgp4::epoch_jd_utc, Sp3Interpolator::jd_ut1 e Propagator::own_jd_utc; nada do que existia os lê.

Navegação em órbita terrestre baixa: sinal

  • Projetos de sinal LEO-PNT e um espetro multibanda. Um novo tipo de cenário leo-signal e um tipo de cenário spectrum que vai além da banda L: um tipo de cenário, quatro ficheiros de cenário (três incluídos; o ficheiro Celeste IOD é só de repositório) e quatro linhas da matriz (duas VALIDATED, duas MODELLED).
    • leo-signal: projetos de sinal parametrizados de posicionamento, navegação e temporização (PNT) em órbita terrestre baixa (LEO) para qualquer sistema (banda, largura de banda de transmissão, atribuição da ITU; componentes de aquisição, de dados e de piloto com espetros BPSK(n), BOC(m,n), MBOC ou planos, partilhas de potência, subportadoras FDMA, comprimentos de código e débitos de dados), a partir de ficheiros de predefinições públicos compilados em data/leo-signals/ (Xona Pulsar X1/X5, Iridium STL, um sinal de oportunidade Starlink, CentiSpace, um projeto representativo de banda C e projetos representativos UHF/L/S/C/C larga, cada um a citar o seu URL de origem) ou escritos em linha. Por sinal: a PSD de banda limitada e as frações de potência na banda, a largura de banda de Gabor, o jitter de seguimento de código early-late de banda limitada face ao C/N0 e ao espaçamento (Betz & Kolodziejski 2009) e a exatidão de medição de distância, o espaço de pesquisa de aquisição, a probabilidade de deteção e o tempo médio de aquisição em série e em paralelo de código, o SSC para e a partir do GPS L1 C/A, do Galileo E1, do GPS L5, do Galileo E5a, E5b e do AltBOC com a perda de C/N0, a tolerância de J/S CW, de banda larga e adaptada a partir do código SSC do tipo de cenário de espetro, um compromisso de bandas (atraso ionosférico, perda em espaço livre, medição de distância com o mesmo C/N0 e a mesma EIRP, tolerância a jammers) e verificações opcionais de forma face a uma medição descrita. Exemplos: scenarios/leo-band-trade.toml, scenarios/xona-pulsar-signals.toml, scenarios/celeste-iod-classical-pilot-signals.toml (as bandas e a configuração de sinal do Celeste IOD apresentadas no workshop LEO-PNT do ESA NAVISP, 2026; retidas com a predefinição Celeste IOD, ver "LEO-PNT end to end" abaixo). Notas em docs/LEO-SIGNAL.md.
    • spectrum: as bandas podem agora ser um projeto de sinal predefinido (cada componente desenhado, de banda limitada, com C/N0 e J/S referidos ao componente seguido) ou uma portadora e uma modulação personalizadas; [[panels]] acrescentam cascatas sobre outras gamas de frequência numa só cronologia; um jammer wideband (barragem) junta-se às quatro formas de onda. O relatório acrescenta bands[].tracked_power_dbw, bands[].design e panels, e uma entrada not_modelled. As bandas simples dão os mesmos números que antes. Exemplo: scenarios/multi-band-jamming-waterfall.toml.
    • navsignal passa a incluir o seno integral, as formas fechadas da potência de BPSK na banda e da largura de banda de Gabor de banda limitada, o jitter early-late de banda limitada para qualquer espetro e o seu limite de Gabor, a forma fechada do SSC de BPSK com desvio, o espetro AltBOC(15 10) do Galileo E5 e um analisador de etiquetas de modulação; Modulation::label imprime BPSK(1/3) como fração.
    • Quatro linhas da matriz: formas fechadas de banda limitada VALIDATED (90,3 % da potência BPSK no lóbulo principal, o jitter a reduzir-se à forma coerente de Kaplan & Hegarty, 0,0039564 chips a 45 dB-Hz, B_L 1 Hz, d 1 chip, T 20 ms, e ao seu limite de Gabor, e o auto-SSC de BPSK 2/(3 R_c); a forma fechada de Gabor e o SSC com desvio face à sua forma de Parseval são indicados como verificações cruzadas internas); Doppler LEO máximo VALIDATED (Xona X1 33,2 kHz dentro dos 32 a 34 kHz publicados, Iridium a 0,5 kHz de 36 kHz); MODELLED leo-signal; espetro multibanda MODELLED.
  • Passagem LEO-PNT e balanço de ligação por banda: o tipo de cenário leo-pass. LEO-PNT é posicionamento, navegação e temporização a partir de satélites em órbita terrestre baixa (LEO). Um utilizador (terrestre, marítimo, aéreo ou em interior, estático ou em movimento) e um ou mais satélites LEO a partir de uma passagem projetada, de elementos explícitos, de um conjunto de elementos de duas linhas (TLE) através do SGP4, ou de uma constelação Walker do código constellation-design. Por satélite, banda e época: ângulos de visada, distância, taxa de variação da distância e aceleração da distância em forma fechada (verificadas em cada execução por diferenças centrais), Doppler e taxa de Doppler, perda em espaço livre, EIRP (potência isotrópica radiada equivalente) com um diagrama de satélite isofluxo, de feixe gaussiano ou plano, uma antena de utilizador de tipo patch, atenuação gasosa ITU-R P.676, atenuação por chuva ITU-R P.838/P.618, cintilação troposférica P.618, perda de penetração em edifícios ITU-R P.2109 para um utilizador em interior, desadaptação de polarização, temperatura de ruído do sistema e C/N0 (densidade portadora-ruído); o atraso ionosférico de primeira ordem por banda a partir de um TEC oblíquo de Klobuchar ou de TEC vertical (conteúdo eletrónico total) abaixo do satélite, e pares de bandas livres de ionosfera com a sua amplificação de ruído. Os satélites Galileo ou GPS são avaliados com o mesmo recetor a partir das potências recebidas dos documentos de interface, pelo que a passagem LEO em forma de sino e as portadoras MEO (órbita terrestre média) planas partilham um gráfico. Uma secção [iot] dá o tempo até à primeira solução de posição, a energia por solução e a duração da bateria face ao ciclo de trabalho (MODELLED).
    • Independente de qualquer sistema: o motor não precisa de nenhuma predefinição. Predefinições opcionais, cada uma no seu próprio ficheiro e marcada PUBLIC (com URL), REPRESENTATIVE ou WORKSHOP: multibanda genérica (UHF, L, S, C), banda C genérica, Xona Pulsar X1/X5 (arXiv 2509,19551), Iridium STL, Starlink como sinal de oportunidade apenas Doppler, CentiSpace e Celeste IOD (demonstração em órbita), cujos parâmetros de sinal foram apresentados no workshop LEO-PNT do ESA NAVISP, 2026, e que vivem em src/celeste_iod.rs para poderem ser retidos (ver "LEO-PNT end to end" abaixo).
    • Blocos de construção públicos em src/leo_link/ (geometry, antenna, itu, iono, energy, presets) para outros módulos chamarem.
    • Cenários: leo-pass-vs-gnss-cn0, leo-indoor-uhf, leo-iot-energy, leo-pass-xona-pulsar, leo-pass-iridium, leo-pass-celeste-iod-multiband.
    • Nove linhas da matriz. VALIDATED (6): coeficientes ITU-R P.838-3 face à sua Tabela 5; atenuação por chuva e cintilação P.618-14 face aos exemplos de validação do Grupo de Estudo 3 do ITU-R; perda de penetração em edifícios P.2109 face à folha de cálculo do Grupo de Estudo 3; escalamento ionosférico de primeira ordem face à razão de atrasos de grupo da IS-GPS-200, com a perda em espaço livre; o Doppler máximo de um utilizador estático numa órbita circular face à Tabela 1 do arXiv 2509,19551. MODELLED (3): a passagem e o balanço de ligação, as predefinições e o orçamento de solução de posição de baixa energia. Um tipo de cenário e seis ficheiros de cenário. Notas em docs/LEO-PASS.md.

Navegação em órbita terrestre baixa: mensagem de navegação

  • Mensagem de navegação LEO (tipo de cenário leo-navmsg, src/leo_navmsg/). A mensagem difundida de efemérides e de relógio de um satélite de posicionamento, navegação e temporização (PNT) em órbita terrestre baixa (LEO), para qualquer órbita, portadora e modelo; as predefinições com nome são dados opcionais e todas as capacidades funcionam sem elas. Um tipo de cenário, cinco ficheiros de cenário e nove linhas da matriz (três VALIDATED, seis MODELLED). Ver docs/LEO-NAVMSG.md.
    • Conteúdo da mensagem: SVID, número de emissão dos dados, banda e saúde do sinal; semana, tempo da semana e um polinómio de relógio de segunda ordem; as efemérides num de quatro modelos — o conjunto kepleriano de 16 parâmetros do Galileo OS SIS ICD, esse conjunto mais polinómios de correção ao longo da trajetória, transversais e radiais, o modelo de 22 parâmetros de Liu et al. 2025 (doi 10.3390/rs17162894) ou o polinómio ECEF de relógio nulo do ATOMIC — e um conjunto de Klobuchar, coeficientes NeQuick-G com o nível de ionização efetivo, e parâmetros de tempo do sistema para UTC com os casos de segundo intercalar do ICD.
    • Ajustador: uma órbita de referência integrada com gravidade zonal J2–J6 ou EGM2008 e arrasto, um relógio com semente livre ou disciplinado, um ajuste de Levenberg–Marquardt em elementos não singulares, depois polinómios de correção por mínimos quadrados lineares e um relógio ajustado líquido do termo relativista do utilizador.
    • Quatro análises e cenários: leo-navmsg-fit-interval-trade (erro de alcance do sinal no espaço (SISRE) face ao intervalo de ajuste e ao período de atualização), leo-navmsg-model-comparison (quatro modelos, bits, e o ajuste de 22 parâmetros do Kshana nas altitudes de Liu et al. ao lado dos valores publicados, MODELLED), leo-navmsg-midpass-update (continuidade em cada mudança de mensagem numa passagem) e leo-navmsg-encode-decode (a trama binária documentada do próprio Kshana com CRC-24Q e um orçamento de quantização, um bloco ao estilo RINEX-4 identificado como extensão do Kshana, e uma tabela CSV).
    • VALIDATED: os pesos de SISRE médio global face à tabela publicada de órbita média e geoestacionária de Montenbruck et al. 2018; o algoritmo de utilizador do Galileo face ao RTKLIB em quatro efemérides de difusão reais do Galileo (tests/leo_navmsg_reference.rs); o CRC-24Q face ao valor de verificação do catálogo e à trama de exemplo RTCM 10403 1005.
    • Predefinições, um ficheiro cada uma com as suas fontes: Xona Pulsar e Pulsar-0, Iridium, Starlink, CentiSpace, um sistema representativo de banda C, ATOMIC e Celeste IOD (a única predefinição que usa material apresentado no workshop LEO-PNT do ESA NAVISP, 2026, mantida em src/celeste_iod.rs com os seus cenários para poder ser retida).

Navegação em órbita terrestre baixa: fusão

  • Posicionamento, navegação e temporização fundidos MEO + LEO: leo-pvt, leo-ppp e ntn-positioning. Três novos tipos de cenário em src/leo_fusion/, independentes de qualquer sistema: cada constelação é feita de camadas Walker, conjuntos de elementos ou uma predefinição GNSS, cada sinal é uma portadora, uma taxa de chips e uma envolvente de densidade portadora-ruído (C/N0), cada orçamento de erro é um sigma explícito, e os sistemas de órbita terrestre baixa (LEO) com nome são predefinições opcionais, um ficheiro cada uma com as suas fontes marcadas como públicas, de workshop ou derivadas (Xona Pulsar X1/X5, Iridium Satellite Time and Location (STL), sinais de oportunidade Starlink, CentiSpace, um sistema representativo de banda C, o modelo de efemérides de relógio nulo ATOMIC e uma predefinição de demonstração em órbita ESA Celeste cujos parâmetros derivados do workshop vivem em src/celeste_iod.rs para poderem ser retidos).
    • leo-pvt tem quatro modos: posicionamento Doppler (mínimos quadrados em lote sobre a taxa de variação da distância com estados de deriva de relógio e de velocidade, um modo de sinais de oportunidade apenas Doppler, a exatidão ao longo e transversal à trajetória numa única passagem, e a envolvente de Doppler, de taxa de Doppler e de jerk); mínimos quadrados ponderados conjuntos GNSS + LEO com um relógio por sistema (o viés intersistemas) ou um desvio conhecido, sigmas por medição como entradas, e o DOP face ao número de satélites LEO; cobertura polar e do Ártico face à latitude; e transferência de tempo LEO para o Tempo Universal Coordenado (UTC) face ao C/N0 e ao oscilador do recetor com a expressão de tempo do sistema para UTC da IS-GPS-200.
    • leo-ppp: um filtro de Kalman estendido de posicionamento preciso de pontos (PPP) com ambiguidades reais sobre código e fase livres de ionosfera, apenas GNSS e com aumento por LEO, com o seu tempo de convergência e um teste de consistência NEES (erro de estimação normalizado ao quadrado) de Monte Carlo. O cenário incluído dá 7,4 min com quatro sistemas MEO e 4,8, 3,2, 2,7 e 2,3 min com 60, 96, 192 e 288 satélites LEO, ao lado dos 9,6, 7,0, 3,2, 2,1 e 1,3 min de Li et al. (J. Geod. 93:749, 2019) como comparação MODELLED da tendência.
    • ntn-positioning: posicionamento em redes não terrestres (NTN) 5G na banda S de satélite móvel n256 do 3GPP a partir do limite de Cramér-Rao sobre o tempo de chegada e o Doppler.
    • Cenários: leo-doppler-positioning, starlink-sop-doppler-positioning, meo-leo-fused-pvt, leo-ppp-convergence, ntn-5g-positioning, polar-arctic-leo-coverage, leo-timing-utc (incluídos) e celeste-iod-fused-pvt (só de repositório, retido com a predefinição Celeste IOD).
    • Oito linhas da matriz: a envolvente de Doppler LEO VALIDATED face aos valores publicados do Iridium (±36 kHz: 35,9 kHz, dentro de 5%) e do Xona Pulsar X1 (32 a 34 kHz: 33,6 kHz a partir da camada de 97 deg, sem alargamento) (tests/leo_doppler_reference.rs); posicionamento Doppler, posicionamento conjunto por pseudo-distâncias, convergência PPP, limites NTN, temporização LEO, cobertura polar e predefinições MODELLED. Três tipos de cenário e oito ficheiros de cenário. Documentação: docs/LEO-PNT-FUSION.md.
  • LEO-PNT de ponta a ponta: o tipo de cenário leo-pnt-chain, e as fases LEO ligadas entre si. Um sistema de posicionamento, navegação e temporização (PNT) em órbita terrestre baixa (LEO) acompanhado desde o projeto do seu sinal até à posição do utilizador, cada fase sendo um tipo de cenário do próprio motor na sua própria tabela de cenário, com valores transmitidos em código (docs/LEO-PNT.md):
    • As bandas de leo-pass podem indicar um projeto leo-signal (signal = "xona-x5"): a banda adota o centro, a largura de banda de transmissão e a taxa de chips do componente seguido do projeto, reparte a sua EIRP (potência isotrópica radiada equivalente) pelos componentes do projeto, e comunica em cada época o C/N0 (densidade portadora-ruído) do componente seguido e o jitter de seguimento de código de banda limitada (o erro de medição de distância; o ruído do par iono_free também o usa). Uma banda sem projeto dá a mesma saída que antes.
    • leo-pnt-chain executa sinal -> passagem -> mensagem de navegação -> solução conjunta fundida leo-pvt -> leo-ppp opcional. Todos os sistemas LEO da fase de posicionamento que os deixem por definir adotam uma linha de C/N0 em sin(elevação) ajustada à passagem, o erro de alcance do sinal no espaço (SISRE) da mensagem (o seu erro de representação na órbita do satélite da passagem, com um termo de determinação de órbita od_sisre_m indicado, em raiz da soma dos quadrados), e a portadora e a taxa de chips do projeto; os casos de posicionamento preciso de pontos (PPP) adotam o SISRE. Cada transferência é listada com o seu valor e a sua unidade, e tests/leo_pnt_chain.rs verifica que cada uma é igual à saída a montante e que as alterações a montante deslocam os valores a jusante. LeoNavmsgScenario::broadcast_sisre é o novo ponto de entrada da mensagem.
    • Cenários: leo-pnt-end-to-end (uma constelação genérica de 1080 km e o sinal generic-l representativo), xona-pulsar-end-to-end (o sinal X5 público), ambos incluídos, e o opcional celeste-iod-end-to-end, só de repositório.
    • As predefinições Celeste IOD (demonstração em órbita) das áreas de passagem, mensagem e posicionamento fundido vivem agora num só ficheiro, src/celeste_iod.rs, que build.rs compila apenas quando existe (a flag de configuração kshana_celeste). Os seus cinco cenários (scenarios/*celeste-iod*.toml) são só de repositório, pelo que apagar esse ficheiro e esses cenários retém todos os números apresentados no workshop LEO-PNT do ESA NAVISP, 2026, sem qualquer alteração ao código-fonte; tests/workshop_preset_isolation.rs verifica que ficheiros podem nomear a predefinição ou conter os números do seu plano de bandas.
    • Todos os tipos de cenário LEO na correspondência do relatório avançado, com as suas linhas específicas de cada caminho listadas apenas quando a execução seguiu esse caminho (uma taxa de chuva, um edifício, uma análise ou um modo que foi executado). As janelas de Doppler de leo-pvt ganham t_s e os casos de leo-ppp ganham t_min, pelo que ambos se animam; leo-pass e leo-pnt-chain exportam efemérides CZML, KML, GeoJSON e STK, e os restantes tipos de cenário LEO indicam porque um formato não se aplica.

Navegação em órbita terrestre baixa: resiliência, áreas de foco e cenários de utilizador final

  • Resiliência LEO-PNT, um cenário por área de foco da experiência e um por vertical de utilizador final, e docs/LEO-PNT.md como visão geral de todos os tipos de cenário e cenários LEO. Todos os cenários funcionam sem quaisquer dados do Celeste e estão incluídos.
    • leo-pass passa a ter uma secção [spoofer]: um spoofer falsifica, de forma autoconsistente em distância e em taxa de variação da distância, os sinais de uma posição declarada que salta e/ou é afastada da verdadeira após um início (por banda LEO, e para o sinal GNSS MEO), com ou sem a ionosfera. Dois monitores funcionam a uma probabilidade de falso alarme indicada: consistência de Doppler e da geometria da passagem (taxas de variação da distância medidas face às previstas a partir das órbitas e de uma posição e velocidade a priori independentes; um qui-quadrado de mínimos quadrados generalizados numa janela, nos canais GNSS, LEO e em todos, com ruído do laço de bloqueio de frequência derivado do C/N0) e consistência entre bandas (o salto da combinação livre de geometria, corrigida pelo modelo, de cada par de bandas LEO). O resultado dá as estatísticas por época (pelo que se anima), cada par, e quando cada monitor deteta. Blocos de construção em leo_link::spoof. Secção ausente, saída inalterada.
    • Cada par de bandas de leo-pass comunica também o conteúdo eletrónico total (TEC) oblíquo que a sua combinação livre de geometria recupera no pico da passagem e o sigma de ruído de código dessa estimativa (sondagem da ionosfera). Isto acrescenta dois campos a cada resultado leo-pass multibanda; nenhum número existente muda.
    • O modo de temporização de leo-pvt aceita trace = true: cada linha comunica então o seu erro de tempo e o sigma previsto em cada época, com as mesmas extrações, pelo que as estatísticas das linhas ficam inalteradas e a execução anima-se e encadeia-se numa campanha.
    • Uma campanha passa a exportar cada cenário membro que tenha geometria (execuções de fase, os cenários base de varrimento e de Monte Carlo, membros compostos com os seus valores partilhados ligados) como o seu próprio conjunto de ficheiros, com a etiqueta do membro no nome do ficheiro; antes, uma campanha não exportava nada. A tabela de interoperabilidade em docs/INTEROP.md muda em consequência.
    • Uma chave de varrimento de campanha pode indexar uma lista de tabelas por posição (system.2.sisre_m).
    • Cenários de resiliência: leo-resilience-multiband-diversity (uma barragem de 50 MHz na banda L5 variada em potência: todos os sinais da banda L caem, os sinais LEO em UHF, banda S e banda C mantêm o seu C/N0), leo-resilience-js-margin (margem de J/S a partir da potência recebida: GPS L5, Galileo E5a e Xona X5 perdidos a -105, -100 e -95 dBW, um sinal LEO genérico de -135 dBW ainda em seguimento a -90 dBW), leo-resilience-spoof-doppler (um salto de 30 m não detetado pelo teste de Doppler apenas GNSS e detetado pelo teste em todos os canais 105 s após o início), leo-resilience-spoof-monitors (quatro spoofers contra ambos os monitores) e leo-resilience-gnss-jammed-leo-carries (GNSS sob jamming, a camada LEO de banda S e C em seguimento, a monitorização autónoma da integridade pelo recetor apenas na camada LEO a dar alarme em 2 de 30 épocas).
    • Cenários de área de foco: leo-focus-ppp-altitude, leo-focus-ntn-bandwidth, leo-focus-iot-eirp, leo-focus-science-iono-sounding, leo-focus-data-services, leo-focus-indoor-uhf, leo-focus-fused-pnt-sisre (a resiliência em L, S e C é leo-resilience-multiband-diversity).
    • Campanhas de vertical, cada uma animada e a exportar as suas passagens LEO: leo-vertical-autonomous-vehicle, leo-vertical-rail-maritime (os cenários marítimos e ferroviários incluídos mais LEO), leo-vertical-critical-infrastructure-timing, leo-vertical-polar-arctic, leo-vertical-5g-network-timing, leo-vertical-asset-tracking-iot. Resultados numa linha em docs/LEO-PNT.md.
    • Três linhas MODELLED da matriz: o monitor de spoofing por Doppler e geometria da passagem, o monitor de spoofing entre bandas e a sondagem da ionosfera. tests/leo_resilience_verticals.rs verifica os monitores (silenciosos antes do início, a estatística de Doppler quadrática num salto, o salto ionosférico de um spoofer terrestre e nenhum num spoofer com conhecimento da ionosfera), a identidade da sondagem, o traço de temporização face às estatísticas das linhas, e que a exportação de uma campanha é igual à de cada membro.
    • A página leo-pass passa para docs/LEO-PASS.md; docs/LEO-PNT.md é a visão geral.

Cenários marítimos, rodoviários e ferroviários

  • Cenários marítimos, rodoviários e ferroviários. Cinco exemplos incluídos sobre tipos de cenário existentes, para que navios, veículos rodoviários e comboios tenham cada um um caso trabalhado. Todos os valores são MODELLED; nenhum é validado face a dados medidos.
    • scenarios/maritime-strait-jamming.toml (jamming): um jammer de banda larga de 50 W num mastro de 30 m, a 30 km de distância sobre águas abertas, face a um navio. A relação média jammer-sinal (J/S) é de cerca de 48 dB, e a disponibilidade desce de 1,00 para 0,00.
    • scenarios/maritime-port-approach-coast.toml (ins-trn-coast): um sistema de navegação inercial (INS) de classe de navegação a 12 nós, com o GNSS perdido e sem auxílio. Atinge 10 m após 281 s e 100 m após 833 s, os valores de aproximação a porto e de águas oceânicas da Resolução A.1046(27) da Organização Marítima Internacional (IMO), aqui usados como orçamentos.
    • scenarios/maritime-spoof-position-push.toml (spoof-detect): um spoofer de +2 dB, não alinhado com a portadora, que empurra quatro satélites para arrastar um navio 500 m. O monitor fundido deteta-o (pontuação 0,70 face a um limiar de 0,50) por monitorização autónoma da integridade pelo recetor (RAIM) e monitorização da qualidade do sinal (SQM); a monitorização de potência isolada não o deteta.
    • scenarios/automotive-urban-canyon.toml (gnss-ins): um automóvel através de uma passagem inferior de 15 s e de uma interrupção de 60 s causada por um jammer à beira da estrada, face a um orçamento de meia faixa de 1,5 m. O erro quadrático médio (RMS) fundido durante a interrupção é 1,9 m para uma unidade de sistema microeletromecânico (MEMS) de classe automóvel e 0,7 m para um comparador de grau tático; em funcionamento livre, a unidade MEMS desvia-se 850,8 m.
    • scenarios/rail-tunnel-coast.toml (ins-trn-coast): um INS de grau tático num comboio a 160 km/h num túnel. Atinge 2 m (discriminação de via) após 35,8 s, a cerca de 1,6 km da entrada, e 20 m após 107,3 s. Isto é apenas INS: o motor não tem modelo de odómetro, pelo que é o limite pessimista. A contagem de ficheiros de cenário do README passa de 77 para 82. Os cinco estão incluídos para kshana example e listados no playground do navegador.

Servidor do Model Context Protocol

  • O servidor do Model Context Protocol (MCP) chega a todos os tipos de cenário e a todas as vistas de uma execução: sete novas ferramentas, catorze no total. run_scenario já despachava todos os tipos de cenário; o que faltava a um agente era um caminho para um cenário válido de um tipo de cenário e para as três saídas que a linha de comandos escreve ao lado de um resultado. Novas ferramentas:

    • list_example_scenarios e get_example_scenario servem os cenários de referência incluídos (a tabela kshana example), cada um com o seu tipo de cenário e a primeira frase do seu próprio cabeçalho, byte a byte o ficheiro em scenarios/. Um cenário que está no repositório mas não incluído é recusado com o motivo. Todos os tipos de cenário, exceto lunar-llr-datum (cuja fatia de dados só vem com o repositório), têm pelo menos um exemplo.
    • report_scenario devolve o relatório da execução como JSON (JavaScript Object Notation) ou como página HTML (HyperText Markup Language) imprimível (docs/REPORTS.md).
    • animate_scenario devolve a série temporal da execução como um desenho SVG (Scalable Vector Graphics) animado, um leitor HTML ou fotogramas numerados, depois de um resumo JSON do que foi desenhado (docs/ANIMATION.md). Uma resposta contém no máximo 120 fotogramas; a linha de comandos escreve qualquer comprimento.
    • list_export_formats, export_interop e import_route servem as exportações de interoperabilidade e a importação de rotas GeoJSON (docs/INTEROP.md): CZML (Cesium Language), KML (Keyhole Markup Language), GeoJSON, as efemérides STK (Systems Tool Kit) .e e SigMF (Signal Metadata Format), com um índice JSON dos ficheiros (sufixo, tamanho e SHA-256, o resumo do Secure Hash Algorithm de 256 bits) e o ficheiro binário de amostras SigMF em base64.

    A biblioteca ganha uma funcionalidade bundled-scenarios desativada por predefinição que expõe a tabela de cenários de referência como kshana::bundled_scenarios; só o servidor MCP a ativa, pelo que a wheel Python e o módulo WebAssembly continuam a não conter o texto dos cenários. Os conjuntos de estudo (--study) continuam a ser apenas de linha de comandos, porque um conjunto nomeia ficheiros em disco e o servidor não lê nenhum. Os testes de ida e volta executam cada nova ferramenta sobre cenários incluídos e verificam os números do motor: espetro, o sistema solar, constelações em torno da Lua e de Europa, um varrimento de campanha, e os tipos de cenário de sinal, passagem, mensagem de navegação, posicionamento fundido, posicionamento preciso de pontos, rede não terrestre e de ponta a ponta de órbita terrestre baixa (LEO). Todas as superfícies que indicam a contagem de ferramentas MCP ou as listam dizem agora catorze, exceto a página do playground em web/, que é substituída pelo site.

kshana.dev, Kshana Studio e o README

  • Um kshana.dev redesenhado. A página única de playground é substituída por um site de várias páginas: Home, Missions, Capabilities, Evidence, Developers, Editions e Docs, com o Kshana Studio a um clique. Todos os gráficos, mapas e números nele são uma execução registada do motor desta versão, com o cenário e uma ligação que reabre a mesma execução no Studio; a compilação do site recusa um registo feito por outro commit do motor. As páginas da documentação são geradas a partir de docs/ do repositório, e as opções de instalação a partir dos seus canais. Os tipos de letra e as bibliotecas de scripts são servidos pelo próprio kshana.dev, pelo que nenhuma página pede nada a um anfitrião de terceiros. Os endereços antigos (/#playground, ligações de partilha /#ledger, /#s=<scenario>, ligações de incorporação /?embed=1&… e as restantes) redirecionam para o seu novo lugar, e um endereço desconhecido recebe uma página 404.
  • Kshana Studio, um painel para cada capacidade. O Studio abre num ecrã inicial com mosaicos de domínio e boas primeiras execuções, e depois conduz uma execução por cinco passos numerados: Escolher um cenário, Definir os seus parâmetros, Executar o motor localmente no navegador, Ler os resultados (primeiro os valores principais, cada um com um chip PASS ou FAIL quando a execução indica um limiar, e depois os painéis) e Partilhar ou exportar. Uma caixa de pesquisa encontra cenários, domínios e os campos dentro deles e salta para o controlo; as execuções podem ser fixadas e comparadas; uma trilha de navegação indica onde se está; num telemóvel os passos tornam-se uma barra de passos. Cada tipo de cenário tem a sua vista, incluindo a cascata de espetro, o sistema solar, a cobertura de constelações, as campanhas, a animação, o relatório da execução, as exportações de interoperabilidade e a cadeia de órbita terrestre baixa. Uma ligação profunda (?scenario=…&tab=…) abre a mesma execução no painel indicado.
  • Investigação e citação. A página Evidence lista os cinco artigos do Kshana no arXiv (2606,22054, 2606,24210, 2607,02566, 2607,05415 e 2607,06212), cada um com um resumo, um valor calculado por este motor, o comando que o reproduz, uma ligação para o Studio e BibTeX, ao lado de como citar o software. O README ganha a mesma secção Research.
  • Uma página pública para o Kshana Pro. docs/PRO.md e a página Editions do site dizem o que a camada proprietária Pro acrescenta sobre o mesmo motor (otimizador de projeto, incerteza e sensibilidade, dossiê de missão, vigilância de campanha, coexistência de espetro, serviço de tarefas nas instalações, rastreabilidade de requisitos), o que cada uma produz e o que não faz. Todos os valores do Pro que o site mostra estão indicados nessa página pública. O Pro não acrescenta nenhum modelo físico, e o motor aberto continua inteiro e gratuito.
  • Um README reescrito. Secções curtas, uma imagem por secção, a marca do Kshana, duas filas de emblemas, imagens geradas de arquitetura, de fluxo de cenário, da cadeia de órbita terrestre baixa e de verificação (tools/gen_readme_assets.py, que falha perante uma imagem desatualizada), e capturas de ecrã do Studio tiradas do Studio em funcionamento por tools/capture_studio_shots.mjs. Os READMEs do crates.io, do PyPI, do npm e do servidor MCP seguem o mesmo desenho. O material de referência longo é recolhido ou movido para docs/.

Alterado#

  • <scenario>.report.html é agora o relatório avançado de execução descrito em Adicionado, e a linha wrote … da CLI nomeia também <scenario>.report.json. O relatório de uma página com pontuação que ele substituiu mantém-se inalterado como RunOutput::html_report(), que as ligações Python e WebAssembly continuam a devolver. OracleKind::modelled_reason() expõe a frase que docs/MODELLED-RATIONALE.md imprime para cada linha MODELLED; esse documento está inalterado.
  • O README diz em que se baseia o Kshana Pro. A secção Editions e a linha do Kshana Pro em "Support & professional services" indicam agora o que as ferramentas de engenharia de sistemas baseada em modelos (MBSE) e de programa do Pro fazem e quais das saídas publicadas do motor aberto leem (o result.json e o report.json de cada execução, o ficheiro do cenário, o esquema de unidades dos campos e as etiquetas da matriz de verificação), e em que assentam no motor aberto os gémeos digitais de relógios, os estudos de compromisso e os pacotes de evidências. Apenas redação: nenhuma saída do motor nem número publicado muda.
  • Compatibilidade. O enum público navsignal::Modulation ganha uma variante Mboc, o que é uma alteração incompatível para um chamador que o trate de forma exaustiva. As colunas gcrs_r_m e gcrs_v_m_s do tipo de cenário ephemeris mudam (ver "Revisões de números publicados"). Uma execução continua a ser reproduzida pela versão do motor que a produziu.

Corrigido#

  • export_table_csv no servidor MCP nomeava quatro tipos de cenário como os únicos com uma tabela CSV (valores separados por vírgulas); seis publicam uma. A ferramenta devolvia sempre a tabela para telecom-timing e para leo-navmsg (a sua análise encode-decode sobre um modelo de mensagem kepler16 ou kepler-rac), mas a sua descrição, a sua mensagem de recusa e os documentos que listam os tipos de cenário omitiam ambos, pelo que se dizia a um agente para não os pedir. Passam agora a ser nomeados, e um teste de ida e volta obtém ambas as tabelas.

  • A trama da mensagem de navegação de órbita terrestre baixa (LEO) não tinha os mesmos bytes em todas as plataformas, nem em todas as compilações de uma mesma plataforma. scenarios/leo-navmsg-encode-decode.toml codificava uma trama com verificação de redundância cíclica 0x110315 na compilação de lançamento em aarch64 macOS, 0x898BD8 numa compilação de depuração do mesmo código-fonte na mesma máquina, e 0x6A82D9 na compilação WebAssembly (WASM); leo-navmsg-celeste-iod.toml dava 0x6EDB2D nativamente face a 0xC6E4F0 no navegador. Três causas, cada uma rastreada até ao primeiro valor divergente:

    • Entre plataformas. A órbita de referência era idêntica ao bit em ambas; o ponto de partida do ajuste não era. truth::state_to_elements obtém a inclinação osculadora a partir de um acos e o argumento do perigeu a partir de um atan2, e as duas bibliotecas matemáticas arredondam-nos de forma diferente na última casa (em 20 000 argumentos discordam em 781 senos, 858 cossenos, 1 931 exponenciais e 1 899 arco-tangentes de dois argumentos).
    • Entre perfis de compilação. Uma compilação otimizada em macOS funde um seno e um cosseno do mesmo argumento numa única chamada à rotina combinada do sistema, e o seu seno não é o do sin isolado em 379 de 200 000 argumentos; uma compilação não otimizada faz as duas chamadas. O tipo de cenário calcula um seno e um cosseno em conjunto em treze locais.
    • No relógio. O amostrador normal de rand_distr chama exp e ln do anfitrião nos seus dois ramos raros: de quatro milhões de extrações com semente, três diferiam no último bit entre a compilação nativa e a WASM.

    O ajuste de Levenberg–Marquardt, que neste arco pára no seu limite de 80 iterações e não num mínimo, transporta uma unidade na última casa para campos quantizados diferentes. O tipo de cenário calcula agora todas as funções transcendentes através do novo src/portable_math.rs, que chama o crate libm em Rust puro (já na árvore de dependências, agora nomeado em Cargo.toml), compilado a partir de um só código-fonte para todos os alvos e não uma chamada de biblioteca que o otimizador reescreve: leo_navmsg::{truth, fit, elements, codec, sisre, services} e o código do cenário. As potências inteiras nesse caminho são escritas por extenso como elevar ao quadrado e multiplicar, porque f64::powi tem precisão não especificada, e o relógio de referência extrai os seus desvios normais de portable_math::standard_normal (o método polar de Marsaglia sobre a saída bruta do gerador). As rotinas partilhadas por que a órbita de referência integra são escritas uma só vez, genéricas sobre a biblioteca matemática, com um ponto de entrada _portable interno ao crate ao lado do existente: a aceleração por harmónicas esféricas, as acelerações zonal e de arrasto, as taxas seculares de J2 e o atraso de Klobuchar. Os pontos de entrada existentes ficam inalterados até ao último bit, pelo que nenhum número de outro tipo de cenário muda. leo_navmsg::tests::the_encoded_frame_is_the_same_bytes_on_every_platform fixa toda a trama de 171 bytes e um valor de verificação por modelo de efemérides, no perfil de teste normal (não otimizado), em todas as plataformas e sem condição de anfitrião de referência; the_kind_never_calls_the_host_mathematics_library lê do disco o código-fonte do tipo de cenário e falha perante uma chamada transcendente inerente, um amostrador rand_distr ou uma chamada a um módulo que não foi revisto. Depois da alteração, uma compilação de depuração, uma de lançamento e a compilação WASM produzem documentos de resultado idênticos byte a byte para os cinco cenários leo-navmsg. Isto altera números, registados aqui como uma revisão. O tipo de cenário leo-navmsg é novo nesta versão, pelo que nada publicado numa versão anterior muda, mas todos os valores de leo-navmsg mudam, nativamente e na compilação WASM, e com eles a fase navmsg de leo-pnt-chain: os valores de órbita porque o ajuste parte agora dos elementos portáteis, os valores de relógio porque o relógio de referência é uma realização diferente do mesmo processo. docs/LEO-NAVMSG.md é regenerado a partir dos novos resultados; o seu valor de verificação publicado para o cenário de codificação e descodificação era 0x110315 e é 0x19105F (posição a 1,126 mm da mensagem exata onde estava a 0,665 mm, relógio a 0,185 mm onde estava a 0,451 mm). A dimensão das alterações nos valores submilimétricos é a sensibilidade do ajuste, não um erro em nenhum dos conjuntos: o ajuste não muda e continua a parar no seu limite de iterações.

  • A reamostragem com semente extraía índices diferentes num alvo de 32 bits. Rng::gen_range sobre usize retira 64 bits do gerador num anfitrião de 64 bits e 32 bits num de 32 bits, pelo que a mesma semente dava outros índices e deixava o fluxo noutro ponto, na compilação WASM. Três locais extraíam assim: os bootstraps de percentis em eval_stats (bootstrap_ci, bootstrap_auc_ci), a permutação antes de cada passagem de treino em impairment_ml e o teste de permutação em impairment_study. Passam agora a extrair através de portable_math::uniform_index, que amostra sempre como u64: exatamente o que fazia um anfitrião de 64 bits, pelo que nenhum número nativo muda. Isto altera números publicados do pacote WASM, registados aqui como uma revisão: o intervalo de bootstrap quantum-anomaly-detect da área sob a curva (quantum_auc_ci, trade.foms[0].ci95) era [0.9901265, 0.9938305] no navegador e é agora o nativo [0.99035875, 0.993861].

  • Nomes de ficheiros de efemérides STK a partir de identificadores de móveis. Um identificador de móvel que contivesse um / ou um espaço (uma camada de constelação e um satélite, Pulsar inclined/S1-0163) fazia a CLI entrar em pânico com --export stk; cada identificador passa agora por uma parte de ficheiro segura (letras, dígitos, -, _).

  • O sinal da nutação TEME→GCRS, descrito acima em "Revisões de números publicados" porque altera saídas publicadas.

0.28.0 - 2026-09-26#

Adicionado#

  • Tipo de cenário slot-timing (src/slot_timing.rs): segundos até um relógio em funcionamento livre sair da guarda de um slot de encaminhamento ou de atribuição de tarefas indexado no tempo, cada termo contribuinte nesse momento com o dominante nomeado, o tempo que resta desde a última solução de posição e o maior intervalo entre soluções que mantém o relógio dentro, líquido da latência da solução. O relógio vem de uma predefinição de classe, de uma predefinição de ficha técnica de telecom-timing, de uma ficha técnica em linha (máximos do desvio de Allan, envelhecimento, coeficiente de temperatura) ou de um registo de fase medido. Uma violação para além do maior tempo de média que a fonte suporta é assinalada como extrapolada. Exemplo incluído: slot-timing-ocxo-leo. Ver docs/SLOT-TIMING.md.
  • Piso de ruído vermelho medido. O desvio de Allan sobreposto de um registo de fase é ajustado por mínimos quadrados ponderados na base de modulação de frequência de fase branca e IEEE Std 1139 (slot_timing::fit_weighted), cada ponto ponderado pelos seus graus de liberdade equivalentes, pelo que uma resposta de holdover pode assentar no piso do próprio relógio em vez do pressuposto da classe. Um ajuste sem ponderação pôs um piso de flicker espúrio num registo de teste de ruído branco e encurtou em 30 % uma violação de 2 000 s.
  • Validação em dados reservados da inversão de holdover num relógio real (tests/slot_timing_cs5071a_holdout.rs): ajustadas no primeiro terço do registo césio 5071A contra maser de hidrogénio, as violações previstas a um sigma em seis limiares de 0,5 a 2,5 ns ficam entre 0,84 e 1,03 das violações medidas nos outros dois terços, face a um limiar de 1,5 fixado antes de o teste correr pela primeira vez. Um controlo (o desvio de Allan a um segundo lido como ruído branco) falha por um fator de cerca de 1 000 e não atinge o limiar. Nova linha VALIDATED do registo; o fluxo de trabalho realdata-clock executa-o agora.
  • A mesma previsão num oscilador de cristal real (tests/slot_timing_ocxo_holdout.rs, scripts/fetch_ocxo.sh): num oscilador de cristal de forno medido, a previsão em dados reservados é conservadora, a 0,59 a 0,70 da violação medida e nunca mais tarde, e na maior parte fora do limiar de 1,5, porque o piso de ruído desse oscilador caiu para metade durante o registo de 5,5 horas; ajustada na amostra, fica entre 0,98 e 1,17. O caso do cristal não é validado e continua MODELLED. A execução expôs também um termo em falta: a frequência de um cristal deriva, pelo que o modelo passa a incluir a incerteza da frequência conhecida na solução de posição (fix_frequency_sigma); sem ela, a previsão era otimista até 2,5×.
  • A mesma previsão em relógios atómicos em órbita (tests/slot_timing_igs_holdout.rs, scripts/fetch_igs_clocks.sh): 14 dias de relógios finais do International GNSS Service para os satélites GPS Block IIF, com o protocolo escrito antes de os dados serem descarregados. Oito de dez satélites ficam dentro do limiar de 1,5; o G25 e o G30 preveem violações até cerca de duas vezes mais tardias do que as medidas. O protocolo exige que todos os satélites passem, pelo que o caso orbital não é validado e continua MODELLED; o resultado fica fixado.
  • Classes de relógio de cristal compensado em temperatura (TCXO), de cristal de forno (OCXO) e de padrão atómico de frequência de rubídio (RAFS) (ClockClass::Tcxo, Ocxo, Rafs), as peças que um barramento comercial de pequeno satélite ou um gateway terrestre transporta, cada uma a citar uma ficha técnica pública (ClockClass::source). Acrescentados ClockClass::ALL, id e from_id. baseline_clock_class de quantum-trade aceita os três novos identificadores. Acrescentar variantes a um enum público é uma alteração incompatível para um chamador que o trate de forma exaustiva.
  • Nível de proteção de temporização para um recetor em órbita (src/orbital_timing.rs, a secção spoofing opcional do tipo de cenário slot-timing): durante quanto tempo um spoofer terrestre pode alcançar um satélite de órbita terrestre baixa por passagem, o desvio que um spoofer a uma taxa de rampa máxima indicada acumula antes de o satélite sair do seu alcance ou de ser executada uma verificação independente, e se cada verificação de contacto com o solo ou de ligação cruzada é independente desse spoofer. Reduz-se exatamente a tpl::timing_protection_level_ns para um relógio sem ruído de flicker, de fase branca ou de passeio aleatório. MODELLED.
  • Três notas: docs/SLOT-TIMING.md (incluindo a métrica de deriva face à qual um slot deve ser aceite: erro de tempo absoluto máximo, e não erro de intervalo de tempo máximo nem desvio de tempo, e porquê), docs/DECEIVED-TIME.md (um comando assinado aplicado num tempo enganado continua a encaminhar mal) e docs/DEPLOYMENT-TARGETS.md (onde o Kshana funciona; não é oferecido nenhum núcleo de voo no_std).

0.27.4 - 2026-09-26#

A versão v0.27.3 chegou ao crates.io (kshana e kshana-mcp) e ao PyPI, e depois parou no npm, pelo que o npm, a imagem MCP do ghcr.io, o registo MCP, o JetBrains Marketplace e o kshana.dev nunca a receberam. A 0.27.4 leva o mesmo motor, com a correção de versão abaixo, a todos os canais.

Corrigido#

  • O passo de publicação npm nomeia o tarball por um caminho explícito. O npm lê um simples npm-dist/kshana-0.27.3.tgz como a abreviatura do GitHub owner/repo, pelo que a tarefa npm da v0.27.3 tentou clonar github.com/npm-dist/kshana-0.27.3.tgz e falhou com "Permission denied (publickey)". O próprio tarball tinha sido construído e atestado. O passo publica agora ./npm-dist/*.tgz. Tudo o que vem depois do npm na ordem da versão (a imagem MCP, o plugin JetBrains, a verificação de paridade de canais e o site) foi ignorado, como previsto.

Alterado#

  • Os catálogos de unidades de telecom-timing e gnss-ins estão isentos da deteção de copiar e colar, sob a mesma política e o mesmo teste de justificação dos outros catálogos. O critério de qualidade do SonarCloud tinha ficado vermelho por duplicação em código novo (4,0% face a 3%), e cada bloco duplicado era uma linha de unidades ou uma entrada de máscara ITU-T.

0.27.3 - 2026-09-25#

Adicionado#

  • scenarios/small-uas-jammed-nav.toml: durante quanto tempo a navegação de um pequeno drone se mantém depois de o GNSS sofrer jamming. Executa uma unidade inercial microeletromecânica (MEMS) de classe de controlador de voo, uma Bosch BMI088, face a uma unidade de grau tático. O sinal GNSS (Global Navigation Satellite System) é nominal durante 100 s, e depois negado durante 60 s (jamming-demo.toml mostra porque é que um jammer próximo faz isso). Os vieses da BMI088 são os resíduos que ficam após a calibração de arranque, tirados dos coeficientes de temperatura da sua ficha técnica (BST-BMI088-DS000-19 rev 1,9): 0,015 °/s por K para o giroscópio e < 0,2 mg por K para o acelerómetro. Duas hipóteses estão assinaladas no ficheiro: um aquecimento de 10 K após a calibração, e um aquecimento contínuo de 1 K por minuto em voo. A deriva em voo é o erro que o filtro não consegue aprender antes de o jamming começar, e é o que termina a navegação por estima. Todos os valores são modelados; validá-lo exige registos de voo de um ambiente sob jamming. kshana example small-uas-jammed-nav imprime-o.

  • Cada sensor de gnss-ins pode definir o seu próprio prior do filtro ([imu_quantum.filter_prior] ou [imu_classical.filter_prior], com sigma_accel_bias e sigma_gyro_bias). A predefinição não muda, pelo que todos os cenários existentes dão o mesmo resultado. O viés residual do giroscópio de uma unidade de grau de consumo fica a cerca de 26 sigma fora da predefinição de grau tático, onde o filtro nunca o aprenderia. Um prior que não seja finito e positivo é rejeitado, e o resultado ecoa o prior quando um é definido.

  • kshana example [<name>] entrega a um utilizador do registo um cenário para executar. Um utilizador de cargo install kshana tem o executável e nenhum diretório scenarios/, pelo que o primeiro comando que todos os inícios rápidos lhe davam falhava. A interface de linha de comandos (CLI) passa a levar os 75 cenários de referência que funcionam sozinhos, byte a byte, compilados a partir de scenarios/ (src/bundled_scenarios.rs; a tabela vive no binário da CLI, pelo que a wheel Python e o módulo WebAssembly não crescem). kshana example lista-os; kshana example clock-holdover > clock-holdover.toml escreve um. Os outros dois ficheiros são só de repositório: lunar-llr-datum lê dados arquivados de telemetria laser lunar que só vêm com o repositório, e quantum-pnt-demonstrator.suite é um manifesto de estudo que executa três ficheiros irmãos com --study. Pedir qualquer um deles diz porquê e termina com 2 em vez de imprimir algo que não pode funcionar sozinho. tests/cli_first_run.rs mantém a tabela alinhada com o diretório nos dois sentidos, pelo que um novo ficheiro de cenário que não esteja incluído nem seja nomeado como só de repositório falha.

  • Cada figura de mérito num resultado de relógio, órbita, híbrido ou fusão indica agora se é VALIDATED ou MODELLED, no próprio resultado. O documento de resultado ganha um bloco figure_tiers, sempre a sua última chave. Lista cada valor comunicado (por exemplo quantum.fom.timing_p95_ns) com o seu nível — VALIDATED significa verificado face a uma referência externa independente, MODELLED significa um modelo de princípios básicos que é testado internamente — e a linha da matriz de verificação de onde o nível é lido. O nível vem de src/verification.rs através de src/fom_label.rs, pelo que não há uma segunda tabela que possa divergir. Antes disto, as palavras "validated" e "modelled" apareciam zero vezes num resultado de holdover de relógio, e quem lesse o JSON (JavaScript Object Notation) em bruto não tinha como distinguir os dois. Os valores de posição de hybrid e fusion não têm linha da matriz que os possua, pelo que são listados em untiered em vez de lhes ser atribuído um nível. O bloco não contém números. Está demonstrado que é aditivo, não assumido: removê-lo devolve o documento anterior à alteração byte a byte, para os cinco tipos de cenário (um teste do motor), e ambos os conjuntos de referência (tests/registry_golden.rs, tests/cross_platform_golden.rs) retiram agora exatamente esta chave, e só quando é a última, e depois calculam o hash do resto face às suas constantes congeladas inalteradas. Uma lista em cada conjunto fixa que cenários têm de conter o bloco, pelo que a exclusão não pode alargar-se em silêncio.

  • Um tipo de cenário telecom-timing responde nas unidades de um engenheiro de temporização: erro de tempo, erro máximo de intervalo de tempo (MTIE) e desvio de tempo (TDEV), cada um com um PASS ou FAIL e uma margem face às máscaras do Setor de Normalização das Telecomunicações da União Internacional das Telecomunicações (ITU-T). As máscaras são transcritas das edições em vigor: G.8272 (07/2025) para as classes A e B do relógio de tempo de referência primário (PRTC), G.8272.1 (2024) Amd. 1 (07/2025) para o PRTC melhorado em modo bloqueado e em holdover (incluindo a sua envolvente de erro de tempo, que sobe de 30 ns para 100 ns durante um período de holdover definido pelo tempo em que o relógio esteve bloqueado), G.8273.2 (2023) Amd. 2 (11/2025) para os relógios de fronteira e de escravo de tempo de telecomunicações, classes A a D, e G.8271.1 (2022) Amd. 3 (05/2025) para os limites de rede no ponto de referência C. Toda a entrada que essas Recomendações deixam "para estudo posterior" está ausente, não estimada, e docs/TELECOM-TIMING.md lista cada número com a sua tabela ou cláusula e cada item que ficou de fora. O relatório dá também o tempo até exceder cada orçamento de erro de tempo: por predefinição, a predefinição de holdover do ePRTC de 100 ns, uma atribuição de holdover de rede de 400 ns, o limite do ponto C de 1 100 ns e o requisito de ponta a ponta da classe 4 de 1,5 microssegundos.

    A entrada é um holdover sintético ou uma série própria. O sintético usa uma de quatro predefinições de oscilador (um oscilador de cristal de forno, um padrão de rubídio, um padrão de césio e um relógio atómico à escala de chip), cada uma com os valores de estabilidade, envelhecimento e temperatura de uma ficha técnica da Microchip identificada. A forma como esses valores se tornam ruído de frequência branco, de flicker e de passeio aleatório, envelhecimento e um termo de temperatura é indicada em cada relatório e identificada como MODELLED. Uma série própria são pares [time_s, time_error_ns], em linha (que é como funciona no navegador) ou, em compilações nativas, a partir de um ficheiro de valores separados por vírgulas. A tabela MTIE/TDEV, com o limite de cada máscara selecionada ao lado, é escrita como o artefacto CSV da execução.

    scenarios/telecom-prtc-holdover-24h.toml é um holdover de rubídio de 24 horas com envelhecimento, flicker e um ciclo diário de temperatura: o seu maior erro de tempo é 603,2 ns, cruza 100 ns 8 206 s após a perda e permanece dentro de 1,5 microssegundos durante todo o dia, e não satisfaz a envolvente de holdover do PRTC melhorado, como um relógio que não é de classe césio deve fazer. scenarios/telecom-tie-ingest.toml mostra a entrada em linha. O MTIE e o TDEV que o tipo de cenário comunica são verificados face ao pacote allantools numa série de holdover registada de 2 048 amostras, exatamente para o MTIE e a 1.1e-15 para o TDEV, pelo que a matriz ganha uma linha VALIDATED e duas MODELLED (a transcrição das máscaras e as predefinições) e fica agora em 171 linhas — 65 VALIDATED, 102 MODELLED, 4 PARTNER. A cobertura de unidades dos campos passa de 60 de 61 tipos de cenário para 61 de 62, e de 1 742 para 1 788 campos descritos. O tipo de cenário é novo e aditivo: nenhum cenário existente, valor fixado ou valor publicado muda.

  • O playground executa o motor num Web Worker em segundo plano, pelo que um cenário lento já não congela a página. web/engine-worker.mjs aloja o motor WebAssembly e web/engine.mjs encaminha para ele todas as execuções de cenários — execuções, varrimentos de parâmetros e as exportações SP3 / OMM / OEM / CSV. Uma execução que dure mais de 150 ms mostra um estado de ocupado (Run desativado, "Running… N s") e um botão Cancel que termina e volta a criar o worker; um navegador que não consiga iniciar um worker de módulo recorre ao antigo caminho da thread principal. cislunar-arc-recovery, deixado de fora do catálogo porque congelava a página, volta a estar nele, identificado como lento: demora cerca de 13 s no Chrome (quatro chamadas ao motor de cerca de 3 s cada), durante as quais a página continua a responder.

  • Todas as grandezas comunicadas de cislunar-observability têm agora uma unidade, uma classe de proveniência e uma definição — o penúltimo tipo de cenário na lista de isenções de todo o crate. Todos os 41 campos numéricos do documento RELEASED estão descritos, pelo que a cobertura de unidades dos campos passa de 59 de 61 tipos de cenário para 60 de 61 e de 1 698 para 1 742 campos descritos, com o atraso de campos sem definição inalterado em 239.

    Isto estava bloqueado pelo valor fixado que congela o documento publicado, que nomeava units como uma chave que o documento nunca podia ganhar. Acrescentá-la teria significado apagar essa asserção e reajustar a linha de base de três hashes em três ficheiros — uma forma indistinguível de encobrir uma regressão. Em vez disso, os dois valores fixados que medem este documento demonstram agora que o acréscimo é aditivo: cada um retira de novo o bloco units e recalcula o hash face à constante congelada antes de o bloco existir, e ambas as constantes estão inalteradas. Uma mutação confirma que a garantia é real — mover um valor publicado e reajustar a linha de base do hash do documento inteiro como faria uma correção descuidada, e a remoção seguida de novo hash continua a falhar. O terceiro valor fixado, no conjunto de referência genérico do registo, é reajustado em linha com os seis irmãos que foram reajustados exatamente por esta razão, e o seu literal expect_summary portador de valores não muda.

  • realtime-frame-eop comunica face a que referência foi avaliada cada linha de orientação da Terra, e com que frequência o recurso foi acionado. table3_joint_eop[].{ut1, polar_motion,combined} ganham truth_source e truth_fallback_rows. O piso final é avaliado face ao Bulletin B final e só pode usar épocas que publiquem um; cada linha dN é avaliada face a truth_pm()/truth_ut1(), que recorrem ao valor rápido do Bulletin A. No extrato incluído de 2026, isso são 12 de 31 amostras a um dia, face a 0 no piso — pelo que a linha do piso e as linhas de previsão ao lado assentam em referências mensuravelmente diferentes, o que o relatório passa a indicar em vez de o deixar para ser inferido de uma contagem de amostras que sobe onde os horizontes encaixados dizem que não pode.

  • moonlight-service-volume emite uma linha de base kepleriana de dimensão igual. ephemeris_comparison.keplerian_matched volta a executar a constelação ilustrativa com o número de satélites do próprio conjunto RECUPERADO, presente apenas quando as contagens diferem. A contagem faz parte da geometria desse projeto — a RAAN e a anomalia média são ambas distribuídas como 360k/n — pelo que, sem ela, um conjunto recuperado de cinco satélites era avaliado face a um ilustrativo de oito e o projeto era confundido com a dimensão. Para o conjunto de referência LANS de cinco satélites, 8,68 dos 14.24 pontos da lacuna de cobertura resultam ser os três satélites em falta e apenas 5,56 pontos o projeto; para as quatro naves realmente em órbita lunar, um conjunto de quatro satélites feito de propósito atinge 4,86 % onde elas atingem 0 %. Um teste fixa que a linha ajustada é uma constelação reconstruída e não a configurada com outra etiqueta, que foi como foi escrita pela primeira vez e o que a execução então comunicava.

  • Nove cartões de capacidades no site público, cobrindo 22 linhas da matriz de verificação que tinham sido publicadas sem cartão ao nível do produto. O motor tinha crescido numa família de capacidades — a verificação ARAIM face a vetores de referência publicados do Working Group C, geometria real de constelações lunares obtidas, o contorno de negação lunar com uma banda de C/N₀ medida, o passo do calendário VLBI para a covariância das estações, a transferência ótica e RF com injeção de falhas entre modalidades, a previsão de orientação da Terra em tempo real face ao Bulletin A arquivado, a partilha de abertura entre navegação e comunicações, a navegação por estima INS/TRN e a cobertura de unidades e proveniência — cada uma com uma linha da matriz e um cenário incluído, e nenhuma delas nomeada em kshana.dev. A cobertura de cartão para linha passa de 72 de 168 linhas para 94.

  • Oito cenários acrescentados ao catálogo do playground. O botão Run de um cartão de capacidade só aparece quando web/app.js também contém o ficheiro; seis cartões nomeavam um cenário que não continha, pelo que eram apresentados sem forma de os executar — um deles, o datum de telemetria laser real, estava nesse estado desde que foi publicado. tests/scenario_examples_doc_sync.rs impõe agora o invariante nas duas metades: o alvo run de um cartão tem de estar incluído em scenarios/ e ser oferecido pelo catálogo. Testado por mutação nos dois modos de falha.

  • moonlight-service-volume emite a sua geometria por satélite como <scenario>.table.csv quando um local de exportação está configurado (G11). É a maior lista que o crate publica — 2304 linhas na tabela conjunta de comunicações e navegação publicada — e chegava aos consumidores apenas dentro de JSON, o formato que truncou a curva de 57 pontos de um cenário irmão para 23 pontos sob uma coluna que alegava conter todos. Uma linha por ligação, a contagem de linhas na linha de cabeçalho, as colunas de antena presentes apenas quando uma antena foi configurada. Uma execução sem local de exportação fica inalterada byte a byte e não escreve nenhum ficheiro.

  • O SBOM descreve agora o que é distribuído: 60 componentes passaram a 66. scripts/gen-sbom.sh listava todos os pacotes da resolução com as funcionalidades predefinidas, incluindo as dev-dependencies. Isso punha sgp4 e chrono — crates só de teste, compilados em nenhum artefacto — na lista de materiais, e deixava de fora a cadeia --features python a que a wheel do PyPI se liga (pyo3, pyo3-ffi, pyo3-macros, pyo3-macros-backend, pyo3-build-config, portable-atomic, target-lexicon, heck), que é a fronteira de interface com código externo dessa wheel. O script percorre agora o grafo de resolução a partir do pacote kshana apenas por arestas normais e de compilação, sobre a união dos conjuntos de funcionalidades predefinido, python e wasm (o pacote npm leva este mesmo SBOM), para todas as plataformas alvo. O veredicto fixado de aderência à norma do CycloneDX é reajustado através do seu gerador registado: 60 → 66 componentes, 53 → 60 expressões de licença compostas e continua a haver zero erros de esquema depois de estas serem colocadas na forma expression normalizada.

  • A tabela CSV de reprodutibilidade chega a todas as portas de entrada, não apenas à CLI e à wheel Python. O servidor MCP ganha uma sétima ferramenta, export_table_csv, que executa um cenário e devolve a tabela estável ao byte que a CLI escreve como <scenario>.table.csv — ou um erro que nomeia os tipos de cenário que publicam uma (realtime-frame-eop, lunar-time-budget, lunar-jamming e moonlight-service-volume apenas quando export_site_lat_deg + export_site_lon_deg estão definidos). O módulo WebAssembly ganha table_csv, que devolve o mesmo texto ou undefined. O teste de ida e volta do MCP e os testes da ligação Python fixam agora o CSV devolvido byte a byte face a tests/golden/realtime-frame-eop.csv, e fixam que RunOutput.write_csv devolve os bytes escritos e 0 sem criar nenhum ficheiro para um tipo de cenário sem tabela. Todas as superfícies que indicam a contagem de ferramentas MCP ou as listam dizem agora sete.

  • run_all no módulo WebAssembly: uma execução do motor para todas as saídas. run, chart_svg, summary e table_csv executam cada uma o cenário de raiz, pelo que o playground pagava quatro execuções completas por clique — cerca de 12 s em vez de 3 s para cislunar-arc-recovery num navegador. run_all devolve {json, svg, summary, csv} a partir de uma só execução, e o playground usa-a agora. Coincide byte a byte com as quatro chamadas separadas.

Corrigido#

  • REVISÃO: o acoplamento do viés do giroscópio no filtro GNSS/INS tinha o sinal errado, e os valores de interrupção de gnss-ins mudam. O filtro de Kalman estendido (EKF) de estado de erro mantém ambos os vieses inerciais como resíduos (verdadeiro menos a estimativa corrente, realimentado por adição). A coluna do acelerómetro conduzia o erro de velocidade com +C_b^n b_a, mas a coluna do giroscópio conduzia o erro de atitude com −C_b^n b_g. Um viés residual do giroscópio roda na realidade a atitude calculada em +C_b^n b_g, pelo que cada estimativa do viés do giroscópio empurrava no sentido errado. O pacote só se manteve estável porque o seu prior predefinido do viés do giroscópio (1e-4 rad/s, 1 sigma) era suficientemente estreito para manter esses estados quietos. Com um prior mais largo, o filtro divergia mesmo quando o viés verdadeiro do giroscópio era zero: 93 m de erro fundido durante a interrupção tornaram-se 4,3 km. Os valores publicados de scenarios/gnss-ins.toml mudam do seguinte modo:

    gnss-ins.toml antes (≤ 0.27.2) depois
    IMU de átomos frios, RMS fundido durante a interrupção 96,1 m 1,9 m
    IMU de átomos frios, navegação por estima dentro da especificação (50 m) 30 s 60 s (a interrupção inteira)
    IMU tática, RMS fundido durante a interrupção 62,5 m 3,1 m
    IMU tática, navegação por estima dentro da especificação (50 m) 37 s 60 s (a interrupção inteira)

    Os valores em funcionamento livre (130,7 m e 314,3 m) não mudam; nunca usaram o filtro. A leitura anterior do pacote, de que a navegação por estima fundida é limitada por um piso de atitude na transferência e por isso não melhora com um sensor melhor, era um artefacto deste erro e é retirada. Com vieses constantes e sem ruído, o filtro aprende-os agora enquanto o GNSS está disponível, pelo que a navegação por estima fundida é um melhor caso. A referência externa filterpy (tests/gnss_ins_sensor_fusion_reference.rs) verifica apenas as atualizações de medição, razão pela qual nunca viu a propagação. Dois testes verificam agora o sinal diretamente e ambos falham com o antigo. O primeiro, em closed_loop.rs, introduz um viés residual conhecido do giroscópio no strapdown e exige que o filtro preveja o erro de atitude resultante com um erro até 2 %. O segundo exige que um prior largo aprenda um viés de giroscópio de 1e-3 rad/s e se mantenha dentro de 6 m. A referência multiplataforma de gnss-ins é fixada de novo por este motivo e por nenhum outro.

  • Todos os inícios rápidos do registo funcionam agora como escritos numa máquina limpa. Medido antes desta alteração, os exemplos do crates.io e do PyPI (Python Package Index) liam scenarios/clock-holdover.toml, que uma instalação a partir do registo não tem, e o exemplo npm falhava no Node.js com TypeError: fetch failed, porque o init() do pacote obtém o seu binário WebAssembly e o fetch do Node não consegue ler um ficheiro local. Agora:

    • README.crates.md e README.pypi.md contêm esse cenário em linha, como README.npm.md já fazia. O bloco de código Rust é um programa completo com o seu próprio main, porque a linha # Ok::<…> oculta pelo rustdoc com que terminava é mostrada no crates.io e não compila quando colada. tests/readme_code_fences_doc_sync.rs continua a compilá-lo byte a byte, e agora recusa também uma linha oculta no bloco.
    • README.npm.md separa o navegador do Node.js e dá uma receita para Node que lê o binário do disco e o passa a initSync. O teste de sincronização da documentação aceita initSync como o carregador que o wasm-bindgen gera.
    • Todos os três incorporam o cenário com as suas cadeias de proveniência por abreviar, pelo que o hash do cenário é 5ba83a232b94 em todas as superfícies. O exemplo npm costumava abreviá-las, o que lhe dava um hash diferente do da CLI.
    • Reproduzido a partir de compilações locais desta árvore: um projeto cargo new novo com uma dependência por caminho do crate empacotado compilou e executou o exemplo Rust; uma wheel construída com maturin a partir das fontes empacotadas, instalada num novo ambiente virtual, executou o exemplo Python; e o pacote wasm-pack --target web, empacotado e instalado com npm, executou a receita para Node. Os três imprimiram a mesma linha de resumo.
  • cargo run -- <scenario.toml> funciona a partir de um clone. Cargo.toml define default-run = "kshana". Sem isso, o cargo recusava com "could not determine which binary to run", que todas as linhas cargo run -- da documentação atingiam.

  • Os erros do primeiro minuto da CLI dizem o que fazer a seguir. Um caminho de cenário que não existe acrescenta agora uma sugestão a apontar para kshana example, e um segundo argumento posicional imprime o texto de utilização além de nomear o argumento. --help, --version, o erro de opção desconhecida (saída 2) e o ok: de uma linha de --validate em caso de sucesso já estavam em main. tests/cli_first_run.rs cobre agora todos eles, uma vez que nenhum teste executava o binário para nenhum deles antes.

  • list_kinds() em Python está documentada como devolvendo uma única cadeia JSON, não uma lista. Devolve os mesmos metadados que scenario_kinds(), serializados, pelo que iterá-la percorre caracteres. Mantém o seu retorno de cadeia para não quebrar os chamadores existentes. kshana.pyi, o comentário de documentação da ligação, docs/PYTHON_API.md e README.pypi.md dizem-no agora e apontam para scenario_kinds().

  • Os três READMEs do registo explicam todas as abreviaturas na primeira utilização. PNT está agora expandido no slogan, onde aparece pela primeira vez, e CLI, TOML, JSON, SVG, CSV, CSAC, HTML, URL e API estão expandidos nos ficheiros que os usam. O título da tabela de referências independentes deixa de dizer "CI-gated" antes de a CI ser definida.

  • Corrigido um valor publicado: a disponibilidade de ARAIM de dupla constelação nos TLE de GPS + Galileo do Celestrak incluídos no repositório. docs/CAPABILITY.md afirmava que juntar o Galileo eleva a disponibilidade de 0,21 para 0,67 com um VAL de 12 m e que o modo robusto a falhas de constelação é limitado com apenas duas constelações. Isso vinha de tests/araim_dual_real_data.rs propagar cada satélite a partir da sua própria época TLE (parse_propagators descarta a época), e as épocas nesses ficheiros abrangem 70,6 h (GPS) e 335,7 h (Galileo), pelo que os satélites estavam em instantes mutuamente inconsistentes. O teste mantém agora cada época (parse_tle) e avalia todos os satélites num único instante UTC comum, a época TLE mais recente do conjunto (2026-06-07T07:21:04). A disponibilidade medida nas mesmas 24 h, numa grelha de 289 amostras, passa a ser GPS isolado 0,993 (era 0,208), conjunto 1,000 (era 0,671) e dupla robusta a falhas de constelação 0,990 (era 0,031); no limite APV-I o modo duplo passa de 0,180 para 1,000. A conclusão inverte-se: num céu consistente, duas constelações sustentam a hipótese de falha de constelação com um VAL de 12 m. Os mesmos valores resultam com a época TLE mais antiga como referência. Uma autoverificação no teste fixa o seu ciclo de disponibilidade amostra a amostra a araim_dual_constellation_availability, pelo que a única diferença é o alinhamento temporal. docs/CAPABILITY.md e docs/REAL_TLE_GUIDE.md §3 contêm os novos números; a entrada 0.13.0 abaixo fica como foi publicada.

  • As superfícies públicas deixam de anunciar o RINEX 4 como validado. O motor recusa agora um ficheiro de navegação RINEX 4 pelo nome em vez de o descodificar mal, mas a grelha de normas ainda mostrava um cartão "RINEX 3 / 4" com uma etiqueta validado, ligada às evidências RINEX-3 do analisador de navegação. O cartão é agora "RINEX 3", e o README, docs/CAPABILITY.md, docs/STANDARDS.md, ROADMAP.md e o resumo de capacidades dizem o que é verdade: os ficheiros de observação RINEX 3.0x são analisados, espera-se que o formato de observação 4,00 também o seja mas nenhum ficheiro 4,00 foi lido pelo código, e os ficheiros de navegação RINEX 4 são recusados.

  • --validate diz quando "ok" significa que não havia nada para verificar. Cerca de dois terços do catálogo não publicam nenhum campo obrigatório — esses pacotes executam a sua configuração de referência a partir de um corpo vazio — pelo que a verificação só podia imprimir "ok" para eles, com as mesmas palavras que usava depois de verificar seis campos. A linha de sucesso indica agora o número de campos obrigatórios que encontrou presentes, ou que o tipo de cenário não exige nenhum.

  • scripts/gate.sh recusa um REPEAT ou TEST_THREADS não numérico. Com o bash 3,2, REPEAT=no fazia a comparação numérica dar erro e ser avaliada como falsa, pelo que o gate anunciava "repeatability loop SKIPPED (REPEAT=0)" para um valor que não era 0 e ainda assim escrevia um recibo. Ambos os parâmetros terminam agora com 2, a menos que sejam inteiros simples.

  • A MSRV é indicada como 1,85 em todo o lado onde uma pessoa a lê. Cargo.toml passou para 1,85 na última versão; o emblema do README, o texto de instalação e de resolução de problemas, codemeta.json e a própria justificação do crate MCP ainda diziam 1,75.

  • RunOutput.__repr__ na ligação Python comunica bytes, não "chars". Imprimia len() de cadeias UTF-8, que é uma contagem de bytes: 710 "chars" para uma tabela de 708 caracteres.

  • O README deixa de documentar --study --study-name em conjunto. --study-name é uma flag de cenário único, ignorada com --study (o binário avisa). Os dois exemplos de copiar e colar em README.md e README.crates.md mostram agora o comando de estudo sozinho.

  • As evidências de estabilidade de relógio do site indicam ambas as tolerâncias observadas. A série de césio 5071A é reproduzida a ≤ 3e-5 e o PHASE.DAT a ≤ 5e-5; o parágrafo indicava 3e-5 para ambos.

  • Dois ficheiros de saída do motor deixam de ser seguidos. scenarios/quantum-pnt-demonstrator.study.{json,html} tinham sido carimbados pelo motor 0.20.0 com todas as figuras de mérito vazias, e o próprio comando de estudo do README sobrescrevia-os, sujando a árvore e bloqueando o gate de push. *.study.json / *.study.html são agora ignorados como as outras quatro saídas do motor.

  • Um varrimento de sementes no playground deixa de falhar em todas as execuções. O varrimento percorria o parâmetro inteiro seed de forma linear (1, 10,9, 20,8, …), e o motor, ao lê-lo como u64, rejeitava cada valor fracionário. Os parâmetros inteiros varrem agora números inteiros distintos.

  • Todas as transferências do playground dizem que motor e que entrada as produziu. Alguns tipos de cenário (por exemplo realtime-frame-eop) não emitem engine_version nem scenario_hash, pelo que as suas transferências se chamavam simplesmente kshana-csv.csv. O nome recorre agora à versão do motor carregado e a uma impressão digital FNV-1a-64 de 12 dígitos hexadecimais do texto do cenário.

Alterado#

  • O crate publicado tem menos de metade do seu tamanho anterior, e cargo install kshana compila apenas a CLI. O pacote costumava incluir os artigos, os seus pacotes de submissão, os artefactos das figuras dos artigos, os notebooks, docs/, os scripts de manutenção e os programas de exemplo. Nenhum deles é compilado pela biblioteca ou pela CLI. Incluía também os três geradores internos em src/bin/ (crossover_study, gen_validation_artifacts, validation_report), pelo que uma instalação a partir do registo compilava e instalava quatro executáveis, três deles úteis apenas dentro de um checkout. Essas árvores e as três fontes dos geradores estão agora excluídas. O Cargo lista os binários de um pacote a partir dos ficheiros que ele contém, pelo que o manifesto publicado nomeia apenas kshana. Num clone, os geradores continuam a ser encontrados automaticamente, pelo que cargo run --bin <name> e a tarefa de versão que executa validation_report ficam inalterados. Medido com cargo package: 763 ficheiros, 16,7 MiB, 6,8 MiB comprimidos antes; 591 ficheiros, 10,5 MiB, 3,0 MiB comprimidos depois. A sua compilação de verificação, que compila apenas os ficheiros empacotados, passa. cargo install --path sobre o crate empacotado instalou um executável, kshana.

  • Uma saída que um engenheiro de temporização consegue ler: acabou p95 0.0ns, acabou security 0.000 sem ataque, e as contagens do site coincidem com as dos READMEs. Esta é uma revisão de apresentação. Nenhum número publicado muda; os valores JSON são idênticos, o que os hashes de referência acima demonstram.

    • A linha de resumo imprimia o erro de temporização do percentil 95 (p95) do relógio ótico como 0.0ns enquanto a tabela ao lado mostrava 1.20e-4 ns. Um valor de temporização não nulo demasiado pequeno para uma casa decimal é agora impresso com três algarismos significativos (p95 1.20e-4ns); um zero exato continua a ser impresso como 0.0. O relatório HTML (HyperText Markup Language), a tabela de comparação do estudo e o relatório transferível do playground usam a mesma regra, pelo que nenhum valor não nulo é impresso como 0.000 também.
    • security é um limite analítico de detetabilidade de spoofing que só tem significado face a um ataque configurado. Os tipos de cenário clock, orbit, hybrid e fusion não configuram nenhum, pelo que o seu resumo imprime agora security n/a (no attack) em vez de um número como 0.000 que se lê como uma deteção falhada. O valor mantém-se em fom.security, marcado applicable: false com o motivo em figure_tiers, e as tabelas dos relatórios mostram "not applicable". O tipo de cenário spoof continua a avaliar a deteção.
    • Dois valores fixados de resumo em tests/registry_golden.rs mudaram exatamente por estas duas razões e nenhuma outra: golden_clock (o p95 quântico e ambos os valores de security) e golden_orbit (ambos os valores de security; os seus valores p95 são exatamente zero). Os hashes dos documentos inteiros não mudaram. Os resumos esperados no README, nos três tutoriais e nos seus cenários didáticos foram atualizados em consonância, e tests/tutorials.rs verifica as cópias didáticas face ao motor.
    • A visita guiada do playground deixa de abrir no primeiro carregamento. O seu modal apanhava os primeiros cliques e o seu foco deslocava a página para longe de onde o visitante tinha chegado. Começa a partir do botão "Take the 60-second tour" ou do botão flutuante Tour.
    • A página deixa de se deslocar na horizontal num telemóvel. A 390 px, a linha da marca e o botão do GitHub chegavam a cerca de 410 px de conteúdo, um excesso de 4 px; o cabeçalho cabe agora a partir de 320 px, e a tabela de figuras de mérito desloca-se dentro da sua própria caixa em vez de alargar a página.
    • O explorador de capacidades começava pela sua própria contagem de cartões ("46 capability cards … 17 backed by an external oracle") ao lado de READMEs que dizem 64 de 168. Agora começa pela matriz de verificação, lida a partir do web/data/verification-matrix.json gerado (a mesma matriz a que as contagens do README estão fixadas), e nomeia os cartões depois, como a camada de resumo que são. web/counts.test.mjs, um novo passo no fluxo de trabalho de integração contínua (CI), verifica a aritmética e cruza o README.md com as descrições da página; tests/web_validation_counts_doc_sync.rs fixa a ligação do lado do Rust.
  • A descrição pública começa agora pela temporização e pelo holdover, o domínio mais bem validado. A abertura do README e docs/POSITIONING.md apresentam o Kshana como um motor aberto e reprodutível de evidências de resiliência PNT com proveniência identificada: primeiro a temporização e o holdover de infraestruturas críticas (os estimadores de Allan, Allan modificado, desvio de tempo e erro máximo de intervalo de tempo e a inversão da variância da navegação por estima em holdover são as linhas VALIDATED que a sustentam), a quântica como um método neutro de compromisso quântico-versus-clássico cujos resultados são identificados como MODELLED, e a navegação lunar / cislunar e de espaço profundo como capacidades mantidas e não como o destaque. Ambas as páginas dizem agora o que o Kshana não é — não é um simulador de sinais de radiofrequência nem uma bancada hardware-in-the-loop, nem um substituto do MATLAB/Simulink, do STK ou do Orekit — e apontam para o novo tipo de cenário telecom-timing e para docs/TELECOM-TIMING.md. A antiga frase "there is no good open tool" desapareceu: uma pesquisa que nada encontra não é evidência de que nada exista. ROADMAP.md ganha uma ordem de prioridades sem datas (primeiro a temporização, em segundo o compromisso quântico, o lunar mantido) e retira três itens desatualizados (as sistemáticas de Coriolis e de desvio de luz, as condições iniciais da NRHO e o cenário lunar, todos já publicados); a linha do README "Coriolis and light-shift remain roadmap" é corrigida da mesma forma.

  • docs/CAPABILITY.md deixou de subestimar-se. A linha dos referenciais fixos à Terra dizia "none" enquanto a matriz classifica GCRS→ITRS como VALIDATED; agora diz "full", e a linha dos referenciais de base regista a verificação cruzada com o ANISE como entregue. O modo guiado estava listado como roteiro; o playground já publicou controlos deslizantes guiados e uma visita guiada. Um varrimento face a src/verification.rs corrigiu mais cinco linhas que eram anteriores às suas validações: o modelo de forças de Cowell e a determinação de órbita em lote/sequencial face ao Orekit 12,2, as passagens de estações terrestres face ao detetor de elevação do Orekit, o núcleo de diluição da precisão face ao gnss_lib_py e a importação OEM face ao analisador independente oem; a linha de verificação e validação nomeia agora as salvaguardas que verificam que todos os testes citados existem.

  • O glossário explica o que diz um ficheiro de resultado. docs/GLOSSARY.md ganha entradas em linguagem simples para os termos de saída (holdover, p95, integridade, a pontuação de segurança, PDOP, sigma_y, q_wf), os termos de temporização de telecomunicações (erro de tempo, max|TE|, cTE, dTE, MTIE, TDEV, PRTC, ePRTC, T-BC, T-TSC, OCXO, CSAC) e os três níveis de evidência (VALIDATED, MODELLED, PARTNER).

  • As abreviaturas são explicadas na primeira utilização em todos os documentos públicos escritos à mão. O README e 24 ficheiros em docs/ tinham várias centenas de abreviaturas usadas antes da sua expansão, ou sem ela; cada uma está agora expandida onde aparece pela primeira vez nesse ficheiro. Os três ficheiros gerados (docs/VERIFICATION-MATRIX.md, docs/MODELLED-RATIONALE.md, docs/SCENARIOS.md) ficam intocados: são escritos a partir de src/verification.rs e api::list_scenario_kinds(), pelo que a sua redação tem de mudar na origem.

  • A cobertura de linhas tem uma medição de referência. docs/COVERAGE.md regista 95,63 % (37 697 de 39 419 linhas) da tarefa coverage da CI em b1d350d, e tests/coverage_figure_doc_sync.rs fixa a ela as cinco superfícies públicas "~96%" — o único número de destaque que era mantido à mão, e que já se tinha movido uma vez sem ser notado.

  • Novos gates de sincronização da documentação para superfícies que nada lia. tests/readme_code_fences_doc_sync.rs verifica cada import { … } from "kshana" num bloco de código JavaScript face às exportações WebAssembly, e fixa o exemplo Rust de README.crates.md byte a byte a uma cópia que o binário de teste compila. tests/security_md_doc_sync.rs falha se src/lib.rs perder #![forbid(unsafe_code)] ou se SECURITY.md deixar de o indicar. tests/no_overclaims.rs examina agora também web/README.md e os três READMEs do registo, e toda a norma no site tem de indicar explicitamente a sua proof.

  • As duas verificações de relógio em hardware real executam-se num runner. realdata-clock.yml (mensalmente e a pedido) obtém as séries 5071A e PHASE.DAT e executa ambos os testes com KSHANA_REQUIRE_REALDATA=1, pelo que uma entrada em falta falha em vez de ser ignorada. Ambos os scripts de obtenção estão fixados a um único commit do allantools e verificam o SHA-256.

  • O stub de tipos Python é verificado face à wheel compilada (mypy.stubtest na tarefa de ligações), que é como csv/write_csv foram publicados sem stub.

  • O glossário define URE, EOP, FoM, CTI e TIB, que o README e o registo usavam sem explicação.

  • O contrato publicado de campos de cada tipo de cenário é agora verdadeiro, e um teste mantém-no assim. Cinco dos 61 tipos de cenário mudaram. Os tipos de cenário com um required_fields não vazio passam de 21 para 22: ephemeris exige agora tle|orbit+epoch (um simples kind = "ephemeris" costumava passar --validate e depois falhar a execução), e quantum-trade acrescenta candidate_adev_taus+candidate_adev_values|candidate_clock_class, que a sua execução já exigia. Uma entrada obrigatória pode usar | (uma destas) e + (todas estas em conjunto); --validate compreende ambos. lunar-joint-od-clock, pvt e earth-gnss-lunar publicam 9 campos opcionais reais que tinham deixado de fora. docs/SCENARIOS.md diz agora que kind é obrigatório para todos os tipos de cenário exceto clock. tests/required_fields_are_true.rs verifica cada tipo de cenário face ao seu cenário distribuído: remover qualquer entrada obrigatória tem de fazer a execução falhar, e um documento que contenha apenas os campos obrigatórios tem de executar.

  • As notas do JetBrains Marketplace passam por um gate. scripts/check-version-sync.sh passa a falhar se a entrada mais recente de <change-notes> em plugin.xml não indicar a versão que está a ser lançada; sete versões publicadas tinham servido as notas da 0.22.0 sem alterações.

  • O valor de cobertura do relatório técnico é o valor medido. paper/kshana-technical-report.md dizia "cerca de 97 %"; passa a dizer cerca de 96 % (95,63 % medido, docs/COVERAGE.md) e é a sexta superfície que o teste de cobertura fixa.

  • O cliente do motor fora da thread principal é testado (web/engine.test.mjs, na CI): lista de permissões de despacho, cancelamento e novo arranque, as três vias de recurso na thread principal e recuperação após falha, tudo contra um worker simulado.

  • Nada é publicado até o commit marcado ter passado nos seus testes, e uma versão só está concluída quando todos os registos a servem. A ordem passa a ser etiqueta, verificação, publicação, paridade, sítio, numa única execução de release.yml (docs/RELEASING.md).

    • A publicação aguarda o veredicto. publish.yml, mcp-publish.yml e jetbrains-plugin.yml deixam de arrancar com o push da etiqueta; release.yml chama-os a partir de tarefas que declaram needs: verify. Antes, corriam em corrida com ela: na v0.27.2, o crates.io, o npm e o Python Package Index (PyPI) tinham todos publicado em 4,5 minutos após a etiqueta, e verify devolveu o resultado 84 minutos depois; na v0.27.0, o npm e o PyPI publicaram enquanto a tarefa do crates.io falhava. Uma repetição manual numa etiqueta é retida pelo novo scripts/check-release-verdict.sh, que exige um verify verde para esse commit exato, obtido a partir da interface de Actions, e falha em modo seguro perante qualquer outra coisa.
    • Tudo é construído antes de qualquer envio, e o crates.io, cujo passo de empacotamento foi o que falhou a meio de uma versão, publica primeiro.
    • A falta de um token de registo faz a tarefa falhar em vez de saltar o envio e comunicar êxito.
    • Uma verificação de paridade após a publicação. scripts/check_channel_parity.py consulta periodicamente o crates.io (kshana e kshana-mcp), o npm, o PyPI (a distribuição de código-fonte e as seis wheels de plataforma) e o ghcr.io até cada um servir a versão, ou falha a execução; o docs.rs e o registo do Model Context Protocol (MCP) são comunicados, mas não exigidos. Executada sobre versões anteriores, deteta a 0.22.0 em falta no npm e no PyPI, a 0.23.0 no PyPI e a 0.27.0 no crates.io.
    • Binários de linha de comandos pré-compilados para macOS (Apple silicon e Intel) e Windows x86-64, com o nome do alvo (kshana-aarch64-apple-darwin e semelhantes), ao lado do kshana para Linux, cujo nome não muda. Um ficheiro SHA256SUMS abrange todos os ativos, e verify-release verifica-o e executa os binários de macOS e de Windows nos respetivos sistemas.
    • O kshana.dev mostra uma versão publicada, não main. Costumava ser reimplantado a cada push para main, enquanto as suas páginas indicavam a última versão. pages.yml passa a construir apenas uma etiqueta de versão: a versão aciona-o quando todos os canais servem a versão, e um acionamento manual reimplanta a última versão (ou uma indicada).
    • Uma única origem de wheels. A matriz de seis alvos copiada à mão em publish.yml desapareceu; passa a chamar wheels.yml, pelo que a barreira de etiquetas do auditwheel e a verificação de reprodutibilidade ao byte avaliam agora as wheels que o PyPI recebe, e uma falha em qualquer delas interrompe a versão.
    • Ferramentas de compilação fixadas. Todos os fluxos de trabalho pedem o Rust 1.93.0 (a tarefa msrv, a sua própria versão); publish.yml e pages.yml tinham pedido @stable, e o registo da v0.27.2 mostra o rustup a instalar a 1.98.1 e a compilar depois com a 1.93.0 apenas porque rust-toolchain.toml tem precedência sobre ela. O wasm-pack está fixado na 0.13.1 (a versão que compilou a v0.27.2, escolhida pelo script instalador sem versão fixada) com uma verificação de soma de controlo, e o mcp-publisher na 1.8.1 com o respetivo SHA-256 publicado. scripts/check-toolchain.sh passa a falhar se um fluxo de trabalho pedir outro compilador ou encaminhar um script descarregado para uma shell. Nenhuma tarefa de verificação, nenhum valor de referência fixado e nenhum script de barreira local foi removido ou afrouxado.

Segurança#

  • Todas as GitHub Actions de terceiros estão fixadas por SHA de commit — 93 referências em 15 fluxos de trabalho, 92 delas de novo — com a etiqueta mantida como comentário final para o Dependabot a atualizar. A exceção é dtolnay/rust-toolchain, cuja etiqueta é o seletor da cadeia de ferramentas.

  • As camadas de base da imagem do servidor MCP estão fixadas por digest multiarquitetura, e o Dependabot passa a vigiar o Dockerfile de mcp/kshana-mcp, pelo que as camadas do SO continuam a receber atualizações de segurança — através de um PR revisto.

  • A verificação etiqueta-versus-manifesto é executada nos dois fluxos de publicação que lançam a versão da etiqueta. mcp-publish.yml (imagem ghcr, registo MCP) e jetbrains-plugin.yml (Marketplace) correm em corrida com publish.yml em vez de o aguardar, pelo que uma etiqueta mal criada só era barrada num fluxo irmão. Ambos passam a executar scripts/check-version-sync.sh antes de compilar.

  • Foram corrigidos quatro avisos de segurança que o Dependabot levantou no dia em que os seus alertas foram ativados. O servidor MCP passa de rmcp 1,7 para 2,2: três avisos contra rmcp < 2,1 (uma fuga na tabela de sessões Streamable-HTTP, a falta de validação de recurso protegido OAuth, cabeçalhos personalizados a seguirem um redirecionamento entre origens) — nenhum alcançável aqui, uma vez que o servidor fala apenas stdio, mas um crate publicado não deve fixar um SDK vulnerável. As macros de rmcp 2 exigem o Rust 1,88, pelo que só kshana-mcp declara agora rust-version = "1.88"; a biblioteca kshana permanece em 1,85. A única alteração de API (Content → ContentBlock) está aplicada, e os testes de ida e volta passam. A ação de análise do SonarQube passa da v5 para a v6, o que corrige um aviso de injeção de argumentos (≥ 4,0, < 6,0).

0.27.2 - 2026-09-22#

Adicionado#

  • Todos os itens Rust citados por uma linha da matriz de verificação são agora resolvidos face ao crate. A proteção existente verificava as citações com forma de caminhos de ficheiro; 63 das 164 linhas que não são de parceiro indicam a sua evidência como um item interno ao crate — navsignal::code_tests, integrity::tpl_scalar::tests, api::tests::tracking_loop_kind_round_trips_through_the_dispatch — e um token sem sufixo .rs era invisível para um analisador de caminhos. Essas linhas podiam ter indicado um módulo renomeado, um módulo de testes esvaziado ou uma função que nunca existiu, e todas as barreiras teriam permanecido verdes.

    tests/verification_rows_name_a_test_that_exists.rs resolve todas as 339 citações deste tipo através da árvore de módulos, exige que cada linha que não é de parceiro indique pelo menos um teste que de facto tenha #[test], e exige que as linhas de parceiro não indiquem nenhum. Foram usadas quatro mutações para o avaliar: renomear um módulo citado, apontar a única citação de teste de uma linha para uma função que não é um teste, renomear o verdadeiro mod tests e retirar-lhe os atributos #[test] — cada uma fica vermelha na asserção que lhe corresponde.

    Uma linha já estava errada: Alternative / complementary PNT citava tests/*, um glob, que não é uma citação. Passa a indicar tests/alternative_complementary_pnt_reference.rs e os três módulos de teste internos ao crate que lhe servem de base.

  • As figuras publicadas são reverificadas face ao motor em cada compilação (tests/published_figures_still_reproduce.rs). Os três gráficos de demonstração do README são a saída chart.svg do próprio motor e nada voltou a executar o cenário; os dois estudos de cruzamento do artigo foram gerados uma só vez e submetidos; e o README indica quatro figuras de mérito em prosa ao lado de scenario-fom.png. Todas as três estão agora fixadas à saída do motor em execução.

    A sua reconciliação revelou o resultado útil: os gráficos de demonstração tinham sido desenhados com o motor 0.22.0 e o JSON de cruzamento do artigo com o 0.20.0, e na 0.27.1 todos os valores representados nos cinco artefactos são idênticos — os três SVG de gráficos diferem de uma execução nova exatamente em dois carateres cada um, o carimbo de versão no rodapé. Os gráficos foram novamente renderizados para que o rodapé seja verdadeiro. O JSON do artigo é deliberadamente deixado com o carimbo 0.20.0: é o registo da execução cuja figura um artigo publicado incorpora, e recarimbá-lo reivindicaria uma proveniência que o PDF não tem. A proteção afirma, em vez disso, a propriedade mais forte — que o motor atual continua a reproduzir todos os valores publicados.

Corrigido#

  • As análises do SonarCloud eram registadas como VERSION=not provided, pelo que o período de código novo de previous_version nunca avançava: continuava ancorado na análise de 2026-07-02, avaliando oitenta e dois dias de trabalho como um único delta e medindo 7877 linhas duplicadas "novas" face a um limiar de 3 %. A análise passa agora a indicar a versão do crate. A duplicação subjacente é real e não é escondida por isto: concentra-se nos registos declarativos FieldUnit repetidos em ensemble, hybrid, fusion, inertial e report, e na tabela de verificação de 168 linhas, e é aqui nomeada como trabalho a fazer em vez de excluída da medição.

  • scripts/gate.sh não tinha um bloqueio de escritor único, e todas as execuções escreviam o mesmo registo. Isto não é uma questão de arrumação: integration_binaries, tests_passed e tests_ignored do recibo são lidos de volta A PARTIR desse registo, e o hook de pre-push confia no recibo. Uma barreira que tivesse sido terminada mas cujo binário de testes ainda estivesse vivo continuava a escrever no ficheiro que a execução seguinte acabara de truncar — pelo que as contagens de uma execução podiam ter sido dadas como as de outra, permitindo um push com base numa suite que nunca correu na árvore que estava a ser enviada. Passa agora a haver uma barreira por cópia de trabalho (recusando com o código de saída 75 se houver uma ativa, e limpando um bloqueio obsoleto cujo pid já não existe) e um registo por execução, com target/gate-run.log atualizado a partir da execução que termina, à saída. Ambos os sentidos são testados: um pid ativo recusa, um pid inexistente é limpo.

  • src/verification.rs afirmava que os seus testes "não provam que as cadeias de teste/referência independente nomeadas resolvem para código ativo". Duas proteções fazem agora exatamente isso, pelo que a documentação do módulo dizia o oposto da verdade; passa agora a indicar o que é verificado por máquina e o que fica ao critério humano. Uma referência desatualizada a verification::gen — o módulo é artifacts — é corrigida na documentação da própria proteção irmã.

Alterado#

  • main foi reescrito em 2026-09-22 e enviado com force-push. Dez commits passaram a quatro. A reescrita fundiu cada commit que deixou uma barreira vermelha no commit que a resolveu, de modo que todos os commits em main têm agora uma árvore que passa, e removeu as execuções canceladas que um grupo de concorrência abrangente a todo o ramo deixava em cada commit substituído.

    Nada foi descartado. Os commits anteriores à reescrita continuam acessíveis através das etiquetas que apontam para eles, e a árvore final é idêntica ao byte à árvore de que a reescrita partiu — git diff entre o antigo topo e o novo é vazio, exceto pelos três ficheiros de fluxo de trabalho que esta versão altera.

    Os SHA substituídos, para quem tenha uma referência a algum deles:

    antigo assunto
    9733177 docs(changelog): disclose the authorship rewrite and the two dangling crate sha1s
    5d16ea8 fix(docs): the engine-flow diagram said 6 figures of merit; the engine scores 7
    148d31d fix(test): two more cross-platform pins, and two wrong assumptions of my own
    a3a2667 feat(web): surface the lunar cluster on the site — seven capability cards
    1e8bec6 docs(lunar): document 42 public fields and ratchet the ceiling down to 985
    7bba514 chore(release): v0.27.0
    3154548 test(docs): guard the distribution diagram, the last unguarded one
    7864142 chore(release): v0.27.1

    As etiquetas v0.27.0 e v0.27.1 deliberadamente NÃO foram movidas. Continuam a apontar para 7bba514 e 7864142, os commits exatos cujas árvores produziram os artefactos agora ativos no crates.io, no npm, no PyPI, no ghcr.io e no registo MCP. O .cargo_vcs_info.json de um crate regista o sha1 a partir do qual foi empacotado, os registos são imutáveis, e a atestação de proveniência de compilação SLSA nos ativos da versão v0.27.1 está ligada a esse commit. Mover as etiquetas teria deixado todos esses artefactos publicados a apontar para um commit que já não existe. Deixá-las mantém os commits antigos acessíveis e todas as cadeias de proveniência publicadas a resolver, ao custo de duas etiquetas que deixam de ser antecessoras de main — que é a razão de esta versão existir: a v0.27.2 dá a main uma etiqueta própria, empacotada a partir de um commit que lhe pertence.

    Esta é a segunda reescrita divulgada deste histórico; a primeira, em 2026-09-21, canonicalizou a autoria e está registada nas notas da 0.27.0 com os seus dois sha1 de crate órfãos. Uma reescrita é aqui divulgada de cada vez, porque um repositório que vende proveniência verificável não pode mover discretamente o chão sob um artefacto publicado.

0.27.1 - 2026-09-22#

Corrigido#

  • O crate publicado não compilava. src/lunar_orientation.rs contém um include_str! de nível superior de tests/fixtures/llr_geometry/de440_moon_pa.csv, e o manifesto exclui /tests/fixtures do pacote, pelo que o tarball que o crates.io recebe não tinha um ficheiro que a própria biblioteca incorpora. A publicação da v0.27.0 falhou a sua compilação de verificação por esse motivo e nenhuma 0.27.0 chegou ao crates.io; o npm e o PyPI, cujas tarefas não dependem dele, publicaram normalmente. A exclusão passa a incluir uma exceção para esse único catálogo.

    Todos os outros include_str! de um ficheiro de teste em src/ estão dentro de um módulo #[cfg(test)] e, por isso, nunca chegam à biblioteca empacotada. Só um de nível superior chega.

  • Nada na CI executava cargo package, razão pela qual um tarball que não compila foi descoberto pela primeira vez pela tarefa de publicação, depois de dois outros registos já o terem lançado. Uma tarefa package passa agora a construir e compilar o tarball exato a cada push.

Alterado#

  • As fixações de emissão da realização do referencial lunar deixam de mudar a cada incremento de versão. O rodapé do SVG contém a versão do motor, pelo que cada versão voltava a fixar três hashes — duas vezes no mesmo dia — e uma fixação refeita por rotina deixa de ser lida. A cadeia de versão é normalizada para um marcador antes do cálculo do hash, e afirma-se separadamente que a emissão indica a versão em execução, de modo que esse facto é verificado com mais precisão do que o hash alguma vez o verificou.

0.27.0 - 2026-09-22#

Adicionado#

  • lunar-llr-datum — o datum do referencial lunar a partir de uma campanha de observação real. lunar-frame-campaign substituiu uma transformação de Helmert injetada por uma campanha simulada e disse-o: a sua rede de estações, o seu calendário e o seu sigma por observação são entradas ilustrativas. Este cenário retira a simulação dos dois sítios onde um calendário e um modelo de erro entram na resposta. As épocas são os instantes de emissão de 337 pontos normais arquivados de telemetria laser lunar do ILRS (2015-04-08 .. 2015-06-27, Grasse MeO 7845 e Matera MLRO 7941, todas as cinco matrizes de retrorrefletores), e cada peso de observação é a precisão arquivada desse próprio ponto normal, bin_rms / sqrt(n_raw) — uma mediana de 5,13 mm de distância de ida, retirada do ficheiro e não escolhida aqui. As coordenadas das estações provêm do IERS ITRF2020 e as coordenadas dos refletores do JPL DE430 Tabela 7; cada ficheiro de teste regista um URL, uma data de obtenção e um SHA-256 e regenera-se a partir da sua fonte por um gerador submetido que verifica a fonte e aborta em vez de emitir um número. O relatório indica quais as ligações medidas e quais continuam modeladas, e as modeladas são medidas: a distância de ida observada menos calculada sobre os dados reais é de 156 494 m RMS, o que o mesmo conjunto de testes confirma face ao JPL Horizons no mesmo intervalo (195 655 m RMS vetorial, pior época 0,054° — dentro dos ~0,3° que a série lunar analítica incorporada reivindica para si própria). Aditivo: um novo tipo de cenário, um novo leitor (realdata::llr_crd) e um novo módulo (lunar_llr); os pacotes de referencial lunar existentes ficam fixados bit a bit.

  • sigma_ure_m como parâmetro de cenário em lunar-integrity e moonlight-service-volume. A exatidão de medição de distância do sinal no espaço era uma constante em tempo de compilação (LUNAR_SIGMA_URE_M), pelo que uma varredura do volume de serviço só podia responder passa/falha a um único valor fixo. Os níveis de proteção são exatamente lineares nela, pelo que expô-la transforma a varredura num requisito de exatidão de medição de distância sobre todo o volume. A predefinição reproduz o comportamento anterior bit a bit.

  • Exportação de geometria por satélite em moonlight-service-volume: export_site_lat_deg + export_site_lon_deg acrescentam uma matriz per_sat_geometry com o azimute, a elevação e a distância oblíqua a cada satélite em cada época para um local selenográfico nomeado, mais o indicador de visibilidade. O resumo agregado de cobertura colapsa deliberadamente a geometria por satélite, mas a distância oblíqua é exatamente o que um balanço de ligação consome, pelo que uma análise conjunta de comunicações e navegação não podia ser feita apenas a partir do resumo. Desativada, a menos que ambas as coordenadas sejam indicadas; puramente aditiva.

  • lunar_service::topocentric, o auxiliar público de ângulos de visão por trás da exportação.

  • Uma linha da matriz de verificação para a nova capacidade de geometria.

  • O diagrama de antena real na exportação de geometria. O motor transporta desde a P1 um diagrama de abertura circular uniformemente iluminada (antenna::pattern_gain_dbi, a forma de Airy [2·J₁(x)/x]²) e nada fora de antenna.rs o usava — em vez disso, quem fazia o trabalho era um ganho no eixo emparelhado com uma regra empírica de ganho para largura de feixe. Uma tabela export_antenna opcional em moonlight-service-volume (lida apenas quando o local de exportação está definido) fornece agora a cada linha exportada o ângulo fora do eixo no satélite e o ganho de emissão em direção ao local a partir desse diagrama, e acrescenta um bloco antenna_pattern que comunica a contagem dentro do feixe segundo o diagrama real ao lado da contagem dentro do feixe segundo a aproximação simétrica (θ₃dB[deg] = √(31000/G_lin)), com a diferença como correção nomeada. Ambos os números são emitidos; nenhum substitui o outro. Medido na abertura lunar representativa do próprio motor (antena parabólica de 1 m, 2,4 GHz, η = 0,60) sobre um local polar sul e a malha ilustrativa de classe LCNS, os dois divergem em mais de um satélite: o diagrama real coloca 0 de 76 ligações visíveis dentro do feixe de meia potência, a aproximação afirma 28 — uma correção de −2,33 satélites por época, pior época individual 3. A aproximação traz uma eficiência de abertura própria (0,641 face à regra de 70·λ/D graus com que é normalmente citada, 0,920 face a uma abertura circular uniforme), pelo que numa antena com η = 0,60 devolve um feixe 1,238× demasiado largo; o bloco emite ambas as eficiências implícitas em vez de as deixar para inferência. Puramente aditiva: medidas no ponto de funcionamento documentado, 597 folhas pré-existentes, 0 alteradas, 0 removidas, 494 acrescentadas.

  • antenna::symmetric_beamwidth_rad, antenna::symmetric_relation_implied_efficiency, antenna::within_half_power_beam, antenna::HALF_POWER_DROP_DB, antenna::SYMMETRIC_GAIN_BEAMWIDTH_CONST_DEG2, antenna::UNIFORM_APERTURE_HPBW_COEFF e lunar_service::nadir_off_boresight_rad, as peças públicas que lhe servem de base. O diagrama está também agora ancorado nas constantes de Airy publicadas, e não apenas em si próprio: o cruzamento de meia potência é localizado por bissecção e comparado com x = 1.61634, o que torna a largura de meia potência exata 1.02899·λ/D e regista com honestidade que o coeficiente convencional 1.02 coloca pattern_gain_dbi em −2,955 dB, não em −3,010 dB.

  • Uma tabela de reprodutibilidade em formato longo para lunar-time-budget. As saídas em matriz do cenário — a grelha de tempos de média, as sete curvas x(τ) por termo e o seu total em raiz da soma dos quadrados — chegavam aos consumidores apenas como matrizes JSON. Uma tabela publicada foi truncada em 400 carateres e publicou 23 dos seus 57 tempos de média sob uma coluna que afirmava conter todos, e o manuscrito reconstruiu as curvas por termo a partir de formas fechadas porque o motor nunca as emitiu. Uma execução simples passa também a escrever <scenario>.table.csv com uma linha por (índice da grelha, tempo de média, termo), que não pode ser truncada em algo que ainda pareça completo. O índice da grelha é uma chave de junção exata; τ é escrito com 13 algarismos significativos e cada x com 7, para que os bytes não divirjam entre compilações da mesma fonte. Puramente aditiva: o JSON do relatório é idêntico ao byte.

  • O relatório de hybrid-optical-rf passa a descrever-se a si próprio. Um bloco link_configuration reproduz as entradas da ligação já resolvidas — comprimento de onda da portadora, abertura de emissão e de receção, distância, largura de impulso, tempo de integração, eficiências e perdas — com as predefinições aplicadas, para que um artigo indique a configuração com que correu em vez de citar uma predefinição lida do código-fonte. Um bloco units indica a unidade e a classe de proveniência de cada grandeza que um artigo provavelmente citará. Os traços das covariâncias de transferência são a razão da sua existência: eram emitidos como um simples variance e um manuscrito inferiu metros quadrados a partir de uma verificação de consistência interna. A inferência estava certa, e é exatamente por isso que era um defeito — nada teria detetado que estivesse errada. Puramente aditivo: medidos em quatro configurações, 456 campos pré-existentes, 0 alterados, 0 removidos, 196 acrescentados.

  • Uma linha da matriz de verificação para a tabela de reprodutibilidade do orçamento de tempo, com honestidade InternalConsistency / MODELLED — o total é verificado face à raiz da soma dos quadrados dos termos no mesmo ficheiro, que partilha as definições de termos do próprio motor e por isso não é uma referência independente. Em conjunto, estas acrescentam três linhas. O total acumulado desta secção por publicar é de 168 linhas — 64 VALIDATED, 100 MODELLED, 4 PARTNER.

Alterado#

  • A autoria dos commits em todo o histórico é agora uma única identidade, e dois crates publicados apontam para um commit que já não existe. Em 2026-09-21, o histórico git foi reescrito de modo que todos os commits humanos são autorados e submetidos por ashfordeOU <236818772+ashfordeOU@users.noreply.github.com>. Anteriormente apresentava três grafias de uma mesma pessoa — 688 commits como ashfordeOU <contact@ashforde.org>, 34 como Chakshu Baweja <contact@ashforde.org> e 94 já canónicos. O único commit de dependabot[bot] foi deliberadamente deixado com o seu próprio autor: renomear o incremento de dependência de um bot reivindicaria a autoria de trabalho que ninguém aqui fez.

    Nenhum conteúdo mudou. A reescrita tocou apenas nos cabeçalhos de autor e de committer, e isso é verificável em vez de afirmado: a árvore de cada etiqueta e de cada ramo é idêntica bit a bit ao que era antes. v0.26.0 continua a resolver para a árvore 92284e9420605568f1bfabb78cd95d383b40f3e2, exatamente como antes.

    O que custou. O nome de um commit é um hash sobre a sua árvore, os seus pais e os seus cabeçalhos de autor, pelo que alterar um antecessor muda o nome de todos os descendentes. O commit da versão v0.26.0 era dce2dbf7700788cf6de46260c14673c0e5347360 e passou a ser d4921f3025569e00e425e1747d0acfc261e96e18. Dois artefactos registaram o nome antigo no momento da publicação e não podem ser corrigidos, porque uma versão publicada num registo é imutável por conceção:

    • kshana 0.26.0 no crates.io — .cargo_vcs_info.json regista dce2dbf…
    • kshana-mcp 0.26.0 no crates.io — o mesmo sha1, path_in_vcs: mcp/kshana-mcp

    Mais nada é afetado. O pacote npm não regista gitHead, e a distribuição PyPI não regista nenhum commit; ambos foram verificados em vez de presumidos.

    Não existe nenhuma reparação que faça dce2dbf… nomear o commit reescrito: essa cadeia é a ascendência antiga, e a única forma de a resolver é manter publicado o histórico anterior à reescrita, o que restauraria a autoria que a reescrita removeu. A proveniência da 0.26.0 passa, portanto, pela etiqueta e não pelo sha1 registado — e a etiqueta entrega os mesmos bytes a partir dos quais o crate foi construído. A versão seguinte regista um commit válido, sem necessidade de qualquer ação.

Corrigido#

  • realtime-frame-eop tinha como predefinição um ficheiro EOP sem linhas de previsão (G12). O cenário incorporava como predefinição offline um extrato finals2000A de cinco linhas apenas finais, pelo que uma execução simples comunicava predicted_rows.n = 0 e a tabela por horizonte assentava em pares de 5, 4, 3 e 2. O motor sempre pôde ler uma linha de previsão — o ficheiro de entrada é que não tinha nenhuma. A predefinição é agora o extrato IERS 2026 textual (tools/finals2000A_2026.txt, MJD 61173–61204): 20 finais do Boletim B e 12 linhas do Boletim A só de previsão, pelo que uma execução simples sem argumento de ficheiro e sem rede comunica predicted_rows.n = 12 e uma tabela por horizonte com n = 20 / 31 / 30 / 29, e a comparação com o previsor operacional e a concordância com as previsões publicadas do próprio produto também ficam preenchidas. O extrato longo de 45 linhas foi medido como alternativa e rejeitado: também é apenas final, pelo que teria deixado predicted_rows.n em 0. Isto altera números publicados, ao abrigo da regra R4 e com autorização do fundador: dez das 22 células do p4_frame_eop.csv publicado e 24 das 42 células preenchidas de tests/golden/realtime-frame-eop.csv. O piso medido do polo rápido-menos-final passa a 0,0678 mas (dos 0,0769 mas), que é o valor que a própria tabela de movimento polar do artigo P4 já publica com n = 20 — os dois passam a concordar em vez de diferirem em 13,5 %. Todas as outras figuras que o P4 imprime a partir desta tabela ficam inalteradas na precisão impressa. A enumeração completa antigo → novo, incluindo os campos que não mudaram, está em docs/revisions/G12-default-eop-cell-changes.md. O extrato apenas final continua a ser distribuído, fixado ao byte e exercitado: uma contagem de zero linhas de previsão nele é uma propriedade do ficheiro, e um teste continua a prová-la.

  • Um limite desatualizado do número de satélites em moonlight-service-volume. O cenário limitava n_sats a 12 embora o seu próprio construtor de constelações suporte 24 e um teste afirme 24, pelo que toda a contagem pedida acima de 12 era reduzida em silêncio e uma varredura do número de satélites devolvia valores idênticos acima de 12 — indistinguíveis de uma saturação geométrica genuína. Passa agora a ser limitado ao limite do construtor. Esta é uma alteração de comportamento apenas para n_sats > 12.

  • O mesmo limite desatualizado em lunar-differential-pnt. lunar_dpnt limitava n_sats a 12 com a mesma consequência, e esta chegou a uma tabela publicada: dpnt_nsats_sweep.csv contém uma linha n = 16 idêntica ao byte à sua linha n = 12, porque o motor devolveu uma resposta de doze satélites sob uma etiqueta de dezasseis satélites. Passa agora a ser limitado ao limite do construtor de 24, e um novo teste fixa-o — cada constelação maior tem de comunicar a sua própria contagem e de melhorar estritamente o nível de proteção, para que o limite não possa regressar sem ser notado. Isto altera números publicados: o nível de proteção com n = 16 passa de 16,92 m → 14,57 m. Varrida até 24, a curva é estritamente monótona (11,94 m com 24 satélites, 29,5 % melhor do que com 12), pelo que não há saturação em 12 — o aparente patamar era o limite. Alteração de comportamento apenas para n_sats > 12.

0.26.0 - 2026-09-18#

Uma versão de documentação, transparência e playground. Nenhum comportamento do motor muda: a matriz de verificação mantém-se em 102 linhas — 56 VALIDATED, 42 MODELLED, 4 PARTNER, sem alteração desde a 0.25.0.

Adicionado#

  • rustdoc ao nível do crate (//! em lib.rs) que abrange os pontos de entrada, o modelo de honestidade/níveis e a reprodutibilidade, para que o docs.rs abra numa verdadeira página de entrada em vez de uma simples parede de módulos.
  • docs/SCENARIOS.md — uma referência por tipo de cenário para todos os 50 tipos de cenário, gerada a partir de api::list_scenario_kinds() (a única fonte de verdade) por gen_validation_artifacts e protegida por tests/scenarios_reference_doc_sync.rs, pelo que não pode divergir do despachante.
  • Documentação de módulos para os 11 módulos públicos anteriormente sem documentação (allan, estimator, fom, hybrid, inertial, models, report, run, scenario, timetransfer, types).
  • Fontes bibliográficas para cinco módulos de fórmulas que enunciavam uma equação mas não indicavam nenhuma referência: batch_ls (Tapley/Schutz/Born; Bjorck), cr3bp (Szebehely; Koon et al.), detection (Kay), attitude_budget (Wertz; Sidi), reentry (Allen-Eggers, NACA TR-1381).
  • Um security.txt publicado em kshana.dev para divulgação coordenada.
  • Nível de validação por execução no playground. A tabela de figuras de mérito de execução única passa a incluir, por figura, uma etiqueta VALIDATED/MODELLED lida da mesma consulta fomTier() que o relatório descarregável usa (espelhando src/fom_label.rs, ele próprio derivado da matriz de verificação), pelo que o nível mostrado ao lado de um número em direto nunca pode divergir do registo.
  • lunar-attack-surface no menu do playground — todos os 50 tipos de cenário despacháveis estão agora a um clique de distância (eram 49/50).
  • Mais cinco cartões de capacidade executáveis (meteorologia espacial, avaliação de degradação por RF, resiliência, interoperabilidade CCSDS OEM, KIF), elevando os cartões executáveis de 11 para 16. Os cartões só de API e de biblioteca mantêm uma ligação honesta para a documentação em vez de um falso botão de execução.

Alterado#

  • A cobertura de documentação passa a ser controlada por catraca na CI. check-doc-coverage.sh compila a biblioteca com missing_docs, conta os avisos e só falha se a contagem subir acima de um teto fixado (986). Um #![warn(missing_docs)] rígido sob -D warnings teria transformado cerca de 1000 itens públicos atualmente sem documentação numa rutura de compilação da noite para o dia; assim, os novos itens públicos sem documentação fazem falhar a compilação enquanto o atraso existente é saldado deliberadamente.

Corrigido#

  • A linha da ferramenta MCP list_scenario_kinds anunciava "~17 tipos de cenário incorporados" enquanto api::list_scenario_kinds() expunha 50 havia algum tempo — uma documentação dirigida a agentes que subestimava a capacidade real em três vezes. Fixada à contagem verdadeira.
  • Regenerada a referência independente de aderência à norma do SBOM CycloneDX para o grafo de dependências atualizado (60 componentes). O veredicto de aderência à norma mantém-se: zero erros de esquema normalizados e todos os identificadores atómicos de licença continuam na enumeração oficial SPDX.

0.25.0 - 2026-07-15#

Adicionado#

  • Cinco capacidades promovidas a externamente VALIDATED, cada uma agora verificada de forma cruzada com uma implementação independente de terceiros da mesma grandeza definida de forma única (não circular, com ficheiros de teste regeneráveis offline):
    • Conversão de lei de potência IEEE-1139 → desvio de Allan face às formas fechadas de allantools para os cinco tipos de ruído (tests/powerlaw_oadev_reference.rs);
    • Pesos do formador de feixe CRPA MVDR / de anulação de norma mínima face ao LAPACK de numpy/scipy (tests/crpa_reference.rs);
    • Determinação de atitude de Wahba / TRIAD / QUEST face ao Rotation.align_vectors por SVD do SciPy em observações sem ruído (tests/wahba_reference.rs);
    • Intercâmbio de blocos de covariância CCSDS 502,0 OEM com ida e volta através do analisador da biblioteca independente oem (tests/ccsds_oem_covariance_reference.rs);
    • o núcleo de estatísticas de deteção de aquisição de lei quadrática (Marcum-Q generalizado / P_d / P_fa / limiar) face ao SciPy ncx2/chi2 (tests/acquisition_reference.rs). A matriz de validação verificada por máquina passa para 56 VALIDATED · 42 MODELLED · 4 PARTNER em 102 linhas (eram 51 · 47 · 4). Mantêm-se as ressalvas honestas de âmbito — por exemplo, a promoção da aquisição abrange apenas o núcleo de estatísticas de deteção; CFAR/perda por desalinhamento continua MODELLED.
  • Figuras de mérito no domínio da posição (fom::positioning_performance): CEP, SEP e 2DRMS exatos a partir da covariância de posição ENU 3-D de uma solução de navegação mais um nível de proteção horizontal. CEP/SEP são os erros radiais medianos exatos (não a regra linear 0.589·(σ₁+σ₂)), verificados de forma cruzada com quantis rayleigh/maxwell de scipy.stats e uma mediana Monte-Carlo independente em NumPy (tests/positioning_fom_reference.rs). Substitui o anterior esboço honesto de não implementado — a assinatura da função mudou de () a devolver um erro para (cov_enu, hpl_m) a devolver um PositioningFom.
  • Graus de liberdade equivalentes (EDF) do intervalo de confiança completados para todos os estimadores da família de Allan (assurance::uncertainty::edf): o EDF do Allan modificado, de Hadamard e da variância total usa agora o algoritmo de EDF combinado de Greenhall & Riley e a forma TOTVAR da Tabela 7 do NIST SP 1065 (anteriormente só estava implementado o EDF do Allan sobreposto; os outros reutilizavam-no em silêncio), verificado de forma cruzada com allantools edf_greenhall/edf_totdev (tests/uncertainty_edf_reference.rs).
  • Verificações cruzadas externas independentes para as capacidades de geometria, DOP, EOP, DRO e medição de distância por RF do PNT lunar (tests/validate_p*.rs, com ficheiros de teste e geradores de referência independente em tests/fixtures/{p1_footprint,lunar_service,eop_prediction,rf_ranging_precision,dro_family_jpl,p2_independent_dop}/). Cada verificação põe uma capacidade modelada já distribuída contra uma referência independente produzida por uma implementação diferente, pelo que a concordância é não circular: a pegada orbital de emissão/captura face a scipy.special.j1 (Cephes — um Bessel J1 genuinamente diferente); o DOP da geometria de balizas de superfície face a uma resolução independente (HᵀH)⁻¹ em NumPy; o crescimento do erro de previsão por persistência UT1/EOP face a uma nova análise separada em NumPy das mesmas linhas IERS finals2000A textuais; a família planar de órbitas retrógradas distantes face à Three-Body Periodic Orbit Database da NASA/JPL; e o orçamento de precisão de medição de distância por RF face a uma referência de primeiros princípios. Estas são evidências de regressão adicionais para módulos existentes; acrescentar estes testes de verificação cruzada não reclassifica por si só nenhuma capacidade (as cinco promoções acima são alterações de estado distintas, apoiadas em referência independente, em src/verification.rs).
  • Cenário lunar-attack-surface (src/attack_surface.rs, kind = "lunar-attack-surface"): uma execução composta de segurança de sinal lunar P1, alcançável por binário (CLI / Python / MCP / wasm através de run_toml), que reúne o défice de potência do balanço de ligação e a sua banda de sensibilidade de 12–18 dB, a potência de emissão de jamming/spoofing necessária em função da distância de afastamento, a pegada orbital de captura sob um diagrama de antena real, o resultado de aquisição por arrastamento na captura de spoofing do circuito de seguimento, o alcance do horizonte em corpo sem atmosfera e o orçamento de autenticação OSNMA/TESLA. Um corpo vazio reproduz a linha de base P1.
  • Banda de sensibilidade do défice de potência (linkbudget::deficit_sensitivity_band, deficit_power_factor): uma varredura genuína de vários eixos (referência × EIRP × distância oblíqua) construída sobre sweep::SweepAxis e avaliada através de received_signal_power_dbw, que reproduz a banda P1 de 12–18 dB e reconcilia as figuras de fator linear de 32× (arredondada) / 36× (não arredondada).
  • Cubo tridimensional de captura de spoofing (spoof_capture::capture_cube): acrescenta ao mapa de captura o eixo de desvio de portadora/Doppler (J/S × desvio de código × desvio de portadora, tempo de bloqueio por célula); a fatia de portadora zero reduz-se exatamente ao capture_map 2-D.

Alterado#

  • A deteção por rede dispersa de monitores (monitor_network) passa a compor a estatística física de AGC de spoof_monitors e a grelha de visibilidade selenográfica de lunar_service para derivar a estatística de deteção e a geometria de cada estação, em vez de parâmetros livres e de uma sobreposição de círculo máximo ad hoc; as probabilidades de deteção por monitor e da rede continuam a ser as formas fechadas de qui-quadrado/Marcum-Q de detection. Os campos de SurfaceMonitor / SpoofEvent mudaram para grandezas físicas (lat/lon/alt/potência).

Corrigido#

  • Dimensionamento da sobrecarga de autenticação OSNMA/TESLA (nma_budget): as porções de campo OSNMA por página (HKROOT de 8 bits + MACK de 32 bits por página de 2 s) estavam mal etiquetadas como totais por subtrama, subestimando a sobrecarga em 15× (1,33 bit/s). Corrigido para os totais publicados do SIS-ICD por subtrama de 30 s (HKROOT 120 + MACK 480 bits ⇒ 20 bit/s). A consequência é agora declarada com honestidade: a uma taxa de mensagem de navegação AFS de 50 bit/s, a sobrecarga de autenticação é um custo de primeira ordem de ≈40 %, e não uns poucos por cento desprezáveis; o campo auth_latency é documentado como o atraso de divulgação da chave (um limite inferior do tempo até à primeira posição autenticada de ponta a ponta).

0.24.0 - 2026-07-09#

Uma versão de capacidades alargada. Traz duas suites de análise totalmente validadas externamente — uma família completa de análise de decisão multicritério (MCDA) e os estimadores de deriva de Allan / estabilidade de relógio em τ longo — e abre uma nova camada de cenários executáveis de orçamento de tempo lunar, referencial/EOP em tempo real, híbrido ótico/RF, observabilidade cislunar e resiliência a conflitos de PNT em camadas sobre o substrato, além de um substrato de capacidades de baliza de superfície lunar e de segurança de sinal. A matriz de validação verificada por máquina cresce para 51 VALIDATED · 47 MODELLED · 4 PARTNER em 102 linhas (eram 40 · 47 · 4 em 91): todas as onze novas linhas são validações com referência independente externa dos estimadores de análise de decisão e de temporização, verificadas face a bibliotecas independentes (SciPy, pymcdm, pyDecision, allantools) com tolerância apertada, enquanto a nova superfície de capacidades de PNT é apresentada com honestidade como MODELLED. Como sempre, nenhuma afirmação de modelo numérico é promovida sem um conjunto de dados externo por trás.

Adicionado#

Cenários executáveis — cada um um kind de cenário registado, despachado através do motor e comprovado de ponta a ponta na CI por tests/determinism.rs (que executa todos os scenarios/*.toml incluídos e falha de forma estrita perante qualquer ficheiro de teste não executável):

  • Resiliência a conflitos de PNT em camadas (conflict-resilience, src/conflict_resilience.rs) — um motor de resiliência Monte-Carlo com semente para uma arquitetura PNT de várias camadas, com um modelo de sobrevivência de degradação gradual por vetor do §4,2 (quatro vetores de ameaça nomeados, a forma fechada de sobrevivência de PNT utilizável para a qual converge o Monte-Carlo de cada camada, emitida no JSON de resultados) e uma proveniência documentada, protegida contra deriva, dos parâmetros de ameaça (src/conflict_threat_params.rs). Arquiteturas MODELLED; a convergência do Monte-Carlo de sobrevivência → forma fechada é o núcleo validado.
  • Observabilidade cislunar (cislunar-observability, src/cislunar_observability.rs) — um espetro de valores próprios da gramiana de observabilidade ao longo de um arco, um gerador de sementes de órbita retrógrada distante (DRO) corrigido diferencialmente e uma verificação cruzada independente por filtro de informação de raiz quadrada cuja covariância a posteriori se torna finita exatamente com a característica observável completa. Constelação MODELLED; os invariantes de característica/gramiana/STM/SRIF são o núcleo validado.
  • Continuidade e integridade híbridas heterogéneas ótico/RF (hybrid-optical-rf, src/hybrid_integrity.rs, src/optical_availability.rs, src/optical_linkbudget.rs, src/cross_raim.rs) — disponibilidade e integridade entre domínios quando o PNT ótico e o de RF são combinados. MODELLED.
  • Orçamento de tempo lunar endógeno (lunar-time-budget, src/lunar_time_budget.rs) e orçamento de referencial / EOP em tempo real (realtime-frame-eop, src/realtime_frame_eop.rs, src/frame_eop.rs) — os orçamentos de tempo lunar e de orientação da Terra P3/P4 derivados endogenamente da cadeia de temporização em vez de afirmados. MODELLED.

Suites de análise validadas externamente — capacidades de biblioteca, cada uma a entrar na matriz como novas linhas VALIDATED (verificadas face a uma referência independente externa, não a uma autoverificação):

  • Suite completa de análise de decisão multicritério (MCDA) (src/mcda/) — as quatro famílias de métodos: agregação de valor (WSM, WPM, WASPAS), sistema de razões (MOORA) e proporcional (COPRAS), distância ao ideal (TOPSIS), programação de compromisso (VIKOR) e sobreclassificação (PROMETHEE II com seis formas de critério generalizado, ELECTRE I concordância/discordância) — mais pesos de prioridade por vetor próprio de Perron do AHP com a barreira da Razão de Consistência de Saaty (CR < 0,10), utilidade MAUT, extração da frente de Pareto e análise de sensibilidade dos pesos. Os nove agregadores reproduzem o pymcdm / pyDecision e o vetor próprio do AHP coincide com o SciPy/LAPACK, tudo com < 1e-9 (tests/mcda_*_reference.rs). O tornado de sensibilidade é também apresentado dentro do cenário de resiliência a conflitos.
  • Estimadores de deriva de Allan e de estabilidade de relógio em τ longo (src/allan.rs) — MTIE (a estatística de deriva de erro de tempo pico a pico ITU-T G.810/G.823/G.8261 em que se baseiam as máscaras de sincronização), deriva no domínio do tempo MDEV e TDEV, e estimadores de alcance alargado Theo1 / TOTVAR. VALIDATED face ao allantools na série NIST SP 1065; o ThéoH híbrido sem enviesamento construído sobre o TOTVAR continua, com honestidade, MODELLED.
  • Estrutura de garantia / referência independente externa (src/assurance/) — uma estrutura de referência independente ligada diretamente à barreira de honestidade da CI, um registo de proveniência W3C-PROV com uma raiz de Merkle determinística, e graus de liberdade equivalentes de Greenhall + intervalos de confiança de qui-quadrado nas estimativas de estabilidade.
  • Ponto de extensão PackRegistry / ExternalPack (src/registry.rs, src/api.rs) — um ponto de despacho para que os pacotes de capacidades passem por um único registo (o despacho incorporado está no caminho crítico da CLI; os pacotes externos à árvore ligam-se por trás de um ExternalPack::register_into com predefinição), protegido por uma suite de aderência à norma de identidade byte a byte de referência e por barreiras de CI autónoma / wasm32.

Substrato de capacidades modeladas — novos módulos de biblioteca que alimentam os cenários acima e futuros (ainda não são um kind de cenário autónomo):

  • DOP de balizas de superfície lunar (src/lunar_beacon.rs) com orçamento de exatidão realizada, varredura de N satélites e mapa de GDOP, mais uma efemérides lunar perturbada (src/lunar_perturbed.rs) e geometria de horizonte sem atmosfera / inversa da potência de spoofing / banda de défice AFS (src/jamming.rs, src/linkbudget.rs). Reutiliza o núcleo de DOP validado pelo gnss_lib_py.
  • Ingestão de DEM em formato LOLA + linha de vista sobre o terreno (src/realdata/lola_dem.rs).
  • Defesa de segurança de sinal em três camadas — captura de spoofing, integridade entre sensores e dimensionamento da rede de monitores (src/spoof_capture.rs, src/cross_sensor_integrity.rs, src/monitor_network.rs) com uma pegada de feixe de antena orbital e um orçamento de autenticação OSNMA (src/antenna.rs, src/nma_budget.rs). MODELLED.

Alterado#

  • A matriz de validação e todos os artefactos derivados foram regenerados a partir da única fonte de verdade (src/verification.rs): o registo no sítio, os diagramas do mapa de módulos e da proveniência da validação, e as cadeias de contagem do README / por superfície indicam agora 51 / 47 / 4 de 102 (eram 40 / 47 / 4 de 91); a proteção de honestidade das contagens passa a analisar todo o histórico git, e as figuras do README estão unificadas na paleta escura da marca.
  • Um único controlador de integração adaptativa partilhado suporta agora integrate e integrate_dopri (src/integrator.rs), removendo o integrador de passos duplicado.
  • Análise estática do SonarQube Cloud acrescentada à CI (Rust + cobertura importada), com selos de classificação de segurança / manutenibilidade / fiabilidade no README.
  • Uma passagem que nomeia clientes de IA de terceiros é omitida aqui; consta de CHANGELOG.md no GitHub.

  • Disciplina de versão / empacotamento: a CI regista um ambiente de implantação por cada publicação de pacote/registo, e a tarefa pública autónoma focada deixou de abranger os binários de validação lentos.
  • A proteção de higiene de não atribuição limita-se a marcadores de autoria, pelo que nomear um anfitrião de integração ou um produto deixa de fazer falhar a compilação.
  • Documentação: a secção Citing do README lista agora os quatro preprints arXiv publicados, e a capacidade de DOP de balizas de superfície está documentada na linha lunar.

Corrigido#

  • Contadores de ciclo inteiros para ciclos conduzidos por vírgula flutuante (Sonar S2193).
  • Inversa do qui-quadrado exata com poucos graus de liberdade, por refinamento de Newton, no caminho do intervalo de confiança de garantia.
  • kshana.dev: a secção de normas passa a abrir por predefinição e a contagem de recurso do registo foi corrigida; cadeias desatualizadas do README / do sítio em torno da camada de observabilidade foram sincronizadas.

0.23.0 - 2026-06-29#

Uma versão de capacidades que acrescenta uma camada geral de informação de Fisher / observabilidade de Cramér–Rao e conceção ótima de experiências, e a versão em que assenta o artigo de observabilidade do PNT lunar. A matriz de validação verificada por máquina cresce para 40 VALIDATED · 47 MODELLED · 4 PARTNER em 91 linhas (eram 39 · 46 · 4 em 89): o novo motor de estimação é verificado face a uma referência independente externa e é VALIDATED; a sua aplicação lunar é, com honestidade, MODELLED. Como sempre, nenhuma afirmação de modelo numérico é promovida sem um conjunto de dados externo por trás.

Adicionado#

  • src/fim.rs — informação de Fisher, limites de Cramér–Rao e conceção ótima de experiências. Um motor geral e reutilizável de teoria da estimação: a matriz de informação de Fisher M = HᵀWH a partir de um jacobiano de medição e de pesos; um resolvedor de valores próprios simétrico (Jacobi cíclico); o limite inferior de Cramér–Rao através da inversa, ou da pseudoinversa de Moore–Penrose mais uma base do espaço nulo quando a informação tem défice de característica (o caso de rede livre / defeito de datum); e métricas de conceção de experiências ótimas D, A, E e T com um seletor best_design sobre geometrias candidatas. VALIDATED face ao NumPy (eigh/inv) e aos limites de forma fechada publicados de Kay (1993) até 1e-9 (tests/fim_observability_reference.rs), pelo que entra na matriz como uma linha com referência independente externa e não como uma autoverificação.
  • Observabilidade de OD conjunta lunar (lunar_observability em src/lunar_combination.rs, apresentada no relatório de combinação lunar): aplica o motor FIM/CRLB à resolução conjunta de órbita e relógio para expor o defeito de datum absoluto das estações, a sua restauração de característica à medida que se acrescentam estações com linha de base na Terra, o CRLB atingido da posição das estações e o condicionamento ótimo E. Com honestidade MODELLED — o motor de estimação é validado externamente, mas a rede lunar a que é aplicado é uma simulação representativa, e nenhum conjunto de dados atual pode transformar essa geometria numa medição.
  • Geometria representativa de órbita lunar elíptica congelada (ELFO) para o cenário de combinação lunar (orbit_ecc, orbit_inc_deg, orbit_argp_deg, orbit_planes; a colocação circular continua a ser a predefinição) e um campo de observabilidade sem VLBI no relatório, para que se possa mostrar que o resultado do defeito de datum é geral quanto à geometria. A mesma escada 3→1→0 e o mesmo limiar de três estações valem numa ELFO da família Moonlight/LCNS, e com três linhas de base VLBI com a Terra a posição absoluta da estação é observável com um limite submétrico — fixado por elfo_geometry_confirms_the_observability_structure. Continua MODELLED.

Alterado#

  • A matriz de validação e todos os artefactos de evidência gerados foram regenerados a partir da única fonte de verdade (src/verification.rs): o registo (web/data/verification-matrix.json), docs/VERIFICATION-MATRIX.md, docs/MODELLED-RATIONALE.md, as figuras de repartição da validação e do tipo de referência independente, e as cadeias de contagem do README em todas as superfícies de distribuição indicam agora 40 / 47 / 4 de 91.

0.22.1 - 2026-06-29#

Uma versão de correção apenas de empacotamento. Sem alterações ao motor, aos cenários ou aos resultados; a matriz de validação mantém-se em 39 VALIDATED · 46 MODELLED · 4 PARTNER em 89 linhas.

Corrigido#

  • Publicação no npm: o pacote repository.url derivado do manifesto do crate usava o proprietário do GitHub com maiúsculas erradas (AshfordeOU), o que falhou a verificação de proveniência sigstore do npm (que compara o proprietário distinguindo maiúsculas de minúsculas). O repository do manifesto é agora o ashfordeOU canónico em minúsculas, pelo que o package.json gerado coincide com o sujeito da proveniência e a versão npm é publicada.

Alterado#

  • A compilação das wheels fixa codegen-units = 1 para que a wheel manylinux seja reproduzível ao byte entre recompilações (a verificação de reprodutibilidade por recompilação e diferença).

0.22.0 - 2026-06-29#

Uma versão de consolidação centrada na disciplina de evidências, proveniência e distribuição. A matriz de validação verificada por máquina cresce para 39 VALIDATED · 46 MODELLED · 4 PARTNER nas suas 89 linhas (eram 15 · 42 · 4 em 61), impulsionada pela verificação cruzada de capacidades modeladas face a referências independentes externas. Todos os artefactos distribuídos passam a incluir uma atestação criptográfica de proveniência de compilação SLSA, distribuem um SBOM CycloneDX e são publicados em simultâneo em todas as superfícies. Nenhuma afirmação de modelo numérico é promovida sem um conjunto de dados externo por trás; a nova capacidade continua, com honestidade, MODELLED.

Adicionado#

  • Dinâmica de atitude (src/attitude_dynamics.rs, MODELLED) — equações de Euler de corpo rígido sem binário + cinemática de quaterniões (RK4), com autotestes de leis de conservação (norma do quaternião, energia cinética, |Iω|, precessão de pião simétrico).
  • Verificação cruzada de capacidades modeladas face a referências independentes externas, levando a matriz de validação a 39 linhas VALIDATED, cada uma apoiada num conjunto de dados externo (a barreira de honestidade da CI proíbe um estado VALIDATED sem um). As validações com referência independente externa mais recentes: a curva de estabilidade medida de relógio ótico (o ajuste da curva de ADEV de quantum_trade reproduz a σ_y(τ) publicada do relógio de rede ótica de ⁸⁸Sr de Norcia et al., Science 366:93 (2019), Zenodo 10.5281/zenodo.3382347, CC-BY-4.0, incorporada em tests/fixtures/optical_clock_adev/); a geração do código de espalhamento GPS L1 C/A (o LFSR G1/G2 de src/sdr.rs reproduz os octais de fase de código da Tabela 3-Ia do IS-GPS-200 para os PRN 1–9); e o leitor de elevação digital SRTM em terreno real (src/altpnt/terrain.rs lê um mosaico SRTM v3 da NASA/USGS de domínio público incorporado, N36W117 / Vale da Morte, colocando Badwater Basin dentro da sua banda de levantamento documentada).
  • Novas capacidades MODELLED, cada uma verificada internamente de forma cruzada com uma forma fechada ou um caminho de código irmão: dinâmica de movimento relativo de Clohessy–Wiltshire / Hill, geolocalização passiva de emissores por TDOA/FDOA, determinação de atitude de Wahba/TRIAD/QUEST, resolução de ambiguidade inteira da fase da portadora GNSS (LAMBDA), apontamento no plano B e assistência gravitacional por cónicas ajustadas, formação de feixe de agrupamento antijamming CRPA, estatísticas de aquisição GNSS de lei quadrática, ambiguidade de franjas / gama dinâmica de sensores inerciais quânticos, ruído de relógio de lei de potência IEEE-1139 + patamar de flicker-FM, e intercâmbio de blocos de covariância CCSDS-OEM.
  • Registo de evidências de fonte única com documentos de verificação gerados e uma proteção contra deriva; um registo de validação navegável em kshana.dev com ligações diretas para as evidências de cada cartão.
  • Metadados de citação legíveis por máquina — codemeta.json (CodeMeta 2,0) e .zenodo.json, fixados ao manifesto do Cargo por tests/citation_metadata_doc_sync.rs.
  • Proveniência da cadeia de fornecimento — atestação de proveniência de compilação SLSA para o tarball do crate, as wheels, o sdist e o tarball do npm; Trusted Publishing OIDC do PyPI; SBOM CycloneDX distribuído dentro da wheel e do pacote npm; diferença de compilação reproduzível e verificação pós-versão.
  • Descobribilidade — robots.txt, sitemap.xml e metadados Open Graph / JSON-LD em kshana.dev; uma figura validation-breakdown gerada, derivada da matriz.
  • READMEs por superfície para crates.io / PyPI / npm com uma proteção de honestidade das contagens.

Alterado#

  • A referência independente de transferência de tempo de Sagnac foi promovida a ExternalDataset — a correção de Sagnac para a circum-navegação equatorial é agora verificada face aos 207,4 ns publicados por Ashby (Living Reviews in Relativity 6:1, 2003, Eq. 1,29; reproduzida com < 0,05 ns). A capacidade composta de transferência de tempo continua, com honestidade, MODELLED.
  • Documentação, diagramas e figuras atualizados para a matriz em vigor (39/46/4/89): o diagrama de proveniência da validação, a figura oracle-kind-stacked (agora gerada a partir da matriz com uma proteção de deriva na CI), VALIDATION/PROVENANCE/CAPABILITY/QUANTUM-MODELS/WHEEL_TAGS, os documentos de arquitetura e de tutorial, e o total do registo em kshana.dev.
  • A árvore de código-fonte foi reformatada com o rustfmt fixado (cadeia de ferramentas 1.93.0) — puro estilo, sem alteração de comportamento.
  • Versionamento em sincronia. Todas as superfícies de distribuição (crate, PyPI, npm, crate MCP + imagem OCI, plugin JetBrains) passam a ter versões em sincronia com o motor, imposto por scripts/check-version-sync.sh na CI.
  • O plugin JetBrains foi relicenciado para AGPL-3.0-only (a 0.1.1 publicada ainda anunciava Apache-2.0) e passa a derivar a sua versão do Marketplace da etiqueta da versão.
  • Reforço de robustez — os unwrap fora dos testes foram removidos ou justificados; clippy::unwrap_used aplicado como barreira ao código fora dos testes.
  • Remodelação de kshana.dev com a prova em primeiro lugar: destaque dominante, diagramas de arquitetura e figuras de resultados, i18n, secções de registo e de Normas recolhíveis e adaptáveis.

Corrigido#

  • Efemérides precisas SP3 — aplicar a correção do nó de rotação da Terra do IGS durante a interpolação.
  • Imagens nos registos — os READMEs do PyPI/crates.io/npm usam URLs de imagem absolutos; os caminhos de imagem relativos do README principal eram apresentados como imagens quebradas na página da 0.21.0 no PyPI. Uma proteção na CI (tests/surface_readme_image_urls_doc_sync.rs) impede a regressão.
  • CI — fmt + clippy verdes; deixar de compilar contra dados reais ignorados pelo git.

Testes#

  • A covariância do relógio de Kalman mantém-se semidefinida positiva e simétrica (teste de propriedade, tests/property.rs).
  • Proteções de sincronização de documentação: todas as cadeias públicas de contagem de validação, os metadados de citação, a figura gerada e os URLs de imagem dos READMEs por superfície estão fixados à respetiva fonte de verdade.

0.21.0 - 2026-06-26#

Esta versão acrescenta dois conjuntos de aplicações MODELLED ao motor aberto — um demonstrador de PNT com Tecnologia Quântica (transferência de tempo quântica fiável, navegação quântica sem GNSS, deteção quântica de falhas/anomalias) e um conjunto de PNT lunar / cislunar (tempo coordenado lunar, VLBI lunar, OD+relógio conjunto, realização de referencial, volume de serviço, PNT diferencial, exportação de interoperabilidade) — cada um executável a partir de um único kind, cada um a emitir um registo TradeEvidence honesto mais um registo de representatividade / lacunas até ao voo. Traz também seis novas validações com referência independente externa, levando a matriz de validação verificada por máquina a 15 VALIDATED · 42 MODELLED · 4 PARTNER nas suas 61 linhas. Os novos números de aplicação são MODELLED a partir de parâmetros ilustrativos de fonte pública — sem TRL, herança de voo, certificação ou aval de agências — e os núcleos validados que reutilizam são etiquetados como tal.

Adicionado#

  • Conjunto de demonstradores de PNT com Tecnologia Quântica (quantum-time-transfer, quantum-gnss-free-nav, quantum-anomaly-detect). Três áreas de aplicação MODELLED executáveis por trás do motor, cada uma a emitir TradeEvidence mais um registo de representatividade / lacunas até ao voo:
    • Transferência de tempo quântica fiável (src/timetransfer_chain.rs) — um orçamento bidirecional de relógio de rede ótica + ligação fotónica face a CSAC + RF, reutilizando o nível de proteção de temporização, com uma figura de mérito de segurança contra ataques de atraso/repetição (1 − P_md) e deteção de anomalias do relógio + latência CUSUM.
    • Navegação quântica sem GNSS (src/quantum_nav_od.rs) — uma deriva inercial com interferómetro de átomos frios face a um INS de qualidade de navegação durante uma falha de GNSS, com a ressalva honesta de que, sem posição externa, o enviesamento do acelerómetro continua inobservável e o erro continua, por isso, a crescer.
    • Deteção quântica de falhas / anomalias (src/quantum_faults.rs) — um catálogo de falhas etiquetadas com uma AUC da ROC com IC por bootstrap e uma falha mínima detetável a uma taxa fixa de falsos alarmes.
    • Uma biblioteca partilhada de modelos de erro de dispositivos quânticos (src/quantum_devices.rs) e uma estrutura unificada de comparação quântico-versus-clássico (src/qtrade.rs) sustentam os três.
  • Conjunto de PNT lunar / cislunar. Sete kinds de cenário MODELLED executáveis em camadas sobre o núcleo CR3BP: Tempo Coordenado Lunar (taxa secular LTC/TCL − TT, src/lunar_time.rs), observável de atraso geodésico de VLBI lunar (src/lunar_vlbi.rs), estimador em lote de OD + relógio conjuntos multitécnica (src/lunar_combination.rs), realização de referencial (Helmert de 7 parâmetros + ligação WGCCRE IAU 2015, src/lunar_frame_realise.rs), análise de volume de serviço de classe Moonlight / LCNS (src/lunar_service.rs), PNT diferencial lunar (src/lunar_dpnt.rs) e uma exportação de interoperabilidade alinhada com LunaNet / IOAG (CCSDS-OEM + escala de tempo lunar no envelope KIF, src/lunar_interop.rs). Tudo MODELLED a partir de parâmetros ilustrativos de fonte pública; não validado face a seguimento real de VLBI / Gateway; sem afiliação nem aval de qualquer agência.
  • Seis novas validações com referência independente externa (a matriz de validação está agora em 15 validadas):
    • ADEV / HDEV num relógio de césio 5071A real — validado face a referências de ponto de década do Stable32 (tests/cs5071a_reference.rs).
    • OADEV / MDEV / TDEV na referência PHASE.DAT do Stable32 — validado face às tabelas publicadas do Stable32 (tests/phasedat_reference.rs).
    • AUC da ROC de deteção de anomalias em telemetria real do ESA OPS-SAT — validada face ao scikit-learn (tests/opssat_ad_reference.rs).
    • Síntese de funcionais gravíticos ICGEM — validada face à norma de gravidade normal GRS80 (γ de Somigliana até 3.5e-12; mapa de perturbação EGM2008, tests/icgem_gravity_reference.rs).
    • Modelo de ionosfera difundido Klobuchar — validado face ao RTKLIB (tests/klobuchar_reference.rs).
    • Núcleo de deteção RAIM (171 casos, tests/raim_reference.rs) e o nível de proteção SBAS DO-229E em dados reais do EGNOS (bifurcação SBAS-PL do RTKLIB, tests/sbas_reference.rs) — ambos validados face às suas referências independentes externas.
  • Registo de representatividade e lacunas até ao voo (src/representativeness.rs). Um registo estruturado que todos os demonstradores emitem — o que é representativo, o que é simplificado e o que separa o modelo do voo — o complemento honesto de cada comparação MODELLED.
  • Agregação de estudos e ergonomia da CLI. Um manifesto de conjunto de cenários com agregação de estudos num só comando, metadados de estudo estáveis por hash + --study-name, verificação de formato de cenários com --validate e apresentação do nível de validação por figura de mérito nos relatórios de estudo.

Alterado#

  • kshana.dev redesenhado em torno de uma espinha de domínio partilhada — capacidades e validação reunidas num único explorador de domínios com um vocabulário comum, as novas ilhas validadas em destaque, um instrumento animado da Terra com contornos de terra fiéis, um apelo à ação para pedir um estudo e a marca/ligações da Ashforde OÜ.
  • README + ARCHITECTURE auditados quanto à completude e à honestidade — contagens de validadas desatualizadas corrigidas (agora 15 referências independentes externas), diagramas alargados, e citados os preprints do Nível de Proteção de Temporização Condicional (arXiv:2606,24210) e da lacuna de otimismo por degradação de RF (arXiv:2606,22054).
  • As fontes de paper/ e o pipeline do rascunho para o JOSS são mantidos no repositório público.

0.20.0 - 2026-06-22#

Esta versão acrescenta quatro capacidades de estudo ao motor aberto — um Nível de Proteção de Temporização condicional, uma pontuação de resiliência de PNT alinhada com um referencial normativo, uma avaliação da lacuna de otimismo por degradação de RF e um front end de recetor definido por software / dados reais — cada uma reproduzível a partir de um só comando e a escrever um artefacto determinístico ao byte. Todos os estudos são MODELLED (calibração sintética ou com conjuntos de dados públicos), apresentam a sua proveniência honesta (versão do motor, sementes, hash da configuração) e etiquetas de validação, e não são certificações.

Adicionado#

  • Nível de Proteção de Temporização condicional (tpl). Um limite, limitado pelo holdover, do erro de tempo não detetado sob spoofing de GNSS, com um piso de monitor de k sigma, uma variância de deriva de van Loan sobre a latência de deteção e um tempo até ao alarme CUSUM. Calibrado num ataque real registado (JammerTest 2024, cenário 2.1.1) através de cargo run --release --example tpl_jammertest, que reproduz a sua tabela de referência a partir de escalares recuperados da gravação pública (o conjunto de dados bruto não é redistribuído).
  • Pontuação de resiliência de PNT alinhada com um referencial normativo + estudo de instabilidade de decisão (resilience). Modelo de arquitetura, pontuação alinhada com o RPCF, simplex de ponderação de Dirichlet, instabilidade por Kendall-tau e taxa de inversão top-1, e colapso da diversidade de modo comum (Hill-N2), com cargo run --release --example resilience_report -- paper-artifacts/resilience-study.json. Correspondência em docs/RESILIENCE-CROSSWALK.md.
  • Estudo da lacuna de otimismo por degradação de RF (impairment_study, impairment_ml, eval_stats). Um painel de 13 detetores sobre um corpus sintético com parâmetros fundamentados, uma lacuna de otimismo dentro versus fora da distribuição, tendências de leis de escala com uma hipótese nula por permutação e um previsor de degradação leave-one-out, através de cargo run --release --example optimism_study -- paper-artifacts/optimism-study.json.
  • Front end de recetor definido por software (sdr) e adaptadores de dados reais (realdata/). De IQ/IF em bruto até às derivações do correlador e SQM, mais adaptadores de ingestão (RINEX, u-blox UBX, GnssLogger, JammerTest, Yunnan, SatGrid) e exemplos de sondagem. Estes leem gravações que o utilizador fornece localmente; nenhuma gravação é submetida.
  • Artefactos de estudo submetidos. Os ficheiros optimism-study.json e resilience-study.json, determinísticos ao byte, passam a ser seguidos em paper-artifacts/, para que os números dos estudos possam ser verificados sem recompilar; continuam regeneráveis a partir dos geradores acima. Os conjuntos de dados brutos ficam fora do repositório (/realdata-cache/).

Alterado#

  • Versão incrementada para 0.20.0 em Cargo.toml, CITATION.cff e README; os artefactos do estudo de cruzamento são regenerados para que o seu carimbo coincida com a versão lançada.

0.19.0 - 2026-06-18#

Alterado#

  • Relicenciado de Apache-2.0 para a GNU AGPL-3.0-only, com uma licença comercial disponível junto da Ashforde OÜ (licenciamento duplo). O motor aberto continua totalmente aberto e publicamente verificável; o copyleft de rede da AGPL (§13) significa que um derivado fechado ou alojado tem de regressar ao código aberto — ou adquirir uma licença comercial. Isto defende o núcleo validado contra a bifurcação seguida de fecho, mantendo a credibilidade de um motor público, executável e auditável. Ver LICENSE (AGPL) e o novo LICENSING.md (o que cada licença abrange e quando se aplica).
    • LICENSE contém agora o texto da AGPL-3.0; os cabeçalhos SPDX em todas as fontes foram atualizados para AGPL-3.0-only; NOTICE, README, GOVERNANCE, GLOSSARY, o sítio web e os metadados de crate/pacote (Cargo.toml, pyproject.toml, CITATION.cff, o crate MCP + imagem) foram atualizados em consonância.
    • Os termos para contribuidores (CONTRIBUTING.md) passam a licenciar a contribuição recebida ao abrigo da AGPL e concedem à Ashforde OÜ o direito de incluir contribuições na edição com licença comercial, para que o licenciamento duplo continue a funcionar.
    • Política de dependências inalterada mas com nova justificação (deny.toml, GOVERNANCE): as dependências continuam permissivas (Apache/MIT/BSD/ISC). A AGPL só é permitida para o próprio crate do kshana — uma dependência com copyleft contaminaria a edição comercial e comprometeria o licenciamento duplo.
    • Nota para quem está a jusante: esta é uma relicenciação para copyleft. Os utilizadores que dependiam dos termos permissivos da Apache-2.0 podem continuar a usar a última versão Apache-2.0 (v0.18.0 e anteriores, tal como publicadas); de v0.19.0 em diante é AGPL-3.0 / comercial.

Segurança#

  • pyo3 atualizado de 0,24 → 0,29 para eliminar RUSTSEC-2026-0176 / RUSTSEC-2026-0177 (GHSA-36hh-v3qg-5jq4 / GHSA-chgr-c6px-7xpp) das análises externas de OSV/dependências. Ambos são avisos ao nível de função cujas funções afetadas (BoundList/TupleIterator::nth/nth_back, PyCFunction::new_closure) o Kshana nunca chama, e pyo3 é uma dependência opcional (da funcionalidade python) — pelo que a exposição real era nula —, mas a atualização mantém uma análise limpa para os auditores a jusante. Migrado src/python.rs para a API do pyo3 0,29 (tipo de retorno Bound para scenario_kinds; skip_from_py_object explícito na pyclass RunOutput). Todos os 11 testes das ligações Python passam contra a extensão recompilada.

0.18.0 - 2026-06-17#

Adicionado#

  • Onze novos tipos de cenário executáveis — demonstradores de dois concursos, uma ponte de interoperabilidade CCSDS e um conjunto de análise de missão / ambiente de primeira ordem (todos MODELLED, aditivos; os valores de referência de reprodutibilidade existentes mantêm-se inalterados). Cada um é despachável por CLI / Python / WASM / MCP, inclui um scenarios/<kind>.toml e traz uma etiqueta MODELLED explícita no seu JSON de resultados e no resumo de uma linha (um teste por tipo de cenário em tests/dominance_demonstrators.rs afirma que a etiqueta está presente e que a saída nunca contém a cadeia VALIDATED):

    • impairment-eval (src/impairment_eval.rs) — banco de ensaio de avaliação de deteção de degradação de RF por aprendizagem automática: um corpus sintético etiquetado + uma estrutura de ROC/AUC independente do detetor + um relatório de lacuna de otimismo dentro/fora da distribuição (apenas características operacionais — nunca dados de campo/IQ).
    • quantum-trade (src/quantum_trade.rs) — comparação PNT quântico-versus-clássico com ingestão de ADEV medido e um envelope de resiliência sem GNSS.
    • space-weather (src/space_weather.rs) — índices solares/geomagnéticos (tabela IAGA Kp↔ap, Ap diário, F10.7a centrado em 81 dias), temperatura exosférica de Jacchia-71 e um acoplamento de densidade termosférica conduzido pela atividade sobre uma atmosfera estática (NÃO um modelo de densidade absoluta NRLMSISE).
    • oem-interop (src/oem.rs) — ponte de importação + ida e volta de CCSDS 502,0 OEM para efemérides GMAT / Orekit / STK (o leitor parse_oem, inverso exato do escritor).
    • launch-window (src/launch.rs) — azimute de lançamento de dois corpos (sin Az = cos i/cos lat), Δv de mudança de plano, bónus de rotação do local e geometria de oportunidades diárias.
    • reentry (src/reentry.rs) — corredor de reentrada balística de Allen-Eggers: desaceleração máxima, velocidades de g máximo e de aquecimento máximo, altitude de g máximo.
    • eo-coverage (src/eo_payload.rs) — geometria de faixa / GSD / acesso / revisita de EO (triângulo espacial SMAD).
    • space-packet (src/space_packet.rs) — codificação/descodificação do cabeçalho primário do Space Packet CCSDS 133.0-B com ida e volta exata ao bit.
    • attitude-budget (src/attitude_budget.rs) — binário de gradiente gravítico de 3 graus de liberdade + orçamento RSS de erro de apontamento (orçamento escalar pré-hardware, não um ciclo de controlo).
    • passes (src/passes.rs) — previsão de passagens de nascer/pôr de estação terrestre (AOS/TCA/LOS, elevação máxima, acesso).
    • link-budget (src/linkbudget.rs) — equação de ligação unidirecional CCSDS-401 / DSN-810-005 (C/N₀ = EIRP − FSPL − L_other + G/T − k, FSPL / Eb·N₀ / margem / fecho).
  • Filtro de Kalman unscented (UKF) híbrido quântico + clássico fortemente acoplado de 17 estados — apresentado como cenário executável (MODELLED). Um novo tipo de cenário hybrid-ukf (src/fusion/hybrid_ukf.rs, scenarios/hybrid-ukf.toml) que transforma o filtro unscented GNSS/INS fortemente acoplado de 17 estados, antes só disponível por API (src/fusion/tightly_coupled17.rs), num cenário que as ligações CLI/Python/WASM/MCP podem despachar. O vetor de erro de 17 estados é composto pelos 15 estados de erro do INS (posição, velocidade, desalinhamento de atitude, enviesamento de acelerómetro + giroscópio) aumentados com a correção do enviesamento do acelerómetro derivada de CAI — o interferómetro de átomos frios (src/inertial/quantum_imu.rs) fixa o piso de passeio aleatório da velocidade q_va, pelo que a deriva de longo prazo em navegação inercial é a limitada pelo sensor quântico — e um relógio de 2 estados de fase + frequência cujo ruído de processo provém do motor de relógio por parâmetros q (clock_state::q_from_allan, que mapeia o perfil de desvio de Allan de um relógio para as PSD de q_wf/q_rw, escaladas para unidades de distância). A plataforma é auxiliada por GNSS durante uma fase inicial (o filtro aprende os enviesamentos, a velocidade e o relógio) e depois segue em deriva durante uma falha de GNSS apenas com a IMU CAI + relógio, pelo que a execução demonstra uma hibridização de IMU clássica a curto prazo + quântica a longo prazo. A figura de mérito é a autoconsistência do filtro: NEES agregado (Normalised Estimation Error Squared, sobre o subconjunto estimável de posição/velocidade/relógio) e NIS de brancura da inovação (Normalised Innovation Squared) sobre um conjunto Monte-Carlo, verificados face às suas bandas de χ² a 95 % (Bar-Shalom §5,4). O filtro ajustado fica dentro das bandas; um filtro deliberadamente mal ajustado (os parâmetros q_factor / r_factor) é assinalado — uma barreira objetivamente verificável e discriminante, não um carimbo automático. A verificação de NEES/brancura da inovação é a REFERÊNCIA INDEPENDENTE ESTATÍSTICA: uma afirmação de autoconsistência (a covariância comunicada pelo filtro corresponde honestamente à dispersão dos seus próprios erros sob o ruído modelado), NÃO uma garantia de exatidão no mundo real. Âmbito honesto: tudo é modelado / simulação — as entradas de CAI e de relógio são valores delimitados e representativos da literatura, não hardware medido; o hardware CAI e a sua pessoa-chave continuam a pertencer ao parceiro; nada aqui implica TRL > 3, herança de voo ou validação externa (o JSON de resultados e o resumo de uma linha trazem estas etiquetas de forma explícita). A trajetória única, de velocidade constante e nivelada, deixa os estados de atitude e de enviesamento da IMU apenas fracamente observáveis, pelo que o NEES é avaliado sobre os 8 estados estimáveis; uma trajetória com manobras para observabilidade total dos 17 estados está no roteiro. Acrescenta também a instrumentação de consistência Ukf::update_stats (devolve o NIS por atualização) e TightlyCoupled17::{update_gnss_nis, nees, nees_subset}. Todos os cenários existentes não são afetados (aditivo; valores de referência de reprodutibilidade inalterados).

  • Navegação sequencial (recursiva) referenciada ao terreno — SITAN como filtro em execução. Um novo tipo de cenário terrain-slam (src/altpnt/sequential.rs, scenarios/terrain-slam.toml) que executa o modelo de medição altímetro-versus-DEM já existente época a época através do motor SIR de particle_filter, em vez da pesquisa em lote do grosseiro ao fino que terrain-nav usa para recuperar um único desvio constante do INS. Em cada ponto de passagem, a nuvem é propagada pelo incremento comunicado pelo INS (ele próprio corrompido pelo crescimento da deriva por passo), repesada pela correspondência de terreno e reamostrada em caso de degenerescência — pelo que uma deriva do INS variável no tempo é seguida ao longo do trajeto, o que um ajuste de desvio constante estruturalmente não consegue. No DEM sintético, a estimativa recursiva mantém-se limitada e reconverge (final ≈ 70 m) enquanto a solução inercial sem auxílio diverge sem limite até ≈ 5 km; o erro por época acompanha a singularidade do terreno (segue em deriva sobre o INS enviesado em selas planas e volta a fixar-se sobre relevo distintivo), e o monitor do tamanho efetivo da amostra confirma uma nuvem saudável. Âmbito honesto: o mapa é conhecido e fixo — localização recursiva face a um DEM armazenado (a metade de localização do SLAM de terreno), não estimação conjunta do mapa; não circular por construção (a rampa de deriva injetada é a verdade independente). Todos os cenários existentes não são afetados (aditivo; valores de referência de reprodutibilidade inalterados).

  • Espinha de resiliência sem GNSS + fatias de demonstrador FutureNAV (src/holdover.rs, e fundamentos de envelope de resiliência em src/impairment_eval.rs, src/quantum_trade.rs, src/navsignal.rs, src/inertial/quantum_imu.rs, com fatias de verificação FutureNAV em src/verification.rs). Compõe os blocos de construção de PNT alternativo — holdover de relógio, seguimento de sinal, deriva inercial, terreno — numa única narrativa de resiliência a falhas de GNSS. MODELLED; aditivo.

  • Kshana Interchange Format (KIF) — um envelope de artefactos versionado e autodescritivo (src/interchange.rs). Um invólucro etiquetado por esquema em torno dos resultados de cenários, para que um artefacto armazenado leve consigo o seu tipo de cenário, a versão do esquema e as etiquetas MODELLED/VALIDATED, e os envelopes mais antigos continuem legíveis com compatibilidade futura. Aditivo; o JSON de resultados existente não muda.

  • Modulação / seguimento de sinais de navegação + corretor diferencial de halo/NRHO em CR3BP (src/navsignal.rs, src/cr3bp.rs). Um modelo de primeira ordem de modulação e seguimento de sinais de navegação, e um corretor diferencial de três corpos restrito circular para órbitas de halo / de halo quase retilíneas, apresentados no eixo de capacidade de espaço profundo já existente. MODELLED.

  • Modo de avaliação de mudança de distribuição + parâmetro de escala de severidade do corpus para impairment-eval (src/impairment_eval.rs). Acrescenta uma divisão explícita dentro/fora da distribuição e uma escala de severidade do corpus ajustável à estrutura de lacuna de otimismo ROC/AUC (apenas características operacionais — nunca dados de campo/IQ).

  • ROI de custo por cobertura + mapeamento do impacto na integridade das deteções falhadas (src/frugal.rs, src/integrity_impact.rs). Uma perspetiva de ROI de engenharia frugal (custo por unidade de cobertura) e um mapeamento da taxa de deteções falhadas para o impacto na integridade. MODELLED; aditivo.

  • Folha de parâmetros citada do modelo de erro do interferómetro de átomos frios (CAI) (src/inertial/quantum_imu.rs). Uma folha de parâmetros delimitados, com referências bibliográficas, para o modelo inercial CAI — as entradas são citadas, não hardware medido (sem alegação de TRL / voo); alimenta o piso de passeio aleatório da velocidade de hybrid-ukf.

  • Governação do projeto. GOVERNANCE.md a documentar o modelo de decisão e a fronteira aberto/fechado; a linha de comunidade/governação do mapa de capacidades passa de none → partial para o refletir.

Corrigido#

  • Nível de proteção de integridade ARAIM — enviesamento nominal (b_nom) e σ_URA agora aplicados. O nível de proteção MHSS subtrai agora a projeção unilateral do enviesamento nominal b_k = Σ_i |s_i|·b_nom por modo de falha, e usa o sigma de integridade σ_URA (distinto do sigma de exatidão σ_URE) transportado na Integrity Support Message. Isto torna o nível de proteção mais conservador e correto segundo as normas e, por isso, altera os valores de PL comunicados pelos cenários de integridade existentes. O ISM/cenário ganha os campos #[serde(default)] sigma_ura_m / b_nom_m, pelo que as entradas que os deixam por definir mantêm o comportamento anterior. Ver docs/ARAIM_REFERENCE.md para a fórmula b_k restaurada e a nota de implementação honesta.

  • Consistência χ² do monitor de spoofing. parity_raim_test passa a usar o caminho partilhado de χ² inverso de raim::chi2_quantile, removendo uma segunda implementação divergente de χ², de modo que o RAIM e o monitor de spoofing por paridade concordem nos seus limiares.

  • gravity-map-nav ligado ao despachante da CLI. Anteriormente, o cenário só era alcançável através da API; passa agora a ser despachado como kind= tal como todos os outros cenários.

  • Exatidão da documentação/contagens. As contagens de tipos de cenário no README passam a estar fixadas a api::list_scenario_kinds().len() por um teste scenario_count_doc_sync, pelo que a contagem documentada já não pode divergir do despachante.

0.17.0 - 2026-06-14#

Adicionado#

  • PNT de espaço profundo e de Marte — motor aberto de navegação radiométrica + simulação GSE. Um novo eixo de capacidades, totalmente aditivo, sobre o núcleo validado na Terra (todos os cenários terrestres existentes ficam idênticos ao byte — os valores de referência de reprodutibilidade passam sem alterações e sem regeneração). Acrescenta: um núcleo de dinâmica multicorpo (Body{mu, re, zonals, gravity, rotation, IAU-pole} com gravidade tesseral GMM-3 de Marte, um referencial de Marte fixo ao corpo da IAU, um ponto de ligação EphemerisProvider substituível, datas julianas de duas partes com precisão submicrossegundo e TT↔TDB); observáveis radiométricos (tempo de luz iterativo + atraso de Shapiro, Doppler e distância a dois/um/três sentidos através da resolução de duas pernas de Moyer, retorno coerente do transponder, medição de distância regenerativa/PN segundo o CCSDS 414, Δ-DOR segundo o CCSDS 506, meios de plasma solar/tropo/iono); análise + emissão de CCSDS-TDM (503); um Filtro de Informação de Raiz Quadrada de dinâmica reduzida com acelerações empíricas RTN, um relógio de bordo de três estados e um modelo de arrasto de Marte; um estimador de fusão conjunto de um sentido + dois sentidos; a superfície de cenários mars-pnt (constelação de retransmissão + LMO/transferência/superfície) em CLI, Python, WASM, MCP e no playground; e um simulador de desempenho GSE de ponta a ponta (geometria → balanço de ligação → observáveis → SRIF → covariância). Nível de validação — validado por simulação: OD sintética em ciclo fechado (LMO de Marte ≈ 0,2 m) e autoconsistência analítica, com a dinâmica de Marte centrada no Sol verificada de forma cruzada e independente face ao DE440 do JPL (xval/anise-mars-od, condicionado ao kernel: 137 m num arco de 1 dia, o resíduo honesto de n corpos não modelados). As exatidões de espaço profundo comunicadas são figuras de mérito de simulação / covariância, não resultados de missões reais; a validação com dados reais de seguimento DSN/ESTRACK continua no roteiro. O ANISE (MPL-2.0, edition-2024) fica confinado a um crate de verificação cruzada excluído do workspace, pelo que a barreira de licenças cargo deny e a tarefa de MSRV-1.75 ficam intactas.
  • Traços no solo com a exatidão de agências a partir da orientação real da Terra do IERS. O cenário ephemeris aceita um campo opcional eop_finals2000a — o corpo incorporado de um ficheiro finals2000A real do IERS — e reduz o traço no solo através do UT1−UTC e do movimento polar por época, interpolados a partir dele (o mesmo EopSeries que precise_od usa), substituindo os escalares nominais dut1_s/xp_arcsec/yp_arcsec. Os dados viajam no cenário, pelo que a execução continua reproduzível e não precisa de sistema de ficheiros (funciona no playground WASM). Uma opção kshana --eop <finals2000A> incorpora um ficheiro real no cenário a partir da CLI. Fecha a assimetria em que só precise_od consumia dados reais de orientação da Terra.

Corrigido#

  • Consistência de referencial da taxa de variação da distância. A estação terrestre é agora mapeada para o referencial inercial através do inverso exato da redução do satélite (frames::itrf_to_teme, desfazendo o movimento polar e a rotação sideral) em vez de uma rotação GMST cega ao movimento polar, pelo que ambas as extremidades partilham um único referencial. O efeito sobre o Doppler comunicado está abaixo do piso de validação, mas elimina uma incompatibilidade de referencial real e uma alegação excessiva de "exato" no código-fonte.
  • carrier_hz é validado. Uma frequência de portadora nula ou não finita passa a devolver um erro em vez de produzir silenciosamente um Doppler nulo (tinha tornado λ = c/portadora infinito), em linha com a proteção existente de step_s.

0.16.0 - 2026-06-11#

Adicionado#

  • Validação do modelo de forças por ajuste de efemérides, verificada de forma cruzada face a produtos reais de agências. Um novo estimador de mínimos quadrados em lote (src/precise_od.rs) com matriz de transição de estado variacional e edição de valores aberrantes, conduzido por um modelo de forças completo (PreciseForceModel: geopotencial EGM2008, terceiros corpos, marés sólidas + oceânicas + atmosféricas e acelerações empíricas CPR/2-por-revolução), alimentado por um analisador real de orientação da Terra IERS finals2000A. Validado face a órbitas de referência publicadas: MEO Galileo até 13 cm pós-ajuste, LEO Swarm-A da ESA e LRO lunar (selenocêntrico, gravidade GRAIL, referencial fixo ao corpo IAU-2015 — dinâmica reduzida 6,6 m, com honestidade acima do objetivo de 5 m no caminho aberto; o caminho ANISE/DE440 de nível DE que o atinge é um crate excluído do workspace).
  • Cenário spoof-detect — um detetor de spoofing integrado de várias camadas que combina paridade RAIM por época, monitores de AGC e de qualidade de sinal (SQM) e uma decisão fundida, validado face aos parâmetros de cenário publicados do TEXBAT (Humphreys et al., ION GNSS 2012), incluindo o caso difícil alinhado com a portadora.
  • Cenário ephemeris — estado, referenciais, traço no solo e Doppler. Propaga um satélite (TLE→SGP4 ou uma órbita analítica) e emite, por passo, o estado inercial TEME e GCRS (posição e velocidade), a posição ITRF/ECEF fixa à Terra, o traço no solo do ponto subsatélite em WGS-84 (latitude / longitude / altitude) e o azimute / elevação / distância topocêntricos, com taxa de variação da distância e Doppler a partir de uma estação terrestre. Alcançável a partir da CLI, de Python, de WASM e do servidor MCP, e distribuído como a predefinição "Ground track" no playground web, onde o traço é desenhado sobre um mapa-mundo real (linhas de costa Natural Earth 1:110m, incorporadas — sem rede nem dependência externa).
  • Exportação CCSDS OEM (--export-oem / export_oem = true) — a Orbit Ephemeris Message com velocidade consumida por GMAT / Orekit / STK, em paridade com os exportadores SP3 e OMM existentes.
  • Marés terrestres sólidas, oceânicas (FES2004) e atmosféricas (Ray 2001 S2) no geopotencial (IERS Conventions cap. 6), ligadas ao modelo de forças.
  • Wheels ARM64 — a compilação do PyPI passa também a produzir wheels Linux aarch64 (manylinux_2_28), macOS arm64 e Windows arm64.
  • Relatório técnico alargado (preprint) ligado a partir do README, e o artigo JOSS tornado submetível (ORCID do autor, compilado para PDF na CI a cada alteração).

Alterado#

  • Referenciais validados ao milímetro face a vetores publicados de Vallado. A redução TEME→PEF/ITRF, a cadeia completa CIO IAU 2006/2000A GCRS→ITRS e a conversão ECEF→geodésica WGS-84 estão agora fixadas ao exemplo trabalhado em Vallado et al. (AIAA 2006-6753) com o seu EOP do IERS, e não apenas à autoconsistência interna.
  • Verificações cruzadas independentes de escalas de tempo. A ERA e as escalas UTC/TAI/TT concordam com hifitime a < 1 µs, e as efemérides planetárias DE440 concordam com o JPL Horizons (posições geocêntricas da Lua/Sol), ambas como barreiras de CI sempre ativas.
  • O playground web esconde o separador de figuras de mérito quando um resultado não traz linhas de figuras de mérito, para que os pacotes só de gráfico (efemérides, RAIM, spoofing) abram no seu gráfico — nas efemérides, o traço no solo — em vez de numa tabela vazia.
  • Os cursores guiados do playground e a varredura de parâmetros funcionam agora para o cenário de efemérides / traço no solo: os seus controlos (latitude / longitude da estação, passo de tempo, duração, UT1−UTC) são ajustáveis, e uma varredura pode representar a geometria da passagem (elevação máxima, Doppler máximo, altitude, velocidade) em função de qualquer um deles — por exemplo, elevação máxima versus latitude da estação. O separador de varredura só é agora mostrado quando um cenário é realmente varrível, pelo que nenhum pacote oferece um controlo que não representa nada.
  • Documentada a aproximação DUT1 ≈ 0 do SGP4 no ponto de chamada do GMST (um erro de rotação ≤ ~13″, bem dentro do erro do próprio modelo do SGP4) e atualizado CAPABILITY.md.

0.15.1 - 2026-06-09#

Adicionado#

  • O plugin JetBrains Kshana — PNT simulator está agora publicado e aceite no JetBrains Marketplace. O README, kshana.dev e os documentos de distribuição ligam diretamente para ele.

Corrigido#

  • A publicação no registo MCP passa agora a ter êxito: o description de server.json excedia o limite de 100 carateres do registo (HTTP 422). Foi encurtado, e o nome do servidor (e a etiqueta de propriedade da imagem) foram alinhados com o espaço de nomes canónico io.github.ashfordeOU/kshana-mcp.
  • A publicação no JetBrains Marketplace passa agora a ter êxito: a CI voltava a enviar a mesma versão do plugin que tinha sido listada manualmente, o que o Marketplace rejeita. A versão do plugin é incrementada para 0.1.1, e a proteção de idempotência passa também a tratar uma resposta "already contains version" como um êxito sem efeito.
  • Invalidação de cache de kshana.dev: as cadeias de consulta com carimbo de versão de style.css/app.js acompanham a versão, pelo que os visitantes que regressam obtêm sempre a compilação atual.

0.15.0 - 2026-06-08#

Adicionado#

  • kshana-mcp — o Kshana como servidor Model Context Protocol (MCP) (mcp/kshana-mcp/). Um crate autónomo, excluído do workspace (o SDK rmcp é edition 2024) que expõe o motor validado a agentes e assistentes de IA — Cursor, JetBrains AI Assistant / Junie e qualquer cliente MCP — por stdio. Ferramentas: run_scenario, list_scenario_kinds, validate_scenario, export_sp3, export_omm, cada uma um invólucro fino sobre kshana::api.
  • Plugin para IDE JetBrains (ide/jetbrains/). Clique com o botão direito num cenário .toml → Run Kshana Scenario; as figuras de mérito e o JSON de resultados chegam em fluxo a uma janela de ferramenta do Kshana. Plugin Kotlin de plataforma pura, compatível com todos os IDE JetBrains 2024,3+.
  • Distribuição pública + publicação automática por versão para ambos:
    • kshana-mcp no crates.io (cargo install kshana-mcp) através de publish.yml.
    • kshana-mcp como imagem OCI multiarquitetura em ghcr.io (docker run ghcr.io/ashfordeou/kshana-mcp) através de um novo mcp-publish.yml.
    • kshana-mcp no registo MCP oficial através de GitHub OIDC (zero segredos); a entrada de registo (server.json) usa o tipo de pacote OCI com um proprietário verificado por etiqueta.
    • o plugin para IDE no JetBrains Marketplace através de publishPlugin (condicionado por token, com assinatura opcional de programador) em cada etiqueta de versão.

0.14.1 - 2026-06-08#

Adicionado#

  • Validação cruzada independente de referenciais ANISE/SPICE (xval/anise-frames/). Um crate autónomo, excluído do workspace, verifica de forma cruzada a redução CIO IAU 2006/2000A de kshana (kshana::cio::gcrs_to_itrs_matrix, GCRS→ITRS) face ao ANISE (a reimplementação NAIF/SPICE em Rust puro) a rodar GCRF→ITRF93 a partir de earth_latest_high_prec.bpc do JPL, com os mesmos parâmetros de orientação da Terra IERS finals2000A fornecidos a ambos os lados, ao longo de oito épocas trimestrais 2020–2023. As duas realizações independentes de referencial concordam com uma rotação relativa máxima de 0,028″ — ≤ 0,86 m no solo, ≤ 0,93 m em LEO, ≤ 3,6 m em órbita GNSS, satisfazendo com ampla margem a antiga verificação cruzada de referencial do ROADMAP "< 10 m" (complementa, e não substitui, as âncoras SOFA/ERFA bit a bit existentes). O crate é isolado porque anise + hifitime são MPL-2.0 / edition-2024 e nunca devem entrar no grafo de dependências publicado de kshana, no seu Cargo.lock, na barreira de licenças cargo deny nem na compilação MSRV; o ANISE está fixado com default-features = false. Inclui um binário frame-xval (obtém o BPC de ~5 MB, imprime uma tabela, escreve report.{json,md}), uma barreira de testes que se salta a si própria sem kernel/rede e uma tarefa de CI opcional apenas de workflow_dispatch (nunca bloqueia main). Documentado em docs/VALIDATION.md (linha CIO) e ROADMAP.md.

Corrigido#

  • Playground adaptado a dispositivos móveis. Corrigido o excesso horizontal de .panel do playground em telemóveis (um item de grelha CSS com min-width: auto por omissão era apresentado com ~100 px a mais do que a janela de visualização) através de min-width: 0 e de controlos com proteção de largura; verificado sem problemas a 360 / 390 / 414 / 768 px. Alinhados os botões de ação "Pin to compare" / "Download report" (caixas de margem iguais na linha flex). Aumentados os botões de execução, os cursores, os seletores e as ligações de navegação para o mínimo de alvo tátil de ~44 px da WCAG 2.5.5 / Apple-HIG em telemóveis e dispositivos táteis, com o tamanho em ecrãs de secretária inalterado.

0.14.0 - 2026-06-08#

Corrigido#

  • Reforço de robustez a partir de uma ronda de testes de combate adversariais. (1) sbas_protection_level passa a rejeitar elevação/azimute/variância não finitos e diagonais de covariância negativas ou não finitas (uma geometria quase singular ampliada por um σ pequeno podia anteriormente escapar à barreira do pivô absoluto e devolver um VPL NaN / um HPL absurdo como um Some válido — uma falha de integridade silenciosa). (2) O propagador numérico (propagate/propagate_dopri) falha em modo seguro perante um estado inicial não finito, em vez de fazer o controlador adaptativo girar para sempre. (3) O auxiliar de células do DEM deixa de entrar em pânico numa grelha de uma só amostra (1×N). (4) O azimute de lunar_look_angle é mantido estritamente em [0, 360). (5) SphericalHarmonicField::from_gfc rejeita GM/raio não físicos (NaN / não positivos).

Adicionado#

  • Binário validation_report + artefacto de versão: um gerador sem dependências que emite um resumo de validação em HTML de uma página, pronto a imprimir, que indexa cada validação imposta pela CI (SGP4 666/666, EGM2008, referenciais bit a bit, Allan NIST, fichas técnicas de IMU, ARAIM/SBAS, reprodutibilidade em 3 SO, cobertura) ao seu teste e à sua referência independente externa. O fluxo de trabalho de versão gera kshana-validation-summary.html e anexa-o (com proveniência SLSA) a cada versão etiquetada.
  • pytest de interoperabilidade com numpy + reforço das wheels: tests/python/test_numpy_interop.py (executado na CI) mais um contentor manylinux fixado e um passo de verificação auditwheel show na compilação das wheels.
  • Tutoriais e educação: docs/tutorials/ (três tutoriais resolvidos, cenários anotados por domínio, exercícios de nível 1/2/3) com tests/tutorials.rs a fixar cada número citado à saída do motor em execução.
  • Artefactos de submissão externa (paper/, notebooks/, submissions/): um rascunho de artigo JOSS, um notebook quântico-versus-clássico e kits prontos a submeter para awesome-gnss / ESA Navipedia / NASA ASCL / ESA ESSR / ION/IAC, mais FUNDING.yml — a preparar os passos externos de submissão.
  • Navegação PNT alternativa referenciada ao terreno e combinada (módulo altpnt): um navegador de correspondência de terreno TERCOM/SITAN sobre um DEM (carregador .hgt + gerador de dados sintéticos) e um navegador combinado de gravidade + magnético (IGRF) + terreno sem GPS, expostos como tipos de cenário terrain-nav e combined-altpnt. Validado pela convergência da correspondência de terreno (um desvio injetado conhecido é recuperado) e por um erro limitado do filtro combinado numa janela sem GPS.
  • Geometria LunaNet LANS (lunar): locais nomeados da superfície lunar (Apollo 11/15/16, rebordo de Shackleton) com coordenadas selenográficas de referência, ângulos de visão à superfície (az/el/distância), visibilidade/cobertura e DOP do local, validados face ao raio da Lua, às coordenadas de locais publicadas e à identidade de elevação de 90° na vertical radial.
  • Playground guiado no navegador: cursores em modo guiado, um painel de saída com separadores, uma sobreposição de visita guiada na primeira execução, modos de varredura de parâmetros e de sobreposição de várias execuções, uma vista 3D de órbita em canvas/SVG sem dependências (o pacote de órbita passa a emitir um eci_track aditivo), um modo embutido/iframe e descarga como relatório HTML — cada um com testes unitários node na CI.
  • Modelo de erro de IMU validado por ficha técnica (tests/imu_allan_spec.rs): ARW/VRW/instabilidade de enviesamento do ADIS16465/16488/16460 recuperados a partir do desvio de Allan sintetizado e verificados face às especificações do fabricante (identificação NIST SP1065 / IEEE 952).
  • Validação dos estimadores de Allan do NIST SP1065 (tests/allan_nist_sp1065_1000point.rs): os quatro estimadores reproduzem os desvios de referência publicados de 1000 pontos e os limites de confiança da Tabela 32.
  • Níveis de proteção SBAS / DO-229E, L1/L5 sem ionosfera e um mapa de compliance DO-316 (módulo sbas). sbas_protection_level forma a matriz de geometria ponderada a partir da elevação/azimute de cada satélite e do orçamento de erros UDRE/GIVE/aerotransportado/tropo, inverte a matriz normal (orbit::invert4 partilhada) e projeta as variâncias em HPL/VPL através dos fatores K do DO-229E (PA 6.0/5.33, NPA 6,18). iono_free_l1l5 acrescenta a pseudodistância L1/L5 sem ionosfera do GPS (IS-GPS-705, γ₁₅ = 1.79327), validada por cancelar o atraso ionosférico de primeira ordem independente do motor. do316_compliance_map faz corresponder os requisitos DO-316/DO-229E às funções que os implementam. Validado face às definições de fator K em forma fechada, à geometria de referência inv(GᵀG) do numpy e à identidade de covariância por duas vias; a verificação cruzada de aderência à norma RTKLIB/gLAB com PL publicado está documentada como pendente de revisão em docs/COMPLIANCE.md.
  • Gravidade tesseral completa em harmónicas esféricas — o campo EGM2008 até ao grau/ordem 70. Um novo gravity_sh::SphericalHarmonicField avalia o geopotencial e a sua aceleração no referencial fixo à Terra a partir de coeficientes C̄_nm, S̄_nm totalmente normalizados, usando a estável recorrência de Legendre normalizada de Holmes–Featherstone (a desnormalização daria excesso de capacidade neste grau). Os coeficientes distribuídos são o produto EGM2008 da NGA (domínio público, via ICGEM), incluído em egm2008_data.rs e reproduzido bit a bit por tools/gen_egm2008.py a partir de tools/egm2008_to70.gfc submetido; qualquer modelo ICGEM .gfc carrega-se através de from_gfc. Validado face a três referências independentes: colapso para massa pontual (só C̄00 = −μr/|r|³), um campo apenas zonal que reproduz o forces::zonal_accel existente até ~1e-9, e a aceleração analítica a coincidir com o gradiente por diferenças finitas do potencial somado diretamente até <1e-6.
  • Aceleração de Lense–Thirring (arrastamento de referencial) da relatividade geral (forces::lense_thirring_accel, IERS 2010 Eq. 10,12), o termo gravitomagnético para além da correção de Schwarzschild existente, ligado ao propagador numérico através de uma nova opção ForceModel::lense_thirring(). Validada como linear no momento angular da Terra e 1–2 ordens de grandeza abaixo do termo de Schwarzschild, o regime das medições do LAGEOS / Gravity Probe B.
  • Um trait Propagator que unifica os propagadores de órbita analítico e numérico. O propagador numérico de modelo de forças de Cowell é agora um par de primeira classe do SGP4: um novo tipo NumericalPropagator (estado inicial + ForceModel + Tolerance + escolha de Integrator por duplicação de passo ou de Dormand–Prince) e Sgp4 implementam ambos propagator::Propagator, cujo state_at(t_seconds) -> StateVector devolve o estado TEME inercial em unidades SI (m, m/s), pelo que os dois são intermutáveis por trás de um Box<dyn Propagator>. A implementação do SGP4 é a conversão exata km/min→SI do método inerente (verificada por um teste de igualdade); a implementação numérica satisfaz, através do trait, a mesma barreira submétrica de Kepler exata, os dois controladores adaptativos concordam e um PropagatorError expõe o código SGP4 subjacente.

0.13.0 - 2026-06-08#

Esta versão fecha a maior lacuna de correção do motor: a orientação da Terra e a redução de referenciais são agora feitas com qualidade de implementação de referência (validadas bit a bit face ao ERFA/SOFA), a pilha de integridade ganha ARAIM de dupla constelação sobre TLE reais de GPS+Galileo, e as camadas de propagação, de sensores quânticos, lunar/cislunar e geomagnética aprofundam-se todas — a par de uma API Python tipada, de um playground de navegador mais rico e de uma matriz de reprodutibilidade em três SO. Destaques:

  • Referenciais, bit a bit. Nutação IAU 2000A e 2000B completas, precessão IAU 2006, a redução GCRS↔ITRS IAU 2006/2000A baseada em CIO (X, Y, s), movimento polar do IERS e referenciais de saída TEME→GCRS/ITRS — cada um validado bit a bit face às rotinas de referência ERFA/SOFA.
  • ARAIM de dupla constelação (GPS + Galileo) sobre TLE reais, com HPL/VPL, saída em diagrama de Stanford e um docs/ARAIM_REFERENCE.md aberto.
  • PNT cislunar: um propagador CR3BP Terra–Lua, referenciais MCI↔MCMF, coordenadas selenográficas e um cenário executável de integridade lunar LunaNet.
  • Deteção quântica: sistemáticos de Coriolis e de AC-Stark para o interferómetro de átomos frios, uma varredura de deriva e validação face ao orçamento de Freier (2016).
  • Modelo geomagnético de campo principal IGRF-14, autónomo e validado.
  • API Python tipada (PyO3 RunOutput/ScenarioMeta, .data(), scenario_kinds, validate_toml, stubs de tipos) com compilação de wheels na CI, mais saída de propagador GCRS/ITRS de primeira classe e exportação CCSDS OMM.
  • Credibilidade e reprodutibilidade: uma comparação direta de exatidão do SGP4 com o crate independente sgp4, uma barreira de cobertura na CI (~97 % de linhas em src/) e uma matriz de reprodutibilidade em três SO (ubuntu/macos/windows).

Alterado#

  • Todos os gráficos do playground correspondem agora ao tema do sítio. Todos os doze geradores de gráficos SVG — o gráfico de resultado/holdover (src/report.rs + src/chart.rs), o gráfico de desvio de Allan (web/app.js) e todos os gráficos de cenários (src/hybrid.rs, jamming.rs, timetransfer.rs, spoof.rs, raim.rs Stanford + disponibilidade, lunar.rs, ensemble.rs, sweep.rs, gnss_sim.rs, fusion/pack.rs, inertial/mod.rs) — usavam painéis azul-marinho frios (#0e131b), eixos/texto cinzento frio e uma paleta de séries vermelho/azul/roxo em conflito. Passam agora a usar em todo o lado a paleta quente de grafite: painéis --bg, grelha quente --line, rótulos --fg, com uma atribuição de séries consistente — quântico = dourado-mel (--accent-bright), clássico = âmbar quente (--partial), especificação/limite = --crit. As vistas com código de segurança mantêm o seu significado: o diagrama de Stanford do RAIM continua verde (disponível) / âmbar (enganoso) / vermelho (perigoso) / aço esbatido (indisponível), e HPL/VPL aparecem a dourado/bronze.
  • Os gráficos são agora autodescritivos quando guardados/descarregados. Ambos os gráficos incorporam o seu título no SVG (o título do gráfico de Allan + o subtítulo "lower is better" estavam anteriormente apenas em HTML à volta da imagem, pelo que uma imagem guardada não tinha legenda), e ambos trazem um rodapé de proveniência — Kshana v<version> · <scenario-hash> · kshana.dev — para que um gráfico descarregado se sustente por si e continue reproduzível.
  • Todos os gráficos trazem agora o rodapé de proveniência. O rodapé — Kshana v<version> · scenario <hash> · kshana.dev — é carimbado centralmente para todos os tipos de cenário em api::run_toml (anteriormente só existia nos gráficos de holdover e de Allan), pelo que qualquer imagem guardada ou descarregada — a partir do playground, da exportação .chart.svg da CLI ou do cartão de pontuação em HTML — identifica a sua versão, a impressão digital do cenário e a fonte. O hash é etiquetado scenario para maior clareza e vem de scenario_hash do resultado, quando existe, com um recurso a um hash da fonte nos relatórios de integridade/lunares. O que é a impressão digital e porque existe está documentado na secção "Output" do README e em docs/PROVENANCE.md.

Corrigido#

  • raim::chi2_quantile e o amostrador de ruído de Stanford do RAIM deixam de entrar em pânico com entradas fora do intervalo / não finitas (uma descoberta de fuzzing dependente da ordem de read_dir, a partir dos novos cenários ARAIM). chi2_quantile passa a proteger p/k como normal_quantile (devolvendo um valor-limite em vez de entrar em pânico com assert!), e o Normal do ruído de Stanford da disponibilidade limita-se a um σ estritamente positivo — pelo que a pilha de integridade/ARAIM nunca entra em pânico com cenários mutados ou mal configurados.

Adicionado#

  • Matriz de CI de reprodutibilidade multiplataforma. Uma nova tarefa reproducibility-matrix executa os testes de reprodutibilidade em ubuntu-latest, macos-latest e windows-latest a cada push. Como o JSON de resultados completo não é idêntico ao byte entre SO (divergência de libm no último ULP), afirma exatamente a projeção invariante da plataforma — a impressão digital da entrada mais a forma da saída, fixadas por cenário como valores de referência SHA-256 em tests/golden/ pelo novo tests/cross_platform_golden.rs — a par dos valores numéricos fixados (golden.rs, até 1e-6), dos estados SGP4 (sgp4_verification.rs, até 2e-5 km) e do determinismo no mesmo processo (determinism.rs). Em conjunto, estes provam a reprodutibilidade multiplataforma em três SO sem a fragilidade de um hash ao byte exato da saída completa. docs/REPRODUCIBILITY.md documenta a divisão.
  • Barreira de cobertura de código na CI. Uma nova tarefa coverage executa cargo-tarpaulin com o motor LLVM baseado em fonte, publica um relatório lcov como artefacto de compilação e impõe um piso de cobertura de linhas em src/ (tabelas de dados geradas, ponto de entrada da CLI, testes e ativos web excluídos). A cobertura de linhas medida é de ~97 % em src/ (SGP4 e os módulos de relógio ≥95 %); a barreira está fixada em 85 % — acima do objetivo de ≥80 % e afastada do valor medido, pelo que apanha regressões sem falhas espúrias. Um selo de cobertura é publicado no README.
  • SGP4/SDP4 em comparação direta com o crate independente sgp4. Um novo teste (tests/sgp4_crate_comparison.rs) verifica de forma cruzada o propagador do Kshana face à biblioteca SGP4 em Rust mais usada (neuromorphicsystems/sgp4, acrescentada como dev-dependency apenas para testes) sobre os mesmos 666 vetores AIAA 2006-6753. Com ambos conduzidos pelo modelo gravítico WGS72 que os vetores usam, as duas implementações independentes concordam a nível submicrométrico em órbitas próximas da Terra e ressonantes e a 4,12 mm no pior caso em todos os regimes, ambas reproduzindo a tabela de referência tcppver.out. A tabela de comparação submetida (tests/fixtures/sgp4_comparison.md, regenerada através de KSHANA_REGEN_FIXTURES=1) decompõe o resultado por regime (LEO/MEO, espaço profundo, ressonância de ½ dia e de 1 dia) e regista os quatro casos deliberadamente patológicos que o crate rejeita na construção. As asserções em execução mantêm ambos a menos de 2e-5 km da referência e a concordar entre si a menos de 4e-5 km — uma proteção contra regressões, não um resultado pontual. Estas são credenciais competitivas: correção face a uma base de código independente, e não apenas uma tabela estática. (O from_elements por omissão do crate usa WGS84 e por isso difere da referência WGS72 em ~km — apresentado com honestidade no texto da tabela.)
  • A exportação CCSDS OMM é agora alcançável de ponta a ponta. O escritor OMM (src/omm.rs) não tinha anteriormente nenhum caminho de CLI/API; os elementos médios de um cenário orbit podem agora ser publicados como um catálogo CCSDS 502.0-B-2 OMM — uma mensagem OMM KVN por satélite definido por TLE — através de kshana <orbit.toml> --export-omm out.omm, ou export_omm = true no cenário escreve automaticamente <scenario>.omm (a espelhar o --export-sp3 existente). Cada mensagem traz o número de catálogo NORAD real do satélite, o designador internacional COSPAR (YYYY-NNNP) e a época (forma de dia do ano do CCSDS), extraídos da linha 1 do TLE pelo novo tle::parse_tle_identity; a linha de nome passa a OBJECT_NAME (caso contrário, OBJECT <id>). CREATION_DATE é a época do cenário, não a hora do relógio, pelo que a saída é reproduzível. Nova API: api::export_omm / api::auto_export_omm, OmmFile::from_tle_block, OrbitClockScenario::to_omm_string. Um cenário sintético Walker ou RINEX (sem elementos médios de TLE) falha com erro em vez de emitir um ficheiro vazio. Validado face ao instantâneo incluído de 30 satélites gps-ops (tests/sp3_export_roundtrip.rs).
  • Leituras interativas ao passar o cursor nos gráficos do playground. Ao mover o cursor sobre um gráfico, uma mira ajusta-se à amostra mais próxima e mostra uma dica com o valor (web/hover.mjs, ligado em web/app.js). No gráfico de Allan, lê τ e o σ_y(τ) de cada relógio; nos gráficos de cenários de séries temporais (holdover de relógio, navegação por estima, transferência de tempo, PNT híbrido, GNSS/INS), lê o tempo e o valor de cada conjunto nas unidades do próprio gráfico (ns / m / ps / utilização), extraídos do resultado para que a leitura coincida com a curva. Os diagramas especializados (RAIM, spoofing, varredura) não recebem sobreposição. Os gráficos continuam a ser <img>s blob autodescritivos — a sobreposição é uma mira transparente + dica por cima, pelo que descarregar/comparar/exportar ficam intactos. A matemática de coordenadas (amostra mais próxima, cursor→fração do gráfico, análise da polilinha) é testada por unidades (web/hover.test.mjs, executados na CI).
  • Modo de comparação A/B no playground. Fixe qualquer execução como linha de base A, execute um segundo cenário, e os dois são mostrados lado a lado com uma tabela de diferenças de figuras de mérito (holdover, RMS/p95 de temporização, disponibilidade) que colore o vencedor por métrica (web/compare.mjs, ligado em web/app.js; lógica de diferenças testada por unidades em web/compare.test.mjs, executada na CI). Todos os valores são inseridos como texto e todos os gráficos através de <img> blob, pelo que nada proveniente de uma cadeia de cenário é alguma vez injetado como marcação.
  • Botões de descarga de gráficos (SVG + PNG). Cada gráfico do playground tem agora uma barra de ferramentas "Download SVG / PNG" com o tema correspondente (web/chartdl.mjs, ligada em web/app.js). O SVG devolve o original fiel e escalável; o PNG rasteriza essa mesma imagem autodescritiva a 2x para diapositivos e documentos. Os ficheiros são nomeados com a sua proveniência — kshana-<chart>-v<version>-<scenario-hash>.<ext> — e a lógica de nome/tamanho de ficheiro é testada por unidades (web/chartdl.test.mjs, executados na CI).
  • Modelo geomagnético de campo principal IGRF-14 (src/igrf.rs). O campo de harmónicas esféricas padrão da IAGA (grau/ordem 13, época 2025,0 + variação secular 2025–2030; coeficientes gerados por máquina a partir do igrf14coeffs.txt oficial por tools/gen_igrf.py para src/igrf_data.rs, reproduzíveis bit a bit). Uma síntese normalizada de Schmidt devolve o vetor do campo (norte/este/baixo) e os elementos derivados (declinação, inclinação, intensidade horizontal/total) em qualquer local/data geodésicos, mais o polo geomagnético e a intensidade do dipolo — a contraparte magnética do correlacionador de mapa gravítico para navegação PNT alternativa. Validado de forma autónoma: a síntese coincide com o dipolo inclinado exato em forma fechada, o campo analítico completo de grau 13 coincide com uma diferença finita do potencial escalar, o eixo do dipolo reproduz o polo geomagnético conhecido (~80,7°N, −72,7°E) e a intensidade de ~29,7 µT, e o campo global é físico.
  • Ligações Python tipadas (src/python.rs). Para além de run/run_full, de cadeia à entrada/cadeia à saída, o módulo expõe agora uma classe RunOutput tipada (.json, .svg, .summary e um acessor .data() que devolve o resultado já analisado num dict Python nativo — sem nova análise de JSON, embrulhável em NumPy), mais run_typed, scenario_kinds() (lista analisada de dicts de metadados) e validate_toml() (uma lista de mensagens de erro que não lança exceções). Distribui um stub de tipos PEP 561 (kshana.pyi + py.typed) para mypy/pyright/editores e um guia de início rápido docs/PYTHON_API.md. As funções existentes não mudam.
  • Referenciais de saída de primeira classe para propagadores (enum src/orbit.rs Frame + position_in_frame + state_gcrs). Qualquer Propagator (Kepler, SGP4, RINEX, GLONASS, SP3) pode agora emitir a sua posição em TEME, GCRS (≈ J2000) ou ITRS (fixo à Terra) — TEME nativo, GCRS através da redução TEME→GCRS validada, ITRS encadeando essa redução na rotação gcrs_to_itrs CIO IAU 2006/2000A — e o seu estado GCRS completo (posição + velocidade) através de state_gcrs. A saída inercial da data deixa de ser apenas TEME.
  • Redução celeste-para-terrestre IAU 2006/2000A baseada em CIO (src/cio.rs). A cadeia GCRS↔CIRS↔ITRS moderna, sem equinócio: coordenadas do CIP X, Y lidas da matriz de viés-precessão-nutação IAU 2006/2000A (reutilizando a precessão FW validada + a nutação 2000A com o ajuste P03 de eraNut06a), a série de 66 termos do localizador de CIO s (eraS06, gerada por máquina a partir da referência ERFA por tools/gen_s06.py para src/cio_s06_data.rs, reproduzível bit a bit), a matriz GCRS→CIRS (eraC2ixys), o ângulo de rotação da Terra (eraEra00) e a rotação GCRS→ITRS completa (eraC2tcio, composta com o movimento polar do IERS existente). Validada bit a bit face ao eraXys06a publicado (X=0.5791308482835292617e-3, Y=0.4020580099454020310e-4, s=-0.1220032294164579896e-7 em JD_TT 2453736,5) e aos vetores de teste eraC2ixys e eraEra00. Mostra-se que a cadeia CIO e a redução TEME legada de equinócio/GMST-1982 concordam, a menos da sua diferença documentada de convenção de tempo sidéreo de ≈2·(equação dos equinócios). Esta é a redução rigorosa que o caminho equinócio/GMST aproximava.
  • Série completa de nutação IAU 2000A (src/nutation.rs nutation_iau2000a, nutation_matrix_2000a). O modelo MHB2000 completo — 678 termos luni-solares + 687 planetários — com exatidão < 0,1 mas, a par do truncamento 2000B de 77 termos existente. As tabelas são geradas por máquina a partir da referência nut00a do IAU SOFA / ERFA por tools/gen_nut00a.py para src/nutation_iau2000a_data.rs (o gerador reproduz o ficheiro submetido bit a bit), e toda a série — tanto os conjuntos de argumentos fundamentais IERS-2003 e MHB2000 como as longitudes planetárias — é validada bit a bit face ao vetor de teste eraNut00a publicado (Δψ = −0.9630909107115518e-5, Δε = 0.4063239174001679e-4 em JD_TT 2453736,5, até 1e-13 rad). A redução TEME→GCRS por omissão mantém a série 2000B (~1 mas, abaixo da simplificação de rotação do referencial de velocidade da cadeia); nutation_matrix_2000a expõe a matriz da data de < 0,1 mas para quem a precisar.
  • Cenário executável de integridade lunar (kind = "lunar-integrity", scenarios/lunanet-araim.toml). Liga a passagem de nível de proteção do polo sul lunar (src/lunar.rs LunarScenario → south_pole_hpl_pass) ao executor de cenários com um LunarReport JSON e um gráfico SVG de HPL versus tempo, para que o caso de integridade cislunar seja alcançável diretamente a partir da CLI. Expõe com honestidade a lacuna: com o σ_URE de 30 m do LANS, o HPL do polo sul (≈ 260–450 m) excede um limite de alerta de 50 m (0 % disponível) — a integridade do PNT lunar ainda não é atingida.
  • Disponibilidade de ARAIM de dupla constelação em TLE reais de GPS+Galileo, e ligação ao executor de cenários (src/raim.rs, src/orbit.rs, scenarios/araim-gps-galileo.toml). Acrescenta araim_dual_constellation_availability (o motor ARAIM avançado — falhas de um só satélite e de toda a constelação — executado numa grelha temporal) e visible_positions_labeled, e liga-o ao executor de IntegrityScenario através de uma opção araim_dual, para que um estudo ARAIM multi-GNSS seja alcançável diretamente a partir de TOML. Um teste com dados reais (tests/araim_dual_real_data.rs) em instantâneos incluídos do Celestrak GPS+Galileo de 2026-06-07 mostra que reunir o Galileo eleva a disponibilidade ARAIM de 0,21 para 0,67 sob um VAL exigente de 12 m (10,5→21,8 satélites à vista), enquanto o modo robusto a falhas de constelação é fundamentalmente limitado com apenas duas constelações — a razão quantitativa pela qual a integridade robusta de dupla constelação tende para uma terceira constelação ou para o SBAS. Resíduo honesto: a reprodução numericamente exata da Tabela A-3 do EU ARAIM TN face a uma única época com versão bloqueada, e um registo de ficheiro de teste no Zenodo.
  • Problema circular restrito de três corpos (CR3BP) para o sistema Terra–Lua (src/cr3bp.rs). Um novo núcleo de dinâmica cislunar que os propagadores de dois corpos/SGP4 não podem fornecer: equações de movimento em referencial rotativo (cr3bp_accel), um propagador RK4 (propagate_cr3bp), o integral da constante de Jacobi (jacobi_constant) e os cinco pontos de Lagrange (lagrange_points). Validado face a âncoras em forma fechada / publicadas: os pontos colineares Terra–Lua (L1 ≈ 0,83692, L2 ≈ 1,15568, L3 ≈ −1,00506), os L4/L5 equiláteros exatos = (½−μ, ±√3/2, 0), os cinco confirmados como equilíbrios do campo, Jacobi conservada com a precisão do integrador durante a propagação, e a força restauradora fora do plano que torna possíveis as órbitas de halo/NRHO. Esta é a base para representar uma NRHO real. Resíduo honesto: condições iniciais NRHO 9:2 periódicas corrigidas diferencialmente, o modelo excêntrico/de efemérides (DE) e a transformação desnormalizada para os referenciais seleno-cêntricos de src/lunar.rs.
  • Movimento polar do IERS e a redução TEME→ITRF (src/frames.rs). Acrescenta polar_motion_matrix (iauPom00 do SOFA: W = Rx(−y_p)·Ry(−x_p)·Rz(s′) com o localizador TIO s′), pef_to_itrf / itrf_to_pef e teme_to_itrf — a rotação TEME→PEF baseada em GMST seguida do movimento polar — completando uma posição fixa à Terra com precisão ITRF sobre o teme_to_ecef apenas com GMST (o movimento polar é um efeito de dezenas de metros ao raio orbital). x_p/y_p são grandezas IERS observadas que o chamador fornece. Resíduo honesto: uma cadeia totalmente baseada em CIO (X, Y, s) e uma verificação numérica cruzada ANISE/SPICE de <10 m continuam a ser trabalhos posteriores.
  • Sistemáticos do interferómetro de átomos frios, varredura de deriva e uma validação com um dispositivo publicado (src/inertial/quantum_imu.rs, docs/QUANTUM.md). Alarga o acelerómetro CAI de primeiros princípios com os dois principais sistemáticos determinísticos: a fase de Coriolis/rotação Φ_cor = 2·k_eff·v_⊥·Ω·T² (coriolis_phase, com o enviesamento de aceleração equivalente 2·Ω×v através de coriolis_accel_bias) e a fase de desvio de luz AC-Stark Φ_LS = (δ_LS,1 − δ_LS,3)/Ω_eff (ac_stark_phase, que se cancela por simetria π/2–π–π/2 para um desvio constante). Acrescenta cai_drift_sweep (deriva de posição por navegação por estima em função do tempo de ciclo — o cerne de uma comparação quântico-versus-clássico) e um teste de validação face ao gravímetro móvel de Freier et al. 2016 (arXiv:1512,05660): o piso modelado de ruído de projeção quântica situa-se abaixo do ruído de curto prazo publicado de 96 nm/s²/√Hz, e a ~2 ordens de grandeza dele. docs/QUANTUM.md atualizado. Resíduo honesto: sistemáticos de frente de onda/apontamento do feixe, resolução de ambiguidade de franjas, a reprodução exata dos ensaios em voo CARIOQA-PMP / Boeing-AOSense (requer PSD de plataforma publicadas) e uma predefinição de playground em JS.
  • Redução de referenciais cislunares e uma passagem de integridade no polo sul lunar (src/lunar.rs). Alarga o motor ARAIM lunar com a rotação MCI↔MCMF (inercial centrado na Lua ↔ fixo à Lua) (mci_to_mcmf / mcmf_to_mci, um modelo simplificado de rotação média à taxa sideral lunar), latitude/longitude/altitude selenográficas (mcmf_to_selenographic / selenographic_to_mcmf) e south_pole_hpl_pass — um recetor pousado na região Artemis face a um conjunto representativo de retransmissores LunaNet ao longo de uma passagem de 24 h, que quantifica com honestidade a lacuna de integridade: com o σ_URE nominal de 30 m do LANS, o nível de proteção é finito mas excede um limite de alerta de operações à superfície de 50 m. Resíduo honesto: as efemérides LANS NRHO precisas (uma órbita cislunar de 3 corpos), a libração física / o polo lunar em precessão (DE421/SPICE) e um cenário TOML LunaNet continuam a ser trabalhos posteriores.
  • Mensagem de suporte de integridade ARAIM, SVG do diagrama de Stanford e a referência ARAIM aberta (src/raim.rs, docs/ARAIM_REFERENCE.md). Acrescenta uma IntegritySupportMessage explícita (σ_URA / σ_URE / b_nom / P_sat / P_const, com os valores de referência GPS+Galileo do WG-C e conversores .fault_priors() / .dual_fault_priors() para os motores de falha única araim_raim e de toda a constelação araim_dual_raim), um renderizador autónomo stanford_svg do diagrama de integridade de Stanford (as quatro zonas, a fronteira PL = error, as guias de limite de alerta, um marcador com código de cores por época) e docs/ARAIM_REFERENCE.md a documentar o algoritmo, o ISM, as hipóteses de falha, o contrato do nível de proteção e o benefício da dupla constelação. Os testes demonstram o ganho de geometria/redundância (reunir uma segunda constelação aperta o HPL de falha única) e a tolerância a falhas de constelação (o utilizador de dupla constelação sobrevive à perda de uma constelação inteira; um utilizador de constelação única não). Resíduo honesto: reproduzir numericamente a Tabela A-3 do EU ARAIM TN / a figura de disponibilidade de 15–25 % face a um instantâneo real de TLE com versão bloqueada, um registo de ficheiro de teste no Zenodo e a ligação de araim_dual_raim ao executor de ficheiros de cenário.
  • Nutação IAU 2000B e a redução inercial completa TEME→GCRS/J2000 (src/nutation.rs). Acrescenta a segunda e a terceira peças de uma verdadeira redução de referencial inercial sobre a precessão IAU 2006 já distribuída: a série de nutação luni-solar MHB2000 de 77 termos (nutation_iau2000b, o truncamento IAU 2000B padrão com exatidão de ~1 mas) com os argumentos fundamentais de Delaunay e a matriz de nutação iauNumat do SOFA, e a cadeia Vallado AIAA-2006-6980 TEME→TOD (equação dos equinócios) → TOD→MOD (nutação) → MOD→GCRS (viés-precessão) exposta como teme_to_gcrs(r, v, jd_tt) / gcrs_to_teme. A série, os argumentos e as constantes de unidades são transcritos da referência nut00b do IAU SOFA / ERFA e validados bit a bit face ao vetor de teste eraNut00b publicado (Δψ, Δε até 1e-13 rad). Resíduo honesto: a série completa IAU 2000A de 678 termos (<0,1 mas), uma verificação numérica cruzada ANISE/SPICE de <10 m e o movimento polar continuam a ser trabalhos posteriores (ver ROADMAP.md).

0.12.0 - 2026-06-06#

Esta versão traz o primeiro propagador de órbita não analítico do Kshana — um integrador de Cowell com um modelo de forças hierárquico de seis perturbações (dois corpos + zonal J2–J6 + terceiro corpo Sol/Lua conduzido por época + pressão de radiação solar com sombra cónica de umbra/penumbra + arrasto atmosférico + a correção relativista pós-newtoniana de Schwarzschild) conduzido por uma escolha de dois integradores adaptativos (RK4 por duplicação de passo e o par embutido Dormand–Prince RK5(4)) — a par de uma camada de manobras / conceção de trajetórias (queimas impulsivas e finitas, um resolvedor de Lambert de Izzo e uma varredura porkchop), uma camada de PNT alternativo de correspondência de mapa gravítico que recupera um traço de 60 minutos sem GPS a menos de 500 m, uma cadeia de determinação de órbita em lote + sequencial e um UKF GNSS/INS de 17 estados fortemente acoplado completo com navegação por estima quântica CAI. Toda a capacidade numérica está fixada face à verdade analítica ou a uma forma fechada deduzida à mão; as perturbações desativadas por omissão deixam intactos os valores de referência já publicados.

Adicionado#

  • Correção relativista pós-newtoniana (Schwarzschild) (forces::relativistic_accel + propagator::ForceModel::relativity). Acrescenta a perturbação dominante da relatividade geral numa órbita próxima da Terra — o principal responsável pelo avanço relativista do perigeu — na forma β = γ = 1 de IERS / Montenbruck–Gill a = (μ/c²r³)·{[4μ/r − v²]·r + 4(r·v)·v}. Tal como o arrasto atmosférico, é dependente da velocidade, pelo que acompanha o membro direito do integrador (r, v) através de [accel_rv], opcional e desativada por omissão. Validada de forma autónoma: numa órbita circular colapsa para a forma fechada 3μ²/(c²r³)·r̂ (puramente radial e para fora, componentes fora do eixo exatamente nulas); a sua razão face a dois corpos é o valor de manual ≈1.9·10⁻⁹ em LEO (a assinatura de μ/(c²r)); um caso de velocidade radial coincide com o μ(4μ + 3v²r)/(c²r³) simplificado à mão; e no propagador perturba a órbita sem a dissipar — o semieixo maior é conservado a bem menos de um metro/dia, o oposto estrutural da decadência monótona do arrasto. Por estar desativada por omissão, os valores de referência de dois corpos/J2/zonais ficam intactos. O ajuste de parâmetros PPN (β,γ) e o termo de arrastamento de referencial de Lense–Thirring continuam a ser trabalhos posteriores.
  • Modelo de sombra cónica de umbra+penumbra (forces::conical_shadow), agora usado pela pressão de radiação solar. Atualiza o eclipse binário de cilindro umbral para um fator ν ∈ [0,1] suave: o Sol e a Terra são modelados como discos de raios angulares aparentes a = asin(R☉/d☉), b = asin(Rₑ/|r|) com separação aparente dos centros c, e ν é um menos a fração do disco do Sol ocultada pelo disco da Terra (a área de sobreposição lenticular círculo–círculo) — sol pleno para c ≥ a+b, umbra total para c ≤ b−a, anular para c ≤ a−b e uma penumbra contínua entre eles. srp_accel passa a usá-lo, pelo que a força de SRP diminui suavemente ao longo do eclipse em vez de ligar/desligar. Acrescenta o forces::SOLAR_RADIUS nominal da IAU. Validado de forma autónoma: ν = 1 em sol pleno e ν = 0 no fundo da umbra (exato), uma penumbra monótona e suave (ν sobe de 0 → ~½ em c = b → 1 ao longo da banda [b−a, b+a]), e a penumbra cónica estende-se para além do cilindro umbral (um ponto que o cilindro binário considera totalmente iluminado é 0 < ν < 1 para o cone). O mais simples cylindrical_shadow continua disponível; o escurecimento do limbo solar e a sombra de uma Terra achatada continuam a ser trabalhos posteriores.
  • Integrador embutido Dormand–Prince RK5(4) (integrator::dopri54_step / integrator::integrate_dopri + propagator::propagate_dopri). Acrescenta o par embutido padrão de tabela de Butcher de Dormand–Prince (1980) a par do controlador existente de duplicação de passo RK4: sete estágios FSAL dão uma solução de 5.ª ordem e uma estimativa de erro de 4.ª ordem a partir de um só conjunto de avaliações (7 contra 11 chamadas de função por passo), uma estimativa de erro local mais barata. O controlador adaptativo reutiliza a mesma norma de erro RMS e o controlador de passo 0.9·(1/err)^(1/5), pelo que é uma alternativa de substituição direta; propagator::propagate_dopri expõe-no no modelo de forças da órbita. Validado de forma autónoma: a estimativa de erro embutida é O(h⁵) (reduzir o passo a metade corta-a ~32×); o DP5(4) integra y' = y até e e o oscilador harmónico ao longo de 50 períodos conservando a energia a <1e-6; atinge o mesmo ponto final com a mesma tolerância em menos avaliações de função do que a duplicação de passo (sem sacrificar a exatidão); e propagate_dopri satisfaz a mesma barreira de verdade analítica que o caminho RK4 — submétrica face à solução de Kepler exata por variáveis universais ao longo de uma órbita LEO de 24 h — enquanto os dois controladores concordam a <1 m numa órbita J2..J6 (sem forma fechada). Pares embutidos de ordem superior (RKF7(8) / DOP853) continuam a ser trabalho posterior.
  • Arrasto atmosférico ligado ao propagador como a sua primeira força dependente da velocidade (forces::atmospheric_density + forces::drag_accel + propagator::ForceModel::drag). Acrescenta a atmosfera exponencial por troços da Tabela 8-4 de Vallado ρ = ρ0·exp(−(h−h0)/H) (28 bandas desde o nível do mar até além de 1000 km, limitada abaixo da superfície) e o arrasto quadrático a = −½ · ρ(h) · (C_D·A/m) · |v_rel| · v_rel face à atmosfera em co-rotação v_rel = v − ωₑ ẑ × r (forces::EARTH_ROTATION_RATE = 7.2921151467e-5). Como o arrasto depende da velocidade, ForceModel ganha um novo accel_rv(t, r, v) e o membro direito do integrador passa agora a velocidade (f(t,[r;v]) = [v; a(t,r,v)]); o accel_at apenas de posição não muda, pelo que os termos conservativos e os valores de referência ficam intactos. Validado de forma autónoma: a densidade ancora no valor ao nível do mar de 1,225 kg/m³, é limitada abaixo da superfície, decresce monotonicamente ao longo da LEO, situa-se na banda de média solar de ~1e-12 kg/m³ a 400 km, e a sua altura de escala local recuperada (≈ 58 km a 400 km) é física; o arrasto opõe-se à velocidade relativa em co-rotação com a magnitude LEO de ~2e-6 m/s² para C_D·A/m = 0.02 m²/kg; e — a assinatura essencial — o arrasto é dissipativo: uma órbita de 300 km perde energia específica monotonicamente e o seu semieixo maior decai uns ~km/dia limitados, enquanto a linha de base no vácuo conserva a energia a <1e-9. A densidade termosférica NRLMSISE-00 (a cláusula de densidade de arrasto < 5 %) continua a ser trabalho posterior.
  • Pressão de radiação solar ligada ao modelo de forças do propagador, conduzida por época (forces::srp_accel + propagator::ForceModel::solar_radiation). Acrescenta o modelo SRP de bala de canhão a = ν · P☉ · cᵣ · (A/m) · (AU/d)² · d̂ com um fator de eclipse de sombra cilíndrica (forces::cylindrical_shadow, ν ∈ {0 1}): a pressão de radiação P☉ = Φ☉/c a partir da irradiância solar total moderna de 1361 W/m² (≈ 4,5398·10⁻⁶ N/m²), a queda de fluxo do inverso do quadrado (AU/d)² e o empurrão radial para longe do Sol. Acompanha o mesmo membro direito conduzido por época que o terceiro corpo, amostrando o Sol de ephem uma única vez na época avançada epoch_jd_tt + t/86400 partilhada entre o terceiro corpo Sol e a SRP. Combinável: with_zonals_j2_j6().third_body(true, true, epoch).solar_radiation(1.5, 0.02). Validado de forma autónoma face a assinaturas deduzidas à mão: a pressão de radiação a 1 UA fixa-se no valor de manual de ≈ 4,5398·10⁻⁶ N/m²; a SRP de um satélite LEO totalmente iluminado é idêntica bit a bit à fórmula de bala de canhão, aponta para longe do Sol e situa-se na banda de ~1,36·10⁻⁷ m/s² para cᵣ = 1,5, A/m = 0,02 m²/kg; duplicar a distância ao Sol divide a magnitude por quatro (inverso do quadrado); a sombra cilíndrica só eclipsa o cilindro umbral (no lado oposto ao Sol e a menos de um raio terrestre da linha Terra–Sol) e dá SRP exatamente nula em eclipse; e no propagador a SRP perturba uma órbita LEO por uma quantidade pequena e limitada que escala ~linearmente com A/m — enquanto um modelo sem perturbações permanece bit a bit independente do tempo, deixando intactos os valores de referência de dois corpos/J2/zonais. A umbra/penumbra cónica (ν suave ∈ [0 1]), o arrasto atmosférico e a validação cruzada externa com GMAT/Orekit continuam a ser trabalhos posteriores.
  • Terceiro corpo Sol/Lua conduzido por época ligado ao membro direito variável no tempo do propagador (propagator::ForceModel::third_body / accel_at). A perturbação de terceiro corpo já não é um termo de força autónomo — é agora integrada pelo propagador de Cowell como uma força genuinamente variável no tempo: cada avaliação do membro direito amostra as posições do Sol/Lua de ephem na época avançada epoch_jd_tt + t/86400 (reutilizando precession::julian_centuries_tt para a conversão dia↔século), de modo que os perturbadores se movem ao longo das suas órbitas durante a integração em vez de ficarem congelados no início. Combinável com qualquer modelo gravítico (ForceModel::with_zonals_j2_j6().third_body(true, true, epoch)). Validado de forma autónoma: o termo Sol do membro direito é idêntico bit a bit a third_body_accel avaliado na posição das efemérides nesse instante, tanto em t = 0 como em t = 1 day (provando exatamente a ligação 86400 s ↔ 1 dia ↔ 1/36525 século), o perturbador avança ~2,6·10⁹ m/dia entre amostras (não congelado), as magnitudes de maré instantâneas em LEO atingem as bandas de manual de ~5·10⁻⁷ m/s² (Sol) e ~1,1·10⁻⁶ m/s² (Lua, ≈ 2× o Sol), cada corpo perturba de forma mensurável a trajetória de um dia mantendo-se limitado, e o mesmo estado inicial propagado em épocas afastadas um quarto de ano dá uma trajetória diferente (o eixo de maré roda 90°) — enquanto um modelo sem nenhum dos corpos ativado é bit a bit independente do tempo, deixando intactos os valores de referência de dois corpos/J2/zonais. A exatidão de efemérides de nível DE e a validação cruzada externa com GMAT/Orekit continuam a ser trabalhos posteriores.
  • Efemérides lunares de baixa precisão (ephem::moon_position), a completar o par de terceiro corpo Sol/Lua. Acrescenta a série lunar de baixa precisão de Montenbruck & Gill (§3.3.2) a par do modelo do Sol, para que o forces::third_body_accel, agnóstico quanto ao corpo, possa agora ser conduzido por qualquer um dos astros sem nenhum kernel DE/SPK externo. Validadas de forma autónoma face a assinaturas lunares deduzidas à mão: a distância geocêntrica mantém-se dentro do envelope real de perigeu/apogeu (~356 500–406 700 km) ao longo de um mês e a sua média mensal recupera o semieixo maior de ~384 400 km; a latitude eclítica nunca excede a inclinação orbital lunar de ~5,3° (verificado projetando sobre o polo da eclítica em coordenadas equatoriais, validando em conjunto a série de latitude e a rotação da obliquidade); a direção da Lua regressa a menos de 1° após um mês sideral (27,3217 d) e o seu movimento diário mantém-se na banda física de 12–15°/dia; e a perturbação de terceiro corpo lunar num satélite LEO tem a magnitude de manual de ~1,1·10⁻⁶ m/s² (≈ o dobro da do Sol). A exatidão de posição de nível DE, o arrasto atmosférico e a SRP continuam a ser trabalhos posteriores.
  • Gravidade de terceiro corpo (Sol) com efemérides de baixa precisão incorporadas (forces::third_body_accel, ephem::sun_position). Acrescenta ao modelo de forças a perturbação de terceiro corpo: a = GM₃·((s−r)/|s−r|³ − s/|s|³) (atração direta menos o termo indireto que o referencial geocêntrico tem de subtrair), com a posição do Sol fornecida pela série analítica de baixa precisão de Montenbruck & Gill do novo módulo ephem — sem necessidade de nenhum kernel DE/SPK externo para uma execução de baixa fidelidade. Validada de forma autónoma: a aceleração coincide com o gradiente exato do seu próprio potencial perturbador (third_body_potential), a perturbação anula-se no geocentro e tem a magnitude de manual de ~5·10⁻⁷ m/s² num satélite LEO, e as efemérides do Sol atingem âncoras J2000 deduzidas à mão — distância ao periélio ≈ 1,471·10¹¹ m, declinação ≈ −23° perto do solstício de dezembro, um movimento aparente de ≈ 1°/dia (≈ 90° por trimestre) e uma distância que se mantém dentro do envelope orbital terrestre de 0,983–1,017 UA ao longo de um ano inteiro. Entrega a metade de terceiro corpo do passo do modelo de forças do marco do propagador numérico (a Lua é entregue numa entrada associada acima); a exatidão de posição de nível DE, o arrasto atmosférico e a SRP continuam a ser trabalhos posteriores.
  • Modelo de forças de harmónicas zonais J2–J6 (forces::zonal_accel / zonal_potential). Alarga o modelo de forças do propagador de Cowell para além de J2 até ao campo zonal completo da Terra até ao grau 6 (os J2..J6 não normalizados do EGM-96 publicados como padrão), ligado ao propagador como ForceModel::with_zonals_j2_j6(). A aceleração é o gradiente analítico exato do potencial perturbador zonal R(r) = −(μ/r)·Σ Jₙ(Re/r)ⁿPₙ(z/r) (polinómios de Legendre por recorrência ascendente), validado de três formas independentes: reduz-se ao j2_accel validado com 666 vetores, até à precisão da máquina, quando restrita a [J2]; coincide com o gradiente numérico do seu próprio potencial em todo o campo J2..J6 (a verificação de referência de ouro do campo conservativo); e os termos ímpares J3 face aos pares J2/J4..J6 exibem a sua (anti)simetria norte–sul característica sob z → −z — a assimetria em forma de pera. Uma órbita J2..J6 propagada conserva a energia total (cinética + central + potencial zonal) até ~1e-8 ao longo de um dia e perturba a órbita apenas com J2 por uma quantidade pequena e não nula. Isto entrega o passo 2 ("harmónicas zonais J2–J6") do marco do propagador numérico; o campo tesseral EGM de grau elevado, o arrasto, a SRP, o terceiro corpo e a validação cruzada externa com GMAT/Orekit continuam a ser trabalhos posteriores.
  • Propagador de órbita numérico (Cowell) (src/propagator.rs). O primeiro propagador não analítico do Kshana (o resto da pilha de órbitas é SGP4/SDP4 analítico): liga o modelo de forças de dois corpos + J2 (src/forces.rs) ao controlador adaptativo RK4 de duplicação de passo (src/integrator.rs) como f(t,[r;v]) = [v; a(r)], com um comutador ForceModel. Validado face a uma verdade analítica mais forte do que seria uma ferramenta numérica cruzada: a órbita não perturbada reproduz a solução exata de Kepler por variáveis universais a nível submétrico ao longo de uma órbita LEO de 24 horas (uma barreira mais apertada do que o "face a uma referência numérica < 10 m" que o marco enuncia), a energia específica e o momento angular conservam-se até ~1e-9 em termos relativos, e a regressão nodal de J2 reproduz o j2_secular_rates em forma fechada segundo a teoria de primeira ordem (a menos de 2 %, o resíduo O(J2²)). Acrescenta também solve_kepler_checked, um resolvedor de Newton para a equação de Kepler que devolve Err em vez de uma resposta silenciosamente errada quando não converge dentro de um orçamento limitado de iterações (o caso e = 0.999 perto do perigeu). Âmbito honesto: o modelo de forças é apenas dois corpos + J2 — o campo tesseral EGM de grau elevado (200×200 + carregador), o arrasto (NRLMSISE-00), a SRP, as forças de terceiro corpo e uma validação cruzada externa com GMAT/Orekit continuam a ser trabalhos posteriores.
  • Correspondência de mapa gravítico sem GPS durante 60 minutos até < 500 m (run_gps_denied_gravity_nav). Aprofunda a camada de PNT alternativo até ao objetivo de validação Quantum Wayfarer do ESA NAVISP: um veículo percorre um trajeto de ~700 km durante uma falha completa de GNSS de uma hora — a sua solução inercial deriva até ≈ 70 km — e um gravímetro de átomos frios mais um correlacionador de partículas/grelha hierárquico do grosseiro ao fino recupera a deriva constante do INS até ≈ 145 m (< 500 m), uma redução de > 480×. O piso real de ruído branco do gravímetro é injetado como uma sequência determinística com semente, pelo que o correlacionador nunca recebe a verdade sem ruído e, ainda assim, a execução é exatamente reproduzível (verificada idêntica bit a bit e estável a alguns metros entre realizações de ruído). Um teste de nível de regressão mostra que o refinamento é necessário — uma única grelha grosseira estagna a ~2 km, e só o refinamento em três fases rompe a barreira de 500 m. Novo cenário submetido scenarios/gps-denied-gravity-nav.toml. A linha docs/CAPABILITY.md continua, com honestidade, parcial (ainda sem mapa EGM2008 incluído), com a sua evidência atualizada para o resultado de 60 min < 500 m. Âmbito honesto inalterado: campo de harmónicas esféricas de grau baixo + mascons sintéticos; um Monte-Carlo sobre realizações de erro de representação do mapa é um trabalho posterior.
  • Registo de alegações excessivas + proteção contra regressões (docs/CLAIMS-VS-REALITY.md, tests/no_overclaims.rs). Fecha a linha de trabalho de honestidade/retirada de alegações: as catorze alegações excessivas que uma auditoria anterior catalogou (OC-0…OC-13) estão agora todas GREEN — as alegações fortes (OC-0 filtro de Kalman acoplado de relógio+posição, OC-2 jamming J/S→C/N₀→perda de bloqueio, OC-7 física CAI Mach–Zehnder, OC-8 ARAIM HPL/VPL) são substituídas por capacidades distribuídas e testadas em vez de uma redação suavizada, e as restantes linhas têm as alegações retiradas para corresponder ao código. Um novo teste de CI analisa as superfícies públicas em vigor (README, CAPABILITY, GLOSSARY, web/) e falha se alguma expressão de alegação excessiva simples já retirada reaparecer sem ressalva, pelo que uma linha GREEN não pode regredir em silêncio. A FoM de "integridade" por execução continua, com honestidade, etiquetada como autoconsistência do filtro (e não integridade de aviação); o HPL/VPL real do ARAIM é apresentado em separado, para que os dois nunca sejam confundidos.
  • Navegação por correspondência de mapa gravítico (PNT alternativo sem GPS). O novo src/gravimeter.rs acrescenta a camada de capacidades de PNT alternativo que os estudos de correspondência de mapa gravítico Quantum Wayfarer / QT-CCI do ESA NAVISP exigem: um modelo de medição de gravímetro de átomos frios cujo piso de ruído branco deriva da ASD do acelerómetro CAI (σ = ASD/√τ); um campo de anomalia gravítica em harmónicas esféricas de grau baixo, totalmente normalizado (validado face às funções de Legendre em forma fechada P̄₁₁=√3·cosφ, P̄₂₀=(√5/2)(3sin²φ−1), P̄₂₂=(√15/2)cos²φ e a uma anomalia de um só termo, deduzida à mão, de 1,897 mGal) mais mascons sintéticos para as características locais de grau elevado; e um filtro de partículas de correspondência de mapa gravítico (compondo mapmatch + particle_filter) que recupera um trajeto sem GPS a partir da sequência de anomalias que atravessa. Um benchmark NAVISP submetido (scenarios/gravity-map-nav.toml) reduz uma deriva inercial livre de ~73 km para uns poucos km. Âmbito honesto: o Kshana não inclui o conjunto completo de coeficientes EGM2008 de 2190° — o campo é de grau baixo + mascons, não um mapa real de alta resolução; o carregador EGM/EIGEN, o mapa magnético, o SLAM auxiliado por terreno e a ligação kind= ao motor de cenários com um gráfico SVG de deriva continuam a ser trabalhos posteriores. docs/CAPABILITY.md "Gravity-map / alt-PNT navigation" → parcial.
  • Modelação de manobras e cabeça de ponte de conceção de trajetórias. O novo src/maneuver.rs acrescenta a primeira camada de conceção de trajetórias acima do SGP4: nós de ΔV impulsivos que aplicam uma descontinuidade de velocidade e propagam uma covariância 6×6 (queima determinística ⇒ transição de estado identidade; a covariância do erro de execução roda do referencial da queima — ECI ou LVLH — para o bloco de velocidade), uma integração de queima finita (empuxo constante ao longo de um arco de queima com a massa como estado) cujo ΔV alcançado é verificado face à equação de foguetão de Tsiolkovsky em forma fechada com melhor de 0,01 %, um resolvedor de Lambert de revolução única de Izzo-2015 (r1, r2, tempo de voo ⇒ v1, v2), um propagador de Kepler exato por variáveis universais (verdade de dois corpos) e uma varredura porkchop que mapeia uma grelha de época de lançamento × época de chegada para o C3 de partida e o V∞ de chegada, emitida como uma matriz JSON 2-D para renderização de contornos no navegador. A validação é autónoma e mais forte do que uma leitura de tutorial: cada saída de Lambert faz a ida e volta pelo propagador de Kepler (tem de aterrar de volta em r2), e o mínimo do porkchop é verificado face ao piso analítico de C3 da transferência de Hohmann para duas órbitas circulares coplanares. O Kshana posiciona isto como a camada de simulação de desempenho acima do GMAT/Orekit, não como um substituto (os ramos de várias revoluções e uma efemérides planetária real continuam fora do âmbito). Dez testes.
  • UKF GNSS/INS fortemente acoplado completo de 17 estados com navegação por estima quântica CAI. O novo src/fusion/tightly_coupled17.rs transporta o estado completo de navegação inercial que um filtro fortemente acoplado estima — [position, velocity, attitude-error, accelerometer bias, gyro bias, clock bias, clock drift] (17 estados) — propagado através da mecanização strapdown conduzida pela força específica e pela taxa angular medidas, com a rotação corpo→inercial de ângulo pequeno C ≈ I + [ψ×], de modo que o erro de atitude se acopla à aceleração horizontal (o acoplamento de inclinação padrão do INS). Durante uma falha de GNSS segue em deriva apenas com a IMU; o ruído de processo de passeio aleatório da velocidade é o q_va derivado do acelerómetro de interferómetro de átomos frios (crate::inertial::quantum_imu), pelo que a deriva da navegação por estima é a limitada pelo sensor quântico — uma falha de 120 segundos mantém-se limitada a umas centenas de metros, contra os quilómetros que um INS livre de qualidade de navegação atingiria. A atualização de pseudodistância/taxa de variação da distância corre pelo filtro unscented partilhado (com α = 1 para pesos bem condicionados a este tamanho de estado). Cinco testes: identidade do modelo de medição, integração de velocidade constante com IMU perfeita, auxílio por GNSS, estimação do enviesamento do acelerómetro e o teste de referência de falha de 120 s limitada por CAI.

0.11.0 - 2026-06-05#

Alterado#

  • Enquadramento honesto do posicionamento quântico. O descritor principal é agora um "simulador de resiliência de PNT com modelos de desempenho de sensores quânticos" de forma consistente no slogan do README, na linha de citação, em CITATION.cff (título + resumo) e na arte do cabeçalho — substituindo a formulação de marketing mais solta "simulador PNT híbrido quântico/clássico". A secção What it is / is not do README ganha uma declaração explícita de âmbito "It is not (yet)" (não é um motor de física de interferometria atómica de primeiros princípios, não é um recetor GNSS/resolvedor PVT, não é uma ferramenta de conceção de missões), e um novo ROADMAP.md de nível superior torna a camada de física quântica um item P2 (fase CAI Mach–Zehnder, ruído de projeção, tensor de vibração), para que os leitores saibam que a física de primeiros princípios está delimitada e a caminho, e não abandonada. Nenhuma alteração de comportamento ou de API.

Adicionado#

  • Estudo de compromissos de conceção de constelações: varredura de conceção Walker com uma frente de Pareto, JSON de tempo de revisita e uma validação submétrica da fórmula de Walker. src/walker.rs ganha walker_design_sweep, que executa uma grelha planes × sats_per_plane (por exemplo, um compromisso 3×3) a uma inclinação fixa e tabula, por conceção, a fração de cobertura, o PDOP no pior caso e a lacuna de revisita máxima/média; pareto_front assinala as conceções não dominadas (menos satélites, mais cobertura, PDOP mais baixo, revisita mais curta), e WalkerDesignReport::to_json serializa as células e a frente de Pareto — incluindo os campos de tempo de revisita — como JSON. Uma nova validação fixa o gerador à fórmula de Walker i:T/P/F: mostra-se que satélites do mesmo slot em planos adjacentes se mapeiam uns nos outros por uma rotação R_z(2π/P) exata a menos de 1 km ao longo de 24 h completas de propagação SGP4 (a respiração de curto período de J2 é de modo comum e cancela-se), e confirma-se que os slots no plano estão espaçados de 2π/S em média. Assenta no instantâneo real submetido do Celestrak gps-ops de 2021-07-28 (scenarios/orbit-sgp4-gps.toml, exercitado pelos testes de cobertura de cenários e de ida e volta de SP3).
  • Transferência avançada de tempo e frequência: TWSTFT, vista comum GNSS, PPP, ótica, ajuste de lei de potência IEEE-1139 e um conjunto de relógios. O novo src/timetransfer_adv.rs constrói os métodos operacionais de transferência sobre as formas fechadas de Sagnac/vista comum já distribuídas e sobre as ferramentas de estabilidade de Allan. twstft_sagnac dá a correção de Sagnac da Transferência de Tempo e Frequência por Satélite Bidirecional como a soma do circuito de três saltos, igual à forma fechada do BIPM Δt = 2·A·ω_E/c² exatamente (verificada de forma cruzada pelo twstft_sagnac_bipm independente); run_twstft emite uma série T_A − T_B de um dia e o seu TDEV. gnss_common_view_series faz a diferença simples de duas estações terrestres sintéticas, de modo que o relógio do satélite se cancela. iono_free_combination + ppp_receiver_clock são a combinação sem ionosfera PPP e a resolução do relógio do recetor face a uma verdade sintética de qualidade SP3, cancelando exatamente a ionosfera de primeira ordem. rytov_variance, fried_parameter e o lognormal_fading de média unitária modelam a cintilação induzida por turbulência de uma ligação ótica em espaço livre. fit_power_law_psd é um ajuste completo por mínimos quadrados de cinco coeficientes h_α IEEE-1139 da curva da variância de Allan (os cinco processos de ruído canónicos em simultâneo), com o processo dominante comunicado por década de τ. ensemble_timescale forma uma escala de tempo de papel ponderada pelo inverso da variância cujo desvio de Allan fica estritamente abaixo do melhor relógio contribuinte. 31 testes unitários; os alvos de validação são formas fechadas e verdade sintética — falta ainda uma ingestão real de Circular-T do BIPM / SP3 do IGS.
  • Mapas de ionosfera IONEX: analisador de ficheiros, interpolação temporal e mapeamento de obliquidade oblíqua. src/ionex.rs ganha parse_ionex, que lê o formato de ficheiro IONEX (definição da grelha no cabeçalho + blocos START/END OF TEC MAP) para uma sequência de IonexMaps — normalizando a ordenação de latitude de norte para sul do ficheiro numa TecGrid de passo positivo e escalando os valores por 10^EXPONENT. interpolate_tec_in_time mistura dois mapas sucessivos numa época de consulta, e obliquity_factor / slant_tec mapeiam o TEC vertical para um raio oblíquo através do fator de casca fina de camada única M(z) = 1/cos z′ (sin z′ = (Rₑ/(Rₑ+H))·sin z). Em conjunto com o modelo de grelha já distribuído, estes transformam um mapa global de ionosfera do IGS medido num atraso oblíquo utilizável.
  • Conceção de constelações: dimensionamento por ruas de cobertura + comparação de várias constelações. src/walker.rs ganha min_satellites_streets_of_coverage, um resolvedor idealizado de número mínimo de satélites por ruas de cobertura — a partir do semiângulo de cobertura λ já distribuído e da meia-largura da rua c, dimensiona a constelação quase polar para cobertura global única contínua como p = ⌈π/(2c)⌉ planos (por exemplo, um plano de 4 satélites à altitude do GPS precisa de 2 planos, 8 satélites), e comunica None quando os satélites são demasiado esparsos para formar uma rua contínua. compare_constellations é a ferramenta de comparação de várias constelações: pontua cada conceção Walker nomeada na mesma estação/janela através de pdop_sweep e devolve lado a lado a sua cobertura / PDOP / dimensão. Âmbito honesto: a correção de Rider exata na junta da fronteira de planos em contrarrotação e um globo de cobertura 3-D são trabalhos posteriores.
  • Deteção de spoofing em várias camadas: detetor de paridade de consistência RAIM + fusão de camadas. src/spoof_monitors.rs ganha a terceira e última camada de deteção e a fase de fusão: parity_raim_test ajusta por mínimos quadrados a solução de posição/relógio a um conjunto redundante de pseudodistâncias e testa a soma dos quadrados residual ponderada restante face ao seu limiar χ²(m−4) — assinalando um subconjunto enviesado de satélites e deixando corretamente um enviesamento de modo comum (absorvido pelo relógio do recetor) invisível ao RAIM, sem o disfarçar. fuse_spoof_layers combina as camadas de paridade, AGC e SQM numa única decisão ponderada que regista quais as camadas que dispararam. Um Monte-Carlo caracteriza o detetor: P_fa ≈ 0,068 empírico face a um ponto de conceção de 0,05, com a deteção falhada a descer de 0,885 com um enviesamento de spoofing de 2σ para 0,16 com 8σ. Âmbito honesto: a validação cruzada face a vetores de teste de spoofing publicados específicos (Spirent / ION GNSS+) exige esses conjuntos de dados externos e continua a ser um trabalho posterior.
  • Conjunto de validação de Kalman acoplado versus desacoplado. Um Monte-Carlo de 100 ensaios em src/fusion/coupled.rs quantifica o valor de transportar a covariância cruzada posição↔relógio: uma linha de base desacoplada fiel e em linha (validada bit a bit face ao CoupledPntFilter distribuído) processa os mesmos dados com os blocos cruzados anulados, e, após pseudodistâncias quase degeneradas mais uma posição só de relógio, o filtro acoplado recupera a posição a 2,97 m RMS contra 48,8 m do filtro desacoplado, ganhando em 97 de 100 ensaios — a posição de relógio só melhora a posição através da correlação que o pacote desacoplado descarta. Isto completa o conjunto de validação da correção de Kalman (forma de Joseph, segurança semidefinida positiva, consistência NEES/NIS e, agora, o conjunto de filtro acoplado).
  • Cadeia de determinação de órbita (em lote + sequencial). Um novo src/orbit_determination.rs recupera o estado orbital [r, v] de um satélite a partir de seguimento de distância por estação terrestre, compondo três peças já distribuídas: o modelo de forças de dois corpos + J2 (src/forces.rs) e o integrador RK4 (src/integrator.rs) propagam um estado candidato ao longo do arco, um modelo de medição de distância prevê cada distância de estação, e o corretor em lote de Gauss–Newton (src/batch_ls.rs) leva o candidato para o estado de melhor ajuste (determine_orbit_batch). A mesma dinâmica e o mesmo modelo de distância conduzem também uma determinação recursiva sequencial sobre o filtro unscented já distribuído (determine_orbit_sequential). Quatro testes validam-no: previsão de distância ao longo do arco; recuperação em lote a nível submétrico / mm·s⁻¹ a partir de distâncias sem ruído; recuperação em lote a ~2 m com um resíduo pós-ajuste no piso de ruído de 5 m (a assinatura de um ajuste de mínimos quadrados consistente); e recuperação sequencial a algumas dezenas de metros. Âmbito honesto: medições de taxa de variação da distância/Doppler e de ângulos, uma matriz de transição de estado analítica de J2 e o mascaramento de visibilidade de estações são trabalhos posteriores.
  • Navegador UKF GNSS/INS fortemente acoplado. Um novo src/fusion/tightly_coupled.rs liga o núcleo de Kalman unscented já distribuído (src/fusion/ukf.rs) a um navegador fortemente acoplado funcional sobre o [px,py,pz,vx,vy,vz,b,d] de oito estados (posição/velocidade ECEF mais enviesamento e deriva do relógio do recetor em unidades de distância). Ingere as medições brutas dos satélites — pseudorange (ρ = |p − sᵢ| + b) e range_rate/Doppler (ρ̇ = (p − sᵢ)·(v − ṡᵢ)/|p − sᵢ| + d) — em vez de uma posição já formada, pelo que TightlyCoupled (com propagate/propagate_orbital/ update_gnss) continua a corrigir com menos de quatro satélites e segue em deriva através de falhas de GNSS sobre a sua dinâmica propagada. Cinco testes validam-no de ponta a ponta, incluindo os cenários de aceitação do marco: a geometria de pseudodistância/Doppler face a valores deduzidos à mão; convergência sem ruído a nível submétrico com cinco satélites; um caso de três satélites a convergir de ~212 m para ~13 m onde nem sequer se consegue formar um PVT instantâneo; uma falha de 120 segundos a velocidade constante a menos de 50 m; e — a aceitação principal — uma passagem LEO curva de 30 minutos (órbita real de dois corpos + J2) com uma falha de GNSS de 120 segundos, mantida a 0,77 m RMS na passagem e 2,9 m no pior caso durante a falha. Essa deriva orbital compõe o modelo de forças gravíticas já distribuído (src/forces.rs) e o integrador RK4 (src/integrator.rs) no modelo de processo do UKF (propagate_orbital), pelo que o filtro segue a curvatura da órbita — o que uma deriva de velocidade constante não consegue (só a curvatura são ~58 km em 120 s em LEO). Âmbito honesto: a deriva orbital usa o modelo de forças de dois corpos + J2 em vez da força específica bruta da IMU (para uma plataforma orbital sem propulsão coincidem); integrar um estado de erro de IMU strapdown e correções de iono/tropo em ciclo são trabalhos posteriores.
  • Modelo de medição de correspondência de mapa (navegação referenciada ao terreno/gravidade). Um novo src/mapmatch.rs fornece o modelo de medição que transforma o filtro de partículas de reamostragem por importância sequencial já distribuído (src/particle_filter.rs) num navegador funcional sem GPS: field_likelihood (uma verosimilhança gaussiana de correspondência de campo) e map_match_likelihood, que amostra qualquer campo de referência georreferenciado — elevação do terreno (TRN) ou uma anomalia gravítica — na posição de uma partícula e pondera-a pela concordância com o valor medido do veículo. O campo é qualquer amostrador Fn(lat, lon) -> value, pelo que se combina com a grelha bilinear em src/ionex.rs ou com um closure. Dois testes ancoram-no — a verosimilhança tem o pico (=1) numa correspondência perfeita e desce para e^(−½) a um sigma, e um filtro de partículas sobre uma zona de terreno sintético distintivo recupera a posição verdadeira a menos de 0,1. Âmbito honesto: os mapas de referência reais (elevação SRTM, anomalia gravítica EGM/EIGEN) e os respetivos carregadores são trabalhos posteriores.
  • Integridade de PNT cislunar (ARAIM lunar). Um novo src/lunar.rs aplica o motor ARAIM MHSS do lado da Terra a um serviço de navegação lunar do tipo LunaNet com os parâmetros lunares (σ_URE ≈ 30 m contra 0,6 m do GPS, P_sat ≈ 1e-4): constantes lunares, uma base selenocêntrica Este/Norte/Cima e um auxiliar de geometria do céu, e lunar_araim (HPL/VPL). Três testes ancoram-no — a base selenocêntrica ortonormal, a geometria da distância oblíqua e a escala linear exata do nível de proteção com σ_URE (o valor lunar de 30 m dá um nível de proteção 50× maior do que a mesma geometria com os 0,6 m do GPS — a razão quantitativa pela qual a integridade do PNT lunar é difícil). Âmbito honesto: as efemérides LANS NRHO precisas, o orçamento de erro do sinal no espaço e a redução de referencial MCI↔MCMF são trabalhos posteriores.
  • Datas julianas de duas partes (alta precisão). Um novo src/jd2.rs acrescenta Jd2, uma data juliana dividida num day inteiro e num frac fracionário em [0,1) (a convenção SOFA/hifitime), com new/from_parts/add_seconds/diff_seconds/total. As diferenças de épocas próximas mantêm-se exatas até ao piso de f64, onde uma JD de f64 único perde ~50 µs perto de J2000. Quatro testes ancoram-no: a ida e volta, a normalização da fração, a recuperação exata de microssegundos (com a falha do f64 único demonstrada a par) e a aritmética de segundos aditiva/reversível.
  • Escritor CCSDS OMM (Orbit Mean-Elements Message). Um novo src/omm.rs complementa o escritor de efemérides oem com a mensagem de elementos médios: OmmFile::from_tle mapeia os elementos médios SGP4/TLE para as unidades OMM (movimento médio em rev/dia, ângulos em graus, mais BSTAR), e to_omm_kvn serializa a forma KVN CCSDS 502.0-B-2 de norma em via de adoção — para que uma órbita do Kshana possa ser consumida por qualquer ferramenta que conheça OMM, em vez de como um TLE à medida. Dois testes ancoram a conversão de unidades TLE→OMM (≈ 15,5 rev/dia, inclinação de 51,6°, etc.) e a presença das palavras-chave KVN exigidas. Âmbito honesto: a forma KVN e o mapeamento de TLE são distribuídos aqui; a renderização XML (ndm/omm) e uma ida e volta com um analisador de referência são trabalhos posteriores.
  • Filtro de partículas de reamostragem por importância sequencial. Um novo src/particle_filter.rs acrescenta o estimador não linear e não gaussiano por trás da navegação auxiliada por mapa e sem GPS (referenciada ao terreno ou por correspondência de mapa gravítico): predict (propagar as partículas pela dinâmica + ruído de processo gaussiano), update (repesar por uma verosimilhança de medição por partícula), resample sistemática, o monitor de degenerescência effective_sample_size e a estimativa de média ponderada. Seis testes ancoram exatamente o núcleo determinístico — ESS a abranger 1…N, a reamostragem sistemática a escolher índices em proporção ao peso, a combinação convexa da média ponderada, uma verosimilhança gaussiana a puxar a estimativa para a medição, o comportamento de reamostragem para uniforme e o determinismo de predict com semente. Âmbito honesto: o motor é distribuído aqui; os mapas de referência (elevação SRTM, anomalia gravítica EGM) e o modelo de medição de mapa são trabalhos posteriores (o amostrador de grelha + bilinear de ionex serviria igualmente para um mapa de gravidade/terreno).
  • Mapas de ionosfera TEC no estilo IONEX. Um novo src/ionex.rs acrescenta a alternativa de ionosfera medida ao modelo de Klobuchar difundido: uma TecGrid (uma grelha regular de latitude/longitude de TEC vertical, um mapa global de ionosfera do IGS) com interpolação bilinear num ponto de perfuração (vtec_at, limitada fora da grelha) e o atraso de primeira ordem Δ = 40.3·TEC/f² (vtec_to_delay_m, delay_at). Quatro testes ancoram-no: 1 TECU ≈ 0.162 m em L1 com a escala 1/f², interpolação exata nos nós, pontos médios bilineares a calcular a média dos cantos e consultas fora da grelha limitadas ao bordo. Âmbito honesto: a grelha e a interpolação são distribuídas aqui; a leitura do formato de ficheiro IONEX, a interpolação temporal entre mapas e a função de mapeamento oblíquo são trabalhos posteriores.
  • Correções geométricas de transferência de tempo (Sagnac + vista comum GNSS). Um novo src/timegeo.rs acrescenta os dois efeitos determinísticos que uma comparação real de relógios tem de ter em conta, complementando o modelo estocástico bidirecional em timetransfer: sagnac_correction (Δt = (ω_E/c²)·(x₁y₂ − x₂y₁), o atraso da Terra em rotação — dezenas de ns para linhas de base continentais) e common_view_offset, a diferença simples de vista comum GNSS que cancela exatamente o erro do relógio do satélite e recupera o desvio entre estações. Três testes ancoram-nas em referências exatas: o efeito de Sagnac de ≈ 33 ns de um quarto de volta equatorial, a antissimetria e os casos radial/polar nulos, e o cancelamento exato do relógio do satélite. Âmbito honesto: um orçamento completo de atrasos de transponder/hardware TWSTFT e uma solução PPP de transferência de tempo sem ionosfera são trabalhos posteriores.
  • Modelo de forças orbitais (dois corpos + J2). Um novo src/forces.rs acrescenta o modelo de aceleração que um propagador numérico integra: two_body_accel (−μ·r/|r|³), a perturbação de achatamento j2_accel (a forma fechada em ECI) e gravity_accel a somá-las — emparelhe-o com src/integrator.rs como f(t,[r;v]) = [v; a(r)]. Expõe também as taxas seculares analíticas de J2 (j2_secular_rates): a regressão nodal Ω̇, a rotação apsidal ω̇ e a deriva da anomalia média Ṁ. Seis testes ancoram a física em referências exatas: μ/r² para o termo de dois corpos, a forma fechada de J2 no equador (~10⁻³ da magnitude de dois corpos), a inclinação crítica (63,4349°) que congela o perigeu (ω̇ = 0), a regressão nodal da ISS (Ω̇ ≈ −5°/day) e a deriva para leste de uma órbita retrógrada heliossíncrona. Âmbito honesto: apenas dois corpos + J2; J3–J6, arrasto, SRP e terceiro corpo são trabalhos posteriores.
  • Ligações permanentes partilháveis de cenários. Um novo src/permalink.rs acrescenta um codec Base64 RFC 4648 sem dependências (alfabeto padrão +/ com preenchimento e um alfabeto -_ seguro para URL, sem preenchimento) e invólucros encode_scenario / decode_scenario, de modo que um TOML do playground possa ser codificado num parâmetro de consulta ?s= e partilhado como URL. Exposto ao navegador como ligações wasm encode_permalink / decode_permalink. Quatro testes ancoram-no nos vetores canónicos da RFC 4648 ("foobar" → "Zm9vYmFy", etc.), numa ida e volta de um cenário seguro para URL (sem +///= a escapar), na rejeição de símbolos inválidos e numa ida e volta de todos os 256 bytes. Âmbito honesto: o codec e as ligações são distribuídos aqui; a interface do botão Partilhar do playground, o gráfico multissérie Plotly/D3 e o modo de comparação A/B são trabalhos posteriores.
  • Mínimos quadrados em lote de Gauss–Newton (o corretor diferencial em lote). Um novo src/batch_ls.rs acrescenta o núcleo de estimação em que assenta uma determinação de órbita em lote (ou qualquer ajuste de parâmetros): gauss_newton linearia um modelo h(x) fornecido pelo utilizador com um jacobiano de diferenças finitas centrais, forma e resolve as equações normais ponderadas (HᵀWH)·Δx = HᵀW·(z − h(x)) (reutilizando a inversa de matrizes testada) e itera até à convergência com ponderações por medição. Quatro testes ancoram-no: um ajuste de reta linear que atinge a solução exata de mínimos quadrados ponderados, um ajuste não linear a·exp(b·t) que recupera os parâmetros verdadeiros, uma multilateração de distâncias 3-D que recupera uma posição conhecida a partir de distâncias sem ruído (a variante da determinação de órbita) e a rejeição de entradas subdeterminadas/incompatíveis. Âmbito honesto: este é o motor genérico do corretor; o modelo de medição de distância/taxa de distância/azimute-elevação específico de órbitas, a matriz analítica de transição de estado de J2 e a validação com casos publicados são trabalhos posteriores.
  • Monitores de spoofing na camada RF (potência AGC e SQM). Um novo src/spoof_monitors.rs acrescenta dois detetores independentes de spoofing no front-end do recetor que complementam o monitor de spoofing temporal assistido por relógio em spoof: um monitor de potência AGC (combine_power_dbm soma incoerente de potências + AgcMonitor) que assinala o excesso de potência recebida que um transmissor de spoofing acrescenta para além de uma margem configurável em dB, e um monitor de qualidade do sinal (bpsk_autocorr autocorrelação triangular do código + SqmMonitor) que assinala o desequilíbrio do correlador Early-menos-Late que o multipercurso/meaconing/replay introduz. Quatro testes ancoram as formas fechadas exatas (3,01 dB para uma duplicação da potência, o agregado 10·log10(N), o R(τ)=1−|τ| triangular e o limiar de alerta Early/Late de 10 %). Âmbito honesto: o detetor completo de spoofing por paridade de consistência RAIM, a fusão multicamada das saídas dos monitores e a validação face a vetores de spoofing publicados da Spirent/ION GNSS+ são trabalhos posteriores.
  • Integrador numérico adaptativo de EDO. Um novo src/integrator.rs acrescenta a primeira peça de um propagador numérico (a propagação de órbitas do Kshana é, de resto, analítica SGP4/SDP4): um passo genérico de Runge–Kutta de quarta ordem (rk4_step) sobre qualquer sistema de primeira ordem y' = f(t, y) e um controlador adaptativo (integrate) que controla o erro local por duplicação do passo (extrapolação de Richardson) com o controlador de passo padrão 0.9·(tol/err)^(1/5) e a lógica de aceitação/rejeição. Seis testes ancoram-no em soluções exatas: a exponencial y' = y → e até < 1e-9, a redução do erro de ~16× por passo reduzido a metade que prova a convergência de quarta ordem, a conservação de energia/retorno do oscilador harmónico ao longo de um período completo e o controlador adaptativo a atingir uma tolerância apertada com passos variáveis. Âmbito honesto: este é o núcleo do integrador e o seu controlo de erro; as tabelas embebidas Dormand–Prince RK5(4)/RKF7(8) e o modelo hierárquico de forças orbitais (dois corpos + J2–J6 + arrasto + SRP + terceiro corpo) que fazem dele um NumericalPropagator são trabalhos posteriores.
  • Filtro de Kalman unscented (UKF, de pontos sigma). Um novo src/fusion/ukf.rs acrescenta o filtro de Kalman unscented (UKF) escalado (Julier & Uhlmann; Wan & van der Merwe) como estimador geral de n estados sobre funções de processo e de medição fornecidas pelo utilizador — o estimador de pontos sigma que um navegador GNSS/INS fortemente acoplado utiliza quando o modelo de pseudodistância/Doppler é fortemente não linear e o jacobiano de um EKF se degrada. Inclui a álgebra linear densa de suporte (fator de Cholesky para a dispersão dos pontos sigma, inversa de Gauss–Jordan para a covariância da inovação) e uma atualização P⁺ = P⁻ − K S Kᵀ sem forma de Joseph. Seis testes fixam-no, os principais a explorar a propriedade exata de que, para um modelo linear, a transformada unscented reproduz o filtro de Kalman com precisão numérica (predição, atualização e um ciclo completo de predição+atualização, todos comparados com um KF linear calculado à mão, além de uma verificação bayesiana analítica a 1-D da posteriori e das identidades de Cholesky/inversa). Âmbito honesto: este é o motor do estimador; o navegador GNSS/INS fortemente acoplado de 17 estados, o modelo de medição de pseudodistância/Doppler e o cenário de validação de interrupções continuam a ser trabalhos posteriores.
  • Níveis de proteção ARAIM de dupla constelação. Um novo araim_dual_raim alarga o RAIM Avançado de falha única (araim_raim) com o modo de falha de constelação inteira do ARAIM da UE / DO-316: a par das hipóteses sem falha e por satélite, cada constelação (identificada por satélite) contribui com uma hipótese que remove todos os seus satélites de uma só vez, com probabilidade a priori P_const (um novo DualFaultPriors { p_sat, p_const }). Cada hipótese acrescenta um termo à mesma soma de integridade MHSS, pelo que VPL/HPL são os menores limites cujo P_HMI total satisfaz o orçamento sobre falhas: sem falha + SV único + por constelação (a repartição de falsos alertas de Bonferroni faz-se por todas as N + C hipóteses). Com P_const = 0 o resultado é idêntico bit a bit a araim_raim; um utilizador de uma só constelação devolve None face à falha da sua própria constelação (não pode ser excluída) — que é exatamente a razão pela qual a cobertura de dupla constelação importa. Quatro testes cobrem a equivalência, o alargamento do nível de proteção, a indisponibilidade de constelação única e a validação das entradas, reutilizando a maquinaria existente de subsoluções de separação de soluções.
  • Precessão IAU 2006 (ângulos de Fukushima–Williams e matriz de desvio-precessão). Um novo src/precession.rs implementa a precessão IAU 2006 (P03; Capitaine, Wallace & Chapront 2003): os quatro ângulos de Fukushima–Williams (γ̄, φ̄, ψ̄, ε̄_A) como polinómios em séculos julianos TT (fw_angles) e a matriz de rotação de desvio-precessão de GCRS para média da data construída a partir deles através da construção SOFA iauFw2m (precession_matrix, com auxiliares gcrs_to_mod / mod_to_gcrs). Esta é a primeira peça de referencial inercial sobre a redução frames já existente, baseada em GMST. Oito testes validam-na face a âncoras de forma fechada — a obliquidade média de J2000 ε̄ = 84381.406″ = 23.4392794°, as constantes publicadas dos termos dos ângulos, a acumulação da precessão geral ψ̄ ≈ 5039.998″ ao longo de um século, a ortonormalidade da matriz e det = +1, o valor quase-identidade (apenas desvio do referencial) em J2000 e o ângulo de rotação líquida de ≈ 1.40°/século. Âmbito honesto (ROADMAP.md): apenas precessão — a nutação IAU 2000A de 678 termos, a cadeia completa TEME→GCRS e uma verificação cruzada numérica SOFA/ANISE de µas/<10 m são trabalhos posteriores.
  • Física de primeiros princípios de um acelerómetro de interferómetro de átomos frios (CAI). src/inertial/quantum_imu.rs modela um interferómetro atómico Mach–Zehnder de três impulsos a partir de primeiros princípios, em vez de uma folha de especificações: vetor de onda efetivo k_eff = 4π/λ, fase do interferómetro Φ = k_eff·a·T², ruído de projeção quântica (shot) σ_Φ = 1/(C·√N), sensibilidade à aceleração por disparo, decaimento do contraste C(t) = C₀·e^(−t/τ) e — o ponto essencial — CaiAccelerometer::q_va(), que deriva a PSD de aceleração branca que o AccelModel clássico já consome a partir do número de átomos, do tempo de interrogação e do contraste. O modelo cobre agora também o acoplamento de vibração — o termo dominante em dispositivos reais: a função de transferência aceleração→fase do interferómetro |H(ω)| = (4/ω²)sin²(ωT/2) (accel_transfer_function), a variância de fase da PSD branca σ_Φ² = k_eff²·S_a·T³/3 (vibration_phase_variance_white, com uma verificação cruzada numérica por integral de banda vibration_phase_variance_band), a projeção de característica 1 ao longo do feixe beam_axis_projection e CaiAccelerometer::vibration_phase_noise / vibration_limited_accel (esta última a reduzir-se ao patamar √(S_a/(3T)) independente de k_eff). Onze testes verificam a física à mão (Rb-87 k_eff ≈ 1.61×10⁷, Φ(1 g) ≈ 1.58×10⁴ rad, patamar de ruído de disparo de σ_a ≈ 0.13 µg/disparo vs patamar de vibração de ≈ 5,9 µg, as leis de escala 1/T², 1/√N e T³). Âmbito honesto em docs/QUANTUM.md: abrange o patamar do ruído de projeção e o regime limitado por vibração acima dele; o ruído de fase do laser, os sistemáticos de Coriolis e de desvio de luz e os cenários de validação PHARAO/CARIOQA continuam a ser trabalhos posteriores.
  • Acelerómetro quântico CAI integrado no cenário inercial. Um acelerómetro num cenário inercial de navegação estimada resolve-se agora para um novo ImuKind — Classical (o sensor existente de coeficientes de folha de especificações) ou QuantumCai quando transporta um bloco opcional [cai] (CaiCfg: comprimento de onda, separação dos impulsos, número de átomos, contraste, tempo de ciclo e uma vibration_psd opcional da plataforma). A PSD de passeio aleatório de velocidade q_va de um sensor quantum_cai é derivada da física do interferómetro — o patamar de ruído de disparo mais, quando é dada uma PSD de vibração, a contribuição limitada por vibração em quadratura — em vez de um coeficiente fornecido, e a proveniência da execução regista que o ruído é derivado da física. O campo cai é skip_serializing_if = "Option::is_none", pelo que os cenários existentes o omitem e são serializados de forma idêntica byte a byte (o hash do cenário não se altera). Cinco testes cobrem a derivação, a soma de vibração em quadratura, a seleção Classical/QuantumCai, a serialização estável do hash e uma execução completa conduzida por CAI.
  • Otimizador de projeto de constelações e geometria de ruas de cobertura. src/walker.rs ganha optimize_walker_design, um otimizador de grelha sem gradiente que pesquisa o espaço de projeto {planes × sats × inclination} e devolve o melhor projeto Walker sob um DesignObjective escolhido — MinSatellitesForCoverage, MaxCoverage ou MinWorstPdop — sobre a varredura de PDOP já validada (um teste confirma que devolve o vencedor por força bruta). Acrescem as formas fechadas analíticas das ruas de cobertura coverage_half_angle_rad (λ = arccos(Re/r·cos ε) − ε) e street_half_width_rad (cos c = cos λ / cos(π/s), Rider/Beste), verificadas à mão face à geometria de manual e a detetar a lacuna de sub-população. O solucionador completo de Rider de cobertura global com o mínimo de satélites, um globo 3-D no playground e uma verificação cruzada de DOP com uma ferramenta externa continuam a ser trabalhos posteriores.
  • Exportação de efemérides precisas SP3 a partir da CLI. Um cenário de órbita/constelação propagado pode agora ser escrito num ficheiro SP3-c: kshana <orbit.toml> --export-sp3 out.sp3, ou export_sp3 = true no cenário escreve automaticamente <scenario>.sp3 (api::export_sp3 / auto_export_sp3, OrbitClockScenario::to_sp3_string, epoch opcional). Um teste de ida e volta (tests/sp3_export_roundtrip.rs) propaga o instantâneo real gps-ops do Celestrak, exporta-o, volta a lê-lo e confirma que as posições ECEF recuperadas coincidem com a referência SGP4 ao longo de 24 h até < 0,5 m (bem dentro da tolerância de 10 m de nível TLE). O README documenta o papel de interoperabilidade (RINEX → RTKLIB/gLAB, SP3 → produtos Ginan/de órbita precisa).
  • Filtro de Kalman acoplado de relógio+posição (covariância entre blocos). src/fusion/coupled.rs CoupledPntFilter é um único filtro [pos, vel, phase, freq] empilhado (atualizações na forma de Joseph) cuja medição de pseudodistância ρ = g·pos + c·phase + noise acopla genuinamente os blocos de posição e de relógio — ao contrário dos dois filtros independentes de dois estados do pacote de fusão legado, que mantêm a covariância entre blocos exatamente nula. Validado: uma pseudodistância partilhada torna P[pos,phase] não nulo; duas geometrias distintas resolvem conjuntamente desvios injetados de posição+relógio que uma só distância não consegue separar; uma solução só de relógio afina a posição através da covariância cruzada (o ganho que filtros desacoplados não conseguem proporcionar); e o NEES de Monte-Carlo é consistente com χ²(4). Esta é a realização de 1 grau de liberdade (a dimensionalidade do pacote de fusão); a extensão 3-D de 8 estados e a ligação ao pacote executável ficam registadas como trabalhos posteriores.
  • Monitorização da saúde da consistência do filtro de Kalman (NIS/NEES). A atualização da covariância do filtro de relógio de dois estados está agora na forma estabilizada de Joseph `P⁺ = (I−KH)P(I−KH)ᵀ
    • KRKᵀ, which stays positive-semidefinite under extreme Q/R ratios (Cholesky-checked in CI at R=1e-26 / Q≈1e-30). A new src/filter_health.rsruns a Monte-Carlo consistency assessment (Bar-Shalom §5.4): pooled **NIS** (normalised innovation², target 1) and **NEES** (normalised estimation error², target 2) against 95% χ² bands, surfaced as afilter_health { nis_mean, nis_chi2_lower_95, nis_chi2_upper_95, nees_mean, nees_chi2_lower_95, nees_chi2_upper_95, consistent } block in the clock result JSON and as a green/amber card in the playground. A Q/R-mismatch sweep test proves the monitor flips to inconsistent when the process noise is mistuned by ×0.1–×10. Adds a general χ² quantile (detection::chi2_inv_cdf`, Wilson–Hilferty, table-checked).
  • docs/PROVENANCE.md — uma tabela de proveniência citável. Consolida todos os parâmetros de sensores (relógios, inercial, transferência de tempo), modelos físicos/algorítmicos (órbita, sistemas de tempo, referenciais, iono/tropo, integridade, deteção, jamming, Allan) e conjuntos de dados de validação (AIAA 2006-6753, gps-ops do Celestrak) com a sua fonte publicada — folha de especificações, artigo, ICD ou norma — e uma etiqueta de maturidade honesta (qualificado para voo / laboratório em terra / objetivo espacial em hardware de terra). Ligado a partir da introdução do README e da tabela de Documentação; complementa as cadeias provenance por execução que já viajam no JSON de resultados.
  • API tipada de cenários. O despacho faz-se agora sobre uma enumeração tipada ScenarioKind em vez de uma correspondência de cadeias kind em bruto (ScenarioKind::classify + despacho exaustivo), pelo que acrescentar um pacote é verificado em compilação. Novas superfícies tipadas a par do run_toml inalterado que devolve cadeias: run_scenario(src) -> Result<RunOutput, KshanaError> com uma taxonomia estruturada de erros (InvalidInput / NonConvergence / Unsupported / IoError, cada um com um kind_tag() estável); um trait Scenario e um ponto de extensão ExternalPack (o pacote jamming está ligado através dele como exemplo trabalhado); e introspeção list_scenario_kinds() (nome, descrição, campos obrigatórios/opcionais por tipo de cenário). As ligações Python e WebAssembly ganham list_kinds() e error_kind(). Documentado em docs/ARCHITECTURE.md.
  • Constelação GPS real + cobertura do envelope operacional. scenarios/orbit-sgp4-gps.toml distribui agora um instantâneo real gps-ops do Celestrak (2021-07-28, 30 satélites) em vez de TLE Walker sintéticos, com strict_checksum = true para que só carregue quando todas as somas de verificação dos TLE são válidas; scripts/fetch_tles.sh documenta a atualização reprodutível e o README credita a fonte de dados abertos. O novo tests/scenario_coverage.rs exercita cada pacote em ≥5 variantes de envelope, a afirmar saída finita/limitada, confirma que o patamar de flicker-FM degrada de forma mensurável a marcha livre de um relógio quando ativado (agora definido em três cenários distribuídos) e confirma que o filtro de fusão converge com um desvio realista não nulo do acelerómetro (dentro de 3× o caso de desvio zerado), fechando a lacuna de realismo «a fusão só funciona com desvios zerados». docs/VALIDATION.md ganha uma tabela de Envelope Operacional.
  • Simulação GNSS no domínio das medições (tipo de cenário gnss-sim). Um modelo direto ao nível da pseudodistância: por satélite visível sintetiza ρ = geometric range + c·δt_rx − c·δt_sv + I + T + noise + multipath e o Doppler em L1, com a ionosfera monofrequência de Klobuchar (IS-GPS-200 §20.3.3.5.2.5) e a troposfera zenital de Saastamoinen projetada pela função de mapeamento de Niell (1996) — expostas como blocos TOML [iono] e [tropo]. Os resíduos alimentam o RAIM instantâneo para HPL/VPL por época, e uma matriz JSON gnss_measurements[] transporta a pseudodistância, o Doppler, o C/N₀ e as correções iono/tropo de cada SV. Uma execução sem ruído reproduz a geometria + correções com precisão sub-milimétrica (teste de CI). Novos src/gnss_sim.rs e scenarios/gnss-sim-raim.toml.
  • Detetor estocástico de spoofing temporal (tipo de cenário spoof). O pacote de spoofing passa a executar um detetor real em vez de uma comparação determinística rampa-contra-limite: quatro formas de injeção (linear_ramp, step_jump, meaconing, replay), um teste de energia / Neyman–Pearson bilateral χ²₁ sobre a estatística do monitor assistido por relógio com o limiar definido a partir de um orçamento-alvo de falsos alarmes target_pfa e a probabilidade de deteção falhada P_md reportada tanto em forma fechada como por Monte-Carlo (mc_runs ensaios por hipótese — os dois concordam até alguns ×1/√N). A figura de mérito de Segurança é agora 1 − P_md na magnitude operacionalmente prejudicial (de especificação). Novos src/detection.rs (funções de cauda gaussiana, teste NP/de energia, P_fa/P_md por Monte-Carlo) e scenarios/spoof-meaconing.toml. Retrocompatível: um simples [attack] rate_ns_per_s continua a ser aceite como rampa linear.

Alterado#

  • Definição da FoM de Segurança (tipo de cenário spoof): do limite analítico de detetabilidade 1 − min_detectable/threshold para o 1 − P_md do detetor estocástico. O campo security do pacote de relógios continua a ser o indicador analítico mais rápido.

Acrescentado (continuação)#

  • Modelo de jamming RF (tipo de cenário jamming). Um modelo de interferência por orçamento de ligação que converte a potência e a geometria de um jammer em perda de seguimento por satélite: a razão jammer-sinal a partir da perda em espaço livre e do ganho da antena de receção por direção, o C/N₀ efetivo pela equação anti-jam padrão (ganho de processamento de despreading × o fator de separação espetral Q; Kaplan & Hegarty §9,4) e um limiar de seguimento configurável, avaliado sobre uma constelação Walker como figura de mérito availability_under_jamming. Novos src/jamming.rs e scenarios/jamming-demo.toml. O âmbito honesto (sem multipercurso, sombra do terreno, AGC nem anulação adaptativa) está documentado em docs/CAPABILITY.md / docs/VALIDATION.md.
  • Varrimento genérico N-D de parâmetros sobre qualquer tipo de cenário (sweep-nd). O varrimento N-D anterior era apenas do pacote de relógios. sweep-nd faz variar chaves TOML pontuadas de um cenário [base] sobre o produto cartesiano dos seus eixos, volta a despachar cada nó da grelha pelo caminho de execução normal e lê uma ou mais métricas do resultado por caminho JSON pontuado — pelo que funciona para todos os pacotes (inercial, gnss-ins, integridade, spoof, …) sem se acoplar ao tipo Rust de cada pacote. Os nós da grelha são avaliados em paralelo por fios do SO em alvos nativos (sem dependências acrescentadas); o wasm recorre ao modo sequencial. Determinístico e por linhas, independentemente do número de fios. Novo exemplo scenarios/sweep-nd-inertial.toml.
  • Modelo determinístico de erros de IMU configurável em TOML no pacote gnss-ins. A cadeia de erros strapdown de três eixos (fator de escala, desalinhamento, sensibilidade a g, quantização, rampa de taxa; IEEE Std 952-1997 §A.2, Groves 2013 §4,3) é agora acessível por sensor a partir de um ficheiro de cenário através de um bloco opcional [imu_*.error_model], por cima dos desvios constantes de arranque. Omitir o bloco deixa cada sensor como uma fonte pura de desvio constante, pelo que as execuções gnss-ins existentes não se alteram. Isto liga o modelo de erros, antes só de biblioteca, a um pacote executável e a uma figura de mérito.

0.10.0 - 2026-06-04#

Alterado#

  • Validação com dados reais. O analisador multi-GNSS de navegação RINEX, o propagador RK4 do GLONASS e o leitor SP3 são agora exercitados com ficheiros IGS/DLR genuínos (um ficheiro real de navegação difundida mista RINEX 3 e um produto de órbita IGS SP3-c), e não apenas com amostras de autoria própria — a afirmar conjuntos de satélites não vazios e posições ECEF finitas e fisicamente dimensionadas. Os ficheiros de apoio servem apenas para testes (excluídos da crate publicada); ver tests/fixtures/igs/NOTICE.
  • RAIM sobre geometria real de órbitas de referência. Os núcleos de nível de proteção instantâneo, de separação de soluções (MHSS) e ARAIM estão agora validados face à geometria real de órbitas precisas IGS (SP3), e não apenas a constelações sintéticas: a geometria da linha de visada é construída a partir da primeira época SP3 numa estação terrestre real, e os testes afirmam níveis de proteção de nível métrico e disponíveis para APV-I, que um desvio de pseudodistância de 60 m dispara o monitor χ², que a separação de soluções identifica o satélite com falha e que os níveis do ARAIM satisfazem o P_HMI atribuído. Fecha a lacuna de validação só em geometria sintética (a paridade com o gLAB no domínio do recetor ao longo de um arco RINEX completo continua a ser um item do roteiro — precisa de uma solução de pseudodistância).

Adicionado#

  • Intervalos de confiança por nó para o varrimento N-D de parâmetros (sweep::nd_sweep_ensemble). Cada nó da grelha do varrimento cartesiano N-dimensional pode agora ser avaliado como um ensemble de Monte-Carlo de sementes, reportando a média da métrica, percentis e um IC de 95 % por bootstrap de percentis por nó (para ambos os relógios) — um varrimento estatisticamente honesto em vez de uma só extração por nó. Reutiliza a maquinaria de ensemble/bootstrap (metric_stat); determinístico; runs = 1 reduz-se exatamente ao nd_sweep de semente única. (A generalização do varrimento a todos os pacotes, entrelaçada com a refatoração do Scenario tipado, e a execução paralela continuam por fazer.)
  • Validação cruzada NaveGo do pipeline de ruído de IMU (tests/navego_imu_crossval.rs). Uma verificação cruzada externa com o NaveGo (a toolbox INS/GNSS de código aberto de R. Gonzalez): reproduz a ida e volta sintética de navego_example_allan.m no seu perfil de referência publicado do Microstrain 3DM-GX3-35, confirmando que o nosso estimador ADEV sobreposto recupera os coeficientes de passeio aleatório de velocidade e de ângulo do NaveGo (ADEV(1 s) = σ·√dt) com menos de 5 % de diferença, com o declive esperado de −1/2 do ruído branco. (O registo STIM300 .mat de 40 MB não é ingerido — está condicionado por um formato binário.)
  • Atualização GNSS/INS fortemente acoplada (pseudodistância). GnssInsEkf::update_tightly_coupled (e o invólucro ClosedLoopInsGnss::fuse_tightly_coupled) implementam a medição no domínio da distância que antes era um esboço: a inovação é a distância prevista da posição INS a cada satélite face à pseudodistância medida, com um jacobiano de linha de visada sobre o erro de posição. Como cada satélite é uma medição escalar, o filtro continua a corrigir com menos de quatro satélites — onde não existe uma solução PVT fracamente acoplada. Cinco testes cobrem a anulação com quatro satélites, a correção com dois satélites (sem PVT possível), a observabilidade ao longo da linha de visada com um único satélite e a validação das entradas. Apenas pseudodistância; a fase da portadora e um estado explícito de relógio do recetor continuam no roteiro. A funcionalidade cargo não utilizada tight_coupling (que condicionava o antigo esboço de erro) foi removida.
  • Pacote de cenários GNSS/INS fracamente acoplado (kind = "gnss-ins", src/fusion/pack.rs). Liga o navegador strapdown de três eixos e o EKF de estados de erro de 15 estados (closed_loop / gnss_ins_ekf) a um cenário executável com uma figura de mérito — o EKF disciplina a mecanização face a soluções GNSS ruidosas enquanto há cobertura e depois segue em marcha livre durante a interrupção, substituindo o reinício por ajuste à referência do antigo pacote escalar de 1 grau de liberdade por fusão genuína. O resultado reporta a série de erro horizontal fundida, a FoM de posição pontuada (disponibilidade / RMS na interrupção / holdover) e o RMS do INS livre em malha aberta para comparação; um par de IMU quântica/clássica difere apenas no desvio verdadeiro. Despachado a partir do ponto de entrada CLI/Python/wasm com um exemplo scenarios/gnss-ins.toml. Enquadramento honesto: apenas fracamente acoplado, uma trajetória determinística, e o erro fundido na interrupção é limitado por um patamar imposto pelo erro de atitude na transferência (pelo que não se afirma que escale com o desvio) — as conclusões robustas são que a fusão supera a navegação estimada sem assistência para um sensor com desvio e que um sensor de menor desvio tem a melhor marcha livre sem assistência.
  • Projeto de constelações sobre o núcleo SGP4 validado (src/walker.rs). Um novo módulo walker emite um padrão Walker-delta projetado (i: T/P/F) como elementos médios SGP4, de modo que a constelação sintética se propaga pelo mesmo caminho SGP4 validado a 4,12 mm face aos vetores AIAA 2006-6753 — e não pelo gerador kepleriano analítico. Por cima: pdop_sweep tabela a cobertura e o PDOP mediano/pior sobre uma grelha de projeto {planes × sats × inclination}, e coverage_revisit reporta a fração de cobertura e as lacunas de revisita (pior/média) num ponto do solo. Validado pelas monotonias físicas a que um compromisso tem de obedecer (mais satélites ⇒ maior cobertura, menor PDOP, revisita mais curta). Em separado, um instantâneo TLE gps-ops real do Celestrak (2021-07-28, 30 satélites GPS operacionais) é acrescentado como ficheiro de apoio apenas de testes e o caminho de geometria TLE real → SGP4 → ECEF é validado face a ele (toda a camada MEO a menos de 1 %, nove satélites todos à vista com PDOP 1,64), a par dos caminhos de dados reais SP3 e RINEX existentes.
  • Graus de liberdade efetivos específicos do tipo de ruído para os intervalos de confiança de Allan. allan::edf_overlapping_adev implementa as formas fechadas da Tabela 5 do NIST SP 1065 (o conjunto simples do Stable32) para os cinco tipos canónicos de ruído em lei de potência — PM branco/flicker, FM branco/flicker, FM de passeio aleatório — substituindo a contagem conservadora sem sobreposição como graus de liberdade do χ². Uma nova enumeração PowerLawNoise e classify_power_law identificam o tipo dominante a partir do declive do desvio de Allan modificado do registo (o MDEV separa o PM branco do PM flicker onde o ADEV não consegue), e overlapping_adev_curve anexa agora o tipo de ruído identificado, o seu edf e uma banda de confiança de 95 % a cada ponto da curva ADEV exportada (AdevPoint ganha noise/edf/ci_lo/ci_hi, aditivos com valores predefinidos serde). Validado de duas formas: as cinco fórmulas coincidem com valores avaliados à mão até 1e-12, e um ensemble de Monte-Carlo de 4 000 registos de FM branco confirma que a fórmula prevê o edf de qui-quadrado real do estimador a menos de 20 % (e que supera substancialmente a contagem conservadora). Oito novos testes.
  • Modelo estocástico de transferência de tempo bidirecional. timetransfer::TwoWayLink substitui o amostrador apenas de ruído branco por um modelo com fundamento físico: o atraso de percurso recíproco (de modo comum) cancela-se na estimativa (m_AB - m_BA)/2 (two_way_offset_estimate, pelo que duas medições unidirecionais independentes fazem a média até 1/sqrt(2)), e o resíduo é o atraso diferencial não recíproco — modelado como um processo colorido de FM branco + FM de passeio aleatório (o ClockModel validado), dando à série de erro de sincronização uma assinatura de Allan realista (sigma_y^2(tau) = q_rw*tau/3) em vez de ruído branco plano. LinkCfg ganha q_wf_s/q_rw_s (valor predefinido serde 0 ⇒ o comportamento antigo apenas de ruído branco, bit a bit), a FoM da ligação reporta adev_tau0 (o desvio de Allan do modelo no passo de base) e o cenário/CLI timetransfer expõem-no. FoM de referência fixada de novo. Seis testes deduzidos à mão (cancelamento de modo comum, o ganho bidirecional sqrt(2), a lei RWFM tau/3 através do próprio step() da ligação, equivalência com o comportamento antigo em q=0, determinismo e exposição da FoM de ponta a ponta).
  • Paridade numérica com o Stable32 para os estimadores da família de Allan (NBS14). tests/allan_reference.rs valida os estimadores ADEV sobreposto, ADEV modificado, desvio de tempo e Hadamard sobreposto face aos desvios de referência do Stable32 para o conjunto de dados canónico NBS14 (W. J. Riley, Handbook of Frequency Stability Analysis, NIST SP 1065, ~p.107) em tau = 1, 2 com uma tolerância relativa de 1e-4 — concordância real de ~1e-6. Isto fixa a matemática dos estimadores face à implementação de referência de facto, e não apenas face à própria autoconsistência analítica dos estimadores. Só são usados os números públicos de referência; nenhum código de terceiros.
  • Diagrama vertical de integridade de Stanford exportado pelo cenário integrity. O tipo de cenário executável integrity exporta agora um diagrama vertical Stanford(-ESA) a par do mapa de disponibilidade HPL/VPL: em cada época protegida, uma extração reproduzível e com semente de erro de distância sem falha é mapeada através da geometria para um erro de posição vertical real e classificada face ao VPL e ao limite de alerta vertical (Available / System-Unavailable / Misleading / Hazardously-Misleading). O diagrama (pontos por época + contagens por região) é transportado no JSON de resultados e as contagens de eventos de integridade / HMI no resumo da CLI, pelo que o classificador de Stanford — antes só de biblioteca — fica acessível de ponta a ponta. IntegrityScenario ganha um campo seed (predefinição 0) que controla a realização do erro; o próprio mapa de disponibilidade continua a depender apenas da geometria e é independente da semente.
  • Orçamento de risco de integridade ARAIM (P_HMI) para os níveis de proteção. raim::araim_raim deriva os níveis de proteção horizontal e vertical a partir de um orçamento explícito de risco de integridade, em vez de um multiplicador fixo K_md: para a solução com todos à vista e para cada subsolução de exclusão de um só satélite constrói o (prior, detection threshold, σ) por modo em cada eixo, e depois araim_protection_level resolve o menor PL cuja probabilidade somada de informação perigosamente enganosa (araim_integrity_risk, P_HMI = Σ_k p_fault,k · Q((PL − T_k)/σ_k), Blanch et al. Baseline ARAIM) satisfaz o P_HMI atribuído. O resultado reporta o risco de integridade que os níveis realmente atingem, de modo que um utilizador possa trocar integridade por limite de alerta de forma explícita. Seis testes deduzidos à mão (formas fechadas de modo único sem falha e com limiar, somatório/monotonia multimodo, proteção sem falha de ponta a ponta com um orçamento 10⁵× mais apertado a subir o PL, deteção/identificação de falhas e o patamar de redundância de seis satélites). O MHSS de falha única é a linha de base do ARAIM; falhas simultâneas em subconjuntos de vários SV, o modo de falha de constelação inteira e a validação com o conjunto de dados de referência do gLAB são extensões documentadas.
  • Compensação de coning/sculling a duas velocidades para a mecanização strapdown. inertial::mechanization::coning_sculling_compensate retira os termos de coning (atitude) e de rotação+sculling (velocidade) de alta taxa dos incrementos de IMU ordenados em subintervalos de uma atualização grosseira, de modo que um NavState::step_increments de taxa moderada reproduza o movimento retificado por vibração que um passo grosseiro sobre as somas em bruto não capta. Um teste de validação aplica um ambiente de coning+sculling de 10 Hz durante 60 s e compara a referência de taxa fina, a integração grosseira ingénua e a integração grosseira com compensação: a compensação reduz o erro de posição em ~18× (metros de deriva ingénua → sub-decímetro), confirmando que os termos de coning/sculling são determinantes. Um alias de tipo ScalarErrorBudget dá ao antigo AccelModel de 1 grau de liberdade o nome que lhe corresponde, distinto do navegador de três eixos NavState.
  • Analisador de ficheiros de observação RINEX. O novo módulo rinex_obs lê o ficheiro de observação RINEX 3.0x / 4,00 — as medições reais do recetor — completando o par RINEX a par do analisador existente de mensagens de navegação. parse_obs descodifica o cabeçalho (versão/tipo, as listas SYS / # / OBS TYPES por sistema com linhas de continuação, posição aproximada, intervalo, instante da primeira observação) e os registos por satélite de cada época: pseudodistância, fase da portadora, Doppler e intensidade do sinal, indexados pelo respetivo código de observação RINEX 3 (C1C, L1C, …) com os indicadores de perda de bloqueio (LLI) e de intensidade do sinal (SSI), mantendo um campo em branco como ausente e não como zero. Âmbito honesto: esta é a ingestão de um formato normalizado (entra um registo real de observações RTKLIB/gLAB/estação IGS, saem medições tipadas), não um motor de posicionamento — aqui não há solução de pseudodistância, PPP nem RTK.
  • Escritor CCSDS OEM (Orbit Ephemeris Message). O novo módulo oem exporta uma constelação propagada como mensagem CCSDS 502.0-B OEM 2,0 válida — o formato KVN de efemérides que o GMAT, o Orekit, o STK e a maioria das ferramentas de dinâmica de voo ingerem. OemFile::from_propagators amostra o estado inercial (TEME) de cada satélite — posição e velocidade, retiradas diretamente do propagador sem rotação para referencial fixo à Terra, ao contrário da exportação SP3 — numa grelha temporal, e OemFile::to_oem_string serializa o cabeçalho CCSDS_OEM_VERS/CREATION_DATE/ ORIGINATOR mais um segmento META_START … META_STOP por satélite (OBJECT_NAME/OBJECT_ID/CENTER_NAME/REF_FRAME = TEME/TIME_SYSTEM = GPS/ START_TIME/STOP_TIME) seguido das suas linhas epoch X Y Z X_DOT Y_DOT Z_DOT (km, km/s). O CREATION_DATE é fornecido por quem chama, nunca a hora do relógio de parede, pelo que a saída é idêntica byte a byte entre execuções (o contrato de reprodutibilidade). Este é o equivalente para efemérides de veículos espaciais da exportação GNSS SP3: uma órbita do Kshana pode agora ser entregue a uma ferramenta de dinâmica de voo num formato normalizado.
  • Efemérides precisas SP3 como fonte de propagação. Sp3File::interpolator constrói um Sp3Interpolator por satélite que preenche a posição entre as épocas SP3 tabeladas com um polinómio de Lagrange de 9.ª ordem (prática padrão do IGS) e a roda para o referencial TEME partilhado, exposto como Propagator::Sp3Precise. Um ficheiro de órbitas precisas de um centro de análise IGS pode agora alimentar o mesmo pipeline de geometria/visibilidade/integridade que os propagadores difundidos e analíticos. Ida e volta validada: uma órbita kepleriana escrita em SP3 e relida através do interpolador coincide com a original a menos de um metro nos nós e < 100 m a meio do intervalo. A interpolação do relógio é o passo seguinte.
  • Efemérides difundidas do GLONASS (completa a navegação RINEX multi-GNSS). Novo módulo glonass: o GLONASS não difunde elementos keplerianos mas um vetor de estado fixo à Terra PZ-90 (posição, velocidade, aceleração luni-solar). parse_glonass_nav lê os registos RINEX 3 R, e a posição do satélite em qualquer instante obtém-se por integração de Runge–Kutta de 4.ª ordem das equações de movimento do ICD do GLONASS (gravidade central + J2 + termos de Coriolis/centrífugo da rotação da Terra + a aceleração difundida). Exposto como Propagator::Glonass, pelo que os satélites GLONASS fluem pelo pipeline de constelação/visibilidade/integridade a par dos sistemas keplerianos; um único bloco de constelação rinex pode agora misturar GPS, Galileo, QZSS, BeiDou e GLONASS.
  • Navegação RINEX multi-GNSS (GPS, Galileo, QZSS, BeiDou). O analisador de navegação RINEX 3 descodifica agora registos Galileo (E), QZSS (J) e BeiDou (C, MEO/IGSO) a par do GPS (G) — partilham a disposição kepleriana e o algoritmo do utilizador — cada um avaliado com a sua própria constante gravitacional e taxa de rotação da Terra (μ de Galileo/BeiDou, Ω̇ₑ de BeiDou). Um ficheiro de constelações mistas produz todos eles, a fluir pelo pipeline de constelação/visibilidade/integridade como Propagator::Rinex. Os satélites geoestacionários BeiDou usam uma rotação de coordenadas diferente e são ignorados até haver um ficheiro de referência face ao qual validar. O percorredor de registos usa contagens de linhas por sistema, corrigindo um erro latente em que os registos GLONASS/SBAS de quatro linhas eram ignorados como se tivessem oito linhas. O GLONASS (um modelo de vetor de estado) é o passo seguinte.
  • Leitor e escritor de efemérides precisas SP3-c/d. O novo módulo sp3 analisa ficheiros de órbitas precisas SP3 de centros de análise IGS (parse_sp3) — o produto pós-processado de posição/relógio ECEF que os motores PPP (Ginan, RTKLIB, gLAB) tratam como referência — para um Sp3File estruturado (cabeçalho, grelha de épocas, posição por satélite km→m, relógio µs e velocidade dm/s→m/s para produtos V), preservando os valores sentinela SP3 de valor inválido. O sentido inverso também está coberto: Sp3File::from_propagators constrói um SP3 a partir de uma constelação propagada (TEME→ECEF por época) e to_sp3_string serializa-o, pelo que as órbitas do Kshana podem ser exportadas no formato que as ferramentas PPP externas ingerem — a ida e volta leitura↔escrita. A interpolação de épocas e uma fonte de propagador SP3 são o passo seguinte.
  • Efemérides difundidas RINEX como fonte de constelação executável. Uma constelação aceita agora um bloco rinex inline (texto de navegação GPS RINEX 3) a par da opção tle existente, de modo que um ficheiro real de difusão conduza um cenário de ponta a ponta a partir da CLI, do Python ou do playground no navegador — entra RINEX, sai geometria PNT. O novo scenarios/orbit-rinex.toml demonstra a disponibilidade GNSS e o DOP a partir de oito satélites GPS construídos diretamente a partir de registos difundidos. (Apenas GPS LNAV; multi-GNSS e SP3 são o passo seguinte.)
  • Efemérides difundidas RINEX como fonte de propagação. Um RinexEphemeris analisado converte-se agora num orbit::Propagator (Propagator::Rinex): a posição é a órbita difundida IS-GPS-200 rodada de ECEF para o referencial inercial TEME partilhado (sv_position_teme, com tempo GPS→UT1 correto quanto aos segundos intercalares), a velocidade por diferença finita central e o período orbital kepleriano. Dados difundidos GPS reais podem agora conduzir o mesmo pipeline de geometria, visibilidade e integridade (RAIM) que os propagadores analíticos SGP4/keplerianos. (Ainda não exposto como tipo de cenário de ficheiro RINEX — isso e multi-GNSS/SP3 são o passo seguinte.)

0.9.2 - 2026-06-03#

Adicionado#

  • DOI de arquivo. As versões são agora depositadas no Zenodo e recebem um DOI citável.

0.9.1 - 2026-06-03#

Alterado#

  • Documentação. O README foi renovado para um nível institucional: uma visão geral de Capacidades de toda a pilha v0.9.0, uma secção de Versões e lançamentos, um cabeçalho limpo com a nova marca e uma linha de estado concisa. Sem alterações ao motor.

0.9.0 - 2026-06-03#

Esta versão acrescenta três áreas substanciais de capacidade sobre o substrato SGP4 0.8.0: um genuíno INS strapdown de três eixos, um EKF de estados de erro GNSS/INS fracamente acoplado com realimentação em malha fechada, RAIM genuíno instantâneo e de separação de soluções (ao estilo ARAIM) com HPL/VPL e um cenário integrity executável, e o primeiro passo da interoperabilidade de formatos GNSS (ingestão de efemérides GPS RINEX-3).

Adicionado#

  • Analisador de mensagens de navegação GPS RINEX 3 (src/rinex.rs). Primeiro passo rumo à interoperabilidade de formatos GNSS: parse_nav lê um ficheiro de navegação RINEX 3.x e descodifica cada registo de efemérides difundidas GPS (G) — o bloco de oito linhas SV/época + BROADCAST ORBIT — para um RinexEphemeris de elementos keplerianos e correções de relógio, com nomes de campos e unidades segundo o IS-GPS-200. Trata o formato de vírgula flutuante com expoente D do Fortran (parse_d) e a disposição de colunas de largura fixa; os registos de sistemas que não o GPS são ignorados, não rejeitados, pelo que um ficheiro misto continua a produzir as suas efemérides GPS. Quatro testes: análise de expoentes D (incluindo brancos e erros), um registo completo descodificado face a valores de campo conhecidos com uma verificação de sanidade do semieixo maior GPS (√A² ≈ 26 560 km), omissão de sistemas que não o GPS e o caso de ficheiro vazio.
  • Efemérides difundidas GPS → posição ECEF (src/rinex.rs). RinexEphemeris::sv_position_ecef(t_tow) avalia a posição do satélite fixa à Terra a partir das efemérides analisadas através do algoritmo do utilizador IS-GPS-200 §20.3.3.4.3.1: solução de Newton da equação de Kepler para a anomalia excêntrica, as correções de segundo harmónico do argumento de latitude / raio / inclinação e a rotação para ECEF tendo em conta a rotação da Terra desde a época de referência (com o μ e o Ω̇ₑ do GPS impostos pela especificação, e uma dobragem tk da mudança de semana). Três testes: o raio geocêntrico mantém-se na banda GPS (≈ 26 560 km), a velocidade fixa à Terra é de ~3,9 km/s, e avaliar com uma semana completa de distância reproduz a mesma posição.
  • Desvio do relógio do SV GPS com a correção relativista (src/rinex.rs). RinexEphemeris::sv_clock_bias_s(t_tow) avalia o polinómio de relógio difundido af0 + af1·Δt + af2·Δt² em torno de Toc mais o termo relativista de excentricidade F·e·√A·sin Ek (IS-GPS-200 §20.3.3.3.3.1). Um novo EpochUtc::gps_time_of_week converte a época de calendário do registo em tempo-da-semana GPS por aritmética de dias julianos a partir da época GPS (1980-01-06), e a resolução de Kepler é partilhada com a avaliação da posição. Testes: o tempo-da-semana GPS para um domingo/terça-feira/sábado (fronteiras de semana) e o desvio de relógio ser dominado por af0 com um termo relativista presente e limitado. O atraso de grupo L1 TGD é exposto mas deliberadamente não incorporado. Âmbito honesto: uma fonte Propagator, Galileo/BeiDou/GLONASS e SP3 continuam a ser passos seguintes. (docs/CAPABILITY.md atualizado de acordo.)
  • Tipo de cenário integrity executável pelo utilizador (scenarios/integrity-raim.toml). A capacidade de disponibilidade RAIM é agora acessível a partir da CLI/TOML como todos os outros pacotes: kind = "integrity" analisa um IntegrityScenario (órbita do utilizador, uma ou mais constelações GNSS, máscara de elevação e a configuração de integridade (sigma, P_fa, P_md, AL_H, AL_V)), executa constellation_raim_availability e emite o mapa de disponibilidade HPL/VPL por época em JSON, mais um SVG autónomo — níveis de proteção ao longo do tempo face aos limites de alerta, com uma faixa de disponibilidade verde/vermelha. kshana scenarios/integrity-raim.toml escreve o JSON, o gráfico e um relatório HTML. O cenário incluído (Walker de 24 satélites, medição de distâncias bifrequência de 1 m, limites APV-I) reporta ~95 % de disponibilidade; documenta que o RAIM monofrequência não satisfaz o limite vertical APV-I com uma só constelação, razão pela qual a orientação vertical usa SBAS/bifrequência/ARAIM. Os testes cobrem o despacho, o JSON do mapa de disponibilidade e o SVG.
  • Disponibilidade RAIM executável sobre uma constelação (src/raim.rs). O módulo de integridade não tinha quem o chamasse — constellation_raim_availability torna-o um ponto de entrada genuíno de ponta a ponta: em cada época numa grelha temporal propaga os satélites visíveis (os mesmos Propagator SGP4/keplerianos que o motor usa), calcula os níveis de proteção sem falha e avalia a disponibilidade face aos limites de alerta horizontal/vertical, devolvendo um RaimAvailabilityReport serializável por serde (n_visible/HPL/VPL/available por época mais a fração de disponibilidade). Um RaimConfig agrupa (sigma, P_fa, P_md, AL_H, AL_V) e o raim_availability_epoch por época é exposto para quem resolve a sua própria geometria. Três testes: uma época avaliada como disponível sob limites APV-I numa geometria de dez satélites, tornada indisponível por um limite impossivelmente apertado, e níveis None abaixo de cinco satélites; e uma execução de ponta a ponta sobre uma constelação Walker de 24 satélites que produz um mapa de disponibilidade finito e se serializa. (Seis satélites — o patamar de redundância do RAIM residual — honestamente não satisfazem o APV-I mesmo com medição de distâncias de 1 m; a disponibilidade APV-I precisa da geometria mais densa que o teste usa.)
  • Acumulador do diagrama de integridade de Stanford(-ESA) (src/raim.rs). A forma padrão de resumir um monitor de integridade ao longo de muitas épocas: representa o erro de posição real (x) face ao nível de proteção (y) e classifica cada época, pela diagonal y = x e pelo limite de alerta, em Available (o PL limita o erro, dentro do AL), SystemUnavailable (o PL limita o erro mas excede o AL — seguro, inutilizável), MisleadingInformation (PL < erro ≤ AL) ou HazardouslyMisleadingInformation (PL < erro e erro > AL — a falha insegura). classify_stanford é o classificador puro; StanfordDiagram acumula pontos (error, PL) face a um limite de alerta fixo, expondo contagens por região, disponibilidade, totais de eventos de integridade e pontos serializáveis por serde para gráficos/exportação JSON. Quatro testes: todas as regiões (incluindo a fronteira limitada error == PL), acumulação de contagens/disponibilidade e ida e volta em JSON. Esta é a superfície de reporte dos níveis de proteção RAIM; ligá-la ao cenário de constelação e validá-la face a um conjunto de dados público continuam a ser itens do roteiro.
  • RAIM de separação de soluções (ao estilo ARAIM) (src/raim.rs). Um monitor de integridade de múltiplas hipóteses a par do snapshot_raim qui-quadrado de resíduos/paridade existente. Para a solução de mínimos quadrados com todos à vista e para cada subsolução de exclusão de um só satélite, forma a separação Δ_k = x_k − x₀ — gaussiana de média nula sem falha, com covariância Cov(x_k) − Cov(x₀) (a identidade dos estimadores aninhados, válida porque a solução com todos à vista é BLUE) — e assim deteta uma falha e identifica o satélite com falha (aquele cuja exclusão dá a maior separação normalizada). Os níveis de proteção horizontal/vertical seguem a alocação MHSS padrão PL = max(K_md·σ₀, max_k[K_fa·σ_ss,k + K_md·σ_k]), com K_fa = Φ⁻¹(1−P_fa/2), K_md = Φ⁻¹(1−P_md). Novos normal_cdf/normal_quantile sem dependências, construídos sobre a função gama incompleta regularizada já existente no módulo (erf(x) = P(½,x²)). Quatro testes deduzidos à mão: a CDF normal / quantil face a valores de manual (Φ(1,95996)=0,975, a cauda de 1e-7 = 5,1993, simetria); uma geometria sem falha que não dá alarme e produz HPL/VPL finitos e positivos; um desvio de 60 σ num só satélite que é detetado e corretamente identificado (excluded_sv == 2); e o patamar de redundância de seis satélites. Fecha a lacuna P0 da auditoria «integridade tautológica — sem RAIM/HPL/VPL reais» do lado do algoritmo; a validação com conjuntos de dados do gLAB e o acumulador do diagrama de Stanford continuam a ser itens do roteiro.
  • Integração GNSS/INS em malha fechada (src/fusion/closed_loop.rs). ClosedLoopInsGnss liga o núcleo EKF de estados de erro à mecanização strapdown de três eixos: cada amostra de IMU é corrigida pelas estimativas de desvio em curso, mecanizada para a frente, e a covariância do EKF é propagada no tempo com o contexto de navegação correspondente; cada solução de posição/velocidade GNSS forma a inovação INS−GNSS e realimenta a solução com o erro de posição, velocidade, atitude (ψ, como rotação em quaterniões) e os desvios do acelerómetro/giroscópio estimados, repondo a média do estado de erro. Realimentar a atitude (e não apenas os desvios) é necessário para a estabilidade — a inclinação e o desvio do acelerómetro formam um par acoplado, pelo que corrigir um sem o outro diverge. O INS e o GNSS são comparados num referencial local de plano tangente NED usando os próprios raios de curvatura da mecanização (novo mechanization::radii_of_curvature; NavState::omega_ie_n/omega_en_n expostos). Esta é a substituição honesta do reinício por ajuste à referência do pacote híbrido. Três testes: uma malha fechada a anular um erro de posição injetado de 8 m / −5 m até <0,1 m; uma solução assistida que se mantém limitada a metros (<6 m) numa trajetória de condução enquanto um INS em marcha livre diverge para além de 100 m; e o teste de referência do marco — o RMS de posição de Monte-Carlo da solução fundida durante uma interrupção GNSS de 60 s supera um estimador de navegação estimada em malha aberta sem assistência por >2× (≈4× entre sementes). Limitação honesta documentada no módulo: em modo fracamente acoplado, o desvio do acelerómetro e a inclinação só são fracamente separáveis (ambos se acoplam através da gravidade), pelo que o valor entregue é o estado limitado e corrigido e uma entrada limpa na interrupção — não uma calibração inercial precisa; dinâmicas mais ricas e a extensão fortemente acoplada continuam a ser itens do roteiro.
  • Núcleo EKF de estados de erro GNSS/INS fracamente acoplado (src/fusion/gnss_ins_ekf.rs). Um filtro de Kalman estendido de estados de erro de 15 estados — δx = [δp, δv, ψ, b_a, b_g] — com a dinâmica de erros strapdown de Groves 2013 §14,2 (acoplamento força específica/inclinação, Coriolis, projeção do desvio do corpo para a navegação, modelos de desvio de Gauss–Markov), uma transição discreta de primeira ordem Φ = I + F·dt e uma atualização de medição fracamente acoplada de posição+velocidade (H = [I₃ 0 0 0 0; 0 I₃ 0 0 0]) na forma de Joseph. Álgebra linear densa sem dependências (inversa de Gauss–Jordan, atualização da covariância de Joseph). Uma funcionalidade cargo tight_coupling condiciona uma atualização de pseudodistância/Doppler documentada e ainda não implementada. 7 testes com resultados esperados deduzidos à mão: a identidade de assimetria/produto vetorial, uma inversa 3×3 verificada, a covariância a manter-se simétrica/PSD na predição (e a incerteza de posição a crescer sem assistência), uma solução de posição a reduzir a covariância da posição, a recuperação exata de um erro de posição conhecido com o ganho de Kalman analítico P/(P+R) e correções menores com maior ruído de medição. Este é o núcleo que substituirá o reinício por ajuste à referência em malha aberta do pacote híbrido por realimentação em malha fechada (ligação ao pacote + validação NaveGo a seguir).
  • Modelo determinístico de erros de IMU para o navegador strapdown de 3 eixos (src/inertial/imu_errors.rs). ImuErrorModel distorce um par (ω, f) verdadeiro no referencial do corpo num par medido através de cinco categorias sistemáticas (IEEE Std 952-1997 §A.2; Groves 2013 §4,3, Tabela 4,1): fator de escala (erro de ganho em ppm por eixo), desalinhamento / acoplamento cruzado (não ortogonalidade fora da diagonal da tríade), sensibilidade a g (um desvio da taxa do giroscópio proporcional à força específica), quantização (arredondamento ao LSB de saída) e rampa de taxa (uma deriva linear no tempo — a terceira região de Allan), mais um desvio constante de arranque. Todos os termos têm zero como predefinição, pelo que ImuErrorModel::ideal() é uma passagem transparente e os cenários existentes não são afetados. Cada fonte de erro tem um teste de isolamento (escala linear a <0,01 %, eixo cruzado do desalinhamento acima do patamar VRW, desvio de sensibilidade a g, grelha LSB, rampa linear), e um teste de ponta a ponta conduz um erro de navegação através da mecanização a partir de uma IMU distorcida. Não modelados: erro de retificação por vibração, deriva por gradiente de temperatura. (O pacote de cenários inertial distribuído continua a executar o antigo orçamento escalar de 1 grau de liberdade; este modelo alimenta a biblioteca de 3 eixos.)
  • Compensação de coning e sculling para o integrador strapdown. O caminho de atitude acrescenta o coning_increment de duas amostras (½ Δθ_prev × Δθ_cur); verifica-se que uma integração a taxa grosseira (30 Hz, 5 amostras/ciclo) de um ambiente de coning de 5 Hz acompanha a referência de taxa fina ≥ 3× melhor com a correção do que com a soma ingénua de incrementos. O caminho de velocidade acrescenta sculling_increment (½ Δθ × Δv, eq. 5,82 de Groves) e resolve o incremento de velocidade do corpo através de uma nova atualização NavState::step_increments baseada em incrementos, usando a rotação relativa ao corpo Δθ_rel = Δθ_b − C_n^b ζ, de modo que uma plataforma fixa à Terra não incorre em sculling espúrio enquanto uma vibração genuína aciona o termo completo.
  • Mecanização strapdown completa de três eixos no referencial NED (src/inertial/mechanization.rs). NavState { q, v_ned, p_llh } é avançado por step(gyro_b, accel_f_b, dt) usando as equações NED padrão em referencial terrestre (Groves §5,4): atitude corpo→NED corrigida pela taxa inercial-para-navegação ω_in = ω_ie + ω_en (rotação da Terra + taxa de transporte); força específica resolvida corpo→NED através da DCM; velocidade a integrar v̇ = f_n − (2 ω_ie + ω_en) × v + g_n (Coriolis/transporte + gravidade); e posição geodésica através dos raios de curvatura meridiano/transversal. A gravidade é a gravidade normal (fio de prumo) WGS-84 de forma fechada de Somigliana com uma correção de altitude em ar livre NIMA — nunca uma constante codificada. Este é o navegador genuíno de três eixos que substitui o caminho escalar de orçamento de erros de 1 grau de liberdade. Verificado por invariantes físicos: uma plataforma presa à Terra em rotação a 45°N (a sentir a taxa de rotação da Terra + 1 g) mantém-se a menos de 1 mm durante 60 s; uma força específica horizontal para norte dá v_N ≈ a·t e um deslocamento ½ a t²; a gravidade normal coincide com os valores de superfície conhecidos no equador/polo/45° e com a taxa de variação em ar livre.
  • Representação de atitude de três eixos para INS strapdown (src/inertial/attitude.rs). Um tipo de quaternião unitário Quaternion (escalar primeiro, convenção de Hamilton) que transporta a rotação corpo→navegação, com uma vista DCM (to_dcm/from_dcm pelo método de Shepperd), produto de Hamilton, construtores de eixo-ângulo e de vetor de rotação (mapa exponencial exato) e cinemática de quaterniões — tanto uma atualização RK de taxa de primeira ordem (q̇ = ½ q ⊗ ω) como uma atualização do vetor de rotação com correção de coning. O coning_increment de duas amostras (Savage / Bryan–Lewantowski, ½ Δθ_prev × Δθ_cur) fornece o termo de acoplamento cruzado da taxa de rotação que a navegação estimada escalar omite. Esta é a base de atitude para a mecanização completa de 3 eixos que substitui o antigo caminho de orçamento de erros de 1 grau de liberdade. Verificado face a rotações de forma fechada: a propagação a taxa constante coincide com o quaternião eixo-ângulo até 1e-6, as DCM são ortonormais com determinante unitário e o coning anula-se para movimento de eixo único. (src/inertial.rs é agora o diretório de módulo src/inertial/; o caminho público crate::inertial não se altera.)
  • Visibilidade de estações terrestres geodesicamente correta (src/frames.rs). elevation, is_visible e visible_count calculam a elevação de um satélite acima do horizonte de uma estação terrestre face à normal ao elipsoide WGS-84 (a vertical local verdadeira), e não ao radial geocêntrico — os dois diferem até cerca de ~0,19° de deflexão geodésica, o suficiente para fazer entrar ou sair satélites próximos do horizonte de uma máscara de elevação. Verificado de ponta a ponta (uma constelação Walker propagada, rodada TEME→ECEF e contada a partir de um local geodésico) e face à aproximação geocêntrica.

Alterado#

  • Fiabilidade da CI. A tarefa test-python-bindings constrói agora a wheel com PyO3/maturin-action (contentor manylinux) em vez de um maturin build direto no anfitrião, eliminando um conflito intermitente de rustup rustfmt-preview/cargo-fmt na imagem do runner. A tarefa deny instala cargo-deny como binário pré-construído através de taiki-e/install-action em vez do cargo-deny-action baseado em Docker, eliminando um tempo limite de obtenção do registo Docker Hub. Nenhuma das alterações afeta as verificações realizadas.

0.8.0 - 2026-06-02#

Adicionado#

  • A velocidade inercial é exposta a jusante. Propagator::velocity_eci e Propagator::state_eci (a devolver StateEci { r_m, v_m_s }) encaminham a velocidade TEME analítica que o SGP4 já calcula — antes descartada — até aos chamadores em m/s; Orbit::velocity_eci dá ao caminho kepleriano uma velocidade coerente. O teste de verificação AIAA 2006-6753 verifica agora também a velocidade em todas as linhas de referência (pior erro de velocidade 1.85e-9 km/s em todos os 666 estados) e fixa o número de linhas comparadas em exatamente 666.

  • Análise de TLE mais estrita e sem pânicos. Exige-se que as linhas sejam ASCII e são fatiadas em segurança (já não há pânicos de índice de bytes com entrada multibyte); os elementos têm os intervalos verificados (inclinação, excentricidade, movimento médio); a soma de verificação da coluna 69 pode ser imposta através de ParseOpts { strict_checksum } / parse_propagators_opts e do novo indicador strict_checksum em ConstellationCfg (tolerante por predefinição).

  • Curva do desvio de Allan na saída. Cada execução de relógio reporta agora um adev_curve ([{tau_s, adev, n_samples}]) e o playground no navegador desenha um gráfico log-log «Estabilidade do relógio (ADEV)».

  • Validação da entrada da grelha temporal. TimeCfg::validate rejeita uma grelha temporal não finita, nula, negativa ou de tamanho excessivo (um passo maior do que a duração, ou mais de MAX_TIME_STEPS amostras) antes de qualquer alocação, pelo que um cenário malformado devolve um erro em vez de entrar em pânico ou esgotar a memória.

  • Ensembles de Monte Carlo para o pacote inercial. runs = N num cenário inercial executa N sementes e reporta a média de cada métrica, o desvio-padrão, os percentis e um intervalo de confiança de 95 % por bootstrap de percentis (ensemble). Cada execução inercial transporta agora um indicador monte_carlo, de modo que uma FoM de realização única deixa de ser confundida com uma distribuição. (CEP/2DRMS não são intencionalmente reportados — exigem o modelo de 3 eixos que está no roteiro.)

  • Modo guiado do playground. O playground no navegador já não o deixa diante de um muro de TOML em bruto: uma faixa «Comece aqui» com cartões de cenário de um clique carrega e executa um exemplo trabalhado, controlos deslizantes expõem os parâmetros universais (semente, limiar de temporização) sem tocar no TOML, uma nota «Como ler isto» explica o resultado e o TOML completo está a um recolhimento de distância. Cada execução é partilhável — Copiar ligação de partilha codifica todo o cenário no fragmento do URL (nada é carregado) para que uma ligação reproduza a execução exata ao abrir. O codec tem testes unitários (web/share.test.mjs, executados na CI).

  • Varrimentos N-dimensionais de parâmetros (src/sweep.rs). nd_sweep avalia uma métrica sobre todo o produto cartesiano de vários intervalos SweepAxis (o estudo de compromisso multiparamétrico), por ordem de linhas, de forma determinística. Aditivo — a API de varrimento 1-D existente não se altera. Os intervalos de confiança por bootstrap por nó e a generalização para além do pacote de relógios continuam no roteiro.

  • RAIM instantâneo real (src/raim.rs). Monitorização Autónoma de Integridade do Recetor genuína no domínio da posição: constrói a geometria de linha de visada para os satélites visíveis, forma a solução de mínimos quadrados e os resíduos, executa um teste de deteção de falhas por resíduos χ² (limiar exato a partir de um χ²/χ² não central de gama incompleta sem dependências) e calcula níveis de proteção horizontal e vertical por declive (HPL/VPL) com o desvio de deteção falhada derivado para os P_fa/P_md configurados. Isto é distinto da figura de Integridade de autoconsistência do filtro do pipeline de cenários — e ainda não está ligado a ela; a exclusão de falhas, o orçamento de limite de alerta/P_HMI e o ARAIM continuam no roteiro.

  • Conjunto de estabilidade de frequência: MDEV, TDEV, HDEV + intervalos de confiança (src/allan.rs). A par do ADEV sobreposto: o desvio de Allan modificado (separa o ruído de fase branco do flicker), o desvio de tempo (TDEV = tau/sqrt(3) * MDEV) e o desvio de Hadamard (rejeita exatamente a deriva linear de frequência e converge para tipos de ruído vermelho divergentes). Os intervalos de confiança baseados em χ² (deviation_ci) usam um par de quantis normal/χ² sem dependências (Acklam + Wilson-Hilferty) com um edf conservador sem sobreposição; o edf específico do tipo de ruído e a paridade numérica com o Stable32 continuam no roteiro.

  • Redução de referenciais (src/frames.rs). Rotação TEME↔ECEF baseada em GMST (usando o mesmo tempo sideral IAU-1982 que o propagador), geodésica WGS-84↔ECEF exata com um inverso iterativo iniciado por Bowring (precisão de máquina a todas as altitudes, incluindo MEO/GEO) e um observador geodésico de estação terrestre que devolve azimute / elevação / distância no referencial local Este-Norte-Cima. O movimento polar e a nutação de sub-segundo de arco não são aplicados (apenas GMST, sub-quilométrico no rasto no solo); uma cadeia CIO de precisão ITRF está no roteiro.

  • Base das escalas de tempo (src/timescales.rs). Uma API de data juliana sem dependências (civil gregoriano ↔ JD, MJD), o historial completo IERS de segundos intercalares inteiros (UTC↔TAI, 10 s em 1972 até 37 s desde 2017), o desvio definido TAI→TT, a correção UT1 através de um DUT1 fornecido e o Ângulo de Rotação da Terra IAU-2000. Este é o substrato de tempo sobre o qual assenta a redução de referenciais fixos à Terra (planeada). Os instantes são Datas Julianas de um único f64 (resolução de ~50 µs perto da época atual; uma JD de duas partes está no roteiro), e a era do segundo elástico anterior a 1972 não é modelada — ambos documentados no módulo.

  • Reprodutibilidade e proveniência. Um gerador determinístico de SBOM CycloneDX (scripts/gen-sbom.sh) e uma atestação de proveniência de compilação SLSA no binário de lançamento e no SBOM; a cadeia de ferramentas de lançamento está fixada para coincidir com a CI. As garantias de determinismo, a ressalva multiplataforma de libm e a abordagem de fixação de valores de referência estão documentadas em docs/REPRODUCIBILITY.md.

  • Testes baseados em propriedades e de fuzzing (tests/property.rs). Testes aleatorizados determinísticos (sem nova dependência) afirmam invariantes sobre milhares de entradas: os analisadores de TLE e de cenários nunca entram em pânico com lixo, não ASCII, entrada mutada ou truncada; TimeCfg::validate nunca entra em pânico com grelhas NaN/inf/negativas; a soma de verificação do TLE é consistente e apenas da coluna 69; as idas e voltas geodésica↔ECEF e a rotação TEME→ECEF preservam a norma em todo o globo e numa ampla banda de altitudes.

Alterado#

  • Os testes de referência fixam agora as figuras de mérito campo a campo para os quatro cenários de referência (com uma tolerância que absorve a variação multiplataforma de libm), substituindo as verificações anteriores apenas de desigualdade, de modo que uma regressão numérica silenciosa seja detetada de imediato.
  • schema_version nos artefactos de resultados passou de 0.1 para 0.7 (estava congelado enquanto o motor evoluía).
  • cargo-deny passa agora a negar (e não apenas a avisar sobre) dependências retiradas (yanked).
  • Nova documentação: CAPABILITY.md (mapa honesto do âmbito), SCHEMA.md (referência dos campos de resultados), INTEGRITY.md, QUANTUM-MODELS.md, REAL_TLE_GUIDE.md. Uma proteção da CI falha se o emblema de versão do README divergir de Cargo.toml.

0.7.0 - 2026-06-02#

Adicionado#

  • Propagação de órbitas SGP4/SDP4. Uma implementação completa e sem dependências do propagador padrão de perturbações simplificadas — SGP4 para órbitas próximas da Terra juntamente com a extensão SDP4 para o espaço profundo (perturbações luni-solares seculares e periódicas e ressonância geopotencial de 12 h / 24 h). É validada face aos vetores de verificação oficiais AIAA 2006-6753 («Revisiting Spacetrack Report #3»): todos os 666 estados de referência nos casos de órbita próxima da Terra, espaço profundo, ressonante e de códigos de erro coincidem com um erro de posição no pior caso de cerca de 4 mm. Este é o modelo face ao qual os conjuntos de elementos de duas linhas são definidos, pelo que representa constelações reais — nomeadamente as órbitas GNSS de ~12 h, que são de espaço profundo e ressonantes e que o anterior modelo de dois corpos + J2 secular não consegue captar.
  • Uma constelação dada como conjuntos completos de elementos de duas linhas (linha 1 + linha 2) é agora propagada com SGP4/SDP4; uma constelação dada com elementos apenas da linha 2 mantém a propagação kepleriana analítica de dois corpos, sem alterações. As duas formas podem ser misturadas num só bloco. Novo cenário de referência orbit-sgp4-gps.toml (uma constelação MEO semelhante ao GPS em formato real de duas linhas, propagada com SGP4) — pode-se acrescentar um conjunto «gps-ops» atual do Celestrak para estudar a constelação em funcionamento.

0.6.0 - 2026-06-02#

Adicionado#

  • Demonstrador de ataque ativo de spoofing. Um novo tipo de cenário spoof injeta um spoof de falso tempo em rampa e executa o monitor de integridade assistido por relógio de cada relógio, reportando se e quando o spoof é detetado e se atinge a especificação operacional sem ser detetado — transformando a figura de mérito de Segurança numa demonstração concreta de ataque/defesa. Novo cenário de referência spoof-attack.toml.
  • Disponibilidade multiconstelação. Um cenário de órbita pode combinar várias constelações (uma lista [[constellations]] a par da [constellation] primária) para disponibilidade multi-GNSS e diluição de precisão — por exemplo GPS mais Galileo. Novo cenário de referência orbit-multignss.toml.

0.5.0 - 2026-06-02#

Adicionado#

  • Relatório de painel de resultados em HTML. Cada execução produz agora também um painel de resultados HTML autónomo e com a marca — o resumo de uma linha, o gráfico (incorporado como imagem data-URI inerte) e o JSON completo — escrito pela CLI a par do JSON e do SVG. Um artefacto partilhável de ficheiro único para um produto de estudo ou anexo.
  • Estimador conjunto de fusão de sensores. Um novo tipo de cenário fusion executa um único filtro de Kalman recursivo como solução de navegação — a fundir o estado do relógio [phase, frequency] e o estado de posição [position, velocity], disciplinado pelo GNSS (a aprender o desvio de frequência e a velocidade) e assistido por transferência de tempo ótica durante a interrupção — em vez de compor preditores independentes. Reporta o holdover fundido de temporização/posição e uma integridade de covariância conjunta. Novo cenário de referência fusion-pnt.toml.
  • Modelo de ruído de IMU mais completo. O acelerómetro modela agora os restantes termos da variância de Allan para além do desvio constante e do passeio aleatório de velocidade: instabilidade do desvio (um patamar de flicker 1/f ao coeficiente padrão de instabilidade do desvio de Allan, reutilizando a síntese de flicker do relógio) e passeio aleatório de aceleração. Novos campos opcionais de cenário inercial bias_instability e q_aa; uma nova solução GNSS recalibra a deriva residual do desvio.
  • Geometria real de constelações a partir de TLE. Uma constelação pode ser dada como um bloco de conjuntos de elementos de duas linhas (o formato padrão NORAD/Celestrak) através de um campo tle, de modo que a disponibilidade e a diluição de precisão usem a geometria publicada de uma constelação real em vez de um padrão Walker sintético. O motor lê os elementos keplerianos médios de cada TLE e propaga-os com dois corpos — não SGP4 — o que é adequado para um estudo instantâneo a partir de uma época comum. Novo cenário de referência orbit-real-tle.toml.

0.4.0 - 2026-06-02#

Adicionado#

  • Varrimentos de parâmetros para estudos de compromisso. Um novo tipo de cenário sweep faz variar um parâmetro (threshold_ns, duration_s, quantum_q_wf ou classical_q_wf) ao longo de um intervalo linear ou logarítmico e regista uma figura de mérito escolhida em cada ponto para ambos os relógios, produzindo o gráfico de comparação «como escala o holdover com a estabilidade do relógio?» de que um compromisso de projeto necessita. Novo cenário de referência sweep-clock-stability.toml.
  • Bandas de confiança de Monte Carlo. O cenário de holdover de relógio pode executar muitas realizações (novo campo opcional runs): cada figura de mérito é então reportada como uma média com uma dispersão entre o 5.º e o 95.º percentil, e o gráfico sombreia o envelope de erro de 5–95 % em torno da mediana para cada relógio. Uma única execução continua a ser a predefinição. Novo cenário de referência clock-ensemble.toml.
  • Órbitas excêntricas e deriva J2. O tipo de órbita é agora uma órbita kepleriana completa (semieixo maior, excentricidade, inclinação, RAAN, argumento do perigeu, anomalia média), propagada pela resolução da equação de Kepler, com regressão nodal e precessão apsidal seculares J2 opcionais. Novos campos opcionais de cenário eccentricity, argp_deg e j2, e um cenário de referência orbit-molniya.toml (um utilizador de 12 h, muito excêntrico e de inclinação crítica). As órbitas circulares mantêm o caminho original de forma fechada bit a bit.
  • O pacote híbrido (PNT combinado) reporta agora Integridade e Segurança, pelo que os quatro pacotes cobrem o conjunto completo de figuras de mérito operacionais. A Integridade é a contenção do limite de proteção do canal de temporização a partir de um estimador de Kalman disciplinado pela referência enquanto o GNSS é nominal e reancorado (de forma mais folgada) em cada ressincronização ótica; o seu limite inclui o patamar de ruído de medição da ligação, de modo que um relógio muito melhor do que a ligação é pontuado face ao ruído real da solução entregue. A Segurança é a pontuação de deteção de spoofing assistida por relógio face à especificação de temporização.

Alterado#

  • As notas de versão são agora geradas a partir da secção selecionada do CHANGELOG para a etiqueta (scripts/changelog-extract.sh), de modo que cada versão no GitHub destaque o que mudou em vez de listar commits em bruto.

0.3.0 - 2026-06-02#

Adicionado#

  • Figura de mérito de Segurança (antes não preenchida): uma pontuação de deteção de spoofing assistida por relógio para os pacotes de holdover de relógio e de órbita. Modela um monitor de integridade que compara o tempo derivado do GNSS com a própria predição em marcha livre do relógio ao longo de uma janela coerente; o limiar de deteção combina o ruído de medição médio com a incerteza da marcha livre do relógio, de modo que um relógio mais silencioso deteta spoofs de tempo menores e mais lentos. A pontuação é reportada em [0, 1] relativamente à especificação de temporização, completando as seis figuras de mérito operacionais.
  • Exatidão de posição derivada da geometria para o pacote de órbita: a partir da geometria de linha de visada para os satélites visíveis forma a matriz de projeto e o seu fator de covariância Q = (HᵀH)⁻¹, produzindo os fatores de diluição de precisão (GDOP/PDOP/HDOP/VDOP/TDOP). A exatidão de posição é o DOP de posição multiplicado por um erro equivalente de distância do utilizador configurável (novo campo opcional de cenário sigma_uere_m). Um resultado de órbita transporta agora um resumo da geometria (fração de amostras com solução de posição, melhor e mediana de PDOP e sigma de posição).
  • Um playground no navegador (web/) que executa o motor do lado do cliente como WebAssembly: escolha um cenário de referência ou edite o TOML, execute-o e veja o resumo, o gráfico e o JSON completo, sem que nada seja carregado. Um fluxo de trabalho pages compila-o e publica-o no GitHub Pages, e uma nova exportação WebAssembly summary suporta a leitura.
  • Eixos y etiquetados nos gráficos SVG: linhas de grelha, etiquetas numéricas de graduação e um título de eixo com unidades (através de um auxiliar chart partilhado), de modo que as magnitudes sejam legíveis.
  • Fluxo de trabalho de publicação de pacotes (publish) para crates.io, PyPI e npm, cada um condicionado ao seu token de registo e acionado por uma versão publicada.

0.2.0 - 2026-06-02#

Adicionado#

  • Patamar de FM flicker (1/f) para o modelo de erros do relógio, sintetizado como soma de processos de Ornstein-Uhlenbeck espaçados logaritmicamente e calibrado de modo que o patamar plano do desvio de Allan fique num nível configurável. Desativado por predefinição; ativado por relógio através do campo opcional de cenário flicker_floor.
  • Canal de giroscópio para o modelo inercial: o desvio residual do giroscópio e o passeio aleatório angular geram um erro de atitude (inclinação) que acopla a gravidade num erro horizontal de força específica, o principal mecanismo de crescimento de erro strapdown. Desativado por predefinição; ativado por sensor através dos campos opcionais gyro_bias e q_arw.
  • Estimador de relógio de Kalman de dois estados (fase, frequência) com discretização exata do ruído de processo de van Loan. A marcha livre a partir de um estado conhecido reproduz exatamente o crescimento analítico do erro de holdover (q_wf*T + q_rw*T^3/3), e o filtro produz adicionalmente um limite de incerteza de 1 sigma em linha.
  • A execução do relógio reporta agora a figura de mérito de Integridade (antes não preenchida): a fração das amostras de interrupção cujo erro se mantém dentro do limite de proteção de 3 sigma do filtro, exposta no resultado JSON e no resumo da CLI.
  • Disponibilidade GNSS derivada da geometria: a propagação de órbitas circulares, um gerador de constelações Walker-delta e a visibilidade de linha de visada (ocultação pela Terra mais máscara de elevação) produzem a cronologia de disponibilidade a partir da geometria orbital real. Novo tipo de cenário orbit e cenário de referência orbit-gnss-challenged.toml (uma nave espacial no interior da camada GNSS com cobertura intermitente).
  • Extensão Python opcional (PyO3, abi3) que expõe run, run_full e version, empacotada com maturin (pyproject.toml) e compilada para Linux, macOS e Windows por um fluxo de trabalho wheels de etiqueta de versão. A ligação é uma dependência opcional condicionada por funcionalidade: a compilação predefinida, os testes e a verificação de auditoria de dependências não são afetados.
  • Módulo WebAssembly opcional (wasm-bindgen) que expõe run, chart_svg e version, compilado com wasm-pack sob a funcionalidade wasm; getrandom está condicionado ao alvo para usar a fonte de entropia do navegador em wasm32.
  • Despacho api::run_toml partilhado usado pela CLI e por ambas as ligações, de modo que a linha de comandos e as ligações não possam divergir.

Alterado#

  • A pontuação de holdover é agora sensível a segmentos: as cronologias de interrupção são divididas em segmentos contíguos na reaquisição do GNSS, e o holdover reportado é a marcha livre no pior caso (a mais curta) entre eles. Os cenários de interrupção única não se alteram. Aplica-se aos pontuadores de relógio, inercial e híbrido.
  • O kind reportado pelo modelo inercial é agora inertial (era accelerometer), refletindo os canais combinados de acelerómetro e giroscópio.

0.1.0 - 2026-06-01#

Versão inicial.

Adicionado#

  • Motor de simulação determinístico para PNT híbrido quântico/clássico: uma interface comum de modelos de erro, cenários declarativos de disponibilidade GNSS, estimadores de holdover / navegação estimada e pontuação de figuras de mérito face aos critérios operacionais PNT padrão. Os resultados são reprodutíveis a partir de scenario + seed + engine version (JSON versionado e autodescritivo com um hash do cenário) e desenhados como gráficos SVG. A CLI despacha os cenários por kind.
  • Quatro pacotes de sensores, cada um calibrado com dados publicados e validado face à relação padrão:
    • Holdover de relógio — FM branco, FM de passeio aleatório e envelhecimento linear; validado pelo desvio de Allan sobreposto (Riley, NIST SP 1065). Relógio atómico à escala de chip vs relógio ótico de rede de estrôncio.
    • Navegação estimada inercial — desvio residual + passeio aleatório de velocidade, integrados duas vezes até ao erro de posição; validada face às relações de crescimento de erro de Groves. Acelerómetro de átomos frios vs acelerómetro de classe de navegação.
    • Transferência de tempo — jitter de temporização de uma ligação ótica vs RF → precisão de sincronização → medição unidirecional de distâncias.
    • Fusão híbrida (peça final) — um conjunto PNT combinado que tem de manter tanto a temporização como a posição, com assistência opcional dos relógios por transferência ótica de tempo entre satélites.
  • Um cenário de referência citado por pacote em scenarios/, com cada parâmetro numérico a transportar uma provenance revista por pares.
  • Proteções de reprodutibilidade e de higiene do repositório; CI (formato, clippy, testes, proteções, MSRV) e um pipeline de lançamento condicionado por etiqueta que volta a executar todas as verificações.
  • Documentação: README com diagramas de arquitetura, relatório do estado de validação, guia de contribuição, política de segurança e código de conduta; licença Apache-2.0; modelos de issues/PR e configuração do Dependabot.
  • Neutro quanto a fornecedores em todo o lado; citações científicas e de metrologia revistas por pares mantidas.
  • Higiene da licença Apache-2.0: cabeçalhos SPDX em todo o código-fonte, um NOTICE com aviso de marca registada, sign-off do Developer Certificate of Origin (DCO) nas contribuições e imposição por cargo-deny das licenças/avisos das dependências na CI.
  • Posicionamento open-core (README): um motor Apache-2.0 gratuito mais apoio comercial, integração e extensões proprietárias disponíveis da Ashforde OÜ — sustentado por serviços, não por taxas de licença.
  • CITATION.cff para que o software possa ser citado.