The public entry point is README.md. The contract version is declared in SPEC.md; filenames remain stable between releases.
examples/ contains eight event fixtures and illustrative Atom/RSS feeds.
generated/ contains derived Schema.org and supported JSCalendar outputs, plus
conversion diagnostics. tools/ and tests/ contain local reference helpers and
regression tests. These are not a deployed authoring website, directory, or app.
The real event names, dates, URLs, prices, and availability came from supplied
example data. They have not been rechecked against live organizer sites. The
fixtures identify Example fixture publisher and use an illustrative revision
instant of 2026-10-29T08:00:00Z. That timestamp describes these example
representations; it does not certify that the source facts are current.
Past events intentionally retain their supplied lifecycle status to test the
distinction between publisher status and a consumer’s past-event classification.
The examples do not demonstrate organizer authorization or HTML discovery on the
real websites. Their Event URLs do not prove those sites support OpenAjang.
Feed Document URLs use example.org placeholders and are not live endpoints.
Use Python 3.11 or newer from the repository root:
python -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements.txt
python tools/openajang.py validate examples/*.openajang.json
python tools/openajang.py generate
python tools/generate_example_feeds.py
python -m unittest discover -s tests -v
Generation validates inputs first. Unsupported calendar conversions are declined
explicitly and recorded in generated/conversion-diagnostics.json. The example
feed generator uses fixed illustrative timestamps for reproducibility; it is not
a live publisher’s timestamp implementation.
The schema uses custom oa-* format annotations that generic schema tools may
ignore. Full document validation needs the bundled format checker and procedural
checks. The validator uses installed ISO code and timezone data plus language-tag
and URI syntax libraries. It does not fetch remote schemas or make network calls.
The bounded HTML discovery helper uses Python’s HTMLParser and explicit <head>
links; it is not a complete HTML5 parser. The refresh-decision helper assumes its
caller has checked source continuity and HTTP behavior. Production services need
integration-tested fetching, conditional requests, redirects, caching, SSRF/DNS
rebinding protection, isolation, moderation, and notification behavior.
schema/event.json at the public HTTPS URL declared in its $id.
The source file has a stable local path; the public URL is versioned. Serve it
as application/schema+json where available. Once published, do not reuse that
identifier for an incompatible contract.application/json or the provisional vendor media type.
Publish fixtures as examples with their provenance notice.The schema’s $id is the runtime source of the supported contract identifier.
The validator loads schema/event.json and derives SCHEMA_URL from it; its Python
source has no separately hardcoded release number.
For a new incompatible contract, update the schema $id, its matching instance
$schema constant, the version declaration in SPEC.md, and the identical schema URL
in documentation examples and event fixtures. Regenerate outputs and rerun tests.
A search for the old full schema URL locates contract references without
modifying unrelated dependency or standards versions.
Keep previously published schema contracts available at their original public URLs. Use repository tags or release archives to preserve historical source snapshots.