fix(ocr): review pass — min-ada floor regression test, auth-before-parse, failure-path reconciliation, disclosure label coverage
Fixes 2 critical, 2 important, and 5 minor findings from review of 069edcb:
- C1: add a happy-path test that reaches postOcrEscrow.ts's escrowLockFloor
call and asserts the locked amount; verified it fails against a bare
economicTotal and passes against the real code.
- C2: gate /v1/ocr/extract (auth + rate limits) before the 16mb body parser
so an unauthenticated caller can no longer force a full buffer/JSON.parse.
- I2: hoist result/used/escrowRef in the OCR one-shot handler so the failure
path records escrow_ref/supplier/cost when an escrow was actually posted,
and emit an ocr_failed structured log line mirroring ocr_settled.
- I3: export venueAttribution and cover its sanitization directly; add a
stubbed happy-path route test asserting the first-party-brokered
disclosure label reaches the response.
- Minor: drop unused hfWeightsSource end to end, rename a misleading test,
make the OCR capability template's pinning language conditional on the
self-hosted upstream, tighten the /v1/ocr path-prefix guard, and make
preflight's required_lovelace use the same escrowLockFloor the builder
locks (exported from the shared tx barrel for gateway use).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -52,7 +52,6 @@ OPENAI_TIMEOUT_MS=120000 # page inference is seconds; keep < advert max
|
||||
# openai-vision upstream only (attestation upgrade path):
|
||||
# OCR_PROMPT_OVERRIDE= # exact serving prompt, pinned at integration
|
||||
# HF_MODEL_REVISION= # 40-hex checkpoint SHA; mismatch refuses Claim
|
||||
# HF_WEIGHTS_SOURCE=hf:datalab-to/chandra-ocr-2
|
||||
# REVISION_PROBE_URL= # e.g. http://chandra-vllm:8000/info
|
||||
|
||||
# ── Service ───────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"capability_id": "ocr.page.extract.chandra-ocr-2.v1",
|
||||
"weights_source": "hf:datalab-to/chandra-ocr-2",
|
||||
"model_revision": "<40-hex commit SHA pinned at endpoint provisioning>",
|
||||
"model_revision": "<40-hex commit SHA; self-hosted (OCR_UPSTREAM=openai-vision) deployments only — the Datalab-hosted default (OCR_UPSTREAM=datalab) is a third-party API with no pinnable checkpoint, so this is unset there>",
|
||||
"license": "modified OpenRAIL-M (weights); Apache-2.0 (code)",
|
||||
"request_shape": {
|
||||
"route": "POST /v1/ocr/extract",
|
||||
@@ -14,8 +14,8 @@
|
||||
"verify": "GET /capability → pub_key_hex; verify signature over canonical(receipt)"
|
||||
},
|
||||
"revision_probe": {
|
||||
"route": "<runtime info route reporting the loaded checkpoint>",
|
||||
"policy": "probe before every Claim; mismatch refuses the job"
|
||||
"route": "<runtime info route reporting the loaded checkpoint; self-hosted (openai-vision) upstream only>",
|
||||
"policy": "self-hosted (OCR_UPSTREAM=openai-vision) upstream: probe before every Claim, mismatch refuses the job. Datalab-hosted default (OCR_UPSTREAM=datalab): per-job liveness probe only, no checkpoint pin."
|
||||
},
|
||||
"operator_disclosure": "first-party (HAL8-operated supplier)"
|
||||
}
|
||||
|
||||
@@ -165,12 +165,6 @@ export interface SupplierConfig {
|
||||
* Env: HF_MODEL_REVISION. "" = no pin.
|
||||
*/
|
||||
hfModelRevision: string;
|
||||
/**
|
||||
* Hub identity of the served weights, e.g. "hf:datalab-to/chandra-ocr-2".
|
||||
* Recorded for telemetry now; feeds the receipt extension when that
|
||||
* schema is added. Env: HF_WEIGHTS_SOURCE. "" = unset.
|
||||
*/
|
||||
hfWeightsSource: string;
|
||||
/**
|
||||
* Serving-runtime info route reporting the loaded checkpoint (TGI-style
|
||||
* /info or vLLM equivalent). Env: REVISION_PROBE_URL. "" = probing off.
|
||||
@@ -422,7 +416,6 @@ export function loadConfig(env: Record<string, string | undefined>): SupplierCon
|
||||
if (hfModelRevision !== "" && !/^[0-9a-fA-F]{40}$/.test(hfModelRevision)) {
|
||||
throw new Error("loadConfig: HF_MODEL_REVISION must be a 40-hex commit SHA when set");
|
||||
}
|
||||
const hfWeightsSource = env.HF_WEIGHTS_SOURCE ?? "";
|
||||
const revisionProbeUrl = env.REVISION_PROBE_URL ?? "";
|
||||
// Datalab upstream: the health route is derived from DATALAB_BASE_URL, so
|
||||
// the liveness probe defaults ON without a REVISION_PROBE_URL. The
|
||||
@@ -489,7 +482,6 @@ export function loadConfig(env: Record<string, string | undefined>): SupplierCon
|
||||
datalabTimeoutMs,
|
||||
ocrPromptOverride,
|
||||
hfModelRevision,
|
||||
hfWeightsSource,
|
||||
revisionProbeUrl,
|
||||
revisionProbeMode,
|
||||
liveChain,
|
||||
|
||||
@@ -1385,7 +1385,7 @@ export function createApp(deps: SupplierDeps): Application {
|
||||
// below; every other route keeps the 1mb ceiling.
|
||||
const jsonBody = express.json({ limit: "1mb" });
|
||||
app.use((req, res, next) =>
|
||||
req.path.startsWith("/v1/ocr") ? next() : jsonBody(req, res, next));
|
||||
req.path.startsWith("/v1/ocr/") ? next() : jsonBody(req, res, next));
|
||||
|
||||
// /healthz is mounted FIRST and uses no deps — it must succeed regardless
|
||||
// of chain/state/config (independent of /status free/working/offline).
|
||||
|
||||
Reference in New Issue
Block a user