Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
63ad3e3
Establish 1.1 ownership SDK and index qualification probes
ThorFuchs Oct 11, 2026
9dc7b32
Complete scoped presence probe and exact index sample checks
ThorFuchs Oct 11, 2026
02998a8
Correct observed simulator availability in R0 decision record
ThorFuchs Oct 11, 2026
2122fc8
Filter wide exact-key lookup with metered cached fingerprints
ThorFuchs Oct 11, 2026
564b415
Keep cancellation qualification off blocking cooperative workers
ThorFuchs Oct 11, 2026
23e4ccd
Merge branch 'chore/1.1-plan-and-qualification' into perf/1.1-exact-k…
ThorFuchs Oct 11, 2026
5d01f88
Cancel lookup probes at owned checkpoints without blocking workers
ThorFuchs Oct 11, 2026
bf37941
Maintain exact-key indexes during bounded construction and native coding
ThorFuchs Oct 12, 2026
f3bb111
Qualify wide index consumers concurrency and measured retention trade…
ThorFuchs Oct 12, 2026
180b5c7
Correct exact discovered bundle cardinalities for the index lane
ThorFuchs Oct 12, 2026
f00452f
Add guarded cumulative scoped reads and native value conveniences
ThorFuchs Oct 12, 2026
33e5cc1
Merge branch 'perf/1.1-exact-key-index' into feat/1.1-scoped-read-access
ThorFuchs Oct 12, 2026
51b7c16
Fix mobile schema bundle layout and declare iOS 27 minima
ThorFuchs Oct 12, 2026
74b09b7
Record disposition for every index benchmark review trigger
ThorFuchs Oct 12, 2026
30c1e69
Latch terminal overflow from lifetime counter retirement as well
ThorFuchs Oct 12, 2026
6995581
Prove caught retired-counter overflow cannot resume the ledger
ThorFuchs Oct 12, 2026
1b7ee43
Latch terminal overflow from lifetime counter retirement as well
ThorFuchs Oct 12, 2026
8b55bd2
Prove caught retired-counter overflow cannot resume the ledger
ThorFuchs Oct 12, 2026
dc4dd42
Record disposition for every index benchmark review trigger
ThorFuchs Oct 12, 2026
bc1c64d
Add immutable exact Version 1 Codable payload with shared native budgets
ThorFuchs Oct 12, 2026
e06639b
Qualify public Apple consumers and disk persistence across process te…
ThorFuchs Oct 12, 2026
2443638
Fix mobile schema bundle layout and declare iOS 27 minima
ThorFuchs Oct 12, 2026
0b53ed7
Merge branch 'feat/1.1-apple-mobile-qualification' into feat/1.1-scop…
ThorFuchs Oct 12, 2026
90f6108
Merge branch 'feat/1.1-scoped-read-access' into feat/1.1-exact-codabl…
ThorFuchs Oct 12, 2026
8efdf33
Track tightening history only in coding and read scopes
ThorFuchs Oct 12, 2026
a48eb33
Merge branch 'feat/1.1-scoped-read-access' into feat/1.1-exact-codabl…
ThorFuchs Oct 12, 2026
9e61f15
Document measured integration review and precise release blockers
ThorFuchs Oct 12, 2026
5d655f2
Release failed Base64 scratch and extend 1.1 acceptance coverage
ThorFuchs Oct 12, 2026
e6eb46d
Record QA evidence and qualify actual index boundary stages
ThorFuchs Oct 12, 2026
c40c5ff
Close QA ledger and record source-bound review disposition
ThorFuchs Oct 12, 2026
65d86ed
Accept iPad simulator qualification for 1.1 release scope
ThorFuchs Oct 12, 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
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## 1.1.0 — unreleased candidate

- Scoped typed reads with cumulative reports, native model projection and guarded
cursor invalidation; explicit numeric fidelity and absent/null presence.
- Native JSON value-coding conveniences and immutable exact Version 1 payload.
- Metered adaptive exact-key metadata and incremental duplicate recognition;
ordered members and exact collision confirmation remain authoritative.
- macOS/iOS 27 deployment minima and corrected schema bundle layout; public
SDK/simulator and disk-backed SwiftData consumers. Full physical-device
qualification follows the approved 1.1 matrix: physical iPhone required, iPad
SDK/simulator acceptance with physical iPad deferred. No tag/publication follows.
- Correct native ISO-8601 calendar fields and strict Base64 unused padding bits.
See API migration guidance; no limits/profile weights or dependencies raised.
- Release failed Base64 scratch from logical retention while preserving consumed
work and terminal operational errors. Add 19 acceptance/conformance tests,
public mobile recovery checks and a focused debug/release/ASAN QA lane.


