SecaniDocumentation
OSCAL

Validateur

Comment le validateur Secani OSCAL prouve la validation vérifiée par la source au-delà de l'implémentation de référence Java : clôture d'exhaustivité, réceptions différentielles et limites honnêtes.

Préparation privée : Le validateur décrit ici est livré à l'intérieur du secani/oscal boîte à outils, qui reste privée tant qu'elle est préparée pour l'open source. Tous les décomptes, citations et localisateurs ci-dessous proviennent du registre lisible par machine dans la boîte à outils. validation/ répertoire et sont revérifiables via pnpm verify.

Résumé

La boîte à outils OSCAL de Secani valide les documents NIST OSCAL par rapport à ce que disent réellement les sources NIST épinglées – et non par rapport à ce que fait une implémentation de référence. Il atteint la parité complète des capacités avec la surface Java OSCAL CLI 3.2.0, puis la dépasse de quatre manières que la pile Java ne tente pas :

  1. Une preuve d'exhaustivité vérifiée par machine : chacune des 348 occurrences de contraintes détectables dans les huit métaschémas racine OSCAL 1.2.2 est réconciliée individuellement – ​​prouvée appliquée, prouvée couverte par le schéma ou explicitement exclue avec une justification écrite. Zéro n'est pas retrouvé.
  2. Sémantique OSCAL 1.2.2 native avec prise en charge de plusieurs versions (1.1.2, 1.1.3, 1.2.1, 1.2.2), où Java CLI 3.2.0 intègre les liaisons OSCAL 1.2.1 et peut traiter les documents 1.2.2 uniquement sur une base de compatibilité.
  3. Validation de flux de travail inter-documents – résolution et vérification du graphique de référence entre les SSP, les plans d'évaluation, les résultats d'évaluation et les POA&M – ce qui est entièrement en dehors de la surface de validation de Java CLI.
  4. Une base de code TypeScript qui s'exécute partout où les documents sont disponibles : les mêmes validateurs précompilés s'exécutent dans le navigateur, dans les routes API sans serveur, dans la CLI et dans le backend – pas de JVM nulle part.

Le processus a également révélé des défauts dans les sources du NIST elles-mêmes (voir Trouver des bugs – dans les deux sens), ce que l’on attend d’une vérification au niveau de l’occurrence – et la preuve la plus solide en ce sens.

Le modèle d'autorité : les sources plutôt que les implémentations

La règle de portée contraignante du projet :

La source NIST OSCAL fait autorité. Java est un comparateur de compatibilité et une preuve d'implémentation, jamais une autorité.

Concrètement, chaque revendication sémantique est épinglée sur des octets :

  • Autorité : usnistgov/OSCAL, tag v1.2.2, commit 21403b4ad2f162ef1201e5ee70e8b93f254f51ac — les huit modules Metaschema racine (catalogue, profil, définition de composant, SSP, plan d’évaluation, résultats d’évaluation, POA&M et mappage), leurs imports communs (métadonnées, contrôles, implémentation, évaluation et mappage) et les entités de contraintes externes. Tous sont mis en cache octet par octet et épinglés par des condensats SHA-256.
  • Résolution de profil : le projet de spécification du NIST src/specifications/profile-resolution/profile-resolution-specml.xml. Parce que c'est un brouillon/WIP, ses exigences sont mises en œuvre derrière une capacité explicite et ne sont jamais intégrées silencieusement dans une validation ordinaire.
  • Comparateur : Java OSCAL CLI 3.2.0 avec liboscal-java 7.2.0, qui intègre les liaisons OSCAL 1.2.1. Les preuves de comparaison sont enregistrées avec des localisateurs précis de l'occurrence ; les références sans octets mis en cache et sans localisateurs exacts sont étiquetées inspection de source non qualifiée et ne peuvent pas fermer une porte de provenance.

C'est l'inversion qui compte : la plupart des outils traitent l'implémentation de référence comme une vérité terrain. Nous traitons les sources de la norme comme une vérité terrain et traitons l'implémentation de référence comme un témoin à contre-interroger.

