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
4 changes: 4 additions & 0 deletions .github/workflows/secret-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@

jobs:
scan:
permissions:
contents: read
pull-requests: write
actions: read
uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@3f34549c03274ec7a74683068f03a492b0fa805f
secrets: inherit

Check warning on line 23 in .github/workflows/secret-scanner.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Only pass required secrets to this workflow.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_standards&issues=AZ-njKZlGn284K-KpeY-&open=AZ-njKZlGn284K-KpeY-&pullRequest=548
121 changes: 121 additions & 0 deletions _shared/assets/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/* SPDX-License-Identifier: MPL-2.0 */
/* Copyright (c) 2025-2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> */
/*
* a2ml.net / k9-svc.net site theme β€” built on the ddraig-ssg AAA base.
* WCAG 2.2 AAA: all text/UI colours contrast-verified >= 7:1 (light + dark),
* focus ring >= 3:1, reduced-motion, reflow, >= 44px targets.
*/

:root {
--bg: #ffffff;
--bg-soft: #f4f5f9;
--bg-code: #eceef5;
--fg: #1a1b26; /* 17.09:1 on --bg */
--fg-muted: #3a3d4d; /* 10.74:1 on --bg */
--link: #3730a3; /* 9.93:1 on --bg */
--link-hover: #1f1b6b;
--border: #5a5e73;
--focus: #3730a3;
--btn-fg: #ffffff; /* on --link (#3730a3) = 9.93:1 */
--radius: 8px;
--maxw: 70rem;
--measure: 40rem;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #0e0f1a;
--bg-soft: #181a2a;
--bg-code: #1c1f33;
--fg: #e6e8f2; /* 15.60:1 */
--fg-muted: #c2c6d8; /* lightened for >=7:1 on --bg-soft */
--link: #b9c2ff; /* 11.09:1 */
--link-hover: #dde2ff;
--border: #8c91ad;
--focus: #b9c2ff;
--btn-fg: #0e0f1a; /* dark text on light --link in dark mode */
}
}

*, *::before, *::after { box-sizing: border-box; }
html { font-size: 100%; -webkit-text-size-adjust: 100%; }
body {
margin: 0;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
font-size: 1.0625rem; line-height: 1.6;
color: var(--fg); background: var(--bg);
overflow-wrap: break-word;
}
.container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: 1.25rem; }

/* Skip link (2.4.1) */
.skip-link { position: absolute; left: -9999px; top: 0; background: var(--link); color: #fff; padding: .75rem 1.25rem; border-radius: 0 0 var(--radius) 0; font-weight: 600; z-index: 100; min-height: 44px; line-height: 1.4; }
.skip-link:focus { left: 0; }

/* Focus (2.4.7/2.4.11/2.4.13) */
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 2px; }
a:focus, button:focus, [tabindex]:focus { outline: 3px solid var(--focus); outline-offset: 2px; }

/* Header / nav */
.site-header { border-bottom: 1px solid var(--border); }
.nav { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; padding-block: .75rem; }
.brand { font-weight: 700; font-size: 1.2rem; color: var(--fg); text-decoration: none; }
.nav-links { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem 1.25rem; margin: 0; padding: 0; }
.nav-links a, .brand { display: inline-flex; align-items: center; min-height: 44px; }

/* Links: underlined (1.4.1) */
a { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: var(--link-hover); }
.brand, .nav-links a, .btn { text-decoration: none; }
.nav-links a:hover, .nav-links a:focus { text-decoration: underline; }

main { display: block; }
.prose { padding-block: 2rem; }
.prose h1 { font-size: 2.25rem; line-height: 1.2; margin: 0 0 1rem; }
.prose h2 { font-size: 1.6rem; line-height: 1.3; margin: 2.25rem 0 .75rem; }
.prose h3 { font-size: 1.25rem; margin: 1.5rem 0 .5rem; }
.prose :is(h1,h2,h3,h4), .prose p, .prose li { max-width: var(--measure); }

