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

01. Record model

Draft 0.1. Reference implementation: frontend/src/utils/timeline.js, frontend/src/services/familyVaultService.js, frontend/src/pages/TranscriptBuilderPage.jsx, api/publish-transcript.js.

1.1 The shape in one paragraph

A Record belongs to one person (the learner) and is held by that person's family, which acts as the records office of record. It is made of entries: things that happened (a book, a project, a course, volunteer hours, a mentor session, a competition, a job, an ESA purchase, an attempt). Some entries are assembled into a Witness Transcript™, a transcript of courses, the receipt (tr_) a family issues to a receiver. Any entry, course, note, or curated wall can be sealed into a content-addressed receipt (chapter 02). Adults outside the family can put their name on a receipt through a witness attestation (chapter 03). The family's device holds the content; the public ledger holds only the metadata a receiver needs to check a printed or shared artifact.

1.2 Persons

A person is a row in the family vault. The reference implementation encrypts the person's content on device (familyVaultService.js, _enc: 'wcv1') and keeps three fields in the clear for indexing.

nametyperequiredmeaning
idstringyesStable identifier for the person within the family. Appears on receipts as person_id.
familyIdstringyesThe family the person belongs to.
rolestringyesFree string; default 'family-member'. The Record does not enumerate roles and MUST NOT treat role as an authorization claim.

A person's content (name, dates, documents) never enters a public receipt except as the surface fields the family chooses to print (chapter 02, per-prefix hash domains).

1.3 Entries (the private timeline, tl_)

Entries are captured on device by appendEntry and stored under the person. An entry's identifier begins with tl_ and is private: it is not hashed, not published, and not verifiable on its own (chapter 02, section 2.2). An entry becomes public only when it is sealed into a ws_ receipt.

kind MUST be one of the closed enum KINDS:

kindmeaning
bookbook read or audiobook completed
projectself-directed project shipped
coursecourse or unit completed
volunteervolunteer hours or community work
mentormentor session, tutoring, 1:1 with a coach
competitioncompetition entered or placed
jobpaid work
esa_expenseESA-funded purchase (compliance metadata only)
attempta try or iteration; in a portfolio, failures never subtract

Entry fields:

nametyperequiredmeaning
idstringyestl_<base36 time>_<6 random>; private, never hashed
person_idstring or nullyesowner person
kindenumyessee above
titlestringyestrimmed, non-empty
detailstring or nullnofree text; stays on device
evidence_urlstring or nullnoinline or external evidence reference (v1 seal)
evidence_sha25664 hex or nullnocontent hash of evidence held in the encrypted evidence store (v2 seal)
evidence_mime, evidence_thumbstring or nullnoon-device display only; never hashed
atISO 8601yeswhen it happened
created_atISO 8601yeswhen it was captured; never hashed
hours, instruction_days, subjects[], state_codenumber, number, string[], string; all nullablenocompliance metadata for jurisdiction plugins (chapter 08); never in any hash domain
category, amount, educational_purposestring or nullnoesa_expense only; amount is the string the family typed, not a normalized number

Normative rules:

1.4 Courses and the transcript

A transcript is a list of course rows assembled by the family in the transcript builder and sealed into one tr_ receipt plus one cr_ receipt per course row that carries the minimum fields.

Course row as authored:

nametyperequiredmeaning
yearstringnoe.g. 2025-26
termstringyes for cr_e.g. Year, Fall
subjectstringnobuilder label (English, Mathematics, ...); read by jurisdiction plugins
titlestringyes for cr_course title
creditstringnoas typed; 1.0 and 1 are different strings by design
gradestringyes for cr_as issued by the family
evidencestringnofree text pointer; stays on device
tierenumyesself, family, mentor, receiver; the family's own description of the row's source (chapter 03, section 3.6)

The tr_ receipt hashes the whole issuance payload (student block, all course rows, issuance time, issuer account, person id); the cr_ receipt hashes only the identity-bearing tuple of one row (chapter 02, section 2.4). The two are related by provenance (tr_receipt_id on the cr_ row), never by hash.

1.5 Work samples, notes, walls

Three further sealable objects exist beyond courses. Their constitutional differences are stamped into the verify payload as transcript_eligible:

objectprefixtranscript_eligiblewho authorsnotes
work sample (a sealed entry)ws_not stamped; may be cited as evidence and may be witnessedfamilytitle, kind, issuer, dates, has_evidence go public; detail and evidence stay on device
weekly note (reflection)wn_falsethe learner (author is fixed to kid inside the hash)never witnessed; excerpt of at most 140 characters goes public; body stays on device; no view tracking
wall (curated surface)wl_falselearner or family (curator)at most 50 pins, ws_ and wn_ only; identity fixed at creation, mutable snapshot hash per re-curation; no view tracking

1.6 The family as records office of record

The Record inverts the default: the family issues, the school (when there is one) is a witness. Concretely:

1.7 The issuer concept

An issuer is the party whose account publishes a receipt and whose key (chapter 04) signs it.

issuer kindstatushow it appears
familybuiltissuer_user = the family account; issuer = the family-chosen display string; family key did:key signs the leaf when signing is enabled
organization (a school, network, or independent counselor issuing on a learner's behalf)planned (gap: no organization-issued tr_/cr_/ws_ path exists; organizations today exist only as receivers, counselors, and witnesses)would carry an organization key, an organization kb_ binding, and an issuer identity level; specified in a later draft once the issuer rail exists

An organization that witnesses a course today does so through chapter 03, not by issuing.

1.8 What this does not prove

The Record model proves structure, not truth. A person row proves nothing about identity. An entry proves that the family captured a claim on a date. A course row proves that the family wrote a title, a term, a grade, and a credit; the tier chip is the family's description of where the claim came from, and no backend enforces it (chapter 03, section 3.6). None of this, by itself, proves that any third party evaluated the work. That is what witnesses (chapter 03) and, later, issuer identity levels are for.