The standard

SIGNET

Secure Intelligent Governed Network for Exchange and Trade — the open specification for governed procurement networks. This page renders directly from the standard's source repository.

SIGNET · Core domain model

Four layers, one dependency stack

The core model. Every entity is defined once and referenced by the layers above it; primitives sit at the foundation and a verifiable record of trust sits at the apex. Extension and profile objects are published separately and are not counted here.

26 core entities · 4 layers
04

Trust layer

Verifiable record

The audit-grade truth every transaction is judged against.

03

Agent layer

Autonomous actors

Who may act, under what mandate, and the decisions they take.

02

Process layer

Commercial lifecycle

The full arc from a need to a settled obligation.

01

Foundation layer

Primitives

The shared vocabulary every other layer is built from.

Specification

The Canonical Data Model

SIGNET Canonical Data Model

CDM version: v0.1 — the version-stable identity of the model, published at https://concert.foundation/signet/v0.1/ (§12.3). This is not the repository release number, and the two move independently. Release: carried in package.json and CHANGELOG.md, and rendered in the banner of the published page. This document does not restate it: a version restated by hand is a version that drifts, which is what happened to the line this one replaces. Steward: Concert Foundation Tier: Normative Licence: CC0 1.0 (public domain dedication) Status: Published and in force. Changed only under the revision process in §12.2.


About this document

This specification defines the SIGNET Canonical Data Model (CDM) — the common vocabulary for representing procurement and multi-party commerce across a SIGNET network. The CDM is the central normative artifact of the SIGNET standard. Every conforming implementation reads and writes data that is expressible in, and losslessly mappable to, this model.

The CDM is deliberately published under CC0. The vocabulary is meant to be implemented everywhere, by anyone, without friction or attribution burden. Concert Foundation holds no proprietary claim over the model, and stewards it toward governance on the OpenPeppol AISBL pattern: a non-profit steward with multi-stakeholder representation and no single-party control. It is not there yet, and says so. The Standards Committee that will govern normative change is not constituted; until it is, changes that would fall to it are taken under the published bootstrap clause in governance/README.md — reasoned in writing, subject to a stated comment period, recorded as interim resolutions, and reversible by the Committee on the record. The change-control process itself is described in §12.

Field-level definitions in §4–§7 are normative and are changed only under §12.2. What a conformance check actually validates against is the published JSON Schema in schema/; this document and those schemas are maintained by hand against each other, and nothing checks that they agree. Where they disagree that is a defect in one of them, and governance/defects.md records both an instance (D-20) and the absent control (D-21). Comments are invited at hello@concert.foundation.


1. Purpose and design principles

The CDM exists to solve one problem: procurement data today is fragmented across mutually unintelligible standards and proprietary platforms, which prevents both interoperability and the deployment of intelligent agents across organisational boundaries. The CDM is the Rosetta Stone — a single coherent model that bridges the established standards and adds the structures needed for agent-native, governed, decentralised commerce.

The model is governed by eight design principles.

1.1 Reuse before invention. The CDM does not reinvent procurement semantics. Where a concept is well defined by an existing open standard — OCDS for the contracting lifecycle, EN 16931 for invoicing, UBL for document syntax, the EU eProcurement Ontology (ePO) for semantic relationships — the CDM adopts and aligns to it. New structure is introduced only where existing standards are silent, principally around synthetic agents, machine-readable policy, and decentralised identity.

1.2 Standards as profiles, not forks. The CDM is expressed as a coherent superset that profiles existing standards. A SIGNET document can always be projected down to a conforming OCDS release, a Peppol BIS invoice, or an eForms notice, and data arriving in those formats can always be lifted into the CDM. Mapping tables (§8) are normative.

1.3 Agent-native by construction. Human and synthetic agents are first-class parties. The model represents not only what was decided but which agent decided it, under what authority, using which inputs, and with what rationale. Provenance is structural, not an afterthought.

1.4 Identity is decentralised. Parties are identified by stable, resolvable identifiers that may be Decentralised Identifiers (DIDs). Claims about parties — certifications, financial standing, qualifications — are represented as W3C Verifiable Credentials, verifiable independently of any central registry.

1.5 Data sovereignty is explicit. The model distinguishes between an assertion and the right to access the data behind it. Consent and access grants are represented as data, consistent with the Solid data-sovereignty pattern. The CDM never assumes a central data warehouse.

1.6 Policy is data. Procurement rules — eligibility thresholds, evaluation weightings, approval routing, agent mandates — are represented as machine-readable, human-auditable policy objects, not buried in application logic.

1.7 Events are immutable. Every material change is an append-only event with provenance. The current state of any object is a projection over its event history. This makes audit native and tampering evident.

1.8 Linked-data foundation. The canonical serialisation is JSON-LD, giving every object and property a globally unique URI while remaining ordinary JSON to consumers that do not process the semantics. This aligns the CDM simultaneously with OCDS (JSON), W3C VC/DID (JSON-LD), ePO (RDF/OWL), and Solid (RDF).


2. Architectural overview

The CDM is organised into four layers. Each layer builds on the one below.

2.1 Foundation layer — the primitive value types and reference objects used everywhere: identifiers, parties, values, periods, classifications, documents, items, credentials. (§4)

2.2 Process layer — the procurement lifecycle objects, aligned to the OCDS stages of planning, tender, award, contract, and implementation: needs, sourcing events, lots, submissions, evaluations, awards, contracts, orders, catalogues, invoices, obligations, performance records. (§5)

2.3 Agent layer — the structures that make SIGNET agent-native: synthetic agents, capabilities, mandates, agent actions, decisions, and the policy objects that govern them. (§6)

2.4 Trust layer — the cross-cutting governance structures: events, provenance, consent, and audit records that wrap every object in the layers above. (§7)


3. Notation and conformance keywords

The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Field cardinality is shown as: 1 (exactly one, required), 0..1 (optional single), 1..* (one or more, required), 0..* (zero or more). Data types reference the foundation types in §4 or the JSON Schema primitives string, number, boolean, integer, and ISO 8601 date-time.


4. Foundation layer

4.1 Identifier

A typed, scheme-qualified identifier. Every Party, document, and major object carries at least one.

FieldTypeCard.Definition
schemestring (URI)1The identifier scheme, as a URI. Registered schemes include did, gleif:lei, gs1:gln, vat, companies-house, peppol.
idstring1The identifier value within the scheme.
uristring (URI)0..1A resolvable URI for the identified entity, where one exists.

A did-scheme identifier (e.g. did:web:supplier.example.com) makes the Party self-sovereign and resolvable without a central registry (§1.4).

4.2 Party

Any actor in the network. The single most important foundation object. Subtyped by role.

FieldTypeCard.Definition
idIdentifier1Primary identifier (DID RECOMMENDED).
identifiersIdentifier[]0..*Additional identifiers (LEI, VAT, GLN, etc.).
namestring1Legal or display name.
rolesstring[]1..*One or more of: buyer, supplier, procuringEntity, payer, payee, humanAgent, syntheticAgent, certifier, observer.
partyTypestring1organization, person, or agent.
addressAddress0..1Postal/registered address.
contactPointContactPoint0..1Contact details.
credentialsCredential[]0..*Verifiable Credentials held by the Party (§4.7).
memberOfIdentifier0..1The organisation a person or agent acts for.

A Party with partyType: agent is further described by the Agent layer (§6).

4.3 Value

A monetary amount. Aligned to EN 16931 monetary representation.

FieldTypeCard.Definition
amountnumber1The numeric amount.
currencystring1ISO 4217 three-letter code.
taxIncludedboolean0..1Whether the amount is tax-inclusive.

4.4 Period

FieldTypeCard.Definition
startDatedate-time0..1Inclusive start.
endDatedate-time0..1Inclusive end.
durationInDaysinteger0..1Convenience duration where dates are indicative.

4.5 Classification

A coded classification against a controlled scheme.

FieldTypeCard.Definition
schemestring1e.g. cpv, unspsc, cpvs, gsin.
idstring1Code value.
descriptionstring0..1Human-readable label.

4.6 Item

A line item — a unit of what is being bought, offered, ordered, or invoiced.

FieldTypeCard.Definition
idstring1Item identifier, unique within its containing object.
descriptionstring1What the item is.
classificationClassification0..1Primary classification.
additionalClassificationsClassification[]0..*Further classifications.
quantitynumber0..1Quantity.
unitUnit0..1Unit of measure (UN/ECE Rec 20) and unit price.
deliveryLocationLocation0..1Where the item is delivered.

4.7 Credential

A reference to a W3C Verifiable Credential asserting a claim about a Party (e.g. ISO 27001 certification, EcoVadis rating, insurance cover).

FieldTypeCard.Definition
idstring (URI)1Credential identifier.
typestring[]1..*VC types, e.g. VerifiableCredential, ISO27001Certificate.
issuerIdentifier1DID or identifier of the issuing authority.
issuanceDatedate-time1When issued.
expirationDatedate-time0..1When it expires.
credentialSubjectobject1The claims, per the VC data model.
proofobject1Cryptographic proof (may be a BBS proof enabling selective disclosure).
selectiveDisclosureboolean0..1Whether the credential supports zero-knowledge selective disclosure.

4.8 Document

FieldTypeCard.Definition
idstring1Document identifier.
documentTypestring1Coded type (e.g. tenderNotice, evaluationCriteria, signedContract).
titlestring0..1Title.
urlstring (URI)0..1Resolvable location.
hashstring0..1Content hash (integrity).
accessGrantIdentifier0..1Reference to a Consent/access-grant object (§7.3) where access is controlled.

5. Process layer

The process layer follows the OCDS lifecycle so that any SIGNET process can be projected to a conforming OCDS release. The five OCDS stages — planning, tender, award, contract, implementation — are preserved as the canonical phase model.

5.1 Need (planning stage)

The demand signal that initiates procurement. Equivalent to OCDS planning.

FieldTypeCard.Definition
idIdentifier1Need identifier.
titlestring1Short description of the need.
descriptionstring0..1Fuller description.
requestingPartyIdentifier1The Party raising the need.
budgetValue0..1Indicative budget.
classificationClassification0..1What is needed.
rationalestring0..1Why it is needed.
governingPoliciesIdentifier[]0..*Policy objects that constrain this procurement (§6.5).

5.2 SourcingEvent (tender stage)

A request to the market — RFP, RFQ, ITT, tender, or call-off competition. Equivalent to OCDS tender.

FieldTypeCard.Definition
idIdentifier1Event identifier.
titlestring1Title.
procuringPartyIdentifier1The buyer/procuring entity.
procedurestring1Procedure type, e.g. open, restricted, competitiveFlexible, directAward, frameworkCallOff.
statusstring1planned, active, evaluating, complete, cancelled, withdrawn.
lotsLot[]0..*Divisible portions (§5.3).
itemsItem[]0..*What is being sourced.
valueValue0..1Estimated value.
eligibilityCriteriaPolicy[]0..*Machine-readable entry criteria (§6.5).
evaluationCriteriaPolicy[]0..*Machine-readable scoring model (§6.5).
periodPeriod0..1Submission window.
documentsDocument[]0..*Tender documents.

5.3 Lot

A divisible portion of a SourcingEvent that may be awarded independently.

FieldTypeCard.Definition
idstring1Lot identifier within the event.
titlestring1Lot title.
itemsItem[]0..*Items in this lot.
valueValue0..1Estimated lot value.

5.4 Submission

A supplier's response to a SourcingEvent — a bid, tender, quote, or proposal.

FieldTypeCard.Definition
idIdentifier1Submission identifier.
sourcingEventIdentifier1The event responded to.
lotstring0..1The lot, if lot-specific.
submittingPartyIdentifier1The supplier.
submittedByIdentifier0..1The agent (human or synthetic) that lodged it.
itemsItem[]0..*Offered items with prices.
valueValue0..1Total offered value.
disclosedCredentialsCredential[]0..*Credentials presented, possibly via selective disclosure.
sealedProofobject0..1Where sealed-bid cryptography applies, the encrypted submission and proof (§9.3).
statusstring1draft, submitted, withdrawn, admissible, inadmissible.

5.5 Evaluation

The scoring of submissions against the evaluation criteria.

FieldTypeCard.Definition
idIdentifier1Evaluation identifier.
submissionIdentifier1The submission scored.
criteriaPolicy1The evaluation model applied.
scoresScore[]1..*Per-criterion scores with rationale.
evaluatedByIdentifier1The agent (human or synthetic) performing the evaluation.
resultstring1passed, failed, ranked.
decisionIdentifier0..1Link to the Decision record (§6.4).

5.6 Award (award stage)

The decision to award. Equivalent to OCDS award.

FieldTypeCard.Definition
idIdentifier1Award identifier.
sourcingEventIdentifier1The event.
awardedPartyIdentifier1The winning supplier.
valueValue1Awarded value.
rationalestring0..1Award rationale.
decisionIdentifier1The Decision record supporting the award (§6.4).
standstillPeriodPeriod0..1Where regulation requires a standstill (e.g. UK Procurement Act).

5.7 Contract (contract stage)

The binding agreement. Equivalent to OCDS contract.

FieldTypeCard.Definition
idIdentifier1Contract identifier.
awardIdentifier0..1The award it derives from.
partiesIdentifier[]1..*Contracting parties.
titlestring1Contract title.
valueValue1Contract value.
periodPeriod1Contract term.
obligationsObligation[]0..*Obligations and milestones (§5.10).
documentsDocument[]0..*Signed contract and annexes.
governingPoliciesIdentifier[]0..*Policies governing performance.

5.8 Order

A call-off or purchase order against a contract or catalogue. Aligned to UBL Order.

FieldTypeCard.Definition
idIdentifier1Order identifier.
contractIdentifier0..1The contract drawn against.
buyerIdentifier1Ordering party.
sellerIdentifier1Supplying party.
itemsItem[]1..*Ordered items.
valueValue1Order value.
deliveryPeriodPeriod0..1Required delivery.

5.9 Catalogue

A structured offering of goods/services. Aligned to UBL Catalogue and Peppol BIS Catalogue.

FieldTypeCard.Definition
idIdentifier1Catalogue identifier.
providerPartyIdentifier1The supplier.
itemsItem[]1..*Catalogue lines with prices.
validityPeriodPeriod0..1Validity.

5.10 Obligation

A contractual obligation, deliverable, or milestone with a compliance state.

FieldTypeCard.Definition
idstring1Obligation identifier within the contract.
descriptionstring1What must be done.
dueDatedate-time0..1When.
responsiblePartyIdentifier0..1Who is responsible.
statusstring1pending, met, breached, waived.
evidenceDocument[]0..*Evidence of fulfilment.