## 1.0.0 — 2026-10-11

First stable release.
Expand Down
24 changes: 23 additions & 1 deletion Documentation/Architecture/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ order by default. Exact duplicates fail checked construction and parsing.
| `JSONObject.build(limits:_:)` | Exclusive noncopyable member accumulator; checks before append |
| `JSON.buildArray(limits:_:)` | Exclusive array accumulator; nested arrays remain one element |
| `append(contentsOf:)` on array accumulator | Explicit flattening with charged work |
| Object subscripts by String/JSONKey | Unmetered linear exact-key lookup; nil means absence |
| Object subscripts by String/JSONKey | Unmetered exact-key lookup using immutable metadata; nil means absence |
| `JSON.requiredMember(_:limits:)` | Bounded lookup; throws on wrong kind or missing member |
| `JSON.presence(of:limits:)` | Bounded lookup separating absent, null and non-null value |
| `JSONObject.presence(of:)` | Unmetered convenience with the same three states |
Expand Down Expand Up @@ -168,3 +168,25 @@ subsystem ceilings independently. WorkUnits includes subsystem work, so subtract
once. Failure/cancellation terminates the composition because no successful report
accounts for failed work. The [actual consumer interface](../ConsumerInterface.md)
and runnable consumer demonstrate this contract.

## Additive 1.1 candidate

JSON and JSONDocument provide `read(limits:_:)` and `readWithReport(limits:_:)`
with synchronous non-Sendable JSONReadCursor. Throwing String/JSONKey/Int brackets,
required kind/integer access, explicit Double/Decimal policies, raw/scalar/model
presence and native projection share one active meter. Paths are typed and bounded;
JSONAccessFailure carries the complete path and structured cause. Scope exit
invalidates handles and releases root/source ownership. Resource/cancellation
failures remain terminal when caught by a caller. See [reading](Release1.1/Reading.md).

JSON `init(encoding:coding:)`, `decode(_:coding:)` and `decodeWithReport(_:coding:)`
delegate to existing native facades. JSONCodablePayload provides
`init(preserving:limits:)`, `preservingWithReport(_:limits:)`, `value(limits:)`
and `valueWithReport(limits:)`. Its explicit Codable Version 1 stores validated
UTF-8 only and shares native parent budgets. See [persistence](Release1.1/Persistence.md).

The native ISO-8601 Date strategy now includes calendar fields as well as fractional
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.
56 changes: 56 additions & 0 deletions Documentation/Architecture/Release1.1/BenchmarkReview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Initial exact-key lookup review

This increment filters the tail of a linear lookup using existing immutable key
fingerprints. Objects below 32 members retain the scalar loop. Wide objects compare
the first eight members scalarly, then hash the query once under the active meter.
Every candidate hit still confirms exact UTF-8 identity. No object representation,
publication path, duplicate detector, capacity weight or public API changes here.
The array-backed AVL and controlled hash prototypes remain experiment subjects.

The matched production-stage comparison used MacBookPro18,2, Apple M1 Max, 32 GiB,
macOS 27.0, Xcode 27.2 / SDK 27.2 and Swift 6.4 in language mode 6, release `-O`.
`Tools/Release1_1Probes/LookupBenchmark.swift` covers ten widths, three key shapes,
first/middle/last/missing queries and the first filtered member. Each run has three
warmups and nine measured samples, twenty lookups with result checks per sample:
129 query cells and 1161 recorded samples. The balanced/hash prototype measurements
are a separate corpus; their timing is not presented as production improvement.

Two sequential matched production pairs were retained, together with an earlier
candidate measurement. The table uses the repeated pair. Times are medians in
milliseconds for twenty lookups, including identical result checks; work counts
are owned package units, excluding the benchmark's result-check work.

