Repository navigation
Host DPP content specifications, DCAT catalogue and mi: vocabulary (#135) - #136
Conversation
…ulary (#135) material-identity/schema generates each content specification; this repo hosts it byte-identical (design: schema docs/design/content-spec-jsonld.md §2.1, §2.3, §3.3, §7). Everything about it is a proof of concept and says so in-band and on every page. - spec/<act>/<version>/ is a new add-only source tree holding the hand-over as is: <act>.jsonld, <act>.context.jsonld, <act>.dcat.jsonld and the two derived schemas. lib/spec.ts loads it through oxigraph with no document loader, so a remote @context fails: the spec's own context must be inline. - Worker: /spec/<act>/<version> (JSON-LD default, HTML; immutable; Link cite-as), its context.jsonld and compressed/full schemas (immutable), /spec/<act> and /catalog (JSON-LD or HTML, short cache), /ns (JSON-LD, Turtle, HTML, short cache). Strict act and version shapes; anything else falls through. Negotiated routes send Vary: Accept. - Build: spec files byte-identical at the origin paths the Worker maps onto, an HTML page per spec (bilingual PoC banner, metadata, SHA-256 of every file, pins, memberships in sh:order), the /spec/<act> series, /catalog and /ns. - lib/dcat.ts: a dcat:Catalog of the dictionary releases (vYYYY.MM.DD tags), the act series and each spec's own DCAT record, embedded with the record's @context so its checksums keep the meaning they were generated with. Deterministic. - Checks: check 1 covers spec/ (add-only). A new unnumbered spec check refuses bad layout, unparseable JSON-LD, a spec not mi:ProofOfConcept or not CC0, an @id/version/act that disagrees with its directory, a pin outside published/ or whose digest differs from the served /def/<uuid>.json, and DCAT checksums that differ from the hosted bytes. - Vocabulary: the design's new mi: terms join LOCAL_TERMS with label and comment; individuals (granularity levels, ProofOfConcept) are skos:Concepts. Terms are now rdfs:isDefinedBy <…/ns>, the resolvable document, and properties are typed rdf:Property (was the non-existent rdfs:Property). Tested against a small fixture spec under test/fixtures/green/spec/, never under the repo's own spec/, which only ever holds hand-overs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- pr-checks: additions under spec/ get the same two-yes gate as published/. - CODEOWNERS: spec/ needs code-owner review. - deploy: the origin smoke test also probes /catalog and /ns, plus every file the build emitted under site/spec/ (read off the build, since specs arrive with hand-overs). - CLAUDE.md, README, REVIEW.md: spec/ is add-only and hosted, never authored; DCAT is promoted off the plan's deferred list; the new routes; what a reviewer checks on a hand-over PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…touch this repo From a worktree, git hands GIT_DIR and GIT_INDEX_FILE to the hook; the tests' throwaway repos (git -C <tmp>) inherited them and committed, tagged and set core.bare=true on the real repository. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Security reviewScope: Findings1. Medium: symlinks under
2. Medium/Low: 3. Low: renaming files into 4. Low: the generated spec HTML is cached as 5. Info: a spec's DCAT record can make statements about other subjects in Checked and clean
|
) 1. Symlinks under spec/: loadSpecs lstats every entry and refuses a symlink or special file (spec/ itself, an act, a version, a file) instead of following it. Check 1 reads git diff --raw and refuses an added 120000/160000 under spec/ or published/. Every served file (JSON-LD, context, both schemas) must now be a DCAT distribution, and every checksum stated for it must match the hosted bytes. 2. Link injection: only http(s) IRIs (case-insensitive) become <a href>; anything else renders as escaped text. adms:status and dcterms:license must be exactly mi:ProofOfConcept / CC0, in the spec and its record, so the page shows the value the gate verified. 3. Two-yes gate counts renamed and copied files whose new path is under published/ or spec/, not only added ones. 4. Worker: the spec's JSON-LD stays immutable; its HTML (our rendering) gets the short cache. Vary: Accept unchanged. 5. DCAT merge: a record whose embedded dataset states anything about a subject other than the spec or its #fragments (nested nodes, @reverse, @included, named graphs) fails the spec check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Security review: findings addressed in 4b88154
|
- spec check: every membership reference (sh:path, mi:itemType, mi:accessCategory) must be pinned and every pin used, as the schema repo's publication gate requires - the DCAT record is checked as /catalog serves it: the statements the record contributes to the built catalogue, not the record parsed alone - distributionPins keeps every checksum per entry, so a conflicting second digest fails whichever comes first - new "spec release" check: the one pinned release is an existing vYYYY.MM.DD tag that already ships every pinned entry; skipped with a notice without git context or release tags. getReleases now counts release tags only - dcat:isVersionOf must be the act's series, in the spec and its record - every git child (lib git(), test helpers) drops git's --local-env-vars; the pre-push hook unsets the same list - emitSpecs summarizes each spec once and passes the summary on - rel=alternate JSON-LD links name the canonical IRIs Finding 1 (two-yes gate label filter for spec/ hand-overs) is left as is, pending an owner decision. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Code-review findings handled in 8e3c220. I checked each finding against the code before fixing it, and all eight that were in scope turned out to be real.
Also checked: the real
|
Owner decision: the release IRIs the specs pin resolve here.
- /release/<tag> (vYYYY.MM.DD): each release tag as a dcat:Dataset —
dcat:version, dcterms:issued (tag date), PoC status, CC0, the GitHub
release page, and a distribution linking dictionary-<tag>.tar.gz (no
checksum: the offline build does not know the asset's digest).
dcterms:hasPart lists every entry the release contains, each with its
JSON distribution and the SHA-256 of the bytes /def/<uuid> serves;
mi:firstShipped (new vocabulary term) names the entries it first
shipped. JSON-LD by default and immutable, HTML (PoC banner) on the
short cache, cite-as like a spec; an unknown tag 404s
- /release: every release as a dcat:Catalog, JSON-LD or HTML, short cache
- /catalog lists each release with the same node /release does; its page
links /release/<tag>, as does the spec page's dictionary release row
- one rule for what a release contains: shippedBy (lib/git.ts) backs both
/release/<tag> and the pinned-release check; entrySha256 (lib/emit.ts)
backs both the release digests and the spec pin check
- deploy origin probes cover /release/index.{jsonld,html} and every
release page the build emits
- tags come from git (no network); a build without tags writes an empty
/release index
The two-yes gate label filter and the dcat:DatasetSeries modelling are
unchanged, pending owner decisions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
c0210f9 makes the release IRIs that specs pin resolve on this site, as the owner decided:
The two-yes gate label filter and the |
Closes #135
What
/spec/<act>/<version>: JSON-LD by default, HTML onAccept: text/html, immutable cache. Its sub-resourcescontext.jsonld,compressed.schema.jsonandfull.schema.jsonare immutable too./spec/<act>(the version series),/catalog(DCAT) and/ns(themi:vocabulary): short cache withVary: Accept.spec/<act>/<version>/, copied byte-identical;scripts/lib/dcat.tsbuilds the catalogue (dictionary releases + specs, with checksums).spec/is add-only;adms:status mi:ProofOfConceptpresent;The two-approval gate and CODEOWNERS cover
spec/.mi:terms for content specifications (elementId, granularity levels, condition, ContentSpecification, ProofOfConcept, act, dppSchemaVersion, passportContext, …)./spec/and/catalogare added to the origin probes..githooks/pre-pushunsets git's repository variables. Pushed from a worktree, git exportedGIT_DIR/GIT_INDEX_FILEto the hook, and the tests' throwaway repos (git -C <tmp>) inherited them. The tests then committed, tagged and setcore.bare=trueon the real repository.Everything served under
/spec/is a PoC, not production.Follow-up
The first real spec (
spec/steel/v0.0.3/) arrives in a separate hand-over PR after this is released (schema#478).Verification
npm run validateandnpm testpass (120 tests, 97.4 % coverage).🤖 Generated with Claude Code