Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a2bc4ed
feat(JSONHTML): prepare exact native transfer and four immutable expo…
ThorFuchs Oct 13, 2026
3dd73ab
docs(JSONHTML): specify prepared transfer budgets and qualification b…
ThorFuchs Oct 13, 2026
471558a
fix(ci): count the two shared JSONHTML cases in their actual test bundle
ThorFuchs Oct 13, 2026
778bd03
fix(ci): verify completed Swift Testing events and exact parameter ca…
ThorFuchs Oct 13, 2026
4b4614b
feat(jsonhtml): prepare bounded styled RTF from exact writer tokens
ThorFuchs Oct 14, 2026
b060ed3
docs(jsonhtml): align catalogue introductions with styled export capa…
ThorFuchs Oct 14, 2026
26a1875
feat(jsonhtml): prepare bounded paginated PDF explicitly
ThorFuchs Oct 14, 2026
eb96ea8
fix(jsonhtml): account PDF tables and qualify suite receipts
ThorFuchs Oct 14, 2026
08a11d8
fix(jsonhtml): admit cancellable PDF syntax extraction
ThorFuchs Oct 14, 2026
8b055e5
fix(jsonhtml): bound and admit PDF navigation events
ThorFuchs Oct 14, 2026
1b0ff71
fix(jsonhtml): audit native PDF memory-safety interop
ThorFuchs Oct 14, 2026
3b7d94c
fix(jsonhtml): accept measured mobile font layout geometry
ThorFuchs Oct 14, 2026
7c8f7fc
test(jsonhtml): close PDF acceptance boundaries and documentation
ThorFuchs Oct 14, 2026
d289993
docs(jsonhtml): record qualified PDF increment closure
ThorFuchs Oct 14, 2026
2f9f0b7
test(jsonhtml): qualify receivers and five-product WASI integration
ThorFuchs Oct 14, 2026
ecfcc2c
Fix selected export filenames in native item providers
ThorFuchs Oct 14, 2026
0f03ee5
feat(jsonhtml): bind typed diagnostics and coherent document spans
ThorFuchs Oct 14, 2026
58b07f7
docs(jsonhtml): correct browser fixture inventory
ThorFuchs Oct 14, 2026
a0a73b0
docs: reconcile JSONHTML qualification and API guidance
ThorFuchs Oct 14, 2026
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
22 changes: 21 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,33 @@

## Unreleased

- Add typed caller diagnostics and coherent JSONDocument byte-span rendering to
JSONHTML, with exact target identity, explicitly missing-parent attachment and
finite cumulative annotation/path/message accounting. Rendering never asserts
schema validity or archives source bytes; replaced roots invent no locations.

- Add explicit main-actor PDF preparation from immutable static HTML, with genuine
A4/Letter text-range pagination, an explicit continuous mode, cumulative finite
accounting, cancellation/deadline lifecycle and prepared-byte-only transfer.

- Add opt-in styled RTF to immutable JSONHTML prepared exports. An owned bounded
strict-token emitter preserves pretty JSON text, Unicode scalar sequences and
number spellings; native decoding checks font, colors and actual tab positions.
Finite style/UTF-16 ceilings complement cumulative work/output/retention limits.
Direct JSON defaults remain JSON, HTML, plain text and Markdown.

- Add immutable prepared JSON, UTF-8 text, Markdown and expanded static HTML in
JSONHTML, plus Apple native JSON Transferable conformance with strict import.
Preparation preserves exact lexemes/scalars/order under one cumulative meter;
selected-format closure guards prevent transport from exposing hidden artifacts.
Real receiving-app/device qualification remains separate.

