Chapter 2

Chapter 2: The Core Protocol Record Model

How WIA-BIO-014 structures a genome-editing protocol as a record: the aggregate root, its eight child structures, and the field-level rules that decide whether the record will still be readable evidence a decade from now.

A data model is a set of promises about what a later reader will be able to find. Chapter 1 argued that a genome-editing project fails as a record long before it fails as science: the plan is in one system, the approval in an inbox, the measured result in a sequencing report, and nobody can reassemble them. This chapter takes the structures WIA-BIO-014 v1.0 defines — CRISPRProtocol and the types beneath it — and reads them the way an archivist reads a form: what is required, what is optional, what carries a unit, what carries a provenance, and who is allowed to write it.

Two boundaries hold for the whole chapter. First, every field here is treated as storage. The book documents a field's name, type, cardinality, validation rule, provenance and writer; it does not tell the reader what value to put in it, and it offers no laboratory or design guidance of any kind. Where a field carries a scientific decision, the decision belongs to the investigator and the institutional committees, and the record's only job is to capture it faithfully. Second, the chapter stays inside the model. Serialization, identifier formats and the schema layers belong to Chapter 3; call signatures to Chapter 4; state and time to Chapter 5. Forward references are marked where the seam matters.

2.1 CRISPRProtocol as the aggregate root

The reference type definitions give CRISPRProtocol twelve members: four administrative scalars — id, version, created, updated — and eight child structures, of which seven are required (target, guideRNA, casSystem, delivery, strategy, validation, safety) and one is optional (parameters). Nothing else sits at the top level.

export interface CRISPRProtocol {
  id: string;                    // protocol identifier
  version: string;               // protocol version
  created: Date;                 // creation instant
  updated: Date;                 // last-updated instant
  target: TargetInfo;            // what was targeted
  guideRNA: GuideRNA;            // guide record (exactly one)
  casSystem: CasSystem;          // system record (exactly one)
  delivery: DeliveryMethod;      // delivery record
  strategy: EditingStrategy;     // strategy record
  validation: ValidationMethod[]; // planned validation methods
  safety: SafetyChecks;          // compliance attestations
  parameters?: ExperimentalParameters; // optional bench context
}

Calling this an aggregate root is not decoration; it is the consistency rule the rest of the system inherits. The root owns identity (id plus version), and none of the children carry an identity of their own. A CasSystem value cannot be cited, fetched, approved or superseded by itself: it is reachable only through a protocol, and the only citable address of any field in this model is the triple protocol id + version + path within the document. That single decision determines a great deal downstream. It means concurrency control is taken at the root, not per field. It means an audit event records a path, not an object id (Chapter 5). It means a correction anywhere in the tree produces a new protocol version rather than a silent in-place edit (Chapter 3).

Cardinality and what the required/optional split actually asserts

validation is the only collection at the root, typed as an array with no declared bounds — structurally 0..n. An empty array therefore satisfies the structural schema, which is almost never what an institution means. The useful rule is a policy-layer one: a protocol may sit in draft with an empty validation array, but the transition out of draft requires at least one entry. That rule cannot live in the TypeScript type; Chapter 5 places it on the lifecycle transition, and Chapter 3 assigns it to the policy validation layer.

parameters? is the only optional child, and its optionality is a statement worth reading deliberately: the standard asserts that a protocol record is complete without bench context. That is coherent for a record standard — culture and handling conditions belong to the execution record — but it also means implementations must not make parameters the place where required project metadata quietly accumulates. Section 2.4 returns to this.

One caution about required-ness: in the reference SDK it is a compile-time fact, and it vanishes at the boundary. A document arriving over HTTP, read from a file or pasted by an operator was never seen by the compiler, so every optionality claim here must be restated in a runtime schema and enforced by the validator.

The root field table

The table below is the field-level contract for the root. Who writes names the role permitted to set the field; the role catalogue itself (submitter, reviewer, safety officer, auditor, read-only) is defined with its permission matrix in Chapter 6. Validation states the rule, and the parenthetical marks which layer enforces it — structural (S), referential (R) or policy (P), in Chapter 3's terms.

