Skip to content

Latest commit

 

History

History
178 lines (145 loc) · 14.7 KB

File metadata and controls

178 lines (145 loc) · 14.7 KB

CCPA Architecture

Top spec: claude-code-parity-apr-poc.md

Defines the record-replay-distill pipeline (3 phases), repo layout, trace schema, mocking strategy, and distillation framing. See falsification-conditions.md for the gate definitions and milestones-m0-m50.md for implementation history.

Architecture

Diagram below shows the original M0 design. Phase 1 (RECORD via live HTTPS proxy) was rescoped OOS at M2.3 ("we will not call api, we will assume claude code"). In the shipping architecture, Phase 1's .ccpa-trace.jsonl fixtures are AUTHORED in fixtures/canonical/ rather than recorded from a live Anthropic session. Phases 2 and 3 are unchanged — the differ + the RecordedDriver LLM mock both consume the same JSONL schema regardless of provenance. The diagram is preserved as historical reference because it explains why the schema looks the way it does (every tool round-trip passes through the Anthropic API in the teacher, so the trace records prompts + tool_use blocks + tool_result blocks + final assistant turns at message granularity).

                    ┌──────────────────────────────────────────────────┐
                    │  Phase 1: RECORD (teacher demonstrations)        │
                    │                                                  │
                    │  Original M0 vision  (now AUTHORED post-M2.3):   │
  user prompt ─────►│   Claude Code ──HTTP──► ccpa-recorder ──► fixture│
                    │                  ▲             │                 │
                    │                  └──── api.anthropic.com (live)  │
                    │                                                  │
                    │  Shipping path:  fixtures/canonical/<id>/        │
                    │                  teacher.ccpa-trace.jsonl        │
                    │                  AUTHORED to schema, no live API │
                    └──────────────────────────────────────────────────┘
                                        │
                                        ▼ (one .ccpa-trace.jsonl file)
                    ┌──────────────────────────────────────────────────┐
                    │  Phase 2: REPLAY (student under test)            │
                    │   fixture ──► ccpa-replayer ──► apr code         │
                    │                  ▲                  │            │
                    │                  └─ mocked LLM ◄────┘            │
                    │     (returns the recorded teacher's assistant    │
                    │      turn — same regardless of fixture origin)   │
                    └──────────────────────────────────────────────────┘
                                        │
                                        ▼ (one .ccpa-trace.jsonl file)
                    ┌──────────────────────────────────────────────────┐
                    │  Phase 3: DISTILL+DIFF (parity verdict)          │
                    │   teacher.jsonl + student.jsonl ──► ccpa-differ  │
                    │      ──► pv validate ──► verdict + drift report  │
                    └──────────────────────────────────────────────────┘

Original Phase 1 rationale — now historical (asserted by FALSIFY-CCPA-001)

This section preserves the M0 reasoning for why a recording HTTPS proxy would have been sufficient, because the trace schema's shape (tool round-trips at message granularity) follows from this argument. Post-M2.3, Phase 1 is AUTHORED, but the schema invariant remains: every committed fixture must be a complete, schema-valid action trace.

Claude Code is closed-source, so we can't hook its tool execution directly. We don't need to: every tool round-trip already round-trips through the Anthropic API. Claude Code submits tool_result blocks back to Anthropic on the next request, so a recording HTTPS proxy at ANTHROPIC_BASE_URL would capture the full action stream — prompts, tool calls, tool outputs, final messages — without any CLI wrapping. In the original M0 design the proxy was the recorder. Whether the trace is recorded or AUTHORED, the same schema invariant applies and is mechanically falsifiable: FALSIFY-CCPA-001 asserts every committed fixture is a complete, schema-valid action trace; failure (truncation, missing tool round-trip) flips the gate.

