Plan · Code Raven · 2 September 2026

Code Raven Mobile

An iOS companion for reading, composing and capture. It carries every project's Foundation in your pocket, assembles context-loaded prompts you paste into Claude or ChatGPT, and takes the results back as captures or off-site meetings.

35Tasks
5Phases
5Screens
0Network calls
The gist

Three pieces. The macOS app exports a versioned sync pack per project into an iCloud container. The iOS app reads those packs, renders them, and composes prompts from a scoped slice of them straight to the clipboard. The iOS app writes captures and pasted results into an inbox folder, which the macOS app imports through the same bridge pattern it already uses for .claude/quick-tasks/.

No model API. No network layer at all. The phone talks to iCloud and to the pasteboard, and that is the entire surface.

The problem

Everything Code Raven knows lives on one Mac. Ideas arrive in the car, at the hardware store, on a walk. Brainstorming with Claude on the phone means working from memory or pasting a stale export by hand. There is no way to read a plan, check a Foundation decision, or think through a feature away from the desk, and no way to get the result of that thinking back into the project.

Approach

One repo, two apps

The iOS app lives at Mobile/ inside this repository, generated by XcodeGen from Mobile/project.yml. XcodeGen is already installed and the iOS 26.2 SDK is present, so the project can be generated and compiled without opening Xcode — which is what makes an unattended pass viable at all.

Transport is an iCloud ubiquity container, not a server

Container iCloud.com.lochlustra.Code-Raven, shared by both apps. macOS writes packs; iOS reads them and writes only to inbox/. Both sides treat it as a dumb file drop, the same shape as every bridge Code Raven already runs.

AI is clipboard-mediated, matching the desktop grammar

Code Raven already hands work to Claude by assembling a prompt and copying it — NotePlanningPromptBuilder, Copy HTML, Copy Foundation Layer. Mobile does the same. The app assembles context plus your question, copies it, and you paste it wherever you like. The result returns through a paste field.

There is no networking code in this app

No URLSession, no API key, no Keychain, no ATS configuration, no streaming parser, no rate limits, no cost. That is a large amount of surface area that simply does not exist — and it is the surface an unattended overnight pass is least able to get right.

Decisions made for you

Judgment call

The pasted transcript is stored as one string

Splitting someone else's conversation into turns is guesswork. The record carries the text verbatim and an assistant field; the Mac renders it as a block and can summarize it later if that turns out to matter.

Judgment call

iCloud Drive rather than CloudKit or a server

CloudKit means a schema, a sync engine and conflict handling. A file drop means neither app needs to know the other exists.

Judgment call

Read-only on the phone

No checking off plan tasks, no editing notes. Two-way editing over a file drop means last-write-wins data loss or a merge UI. The phone writes only new records.

Judgment call

A context scope picker instead of assembling everything

All nine Foundation layers plus blueprints is a paste of several hundred kilobytes. Mission plus personas is roughly 60 KB, and for design work visualdesign and uiux carry the signal the rest dilutes.

Judgment call

Foundation ships as markdown, not JSON

Smaller on the wire, keeps Foundation's decoding rules on one side of the boundary, and markdown is what gets pasted into a chat box anyway.

The work

Phase 1 — Project scaffolding

5 tasksNothing else compiles until this lands.
  • Create Mobile/project.yml for XcodeGen targeting iOS 26.2 with bundle id com.lochlustra.Code-Raven-Mobile
  • Set DEVELOPMENT_TEAM to X7BPXRX9NA in the generated target
  • Add the iCloud container entitlement for iCloud.com.lochlustra.Code-Raven to the iOS target
  • Add the same iCloud container entitlement to the macOS target's Code_Raven.entitlements
  • Generate the project with xcodegen and confirm it compiles against the simulator SDK

Phase 2 — The sync contract

9 tasksBoth apps. The load-bearing agreement.
  • Define the shared Codable models for manifest, pack, and inbox records
  • Reject inbox records missing type or id rather than defaulting them
  • Build MobilePackExporter on macOS that renders Foundation layers to markdown
  • Write the manifest and one pack per project into the iCloud container
  • Re-export a project's pack when its Foundation, plans, or notes change
  • Build MobileInboxImporter on macOS following the existing bridge importer pattern
  • Move consumed inbox files to inbox/processed rather than deleting them
  • Add an offsite case to MeetingFormat so imported conversations land as meetings
  • Render an imported off-site transcript as a single block in the meeting detail view