Exemple : à quoi ressemble une revendication épinglée par un localisateur. Le registre ne dit pas « nous prenons en charge les vérifications du rôle des parties responsables ». Il dit : contrainte oscal-metadata-responsible-party-role-ids, source oscal_metadata_metaschema.xml@L400, fichier source SHA-256 épinglé, appliqué par une règle META-002.a, prouvé par un test nommé dont le hachage AST est enregistré. Si le NIST modifie cette ligne, la goupille se brise et la réclamation doit être requalifiée.

La clôture de complétude : prendre en compte chaque contrainte

Les sources Metaschema définissent des contraintes (allowed-values, is-unique, matches, index, index-has-key, has-cardinality, expect) dispersés sur des milliers de lignes XML. Un validateur peut prétendre « prendre en charge les contraintes OSCAL » sans que personne ne puisse vérifier ce que cela signifie. Nous l'avons rendu vérifiable.

La fermeture de l'exhaustivité inventorie lexicalement 348 occurrences de contraintes sur le graphique du module épinglé, dont 17 occurrences anonymes et 8 occurrences conservées dans les commentaires sources, car décider qu'elles ne comptent pas est en soi une décision révisable. L'identité d'occurrence inclut le chemin et la ligne source, de sorte que les ID de contrainte répétés ne s'effondrent jamais.

Chaque occurrence doit atterrir dans exactement un ensemble de preuves fermé :

SeauCompterSignification
assertion303Prouvé appliqué au moment de l'exécution par un test d'occurrence exacte
schema-enforced1Prouvé couvert par la version JSON Schema
excluded-with-rationale44Explicitement exclus, chacun nommant sa raison concrète
unresolved0–

Exemple : ce que signifie "preuve exacte d'occurrence" dans le code. Chaque occurrence prouvée a une déclaration comme celle-ci dans la suite de tests :

closureEvidenceTest(
  {
    assertionIds: ["META-012.b"],
    name: "allowed-values assessment-common oscal-assessment-objective-types@L65 occurrence",
    releases: [],
    subject: "evaluateBuiltinAllowedValues",
  },
  () => {
    const evaluation = evaluateBuiltinAllowedValues(
      {
        "assessment-results": {
          "local-definitions": {
            "objectives-and-methods": [{ parts: [{ name: "assessment" }] }],
          },
        },
      },
      "assessment-results",
    );
    expect(evaluation).toMatchObject({
      evaluatedInventoryIds: expect.arrayContaining([
        "oscal_assessment-common_metaschema.xml#oscal-assessment-objective-types@L65",
      ]),
    });
  },
);

Le test pilote l'évaluateur réel sur un document minimal et affirme que l'occurrence source exacte – fichier, identifiant de contrainte, ligne – a été évaluée. Le format de preuve est délibérément difficile à falsifier : l'AST TypeScript de la déclaration est vérifié (le sujet déclaré doit s'exécuter exactement une fois ; son résultat doit couler dans exactement un niveau supérieur expect), et la déclaration, son dossier et le SHA-256 de sa clôture transitive d'import sont épinglés. Changez l'évaluateur et chaque hachage de preuve dépendante devient obsolète jusqu'à ce qu'il soit redérivé mécaniquement. Un test renommé, un corps non opérationnel ou un assistant muté invalide automatiquement la preuve.

Les 44 exclusions ne sont pas agitées : 5 occurrences se trouvent dans les commentaires XML dans les sources du NIST (texte mort), 2 sont des défauts en amont (voir ci-dessous), 3 sont des éléments de limite de modèle documentés et 34 sont des contraintes actives qui sont appliquées au moment de l'exécution par défaut mais ne relèvent pas de l'inventaire verrouillé de 93 assertions du registre de recherche - chaque exclusion nomme le évaluateur généré qui l’applique.

Avec unresolved = 0, l'artefact se retourne exhaustiveRequirementClaimAllowed: true – un indicateur que le générateur calcule à partir du nombre de seaux, pas une phrase écrite par un humain.

Registre des exigences : 40 sur 42, avec des prises honnêtes

