You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Connect the qualified Temporal Rust workflow to the existing tenant/product-scoped CheckpointedPageRunner and DocumentFinalizer, preserving durable page checkpoints and publishing a provider-neutral complete or partial result without placing document content in Temporal history.
Capacity and SLO assumptions
20 job starts/s peak per region, burstable to 50/s.
1–300 pages/job; 10 MiB/page decoded ceiling; page artifacts remain in object storage, never workflow history.
At 20 starts/s and an assumed 10 pages/job, the worker tier must sustain 200 page attempts/s; page concurrency remains a bounded deployment setting.
Job-control API availability target: 99.9% monthly.
Accepted-job durability target: no acknowledged job loss; RPO 0 for CNPG workflow metadata, provider artifacts governed by object-storage durability.
Control-plane p99 target: 500 ms excluding OCR execution; page and document completion latency are measured separately by document class.
These assumptions must be validated by the qualification soak before production sizing.
Architectural decision to review
CNPG PageWorkflow is the sole authority for page-attempt count and terminal page state. Temporal owns durable orchestration, cancellation, timers and worker recovery, but does not count a provider/page failure as a Temporal retry.
One identifiers-only Temporal activity calls CheckpointedPageRunner::run_once.
A recorded retryable page failure returns activity success with metadata-only running state; the workflow schedules the next bounded runner iteration and CNPG advances the attempt.
Temporal activity retries are reserved for failures where the durable CNPG transition is unknown or unavailable (connection loss, timeout, optimistic revision conflict). Duplicate delivery is safe through CNPG revision checks and deterministic page activity keys.
Validation, tenant/product scope, missing workflow and permanent-input failures are non-retryable activity failures.
Once CNPG reports completed or partial, a metadata-only finalizer activity invokes DocumentFinalizer; result bytes move only between object storage and the service process.
Cancellation records durable cancellation before workflow closure; no new page work is claimed afterward.
This separates transport recovery from business retry policy and avoids two competing page retry counters.
Every activity input is bounded and contains only validated tenant_id, product_id, job_id, document identity/version and correlation metadata. Every CNPG lookup is scoped by tenant and product under RLS. Activity outputs, errors, logs, traces and Temporal search/history attributes contain no OCR text, page bytes, signed URLs, secret values or extracted fields.
Acceptance criteria
ADR records the retry-authority decision, alternatives, dependency failure behaviour, rollback and cost implications.
Red tests prove identifiers-only activity serialization and metadata-only results/errors.
Real Temporal + real PostgreSQL test proves page attempt exhaustion through the SDK produces the existing durable partial result and preserves successful page artifacts.
Duplicate activity delivery does not reprocess a successfully checkpointed page or double-publish a result.
Cross-tenant and cross-product activity identifiers cannot load or mutate a job.
Cancellation before start, during page work, between runner iterations and during finalization is deterministic and leaves a recoverable durable state.
Dependency timeout/revision conflict is retryable; scope/validation/not-found is non-retryable; page-provider failure is recorded by CNPG and returned as activity success.
Finalizer delivery is idempotent and returns only result status/locator metadata allowed by the public contract.
1/50/51/300-page live cases preserve continue-as-new and bounded history.
PR remains draft until the design decision and Temporal Rust qualification are human-reviewed.
Failure behaviour
CNPG unavailable: activity fails retryably with bounded backoff; no provider work starts without a durable claim.
Object storage/provider unavailable: the page runner records the bounded page failure; surviving pages continue and the final result may be partial.
Temporal unavailable: accepted histories remain durable and workers reconnect; API starts fail fast after the bounded RPC deadline.
Final result publication interrupted: idempotent publication resumes from durable page artifacts.
Valkey/Qdrant/Langfuse unavailable: not part of this activity correctness path; processing continues with degraded cache, memory or telemetry.
Delivery and rollback
Ship behind a separate worker build/version and task-queue route. Run sandbox, replay, shadow and canary qualification before switching new workflows. Rollback routes new starts to the prior build while candidate histories remain replayable by their compatible worker. No schema deletion or production rollout is part of this issue.
Explicitly out of scope
Production provider credentials or provider selection policy.
Kubernetes/GitOps rollout and secret mutation.
Human review UI.
Claiming completion of the required 24-hour soak before it has actually run.
Outcome
Connect the qualified Temporal Rust workflow to the existing tenant/product-scoped
CheckpointedPageRunnerandDocumentFinalizer, preserving durable page checkpoints and publishing a provider-neutral complete or partial result without placing document content in Temporal history.Capacity and SLO assumptions
These assumptions must be validated by the qualification soak before production sizing.
Architectural decision to review
CNPG
PageWorkflowis the sole authority for page-attempt count and terminal page state. Temporal owns durable orchestration, cancellation, timers and worker recovery, but does not count a provider/page failure as a Temporal retry.CheckpointedPageRunner::run_once.runningstate; the workflow schedules the next bounded runner iteration and CNPG advances the attempt.completedorpartial, a metadata-only finalizer activity invokesDocumentFinalizer; result bytes move only between object storage and the service process.This separates transport recovery from business retry policy and avoids two competing page retry counters.
Security and trust boundaries
Assets: tenant documents, extracted PII, object locators and product identity. Threats: cross-tenant callers, malicious uploads/OCR prompt injection, compromised worker/provider, and accidental telemetry leakage.
Every activity input is bounded and contains only validated
tenant_id,product_id,job_id, document identity/version and correlation metadata. Every CNPG lookup is scoped by tenant and product under RLS. Activity outputs, errors, logs, traces and Temporal search/history attributes contain no OCR text, page bytes, signed URLs, secret values or extracted fields.Acceptance criteria
partialresult and preserves successful page artifacts.Failure behaviour
Delivery and rollback
Ship behind a separate worker build/version and task-queue route. Run sandbox, replay, shadow and canary qualification before switching new workflows. Rollback routes new starts to the prior build while candidate histories remain replayable by their compatible worker. No schema deletion or production rollout is part of this issue.
Explicitly out of scope
Parent: #1
Qualification dependency: #25