Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Code of Conduct

## The short version

Be straight with people and assume they are doing the same. Argue about the
work, not the person doing it. Technical disagreement is the point of an open
specification and is always welcome; contempt is not.

## Expected behaviour

- Engage with what someone actually wrote, not the weakest version of it.
- Say what you verified and how. In a project whose whole premise is that claims
should be checkable, "I ran X and it printed Y" carries more weight than
confidence.
- Be willing to be wrong in public. Correcting a claim is normal maintenance
here — this repository ships a release note correcting one of its own.
- Give people room to be new. The schema-authorship rule in
[CONTRIBUTING.md](CONTRIBUTING.md) catches almost everyone the first time.

## Unacceptable behaviour

- Harassment, insults, or personal attacks, public or private.
- Discriminatory language or conduct, including about protected characteristics.
- Publishing others' private information without permission.
- Sustained disruption of discussion, or deliberately arguing in bad faith.
- Sexualised language, imagery, or attention in any project space.

## Scope

This applies in every project space — issues, pull requests, discussions,
commits, and any channel where you are representing the project.

## Reporting

Report conduct concerns to **change@agenticstransformation.com**.

Reports are handled confidentially. You will get an acknowledgement within 48
hours and an indication of what we intend to do. If your report concerns a
maintainer, say so in the message — it will be handled by someone else.

We would rather hear about something small and early than a pattern that has
been building for months.

## Enforcement

Maintainers will act in proportion to what happened: a private word, a public
correction, editing or removing contributions, or a temporary or permanent ban
from project spaces. We will say what we decided and why, in as much detail as
respects the reporter's privacy.

## Attribution

Adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
version 2.1.
114 changes: 114 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Contributing to FLUID

Thanks for helping build FLUID. Read the first section before opening a pull
request — it is the rule that most often surprises people.

## The schemas are not authored here

`schema/fluid-schema-*.json` is **vendored**. The FLUID JSON Schemas are
authored in [`forge-cli`](https://github.com/Agenticstiger/forge-cli), the
reference implementation, and land here through
[`.github/workflows/schema-sync.yml`](.github/workflows/schema-sync.yml), which
fails the build if the two ever drift. This repository is the public
distribution point.

**So a pull request that edits a file under `schema/` will be rejected**, not
because the change is wrong but because it will be silently reverted by the next
sync. Propose schema changes upstream in forge-cli. The sync currently covers
0.7.2 and later; earlier versions diverge historically and are excluded on
purpose.

What you *can* change here:

| Area | Notes |
|---|---|
| `tests/**` | The conformance corpus. This is where "FLUID-conformant" is defined — see [tests/README.md](tests/README.md). |
| `conformance/**` | The runner, the reference check, the coverage tool. |
| `scripts/check-compat.py`, `scripts/compat-waivers.txt` | The backward-compatibility gate. |
| `docs/**` | The documentation site. |
| `examples/**` | Example contracts. |

## Setup

```bash
pip install "jsonschema[format]>=4.22"

python3 conformance/run.py # the corpus must be green
python3 tests/meta_test.py # the gates must be able to fail
python3 scripts/check-compat.py # no release may break its promise
```

The `[format]` extra is not optional. Without it `jsonschema` registers no
`date-time` checker, and the `tests/optional/` cases pass vacuously in one
environment and fail in another.

Optionally, to check the corpus against the reference implementation:

```bash
pip install data-product-forge
python3 conformance/check_reference.py
```

## Adding conformance cases

The corpus is the most valuable thing you can contribute, because it is what
makes conformance a fact rather than a claim. [tests/README.md](tests/README.md)
has the file format and the rules in full; the short version:

- Assert on **JSON Schema keyword + RFC 6901 pointer**, never message text.
Wording is a rendering choice; keywords and pointers are interoperable facts.
- An invalid case must declare **why** it is invalid. The loader refuses one
that does not — a case asserting only "rejected" passes for any reason at all.
- Keep cases **minimal**: an invalid document differs from a valid one in
exactly the one way under test.
- The bar is **falsifiability**, not case count. Run
`python3 conformance/mutation_coverage.py --group <yours>`; if deleting the
constraint you meant to pin leaves the corpus green, your case is not doing
the work you think it is.

## Changing the schema's meaning

Anything that changes which documents validate is normative. Open an issue
before writing code, and expect to be asked for the corpus cases that pin the
new behaviour. Editorial changes — typos, prose, descriptions that do not affect
validation — can go straight to a pull request.

## The compatibility promise

Every FLUID release has claimed that valid contracts keep validating. That
promise is now enforced by `scripts/check-compat.py` on every pull request.

If it reports a narrowing change, one of two things is true: the change is a
mistake, or it is deliberate. A deliberate one goes in
[`scripts/compat-waivers.txt`](scripts/compat-waivers.txt) **with the evidence
that settled it**. The waiver file is a decision record, not a mute button —
read the existing entries for the standard being applied.

## Pull requests

- One concern per pull request.
- Say what you verified and how. "Tests pass" is less useful than the command
you ran and what it printed.
- New behaviour needs a case that would fail without it.
- Be honest about what you did not do. A known gap that is written down is worth
more than a claim nobody checked.

## Reporting problems

- **Bugs and spec questions** — open an issue.
- **Security vulnerabilities** — do not open an issue. See
[SECURITY.md](SECURITY.md).
- **Conduct** — see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).