Au-dessus du niveau d'occurrence se trouve un registre de 42 exigences de recherche (93 assertions atomiques) couvrant le routage des schémas, la sémantique des métadonnées, le catalogue/profile règles, résolution de profil, résolution inter-documents et validation de flux de travail. 40 sont implemented; chaque retournement nécessitait un chemin d'exécution nommé plus un réel positif/negative essais. Les deux postes non soldés sont des retenues volontaires et documentées :

  • PRES-004 (mappages d'identifiants d'importation) : le projet de spécification indique que le mappage comporte cinq sous-sections facultatives mais n'en définit qu'une concrètement (mapping[].controls[{from,to}]), et le métaschéma de profil 1.2.2 épinglé ne définit aucun mapping sur import du tout. Nous implémentons la forme basée sur des exemples et échouons sur tout le reste :

    $ oscal-cli resolve-profile --to JSON profile-with-param-mapping.json
    oscal-cli: unsupported import mapping subsection 'params' in pinned draft

Revendiquer une prise en charge complète du mappage signifierait inventer une sémantique que la source ne contient pas.

  • META-013 (représentations de ressources alternatives équivalentes) : la source nécessite plusieurs rlink/base64 représentations d'une ressource pour « contenir des informations équivalentes » sans définir opérationnellement l'équivalence (égalité d'octets ? égalité sémantique après conversion de format ?). L’application reste en attente d’une définition, plutôt que d’en inventer une.

Ce que fait le validateur et que Java CLI 3.2.0 ne fait pas

Sémantique native 1.2.2, routage multi-release

Java CLI 3.2.0 intègre liboscal-java 7.2.0 avec les liaisons OSCAL 1.2.1 ; une exécution inchangée sur un document 1.2.2 est une compatibilité observationnelle, pas une validation 1.2.2. Secani fournit un routage de schéma prenant en compte les versions et des validateurs précompilés pour 1.1.2, 1.1.3, 1.2.1 et 1.2.2, avec 1.2.2 comme cible d'implémentation sémantique – et échoue à la fermeture des versions qu'il n'a pas qualifiées au lieu de valider silencieusement contre la mauvaise génération.

La couche de contrainte sémantique générée

La couche sémantique ordinaire (activée par défaut) évalue, par document, l'inventaire des contraintes épinglées : toutes les 200 actives allowed-values occurrences (y compris les cibles d'axe descendant et les cibles adressées par drapeau comme action/@type), tous 27 couverts is-unique occurrences, ** 24 sur 25 actifs matches** occurrences (la 25ème est imposée par une règle de possession de métadonnées), le généré expect, has-cardinality, et fichier local index/index-has-key évaluateurs et les métadonnées/catalog/profile/SSP familles de règles sémantiques. Chaque diagnostic porte sa provenance NIST. Il s'agit de la sortie d'exécution textuelle d'un catalogue dont les métadonnées action déclare "type": "invented-type":

{
  "ruleId": "oscal-metadata-action-type-values",
  "sourceId": "https://raw.githubusercontent.com/usnistgov/OSCAL/21403b4ad2f162ef1201e5ee70e8b93f254f51ac/src/metaschema/oscal_metadata_metaschema.xml#L877",
  "sourceType": "oscal-constraint",
  "authority": "nist-metaschema",
  "severity": "error",
  "phase": "semantic",
  "path": "/catalog/metadata/actions/0/type",
  "message": "value \"invented-type\" is not one of the allowed values: \"approval\", \"request-changes\"",
  "keyword": "allowed-values"
}

Le sourceId n'est pas une étiquette - c'est un pointeur cliquable et épinglé vers la ligne exacte du métaschéma qui impose la règle. (Ce diagnostic particulier est également un différentiel en direct : Java CLI 3.2.0 accepte exactement ce document – ​​en JSON et XML – même si la contrainte se trouve au niveau L877 du métaschéma de métadonnées 1.2.1 intégré dans ses propres liaisons ; voir le reçu R4 ci-dessous.)

Résolution de profil complète selon le projet de spécification

resolve-profile met en œuvre le pipeline de projets de résolution du NIST de bout en bout – et échoue lorsque le projet est indéfini plutôt que de deviner :

$ oscal-cli resolve-profile --to JSON baseline-profile.json resolved-catalog.json
$ oscal-cli resolve-profile --to JSON legacy-combine.json
oscal-cli: deprecated combine method 'merge' has undefined resolution behavior

$ oscal-cli resolve-profile --to JSON mixed-major.json
oscal-cli: major OSCAL version mismatch between '1.2.2' and '2.0.0' at 'file:///…/legacy.json'

