~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/atirc-ios-client

0
1
main
110 lines · 6.1 KB Raw History

iOS embedded kcp — plan

Status: 2026-10-30. Lead: atirc-ios-client-dev.

Canonical cross-repo plan: socialweb-computer-kcp docs/plans/0038-ios-embedded-kcp.yaml (plan owner linux-kcp). This file is the app-side milestone plan; 0038 is the system view. Item mapping: M1/M2 = I1-BOOT + I2-RUNTIME (done), M2 = I3-PERSIST, M5 = I5-OAUTH, M3 = I4-SOCIALWEB-IOS (linux-kcp) + I6-POLICY-SANDBOX (linux-kcp) + I7-AGENTS, M4 = I8-ASK-OWNER, device e2e = I9 (linux-kcp).

Goal: run the real kcp control plane and the socialweb requester inside the AT-IRC iOS app so the app can launch and manage agents through the same market request flow the web page uses.

Architecture (locked decisions)

  • One Go runtime per process. A combined AtircGo.xcframework (package github.com/kcp-dev/kcp/contrib/wasm/ios/atircgo, built with gomobile) contains both the app's IRC helpers and the kcp bridge. Linking a second gomobile framework (e.g. a separate KCPGo) crashes at launch: duplicate Go runtimes. Never add another Go framework; extend atircgo.
  • No sockets. contrib/wasm/real boots kcp over an in-process net.Pipe listener/dialer with memory:// storage. The apiserver never binds a port.
  • Storage. The patched apiserver memory backend (KCP_PATCH_MODE=native, k8s.io/apiserver replaced with the patched copy) plus contrib/wasm/storage snapshot/restore. kcp root lives in Application Support/kcp; the service-account key is ECDSA P-256.
  • Memory. KCP_MEMORY_STORAGE=main, KCP_LOW_MEMORY=1 (watch cache off, short watch history), debug.SetGCPercent(25) after ready, and a debug.SetMemoryLimit(1 GiB) soft limit. iOS jetsam is the limit, not wasm's tab heap; measure on a device and raise the limit if the requester needs it.
  • Bridge API (Swift): AtircgoKCPStart(root, snapshot), AtircgoKCPRequest(method, path, headersJSON, body), AtircgoKCPSnapshot(), AtircgoKCPReady(), AtircgoKCPStatus(), AtircgoKCPStop().
  • Build. Regenerate the native patched modfile, then gomobile bind -target=ios,iossimulator -ldflags="-s -w" into GoLib/AtircGo.xcframework. The app links AtircGo and -lresolv (Go's BIND resolver symbols). Build artifacts are large; keep the release dirs pruned.

Milestones

  1. M1 — boots (done). kcp boots in-process on darwin and iOS; /version and /apis return 200; combined framework builds; app compiles and shows a kcp status bar.
  2. M2 — simulator e2e (done). Launch in simulator, kcp reaches ready, status bar shows kcp state. Snapshot persistence implemented: save after ready and on scenePhase background to Application Support/kcp/snapshot.b64 (1.3 MB after a cold boot), restore on launch, fail-closed drop of an unreadable snapshot. Verified across terminate/relaunch; kcp ready again.
  3. M3 — socialweb + agents (I4 integrated). The Agents tab starts kcp lazily (8.7 s in the simulator), then the embedded socialweb requester against the same kcp (ready ~2.7 s later), and shows "socialweb requester ready". The Agents API creates the session EphemeralInfra and applies ComputeContract entries with spec.agent; Release/revoke remain for I7. Launching is still unavailable/denied until (a) linux-kcp's I6 policy sandbox runs the requester's tangled-vouch, and (b) pkg/embedded exposes the page's PutContractSecrets (the ATIRC_TOKEN bundle written before the contract). Both requested.
  4. M4 — ask-owner UI (done, runtime pending deploy). Pending list, answer sheet, availability toggle, decided/ADR rows, local notification when mode is available. Uses the account-level minted atirc token per path (a). Live calls 401 until atirc-dev deploys the server change that adds the five ask NSIDs to the minted token scope.
  5. M5 — OAuth scopes (done in simulator). iOS metadata and authorize request carry 28 scopes = exact requester-scope.txt (27, r131) plus rpc:chat.atirc.revoke?aud=did:web:irc.fedfork.com%23atirc; dedupe when socialweb rc133 generates revoke itself. Scripted alice sign-in in the simulator succeeded end to end (OAuth -> loopback -> DPoP -> mint, 28/28 granted). Device signing/TestFlight pending.

Workstreams and owners

  • kcp core, framework build, app integration: atirc-ios-client-dev (lead).
  • ask-owner iOS UI + notification: subagent ask-owner (scope now iOS-only; server/CLI owned by atirc-dev/atirc-ask).
  • OAuth full scopes + Agents nav: subagent scopes-agents.
  • Server XRPC (ask/answer/decide/questions/owner_mode), token scopes: atirc-dev / atirc-ask.
  • Wasm reference flow (page) and native-overlay guidance: wasm; source tree /Users/johnandersen777/src/linux-kcp/kcp-wasm-mac is read-only.

Risks / open decisions

  • Memory: watch cache off + GOGC 25; measure with a VM lifecycle. Watch jetsam.
  • Snapshot size/write cost: write on a debounce (page uses >=15 s gap + 3 s trailing), never on every mutation.
  • Background: iOS suspends the app; kcp and the requester stall. A release asked before suspension finishes on the next launch from persisted state; ask iOS for background time to finish it first (0038 agents decision).
  • Policy: the requester runs requester-tangled-vouch; iOS has no deno, so it fails closed until linux-kcp's iOS policy sandbox provider (I6) sets PolicyEngine spec.sandbox with a Prober/Fenced condition. No contract is created while the policy cannot run.
  • Credentials: ~/.aliceoa_bsky_social_source is sourced only inside the sign-in command; values never printed/logged/copied; sign-in URLs never posted.
  • App repo is not a git checkout; keep edits local and coordinate files between the lead and subagents.

Verification

  • Host smoke: go build -modfile=.go.memory.mod ./contrib/wasm/ios/cmd/kcpsmoke then run; expect real: ready, /version 200, /apis APIGroupList.
  • Framework: gomobile bind ... atircgo; headers expose AtircgoKCP*.
  • App: xcodebuild -project AT-IRC.xcodeproj -scheme AT-IRC -destination 'generic/platform=iOS Simulator' build; install/launch in the booted simulator; screenshot status bar shows kcp: ready · <gitVersion>.