M118 prior-art validation (2026-05-10) — the M0 design assumption that Claude Code respects ANTHROPIC_BASE_URL is independently confirmed by deepclaude, a separately-developed open-source project that ships a working localhost:3200 HTTPS proxy intercepting /v1/messages calls from Claude Code and routing them to DeepSeek/OpenRouter/Fireworks/Anthropic interchangeably. This positively discharges the R2 risk's technical premise (see risks.md). Documented overridable env-vars per deepclaude's mapping: ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODEL, CLAUDE_CODE_SUBAGENT_MODEL. Token-stream cost tracking through the proxy is exposed at /_proxy/cost. The ccpa-recorder crate (retained for FALSIFY-CCPA-001 schema-roundtrip and as scaffolding) can adopt this interception pattern verbatim if Phase 1 RECORD is ever reinstated. Known interception gotchas (per deepclaude): MCP server tools and image/vision input do not survive transformation through Anthropic-compatible compatibility layers — for CCPA's pure passthrough-and-log use case (we record traffic to real Anthropic, we don't transform to a different backend), those gotchas are non-issues. Known non-interceptable: remote-control sessions, which use a hardcoded wss://bridge.claudeusercontent.com WebSocket, are NOT redirectable via ANTHROPIC_BASE_URL — out-of-scope for any RECORD path. See axis-2-closure-plan.md § (1) HTTPS-proxy reinstatement for cost re-estimate (~3-7 days aprender-side, down from 1-2 weeks, by adapting deepclaude's pattern).

Why apr code replay needs LLM mocking (asserted by FALSIFY-CCPA-002 + FALSIFY-CCPA-003)

The student is apr code, which talks to a local model. If we feed the same prompt to apr code, the local model produces its own tool calls, which may differ purely due to model quality, not orchestration. To isolate orchestration drift from model drift, the replayer:

  1. Plays the user prompts back to apr code in order.
  2. Intercepts apr code's LLM calls and returns the recorded teacher's assistant turn verbatim via RecordedDriver: LlmDriver.
  3. Lets apr code's orchestration (tool dispatch, permission gates, hook firing, memory loading, etc.) execute against that fixed teacher output.
  4. Captures apr code's emitted tool calls + final state.

Drift now has a single source: orchestration. Falsifiable via two gates:

  • FALSIFY-CCPA-002 (replay determinism): re-running the same fixture twice with the same apr code revision yields byte-identical student traces (after <SESSION>/<TS>/<TOOL-N> normalization).
  • FALSIFY-CCPA-003 (mock completeness): RecordedDriver consumes every teacher turn exactly once; missing turn → panic, extra turn → assertion fail.

This is structurally identical to the existing MockDriver used by crates/aprender-orchestrate/src/agent/task_tool/tests.rs, so no new abstraction is needed — RecordedDriver is a ~100-line file. Academic basis: behavioral cloning / imitation-learning evaluation methodology (cf. agent-task literature in arXiv:2310.06770 SWE-bench).

New repo layout (claude-code-parity-apr)

claude-code-parity-apr/                 # source of truth for code, fixtures, CI
├── Cargo.toml                          # workspace root
├── README.md
├── .github/workflows/
│   └── ci.yml                          # ci/gate job (FALSIFY-CCPA-009 enforces required check)
├── .pmat-comply.toml                   # FALSIFY-CCPA-010 config, 100 % strict
├── Makefile                            # `make tier3` runs all 16 gates locally
├── crates/
│   ├── ccpa-trace/                     # serde schema for .ccpa-trace.jsonl
│   ├── ccpa-recorder/                  # original M0 vision: mitm-style HTTPS
│   │                                   # proxy at ANTHROPIC_BASE_URL. OOS post-
│   │                                   # M2.3 rescope; crate retained as
│   │                                   # scaffolding for the schema-roundtrip path.
│   ├── ccpa-replayer/                  # drives `apr code` with mocked LLM responses
│   ├── ccpa-differ/                    # semantic diff + parity score
│   └── ccpa-cli/                       # `ccpa diff|corpus|coverage|validate|measure`
│                                       # (binary: `ccpa`)
├── contracts/
│   ├── claude-code-parity-apr-v1.yaml  # MIRROR of aprender/contracts/...v1.yaml
│   │                                   # (M22 byte-identical guard via pin.lock)
│   └── pin.lock                        # pinned commit-hash + sha256 of authoritative
│                                       # aprender contract
├── fixtures/                           # AUTHORED canonical sessions (M2.3 rescope)
│   ├── canonical/                      # 30 paired teacher/student fixtures
│   │   ├── 0001-edit-readme/
│   │   │   ├── teacher.ccpa-trace.jsonl
│   │   │   ├── student.ccpa-trace.jsonl
│   │   │   └── meta.toml               # per-fixture parity-matrix row + tags
│   │   ├── 0002-fix-failing-test/
│   │   └── ...                         # 30 total per FALSIFY-CCPA-007
│   ├── regression/                     # M13.5 bidirectional sensitivity corpus
│   │                                   # (deliberate drift; meter MUST score < 1)
│   └── synthetic/                      # M26 measure-bridge synthetic traces
└── docs/
    └── specifications/
        └── claude-code-parity-apr-poc.md   # this spec

