EnVar microschema · class
Tool Run
ToolRun
A single tool invocation that produced an output from one or more inputs: tool name and version, container image (where applicable), arguments, environment, run timestamp and duration, input / output hashes and row counts, and an optional log excerpt.
Where it sits
Composed intoProvenanceChainEnvironmentalExposureRecord
ReferencesAnyValue
Fields
This simply records which program was used — like noting the make and model of an appliance before describing its settings. Everything else about the run only makes sense once you know what tool ran.
Tool name, e.g. daymet, narr, pm, amadeus, geocoder.
Example
daymet — DeGAUSS Daymet extraction tool
Covered by — 5 standards
Why it matters & mappings
Without the tool name, a consumer cannot tell which piece of software produced the value, so the run cannot be re-executed and the tool's known behaviours and biases cannot be looked up. It is the entry point for every reproducibility check on the run.
See also: https://degauss.org/
Software changes over time, and a version number labels one specific edition of it — like the edition of a book. Recording it says exactly which edition of the tool did the work.
Semver tool version. Mandatory.
Example
1.0.0
Covered by — 5 standards
Why it matters & mappings
Two versions of the same tool can produce different outputs from identical inputs, so "we ran daymet" without a version is not reproducible. It is mandatory because it is the cheapest and most decisive reproducibility anchor after the tool name.
See also: https://semver.org/
Containers are self-contained software bundles, and the repository is the public shelf address where a bundle is published — effectively the download location of the exact software package used.
Container image repository, e.g. ghcr.io/degauss-org/daymet. Null for non-containerised tools.
Example
ghcr.io/degauss-org/daymet
Covered by — 5 standards
Why it matters & mappings
The repository says where the packaged software lives, so anyone can pull the same container and re-run the step. Without it the image digest has nothing to be resolved against, and re-execution requires guessing where the tool came from.
See also: https://degauss.org/
A digest is an exact serial number for the software bundle actually used — stronger than a version label, which can be reused for different contents. If the bundle changes at all, the serial number changes.
SHA256 of the container image actually used (not just the tag). Reproducibility-critical.
Example
sha256:a8b3c2d1e0f9...
Covered by — 5 standards
Why it matters & mappings
Image tags are mutable, so "same tag" does not mean same code; only the digest pins the exact bytes that ran. It is the strongest reproducibility anchor available for a containerised run.
These are the settings the program was started with — like the knob positions on a machine. Writing them down means someone else can set the knobs identically before pressing start.
The exact argument map passed at invocation, serialised as a JSON string.
Example
{"variables": "tmax"}
Covered by — 5 standards
Why it matters & mappings
The same tool run with different arguments produces different outputs; without the exact argument map, re-running the tool reproduces the tool, not the result. Recording it verbatim removes all guesswork about settings.
Simply when the program started, expressed on a single worldwide clock (UTC) so that times recorded on different machines in different time zones line up.
When the run started (UTC).
Example
2026-05-23T14:18:42Z
Covered by — 5 standards
Why it matters & mappings
The timestamp orders runs within the provenance chain and lets auditors match the record against external logs and the state of upstream data sources at that moment. Without it, "which run produced this file" can become undecidable.
See also: https://www.w3.org/TR/prov-o/
A SHA-256 hash is a fingerprint of a file — if even one byte changes, the fingerprint changes completely. Comparing fingerprints proves two files are exactly the same without inspecting their contents.
SHA256 of the input file (CSV / parquet).
Example
9f8e7d6c5b4a...
Covered by — 5 standards
Why it matters & mappings
The input hash lets anyone verify they are re-running on byte-identical inputs; without it, a "reproduction" may quietly use different data, and disagreements can no longer be traced to inputs versus code.
See also: https://doi.org/10.6028/NIST.FIPS.180-4
Just the number of lines of data that went in. If you expected 3 addresses and the count says 2, something was lost before the tool ever ran.
Number of rows in the input.
Example
3 — one row per cohort address
Covered by — 5 standards
Why it matters & mappings
The row count is a coarse but instant integrity check — a truncated or partially delivered input shows up immediately as the wrong count. It also anchors the input side of input/output cardinality checks.
A fingerprint of the result file — change one byte and the fingerprint changes. It ties this metadata record to exactly one version of the data it describes.
SHA256 of the output file (CSV / parquet).
Example
1c2d3e4f5a6b...
Covered by — 5 standards
Why it matters & mappings
The output hash proves the companion data file is the one this metadata describes; without it, a swapped or regenerated file can silently detach the values from their provenance.
See also: https://doi.org/10.6028/NIST.FIPS.180-4
The number of lines of data produced. Outputs often have a predictable size, so a wrong count is an early warning that rows went missing along the way.
Number of rows in the output.
Example
459 — 3 subjects × 153 days
Covered by — 5 standards
Why it matters & mappings
The expected output cardinality (e.g. 3 subjects × 153 days = 459 rows) is checkable at a glance; a mismatch flags dropped subjects or dates before any analysis runs on the data.
A short plain-language note on the tool's job, for example "extracts daily temperature for a list of addresses". It saves the reader a lookup elsewhere.
One-line tool description (from the tool's dht env var or equivalent).
Example
DeGAUSS Daymet extraction container
Why it matters & mappings
A one-line description lets a reader understand what the tool does without leaving the record or resolving the tool name against external documentation. Omitting it costs readability, not reproducibility.
See also: https://degauss.org/
When the repository field is deliberately empty, this note says why — for example, the tool simply was not run inside a container. An explained blank can be trusted; an unexplained one is a question mark.
Reason container_image_repository is null.
Example
not_applicable — e.g. the tool is not containerised
Allowed values
not_provided_by_source Source product does not produce this information
available_but_not_extracted Source produces this information but the current pipeline does not surface it
upstream_data_not_propagated An upstream tool emitted this information but the current pipeline dropped it...
under_investigation We are working on populating this slot
not_applicable This slot does not apply to this variable / record
Why it matters & mappings
A blank repository is ambiguous — it could mean "the tool is not containerised" or "we forgot to record it". Stating the reason turns a silent gap into checkable information; a blank is a bug, a null-with-reason is information.
This note explains why the software bundle's exact serial number was not recorded — often the runner only kept the human-friendly version label and never looked up the precise identifier behind it.
Reason container_image_digest is null.
Example
available_but_not_extracted — e.g. the runner did not resolve the tag to a digest
Allowed values
not_provided_by_source Source product does not produce this information
available_but_not_extracted Source produces this information but the current pipeline does not surface it
upstream_data_not_propagated An upstream tool emitted this information but the current pipeline dropped it...
under_investigation We are working on populating this slot
not_applicable This slot does not apply to this variable / record
Why it matters & mappings
Without a stated reason, a missing digest is indistinguishable from a pipeline bug; with one (e.g. the runner never resolved the tag) the gap is auditable and fixable rather than silent.
How long the program ran, in seconds. A wildly unusual run time is often the first clue that something went wrong even when the tool reported success.
How long the run took, in seconds.
Example
37
Why it matters & mappings
Duration is a cheap sanity signal — a step that normally takes an hour finishing in two seconds hints at silent failure or truncated input. Omitting it loses a diagnostic, not reproducibility.
A snapshot of the computer setup around the tool — operating system, language versions, key libraries. Like noting the oven and altitude alongside a recipe, because the surroundings can change the outcome.
Host OS, Docker / podman version, R / Python version, key library versions, as a native key/value object.
Example
None
Why it matters & mappings
Library and runtime versions can change numeric results even when the tool version is fixed; recording the environment explains otherwise-mysterious differences between re-runs. For non-containerised tools it is the only record of the software stack.
The last few lines the program printed while running — its own account of what it did and whether anything looked wrong. Keeping a snippet is like stapling the receipt to the record.
Last ~50 lines of the run log, where useful for debugging or audit.
Example
[2026-05-23 14:19:19] daymet 1.0.0 finished: wrote 459 rows to /output/tmax.csv (0 errors, 0 warnings)
Why it matters & mappings
The log tail captures warnings and error summaries that no structured field carries; without it, diagnosing a suspect run means hunting for logs that may no longer exist. Omission costs auditability, not reproducibility.
A note explaining why no log snippet is attached — often the logs live on the machine that ran the job and were simply never copied into the record.
Reason run_log_excerpt is null.
Example
available_but_not_extracted — e.g. logs exist on the runner but are not captured by the pipeline
Allowed values
not_provided_by_source Source product does not produce this information
available_but_not_extracted Source produces this information but the current pipeline does not surface it
upstream_data_not_propagated An upstream tool emitted this information but the current pipeline dropped it...
under_investigation We are working on populating this slot
not_applicable This slot does not apply to this variable / record
Why it matters & mappings
Stating why the log excerpt is absent (e.g. logs exist on the runner but are not captured) distinguishes a deliberate omission from data loss and tells auditors where to look. A blank is a bug; a null-with-reason is information.
Full field reference — every slot, cardinality & inheritance
| Field | Name | Tier | Cardinality / Range | Description |
|---|---|---|---|---|
| Tool Name | tool_name |
core | 1 String |
Tool name, e |
| Tool Version | tool_version |
core | 1 String |
Semver tool version |
| Tool Description | tool_description |
optional | 0..1 String |
One-line tool description (from the tool's dht env var or equivalent) |
| Container Image Repository | container_image_repository |
recommended | 0..1 String |
Container image repository, e |
| Reason Image Repository Is Missing | container_image_repository_missing_reason |
optional | 0..1 MissingReasonEnum |
Reason container_image_repository is null |
| Container Image Digest | container_image_digest |
recommended | 0..1 String |
SHA256 of the container image actually used (not just the tag) |
| Reason Image Digest Is Missing | container_image_digest_missing_reason |
optional | 0..1 MissingReasonEnum |
Reason container_image_digest is null |
| Run Arguments | run_arguments |
recommended | 0..1 String |
The exact argument map passed at invocation, serialised as a JSON string |
| Run Timestamp (UTC) | run_timestamp_utc |
recommended | 0..1 datetime |
When the run started (UTC) |
| Run Duration (Seconds) | run_duration_seconds |
optional | 0..1 Float |
How long the run took, in seconds |
| Run Environment | run_environment |
optional | 0..1 AnyValue |
Host OS, Docker / podman version, R / Python version, key library versions, a... |
| Input File SHA-256 Hash | input_file_sha256 |
recommended | 0..1 String |
SHA256 of the input file (CSV / parquet) |
| Input Row Count | input_row_count |
recommended | 0..1 Integer |
Number of rows in the input |
| Output File SHA-256 Hash | output_file_sha256 |
recommended | 0..1 String |
SHA256 of the output file (CSV / parquet) |
| Output Row Count | output_row_count |
recommended | 0..1 Integer |
Number of rows in the output |
| Run Log Excerpt | run_log_excerpt |
optional | 0..1 String |
Last ~50 lines of the run log, where useful for debugging or audit |
| Reason Log Excerpt Is Missing | run_log_excerpt_missing_reason |
optional | 0..1 MissingReasonEnum |
Reason run_log_excerpt is null |
Diagram & LinkML source
classDiagram
class ToolRun
click ToolRun href "../../classes/ToolRun/"
ToolRun : container_image_digest
ToolRun : container_image_digest_missing_reason
ToolRun --> "0..1" MissingReasonEnum : container_image_digest_missing_reason
click MissingReasonEnum href "../../enums/MissingReasonEnum/"
ToolRun : container_image_repository
ToolRun : container_image_repository_missing_reason
ToolRun --> "0..1" MissingReasonEnum : container_image_repository_missing_reason
click MissingReasonEnum href "../../enums/MissingReasonEnum/"
ToolRun : input_file_sha256
ToolRun : input_row_count
ToolRun : output_file_sha256
ToolRun : output_row_count
ToolRun : run_arguments
ToolRun : run_duration_seconds
ToolRun : run_environment
ToolRun --> "0..1" AnyValue : run_environment
click AnyValue href "../../classes/AnyValue/"
ToolRun : run_log_excerpt
ToolRun : run_log_excerpt_missing_reason
ToolRun --> "0..1" MissingReasonEnum : run_log_excerpt_missing_reason
click MissingReasonEnum href "../../enums/MissingReasonEnum/"
ToolRun : run_timestamp_utc
ToolRun : tool_description
ToolRun : tool_name
ToolRun : tool_version
name: ToolRun
annotations:
domain_of_use:
tag: domain_of_use
value: environmental_exposure
description: 'A single tool invocation that produced an output from one or more inputs:
tool name and version, container image (where applicable), arguments, environment,
run timestamp and duration, input / output hashes and row counts, and an optional
log excerpt.'
title: Tool Run
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://www.w3.org/TR/prov-o/
rank: 1000
slot_usage:
tool_name:
name: tool_name
required: true
tool_version:
name: tool_version
required: true
attributes:
tool_name:
name: tool_name
annotations:
tier:
tag: tier
value: core
justification:
tag: justification
value: Without the tool name, a consumer cannot tell which piece of software
produced the value, so the run cannot be re-executed and the tool's known
behaviours and biases cannot be looked up. It is the entry point for every
reproducibility check on the run.
explanation:
tag: explanation
value: This simply records which program was used — like noting the make and
model of an appliance before describing its settings. Everything else about
the run only makes sense once you know what tool ran.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No gaia table records a tool-name field; the gaia-db image
name is not carried on any native output.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: partial
status:
tag: status
value: asserted
where:
tag: where
value: output filename stem (e.g. ...daymet_1.0.0.csv / ...geocoder_3.3.0...csv)
note:
tag: note
value: Tool name is embedded in the output CSV filename, recoverable
but not a first-class field.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No native Amadeus output file records the tool name.
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER's table_dictionary carries dataset/resource metadata,
not a per-run producing-tool name.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Tool-run provenance is instance-layer; CODATA EVs/CDIF operate
at the conceptual/represented layer and are excluded from scoring.
description: Tool name, e.g. `daymet`, `narr`, `pm`, `amadeus`, `geocoder`.
title: Tool Name
examples:
- value: daymet
description: DeGAUSS Daymet extraction tool
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://degauss.org/
owner: ToolRun
domain_of:
- ToolRun
range: string
required: true
tool_version:
name: tool_version
annotations:
tier:
tag: tier
value: core
justification:
tag: justification
value: Two versions of the same tool can produce different outputs from identical
inputs, so "we ran daymet" without a version is not reproducible. It is
mandatory because it is the cheapest and most decisive reproducibility anchor
after the tool name.
explanation:
tag: explanation
value: Software changes over time, and a version number labels one specific
edition of it — like the edition of a book. Recording it says exactly which
edition of the tool did the work.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No gaia table records the gaia-db image version.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: full
status:
tag: status
value: verified
where:
tag: where
value: output filename container image tag (e.g. daymet_1.0.0) and
ghcr.io/degauss-org/... reference
evidence:
tag: evidence
value: COMPARISON.md §K — tool version ✅ carried as the container
image tag in the filename
note:
tag: note
value: Container image tag baked into the filename pins the exact
tool version.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Amadeus's R package version lives in the object attributes
but no native file records it.
cher:
tag: cher
annotations:
extent:
tag: extent
value: partial
status:
tag: status
value: asserted
where:
tag: where
value: table_dictionary.version (resource version 001/002...) via
§2.6
note:
tag: note
value: C-HER carries a resource version code, but it versions the
dataset resource, not a per-run producing tool.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Per-run tool version is instance-layer; out of scope for CODATA
EV/CDIF conceptual layer.
description: Semver tool version. Mandatory.
title: Tool Version
examples:
- value: 1.0.0
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://semver.org/
owner: ToolRun
domain_of:
- ToolRun
range: string
required: true
tool_description:
name: tool_description
annotations:
tier:
tag: tier
value: optional
justification:
tag: justification
value: A one-line description lets a reader understand what the tool does
without leaving the record or resolving the tool name against external documentation.
Omitting it costs readability, not reproducibility.
explanation:
tag: explanation
value: A short plain-language note on the tool's job, for example "extracts
daily temperature for a list of addresses". It saves the reader a lookup
elsewhere.
description: One-line tool description (from the tool's `dht` env var or equivalent).
title: Tool Description
examples:
- value: DeGAUSS Daymet extraction container
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://degauss.org/
owner: ToolRun
domain_of:
- ToolRun
range: string
container_image_repository:
name: container_image_repository
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: The repository says where the packaged software lives, so anyone can
pull the same container and re-run the step. Without it the image digest
has nothing to be resolved against, and re-execution requires guessing where
the tool came from.
explanation:
tag: explanation
value: Containers are self-contained software bundles, and the repository
is the public shelf address where a bundle is published — effectively the
download location of the exact software package used.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No gaia table records a container image repository.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: partial
status:
tag: status
value: asserted
where:
tag: where
value: ghcr.io/degauss-org/... reference implicit in the container
invocation
note:
tag: note
value: The repository is implied by the DeGAUSS container reference
but not written to any native output column.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Amadeus is an R package, not a container; no image repository
applies.
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER records no producing-tool container image repository.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Container provenance is instance-layer; out of scope for CODATA.
description: Container image repository, e.g. `ghcr.io/degauss-org/daymet`. Null
for non-containerised tools.
title: Container Image Repository
examples:
- value: ghcr.io/degauss-org/daymet
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://degauss.org/
owner: ToolRun
domain_of:
- ToolRun
range: string
container_image_repository_missing_reason:
name: container_image_repository_missing_reason
annotations:
tier:
tag: tier
value: optional
justification:
tag: justification
value: A blank repository is ambiguous — it could mean "the tool is not containerised"
or "we forgot to record it". Stating the reason turns a silent gap into
checkable information; a blank is a bug, a null-with-reason is information.
explanation:
tag: explanation
value: When the repository field is deliberately empty, this note says why
— for example, the tool simply was not run inside a container. An explained
blank can be trusted; an unexplained one is a question mark.
description: Reason `container_image_repository` is null.
title: Reason Image Repository Is Missing
examples:
- value: not_applicable
description: e.g. the tool is not containerised
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: MissingReasonEnum
container_image_digest:
name: container_image_digest
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: Image tags are mutable, so "same tag" does not mean same code; only
the digest pins the exact bytes that ran. It is the strongest reproducibility
anchor available for a containerised run.
explanation:
tag: explanation
value: A digest is an exact serial number for the software bundle actually
used — stronger than a version label, which can be reused for different
contents. If the bundle changes at all, the serial number changes.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Container image digest is not carried by any native gaia output.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Only the mutable image tag is in the filename; no SHA256 digest
is emitted.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No container image digest is emitted.
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER records no producing-tool container image digest.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Container digest is instance-layer; out of scope for CODATA.
description: SHA256 of the container image actually used (not just the tag). Reproducibility-critical.
title: Container Image Digest
examples:
- value: sha256:a8b3c2d1e0f9...
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://github.com/opencontainers/image-spec
owner: ToolRun
domain_of:
- ToolRun
range: string
container_image_digest_missing_reason:
name: container_image_digest_missing_reason
annotations:
tier:
tag: tier
value: optional
justification:
tag: justification
value: Without a stated reason, a missing digest is indistinguishable from
a pipeline bug; with one (e.g. the runner never resolved the tag) the gap
is auditable and fixable rather than silent.
explanation:
tag: explanation
value: This note explains why the software bundle's exact serial number was
not recorded — often the runner only kept the human-friendly version label
and never looked up the precise identifier behind it.
description: Reason `container_image_digest` is null.
title: Reason Image Digest Is Missing
examples:
- value: available_but_not_extracted
description: e.g. the runner did not resolve the tag to a digest
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: MissingReasonEnum
run_arguments:
name: run_arguments
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: The same tool run with different arguments produces different outputs;
without the exact argument map, re-running the tool reproduces the tool,
not the result. Recording it verbatim removes all guesswork about settings.
explanation:
tag: explanation
value: These are the settings the program was started with — like the knob
positions on a machine. Writing them down means someone else can set the
knobs identically before pressing start.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No gaia output records the invocation argument map.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: DeGAUSS emits no per-run argument map on its native outputs.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No native Amadeus file records the run argument map.
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER records no per-run argument map.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Run arguments are instance-layer; out of scope for CODATA.
description: The exact argument map passed at invocation, serialised as a JSON
string.
title: Run Arguments
examples:
- value: '{"variables": "tmax"}'
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: string
run_timestamp_utc:
name: run_timestamp_utc
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: The timestamp orders runs within the provenance chain and lets auditors
match the record against external logs and the state of upstream data sources
at that moment. Without it, "which run produced this file" can become undecidable.
explanation:
tag: explanation
value: Simply when the program started, expressed on a single worldwide clock
(UTC) so that times recorded on different machines in different time zones
line up.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: partial
status:
tag: status
value: asserted
where:
tag: where
value: gaia_db data_source.created_at/updated_at and location.created_at
(load time, not run timestamp)
note:
tag: note
value: Gaia records per-row load times, which approximate but are
not the tool-run start timestamp.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Only OS file mtime is available; no run timestamp is emitted.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: partial
status:
tag: status
value: asserted
where:
tag: where
value: thredds_response_headers.json HTTP Date header
note:
tag: note
value: The HTTP Date header is the only timestamp captured, recoverable
but not a first-class run-timestamp field.
cher:
tag: cher
annotations:
extent:
tag: extent
value: partial
status:
tag: status
value: asserted
where:
tag: where
value: table_dictionary.metadata_created_at/metadata_updated_at (metadata
time, not producing-run time)
note:
tag: note
value: C-HER stamps metadata create/update times, which are registration
times, not the producing tool-run timestamp.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Run timestamp is instance-layer; out of scope for CODATA.
description: When the run started (UTC).
title: Run Timestamp (UTC)
examples:
- value: '2026-05-23T14:18:42Z'
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://www.w3.org/TR/prov-o/
owner: ToolRun
domain_of:
- ToolRun
range: datetime
run_duration_seconds:
name: run_duration_seconds
annotations:
tier:
tag: tier
value: optional
justification:
tag: justification
value: Duration is a cheap sanity signal — a step that normally takes an hour
finishing in two seconds hints at silent failure or truncated input. Omitting
it loses a diagnostic, not reproducibility.
explanation:
tag: explanation
value: How long the program ran, in seconds. A wildly unusual run time is
often the first clue that something went wrong even when the tool reported
success.
description: How long the run took, in seconds.
title: Run Duration (Seconds)
examples:
- value: '37'
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: float
run_environment:
name: run_environment
annotations:
tier:
tag: tier
value: optional
justification:
tag: justification
value: Library and runtime versions can change numeric results even when the
tool version is fixed; recording the environment explains otherwise-mysterious
differences between re-runs. For non-containerised tools it is the only
record of the software stack.
explanation:
tag: explanation
value: A snapshot of the computer setup around the tool — operating system,
language versions, key libraries. Like noting the oven and altitude alongside
a recipe, because the surroundings can change the outcome.
description: Host OS, Docker / podman version, R / Python version, key library
versions, as a native key/value object.
title: Run Environment
examples:
- object:
os: Ubuntu 22.04
container_runtime: docker 24.0.7
r_version: 4.3.1
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: AnyValue
inlined: true
input_file_sha256:
name: input_file_sha256
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: The input hash lets anyone verify they are re-running on byte-identical
inputs; without it, a "reproduction" may quietly use different data, and
disagreements can no longer be traced to inputs versus code.
explanation:
tag: explanation
value: A SHA-256 hash is a fingerprint of a file — if even one byte changes,
the fingerprint changes completely. Comparing fingerprints proves two files
are exactly the same without inspecting their contents.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No gaia output records an input-file SHA256.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: DeGAUSS emits no input-file checksum.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No native Amadeus file records an input-file SHA256 in this
scenario.
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER records no per-run input-file hash.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: File checksums are instance-layer; out of scope for CODATA.
description: SHA256 of the input file (CSV / parquet).
title: Input File SHA-256 Hash
examples:
- value: 9f8e7d6c5b4a...
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://doi.org/10.6028/NIST.FIPS.180-4
owner: ToolRun
domain_of:
- ToolRun
range: string
input_row_count:
name: input_row_count
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: The row count is a coarse but instant integrity check — a truncated
or partially delivered input shows up immediately as the wrong count. It
also anchors the input side of input/output cardinality checks.
explanation:
tag: explanation
value: Just the number of lines of data that went in. If you expected 3 addresses
and the count says 2, something was lost before the tool ever ran.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No native gaia output records an input row count; you would
wc -l.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: DeGAUSS emits no input row count.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No native Amadeus file records an input row count.
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER records no per-run input row count.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Row counts are instance-layer; out of scope for CODATA.
description: Number of rows in the input.
title: Input Row Count
examples:
- value: '3'
description: one row per cohort address
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: integer
output_file_sha256:
name: output_file_sha256
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: The output hash proves the companion data file is the one this metadata
describes; without it, a swapped or regenerated file can silently detach
the values from their provenance.
explanation:
tag: explanation
value: A fingerprint of the result file — change one byte and the fingerprint
changes. It ties this metadata record to exactly one version of the data
it describes.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No gaia output records an output-file SHA256.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: DeGAUSS emits no output-file checksum.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No native Amadeus file records an output-file SHA256 in this
scenario.
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER records no per-run output-file hash.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: File checksums are instance-layer; out of scope for CODATA.
description: SHA256 of the output file (CSV / parquet).
title: Output File SHA-256 Hash
examples:
- value: 1c2d3e4f5a6b...
from_schema: https://w3id.org/linkml/microschemas/envar
see_also:
- https://doi.org/10.6028/NIST.FIPS.180-4
owner: ToolRun
domain_of:
- ToolRun
range: string
output_row_count:
name: output_row_count
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: The expected output cardinality (e.g. 3 subjects × 153 days = 459 rows)
is checkable at a glance; a mismatch flags dropped subjects or dates before
any analysis runs on the data.
explanation:
tag: explanation
value: The number of lines of data produced. Outputs often have a predictable
size, so a wrong count is an early warning that rows went missing along
the way.
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No native gaia output records an output row count; you would
wc -l.
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: DeGAUSS emits no output row count.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: No native Amadeus file records an output row count.
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER records no per-run output row count.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: Row counts are instance-layer; out of scope for CODATA.
description: Number of rows in the output.
title: Output Row Count
examples:
- value: '459'
description: 3 subjects × 153 days
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: integer
run_log_excerpt:
name: run_log_excerpt
annotations:
tier:
tag: tier
value: optional
justification:
tag: justification
value: The log tail captures warnings and error summaries that no structured
field carries; without it, diagnosing a suspect run means hunting for logs
that may no longer exist. Omission costs auditability, not reproducibility.
explanation:
tag: explanation
value: The last few lines the program printed while running — its own account
of what it did and whether anything looked wrong. Keeping a snippet is like
stapling the receipt to the record.
description: Last ~50 lines of the run log, where useful for debugging or audit.
title: Run Log Excerpt
examples:
- value: '[2026-05-23 14:19:19] daymet 1.0.0 finished: wrote 459 rows to /output/tmax.csv
(0 errors, 0 warnings)'
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: string
run_log_excerpt_missing_reason:
name: run_log_excerpt_missing_reason
annotations:
tier:
tag: tier
value: optional
justification:
tag: justification
value: Stating why the log excerpt is absent (e.g. logs exist on the runner
but are not captured) distinguishes a deliberate omission from data loss
and tells auditors where to look. A blank is a bug; a null-with-reason is
information.
explanation:
tag: explanation
value: A note explaining why no log snippet is attached — often the logs live
on the machine that ran the job and were simply never copied into the record.
description: Reason `run_log_excerpt` is null.
title: Reason Log Excerpt Is Missing
examples:
- value: available_but_not_extracted
description: e.g. logs exist on the runner but are not captured by the pipeline
from_schema: https://w3id.org/linkml/microschemas/envar
owner: ToolRun
domain_of:
- ToolRun
range: MissingReasonEnum
class_uri: prov:Activity
See Also
Identifier and Mapping Information
Annotations
| property | value |
|---|---|
| domain_of_use | environmental_exposure |
Schema Source
- from schema: https://w3id.org/linkml/microschemas/envar
Mappings
| Mapping Type | Mapped Value |
|---|---|
| self | prov:Activity |
| native | envar:ToolRun |