Merge Store 6 main onto store6 and remove Store 5 - #52
Merged
Conversation
Completes the frozen Store6 core API, epoch-safe engine semantics, multiplatform ABI baselines, two-bridge Swift dump gates, and CI enforcement. All required checks passed; approved by Matt Ramotar on 2026-07-18.
…cies, typed meta (#3) Implements the typed fetch-result surface, all five freshness policies, ordered and cancellable bookkeeping, lossless active-stream residence events, multiplatform conformance coverage, and regenerated ABI/Swift dumps. All required checks passed; approved by Matt Ramotar on 2026-07-19.
* Add readerGen and value-bound attribution to the key state machine * Add SourceOfTruth seam with reader liveness contract and DSL default * Rework KeyEngine onto the shared SoT reader pipeline with honest attribution * Add store6-contract-tests module with the SoT contract kit and kit runs * Run conformance suites against a substituted SoT * Pin origin honesty, orphan regression, and reader liveness through the store * Regenerate ABI and Swift dumps for the SourceOfTruth seam * test(store6-core): harden SoT race fixtures * test(store6-core): make dormant SoT replay causal * test(store6-core): gate dormant replay revalidation * test(store6-core): make grace replay barriers causal * fix(store6-core): fence post-match write observations * test(store6-core): make max-age seed causal * test(store6-core): make reader barriers causal Seed the successful SWR fixture through the shared reader pipeline before invalidation. Gate rotating-slot refetches on downstream delivery of the replacement slot snapshot so post-cutoff authority is tested deterministically. * test(store6-core): virtualize grace races Run zero-subscriber grace schedules on the KeyEngine test scope and advance to the last virtual millisecond before reader shutdown. Keep every fake reader collection live so one-shot hydration and shared pipeline roles are distinguished causally. * fix(store6-core): preserve cold-start loading order * test(store6-core): make swr refetch registration causal * test(store6-core): gate external delete revalidation * test(store6-core): gate orphan invalidation enrollment
…lidation (#5) * feat(maintenance): coordinate scoped commits * fix(maintenance): reject callback re-entry * feat(flow): preserve lifecycle while conflating data * fix(flow): preserve synchronous data bursts * fix(flow): propagate terminal failures * feat(sot): add scoped bulk deletion * fix(sot): serialize bulk fake mutations * fix(sot): harden bulk deletion gates * feat(bookkeeper): add durable stale watermarks * fix(bookkeeper): make maintenance atomic Stage fallible maintenance updates before a single publish gate so failures leave records, watermarks, and sequence state untouched. Guard sequence exhaustion, preserve status identity semantics, and reuse the watermark-only status. * Wire durable staleness, sidecar hydration, and discrete Revalidated through the engine * Rebuild namespace maintenance on durable watermarks and supersede-first clears * Add durable invalidation, revalidation, and stress conformance suites * Regenerate ABI and Swift dumps for the grown SourceOfTruth seam * test(maintenance): use real time for engine-tail race gates * test(store6-core): harden emission sequence controls
* Move seam contracts into store6.core.seam and promote freshness, bookkeeping, and clock types * Add seam Fetcher and public config install points with behavioral coverage Route lambda sugar through internal Fetcher adapters and transport conditional ETags from the coherent reservation plan. Expose clock, bookkeeping, and freshness-validator installers and thread them through the store engine. The restart seam test uses MaxAge to prove durable staleness forces a blocking refetch while preserving CachedOrFetch stale-while-revalidate semantics. * Add StoreTelemetry seam with null-guarded hooks and pinned emission placement * Add StoreRuntime capability handle with write handle and KeyEvents stream Recognition amendments replace exactly these landed lines: - revalidatedSatisfiesDemand: envelope.origin == Origin.FETCHER && - StreamDelivery.envelopeSatisfiesDemand: envelope.origin == Origin.FETCHER && The exact installed writer envelope now satisfies both checks. * Add Overlay seam with a single-writer per-key projection layer * Add seam StoreResults factory with the sanctioned exception door * Add store6-extension-probe module with seam-only CI gates * Stabilize replay-based binding conformance barriers * Regenerate ABI and Swift dumps for the seam v1 surface * Stabilize overlay reader-failure protocol assertion * Gate overlay reader-failure proof causally * fix(core): defer covered 304 replacement Do not let pre-success durable status reserve a replacement while the exact revalidation owner covers the current stale epoch. Add a gated initial-delivery regression for the disposition/outcome tail window. Reference: Issue 008 hosted Apple verification * test(extension-probe): gate retirement signal observers * fix(core): preserve projection failure causes Use an upstream Flow.catch boundary so a downstream apply failure remains the terminal cause while self-originated changes cancellation is still retained. Replace the clear-namespace counter TOCTOU with the existing causal freshness proof and add a live-subscriber regression. * fix(core): harden seam race handling
* Add store6-testing module skeleton on the store6 convention plugin * Absorb the SourceOfTruth and Bookkeeper contract kits into store6-testing * Add store6-testing fakes, test clock, meta, and result factories * Add store6-testing conformance suites and the ViewModel sample test * Extend Store6 CI to build, test, and verify store6-testing publications * Harden FakeStore demand-driven consumption under concurrency * Document effective Turbine publication scopes
…pter/compose catalog, subset convention plugin (#8)
…n, close lifecycle, stress lanes (#9) * Bound conflateLatestData with per-kind lifecycle coalescing (FS-1) * Refcounted KeyRegistry with quiescent-only idle LRU eviction * CI: TD-8 whitelist audit, explicit JS lock canary, macOS native stress lane * Complete store.close() lifecycle: registry release and leak-checked teardown * store6-testing: finalize the PROVISIONAL-PENDING-007 close-semantics pins * AC-6 conformance: zero-config and expert-config defaults are identical * Eviction, close-leak, and backpressure conformance and stress suites * test(store6-core): make close waiter causal * Refresh BCV and Swift dumps for StoreBuilder.maxIdleKeys
…and transactions (#10) * Store v6 issue 010: store6-sqldelight module scaffold on the preflight toolchain * Store v6 issue 010: durable meta sidecar schema, sequence algebra, and sync-transaction bridge * Store v6 issue 010: durable SqlDelight bookkeeper passes the contract kit with restart coverage * Store v6 issue 010: SqlDelight source of truth passes the 15-test contract kit over live drivers * Store v6 issue 010: transactional atomicity, kill-point rollback, and TD-6 crash-window closure proofs * Store v6 issue 010: core conformance suites green with the SqlDelight adapter substituted (AC-5) * Store v6 issue 010: sample app and 15-minute existing-schema walkthrough with measured timings * Store v6 issue 010: CI lanes, klib publication loop (39 artifacts), and BCV dumps for store6-sqldelight
…dent conformance suites and failure-time CI evidence (#11) * Store v6 issue 017: adversarial reader-hop perturbation runs reproduce the scheduler race class (red) Core perturbation lane: 3 of 10 serial repetitions red, including matrix A observing v3 instead of v2 and matrix C observing a stale terminal candidate. SQLDelight perturbation lane: 7 of 10 serial repetitions red, including matrix C observing v1, v3, or stale data and the clear sibling starting a third fetch. Temporary provenance probes (not committed) reproduced the same sequence in both adapters: stale SOT(v2), calls=3, then fresh FETCHER(v3). Evidence is archived under /private/tmp/store6-017-red-evidence/approved.XrR8kt. * Store v6 issue 017: closeAndSettleForTest support seam (core joins; borrowed compilation settles with close) * Store v6 issue 017: failure-time test-report uploads so assertion-level evidence survives red CI runs * Store v6 issue 017: causal barriers, ratified-bound drains, and joined cleanup make conformance scenarios scheduler-independent (green under reader-hop perturbation) * Store v6 issue 017: substitution and perturbation fixtures track and close their SQLDelight drivers * Store v6 issue 017: settle the seed fetch before MaxAge advance * Store v6 issue 017: fence only reader-hop seed fetches * Store v6 issue 017: fence every cold seed on observed reader delivery * Store v6 issue 017: fence stale reader ticket enrollment
…y the pre-clear drain (#12) * test(store6-core): remove short wait deadlines Preserve Default-dispatch ordering while letting a 25-second runTest bound own cancellation. This prevents nested 2-second and 5-second wall-clock timers from expiring under broad root-CI load and keeps cleanup below the JS runner's 30-second ceiling. Post-merge evidence: root CI 30046754162 * test(store6-core): complete causal wait hardening Remove the remaining nested physical timers from causal test waits while preserving their Default-dispatch ordering. Bound ordinary suites at 25 seconds, keep the 240-second stress watchdog, align JS Mocha at 300 seconds, and close Store before cancellation-sensitive joins. * test: complete the wall-clock causal-wait sweep and add the ratified pre-clear drain Remove every remaining nested wall-clock withTimeout that hops to Dispatchers.Default across core commonTest and the sqldelight JVM lane, preserving each cross-scheduler hop. Bound every swept suite with the same file-private 25-second runTest shadow; StoreZeroConfigEquivalenceTest keeps its deliberate inline 60-second bounds. Virtual-time timeouts on the test scheduler are untouched: they are deterministic and out of the class. Also repair the fifth same-class frame race surfaced by the serial repetition lane: clearNamespace_activeLocalOnlyStreamObservesMissingWithoutRefetch now drains at most one queued pre-clear Data frame, exactly asserted (value and flags), per the fenced-clear ruling in decision 006 that a pipeline may queue one duplicate pre-clear Data. Loading then Missing remain strictly asserted, and the LocalOnly no-refetch bound stays exact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…lidation (#13) Post-merge evidence at ed81900 (Store6 run 30056554434, apple-tests, macosArm64Test, T6 artifact 8583026634): StoreRevalidationConformanceTest- AgainstSharedFlowSot.conditionalRefetch_notModified_emitsOwnerRevalidated- AndClearsStaleness failed with "unexpected lifecycle item Error". The engine launched the invalidate-wake refetch while residence transiently read null, so commitNotModified took the baseline == null branch and surfaced the adapter-contract Missing error for a durably resident key — a public Error frame inside a healthy 304 cycle, violating ratified C-24. Per the T2E ruling (Matt approved option 1): a null launch baseline with residence present at commit is an obsolete launch snapshot, classified ObsoleteRevalidation like every other stale snapshot, which self-heals by replanning once. Only a 304 with no value on either side remains the typed Missing adapter-contract failure. Red-first: coldBaselineNotModified_hydratedBeforeCommit_classifiesObsolete- AndReplans deterministically pins the racy commit state on the virtual-time scheduler (Failed before the fix, ObsoleteRevalidation plus exactly one replan after); trulyColdNotModified_staysTypedMissingAdapterContractFailure pins the preserved boundary. The three 304-cycle conformance tests legalize the bounded self-heal (fetch call 3 answers NotModified; count bound 2..3) while keeping every frame assertion and the staleness-clearing proof exact. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Lift Kotlin and KSP to 2.2 while preserving existing JVM-default bytecode and Swift dump output across shared convention paths. Co-authored-by: OpenAI Codex <noreply@openai.com>
…, androidx.room3 catalog (#16) Kotlin 2.2.21 -> 2.3.20 (room3 native KLIBs are ABI 2.3.0), KSP -> 2.3.10 (standalone versioning), AGP 8.9.3 -> 8.10.0 (room3 plugin floor), androidx.sqlite 2.6.2 -> 2.7.0 (room3 3.0.0 POM), room 2.8.4 catalog entries replaced by androidx.room3 3.0.0 (dormant until 011 retargets), androidCompileSdk 33 -> 34 (room3/sqlite AAR metadata floor; no tree consumer), renovate freeze moved to androidx.room3. Swift dumps refreshed for the Kotlin 2.3 SubclassOptInRequired @note rendering: +30/-0, doc comments only, no selector or type changes (shaped bounded-churn gate per the amended plan). Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…line, and demo (#17) * Store v6 issue 012: store6-compose module skeleton and stability conf on the preflight toolchain Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: skipEqualData operator and storeResultMutationPolicy (TDD) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: Store.collectAsState and Flow.collectAsStoreState with structural skipping Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: lifecycle-aware collection on the CMP lifecycle tier Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: store6-compose-demo desktop screen, DemoUiState derivation, and stability probe Registers the shipped stability conf as a compile input and opts the demo compilations out of the build cache: the Compose plugin tracks neither, so a conf-only edit or a cache hit would otherwise leave the CI gate asserting against a stale stability report. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: stability calibration ruling and consumer docs Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: CI lanes for store6-compose and the tiered compose-stability gate Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: BCV dumps for store6-compose Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: run the shared compose suites on the Android unit-test variant Composition.dispose() traces through android.os.Trace, which is an unimplemented android.jar stub under local unit tests and throws rather than no-ops. Returning stub defaults keeps the Android variant executing the same 17 commonTest suites as every other target. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: ship the lifecycle entry points on all 12 targets and harden the stability gate Review found the lifecycleMain tier rested on a false premise. lifecycle-runtime-compose 2.9.1 does publish linuxX64, mingwX64, tvosArm64 and watchosArm64 — verified against the published Gradle module metadata and by compiling all four — so the restriction omitted the API from a third of the published artifacts, and the README and KDoc shipped a wrong reason to consumers. The lifecycle-gated entry points move to commonMain and the klib dump now carries them on every target. Two gate defects fixed: - it asserted the ABSENCE of 'unstable' rather than the PRESENCE of 'stable', so the compiler's third parameter rendering — a bare, unprefixed 'value: X' emitted for unknown/runtime stability — passed silently. Demonstrated as a false green against a doctored report. - Kotlin incremental compilation rewrites the stability report with only the recompiled subset, and the report is an undeclared output, so an incremental CI build could gate against a one-entry report. The step now discards the module build directory and forces a full compile. Test gaps closed, each verified by mutation: custom valueEquivalence in the mutation policy, origin as a discriminator, the MaxAge restart-key normalization, collectAsStoreState's initial parameter, the collection-start close guard, collectAsStoreStateWithLifecycle, lifecycle re-entry retention, and the demo's non-stale error banner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Store v6 issue 012: review follow-ups — commonTest lifecycle coverage, restart-token guard, demo SideEffect Promotes the lifecycle behavior tests from jvmTest to commonTest: LifecycleRegistry.createUnsafe and Dispatchers.setMain both work off-JVM, so the all-12-target lifecycle claim is now behavior-verified on every runnable lane (jvm, js, wasmJs, iosSimulatorArm64, macosArm64, androidDebug, androidRelease — 25 tests, 0 failures each) rather than compile-verified everywhere and behavior-verified only on JVM. Adds a guard comment on freshnessToken's else branch: it is safe only because every other landed Freshness is a data object, and a future non-singleton subtype would silently restart collection on every recomposition. Replaces the demo's write-during-composition of lastData with SideEffect, so the retained-Data write no longer lands as a backwards write to state the same composition already read. No ABI change: api dumps are byte-identical. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…fective test deadline (#18) Turbine 1.2.0's 3-second wall-clock default nested inside every 017 25-second runTest shadow, so a starved runner could fail a test via Turbine's deadline instead of the ratified bound (PR #15 D0: OverlayProjectionProtocolTest red at 3.065s). No turbineTimeout override existed repo-wide. Each of the 12 shadow files that also uses Turbine now wraps its test body in withTurbineTimeout(30s). 30s is strictly greater than the 25s bound: equal bounds would race, so the shadow is now provably the sole effective deadline and starvation converts to the uniform UncompletedCoroutinesError with a full coroutine dump, as designed. Test-only: shim, import, and constant lines exclusively. No assertion, drain, tolerance, or scripted-response change; no production code, workflow, toolchain, or store6-room path touched. The 5 files borrowed byte-identically by store6-sqldelight stay identical (Gradle Sync from core's tree). Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…r with durable bookkeeping (#15) * Store v6 issue 011: store6-room module scaffold and Room KMP test rig Co-authored-by: OpenAI Codex <noreply@openai.com> * Store v6 issue 011: adapter-owned bookkeeping schema (entities, DAO, migration SQL) * Store v6 issue 011: RoomBookkeeper — durable watermark algebra on Room * Store v6 issue 011: RoomSourceOfTruth with generation-gated reader and transactional capability * Store v6 issue 011: transactional atomicity and AC-5 substitution conformance suites * fix(store6-room): keep bookkeeping scopes internal * Store v6 issue 011: Room sample app, walkthrough, and compatibility statement * Store v6 issue 011: CI lanes and ABI dumps for store6-room * fix(store6-room): preserve transaction contracts Coordinate adapters that share a database, buffer reader echoes until transaction and savepoint outcomes, and keep mutation generations monotonic. Make the admitted commit boundary exception-atomic, fail fast on launched-child transaction mutations, and close every Room database created by the inherited contract kits. Tests: 59/59 on JVM, iOS simulator, and macOS; module build, API checks, lint, and sample green. * Store v6 issue 011: retarget store6-room to Room 3.0.0 The unreleased adapter moves to androidx.room3 3.0.0 before first publication rather than shipping a known-breaking Room 2 surface: Room types are this artifact's public ABI, so the coordinate/package/type-identity change is a breaking change that must not land post-release. Consumes the Kotlin 2.3.20 / AGP 8.10.0 / SQLite 2.7.0 / androidx.room3 preflight as landed (#16, 1322eeb) on top of #17 compose (e0449fc) and #18 turbine deadline (3db78fa). Targets drop from 9 to 8: room3 publishes no iosX64 variant, verified directly against the resolved 3.0.0 artifacts, so the drop is inherent to the retarget rather than a discretionary cut. js/wasmJs are Room-3-supported and tracked as a separate follow-up; they need a suspend schema API and async SQLite. Two API deltas the port had to absorb. Room 3's Gradle plugin registers its extension as `room3`, not Room 2's `room`. Room 3's Migration.migrate is suspend, while androidx.sqlite 2.7.0's execSQL is still synchronous, so Store6RoomSchema.createTables stays non-suspend and the public surface keeps its shape there. The connection API (useWriterConnection, useReaderConnection, immediateTransaction, deferredTransaction) carries over unchanged. Tests carry over semantically unchanged and pass 59/59 on jvm, iosSimulatorArm64 and macosArm64, including the 15 SourceOfTruth and 6 Bookkeeper inherited kit tests. The three Turbine-using test files adopt PR #18's shim shape (25s runTest shadow, 30s Turbine deadline strictly above it); the two Turbine-free files keep the plain 25s shadow, mirroring #18's own exclusion rule. CI: the four single-line lists become five-way unions carrying sqldelight, compose and room without dropping any entry; #17's inserted steps are preserved verbatim and unreordered; the klib skip-case gains iosx64 for four suffixes. Verified publication is 61 primary artifacts (52 landed plus room's 9). BCV dumps regenerate to name androidx.room3.RoomDatabase, and the klib dump's target header drops iosX64. Zero drift outside store6-room, settings.gradle and store6.yml. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: OpenAI Codex <noreply@openai.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…irst pin (#19) * test(core): pin cold origin cutoff race (red) Hold a pre-write cold absence across durable write return on runTest's virtual scheduler, then assert the full C-05 contract: FETCHER origin, non-stale/non-refreshing delivery, non-null metadata, and one fetch. The test is intentionally red on unfixed origin/main. The archived XML proves the SOT, stale, refreshing, null-metadata, two-fetch shape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(core): fence queued pre-return observations Track the active raw-reader session at the successful write boundary. When its final writer-current notification is still queued, reject preceding mismatches, preserve the committed envelope, and release the fence only on the exact writer echo. The write-return CAS remains non-suspending, ordinary post-echo observations retain later source authority, and no public or seam API changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(core): pin concurrent cutoff mirror Hold both cold collectors after Launch/Join reservation and gate both ticket outcomes while a shared pre-write absence crosses durable return. The unfixed engine deterministically produces SOT/stale/null-meta frames and a second fetch; the writer-current fence preserves FETCHER convergence and one call. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(core): pin successor fence overwrite (red) Hold a committed fetcher echo across the start of a second apply write. The current fence is cleared by the successor and deterministically reproduces the full SOT, stale, refreshing, null-metadata, two-fetch failure shape. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(core): preserve predecessor fence across writes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(core): pin failed successor rollback (red) Hold a committed predecessor echo unresolved, stamp and conflate a failing successor, then prove the rollback cannot strip the predecessor envelope or launch a redundant fetch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(core): retain envelope after failed successor Discard a failed or cancelled owner's consumed tag before resuming its nonmatching row. Equal predecessor content keeps the installed envelope; different content remains source-of-truth authority. Avoid copying the raw observation on the ordinary attribution path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(core): pin hosted fence liveness regressions (red) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(core): recover fenced reader liveness Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…lemetry overhead, non-blocking CI lane (#20) * Store v6 issue 016: store6-benchmarks module skeleton and kotlinx-benchmark toolchain Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 016: benchmark fixtures and the harness smoke-test contract (red) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 016: METRIC-1 stream/cold/get/churn benchmarks Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(benchmarks): use JMH 1.37 Blackhole guard Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 016: telemetry overhead benchmarks and allocation probe Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 016: CI wiring — blocking build step, grep-loop union, non-blocking benchmarks lane Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 016: harness README and calibration config finalization Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(benchmarks): address final review findings Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…pp Compose inspector (#22) * Store v6 issue 013: devtools module skeletons on the landed toolchain Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 013: devtools event model and StoreDevtoolsMonitor (TDD) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 013: structured logger sink, composite telemetry, and EVENTS.md v0 (TDD) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 013: in-app Compose inspector with pure presenter derivation (TDD) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 013: devtools demo app on Android, desktop, and iOS with the inspector overlay Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 013: CI lanes for devtools modules and BCV dumps Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 013: document devtools modules and demo runbook Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 013: keep Linux JS lock graph complete Disable configuration on demand for the full Linux job so Kotlin JS/Wasm lock tasks see one consistent project graph across separate Gradle invocations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Store v6 issue 013: keep iOS demo launchable Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 013: keep timeline transitions visible Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…nd the public roadmap (#21) * Store v6 issue 014: STABILITY.md — tiers, deprecation, cadence, and the mutations honesty section Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 014: README Store 6 section and llms.txt Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 014: public roadmap page Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 014: pin tests for the documented zero-config defaults Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 014: docs pages at docs/store6/, publish-time placeholders resolved Materializes the four teaching pages as tracked files per the OQ-1 ruling (docs-site content lives in the Store repo). Directory proposed as docs/store6/, distinct from the untracked docs/v6 planning corpus; Matt confirms it in the voice pass. Resolves every <PLACEHOLDER-*> token: roadmap and quickstart homes to in-repo paths, llms.txt to repo-relative links, and <PLACEHOLDER-GRADUATION> rewritten as the named prose reservation (no token, no dead link). Corrects store6-sqldelight/README.md's stale "Kotlin 2.1.21" pin per the OQ-6 ruling. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 014: apply code-review and plan-ADDENDUM-3 findings ADDENDUM 3 was appended to the plan mid-execution and carries an unruled gate on STABILITY §3 (open item (b)). Discharging its T1 Step 4 obligation found a real error: §3 published store6-testing as stable-track while every public declaration in that artifact carries @ExperimentalStoreApi. The row now states the verifiable fact and the discrepancy is routed to Matt, same disposition as the Kotlin-floor STOP-gate. Test fixes, both of which made the pins prove more than they did: - advanceUntilIdle() proved nothing about retries. RealStore runs the engine on Dispatchers.Default, which never observes runTest's virtual clock, so the assertion was a snapshot taken immediately after get() returned. Replaced with real-time quiet windows an order of magnitude above the engine's internal fixed-delay scale. - The retry pin only covered the terminalizing get(MustBeFresh) path, which is where a background retry is least possible. Added a live-stream-collector leg, which is where one could actually hide. Green on jvm, macosArm64, and jsNode. Documentation corrections: - The defaults page misquoted the fetcher-requirement message it cited: a source of truth does not substitute for a fetcher (sot is defaulted; requireNotNull(fetcher) is unconditional). The third alternative is fetcher(Fetcher). - Quickstart step 4 asserted the exact convergence issue 020 is currently stopped on. Re-attributed to the acknowledgement contract; active-collector convergence is explicitly not promised until the engine work lands. - STABILITY and ROADMAP disagreed on the adapters; STABILITY now carries may-slip. - §3 now tells seam implementors the seam types are @ExperimentalStoreApi today. - Narrowed the atomicity gate to Overlay/StoreWriteHandle per the ratified RISK-2 text. - LocalOnly line now cites evidence for both of its claims. - Quickstart states plainly that nothing is published yet; no install block ships, because no ratified document sanctions a snapshot coordinate (ADDENDUM 3 item (a)). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Store v6 issue 014: apply voice-pass round 1 — cut the v5 archaeology Matt: "it currently reads like airing dirty laundry." Both documents recited Store 5's failures in six separate places — the 30-month alpha line, MutableStore's annotation-gated years, the dropped FileSystem support, the stalled 4-to-5 migration, an unanswered contribution offer, and a "trust deficit" framing. Each was defensible alone; together they made a policy document read as an apology, which undercuts the confidence it exists to project. Each site now states the commitment and stops. Principles 3 and 4 gained forward-looking clauses where a failure used to serve as the rationale. The alpha01 schedule honesty moves to where it belongs: the confidence range. Extended to the two closure comments, which carried the same register and are the most public artifact here. Nothing load-bearing was lost. AC-1's never-again statement is intact verbatim, as are the tier markers, deprecation stages, cadence, side-by-side promise, the two-step ack obligation in both README and STABILITY, the OVERLAY consumer guidance, and the two-stage RISK-2 text. Re-verified: no frozen-claims, no performance numbers, no PLACEHOLDER, zero dead links, and all five anchors the closure comments target still resolve. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* test(core): pin active confirmFresh liveness Adopt the Issue 020 diagnostic fixture byte-for-byte and hold the exact active writer row across durable return and confirmFresh metadata advancement. The unfixed engine drops the row and strands the active projection authorization. Fresh T0 XML: 0072577630c0cd65cb2d6e5909202931b69a9ac5b1065ea3f0bcd40c66e543c6. * fix(core): preserve confirmFresh writer-row liveness Reuse the live metadata-advanced envelope only for the exact committed authoritative raw token, while excluding direct revalidation owners and preserving resumed attribution. * test(core): make projection gate observation causal * test(core): await durable mark entry causally
* test(core): pin projection auth handoff Apply the archived two-interleaving patch unchanged at 451bb9c. The mapping-before pin fails directly while the mapping-after F-0 control passes. Patch SHA-256: 2f819b8841c21961f87bf7de3858f7e8ff42299e760489e80f00a47cc2ae475c Red XML SHA-256: 96770b5d1bf16d04fa611b5e7b45d2d7fe17f552f9265867139434ee056dd324 * test(core): cover projection auth matrix Execute all 32 projection authorization handoff cells and pin consecutive metadata successors plus obsolete readiness. * test(core): gate invalidation delivery timing Keep the stale-epoch delivery path on the intended side of confirmFresh in every matrix cell. * test(core): pin authorization construction race Gate confirmFresh after coherent reader resolution and before projection authorization construction. * fix(core): hand off projection authorization Preserve a private causal lineage across confirmFresh metadata successors and carry the coherent projection base from reader resolution through authorization.
* store6-mutations: module scaffold, test fixtures, wiring spike (issue 020 T1) * store6-mutations: journal boundary, mutator registry, producer-failure containment (T2) * store6-mutations: real Overlay producer over the pending journal (T3) * store6-mutations: non-transactional ack path (apply → confirmFresh → retire) (T4) * store6-mutations: walking-skeleton tracer, enqueue → OVERLAY → ack → SOT (T5) * store6-mutations: CI lanes and klib verification (T6) * store6-mutations: harden drain and signal handoffs
Issue 021 (STORE-8): the twenty-ruling mutations API review executed against base e3c9e6d. Presence algebra with explicit Present/Absent (null projector result = decline only); required-input mutationStore factory (registry, server, keyResolver, valueCodecVersion, valueCodec) over an overlay-free builder with retained Bookkeeper/SourceOfTruth; two-method MutationServer (push + retire); sealed present/absent acks with clear-based absent adoption; resolver-backed drain()/drain(key) replacing drainOnce; real in-memory attempt generations with defensively copied codec blobs; normalized failure/inspection carriers; typed advisory event algebra; in-memory canonical alias facade with explicit key-taking Store overrides and lost-wakeup-free revision signals; effects capture (never execution); permanent mutations ObjC/SKIE dump lanes via the parameterized SwiftDumpTasksPlugin (core lanes byte-identical); BCV dumps refreshed; quickstart/STABILITY updated to the ratified surface. Zero changes under store6-core/ and store6-testing/. Durable journal, drain orchestration, and ack-path atomicity remain Issues 022/023/024 per the frozen R-0/R-1 handoff. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* test(core): pin overlay authorization ordering Add deterministic reader-first and owner-first interleavings for Issue 029. Reader-first preserves the classified legacy red; owner-first proves the equal-but-distinct target is rejected. No production code changes. * test(core): accept authorized overlay reuse Replace the obsolete origin-only rejection with the value- and authorization-aware C1 contract after the F-B ruling. Preserve the owner-first negative control unchanged.
* feat(mutations): add durable journal storage Implement the public journal seam, in-memory and SQLDelight storage, restart hydration, pruning safety, and published contract kits. Wire additive API dumps, module publication, and the required CI verification lanes for Issue 022. * test(mutations): use durable unit codec in walking test * test(mutations): isolate lincheck record fixtures
Implement the ruled parking, backoff, conflict, acknowledgement, effect, checkpoint, event, and restart semantics across the mutation engine and both journal adapters. Add deterministic contract, scheduling, resumability, and API guards while preserving the public ABI and storage schema. Reference: Issue 023
* docs: add source-doc cleanup inventory baseline Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: record inventory 4-column format in plan Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: remove internal sign-off stamp from freeze-candidate KDoc Removes the freeze-candidate/sign-off governance stamp and its variants (personal-name references, issue-007 landing-state language) from KDoc and comments across store6-core, store6-testing, store6-room, store6-sqldelight, store6-compose, store6-compose-demo, store6-devtools, store6-mutations, and store6-benchmarks. The @ExperimentalStoreApi annotation and STABILITY.md already carry the public stability contract, so no replacement text is added. 44 hits classified per the rewrite rubric: 33 P2 (governance/decision- provenance stamps), 2 P1 (bare issue-007 tags), 2 P3 (speculative-intent lifecycle-policy deferrals), and 2 FP (a test-fixture User.name string literal that coincidentally matches "Matt", left unchanged). Verification: root ./gradlew apiCheck ktlintCheck green; module compileKotlinJvm green for store6-core/testing/room/sqldelight/compose/ mutations/devtools; api/ dumps unchanged; every diff hunk touches only comment/KDoc content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(core): remove internal issue and design-doc references from KDoc Clears the remaining store6-core sweep hits after the cross-module freeze-candidate stamp removal: TD-11, FS-1/FS-2/FS-5/FS-6, (D0, PR #15), issue 006, and the T2E / fenced-clear ruling attributions. Every rewrite is comment-only; each surviving contract clause is unchanged in meaning and its pinning test or code site is recorded in the cleanup inventory. Both detection sweeps now return zero for store6-core/src. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: amend plan with Sweep v2 and Task 3b (execution amendment A1) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(core): clear design-doc referents surfaced by widened sweep Applies Sweep v2 (plan Amendment A1) to store6-core/src, clearing the referent families the original Detection sweep does not match: design-doc section references (engine-design §7, R3, R7), acceptance/test/criteria tags (AC-3, AC-6, C-01..C-12, TEST-1, TEST-7), the row-7/8 design-table reference, and bare zero-padded issue numbers (001, 004, 010/011, 016). Hard pattern: 14 hits -> 0. Classify-only pattern: 8 hits -> 2, both recorded as FP (internal shorthand inside executable string literals, in SourceOfTruthHydrationRaceTest and KeyEnginePlanningTest, which are protected content outside this pass's charter). Notable: deletes the second KDoc paragraph of seam/TransactionalSourceOfTruth, which prescribed an extension-side coordinated-decorator protocol on a published @ExperimentalStoreApi interface. The interface's own contract sentences, the confirmFresh caveat, and both @PARAM lines are kept; the protocol remains documented where it is implemented, on store6-extension-probe's CoordinatedTransactionalSourceOfTruth. Every hunk is comment- or KDoc-only. Verified: root apiCheck, :store6-core:compileKotlinJvm, :store6-core:jvmTest all BUILD SUCCESSFUL; git diff of store6-core/api empty; Sweep v1 still zero for the module. Inventory updated with a Task 3b section: 22 rows over 20 distinct lines, P1 13, P3 3, P4 2, FP 2, Unverifiable 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(mutations): make KDoc contracts self-contained, drop internal issue references Resolves all 269 Detection-sweep (v1) and Amendment A1 (v2) hits in store6-mutations/src: 171 P1 bare provenance tags, 1 P2 governance stamp, 61 P3 speculative/stale future claims, 30 P4 rationales restated against the components in this tree, 6 FPs recorded. Behavioral guarantees survive verbatim in meaning. The facade's `runtime()` returning null (pinned by MutationAckPathTest.rawWriteHandleUnreachable- ThroughFacade) and the deliberate adopt-then-retire ordering on the ack path (pinned by presentAck_appliesConfirmsFreshThenRetires and absentAck_clearsThenRetires_andHasNoCanonicalKey) keep every clause; only the labels are gone. Several deleted sentences were not merely speculative but false in this tree, since the journal storage, drain pipeline, conflict pipeline, tombstones and durable parking have all landed: deadLetters() is no longer "always empty", the conflict policy is no longer "stored, never executed", effects are executed, and tombstones are recorded. Each was verified against code before deletion. Every hunk is comment/KDoc-only (mechanically checked: zero non-comment changed lines). `git diff -- store6-mutations/api` is empty. Root apiCheck and :store6-mutations:compileKotlinJvm pass; jvmTest runs 270 tests with one failure, MutationJournalLincheckTest, which compiles to byte-identical bytecode with and without this change and is a pre-existing flake. One Sweep-v2 hard-gate hit is deliberately left: MutationRestartWalkingTest keeps `error("The AC-4 LocalOnly scenario must not fetch")`, where the referent sits inside a string literal in executable code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(mutations): restate conflict-repeat bound on merge door; wrap fix Review follow-up, three fixes. 1. The public `conflicts { merge { } }` KDoc lost its bounded-repeat contract under the P4 delete-fallback, but the bound is restateable from code: CONFLICT_UNCHANGED_BOUND = 3 (MutationEngine.kt:62) is applied at MutationEngine.kt:2226, where a trailing run of conflict receipts carrying identical server metadata (non-null conflict meta, equal etag and writtenAt) parks the execution with a normalized CONFLICT failure (detail "conflict-unchanged-bound"). Restated on the merge door, together with the merge-throws park (detail "merge-failed"). Pinned by MutationConflictTest.unchangedRepeatedConflictEventuallyParks. The inventory row is reclassified P3 -> P4 (it had been P3, since the first pass deleted rather than restated) and now records both code sites, so no row in this module ends on the delete-the-rationale fallback. 2. Re-wrapped MutationEngine.flushRetirementCheckpoint's KDoc: the previous pass left a 163-column line, the module's only comment line over 100 columns. No formatter catches this, since ktlint and spotless are both no-ops for store6-* modules. Every remaining >100-column comment line in the module is byte-identical to its form at 1d1607a. 3. Added the inventory row for MutatorRegistry.kt:38, where the published MutatorRef KDoc's graduation-review waiver was deleted. No sweep pattern matches "R-2a", so the row is recorded as a non-sweep addition and excluded from the 269 measured sweep hits; the table now holds 270 rows. Class counts are now P1 171, P2 2, P3 60, P4 31, FP 6, Unverifiable 0. Both source hunks are comment/KDoc-only. `git diff -- store6-mutations/api` is empty; root apiCheck and :store6-mutations:compileKotlinJvm pass; both sweep hard patterns remain clean over store6-mutations/src apart from the already-reported string-literal boundary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(adapters): remove internal references from room, sqldelight, compose, mutations-sqldelight Resolves the 23 remaining unclassified Task-1-baseline hits across the four adapter modules plus 10 additional Sweep-v2 hits enumerated fresh for this task: 4 in store6-room, 5 in store6-compose, 1 in store6-mutations-sqldelight (protected, FP), 0 in store6-sqldelight. 33 rows classified: P1 29, P3 1, P4 2, FP 1. P1: bare `TD-6`/`TD-8`/`(OQ-3)`/`(D0, PR #15)` tags and leading test-doc tags (`FS-#`, `AC-#`, `Issue-017 convention:`, `017 residual-deadline repair:`) deleted, sentences otherwise unchanged. The two room Turbine-deadline comments now read as the equivalent wording already landed in store6-core's conformance tests. P3: RoomSourceOfTruth's nested-transaction paragraph dropped its "for the future TD-11 mutations decorator" framing; the remaining sentence documents withTransaction's current nested-write contract, pinned generically by RoomTransactionalSourceOfTruthTest's nestedWrite_outerRollback_never- PublishesEcho and nestedWrite_outerCommit_publishesEchoOnlyAfterCommit. P4: StoreResultEquivalence's "issue-007 OQ-1 ruling" restated as conflateLatestData's own documented contract (verified against store6-core/internal/StoreResultFlows.kt and the quoted StoreResult.kt Revalidated KDoc); CollectAsStateWithLifecycle's "landed issue-007 bounded registry" restated as "the bounded key registry" (verified against store6-core/internal/KeyRegistry.kt and StoreBuilder.maxIdleKeys). FP: SqlDelightMutationRestartWalkingTest's error("... AC-4 ...") message is inside an executable string literal, out of doc-pass charter. Every hunk is comment/KDoc-only (hunk-reviewed by hand and by grep-filtering added lines for anything not starting with `*` or `//`). Verified: root apiCheck, module compileKotlinJvm for all four modules, jvmTest for room/ sqldelight/compose (re-run with --rerun-tasks) all BUILD SUCCESSFUL with zero failures; git diff of */api empty; Detection sweep v1 + Amendment A1 v2 both zero across the four module trees except the recorded FP. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: clear internal references from testing, devtools, and test sources Task 6: full Sweep v1+v2 enumeration over store6-testing, store6-mutations-testing, store6-devtools, store6-devtools-inspector, store6-benchmarks, store6-quickstart, store6-extension-probe, store6-compose-demo, and store6-devtools-demo. Resolves 20 module-scope provenance/referent hits (16 Task-1 baseline unclassified + 9 Sweep-v2 additions, minus one line already resolved as baseline) plus 3 controller-named residue items in already-cleaned store6-core files (StoreDurableMaintenanceConformanceTest.kt, StoreConformanceTest.kt, KeyRegistry.kt). Relabels the Task 3b StoreTelemetryTest.kt:114 inventory row from P1 to P3 to match its P3-shaped edit. Full-tree Sweep v1+v2 gate (store6-*/src) is now clean except previously recorded false positives (test-fixture data literals and error(...) string-literal referents in executable test code). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: interface KDoc audit fixes for alpha01 artifacts Audits every public declaration in the commonMain source sets of the six alpha01 artifacts (628 declarations) against the interface-documentation checklist, records the findings table in the plan inventory, and applies the recorded fixes. Missing contracts written from code evidence: per-constant docs for MutationFailureKind; @return and @throws for MutationStore.mutate; @throws for the mutationStore factory; per-property docs for KeyStatus and FreshnessContext; a class KDoc for FakeStoreInteraction and per-member docs for FakeStore's scripting and inspection surface; a class KDoc for FakeFetcherInvocation; the terminal/nonterminal split on MutationExecutionPhase; the null-wallClock default on SqlDelightSourceOfTruth. Stale and contradictory claims corrected: Freshness.LocalOnly no longer promises fetcher-less stores in a later release; RoomBookkeeper no longer describes RoomSourceOfTruth.withTransaction as a future capability when it ships today. Narration and per-declaration governance stamps removed from StoreBuilder, TestStoreMeta, TestWallClock, and the three store6-compose entry points. Also clears internal referents that neither detection sweep matches (FR-10, R-0 rule 9, C8-15, Rows 3/10, T5.5, T2.2, Decision #37, phase0 item 36, and the remaining "landed" adjectives) from the audited modules. Comment and KDoc content only: no executable token changes, every api dump byte-identical, apiCheck and the six JVM compilations green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: address Task 7 review findings; clear remaining known referents Review findings: - MutationJournalRecords: fully qualify the MutationPendingState link. The file's package is mutations.storage and the type lives in the parent package, which is not in scope for a subpackage and is not imported here, so Dokka rendered it as plain text. - StoreWriteHandle.confirmFresh: split the relocated guarantee back into its own sentence. Joining it to the empty-residence clause with a colon had narrowed an unconditional guarantee to that one branch. - MutationExecutionRecord: document the six properties whose contracts the init block already pins - clientSequence, currentGeneration, attempt, lastAttemptAt, activeFailureId, retiredAt - each written from its own require. The remaining 81 of 92 record properties stay deferred, now scoped to the fields with no init pin behind them. Also clears the last four internal referents, in store6-mutations-testing's contract kit, so no known referent remains outside the recorded protected-content false positives; rewords a tautology left by an earlier parenthetical removal; and reconciles the Task 7 inventory arithmetic, whose row totals, class totals, and scope note disagreed. Sufficient is now 485, computed from declarations rather than by subtracting row counts. Comment and KDoc content only: no executable token changes, every api dump byte-identical, apiCheck and the touched compilations and test tasks green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: source-doc cleanup completion report Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: apply final whole-branch review polish Apply the final whole-branch review's Minor items as one comment/KDoc-only pass, plus four inventory corrections. Source: drop the unsupported "single custom operator" rule claim from StoreResultEquivalence.kt (store6-core states no such rule; only the conflateLatestData operator itself exists); drop "ratified" from internal/FreshnessValidator.kt; fix the drainFailuresForInspection category error and rename the codec-less path's generation comment away from the "in-memory" sense that MutationStoreBuilder.kt uses for journal storage; restate the emptied Iface tier clause in StabilityProbe.kt against what the CI gate actually asserts; repair "nested inside" in three room hostTest comments; document the FreshnessContext.status sibling; repair a mid-sentence comment opening in MutationStoreBuilderTest.kt; reflow nine ragged comment blocks (line breaks only); collapse six one-sentence KDoc blocks that became three-line only because this branch removed their second paragraph. Inventory: remove an invented line-37 citation, correct the TestWallClock evidence note to signature-narration grounds, add the verified parked-row pin (publishDurablePark retires at MutationEngine.kt:2551, MutationJournal retire filters at MutationJournal.kt:313), and record this polish pass plus the accepted-as-is items in the completion report's residue section. Verification: root apiCheck and the five module jvm compiles BUILD SUCCESSFUL; :store6-room:jvmTest (the task covering the hostTest source set) 59/59 green; :store6-testing:jvmTest 54/54 green; :store6-mutations:jvmTest 270 tests, 1 failure — the pre-existing MutationJournalLincheckTest hang already recorded as change-independent, in files this commit does not touch. Both hard sweeps return only the recorded out-of-charter string-literal residue. git diff over */api empty at every scope. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(core): revert two polish wraps per final review Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…CI comments (#32) Extends the alpha01 source-doc cleanup (KDoc/comments) to the surfaces its charter excluded: store6-*/README.md, store6-devtools/EVENTS.md, and workflow comments. Deletes issue numbers, decision/requirement tags (FS-10, OQ-6, OQ-3, DR-3, METRIC-1, NFR-8, TEST-7, Ruling B), sign-off and ratification stamps, personal names, and a pointer to a private non-repo doc. Freeze-status language is aligned with STABILITY.md ("freeze candidate, not frozen"). Workflow YAML is structurally unchanged: store6-benchmarks.yml parses byte-identically to HEAD modulo comments; store6.yml differs only inside one run block's shell comment plus a log-message string in an awk branch that is dead at the shipped iface_strict=1. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The store6 convention plugin never applied org.jetbrains.dokka, so no dokkaHtml task existed for any store6-* module and their KDoc could not be generated or link-checked. Apply the plugin in configureStore6Module() and reuse the existing configureDokka() helper (reportUndocumented=false, skipDeprecated=true, jdkVersion=11), covering both the full and subset plugin variants. Verified: dokkaHtml builds green with real HTML output for all ten store6 modules. Note for future link checks: Dokka 1.9.20 renders unresolved KDoc comment links as plain text without logging a warning (verified with a canary link at --info), so link health must be checked by grepping build/dokka/html for data-unresolved-link, not by reading the build log. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…utations JVM suite (#34) Ruling: 031 remedy ruling: RD-1=3 RD-2=b RD-3=A RD-4=—. Default jvmTest excludes the Lincheck budget via a property-gated filter (census-guarded in both required lanes); the scheduled Store6 full mutations JVM suite workflow (daily + dispatch, 360m) owns the full suite. Demonstrated attempt-1 at 94b9337: CI 25m34s / Store6 25m45s green, census 33/33. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: add AGENTS.md instructing documentation discipline Governs every documentation surface agents touch in this repo: the master test, protected technical content, the no-internal-context rule for code surfaces (with the durable-attribution alternative), evidence-before-claims, byte-identical sibling comment conventions, and the three-pass review. Names the authoring skills as the preferred entry point where available; the inline rules stand alone otherwise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: embed the documentation skills in-repo and point AGENTS.md at them Copies documentation-discipline (2 files) and code-documentation (13 files) verbatim from the authoring plugin into .claude/skills/ so any agent working in this repository gets the full rules without the plugin installed — skill harnesses invoke them by name; anything else reads SKILL.md and references/ directly. AGENTS.md now names the embedded copies as the source of the full rules, with its inline summary standing alone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…suites (#35) CI-green Phase 1.1. MutationEventSurfaceTest carried the plain one-line 25s shadow and MutationOverlayReplayPropertyTest used inline runTest(timeout=25s) at three sites while both make Turbine awaits. Under runner load Turbine's 3s default nested inside the shadow (register class (b) exposure). Both now carry the shim wrapper (TEST_TIMEOUT 25s / TURBINE_DEADLINE 30s) so the shadow is the sole effective deadline. The wrapper matches the established shape; its comment is reworded to the repository documentation discipline (AGENTS.md), which the sibling carriers predate. Coverage determinations recorded: MutationsTestFixtures defines no test runner (its Turbine helper inherits the caller's deadline context). The store6-mutations-sqldelight tree has zero Turbine files. store6-room already carries the shim. Test-only change with no assertion, budget, or production edits. Local proof: both suites green. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ll carriers (#37) Comment-only sweep (36+/36-, 18 files across store6-core, store6-mutations, store6-room). Two legacy variants of the shim comment existed; every carrier now matches the repository documentation discipline shape with byte-identical wording. No code, measurement, or deadline token changed; test classes of all three modules compile. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix(mutations): fence alias projection replay * fix(mutations): snapshot projection state once MutationEngine.kt: projectAll captures one storage-backed runtime snapshot and one tombstone snapshot, then threads their entries and aliases through filtering. Projector application and sequence order remain behaviorally equivalent. MutationEngine.kt: orderedPending and replayableEntries now accept captured entries, aliases, and tombstones. Call-site ripples are pendingForIdentity, pendingWrites, projectAll, pendingRows, nextEligibleHead, and the retireAndActivateAlias legacy rehome branch. Selection, filtering, and FIFO behavior remain equivalent. MutationEngine.kt: pendingWrites derives storage-backed entries and routing from the same runtime snapshot, uses one tombstone capture, and preserves durable client-sequence ordering. MutationJournal.kt: add only InMemoryAliasRouter.aliasesSnapshot for the behaviorally equivalent non-storage call-site adaptations. * refactor(mutations): require storage-backed journals The census found 65 MutationEngine construction sites: one production and 64 commonTest. Product construction already used storage-backed journals. The only non-storage inputs were two RetireOrderingJournal uses and one ClearOrderingJournal use; every aliasHarness caller already supplied the storage-backed default or a subclass. - MutationEngine.kt narrows the constructor, removes redundant storage/null branches, and captures one runtime and tombstone snapshot per projection. - MutationJournal.kt removes the unused InMemoryAliasRouter snapshot accessor. - MutationAckPathTest.kt migrates RetireOrderingJournal and ClearOrderingJournal to in-memory-storage-backed subclasses. - MutationAliasFacadeTest.kt narrows aliasHarness to the storage-backed seam. F2 is superseded and removed: its legacy emitted-stamp bump is deleted and no legacy trigger is added. NonCancellable ordering, alias revision and resolution pulses, live-key cache publication, retirement accounting, source/target emissions, ordering assertions, and projection behavior are preserved. * test(mutations): fence alias projection replay Carry ProjectionRecomputeVisibilityProbeTest from a23ff03 with the approved kotlinx.coroutines.Runnable portability import; keep the probe body unchanged. Add publicFacadeFreshAttachAfterAliasPublication_firstFrameIsCompleteOverlay through the public mutationStore factory with AliasActivationCommitGateStorage holding the post-commit activation boundary. * test(mutations): expose active alias window Add a deterministic fresh-attach regression at the runtime ACTIVE publication boundary. It retains the target head frame and expects the complete head+tail overlay. * fix(mutations): close alias publication window Serialize durable ACTIVE publication and its target fence stamp behind a narrow mutex. Capture facade resolution signals as one close-aware epoch before resolver and delegate work. * test(core): await live reader subscription Replace the reader-factory latch with a subscription-count barrier before releasing the queued-absent fetch. This prevents a zero-replay SharedFlow emission from being dropped before the KeyEngine collector attaches. * docs(core): make projection probe self-contained Describe the pending recompute experiment in durable technical terms. Preserve the first-frame measurement and convergence assertion boundary.
* ci(docs): guard synchronized sources * chore(docs): guard Room sync source (STORE-31)
* docs(store6): publish guide and mutation contracts (STORE-33, STORE-34) * docs(quickstart): certify migration result snippet (STORE-35) * docs(llms): publish only visible guide routes (STORE-33) * fix(mutations-testing): specify purity key type
* docs(dokka): add Store 6 module framing (STORE-28) * docs(dokka): restore guide escape links (STORE-28)
* feat(plugins): add store plugin with Store 6 migration skill Store 6 is unpublished, so coding agents in consumer apps invent its API when porting from Store 4/5. The migrating-to-store6 skill ships verified translation tables and a worked port, with an eval recording the failing no-skill baseline and the passing with-skill run. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(plugins): address store plugin review Replaces the unreal store.cached(key, refresh = true) Store 4 spelling with store.stream(StoreRequest.cached(key, refresh = true)), adds the missing Initial row to the origins table, notes that core's experimental overlay seam can also produce OVERLAY, and ships plugin.json plus schemastore $schema keys for editor validation. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…tor interop over any Store (#47) * store6-paging-androidx: TD-14 mapping, catalog pins, module scaffold, de-risk spikes (T1) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * store6-paging-androidx: StorePagingSource single-shot stream-first load + builder doors (T2) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * store6-paging-androidx: generation watcher — level-triggered invalidation wiring, KeyEvents-free (T3) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * store6-paging-androidx: MobileNativeFoundation#602 tracer — OVERLAY→SOT over MutationStore, honesty-tiered (T4) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * store6-paging-androidx: StoreRemoteMediator boundary-freshness surface (RD-2 shape) (T5) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * store6-paging-androidx: headless four-scene Paging3 sample (roadmap:53 exit) (T6) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * store6-paging-androidx: CI registration (build, sample, gates, apple, klib, JS canary) and ABI dumps (T7) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: update paging release promise Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(store6-paging-androidx): await watcher completion Wait on the completion StateFlow instead of inferring completion from the preceding active-collector decrement. This removes the scheduler-dependent assertion ordering exposed by the Android release unit-test lane. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(paging): harden refresh and watcher lifecycle Use the configured initial load size for mediator refresh keys, preserve Store error causes, and make generation baseline failure and cancellation bounded. Document the pager and namespace lifecycle obligations while removing internal delivery context from tracked documentation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* docs(plans): add STORE-38 data-layer skill plan Records the RED-first plan for the building-a-store6-data-layer plugin skill. * feat(plugins): draft building-a-store6-data-layer skill and eval scaffold (STORE-38) Adds the greenfield Store 6 data-layer skill, Room/SQLDelight/Compose/Swift references, and the RED-first eval fixture plus pass criteria. * test(plugins): record data-layer skill eval runs (STORE-38) Records the RED baseline, with-skill pass (12/12), retrieval probes, and the two SKILL.md gaps closed after the first with-skill notes. * chore(plugins): register data-layer skill, bump store plugin to 0.2.0 (STORE-38) * fix(plugins): data-layer skill review pass (STORE-38) Tighten StoreBuilder wording (DSL receiver exists; StoreBuilder.from does not) and stamp swift.md at 6790606.
* Scaffold store6-graphql module and headless JVM sample
Full 12-target convention plugin, api(store6-core) as the only commonMain
dependency, 6.0.0-SNAPSHOT publishing coordinates, and a placeholder
sample entry point. Sample registers as :store6-graphql-sample with
projectDir store6-graphql/sample, matching the paging sample layout.
Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
* Add GraphQL value model, operation key, and fetcher adapter
GraphQlValue mirrors the GraphQL input grammar with structural equality;
GraphQlOperationKey renders canonicalId as <name>(<canonical vars>) with
UTF-16-code-unit-sorted object keys, JSON string escaping, significant
list order, and explicit null distinct from absent. graphQlFetcher maps
executor outcomes onto FetcherResult: NotModified passes through, errors
follow the partial-data policy (fail by default, adopt on opt-in), null
data without errors is a protocol violation, key/operation mismatch
fails without executing, and CancellationException propagates.
Pinned by GraphQlCanonicalizationTest (17 cases) and
GraphQlFetcherMappingTest (14 cases), green on jvmTest.
Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
* Add store-integration suite over real store { }
GraphQlStoreIntegrationTest exercises the adapter through the engine:
document-cache serve without re-execution (including across variable
insertion orders), concurrent readers sharing one execution, MustBeFresh
re-execution, conditional NotModified emitting Revalidated with ETags
threaded both directions (tolerating the legal cold-baseline self-heal),
and response errors surfacing as StoreError.Fetch frames and
StoreException causes carrying GraphQlOperationException. Fixtures follow
the paging ScriptedPageFetcher shape. 8 cases, green on jvmTest.
Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
* Flesh out store6-graphql sample with asserted scenes
Four scenes over an in-process scripted executor, each check()-asserted:
variable-order-independent key identity, document-cache serve without
re-execution, the fail-vs-adopt partial-response policy split, and
conditional NotModified revalidation with recorded ETags. Exits nonzero
on any failed assertion so CI can gate on the run.
Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
* Wire store6-graphql into store6.yml and commit BCV dumps
Build and sample-run steps after the paging steps; module added to the
core-internal access grep, the TD-8 production-source sweep, the JS and
Apple test lanes, the publish list, and the publication census (full
12-target module, so no census case exclusion). BCV dumps generated via
apiDump with klib cross-compilation enabled.
Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
* Add store6-graphql README
Package promise and boundary (document cache, executor owns the wire),
Maven Local install path, first-result example, entry points, the
canonical-identity contract with the FloatValue cross-runtime caveat,
the response mapping table, conditional-request behavior, and the
asserted sample scenes. Not registered in docs-sync-sources.txt; site
registration is raised in the PR.
Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
… cancellation (#51) cancellationAfterAliasCommit_stillPublishesRevisionAndSwitchesLiveStream asserted provisionalObserved.isCompleted and canonicalObserved.isCompleted immediately after joining the cancelled drain. The emissions complete inside the NonCancellable handoff before join() returns, but the observing collector is dispatched separately, so the asserts raced the collector by one dispatch. Observed on the Android debug lane: canonicalObserved.isCompleted was false. Await both observations instead; the suite-level runTest shadow owns the deadline, matching the sibling regression tests that already await an observation barrier before asserting. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
* feat(store6-realtime): add transport-agnostic realtime push adapter Map app-owned realtime frames onto Store invalidate/adopt/clear through StoreWriteHandle, giving the freeze-candidate write seam a second real producer without changing store6-core. Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com> * fix(store6-realtime): pin etag list types and stabilize the sample Specify String? on the conditional-fetch etag assertions so commonTest compiles, and prove sample adoption through KeyEvents.Written rather than a racy LocalOnly origin read. Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com> * fix(store6-realtime): pin watermark stale-marking and telemetry contracts Correct the README telemetry section so apply/confirmFresh match KeyEngine emission. Rewrite the vacuous MustBeFresh watermark and MutationStore tests to assert FakeBookkeeper.durablyStale and MaxAge refetch. Inline the unused RecordingFetcher.nextValue hook. Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com> * test(store6-realtime): drain the queued pre-clear replay after Deleted deleted_emitsLoadingThenRefetch asserted Loading strictly as the next frame after the Deleted clear, but a fenced clear may queue one duplicate pre-clear Data frame for an already-active pipeline. Adopt the bounded drain shape that core's StoreInvalidationConformanceTest uses for the same window. Observed on the Android release lane: assertIs<Loading> received Data(fetched-1). Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Matt Ramotar <matt-ramotar@users.noreply.github.com>
Records ancestry with upstream's store6 tip (f45df77, the Store 5 build modernization) while keeping main's tree byte-for-byte. The following commit removes the Store 5 modules from this branch, so the modernization has no remaining scope here; Store 6 modules stay on their pinned toolchain.
Deletes the store, cache, multicast, rx2, and core modules and their settings.gradle includes; no store6-* module depends on them. Drops the kover build step and Codecov upload from CI (kover was applied only in the store module) and the KMMBridge Swift-package workflow (only the Store 5 convention plugin applied KMMBridge). Adds store6 to the CI, Store6, and benchmarks workflow branch filters so pull requests into store6 and pushes to it run the same gates as main. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
store6...matt-ramotar:Store6:main— ontostore6with the original SHAs preserved (merge, not rebase).store6with the ours strategy. The base tipf45df778(MobileNativeFoundation/Store#736) is a Store 5 build modernization (Gradle 9.6.1, AGP 9.3.0, Kotlin 2.3.21) that conflicts with Store 6's pinned toolchain in 10 root build files. Since this PR also removes Store 5, that modernization has no remaining scope on this branch; Store 6 stays on its CI-proven toolchain (Gradle 8.11.1, AGP 8.10.0, Kotlin 2.3.20)..editorconfigandKMMBridge-Release.ymlfrom Build modernization: Gradle 9.5, AGP 9.2, Kotlin 2.3, and tooling updates MobileNativeFoundation/Store#736 intentionally do not carry over.store,cache,multicast,rx2, andcoremodules and theirsettings.gradleincludes (166 files, −15,469 lines). Nostore6-*module references them (verified by sweep).koverXmlReportand the Codecov upload; kover was applied only in thestoremodule.create_swift_package.yml; it drives KMMBridge, which only the Store 5 convention plugin applied.store6to the CI, Store6, and benchmarks workflow branch filters so PRs intostore6and pushes to it run the same gates asmain.Docs-sync note
The docs-sync guard flags this PR because the diff against
store6includes synced sources (STABILITY.md, ROADMAP.md, module READMEs) carried by the 51 commits. The docs site pinsmainrevisions, andmainis unchanged by this PR, so no re-pin is triggered by merging it; thedocs-sync-acklabel acknowledges the guard.Intentionally untouched (follow-up candidates)
tooling/plugins(they compile standalone).kover,rxjava,kotlinx-coroutines-rx2).rootProject.name = "Store5"and Store 5 mentions in README, STABILITY.md, llms.txt, and thegradle.propertiesPOM description.Test plan
git merge-base --is-ancestor;store6..HEADis exactly 53 commits (51 + ours-merge + removal commit)../gradlew :store6-core:compileKotlinJvm— BUILD SUCCESSFUL (settings and convention plugins configure cleanly without the v5 modules).Made with Cursor