Couvert : acquisition import avec cycle/depth/byte budgets, internes #uuid les importations, y compris les documents intégrés en base64, incluent/exclude sélection avec with-child-controls expansion, keep/use-first combiner la sémantique, as-is/custom/flat la structuration, l'application déterministe des paramètres et des modifications, et le back-matter fusionnent avec les règles de classement exactes du projet (les doublons ultérieurs sont remplacés à la position ultérieure ; un keep=always blocs de ressources remplacement non marqué).

La finalisation du résultat est le lieu où résident plusieurs garanties subtiles : la valeur déclarée oscal-version du résultat est limité à la version la plus élevée prise en charge de la même version majeure ; les clés sont émises dans l'ordre canonique OSCAL ; et le catalogue résolu est re-validé – contraintes de schéma et sémantiques – avant la sérialisation, donc un résultat de résolution invalide est un refus, pas une sortie. La CLI Java n'effectue pas cette vérification sur sa propre sortie : son résolveur écrira un catalogue que son propre validateur rejettera ensuite (reçu R6 ci-dessous).

Validation du flux de travail inter-documents (pas dans la surface Java)

C'est le différenciateur. Les artefacts de conformité OSCAL forment un graphique : un résultat d'évaluation importe un plan d'évaluation, qui importe un SSP, qui importe un profil, qui est résolu par rapport aux catalogues - et la documentation du modèle indique les relations qu'aucun schéma JSON ne peut vérifier. Le validateur document-graph résout ces bords et les vérifie.

Exemple. Un SSP prétend mettre en œuvre le contrôle ac-99, mais la référence qu’il importe ne fournit jamais ce contrôle. Une fois les règles d'interprétation activées, le validateur de graphiques résout la ligne de base via le pipeline complet de résolution de profil jusqu'à ses catalogues, calcule l'ensemble de contrôles sélectionné et émet (forme de problème textuelle) :

{
  "ruleId": "SSP-003.b",
  "sourceId": "secani:oscal-ssp-import-profile-interpretation:v1",
  "sourceType": "validation-dispatch",
  "authority": "secani-policy",
  "severity": "warning",
  "phase": "resolution",
  "path": "/system-security-plan/control-implementation/implemented-requirements/1/control-id",
  "message": "implemented control 'ac-99' is not supplied by the resolved import-profile 'file:///…/baseline.json'",
  "keyword": "implemented-control-supplied"
}

Notez la discipline de provenance même ici : l'autorité est secani-policy sous une source d’interprétation versionnée – non nist-metaschema – parce que cette vérification est notre interprétation documentée, et non la contrainte machine du NIST. Depuis la CLI, les contrôles sont accessibles via oscal-cli validate --resolve-imports --interpretive SSP-003.b ssp.json (répétable, ou --interpretive all; --warnings-as-errors les promeut vers une sortie ratée).

La famille complète des règles, chacune épinglée à son ancre dans les sources :

RègleCe qu'il vérifieAncre
SSP-003Chaque SSP implemented-requirement/control-id est fourni par le résolu import-profilerésolu via le pipeline de résolution de profil
XDOC-001PA import-ssp → un SSP ; RA import-ap → un PA ; POA&M import-ssp → un SSP ; libérationimporter des champs dans l'AP/AR/POA&M Métaschémas
ASMT-002related-observation/associated-risk/related-finding Les UUID sont résolus dans leur portée locale documentéeoscal_assessment-common_metaschema.xml @L863/@L877; oscal_poam_metaschema.xml @L135
ASMT-003Les références des composants de l'outil d'évaluation sont résolues par rapport aux actifs d'évaluation, y compris la visibilité des actifs AR → AP.origin-actor @L1025-1039
ASMT-001La recherche de cibles est résolue via la chaîne AR→AP→SSP→profile→catalog, avec target/@type accordrecherche-cible @L735-755 + vocabulaire des pièces de catalogue @L316-341
POAM-001Le prédicat de contexte système documenté – exactement tel qu’écritvoir ci-dessous

Exemple – implémentation exacte de la prose. La remarque POA&M Metaschema se lit comme suit :

