Back

Inference-Time Skill Acquisition with Claude Code Agent Teams

·21 min read
Inference-Time Skill Acquisition with Claude Code Agent Teams

What if you could teach Claude Code a new domain — not by training on it, but by having a team of agents research it live, at inference time, working in parallel? My setup is nowadays is Warp + tmux + Claude Code orchestration through my custom agent cluster + minimal tooling for a central session and memory system + Obsidian-cloud-synced markdown artifacts. No code editor. The terminal is the interface.

What I want to talk about isn't the tools though. It's what happens when the agents coordinate themselves.

The Setup

I run my Agent Cluster — a shared workspace where multiple Claude and Codex instances operate with persistent memory (SQLite + Qdrant), session artifacts synced to iCloud for Obsidian, and a growing set of skills any agent can invoke. Skills are just markdown files that encode domain expertise: what tools to use, which commands to run, what patterns to follow, what to avoid. They're the operational knowledge of the system.

I needed a React Native skill. Not a surface-level overview — a real, production-grade reference covering the full 2026 stack: New Architecture (JSI, Fabric, TurboModules), Hermes V1, Expo SDK 55, navigation, state management, animations, performance, native modules, EAS cloud builds. The kind of thing that would take a developer days to compile from scattered docs, blog posts, changelogs, and release notes.

I gave the lead agent one instruction: integrate a React Native skill for the cluster, use an agent team.

What Happened

The lead (Opus 4.6) did four things:

  1. Read the system prompt and existing skills to understand the expected format and depth
  2. Ran web searches to get the current state of React Native (0.82-0.83, New Architecture mandatory, Expo SDK 55, Hermes V1)
  3. Created a team with a shared task list and dependency graph
  4. Spawned three Sonnet researchers in parallel, each with a focused brief

The task breakdown:

Task #1: Architecture deep dive (arch-researcher)
         JSI, Fabric, TurboModules, Hermes V1, Yoga, threading,
         render pipeline, Codegen, view flattening

Task #2: Tooling & workflow (tooling-researcher)
         Expo SDK 55, Expo CLI, React Native CLI, EAS Build/Submit/Update,
         project structure, config plugins

Task #3: UI, state & performance (ui-perf-researcher)
         Navigation, state management, animations, gestures,
         performance optimization, native modules

Task #4: Write the skill files (blocked by #1, #2, #3)

All three researchers ran simultaneously — web searches, official docs, blog posts, release notes — writing their findings into structured markdown. No coordination needed between them. The task split was clean enough that there was zero overlap.

Three Sonnet researchers running in parallel while the Opus lead coordinates

Three minutes later, all three delivered. The lead read every output (4,300+ lines of research across three files) and synthesized them into the final skill:

  • SKILL.md — the operational reference (quick start, CLI commands, navigation, state, animations, performance, native modules, EAS, common issues, recommended stack)
  • references/architecture.md — 1,155 lines deep on JSI, Fabric, TurboModules, Hermes, threading, render pipeline, Codegen, view flattening
  • references/troubleshooting.md — debugging and performance guide

Updated the system prompt, registered the skill, committed, pushed. Under 15 minutes total.

The Output

Here are the three skill files the team produced — the files any agent in the cluster loads when it hits a React Native task.

SKILL.md — Main Operational Reference

markdown
---
name: "react-native"
description: "Use when building, debugging, or maintaining React Native iOS/Android apps — covers project setup, Expo/bare CLI workflows, New Architecture (JSI/Fabric/TurboModules), navigation, state management, animations, performance tuning, native modules, and EAS cloud builds/OTA updates."
version: 1.0.0
tags: [React Native, Expo, iOS, Android, Mobile, Fabric, TurboModules, JSI, Hermes, EAS]
dependencies: [node>=18, npx]
---

# React Native Skill (LTS 2026)

Build production iOS/Android apps with React Native 0.82+ and Expo SDK 55+. New Architecture only (Fabric, TurboModules, JSI). Hermes engine default.

## When to use