## Licence and provenance

Contributions are accepted under this repository's [MIT licence](LICENSE). By
opening a pull request you certify that you wrote the contribution or otherwise
have the right to submit it under that licence — the
[Developer Certificate of Origin](https://developercertificate.org/). Sign your
commits with `git commit -s` if you would like that certification recorded
explicitly.

There is no contributor licence agreement. A CLA on a specification would signal
reserved relicensing rights, which is not the intent — see
[GOVERNANCE.md](GOVERNANCE.md).
78 changes: 78 additions & 0 deletions GOVERNANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Governance

## Current model: steward-maintainer

FLUID is pre-1.0. The specification is stewarded by its originating maintainers
in the [open-data-protocol](https://github.com/open-data-protocol) organization.
Decisions on spec changes are made by the maintainers, in the open, through
issues and pull requests on this repository.

This is an honest description of a small project, not a claim of formal
multi-vendor governance. There is no steering committee and no vote, because
there is not yet a constituency to hold one.

## Where things are decided

FLUID has two homes, on purpose, and the split matters for anyone proposing a
change:

| Artefact | Authored in | Why |
|---|---|---|
| The JSON Schemas | [`forge-cli`](https://github.com/Agenticstiger/forge-cli) | It is the only place with an exercised test suite over them, and it is the engine that enforces them. |
| The conformance corpus | **here** | Conformance must be checkable by someone who has neither the engine nor an account with us. |

That second row is the load-bearing one. A standard whose only definition is
"whatever the reference implementation accepts" is a vendor format with a
specification-shaped document attached. The corpus in [`tests/`](tests/) is what
makes "FLUID-conformant" mean something independent, and forge-cli is
implementation #1 under test — never the referee.

## Vendor neutrality

FLUID already lives in a vendor-neutral organization. The maintainers are
employed by a company that also ships a commercial control plane built on FLUID,
and that is a real conflict of interest, so the mitigations are structural
rather than promissory:

- The schemas are **MIT** and the corpus is data. Anyone can implement FLUID and
demonstrate conformance without permission, tooling, or a relationship with us.
- **No CLA.** Contributions are accepted under the repository licence via the
[DCO](https://developercertificate.org/). There is no mechanism by which
contributed work could be relicensed out from under contributors.
- Compatibility is **enforced by CI**, not asserted in prose, so a change that
would strand existing contracts is visible to everyone at review time rather
than discovered later by users.
- Anything the specification does not decide is written down as an open question
rather than settled silently by implementation behaviour. See "Known
ambiguities" in [tests/README.md](tests/README.md).

As FLUID gains external implementers, the intent is to move toward a formal
governance model with representation from parties who do not share an employer.
Concrete triggers: a second independent implementation demonstrating
conformance, or sustained contribution from outside the current maintainers.

## Versioning and compatibility

Pre-1.0, minor versions may add. They may not narrow: a contract valid under one
version must stay valid under its successor. `scripts/check-compat.py` enforces
this on every pull request, and deliberate exceptions are recorded in
[`scripts/compat-waivers.txt`](scripts/compat-waivers.txt) with the evidence that
justified them.

One historical break is on record (0.7.1 → 0.7.2, `notification` became a closed
object). It was found by the gate after the fact, and the release note that
claimed otherwise has been corrected rather than quietly left standing.

## Trademarks

"FLUID" as a name for this specification is reserved by the maintainers. The
format is free to implement, describe, and build products on; the mark exists so
that "FLUID-conformant" keeps meaning what the corpus says it means. If you ship
an implementation, say so plainly — you do not need permission to state that
your tool implements FLUID.

## Contact

Open an issue for anything about the specification. See
[SECURITY.md](SECURITY.md) for vulnerabilities and
[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for conduct concerns.
75 changes: 75 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Security Policy

## What "security" means for a specification repository

This repository publishes JSON Schemas, a conformance corpus, and the small
Python tools that check them. It is not a service and holds no user data, so the
realistic threat model is narrower than for an application — but not empty:

- A schema that **fails open** — accepting a contract it should reject — can let
an unsafe data product through a downstream gate that trusted it.
- A conformance case that **passes for the wrong reason** launders a false
assurance into every implementation that trusts the corpus.
- The **compatibility gate** or the **conformance runner** silently not doing
what it claims. A gate that cannot fail is worse than no gate, because it is
believed. This is why [`tests/meta_test.py`](tests/meta_test.py) exists and
runs first in CI.
- Anything that would cause a consumer to execute code, exfiltrate data, or
escalate privilege while processing a published artefact.

If you have found something in those categories, we want to hear about it, even
if you are unsure it qualifies.

## Supported versions

| Schema version | Supported |
|---|---|
| 0.7.5 | ✅ |
| 0.7.3 – 0.7.4 | ✅ |
| ≤ 0.7.2 | ❌ |

Fixes land on the current version. Because the compatibility promise forbids
narrowing, a fix that would reject a previously-valid contract is a version
increment, not a patch to a published schema — a published schema is an
immutable artefact that people validate against by URL.

## Reporting a vulnerability

**Please do not report security vulnerabilities through public GitHub issues.**

Use GitHub's
[Private Vulnerability Reporting](https://github.com/open-data-protocol/fluid/security/advisories/new).
It keeps the report private until a fix ships, gives us somewhere to draft the
advisory, and lets you follow the fix without leaving GitHub.

If you cannot use that form, email **change@agenticstransformation.com**.

You should get a response within **48 hours**. If you do not, please follow up —
assume the message was lost rather than ignored.

Please include as much as you can:

- What the issue is, and which artefact it affects (schema version, corpus file,
or tool).
- A contract, corpus case, or command that demonstrates it.
- What you expected to happen and what happened instead.
- Any impact you can see on downstream consumers.

## What happens next

1. We acknowledge within 48 hours.
2. We reproduce it, and tell you if we cannot.
3. We agree a fix and a disclosure timeline with you. We will not sit on a
confirmed issue quietly; if we disagree on severity we will say so rather
than let it go silent.
4. We credit you in the advisory unless you would rather we did not.

## Scope

**In scope:** the schemas under `schema/`, the corpus under `tests/`, and the
tools under `conformance/` and `scripts/`.

**Out of scope here, but still worth reporting to their owners:** the reference
implementation ([forge-cli](https://github.com/Agenticstiger/forge-cli)) and any
product built on FLUID. If you are unsure which, report it here and we will route
it.
32 changes: 30 additions & 2 deletions docs/releases/0.7.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,39 @@ binding:

---

## 🔄 100% backward compatible with 0.7.1
## 🔄 Backward compatibility with 0.7.1 — one narrowing change

- ✅ No breaking changes
- ✅ `semantics` and `icebergConfig` are both opt-in
- ✅ All 0.7.1 features (agentPolicy, sovereignty, provider-first orchestration, root accessPolicy) fully preserved
- ⚠️ **One breaking change**, corrected here after the fact: `notification` became a
closed object.

This page previously claimed "100% backward compatible" and "no breaking changes".
That was not true, and the conformance gate added in
[#44](https://github.com/open-data-protocol/fluid/pull/44) proved it. `$defs/notification`
gained `"additionalProperties": false` in 0.7.2, so a contract carrying **any** extra
member on a `build.execution.notifications[]` entry validated under 0.7.1 and is
rejected by 0.7.2:

```yaml
build:
execution:
notifications:
- type: slack
target: "#data-alerts"
condition: failure
retryOnFailure: true # accepted by 0.7.1, REJECTED by 0.7.2
```

Verified with that document plus a negative control — the same contract without
`retryOnFailure` validates under both — so the rejection is attributable to this
change and nothing else. The finding is recorded in
[`scripts/compat-waivers.txt`](https://github.com/open-data-protocol/fluid/blob/main/scripts/compat-waivers.txt),
and `scripts/check-compat.py` now runs on every pull request so a narrowing change
cannot ship unannounced again.

If you hit this, drop the unrecognised member from your `notifications` entries; every
field the schema does declare is unchanged.

**Migration:**

Expand Down
5 changes: 3 additions & 2 deletions docs/schema/versions.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Schema Versions

Every published version of the FLUID JSON Schema. Point your validator at a version's JSON Schema; read its generated HTML reference for the field-by-field detail. The latest version is **0.7.4**.
Every published version of the FLUID JSON Schema. Point your validator at a version's JSON Schema; read its generated HTML reference for the field-by-field detail. The latest version is **0.7.5**.

| Version | JSON Schema | HTML Reference |
|---|---|---|
| **0.7.4** **(latest)** | [`fluid-schema-0.7.4.json`](/fluid/schema/fluid-schema-0.7.4.json) | [`0.7.4/fluid-spec.html`](/fluid/specs/0.7.4/fluid-spec.html) |
| **0.7.5** **(latest)** | [`fluid-schema-0.7.5.json`](/fluid/schema/fluid-schema-0.7.5.json) | [`0.7.5/fluid-spec.html`](/fluid/specs/0.7.5/fluid-spec.html) |
| 0.7.4 | [`fluid-schema-0.7.4.json`](/fluid/schema/fluid-schema-0.7.4.json) | [`0.7.4/fluid-spec.html`](/fluid/specs/0.7.4/fluid-spec.html) |
| 0.7.3 | [`fluid-schema-0.7.3.json`](/fluid/schema/fluid-schema-0.7.3.json) | [`0.7.3/fluid-spec.html`](/fluid/specs/0.7.3/fluid-spec.html) |
| 0.7.2 | [`fluid-schema-0.7.2.json`](/fluid/schema/fluid-schema-0.7.2.json) | [`0.7.2/fluid-spec.html`](/fluid/specs/0.7.2/fluid-spec.html) |
| 0.7.1 | [`fluid-schema-0.7.1.json`](/fluid/schema/fluid-schema-0.7.1.json) | [`0.7.1/fluid-spec.html`](/fluid/specs/0.7.1/fluid-spec.html) |
Expand Down
Loading