5.11 Invoice (implementation stage)

An invoice, fully aligned to EN 16931 so it is convertible to Peppol BIS / UBL Invoice or Factur-X. Field names below reference EN 16931 Business Terms (BT) for traceability.

FieldTypeCard.EN 16931Definition
idIdentifier1BT-1Invoice number.
issueDatedate-time1BT-2Issue date.
contractIdentifier0..1BT-12Related contract.
orderIdentifier0..1BT-13Related order.
sellerIdentifier1BG-4Seller.
buyerIdentifier1BG-7Buyer.
linesInvoiceLine[]1..*BG-25Invoice lines.
taxTotalValue1BG-22Total tax.
payableAmountValue1BT-115Amount due for payment.
paymentTermsstring0..1BT-20Payment terms.

The CDM's EN 16931 alignment is what makes a SIGNET network natively compliant with the EU ViDA cross-border e-invoicing mandate (from July 2030) and the national B2B mandates preceding it.


6. Agent layer

This layer is SIGNET's distinctive contribution. No existing procurement standard represents synthetic agents as first-class, governed, accountable participants. The agent layer does.

6.1 SyntheticAgent

An AI agent operating within the network as a first-class Party (partyType: agent, role syntheticAgent).

FieldTypeCard.Definition
idIdentifier1Agent DID.
namestring1Agent name.
operatedByIdentifier1The Party accountable for the agent.
modelstring0..1The underlying model family (model-agnostic; for provenance only).
capabilitiesAgentCapability[]1..*Declared capabilities (§6.2).
mandateIdentifier1The Mandate governing the agent (§6.3).
agentCardstring (URI)0..1A2A Agent Card location (/.well-known/agent.json).

6.2 AgentCapability

A declared capability, aligned to the A2A Agent Card model so capabilities are discoverable across organisational boundaries.

FieldTypeCard.Definition
namestring1Capability name, e.g. evaluate.submission, negotiate.price.
descriptionstring0..1What it does.
inputSchemaobject0..1Expected input.
outputSchemaobject0..1Produced output.

6.3 Mandate

The authority granted to an agent — what it may do, within what limits, and where human approval is required. The structure that bounds an agent's remit, and makes an action outside it visible in the record. A grant-type object (§7.4): its withdrawal is recorded by appending an event, never by mutating the object.

FieldTypeCard.Definition
idIdentifier1Mandate identifier.
agentIdentifier1The agent governed.
grantedByIdentifier1The Party granting authority.
permittedCapabilitiesstring[]1..*Capabilities the agent may exercise.
constraintsPolicy[]0..*Hard limits (e.g. max discount, value ceiling).
approvalThresholdsPolicy[]0..*Conditions requiring human-in-the-loop approval.
scopeobject1Data and entity scope the agent may operate within (sandbox boundary).
validityPeriod0..1Time bound on the mandate.

6.4 Decision

A record of a decision taken in the network, by a human or synthetic agent, with the inputs and rationale that produced it. The backbone of accountability.

FieldTypeCard.Definition
idIdentifier1Decision identifier.
decisionTypestring1e.g. admissibility, evaluation, award, negotiationMove.
madeByIdentifier1The agent (human or synthetic) that decided.
underMandateIdentifier0..1The mandate relied on, where the decider is synthetic.
inputsIdentifier[]0..*The objects considered (submissions, credentials, policies).
policiesAppliedIdentifier[]0..*The policies applied.
rationalestring1Human-readable rationale.
outcomeobject1The decision outcome.
humanApprovalIdentifier0..1Where a mandate threshold required it, the approving Party and record.
provenanceProvenance1Full provenance (§7.2).

A Decision record satisfies the "material decision" record-keeping that regulation increasingly requires — including the assessment-summary and decision-record obligations of the UK Procurement Act 2023, and the documentation expectations for AI-assisted evaluation under the EU AI Act.

6.5 Policy

A machine-readable, human-auditable rule. Policies express eligibility criteria, evaluation models, approval routing, agent constraints, and compliance rules. "Rules as code" made concrete.

FieldTypeCard.Definition
idIdentifier1Policy identifier.
policyTypestring1eligibility, evaluation, approval, constraint, compliance.
expressionLanguagestring1The language the rule is written in, e.g. rego, dmn, cel.
expressionstring1The executable rule.
humanReadablestring1A plain-language statement of the same rule.
versionstring1Policy version.
issuedByIdentifier1The governing Party.

The dual requirement — expression (machine-executable) and humanReadable (auditable) — is mandatory. A Policy MUST carry both so that the same rule governs agents and is reviewable by humans.


7. Trust layer

Cross-cutting structures that wrap every object above with auditability, provenance, and consent.

7.1 Event

An append-only record of a material change. The current state of any object is the projection of its ordered Event stream (§1.7).

FieldTypeCard.Definition
idIdentifier1Event identifier.
eventTypestring1e.g. submission.lodged, award.decided, mandate.granted.
subjectIdentifier1The object the event concerns.
actorIdentifier1The Party (human or synthetic) that caused the event.
timestampdate-time1When it occurred.
payloadobject0..1The change.
previousEventHashstring0..1Hash of the prior event, forming a tamper-evident chain.
provenanceProvenance1Provenance (§7.2).

7.2 Provenance

Who or what produced an assertion, when, and from what. Aligned to W3C PROV.

FieldTypeCard.Definition
generatedByIdentifier1The agent or activity that produced the assertion.
generatedAtdate-time1When.
derivedFromIdentifier[]0..*Source objects.
usedPoliciesIdentifier[]0..*Policies applied.
signatureobject0..1Cryptographic signature over the assertion.

7.3 Consent

A data-sovereignty access grant — the right of a named party, for a stated purpose, for a bounded time, to access data held by another party. Expresses the Solid consent pattern as CDM data (§1.5).

FieldTypeCard.Definition
idIdentifier1Consent identifier.
grantorIdentifier1The party who owns the data.
granteeIdentifier1The party granted access.
resourceIdentifier[]1..*The data resources covered.
purposestring1The permitted purpose.
validityPeriod1Time bound.
revocableboolean1Whether revocable before expiry.
proofobject0..1Signed grant.

purpose is a human-readable statement of the purpose for which access is granted, not a machine-evaluable term. The string interoperates; its evaluation is not defined by this specification. A profile MAY define a purposeCode extension with a codelist appropriate to its jurisdiction or sector (§11).

revocable records whether a grant may be withdrawn. It does not record whether one has been: withdrawal is an event, per §7.4.

7.4 Grant-type objects and withdrawal

Grant-type object. A CDM object that confers authority or permission from one party to another for a bounded period, and whose conferred authority may cease before the end of that period.

7.4.1 In this version the grant-type objects are Consent (§7.3) and Mandate (§6.3). The list is enumerated: a later primitive meeting the definition acquires the obligations below only through an explicit amendment naming it. Open-ended inheritance would let a future proposal's author acquire obligations silently.

7.4.2 Withdrawal is an event, not a field. An implementation MUST NOT mutate a grant-type object to record that its authority has been withdrawn. Withdrawal is recorded by appending an Event (§7.1) whose subject is the grant object. This follows §1.7: current state is the projection of the ordered event stream, not mutable state carried on the object.

7.4.3 Projection rule (normative). A grant-type object G is effective at time T if and only if:

  1. an event of type <object>.granted naming G as subject precedes T; and
  2. no event of type <object>.revoked naming G as subject precedes T; and
  3. T falls within G's validity Period.

The effective/not-effective determination MUST be reproducible by a third party from the published event stream alone.

7.4.4 Closed core within eventType. The eventType codelist remains open as an extension space, but the subset published in codelists/eventTypeCore.csv is closed and normative: codes in that subset MUST carry the meanings given there, and MUST NOT be redefined, reused, or narrowed by implementations, extensions, or profiles. A code appears in exactly one of the two files, and consumers take the union. Admission to the closed subset is append-only and occurs only through the change-control process (§12); adding an entry is a minor version, and changing the meaning of an existing entry is a major version.

The initial closed subset is consent.granted, consent.revoked, mandate.granted, mandate.revoked.

No *.expired code exists. Expiry occurs by the clock rather than by any party's act, so an expiry event would have no honest actor — which Event requires — and clause 3 of the projection rule tests validity directly.

7.4.5 No field is added to Consent or Mandate by this section. Event.subject already carries the grant object's identifier, so withdrawal is fully expressible once the event types exist and their meanings are fixed.


8. Standards mapping (normative)

The CDM is a profile-and-bridge over established standards. The following mappings are normative: a conforming implementation MUST be able to transform between the CDM and these formats without loss of the fields defined in the mapping.

CDM objectMaps to / fromMapping basis
NeedOCDS planningOCDS 1.1 release
SourcingEvent, LotOCDS tender; eForms noticeOCDS 1.1; eForms
SubmissionOCDS bid (bid extension); UBL TenderOCDS bid extension
AwardOCDS awardOCDS 1.1
ContractOCDS contractOCDS 1.1
OrderUBL 2.3 Order; Peppol BIS OrderingUBL 2.3
CatalogueUBL 2.3 Catalogue; Peppol BIS CatalogueUBL 2.3
InvoiceEN 16931; Peppol BIS Billing; UBL Invoice; Factur-XEN 16931 semantic model
PartyOCDS parties; ePO AgentOCDS org; ePO
CredentialW3C Verifiable Credentials 2.0VC data model
Identifier (did)W3C DID 1.0DID core
ProvenanceW3C PROV-OPROV
Semantic layer (all)EU eProcurement Ontology (ePO)ePO OWL/RDF

Where a CDM object has no counterpart in a target standard (notably the entire Agent layer when projecting to OCDS), the projection omits it without error, and the reverse lift leaves those fields empty. SIGNET-original structures are always cleanly separable from third-party standards, consistent with the IP & Licensing Policy.


9. Serialisation

9.1 Canonical form. The canonical serialisation is JSON-LD 1.1. Concert publishes the SIGNET @context at a stable URI. Every object type and property resolves to a URI in the SIGNET vocabulary namespace, itself aligned to ePO terms where equivalents exist.

9.2 Plain-JSON consumption. Consumers that do not process linked-data semantics MAY treat CDM documents as ordinary JSON; the @context is ignorable without loss of the document's tree structure. This preserves the low-friction adoption that made OCDS's plain-JSON approach successful.

9.3 Cryptographic envelopes. Where confidentiality is required — sealed-bid submissions (§5.4), selective credential disclosure (§4.7) — the relevant fields carry a cryptographic envelope (zero-knowledge proof, homomorphic ciphertext, or BBS selective-disclosure proof) in place of cleartext, with verification metadata. The envelope formats are specified in the separate SIGNET Cryptographic Profiles document.


10. Identifiers and namespaces

10.1 Every CDM object MUST carry a network-unique id. Decentralised Identifiers (DIDs) are RECOMMENDED for Parties and agents; URN or URI identifiers are acceptable for process objects.

10.2 The SIGNET vocabulary namespace, the published @context, and the registry of identifier schemes and codelists are maintained by Concert at stable URIs under the concert.foundation domain and MUST NOT be repurposed by implementers to publish non-conforming extensions under the SIGNET name.


11. Extension mechanism

The CDM is extensible without forking, following the OCDS extension pattern.

11.1 An extension is a published, versioned package that adds object types, fields, or codelist values under its own namespace. Extensions MUST NOT redefine or remove core fields.

11.2 Community extensions MAY be submitted to Concert for review and, if broadly useful, promotion into the core model through the change-control process (§12). This keeps the core lean while allowing domain-specific elaboration (e.g. a defence-procurement extension, a construction extension).

11.3 Core conformance (§13) is assessed against the core model only; extensions are conformance-assessed separately.


12. Versioning and change control

12.1 The CDM uses semantic versioning. The major version changes only on a breaking change to the core model; minor versions add backward-compatible structure; patch versions clarify without changing meaning.

12.2 As a normative artifact, the core model changes only through the formal revision process, which requires a recorded resolution, a stated comment period of at least fourteen calendar days, and an approving review. Non-normative material (examples, guidance, mapping notes) MAY be updated under a single approving review with no comment period, consistent with the normative/non-normative distinction in the governance model. The process is recorded in GOVERNANCE.md and took effect on 20 August 2026; changes merged before that date followed prior practice, and governance/reviews/2026-08-normative-approval-audit.md records what that practice was. No Standards Committee is constituted: until one is, decisions that would fall to it are taken under the bootstrap clause in governance/README.md and recorded as interim resolutions.

12.3 Every published version is permanently retrievable at a version-stable URI. Implementations declare the CDM version they target.


13. Conformance

13.1 A document conforms to the CDM if it validates against the published SIGNET JSON Schema for its declared version and satisfies the structural rules in this specification.

13.2 An implementation conforms if it (a) reads and writes conforming documents, (b) performs the normative standards mappings in §8 without loss of mapped fields, and (c) preserves provenance and event integrity for every material change it makes.

13.3 Conformance is verified against the SIGNET conformance test suite (a separate normative artifact, Apache-2.0 licensed) and its synthetic test datasets (CDLA-Permissive). Certification of conformance, and the "SIGNET Certified" mark, are administered by Concert under the IP & Licensing Policy, on identical terms to all implementers.


Appendix A — Worked example (illustrative)

A minimal award Decision made by a synthetic evaluation agent, in canonical JSON-LD (abbreviated):

{
  "@context": "https://concert.foundation/signet/v0.1/context.jsonld",
  "type": "Decision",
  "id": { "scheme": "did", "id": "did:web:buyer.example#decision-8842" },
  "decisionType": "award",
  "madeBy": { "scheme": "did", "id": "did:web:buyer.example#agent-eval-3" },
  "underMandate": { "scheme": "did", "id": "did:web:buyer.example#mandate-eval-3" },
  "inputs": [
    { "scheme": "did", "id": "did:web:buyer.example#submission-5521" },
    { "scheme": "did", "id": "did:web:buyer.example#submission-5522" }
  ],
  "policiesApplied": [
    { "scheme": "did", "id": "did:web:buyer.example#policy-eval-mat" }
  ],
  "rationale": "Most Advantageous Tender (price 0.2, quality 0.55, social 0.25). submission-5521 scored 0.859474, ahead of submission-5522 at 0.841500 (margin 0.017974). The dearer bid wins on materially higher quality, accepting a 5.56% price premium over the lower bid.",
  "outcome": { "awardedSubmission": "did:web:buyer.example#submission-5521" },
  "humanApproval": { "scheme": "did", "id": "did:web:buyer.example#approval-771" },
  "provenance": {
    "generatedBy": { "scheme": "did", "id": "did:web:buyer.example#agent-eval-3" },
    "generatedAt": "2026-06-21T14:08:00Z",
    "usedPolicies": [{ "scheme": "did", "id": "did:web:buyer.example#policy-eval-mat" }],
    "signature": { "type": "Ed25519Signature2020", "value": "z58…" }
  }
}