Naming: ccpa = claude-code-parity-apr. Binary name is ccpa. Repo name claude-code-parity-apr is explicit on GitHub.

Monorepo policy compliance (feedback_monorepo_single_source_of_truth.md): aprender stays canonical for the contract text; the companion repo is canonical for enforcement (CI, coverage, pmat-comply, contract gate). pin.lock records the commit hash of the authoritative aprender contract being consumed; pv is invoked as a binary, not as a re-implemented schema.

Trace schema (.ccpa-trace.jsonl)

One JSON object per line. Schema lives in ccpa-trace crate and is contracted by contracts/claude-code-parity-apr-v1.yaml § trace_schema. FALSIFY-CCPA-001 asserts roundtrip-equality.

{"v": 1, "kind": "session_start", "session_id": "uuidv7", "ts": "2026-04-26T01:23:45Z",
 "actor": "claude-code|apr-code", "model": "claude-sonnet-4-6|qwen3-coder-30b-a3b-q4km",
 "cwd_sha256": "<git-tree-hash>"}

{"v": 1, "kind": "user_prompt", "turn": 0, "text": "fix the failing test"}

{"v": 1, "kind": "assistant_turn", "turn": 1,
 "blocks": [
   {"type": "thinking", "thinking": "..."},
   {"type": "text", "text": "I'll start by..."},
   {"type": "tool_use", "id": "toolu_01...", "name": "Bash",
    "input": {"command": "cargo test --lib"}}
 ],
 "stop_reason": "tool_use"}

{"v": 1, "kind": "tool_result", "turn": 2, "tool_use_id": "toolu_01...",
 "ok": false, "content": "test failed: ...",
 "side_effects": {"files_read": [], "files_written": [], "exit_code": 101}}

{"v": 1, "kind": "session_end", "turn": 7, "stop_reason": "end_turn",
 "elapsed_ms": 12340, "tokens_in": 4521, "tokens_out": 891}

Determinism guarantees (asserted by FALSIFY-CCPA-002):

  • session_id and ts are replaced with stable placeholders during diff (<SESSION> / <TS>).
  • tool_use.id is normalized to <TOOL-N> per turn.
  • cwd_sha256 is asserted equal between teacher and student fixtures (same starting state).

Mocking strategy (asserted by FALSIFY-CCPA-002 + FALSIFY-CCPA-003)

The student-side LLM mock implements apr code's LlmDriver trait (already abstract — see crates/aprender-orchestrate/src/agent/code.rs). The replayer constructs a RecordedDriver { trace: Vec<AssistantTurn> } that returns turn N when called for the Nth time. Mismatches (apr code calls the LLM at an unexpected point) are recorded as OrchestrationDrift::ExtraneousLlmCall and surfaced in the diff.

Pre-requisite: LlmDriver must be pub from aprender-orchestrate (today it is pub(crate) behind no feature flag). Tracked as PMAT-CODE-LLM-DRIVER-PUBLIC-001, blocking M3. (M150 finding 2026-05-12: PMAT-CODE-LLM-DRIVER-PUBLIC-001 was NOT the actual blocker — LlmDriver was already pub. The real upstream surface is aprender#1638, a feature-flag config in apr-cli/Cargo.toml. M150-M154 SHIPPED the full Phase 3 outcome-parity sequence using a locally-built apr with the flag manually removed. See outcome-parity-plan.md § Implementation blocker for the corrected analysis.)

Distillation framing

Calling this "distillation" is not metaphorical. The framing maps directly onto Hinton et al. (arXiv:1503.02531):

Hinton 2015 This POC
Teacher network Claude Code (closed-source orchestration over claude-sonnet-4.6)
Student network apr code (open orchestration over Qwen3-Coder-30B-A3B-Q4_K_M via realizar)
Soft target distribution AUTHORED action stream (the assistant turns + tool round-trips), per the M2.3 rescope away from live HTTPS-proxy recording
Demonstration corpus fixtures/canonical/*.ccpa-trace.jsonl (30 sessions covering 15/15 reachable rows of apr-code-parity-v1.yaml after OOS exclusion of keyboard-shortcuts + status-line)
Loss function 1 − parity_score, where parity_score = matched_actions / total_actions
Optimizer step File-by-file PR review of apr code orchestration, driven by drift report
Convergence criterion Aggregate parity_score ≥ 0.95 (FALSIFY-CCPA-008)