-
Notifications
You must be signed in to change notification settings - Fork 2
Native OO-LD validator driven by the specification rule catalogue #114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
80ee29a
8e96921
f39b280
3030aa8
71c734c
8c965d6
988bc38
4fdda5e
26ceba9
264d71e
3ba00a6
08b9945
3b497b5
57c1945
f6fcbbb
bd34c1b
ca11109
a7a7f3c
92524af
6589527
793aaa1
ebc3907
fb99f5c
cbcf95a
5bcd043
09ede4a
bee7204
13ade19
5a6b6d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Files copied verbatim from the oold-schema repository at a release tag must keep their exact | ||
| # bytes: `src/oold/validation/meta/index.json` records a sha256 for each vendored meta-schema, and | ||
| # the fixtures are refreshed by copying bytes straight out of a tag. With `core.autocrlf=true` - | ||
| # the Windows default - git would rewrite their line endings on checkout, silently breaking those | ||
| # checksums and making every refresh from upstream show a whole-file diff. | ||
| src/oold/validation/meta/*/** -text | ||
| tests/data/oold/** -text |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -224,6 +224,5 @@ benchmark_comparison.txt | |
| */osw_files/* | ||
|
|
||
| # Local | ||
| CLAUDE.md | ||
| AGENTS.md | ||
| .ign | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| { | ||
| "mcpServers": { | ||
| "oold-validation": { | ||
| "command": "uv", | ||
| "args": [ | ||
| "run", | ||
| "--directory", | ||
| ".", | ||
| "python", | ||
| "-m", | ||
| "oold.validation.mcp_server" | ||
| ] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # Working in this repository | ||
|
|
||
| Guidance for AI agents. Human contributors want `CONTRIBUTING.md`, which this file does not repeat. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```bash | ||
| make check # lint, type-check, dependency audit | ||
| make test # pytest with coverage | ||
| make validate # run the validator over the committed fixtures | ||
| make docs-test # strict docs build, fails on any warning | ||
|
|
||
| OOLD_SCHEMA_DIR=../oold-schema uv run pytest -m parity # compare against the reference harness | ||
| ``` | ||
|
|
||
| The parity tests skip silently without `OOLD_SCHEMA_DIR`, so a green `make test` does not mean | ||
| parity holds. Run them explicitly when touching `src/oold/validation/`. | ||
|
|
||
| ## The validation subsystem | ||
|
|
||
| `src/oold/validation/` is a native Python port of `oold-schema/scripts/validate.mjs`, deliberately | ||
| not a subprocess wrapper. The reference harness is still the oracle: the parity tests assert this | ||
| port reaches the same verdicts on the same fixtures, including check labels and triple counts. | ||
|
|
||
| **Changes here must not change verdicts unless that is the point of the change.** Reporting, | ||
| wording and detail payloads are free to move; a schema that passed must still pass. If parity | ||
| drops, treat it as a defect in this port until proven otherwise. Upstream has been wrong before, | ||
| but that is the rarer case. | ||
|
|
||
| ### Rules come from the specification, not from this code | ||
|
|
||
| The OO-LD spec numbers its normative statements (`OOLD-RT-08f2`) and publishes them as | ||
| `oold-rules.json`, vendored per version under `src/oold/validation/meta/<version>/`. Three | ||
| consequences that are easy to get wrong: | ||
|
|
||
| - **Severity is read, never written.** A check reports a problem; whether that is a failure or a | ||
| warning comes from the rule's `level` in the catalogue. Do not reintroduce a hardcoded | ||
| FAIL/WARN column. This is what lets one code base validate against several spec versions. | ||
| - **Skip rather than guess.** A rule absent from the selected version's catalogue, or marked | ||
| deprecated there, is skipped with a message saying so. Older versions ship no catalogue at all | ||
| and skip the whole `rule.*` family. Never fall back to "check it anyway". | ||
| - **Judge the resolved context.** Checks receive a `ContextView`, which is what terms mean after | ||
| remote contexts and prefixes are applied. Reading `schema["@context"]` directly reports | ||
| violations against correct schemas. | ||
|
|
||
| A false positive costs far more than a missed finding, because it teaches people to ignore the | ||
| output. When a rule is only partly decidable, check the part you are sure of. | ||
|
|
||
| ### Vendored meta-schemas are byte-exact | ||
|
|
||
| `src/oold/validation/meta/<version>/` holds verbatim copies from oold-schema release tags, and | ||
| `index.json` records a sha256 of each. They are therefore not ordinary source files: | ||
|
|
||
| - never reformat them, and never let a formatting hook touch them (`.pre-commit-config.yaml` | ||
| excludes these paths, `.gitattributes` marks them `-text`); | ||
| - they must be LF. A CRLF copy hashes differently, which passes on Windows and fails on Linux. | ||
| This has happened; `test_the_vendored_files_are_stored_with_unix_line_endings` now guards it; | ||
| - to add a version, follow `src/oold/validation/meta/README.md` and recompute the digests. | ||
|
|
||
| ## This repo and oold-schema are decoupled on purpose | ||
|
|
||
| They release on separate schedules, so neither pipeline waits on the other: | ||
|
|
||
| - `coverage.rules` **warns** when a rule has no check, rather than failing. A spec that has moved | ||
| ahead must not break this build. | ||
| - Adding a check for a rule is described in `CONTRIBUTING.md#translating-a-specification-rule`. | ||
| oold-schema's `make check` prints that link when the catalogue changes. | ||
|
|
||
| Do not add a check for a rule that is not in any vendored catalogue. Vendor the version first. | ||
|
|
||
| ## Check ids are a public interface | ||
|
|
||
| Check ids (`lint.container`, `roundtrip.instance`, `rule.id-fragment`) appear in reports, CI logs | ||
| and, before long, in suppression comments. Renaming one silently breaks whatever depended on it, | ||
| and unlike rule ids there is no guard. Treat a rename as a breaking change: say so in the commit, | ||
| and prefer adding a new id over repurposing an existing one. | ||
|
|
||
| ## Conventions | ||
|
|
||
| - Conventional Commits; releases are automated by python-semantic-release, so the type prefix | ||
| decides the version bump. | ||
| - No AI attribution or co-author trailers in commits or PR descriptions. | ||
| - In prose and comments, use regular dashes rather than em or en dashes. | ||
| - Do not create scratch files inside this repository or in `../oold-schema`. To see what a file | ||
| looks like on a clean checkout, read git state (`git show :path`, `git check-attr`) instead of | ||
| deleting and restoring it. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should avoid spreading between root level markdown and published docs => move all content in docs, keep shallow references in files like CONTRIBUTING.md + concise (overview/simple getting started only) root-level README that points to the docs
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -106,6 +106,18 @@ Backends are registered per IRI prefix via `set_resolver` / `set_backend`, so mu | |
|
|
||
| `oold.ui` contains optional integrations for [Panel](https://panel.holoviz.org/), [NiceGUI](https://nicegui.io/), and [Jupyter anywidget](https://anywidget.dev/). These are not installed by default. | ||
|
|
||
| ### Validation Layer (optional) | ||
|
|
||
| `oold.validation` checks that a schema is well formed and that its `@context` actually carries | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see previous comment |
||
| every declared property into RDF. It is a native port of the reference harness in | ||
| [oold-schema](https://github.com/OO-LD/oold-schema), and reuses `pyld` from the serialization | ||
| layer, so the JSON-LD half of it adds no dependencies. | ||
|
|
||
| One pipeline backs three surfaces - the library API, the `oold validate` CLI, and an MCP server - | ||
| so there is a single implementation to keep correct. The meta-schemas it validates against are | ||
| versioned: a hand-curated history ships in the package, and a schema can be checked against | ||
| several versions in one run. See [Validation](how-to/validation.md). | ||
|
|
||
| --- | ||
|
|
||
| ## Data flow | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as mentioned: no AI only documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reduced to a pointer. The validation invariants moved to
docs/architecture.md("Validation subsystem design"), the vendoring rules todocs/maintaining-meta-schemas.md, the working conventions todocs/contributing.md. What is left is the command list plus links. No file undersrc/ortests/cites it any more.