This single object records what was decided, which synthetic agent decided it, under which mandate, from which inputs, under which policy, with what rationale, with which human approval, and with cryptographic provenance — the accountability guarantee that distinguishes a SIGNET network from a conventional procurement platform.


Published under CC0 1.0. © 2026 Concert Foundation — to the extent any rights subsist, they are dedicated to the public domain. SIGNET and "SIGNET Certified" are marks administered by Concert Foundation under the IP & Licensing Policy.

Positions: oneNDA and SIGNET (proposal)

Object reference

The core model, field by field

Generated from the JSON Schema. EN 16931 Business Term mappings appear on the invoicing objects. Extension and profile objects are specified in their own documents, indexed below; their schemas are in the download list.

Foundation layer

Identifier

A typed, scheme-qualified identifier.

FieldTypeCard.Definition
schemestring1Identifier scheme. See codelists/identifierScheme.csv.
idstring1Identifier value within the scheme.
uristring0..1Resolvable URI for the identified entity, where one exists.

Value

A monetary amount (EN 16931 aligned).

FieldTypeCard.Definition
amountnumber1Numeric amount.
currencystring1ISO 4217 three-letter code.
taxIncludedboolean0..1Whether the amount is tax-inclusive.

Period

A span of time.

FieldTypeCard.Definition
startDatestring0..1Inclusive start.
endDatestring0..1Inclusive end.
durationInDaysinteger0..1Convenience duration where dates are indicative.

Classification

A coded classification against a controlled scheme.

FieldTypeCard.Definition
schemestring1Classification scheme.
idstring1Code value.
descriptionstring0..1Human-readable label.

Item

A line item.

FieldTypeCard.Definition
idstring1Item identifier, unique within its containing object.
descriptionstring1What the item is.
classificationClassification0..1
additionalClassificationsClassification[]0..*
quantitynumber0..1Quantity.
unitPriceValue0..1Price per unit.

Credential

Reference to a W3C Verifiable Credential asserting a claim about a Party.

FieldTypeCard.Definition
idstring1Credential identifier.
typestring[]1..*VC types.
issuerIdentifier1Issuing authority.
issuanceDatestring1
expirationDatestring0..1
credentialSubjectobject1The claims, per the VC data model.
proofobject1Cryptographic proof (may be a BBS selective-disclosure proof).
selectiveDisclosureboolean0..1Whether the credential supports zero-knowledge selective disclosure.

Document

A reference to a document or attachment.

FieldTypeCard.Definition
idstring1
documentTypestring1Coded type. See codelists/documentType.csv.
titlestring0..1
urlstring0..1
hashstring0..1Content hash for integrity.
accessGrantIdentifier0..1Reference to a Consent object where access is controlled.

Provenance

Who or what produced an assertion, when, and from what (W3C PROV aligned).

FieldTypeCard.Definition
generatedByIdentifier1The agent or activity that produced the assertion.
generatedAtstring1
derivedFromIdentifier[]0..*
usedPoliciesIdentifier[]0..*
signatureobject0..1Cryptographic signature over the assertion.

Score

A per-criterion evaluation score.

FieldTypeCard.Definition
criterionstring1The criterion scored.
valuenumber1The score.
weightnumber0..1Criterion weight, where applicable.
rationalestring0..1Why this score.

Unit

Unit of measure and unit price.

FieldTypeCard.Definition
codestring0..1UN/ECE Rec 20 unit-of-measure code (e.g. C62, DAY, MTR).
namestring0..1
unitPriceValue0..1

InvoiceLine

A single invoice line. Aligned to EN 16931 BG-25 (INVOICE LINE).

FieldTypeCard.DefinitionEN 16931
idstring1Invoice line identifier.BT-126 Invoice line identifier
notestring0..1BT-127 Invoice line note
quantitynumber1BT-129 Invoiced quantity
unitOfMeasurestring0..1BT-130 Invoiced quantity unit of measure code (UN/ECE Rec 20)
itemNamestring1BT-153 Item name
itemNetPriceValue0..1BT-146 Item net price
netAmountValue1BT-131 Invoice line net amount
classificationClassification0..1BT-158 Item classification identifier
vatCategoryCodestring0..1BT-151 Invoiced item VAT category code
vatRatenumber0..1BT-152 Invoiced item VAT rate

VatBreakdown

A VAT category subtotal. Aligned to EN 16931 BG-23 (VAT BREAKDOWN).

FieldTypeCard.DefinitionEN 16931
taxableAmountValue1BT-116 VAT category taxable amount
taxAmountValue1BT-117 VAT category tax amount
categoryCodestring1BT-118 VAT category code (e.g. S, Z, E, AE)
ratenumber0..1BT-119 VAT category rate

Party

Any actor in the network. Subtyped by role.

FieldTypeCard.Definition
type"Party"0..1
idIdentifier1
identifiersIdentifier[]0..*
namestring1
rolesstring[]1..*
partyTypestring organization · person · agent1
addressobject0..1
contactPointobject0..1
credentialsCredential[]0..*
memberOfIdentifier0..1

Process layer

Need

The demand signal that initiates procurement (OCDS planning stage).

FieldTypeCard.Definition
type"Need"0..1
idIdentifier1
titlestring1
descriptionstring0..1
requestingPartyIdentifier1
budgetValue0..1
classificationClassification0..1
rationalestring0..1
governingPoliciesIdentifier[]0..*Policy references constraining this procurement.

SourcingEvent

A request to the market: RFP, RFQ, ITT, tender, or call-off competition (OCDS tender stage).

FieldTypeCard.Definition
type"SourcingEvent"0..1
idIdentifier1
titlestring1
procuringPartyIdentifier1
procedurestring1See codelists/procedure.csv.
statusstring planned · active · evaluating · complete · cancelled · withdrawn1
lotsobject[]0..*
itemsItem[]0..*
valueValue0..1
eligibilityCriteriaIdentifier[]0..*References to Policy objects.
evaluationCriteriaIdentifier[]0..*References to Policy objects.
periodPeriod0..1
documentsDocument[]0..*

Submission

A supplier's response to a SourcingEvent: bid, tender, quote, or proposal.

FieldTypeCard.Definition
type"Submission"0..1
idIdentifier1
sourcingEventIdentifier1
lotstring0..1
submittingPartyIdentifier1
submittedByIdentifier0..1
itemsItem[]0..*
valueValue0..1
disclosedCredentialsCredential[]0..*
sealedProofobject0..1Encrypted submission + proof where sealed-bid cryptography applies.
statusstring draft · submitted · withdrawn · admissible · inadmissible1

Evaluation

The scoring of a submission against the evaluation criteria.

FieldTypeCard.Definition
type"Evaluation"0..1
idIdentifier1
submissionIdentifier1
criteriaIdentifier1Reference to the Policy holding the evaluation model.
scoresScore[]1..*
evaluatedByIdentifier1The agent (human or synthetic) performing the evaluation.
resultstring passed · failed · ranked1
decisionIdentifier0..1Link to the Decision record.

Award

The decision to award (OCDS award stage).

FieldTypeCard.Definition
type"Award"0..1
idIdentifier1
sourcingEventIdentifier1
awardedPartyIdentifier1
valueValue1
rationalestring0..1
decisionIdentifier1The Decision record supporting the award.
standstillPeriodPeriod0..1Where regulation requires a standstill (e.g. UK Procurement Act).

Contract

The binding agreement (OCDS contract stage).

FieldTypeCard.Definition
type"Contract"0..1
idIdentifier1
awardIdentifier0..1The award it derives from.
partiesIdentifier[]1..*
titlestring1
valueValue1
periodPeriod1
obligationsobligation[]0..*
documentsDocument[]0..*
governingPoliciesIdentifier[]0..*

Order

A call-off or purchase order against a contract or catalogue (UBL Order aligned).

FieldTypeCard.Definition
type"Order"0..1
idIdentifier1
contractIdentifier0..1The contract drawn against.
buyerIdentifier1
sellerIdentifier1
itemsItem[]1..*
valueValue1
deliveryPeriodPeriod0..1

Catalogue

A structured offering of goods/services (UBL Catalogue / Peppol BIS Catalogue aligned).

FieldTypeCard.Definition
type"Catalogue"0..1
idIdentifier1
providerPartyIdentifier1
itemsItem[]1..*
validityPeriodPeriod0..1

Obligation

A contractual obligation, deliverable, or milestone with a compliance state.

FieldTypeCard.Definition
type"Obligation"0..1
idstring1
descriptionstring1
dueDatestring0..1
responsiblePartyIdentifier0..1
statusstring pending · met · breached · waived1
evidenceDocument[]0..*
dischargedByIdentifier[]0..*The Order, Invoice, or Document(s) that discharged this obligation. SHOULD be present once status is `met`.

Invoice

An invoice, fully aligned to EN 16931 so it is convertible to Peppol BIS Billing / UBL Invoice / Factur-X. This alignment is what makes a SIGNET network natively compliant with the EU ViDA cross-border e-invoicing mandate.

FieldTypeCard.DefinitionEN 16931
type"Invoice"0..1
idIdentifier1BT-1 Invoice number
invoiceTypeCodestring0..1BT-3 Invoice type code (e.g. 380 commercial invoice)
issueDatestring1BT-2 Invoice issue date
currencystring1BT-5 Invoice currency code (ISO 4217)
contractIdentifier0..1BT-12 Contract reference
orderIdentifier0..1BT-13 Purchase order reference
settlesIdentifier[]0..*SIGNET-original (not an EN 16931 BT). The Obligation(s) this invoice settles. Omitted on Peppol BIS projection.
sellerIdentifier1BG-4 SELLER (BT-27 seller name resolved via Party)
buyerIdentifier1BG-7 BUYER (BT-44 buyer name resolved via Party)
linesInvoiceLine[]1..*BG-25 INVOICE LINE
vatBreakdownVatBreakdown[]0..*BG-23 VAT BREAKDOWN
lineExtensionTotalValue0..1BT-106 Sum of invoice line net amount
taxExclusiveTotalValue0..1BT-109 Invoice total amount without VAT
taxTotalValue1BT-110 Invoice total VAT amount
taxInclusiveTotalValue0..1BT-112 Invoice total amount with VAT
payableAmountValue1BT-115 Amount due for payment
paymentDueDatestring0..1BT-9 Payment due date
paymentTermsstring0..1BT-20 Payment terms

Agent layer

SyntheticAgent

An AI agent operating in the network as a first-class Party.

FieldTypeCard.Definition
type"SyntheticAgent"0..1
idIdentifier1
namestring1
operatedByIdentifier1
modelstring0..1Underlying model family (provenance only; SIGNET is model-agnostic).
capabilitiesobject[]1..*
mandateIdentifier1
agentCardstring0..1A2A Agent Card location.

Mandate

The authority granted to an agent: what it may do, within what limits.

FieldTypeCard.Definition
type"Mandate"0..1
idIdentifier1
agentIdentifier1
grantedByIdentifier1
permittedCapabilitiesstring[]1..*
constraintsIdentifier[]0..*Policy references: hard limits.
approvalThresholdsIdentifier[]0..*Policy references: human-in-the-loop conditions.
scopeobject1Data and entity scope (sandbox boundary).
validityPeriod0..1

Decision

A decision taken in the network, by a human or synthetic agent, with inputs and rationale.

FieldTypeCard.Definition
type"Decision"0..1
idIdentifier1
decisionTypestring1See codelists/decisionType.csv.
madeByIdentifier1
underMandateIdentifier0..1
inputsIdentifier[]0..*
policiesAppliedIdentifier[]0..*
rationalestring1Human-readable rationale. MANDATORY.
outcomeobject1The decision outcome.
humanApprovalIdentifier0..1
provenanceProvenance1

Policy

A machine-readable, human-auditable rule. Rules-as-code.

FieldTypeCard.Definition
type"Policy"0..1
idIdentifier1
policyTypestring eligibility · evaluation · approval · constraint · compliance1
expressionLanguagestring1e.g. rego, dmn, cel.
expressionstring1The executable rule.
humanReadablestring1Plain-language statement of the same rule. MANDATORY.
versionstring1
issuedByIdentifier1

Trust layer

Event

An append-only record of a material change. Tamper-evident via hash chaining.

FieldTypeCard.Definition
type"Event"0..1
idIdentifier1
eventTypestring1See codelists/eventType.csv (open).
subjectIdentifier1
actorIdentifier1
timestampstring1
payloadobject0..1
previousEventHashstring0..1Hash of the prior event, forming a tamper-evident chain.
provenanceProvenance1

Codelists

Controlled vocabularies

Closed lists are normative; open lists are extensible.

