The pages say what they are about, and the card's size is read off the card - #81
Merged
Merged
Conversation
…e card Every page of the documentation site stated what it was to a person and nothing at all to a machine: parsing the five live pages for `<script type="application/ld+json">` returned zero blocks on all five. Each page now carries one `@graph` of four nodes -- the site, the page, the share card, and the software the page is about. Nothing in it is typed. The page node's name is the `<title>`, its description is the `<meta name="description">`, its url is the canonical; the site node's name is what `og:site_name` already renders; the card node's dimensions are read out of the committed PNG's own IHDR chunk; and the software node's name, sentence and links are the installed distribution's metadata, which is `pyproject.toml` speaking through the install rather than a paraphrase of it. Read from the installed metadata rather than the file because `gauntlet site` has to work from a wheel; the test reads the source table instead, so a stale environment is a failing comparison rather than an older sentence published. There is no `Dataset` node, no `distribution`, and no DCAT vocabulary, and a test forbids all of it permanently. A dataset descriptor is not a description, it is an invitation: it exists so dataset search engines and state open-data catalogs harvest what it names, and a catalog listing is far easier to acquire than to withdraw. Whether an evaluation pack should solicit that is an open question with an owner's name on it, and the test is there so it stays a decision somebody makes rather than a line somebody adds. There is no `softwareVersion` either: these pages are built from `main`, which carries the version being prepared and not the one on the index, so the field would announce a release that does not exist yet. The check parses every built page with a parser that matches on the script element and its `type` attribute, never on the string, and holds every value against the tag, the file or the `pyproject.toml` table it came from, so a node that stopped being derived fails while it still says something plausible. It names the examinable set so it cannot pass having read nothing, and it runs inside `make verify`. Two things fixed on the way: `og:image:width` and `og:image:height` were the literals 1200 and 630. They happened to be right, and nothing would have said so if the card were re-rendered at another size. Both are now read off the card, a build refuses a card it cannot read rather than stating a size it guessed, and a missing card refuses before anything is rendered rather than after. The no-script check asserted `scripts == 0`, which the data block would end. A script element whose type is not a script type is never prepared and never executed, so "static pages, no runtime, nothing for a CSP to have to allow" is unchanged; the count that replaces it is stricter rather than looser, because it reddens for an inline script, a `src`, a `type="module"` and a `type="text/javascript"` alike. The three places that said "no script at all" in prose now say "no executable script" and name the data block, because a promise quietly narrowed is worse than a promise restated.
…t-they-are-about # Conflicts: # CHANGELOG.md
Resolves the overlap with GA4 (#83): each page now carries the GA4 loader and the ld+json data block, and the script checks in tests/test_site.py and tests/test_analytics.py count executable scripts so the data block is not mistaken for a second loader.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every page of the documentation site stated what it was to a person and nothing
at all to a machine. Parsing the five live pages at
https://chelseakr.github.io/gauntlet/for<script type="application/ld+json">returns zero blocks on all five. After this change it returns one on each.
What the page now says
One
@graphper page, four nodes: the site, the page, the share card, and thesoftware the page is about.
Nothing in it is typed. Every value is read back out of the same constant, tag
or file that renders the visible head, so the claim a crawler reads and the
claim a person reads cannot disagree:
WebPage.name<title>WebPage.description<meta name="description">WebPage.urlWebSite.nameog:site_namealready rendersImageObject.url,.captionog:imageandog:image:altalready renderImageObject.width,.heightSoftwareApplication.alternateName,.description,.url,.codeRepositorypyproject.tomlspeaking through the installinLanguage<html lang>Read from the installed metadata rather than from
pyproject.tomlfor thereason
ASSETSis a package path:gauntlet sitehas to work from a wheel,where there is no repository to read a source file out of. The test reads the
source table instead, so the two agree only when the environment was synced
from this tree and a stale install is a failing comparison rather than an older
sentence on a published page.
What it deliberately does not say
No
Dataset, nodistribution, no DCAT. A dataset descriptor is not adescription, it is an invitation: it exists so that dataset search engines and
state open-data catalogs harvest what it names and list it as a dataset of
record, and a catalog listing is far easier to acquire than to withdraw.
Whether an evaluation pack, a JSON pack or a reviewer document should solicit
that is an open question with an owner's name on it.
test_it_solicits_no_dataset_harvestforbids the vocabulary permanently so the difference stays a decision somebody
makes rather than a line somebody adds, and a companion test runs each
forbidden term through the same scanner to prove the scanner bites.
No
softwareVersion. These pages are built frommain, which carries theversion being prepared, while the index carries the last one released -- the two
have differed for most of this project's life, including right now. The field
would announce a release that does not exist yet, to consumers that read
structured data and to nobody in a position to see it was wrong.
The check
tests/test_site.pygains a section that parses all five built pages with aparser matching on the script element and its
typeattribute, never on thestring. That distinction is not fastidiousness: an audit of this portfolio
scored a sibling project as carrying structured data because the string
application/ld+jsonoccurred on its page, and the one occurrence was theacceptattribute of a file picker.Coverage is 5 pages examined / 5 examinable, and
test_there_are_pages_to_examineasserts the examinable set equals what thebuild wrote and is not empty, so the section cannot pass having read nothing.
It runs inside
make verify, which is what CI runs.Each assertion class was checked by sabotaging the generator, rebuilding, and
confirming the gate goes red: a missing block, a page node that stopped reading
the
<title>, an@idreference to a node the graph does not define, carddimensions that stopped being read off the PNG, a software node that stopped
reading the packaging metadata, a
Datasetnode with adistribution, anexecutable
<script>, an empty property, and a dropped node. All nine reddened;each was reverted and the tree hash checked back to the byte.
Two things fixed on the way
The share card's size is read off the card.
og:image:widthandog:image:heightwere the literals 1200 and 630. They happened to be right, andnothing would have said so if the card were re-rendered at another size: every
page would have gone on announcing the old one with every check green. A build
now refuses a card it cannot read rather than stating a size it guessed, and
refuses a missing card before it renders anything rather than after.
The no-script check now counts what it was named for. It asserted
scripts == 0, which the data block above would end. A script element whosetype is not a script type is a data block: the HTML spec never prepares it, it
never executes, and
script-srchas no say over it, so "static pages, noruntime, nothing for a CSP to have to allow" is unchanged. What replaces the old
count is stricter rather than looser -- it goes red for an inline script, a
src, atype="module"and atype="text/javascript"alike, none of which theold assertion distinguished because none of them could occur. The three places
that stated "no script at all" in prose (
.htmlvalidate.mjs,tools/a11y.mjs,package.json) now say "no executable script" and name the data block, becausea promise quietly narrowed is worse than a promise restated. This is the one
judgement call in the change and it is the thing to disagree with if any part of
it is wrong.
make verifyis green (1253 passed, 96.20% coverage), andnpx html-validateand
node tools/a11y.mjsare clean over the five built pages.Prepared with AI assistance; reviewed before submission.