- Building new mobile apps (iOS, Android, or both)
- Adding features or fixing bugs in existing React Native projects
- Performance optimization, animation work, native module integration
- Setting up CI/CD with EAS Build/Submit/Update
- Migrating from legacy architecture to New Architecture

## Quick start

### New project (Expo — recommended for ~95% of projects)

npx create-expo-app@latest MyApp
cd MyApp
npx expo start

Press i for iOS simulator, a for Android emulator, or scan QR with Expo Go.

### New project (Bare React Native)

npx react-native init MyApp
cd MyApp
npx react-native run-ios    # or run-android

### Run on device

# Expo
npx expo run:ios --device
npx expo run:android --device

# Bare RN
npx react-native run-ios --device "iPhone"
npx react-native run-android

### Production build (EAS)

npm install -g eas-cli
eas login
eas build:configure
eas build --platform all
eas submit --platform all

## Architecture overview (New Architecture — mandatory since RN 0.82)

JavaScript  <--JSI (synchronous, C++)-->  TurboModules
     |                                        |
  Hermes VM                             Platform APIs
     |
  Fabric Renderer  <--C++ Shadow Tree-->  Host Views

- **JSI**: Direct JS↔C++ calls, no serialization, microsecond latency
- **Fabric**: C++ renderer with synchronous layout, concurrent rendering (React 18+)
- **TurboModules**: Lazy-loaded, type-safe native modules via JSI + Codegen
- **Hermes**: AOT bytecode compilation, 40% faster startup, 20-30% less memory
- **Codegen**: TypeScript specs → native interfaces (compile-time type safety)

## CLI commands

### Expo CLI

| Command | Purpose |
|---------|---------|
| npx expo start | Start dev server (Metro) |
| npx expo start --dev-client | Launch in development build |
| npx expo run:ios | Compile + run on iOS |
| npx expo run:android | Compile + run on Android |
| npx expo prebuild | Generate native directories (CNG) |
| npx expo prebuild --clean | Regenerate native dirs from scratch |
| npx expo install <pkg> | Install version-compatible package |
| npx expo install --fix | Fix mismatched package versions |
| npx expo export | Bundle for production |
| npx expo lint | Run ESLint with Expo rules |
| npx expo config --full | View full resolved config |

### React Native CLI

| Command | Purpose |
|---------|---------|
| npx react-native init <name> | Create new bare project |
| npx react-native start | Start Metro bundler |
| npx react-native start --reset-cache | Start with cleared cache |
| npx react-native run-ios | Build + run iOS |
| npx react-native run-android | Build + run Android |
| npx react-native bundle | Create offline JS bundle |
| npx react-native clean | Remove build artifacts |
| npx react-native doctor | Check environment setup |
| npx react-native info | Show environment info |

### EAS commands

| Command | Purpose |
|---------|---------|
| eas build --platform ios | Cloud build for iOS |
| eas build --platform android | Cloud build for Android |
| eas build --profile preview | Build with specific profile |
| eas submit --platform all | Submit to App Store + Play Store |
| eas update --channel production | Push OTA update |
| eas update --auto | Auto-detect branch/channel |

## Navigation

### Expo Router (recommended — file-based routing)

app/
  _layout.tsx          # Root layout (Stack)
  index.tsx            # "/" route
  (tabs)/
    _layout.tsx        # Tab navigator
    index.tsx          # Home tab
    explore.tsx        # Explore tab
  user/[id].tsx        # Dynamic route "/user/:id"
  +not-found.tsx       # 404 page

// app/_layout.tsx
import { Stack } from 'expo-router';
export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
      <Stack.Screen name="modal" options={{ presentation: 'modal' }} />
    </Stack>
  );
}

// Navigation
import { router } from 'expo-router';
router.push('/user/123');
router.replace('/login');
router.back();

### React Navigation v7 (when you need more control)

import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createStaticNavigation } from '@react-navigation/native';

