Skip to content
Reference

Case Model Fields

This page lists the fields of the core domain objects that make up a Vultron case, as the reference implementation defines them in vultron/core/models/. For what these objects are for and how a case uses them, read The Case Model first. For how the same objects appear on the wire, see Vultron AS Objects.

Implementation fields, not wire properties

The names below are the Python field names. On the wire they are rendered in camelCase, and fields the implementation keeps only for its own bookkeeping are not sent.

VulnerabilityCase

Defined in vultron/core/models/case.py.

Field Description
attributed_to The case owner: set when the case is created, where it is an input to genesis_hash, and changed to the new owner when an ownership transfer is accepted (CM-21-002). Required: a case without an owner is refused when it is built, loaded or received (ARCH-10-001)
case_participants CaseParticipant records (or their URIs)
actor_participant_index Fast-lookup map: actor URI → participant URI
vulnerability_reports Reports associated with this case (objects or URIs)
case_statuses Append-only history of CaseStatus snapshots
notes URIs of notes attached to the case
embargo_register One entry per embargo ever proposed on the case, appended and never removed: the embargo (object or URI), its status (PROPOSED, ACTIVE, REJECTED, SUPERSEDED, CANCELLED or TERMINATED) and the embargo an activated revision replaced. The case's Embargo Management (EM) state, its active embargo and its open proposals are all read from it (ADR-0122)
pending_embargo_proposal_index Map: embargo URI → the proposal activity that offered it, for open proposals only
case_activity Activity IDs recorded against this case (not the case ledger — see genesis_hash)
genesis_hash SHA-256 hash binding the ledger to this case's origin identity: the case id, creation time and owner (attributed_to), computed when the case is created; a replica keeps the hash it receives, or derives the same value from the carried case when none arrives (CLP-08-002)
ledger_position The ledger position the case file is a projection of: the log_index and entry_hash of the last ledger entry applied to it, or log_index -1 with genesis_hash before any. Every case has one, since every case has an owner and so a genesis hash. Committing an entry, or a replica storing one, moves it to that entry, and it travels with the case on the wire as ledgerPosition (SYNC-16-005)
stub_summary Owner-chosen, human-readable description of the case used as the summary of the VulnerabilityCaseStub carried in a stub Invite. Must be set before emitting an Invite(Actor, target=VulnerabilityCaseStub) — the factory raises if absent (CM-17-010, MV-10-001)
parent_cases, child_cases, sibling_cases URIs of related cases, held as IDs only (ADR-0017); no protocol flow sets them yet. A case split will set parent_cases on the child and child_cases on the parent, and leaves sibling_cases unwritten (ADR-0125)
active_participants Computed, not stored: the ids of the inline participant records that is_active_participant finds active, in roster order. Sent on the wire as activeParticipants only; the AS2 form leaves it out while any case_participants entry is a bare URI, so it is never a partial list. A received value that contradicts the recomputed one is refused (CM-31-003, ARCH-23-005)

CaseParticipant

Defined in vultron/core/models/case_participant.py.

Field Description
attributed_to The actor this record stands for; actor_participant_index is keyed on it
case_roles list[CVDRole] — the roles this actor holds in this case
participant_statuses Append-only history of ParticipantStatus snapshots
embargo_consents list[EmbargoConsent] — one Participant Embargo Consent (PEC) row for every entry in the case's embargo register, each holding the embargo URI, one of UNINVITED, INVITED, AGREED, DECLINED or TIMED_OUT, and, on an INVITED row only, that invitation's rsvp_deadline (ADR-0122). A row is written UNINVITED when an embargo is proposed and when the participant joins the case; a missing row is a defect. Each row is an AS2 object of type EmbargoConsent, attributed to the participant's actor (attributedTo) under an id derived from that actor and the embargo, so the CASE_MANAGER can commit a changed row as its own ledger entry and every replica copies it. "Signatory" and "lapsed" are read from these rows and the register, never stored
joined Whether the participant has joined the case: it was seated by case initialization or accepted its stub Invite. Defaults to true. One input to VulnerabilityCase.is_active_participant, which decides whether the participant is sent case content (CM-10-004, ADR-0114)
removal_activity The removal fact: the id of the Remove(CaseParticipant) activity that took this participant out of active participation, or None when it is not removed. The record stays on the roster. One input to VulnerabilityCase.is_active_participant: a removed participant is inert whatever its embargo consent (CM-31-001, ADR-0116)
participant_case_name Optional human-readable name for this participant in this case

Role-specific subclasses (VendorParticipant, CoordinatorParticipant, ObserverParticipant, CaseActorParticipant, and others) set case_roles for convenience. All of them share the same type_ value, "CaseParticipant".

CaseStatus

