This repository is large enough that the main efficiency problem is usually not model intelligence: it is feeding an agent irrelevant code, duplicate instructions, and unstable request prefixes. This playbook keeps the shared project memory small, makes changes local, and preserves Harness behavior.
AGENTS.md is the source of truth for shared rules. CLAUDE.md imports it, and .github/copilot-instructions.md is a short entry point for Copilot. Do not maintain three long copies. Store personal machine choices in ignored CLAUDE.local.md, never in tracked instructions.
Nearest-directory AGENTS.md files are intentionally short and load only for the relevant module:
| Scope | Why it exists | First verification |
|---|---|---|
HarnessMobile/App/ |
UI/lifecycle composition and the AppModel boundary | affected AppModel/UI tests |
HarnessMobile/Core/Agent/ |
ordered model loop, compaction, cancellation, caching | AgentRuntimeTests, ConversationCompactorTests |
HarnessMobile/Core/Plugins/ |
manifest/Host/Cordis safety and compatibility | NativeAgentPluginTests, Host check |
HarnessMobileTests/ |
characterization and real-device evidence rules | narrow target, then package suite |
When using Claude Code, path-scoped rules may later be added under .claude/rules/ only for a rule that cannot fit in the relevant AGENTS.md. Do not add unconditional rule files: they consume context on every request.
- Read root
AGENTS.md, the nearest scopedAGENTS.md, the existing test, and the smallest upstream/fixture contract. - Search before reading:
rg -n 'TypeName|functionName|error code'. Read a smallsed -nwindow only. - Write a one-sentence contract: input, durable state, output/error, and required device boundary.
- Make one reversible domain change. Do not combine a refactor, a wire change, and a UI redesign.
- Run the narrowest relevant test. Inspect failures before changing behavior.
- Update
Docs/DESKTOP_PARITY_REMEDIATION.mdasTODO,VERIFY, orDONE; only device evidence can close a device requirement. - Finish with
git diff --check, the boundary audit, and the targeted/full suite required by root instructions.
For a failure report, give an AI only: error text, relevant trajectory IDs (redacted), the smallest source window, the contract test, and the specific parity row. Do not attach all logs or an 8,000-line file.
| Priority | Evidence | Safe extraction order | Acceptance |
|---|---|---|---|
| P0 | AppModel.swift was about 8,643 lines and mixed provider, marketplace and native-plugin coordination |
extract one bounded domain at a time; provider and marketplace/native lifecycle are now split, leaving session lifecycle and diagnostics as later seams | public behavior and session/run ownership unchanged |
| P0 | AgentRuntime.swift is about 4,534 lines and mixes loop, context, tools and trace |
context policy and route-only request assembly are now isolated; tool execution and trace recording remain later seams | identical request/message/event characterization tests |
| P1 | AppModel mixes marketplace installation, native compilation and UI error projection | split the UI-owned lifecycle and Agent adapter into focused extensions over existing Core coordinators | keep the main-Agent compiler flow, install state and diagnostics ownership intact |
| P1 | several app-facing features have their own persistence/lifecycle coordination | extract session lifecycle and diagnostics coordinators one domain at a time | no callback from an old run can update the active session |
| P2 | each model request includes tool schemas, generated SDK and Skill catalog text | keep provider request economics as a separately measured product concern | tool names, permission filtering and plugin tools remain available |
Do not start with a blanket AppModel or AgentRuntime rewrite. First write characterization tests, extract one dependency group with unchanged API, and only then move the next group.
- 2026-08-23 — Provider bundles:
AppModel+ProviderBundles.swiftnow owns provider Bundle installation and model discovery. The composition root keeps only the narrow dependency seams; the focused provider tests passed on the booted simulator. - 2026-08-23 — Context policy:
AgentContextPipeline.swiftnow owns normalized user-instruction and append-only runtime-context snapshot rules.AgentRuntimestill owns durable writes, event ordering, compaction, and streaming. The 62-testAgentRuntimeTestssuite passed on the booted simulator. - 2026-08-23 — Plugin marketplace/native lifecycle:
AppModel+NativePluginLifecycle.swiftnow owns native manifest materialization, store/runtime registration, rollback, and compilation-trace projection;AppModel+PluginMarketplaceTool.swiftowns the conversation marketplace adapter and prepared-source handoff. Both retain the existingPluginInstallCoordinator,NativeAgentPluginCompiler, native store, and iSH Host paths rather than creating a parallel installer. - 2026-08-23 — Request assembly:
AgentRuntimenow isolates the two Cordis route-only request checkpoints inAssembledStepRequest/assembleStepRequest. Prompt assembly, runtime snapshots, header/context events, credentials, images, compaction, trace/checkpoint, streaming and tool execution retain their original ordered ownership.
This round deliberately stops at proven boundaries rather than turning the loop into a generic mutable request builder. Any later extraction must preserve: Cordis assembly → tail snapshot → request hooks → header/context events → credentials/images → compaction → trace/checkpoint.
There are two different budgets that must not be confused:
- Coding-agent context: files, instructions, logs, diffs, and chat sent to Codex/Claude/Copilot. Nested rules, symbol-first reading, and small changes reduce this budget.
- End-user model request: system prompt, schemas, conversation, tool results, images, and plugin context sent to the configured provider.
ConversationTokenMeteris a pressure estimator; provider-reported usage/cache fields remain billing truth.
Current strengths: MobileHarnessPrompt.text is a stable prefix; tool definitions are sorted; long tool results use spill locators; context compaction exists; and request headers are only re-recorded when changed. Preserve these properties.
Near-term instrumentation before any tool hiding:
- Record estimated
system,tools, andmessagestoken buckets beside each model request in the redacted trajectory. - Show the three buckets in Diagnostics/Trajectory, alongside provider prompt/cache usage.
- Add a regression test that dynamic runtime context is appended after the stable prompt and that tool ordering is deterministic.
- Capture a real iPhone trace for text, code mode, plugin-heavy, and long-session turns.
Only after those measurements should the project consider progressive tool discovery. It must be an opt-in policy with a stable core catalog, a bounded discovery tool, explicit enablement, plugin compatibility, and a fallback to the full catalog. Removing schemas blindly saves tokens but breaks tool discovery and desktop parity.
- Keep
MobileHarnessPrompt.textdeterministic and remove only exact duplication; it is a cacheable policy prefix. - Append changing work-state, plugin context, session reference content, and skill bodies as typed deltas/snapshots after the stable prefix.
- Keep tools deterministically sorted. A schema change should be a deliberate request-header change, not incidental dictionary order.
- Do not encode API keys, raw logs, complete source archives, or full tool output into prompts. Use redacted diagnostics, workspace paths, pagination, and spill locators.
- Code mode is intentionally more expensive because it supplies its generated SDK. Measure it separately; do not weaken its only-direct-tool contract merely to reduce tokens.
DEVELOPER_DIR=/Applications/Xcode-beta.app/Contents/Developer swift test --build-path /tmp/hm-build
./Scripts/audit-no-remote-execution.sh
./Scripts/check-upstream-parity.sh
git diff --checkFor an Xcode device build add ARCHS=arm64 ONLY_ACTIVE_ARCH=YES. Store build caches in /tmp, not the repository.
- DONE — Extract
AgentContextPipelinefromAgentRuntimebehind the existing context/header characterization tests. - DONE — Split
AppModelprovider bundles plus marketplace/native lifecycle and conversation adapter, retaining the existing main-Agent compiler flow. - DONE — Isolate route-only request assembly inside
AgentRuntimewithout broadening the Cordis request contract. - TODO — Extract session lifecycle or diagnostics coordination from
AppModel, never both in one change. - Keep every future extraction in a small file with an explicit input/output contract and nearest-directory rules.
The optional request-token telemetry work belongs after these source-boundary splits. It is useful product diagnostics, but it is not a prerequisite for reducing the context, ambiguity, or maintenance cost of coding agents.