Austauschformat grcaplaneth-audit/1 – Leitfaden für Entwickler von Revisionssoftware

Stand: 25.10.2026

GRCA-Planeth exportiert ein Prüfungskonzept als JSON-Datei im Format grcaplaneth-audit/1: die geplante Prüfung (Audit) mit ihren Prüfungshandlungen (Audit Tasks), den geprüften Anforderungen und deren Bewertungsgrundlage. Die Prüferin oder der Prüfer lädt die Datei in GRCA-Planeth herunter und lädt sie in die Revisionssoftware hoch. Dieser Leitfaden beschreibt das Dateiformat und die Import-Regeln so genau, dass eine Revisionssoftware die Datei einlesen und bei jedem erneuten Hochladen aktualisieren kann.

Die Datei

Jede Datei enthält genau ein Prüfungskonzept als ein JSON-Objekt.

Eigenschaft Wert
Entstehung In GRCA-Planeth im Prüfungskonzept über Für Revisionssoftware exportieren
Dateiname <Schlüssel des Konzepts>.grcaplaneth-audit.json, z. B. AU-52.grcaplaneth-audit.json; ohne Schlüssel Audit-Concept-<ID>.grcaplaneth-audit.json. Der Name trägt keine Bedeutung für den Import.
Kodierung UTF-8 ohne BOM; Umlaute stehen unverändert, nicht als \u-Escape
Formatierung eingerückt mit 2 Leerzeichen; für den Import ohne Bedeutung
Medientyp application/json
  • Inhalt nach Berechtigung: Die Datei enthält nur, was die exportierende Person in GRCA-Planeth sehen darf. Verknüpfte Einträge ohne Leserecht fehlen ohne Hinweis.
  • Sprache: Titel und Beschreibungen stehen in der Sprache, in der sie in GRCA-Planeth gepflegt sind. Bei übersetzten Rechtstexten, etwa EU-Recht, gilt die Sprache, die die exportierende Person in GRCA-Planeth für Rechtstexte gewählt hat.
  • Stand: Die Datei gibt den Stand zum Exportzeitpunkt wieder (metadata.generated). Spätere Änderungen erreichen die Revisionssoftware erst mit dem nächsten Export.

Aufbau

Ein Dokument ist ein JSON-Objekt mit genau diesen neun Feldern; alle sind Pflicht.

Feld Typ Inhalt
format String immer grcaplaneth-audit/1
uuid UUID ID des Prüfungskonzepts
metadata Objekt Titel, Exportzeitpunkt, Erzeuger, Projekt
audit_concept Objekt das Prüfungskonzept
audit_object Objekt das geprüfte Audit-Objekt, z. B. ein Prozess oder IT-System
scales Objekt die drei Bewertungsskalen risk, regulation, requirement
subjects Array geprüfte Gegenstände: Regulierungen, Risiken, Standards
requirements Array alle Anforderungen des Audit-Objekts, berücksichtigt oder nicht
audit Objekt die geplante Prüfung mit ihren Prüfungshandlungen tasks
Querverweise: Tasks verweisen per uuid auf Requirements, Requirements auf Subjects; jede Stufe stammt aus scales
Querverweise zwischen tasks, requirements, subjects und scales

Querverweise innerhalb des Dokuments laufen immer über uuid; issue_id verweist zurück auf GRCA-Planeth. Die Beschreibung der Assessment Procedure steckt eingebettet in der Task, nicht in einem eigenen Array.

Feldreferenz

Pflicht = das Schema verlangt das Feld; „immer“ = GRCA-Planeth schreibt es stets, das Schema erlaubt aber sein Fehlen. Kein Objekt enthält weitere Felder als die hier genannten.

Gemeinsame Typen

UUID: String, kleingeschrieben, Muster ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$.

Issue – ein Eintrag aus GRCA-Planeth (Konzept, Audit-Objekt, Anforderung, Assessment Procedure):

Feld Typ Pflicht Bedeutung
issue_id Integer ≥ 1 ja ID in GRCA-Planeth
issuekey String oder null immer lesbarer Schlüssel, z. B. AU-12; null, wenn keiner vergeben ist
title String ja Titel
description String ja Klartext; eine Zeile je Absatz oder Listenpunkt, getrennt durch \n; leer, wenn keine Beschreibung
description_html String ja dieselbe Beschreibung als bereinigtes HTML, wie GRCA-Planeth sie speichert; leer, wenn keine