Table 2-1. CRISPRProtocol — field contract
Field Type Required Validation rule (layer) Who writes
idstringYesMatches the institution's documented identifier pattern; immutable across versions of the same protocol (S, P)System, at record creation
versionstringYesOrdered version string; a new value is required for any content change; never reused (S, P)System, on version bump
createdDateYesServer-assigned instant, serialized with an explicit UTC offset; never later than updated (S, R)System only
updatedDateYesServer-assigned on every accepted write; monotonic per protocol (S, R)System only
targetTargetInfoYesPresent and internally consistent; coordinates.assembly non-empty (S, R)Submitter
guideRNAGuideRNAYesExactly one; every stored score accompanied by a provenance entry (S, P)Submitter; scores written by the designated tool account
casSystemCasSystemYesExactly one; type and variant within the controlled vocabulary (S)Submitter
deliveryDeliveryMethodYesmethod within the vocabulary; every open-map key documented per Table 2-3 (S, P)Submitter
strategyEditingStrategyYesConditional members consistent with type (discriminated union) (R)Submitter
validationValidationMethod[]Yes (array may be empty structurally)At least one entry before the protocol leaves draft; each timing carries its unit and anchor event (P, R)Submitter
safetySafetyChecksYesEvery true attestation resolves to an approval record that is in force (P) — see Table 2-4Safety officer / IBC-IRB secretariat; never the submitter alone
parameters?ExperimentalParametersNoIf present, each key satisfies the open-map contract (P)Submitter

What the root does not contain

Reading the root for absences is as informative as reading it for fields. Version 1.0 of the model has no author or owner, no institution, no lifecycle state, no reference to an approval document, no link to a sample or a sequencing run, and no signature. These are not oversights in a data-format specification — they are simply outside the structure it defines — but they are all indispensable in operation. Implementations therefore wrap the protocol in what this book calls a record envelope: an implementation-owned object holding the storage identifier, the owning institution and unit, the lifecycle state, the responsible people, the audit-trail head, and the integrity signature, with the conformant CRISPRProtocol document carried inside it unmodified.

Keeping the envelope strictly outside the standardized document is what makes exchange possible: the envelope is local policy and may differ between partners, while the document inside it is what both sides validate against the same schema. Chapter 5 specifies the envelope's state and audit members; Chapter 6, what it must strip before a document is sent.

record envelope (implementation-owned, NOT part of the standardized document)
  |
  +-- CRISPRProtocol  (id + version = the only citable identity)
        |
        +-- target ........ TargetInfo ------ coordinates -- GenomicCoordinates
        +-- guideRNA ...... GuideRNA --+----- coordinates -- GenomicCoordinates
        |                              +----- offTargets[] - OffTargetSite
        |                                                     +-- annotation - OffTargetAnnotation
        +-- casSystem ..... CasSystem
        +-- delivery ...... DeliveryMethod -- parameters -- DeliveryParameters
        |                                     (typed members + open map)
        +-- strategy ...... EditingStrategy -+- template? -- RepairTemplate
        |                                    +- pegRNA?   -- PrimeEditingRNA
        +-- validation[] .. ValidationMethod -- parameters? (open map)
        +-- safety ........ SafetyChecks ----> external approval records (by reference)
        +-- parameters? ... ExperimentalParameters (open map)

not reachable from the root in v1.0, joined by protocol id + version:
  EditingOutcomes -- indelSpectrum[] -- IndelAllele     (measured; execution/validation record)
  ValidationResult                                      (validator output; Chapter 4)

2.2 TargetInfo: naming what was targeted

TargetInfo holds a gene symbol (gene, required), an optional namespaced gene identifier (geneId), a required coordinates object, two required controlled-vocabulary members (regionType, purpose) and an optional free-text description.

The required member is the weakest one. A gene symbol is a human-facing label maintained by a nomenclature authority — for human genes, the HUGO Gene Nomenclature Committee — and symbols are revised, merged and reassigned over time. A record that stores only a symbol has a subject that can drift: the same string may resolve to a different entity years later, and the reader cannot detect the change. The optional geneId is the stable member, so this book's recommendation is unambiguous: treat it as operationally mandatory, store it with its namespace made explicit (an Ensembl or NCBI Gene accession recorded as namespace plus accession, never as a bare number), and record which release of that namespace was consulted. Where a target has no catalogued identifier, say so explicitly rather than leaving the field absent — an absent field cannot be distinguished from a forgotten one.

Coordinates are meaningless without their conventions

GenomicCoordinates carries chromosome, start, end, strand and assembly. All five are required, and the fifth is the one that makes the other four interpretable: a numeric interval without an assembly label is not a location, because the same interval denotes different sequence in different assemblies. Storing the assembly as a plain string is adequate provided the string is drawn from the published naming of the relevant reference consortium and is written identically everywhere, which in practice means the field needs a controlled vocabulary at the institution level even though the type does not impose one.

The second interpretability question is the coordinate convention. The reference type definitions annotate start and end as zero-based, while widely used genomic file formats disagree with each other on this point: some are zero-based and half-open, others are one-based and inclusive. Nothing in the record states which convention a given document used, so a document that crosses a system boundary can be silently shifted by one base. The remedy is not clever parsing but an explicit statement. Table 2-2 lists the questions a coordinate record must answer, each of which should be either fixed by the institution's profile and documented, or carried as an extra field.

Table 2-2. Conventions a coordinate record must pin down
Question Why it matters Where the answer is recorded
Index origin: zero-based or one-based?An off-by-one shift is invisible and never raises an errorProfile document, plus a convention field in the envelope
Interval closure: is end included?Changes the reported length by one baseProfile document; asserted by the validator
Assembly label spellingTwo spellings of one assembly break joins and reportsInstitutional controlled vocabulary for assembly
Chromosome naming stylePrefixed and unprefixed names do not joinInstitutional controlled vocabulary for chromosome
Strand semantics for zero-length or reversed intervalsAmbiguous records cannot be validatedReferential rule: start <= end, with strand independent of ordering
Which namespace release produced geneIdIdentifier meaning can change between releasesProvenance entry beside geneId

regionType (exon, intron, promoter, enhancer, other) and purpose (knockout, knockin, correction, tagging, activation, repression) are the members that make a corpus of protocols searchable and reportable; Chapter 3 consolidates them with the model's other vocabularies and fixes the rule that enum values are stored in English in both editions. Two model-level rules belong here. The value other must never stand alone — a record that selects it must fill description, or the vocabulary degrades into a single bucket within a year. And a value must never be repurposed: a distinction the enum does not offer calls for an additive schema change with a version bump, because a local redefinition is invisible to every partner who later reads the document.

description, finally, is free text in a record that will be exported, mirrored into reporting tools and eventually shared — the likeliest place in the model for a name, a chart number or a date of birth to arrive by accident. Section 2.7 treats that as a modelling defect, not a privacy afterthought.

2.3 GuideRNA and CasSystem as record fields

This section documents two structures that in other books would be the occasion for design advice. It contains none: no member below is discussed in terms of what value is preferable, what a score means, or how any of it should be chosen. Those are scientific decisions belonging to the investigator and the institutional committees. What follows is a filing question — given that a number exists, what must be stored alongside it for the number to be usable as evidence later?

GuideRNA holds sequence, pam and fullTarget as strings; onTargetScore, gcContent, predictedEfficiency and specificityScore as numbers; warnings as a string array; and two optional members, coordinates and offTargets. CasSystem holds type and variant and source as controlled vocabularies, an optional concentration string and an optional modifications string array.

A computed number without provenance is not evidence

Four of GuideRNA's members are outputs of software. The type gives each of them a bare numeric slot and no place to say what produced it. For a record standard that is the structure's most consequential gap, because the same nominal quantity computed by two tools, or by two versions of one tool, is not the same measurement — and a reviewer asking "where did this number come from?" has nowhere in the document to look. The rule this book applies throughout is that a stored computed value is incomplete without a provenance entry, and that the entry must be written by the same operation that wrote the value, not reconstructed afterwards.

A provenance entry carries, at minimum: the producing tool's name and exact version, the identifier of the model or algorithm configuration used, the parameter set, a digest of the exact input the tool received, the instant of computation, and the account under which it ran. Where the institution's profile permits, the entry also names the reference data release consulted. The shape below is illustrative — the field names are this book's proposal, not part of v1.0 — and every value shown is an obvious placeholder.

{
  "field": "guideRNA.onTargetScore",
  "value": null,
  "provenance": {
    "tool": "<tool-name>",
    "toolVersion": "<exact-version-string>",
    "configuration": "<model-or-config-id>",
    "parameters": { "<key>": "<value-with-unit>" },
    "inputDigest": "sha256:<digest-of-the-exact-input>",
    "computedAt": "<ISO-8601 instant with offset>",
    "computedBy": "<service-account-id>",
    "referenceRelease": "<namespace-release-label>"
  },
  "kind": "computed"
}

The kind member is deliberate. Every number in the model is one of three things, and conflating them is how a record stops being trustworthy: asserted values are entered by a person and carry an author; computed values are produced by software from a stated input and carry a tool version; measured values come from an instrument or assay and carry counts and a method. A single tag on every numeric field costs almost nothing and answers the question a reviewer actually asks.

Derived members, free-text warnings, and quantities inside strings

fullTarget and gcContent are both derivable from other stored members, and storing a derived value is a choice with a cost: the stored copy and the derivation can disagree, and the record gives no clue which is authoritative. Two disciplines make this safe. Store the derived value only with a provenance entry that names the deriving code, and have the validator re-derive it on read and flag a mismatch rather than silently trusting the stored copy. The same rule applies to every percentage in Section 2.5.

warnings is an array of human-readable strings, which makes it useful for a person and useless for a program. Strings drift with every release, are translated, and get reworded, so any code that switches on their text is broken by the next patch. Where a warning must drive behaviour — blocking a transition, requiring a second reviewer — the machine-readable meaning belongs in a code, with the string kept alongside it as the display form. Chapter 4 makes the same point about the SDK's recommendation text.

CasSystem.concentration is typed as a string, so a quantity and its unit arrive as one undifferentiated token. Such fields cannot be compared, aggregated, converted or range-checked, and they are a classic source of silent unit errors. The rule for every quantity-in-a-string field in this model is the same: parse it into a numeric value plus an explicit unit code from an established unit vocabulary such as UCUM, store both, and keep the operator's original text verbatim in an asEntered member. What values these fields should hold is not this book's subject. modifications is likewise free text where a controlled vocabulary would serve reporting better; until the standard offers one, an institution should publish its own list and validate against it.

A cardinality limit worth knowing before you build

The root holds exactly one guideRNA and exactly one casSystem. Projects that involve several guides in one plan therefore cannot be expressed as a single conformant document: the modeller must either create one protocol record per guide and link them through the envelope, or extend the schema locally, which breaks portability. Neither option is free, and choosing one is an architectural decision to take deliberately and record in the institution's profile. Chapter 8 lists this among the v1.0 gaps a future minor version should close.

2.4 Delivery, strategy, and the opaque-parameter pattern

DeliveryMethod has a required method vocabulary member, a required cellType string, a required parameters object typed as DeliveryParameters, and an optional numeric expectedEfficiency. DeliveryParameters is the model's clearest instance of a pattern that recurs three times: a handful of named optional members followed by an index signature, [key: string]: unknown. ExperimentalParameters has the same shape, and ValidationMethod.parameters is an open map from the start (Record<string, unknown>).

The pattern exists for a real reason. The set of parameters that matters varies across methods, and a specification that enumerated all of them would be obsolete before publication and would force unrelated fields on every record. The cost is equally real: values in an open map are unvalidated, unitless, unsearchable and unmigratable. Nothing checks a key's spelling, so incubation_time and incubationTime coexist; nothing records what a bare number meant; and a later schema change cannot find the fields it should have rewritten.

An open map can nevertheless be kept auditable, at the price of a small discipline enforced by the validator rather than by hope. This book's contract is in Table 2-3, and its most important clause is the last one: an open map is a staging area, not a destination. A key that appears repeatedly across records has earned promotion to a typed field in the next schema version, and a key that nobody can define should be removed rather than inherited forever.

Table 2-3. Contract for open-map members (DeliveryParameters, ExperimentalParameters, ValidationMethod.parameters)
Requirement What it means concretely Failure it prevents
Registered keyEvery key used in production appears in the institution's published key register with a definition and an ownerSynonym keys; fields nobody can interpret
Structured valueA value is an object carrying the value, its unit code, and its kind (asserted / computed / measured) — not a bare scalarUnit confusion; numbers of unknown origin
AttributionEach entry records who wrote it and whenUnattributable changes in the audit trail
Source noteWhere the value came from: an instrument, a person, a prior documentValues that cannot be corroborated
Type stabilityA key's value type never changes; a new meaning takes a new keyConsumers breaking on a silently retyped field
No identifiers of peoplePersonal and subject-identifying data are excluded from open maps entirelyUndiscoverable personal data in exports
Promotion and retirement reviewKeys are reviewed each schema cycle: promote the common, retire the undefinedThe map becoming a permanent dumping ground

