Task 9 — Packaging, example config, docs, Job API smoke (P2 exit)
Branch: feat/gateway-p2-jobs-ocr · Base HEAD: b8661b1
What was added
1. Example config — deploy/gateway.example.yaml
Three job-typed upstreams appended (existing LLM/embedding upstreams kept intact):
| id | type | adapter | operation | models | api_key_env | submit_path | slots |
|---|---|---|---|---|---|---|---|
paddleocr |
ocr-http |
sync-http |
ocr |
paddleocr |
— | /predict |
total 4 / batch 4 |
azure-di |
ocr-http |
azure-di |
ocr |
azure-di-layout-v4, azure-di-read-v4 |
AZURE_DI_KEY |
…prebuilt-layout:analyze?api-version=… (+ poll_path) |
total 2 / batch 2 |
doc-classifier |
classify |
classify |
classify |
doc-classifier |
— | /classify |
total 4 / batch 2 |
All class: on_prem. The azure-di entry carries the Task-5 caveat comment: DI returns an absolute
Operation-Location; its host/scheme may not be reachable as-is on an on-prem/proxied DI and must be
normalized to endpoints[0] / poll_path at deploy. config.Load accepts the file (verified: 7 upstreams
parse, adapter/operation/slots resolved correctly).
2. README — README.md
New Job API section: POST /jobs (single + fan-out envelope) with the full header table
(X-Tenant-Id/Surface/User-Id/Request-Id/Priority/Idempotency-Key/X-Doc-Hash/X-Doc-Pages), GET /jobs/{id}
with queued (queue_position/eta_ms) vs processing (stage/progress) vs completed/failed fields,
idempotency + JOB_UNKNOWN-resubmit semantics, fan-out max_parallel, and the note that the Job API only
activates when a ocr-http/classify upstream is configured. Plus a Deploy-time live-fire checklist
(see below) and pointers to both smoke entry points.
Upload: https://x056.think.val.id/README.md
3. Smoke — Go integration test + deploy bash script
Chosen approach: a Go integration test as the reliably-runnable-here smoke, plus a bash script for deploy-time.
internal/server/jobs_smoke_test.go—TestJobAPISmoke(GREEN,-race): wires the REAL server mux +
EnableJobs(LocalStore + realSyncHTTPAdapter) against a local echo stub ocr-http upstream — no
real PaddleOCR/Azure-DI needed. Asserts:
1.POST /jobs(withIdempotency-Key) → 202queued, then polls tocompletedand verifies the stub's
result body is returned verbatim; upstream hit exactly once.
2. Resubmit same(tenant, Idempotency-Key)→ samejob_id, upstream still hit exactly once (no dup run).
3.GET /jobs/{unknown}→404 {code:"JOB_UNKNOWN"}.scripts/jobs_smoke.sh(matches P0smoke.shstyle): deploy-time drill against a running gateway with
a live job upstream — submit→poll→completed, idempotent resubmit (same job_id), JOB_UNKNOWN 404.bash -nclean.
4. CONVENTIONS.md — untouched (intentional)
The Job API contract engines rely on (JOB_UNKNOWN, queued-vs-processing clock, idempotency-resubmit) is
already in v1.0 §3/§4. Adapter names and submit_path are engine-invisible gateway config, not part of the
cross-service contract, so no clarification / version bump is warranted per the file's own rule.
Gate results
go build ./...— OKgo vet ./...— OKgo test -race ./internal/jobs/ ./internal/server/— ok (jobs 4.1s, server 2.0s)go test ./...— all packages ok
Deploy-time live-fire checklist (NOT run here — no real upstreams reachable from the dev box)
Documented in README under "Deploy-time live-fire checklist":
- PaddleOCR reachability: paddleocr endpoint + /predict answers from the gateway container; a real doc
round-trips to completed (scripts/jobs_smoke.sh MODEL=paddleocr).
- Azure-DI Operation-Location normalization: confirm the returned absolute URL's host/scheme is reachable
from the gateway (or normalize to endpoints[0]/poll_path); verify AZURE_DI_KEY set.
- doc-classifier /classify reachability; interactive-priority submissions complete quickly.
- Audit: an OCR job emits an event on ahu.ai.audit with operation=ocr + doc_hash (redis-cli XLEN ahu.ai.audit).
Concerns
- The example
paddleocr/azure-di/doc-classifierendpoints (ports 8010/8011/8012 on 192.168.83.20) are
placeholders — real ports must be set at deploy (the GPU-host survey lists ahu-classifier as loopback-bound). - Azure-DI
submit_pathhardcodesprebuilt-layout+ api-version; multi-model DI use (e.g.azure-di-read-v4)
may need the model id templated into the path at deploy rather than a fixed submit_path. - The bash
scripts/jobs_smoke.shcannot be exercised on the dev box (no live upstream); its logic mirrors the
green Go test.