~ 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>`.