expectedEfficiency deserves separate attention because of where it sits. It is a prediction, and it lives one structure away from the measured results of Section 2.5. Once both are in a reporting tool, nothing about the field names tells an analyst which is which. The model rule is therefore that any predicted quantity is stored with its kind set to computed, with the tool and version that produced it, and is never aggregated with measured values in the same column of a report. Chapter 4 applies the identical rule to the SDK's simulation output.

EditingStrategy and its conditional children

EditingStrategy has a required type drawn from the EditType vocabulary, two optional structured children (template of type RepairTemplate, pegRNA of type PrimeEditingRNA), and two required strings: expectedOutcome and timeline.

Those two required strings are the structure's weak point. expectedOutcome is the sentence a reviewer most wants to compare against the measured result, and as free text it can only be read, never checked; a record model that intends to support comparison needs at least a coded outcome class beside the prose. timeline is worse, because Chapter 5 needs to compute on durations — to ask which protocols are overdue for validation — and a string cannot be computed on. The remedy in both cases is additive: keep the prose member for the reader, and add a structured companion, with durations expressed in the standard duration notation of ISO 8601 rather than in words.

The relationship between type and the optional children is a discriminated union in all but name: certain values of type make one of the children meaningful and the others inapplicable. The structural schema cannot express that on its own, so it becomes a referential rule the validator enforces — a child that is inapplicable for the selected type is an error, not an ignorable extra. This matters for auditability rather than for science: a document carrying contradictory members has no single interpretation, and two readers will legitimately disagree about what was planned.

RepairTemplate (with type, sequence, two numeric homology-arm lengths in base pairs, an edit string and an optional strand) and PrimeEditingRNA (with spacer, pbs, rtTemplate, an optional nickingSgRNA and an optional extension vocabulary) are documented here as record fields and nothing more: names, types, cardinality, and the requirement that any numeric member states its unit and any sequence-bearing member states its provenance. This book offers no guidance on their values, and readers with questions about them should take those questions to their institutional committees and the official authorities named at the end of this chapter.

One access-control consequence follows from the model and belongs here even though Chapter 6 owns enforcement. The sequence-bearing members of this structure and of GuideRNA are the fields most likely to be commercially sensitive, and in combination with subject-linked data they can contribute to re-identification. They are therefore prime candidates for field-level restriction and for redaction before a document leaves the institution — which is only possible because they are typed fields at known paths rather than entries buried in an open map. Structure is what makes a privacy control implementable.

2.5 The result side: ValidationMethod[], EditingOutcomes, IndelAllele

ValidationMethod has a required method vocabulary member (T7E1, Sanger, NGS, ddPCR, Western, Flow, Other), a required description string, a required numeric timing, and an optional open parameters map. It is worth stating plainly what this array is and is not: it is the plan for how the project will be checked. It holds no results at all.

timing shows two defects that are easy to miss because the type compiles. Its unit — days — exists only in a source comment, which means no consumer can discover it from the document; the unit must be carried in the record. And it is a relative offset from an event the protocol record does not identify, because the root has no execution event to anchor to. A relative time without an anchor cannot be turned into a date, so the field is uncomputable as specified. The fix is again additive and belongs to the profile: carry the unit explicitly, and carry the identifier of the anchoring execution event so that a scheduled check resolves to a real instant.

The larger observation is structural. Measured results are modelled in EditingOutcomes and IndelAllele, and the root has no member that holds them — EditingOutcomes is not reachable from CRISPRProtocol at all. That is not a flaw to paper over; it is the model agreeing with Chapter 1's separation of the protocol record from the execution and validation records. The consequence for implementers is concrete: results live in their own records, joined to the plan by protocol id and version, and an implementation that quietly bolts an outcomes member onto the root has left the standard and will not exchange cleanly with anyone.

Counts are the evidence; percentages are a convenience

EditingOutcomes stores totalReads, wildType, edited and an indelSpectrum array of IndelAllele, together with wildTypePercent, editedPercent, optional hdrEvents and hdrPercent, and a topEdit. Both counts and derived percentages are present, and that redundancy is exactly where records go wrong.

The rule this book states without exception: a stored percentage is never evidence on its own and must never be recorded without its numerator and denominator. A proportion with the counts removed cannot be audited, cannot be pooled with another record, and hides the one thing a reviewer needs to judge it — how many observations it rests on. Two arithmetic facts reinforce the rule. Percentages held as binary floating-point values are inexact for most decimal fractions, so a stored percentage and a freshly computed one often differ in their last digits: an equality check on them is a bug, and comparisons need a stated tolerance. And rounding at storage time is irreversible, so display rounding belongs in the presentation layer, never in the record.

