Message Types
Each row of the table below is an occasion: a situation in a Coordinated Vulnerability Disclosure (CVD) case that a sender conveys with a wire activity. The row names the activity to send, whom to send it to, who may send it, and the section that documents it. "Send to" is the addressee: the Case Manager, a participant, or, before a case exists, an actor outside any case. "Sent by" is the standing a receiver requires of the sender of an activity sent to that addressee. It reads "not handled" when Vultron recognizes the activity but no receiver handles it, and such an activity is reported as "no use case found" rather than processed. One activity sent to two addressees can therefore have two rows with different senders. Where several rows share one activity, a field value, the receiver's Embargo Management (EM) state, the register status of the embargo the activity names, the sender's standing, or the addressee tells them apart. The groups follow the case lifecycle, then the protocol mechanics that carry it.
Report
| When… | Send | Send to | Sent by | Distinguished by | Details |
|---|---|---|---|---|---|
| a Reporter has written up a vulnerability and is about to submit the report | Create(VulnerabilityReport) |
an actor outside any case | any actor (usually: reporter) | — | Create report |
| a Reporter submits a vulnerability report to a Vendor or Coordinator | Offer(VulnerabilityReport) |
an actor outside any case | any actor (usually: reporter) | — | Report Submission (RS) |
| a report receiver has read a submitted report | Read(Offer(VulnerabilityReport)) |
an actor outside any case | the addressee of the vulnerability report offer (usually: vendor, coordinator) | — | Report Acknowledgment (RK) |
| a report receiver judges the report valid | Accept(Offer(VulnerabilityReport)) |
the case manager | a participant (usually: vendor, coordinator) | — | Validate report |
| a report receiver judges the report invalid | TentativeReject(Offer(VulnerabilityReport)) |
the case manager | a participant (usually: vendor, coordinator) | — | Invalidate report |
| a report receiver closes a report no case holds | Reject(Offer(VulnerabilityReport)) |
an actor outside any case | the addressee of the vulnerability report offer (usually: vendor, coordinator) | — | Close report |
| a Participant accepts the case for further action | Join(VulnerabilityCase) |
the case manager | a participant | — | Report/Case Accepted (RA) |
| a Participant defers further action on the case | Ignore(VulnerabilityCase) |
the case manager | a participant | — | Report/Case Deferred (RD) |
Case proposal
| When… | Send | Send to | Sent by | Distinguished by | Details |
|---|---|---|---|---|---|
| a report receiver asks a Case Actor Service to open a case for a report | Create(CaseProposal) |
an actor outside any case | the case proposal's author (usually: vendor, coordinator) | — | Create case proposal |
| a Case Actor Service agrees to open the proposed case | Accept(CaseProposal) |
an actor outside any case | the addressee of the case proposal | — | Accept case proposal |
| a Case Actor Service declines to open the proposed case | Reject(CaseProposal) |
an actor outside any case | the addressee of the case proposal | — | Reject case proposal |
Case and participants
| When… | Send | Send to | Sent by | Distinguished by | Details |
|---|---|---|---|---|---|
| the Case Manager has opened a case for a submitted report | Create(VulnerabilityCase) |
a participant | the addressee of the case proposal or vulnerability report offer | — | Create case |
| the Case Owner links a further report to an existing case | Add(VulnerabilityReport)[target=VulnerabilityCase] |
the case manager | the case owner | — | Add report to case |
| the Case Manager records the new Case Owner once a case ownership transfer is accepted | Update(VulnerabilityCase) |
a participant | not handled | — | Update case owner |
| the Case Owner offers a CVD role on the case to another participant | Offer(CaseParticipantRole)[context=VulnerabilityCase] |
the case manager | the case owner | — | Offer case participant role |
| a participant accepts a role offered to it on the case | Accept(Offer(CaseParticipantRole)[context=VulnerabilityCase]) |
the case manager | the addressee of the case participant role offer | — | Accept case participant role |
| a participant declines a role offered to it on the case | Reject(Offer(CaseParticipantRole)[context=VulnerabilityCase]) |
the case manager | the addressee of the case participant role offer | — | Reject case participant role |
| the Case Owner proposes to transfer ownership of the case to another actor | Offer(Offer(VulnerabilityCase)) |
the case manager | the case owner | — | Propose case ownership transfer |
| the Case Manager offers the case to the actor the Case Owner proposed | Offer(VulnerabilityCase) |
a participant | the case manager | — | Offer case ownership transfer |
| an actor accepts an offer of case ownership | Accept(Offer(VulnerabilityCase)) |
the case manager | the addressee of the vulnerability case offer | — | Accept case ownership transfer |
| an actor declines an offer of case ownership | Reject(Offer(VulnerabilityCase)) |
the case manager | the addressee of the vulnerability case offer | — | Reject case ownership transfer |
| the Case Owner withdraws its proposal while the offer of case ownership is open | Undo(Offer(Offer(VulnerabilityCase))) |
the case manager | the case owner | — | Withdraw case ownership transfer |
| the Case Manager invites an actor to join the case | Invite(Actor)[target=VulnerabilityCaseStub] |
a participant | the case manager | — | Invite actor to case |
| an invited actor agrees to join the case | Accept(Invite(Actor)[target=VulnerabilityCaseStub]) |
the case manager | the invitee | — | Accept invite to case |
| an invited actor declines to join the case | Reject(Invite(Actor)[target=VulnerabilityCaseStub]) |
the case manager | the invitee | — | Reject invite to case |
| the Case Manager has replayed the case ledger to a newly joined Participant | Invite(Actor)[target=VulnerabilityCase] |
a participant | the case manager | — | Send Full-Case Invite |
| a Participant asked by a Full-Case Invite judges the case valid | Accept(Invite(Actor)[target=VulnerabilityCase]) |
the case manager | the invitee | — | Accept Full-Case Invite |
| a Participant asked by a Full-Case Invite judges the case invalid | TentativeReject(Invite(Actor)[target=VulnerabilityCase]) |
the case manager | the invitee | — | Tentatively reject Full-Case Invite |
| a Participant asked by a Full-Case Invite closes the case | Reject(Invite(Actor)[target=VulnerabilityCase]) |
the case manager | the invitee | — | Reject Full-Case Invite |
| the Case Manager has admitted a new Participant to the case | Announce(VulnerabilityCase) |
a participant | the case manager | — | Announce vulnerability case |
| a Participant ends its participation in the case | Leave(VulnerabilityCase) |
the case manager | the case owner or a participant | — | Close case |
| the Case Owner reinstates a removed Participant | Add(CaseParticipant)[target=VulnerabilityCase] |
the case manager | the case owner | — | Add case participant to case |
| the Case Owner removes a Participant from active participation | Remove(CaseParticipant)[target=VulnerabilityCase] |
the case manager | the case owner | — | Remove case participant from case |
| the Case Manager creates a participant record, such as the inert record for the invitee of a stub Invite | Create(CaseParticipant) |
a participant | not handled | — | Create case participant |
| the Case Manager changes a participant record, such as moving the CASE_OWNER role on an ownership transfer | Update(CaseParticipant) |
a participant | not handled | — | Update case participant |
Embargo
| When… | Send | Send to | Sent by | Distinguished by | Details |
|---|---|---|---|---|---|
| the Case Owner terminates the active embargo | Remove(Event) |
the case manager | the case manager or the case owner | — | Embargo Termination (ET) |
| the Case Manager ends the active embargo, on its own decision or on the Case Owner's | Remove(Event) |
a participant | the case manager | — | Tell a participant the embargo has ended |
| the Case Manager states the terms of the embargo in force | Announce(Event)[context=VulnerabilityCase] |
a participant | the case manager | register status of the named embargo ACTIVE |
Announce embargo |
| the Case Manager has applied an Embargo Termination a Case Owner sent before the end time | Announce(Event)[context=VulnerabilityCase] |
a participant | the case manager | register status of the named embargo TERMINATED |
Announce embargo termination |
| a Participant proposes embargo terms for a case with no active embargo | Invite(Event)[context=VulnerabilityCase] |
the case manager | the case manager or an active participant | EM state NONE or PROPOSED |
Embargo Proposal (EP) |
| a Participant proposes revised terms for the active embargo | Invite(Event)[context=VulnerabilityCase] |
the case manager | the case manager or an active participant | EM state ACTIVE or REVISE |
Embargo Revision Proposal (EV) |
| the Case Manager asks a Participant to answer embargo terms another Participant proposed | Invite(Event)[context=VulnerabilityCase] |
a participant | the case manager | — | Ask a participant about proposed embargo terms |
| a Participant agrees to proposed embargo terms | Accept(Invite(Event)[context=VulnerabilityCase]) |
the case manager | the invitee | EM state PROPOSED |
Embargo Proposal Acceptance (EA) |
| a Participant agrees to a proposed embargo revision | Accept(Invite(Event)[context=VulnerabilityCase]) |
the case manager | the invitee | EM state REVISE |
Embargo Revision Acceptance (EC) |
| a Participant refuses proposed embargo terms | Reject(Invite(Event)[context=VulnerabilityCase]) |
the case manager | the invitee | EM state PROPOSED |
Embargo Proposal Rejection (ER) |
| a Participant refuses a proposed embargo revision | Reject(Invite(Event)[context=VulnerabilityCase]) |
the case manager | the invitee | EM state REVISE |
Embargo Revision Rejection (EJ) |
| the Case Manager abandons an open embargo proposal once the case is public, an exploit is public or attacks are observed | Undo(Invite(Event)[context=VulnerabilityCase]) |
a participant | not handled | — | Withdraw an embargo invitation |
| the Case Owner decides to activate a proposed embargo | Accept(Event)[target=VulnerabilityCase] |
the case manager | the case owner | — | Activate embargo |
| the Case Owner decides to reject a proposed embargo | Reject(Event)[target=VulnerabilityCase] |
the case manager | the case owner | — | Reject embargo proposal |
| a Participant bound by the active embargo stops complying with it | Leave(Event)[context=VulnerabilityCase] |
the case manager | a participant | — | Withdraw from embargo |
| the Case Manager has created a case and, with it, an embargo such as the default embargo | Create(EmbargoEvent) |
a participant | not handled | — | Create embargo event |
| the Case Manager creates a participant's consent row for an embargo, such as the UNINVITED row a proposal writes | Create(EmbargoConsent) |
a participant | not handled | — | Create embargo consent |
| the Case Manager changes a participant's consent row, such as an invitation timing out, the rows carried over at activation or a change of its own consent | Update(EmbargoConsent) |
a participant | not handled | — | Update embargo consent |
Case status
| When… | Send | Send to | Sent by | Distinguished by | Details |
|---|---|---|---|---|---|
| the Case Manager records that the public knows of the vulnerability | Add(CaseStatus)[target=VulnerabilityCase] |
a participant | the case manager | pxaState = Pxa |
Public awareness in a case status |
| the Case Manager records that an exploit for the vulnerability is public | Add(CaseStatus)[target=VulnerabilityCase] |
a participant | the case manager | pxaState = PXa |
Exploit public in a case status |
| the Case Manager records that attackers are exploiting the vulnerability | Add(CaseStatus)[target=VulnerabilityCase] |
a participant | the case manager | pxaState = pxA |
Attacks observed in a case status |
| a Vendor becomes aware of the vulnerability | Add(ParticipantStatus)[target=CaseParticipant] |
the case manager | the case manager or the case owner or the participant status's author (usually: vendor) | vfState = Vf |
Vendor Awareness (CV) |
| a Vendor has a fix ready | Add(ParticipantStatus)[target=CaseParticipant] |
the case manager | the case manager or the case owner or the participant status's author (usually: vendor) | vfState = VF |
Fix Readiness (CF) |
| a Deployer has deployed the fix | Add(ParticipantStatus)[target=CaseParticipant] |
the case manager | the case manager or the case owner or the participant status's author (usually: deployer) | dState = D |
Fix Deployed (CD) |
| a Participant learns that the public knows of the vulnerability | Add(ParticipantStatus)[target=CaseParticipant] |
the case manager | the case manager or the case owner or the participant status's author | caseStatus.pxaState = Pxa |
Public awareness in a participant status |
| a Participant learns that an exploit for the vulnerability is public | Add(ParticipantStatus)[target=CaseParticipant] |
the case manager | the case manager or the case owner or the participant status's author | caseStatus.pxaState = PXa |
Exploit public in a participant status |
| a Participant observes attacks that exploit the vulnerability | Add(ParticipantStatus)[target=CaseParticipant] |
the case manager | the case manager or the case owner or the participant status's author | caseStatus.pxaState = pxA |
Attacks observed in a participant status |
General
| When… | Send | Send to | Sent by | Distinguished by | Details |
|---|---|---|---|---|---|
| a Participant suggests an actor that the case should include | Offer(Actor)[target=VulnerabilityCase] |
the case manager | a participant | sender is not the case owner | Suggest actor to case |
| the Case Owner decides to invite an actor to the case | Offer(Actor)[target=VulnerabilityCase] |
the case manager | a participant | sender is the case owner | Ask the Case Manager to invite an actor |
| the Case Manager presents a suggested actor to the Case Owner | Offer(CaseParticipant)[target=VulnerabilityCase] |
a participant | the case manager | — | Offer case participant |
| the Case Owner approves a suggested actor | Accept(Offer(CaseParticipant)[target=VulnerabilityCase]) |
the case manager | the case owner | — | Accept case participant offer |
| the Case Owner declines a suggested actor | Reject(Offer(CaseParticipant)[target=VulnerabilityCase]) |
the case manager | the case owner | — | Reject case participant offer |
| the Case Manager tells a recommender that the actor it suggested will be invited | Accept(Offer(Actor)[target=VulnerabilityCase]) |
a participant | the case manager | — | Accept actor recommendation |
| the Case Manager tells a recommender that the Case Owner declined the actor it suggested | Reject(Offer(Actor)[target=VulnerabilityCase]) |
a participant | the case manager | — | Reject actor recommendation |
| a Participant posts a note to the case | Add(Note)[target=VulnerabilityCase] |
the case manager | an active participant | — | Add note to case |
| a note's author or the Case Owner withdraws a note from the case | Remove(Note)[target=VulnerabilityCase] |
the case manager | the case owner or the note's author | — | Remove note from case |
Faults and acknowledgments
| When… | Send | Send to | Sent by | Distinguished by | Details |
|---|---|---|---|---|---|
| a Participant has received a message it cannot process | Create(ProcessingFault) |
the case manager | not yet checked | — | Create processing fault |
| the Case Manager has refused a participant's assertion because a precondition did not hold | Reject(Activity) |
a participant | the case manager | — | Refusal notice |
Ledger replication
| When… | Send | Send to | Sent by | Distinguished by | Details |
|---|---|---|---|---|---|
| the Case Manager has committed a case event to the case ledger | Announce(CaseLedgerEntry) |
a participant | the case manager | — | Announce case ledger entry |
| a received ledger entry does not chain onto the Participant's own ledger | Reject(CaseLedgerEntry) |
the case manager | an active participant, including one that has left the case | — | Reject case ledger entry |
Two vocabularies
Vultron describes its protocol messages in two vocabularies, and they do not correspond one-to-one:
- The formal message set is 28 shorthand symbols, partitioned by which state machine a message belongs to — Report Management (RM), Embargo Management (EM), Case State (CS), and General (GI). It is normative and versioned with the protocol. See Message Types and Transitions.
- The AS2 wire vocabulary is the set of ActivityStreams 2.0 (AS2) activities the prototype sends and receives, keyed by
MessageSemantics. See the Vultron AS Activity Guides.
The mapping between the two is many-to-many in both directions, and roughly half the wire vocabulary has no formal shorthand at all.
A shorthand and a wire activity are not interchangeable names for one thing.
The design rationale for keeping the two vocabularies distinct is recorded in ADR-0083.
Activity Vocabulary Design explains it, along with the verb choices and the Create/Add split that produce the collapses and expansions cataloged here.
The pages
Each page includes its slice of the occasion table under an Occasions heading. One section per occasion follows, stating when it applies, the wire activity to send, whom to send it to, who may send it, the field or state that distinguishes it, its mapping status, the pages that embed it, and a rendered example. The four formal-model pages end with a section for each shorthand that has no dedicated wire activity.
- Report Management (RM) — Wire activities for the Report Management message types RS, RI, RV, RD, RA, RC, RK, and RE.
- Embargo Management (EM) — Wire activities for the Embargo Management message types EP, ER, EA, EV, EJ, EC, ET, EK, and EE, the Case Owner's decision on a proposal, and a participant's withdrawal from the embargo in force.
- Case State (CS) — Wire activities for the Case State message types CV, CF, CD, CP, CX, CA, CK, and CE.
- General (GI) — Wire activities for the General message types GI, GK, and GE.
- Faults and Acknowledgments — The fault trichotomy and the cumulative hash-chain acknowledgment.
- Case Management — Case lifecycle, participant roster, and ownership transfer activities.
- Case Proposal — The pre-case bootstrap exchange (ADR-0023).
- Ledger Replication — The SYNC substrate that replicates the case ledger (ADR-0077).
Mapping status
Each occasion section states its entry's mapping status, the relationship between the wire activity and the formal shorthands:
| Status | Meaning |
|---|---|
direct |
One shorthand maps to exactly one wire activity. |
collapse |
Several shorthands share one wire activity. A field value or the receiver's state distinguishes them, as the section's Distinguished by line states. |
expansion |
One shorthand is realized by several wire activities, so the same shorthand appears in more than one section. |
evolved |
The shorthand's purpose is served by a mechanism partitioned on a different axis (fault reporting or cumulative acknowledgment), not by a dedicated wire activity. |
none |
The wire activity has no formal shorthand counterpart. |
Two examples show the many-to-many relationship:
CP,CXandCAare a collapse: all three rideAdd(CaseStatus), distinguished bypxaState.GIis an expansion: it spans the note lifecycle and the actor-suggestion exchange.
The shorthands RE, EE, CE, GE, EK, CK and GK have no dedicated wire activity.
Faults are conveyed by Create(ProcessingFault), as:Reject, or Add(Note), partitioned by failure mode.
Acknowledgment of ledger-replicated state is cumulative and implicit through hash-chain continuity.
RK survives as a real wire activity because report submission is not ledger-replicated.
Faults and Acknowledgments describes both mechanisms, and ADR-0083 records the decision.
Reading path: You maintain a vulnerability tracker and want it to talk to your partners
This page is part of Build against the contract.
Before this page: