Previously POST returned only { id, name }, while GET returns
{ id, name, state, lastOutputAt }. iOS clients that share a Decodable
for both endpoints (e.g. SessionItem in pi-remote-ios) failed to decode
the POST response with 'data couldn't be read because it is missing'.
The new session always starts in 'idle' state with empty lastOutputAt.
Documented the new shape in the route header comment.
Open `PHASE-1-sidecar.md` §Interface Contracts and re-read IC-1..IC-4.
### Bug backlog (not regressions, pre-existing)
For each: does it still look right after the spikes? Anything to tweak?
Things to double-check:
- **Keychain unit tests fail with `-34018` errSecMissingEntitlement** (4 cases).
- **IC-1 ClientToServer**: do we want to add `{ type:"resize"; cols:int; rows:int }` so iPad-Landscape can renegotiate tmux pane size? (Spec said fixed 120×40, but if we ever want elastic, this is the place.) Recommendation: defer, fix at 120×40 for v1, revisit only if it bites.
Likely needs Keychain-Access-Group in the test target's entitlements,
- **IC-1 ServerToClient**: `tree` event — gruppe T is out of iOS scope, so this can be dropped from the contract OR kept as "reserved, server may emit but client ignores". Recommendation: drop to keep contract tight.
or running under signed bundle. Investigate or skip with a documented reason.
- **IC-2 REST shape**: `/sessions/:id/thumbnail` is referenced by iOS-D-01c (Phase 3). Should the endpoint return raw text/plain capture, or a structured JSON `{cols,rows,lines:[…]}`? Recommendation: raw text/plain — simpler, smaller, client parses lines itself.
- **Pairing unit tests `testParseQR_{http,https,wrongScheme}_throws` fail**
- **IC-3 pairing**: `deviceToken` and `environment` are now mandatory in Phase 2. Pre-Phase-2 they're optional. Mark accordingly.
(4 cases). Either the parser silently accepts http/https now (regression
- **IC-4 TOML config**: `[apns]` section can have an `environment_default` for testing convenience? Probably no — environment is per-device. Leave as-is.
hidden by the `fp` optional change) or the tests need updating to match
the new lenient behaviour.
After review:
### Phase 3 — not yet in scope
- Edit `SYNC.md` "Frozen Interface Contracts" table: set Status `frozen` and fill `Frozen at` date.
- Commit on main.
### 2. Dispatch T-1.0 — Server Refactor
Slash palette, voice, themes, search, etc. See `docs/PHASE-3-ios-augmentation.md`.
Single agent, blocking everyone else. Refactor existing
`extensions/remote-control/server.ts` (335 lines) and friends into the
modular layout from `PHASE-1-sidecar.md` §Architecture Sketch.
Prompt template (adapt with concrete contract numbers):
```
# Task: Phase 1 T-1.0 — Server Refactor
Working dir: /Users/jay/.pi/agent/git/git.vpsj.de/jay/pi-remote-control
Read first:
- docs/NEXT-STEPS.md (state of play)
- docs/PHASE-1-sidecar.md §Architecture Sketch and §Task Breakdown row T-1.0
5. Spec only if you forget the why: `docs/reference/SPEC-ios-app.md`
6. Spec only if you forget the why: `docs/reference/SPEC-ios-app.md`
---
---
## Open questions for next session
## Conventions established
- ~~**OQ-1.** Drop the `tree` event from IC-1 ServerToClient~~ — **resolved**: dropped. IC-1 frozen 2026-05-15.
- **Async subagent dispatch.** All worker tasks via `subagent({ async: true, context: "fresh" })`. Worktree isolation for parallel-on-same-repo work; same-repo iOS+sidecar splits are inherently isolated.
- ~~**OQ-2.** Resize message in IC-1?~~ — **resolved**: deferred, fixed 120×40 for v1.
- **Reviewer fan-in.** After parallel implementation, dispatch one reviewer agent with all branch summaries pre-loaded; reviewer writes `review.md` for the orchestrator to apply.
- ~~**OQ-3.** tmux control-mode connection per-server vs per-session?~~ — **resolved**: per-session (like the spike). Simpler, spike reference code exists, isolates parser state per session. Refactor to per-server later if scale demands it.
- **Sim test infra (`--uitest` mode).** Pre-fetch a fresh `/pair-qr` token per test, launch with `--reset-state --pair-with-url <url>`. `MainTerminalView` in `--uitest` mode skips the WS so XCUITest can reach app-idle within the 120 s window. Pasteboard prompt suppressed via `xcrun simctl privacy grant pasteboard de.vpsj.pi-remote`.
- ~~**OQ-4.** Worker model for T-1.0?~~ — **resolved**: `anthropic/claude-sonnet-4-6` with `context: fresh`. Haiku rejected: previous swarm attempt produced broken imports across `index.ts`/`html.ts`/`messages.ts` even on a stronger model (see deleted `feat/p1-t1-0-server-refactor` branch). T-1.0 is the blocker for all parallel fan-out — reliability over cost.