const RootStack = createNativeStackNavigator({
  screens: {
    Home: HomeScreen,
    Details: { screen: DetailsScreen, linking: 'details/:id' },
  },
});
const Navigation = createStaticNavigation(RootStack);

## State management

**2026 best practice:** Zustand (client) + TanStack Query (server) + MMKV (persistence)

// Zustand store
import { create } from 'zustand';
const useAuthStore = create((set) => ({
  user: null, token: null,
  login: (user, token) => set({ user, token }),
  logout: () => set({ user: null, token: null }),
}));
const user = useAuthStore((s) => s.user); // selective subscription

// TanStack Query (server state)
import { useQuery } from '@tanstack/react-query';
function useUser(id: string) {
  return useQuery({ queryKey: ['user', id], queryFn: () => api.getUser(id) });
}

// MMKV (persistent storage — 30x faster than AsyncStorage)
import { MMKV } from 'react-native-mmkv';
const storage = new MMKV();
storage.set('token', 'abc123');
const token = storage.getString('token');

| Need | Use |
|------|-----|
| Local component state | useState / useReducer |
| Shared UI state | Zustand |
| Server/API data | TanStack Query |
| Persistent storage | MMKV |
| Fine-grained atoms | Jotai |
| Complex middleware | Redux Toolkit |

## UI components

### Core components

| Component | Purpose |
|-----------|---------|
| View | Container (div equivalent) |
| Text | All text must be in <Text> |
| Pressable | Touch handler (preferred over TouchableOpacity) |
| ScrollView | Scrollable container (small content) |
| FlatList | Virtualized list (large datasets) |
| TextInput | Text input field |
| Image | Display images (use expo-image for production) |
| Modal | Native modal overlay |
| KeyboardAvoidingView | Adjust layout for keyboard |

### Lists — always use FlashList in production

import { FlashList } from '@shopify/flash-list';
<FlashList
  data={items}
  renderItem={({ item }) => <ItemCard item={item} />}
  estimatedItemSize={80}
  keyExtractor={(item) => item.id}
  onEndReached={loadMore}
  onEndReachedThreshold={0.5}
/>

### Styling — NativeWind (Tailwind for RN)

<View className="bg-white dark:bg-gray-800 rounded-2xl p-4 shadow-md">
  <Text className="text-lg font-bold text-gray-900 dark:text-white">Title</Text>
  <Pressable className="bg-blue-500 active:bg-blue-700 rounded-lg py-2 px-4 mt-3">
    <Text className="text-white text-center font-semibold">Action</Text>
  </Pressable>
</View>

## Animations

### Reanimated v3 (standard — UI thread, 60fps)

import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
function AnimatedBox() {
  const offset = useSharedValue(0);
  const style = useAnimatedStyle(() => ({
    transform: [{ translateX: offset.value }],
  }));
  return (
    <Pressable onPress={() => { offset.value = withSpring(200); }}>
      <Animated.View style={[styles.box, style]} />
    </Pressable>
  );
}

### Gesture Handler v2

import { Gesture, GestureDetector } from 'react-native-gesture-handler';
const pan = Gesture.Pan()
  .onUpdate((e) => { translateX.value = e.translationX; })
  .onEnd(() => { translateX.value = withSpring(0); });
<GestureDetector gesture={pan}>
  <Animated.View style={animatedStyle} />
</GestureDetector>

### Layout animations

<Animated.View
  entering={FadeIn.duration(300)}
  exiting={FadeOut.duration(200)}
  layout={LinearTransition.springify()}
>
  <Content />
</Animated.View>

## Performance

### Targets

| Metric | Target |
|--------|--------|
| Frame rate | 60 FPS (120 on ProMotion) |
| JS frame budget | <16.67ms |
| TTI | <2s with Hermes |
| Bundle size | <5MB JS |

### Key optimizations

- **Lists**: Use FlashList, not FlatList. Add getItemType for mixed lists
- **Memoization**: React.memo for list items, useCallback for handlers passed to children
- **Images**: Use expo-image with cachePolicy="memory-disk" and blurhash placeholders
- **Deferred work**: InteractionManager.runAfterInteractions() for post-navigation loads
- **Animations**: Animate transform/opacity (non-layout), not width/height/margin
- **Tree shaking**: Enable in app.json { "expo": { "experiments": { "treeShaking": true } } }