"Soit un SSP basé sur OSCAL doit être importé, soit un identifiant système unique doit être spécifié. Les deux peuvent être présents. » – oscal_poam_metaschema.xml @L58-60

POAM-001.a avertit uniquement lorsque ni l'un ni l'autre n'est présent. Un test de broches qui fournit les deux reste silencieux – parce qu’inventer une exclusivité – ou la source ne l’indique pas – est exactement le genre de sur-validation que ce projet refuse de faire.

Deux décisions de conception comptent autant que les contrôles :

  • Honnêteté interprétative. Ces relations sont documentées en prose et non comme des contraintes de machine – ce qui est révélateur, c'est le propre du plan d'évaluation. index-has-key car ces UUID n'existent dans la source NIST qu'en tant que "faux exemple" commenté. Ainsi, les règles sont désactivées par défaut, émettent des avertissements, ne rendent jamais un document invalide et ne s'exécutent que lorsqu'un appelant les nomme explicitement.
  • Portée épinglée avant le code. La note de registre de chaque règle enregistre, par champ de référence, la portée et le localisateur de résolution documentés, ainsi que ce qui a été exclu par son nom. subject-uuid, par exemple, est documenté comme résolvant "chaque fichier importé directement ou indirectement" (@ L652-654) - de manière transitive entre documents - il est donc explicitement hors de portée plutôt qu'à moitié implémenté.

Surface CLI : parité plus

Les 22 fonctionnalités Java CLI orientées OSCAL sont couvertes par des contrats d'acceptation observables (commande, options, saisie, réussite)./failure sortie, codes de sortie) : valider/convert à travers JSON/XML/YAML, resolve-profile, list-allowed-values, SARIF déterministe (--sarif-include-pass, --sarif-timing), --threads partitionnement des travailleurs avec ordre canonique des résultats, metapath/xpath/jsonpointer rendu du chemin, alias de commande de modèle, achèvement du shell. En haut: --prune, --interpretive, les exportations de schéma épinglées par version et l'API de diagnostic programmatique.

Pourquoi TypeScript

  1. Un artefact, chaque exécution. Les validateurs sont des modules Ajv autonomes précompilés – JavaScript généré simplement, pas de compilation de schéma d'exécution, pas de réflexion, pas d'interpréteur Metaschema. Le chemin de code identique s'exécute dans le navigateur, dans les routes API sans serveur, dans Node (CLI) et à l'intérieur du backend. La pile Java nécessiterait une JVM à chacun de ces emplacements, ou un port avec perte.

  2. La plateforme est l'endroit où vivent les documents. Le produit de Secani est une plateforme Web ; son API de validation, son atelier de création et son serveur MCP consomment la boîte à outils en tant que bibliothèque typée en cours :

    import { createDiagnosticsOscalProcessor } from "@secani/oscal/diagnostics";
    
    const processor = createDiagnosticsOscalProcessor({ maxIssues: 50 });
    const result = processor.validate(document);
    // OscalValidationResult:
    // { ok, complete, modelType, oscalVersion, layers,
    //   errors, issues, totalIssueCount, truncated }

Pas de sous-processus IPC par rapport à un binaire Java, pas de conteneur side-car, pas de JVM à démarrage à froid. 3. Le déterminisme en tant que fonctionnalité. Les validateurs précompilés + les évaluateurs générés + l'ordre canonique des clés rendent les sorties stables en octets – ce qui permet au système de preuves d'épingler les hachages sur le comportement en premier lieu. 4. Distribution. Un package typé avec des points d'entrée dédiés (., ./browser, ./versioned, ./diagnostics) atteint l'écosystème dans lequel les interfaces utilisateur de conformité sont réellement créées. 5. Sécurité de type par rapport au modèle. Les cartes de modèle générées font de "cette contrainte cible un indicateur, pas un élément" une propriété vérifiable statiquement - avec un test de garde n'affirmant aucun indicateur/element une collision de noms existe dans les 1 011 formes de nœuds du modèle épinglé.

Ce que TypeScript ne nous a pas acheté, c'est l'exemption de preuve : la fermeture d'exhaustivité existe précisément pour que le choix du langage soit soutenu par des preuves au niveau de l'occurrence, et non par des affirmations sur l'expérience du développeur.

Trouver des bugs – dans les deux sens