/* Lede */
.lede { font-size: 1.3rem; line-height: 1.5; color: var(--fg); max-width: var(--measure); margin: 0 0 1.5rem; }

/* Badges */
.badges { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1rem 0; padding: 0; list-style: none; }
.badge { display: inline-flex; align-items: center; min-height: 1.9rem; padding: .25rem .7rem; border: 1px solid var(--border); border-radius: 999px; font-size: .85rem; color: var(--fg); background: var(--bg-soft); }

/* Buttons (>=44px target, 2.5.5) */
.btn-row { display: flex; flex-wrap: wrap; gap: .75rem; margin: 1.5rem 0; }
.btn { display: inline-flex; align-items: center; min-height: 44px; padding: .6rem 1.15rem; border-radius: var(--radius); font-weight: 600; border: 2px solid var(--link); }
.btn-primary { background: var(--link); color: var(--btn-fg); }
.btn-primary:hover { background: var(--link-hover); border-color: var(--link-hover); color: var(--btn-fg); }
.btn-ghost { background: transparent; color: var(--link); }
.btn-ghost:hover { background: var(--bg-soft); }

/* Cards */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem; margin: 1.5rem 0; }
.card { border: 1px solid var(--border); border-radius: var(--radius); padding: 1.25rem; background: var(--bg-soft); }
.card h3 { margin: 0 0 .5rem; font-size: 1.1rem; }
.card p { margin: 0; color: var(--fg); }

/* Code */
code { background: var(--bg-code); padding: .15em .35em; border-radius: 4px; font-size: .9em; }
pre { background: var(--bg-code); padding: 1rem; border-radius: var(--radius); overflow-x: auto; }
pre code { background: none; padding: 0; }

/* Tables */
.prose table { border-collapse: collapse; width: 100%; max-width: 100%; margin: 1rem 0; }
.prose caption { text-align: left; font-weight: 600; color: var(--fg-muted); padding: .5rem 0; }
.prose th, .prose td { border: 1px solid var(--border); padding: .5rem .75rem; text-align: left; }
.prose th { background: var(--bg-soft); }

blockquote { margin: 1rem 0; padding: .5rem 1rem; border-left: 4px solid var(--link); color: var(--fg); background: var(--bg-soft); }
img { max-width: 100%; height: auto; }
hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
.muted { color: var(--fg-muted); }

.site-footer { border-top: 1px solid var(--border); margin-top: 3rem; padding-block: 1.5rem; color: var(--fg-muted); font-size: .95rem; }
.site-footer a { color: var(--link); }

@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}
@media (max-width: 30rem) { .nav { gap: .5rem; } body { font-size: 1rem; } }
40 changes: 40 additions & 0 deletions _shared/templates/site-default.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<!--
SPDX-License-Identifier: MPL-2.0
Shared site template (ddraig-ssg) β€” WCAG 2.2 AAA-capable.
Variables: title, site (used as brand), description, date, content (content substituted last).
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<meta name="description" content="{{description}}">
<meta name="color-scheme" content="light dark">
<link rel="stylesheet" href="/assets/style.css">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<header class="site-header">
<nav class="container nav" aria-label="Primary">
<a class="brand" href="/">{{brand}}</a>
<ul class="nav-links">
<li><a href="/">Home</a></li>
<li><a href="/spec.html">Spec</a></li>
<li><a href="/start.html">Get started</a></li>
</ul>
</nav>
</header>
<main id="main" class="container" tabindex="-1">
<article class="prose">
{{content}}
</article>
</main>
<footer class="site-footer">
<div class="container">
<p class="muted">&#169; Jonathan D.A. Jewell &middot; Code <a href="https://www.mozilla.org/MPL/2.0/">MPL-2.0</a>, docs <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA-4.0</a> &middot; <a href="/.well-known/security.txt">security.txt</a> &middot; <time>{{date}}</time></p>
</div>
</footer>
</body>
</html>
File renamed without changes.
1 change: 1 addition & 0 deletions a2ml/site/assets/style.css
79 changes: 79 additions & 0 deletions a2ml/site/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
---
title: A2ML
site: A2ML
description: Attested Markup Language β€” a lightweight, Djot-like markup that compiles into a typed, attested core
brand: A2ML
date: 2026-06-22
---