- Add opt-in JSONHTML interactive disclosure, container outline, literal search,
native-byte JSON/Pointer copy and downloads, and complete print content; qualify
three browser engines separately from Safari/device/accessibility release gates.
- Develop JSONHTML as the fifth product for 1.3: exact formatted standalone HTML,
shared strict-writer token formatting, literal tab indentation, cumulative
finite reports, bounded script-free output and a fifth native DocC catalogue.
Annotations and transfer/RTF/PDF export remain later increments.
- Add local full-language wasm32 WASI support, preserving all four products and
the empty root dependency graph. Twelve cumulative UInt64 quotas can exceed
Int.max without changing profiles; allocation capacities retain Int guards.
Expand Down
13 changes: 12 additions & 1 deletion Documentation/Architecture/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ in the [README](../../README.md) are compiled and executed by the public consume
| JSONSchema | JSONSchemaDocument, JSONSchemaRegistry, JSONSchemaCompiler, CompiledJSONSchema, JSONSchemaValidator | Offline immutable plan, invocation-owned evaluation and private native regex |
| JSONStreaming | JSONEventSequence, JSONValueSequence, NDJSONValueSequence, JSONTopLevelArraySequence, JSONAsyncWriter | Exclusive pull state, shared codec, strict framing and awaited handoffs |
| JSONPatch | JSONPatch, JSONPatchOperation, JSONPatchResult, JSONMergePatch | Transaction staging, exact comparison and iterative editing |
| JSONHTML | JSONHTMLRenderer, JSONHTMLRenderingOptions, JSONHTMLLimits, JSONHTMLRenderReport | Shared exact formatting, offline interactive HTML, exact copy/download and cumulative bounded emission |
| JSONHTML | JSONHTMLRenderer, JSONHTMLRenderingOptions, JSONHTMLLimits, JSONHTMLRenderReport, JSONHTMLAnnotation, JSONExportDocument, JSONExportOptions, JSONExportReport | Exact HTML, native Apple transfer, immutable prepared JSON/text/Markdown/static HTML/opt-in styled RTF and cumulative budgets |

JSON imports no siblings. JSONSchema depends on JSON and package-private
JSONRegexRuntime. Streaming, Patch and HTML depend on JSON. There are five public
Expand Down Expand Up @@ -191,3 +191,14 @@ UTC time. Prior time-only stored values cannot recover their original calendar
date; application migration needs an independent source of that information.
Noncanonical Base64 with nonzero unused padding bits now rejects. These corrections
restore the documented strict/native contracts; they do not add a permissive mode.

## Additive 1.3 prepared export

See the [export contract](JSONHTMLExport.md) for compiler-proven declarations,
finite limits, selected-format transfer guards and the remaining RTF/PDF and
receiving-app qualification boundaries.