## Native modules

### Expo Modules API (recommended — Swift + Kotlin)

npx create-expo-module@latest my-module

// TypeScript definition
import { NativeModule, requireNativeModule } from 'expo';
declare class MyModule extends NativeModule<{}> {
  getValue: () => string;
  setValue: (value: string) => void;
}
export default requireNativeModule<MyModule>('MyModule');

### TurboModules (bare RN — C++ level control)

// specs/NativeMyModule.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
  multiply(a: number, b: number): number;
}
export default TurboModuleRegistry.getEnforcing<Spec>('NativeMyModule');

Then implement in Kotlin (Android) + Objective-C++ (iOS). Codegen generates interfaces at build time.

## EAS configuration

### eas.json

{
  "build": {
    "development": { "developmentClient": true, "distribution": "internal" },
    "preview": { "distribution": "internal" },
    "production": { "autoIncrement": true }
  },
  "submit": {
    "production": {
      "android": { "serviceAccountKeyPath": "./google-services.json", "track": "internal" },
      "ios": { "ascAppId": "1234567890" }
    }
  }
}

### OTA updates

eas update --channel production --message "Fix login bug"

**Can update OTA**: JS code, styles, images, translations
**Requires new binary**: Native code, native deps, permissions, SDK version

## Project structure (Expo SDK 55)

my-app/
  src/app/               # Routes (Expo Router)
  src/components/        # Shared components
  src/hooks/             # Custom hooks
  src/stores/            # Zustand stores
  src/utils/             # Utilities
  assets/                # Images, fonts
  app.json               # Expo config
  eas.json               # EAS config
  metro.config.js        # Metro config
  babel.config.js        # Babel config (reanimated plugin last)
  tsconfig.json          # TypeScript config

## Common issues

**Metro cache stale**: npx expo start -c or npx react-native start --reset-cache
**Pods out of sync (iOS)**: cd ios && bundle exec pod install && cd ..
**Android build fails**: cd android && ./gradlew clean && cd ..
**Reanimated not working**: Ensure react-native-reanimated/plugin is LAST in babel.config.js plugins
**FlashList blank**: Parent must have flex: 1 (FlashList needs bounded height)
**MMKV crash on dev**: Requires dev build, not Expo Go
**New Architecture issues**: Run npx react-native doctor to verify environment

## Recommended 2026 stack

| Category | Pick |
|----------|------|
| Navigation | Expo Router v4 |
| Client State | Zustand |
| Server State | TanStack Query |
| Persistence | MMKV |
| Styling | NativeWind v4 |
| Lists | FlashList |
| Animations | Reanimated v3 |
| Gestures | Gesture Handler v2 |
| Images | expo-image |
| Bottom Sheets | @gorhom/bottom-sheet |
| Native Modules | Expo Modules API |
| Drawing/GPU | React Native Skia |

references/architecture.md — Deep Dive (1,155 lines)

markdown
# React Native New Architecture Deep Dive (2026)

## 1. Architecture Overview

The New Architecture replaces React Native's legacy bridge-based system with a direct C++ communication layer. Default since RN 0.76, the only option since RN 0.82.

Old Architecture:
  JavaScript  <--JSON Bridge (async)-->  Native Modules
  Problems: All communication serialized as JSON, async only, single bridge bottleneck, no type safety, no lazy loading

New Architecture:
  JavaScript  <--JSI (synchronous, C++)-->  TurboModules
       |                                        |
    Hermes VM                             Platform APIs
       |
    Fabric Renderer  <--C++ Shadow Tree-->  Host Views

Performance Impact: 60fps solid, 40% faster startup, 20-30% less memory, 30-50% faster JS-native communication

## 2. JSI (JavaScript Interface)