Phase 3 — The iOS app

6 tasksReading and capture. Useful before Compose exists.
  • Build the iCloud container reader with a metadata query that watches for pack changes
  • Build the Projects list screen from the manifest
  • Build the Project reader with Foundation, Plans, Chronicle and Pursuits segments
  • Render markdown with a reusable view that handles headings, lists and code blocks
  • Build the Capture screen with project picker, tag picker and one-tap save
  • Write captures into the iCloud inbox folder as capture records

Phase 4 — Prompt composer and return path

8 tasksThe only AI path, so it gets designed rather than bolted on.
  • Build the prompt assembler that joins preamble, context slices and user text in order
  • Build the context scope picker defaulting to mission plus personas
  • Show assembled character count and approximate token count before copying
  • Add the three presets: brainstorm a feature, review this plan, think through a pursuit
  • Copy the assembled prompt to the pasteboard with a confirmation
  • Build the paste-back field that accepts a reply or a full conversation
  • Let the paste-back be saved as either a capture or an off-site meeting
  • Emit the existing Code Raven prompt text where a desktop builder already covers the job

Phase 5 — Verification

2 tasks
  • Build the iOS target for the simulator and fix every compile error
  • Build the macOS target and verify the product with scripts/verify-build-product.sh

Manual Testing

5 tasksYours — signing and device behaviour cannot be verified from a terminal.
  • Sign both targets and confirm the iCloud container appears on the deviceyou
  • Confirm a pack written on the Mac appears on the phone within a minuteyou
  • Confirm a capture made on the phone lands in the right project's Scratchpadyou
  • Paste a composed prompt into the Claude app and confirm the context reads cleanlyyou
  • Paste a reply back and confirm it appears in Code Raven as an off-site meetingyou

Risks & edge cases

Blocks the device build

Signing cannot be done unattended

The iCloud container has to exist in the Apple Developer portal and be enabled for both bundle ids. Claude Code can write the entitlements; the container will not provision itself. Expect a trip through Signing & Capabilities before the first device run.

Accepted trade

The return path is manual

Nothing extracts a conversation from the Claude or ChatGPT app automatically. Getting a result back means select, copy, paste into Compose. If that friction is what stops the loop being used, the fix is the model API — deferred here, not rejected.

Ergonomics

A large paste is visually heavy

Mission plus personas is roughly 60 KB. iOS handles it on the pasteboard fine, but some chat inputs render it slowly. This is why the size indicator exists and why full scope is never the default.

Edge case

iCloud propagation is neither instant nor ordered

A pack may arrive before or after the manifest that references it. Tolerate a manifest entry whose pack has not downloaded, and call startDownloadingUbiquitousItem rather than assume the file is local.

Watch

The macOS entitlements file is empty today

The iCloud container is the first entitlement it will carry. Verify the Mac app still launches and still reads ~/Developer afterwards — entitlement changes can quietly re-enable sandboxing.

Decoding

An all-defaulted decode can never fail

Every inbox field defaults except type and id. Without that, any stray JSON in the folder becomes a valid record — the trap this codebase has already hit once.

Out of scope

Final review

Dropping the model API took the riskiest code out of the plan. SSE streaming, Keychain handling and refusal branching written blind, with no device and no way to run them, was the part of the previous draft most likely to look finished and not work. What replaces it is a string builder and a paste field, both of which are verifiable in the simulator.

The cost is that the return path is now a human copying text. That is a real loss and worth watching — if the loop goes unused, the friction is where to look first.

The weakest remaining piece is the markdown renderer. "Handles headings, lists and code blocks" hides a day of fiddly work, and Foundation content is dense. If one phase overruns, it is that one.

84/100

Up from 76 on the API draft. The architecture is unchanged and still matches how this codebase works, but the novel-and-unverifiable third of the code is gone. What remains is iCloud file handling, SwiftUI reading surfaces and string assembly. Held below 90 because nothing can be verified on device overnight, the entitlement change touches a macOS app that currently carries none, and the reading experience will need real taste applied in the morning.