| Shape / width / query | Scalar ms | Filter ms | Change | Scalar / filter work |
| --- | ---: | ---: | ---: | ---: |
| ASCII / 8 / last | 0.018041 | 0.018083 | +0.23% | 1620 / 1620 |
| ASCII / 16 / middle | 0.020166 | 0.020167 | approximately 0% | 1820 / 1820 |
| ASCII / 32 / first filtered | 0.020209 | 0.023750 | +17.52% | 1820 / 2020 |
| ASCII / 32 / miss | 0.017584 | 0.019375 | +10.19% | 1280 / 1400 |
| Prefix / 32 / first filtered | 0.230042 | 0.252583 | +9.80% | 24320 / 27020 |
| ASCII / 1024 / last | 1.657416 | 0.525750 | -68.28% | 144420 / 42140 |
| Prefix / 1024 / last | 24.807875 | 0.848333 | -96.58% | 2704420 / 67140 |
| ASCII / 10000 / last | 16.837083 | 5.013375 | -70.22% | 1422220 / 401180 |
| Prefix / 10000 / last | 248.313000 | 6.156417 | -97.52% | 26422220 / 426180 |

The unchanged 10% review trigger applies. Accept the observed boundary cost for
this focused draft increment: query hashing adds ten work units to the first
filtered ASCII hit and six to the short missing key, approximately 0.18 and 0.09
microseconds per lookup in the repeated pair. Later wide hits materially reduce
owned comparisons. This is an explicit tradeoff, not an assertion that every
lookup improves. Keep the scalar path and qualify adaptive metadata separately.

Timings are host observations. An initial width-16 ASCII timing outlier disappeared
in the unchanged-code repeat, and wide scalar timings varied between runs; retain
both raw sets and variance instead of attributing those changes to the algorithm.
Empty-loop timings are at timer/call-overhead scale and establish no throughput
claim. This stage retains no owned buffer and reports zero logical retained bytes;
it measures neither process RSS nor allocator counts. Construction, whole-root
admission, native keyed encoding, thermal/energy effects and mobile crossovers
remain unqualified R1/R5 work. Algorithm costs may change resource failure points;
all finite profiles and counter version/weights remain unchanged.

The historical stream median 1.0749626803 seconds versus 0.968493986 seconds
(+10.9932%) retains its existing accepted disposition and 10% trigger. This lookup
stage gives no stream attribution or fresh full-workload release qualification.
Raw samples, source/input hashes, command receipts and medians/variance are retained
in the milestone return bundle, with compiler, SDK, CI and fixture evidence.
139 changes: 139 additions & 0 deletions Documentation/Architecture/Release1.1/Decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Current 1.1 decisions

The sections below preserve the initial R0/first-filter stage history. Current
successors are [Index](Index.md), [IndexMeasurements](IndexMeasurements.md),
[Reading](Reading.md), [Persistence](Persistence.md) and [Mobile](Mobile.md).
Production selects the controlled adaptive hash index with exact confirmation,
32-member threshold and first-eight scalar lookup path. Every published object
owns valid immutable metadata; construction/native keyed storage maintain it.
The guarded reader fallback, one cumulative meter and fixed Version 1 payload
are implemented. Resource packaging is corrected under the default build engine.

SIMD and independent-work parallel batches remain deferred conditional experiments.
The scalar path and checked Sendable immutable sharing remain. No measured mobile
crossover/energy evidence supports shipping a new accelerator, and the selected
wide-object change supplies the demonstrated workload benefit. This is a scope
decision, not completed SIMD/parallel qualification. E11/E12 remain deferred.
The maintainer's 2026-10-12 decision accepts SDK and iPad simulator qualification
for 1.1.0. Physical iPad execution is deferred and does not block R5/R8; simulator
results remain distinct from physical qualification. Physical iPhone evidence and
the three protected Native check names remain required. The exact amended scope
is [QualificationPolicy.json](QualificationPolicy.json).

# R0 architecture decisions

## Reader ownership and declarations

On Apple Swift 6.4 (swiftlang-6.4.0.34.1), ordinary returned `~Escapable` cursors
are rejected. Explicit `@_lifetime` annotations require the experimental Lifetimes
feature. Preserve the current language configuration. Select a guarded synchronous
scope as the reference implementation; no lifetime flag or unsafe annotation is
added to the libraries. See the compiler fixtures in Tools/Release1_1Probes.