JSI allows JavaScript to hold references to C++ host objects and vice versa. Instead of serializing to JSON, JSI lets JS directly invoke methods on native objects through shared memory.

Old Bridge: JS Object --> JSON.stringify --> Bridge Queue --> JSON.parse --> Native Object (~1ms+ per call)
JSI: JS Object --> C++ HostObject reference --> Direct method call (microseconds)

Key Properties:
- Synchronous: JS calls native and gets return values immediately
- Zero-copy: Data shared via memory references, no serialization
- Bidirectional: Native can call JS and JS can call native
- Engine-agnostic: Works with Hermes, JSC, V8
- Type-safe: Combined with Codegen, compile-time type checking

Real-world impact: VisionCamera processes ~30 MB frames in real-time (~2 GB/second) through JSI. MMKV storage is ~30x faster than AsyncStorage.

## 3. Fabric Renderer

C++ rendering system supporting synchronous layout, concurrent rendering, React 18+ features.

React (JS) → React Element Tree → React Shadow Tree (C++, immutable, thread-safe) → Yoga layout → Host View Tree → Screen pixels

Shadow Tree: C++ data structure mirroring the React Element Tree but containing only host components (View, Text, Image).
Concurrent Rendering: useTransition for low-priority updates, Suspense for data-fetching boundaries, automatic batching, interruptible rendering.

## 4. TurboModules

Lazy-loaded, type-safe native modules via JSI. Define TypeScript spec → Codegen generates native interfaces → implement in Kotlin/ObjC++ → call from JS via JSI.

| Feature | Legacy | TurboModules |
|---------|--------|-------------|
| Loading | Eager (all at startup) | Lazy (on first use) |
| Communication | Async JSON bridge | Synchronous JSI |
| Type Safety | None | Compile-time (Codegen) |
| Data Transfer | JSON serialization | Direct memory access |

Type Mapping:
| TypeScript | Android (Kotlin) | iOS (Objective-C) |
|-----------|-----------------|------------------|
| string | String | NSString * |
| number | Double | NSNumber * |
| boolean | Boolean | Bool |
| Object | ReadableMap | NSDictionary * |
| Array | ReadableArray | NSArray * |
| Promise<T> | Promise | RCTPromiseResolveBlock |

## 5. Hermes V1

Default JS engine, AOT bytecode compilation. V1 shipped experimentally in RN 0.82.

Compilation: Source (.js/.ts) → Metro → JS Bundle → Hermes Compiler (AOT) → Bytecode (.hbc) → Hermes VM

V1 improvements: Native let/const, async/await, ES6 classes, Map/Set (no more polyfills), experimental JIT, bytecode-level dead code elimination.

Benchmarks (Expensify): Android 7.6% faster TTI, iOS 9% faster bundle load, ~33% smaller bytecode, ~15.5% APK size savings.

## 6. Yoga Layout Engine (v3.0)

Cross-platform C++ Flexbox engine. Calculates position/size for every shadow node.
Yoga 3.0: Static positioning, containing blocks, row-reverse fix, align-content: space-evenly, percentage calculation fixes.

## 7. Threading Model

Two primary threads + background threads:
- UI Thread (Main): Manipulates host views, high-priority events
- JavaScript Thread: React render phase, layout calculations, business logic

Five render scenarios:
1. Standard render (JS thread → mount on UI thread)
2. Synchronous UI thread render (touch responses)
3. Default event interruption (low-priority, merged state)
4. Discrete event interruption (high-priority, UI thread takeover)
5. C++ state update (skips render phase entirely, e.g. ScrollView offset)

## 8. Render Pipeline (Render → Commit → Mount)

Render: React executes components, creates shadow nodes
Commit: Yoga layout calculation + tree promotion
Mount: Tree diffing (createView, updateView, removeView, deleteView) + view mounting

Structural sharing: Only affected nodes cloned on state update, unaffected nodes shared between trees.

## 9. Codegen

Build-time tool generating native interfaces from TypeScript specs. Ensures compile-time type safety.
TurboModule specs prefixed Native*, Fabric components suffixed NativeComponent.
Generates: Java interfaces + C++ JSI bindings (Android), ObjC protocols + C++ JSI bindings (iOS), ComponentDescriptors, Props, ShadowNodes, EventEmitters.

## 10. View Flattening

Automatic optimization merging layout-only nodes. Reduces host view hierarchy from 600-1000 nodes to ~200 (3-5x reduction). Integrated into diffing stage, implemented in C++, automatic, transparent.

## 11. Release Timeline

- RN 0.76 (Oct 2024): New Arch default
- RN 0.82 (Oct 2025): New Arch only, Hermes V1 experimental
- RN 0.83 (Dec 2025): Zero breaking changes, React 19.2, Expo SDK 55

Quick Reference:
Need synchronous native calls?     → JSI + TurboModules
Need custom native UI component?   → Fabric Native Component + Codegen
Need 60fps animations?             → Reanimated (UI thread worklets)
Need gesture handling?              → React Native Gesture Handler
Need OTA updates?                   → Hermes bytecode diffing + EAS Updates
Need type-safe native bridge?       → TypeScript spec + Codegen

references/troubleshooting.md — Debugging & Performance

markdown
# React Native Troubleshooting & Performance Guide

## Common Issues

### Build & Environment

**Metro cache stale**
npx expo start -c                    # Expo
npx react-native start --reset-cache # Bare RN
rm -rf node_modules && npm install   # Nuclear option

**iOS pods out of sync**
cd ios && rm -rf Pods Podfile.lock && bundle exec pod install && cd ..

**Android build fails**
cd android && ./gradlew clean && cd ..
rm -rf android/.gradle android/app/build  # If persists

**Environment check**
npx react-native doctor          # Bare RN
npx expo-env-info                # Expo
npx expo install --fix           # Fix version mismatches

### Runtime Errors

**"Invariant Violation: requireNativeComponent"** → npx expo prebuild after adding native deps
**"Cannot read property 'X' of null" (TurboModule)** → Check registration, run Codegen, verify spec naming
**"Reanimated: Failed to create a worklet"** → reanimated/plugin must be LAST in babel plugins
**FlashList blank** → Parent needs flex: 1, add estimatedItemSize
**MMKV crashes in Expo Go** → Requires dev build: eas build --profile development
**Gesture Handler not responding** → Wrap root with <GestureHandlerRootView style={{ flex: 1 }}>

### Navigation Issues

**Expo Router screen not found** → File must be in app/ dir with .tsx extension, check _layout.tsx
**Deep links not working** → Add scheme to app.json, add associated domains (iOS), intent filters (Android)
**Nav state persists after logout** → Use router.replace('/login') not router.push

## Performance Debugging

Step 1: Enable Performance Monitor (shake → Show Perf Monitor)
Step 2: Profile with React DevTools (press j in Metro → Profiler tab)
Step 3: Hermes Profiler: npx react-native profile-hermes
Step 4: Platform profiling (Xcode Instruments / Android Studio Profiler)

## Common Performance Fixes

**Slow lists** → FlashList + estimatedItemSize + memoized renderItem + getItemType for mixed content
**Excessive re-renders** → React.memo, useCallback, selective Zustand subscriptions, useMemo
**Slow transitions** → InteractionManager.runAfterInteractions() for deferred work
**Image jank** → expo-image with cachePolicy="memory-disk", blurhash placeholders, recyclingKey
**Animation jank** → Animate transform/opacity (GPU), avoid width/height/margin (Yoga recalc)
**Bundle too large** → Tree shaking in app.json, React.lazy, specific imports (lodash/get not lodash)
**Memory leaks** → Clean up subscriptions/timers in useEffect return, AbortController for fetch

## Version Compatibility

| Expo SDK | React Native | React | Key Feature |
|----------|-------------|-------|-------------|
| 55 | 0.83 | 19.2 | New Arch only, bytecode diffing |
| 54 | 0.81 | 18.3 | Last with Legacy Arch support |
| 53 | 0.79 | 18.3 | New Arch default but opt-out available |

