Consume octi-desktop's published wire-format fixtures#319
Merged
Conversation
Adds d4rken-org/octi-desktop as a second pinned source on app-main's multi-source fixture-lock.json and ships per-module Desktop*InteropTest files that decode each payloadJson through the production decoder. Desktop's wire shape differs from web in places — SharedFile.blobKey is a plain UUID (not sha256:<hex>), deviceBootedAt emits a real Instant for the full meta vector — and the tests pin those values. Multi-source infrastructure from B2 reused as-is. SyncRefResolverTest gains a multi-source resolveAllFromEnv regression test that goes through the full env → parseOverrides → resolveAll path so SOURCE_PATHS validation is exercised end-to-end. Pairs with octi-desktop#56 (the producer).
This was referenced May 21, 2026
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.
What changed
No user-facing behavior change. Internal: app-main now consumes
d4rken-org/octi-desktop's published wire-format fixtures alongside the existingd4rken-org/octi-webones. A serializer change in either producer that drops a required field, retypes a value, or renames an enum entry breaks the matching consumer test here.Mirror of B2 (
d4rken-org/octi#318, merged) pointed at the second producer. The multi-source v2 lockfile + sync infrastructure landed in B2 already supports two (or more) sources; this PR just wires up the desktop entry.Technical Context
fixture-lock.json.d4rken-org/octi-desktop @ 1e00e71fc60841fda80d7db4f630aa99b1112c9d(the C1 merge SHA), manifest_sha256ce2fd860ff124599bfc61a94f824c17c521cf79d744f06bc3551e284e6a37fe4. The existingd4rken-org/octi-webentry is untouched. Each source bumps independently; one stale entry doesn't poison the other on cache (though the first sync call still does fetch both — see note inInteropFixtureSync.kt).SyncRefResolver.SOURCE_PATHSgains"d4rken-org/octi-desktop" to "src/test/resources/interop/published". The doc comment was sharpened along the way ("Keep in lockstep across all three" → "for any shared source, the path string must agree across consumers") — the registry is subset-based per consumer, not a single global allowlist.Desktop*InteropTestfiles, one per module, sitting next to the existingWeb*InteropTestsiblings. Each callsInteropFixtureSync.ensureSynced("d4rken-org/octi-desktop")in@BeforeAll, parses every vector through the production decoder, and asserts field-by-field against octi-desktop's canonical inputs inInteropFixtureGenerator.kt.MetaInfo.deviceType = DESKTOP(not BROWSER like web).MetaInfo.deviceBootedAt = Instant.parse("2026-05-01T10:00:00Z")in thefullandunicode-labelvectors. Desktop'sMetaWritercallsProcessHandle.startInstant()and emits a real Instant — never null, unlike web.minimalmeta vector'sdeviceBootedAtis absent on the wire (the test pinspayloadJson.contains("deviceBootedAt") shouldBe falseANDinfo.deviceBootedAt shouldBe nullso a future shift from "absent" to "explicitly null" is caught).SharedFile.blobKeyis a plain UUID (00000000-0000-0000-0000-000000000001), NOT thesha256:<hex>shape web/android use. Verified viaFileShareRepo.kt— desktop callsUUID.randomUUID().toString(). Consumers see two differentblobKeyshapes on the wire depending on which producer wrote the payload; the dashboard treats the string as opaque so the asymmetry is fine. Codex confirmed app-main itself also emits UUIDs for its own blobs.kserver-prod.kserver.octi.darken.eu-77777777-...vs web'saaaaaaaa-...). Routed throughConnectorId(...).idStringon the producer side so a future format change propagates.SyncRefResolverTestgets one new regression test + one comment cleanup. The renamedresolveAllFromEnv throws when override targets a source not present in the locknow goes through the full env → parseOverrides → resolveAll path (was directly hittingresolveAll, which bypassed SOURCE_PATHS validation). A newresolveAllFromEnv applies an override to one source of a multi-source lock and leaves the other anchoredtest pins the exact path the C4 cross-repo workflow will exercise: override desktop, leave web on its locked ref + manifestSha256.InteropFixtureSyncdoc comment softened. The previous "per-source independent" framing was misleading: cache directories are per-source, but the firstensureSynced()call syncs all sources before any test executes. Codex flagged this; the doc now states it explicitly.Review guidance
d4rken-org/octi-desktop— verified by fetchingmanifest.jsonat that SHA andsha256sum-ing it.sha256:would surface here.Test plan
./gradlew :sync-core:testDebugUnitTest :modules-meta:testDebugUnitTest :modules-clipboard:testDebugUnitTest :modules-files:testDebugUnitTestgreen on cold cache (fetched both octi-web and octi-desktop fixtures).DesktopMetaInteropTest, 4 inDesktopClipboardInteropTest, 7 inDesktopFilesInteropTest, +1 new resolver test.Web*InteropTestfiles untouched and still pass — the two consumer test families coexist without coupling.main).Sister PRs: