feat(ios): extract an atomic host-readiness state machine core (slice 1) - #313
Open
CompleteDotTech wants to merge 6 commits into
Open
Conversation
Extract the first focused iOS replacement slice from PR OpenCoven#193: a HostReadinessMachine that makes host readiness atomic, deterministic, and unable to expose a newly fetched workspace as authoritative. - Pure transition table (HostReadinessTransitions) over the issue OpenCoven#241 state contract: unknown, discovering, pairing, authenticating, host_committed, synchronizing, ready, degraded, reconnecting, revoked. - HostReadinessMachine commits authoritative paired-host identity through a secure-store adapter BEFORE any workspace snapshot is validated or applied; ready is reachable only through that committed spine. - Deterministic rollback per boundary: transport, authentication, secure-store, decode/revision, workspace-apply, revocation. A failed new host leaves no state; a previously authoritative host's workspace stays visible labeled stale (stale is semantically distinct from live, with the previous confirmed-at timestamp preserved). - Wrong-host identity and revocation fail closed without overwriting committed authority; concurrent or superseded flows cannot commit or apply (single active flow, superseded flows rejected). - Exhaustive transition-table tests plus machine behavior tests covering every rollback boundary and the concurrency guard. Slice 1 of the OpenCoven#241 decomposition (readiness core); discovery UI, app composition, and lifecycle coverage follow as later slices. Refs OpenCoven#241 Signed-off-by: Timothy Wayne Gregg <5861166+CompleteDotTech@users.noreply.github.com>
|
@CompleteDotTech is attempting to deploy a commit to the 0xBuns Team on Vercel. A member of the Team first needs to authorize it. |
CI caught two things on the first head: the non-transport failure table did not handle the degraded state (switch must be exhaustive), and the table's tests asserted the pre-slice pairing behavior instead of the retarget flow that atomic authority actually protects. - the authentication/secure-store/decode/revision/workspace-apply table now handles degraded explicitly: resting states own no flow, so a failure event is inert there and recovery starts a new flow; - pairing may start from ready — pairing a new host while one is ready is exactly the retarget flow whose authority must be atomic — while it stays rejected inside an in-flight flow and from degraded; - the discarded rollback results are discarded explicitly, matching Swift 6 strictness; - transition tests updated to pin the corrected table (including the ready→pairing retarget edge and the two new rejections). Refs OpenCoven#241 Signed-off-by: Timothy Wayne Gregg <5861166+CompleteDotTech@users.noreply.github.com>
The pull_request synchronize run for 5ecdf72 did not start within 15 minutes of the push (no run, zero check-runs on the head SHA, and the PR object still reporting the prior head). An empty commit nudges a fresh synchronize event; no content changes. Refs OpenCoven#241 Signed-off-by: Timothy Wayne Gregg <5861166+CompleteDotTech@users.noreply.github.com>
The machine source compiled; the readiness test additions did not. XCTest assertion autoclosures cannot contain `await`, so actor property reads are hoisted into locals before asserting. Also fixes one test that referenced the wrong binding for the still-committed host and makes the shared drive-to-ready helper @discardableResult so every call site stays warning-free. Refs OpenCoven#241 Signed-off-by: Timothy Wayne Gregg <5861166+CompleteDotTech@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- the workspace-apply rollback test forgot the accumulated boundary log from establishing the previously authoritative host; - the degraded-recovery test kept the apply-boundary failure stub armed into the recovery flow, so the retry's apply legitimately failed. Clear the stub before the recovery spine runs. Refs OpenCoven#241 Signed-off-by: Timothy Wayne Gregg <5861166+CompleteDotTech@users.noreply.github.com>
CompleteDotTech
marked this pull request as ready for review
August 30, 2026 16:51
…ract-an-atomic-ios-host-readiness
5 tasks
BunsDev
requested changes
Aug 31, 2026
BunsDev
left a comment
Member
There was a problem hiding this comment.
Keep this as the active first iOS gate, but fix the actor reentrancy boundary before merge. revoke() can interleave while external commit/apply adapters are awaited, leaving durable or visible state changed while the machine reports revoked/superseded. Add adversarial revocation/supersession tests and make publication atomic or compensatable, then request independent R3 review.
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
Extracts the first focused iOS replacement slice from PR #193: an atomic host-readiness state machine in
PsycheCore, implementing the exact ten-state model required by issue #241 —unknown,discovering,pairing,authenticating,host_committed,synchronizing,ready,degraded,reconnecting,revoked(raw values are the contract names; case names follow repository Swift style).What the machine enforces:
commitHostIdentity(_:for:)persists the authoritative paired-host identity and selected-host state through a secure-store adapter before any snapshot can be validated or applied.readyis reachable only through the spineauthenticating → host_committed → synchronizing → ready, and onlysynchronizeWorkspacecan set it, after decode/revision validation and workspace acceptance both succeeded. There is no code path where a secure-store failure leaves the new workspace visible while readiness reports failure — the apply adapter cannot run after a failed commit.HostReadinessTransitions). No failure path labels newly fetched state asready; no failure leaves a success-shaped workspace.HostWorkspacePresentationis.noState,.live(hostID:confirmedAt:), or.stale(hostID:confirmedAt:). A previously authoritative host's workspace stays on screen labeledstale(previousconfirmedAtpreserved); a failed first host leaves no state at all. Beginning any readiness flow relabels a live workspace stale immediately — the single transport is about to be retargeted, so the visible workspace cannot vouch for itself.beginPairing/beginReconnectionis refused, and a superseded flow cannot commit or apply anything (every boundary call is flow-bound).HostReadinessAdapters(commit / validate / apply) is the whole integration surface — no Bonjour discovery, no selection UI, no physical-device logic in this slice, exactly as issue Extract an atomic iOS host-readiness state machine from PR #193 #241 requires.Slice 1 of the #241 decomposition (per the 2026-08-24 disposition on PR #193): the readiness core + its contract + deterministic tests. Remaining for later slices: composition into
ConnectionManager's readiness finalization path (replacing the pre-#241 ordering), rebasing PR #193's Bonjour/manual/re-pair UI onto this contract, lifecycle coverage (restart, host restart, foreground/background, Wi-Fi interruption, credential expiry), and physical same-LAN acceptance.Scope note: file placement and size
New types live in
PairedHost.swift(Pairing domain, wherePairedHostandPairingStatusalready live) and their tests inPairedHostStoreTests.swift. This keeps the generated Xcode project untouched: adding a new.swiftfile requires regeneratingPsyche.xcodeprojwith the pinned XcodeGen 2.45.4, which only runs on a macOS host — and hand-editing generated output is not allowed by repository policy. Re-homing intoHostReadiness.swiftis a mechanical move for a slice that next regenerates the project.The change is 1,366 added lines (569 source + 797 tests), above the ~800-line split heuristic. The test file carries the issue's explicit requirement that tests cover every allowed transition and every rollback boundary (23 new tests: the full transition table, all five failure boundaries × with/without prior authority, stale-state preservation, wrong-host/revocation fail-closed, supersession, and concurrency). Splitting the tests from the table they verify would make both harder to review; splitting them into a second PR would land the untested machine.
Issue
Refs #241
Closes #241
Risk class
Test plan
pnpm typecheck— passed locally (Node 24.16.0, pnpm 10.34.5,--ignore-scriptsinstall).pnpm test— 4,791 passed / 57 failed / 11 skipped. All 57 failures reproduce on a pristine checkout ofmain(verified by stashing this change and re-running) — they are environmental on this Linux host (notmux, sandboxed process groups; e.g.gitMutationSupervisor.test.tsfails 4/4 with the change stashed). None touch iOS or the changed files.pnpm vitest --run __tests__/repositoryMapContract.test.ts— 4 passed (repository-map contract unchanged).xcodebuild test -scheme PsycheCore) — deferred to CI; no macOS/Xcode host available for this change. This is where the 23 new machine tests run.pnpm ios:project:check— expected clean: no generated file changed, file set unchanged.Validation and evidence
Proof gaps, stated plainly: Swift compilation and test execution are proven only by CI on this PR's head; no local iOS evidence exists. No production-path, physical-device, or TestFlight claim is made or implied by this slice.
Generated outputs
Psyche.xcodeproj, noInfo.plist, no docs generation diff.)Authority/security impact
New
HostReadinessMachinetype only; no existing persistence format, wire protocol, command, or security boundary changes in this slice. The machine's contract is designed so composition (next slice) can only apply a snapshot after the secure-store commit succeeded — the fix for the contract-level finding recorded on PR #193 (finalizeWorkspaceReadinessordering). Rollback: revert the single commit; nothing persisted changes format or behavior.