Eformogi
The Record: protocol draft 0.1 (CC BY 4.0; verifier Apache-2.0)

07. Exports

Draft 0.1. Reference implementation: shared/verifiableCredentials.js, api/issue-credential.js, api/verify-credential.js, api/did.js, api/jsonld-context.js, api/protocol-spec.js. Vector v20. No code is specified in this chapter; every mapping not backed by code is marked planned with the gap named.

7.1 What exists today

The reference implementation issues one kind of W3C Verifiable Credential: a vault-field credential over a category of the family's profile, signed with the organization key. It does not yet export a transcript, a course receipt, a work sample, or an attestation as a credential; those are the receipts of chapter 02, and their export is the subject of sections 7.3 and 7.4.

The issued credential

POST /api/issue-credential (family session; 20 per minute per IP) takes {categoryId, fields, provenance, personName} and returns:

fieldtypevalue or rule
@contextarray["https://www.w3.org/2018/credentials/v1", "https://eformogi.com/credentials/v1"]
idURIurn:eformogi:vc:<32 hex random>
typearray["VerifiableCredential", <one of the six types below>]
issuerobject{id: "did:web:eformogi.com", name: "Eformogi"}
issuanceDateISO 8601
credentialSubjectobjectid: "did:eformogi:user:<account uuid>", one property per claim, displayName when given
credentialStatusobject{id: "https://api.eformogi.com/credentials/status/<id>", type: "StatusList2021Entry"}
eformogiMetadataobject{version: "1.0.0", verificationDetails {field: {method, source, confidence, sourceDocument, extractedAt}}, fieldCount}
proofobject{type: "DataIntegrityProof", cryptosuite: "eddsa-jcs-2022", created, verificationMethod: "did:web:eformogi.com#key-1", proofPurpose: "assertionMethod", proofValue: "z..."}

Credential types: EformogiFamilyProfile, EformogiEducationRecord, EformogiMedicalRecord, EformogiIdentityDocument, EformogiFinancialRecord, EformogiInsuranceRecord. Provenance sources map to verification methods: document_extraction to DocumentExtraction, ai_extraction to AIExtraction, institutional_api to InstitutionalVerification, user_input to SelfAsserted, parent_entry to ParentAsserted, imported to ImportedData, verified to IndependentVerification.

Fields named ssn, creditCard, bankAccount, driversLicense, or passportNumber are stripped before issuance and MUST never appear in a credential.

The proof

The suite is Data Integrity eddsa-jcs-2022: signInput = sha256(utf8(JCS(proof options))) || sha256(utf8(JCS(document))), 64 bytes, signed raw with Ed25519; proofValue is multibase base58btc. JCS here is the canonical form of chapter 02, section 2.3, and every non-integer number in the document is coerced to a string before signing (jcsCoerceNumbers), so a GPA of 3.7 travels as "3.7". Any receiver verifies against the JWK at /.well-known/did.json with no secret and no call to the operator (vector v20). The former symmetric suite HmacSha256Signature2024 is retired and refused with a re-issue message.

POST /api/verify-credential (public) returns {verified, checks: {proof, issuer, revocation, expiration}, credential: {...summary}}; revocation is read from the operator's verifiable_credentials table, not from a status list.

Known gaps in the existing shape

gapstatus
@context is the VC Data Model 1.1 context while the code describes itself as 2.0-compatible; issuanceDate is the 1.1 name (2.0 uses validFrom)planned: move to https://www.w3.org/ns/credentials/v2 and validFrom
credentialStatus names StatusList2021Entry but no status list is served; revocation is a database readplanned: publish a BitstringStatusList, or drop the field until it is real
credentialSubject.id is did:eformogi:user:<uuid>, a non-resolvable DID methodplanned: the learner's did:key once wallet custody exists (chapter 04)
https://eformogi.com/credentials/v1 context resolves to api/jsonld-context.js, which maps vault fields (identity, contact, education, medical, financial, family, activities, employment, provenance) to schema.org and eformogi: terms; it does not define receipt or attestation termsplanned: a receipt context
api/protocol-spec.js (FDEP 1.0.0-draft, 2026-03-02) still states credentialIntegrity: 'HMAC-SHA256 proof'stale text; planned: update or retire (it is a Rule 8 audit item)

7.2 The DID document