Stufe – eine Stufe einer Bewertungsskala, wie sie importance und rating nennen:

Feld Typ Pflicht Bedeutung
code String, nicht leer ja ID der Stufe in ihrer Skala, z. B. 3 oder H
label String, nicht leer ja Bezeichnung, z. B. Hoch
weight Zahl ja Gewicht; höher = wichtiger; bis zu 2 Nachkommastellen

metadata

Feld Typ Pflicht Bedeutung
title String, nicht leer ja Titel des Prüfungskonzepts
generated String, ISO 8601 mit Zeitzone ja Exportzeitpunkt in UTC, z. B. 2026-10-25T14:03:11.482913+00:00
generator String ja immer GRCA-Planeth
project String immer Name des Projekts (der Source), in dem das Konzept liegt

audit_concept und audit_object

Beide sind ein Issue. audit_concept hat zusätzlich status (String oder null, Pflicht), den Bearbeitungsstatus in GRCA-Planeth, z. B. Backlog.

scales

Ein Objekt mit genau den Schlüsseln risk, regulation und requirement. Jeder Wert ist ein Array mit mindestens einer Stufe in der Reihenfolge, die das Projekt festgelegt hat:

Feld Typ Pflicht Bedeutung
code String, nicht leer ja ID der Stufe, in der Skala eindeutig
label String, nicht leer ja Bezeichnung
weight Zahl ja Gewicht
description String ja Erläuterung; kann leer sein
color String #rrggbb, kleingeschrieben ja Farbe der Stufe in GRCA-Planeth

subjects[]

Jede Regulierung, jedes Risiko und jeder Standard, den mindestens eine Anforderung abdeckt, genau einmal. Subjects haben keine Beschreibung.

Feld Typ Pflicht Bedeutung
uuid UUID ja ID im Austauschformat
type regulation, risk oder standard ja Art des Gegenstands
issue_id Integer ja ID in GRCA-Planeth
issuekey String oder null immer lesbarer Schlüssel
title String ja Titel, z. B. Artikel 9 (4)
rating Stufe oder null ja Bewertung im Audit-Objekt; bei Standards immer null
rating_inherited_from Integer oder null immer issue_id der übergeordneten Regelung, deren Bewertung eine Unterregelung übernimmt; sonst null

requirements[]

Alle Anforderungen des Audit-Objekts, sortiert nach Titel. Jede ist ein Issue mit diesen weiteren Feldern (alle Pflicht):

Feld Typ Bedeutung
uuid UUID ID im Austauschformat
included Boolean true = wird geprüft
importance Stufe oder null geltende Bedeutung aus Skala requirement; null = nicht bewertet
proposed_importance Stufe oder null von GRCA-Planeth vorgeschlagene Bedeutung
deviates_from_proposal Boolean Prüfer ist bei Bedeutung oder Berücksichtigung vom Vorschlag abgewichen
justification String Begründung der Prüferin oder des Prüfers; leer, wenn keine
subjects Array von UUID die Subjects, welche die Anforderung abdeckt; kann leer sein
assessment_procedures Array von Integer issue_id der gewählten Assessment Procedures; auch bei nicht berücksichtigten Anforderungen möglich

audit

Feld Typ Pflicht Bedeutung
uuid UUID ja ID der Prüfung
issue_id Integer nein Issue „Audit“ in GRCA-Planeth, sobald dort erzeugt
issuekey String oder null nein dessen Schlüssel, zusammen mit issue_id
title String ja Titel der Prüfung (= Titel des Konzepts)
tasks Array ja Prüfungshandlungen, kann leer sein

audit.tasks[]

Sortiert nach importance.weight absteigend (null zählt wie Gewicht 0), dann nach Titel.

Feld Typ Pflicht Bedeutung
uuid UUID ja ID der Prüfungshandlung
issue_id Integer nein Issue „Audit Task“ in GRCA-Planeth, sobald dort erzeugt
title String ja Titel (= Titel der Assessment Procedure)
assessment_procedure Issue ja die Assessment Procedure mit Beschreibung, also das Prüfvorgehen
requirements Array von UUID, mind. 1 ja die berücksichtigten Anforderungen, die diese Task prüft
importance Stufe oder null ja höchste Bedeutung ihrer Anforderungen

Fachliche Regeln

Was geprüft wird, steht in requirements[].included; wie wichtig es ist, in importance. Beides ist bereits aufgelöst: Die Revisionssoftware muss nichts nachrechnen.