Consequently the validator should treat each percentage as a derived member: re-derive it from the counts at read time, compare within the profile's tolerance, and raise a referential error on mismatch. A mismatch is a genuinely important signal — it usually means the counts were revised while the percentage was not, which is to say the record has been partially updated, which is precisely the failure mode an audit trail exists to catch.

topEdit duplicates one element of indelSpectrum. Denormalization is defensible for read performance, but only with a consistency rule: either store a reference into the array rather than a copy, or keep the copy and have the validator assert that it matches an element of the array. Without one of those, the two can diverge, and then the record contains two different answers to the same question.

IndelAllele holds a sequence, a type from a four-value vocabulary, a numeric size, a numeric position, a count, a percentage and an optional inFrame flag. position raises the same question as timing: relative to what? An allele position can be expressed relative to an amplicon start, to a feature, or in genome coordinates, and the record does not say which. An anchor member is therefore required — the alternative is a number that different readers interpret differently, which in a compliance record is worse than no number at all. size needs its unit stated for the same reason, and percentage falls under the denominator rule above.

2.6 SafetyChecks: attestations that must resolve to records

SafetyChecks has six required members: two booleans (offTargetAnalysis, ethicsApproval), a four-value biosafety label, a regulatory string array, a three-value riskLevel, and a mitigation string array. It is the block a reviewer opens first, and as typed it is the block least able to answer a reviewer's questions.

The reason is that a boolean records only that somebody set a flag. ethicsApproval: true does not say which body decided, what it decided, what scope it covered, when it was issued, whether it is still in force, or who entered the value. Those are exactly the facts the approval gate needs, so the flag must not be the authority. The rule for this whole block is that every attestation resolves to an approval record: the boolean is a convenience for display and filtering, and its truth is derived from the presence of a referenced approval that is in force at the time of the check. Chapter 5 turns that into a blocking lifecycle rule; the model-level requirement is that the reference exists in the record at all.

biosafety is a stored label with four permitted values (BSL1 through BSL4) and nothing more. Its meaning is fixed by the institution's biosafety framework and by the national authority, not by this book, which supplies no facility, containment, agent or procedural content of any kind. As a data element, the label has two requirements: it must be written by the role authorized to assign it — the safety officer or the committee secretariat, never the submitter acting alone — and any change to it must be an auditable event with a stated authority, because a downgrade is a compliance-relevant act.

regulatory as an array of bare strings loses the structure a compliance reader needs: two records claiming compliance with the same framework may mean entirely different things, and a string cannot express jurisdiction, identifier, status or expiry. The profile this book recommends replaces each string with an object naming the framework, its identifier, the jurisdiction, the record's status under it, and a reference to the authorizing document. Which frameworks apply is a governance question; Chapter 8 handles it by citing the real reference frames — national LMO legislation and its institutional reporting duties, the NIH Guidelines and the institutional biosafety committee concept, WHO guidance — by name and without paraphrase.

riskLevel is a three-value label, and this book supplies no method for choosing it. What the model requires is the audit trail around it: the identifier of the assessment that produced the label, the role that set it, the date, and a rule that raising it is always permitted while lowering it requires a documented re-assessment. mitigation is an array of prose, and prose is unverifiable; each entry should carry a controlled action identifier, a named owner and a reference to the evidence that the action was taken. Otherwise the field records intentions, and a later reader cannot tell which of them happened.

Table 2-4. SafetyChecks — field contract
Field Type Required Validation rule (layer) Who writes
offTargetAnalysisbooleanYesTrue only if an analysis record is referenced, with tool, version and input digest; derived, never hand-set (P)Tool account writes the analysis record; safety officer confirms
ethicsApprovalbooleanYesTrue only if a referenced approval record is present and in force; expiry blocks the execution transition (P)IBC/IRB secretariat or safety officer
biosafetyenum: BSL1 | BSL2 | BSL3 | BSL4YesWithin the vocabulary; any change is an audited event with a stated authority; lowering requires re-assessment (S, P)Safety officer / committee secretariat only
regulatorystring[]YesEach entry resolves to framework, identifier, jurisdiction, status and authorizing document (P)Compliance role; submitter proposes
riskLevelenum: low | medium | highYesReferences the assessment record that produced it; lowering requires a documented re-assessment (P)Safety officer
mitigationstring[]YesEach entry carries an action identifier, an owner and verification evidence (P)Submitter proposes; safety officer accepts

