v0.8.0 — schema validation on /openai/v1 + smart JSON extraction

v0.7.0 plumbed x-aicodebox-json-schema through to RunSpec but the OAI
route never validated. Schema-set callers got 200 OK on malformed JSON.

/openai/v1/chat/completions now runs the same self-correction path
/run uses when x-aicodebox-json-schema is set (up to 3 re-prompts on
parse / validation failure):

  Success     → message.content = canonical re-serialized JSON
                (no fences, no prose) regardless of LLM formatting.
  Exhaustion  → HTTP 422 with the validation error in detail.
  stream=true → HTTP 400 (schema validation needs the complete
                response; no clean recovery from mid-stream parse
                failure over SSE).

parse_json_response is now tolerant of LLMs that wrap JSON in fences
mid-prose: tries clean → edge-fences → each ``` block (LAST first) →
balanced-brace {...}/[...] with string-literal + escape handling.
With a schema, the loop prefers candidates that BOTH parse AND
schema-validate. The retry budget is reserved for actual structural
failures. /run benefits too (shared helper).

Refactor: _retry_prompt + _run_json_with_retry moved from
modes/api/server.py into shared/runner.py as _json_retry_prompt +
run_with_json_retry. JSON_RETRY_MAX lives next to it.

Tests: 22 new (15 extraction + 7 OAI schema flow). test_api_run_
response patcher updated for the new call site.

Docs: README's /v1/chat/completions bullet expanded to list all the
x-aicodebox-* headers and the new 422 / 400 failure semantics —
backfills the v0.7.0 doc gap.

Migration: additive. v0.7.0 callers that silently accepted malformed
JSON now get either canonical JSON or HTTP 422 — strict improvement.