{
  "$schema": "https://cyclonedx.org/schema/bom-1.7.schema.json",
  "bomFormat": "CycloneDX",
  "specVersion": "1.7",
  "serialNumber": "urn:uuid:333295bf-a60e-4b65-ae07-27c15447b306",
  "version": 1,
  "metadata": {
    "timestamp": "2026-07-11T00:00:00Z",
    "authors": [
      {
        "name": "Hypermedia Au Security Team"
      }
    ],
    "component": {
      "type": "data",
      "name": "Finding Approval Specification",
      "version": "1.0.0"
    },
    "properties": [
      {
        "name": "cyberbench:artifact-kind",
        "value": "attestation (declarations document; the checker side of maker-checker; L2)"
      },
      {
        "name": "cyberbench:fullname",
        "value": "Finding Approval (maker-checker; approver B distinct from author A)"
      },
      {
        "name": "cyberbench:claim-predicates",
        "value": "finding-approved,finding-rejected,changes-requested"
      }
    ]
  },
  "definitions": {
    "standards": [
      {
        "bom-ref": "finding-approval-v1.0.0",
        "name": "Hypermedia Security: Finding Approval Specification",
        "version": "1.0.0",
        "description": "The finding-approval attestation: the checker side of maker-checker. The author signs the finding and its analysis-provenance (the maker side); here a second, cryptographically distinct identity signs the review outcome. Three predicates: finding-approved (terminal, positive), finding-rejected (terminal, negative), changes-requested (non-terminal — a signed send-back that bumps the finding version and re-enters review). approver-not-equal-author is enforced by comparing two Fulcio-verified identities, never name strings. The invariant every downstream object leans on: a finding version entering a publication must carry exactly one current terminal finding-approved from an identity distinct from its author.",
        "owner": "Hypermedia Au",
        "externalReferences": [
          {
            "type": "other",
            "url": "https://sec.hypermedia.au/attestations/finding-approval/v1",
            "comment": "The attestation schema enforcing this standard.",
            "properties": [
              {
                "name": "cyberbench:role",
                "value": "attestation-schema"
              }
            ]
          },
          {
            "type": "other",
            "url": "https://sec.hypermedia.au/standards/finding/v1",
            "comment": "cyberbench:approvalRef",
            "properties": [
              {
                "name": "cyberbench:role",
                "value": "referenced-from"
              }
            ]
          },
          {
            "type": "other",
            "url": "https://sec.hypermedia.au/standards/analysis-provenance/v1",
            "comment": "the maker side of maker-checker",
            "properties": [
              {
                "name": "cyberbench:role",
                "value": "references"
              }
            ]
          },
          {
            "type": "documentation",
            "url": "https://www.iso.org/standard/44408.html",
            "comment": "ISO/IEC 27042:2015 §6.4 — the review record: contemporaneous notes of actions, results, decisions taken and reasons (the reasoning field is the reviewer's structured form of this); verified against the standard text 2026-07-11 (SPEC-9 note)"
          },
          {
            "type": "documentation",
            "url": "https://www.rfc-editor.org/rfc/rfc2119",
            "comment": "RFC 2119 (as clarified by RFC 8174) — requirement key words; only capitalised forms are normative"
          },
          {
            "type": "website",
            "url": "https://sec.hypermedia.au"
          }
        ],
        "requirements": [
          {
            "bom-ref": "approver-identity",
            "identifier": "FAPP-001",
            "title": "Approver Identity",
            "text": "assessors[] MUST identify the approver (approver B), and the attestation MUST be signed by that identity (Fulcio-verified).",
            "descriptions": [
              "The reviewer is a named, cryptographically bound actor: the identity in assessors[] is the identity on the signature. Who reviewed is as much a part of the record as what they decided."
            ],
            "parent": "finding-approval-v1.0.0",
            "properties": [
              {
                "name": "requirement-uri",
                "value": "https://sec.hypermedia.au/standards/finding-approval/v1#approver-identity"
              },
              {
                "name": "validation-method",
                "value": "certificate-identity-comparison"
              }
            ]
          },
          {
            "bom-ref": "target-finding-reference",
            "identifier": "FAPP-002",
            "title": "Target Finding Reference",
            "text": "The attestation MUST carry exactly one claim whose target is the L2 Finding by BOM-Link and paired hash. The hash binds the approval to the exact finding version reviewed.",
            "descriptions": [
              "The paired hash is what makes the approval version-specific: it approves the bytes that were reviewed, not a mutable pointer. A later finding version is a different object with its own approval."
            ],
            "parent": "finding-approval-v1.0.0",
            "properties": [
              {
                "name": "requirement-uri",
                "value": "https://sec.hypermedia.au/standards/finding-approval/v1#target-finding-reference"
              },
              {
                "name": "validation-method",
                "value": "cross-reference"
              }
            ]
          },
          {
            "bom-ref": "approver-distinct-from-author",
            "identifier": "FAPP-003",
            "title": "Approver Distinct From Author",
            "text": "The approver's Fulcio identity MUST differ from the finding author's. This MUST be enforced by comparing two Fulcio-verified identities, never by comparing name strings, and MUST be asserted as a map row. The verifier performs the comparison against the finding's author identity; the schema alone cannot.",
            "descriptions": [
              "Maker-checker is the single-author-fraud control: the person who made a finding cannot be the person who approves it for disclosure. Binding on cryptographic identity, not a name, is what makes 'a different person' unfakeable — a renamed account is still the same key."
            ],
            "parent": "finding-approval-v1.0.0",
            "properties": [
              {
                "name": "requirement-uri",
                "value": "https://sec.hypermedia.au/standards/finding-approval/v1#approver-distinct-from-author"
              },
              {
                "name": "validation-method",
                "value": "certificate-identity-comparison (verifier)"
              }
            ]
          },
          {
            "bom-ref": "approval-predicate",
            "identifier": "FAPP-004",
            "title": "Approval Predicate",
            "text": "The claim predicate MUST be exactly one of: finding-approved (terminal, positive), finding-rejected (terminal, negative), changes-requested (non-terminal, returns to the author). Closed set. changes-requested MUST bump the Finding BOM version.",
            "descriptions": [
              "The three outcomes are the review state machine's transitions. finding-approved and finding-rejected are terminal; changes-requested is a signed send-back — signing it is intentional, producing a defensible record of substantive iterative review rather than an untracked back-channel. A rejected finding is kept, marked rejected; nothing is deleted."
            ],
            "parent": "finding-approval-v1.0.0",
            "properties": [
              {
                "name": "requirement-uri",
                "value": "https://sec.hypermedia.au/standards/finding-approval/v1#approval-predicate"
              },
              {
                "name": "validation-method",
                "value": "schema"
              },
              {
                "name": "allowed-values",
                "value": "finding-approved,finding-rejected,changes-requested"
              },
              {
                "name": "terminal",
                "value": "finding-approved,finding-rejected"
              },
              {
                "name": "non-terminal",
                "value": "changes-requested"
              },
              {
                "name": "vocabulary",
                "value": "closed (locked v1.0.0)"
              }
            ]
          },
          {
            "bom-ref": "approval-rationale",
            "identifier": "FAPP-005",
            "title": "Approval Rationale",
            "text": "The claim MUST carry a non-empty reasoning field stating the basis for the outcome. The rationale is required for every predicate, including changes-requested.",
            "descriptions": [
              "The rationale is the review's substance, not a formality: it is what an auditor reads to see that a real second look happened. ISO/IEC 27042 §6.4 requires records of decisions taken and reasons; the reviewer's reasoning is that record for the approval decision."
            ],
            "parent": "finding-approval-v1.0.0",
            "properties": [
              {
                "name": "requirement-uri",
                "value": "https://sec.hypermedia.au/standards/finding-approval/v1#approval-rationale"
              },
              {
                "name": "validation-method",
                "value": "schema"
              },
              {
                "name": "iso-basis",
                "value": "ISO/IEC 27042 §6.4 (decisions taken and reasons)"
              }
            ]
          },
          {
            "bom-ref": "supersession-and-invariant",
            "identifier": "FAPP-006",
            "title": "Supersession And Publication Invariant",
            "text": "A changes-requested outcome MUST result in a new signed Finding version that links to and supersedes the version it replaces; the superseded version is kept and marked superseded, never edited in place. A finding version composed into a Publication MUST carry exactly one current terminal finding-approved from an identity distinct from its author; a finding whose only approval is changes-requested or finding-rejected MUST NOT be disclosed.",
            "descriptions": [
              "This is the rule the publication layer enforces at composition time: nothing reaches a report without a live, distinct-identity approval. Revision as a new object (rather than an edit) is what keeps the history intact — the review trail shows every version and every outcome, so a challenge to 'what changed and why' is answered from the record."
            ],
            "parent": "finding-approval-v1.0.0",
            "properties": [
              {
                "name": "requirement-uri",
                "value": "https://sec.hypermedia.au/standards/finding-approval/v1#supersession-and-invariant"
              },
              {
                "name": "validation-method",
                "value": "cross-reference (verifier)"
              },
              {
                "name": "enforced-at",
                "value": "publication composition (publication/v1); finding versioning (finding/v1)"
              }
            ]
          }
        ]
      }
    ]
  }
}
