@aruzone/aze-forge 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -0
  3. package/dist/acceptance.d.ts +48 -0
  4. package/dist/acceptance.js +180 -0
  5. package/dist/acceptance.js.map +1 -0
  6. package/dist/assets.d.ts +19 -0
  7. package/dist/assets.js +509 -0
  8. package/dist/assets.js.map +1 -0
  9. package/dist/atomic-write.d.ts +1 -0
  10. package/dist/atomic-write.js +23 -0
  11. package/dist/atomic-write.js.map +1 -0
  12. package/dist/callout.d.ts +27 -0
  13. package/dist/callout.js +78 -0
  14. package/dist/callout.js.map +1 -0
  15. package/dist/capabilities-json.d.ts +4 -0
  16. package/dist/capabilities-json.js +225 -0
  17. package/dist/capabilities-json.js.map +1 -0
  18. package/dist/capabilities.d.ts +110 -0
  19. package/dist/capabilities.js +270 -0
  20. package/dist/capabilities.js.map +1 -0
  21. package/dist/cli.d.ts +2 -0
  22. package/dist/cli.js +1096 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/compiler.d.ts +3 -0
  25. package/dist/compiler.js +1034 -0
  26. package/dist/compiler.js.map +1 -0
  27. package/dist/configuration-error.d.ts +4 -0
  28. package/dist/configuration-error.js +9 -0
  29. package/dist/configuration-error.js.map +1 -0
  30. package/dist/diagnostics-json.d.ts +23 -0
  31. package/dist/diagnostics-json.js +143 -0
  32. package/dist/diagnostics-json.js.map +1 -0
  33. package/dist/diagnostics.d.ts +16 -0
  34. package/dist/diagnostics.js +154 -0
  35. package/dist/diagnostics.js.map +1 -0
  36. package/dist/equation.d.ts +74 -0
  37. package/dist/equation.js +485 -0
  38. package/dist/equation.js.map +1 -0
  39. package/dist/font.d.ts +19 -0
  40. package/dist/font.js +75 -0
  41. package/dist/font.js.map +1 -0
  42. package/dist/format.d.ts +2 -0
  43. package/dist/format.js +308 -0
  44. package/dist/format.js.map +1 -0
  45. package/dist/hash.d.ts +5 -0
  46. package/dist/hash.js +189 -0
  47. package/dist/hash.js.map +1 -0
  48. package/dist/help.d.ts +9 -0
  49. package/dist/help.js +102 -0
  50. package/dist/help.js.map +1 -0
  51. package/dist/html-fragment.d.ts +7 -0
  52. package/dist/html-fragment.js +70 -0
  53. package/dist/html-fragment.js.map +1 -0
  54. package/dist/index.d.ts +39 -0
  55. package/dist/index.js +32 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/markdown.d.ts +14 -0
  58. package/dist/markdown.js +425 -0
  59. package/dist/markdown.js.map +1 -0
  60. package/dist/mermaid-browser.d.ts +43 -0
  61. package/dist/mermaid-browser.js +358 -0
  62. package/dist/mermaid-browser.js.map +1 -0
  63. package/dist/mermaid.d.ts +84 -0
  64. package/dist/mermaid.js +740 -0
  65. package/dist/mermaid.js.map +1 -0
  66. package/dist/model.d.ts +406 -0
  67. package/dist/model.js +2 -0
  68. package/dist/model.js.map +1 -0
  69. package/dist/parse.d.ts +3 -0
  70. package/dist/parse.js +1374 -0
  71. package/dist/parse.js.map +1 -0
  72. package/dist/preview-server.d.ts +39 -0
  73. package/dist/preview-server.js +156 -0
  74. package/dist/preview-server.js.map +1 -0
  75. package/dist/preview-shell.d.ts +29 -0
  76. package/dist/preview-shell.js +102 -0
  77. package/dist/preview-shell.js.map +1 -0
  78. package/dist/reference-validation.d.ts +7 -0
  79. package/dist/reference-validation.js +42 -0
  80. package/dist/reference-validation.js.map +1 -0
  81. package/dist/registry.d.ts +29 -0
  82. package/dist/registry.js +384 -0
  83. package/dist/registry.js.map +1 -0
  84. package/dist/render-html.d.ts +24 -0
  85. package/dist/render-html.js +149 -0
  86. package/dist/render-html.js.map +1 -0
  87. package/dist/render-pdf.d.ts +64 -0
  88. package/dist/render-pdf.js +503 -0
  89. package/dist/render-pdf.js.map +1 -0
  90. package/dist/render-png.d.ts +32 -0
  91. package/dist/render-png.js +427 -0
  92. package/dist/render-png.js.map +1 -0
  93. package/dist/render-svg.d.ts +23 -0
  94. package/dist/render-svg.js +243 -0
  95. package/dist/render-svg.js.map +1 -0
  96. package/dist/runtime-support.d.ts +26 -0
  97. package/dist/runtime-support.js +62 -0
  98. package/dist/runtime-support.js.map +1 -0
  99. package/dist/source-map.d.ts +12 -0
  100. package/dist/source-map.js +75 -0
  101. package/dist/source-map.js.map +1 -0
  102. package/dist/table.d.ts +22 -0
  103. package/dist/table.js +90 -0
  104. package/dist/table.js.map +1 -0
  105. package/dist/theme.d.ts +6 -0
  106. package/dist/theme.js +89 -0
  107. package/dist/theme.js.map +1 -0
  108. package/dist/tool-version.d.ts +3 -0
  109. package/dist/tool-version.js +3 -0
  110. package/dist/tool-version.js.map +1 -0
  111. package/dist/type-guards.d.ts +1 -0
  112. package/dist/type-guards.js +4 -0
  113. package/dist/type-guards.js.map +1 -0
  114. package/dist/validate-document.d.ts +2 -0
  115. package/dist/validate-document.js +248 -0
  116. package/dist/validate-document.js.map +1 -0
  117. package/dist/version.d.ts +37 -0
  118. package/dist/version.js +111 -0
  119. package/dist/version.js.map +1 -0
  120. package/dist/watch-dependencies.d.ts +15 -0
  121. package/dist/watch-dependencies.js +93 -0
  122. package/dist/watch-dependencies.js.map +1 -0
  123. package/dist/watch-events.d.ts +51 -0
  124. package/dist/watch-events.js +27 -0
  125. package/dist/watch-events.js.map +1 -0
  126. package/dist/watch-loop.d.ts +39 -0
  127. package/dist/watch-loop.js +117 -0
  128. package/dist/watch-loop.js.map +1 -0
  129. package/package.json +70 -0
  130. package/schemas/acceptance.json +104 -0
  131. package/schemas/capabilities.json +491 -0
  132. package/schemas/diagnostics.json +219 -0
  133. package/schemas/version.json +167 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 aruzone
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,408 @@
1
+ # AzeForge
2
+
3
+ AzeForge compiles AzeMark into deterministic, self-contained HTML and continuous-layout SVG Artifacts.
4
+
5
+ ## Supported syntax
6
+
7
+ - AzeMark v1 YAML front matter
8
+ - ATX headings such as `# Heading`
9
+ - Setext headings
10
+ - paragraphs
11
+ - plain inline text
12
+ - equation directive Blocks (readable aliases plus trusted-local raw LaTeX)
13
+
14
+ Readable equation example:
15
+
16
+ ```text
17
+ :::: equation
18
+ id: euler
19
+ number: true
20
+ align: center
21
+
22
+ F(omega) =
23
+ integral t=-infinity..infinity of
24
+ f(t) exp(-i omega t) dt
25
+ ::::
26
+ ```
27
+
28
+ Header attributes are `id`, `number: true|false`, `align: left|center|right`,
29
+ and `syntax: readable|latex` (default `readable`). Readable aliases cover
30
+ Greek letters, `sqrt`/`frac`/`root`, `sum`/`product`, `integral`, `limit`,
31
+ derivatives, `matrix`, `cases`, and relations/sets; they render through
32
+ pinned KaTeX (`0.18.5`, offline `htmlAndMathml`, `trust: false`, bounded,
33
+ sanitized). Raw LaTeX is denied by default with
34
+ `azeforge.security#raw-latex-disabled` and renders only with
35
+ `--allow-raw-latex` on `validate` or `render`:
36
+
37
+ ```text
38
+ :::: equation
39
+ syntax: latex
40
+
41
+ \frac{a}{b}
42
+ ::::
43
+ ```
44
+
45
+ Directive envelopes are recovered as `InvalidBlock` values until Plugins are registered. Raw HTML is denied and never rendered as text or markup. Lists, Mermaid, images, and other Markdown constructs are not implemented yet.
46
+
47
+ ## Install
48
+
49
+ Consumers install the published package; no repo checkout is needed:
50
+
51
+ ```bash
52
+ npm install -g @aruzone/aze-forge
53
+ azeforge --help
54
+ ```
55
+
56
+ Prerequisites: Node.js 22 or 24, on Ubuntu or macOS.
57
+ Windows support is parked until platform-specific verification lands (see issue #43).
58
+ There is no standalone binary: the npm global install is the distribution
59
+ path, so the Node prerequisite always applies. A single-file binary would
60
+ have to bundle Node plus the pinned browser engine and fonts below, and is
61
+ deferred; users re-install for new versions (no auto-update).
62
+
63
+ The install downloads the pinned browser engine (Chrome Headless Shell
64
+ `152.0.7977.75` into `~/.cache/puppeteer`) via the `puppeteer` postinstall
65
+ script, so the installing machine needs network access once. Verify it with
66
+ a browser-backed format:
67
+
68
+ ```bash
69
+ azeforge capabilities --probe --json
70
+ azeforge render /tmp/manual.aze.md --output /tmp/manual.svg
71
+ ```
72
+
73
+ Offline or browser-missing installs stay structured: browser-backed formats
74
+ (`svg`, `png`, `pdf`, Mermaid diagrams) fail with exit `1` and a
75
+ `azeforge.renderer#browser-unavailable` (or `adapter-missing`) diagnostic
76
+ suggesting `Reinstall AzeForge browser dependencies and retry`, never a
77
+ stack trace. Plain-HTML rendering without diagrams keeps working. Remedy:
78
+ re-install with network access, or fetch only the engine with
79
+ `npx puppeteer browsers install chrome-headless-shell@152.0.7977.75`.
80
+
81
+ The acceptance gate runs identically against the consumer install by
82
+ pointing the runner at the `azeforge` on `PATH`:
83
+
84
+ ```bash
85
+ AZEFORGE_CLI=azeforge node scripts/acceptance.mjs
86
+ ```
87
+
88
+ (from a checkout; the runner itself ships in the repo, the CLI under test
89
+ is the installed one).
90
+
91
+ Uninstall:
92
+
93
+ ```bash
94
+ npm uninstall -g @aruzone/aze-forge
95
+ # optional: remove the downloaded browser engine
96
+ rm -rf ~/.cache/puppeteer
97
+ ```
98
+
99
+ ## Build
100
+
101
+ The project requires Node.js 22 or newer.
102
+
103
+ Supported releases run on Node.js 22 and 24 (Ubuntu, macOS);
104
+ Windows support is parked until platform-specific verification lands (see issue #43).
105
+ Canonical HTML/SVG/PNG/PDF golden and visual evidence is built on pinned
106
+ Ubuntu x64 with Node 24. `azeforge capabilities --json` reports the exact
107
+ support matrix under `runtime`.
108
+
109
+ ```bash
110
+ npm install
111
+ npm run build
112
+ ```
113
+
114
+ The examples below invoke the built CLI directly:
115
+
116
+ ```bash
117
+ node dist/cli.js
118
+ ```
119
+ ## Create a Source file
120
+
121
+ ```bash
122
+ cat >/tmp/manual.aze.md <<'EOF'
123
+ ---
124
+ azemark: 1
125
+ title: Manual AzeForge test
126
+ author:
127
+ - Test Author
128
+ theme: default
129
+ outputs:
130
+ - html
131
+ ---
132
+
133
+ # Introduction
134
+
135
+ This document tests the current compiler.
136
+
137
+ Results
138
+ -------
139
+
140
+ The render is deterministic.
141
+ EOF
142
+ ```
143
+
144
+ ## Validate
145
+
146
+ ```bash
147
+ node dist/cli.js validate /tmp/manual.aze.md
148
+ echo $?
149
+ ```
150
+
151
+ A valid Source produces no stdout or stderr and exits with status `0`.
152
+
153
+ Add `--diagnostics json` to `validate` or file-targeted `render` to emit exactly one `azeforge.diagnostics/v1` report on stdout. The package exports `diagnosticsJsonSchema` for JSON Schema 2020-12 validation. Human diagnostics remain on stderr.
154
+
155
+ ## Format Source
156
+
157
+ ```bash
158
+ # Write LF-formatted UTF-8 Source to stdout.
159
+ node dist/cli.js format /tmp/manual.aze.md
160
+
161
+ # Atomically replace a file.
162
+ node dist/cli.js format /tmp/manual.aze.md --write
163
+
164
+ # Emit no Source; exit 1 only when formatting is required.
165
+ node dist/cli.js format /tmp/manual.aze.md --check
166
+
167
+ # Stdin is explicit; `-` is not an alias.
168
+ cat /tmp/manual.aze.md | node dist/cli.js format --stdin
169
+ ```
170
+
171
+ Formatting removes a leading BOM, emits LF line endings, preserves comments,
172
+ unknown directive bodies, invalid regions, and denied raw content, and writes
173
+ nothing when structural syntax is ambiguous. `--write` rejects stdin, and
174
+ `--write` and `--check` cannot be combined.
175
+
176
+ ## Render to a file
177
+
178
+ ```bash
179
+ node dist/cli.js render \
180
+ /tmp/manual.aze.md \
181
+ --output /tmp/manual.html
182
+
183
+ echo $?
184
+ open /tmp/manual.html
185
+ ```
186
+
187
+ A successful render exits with status `0` and atomically replaces `/tmp/manual.html`.
188
+
189
+ Use an `.svg` destination or pass `--format svg` to produce SVG2 with an
190
+ XHTML `foreignObject`. The SVG records its required `svg2` and
191
+ `xhtml-foreign-object` capabilities in Artifact metadata; it does not emit a
192
+ fallback format.
193
+
194
+ ```bash
195
+ node dist/cli.js render \
196
+ /tmp/manual.aze.md \
197
+ --output /tmp/manual.svg
198
+ ```
199
+
200
+ Check that the Artifact embeds its fonts and contains no scripts:
201
+
202
+ ```bash
203
+ grep -o 'data:font/woff2;base64' /tmp/manual.html | sort -u
204
+ grep -i '<script' /tmp/manual.html
205
+ ```
206
+
207
+ The first command prints `data:font/woff2;base64`. The second prints nothing.
208
+
209
+ ## Render to stdout
210
+
211
+ ```bash
212
+ node dist/cli.js render \
213
+ /tmp/manual.aze.md \
214
+ --stdout \
215
+ --format html \
216
+ >/tmp/manual-stdout.html
217
+
218
+ cmp /tmp/manual.html /tmp/manual-stdout.html
219
+ echo $?
220
+ ```
221
+
222
+ `cmp` produces no output and exits with status `0`.
223
+
224
+ ## Watch a Source
225
+
226
+ ```bash
227
+ node dist/cli.js watch \
228
+ /tmp/manual.aze.md \
229
+ --output /tmp/manual.html
230
+ ```
231
+
232
+ `watch` compiles immediately, then fully recompiles after coalesced changes to
233
+ the Source or its project images. Compiles are serialized; a failed cycle
234
+ preserves the last successful Artifact and keeps watching. Add
235
+ `--diagnostics json` to stream `azeforge.event/v1` NDJSON records on stdout
236
+ instead of human diagnostics on stderr.
237
+
238
+ ## Serve a preview
239
+
240
+ ```bash
241
+ node dist/cli.js serve /tmp/manual.aze.md --port 0
242
+ # serve: listening on http://127.0.0.1:62545/ for /tmp/manual.aze.md
243
+ ```
244
+
245
+ `serve` binds only loopback (ephemeral port by default) and shows the current
246
+ HTML preview or the current diagnostics, never stale content. The preview
247
+ wraps the exact Artifact bytes in an unhashable reload shell; only preview,
248
+ SSE, and opaque asset routes exist. Stop with `SIGINT` or `SIGTERM`.
249
+
250
+ ## Check deterministic output
251
+
252
+ ```bash
253
+ cp /tmp/manual.html /tmp/manual-first.html
254
+
255
+ node dist/cli.js render \
256
+ /tmp/manual.aze.md \
257
+ --output /tmp/manual.html
258
+
259
+ cmp /tmp/manual-first.html /tmp/manual.html
260
+ shasum -a 256 /tmp/manual-first.html /tmp/manual.html
261
+ ```
262
+
263
+ The files must be byte-identical and have the same SHA-256 value.
264
+
265
+ The HTML also records the semantic content hash:
266
+
267
+ ```bash
268
+ grep -o 'name="azeforge-content-hash" content="sha256:[^"]*"' \
269
+ /tmp/manual.html
270
+ ```
271
+
272
+ ## Check failure handling
273
+
274
+ ```bash
275
+ cat >/tmp/invalid.aze.md <<'EOF'
276
+ ---
277
+ azemark: 2
278
+ ---
279
+
280
+ This version is unsupported.
281
+ EOF
282
+
283
+ printf 'previous successful Artifact' >/tmp/preserved.html
284
+
285
+ node dist/cli.js render \
286
+ /tmp/invalid.aze.md \
287
+ --output /tmp/preserved.html
288
+
289
+ echo "exit: $?"
290
+ cat /tmp/preserved.html
291
+ ```
292
+
293
+ The command reports `azeforge.source#version-unsupported`, exits with status `1`, and leaves the previous Artifact unchanged.
294
+
295
+ CLI exit statuses:
296
+
297
+ - `0`: the operation succeeded, including warning-only validation
298
+ - `1`: an accepted operation failed on Source or component diagnostics
299
+ - `2`: arguments or options could not form an operation
300
+
301
+ ## Test invalid Source recovery
302
+
303
+ Exercise the recovery seam with malformed UTF-8, malformed front matter, duplicate IDs, unknown directives, raw HTML, CRLF, and multi-error Source:
304
+
305
+ ```bash
306
+ node dist/cli.js validate /tmp/bad.aze.md; echo "exit=$?"
307
+ node dist/cli.js validate /tmp/bad.aze.md --diagnostics json > /tmp/report.json; echo "exit=$?"
308
+ node dist/cli.js render /tmp/bad.aze.md --output /tmp/bad.html --diagnostics json; echo "exit=$?"
309
+ ```
310
+
311
+ Exit `2` is reserved for malformed operations (bad flags or arguments). Exit `1` means an accepted operation failed on Source or component diagnostics. Exit `0` with no stdout or stderr means a valid Source.
312
+
313
+ Confirm the JSON report is the single finite `azeforge.diagnostics/v1` document on stdout while human diagnostics stay on stderr, and validate it against the exported `diagnosticsJsonSchema` (JSON Schema 2020-12):
314
+
315
+ ```bash
316
+ node dist/cli.js render /tmp/bad.aze.md --output /tmp/bad.html --diagnostics json 2>/tmp/stderr.txt | tee /tmp/report.json
317
+ test ! -s /tmp/stderr.txt && echo "stderr clean in json mode"
318
+ ```
319
+
320
+ Confirm a failed render never commits an Artifact by pre-seeding the destination:
321
+
322
+ ```bash
323
+ echo "last successful Artifact" > /tmp/out.html
324
+ node dist/cli.js render /tmp/bad.aze.md --output /tmp/out.html; echo "exit=$?"
325
+ grep -qx "last successful Artifact" /tmp/out.html && echo "artifact preserved"
326
+ ```
327
+
328
+ Probe raw HTML denial, which must report `azeforge.security#raw-html-disabled`, exit `1`, and never render the markup:
329
+
330
+ ```bash
331
+ printf -- '---\nazemark: 1\n---\n\nBefore\n\n<div>\n\nAfter\n' > /tmp/html.aze.md
332
+ node dist/cli.js render /tmp/html.aze.md --output /tmp/html.html --diagnostics json
333
+ grep -i '<script\|<div' /tmp/html.html || echo "no raw html rendered"
334
+ ```
335
+
336
+ Repeat the probes with CRLF line endings and a BOM prefix; diagnostic ranges, columns, and offsets must still line up in the JSON report.
337
+
338
+ ## Automated checks
339
+
340
+ ```bash
341
+ npm run typecheck
342
+ npm test
343
+ ```
344
+
345
+ `npm test` rebuilds `dist/` and runs the full suite (`test/*.test.mjs`).
346
+ Bare `node --test` reuses the last build, so rebuild after editing `src/`.
347
+ Target one layer while working:
348
+
349
+ ```bash
350
+ npm run build
351
+ npm run test:compiler
352
+ npm run test:cli
353
+ npm run test:matrix
354
+ npm run test:browser-smoke
355
+ npm run test:canonical-suite
356
+ npm run test:canonical
357
+ node --test test/equation.test.mjs
358
+ ```
359
+
360
+ `test:matrix` is the browser-independent unit, schema, and installed-CLI
361
+ compatibility seam. `test:browser-smoke` invokes the packaged pinned engine.
362
+ `test:canonical-suite` and `test:canonical` own Golden report and visual
363
+ evidence and are authoritative only on Ubuntu 24.04 x64 with Node 24.
364
+
365
+ `test/equation.test.mjs` is the equation seam: versioned Blocks, alias
366
+ coverage, ranged diagnostics, raw-LaTeX policy, adapter failure modes,
367
+ registry rejection, descriptor conformance, and real CLI calls.
368
+
369
+ Probe equations by hand:
370
+
371
+ ```bash
372
+ cat >/tmp/eq.aze.md <<'EOF'
373
+ ---
374
+ azemark: 1
375
+ title: Equation check
376
+ ---
377
+
378
+ :::: equation
379
+ id: euler
380
+
381
+ F(omega) = integral x=0..infinity of x^2 dx
382
+ ::::
383
+ EOF
384
+
385
+ node dist/cli.js validate /tmp/eq.aze.md && echo VALID
386
+ node dist/cli.js render /tmp/eq.aze.md --output /tmp/eq.html
387
+ grep -o 'class="katex"\|<math\|<annotation' /tmp/eq.html | sort | uniq -c
388
+ ```
389
+
390
+ Probe the raw-LaTeX gate (denied by default, trusted-local opt-in):
391
+
392
+ ```bash
393
+ cat >/tmp/raw.aze.md <<'EOF'
394
+ ---
395
+ azemark: 1
396
+ ---
397
+
398
+ :::: equation
399
+ syntax: latex
400
+
401
+ \frac{a}{b}
402
+ ::::
403
+ EOF
404
+
405
+ node dist/cli.js validate /tmp/raw.aze.md; echo "exit=$? (expect 1)"
406
+ node dist/cli.js validate /tmp/raw.aze.md --allow-raw-latex && echo ALLOWED
407
+ node dist/cli.js render /tmp/raw.aze.md --output /tmp/raw.html --allow-raw-latex
408
+ ```
@@ -0,0 +1,48 @@
1
+ import type { JsonValue } from "./model.js";
2
+ export declare const ACCEPTANCE_SCHEMA_ID: "azeforge.acceptance/v1";
3
+ export declare const ACCEPTANCE_SCHEMA_VERSION: 1;
4
+ export declare const ACCEPTANCE_CATALOG_ID: "azeforge.acceptance/v1";
5
+ export declare const ACCEPTANCE_CATALOG_VERSION: 1;
6
+ export type AcceptanceGate = "p0" | "p0.5";
7
+ export type AcceptanceEvidence = "automated" | "manual";
8
+ export interface AcceptanceEntry {
9
+ readonly id: string;
10
+ readonly gate: AcceptanceGate;
11
+ readonly area: string;
12
+ readonly given: string;
13
+ readonly when: string;
14
+ readonly then: readonly string[];
15
+ readonly evidence: AcceptanceEvidence;
16
+ readonly required: boolean;
17
+ readonly contracts: readonly string[];
18
+ }
19
+ /**
20
+ * Normative P0 release inventory from the golden-report acceptance gate.
21
+ * P0.5 entries are required for their own gate only; a P0.5 failure never
22
+ * delays or invalidates P0.
23
+ */
24
+ export declare const ACCEPTANCE_ENTRIES: readonly AcceptanceEntry[];
25
+ export declare const REQUIRED_P0_IDS: readonly string[];
26
+ export declare const AUTOMATED_P0_IDS: readonly string[];
27
+ /**
28
+ * Coverage gate: every required automated P0 entry needs declared evidence,
29
+ * and no declaration may name an unknown ID.
30
+ */
31
+ export declare function checkAcceptanceCoverage(declaredIds: readonly string[]): {
32
+ readonly missing: readonly string[];
33
+ readonly unknown: readonly string[];
34
+ };
35
+ export declare const acceptanceJsonSchema: JsonValue;
36
+ export interface AcceptanceCatalogDocument {
37
+ readonly schema: typeof ACCEPTANCE_SCHEMA_ID;
38
+ readonly schemaVersion: typeof ACCEPTANCE_SCHEMA_VERSION;
39
+ readonly catalog: Readonly<{
40
+ id: typeof ACCEPTANCE_CATALOG_ID;
41
+ version: typeof ACCEPTANCE_CATALOG_VERSION;
42
+ }>;
43
+ readonly entries: readonly AcceptanceEntry[];
44
+ }
45
+ /**
46
+ * Canonical catalog document with logical identity azeforge.acceptance/v1.
47
+ */
48
+ export declare function createAcceptanceCatalog(): AcceptanceCatalogDocument;
@@ -0,0 +1,180 @@
1
+ export const ACCEPTANCE_SCHEMA_ID = "azeforge.acceptance/v1";
2
+ export const ACCEPTANCE_SCHEMA_VERSION = 1;
3
+ export const ACCEPTANCE_CATALOG_ID = "azeforge.acceptance/v1";
4
+ export const ACCEPTANCE_CATALOG_VERSION = 1;
5
+ function acceptanceEntry(id, gate, area, given, when, then, evidence, contracts) {
6
+ return { id, gate, area, given, when, then, evidence, required: true, contracts };
7
+ }
8
+ /**
9
+ * Normative P0 release inventory from the golden-report acceptance gate.
10
+ * P0.5 entries are required for their own gate only; a P0.5 failure never
11
+ * delays or invalidates P0.
12
+ */
13
+ export const ACCEPTANCE_ENTRIES = Object.freeze([
14
+ acceptanceEntry("P0-DOC-001", "p0", "document", "Valid Engineering-notation Source", "the compiler parses and validates it", ["an error-free versioned serializable Document is produced"], "automated", ["#6"]),
15
+ acceptanceEntry("P0-DOC-002", "p0", "document", "Source with invalid regions", "the compiler parses it", [
16
+ "valid regions recover into the Document",
17
+ "errors prevent AzeDocument and Artifact production",
18
+ ], "automated", ["#6"]),
19
+ acceptanceEntry("P0-DOC-003", "p0", "document", "Source with metadata, version, or unknown-directive failures", "the compiler reports Diagnostics", ["each Diagnostic carries the correct SourceRange and lists alternatives"], "automated", ["#6", "#9"]),
20
+ acceptanceEntry("P0-DOC-004", "p0", "document", "Two Sources differing only in trivia, paths, diagnostics, ranges, or render options", "both Documents are hashed", ["both contentHashes are equal"], "automated", ["#6", "ADR 0002"]),
21
+ acceptanceEntry("P0-DIAG-001", "p0", "diagnostics", "A failing compilation", "an author reads the human Diagnostic report", ["every Diagnostic is line-specific and author-facing"], "automated", ["#9"]),
22
+ acceptanceEntry("P0-DIAG-002", "p0", "diagnostics", "A failing compilation", "a tool reads the JSON Diagnostic report", ["stable code, data, range, order, and fix semantics are preserved"], "automated", ["#9"]),
23
+ acceptanceEntry("P0-DIAG-003", "p0", "diagnostics", "Malformed input or a component fault", "the compiler handles it", ["the fault is bounded, redacted, and contained without crashing"], "automated", ["#9"]),
24
+ acceptanceEntry("P0-PLUGIN-001", "p0", "plugin", "The built-in registry, schemas, versions, and capabilities", "they are constructed", [
25
+ "construction is deterministic",
26
+ "ambiguous registrations are rejected with a stable error",
27
+ ], "automated", ["#7"]),
28
+ acceptanceEntry("P0-PLUGIN-002", "p0", "plugin", "A Plugin, Block renderer, or Renderer fault", "the fault fires mid-render", [
29
+ "partial Artifacts are discarded",
30
+ "ordered Diagnostics are preserved",
31
+ ], "automated", ["#7"]),
32
+ acceptanceEntry("P0-CLI-001", "p0", "cli", "A Source render", "it succeeds or fails", [
33
+ "success atomically commits exactly one requested Artifact",
34
+ "failure preserves the prior Artifact",
35
+ ], "automated", ["#8"]),
36
+ acceptanceEntry("P0-CLI-002", "p0", "cli", "Stdin, stdout, format, and destination modes", "they are exercised", ["behavior matches the CLI contract including binary-terminal denial"], "automated", ["#8"]),
37
+ acceptanceEntry("P0-CLI-003", "p0", "cli", "Validate and format commands", "they run", ["each executes only its specified layers and write modes"], "automated", ["#8"]),
38
+ acceptanceEntry("P0-CLI-004", "p0", "cli", "A watched Source with discovered and missing dependencies", "it changes and breaks", [
39
+ "rebuilds serialize",
40
+ "failure preserves the prior Artifact",
41
+ ], "automated", ["#8"]),
42
+ acceptanceEntry("P0-CLI-005", "p0", "cli", "A served Source", "it is previewed", [
43
+ "the server is loopback-only and constrained",
44
+ "it exposes current Diagnostics rather than stale content",
45
+ ], "automated", ["#8"]),
46
+ acceptanceEntry("P0-CLI-006", "p0", "cli", "Every CLI command", "it exits", [
47
+ "exit codes, stdout purity, finite JSON, NDJSON lifecycle, quiet mode, and signal cleanup match the CLI contract",
48
+ ], "automated", ["#8"]),
49
+ acceptanceEntry("P0-CLI-007", "p0", "cli", "Capability and version reports", "they are requested", ["they are complete, deterministic, local-only, and truthful"], "automated", ["#8"]),
50
+ acceptanceEntry("P0-EQN-001", "p0", "equation", "Readable equation Blocks", "they render", ["HTML carries visual plus MathML pairs and visual Artifacts stay consistent"], "automated", ["#7"]),
51
+ acceptanceEntry("P0-EQN-002", "p0", "equation", "Invalid equations and raw LaTeX", "they are compiled", [
52
+ "invalid equations diagnose precisely",
53
+ "raw LaTeX is denied by default and bounded when explicitly trusted",
54
+ ], "automated", ["#7", "#9"]),
55
+ acceptanceEntry("P0-MMD-001", "p0", "mermaid", "A Mermaid Block", "it renders offline", [
56
+ "the SVG is deterministic, sanitized, and accessible",
57
+ "active or invalid content fails safely",
58
+ ], "automated", ["#7", "#9"]),
59
+ acceptanceEntry("P0-OUT-001", "p0", "artifact", "The Golden report under all three Themes", "it renders to HTML, SVG, PNG, and PDF", ["every semantic object is present with format-appropriate proof"], "automated", ["#10", "#12"]),
60
+ acceptanceEntry("P0-OUT-002", "p0", "artifact", "Every rendered Artifact", "its bytes and manifest are inspected", ["it is self-contained, profile/MIME/geometry-correct, and truthfully hashed"], "automated", ["#10", "ADR 0002"]),
61
+ acceptanceEntry("P0-OUT-003", "p0", "artifact", "Pagination boundary fixtures", "they render to PDF", ["every keep, split, scaling, and oversize-error rule holds"], "automated", ["#10"]),
62
+ acceptanceEntry("P0-OUT-004", "p0", "artifact", "Reference fixtures compiled twice in fresh directories under one fingerprint", "both builds are compared", [
63
+ "contentHash, assetManifestHash, renderer fingerprint, Artifact bytes, and artifactHash are equal",
64
+ "trivia and path moves preserve identity while semantic, Theme, asset, and dependency changes invalidate only the specified identities",
65
+ ], "automated", ["#10", "ADR 0002"]),
66
+ acceptanceEntry("P0-OUT-005", "p0", "artifact", "A missing browser or format adapter", "an affected format is requested", [
67
+ "a structured remedy is reported",
68
+ "unaffected formats remain usable",
69
+ ], "automated", ["#10"]),
70
+ acceptanceEntry("P0-SEC-001", "p0", "security", "Traversal and symlink escapes", "they are attempted", ["the root confinement rejects them without leaking host paths"], "automated", ["#9"]),
71
+ acceptanceEntry("P0-SEC-002", "p0", "security", "An offline compilation", "its requests are observed", ["no non-loopback request or external name resolution occurs"], "automated", ["#9"]),
72
+ acceptanceEntry("P0-SEC-003", "p0", "security", "Raw or embedded active content, unsafe protocols, malformed assets, and unsafe sanitizer rewrites", "they are compiled", ["each is rejected"], "automated", ["#9"]),
73
+ acceptanceEntry("P0-SEC-004", "p0", "security", "Capability, time, memory, Diagnostic, asset, temp, and Artifact bounds", "a bound is exceeded", ["compilation fails closed without partial Artifacts"], "automated", ["#9"]),
74
+ acceptanceEntry("P0-COMPAT-001", "p0", "compatibility", "Supported Node and OS combinations", "the suite runs", ["all pass and system fonts, locales, and timezones do not alter Artifact eligibility"], "automated", ["#10"]),
75
+ acceptanceEntry("P0-AUTHOR-001", "p0", "author", "A temporary copy of the Golden report", "the modify-equation and table-value loop runs", [
76
+ "edits change content and Artifact identities while presence checks still pass",
77
+ "the missing-dx step fails line-specifically without committing an Artifact",
78
+ "restoration passes",
79
+ ], "automated", ["#12"]),
80
+ acceptanceEntry("P05-CIR-001", "p0.5", "circuit", "Five approved Circuit Sources", "they normalize", ["each matches its exact semantic oracle and content hash"], "manual", ["#11"]),
81
+ acceptanceEntry("P05-CIR-002", "p0.5", "circuit", "The closed component, value, and annotation union", "focused conformance runs", ["every member passes"], "manual", ["#11"]),
82
+ acceptanceEntry("P05-CIR-003", "p0.5", "circuit", "Unknown, duplicate, terminal, quantity, limit, and convention failures", "they are compiled", ["stable typed ranged Diagnostics are emitted"], "manual", ["#11", "#9"]),
83
+ acceptanceEntry("P05-CIR-004", "p0.5", "circuit", "Unused nodes and disconnected residual subgraphs", "they are compiled", ["each warns without cascades"], "manual", ["#11"]),
84
+ acceptanceEntry("P05-CIR-005", "p0.5", "circuit", "Circuit topology", "it is derived", ["only explicit terminal-node relations create connectivity"], "manual", ["#11"]),
85
+ acceptanceEntry("P05-CIR-006", "p0.5", "circuit", "Directional hints, limits, labels, reference ground, and unsupported layout", "they are compiled", ["behavior matches the Circuit contract"], "manual", ["#11"]),
86
+ acceptanceEntry("P05-OUT-001", "p0.5", "circuit-artifact", "Five Circuits under the required convention and Theme matrix", "they render canonical accessible SVG", ["every cell passes"], "manual", ["#11"]),
87
+ acceptanceEntry("P05-OUT-002", "p0.5", "circuit-artifact", "Five Circuits embedded through four formats", "they render", ["labels stay legible after semantic connectivity passes"], "manual", ["#11", "#10"]),
88
+ acceptanceEntry("P05-OUT-003", "p0.5", "circuit-artifact", "Canonical Circuit SVG bytes across claimed pilot platforms", "they are compared", ["bytes match under the pinned closure"], "manual", ["#11"]),
89
+ acceptanceEntry("P05-ADAPTER-001", "p0.5", "circuit-adapter", "The selected Circuit adapter", "probes run", ["restricted execution, cleanup, timeout, budget, and availability all pass"], "manual", ["#11"]),
90
+ acceptanceEntry("P05-ADAPTER-002", "p0.5", "circuit-adapter", "Missing, disabled, or incompatible engines", "a Circuit render is requested", [
91
+ "a structured exact remedy is reported",
92
+ "non-Circuit Documents never probe the adapter",
93
+ ], "manual", ["#11"]),
94
+ acceptanceEntry("P05-PLATFORM-001", "p0.5", "circuit-platform", "Every supported-pilot-platform manifest row", "installation and remedy rehearsal run", ["every row passes"], "manual", ["#11"]),
95
+ acceptanceEntry("P05-SYNTAX-001", "p0.5", "circuit-syntax", "Five lecturer-reviewed Source and semantic pairs", "they are approved", ["they freeze Circuit body syntax 1.0.0 as the conformance corpus"], "manual", ["#11"]),
96
+ acceptanceEntry("P05-PILOT-001", "p0.5", "circuit-pilot", "The five-fixture set with immutable evidence", "lecturers review it", [
97
+ "two lecturers approve the set",
98
+ "one course owner approves usefulness and convention",
99
+ ], "manual", ["#11"]),
100
+ ]);
101
+ export const REQUIRED_P0_IDS = Object.freeze(ACCEPTANCE_ENTRIES.filter((item) => item.gate === "p0" && item.required).map((item) => item.id));
102
+ export const AUTOMATED_P0_IDS = Object.freeze(ACCEPTANCE_ENTRIES.filter((item) => item.gate === "p0" && item.required && item.evidence === "automated").map((item) => item.id));
103
+ /**
104
+ * Coverage gate: every required automated P0 entry needs declared evidence,
105
+ * and no declaration may name an unknown ID.
106
+ */
107
+ export function checkAcceptanceCoverage(declaredIds) {
108
+ const known = new Set(ACCEPTANCE_ENTRIES.map((item) => item.id));
109
+ const declared = new Set(declaredIds);
110
+ return {
111
+ missing: AUTOMATED_P0_IDS.filter((id) => !declared.has(id)),
112
+ unknown: [...declared].filter((id) => !known.has(id)),
113
+ };
114
+ }
115
+ export const acceptanceJsonSchema = Object.freeze({
116
+ $schema: "https://json-schema.org/draft/2020-12/schema",
117
+ $id: ACCEPTANCE_SCHEMA_ID,
118
+ type: "object",
119
+ required: ["schema", "schemaVersion", "catalog", "entries"],
120
+ additionalProperties: false,
121
+ properties: {
122
+ schema: { const: ACCEPTANCE_SCHEMA_ID },
123
+ schemaVersion: { const: ACCEPTANCE_SCHEMA_VERSION },
124
+ catalog: {
125
+ type: "object",
126
+ required: ["id", "version"],
127
+ additionalProperties: false,
128
+ properties: {
129
+ id: { const: ACCEPTANCE_CATALOG_ID },
130
+ version: { const: ACCEPTANCE_CATALOG_VERSION },
131
+ },
132
+ },
133
+ entries: {
134
+ type: "array",
135
+ minItems: 1,
136
+ items: {
137
+ type: "object",
138
+ required: [
139
+ "id",
140
+ "gate",
141
+ "area",
142
+ "given",
143
+ "when",
144
+ "then",
145
+ "evidence",
146
+ "required",
147
+ "contracts",
148
+ ],
149
+ additionalProperties: false,
150
+ properties: {
151
+ id: { type: "string", pattern: "^P0[A-Z0-9]*-[A-Z]+-[0-9]{3}$" },
152
+ gate: { enum: ["p0", "p0.5"] },
153
+ area: { type: "string", minLength: 1 },
154
+ given: { type: "string", minLength: 1 },
155
+ when: { type: "string", minLength: 1 },
156
+ then: { type: "array", minItems: 1, items: { type: "string", minLength: 1 } },
157
+ evidence: { enum: ["automated", "manual"] },
158
+ required: { const: true },
159
+ contracts: {
160
+ type: "array",
161
+ minItems: 1,
162
+ items: { type: "string", minLength: 1 },
163
+ },
164
+ },
165
+ },
166
+ },
167
+ },
168
+ });
169
+ /**
170
+ * Canonical catalog document with logical identity azeforge.acceptance/v1.
171
+ */
172
+ export function createAcceptanceCatalog() {
173
+ return {
174
+ schema: ACCEPTANCE_SCHEMA_ID,
175
+ schemaVersion: ACCEPTANCE_SCHEMA_VERSION,
176
+ catalog: { id: ACCEPTANCE_CATALOG_ID, version: ACCEPTANCE_CATALOG_VERSION },
177
+ entries: ACCEPTANCE_ENTRIES,
178
+ };
179
+ }
180
+ //# sourceMappingURL=acceptance.js.map