# A2ML β€” Attested Markup Language

<p class="lede">A lightweight, Djot-like markup that compiles into a typed, attested core. Authoring stays simple; structural guarantees switch on when you want them.</p>

<div class="badges">
<span class="badge">Spec v1.1.0</span>
<span class="badge">Typed core</span>
<span class="badge">Progressive strictness</span>
<span class="badge">Byte-for-byte payloads</span>
<span class="badge">MPL-2.0 / CC-BY-SA-4.0</span>
</div>

<div class="btn-row">
<a class="btn btn-primary" href="/start.html">Get started</a>
<a class="btn btn-ghost" href="/spec.html">Read the spec</a>
<a class="btn btn-ghost" href="https://github.com/hyperpolymath/a2ml-ecosystem">GitHub</a>
</div>

## What it does

<div class="cards">
<div class="card">
<h3>Readable surface</h3>
<p>Write a clean, Djot-like format. No ceremony when you don't need it.</p>
</div>
<div class="card">
<h3>Typed, attested core</h3>
<p>Required sections, resolved references and unique IDs β€” verified, not hoped for.</p>
</div>
<div class="card">
<h3>Faithful payloads</h3>
<p>Opaque content is preserved byte-for-byte for reliable embedding.</p>
</div>
<div class="card">
<h3>Portable rendering</h3>
<p>One source, many targets β€” HTML, Markdown and PDF pipelines.</p>
</div>
</div>

## Progressive strictness

A2ML lets you dial guarantees up as a document matures:

| Mode | Guarantee |
|------|-----------|
| **lax** | Parse and render; no structural enforcement. |
| **checked** | Required sections exist, references resolve, IDs are unique. |
| **attested** | Checked, plus a verifiable attestation over the typed core. |

## A taste

```a2ml
# A2ML Overview

@abstract:
A2ML is a typed, attested markup format. It verifies structure and references.
@end

## Claims
- Required sections must exist.
- References must resolve.

@refs:
[1] Attested Markup Language Spec (draft)
@end
```

## Part of the standards estate