Why This Matters

No training required

The usual way to make an AI better at something is to train it — fine-tuning, RLHF, continued pretraining. That's expensive, slow, and static. The knowledge is frozen the moment training ends.

This is different. The agents picked up React Native expertise at inference time by reading current docs, synthesizing what they found into a structured format, and saving it as a reusable skill. Next time any agent in the cluster hits a React Native task, it loads the skill and just knows what to do. No weights changed. The system got smarter through artifacts, not parameters.

It's actually closer to how people learn. You don't retrain your brain — you read, take notes, organize what you learned, and refer back to it later.

Parallel research is multiplicative

You can run multiple agents manually — split tasks across tmux panes, decide the partition yourself, merge results by hand. It works. But you become the bottleneck. You can't synthesize four agents' outputs faster than you can read them. You can't track task dependencies in your head past a handful of items. And you can't do all that while also writing code.

Native agent teams move the coordination overhead from your attention to the lead agent's context window. The lead builds the task graph, spawns teammates, they report back when done, blocked tasks auto-unblock, and the lead synthesizes. You give the high-level instruction and review the output. Everything in between runs on its own.

And three researchers in parallel isn't just 3x faster. Each one went deeper than a single agent could have in the same total context, because they weren't competing for context space. The architecture researcher spent its entire window on JSI internals and C++ host objects. The tooling researcher spent its entire window on every eas.json property and CLI flag. Full depth on every axis, no tradeoffs.

Skills compound

The React Native skill isn't a one-off output. It's now part of the cluster's permanent knowledge. Every future session, every agent, can use it. And it can be updated — next time React Native ships a breaking change, an agent can read the existing skill, research the delta, and patch it. Incremental maintenance, not full rebuilds.

That's the difference between "AI that can look things up" and "AI that builds and maintains its own knowledge base."

The Architecture

Human instruction
       |
       v
  Lead Agent (Opus 4.6)
       |
       |-- reads system prompt, existing skills
       |-- web searches for current state
       |-- creates team + task list with dependencies
       |
       +-- spawns arch-researcher (Sonnet)
       +-- spawns tooling-researcher (Sonnet)
       +-- spawns ui-perf-researcher (Sonnet)
       |        |                |
       |   (parallel research, ~3 min)
       |        |                |
       +-- all complete, task #4 unblocks
       |
       |-- reads all research outputs
       |-- synthesizes into SKILL.md + references
       |-- updates system prompt
       |-- commits + pushes
       |
       v
  Skill integrated, team cleaned up

The lead ran Opus for orchestration and synthesis. The researchers ran Sonnet — cheaper, faster, and perfectly capable of web research and structured writing. This model mixing matters. You don't need the most expensive model for every subtask. You need the right model for each role.

The Hard Part

This worked because the task split cleanly. Three independent research domains, no shared state, no file conflicts, clear deliverables. Not every task looks like this.

When agents need to edit the same files, share intermediate results, or make decisions that depend on each other's progress — coordination gets harder. The system handles it through task dependencies and messaging, but it doesn't yet cover the case where Agent A discovers something that should change Agent B's approach mid-flight.

The other limitation is verification. The lead read all the research and synthesized it, but didn't independently verify every claim against primary sources. The skill is as good as the researchers' web searches were. For a reference document, that's fine. For safety-critical code, it wouldn't be.

What's Next

The pattern generalizes. Any domain that decomposes into independent research threads, can be synthesized into structured artifacts, and benefits from persistence — that's a candidate for inference-time skill acquisition. Backend frameworks, cloud infrastructure, data engineering tools, design systems. They all follow the same shape.

The interesting question is whether this scales to domains where the knowledge isn't "what commands to run" but "how to think about the problem." Architecture patterns, debugging heuristics, design taste. Harder to encode in a markdown file. But also harder to encode in model weights. Maybe the answer is the same for both: accumulate examples, extract patterns, iterate.