/.well-known/did.json publishes did:web:eformogi.com with one verification method (#key-1, JsonWebKey2020, the Ed25519 JWK of chapter 04), used for authentication and assertionMethod, and services #schema, #verify, #revocations, #issue, #vault, #context, #openapi, #fdep, and #receipt-log (type TransparencyLog, endpoint /api/tree-heads). A receiver resolving the issuer of any signed artifact in this specification lands here.

7.3 Mapping to Open Badges 3.0 (AchievementCredential)

Open Badges 3.0 is a VC profile: an AchievementCredential whose credentialSubject is an AchievementSubject holding an Achievement. The natural unit is one course row (cr_) or one work sample (ws_), with attestations as Evidence and the family as Profile issuer. Status: planned end to end; no OB3 credential is issued today.

OB3 fieldsource in the Recordstatus
@contexthttps://www.w3.org/ns/credentials/v2, https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.jsonplanned
type["VerifiableCredential", "AchievementCredential"]planned
idhttps://eformogi.com/verify/<cr_ or ws_ id>planned (gap: a resolvable credential URL that returns the VC, not the HTML page)
issuer (Profile)family: id = family did:key (chapter 04), name = the family's issuer string; organization issuer: planned with the issuer railplanned (gap: Profile.type for a family issuer; OB3 assumes an organization)
validFromissued_at (cr_: the row's created_at)planned
credentialSubject.typeAchievementSubjectplanned
credentialSubject.idlearner did:keyplanned (gap: learners have no key today; the family key is per account, not per person)
credentialSubject.achievement.typeAchievementplanned
credentialSubject.achievement.namecourse_title or ws_.titleplanned
credentialSubject.achievement.descriptionstatement-free description of the course or entryplanned
credentialSubject.achievement.criteria.narrativefor cr_: term, credits; for ws_: entry_kind, occurred_atplanned
credentialSubject.achievement.achievementTypeCourse for cr_; Competency or LearningProgram for ws_ by kindplanned
credentialSubject.achievement.creditsAvailablecredits (numeric)planned (gap: credits is a string in the hash domain by design; the numeric projection is display-only)
credentialSubject.result[] (Result)family_stated_grade as value, resultDescription "Family-graded"planned
credentialSubject.sourcethe family Profileplanned
evidence[] (Evidence)one entry per attestation: id = /verify/<att_ id>, name = signer name and role, description = statement, genre = "witness attestation", audience = signer organizationplanned (gap: OB3 Evidence has no slot for signed_grade disagreement; carry it in description and keep the authoritative rendering on the verify page)
credentialStatusBitstringStatusList entry driven by revoked_atplanned (gap: no status list today; revocation is online-only)
proofeddsa-jcs-2022 by the family key, plus the organization key as a second proof for the ceremonyplanned (gap: the family key is escrowed; an OB3 issuer proof by an escrowed key must be disclosed as such)
endorsement[] (EndorsementCredential)organization countersignature (chapter 03, section 3.5) as an endorsement of the ceremonyplanned (gap: the countersignature endorses processing, not the achievement; the endorsement text must say that)
image, alignment[]nonenot applicable

7.4 Mapping to Comprehensive Learner Record v2.0 (ClrCredential)

CLR v2 wraps many AchievementCredentials plus a ClrSubject and optional associations into one record. The natural unit is the transcript (tr_), holding one AchievementCredential per cr_. Status: planned; no CLR is issued today.

CLR v2 fieldsource in the Recordstatus
type["VerifiableCredential", "ClrCredential"]planned
idhttps://eformogi.com/verify/<tr_ id>planned
issuerfamily Profile (as above)planned
validFromtr_.issued_atplanned
credentialSubject.typeClrSubjectplanned
credentialSubject.idlearner did:keyplanned (same gap as OB3)
credentialSubject.verifiableCredential[]one OB3 AchievementCredential per cr_ on the transcriptplanned
credentialSubject.achievement[]the achievements referenced aboveplanned
credentialSubject.association[]tr_ to cr_ provenance (tr_receipt_id) as isChildOfplanned
credentialSubject.identifier[]the tr_ id and its sha256 as IdentifierEntry (identityType: "identifier")planned
credentialSubject.narrativeprogram, philosophy (only if the family opts in; it is on the printed transcript but not on the public payload today)planned (gap: privacy decision)
credentialSubject.activityStartDate / activityEndDateearliest and latest year on the rowsplanned
credentialSchemathe CLR JSON schemaplanned
proofas OB3planned
tier chips (tier_counts, "issuer-declared" muting)no CLR slotgap: CLR has no notion of per-row trust tier; the honesty rendering stays on the verify page and the mapping MUST NOT upgrade a chip into a Result the ledger did not corroborate
transcript_eligible: false objects (wn_, wl_)excluded from CLR by rulenot applicable

7.5 Rules for any export (MUST)

  1. An export MUST link back to the receipt id it was derived from, so a receiver can drop back to chapter 06 and verify the source independently of the export's own proof.
  2. An export MUST NOT contain more of the family's content than the public verify payload does, unless the family explicitly includes it at export time.
  3. An export MUST carry the same honesty statements as the verify page (chapter 06, section 6.6) in a human-readable field, and MUST label any proof by an escrowed key as escrowed (chapter 04, section 4.7).
  4. An export MUST NOT promote a self-declared witness or an issuer-declared tier into a claim that the receiver could read as third-party verification.
  5. Numbers in signed documents MUST be JCS-safe (strings for anything non-integer).

7.6 What this does not prove

A credential proves the organization key signed a document at a time. It does not prove the provenance labels inside it are true (they are the family's and the extraction pipeline's labels), and a verified: true from the verification endpoint is a proof and issuer check, not an endorsement of the claims. Planned mappings prove nothing until they ship; this chapter records intent so a standards reviewer can mark gaps against a fixed text.