nofuture audit-manifest turns a dataset’s historical availability assumptions
into an executable CI contract. The validator itself remains zero-dependency and
the same contract is published as JSON Schema for editors and other tooling.
{
"schema_version": 1,
"datasets": [
{
"path": "features/vintages.csv",
"format": "csv",
"event_time": {
"column": "event_time",
"semantics": "observation_period"
},
"known_at": {
"column": "known_at",
"semantics": "first_observed_by_consumer"
},
"eligible_from": {
"policy": "explicit_column",
"column": "eligible_from"
},
"timezone": "offset-aware",
"revision": {
"policy": "append_only_vintages",
"key": ["series_id", "event_time"]
},
"null_reason": {
"policy": "required_when_value_missing",
"column": "null_reason",
"value_columns": ["value"]
}
}
]
}
Paths are resolved relative to the manifest. format currently supports CSV.
event_time.semantics and known_at.semantics are deliberately descriptive
strings so providers can document their own meaning without a NoFutureData-
specific vocabulary.
Availability timestamps must be offset-aware. eligible_from.policy is either
explicit_column or known_at; the explicit policy requires every row to carry
an eligible timestamp. An optional decision_time object can name a decision
column and reuse the normal LEAK001 causality check.
For revised data, append_only_vintages requires a key containing the event-time
column. Two vintages with the same logical key and the same known_at fail as
ambiguous. Use revision.policy: "none" for immutable datasets.
Null handling is explicit too. required_when_value_missing names the data
columns being monitored and a reason column; missing values without a reason fail
CI. Use not_applicable when the dataset contract intentionally has no nullable
value fields.
Run the contract locally or in CI:
nofuture audit-manifest temporal-contract.json
The portable schema lives at
schemas/temporal-contract.schema.json.
The repository also contains a passing contract, a schema-invalid contract, and
a schema-valid dataset with deliberately invalid temporal rows under
tests/fixtures/manifest/.
| Code | Meaning |
|---|---|
MAN001 |
manifest is missing, malformed JSON, or not a JSON object |
MAN002 |
unsupported schema_version |
MAN003 |
datasets is missing, empty, or not a list |
MAN004 |
a dataset’s temporal contract is incomplete or malformed |
MAN005 |
a referenced dataset does not exist |
MAN006 |
dataset format is unsupported |
MAN007 |
dataset is missing a required contract column |
TIME005 |
explicit eligible_from policy has a missing row value |
REV001 |
a logical observation has duplicate revision availability time |
REV002 |
a logical observation has a missing revision-key value |
NULL001 |
a monitored value is missing without a null reason |
Availability findings such as TIME001, TIME003, and LEAK001 are reused
unchanged so direct CSV audits and manifest-driven audits share the same causal
rule IDs.