Read together, Tables 2-1 and 2-4 make a single point about writer roles: the fields that establish what was planned are written by the submitter, and the fields that establish that it was permitted are written by someone else. A system in which one account can do both has no approval gate, whatever its user interface claims.

2.7 Modelling pitfalls

The defects below survive review because none of them produces an error. Each is stated as a symptom a reader can look for in an existing implementation, with the correction expressed as a rule the validator can enforce. Two established disciplines underlie the table: defining each data element with a name, a definition, a value domain and a permitted representation, as metadata-registry practice describes; and using one unambiguous timestamp format, for which ISO 8601 and its internet profile RFC 3339 are the settled choices.

Table 2-5. Pitfalls, symptoms and corrections
Pitfall How it shows up Correction
A boolean hides a missing documentAll attestations read true; no approval document can be produced on requestDerive every attestation from a referenced approval record; block the transition when the reference is absent or expired
Timestamps without an offsetcreated and updated differ by hours between sites; event ordering disagrees across systemsSerialize instants with an explicit UTC offset (ISO 8601 / RFC 3339); assign them server-side, never from the client
The open map as a dumping groundHundreds of one-off keys; synonyms; values whose units nobody remembersEnforce the Table 2-3 contract; review keys each schema cycle for promotion or retirement
Personal data in descriptionNames, chart numbers or dates of birth surface in an export or a partner packageExclude subject-identifying data from the protocol record; carry pseudonymous identifiers only; scan free-text fields before export
Computed values without provenanceA score cannot be reproduced; nobody knows which tool version produced itWrite the provenance entry in the same operation that writes the value; tag every number as asserted, computed or measured
Percentages without denominatorsTwo records report the same proportion; one rests on a handful of observationsAlways store numerator and denominator; re-derive percentages on read within a stated tolerance
Quantities inside stringsConcentrations and timings cannot be compared, converted or range-checkedSplit into a numeric value plus an explicit unit code; retain the original text as asEntered
Gene symbol used as an identifierA record's subject appears to change when nomenclature is revisedTreat geneId as operationally mandatory, with its namespace and release recorded
Relative times and positions without an anchortiming and IndelAllele.position cannot be resolved to an instant or a locusCarry the unit and the identifier of the anchoring event or reference point
Enum value other without explanationMost records fall into other within a year; reports become uninformativeRequire description whenever other is selected; propose an additive vocabulary extension
Silently redefining a vocabulary valueA partner's reports disagree with yours although both validateAdditive change plus version bump; never repurpose an existing value
Type declarations mistaken for enforcementMalformed documents enter through an import path that the SDK never seesRestate every optionality and vocabulary rule in the runtime schema and the validator (Chapter 3)
Predictions stored beside measurementsexpectedEfficiency is aggregated with measured results in a dashboard columnTag predictions as computed, keep them in separate fields and separate report columns
Denormalized copies without a consistency ruletopEdit no longer matches any element of indelSpectrumStore a reference, or validate the copy against the array on every write

2.8 Summary

CRISPRProtocol is a small structure carrying a great deal of institutional weight. Its identity is the pair id plus version, and no child has an identity of its own, which makes the root the unit of locking, of versioning and of citation. The model is strongest where it is typed and weakest in three recurring places: computed numbers with no slot for provenance, quantities and durations carried as free text, and open maps with no contract. Around those weaknesses the chapter proposed four rules that cost little and pay for themselves at the first audit — tag every number as asserted, computed or measured; never store a percentage without its counts; give every open-map key a definition, a unit and an owner; and let no attestation be true unless it resolves to an approval record in force.

Chapter 3 takes the same structures to the wire: the canonical JSON document and its snake_case naming, the identifier and immutability rules, the consolidated vocabulary table, the three validation layers with the error codes assigned to each, and an honest account of the reference implementation's constants — which are software defaults, not scientific recommendations.

Editorial note on the sources. This book uses the identifier WIA-BIO-014 and version v1.0 throughout; the disagreement among the published sources over identifier, licence and dates is stated once in Chapter 1 §1.6. Chapter 8 §8.5 treats the mismatch as a maintenance item, and Chapter 7 §7.1 shows how claim artifacts cope with it.

Scientific and laboratory-safety content: consult your IBC/IRB and the official biosafety and regulatory authorities (KDCA/LMO Act authorities, WHO, NIH Guidelines, your national regulator).