Crux Response Contract v1 (CRC-v1)

June 10, 2026 · View on GitHub

Status: M0 — spec frozen. Canonical home for the portfolio-wide response contract. Oracle: crc-v1.schema.json is the single source of truth. Every emitting endpoint serialises through it; CI validates real responses against it; the daemon serves it verbatim via get_bootstrap(topic="tool-output").

What it is

A unified, pointer-first, progressively-hydrated response envelope shared across CoreCrux /v1/query/*, VaultCrux /v1/memory/retrieve, and the Crux daemon HTTP + MCP surface. Instead of every endpoint stuffing full content in an ad-hoc JSON shape (~56K tok/q on the LME bench), a CRC-v1 response returns cheap pointers + a cost_estimate + an agent_decision + a freshness/receipts envelope, and the caller hydrates only what it needs (~1.6–7.5K tok/q at equal recall, measured on the agent-native LME benchmark).

Default-on, with a legacy escape hatch

CRC-v1 is the default response contract — there are no legacy consumers to preserve, so every read endpoint returns the pointer-first envelope by default. A caller that can't yet parse it opts out to the old full payload:

SurfaceOpt OUT to legacy (full payload)
HTTPAccept-Contract: legacy request header (also v0/none/off, or ?contract=legacy)
MCP tool callcontract: "legacy" argument

When opted out, the endpoint returns its legacy shape, byte-identical to pre-CRC-v1 — preserving CROWN receipt byte-identity for anyone who needs the old shape. The explicit opt-IN forms (Accept-Contract: crc-v1 / contract:"v1") still work but are redundant now that CRC-v1 is the default.

Default hydration is pointer (cheap epitomes); ask for ?hydrate=full|summary to get content inline within the CRC-v1 envelope, or opt out to legacy for the old full payload.

Shape (see the schema for the authority)

{
  "contract": "crc-v1",
  "kind": "search" | "addressed" | "fact" | "session",
  "hydrate_tier": "pointer" | "summary" | "full",   // CRC-v1 default = pointer
  "pointers": [ { "id", "score", "epitome<=40tok", "reason" } ],
  "content":  [ { "id", "text", "token_count" } ],   // ABSENT at pointer tier
  "cost_estimate": { "pointer": N, "summary": N, "full": N },
  "agent_decision": { "load_bearing_lane", "fused_confidence", "suggested_next_lane",
                      "lane_attribution", "read_pointers" } | null,   // null unless kind=search
  "envelope": { "freshness": {...}|null, "receipts_used", "memories_used",
                "autonomy_consumed", "links": { "verify", "open_in_console" } },
  "next": { "expand", "resolution_pointer", "canonical_slug" },
  "meta": { ... per-endpoint diagnostics ... }
}

Per-kind field presence

fieldsearchaddressedfactsession
pointers✅✅——
content (at summary/full)✅✅✅ (value)✅ (state)
cost_estimate✅ required✅optionaloptional
agent_decision✅ non-nullnullnullnull
envelope.freshness—optional✅ requiredoptional
next.canonical_slugoptionaloptional✅✅

addressed = content-pointer hydration (fetch-content / query_expand): chunk bodies don't decay, so freshness/slug are optional. fact = fact-store resolve where decay/supersession is the whole point, so envelope.freshness is required.

Addressed recall is first-class: kind=addressed|fact|session is an exact key resolve and is never routed through the BM25 ranker. It echoes next.canonical_slug so the next turn re-addresses by key (cheap, exact) instead of re-searching (fuzzy, lossy), and carries envelope.freshness so a re-verify turn is unnecessary.

Invariants (enforced by the schema + per-repo tests)

  1. hydrate_tier=pointer ⇒ content absent/empty (the cheap default actually stays cheap).
  2. kind=search ⇒ pointers and cost_estimate present.
  3. Opted-out responses (Accept-Contract: legacy) are byte-identical to pre-CRC-v1 (per-repo golden test; not expressible in this schema).
  4. The schema served by get_bootstrap("tool-output") is this exact file — drift between schema, serializer, and bootstrap seed is the failure mode M4 guards.

Vendoring

Repos that emit CRC-v1 (CoreCrux, VaultCrux) vendor a copy of crc-v1.schema.json and run validate_crc_v1.py against representative responses in CI. The canonical copy lives here; vendored copies are checked byte-equal in CI.

Validate

python3 validate_crc_v1.py crc-v1.schema.json fixtures/*.json