A2ML is a satellite of the [Hyperpolymath standards hub](https://github.com/hyperpolymath/standards). The normative specification, conformance vectors and profiles live there; this site is the front door.
29 changes: 29 additions & 0 deletions a2ml/site/public/.well-known/security.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

# Security contact for a2ml.net β€” RFC 9116
# https://a2ml.net/.well-known/security.txt

Contact: mailto:j.d.a.jewell@open.ac.uk
Encryption: openpgp4fpr:4A03639C1EB1F86C7F0C97A91835A14A2867091E
Expires: 2027-06-21T00:00:00Z
Preferred-Languages: en
Canonical: https://a2ml.net/.well-known/security.txt
Policy: https://github.com/hyperpolymath/a2ml-ecosystem/security/policy
Acknowledgments: https://github.com/hyperpolymath/a2ml-ecosystem/security/advisories
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEljlFF1RJblHWtTfK0RkBfr9pWrEFAmo5ozcACgkQ0RkBfr9p
WrH2ORAAvgcBt6nmPx96PfNW6iwOKulGyx5suCH7+vfNZY5Y91U2ONOgiskpA3Oc
HLQ2j79cWv96C50SvWahHGu6xUCovMKPAJYpCeSV973mpsLGuxzOXghfTZw9re5F
E1W3BuuSYCGsb04maxSw8uWZ9H/ik3JJnrvOiXEcxUihJlfJSsxy6ZXZ8WwC+ajO
k90f2yaS/TN9JPgyXwH8WwaNeVh1ZnnWUSdfLVmCvu5aXp+J21EqlJBumO/HCTRe
hh8ojRwr8BGib4jbaAfPRfOZ3VIs1JUx1cJuRGsn3BkqLWuIyIeP9Xw3AVEt4pbv
9G/XYAz0MULTxqA7pJUtMwF91KOlZ24DtB0yxKjcXev8L/1vW7EU0pBsO140Kqhq
ULpPos0LpO/bGgeOBSQr164XTNFcWrEBmLjN1Qyi7ZqdMqTU2cNyM+3KFyPiPfnM
7cW7H7R8xhr/RTzN8zz0eJnOFmX3rVSy854CUW/kmTBU/5GhFFBP7YqB2QBACqqW
g+DpKobebYdL+B1jokzu4umhLd37hssojOcm0RuS13Fz3JSkvYpDKKHEjTTUO/lY
k8EuilmGKWFXNwwDhwLzrx307N+9gqoDwTKBkuOx8lj5IwjJXZvO1R6pWrIR8quF
7It/9vKqNo0O2xoebNsDM5DAn2zCtViftOieM2Tjk+gtLuxQ5yo=
=vBOZ
-----END PGP SIGNATURE-----
1 change: 1 addition & 0 deletions a2ml/site/public/CNAME
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a2ml.net
10 changes: 10 additions & 0 deletions a2ml/site/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions a2ml/site/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
User-agent: *
Allow: /

Sitemap: https://a2ml.net/sitemap.xml
34 changes: 34 additions & 0 deletions a2ml/site/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
---
title: A2ML specification
site: A2ML
description: A2ML v1.1.0 normative specification β€” Surface Grammar + Typed Core + Profiles
brand: A2ML
date: 2026-06-22
---

# Specification

The current normative specification is **A2ML v1.1.0** β€” Surface Grammar + Typed Core + Profiles.

## Documents

- **Spec (normative, v1.1.0)** β€” surface grammar, typed core, profiles
- **Specification lineage** β€” versions and era
- **Module 0 quickstart + FAQ**
- **Syntax modules** (opt-in)
- **Grammar appendix**
- **Conformance + test vectors**
- **IANA media type draft** β€” `application/a2ml`
- **Comparison matrix**
- **Citation guide**

All specification documents are maintained in the [standards](https://github.com/hyperpolymath/standards) repository under `a2ml/`. This page links the front door; the repository is the source of truth.

## Profiles

Profiles layer domain-specific validation on top of the base vocabulary. A2ML v1.1 introduced profiles, an expanded base vocabulary, citation support and content hashing.

## Conformance

Conformance is defined by published test vectors (positive and negative fixtures). Implementations validate against these to claim a given strictness level.
42 changes: 42 additions & 0 deletions a2ml/site/start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
---
title: Get started with A2ML
site: A2ML
description: Learn how to write, validate, and render A2ML documents with progressive strictness modes
brand: A2ML
date: 2026-06-22
---

# Get started

A2ML is authored as plain text and validated in progressive modes. Start lax, tighten to checked, attest when ready.

## 1. Write a document

```a2ml
# Release Notes

@abstract:
What changed in this release, in one paragraph.
@end

## Changes
- Added profiles for domain validation.
- Resolved all cross-references.

@refs:
[1] A2ML Spec v1.1.0
@end
```

## 2. Validate

Run the validator over your document. In **checked** mode it confirms that required sections exist, references resolve, and IDs are unique. In **attested** mode it additionally produces a verifiable attestation over the typed core.

## 3. Render

The typed core is renderer-portable: emit HTML, Markdown or feed a PDF pipeline from a single source, with opaque payloads preserved byte-for-byte.

## Tooling

Implementations, editor support and CI actions are coordinated in the [a2ml-ecosystem](https://github.com/hyperpolymath/a2ml-ecosystem) hub. The normative spec and conformance vectors live in [standards](https://github.com/hyperpolymath/standards).
1 change: 1 addition & 0 deletions a2ml/site/templates/default.html
Loading