Bewertung der Subjects

  • Ein Risiko hat ein rating, wenn es mit dem Audit-Objekt verknüpft und dort bewertet ist; sonst null.
  • Eine Regulierung hat ihre eigene Bewertung oder, ohne eigene, die ihrer nächsten bewerteten übergeordneten Regelung; dann nennt rating_inherited_from deren issue_id.
  • Ein Standard wird nicht bewertet.

Vorschlag und Entscheidung

  1. GRCA-Planeth nimmt die höchste Bewertung (weight) unter den Risiken und Regulierungen einer Anforderung.
  2. proposed_importance ist die Stufe der Skala requirement mit dem höchsten Gewicht, das diese Bewertung erreicht; erreicht sie keines, die leichteste Stufe. Ohne Bewertung: null.
  3. Eine Anforderung mit Vorschlag wird zur Berücksichtigung vorgeschlagen, eine ohne nicht.
  4. Die Prüferin oder der Prüfer kann Stufe und Berücksichtigung ändern. importance und included enthalten, was gilt. Jede Abweichung setzt deviates_from_proposal und ist in justification begründet.

Wie Tasks entstehen

  • Je Assessment Procedure, die für mindestens eine berücksichtigte Anforderung gewählt ist, gibt es genau eine Task.
  • Prüft eine Procedure mehrere Anforderungen, nennt ihre Task alle in requirements.
  • Nicht berücksichtigte Anforderungen erzeugen keine Task, auch wenn bei ihnen Procedures gewählt sind.
  • importance der Task ist die höchste importance ihrer Anforderungen.
  • Eine berücksichtigte Anforderung ohne gewählte Procedure erscheint in keiner Task; die Revisionssoftware kann sie als offenen Punkt zeigen.

Import-Regeln

Ein Prüfungskonzept wird über Wochen geändert und mehrfach exportiert. Gleicht jeden Datensatz über seine uuid ab, nie über Titel oder Position.

Stabile IDs

Datensatz uuid entsteht aus bleibt gleich, solange
Prüfungskonzept (uuid oben) Zufallswert, in GRCA-Planeth gespeichert das Konzept existiert
Prüfung (audit.uuid) UUIDv5(Konzept-UUID, audit) das Konzept existiert
Task UUIDv5(Konzept-UUID, task:<issue_id der Procedure>) dieselbe Procedure gewählt ist
Anforderung UUIDv5(Konzept-UUID, requirement:<issue_id>) sie zum Audit-Objekt gehört
Subject UUIDv5(Konzept-UUID, subject:<issue_id>) eine Anforderung es abdeckt

UUIDs sind über Konzepte hinweg eindeutig: Dieselbe Anforderung hat in zwei Konzepten zwei verschiedene uuid. Die Kopie eines Audit-Objekts in GRCA-Planeth erhält ein neues Konzept mit neuen UUIDs. Die Ableitung dient nur zur Erklärung; verwendet die gelieferten Werte.

Abgleich bei erneutem Import

  1. Konzept über die oberste uuid finden; unbekannt = neues Konzept anlegen.
  2. Prüfung, Tasks, Anforderungen und Subjects über ihre uuid aktualisieren oder neu anlegen.
  3. Datensätze, die im neuen Export fehlen, als entfallen markieren, nicht löschen: An einer Task kann bereits geprüft worden sein. GRCA-Planeth verfährt mit seinen eigenen Audit Tasks ebenso.
  4. Eine Task entfällt, wenn ihre Procedure abgewählt oder alle ihre Anforderungen ausgeschlossen werden; eine Anforderung, wenn sie aus dem Audit-Objekt entfernt wird.

Änderungen erkennen

Bei unverändertem Stand ergeben zwei Exporte inhaltlich dieselbe Datei. Sie unterscheiden sich nur in metadata.generated, und die Reihenfolge der Schlüssel in JSON-Objekten (etwa in scales) ist nicht festgelegt. Die Reihenfolge der Arrays ist dagegen stabil. Die Datei trägt keinen Versionszähler: Wer erkennen will, ob eine hochgeladene Datei etwas ändert, bildet einen Hash über das Dokument mit sortierten Schlüsseln und ohne metadata.generated.

Formatversion

  • Prüft format auf genau grcaplaneth-audit/1 und weist Dateien mit anderem Wert ab.
  • Innerhalb von Version 1 kommen höchstens optionale Felder hinzu; ignoriert unbekannte Felder. Wer streng gegen eine lokal gespeicherte Kopie des Schemas validiert, aktualisiert diese mit jeder neuen Fassung dieses Leitfadens.
  • Entfernte, umbenannte oder anders bedeutete Felder führen zu grcaplaneth-audit/2.

Vollständiges Beispiel

Das folgende Dokument hat die Export-Funktion von GRCA-Planeth erzeugt; es ist gegen das Schema geprüft. Es enthält:

  • eine berücksichtigte Anforderung mit zwei Tasks,
  • eine ausgeschlossene Anforderung mit Begründung,
  • eine Regulierung, die ihre Bewertung erbt,
  • eine Prüfung, die in GRCA-Planeth bereits als Issue existiert. Nur die zweite Task wurde dort schon angelegt, die erste kam danach hinzu und hat deshalb noch keine issue_id.
{
  "format": "grcaplaneth-audit/1",
  "uuid": "3f2b8c4e-9d1a-4b6e-8f7c-2a5d9e0b1c34",
  "metadata": {
    "title": "Prüfungskonzept IAM 2026",
    "generated": "2026-10-25T14:03:11+00:00",
    "generator": "GRCA-Planeth",
    "project": "Interne Revision"
  },
  "audit_concept": {
    "issue_id": 196002,
    "issuekey": "AU-52",
    "title": "Prüfungskonzept IAM 2026",
    "description": "Prüfung des Identity & Access Managements im Geschäftsjahr 2026.",
    "description_html": "<p>Prüfung des Identity &amp; Access Managements im Geschäftsjahr 2026.</p>",
    "status": "Backlog"
  },
  "audit_object": {
    "issue_id": 3660,
    "issuekey": "AU-1",
    "title": "Identity & Access Management",
    "description": "Prozesse und Verfahren zur Identifizierung, Authentifizierung und Autorisierung.",
    "description_html": "<p>Prozesse und Verfahren zur Identifizierung, Authentifizierung und Autorisierung.</p>"
  },
  "scales": {
    "risk": [
      { "code": "1", "label": "Gering", "weight": 1.0, "description": "", "color": "#5aa469" },
      { "code": "2", "label": "Mittel", "weight": 2.0, "description": "", "color": "#e3b505" },
      { "code": "3", "label": "Hoch", "weight": 3.0, "description": "", "color": "#e8833a" },
      { "code": "4", "label": "Sehr hoch", "weight": 4.0, "description": "", "color": "#c8423b" }
    ],
    "regulation": [
      { "code": "1", "label": "Niedrig", "weight": 1.0, "description": "", "color": "#9dbbe0" },
      { "code": "2", "label": "Mittel", "weight": 2.0, "description": "", "color": "#4f86c6" },
      { "code": "3", "label": "Hoch", "weight": 3.0, "description": "", "color": "#1f4e8c" }
    ],
    "requirement": [
      { "code": "1", "label": "Gering", "weight": 1.0, "description": "Kann im Prüfungskonzept entfallen.", "color": "#8fbf9f" },
      { "code": "2", "label": "Mittel", "weight": 2.0, "description": "Stichprobenartig prüfen.", "color": "#d9b44a" },
      { "code": "3", "label": "Hoch", "weight": 3.0, "description": "Im Prüfungskonzept vorsehen.", "color": "#d9773a" },
      { "code": "4", "label": "Sehr hoch", "weight": 4.0, "description": "Vorrangig und vollständig prüfen.", "color": "#b8322d" }
    ]
  },
  "subjects": [
    {
      "uuid": "b6d3a015-b15b-55e4-a286-b5b01cb45a6a",
      "type": "regulation",
      "issue_id": 30411,
      "issuekey": null,
      "title": "Artikel 9 (4)",
      "rating": { "code": "3", "label": "Hoch", "weight": 3.0 },
      "rating_inherited_from": 30402
    },
    {
      "uuid": "418585cb-5865-511e-8a35-41a4d9e55ed8",
      "type": "risk",
      "issue_id": 5402,
      "issuekey": "AU-31",
      "title": "Unberechtigte Zugriffe durch verwaiste Konten",
      "rating": { "code": "3", "label": "Hoch", "weight": 3.0 },
      "rating_inherited_from": null
    },
    {
      "uuid": "f21ca482-7b5a-56b3-9ada-788afa08a43a",
      "type": "standard",
      "issue_id": 81233,
      "issuekey": null,
      "title": "ISO/IEC 27001 A.5.18 Zugangsrechte",
      "rating": null,
      "rating_inherited_from": null
    }
  ],
  "requirements": [
    {
      "uuid": "5da9c3ff-51c0-52cd-889e-f6386ea4affe",
      "issue_id": 5488,
      "issuekey": "AU-10",
      "title": "IAM – Rezertifizierung der Zugriffsrechte",
      "description": "jährliche Rezertifizierung\nEntzug nicht bestätigter Rechte",
      "description_html": "<ul><li>jährliche Rezertifizierung</li><li>Entzug nicht bestätigter Rechte</li></ul>",
      "included": true,
      "importance": { "code": "3", "label": "Hoch", "weight": 3.0 },
      "proposed_importance": { "code": "3", "label": "Hoch", "weight": 3.0 },
      "deviates_from_proposal": false,
      "justification": "",
      "subjects": [
        "b6d3a015-b15b-55e4-a286-b5b01cb45a6a",
        "418585cb-5865-511e-8a35-41a4d9e55ed8",
        "f21ca482-7b5a-56b3-9ada-788afa08a43a"
      ],
      "assessment_procedures": [5500, 5501]
    },
    {
      "uuid": "43da23e2-e523-52c7-a76a-32dd6d8fbaf6",
      "issue_id": 5489,
      "issuekey": "AU-11",
      "title": "IAM – Aufbewahrung von Berechtigungsnachweisen",
      "description": "",
      "description_html": "",
      "included": false,
      "importance": { "code": "3", "label": "Hoch", "weight": 3.0 },
      "proposed_importance": { "code": "3", "label": "Hoch", "weight": 3.0 },
      "deviates_from_proposal": true,
      "justification": "Im Vorjahr ohne Feststellungen geprüft.",
      "subjects": ["b6d3a015-b15b-55e4-a286-b5b01cb45a6a"],
      "assessment_procedures": []
    }
  ],
  "audit": {
    "uuid": "3982c91b-4164-55fb-aab8-bf5f79ce4891",
    "issue_id": 196014,
    "issuekey": "AU-60",
    "title": "Prüfungskonzept IAM 2026",
    "tasks": [
      {
        "uuid": "7eb40882-ae06-528a-9f8b-6a510ee58dff",
        "title": "Berechtigungen regelmäßig rezertifizieren",
        "assessment_procedure": {
          "issue_id": 5500,
          "issuekey": "AU-39",
          "title": "Berechtigungen regelmäßig rezertifizieren",
          "description": "Zugriffsrechte werden mindestens jährlich durch die Fachverantwortlichen bestätigt.",
          "description_html": "<p>Zugriffsrechte werden mindestens jährlich durch die Fachverantwortlichen bestätigt.</p>"
        },
        "requirements": ["5da9c3ff-51c0-52cd-889e-f6386ea4affe"],
        "importance": { "code": "3", "label": "Hoch", "weight": 3.0 }
      },
      {
        "uuid": "c90da492-2c8a-5516-8b4c-ab7e8bea6fa1",
        "issue_id": 196015,
        "title": "Stichprobe privilegierter Konten",
        "assessment_procedure": {
          "issue_id": 5501,
          "issuekey": "AU-40",
          "title": "Stichprobe privilegierter Konten",
          "description": "25 privilegierte Konten gegen die Genehmigungen abgleichen.",
          "description_html": "<p>25 privilegierte Konten gegen die Genehmigungen abgleichen.</p>"
        },
        "requirements": ["5da9c3ff-51c0-52cd-889e-f6386ea4affe"],
        "importance": { "code": "3", "label": "Hoch", "weight": 3.0 }
      }
    ]
  }
}