partyRoleClosed
CodeTitleDescription
buyerBuyerThe party acquiring goods/services.
supplierSupplierThe party offering goods/services.
procuringEntityProcuring entityThe entity running the procurement on behalf of the buyer.
payerPayerThe party making payment.
payeePayeeThe party receiving payment.
humanAgentHuman agentA natural person acting in the network.
syntheticAgentSynthetic agentAn AI agent acting in the network.
certifierCertifierAn authority issuing verifiable credentials.
observerObserverA read-only participant (auditor, regulator).
procedureClosed
CodeTitleDescription
openOpenAny interested supplier may submit.
restrictedRestrictedTwo-stage: select then invite.
competitiveFlexibleCompetitive flexible procedureBespoke multi-stage procedure (UK Procurement Act 2023).
directAwardDirect awardAward without competition where permitted.
frameworkCallOffFramework call-offCall-off competition under an existing framework.
policyTypeClosed
CodeTitleDescription
eligibilityEligibilityEntry criteria for participation.
evaluationEvaluationScoring model for submissions.
approvalApprovalApproval routing and thresholds.
constraintConstraintHard limits on agent behaviour.
complianceComplianceRegulatory or policy compliance rules.
submissionStatusClosed
CodeTitleDescription
draftDraftNot yet submitted.
submittedSubmittedLodged with the procuring entity.
withdrawnWithdrawnWithdrawn by the supplier.
admissibleAdmissiblePassed admissibility checks.
inadmissibleInadmissibleFailed admissibility checks.
decisionTypeClosed
CodeTitleDescription
admissibilityAdmissibilityWhether a submission is admissible.
evaluationEvaluationScoring of a submission.
awardAwardDecision to award.
negotiationMoveNegotiation moveA move within a negotiation.
qualificationQualificationDecision to qualify a supplier (onboarding).
identifierSchemeClosed
CodeTitleDescription
didDecentralised IdentifierW3C DID. RECOMMENDED for parties and agents.
gleif:leiLegal Entity IdentifierISO 17442 LEI issued under GLEIF.
gs1:glnGlobal Location NumberGS1 GLN.
vatVAT numberNational VAT registration number.
companies-houseUK Companies House numberUK company registration number.
peppolPEPPOL Participant IdentifierPeppol network participant id.
invoiceTypeCodeClosed
CodeTitleDescription
380Commercial invoiceStandard commercial invoice (EN 16931 BT-3 default).
381Credit noteDocument cancelling all or part of an invoice.
384Corrected invoiceInvoice correcting a previously issued invoice.
389Self-billed invoiceInvoice raised by the buyer on behalf of the supplier.
326Partial invoiceInvoice for part of a delivery or contract.
vatCategoryClosed
CodeTitleDescription
SStandard rateStandard VAT rate applies (EN 16931 BT-151/BT-118).
ZZero ratedGoods/services taxed at zero rate.
EExemptExempt from VAT.
AEReverse chargeVAT reverse charge applies (buyer accounts for VAT).
GExport outside EUFree export item, VAT not charged.
KIntra-community supplyZero-rated intra-community supply of goods/services.
OOutside scopeServices outside the scope of VAT.
eventTypeOpen
CodeTitleDescription
need.raisedNeed raisedA procurement need was raised.
sourcingEvent.publishedSourcing event publishedA sourcing event was published to the market.
submission.lodgedSubmission lodgedA supplier lodged a submission.
evaluation.completedEvaluation completedA submission was evaluated.
award.decidedAward decidedAn award decision was taken.
contract.signedContract signedA contract was executed.
mandate.refusedMandate refusedAn agent action was refused because it fell outside the mandate relied on.
obligation.dischargedObligation dischargedAn obligation reached `met`, discharged by a settling artefact (Order/Invoice/Document).
bid.placedBid placedA bid was placed or revised in an Auction; the ordered bid.placed stream is the hash-chained auction record.
sourcingEvent.plannedSourcing event plannedA sourcing event was created in the planning stage.
sourcingEvent.closedSourcing event closedThe submission window closed and evaluation began.
sourcingEvent.completedSourcing event completedA sourcing event reached its intended end.
sourcingEvent.cancelledSourcing event cancelledA sourcing event was cancelled before completion.
sourcingEvent.withdrawnSourcing event withdrawnA sourcing event was withdrawn by the procuring party.
submission.createdSubmission createdA submission was created in draft.
submission.admittedSubmission admittedA submission was ruled admissible by an admissibility Decision.
submission.excludedSubmission excludedA submission was ruled inadmissible by an admissibility Decision.
submission.withdrawnSubmission withdrawnA submission was withdrawn by the supplier.
obligation.createdObligation createdAn obligation was created pending fulfilment.
obligation.breachedObligation breachedAn obligation was not fulfilled as required.
obligation.waivedObligation waivedAn obligation was waived by the party entitled to enforce it.
auction.scheduledAuction scheduledAn auction was created and scheduled.
auction.openedAuction openedAn auction opened for participation.
auction.startedAuction startedBidding began.
auction.closedAuction closedAn auction closed under its deterministic rules.
auction.cancelledAuction cancelledAn auction was cancelled before close.
bid.withdrawnBid withdrawnA bid was withdrawn by the bidder.
bid.wonBid wonA bid was determined the winning bid at close.
bid.rejectedBid rejectedA bid was rejected as invalid.
bid.supersededBid supersededA standing bid was superseded by a later bid from the same bidder; the payload carries supersededBy.
eventTypeCoreClosed
CodeTitleDescription
consent.grantedConsent grantedA data-sovereignty access grant was issued.
consent.revokedConsent revokedAn access grant was withdrawn before expiry.
mandate.grantedMandate grantedDelegated authority was conferred on an agent.
mandate.revokedMandate revokedDelegated authority was withdrawn before expiry.
documentTypeOpen
CodeTitleDescription
tenderNoticeTender noticeNotice advertising a sourcing event.
evaluationCriteriaEvaluation criteriaThe published evaluation model.
specificationSpecificationTechnical or service specification.
signedContractSigned contractThe executed contract document.
evidenceEvidenceEvidence of obligation fulfilment.

Examples

Worked instances

invoice.json
{
  "@context": "https://concert.foundation/signet/v0.1/context.jsonld",
  "type": "Invoice",
  "id": {
    "scheme": "peppol",
    "id": "INV-2026-000512"
  },
  "invoiceTypeCode": "380",
  "issueDate": "2026-10-05T00:00:00Z",
  "currency": "EUR",
  "contract": {
    "scheme": "did",
    "id": "did:web:buyer.example#contract-3310"
  },
  "order": {
    "scheme": "did",
    "id": "did:web:buyer.example#order-7781"
  },
  "settles": [
    {
      "scheme": "did",
      "id": "did:web:buyer.example#contract-3310/ob-1"
    }
  ],
  "seller": {
    "scheme": "gleif:lei",
    "id": "5299000ACME00NETWRK1"
  },
  "buyer": {
    "scheme": "gleif:lei",
    "id": "5299000BUYER00000001"
  },
  "lines": [
    {
      "id": "1",
      "itemName": "Core router managed service — monthly",
      "quantity": 100,
      "unitOfMeasure": "MON",
      "itemNetPrice": {
        "amount": 50,
        "currency": "EUR"
      },
      "netAmount": {
        "amount": 5000,
        "currency": "EUR"
      },
      "classification": {
        "scheme": "cpv",
        "id": "72720000"
      },
      "vatCategoryCode": "S",
      "vatRate": 21
    },
    {
      "id": "2",
      "itemName": "Field engineering — day rate",
      "quantity": 10,
      "unitOfMeasure": "DAY",
      "itemNetPrice": {
        "amount": 120,
        "currency": "EUR"
      },
      "netAmount": {
        "amount": 1200,
        "currency": "EUR"
      },
      "vatCategoryCode": "S",
      "vatRate": 21
    }
  ],
  "vatBreakdown": [
    {
      "taxableAmount": {
        "amount": 6200,
        "currency": "EUR"
      },
      "taxAmount": {
        "amount": 1302,
        "currency": "EUR"
      },
      "categoryCode": "S",
      "rate": 21
    }
  ],
  "lineExtensionTotal": {
    "amount": 6200,
    "currency": "EUR"
  },
  "taxExclusiveTotal": {
    "amount": 6200,
    "currency": "EUR"
  },
  "taxTotal": {
    "amount": 1302,
    "currency": "EUR"
  },
  "taxInclusiveTotal": {
    "amount": 7502,
    "currency": "EUR"
  },
  "payableAmount": {
    "amount": 7502,
    "currency": "EUR"
  },
  "paymentDueDate": "2026-11-04T00:00:00Z",
  "paymentTerms": "Net 30 days from invoice date."
}
sourcing-event.json
{
  "@context": "https://concert.foundation/signet/v0.1/context.jsonld",
  "type": "SourcingEvent",
  "id": {
    "scheme": "did",
    "id": "did:web:buyer.example#event-1207"
  },
  "title": "Network managed services — Northern region",
  "procuringParty": {
    "scheme": "did",
    "id": "did:web:buyer.example#buyer"
  },
  "procedure": "competitiveFlexible",
  "status": "active",
  "lots": [
    {
      "id": "lot-1",
      "title": "Core transport",
      "value": {
        "amount": 12000000,
        "currency": "EUR"
      }
    }
  ],
  "value": {
    "amount": 12000000,
    "currency": "EUR"
  },
  "eligibilityCriteria": [
    {
      "scheme": "did",
      "id": "did:web:buyer.example#policy-elig-iso27001"
    }
  ],
  "evaluationCriteria": [
    {
      "scheme": "did",
      "id": "did:web:buyer.example#policy-eval-mat"
    }
  ],
  "period": {
    "startDate": "2026-07-01T00:00:00Z",
    "endDate": "2026-08-15T17:00:00Z"
  }
}
award-decision.json
{
  "@context": "https://concert.foundation/signet/v0.1/context.jsonld",
  "type": "Decision",
  "id": { "scheme": "did", "id": "did:web:buyer.example#decision-8842" },
  "decisionType": "award",
  "madeBy": { "scheme": "did", "id": "did:web:buyer.example#agent-eval-3" },
  "underMandate": { "scheme": "did", "id": "did:web:buyer.example#mandate-eval-3" },
  "inputs": [
    { "scheme": "did", "id": "did:web:buyer.example#submission-5521" },
    { "scheme": "did", "id": "did:web:buyer.example#submission-5522" }
  ],
  "policiesApplied": [ { "scheme": "did", "id": "did:web:buyer.example#policy-eval-mat" } ],
  "rationale": "Most Advantageous Tender (price 0.2, quality 0.55, social 0.25). submission-5521 scored 0.859474, ahead of submission-5522 at 0.841500 (margin 0.017974). The dearer bid wins on materially higher quality, accepting a 5.56% price premium over the lower bid.",
  "outcome": {
    "awardedSubmission": "did:web:buyer.example#submission-5521",
    "ranking": [
      { "submission": "did:web:buyer.example#submission-5521", "total": 0.859474 },
      { "submission": "did:web:buyer.example#submission-5522", "total": 0.8415 }
    ]
  },
  "humanApproval": { "scheme": "did", "id": "did:web:buyer.example#approval-771" },
  "provenance": {
    "generatedBy": { "scheme": "did", "id": "did:web:buyer.example#agent-eval-3" },
    "generatedAt": "2026-06-21T14:08:00Z",
    "derivedFrom": [
      { "scheme": "did", "id": "did:web:buyer.example#submission-5521" },
      { "scheme": "did", "id": "did:web:buyer.example#submission-5522" }
    ],
    "usedPolicies": [ { "scheme": "did", "id": "did:web:buyer.example#policy-eval-mat" } ],
    "signature": { "type": "Ed25519Signature2020", "value": "z58…" }
  }
}
need.json
{
  "@context": "https://concert.foundation/signet/v0.1/context.jsonld",
  "type": "Need",
  "id": {
    "scheme": "did",
    "id": "did:web:buyer.example#need-0420"
  },
  "title": "Managed network services — Northern region refresh",
  "requestingParty": {
    "scheme": "did",
    "id": "did:web:buyer.example#buyer"
  },
  "budget": {
    "amount": 12000000,
    "currency": "EUR"
  },
  "classification": {
    "scheme": "cpv",
    "id": "72720000",
    "description": "Wide area network services"
  },
  "rationale": "End-of-life transport equipment refresh across the northern operating region.",
  "governingPolicies": [
    {
      "scheme": "did",
      "id": "did:web:buyer.example#policy-elig-iso27001"
    }
  ]
}
contract.json
{
  "@context": "https://concert.foundation/signet/v0.1/context.jsonld",
  "type": "Contract",
  "id": {
    "scheme": "did",
    "id": "did:web:buyer.example#contract-3310"
  },
  "award": {
    "scheme": "did",
    "id": "did:web:buyer.example#award-2208"
  },
  "parties": [
    {
      "scheme": "did",
      "id": "did:web:buyer.example#buyer"
    },
    {
      "scheme": "did",
      "id": "did:web:acme-networks.example#acme"
    }
  ],
  "title": "Managed network services — Northern region",
  "value": {
    "amount": 12000000,
    "currency": "EUR"
  },
  "period": {
    "startDate": "2026-09-01T00:00:00Z",
    "endDate": "2029-08-31T23:59:59Z"
  },
  "obligations": [
    {
      "type": "Obligation",
      "id": "ob-1",
      "description": "Achieve 99.95% core availability each calendar month.",
      "status": "met",
      "dischargedBy": [
        {
          "scheme": "peppol",
          "id": "INV-2026-000512"
        }
      ]
    },
    {
      "type": "Obligation",
      "id": "ob-2",
      "description": "Complete northern transport migration by 2027-06-30.",
      "dueDate": "2027-06-30T00:00:00Z",
      "status": "pending"
    }
  ]
}
policy-evaluation.json
{
  "@context": "https://concert.foundation/signet/v0.1/context.jsonld",
  "type": "Policy",
  "id": {
    "scheme": "did",
    "id": "did:web:buyer.example#policy-eval-mat"
  },
  "policyType": "evaluation",
  "expressionLanguage": "rego",
  "expression": "package signet.eval\nscore := price*0.2 + quality*0.55 + social*0.25",
  "humanReadable": "Most Advantageous Tender: price 20%, quality 55%, social value 25%.",
  "version": "1.1.0",
  "issuedBy": {
    "scheme": "did",
    "id": "did:web:buyer.example#buyer"
  }
}

Extensions & profiles

The core stays lean; domains extend it

Domain structure is added through extensions and profiles that add object types, fields, or codelist values and never redefine core fields — the OCDS extension pattern. This index is maintained in the standard's repository.

onboarding

Schemas + demo shipped (in-tree, core v0.1); conformance rules ship (conformance/rules/check-onboarding.js)

OnboardingCase, SupplierQualification (durable status with first-class conditional qualification, value caps, category restrictions); credentialType codelist

onboarding.md
auction

Schemas + demo shipped (in-tree, core v0.1); conformance rules ship (conformance/rules/check-auction.js)

Auction, Bid (a profile of the sourcing flow — reverse / english / dutch / sealed-bid / multi-criteria; deterministic, operator-independent close); auctionType codelist

auction.md
identity

Working Draft — schema + worked example shipped; demo emits Approval; conformance rules ship (conformance/rules/check-identity.js)

Approval (verifiable human approval); delegationOfAuthority credential type; normative no-PII rule for hash-anchored records

identity.md
commodity-risk

Spec + schemas + conformance rules shipped — six schemas, ten codelists, an eleven-file full-loop example, and the six rules as an executable checker (conformance/rules/check-commodity-risk.js); separately-namespaced

Portfolio-level commodity risk governance (positions, coverage corridors as Policy subtypes, price marks, assessments, price-shock scenarios, hedge proposals bridging to core Need)

commodity-risk.md
receipt

Working Draft (spec only; schemas to follow)

Receipt, MatchResult — receipt/acceptance and the governed three-way match (tolerances as a matchTolerance Policy; the match is a mandate-bound Decision)

receipt.md
performance

Working Draft (spec only; schemas to follow)

ServiceLevelPolicy, PerformanceAssessment — SLAs/KPIs as Policy and derived, event-anchored supplier performance assessments that feed the qualification lifecycle

performance.md
amendments