La vérification au niveau de l’occurrence a révélé de réels défauts des deux côtés, ce qui constitue l’argument le plus solide démontrant que la méthodologie fonctionne.

Dans notre propre évaluateur (trouvé par la porte de fermeture). Deux contraintes de métadonnées ciblent les flags (attributs) plutôt que les éléments enfants – les valeurs autorisées de action/@system et action/@type (oscal_metadata_metaschema.xml @L874, @L877). Ils ont compilé dans l'inventaire pris en charge mais n'ont jamais déclenché : le chemineur de l'évaluateur a résolu les étapes enfants uniquement par rapport aux éléments du modèle, de sorte que les deux contraintes n'ont rien évalué en silence. La porte de fermeture a refusé d'accepter des preuves en leur faveur, c'est ainsi que le bug est apparu. Corrigé avec une résolution appropriée par étape de drapeau ; une promenade statique sur le graphique de définition a prouvé exactement que ces deux occurrences étaient affectées.

Dans notre propre évaluateur (trouvé par l'exécution différentielle en direct – les deux ont été corrigés le même jour). Premièrement, le index L'évaluateur a traité une valeur de champ clé manquante comme une erreur et a rejeté tout catalogue contenant un prop sans un uuid – y compris le propre catalogue SP 800-53 rev5 du NIST (20 erreurs signalées ; Java 3.2.0 l'accepte). La spécification Metaschema est explicite : une valeur de champ clé manquante génère une clé d'index nulle, et non une violation ; 800-53 valide désormais le nettoyage. Deuxièmement, le vocabulaire de type action OSCAL est resté limité même lorsque action/@system a déclaré un URI personnalisé – contredisant les remarques du NIST selon lesquelles @system "fournit un moyen de segmenter l'espace de valeurs pour le type" par organisation. Les deux correctifs sont livrés avec des tests de régression et des hachages de preuves redérivés.

Dans les sources NIST :

  • Une contrainte orpheline. oscal_mapping-common_metaschema.xml @L657 contraint un indicateur défini en @L652 – qui n'est jamais référencé par aucun flag ref. Aucun nœud modèle ne le porte ; la contrainte est insatisfaisante pour tout document pouvant exister.
  • Un prédicat impossible. oscal_implementation-common_metaschema.xml @L567 contraint les noms d'accessoires sous un @type prédicat sur inventory-item - mais inventory-item déclare non type drapeau (son frère asset-id flag est lui-même commenté à @L456-461). Le prédicat ne peut jamais correspondre.
  • Contraintes vivant à l'intérieur des commentaires. Cinq occurrences – dont une with-child-controls vocabulaire de valeurs dans le profil Metaschema – n'existe qu'à l'intérieur des blocs de commentaires : texte qu'un lecteur lexical trouve mais le schéma compilé ne l'applique jamais.

Chacun est enregistré comme excluded-with-rationale avec son localisateur exact – vérifiable et signalé en amont : usnistgov/OSCAL#2254 (drapeau orphelin), #2255 (prédicat impossible), #2256 (contraintes dans les commentaires). L'écart d'application des indicateurs dans l'outillage de référence est signalé comme suit : métaschéma-framework/oscal-cli#279.

Le différentiel en direct : recettes, dans les deux sens

Le 18/07/2026, nous avons comblé l'écart entre les affirmations du comparateur inspecté par la source et les preuves exécutées : Java OSCAL CLI 3.2.0 a été téléchargé depuis Maven Central, vérifié en octets par rapport au SHA-256 épinglé dans le registre./SHA-512, et exécutez une famille de luminaires spécialement conçue dont les documents de base sont validés proprement sur les deux chaînes d'outils - de sorte que chaque différentiel est attribuable à un seul changement injecté. Son commit OSCAL intégré (26df0501) est la validation de la version 1.2.1 du correctif, confirmant l'écart de liaison au moment de l'exécution. Les relevés de notes complets, les rencontres et les codes de sortie sont enregistrés dans les reçus différentiels à côté du registre.

ReçuChangement unique par rapport à la ligne de baseSelon les sources NIST 1.2.2Java3.2.0Secani
R1Lien vers le composant SSP rel="validation", pendre #hrefinvalide (ssp L628)valide, sortie 0invalide, sortie 1
R2Lien vers le composant SSP rel="validated-by", pendre #hrefvalide (contrainte supprimée en 1.2.2)invalide, sortie 1valide, sortie 0
R3responsible-role sans option party-uuidvalide (1.2.2 ajouté [party-uuid], L736)invalide, sortie 1 – Key reference [null] not foundvalide, sortie 0
R4metadata/action/@type = "invented-type"invalide (L877 – dans les sources 1.2.1 et 1.2.2)valide, quittez 0 (JSON et XML)invalide, sortie 1
R5Le SSP met en œuvre ac-99, absent de la ligne de base résolueprose interprétativevalide, sortie 0avertissement d'adhésion SSP-003.b
R6Modification du profil ajoute prop status="operational" au contrôle résolusortie résolue invalide (L289)résoudre la sortie 0 – puis rejette sa propre sortie lors de la validationrefuse d'écrire la sortie
R7Catalogue NIST SP 800-53 rev5, non modifiévalidevalide, sortie 0n'était pas valide – notre bug, corrigé le jour même ; maintenant valide

Trois modèles, honnêtement séparés : R1–R3 sont de purs différentiels de liaisons obsolètes – 1.2.2 a modifié exactement deux contraintes au-delà des changements de version, tous deux dans le modèle SSP, et Java est du mauvais côté des trois comportements observables (un faux négatif, deux faux positifs, l'un d'eux se trompant sur l'absence de champ facultatif). R4 est un écart d'application indépendant du biais de version : le texte de contrainte est identique en octets dans les sources intégrées par Java - et la classe affectée est entièrement mappée : une énumération mécanique sur l'inventaire épinglé montre exactement 2 des 200 indicateurs cibles d'occurrences de valeurs autorisées actives ; le seul membre de niveau d'erreur est celui testé en direct, donc pas de non testé le reste existe. R5 est un écart de capacité, pas un défaut – et notre vérification reste un avertissement d'adhésion car la source est de la prose, pas une contrainte machine. R6 et R7 ont coupé notre chemin en premier et ont été réparés le même jour ; ils restent dans le tableau car un harnais différentiel qui ne trouve que les bugs de l'autre côté n'est pas un harnais.

Ce que nous ne prétendons délibérément pas

  • La spécification de résolution de profil est projet ; Le comportement de la famille PRES est fonction des fonctionnalités et les contraintes de niveau AVERTISSEMENT NIST restent des avertissements.
  • Les règles de workflow sont des interprétations de relations documentées, marquées comme telles, désactivées par défaut.
  • Les preuves de comparaison du registre restent étiquetées comme ayant été inspectées à la source ; l'exécution différentielle en direct le complète avec des reçus exécutés et épinglés par hachage, mais n'améliore pas silencieusement le niveau de preuve du registre – le pliage des transcriptions dans la porte de qualification formelle est suivi séparément.
  • 34 contraintes imposées par l'exécution attendent une révision de la portée avant d'obtenir des assertions de registre de première classe ; leur application d'exécution n'est pas affectée.
  • L'hébergeur API de validation expose actuellement le niveau du schéma ; la couche de contrainte sémantique décrite ici est livrée avec une version ultérieure de l'API.

Annexe : références épinglées

  • Sources OSCAL : usnistgov/OSCAL @ 21403b4ad2f162ef1201e5ee70e8b93f254f51ac (v1.2.2) – Métaschémas, schémas JSON, projet de spécification de résolution de profil
  • Versions OSCAL prises en charge : 1.1.2, 1.1.3, 1.2.1, 1.2.2 (cible sémantique : 1.2.2)
  • Documentation du modèle : https://pages.nist.gov/OSCAL/
  • Comparateur : Java OSCAL CLI 3.2.0 / liboscal-java 7.2.0 (liaison OSCAL 1.2.1)
  • Acceptation lisible par machine : validation/requirements.json (42 exigences / 93 affirmations), validation/capabilities.json (22 contrats de capacité), validation/completeness-closure.json (348 occurrences), validation/scope-lock.json
  • Vérification : plus de 1 000 tests ; pnpm verify (vérification de type → tests → 13 portes d'artefacts générés → construction → vérifications de packages → fumée)