Executive Summary
A machine learning dataset travels with a descriptor, a document that states in machine-readable form what the data is, where it came from and how to load it. Croissant is the standard for that document, and since version 1.1, published in January of this year, it carries conditions of use as well. There is now a place to write down that the data is for non-commercial purposes only, or that it may be used only after it has passed quality control. This article looks at an arXiv paper posted on September 17 that supplies the procedure by which a machine reads what sits in that place and actually refuses a request.
The paper names five gaps. Croissant 1.1 settled where a condition is written and left open how a condition is evaluated, what evaluation may cost, what happens to a condition an implementation cannot check, whether anything is recorded about what was checked, and how all of this composes with the authority that governs the caller. The author closes the operator set at five and states each operator's decision procedure in the paper itself, which supplies half of that list. Across three descriptors that gated a real analysis pipeline, decisions taken from the profile document matched the existing gate's records exactly. Across a corpus generated from the profile's grammar, 552 decision records agreed three ways.
Sections 1 through 5 follow what the paper reports. Section 4 on evaluation cost and Section 5 on the two authorities both mix measurement with claims the author withdraws and with a caller side the author describes as modelled, so each of those is marked where it appears. Section 6 reads the structure from the AI-Ready Data side, and that reading belongs to this article.
Key figures
Source: arXiv:2609.19640, "A Policy Profile for Croissant" (September 17, 2026)
+11.7µs
Added to a single decision
Measured against a decision that takes 119µs. Translate the document once and reuse it, and the addition is zero
~250×
Delivery against the decision itself
The decision costs 119µs and the process that delivers one costs 30ms. The paper works out the ratio itself and prints it
552
Decision records three carriers agreed on
Not the permit and refuse verdicts alone. The refusal class, the reasons, and every condition with its observed value were compared too
19%
Where the two authorities disagreed
35 of 184 requests. Keep one authority only and that is the share the other would have stopped, though the caller side here is a model the author wrote
Writing a Restriction Down, and Refusing a Request
Writing "not for commercial use" onto a data card is an old practice. Licence documents, terms of use, the restriction clauses stapled to a consent form: in the end all of them were sentences a person read and a person honoured. A machine could carry those sentences around inside a file, but it never stopped a job on the strength of one.
Croissant is the standard that moved those sentences somewhere a machine can read them. It is a dataset descriptor written as JSON-LD over schema.org, and Hugging Face, Kaggle and OpenML publish datasets in it while Google Dataset Search consumes it. Version 1.1 added a responsible-AI and governance section, which puts use restrictions in the sc:usageInfo slot. For simple conditions it points at DUO, the consent vocabulary that came out of biomedical data sharing, and for fine-grained permissions at ODRL, the W3C Recommendation. The specification states that machine-readable use restrictions can support automated compliance checking. A further thread runs alongside that one: an endpoint through which an agent discovers, downloads and loads a dataset, built on top of the same descriptor. Describing the data and driving an agent from that description now run alongside each other. Neither one refuses.
The gap the paper works in is the second half of that sentence about compliance checking. The standard never says how. A vocabulary in which a condition can be written is not a procedure by which a request is decided, and the paper splits the difference into five items.
- No evaluation semantics. Neither the standard nor either vocabulary it recommends says what it means to check a condition against a request. Two conforming consumers may reach different verdicts on the same document without either being wrong.
- No bound on cost. Nothing constrains what a condition may cost to evaluate. In a check that runs on every access, that turns into a performance question.
- No failure semantics. A condition an implementation does not understand has no specified outcome. Whether the request is refused or the condition is skipped decides whether the mechanism is a gate or a suggestion.
- No record. A check that leaves no trace of which conditions it evaluated, with the values it observed, cannot be audited after the fact and cannot be re-decided against a later policy.
- No composition. A dataset-side condition and a caller-side authority constrain the same request, and the standard does not address the relationship.
The paper's claim is not that Croissant cannot express policy. It is that expressing policy and admitting a request are different problems. The properties an auditor needs are won or lost in the second. That is why the title calls refusal a property of the dataset.
A Decision Language Closed at Five Operators
The proposed profile hangs a single policy node off Croissant's dataset node. The policy carries the dataset's lifecycle state. A failClosed field is mandatory, meaning that anything unevaluable is refused. It also carries one or more actions, each naming the states that admit it and the list of conditions attached to it. Conditions may use five operators, and those five are the whole language.
| Operator | Decision, observed o against operand e | ODRL | JSON Schema |
|---|---|---|---|
| min | o ≥ e. Refuse if either is non-numeric | odrl:gteq | minimum |
| max | o ≤ e. Refuse if either is non-numeric | odrl:lteq | maximum |
| in | o equals a member of the array e | odrl:isAnyOf | enum |
| equals | o = e | odrl:eq | const |
| present | Whether a value exists equals the boolean e | minted, none existed | required, negated |
Table 1 of the paper, carried over. Four of the five are operators ODRL already had, and only the presence test is minted, because ODRL defines no existence operator. A design meant to beat ODRL on expressiveness would not look like this table.
The table splits a single kind of mistake in two. The operand is written in the document in advance and the observation arrives with the request, and they fail differently. An observation of the wrong type is an ordinary condition violation and is refused right there. An operand of the wrong type is a defect in the policy itself, and it is refused at the translation step before any comparison is attempted. The profile also fixes how values compare. Numbers compare by value, so 1 and 1.0 are equal, and a boolean is equal only to a boolean, so true is not 1.
Closing the set at five is where this design earns its keep. Every condition carries an explicitly specified decision procedure, so a decision record can state in one line what was compared to what, and the cost of a whole decision is linear in the number of conditions checked. The paper declines to claim constant time. An auditor is not asking for a promise that decisions are always fast. The document alone is enough to count the work a decision takes. A sixth operator slipped into a document turns permit into refuse, never into an unchecked pass.
The last column of the table comes along with the closure. Each of the five operators has an image in JSON Schema. Each action projects onto one MCP tool that an agent can call. The tool's input schema gets one property per condition, with min becoming minimum and in becoming an enum. A caller reads the constraint before calling instead of discovering it in a refusal. The advertised schema and the enforced condition are generated from the same node, so changing a threshold in the document changes both in one edit, and the class of drift that comes from a human copying a number out of one artifact and into another disappears. The projection never replaces the check. Lifecycle state is a property of the dataset and the schema cannot carry it, so a request satisfying every advertised constraint is still refused when the state is wrong.
This profile builds no new decision engine. It translates a document into the native descriptor model of a gate that already exists and calls that gate. The semantics belongs to the profile and the engine is borrowed. Every defect, an unknown operator, a missing field, a duplicate condition name, a policy that does not declare failClosed, is mapped onto the one condition that gate already knows how to refuse on. A translation that fails produces a refusal rather than a gap.
That leaves the obvious question of why this is not simply an ODRL profile. The paper declines to take it as a fight about expressiveness. ODRL has a profile mechanism, the author writes, and it is more than adequate for everything expressed here. The objection sits elsewhere. Minting an operator in a profile gives it an IRI and a definition in prose, and it does not give it a decision procedure, because the standard specifies none. Two independent research groups supplying two different evaluation semantics for the same standard is the evidence for that. One translates ODRL into Answer Set Programming so compliance can be checked against regulatory requirements, and the other, ODRE, attaches executable functions to constraints so a policy can be enforced, not just read. Where the standard leaves a hole is exactly where those two results landed.
One condition is nailed into the design: removing every policy term must leave a valid Croissant document, and no core term may be redefined. A consumer that does not know the profile reads the document, loses the policy and keeps everything else. This layers onto the standard instead of replacing it, in the same lineage as DCAT-AP over DCAT.
Once on a Real Pipeline, Once on Generated Documents
The evaluation comes in two corpora, and the reason for keeping them apart is stated before either one. One is three descriptors that gated a pipeline that actually ran. That is the evidence the mechanism works in front of real execution, and every timing figure in this article comes from it. The other is a set of documents generated from the profile's grammar. That is the evidence the profile covers every feature the specification defines, and it carries no timing at all. Three real descriptors are thin evidence about a feature space, and generated documents are no evidence about production reality.
3.1A Gate in Front of the Work
The target is nf-core/demo v1.0.1. It is a three-stage bioinformatics pipeline that runs quality control on genomic sequence reads, trims them and produces a report, and it runs on public test data rather than on a fixture written for this paper. The gate hooks into the step Nextflow places before each task. A non-zero exit stops that task before its script runs. This is a block at execution time rather than an audit that reads the logs afterward.
The comparison method is the core of this part. The request matrix is generated from the descriptor rather than listed by hand: the satisfying context, the empty context, a context of irrelevant keys, one violation per condition, a non-numeric value for each numeric condition, and two undeclared action names. Each request is decided twice, once from the native descriptor and once from the emitted profile document. What gets compared is not the permit or refuse verdict but the complete decision record. Two evaluators that agree on the verdict and disagree on the refusal class, the reasons, or the conditions they claim to have checked are not equivalent in any sense an auditor would accept. All records matched.
A caveat travels with that result. Both sides of the comparison were decided by the same native gate, and the paper says that was deliberate, since a second evaluator would let a disagreement come from the evaluators rather than from the documents. So what this experiment establishes is the fidelity of the Croissant-to-native translation, and whether the gate's own authorization semantics are correct falls outside the paper.
3.257 Documents Built to Reach Every Corner of the Spec
The second corpus is built to reach everything the specification names. Five operators, three refusal classes, five conformance clauses, two carriers, and a handful of structural forms. It holds 22 valid cases and 13 defect cases, and since a valid case is stored in both carriers, 22 cases come to 44 documents, which with the 13 defect fixtures makes 57 in total. The paper nails down that these numbers are reproducibility information rather than a result. A larger corpus may exercise fewer specification features than a smaller one built to exercise them all, and only the size is visible from the size.
The three-way agreement is a claim about the valid cases only. Each case is written three ways: as the native descriptor, as the profile's own terms, and as an ODRL policy in the sc:usageInfo slot Croissant 1.1 designates for use conditions. Each of the three is run against its generated request matrix. That is 184 requests per representation and 552 complete decision records, all matching three ways. The outcome mix is recorded alongside: 20 permits, 83 condition violations, 44 undeclared actions and 37 state refusals. Agreement was not established over a pile of refusals.
In a comparison like this one, the first thing to establish is that the test can fail at all. Flipping a single row of the operator table, mapping min to odrl:lteq, broke nineteen of the comparisons. The two documents are required to be identical outside the policy node, so whatever difference remains comes from the carrier alone. The defect cases have their own record. Every defect case refuses every request put to it, 91 requests through the profile's own carrier across all 13, and 77 through the ODRL carrier across the 11 that have an ODRL form. The design in which a failed translation yields a refusal was checked document by document.
What this corpus bought is five defects, none of them reachable from three well-formed descriptors. Two of the five look fine in both the document and the code.
- A policy that wrote a string where an array belonged fell through to substring matching. A document with "illumina" written into an in condition silently permitted "illu". Forgetting the array brackets is the obvious authoring slip, and no validator complained about the document.
- In Python a boolean is a subclass of integer, so true compared equal to 1. A policy requiring equals: true was satisfied by an observed 1, and a condition allowing 1 or 2 admitted true. The code looked right, which is why this one took longest to see.
Both defects admit more than the policy's author wrote, and the author calls that the failure this profile exists to prevent. The sentence that follows is that writing down a decision procedure turns out to be a good way to discover that the implementation has a different one. The other repairs went the same way: a numeric operand written into an in condition crashed the evaluator instead of being refused by it, the ODRL carrier raised an exception where it should have refused, and a document that never claimed the profile was being decided anyway. Replaying the deployment corpus under the corrected comparison altered none of its 46 decisions, because the three real descriptors carry no boolean conditions.
Writing the conformance checks as SHACL shapes turned up a defect in Croissant itself. Croissant's context does not declare conformsTo as an IRI and sets a global language tag, so the values of the one property whose purpose is to identify a profile expand to language-tagged string literals rather than to IRIs. A conforming document ends up claiming conformance to the text of the address rather than to the profile that address names. The author reported this to MLCommons as issue 1047, and records that it was still open with no response from the project as of September 16, while the paper was being written.
The Decision Is Microseconds, Delivering It Is Milliseconds
Cost was measured over the three descriptors, 5,000 iterations per case, in-process. In the warm regime, where the document is translated once and the descriptor reused, the native descriptor and the profile document both come to 1.8µs, and the addition is zero because it is the same function on the same object. In the cold regime, where the document is read and translated per decision, 8.5µs becomes 20.2µs, an addition of 11.7µs. Most of that addition is not the profile either. JSON parsing accounts for about 9.7 of the 11.7µs, and the profile-specific translation is about 2µs. The Croissant document with its context runs to 3.1 KB against the native descriptor's 754 B.
That is where the abstract's figures stop, and an 11.7µs addition to a 119µs decision reads as nearly free. The paper blocks that reading in the very next passage. The same harness answers the question directly, the author writes, and the answer is not the comfortable one.
Replicating the gated and ungated arms 30 times each and pairing by replicate, the per-task end-to-end cost of gating resolves at 25.7 milliseconds, with a 95% confidence interval of 3.3 to 48.2 milliseconds. The increase is not the policy. It is one Python interpreter spawned per task, measured separately at 30.2 milliseconds against 9.6 milliseconds for an interpreter that does nothing at all.
So the honest statement the paper offers is a ratio rather than an absence. The decision costs 119µs and the mechanism delivering it costs 30 milliseconds, a factor of roughly 250. Expressing policy as a standard descriptor is therefore invisible inside a per-task cost dominated by process startup, and the author adds that it would remain small against a resident gate that removed the startup entirely.
The most striking thing in this section is not a number but a withdrawal. An earlier single-run version of this measurement reported the overhead as lying below the resolution of the engine's own trace. At n=30 that is not true, and the author writes that the claim is withdrawn here, not repeated. Given that recording what was checked and how is itself the paper's subject, this passage reads as a demonstration of the method.
Why Pebblous Is Watching This Paper
The question Pebblous has held onto for a long time is where a value came from and what it passed through to become what it is now. Conditions of use sit at the opposite end of that question. Where the data came from looks backward, and what it may be used for looks forward. Both are questions the data itself should be able to answer.
Narrow AI-Ready Data down to clean data and this paper reads as somebody else's business. Under a definition where ready data means no missing values, even labels and a matching schema, a sentence saying "do not use this here" is administrative paperwork outside the data. That boundary collapses once agents start finding, downloading and running datasets on their own, because the person who would have read the condition is no longer in the middle. The narrow thing this paper proves is exactly that point. A dataset that carries its own use conditions in a standard descriptor lets a gate decide from that document alone, and it gains nothing beyond that.
What we looked at longest in this structure is the record more than the decision itself. Once every decision retains which conditions were checked and what values were observed, that record becomes an asset that can be re-decided against a later policy. The paper ships a tool that replays a stored decision against a new policy without the original data, the original pipeline or the evaluator that produced it, and reports the fraction of an archive that cannot be decided, a number that would otherwise be a guess. Anyone who works on data quality diagnostics will recognise the shape. It is the difference between keeping a score and keeping the checks the score came from. The first gets thrown away when the criteria change, and the second gets recomputed.
The withdrawal in Section 4 is not the only one. An earlier version of the paper recorded the profile's identifier as not yet resolvable, and after the registration landed the author verified the redirect end to end and updated the sentence. Writing the conformance tests changed a sentence of the specification too, once it turned out that a document stripped of its policy terms could still claim to conform to the profile. The demand that every decision record what it checked is a rule the author also applied to their own manuscript.
A team that wants to hold its own organisation to the idea of data that states and proves its conditions has four things worth checking.
- Where are our datasets' use restrictions written today? If they live only in contracts and a wiki, moving them somewhere a machine reads is the first step.
- Is the procedure for deciding those restrictions written down in prose? With implementation code and no written procedure, nobody notices when the implementation follows a different rule. That is how three of the defects in this paper surfaced.
- When our system meets a condition it cannot evaluate, does it block or skip? That choice separates a gate from a suggestion.
- Does a refusal record what was checked? Without it, a refusal is indistinguishable from a bug later on.
One thing is worth saying plainly. This is a preprint that has not been peer reviewed, the evidence from real execution is three descriptors, and half the composition result is a model. The author writes all of that down. Pulling a conclusion out of it about data governance having entered its automated era would be overreach, not a reading. What we took from it is smaller. It is a record of one person building a minimal version of what has to exist, past the point where there is a slot to write a condition in, before that sentence actually stops a request, and measuring it.
Thanks for reading this far. The figures and quotations this article cites can be checked by anyone in the original at arXiv:2609.19640. We would be glad to hear what form your organisation keeps its data use conditions in, and where the place that actually checks them sits.
References
Academic Papers
- 1.Chernov, A. (2026). "A Policy Profile for Croissant: Refusal as a Property of the Dataset." arXiv:2609.19640.
- 2.Chernov, A. (2026). "Dataset Descriptors for Autonomous and Observable Biomedical Data Pipelines." IEEE EMBC 2026, Toronto.
Standards & Specifications
- 3.MLCommons. (2026). "What's New in Croissant 1.1: Extensible, Agent-Ready ML Dataset Standard."
- 4.MLCommons. "Croissant Format Specification 1.1."
Reference Implementations
- 5.doytsujin. "ok-nfcore-admission-gate." GitHub. An unreviewed repository from the author's circle — revalidates the gate's deployment cost.
- 6.doytsujin. "ok-croissant-policy-profile." GitHub. An unreviewed repository from the author's circle — reference implementation of the policy profile.