JSONHTMLRenderer also accepts JSONDocument in its four rendering/report methods.
Caller annotations use exact typed paths, explicit missing-parent attachment and
coherent value byte spans without schema execution or source-byte archival.
See [diagnostic rendering](Release1.3/DiagnosticAnnotations.md).
14 changes: 12 additions & 2 deletions Documentation/Architecture/ExtractionManifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,17 @@
"Native codec, Codable, Pointer, Patch and streaming are original implementations from the integrated contract, not automatically attributed to candidates.",
"Schema graph, explicit evaluator, exact sets/assertions and scalar format recognizers are original implementations from Draft 2020-12, RFC3986/3987/3339/3492/5321/5891/5892/5893/6531/6570/6901 and fixed Unicode13 data.",
"Private FIPS 180-4 SHA-256 is an original Swift implementation with checked cumulative production accounting, bounded scratch and inner cancellation. The separate trusted fixture tool mirrors its primitive core byte-for-byte; public_check verifies parity. No CryptoKit fallback or runtime dependency is introduced.",
"JSONHTML formatted rendering, original fixed CSS and shared strict-writer token classification are original Apache-2.0 code. No third-party renderer, browser numeric authority or runtime dependency is adapted."
"JSONHTML formatted rendering, original fixed CSS and shared strict-writer token classification are original Apache-2.0 code. No third-party renderer, browser numeric authority or runtime dependency is adapted.",
"JSONHTML typed annotations, iterative exact-path binding, static/interactive attachment and coherent JSONDocument span presentation are original Apache-2.0 code. No schema engine, third-party renderer, source archive or new dependency is adapted."
],
"policy": "Record actual adaptations and retain applicable upstream copyrights and licenses. Reference inputs and comparison experiments are not distributed runtime dependencies."
"policy": "Record actual adaptations and retain applicable upstream copyrights and licenses. Reference inputs and comparison experiments are not distributed runtime dependencies.",
"jsonhtml_export_original_contributions": {
"license": "Apache-2.0",
"adapted_third_party_code": false,
"source": "Sources/JSONHTML/JSONExportDocument.swift; JSONExportOptions.swift; JSONTransferable.swift; JSONRTFWriter.swift; JSONPDFOptions.swift; JSONPDFPreparation.swift; JSONPDFBackend.swift",
"synthetic_fixture_pack_sha256": "5394fccbcd48244004e146189f4c764857cb83c05fd8a2a91380ca4f9d752105",
"framework_boundary": "Conditional CoreTransferable/UniformTypeIdentifiers plus a narrow explicit main-actor Apple PDF boundary using WebKit, CoreText, CoreGraphics and AppKit/UIKit paragraph styles. Core JSON imports none of these; no new root dependency.",
"rtf": "Original bounded strict-token emitter; AppKit/UIKit native decoding only in tests and qualification consumers, not generation.",
"pdf": "Original invocation-owned lifecycle, finite adapter accounting and visible-range pagination using Apple SDK APIs. PDFKit is independent qualification only; no third-party renderer adapted."
}
}
182 changes: 182 additions & 0 deletions Documentation/Architecture/JSONHTMLExport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# JSONHTML native transfer and prepared export

This additive 1.3 development increment provides JSON, UTF-8 text, Markdown and
static HTML, plus explicitly requested styled RTF and separately prepared Apple PDF.
Synchronous preparation rejects PDF; only successful explicit async preparation advertises it. Published 1.2 versions do not
provide this API.

`JSONExportDocument.prepare(_:options:)` and
`prepareWithReport(_:options:)` synchronously prepare immutable artifacts without
executing WebKit. No source root, mutable cache, native view or temporary file is
retained. `data(for:)` looks up the exact identifier. `selecting(_:)` changes only
per-item advertisement; hidden artifacts remain retained and available for exact
lookup. Empty or unavailable selections fail. There is no public artifact injection.

Defaults request all four formats, filename stem `JSON`, title `JSON`, one literal
tab per level, LF, light HTML and tab display width four. Indentation is 0...8;
display width is 1...8. `compactJSON` affects native JSON only. Existing writer and
renderer defaults and typed initializer references are unchanged.

Native JSON uses the strict writer/parser, insertion order and preserved numeric
lexemes. Constructed numbers retain the exact normalized fallback. Whitespace and
original string escape spellings are not source-document reconstruction. Decoded
scalar sequences remain distinct; neither Swift String equality nor floating-point
round trips establish fidelity. Text is the pretty JSON body with quoted string
roots. Markdown adds a `json` code fence longer than any backtick run in the body,
using LF before and after the unchanged body and after the closing fence.

HTML is expanded and script-free, with fixed hash-authorized CSS and escaped data.
It includes a bounded escaped title and has no disclosure controls, outline,
annotations, line numbers or hidden values. Default light styling is deterministic.
System fonts and the renderer's offline CSP remain in effect. Standalone file
opening and rich-editor paste compatibility are separate qualification claims.

## Apple transfer boundary

Importing JSONHTML on supported Apple SDKs introduces the package's sole
`JSON: Transferable` conformance. Its declaration needs no `@retroactive` because
the compiler recognizes the same-package ownership exception. Compilation with
warnings as errors and an independent consumer qualify this placement.