Defined in vultron/core/models/case_status.py. Stored in VulnerabilityCase.case_statuses.

Field Description
em EmDimension — the Embargo Management (EM) state (None / Proposed / Active / Revise / eXited). On a case's status this is a read-only copy the case stamps from its embargo_register, so it never disagrees with the register (ADR-0122). Assigning it, or its state, raises (SDO-03-006)
pxa PxaDimension — the Publication/eXploit/Active-attacks (PXA) state
context The URI of the case this status belongs to
attributed_to The actor who reported this status (optional)

ParticipantStatus

Defined in vultron/core/models/participant_status.py. Stored in CaseParticipant.participant_statuses.

Field Description
context The URI of the case this status belongs to
rm RmDimension — the participant's Report Management (RM) state (Start → Received → … → Closed)
vf VfDimension — Vendor-awareness / Fix-readiness state (vf → Vf → VF); present only for VENDOR participants
d DDimension — Fix-deployment state (d → D); present only for DEPLOYER participants
cvd_role The CVD roles this participant held at the time of the snapshot
case_engagement Whether this participant is actively engaged
tracking_id Optional identifier this participant uses for the case in its own tracker
case_status Optional CaseStatus the participant believes the case to be in

Dimension objects

Defined in vultron/core/models/dimensions.py (ADR-0036).

Dimension Full name State machine Used in
EmDimension Embargo Management (EM) None/Proposed/Active/Revise/eXited CaseStatus
PxaDimension Publication/eXploit/Active-attacks (PXA) public awareness, exploit, active-attacks CaseStatus
RmDimension Report Management (RM) Start → Received → … → Closed ParticipantStatus
VfDimension Vendor-awareness / Fix-readiness (VF) vf → Vf → VF ParticipantStatus (VENDOR only)
DDimension Fix-deployment (D) d → D ParticipantStatus (DEPLOYER only)

CVDRole

Defined in vultron/enums/roles.py as a StrEnum. Participants hold zero or more roles as list[CVDRole].

Role Meaning
REPORTER Submitted the vulnerability report to others
VENDOR Supplies the affected product; has Vendor Fix Path obligations
DEPLOYER Deploys the vendor's fix; has deployment obligations
COORDINATOR Neutral third party facilitating coordination
OBSERVER Base role — admitted via Invite/Accept; no VFD obligations (ADR-0057)
CASE_OWNER Decision-maker who administers the case
CASE_MANAGER The case's single-writer authority for the ledger; usually held alongside COORDINATOR (CBT-01-003); any actor type may hold it
CVE_NUMBERING_AUTHORITY Holds CNA status; may assign CVE IDs directly

Do not use CVDRolesFlag

CVDRolesFlag is a legacy bitmask enum retained only for the vultron.bt simulator layer. Always use list[CVDRole] in new code.

How the objects relate

classDiagram
    direction TB

    class VulnerabilityCase {
        id_ URI
        attributed_to URI
        case_participants list~str|CaseParticipant~
        actor_participant_index dict~str,str~
        vulnerability_reports list~str|VulnerabilityReport~
        case_statuses list~CaseStatus~
        active_embargo EmbargoEvent | None
        genesis_hash str
        ledger_position LedgerPosition
    }

    class CaseParticipant {
        id_ URI
        case_roles list~CVDRole~
        participant_statuses list~ParticipantStatus~
        embargo_consents list~EmbargoConsent~
    }

    class CaseStatus {
        em EmDimension
        pxa PxaDimension
        context URI
    }

    class ParticipantStatus {
        rm RmDimension
        vf VfDimension
        d DDimension
    }

    class CVDRole {
        <<enumeration>>
        REPORTER
        VENDOR
        DEPLOYER
        COORDINATOR
        OBSERVER
        CASE_OWNER
        CASE_MANAGER
        CVE_NUMBERING_AUTHORITY
    }

    VulnerabilityCase "1" *--> "0..*" CaseParticipant : case_participants
    VulnerabilityCase "1" *--> "0..*" CaseStatus : case_statuses
    CaseParticipant "1" *--> "0..*" ParticipantStatus : participant_statuses
    CaseParticipant --> CVDRole : case_roles

See also

  • The Case Model — what each object is for
  • The CASE_MANAGER and the Case Ledger — who writes the case history
  • ADR-0036: Per-Machine Dimension Objects for CaseStatus and ParticipantStatus
  • ADR-0051: CaseActor Has Its Own RM Lifecycle Tracked via CaseParticipant
  • ADR-0122: Participant embargo consent is recorded per (participant, embargo)
  • ADR-0057: Observer role (CVDRole.OBSERVER)
  • ADR-0078: Retire CVDRole.FINDER — Reporter Is the Protocol-Salient Role