Validierung und Checkliste

Das Schema im Anhang ist JSON Schema Draft 2020-12; jeder Validator dieser Version prüft eine Datei vollständig. Speichert es als grcaplaneth-audit-1.schema.json. Seine $id ist nur ein Bezeichner, keine Abrufadresse. Beispiel in Python:

import json
import jsonschema

with open("grcaplaneth-audit-1.schema.json", encoding="utf-8") as file:
    schema = json.load(file)
with open("AU-52.grcaplaneth-audit.json", encoding="utf-8") as file:
    document = json.load(file)

if document.get("format") != "grcaplaneth-audit/1":
    raise ValueError("Kein Prüfungskonzept im Format grcaplaneth-audit/1")
jsonschema.Draft202012Validator(schema).validate(document)

Vor dem ersten produktiven Import:

  • ☐ Hochgeladene Datei als UTF-8 gelesen
  • ☐ format geprüft und Datei gegen das Schema validiert
  • ☐ Alle Datensätze per uuid abgeglichen, nicht per Titel oder issue_id
  • ☐ Erneutes Hochladen derselben oder einer neueren Datei aktualisiert, statt zu verdoppeln
  • ☐ Fehlende Datensätze als entfallen markiert statt gelöscht
  • ☐ Unbekannte Felder werden ignoriert
  • ☐ importance: null und rating: null werden angezeigt, ohne Fehler
  • ☐ Berücksichtigte Anforderungen ohne Task werden als offener Punkt sichtbar