Direct representations are JSON, static HTML, UTF-8 plain text, Markdown in that
order. Only JSON imports. Every direct request gets fixed finite defaults and its
own invocation. The prepared wrapper is export-only in JSON, HTML, RTF, text, Markdown, PDF order, with
conditions for available/selected artifacts and matching filename extensions.
Closures additionally guard selection: the SDK's generic-text helper can try a
hidden statically declared representation before reaching the selected subtype.
Conditions alone are insufficient to protect that path. An explicit hidden JSON
request fails; Markdown-only generic text reaches Markdown after hidden candidates
are refused. Prefer explicit format selection when a receiver's choice matters.

CoreTransferable may wrap a parser failure in its transport error. Applications
requiring native structured diagnostics should call JSONParser directly. Transfer
does not add a permissive parser. JSON text import rejects invalid UTF-8, decoded
duplicate keys, trailing syntax and trailing commas under balanced finite limits.

The initial module links CoreTransferable and UniformTypeIdentifiers conditionally.
Pure preparation is actor-independent and remains available without those modules.
The approved future PDF amendment permits narrow WebKit/platform-print support in
JSONHTML, while core JSON must never import those frameworks. WebKit/CoreText/CoreGraphics and AppKit/UIKit paragraph styles
are confined to explicit PDF generation. PDFKit remains independent qualification only. JH25's old
module-wide UI dependency exclusion is superseded by this explicit boundary.

## Finite accounting

One noncopyable JSONWorkMeter admits the root once, then serves cursor formatting,
Markdown scan/wrapping, static HTML, RTF encoding, bounded metadata, artifact tables and result
copies. The HTML helper accepts an already admitted root under that same meter.
Export and HTML core limits intersect before execution; no nested public facade
starts a fresh budget. Checked output growth, cancellation inside owned loops,
copy admission and terminal latching apply throughout. Failure returns no partial
document/report, releases owned scratch and preserves an enclosing reservation.

Initial export policy:

| Capacity | Default inclusive ceiling |
| --- | ---: |
| Core | JSONLimits.balanced, all 49 existing metrics |
| One representation | 8,388,608 bytes |
| All prepared artifacts | 16,777,216 bytes |
| Plain title | 4,096 UTF-8 bytes |
| Filename component | 128 UTF-8 bytes |
| RTF syntax color runs | 1,000,000 per artifact |
| Decoded RTF body | 8,388,608 UTF-16 units per artifact |
| RTF tab positions | Int32.max twips, a format parameter bound |
| HTML | JSONHTMLLimits defaults, document ceiling intersected with representation ceiling |

Zero forbids usage. Allocation capacities must be below Int.max; UInt64.max is
invalid. Checked arithmetic refuses overflow. Title controls are rejected. Filename
components additionally reject empty/dot components, slash, backslash, colon and
bidi controls. No path is derived from the JSON or title. Extensions are fixed.

Each artifact reserves its logical bytes even if Foundation shares actual storage.
Construction buffers coexist with copies and contribute to peak logical retention;
table/report/selection entries reserve 48 logical bytes per format. The report
contains core statistics, per-format bytes and their aggregate. The title is
released after preparation; the bounded filename remains owned. Hidden artifacts
remain in aggregate counts after selection. Logical retained bytes are not RSS;
owned work units are not caller/transport instructions or an elapsed-time deadline.
Separate public calls require caller composition. There is no failure report that
would justify retrying with a fresh budget.

These are initial finite policy values, exercised with pinned small fixtures,
generated deep/wide values and inclusive boundary tests. Measurements do not
establish maximum workload throughput, hard RSS or receiving-app resource bounds.
There is no unlimited or device-specific widening preset.

## Qualification and remaining scope

`Scripts/ci.py --lane export` runs fixed-count debug/release behavior tests and the
independent five-product consumer, verifies all six fixture hashes, compiles
WebPage declarations on macOS/iPhoneOS/iPhoneSimulator and builds the public mobile
consumers. It records actual commands, exits, source manifest and toolchain.
The consumer records 65 outcomes and eight artifacts, including explicit opt-in RTF
and A4, US Letter and continuous PDFs. It tests native import, exact selected exports,
discovery, suggested filenames, immutable selection and cumulative reports.
SDK builds do not establish simulator/device/share-sheet/drag/drop qualification.