Working Draft (spec only; schemas to follow)

Amendment — event-anchored contract deltas (variation / extension / renewal / novation / termination) with derived current state

amendments.md
frameworks

Working Draft (spec only; schemas to follow)

FrameworkAgreement (Contract subtype), CallOff (direct award / mini-competition) with a conformance-checkable drawdown invariant (Σ call-offs ≤ ceiling)

frameworks.md
negotiation

Working Draft (spec only; schemas to follow)

Negotiation, Offer — a governed exchange of offers over named terms under per-term Mandates; the object model behind the existing decisionType: negotiationMove

negotiation.md
requirements

Working Draft (spec; schemas to follow)

Requirement, RequirementSet — what was asked, as a versioned addressable object; selection-is-derivation, variance as a Decision-backed relation; relies on three core sockets (Score.criterionRef, Obligation.provenance, Submission.responses)

requirements.md
auction-platform

Working Draft

Certification profile for eAuction platforms — the first product-certification path; composes the auction + identity extensions and the public conformance suite into five demonstrable requirements (valid objects · deterministic close · tamper-evident record · governed awards · no PII in the chain)

auction-platform.md

The full index — its status vocabulary, the governance notes, and the in-tree versus separately-namespaced rule — is maintained at docs/extensions/README.md at v0.17.1.

Private fields

Carrying local structure without leaving the standard

A published extension is not the only way to add structure. An implementer can carry a private local field - an ERP company code, a cost centre, an internal approval reference - on a core object, without failing document conformance and without publishing anything.

The mechanism
Object schemas admit any property matching ^[a-z][a-z0-9-]*:[A-Za-z][A-Za-z0-9]*$ — a prefix, a colon, a field name — alongside an unchanged additionalProperties: false. It is present at 22 sites across the published schemas. So example-org:costCentre validates, while a misspelled core field carries no prefix and is still refused. That refusal is the property the wire contract rests on, and it is untouched.
What a prefixed field is not
Permitted by the core schema and constrained by nothing else. It is not modelled, not assessed by core conformance, earns no mark, and is never promoted into the core model without first becoming a published extension.
Reserved and forbidden prefixes
signet: and concert: are reserved to Concert, and bare x- is forbidden. These are enforced by the conformance suite rather than by the schema pattern: a negative-lookahead regex works under one validator but sits outside the portable subset others implement, and a governance rule encoded there would be silently unenforced on exactly the implementations least likely to be checked. Prefixes are otherwise self-asserted and first-come — Concert operates no prefix registry.
JSON-LD corollary
A private prefixed field has no context mapping, so it is dropped during JSON-LD expansion. That is semantically correct — a private field has no global meaning — and it is a forcing function: to survive expansion you must publish a context, which is the first step toward being an extension rather than a private field.

Machine-readable source

Download the artifacts

Core model
Extensions & profiles
Codelists

How the standard evolves

Changelog

0.17.12026-09-12

Added

  • docs/positions/onenda-and-signet.md — a positioning paper on adopting oneNDA as the NDA step in sourcing. Non-normative and a proposal only: it states in its own summary that SIGNET does not currently model an NDA, and its front matter carries the claim triad (modelled: none, tested: none, certified: none) as data rather than prose. No schema, closed codelist, event code or governance register changes, and no change proposal is registered by it. public-interface.json declares the file as consumed by the site build.

Changed

  • check-naming.js admits addresses on the domains reserved by RFC 2606 and RFC 6761. allowEmails entries now take *, and the reserved domains are listed in the manifest as data. The rule failed on a worked example showing the shape of a notice address; an address on a reserved domain resolves to no one, so it discloses no person. This is a widening of the rule and is recorded as one — any address the patterns admit stops being a failure. Every other address still fails.

Fixed

  • check-release-version.js (npm run conformance:release-version), in validate.yml: the version in package.json and package-lock.json must equal the newest released heading in this file. The v0.17.1 tag was first cut with a [0.17.1] heading and 0.17.0 in package.json, because the release step cut a tag without the release commit every previous release had made. Nothing in this repository noticed, and the failure surfaced two repositories downstream in the website's build gate. A standard that depends on a consumer to detect its own release inconsistency has the control in the wrong repository — the D-19 shape, recorded again. The tag was re-cut on the corrected commit; nothing consumed the first cut, which existed for minutes and was never pinned by the site.
  • CITATION.cff named version 0.3.0 with a release date of 2026-06-22. It was added once and never touched again, so a citation of this standard has named a version this repository never released since around v0.4.0 — the same fault as the tag, undetected across roughly fourteen releases because nothing downstream reads the file. Corrected to 0.17.1 / 2026-09-12, and check-release-version.js now covers it: the files a release must keep in step are the ones that name a version, not the ones a build happens to consume. cff-version is the CFF schema version and is deliberately not checked.
0.17.02026-09-11