Fragen zum Format beantwortet der Betreiber der GRCA-Planeth-Instanz, aus der die Datei stammt.

Anhang: JSON-Schema

Das verbindliche Schema für grcaplaneth-audit/1, Stand 2026-10-25. Speichert es als grcaplaneth-audit-1.schema.json.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://grca.planeth.de/schema/grcaplaneth-audit-1.schema.json",
  "title": "GRCA-Planeth audit concept, format 1",
  "description": "An Audit Concept with the audit it plans, for audit management software. Modelled on the OSCAL Assessment Plan: subjects (what is assessed), requirements (the reviewed controls) and tasks (one per assessment procedure). Every uuid stays the same when the concept is exported again, so an import can update instead of duplicate.",
  "type": "object",
  "required": ["format", "uuid", "metadata", "audit_concept", "audit_object", "scales", "subjects", "requirements", "audit"],
  "additionalProperties": false,
  "properties": {
    "format": { "const": "grcaplaneth-audit/1" },
    "uuid": {
      "description": "The Audit Concept's stable ID.",
      "$ref": "#/$defs/uuid"
    },
    "metadata": {
      "type": "object",
      "required": ["title", "generated", "generator"],
      "additionalProperties": false,
      "properties": {
        "title": { "$ref": "#/$defs/text" },
        "generated": {
          "description": "When the document was written (ISO 8601 with time zone).",
          "type": "string",
          "format": "date-time"
        },
        "generator": { "const": "GRCA-Planeth" },
        "project": {
          "description": "The project (source) the concept belongs to.",
          "type": "string"
        }
      }
    },
    "audit_concept": {
      "allOf": [{ "$ref": "#/$defs/issue" }],
      "properties": {
        "status": { "type": ["string", "null"] }
      },
      "unevaluatedProperties": false
    },
    "audit_object": {
      "description": "What is audited, e.g. a process or an IT system.",
      "allOf": [{ "$ref": "#/$defs/issue" }],
      "unevaluatedProperties": false
    },
    "scales": {
      "description": "The rating scales used: risk and regulation for the subjects, requirement for the importance of requirements and tasks.",
      "type": "object",
      "required": ["risk", "regulation", "requirement"],
      "additionalProperties": false,
      "properties": {
        "risk": { "$ref": "#/$defs/scale" },
        "regulation": { "$ref": "#/$defs/scale" },
        "requirement": { "$ref": "#/$defs/scale" }
      }
    },
    "subjects": {
      "description": "The regulations, risks and standards the requirements address.",
      "type": "array",
      "items": {
        "type": "object",
        "required": ["uuid", "type", "issue_id", "title", "rating"],
        "additionalProperties": false,
        "properties": {
          "uuid": { "$ref": "#/$defs/uuid" },
          "type": { "enum": ["regulation", "risk", "standard"] },
          "issue_id": { "$ref": "#/$defs/issue_id" },
          "issuekey": { "$ref": "#/$defs/issuekey" },
          "title": { "type": "string" },
          "rating": {
            "description": "The rating in the Audit Object; standards are not rated.",
            "oneOf": [{ "$ref": "#/$defs/level" }, { "type": "null" }]
          },
          "rating_inherited_from": {
            "description": "issue_id of the parent regulation whose rating a sub-regulation has.",
            "oneOf": [{ "$ref": "#/$defs/issue_id" }, { "type": "null" }]
          }
        }
      }
    },
    "requirements": {
      "description": "Every requirement of the Audit Object, included in the audit or not.",
      "type": "array",
      "items": {
        "allOf": [{ "$ref": "#/$defs/issue" }],
        "required": ["uuid", "included", "importance", "proposed_importance", "deviates_from_proposal", "justification", "subjects", "assessment_procedures"],
        "properties": {
          "uuid": { "$ref": "#/$defs/uuid" },
          "included": {
            "description": "Whether the requirement is audited.",
            "type": "boolean"
          },
          "importance": {
            "description": "The level that applies: the auditor's, else the proposal.",
            "oneOf": [{ "$ref": "#/$defs/level" }, { "type": "null" }]
          },
          "proposed_importance": {
            "description": "Derived from the heaviest rating of the requirement's risks and regulations.",
            "oneOf": [{ "$ref": "#/$defs/level" }, { "type": "null" }]
          },
          "deviates_from_proposal": { "type": "boolean" },
          "justification": {
            "description": "Why the auditor deviated from the proposal (or a remark).",
            "type": "string"
          },
          "subjects": {
            "description": "uuids of the subjects the requirement addresses.",
            "type": "array",
            "items": { "$ref": "#/$defs/uuid" }
          },
          "assessment_procedures": {
            "description": "issue_ids of the chosen assessment procedures.",
            "type": "array",
            "items": { "$ref": "#/$defs/issue_id" }
          }
        },
        "unevaluatedProperties": false
      }
    },
    "audit": {
      "description": "The audit planned by the concept.",
      "type": "object",
      "required": ["uuid", "title", "tasks"],
      "additionalProperties": false,
      "properties": {
        "uuid": { "$ref": "#/$defs/uuid" },
        "issue_id": {
          "description": "The Audit issue in GRCA-Planeth, once created from the concept.",
          "$ref": "#/$defs/issue_id"
        },
        "issuekey": { "$ref": "#/$defs/issuekey" },
        "title": { "type": "string" },
        "tasks": {
          "description": "One Audit Task per assessment procedure chosen for an included requirement, the most important first.",
          "type": "array",
          "items": {
            "type": "object",
            "required": ["uuid", "title", "assessment_procedure", "requirements", "importance"],
            "additionalProperties": false,
            "properties": {
              "uuid": { "$ref": "#/$defs/uuid" },
              "issue_id": {
                "description": "The Audit Task issue in GRCA-Planeth, once created from the concept.",
                "$ref": "#/$defs/issue_id"
              },
              "title": { "type": "string" },
              "assessment_procedure": {
                "allOf": [{ "$ref": "#/$defs/issue" }],
                "unevaluatedProperties": false
              },
              "requirements": {
                "description": "uuids of the included requirements the task assesses.",
                "type": "array",
                "minItems": 1,
                "items": { "$ref": "#/$defs/uuid" }
              },
              "importance": {
                "description": "The highest importance of its requirements.",
                "oneOf": [{ "$ref": "#/$defs/level" }, { "type": "null" }]
              }
            }
          }
        }
      }
    }
  },
  "$defs": {
    "text": { "type": "string", "minLength": 1 },
    "uuid": {
      "type": "string",
      "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
    },
    "issue_id": {
      "description": "The issue's id in GRCA-Planeth.",
      "type": "integer",
      "minimum": 1
    },
    "issuekey": { "type": ["string", "null"] },
    "issue": {
      "type": "object",
      "required": ["issue_id", "title", "description", "description_html"],
      "properties": {
        "issue_id": { "$ref": "#/$defs/issue_id" },
        "issuekey": { "$ref": "#/$defs/issuekey" },
        "title": { "type": "string" },
        "description": {
          "description": "Plain text, one line per paragraph or list item.",
          "type": "string"
        },
        "description_html": { "type": "string" }
      }
    },
    "level": {
      "type": "object",
      "required": ["code", "label", "weight"],
      "additionalProperties": false,
      "properties": {
        "code": { "$ref": "#/$defs/text" },
        "label": { "$ref": "#/$defs/text" },
        "weight": { "type": "number" }
      }
    },
    "scale": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["code", "label", "weight", "description", "color"],
        "additionalProperties": false,
        "properties": {
          "code": { "$ref": "#/$defs/text" },
          "label": { "$ref": "#/$defs/text" },
          "weight": { "type": "number" },
          "description": { "type": "string" },
          "color": { "type": "string", "pattern": "^#[0-9a-f]{6}$" }
        }
      }
    }
  }
}