The actual compiling reference declarations are `ProbeReadCursor` with throwing
String, JSONKey and Int subscripts, `requiredString()`, generic
`requiredInteger(as:)`, `presence(of: JSONKey)` and `decode(_:)`, plus generic
`probeReadWithReport(_:limits:_:) -> JSONOperationReport<Result>`. These are compiled
into a separate ReaderProbe module and Swift Testing target, not the JSON product.
The consumer imports the public JSON model and ReaderProbe; it imports no meter.
No complete production cursor API is frozen by these subset declarations.

One JSONCodingState owns one noncopyable JSONWorkMeter in domain core. Selection,
path work, integer conversion and JSONNativeDecoder projection borrow that state;
root admission occurs once. A cursor retains only its scope and typed path. Scope
exit invalidates access and clears root/document/source and coding-state references.
Resource and cancellation failures latch, including when the callback catches them.
Ordinary missing-member failures may be caught without refunding charged work.

Swift 6 rejects Sendable closure capture and actual detached-task transfer. The
latter must be tested with object compilation: typecheck alone does not execute
region-based ownership analysis. Escaped synchronous handles are permitted by the
fallback shape but all later operations fail before root/meter access.

R2/R3 must still qualify the full typed presence/conversion surface, mapped-source
diagnostics, live retention/refunds and stricter projection limits against already
consumed counters. The current meter's immutable limits require a reviewed
restriction adapter; copying/replacing the meter is prohibited. No fresh decoder
facade is permitted inside a scoped projection. The prototype intentionally does
not claim these unimplemented behaviors.

## Index candidates and publication

Tests exercise a scalar reference, fingerprint-assisted linear reference,
array-backed AVL tree and controlled open-address hash table. All confirm exact
UTF-8 identity after candidate filtering, including injected same-fingerprint
collisions. Tree rotations, searches, table scans/rebuilds, key bytes and spare
capacity use the actual core meter. New capacities are admitted while old storage
coexists; owned loops check cancellation. These are test-only candidates.

The release-native corpus covers widths 0, 1, 4, 8, 16, 32, 64, 256, 1024 and 10000,
ASCII, 128-byte common prefixes and scalar-distinct Unicode. It records three
warmups, nine samples, one construction per sample and three sets of four lookup
queries. Construction and lookup work/timing are separate. A resource refusal
stops that comparison and is never counted as a successful fast sample.

No adaptive threshold or wide representation is selected yet. Mac measurements
cannot select a mobile crossover. The next small increment may filter a linear
lookup by its existing cached fingerprint, with exact comparison retained. R1
must audit every publication path, incremental duplicate timing, nonthrowing finish,
keyed encoder traversal/allocation, failure cleanup and immutable Sendable metadata.
Existing 32-byte index-slot reservations include grammar-owned duplicate slots,
materialized object/member slots and admitted graph slots; these are distinct
ownerships. They do not automatically cover new simultaneous buffers. Version 1
weights and all 49 metric caps remain unchanged.

## Version 1 persistence and SDK boundary

Freeze the logical envelope: String format exactly `swift-json-value`, integer
version exactly 1, String utf8Base64 strict standard Base64 of one complete strict
UTF-8 JSON document. Inner writing is compact, insertion order, preserved admitted
number lexemes with the existing fallback. The 0.1 fixture is `MC4x`; present JSON
null is `bnVsbA==` and differs from an optional absent payload.

SwiftDataShape explicitly implements these fixed Codable fields and compiles
nonoptional and optional `@Attribute(.codable)` attributes on macOS, iPhoneOS and
iPhoneSimulator SDK 27.2. It is an SDK shape subject, not the exact owned codec:
strict Base64/inner JSON validation, native nested budgets and fidelity remain R4.
The later persistence test must save to a unique disk URL, leave the scope holding
all models/context/container, recreate the container, fetch and check scalar bytes,
member order and original lexemes. Repeat update/reopen and query/sort ordinary
fields. In-memory rereading is not evidence; no cloud-sync claim is intended.

## Mobile platform and CI

The mobile feature manifest declares `.macOS("27.0")` and `.iOS("27.0")`;
iPadOS shares iOS. See [mobile qualification](Mobile.md) for the packaging fix
and the distinction between deployment minima and executed support evidence. All four products, private
regex and schema resources compile for iPhoneOS with the default build engine.
The simulator default engine fails while signing the schema resource bundle; its
`Resources` directory layout needs qualification. The documented deprecated native
SwiftPM backend compiles the same simulator consumer without that signing step.
This alternate build is compile evidence, not resolution of the default-engine
failure. The saved inventory lists iOS 27.0 (24A5390f) and eight available
simulator devices. Runtime behavior has not been executed in this milestone;
availability is not runtime qualification.