The T0 offscreen WebPage probe uses nonpersistent per-job state, disables content
JavaScript/subresources, denies external navigation, awaits finished navigation,
sets print media and captures an explicit region. Independent PDFKit inspection
finds the final sentinel on one tall page. This is region capture, not paginated
A4/Letter output or a qualified cancellation/timeout backend. The current paginated backend is qualified separately; neither its public API
nor paper policy is inferred from the historical T0 result. An external
probe watchdog is not a production timeout guarantee.

The initial receiving/device milestones above are historical. The
[qualification closure](Release1.3/ReviewAndQualification.md) records their actual
source-bound completion, including corrected PDF filenames, delivered drag events
and the approved physical-iPad deferral. SDK builds, automated device outcomes and
manual receiving observations remain separately attributed. Final PR-head checks
are required before a protected merge; tagging and release publication remain separate.

The synthetic fixture bytes originate in the JSONHTML Transfer/Export briefing
ZIP SHA-256 `5394fccbcd48244004e146189f4c764857cb83c05fd8a2a91380ca4f9d752105`.
Their registry pins all six files; no fixture is executable instruction input.
All export implementation and fixed assets are original Apache-2.0 code; upstream
notices remain intact. No third-party renderer or external package is introduced.

## Styled RTF increment

`JSONRTFWriter` is package-only original code. It consumes the existing strict
writer's classified bytes after the single admission. Scalar state is fixed-width;
there is no token-sized buffer, Foundation serialization or native attributed-string
allocation in generation. UTF-8 validation prevents malformed sequences even at
this internal boundary. Unicode is emitted as signed `\uN?` UTF-16 units with
`\uc1`; braces and backslashes are escaped. Actual indentation uses `\tab`, while
JSON string escapes remain visible text. `\par` preserves LF; `\line` failed the
initial independent probe's exact decoded-text requirement.

The fixed Menlo 11-point font has no external asset. RTF always uses a light palette:
punctuation/whitespace RGB 35/40/48, keys 33/75/110, strings 35/111/59, numbers
143/59/16, booleans 106/58/156, null 100/100/100. Native calibrated-color conversion
is compared in a common color space. HTML theme selection is independent. Each
paragraph gets explicit tab stops for every actual indentation tab, at 132 twips
per display cell times `tabWidth`; native AppKit decoding ignored `deftab` for its
default interval. No arbitrary HTML import, attachment or executable link occurs.
Receiver font/color substitution remains outside byte-export fidelity.

Style runs count the initial color and every emitted color change; decoded UTF-16
units include syntax, whitespace and supplementary pairs. Both counters are checked
before emission. Output buffers, wrapping, tab parameters and final result copies
remain charged to the shared meter. New counters do not replace or widen any of
the 49 core metrics. Failure/cancellation latches and releases scratch while
preserving an outer reservation. RTF is export-only and offered only when present
and selected, with a guarded `.rtf` transfer closure and `.rtf` filename.

The initial finite policies are boundary-tested rather than hard RSS/throughput
claims. Small exact fixtures and generated deep/wide/cancellation inputs support
this increment; maximum-workload calibration and receiving-app qualification
remain distinct release evidence. See [RTF increment](Release1.3/RTFIncrement.md).

## Explicit PDF increment

See the [PDF decisions and acceptance map](Release1.3/PDFIncrement.md) and
[DocC guide](../../Sources/JSONHTML/Documentation.docc/PDFPreparation.md).
The new public async MainActor methods use only the document-owned static HTML.
Paginated CoreText visible ranges avoid duplicated text from clipped WebPage regions;
continuous WebPage capture is explicit. One cumulative PDF-phase core meter and
six finite PDF caps cover owned admission, adapter work, captures and copies.
Opaque platform work/allocation and the soft lifecycle deadline are distinct.
Only completed immutable PDF bytes can be selected for transfer. Missing HTML,
failures and cancellation preserve the original item and install no artifact.
Loading