Format reference
Causal roles
Who or what determined a value. The four Core roles, the obligation each carries, every registry term grouped by causal class, the diagnostics a wrong role raises, and the causal projection of a build.
Definition
A causal role states who or what determined a value. Every field, state value, model input, model output, acceptance criterion and result in a WWD package MUST declare one, alongside its provenance class, and a producer MUST NOT omit it or rely on a default. The Core roles are control, a quantity the producer sets; response, a quantity the biological system determines; context, a quantity observed but not chosen; and derived, a quantity computed from others by a stated rule. A control MUST name the means that imposes it. A response MUST NOT be expressed as a manufacturing instruction and is stated as a target plus an acceptance criterion. A derived quantity MUST name its inputs and its rule. The Core property registry fixes a causal class per term, and a field MUST NOT declare a role contradicting it. Because controls are declared as interventions, an as-built package projects to the tuple (do(controls), context, responses, yield).
Provenance answers where a number came from. It does not answer who or what determined
it. Consider two properties of one strip: ECM stiffness rising from 10 kPa at the
anchors to 16 kPa at midspan, and fiber alignment rising from S = 0.60 at the anchors to
S = 0.80 at midspan. Under provenance alone they are indistinguishable: both are
designed fields, same type, same units, same position in the document. The
first is imposed by the producer. The second is produced by the tissue in response to
what was imposed.
Where a quantity is set at one time and observed later, seeding density at plating against cell density after three days, these are distinct fields at distinct times, not one field with an ambiguous role. A conforming consumer MUST NOT treat an intended control value and an observed control value as interchangeable.
The four roles
What each one means and what each one obliges.
| Role | Meaning | Examples | Obligation | Registry |
|---|---|---|---|---|
| control | The producer sets it. An intervention. | Matrix stiffness, seeding density, anchor spacing, stimulation schedule, medium formulation, incubation temperature. | MUST identify the means that imposes it, naming the protocol step, apparatus or delegated process part responsible. A quantity that no stated means can set is not a control. | 27 registry terms |
| response | The biological system determines it. Targetable and measurable, never directly settable. | Fiber alignment, twitch force, firing rate, network burst rate, differentiation purity, viability. | MUST NOT be expressed as a manufacturing instruction. It is stated as a target together with an acceptance criterion. | 26 registry terms |
| context | Observed but not chosen by the producer. Neither an intervention nor a response to one. | Donor identity, passage number on receipt, ambient excursion during transit, lot-to-lot reagent variation. | Recorded as a covariate. It carries a provenance class as any other assertion does. | 8 registry terms |
| derived | Computed from others by a stated rule. It carries no independent causal standing. | A specific tension computed from a force and an area. | MUST identify the inputs and the rule. | 1 registry term |
The causal axis and the provenance axis are orthogonal and both are required. Seven distinct concepts fall out of the combination, with one field object and no additional schema branches.
| causal role | provenance | The assertion is | Reading |
|---|---|---|---|
| control | designed | the protocol | What will be imposed |
| control | measured | the process log | What was imposed in the event |
| response | designed | the specification | What the tissue must become |
| response | simulated | the prediction | What a model says it will become |
| response | measured | the result | What it became |
| context | measured | a covariate | What was observed and not chosen |
| derived | inferred | a statistic | What was computed from the others |
The means of imposition
What a control carries beyond its value.
A field with causal role control MUST identify the means that imposes it, by
naming the protocol step, apparatus or delegated process part responsible. The key is
imposed_by. Where the design carries a protocol, the means MUST be one of its
steps, and a step that lists a property in its sets list must find that
property bound as a control on its target. A step claiming to impose a quantity the
biology determines is refused.
{
"property": "wwd:ecm_stiffness",
"causal_role": "control",
"provenance": "designed",
"imposed_by": "protocol/gel-casting#step-2",
"value": "12 kPa"
} Stiffness is set by the producer. The means is the second step of the gel-casting protocol, and that step exists in the package. Both axes are declared.
{
"property": "wwd:fiber_alignment",
"causal_role": "response",
"provenance": "designed",
"imposed_by": null,
"value": "0.72 1"
} Alignment sits in the same component with the same provenance. It carries no means. The value is a target, held by an acceptance criterion on the response axis.
Recording a response
Measurement against simulation.
A response is stated as a target together with an acceptance criterion, never as a
directive. In an as-built package the answer sits in measured_results: a
criterion reference, a status, a value with a unit, a statistic, an observed sample size,
provenance measured, causal role response, and an observation
activity. Measured content that names no observation activity is refused.
A simulated value lives elsewhere. Simulation results carry provenance
simulated and a run identifier, and a simulated value MUST NOT satisfy a
measured acceptance criterion. The two sit in one package in
simulated-strip.wwd, in separate blocks.
{
"id": "mr-0001",
"criterion": "3f7c2a9e-51b4-4c1e-9a77-0d2f8e6b1c44",
"status": "pass",
"value": 612,
"unit": "uN",
"statistic": "median",
"n_observed": 12,
"provenance": "measured",
"causal_role": "response",
"observation_activity": "activity/twitch-assay",
"raw_data": "data/twitch.csv"
} 612 uN, median of 12 constructs, produced by the twitch assay, with the raw data carried in the package.
{
"id": "sr-0001",
"run": "run/fea-001",
"quantity": "peak_twitch_force",
"value": 648,
"unit": "uN",
"provenance": "simulated",
"causal_role": "response"
}
This is a simulation result: 648 uN predicted by the FEA contraction model. Moved into
measured_results, it raises F09_SIMULATED_AS_MEASURED and is
refused. In its own block it is a prediction, and the package still conforms.
The outcome
How acceptance reads a build.
Every acceptance criterion declares tests_axis. A criterion on a
control asks whether the protocol was executed as written. A criterion on a
response asks whether the biology delivered. These are different failures
with different remedies. A yield statement identifies the criterion it summarises, MUST
NOT claim that more units met a criterion than were tested, MUST NOT report a yield over
zero units, and where it states both counts and a fraction the two MUST agree. A failing
non-critical criterion yields a conditional disposition, and an unanswered critical
criterion yields an incomplete disposition, which MUST NOT be presented as a pass.
| Criterion | Role | Statistic | Value | n | Status |
|---|---|---|---|---|---|
| AC-001 | response | median | 612 uN | 12 | pass |
| AC-002 | response | cv | 0.14 1 | 12 | pass |
| AC-003 | response | median | 0.71 1 | 5 | pass |
| PC-001 | control | value | 12.4 kPa | - | pass |
Three response results and one control result. The control result, 12.4 kPa read by rheometry against a designed 12 kPa, is the process log: it says the protocol was executed as written. The yield statement covers criterion AC-001, 12 of 12 units meeting it. Context carried alongside: wwd:donor_id, wwd:passage_number.
Registry terms by causal class
62 Core terms. Each fixes a causal class, and a field MUST NOT contradict it.
The causal vocabulary of the reference validator is read from the published registry
rather than held in the code, so a term added to the registry is a data change. A
property in the wwd: namespace that is not in the registry is refused, and a
producer needing a property the registry does not define namespaces it as an extension
term.
| Term | Quantity kind | Canonical unit | Value shape | Definition |
|---|---|---|---|---|
| wwd:anchor_spacing | length | mm | scalar | Distance between the mechanical anchors a tissue develops tension against. |
| wwd:coating_areal_density | areal_mass_density | ug/cm2 | scalar | Mass of adhesion coating applied per unit substrate area, such as laminin or fibronectin. |
| wwd:culture_co2_fraction | fraction | 1 | scalar | Volume fraction of carbon dioxide in the incubator or vessel headspace. |
| wwd:culture_oxygen_fraction | fraction | 1 | scalar | Volume fraction of oxygen in the incubator or vessel headspace. |
| wwd:culture_temperature | temperature | degC | scalar | Incubation temperature during culture. |
| wwd:ecm_stiffness | modulus | kPa | scalar | Elastic modulus of the extracellular matrix the cells are embedded in or plated on, as prepared. |
| wwd:electrode_count | count | 1 | scalar | Number of electrodes in the array serving one sampling unit. |
| wwd:electrode_diameter | length | mm | scalar | Diameter of one electrode's exposed contact area. |
| wwd:electrode_pitch | length | mm | scalar | Centre-to-centre spacing of adjacent electrodes in an array. |
| wwd:matrix_composition | categorical | 1 | categorical | Identity of the matrix formulation, by reference to a protocol or a ChEBI/vendor identifier. |
| wwd:matrix_concentration | mass_concentration | mg/mL | scalar | Total mass of matrix solids per unit volume of the cast mixture, before compaction. |
| wwd:matrix_formulation | composition | 1 | composition | Proportions of the identified constituents of the matrix, as nonnegative fractions summing to one. |
| wwd:mechanical_preload | force | uN | scalar | Static tension applied to a tissue before functional measurement. |
| wwd:medium_formulation | categorical | 1 | categorical | Identity of the culture medium formulation, by reference to a protocol or vendor catalogue identifier. |
| wwd:oxygen_tension | pressure | kPa | scalar | Partial pressure of oxygen in the culture environment. |
| wwd:photostimulation_irradiance | irradiance | mW/mm2 | scalar | Optical power per unit area delivered at the tissue surface. |
| wwd:photostimulation_wavelength | wavelength | nm | scalar | Peak wavelength of light delivered for optogenetic stimulation. |
| wwd:pillar_stiffness | spring_constant | uN/um | scalar | Lateral bending stiffness of a compliant post used to anchor a tissue and to read out its force from deflection. |
| wwd:print_nozzle_temperature | temperature | degC | scalar | Extrusion nozzle temperature during bioprinting. |
| wwd:recovery_duration | elapsed_time | h | scalar | Time a component is held under stated conditions after unpacking, before acceptance measurement. |
| wwd:seeding_density_areal | areal_density | cells/mm2 | scalar | Cell count per unit area of substrate at the moment of plating. |
| wwd:seeding_density_volumetric | number_density | cells/mL | scalar | Cell count per unit volume of a cast or cell-laden gel at the moment of casting. |
| wwd:stimulation_amplitude | electric_field_strength | V/cm | scalar | Applied field strength during electrical stimulation. |
| wwd:stimulation_duty_cycle | fraction | 1 | scalar | Fraction of the stimulation period during which the stimulus is on. |
| wwd:stimulation_frequency | frequency | Hz | scalar | Pulse repetition rate during electrical stimulation. |
| wwd:stimulation_pulse_width | signal_duration | ms | scalar | Duration of one stimulation pulse. |
| wwd:substrate_modulus | modulus | kPa | scalar | Elastic modulus of the non-living substrate or scaffold body the cells are plated on or cast against, as prepared. |
| Term | Quantity kind | Canonical unit | Value shape | Definition |
|---|---|---|---|---|
| wwd:active_electrode_fraction | fraction | 1 | scalar | Fraction of electrodes meeting a stated activity threshold. |
| wwd:burst_duration | event_duration | s | scalar | Duration of a single-electrode burst under the stated detection settings. |
| wwd:burst_rate | event_rate | 1/min | scalar | Rate of single-electrode bursts, averaged over the declared analysis population. |
| wwd:capillary_density | areal_density | 1/mm2 | scalar | Vessel count per unit cross-sectional area. |
| wwd:cell_alignment | order_parameter | 1 | alignment | Degree of cell-body alignment, expressed as for wwd:fiber_alignment. |
| wwd:compaction_ratio | ratio | 1 | scalar | Final dimension as a fraction of the as-cast dimension after cell-driven matrix remodelling. |
| wwd:conduction_velocity | velocity | cm/s | scalar | Propagation speed of an excitation wave across the construct. |
| wwd:contraction_frequency | frequency | Hz | scalar | Spontaneous contraction rate. |
| wwd:cross_sectional_area | area | mm2 | scalar | Area of the load-bearing cross-section, perpendicular to the axis along which force is developed and reported. |
| wwd:fatigue_retention | fraction | 1 | scalar | Fraction of initial force retained after a stated fatigue protocol. |
| wwd:fiber_alignment | order_parameter | 1 | alignment | Degree of fiber alignment expressed as a director plus an order parameter S in [0,1]. |
| wwd:half_relaxation_time | signal_duration | ms | scalar | Interval from peak twitch force to half of that peak during relaxation. |
| wwd:mean_firing_rate | frequency | Hz | scalar | Mean spike rate across analysed electrodes. |
| wwd:microbial_growth | categorical | 1 | categorical | Outcome of a sterility test: growth or no growth, under a stated medium, temperature and incubation period. |
| wwd:mycoplasma | categorical | 1 | categorical | Outcome of a mycoplasma test under a stated detection method. |
| wwd:network_burst_duration | event_duration | s | scalar | Duration of a network-wide synchronous burst, from the first to the last spike of the burst under the stated detection settings. |
| wwd:network_burst_participation | fraction | 1 | scalar | Fraction of electrodes taking part in a network burst. |
| wwd:network_burst_rate | event_rate | 1/min | scalar | Rate of network-wide synchronous bursts. |
| wwd:passive_tension | force | uN | scalar | Static tension a tissue develops against its anchors at rest, before stimulation. |
| wwd:peak_twitch_force | force | uN | scalar | Peak force of a single twitch contraction under a stated stimulation protocol. |
| wwd:purity | fraction | 1 | scalar | Fraction of cells expressing the stated identity marker set. |
| wwd:spontaneous_beat_rate | frequency | Hz | scalar | Spontaneous beat rate of a cardiac construct. |
| wwd:tetanic_force | force | uN | scalar | Peak force under fused tetanic stimulation. |
| wwd:time_to_peak_force | signal_duration | ms | scalar | Interval from stimulus onset to peak twitch force. |
| wwd:unloaded_shortening | ratio | 1 | scalar | Fractional shortening of an unloaded construct during contraction. |
| wwd:viability | fraction | 1 | scalar | Fraction of cells scored viable by a stated assay. |
| Term | Quantity kind | Canonical unit | Value shape | Definition |
|---|---|---|---|---|
| wwd:days_in_vitro | time | d | scalar | Days elapsed since plating or seeding, the conventional developmental clock for cultures. |
| wwd:differentiation_batch | categorical | 1 | categorical | Identifier of the independent differentiation run a population came from. |
| wwd:donor_id | categorical | 1 | categorical | Pseudonymous donor identifier. MUST NOT carry direct personal identifiers. |
| wwd:electrode_impedance | impedance | kohm | scalar | Electrode impedance magnitude at a stated frequency and in a stated electrolyte. |
| wwd:passage_number | count | 1 | scalar | Number of passages a population has undergone on receipt. |
| wwd:population_doublings | count | 1 | scalar | Cumulative population doublings a population has undergone. |
| wwd:reagent_lot | categorical | 1 | categorical | Lot identifier of a medium component, matrix, coating or supplement, as supplied. |
| wwd:transit_duration | elapsed_time | h | scalar | Time elapsed between despatch and unpacking. |
| Term | Quantity kind | Canonical unit | Value shape | Definition |
|---|---|---|---|---|
| wwd:specific_force | stress | kPa | scalar | Active force normalised by the cross-sectional area that generated it. |
The property registry in full, with domains and literature references
What the validator refuses
Code, trigger, and the change the writer makes.
| Code | Severity | Trigger | Change |
|---|---|---|---|
| A8_NO_CAUSAL_ROLE | ERROR | A field carries no causal_role key. | Add causal_role: control, response, context or derived. There is no default. |
| A8_UNKNOWN_CAUSAL_ROLE | ERROR | causal_role holds a value outside the Core set. | Use one of control, response, context, derived. |
| A8_CONTROL_NO_MEANS | ERROR | causal_role is control and imposed_by is absent or empty. | Add imposed_by pointing at the protocol step or apparatus that sets the value. |
| A8_RESPONSE_IMPOSED | ERROR | causal_role is response and imposed_by is present, or causal_role is control on a property the registry classes as a response. | Drop imposed_by and give the quantity a target plus an acceptance criterion, or declare causal_role response. |
| A8_CONTROL_AS_RESPONSE | WARNING | causal_role is response on a property the registry classes as a control. | Confirm the property term. A directly settable quantity is normally a control with a means. |
| A8_DERIVED_NO_INPUTS | ERROR | causal_role is derived and derived_from lists nothing. | List the quantities the value was computed from, so it can be recomputed. |
| A8_DERIVED_NO_RULE | ERROR | causal_role is derived and rule is absent. | Give the expression, standard or protocol that computes the value. |
| A8_CRITERION_NO_AXIS | ERROR | An acceptance criterion has no tests_axis key. | Add tests_axis: control for was the protocol executed as written, response for did the biology deliver. |
| A8_CRITERION_BAD_AXIS | ERROR | tests_axis holds a value other than control or response. | Set tests_axis to control or response. |
| V03_CAUSAL_CLASS_MISMATCH | ERROR | A declared causal_role contradicts the causal class the registry fixes for the term. | Declare the registered role, or use a different term if a different quantity is meant. |
| Z02_DIMENSION_NO_ROLE | ERROR | A dimension object declares no valid causal role or no valid provenance. | Add both. A cast diameter and a compacted diameter share a name and a unit and are causally opposite. |
| Z03_DIMENSION_CONTROL_NO_MEANS | ERROR | A dimension with role control names no means. | Name the protocol step, mould or apparatus that sets it. |
| Z04_DIMENSION_RESPONSE_IMPOSED | ERROR | A dimension with role response carries imposed_by. | Give the dimension a target and an acceptance criterion instead of a means. |
| H03_IMPOSED_BY_DANGLING | ERROR | imposed_by names a step the package protocol does not contain. | Point imposed_by at an existing protocol step identifier. |
| H06_STEP_SETS_A_RESPONSE | ERROR | A protocol step claims to impose a quantity the biology determines. | Remove the property from the step sets list, or bind it as a response with a criterion. |
| H07_STEP_SETS_UNBOUND | WARNING | A step names a property bound nowhere on its target. | Bind the property as a control on the target, or drop it from sets. |
| F09_SIMULATED_AS_MEASURED | ERROR | A result with provenance simulated sits in measured_results. | Move the value to a simulation result linked to its run. |
| R05_NO_OBSERVATION | ERROR | Measured content identifies no observation activity. | Add observation_activity naming the activity that produced the number. |
Declaring wwd:fiber_alignment with causal role control raises two
of these at once: V03_CAUSAL_CLASS_MISMATCH, because the registry classes the
term as a response, and A8_RESPONSE_IMPOSED, because the property is an
emergent outcome rather than a settable control. Adding an imposed_by to the
same field does not clear either code.
The causal projection
do(controls), context, responses, yield.
A conforming as-built package is losslessly projectable to the tuple
(do(controls), context, responses, yield), where do denotes the
interventional operator of Pearl causal calculus. An accumulated corpus of such packages
constitutes interventional rather than observational evidence, and the distinction is not
recoverable after the fact: a corpus that failed to record it at authoring time cannot
have it restored by later analysis. The reference implementation is
validator/wwd/causal.py, and a design-only package projects to nothing,
because no results means no observation.
| Slot | Source | Contents |
|---|---|---|
| do(controls) | design.json | Every field with causal_role control, keyed by its short property name, carrying the value as designed. |
| actual controls | results.json | Every measured result whose causal role is control. This is the process log, held apart from the intended value so a process deviation stays visible. |
| context | design.json and results.json | Fields with causal_role context, plus every entry of the results context block. |
| responses | results.json | Every measured result whose causal role is response, keyed by measurand quantity and, where the statistic is not a location statistic, by quantity and statistic together. |
| targets | design.json | Every field with causal_role response, the value the tissue was asked to reach. |
| yield | results.json | units_meeting over units_tested, with the criterion the yield summarises. |
The projection keeps the designed control and the measured control in separate slots, so the
gap between them is readable as a process deviation rather than as biological variability.
Two builds differing in one control field, muscle-strip-designed.wwd at 12 kPa
and muscle-strip-highstiff.wwd at 20 kPa, stack into a two-point design.
Questions
What are the four causal roles in WWD?
control, response, context and derived. A control is a quantity the producer sets, such as matrix stiffness, seeding density, anchor spacing, stimulation schedule, medium formulation or incubation temperature. A response is a quantity the biological system determines, such as fiber alignment, twitch force, firing rate, network burst rate, differentiation purity or viability. A context quantity is observed but not chosen: donor identity, passage number on receipt, an ambient excursion during transit, lot-to-lot reagent variation. A derived quantity is computed from others by a stated rule and carries no independent causal standing.
Why does a control have to name a means?
The specification states that a field with causal role control MUST identify the means that imposes it, by naming the protocol step, apparatus or delegated process part responsible, and that a quantity no stated means can set is not a control. The reference validator reports a control without a means as A8_CONTROL_NO_MEANS, and where the design carries a protocol, an imposed_by naming a step the protocol does not contain is H03_IMPOSED_BY_DANGLING.
How is a response recorded?
As a target together with an acceptance criterion, never as a directive. In an as-built package the response appears in measured_results with provenance measured, causal role response, a criterion reference, a statistic, an observed sample size and an observation activity. A result declaring provenance simulated in measured_results is reported as F09_SIMULATED_AS_MEASURED, and measured content identifying no observation activity is R05_NO_OBSERVATION.
What is the difference between causal role and provenance?
Provenance answers where a number came from: designed, simulated, measured, inferred or assumed. Causal role answers who or what determined it. The two axes are orthogonal and both are required. control plus designed is the protocol, control plus measured is the process log, response plus designed is the specification, response plus simulated is the prediction, response plus measured is the result, context plus measured is a covariate, and derived plus inferred is a statistic.
Can a package redefine the causal class of a registry term?
No. A registered term fixes a canonical quantity kind, a canonical unit, an allowed value shape and a causal class. A field MUST NOT declare a causal role contradicting the registered causal class; wwd:fiber_alignment is a response in every package. The reference validator reports the contradiction as V03_CAUSAL_CLASS_MISMATCH.
What does an acceptance criterion test?
Each criterion declares tests_axis, which is control or response. A criterion on a control asks whether the protocol was executed as written. A criterion on a response asks whether the biology delivered. A criterion with no axis is A8_CRITERION_NO_AXIS, and an axis outside control or response is A8_CRITERION_BAD_AXIS.
What is the causal projection of a build?
An as-built package projects losslessly to (do(controls), context, responses, yield), where do denotes the interventional operator of Pearl causal calculus. The reference implementation builds that projection in validator/wwd/causal.py: controls and response targets come from the design fields, context covariates from the design and from the results context block, measured results split by causal role so that responses are outcomes and measured controls are the process log, and the yield fraction is units meeting over units tested.
Continue
Related pages.
- Property fields. Scalar-or-field slots, the five Core backings and the common field contract.
- The WWD file format. Container, manifest, design and results documents.
- The Core property registry. Every term with its causal class, domain and reference.
- Seven example packages, each read field by field.
- The reference validator. Every diagnostic code and how to run it.
- The WWD 0.1 draft specification. All normative sections with anchors.