Keep the three protected check names and strict/no-bypass rules unchanged. The
seven authored prototype cases extend JSONTests from 54 to 61 functions: all other
bundle cardinalities, three targeted Thread Sanitizer cases, 49 exact cap probes,
independent corpus counts and exclusions remain intact. R0's filtered run requires
exactly seven cases. New platform declarations must later update the exact
macOS-only manifest expectation in the same focused change.

## First production increment

Select only the narrow cached-fingerprint filter described in
[BenchmarkReview](BenchmarkReview.md). The below-32-member scalar path and first
eight scalar probes remain available. A query hash, each member probe, fingerprint
comparison and exact candidate comparison consume the same noncopyable meter;
there is no new table, cached mutable state or owned index allocation. The two
additional behavior cases exercise public presence/Pointer/equality, insertion
order, forced collision confirmation in the production comparator, inclusive and
cumulative work exhaustion and cancellation during actual lookup work.

The current 10% performance review trigger is unchanged; accept the measured
first-filtered-hit and short-miss cost for this limited draft change. Full adaptive
index publication/construction and keyed-builder/mobile measurement remain R1/R5,
not completed by these tests. CI now expects JSONTests 63 and total 131 functions;
the seven-case R0 subset, baseline parameterized invocations and all other exact
cardinality/49-cap checks remain unchanged.
48 changes: 48 additions & 0 deletions Documentation/Architecture/Release1.1/Index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Exact-key construction and publication

Ordered members remain the public collection and writer authority. Each published
object also owns immutable exact-key metadata. The index stores decoded JSONKey
identity and insertion positions, never canonically equating String dictionary keys.

The R0 release-native comparisons favored controlled open addressing for wide
objects. The current candidate uses a linear index below 32 keys, then a power-of-two
table with occupancy at most one half. Lookups keep the scalar path for small
objects and the first eight members. A wide lookup hashes its query once, probes
the table and confirms exact UTF-8 on every candidate hit. Collision scans are
finite and metered; this is no adversarial constant-time guarantee.

Each metadata capacity slot retains the existing Version 1 `indexSlot` weight of
32 logical bytes. Unused capacity is included. New capacity is admitted while old
capacity remains live; copying, initialization, rehashing and exact probes consume
the same meter. Rejected growth releases its replacement reservation and leaves
prior metadata valid. Logical capacities do not assert allocator or RSS ceilings.

The shared grammar maintains its own duplicate index at decoded key recognition.
A duplicate still fails at the second encoded key's start before its colon/value.
Materialized objects maintain separate metadata as keys arrive. Checked
construction and the accumulator maintain their index before publication; consuming
nonthrowing `finish` transfers it without search, allocation or a fresh budget.
Editing, native materialization and schema inspection/output build metered metadata
before returning a value. Empty Merge Patch targets use an explicit empty index.

Grammar duplicate capacity and DOM metadata are distinct live owners. Full owned
graph admission includes the published index's actual logical capacity and member
slots separately. The metric and weight meanings stay at Version 1; capacity/work
counts legitimately differ with the algorithm, and defaults are not raised.

Native keyed encoding now keeps one invocation-owned mutable storage object and
maintained exact index. Updating a field no longer extracts and rewrites the entire
member array. Member growth admits old/new capacities together. Materialization
charges key traversal and builds immutable output metadata under the same meter.
This source observation alone makes no claim of one allocation per field.

`IndexPublicationTests` covers all JSON publication routes, scalar-distinct keys,
forced collisions, failed rehash, duplicate timing and cancellation. The separate
release construction benchmark measures checked, parser, accumulator and native
keyed paths over 120 cells, using the matched finite offline profile. It records
resource refusals separately, and allocator snapshots separately from timing and
logical retention. A successful SDK build does not establish a mobile crossover.

Full R1 closure requires the actual final native/safety/consumer measurements and
review receipts. The test-only AVL/scalar alternatives remain qualification
references; no table, platform or throughput result is inferred from this prose.
Loading