DisclosureOS documentation · v2 Beta
Connect measurements to instruments
Link a measured value to the captured channel and source file that support it.
An observation records a measured value. An acquisition context describes the equipment and capture. Bindings connect the two: they identify which raw product supports the value, which instrument produced it and which channel was recorded.
Use this guide after Equipment and captures. It follows the same synthetic station and one radial-velocity measurement of −3 m/s. The complete measured-value example supplies all four documents, the source files and a runnable check.
Start with a working connection
Download the complete example, unzip it and open the measurement folder. With Node.js 22 or newer, run:
npm install
npm startThe download pins the published @disclosureos/schema@2.0.0-beta.4. The result reports success: true, with structural, semantic and profile checks passed. Keep the example open as you follow the connections below; the walkthrough explains each result.
This binding profile accepts claim history 0.1.0, with its observation embedded, plus acquisition context and binding documents at 0.1.0. These are document schema versions, separate from the npm package version. The profile does not accept a newer research claim-history document merely because it is also called a history. Use the supplied documents for this exercise.
Two mapping documents
The mapping documents connect identifiers in different documents. They do not contain the measured value or duplicate the equipment inventory.
| Document | Question it answers | Example connection |
|---|---|---|
| Acquisition bindings | Which equipment and captured file do these observation sources describe? | Observation source:station → context instrument:station; observation product:raw → context product:captured-raw. |
| Measurement bindings | Which channel and capture time support this measurement? | Observation measurement:velocity → its bound raw product → channel radar at an explicit UTC instant. |
A product: reference is local to its document. product:raw in the observation and product:captured-raw in the context name the two declarations that the acquisition binding connects. The evaluator does not infer this link from equal names, filenames or display labels.
1. Connect the source and raw product
Open bindings.json. Its document identifiers select the supplied history, its embedded observation and the acquisition context:
{
"kind": "acquisition_bindings",
"schemaVersion": "0.1.0",
"id": "synthetic-binding",
"historyId": "profile-example",
"observationId": "synthetic",
"contextId": "synthetic-context",
"sources": [
{
"sourceRef": "source:station",
"instrumentRef": "instrument:station"
}
],
"products": [
{
"observationProductRef": "product:raw",
"contextProductRef": "product:captured-raw"
}
]
}This shows the complete mapping without the download's optional extensions metadata. The source must be an instrument-data source, and the mapped product must be raw. The acquisition evaluator follows the context product to its capture and pinned configuration. It also checks that the two raw-product declarations agree on their digest and media type.
The derived product:summary is not mapped as a second capture. Its declared processing inputs lead back to the raw product. Keep that processing relationship in the observation.
Inspect source and product mapping fields.
2. Name the channel and measurement time
Open measurements.json. It names the same three input documents and adds the acquisition-binding document's ID:
{
"kind": "measurement_bindings",
"schemaVersion": "0.1.0",
"id": "synthetic-measurements",
"historyId": "profile-example",
"observationId": "synthetic",
"contextId": "synthetic-context",
"acquisitionBindingsId": "synthetic-binding",
"measurements": [
{
"measurementRef": "measurement:velocity",
"observationProductRef": "product:raw",
"channelId": "radar",
"time": {
"state": "known",
"kind": "instant",
"value": "2026-07-28T12:10:00Z",
"timeScale": "UTC"
}
}
]
}channelId is a bare ID within the capture's pinned manifest. It must also appear among the capture's active channels. This mapping selects the channel; it does not create one.
The measurement time describes when the measured value was captured. It is separate from the observation's event time and the time an analyst saved an assessment. Here it is exactly the start of capture a1, whose interval ends at 12:11:00Z.
Inspect measurement mapping fields.
3. Check the connected documents
The downloaded run.mjs loads the four JSON documents and the required local files. Its central call is:
const result = await evaluateMeasurementBindings(
history,
context,
bindings,
measurements,
{ assets },
);Import evaluateMeasurementBindings from @disclosureos/schema/experimental/v2. assets is a Map<string, Uint8Array> of complete file bytes. Keys belong to the acquisition context:
| Key in this example | Bytes supplied |
|---|---|
product:captured-raw | The captured raw product. Do not key it as the observation's product:raw. |
manifest:r1 | The configuration artifact. |
calibration:c1/report | The calibration report artifact. |
A supplied calibration review artifact uses calibration:ID/review. This fixture has an unreviewed calibration and no review artifact. A URL or declared digest does not supply bytes; the evaluator never fetches artifact URLs. See the complete script and file inventory for a runnable integration.
What the measurement profile checks
- Each instrument-supported measurement has one explicit channel-and-time mapping.
- Its primary source chain reaches the mapped raw product and an instrument-data source. An uncertainty reference or an unused assertion alone does not supply that chain.
- The raw product is connected by the acquisition bindings, and the channel belongs to the pinned manifest and capture.
- The measurement and channel use exactly the same quantity and unit strings. This profile does not convert units or infer equivalent quantities.
- The explicit measurement time fits within the nominal capture. Intervals are half-open:
[start, end). An instant at the capture start is inside; an instant at its end is outside. A contained interval may end at the same exclusive endpoint. - Required raw-product, configuration and calibration-report bytes match their declarations through the acquisition evaluator.
This profile supports one captured channel and one instrument raw product per measurement. Separate measurements can use different channels. A fused measurement with multiple instrument raw products needs an explicit fusion profile; displaying several recordings together does not validate fusion.
Try a wrong channel
From the example folder, run:
npm start -- --wrong-channelThe script changes the channel to missing-channel in memory. Structure still passes, but semantic and profile checks fail. The diagnostic identifies the exact mapping:
{
"code": "MEASUREMENT.CHANNEL",
"stage": "semantic",
"severity": "error",
"pointer": "/measurements/measurements/0/channelId",
"message": "Channel must be declared by the pinned manifest and captured by this acquisition."
}The first measurements in the pointer names the input document; the second names its mappings array. The script prints this issue inside an array and exits with status 1. Run npm start again to check the original, unchanged files. The worked example also lets you test missing bytes, changed bytes and the capture boundary.
Interpret the result
| Situation | Result to distinguish |
|---|---|
| Valid connections and matching required bytes | The binding profile can pass. |
| Required raw bytes withheld | The otherwise eligible profile remains not_checked; success is false. |
| Supplied bytes disagree with their digest | External and profile checks fail. |
| Channel or time outside the declared capture | The connection fails; artifact checking can remain unattempted. |
| Unknown measurement time | Representable in the schema, but the profile fails because it requires an explicit time. |
| No instrument-supported measurements | The profile remains not_checked. |
Keep the individual stages and diagnostics when handling a result. success: false can mean an incomplete check or a detected inconsistency. Do not turn both into a finding that a measurement is false. In this evaluator, even the passing example retains external: "not_checked"; the result explanation distinguishes that overall status from the artifact matches performed by the profile.
A passing binding check does not reproduce processing, apply clock uncertainty, inspect artifact contents or validate the scientific result. Calibration-review prerequisites are a separate profile; independent scientific review remains a further task.
Build with your own capture
Start with one measured value and its actual source files. Preserve the observation's primary source chain, select the capture's configuration and channel, then create the two mappings. Check quantity, units and time against provider metadata before supplying the exact artifact bytes. Do not fill missing calibration or timing declarations with the synthetic example's values to make a profile pass.
Use the shared field reference for required fields, alternatives and constraints. The JSON Schema exports are @disclosureos/schema/experimental/v2/bindings/schema and @disclosureos/schema/experimental/v2/measurements/schema. Their identifiers, urn:disclosureos:experimental:acquisition-bindings:0.1.0 and urn:disclosureos:experimental:measurement-bindings:0.1.0, name the contracts; they are not downloadable HTTP endpoints.
Continue with the complete measured-value example, or inspect connected recordings in the research desk. The viewer's fictional case is distinct from this small validation fixture.