Governance

  • Defect register: D-45..D-52 recorded against the commodity-risk extension (spec/tree divergences: core linkage, event types, policyEvaluationStatus binding, Policy subtype, HedgeProposal lifecycle) and the core primitives it leans on (unit of measure, delivery period, market identifiers). Facts only; no artifact changed.
  • Interests register: entry 4 (steward's origination of the commodity-risk extension and of its remedies).
  • Registered under IAR-0006: CP-Commodity-Risk-Linkage, CP-Quantity-Unit, CP-Market-Identifiers — defect-remedying (D-45..D-52). Adoption parked; comment periods run from ready-for-review.
  • governance/EAE-0001.md — the first external analyst enquiry, received 9 September 2026 and decomposed into six dispositions. Role-based throughout; the originator is a Standards Committee candidate, so the verbatim comments are retained off-tree and the recusal consequence is recorded at intake. The record decides nothing.
  • Defect register: D-58..D-61 recorded, all from EAE-0001 — SourcingEvent has no held state; reissuance has no lineage field; procedure.csv conflates legal procedure with event kind and is framed on one statute; Evaluation admits one evaluator and Score's additionalProperties: false forecloses a per-criterion one. Facts only; no artifact changed.
  • Registered under IAR-0006: CP-Qualification-Lifecycle — defect-remedying (D-57 on its second surface, SupplierQualification). Three gates open; no shape proposed. Adoption parked; comment period runs from ready-for-review.
  • SE-0002 filed through the scope-enquiry route as issue #62 — what Contract denotes in v1, and whether organisational units are in scope. Two registered questions, no proposal. Same route SE-0001 took (#49); the mapping from SE number to issue is recorded here because the records cross-reference SE-0002 by name.
  • Evidence appended from EAE-0001, no existing text edited: CP-Extension-Composition gains §10 Evidence (an independent practitioner statement of the adoption risk the proposal exists to manage); governance/defects.md gains an evidence section carrying the D-39 append and the D-57 second-surface cross-reference, so no defect row is edited.
  • Published governance/RESPONSE-2026-08-implementer-enquiry.md, the response the v0.16.0 entry cited eleven days before it existed (D-40, closed). Drafted against v0.15.0 on 20 August; published against v0.16.1 stating per correction what has landed and what rides IAR-0003 (#43). The enquiry is published de-named; verbatim publication is forbidden by the naming rule. Comment period fourteen days from publication, not waived.

Added

  • Adopter register. registry/adopters.json (opens empty), registry/adopter-entry.schema.json, registry/founding-window.json and tools/check-adopters.js (npm run registry:adopters). An entry is a self-declared statement of practice (accepts, emits, internal-model) by an organisation, never a conformance claim: the schema admits no claim field or free text, and the checker bans claim words in keys and values independently of the schema. The checker also enforces uniqueness, date order, the published CDM namespace version (read from the definitions schema $id) and the founding window. CONTRIBUTING.md gains "Declaring adoption"; the PR template gains an adopter-entry checklist; public-interface.json declares both register files as consumed by the site build. Non-normative.
  • governance/IAR-0007-founding-adopter-window.md — interim resolution establishing the register and a founding-adopter window that closes on constitution of the Standards Committee or at 23:59 UTC 31 December 2026, whichever is earlier. Founding status is a fact about timing and confers nothing. Nine declined alternatives recorded, including alignment to IAR-0006's expiry. Tier 1.

Fixed

  • check-state-model.js gains C11 (terminal reachability), C12 (registry completeness), C13 (authority evidence) and C14 (basis scope). The v0.16.0 entry describing C11 and the D-15/D-16 closures citing C12 and C14 were premature: the registry changes had landed, the checks had not. Recorded as D-53.
0.16.12026-08-30

Added — a registration window, two registered proposals, and the constitution drafts

governance/IAR-0006-registration-window.md reopens registration only, for change proposals that remedy a recorded defect or resolve a timing dependency in a change already in flight. Adoption stays parked and the harm carve-out is untouched. The window expires automatically on constitution of the Standards Committee or at 23:59 UTC 30 September 2026, whichever is earlier, and the record states the new facts that justify revisiting the 20 August standing rule nine days after its adoption, rather than editing the rule away.

Registered under the window, each carrying the required banner, a role-based origin statement and the steward's recusal: governance/proposals/CP-Requirement-Sockets.md — the remedy for D-34, D-35 and D-36 as three additive, target-neutral core sockets — and governance/proposals/CP-Extension-Composition-Amendment-A.md — published-extension fields ride the landed Part 1 pattern with resolution by path, so Part 2 keeps the 2020-12 migration for its remaining merit ($ref siblings) and drops unevaluatedProperties. Registration is not adoption; both wait for the Committee, with their comment periods running meanwhile.

Drafted and deciding nothing until executed at the first session: governance/CONSTITUTION-2026-09.md — appointments void without a completed assessment; quorum is both members; adoption is by unanimity; the steward does not vote; deadlock leaves a proposal Draft with the disagreement recorded; a recused matter falls to the remaining member; the change of constitution trigger is minuted as a decision, not drifted past — with governance/interests-register.md (initiates at execution; the steward's dual role and the SE-0001 recusal are entries 1 and 2), governance/first-session-agenda.md (the twenty interim resolutions triaged into ratification buckets) and governance/member-brief.md (the reading path in, and the habits of the record).

Added — the requirements extension, spec-first, and the defect rows that ground it

docs/extensions/requirements.md (Working Draft — spec; schemas to follow): Requirement and RequirementSet as first-class, versioned, addressable objects; three closed relation types (derivesFrom, varies with a mandatory Decision as authority, testedBy); statement patterns adapted from EARS with deterministic checks only; parameters declared on the requirement and bound on the set; tenancy, quality assessment and requirement content explicitly out of scope. The three core sockets it relies on are proposed, not shipped, and the spec says so.

Grounded by defect rows rather than argument: D-34 (no object addresses an evaluation criterion), D-35 (Obligation records what discharges it and nothing about where it came from), D-36 (a submission cannot state a structured position on what was asked), D-37 (two core identifierScheme codes collide with the extension prefix grammar), D-38 (nine in-tree extension roots lack the Part 1 pattern), D-39 (a generated bare enum would decide gate C-4 by generator shape; resolved on the record as an amendment folded into IAR-0003's open pull request — anyOf of the enum and the prefix pattern, plus a reservation rule for prefixes already used by core codes). D-40..D-42 are recorded from verification candidates checked against main, and D-43 records that forge state — pull requests, review decisions — is invisible to tree evidence, with three instances of records asserting forge state that did not hold; it closes when the inventory extractor gains a forge section or such assertions are forbidden.

.github/ISSUE_TEMPLATE/scope-enquiry.md adds the intake route the originating enquiry had to do without; SE-0001 is the first record through it, filed with the recusal attached.

Added — dialect tooling, report-only

tools/migrate-2020-12.js (mechanical Draft-07 → 2020-12 rewrite) and conformance/rules/check-dialect-equivalence.js (identical verdicts across the corpus under both dialects). Report-only until the v1.0 train decides the migration; a reported verdict difference is evidence for that decision, not a failure of this one.

Changed — CI: the binding step is temporarily non-gating, with its revert condition stated

The closed-codelist binding step carries continue-on-error pending IAR-0003 as amended, whose branch generates the enums and fixes the four failures the step reports (D-14, D-30 — both unchanged by this). The failure stays visible as a warning annotation on every run, and the revert travels with that merge: the check goes hard again at the moment it starts passing. One dated workflow statement instead of repeated required-check overrides.

Added — the wiki becomes a projection

tools/wiki-sync.js: the live GitHub wiki has no pull requests and no CI of its own, so it is treated as a projection of the reviewed wiki/ directory, never an editing surface. The check mode reports drift in both directions — a live-only page is D-33's pattern and requires a human decision — and every push records the source commit, so each live-wiki state traces to a reviewed tree state.

Fixed — the specification's self-description, and the registry it named but did not have

docs/specification.md was the second record to keep the corrected wording out. The v0.16.0 reconciliation replaced the claim that Concert "stewards its evolution through the Standards Committee" with the bootstrap-honest formulation, and landed it in §12.2 — which states plainly that no Standards Committee is constituted — while the same claim survived twenty-two lines from the top of the same file, in "About this document". One document, two statements of the same fact, corrected in one place and not the other. governance/defects.md D-33 records the wiki as the third record to drift on this claim; the pattern is not a missed line, it is that the repository holds the same governance fact in several hand-maintained places and nothing compares them.

The status header was stale in a second way. It read "Specification v0.1 (Working Draft)" and "Status: Request for Comments", and "About this document" said field-level definitions were "illustrative" and "not yet frozen" — against a repository with a machine-runnable conformance suite, four certifiable extensions, a normative state model and an interims register. The header now separates the two identities that were being conflated: CDM v0.1 is the version-stable namespace at https://concert.foundation/signet/v0.1/ and does not move with the repository release. The release number is deliberately not restated in the document. It has a single source in package.json, is rendered into the published page by tools/build-pages.js, and is pinned for the website by standard-ref.mjs; a fourth hand-maintained copy would be stale at the next release, which is the defect being fixed rather than a fix for it.

Also corrected in the same class:

  • docs/specification.md "About this document" cited §11 for change control. Change control is §12; §11 is Extensions. The cross-reference had been wrong since the section was written.
  • docs/extensions/README.md stated that "Standards Committee decision records are published under governance/reviews/". None of them is a Committee decision, because there is no Committee; each is an interim resolution taken under the bootstrap clause.
  • docs/extensions/README.md named the Committee as the operative route for promoting an extension toward the core, and docs/profiles/auction-platform.md referred a grammar question to it. Both now say what is true today and what changes on constitution.

Fixed — the same class in the other hand-maintained records, and what the pattern shows

governance/README.md stated "Twenty interim resolutions are currently in force, across four documents" directly above a table of seven — D-33's fourteen-lines-apart shape compressed to one line. The count is removed rather than corrected: the table is the record, and a number restated in prose drifts out of step with it the moment a resolution is adopted. This is the shape the site checker now forbids on /governance, so the two records fail the same way or not at all.

wiki/Home.md, wiki/FAQ.md and wiki/Governance-and-Versioning.md carried the same "v0.1 (Working Draft / Request for Comments)" / "not yet frozen" self-description that docs/specification.md carried, and two of them stated the repository at v0.10.0. All are corrected the same way as the specification header: the CDM-versus-release identities are separated, and the release number is removed, not re-pinned. A hand-typed release number in wiki prose is the drift mechanism itself, and six releases is the proof.

The asymmetry is the finding, and it is recorded as a dated note on D-33 rather than a new row. The v0.16.0 reconciliation corrected the Standards Committee clause in both records — docs/specification.md §12.2 and wiki/Governance-and-Versioning.md:17 each say plainly that no Committee is constituted. The version claim was corrected in neither, surviving simultaneously in the spec header and on three wiki surfaces. The sweep discipline therefore works per topic, not per record: a reconciliation fixes the clause it was called for wherever that clause appears and leaves every other stale clause in the same paragraph standing. D-33's closure condition is widened accordingly — the cross-reference check it waits on must compare version and status claims, not only enums and process, or the next reconciliation passes over them again.

One further clause: wiki/Home.md, wiki/FAQ.md and the release-history table in wiki/Governance-and-Versioning.md were frozen at exactly 0.10.0, and _site/index.html states the same 0.10.0 under D-23. Four surfaces at one value is not four independent lapses — it dates the last sweep and says the remedy is regeneration rather than editing. The release-history table was subsequently cut rather than backfilled; see below.

Changed — wiki/ is scanned by the naming check, and the release table is cut

conformance/rules/naming-denylist.json adds wiki to its scan list. The rule that Concert names no individual and no commercial implementer covered docs, governance, codelists, schema, conformance and state-model. It did not cover wiki/ — which tools/wiki-sync.js projects to the public GitHub wiki, a Concert-voiced surface with no pull requests and no CI of its own. The rule applied to it on paper and no check ever read it. That is the D-19 shape exactly: the defect is the absent control, and no breach is asserted. check-naming.js's fallback list is kept in step so the two copies cannot disagree; no rule logic changed.

Structurally the newly-scanned files are clean. Salted digest detection needs SIGNET_NAMING_SALT, which is held in CI and not in the repository, so the first pass with name detection actually on runs in CI for this change — not locally, and not before now.

The release-history table in wiki/Governance-and-Versioning.md is cut, replaced by a pointer to CHANGELOG.md as the single release record. A table of releases in a wiki page is a second hand-maintained copy of the changelog — the file class this workstream exists to remove — and it drifted as a second copy does, stopping at 0.10.0 for six releases. It is cut rather than backfilled: six release summaries is authoring, not a correction. The finding is not lost, because it never lived in the table — D-33's dated note records the stale value as evidence dating the last sweep of these pages, and the register keeps the history of the drift while the drifting artifact goes.

Added — the certification register

conformance/certification-register.md: normative, closed, append-only, zero entries.

conformance/certification.md has specified a public registry since it was written — §2 step 4 issues into it, §3 makes the registry record the source of truth and licenses a short-form mark only against "a resolvable link to the registry entry", and §3.1 lists an entry's fields. The artifact did not exist, so §3's resolvability condition was unsatisfiable by construction and a published news post promised implementers a listing in a register that could not be read. That is the D-31 / D-40 family — a released or published record citing an artifact absent from the tree — and it is now recorded three times over, which is the argument for a check rather than for closer reading. Recorded as D-44.

The register opens empty and says so in its own header: emptiness is the accurate state, not a gap in the file. No certification has been issued to anyone, including Score Networks. It is indexed from governance/README.md, linked from certification.md §2, §3 and §3.1, and declared published in public-interface.json, so check-public-interface.js fails if it is ever removed — the register cannot now go missing the way the artifact it replaces never arrived.

governance/README.md's series-gaps note is corrected with it: it stated the defect register ran to D-31 when it runs to D-44, and listed D-33 as reserved on an unmerged branch after that branch merged.

Added — repository inventory extractor (non-normative tooling)

Added tools/inventory/inventory.js: a dependency-free repository inventory extractor producing signet-inventory.json (schema v2), a CLAIMS.json verifier for evidence-bound repository claims in handoff packs, and a CI self-test with the inventory uploaded as a workflow artifact. The inventory is generated, not committed.

Scope is git ls-files. The extractor states what the tracked tree contains — manifest with per-file hashes, schemas with their full field universe, codelists with the register line that decided closure, the state model, conformance requirements and checkers, and the whole text of every tracked Markdown file — and classifies nothing as correct, stale or missing. Where a fact is derived, the line that decided it is recorded alongside.

referencedFields splits every backticked Object.field in tracked prose into shipped, proposed and unresolved against the schemas. It is data, not a gate: making it a gate would fail builds on prose that is already merged, and belongs in its own change proposal.

A claim in a CLAIMS.json with no evidence fails verification rather than warning. A marker that can be read past is not a control.

0.16.02026-08-20

Changed — implementer review of v0.15.0, and three defects it found in four-day-old artifacts

A twenty-one question enquiry from a deploying implementer, answered at governance/RESPONSE-2026-08-implementer-enquiry.md. Corrections landed before the response was written, so the response describes the repository rather than promising it.

docs/state-model.md §2a — CDM status is market-facing (normative). A core state vocabulary describes what a counterparty can observe, not a party's internal governance. This is not a new decision: every core edge must be justified from OCDS, the Procurement Act procedures, UBL / EN 16931 or ePO, and none of those models a buyer's internal review, so an internal-governance edge could never satisfy B-1. Core status has been market-facing by construction since the basis rule landed. Internal workflow goes to a namespaced profile with a declared coreEquivalent; extending a core vocabulary to carry it is forbidden.

§6 B-3 — externality is not generality. B-1 asked only whether a basis was external to the implementer. A national procurement act or a sector security regulation passes that and still should not oblige every implementer in every market. Each basis now carries a scope — general, jurisdictional, implementer — and only general justifies a core entry alone. When the check was first run it flagged two core edges in this repository's own registry; both were corroborated against a general source rather than the check being relaxed. (D-16)

§5 R-3 — derived predicates. A condition computable from another object is neither a state nor an annotation. An Evaluation is "consumed" when an Award references it; that is a fact about the graph, and storing it creates a value that can drift.

§5a — controlled reopen. A transition, not an annotation. A terminal: true state cannot be reopened; an edge marked requiresAuthority must name a decisionType, so the requirement cannot be documented and left unenforced.

§4a — entry-kind test. Does something exist that did not? Creation. Does this object's own state differ? Transition. Is a fact recorded about it? Annotation.

§11 — derived artefacts. Where two records of one relationship exist, keep one and generate the other. sourcingEvent.published drifted for this reason and so did the closed codelists. Contributed by an implementer who measured it: 58 of 68 policy gates carried a transition label disagreeing with the state the rule tested.

Changed — the process claim reconciled with the record

docs/specification.md §12.2 and wiki/Governance-and-Versioning.md had said since v0.1.0 that the core model changes "through the formal revision process governed by the Standards Committee, with a published comment period." Two things were wrong with that. No Standards Committee is constituted. And of the twelve normative changes made between v0.1.0 and 20 August 2026, none carried a comment period.

Both now state the rule that actually applies — a recorded resolution, a stated comment period of at least fourteen calendar days, and an approving review, every change by pull request — say that it took effect on 20 August 2026, say that no Committee is constituted, and point at the audit for what preceded it.

  • governance/IR-2026-08-prior-normative-changes.md — an interim resolution covering the eleven normative changes that carry no approval record. They stand; they are recorded as predating the written rule rather than as having satisfied it; and it is one resolution rather than eleven back-dated approvals, which would be a fabrication of evidence. It is not an assessment of merit: every one passed CI, and the commodity-risk extension was reviewed twice on the record.
  • Both commodity-risk review memos gain a note recording the arrangement under which they were taken. They are titled as Standards Committee reviews and no Committee existed; their closing line, "Recorded for the Standards Committee," is accurate, but the titles read otherwise. The titles are left as written rather than changed after the fact.
  • governance/README.md now indexes the interim approval record, the interim resolution, the withdrawal, and the drafted site corrections, so the bootstrap-clause table is the single index it claims to be.

Closed out, and outside this repository: concert.foundation/governance no longer presents the Standards Committee as a currently operating body. The drafted correction at governance/site-alignment/ was superseded before it was applied — the live page already said what it proposed. The outcome is recorded at governance/site-alignment/OUTCOME.md. Three claims the draft did not examine are addressed in concerthq/concert-website.

Fixed

  • Registry completed to all 29 objects, up from 9. §L-2 has said since v0.15.0 that statelessness by omission is a defect. The registry reproduced that defect in the artifact that defines it. Evaluation is now declared a terminal record. New check C12 fails any schema file without a declaration. (D-15)

  • Closed codelists bound. Not enforced — see the correction below. Five were "type": "string" with the CSV named only in a description; {"procedure": "banana"} validated. codelists/bindings.json binds each closed codelist to the schema location whose enum it governs, and check-codelist-binding.js asserts that the CSV and the enum agree and, with --write, generates the enum from the CSV. Those two artifacts are what landed here. (D-14)

    Corrected 2026-08-21. This bullet was headed "Closed codelists enforced" and ended "Tier 2, landed under governance/IAR-0003." Both statements were wrong. The binding manifest and the checker landed at v0.16.0; the generated enums did not. Generating them alters schema/, which is normative, so it is a Tier 2 act under governance/IAR-0003 — and that record's pull request has never been opened, so its comment period has never started. On main at v0.16.0, five closed codelists carry no enum at the bound property and any string validates against it: {"procedure": "banana"} is accepted today, in the present tense, exactly as this bullet says it once was. check-codelist-binding.js fails on four of the five and records the fifth, identifierScheme, as a binding deferred pending D-20. It was not wired into validate.yml, so nothing surfaced the gap. The tag is not amended — the correction is recorded here, in the entry that made the claim, and as D-30. D-14 is reopened.

  • codelists/submissionStatus.csv deleted. It duplicated the vocabulary carried inline on Submission.status and was referenced by no schema. The inline enum is the single record, as for every other lifecycle-bearing object. The binding check fails if the file reappears. (D-13)

  • Terminal reachability. Check C11, contributed: every lifecycle-bearing object must have a terminal state and every state must be able to reach one. Distinct from C9, which asks only whether a state can be entered — C11 catches an object that can never end.

  • State vocabularies are now generated from the registry, not merely checked against it. §11 said a second hand-maintained copy is a defect; state vocabularies were exactly that, so the rule was violated by the artifact that states it. check-state-model.js --write generates the schema enum from the declared states. This promotes state-model/state-model.json from informative to normative for every lifecycle vocabulary it declares — a normative enum cannot be derived from an informative source — so the file gains CODEOWNERS protection and a change to a declared state is Tier 2 wherever it is made. Landed under governance/IAR-0004. Objects declared lifecycle-bearing but not yet modelled keep their vocabularies. (D-18)

  • codelists/submissionStatus.csv restored, retired but resolvable. Deleting it under IAR-0003 made concert.foundation/signet/v0.1/codelists/submissionStatus.csv return 404 — a published URL in the $id namespace, proxied from main with no cache and no fallback — and failed the site build cold on a second consumer. IAR-0003 stated the file had no consumer; two existed in concert-website, and neither was recorded in this repository, so the claim was unfalsifiable from inside it. That is the defect, not the deletion. The file is restored byte-identical to what was deleted, bound to no schema and absent from closed; codelists/bindings.json carries the disposition and check-codelist-binding.js now distinguishes deleted from retired-but-resolvable, failing in both directions. Retirement says nothing is maintained here; it does not say the URL may stop answering. Landed under governance/IAR-0005. (D-24)

Added

  • docs/absence-discipline.md. Empty, null and absent are three states and only absence fails open: an undefined operand yields an undefined rule body and the rule does not fire. Every negative fixture requires an absence twin. Contributed from a measurement of 259 references across 68 gates, published de-named.
  • conformance/rules/check-naming.js. Concert names no individual and no commercial implementer. That rule has existed since v0.13.0 and was enforced by nothing — the defect is the absent control, and no instance of a breach is identified in the repository. The deny-list is stored as salted digests, never as terms — a published list of names that must not appear is the disclosure it exists to prevent — with the salt held in CI. Verbatim third-party documents are excluded, with the reason recorded in the manifest so the exclusion is auditable. (D-19)
  • governance/defects.md. Promoted out of WITHDRAWAL-2026-08.md so that record stops accreting. Twenty-five entries at this release — twelve closed, twelve open, one in progress.
  • governance/REVERSAL-RISK.md. Each interim resolution gains a band and reasoning, answering an implementer question about which of twenty unratified decisions carry reversal risk. Eighteen are unassigned, and unassigned reads as unassessed rather than low.

Governance

  • governance/IAR-0005-published-url-restoration.md — Tier 2, under the bootstrap clause, restoring the published URL above. Its stated fourteen-day comment period did not run. The record was merged on the day it was opened, because the period would have extended a live 404 by fourteen days.

    That is recorded as a departure, not an exemption. GOVERNANCE.md requires the period before merge for every Tier 2 change and names no exception for urgency, and the carve-out in governance/WITHDRAWAL-2026-08.md is an exception to the proposal moratorium that itself requires a stated period. The rule applied and was not observed, and GOVERNANCE.md names such a merge a defect in this process. The stated period is left in the record verbatim and the departure is recorded beside it, on the shape of IAR-0002. Comment remains open for fourteen days from merge; the change will be reversed or amended on sustained objection. What does not stand is any claim that this record followed the process in full. (D-29)

  • Four defects recorded since the register was drafted. D-24 closed — the 404 above. D-27 open — the repository declares no public interface, so a claim that a file has no consumer is not testable from inside it. D-28 open — codelists/*.csv admits no comment line, so the format cannot record that a file is retired. D-29 open — it closes when GOVERNANCE.md gains a carve-out for a defect actively causing harm, adopted under its own Tier 2 route. D-25 and D-26 are reserved for the site-pinning work and are not recorded here.

Note on interests

The enquiry is signed by the same natural person who operates both stewardship identities — the most acute instance of the disclosed overlap to date. Accordingly the enquiry is published verbatim, the response carries the full comment period with no waiver, and no correction here rests on the enquiry's evidence: each is verifiable against schema/, codelists/ and conformance/ by a reader who has never seen it. Contributed patterns are adopted as evidence, published de-named, and are never basis.

The bootstrap arrangement was scoped to let design proceed without a Committee. It was not scoped to absorb a public enquiry from the steward's own implementer alongside twenty unratified resolutions. The governance load, not the design load, is now the binding constraint.

0.15.02026-08-20

Added — the state model: surface authority, a transition registry, and the basis rule

Design principle §1.7 and conformance/levels.md GRT-1 both say the event stream is authoritative. Neither was executable: projecting a stream into a state needs a mapping from events to state changes, and no artifact published one. Mandate asserted a lifecycle it could record on no surface; sourcingEvent.published named a state the enum does not contain; nine objects carried a state field and one rule governed none of them.

  • Surface authority stated generally (docs/state-model.md §2). Current state is the projection of the event stream. A stored state value is the serialising party's assertion as at provenance.generatedAt and MUST equal the projection at that instant; between parties holding the stream, the projection governs. This generalises GRT-1 from grant-type objects to all objects, and supplies the rule whose absence was the stated reason status fields on Consent were rejected. No field is added to any object — that rejection is closed out, not reopened.
  • Transition registry (state-model/state-model.json). Three entry kinds — creation, transition, annotation. Every state declares terminal, appendable, and a terminal class of completion / abandonment / revocation. Event codes may serve several entries provided their source sets are disjoint, which is what makes projection a function.
  • Relations are not states; outcomes may be (§5). Bid.superseded is a relation and cannot be projected — removed from the enum and expressed as a bid.superseded annotation event carrying supersededBy. admissible, winning, approved and qualified are outcomes of Decisions, are projectable, and stand unchanged.
  • The basis rule as a CI check (conformance/rules/check-state-model.js). Every core entry must name an external justification — OCDS status codelists, the Procurement Act 2023 procedures, UBL/EN 16931 lifecycles, ePO, or a named instrument. An edge justifiable only from one implementer's workflow goes to a profile. This is the neutrality control, deliberately automated rather than left to review: it runs on every push and is auditable after the fact.
  • 21 open codelist values added to codelists/eventType.csv. eventTypeCore.csv is untouched.
  • A reachability defect fixed without a schema change. A Submission ruled admissible could not reach withdrawn under any reading of the enum. The registry permits the edge.

Coverage is reported, not assumed: five of eight lifecycle-bearing objects are modelled. OnboardingCase, SupplierQualification and HedgeProposal are declared lifecycle-bearing and not yet modelled — their edges need a basis from the extension maintainers. ExposurePosition.positionStatus is declared non-lifecycle: it classifies what a position is, and reconciliation depends on it as a category.

No conformance requirement is added. This is modelled and specified, not certified. An F-STATE requirement belongs at Full and is deferred.

Four of the five artifacts are Tier 1. The one Tier 2 item — removing superseded from Bid.status — lands under the bootstrap clause per governance/IAR-0002-state-model.md. Landing does not ratify.

The fourteen-day comment period was waived. It opened on 20 August 2026 and would have closed on 3 September; the change was merged on 20 August by explicit decision of the repository owner. This is a recorded departure from GOVERNANCE.md Tier 2, not an interpretation of it, and it is written into governance/IAR-0002-state-model.md rather than left to be inferred from the merge dates. No comments were received, because there was no interval in which to receive any. The change stands on its merits; what does not stand is any claim that it followed the process in full.

Changed — the v1.0 proposal train withdrawn; its findings kept

The seven registered proposals are parked, not rejected, per governance/WITHDRAWAL-2026-08.md. Registration is Tier 1 and adoption is Tier 2, so a queue that costs one review to grow and a Committee to clear will grow without bound. Eight defects are extracted and recorded as facts about current artifacts; five are addressed by the change above, three stand open. No further proposals are registered until the Committee is constituted, except to correct a defect actively causing harm.

Found — one of twelve normative changes carries an approving review

An audit of every commit since v0.1.0 touching a Tier 2 path, at governance/reviews/2026-08-normative-approval-audit.md. Twelve commits qualify. One carries an approving review; two carry a written approval record of any kind; four reached main as direct commits with no pull request; none had a stated comment period, which the specification and CONTRIBUTING.md have claimed for normative changes since v0.1.0.

Nothing merged is thereby wrong — every commit passed CI, and the commodity-risk extension was reviewed twice on its substance. The gap is in evidence of process, not in care. But it means v1.0 cannot currently claim its normative content went through the process the specification describes, which is the same shape as the two conformance findings behind the endorsement proposals. Recorded before the fact rather than after someone else establishes it, and deliberately not relabelled: the audit recommends one resolution acknowledging the eleven as predating the written rule, not eleven back-dated approvals.

Added — GOVERNANCE.md: the review rule, written down

The rule was being followed by habit. Writing it down now makes it a choice; writing it after someone observes that normative changes were merged by a second account under the same control would be damage control, and would read as such.

  • Two-tier review, by pull request only. Tier 1 (non-normative) takes one approving review and no comment period. Tier 2 (schema/, closed codelists, conformance/levels.md, the suite, the report schema — and the mark grammar and the two closed registers, which are normative for licensees rather than CDM artifacts) additionally requires a recorded resolution and a stated comment period of at least 14 calendar days. Direct commits to main are not a permitted route for any change of any class.
  • The Standards Committee is not constituted, and the document says so. It will be constituted at the first external certification — externally observable, and not quietly deferrable. Until then decisions are interim resolutions under the bootstrap clause, which stays authoritative in governance/README.md and is referenced rather than paraphrased.
  • The two repository identities are disclosed. concertfoundation authors; concertcustodian reviews, approves and merges; both are operated by the same natural person. The separation is procedural, not independent, and the document says that in those words. A governance document that implied independence it lacks would be worse than none, because it would convert an undisclosed limitation into a false statement.
  • Registration is not adoption. governance/proposals/ is non-normative: a proposal's presence in this repository is not a statement that it has been accepted, and it is not part of the standard.
  • An effective date, and no retroactive relabelling. The process applies from 20 August 2026. Earlier changes followed prior practice — including direct commits to main and pull requests merged with administrative override — and are recorded as superseded, not as having followed a rule that did not exist.

Found — the published governance page contradicts the repository

concert.foundation/governance presents the Standards Committee as a currently operating body, with a membership composition. The repository states that none is constituted, and twenty interim resolutions are in force precisely because none is. A draft correction for the page is recorded at governance/site-alignment/, not applied — the page is outside this repository. This is the same class of defect the claim triad exists to catch: a body that is designed being described as one that is operating.

Superseded. The drafted correction was overtaken before it was applied; the live page already stated what it proposed. Recorded at governance/site-alignment/OUTCOME.md.

0.14.02026-08-20

Added — the v1.0 train, specified and registered (not started)

Four further proposals from a second round of multi-market, multi-tenant implementation questions, plus an amendment record that revises two of the existing ones. Nothing here touches a normative artifact. The seven proposals that make up the v1.0 train are registered so the train can be planned, sequenced and estimated; twenty-two gates are open and every one of them is for the Standards Committee.

  • CP-EventType-ClosureeventType has eight values for eighteen objects and stops at contract.signed; the entire implementation stage has no codes. The gap is already being filled silently: an implementation that places an Order must emit an Event, there is no code for it, so it mints one and passes conformance. The proposal derives the vocabulary from the existing lifecycle enums and checks it in CI for drift, rather than curating it by hand.
  • CP-Policy-Applicability — every gate in the model is opt-in at instance level: a Policy that is never cited is never applied. Adds Policy.appliesTo and a derived required-set, with a new F-GATE requirement at Full.
  • CP-Mandate-ScopeMandate.scope is required and completely unconstrained. {} satisfies it. Adds structure, and an F-SCOPE requirement whose limit is stated rather than left to be discovered: SIGNET can test what an agent declares it read, not what it actually read.
  • CP-Process-SpineSourcingEvent has no link back to Need, the one break in an otherwise fully linked spine. One optional field. The only item in the set that delivers value alone, and a candidate for an earlier v0.x minor.
  • CP-Amendments-Round-2 — recorded as a reviewable amendment rather than folded silently into what it touches, and applied to both. §A1 adds same-tenant event chaining to CP-Tenancy; §A2 dissolves gate C-3 in CP-Codelist-Enforcement.

Two gates dissolved rather than resolved, which is why the train's gate count fell from twenty-four to twenty-two:

  • Event chain partitioning. The question — is the chain partitioned by tenant, or one chain with tenant recorded per event — is well-formed, and the model answers it in neither of the terms offered. The chain is per subject: there are as many chains as there are subjects. There is nothing to partition, so isolation becomes a conformance rule over the existing structure. What that does not give you is stated too: there is no total order within a tenant, and any tenant-level ordering is a projection an implementation constructs.
  • C-3 retirement semantics. A closed vocabulary over an append-only stream cannot retire a value, because retirement means "no longer valid" and every historical event asserts otherwise. Codes are never retired. The discouraged marker becomes guidance in the non-normative disposition file; the fourth CSV Status column is declined with its reasoning, because it is the obvious answer and will be re-proposed otherwise.
0.13.02026-08-19

Added — extension composition, part 1: namespaced private fields

Proposed under CP-Extension-Composition and landed ahead of ballot under the bootstrap clause: schema/ and conformance/suite/ are normative, so it went through the change-proposal path rather than a direct merge, non-breaking though it is. Landing it does not ratify it — the proposal remains a draft until balloted, and the Standards Committee may amend or reverse it.

The Extensions page has always told implementers to add structure "under their own namespace." Against the published schemas that instruction was unexecutable: every object schema sets additionalProperties: false, so an ERP company code, a cost centre or an internal approval reference could not be carried at all without failing document conformance.

  • Object schemas now permit namespaced properties. A patternProperties entry admitting ^[a-z][a-z0-9-]*:[A-Za-z][A-Za-z0-9]*$ sits alongside the unchanged additionalProperties: false, at 22 sites: the 18 root objects, Obligation, Item, InvoiceLine, and the inline Lot. So example-org:costCentre validates, while procurringParty — a misspelling of a core field — is still refused, because it carries no prefix. That refusal is the property the wire contract rests on and it is untouched.
  • Say exactly what a prefixed field is. Permitted by the core schema and constrained by nothing. It is not modelled, not assessed by core conformance, earns no mark, and is never promoted into the core model without first becoming a published extension. Nothing here adds tenancy, market or marketplace support, and nothing here is a partial delivery of CP-Tenancy.
  • signet: and concert: are reserved; bare x- is forbidden. Both are enforced by the conformance suite rather than the schema pattern: a negative-lookahead regex works under Ajv but sits outside the portable ECMA-262 subset that non-JavaScript validators reliably implement, and a governance rule encoded there would be silently unenforced on exactly the implementations least likely to be checked. Prefixes are otherwise self-asserted and first-come — Concert operates no prefix registry.
  • Four fixtures, so the escape hatch is proven rather than asserted. fixtures/valid/order-private-extension.json (new, and the load-bearing one) must validate; party-unknown-property.json (new) must be rejected; party-reserved-prefix.json (new) must validate against the schema and still be refused by C-DOC; and party-bad.json is narrowed to the partyType enum rule alone, its additionalProperties role having moved to party-unknown-property.json. Without the positive fixture a later schema edit could close the hatch unnoticed.
  • A JSON-LD corollary, documented so implementers do not meet it by surprise. A private prefixed field has no context mapping and is therefore dropped during JSON-LD expansion. That is semantically correct — a private field has no global meaning — and it is a useful forcing function: to survive expansion you must publish a context, which is the first step toward being an extension rather than a private field.

Non-breaking. Every instance valid before this change is still valid, and existing certifications are unaffected.

Added — the tenancy change-proposal set

Three linked proposals registered in governance/proposals/, arising from a multi-market, multi-tenant implementation question. None is balloted and none is implemented beyond Part 1 above.

  • CP-Extension-Composition — two mechanisms where the model conflates one: a private prefixed field (Part 1, above) and a composed published extension (Part 2, requiring the 2020-12 migration and therefore the v1.0 train). Three gates open.
  • CP-Tenancy — tenant, market and marketplace are three independent concepts and none exists in the CDM; today all three are carried implicitly in the DID authority of an identifier, which is unpatchable once instances exist. Breaking, so v1.0 or never. Four gates open; T-4 resolved as deferred — a network of SIGNETs is a roadmap item, Event.tenancy.marketplaces would record the emitting node as attribution only, and no federation capability is claimed.
  • CP-Codelist-Enforcement — seven closed codelists are enforced by nothing: they are "type": "string" with a CSV pointer in a description, so "procedure": "banana" passes C-DOC today. Four gates open. It must land in or before the v1.0 train if CP-Tenancy does, or v1.0 ships regulatoryRegime modelled as closed and tested as open — the claim-triad failure the suite exists to prevent.

Added — governance: marks, registers, and two conformance findings

A single workstream. It began as a question about where implementation-roadmap collateral should sit, and drafting a competency framework against the actual JSON schemas rather than the wiki prose surfaced two gaps between what is claimed and what is tested. Those are the substantive discovery; everything else is consequence.

  • The two findings. Consent has no conformance requirement — C-DOC validates it structurally and nothing tests that access is gated, that revocation takes effect, or that Document.accessGrant is honoured. And mandate enforcement is demonstrated, not certified — F-SEM requires a Decision to cite policiesApplied; nothing requires the limits in those policies to have been respected. An implementation that awards beyond an approvalThresholds policy with no humanApproval, while recording underMandate and policiesApplied correctly, passes F-SEM and reaches Full. The record is well-formed, hash-chained, provenance-bearing, and false. Both are now stated plainly in conformance/levels.md §5 and conformance/README.md, whatever happens to the proposals below.
  • governance/mark-grammar.md — the complete set of marks Concert issues, in one document rather than extended per requirement: three head terms never crossed (SIGNET Certified for implementations, SIGNET Registered for people, SIGNET Accredited for training providers), an ASCII ABNF, short forms licensed only where they resolve to the registry, prohibited constructions, the wind-down windows, and what anyone may say without a licence. Six interim resolutions recorded with their reasoning. Marks as W3C Verifiable Credentials was considered and declined, with the reasoning kept because the idea will return.
  • tools/lint-mark-strings.js (npm run lint:marks) — the ABNF, checked mechanically in CI, against the registers rather than a hard-coded list. It also fails the build on a superseded mark form or a prohibited construction anywhere in published copy.
  • Two registers, closed and append-onlygovernance/endorsement-register.md (two entries, each recording the three-part admission test; Consent Enforcement carries its scope limit in the register itself) and governance/role-register.md (four roles; Foundations confers no mark).
  • governance/role-competency-framework.md and governance/person-assessment.md — what a person must be able to do, stated by reference to normative artifacts, with the assessment mode declared per domain, plus the rubric and the binding appeals route that must exist before any person mark issues.
  • Four change proposals in governance/proposals/, none balloted: grant lifecycle, mandate enforcement (E-MDT), consent revocation (E-CNS), and credential semantics.
  • Endorsements — a second, additive axis (conformance/levels.md §2.4). Draft and not in force: conformance/rules/check-endorsements.js runs twelve checks against two optional adapter surfaces (conformance/adapter/endorsement-adapters.md), decides no level, and licenses no mark.
  • A third planted defect in the broken adapter — an agent that cites its mandate and its policies correctly and does not enforce them. It passes F-SEM and fails E-MDT-1, in CI, on every commit. The distance between those two results is the whole argument for the endorsement, and it is worth keeping even if that proposal is declined.
  • codelists/eventTypeCore.csv — a closed, normative core subset within the open eventType list, with consent.granted, consent.revoked, mandate.granted, mandate.revoked. The two mandate.* codes are promoted, not added: their meanings are fixed rather than changed. Protected by CODEOWNERS, and conformance/rules/check-codelists.js asserts in CI that the open and closed files never intersect — a closed codelist whose closure depends on someone noticing is not closed.

Changed

  • Specification §7.4 — grant-type objects and withdrawal. A normative defined term (Consent and Mandate, enumerated), the rule that withdrawal is an appended event and never a mutated field, and the effective/not-effective projection rule, reproducible by a third party from the event stream alone. No schema changeEvent.subject already carries the grant identifier. No *.expired code exists: expiry has no actor, and Event requires one.
  • Positioning corrected against the claim triad. Modelled, tested, and certified are three different statements, and the copy blurred them — always in the direction that overstates. The Architecture Overview no longer says conformance with the specification's MUSTs "is decided mechanically by the Conformance Harness" without qualification; Mandate is no longer "the structural guarantee that agents cannot exceed their remit"; and the auction profile's AP-4 now says it tests record completeness, not that the ceiling held.
  • The canonical mark form is now SIGNET Certified: Full (CDM v0.1, suite v0.1) — ASCII, colon-delimited, lintable. The em-dash form is superseded and CI rejects it.
  • Consent.purpose and Consent.revocable descriptionspurpose is a human-readable statement, not a machine-evaluable term, with the profile extension path stated; revocable is a capability flag, not a status.

Note on status

Nothing here has been balloted. Twenty interim resolutions are in force under the bootstrap clause, each ratifiable, amendable, or reversible by the Standards Committee once constituted. CP-Grant-lifecycle is the only item that must clear before v1.0; its mechanism is landed ahead of ballot because closing a codelist subset is materially cheaper before publication under a stable URI and DOI than after. Neither endorsement proposal gates v1.0 — both must land before the first certification, which is a separate and later constraint.

0.12.02026-07-20

Added

  • Auction conformance profile — the first product-certification path (docs/profiles/auction-platform.md), composing entirely from shipped artifacts: it names five demonstrable requirements (valid objects, deterministic close, tamper-evident record, governed awards, no PII in the chain) checkable with the public suite.
  • Extension conformance rules — executable cross-object checkers for the onboarding (case↔qualification closure, conditional integrity), auction (the recorded winner equals the deterministic close; reserve integrity), and identity (Full-level: humanApproval resolves both ways; approver ceiling covers the decided value) extensions, wired into CI. All four extensions now have machine-backed conformance. Governance: commodity-risk resubmission record — merged as Working Draft.
  • Five P2P/SRM extension specs (Working Drafts, spec-first) — receipt & governed three-way match; supplier performance (SLAs as Policy, assessments feeding the qualification lifecycle); contract amendments (event-anchored deltas, derived state); framework agreements & call-offs; negotiation under per-term mandates. Schemas and conformance rules follow per-extension after review, per the process established by commodity-risk.
0.10.02026-07-05

Added

  • Onboarding extension spec at docs/extensions/onboarding.md (previously undelivered; schemas and demo shipped in 0.6.x).
  • Commodity-risk extension — technical artifacts. Six schemas (ExposurePosition, CoveragePolicy as a Policy subtype, PriceMark, CoverageAssessment, Scenario, HedgeProposal), ten codelists (positionStatus and policyEvaluationStatus closed), an eleven-file full-loop worked example (belowMinimum → proposal → executed → withinCorridor, arithmetically reconciled), and the six conformance rules as an executable checker (conformance/rules/check-commodity-risk.js) — three are cross-object checks beyond schema validation: reconciliation arithmetic, scenario fixed-cost invariance, escalation-first rule ordering. Completes the extension accepted in principle in governance/reviews/2026-07-commodity-risk.md.
0.9.02026-07-05

Added

  • Identity profile (Working Draft)docs/extensions/identity.md: how SIGNET represents natural persons. Humans act under Mandates (core Mandate reused — agent accepts any actor); authority is a delegationOfAuthority Credential; new Approval object makes humanApproval resolvable and verifiable (approver pseudonym, role, authority credential, provenance). Normative no-PII rule for hash-anchored records (pseudonymous person references only; resolution is an organisational obligation). Authentication is out of scope by design. The agent demo now emits the verifiable Approval at runtime and checks the approver's authority ceiling covers the award value.
  • Commodity-risk extension (Working Draft spec)docs/extensions/commodity-risk.md: portfolio-level commodity risk governance (positions, coverage corridors as Agent-layer Policy subtypes, price marks, assessments, scenarios, hedge proposals bridging to core Need). Accepted in principle by the Standards Committee (governance/reviews/2026-07-commodity-risk.md) — the first member-proposed extension, reviewed under the identical process as any proposer. Schemas, worked example, and conformance rules to follow as a separate change.

Changed

  • Documentation & demo alignment. Brought the repository's prose level with its code: the top-level README.md now documents the conformance harness, the three demonstrations (agent award, onboarding, auction) with their current outcomes, and an Extensions & profiles table with per-item status. agent/README.md was corrected to the current MAT weighting (price 0.20 / quality 0.55 / social 0.25 — the dearer, higher-quality bid wins 0.859474 vs 0.8415) and the verifiable-Approval check. Extension specs are consolidated under docs/extensions/<id>.md (the auction spec renamed to auction.md) with a new docs/extensions/README.md index; the wiki sidebar points at the specs and demos. No schema or normative change.
0.8.02026-07

Added

  • Auction extension — process-layer objects Auction (a profile of the sourcing flow; reverse / english / dutch / sealed-bid / multi-criteria via auctionType + deterministic rules) and Bid. The auction rules and canonical bid record are normative and operator-independent — any conformant operator closing the same bids under the same rules MUST reach the same Award. The close reuses Decision/Award; eligibility ties to SupplierQualification; the bid history is a hash-chained Event trail. Open auctionType codelist; reverse-auction worked example. Modelled on Prozorro's neutral-core architecture: price formation in the standard, UX in the operators.
0.7.02026-06

Added (all optional, non-breaking)

  • Settlement linkage — makes the commitment→discharge loop traversable as data (Concepts of Open Commerce §9, the Settlement primitive):
    • Obligation.dischargedBy — references the Order/Invoice/Document(s) that discharged the obligation. SHOULD be present once status is met.
    • Invoice.settles — references the Obligation(s) the invoice settles. SIGNET-original: it is not an EN 16931 Business Term and is omitted on the Peppol BIS projection, so ViDA convertibility is unchanged. A new projection-skip guard (npm run test:projection-skip) proves settles never leaks into UBL.
    • eventType codelist: obligation.discharged.
    • Three worked fixtures, all conformance-checked: a discharged obligation, a pending obligation carrying neither new field (the machine proof the additions are optional), and an invoice with settles.
  • Referent granularity uses a composite contractId/obligationId URI (option (a)); Obligation.id is unchanged. No existing field changed; documents valid before this release remain valid.

Changed (non-breaking; examples only)

  • MAT evaluation policy reweighted to price 20% / quality 55% / social value 25% (was 40 / 35 / 25). The change is carried in the policy's own expression (score := price*0.2 + quality*0.55 + social*0.25) and its humanReadable statement; examples/policy-evaluation.json bumped to version: 1.1.0. The agent demo reads the weights from the Policy expression, so its trace and scores regenerate from this single source.
  • Award scenario now demonstrates a justified price premium. Under the new weighting the dearer bid wins: submission-5521 (€11.4M, quality 0.9, social 0.7) scores 0.859474, ahead of submission-5522 (€10.8M, quality 0.78, social 0.85) at 0.841500 (margin 0.017974) — a 5.56% price premium accepted on materially higher quality. The demo is now a proof of governed multi-criteria judgement rather than a low-bid pick. examples/award-decision.json (Appendix A) and the agent run resolve to the same winner, weights, and scores.
  • The award value (€11.4M, the winning bid) remains intentionally distinct from the contract value (€12M, the category tier) in examples/contract.json: awards are struck at the bid, contracts at the tier/ceiling. No schema or normative-grammar changes; sub-criterion scores are unchanged, only the weighting and resulting totals.
0.6.02026-06

Added

  • Supplier onboarding extension — process-layer objects OnboardingCase (buyer-internal workflow; invited + submitted entry; revalidation/remediation case types) and SupplierQualification (durable status with first-class conditional qualification, value caps and category restrictions). Reuses Credential/Policy/Decision/Event/Consent. Screening results carried as attestations, never performed by SIGNET. Open credentialType codelist; two worked examples. Workflow states are normative; credential types are extensible.
0.5.02026-06

Added

  • Agent demonstration (agent/) — a runnable proof that a synthetic agent can take a governed, accountable, conformant action. An agent reads a SourcingEvent, is bounded by a Mandate (its €12M value exceeds the €10M autonomous ceiling, so human approval is required), applies the published MAT evaluation Policy (weights parsed from the Policy's own expression), and emits an Award Decision with rationale, inputs, policies applied, human approval, and provenance — plus a five-event, hash-chained audit trail.
    • agent-card.json (A2A), mandate.json, two Submission bids, assessment inputs.
    • reasoner.js — the pluggable "Model" (deterministic default; marked seam for a live frontier model via MCP/A2A).
    • agent-runtime.js — the "Harness": mandate gate, policy application, provenance, event-chaining.
    • run-agent.js — runs the scenario, narrates it, and verifies the output is conformance-clean (every object validates; chain holds; tampering detected).
    • LIVE_MODEL_NOTE.md — how to swap in a real model for a live demo with no change to the harness.
  • CI now runs the agent demo on every commit; its output must validate and the event chain must hold.
0.4.02026-06

Added

  • Conformance harness (conformance/) — the machine-runnable suite behind the "SIGNET Certified" mark. Implements CDM §13 and the certification neutrality rules CN-1…CN-4.
    • levels.md — Core vs Full levels; requirements C-DOC, C-EVT, C-PROV (Core) and F-MAP, F-SEM (Full); CN neutrality rules.
    • certification.md — the identical-for-all certification process.
    • runner/run-conformance.js — runs the suite against any implementation via a small adapter, emits a machine-readable report, computes the level achieved.
    • adapter/reference-adapter.js — a complete conformant implementation (reaches Full); adapter/broken-adapter.js — deliberately non-conformant, failed by the harness at C-EVT and F-MAP, proving the suite discriminates.
    • Positive + negative document fixtures (invalid documents that MUST be rejected).
    • report-schema.json — schema every conformance report conforms to (CN-4).
  • CI now runs the harness on every commit: the reference implementation must reach Core+, and the broken implementation must be rejected.

Changed

  • tools/signet-to-ubl.js refactored to export a pure toUBL(invoice) function (shared by the CLI, the harness, and the website); CLI output unchanged.
0.3.02026-06

Added

  • tools/signet-to-ubl.js — a dependency-free reference transform that projects a SIGNET canonical Invoice into a UBL 2.1 Invoice conforming to Peppol BIS Billing 3.0 (EN 16931 compliant). Each mapping is annotated with its BT/BG reference.
  • examples/invoice.ubl.xml — the generated Peppol BIS Billing output for the worked invoice, committed so the projection is visible without running it.
  • tools/verify-ubl.py — parses the generated UBL and reconciles every key EN 16931 Business Term and the monetary totals against the source invoice; exits non-zero on mismatch.
  • CI now runs the transform and verification on every push, so "convertible to Peppol BIS" is a continuously-proven claim, not an assertion.
  • npm run transform and npm run verify-ubl scripts.

Notes

  • This is a faithful reference projection, not a substitute for official Peppol validation. Production use should additionally run the output through the Peppol/EN 16931 XSD + Schematron validation artefacts.
0.2.02026-06

Added

  • Complete process layer. JSON Schema for the remaining OCDS-aligned lifecycle objects: Need, Evaluation, Award, Contract, Order, Catalogue, Obligation, and Invoice.
  • EN 16931 building blocks in the foundation definitions: Unit, InvoiceLine, and VatBreakdown, with field-level mappings to EN 16931 Business Terms.
  • EN 16931-mapped Invoice schema and worked example. The Invoice carries 33 EN 16931 Business Terms / Groups (BT-1…BT-158, BG-4/7/23/25), so a SIGNET invoice is convertible to Peppol BIS Billing / UBL Invoice / Factur-X. This is the structural basis for the EU ViDA cross-border e-invoicing claim.
  • New worked examples: need.json, contract.json (with embedded obligations), and invoice.json (EN 16931-mapped, arithmetically consistent: €6,200 net + €1,302 VAT @ 21% = €7,502 payable), all CI-validated.

Fixed

  • BT-mapping annotations on $ref fields are now preserved under Draft-07 by wrapping the reference in allOf (Draft-07 ignores keywords that sit beside a bare $ref). EN 16931 traceability is now structurally retained in the schema.
0.1.02026-06

Added

  • Foundation layer: Identifier, Party, Value, Period, Classification, Item, Credential, Document, Provenance, Score.
  • Process layer (initial): SourcingEvent, Submission, Policy.
  • Agent layer: SyntheticAgent, Mandate, Decision.
  • Trust layer: Event, Consent.
  • JSON-LD @context aligning to ePO, PROV, and W3C VC.
  • Closed and open codelists (CSV).
  • Worked examples with CI validation.

Notes

  • This is a working draft for community review. Field-level definitions are illustrative of the model's shape and not yet frozen.
  • Targets JSON Schema Draft-07 for maximum implementer-tooling compatibility. A migration to 2020-12 will be considered before v1.0.
Concert

Adopt SIGNET

Adoption is free, public, and takes one pull request. It is a statement of practice, not certification.

How to declare