Repository navigation
Dirty Runs: connect the typed worker path and close the A → B evidence gate #706
Description
Parent epic: #699. Depends on #701 and #705 (including their storage/claim/settlement dependencies).
Deliverable
A narrow internal/opt-in typed SQL-client bridge from real v2 claim/settlement results to the existing worker/executor and a repeatable end-to-end correctness packet for the exact candidate. Keep released v1 adapter/public start defaults unchanged. No generic protocol abstraction, new public DSL authoring API, supervisor, or production runtime promise.
Carry claim_id, exact queue/message identity, effective policy, and typed accepted/conflict/stale/terminal dispositions through the result-reporting path. Never silently fall back to v1 when v2 fails. Limit bridge entry points to the reviewed two-step contract and dedicated test flows/queues; startup compilation cannot bypass live-definition guards or enable unsupported shapes.
Use singleton reservations/claims and explicit-task recovery from #700/#703; do not restore cross-run batching through this bridge.
V2 acknowledgement transport retry resubmits the SAME retained outcome/canonical value and claim, not the handler. Implement #700's already-reviewed attempt count, absolute deadline covering in-flight SQL waits, and explicit unconfirmed-acknowledgement stopping/error surface. Preserve the first handler outcome despite shutdown or logging/reporting failures. Timeout/cancellation does not prove rollback; observe late completion/rejection without a second business outcome. Stop retries on definite accepted/conflict/stale/terminal responses. Accepted fatal size/failure results, conflict, and stale/terminal results are protocol outcomes, not new handler failures. Process death before settlement remains an external-effect uncertainty gap; no exactly-once claim.
Evidence matrix
Run the actual worker handler/executor against real PostgreSQL/PGMQ for both flow and private-step queues:
- Start A → B; no reconciler exists; A runs once and commits output + archive + durable pending work. B does not execute before later manual reconciliation.
- Simulate a LOST RESPONSE AFTER SQL COMMIT. Bounded same-result resubmission returns the stored disposition without re-running A. A mock that rejects before SQL runs does not prove this boundary.
- Keep a reporting promise pending beyond Dirty Runs: freeze the bounded A → B protocol and proof envelope #700's absolute deadline; prove bounded return to the existing worker error boundary, one handler invocation, no
failTask()substitution, and safe observation of late responses. Include shutdown during reporting and a committed-but-unobserved response. A finite retry count alone does not pass. - Throw completion/failure loggers with actual v2 settlement: the original result-reporting attempt still occurs, including bounded same-result transport replay after a telemetry error. Logging itself never triggers a transport retry or substitutes the handler outcome.
- Reconcile in separate commits, restart the processor client between dispatch/fixed point, and attempt a B claim while dispatch is still pending: no handler/history may start. Commit fixed-point clean, run B once, and finalize after B's settlement in a later chunk. Preserve B's dispatch-based delay/input and falsy/null results.
- Race claims, takeover/settlement, processors, and generations with independent connections and deterministic barriers. Exercise rollback, re-dirty, wrong protocol/route, private message-ID collisions, size boundary, poison/backoff/attention, live-definition/delete/prune rejection, and terminal replay.
- Run a baseline v1 flow and populated-baseline additive migration/type checks. Preserve actual JSR Edge and npm Node/Bun shared code paths; scope any runtime-specific evidence precisely.
Each implementation subissue supplies focused red/green tests. This issue assembles and closes the combined gate; it is not a reason to delay all tests until the end.
Repository workflow and command set
Before code, read current repository/package instructions, companion developing-pgflow, schema-dev, pgtap-testing, and migration workflow as it applies. Inspect targets with pnpm nx show project <project> --json. Start one fresh pgflow-owned environment with pnpm nx test-env:fresh edge-worker after implementation starts and before the first batch. Reuse it across batches/corrections; only one editing/database-mutating implementer at a time.
Use focused → batch → final → post-commit checks through Nx without cache overrides. Current focused interfaces:
pnpm nx test:pgtap:file core --args=--file=supabase/tests/<file>.test.sql
pnpm nx test:integration:file edge-worker --args=--file=tests/integration/<file>.test.tsAfter schemas pass focused TDD, generate the migration/types and rerun the focused check from generated artifacts. At the final exact-candidate gate, inspect affected projects, run affected lint/build/unit/types, and each applicable full target once: test:pgtap core, test:integration edge-worker, e2e edge-worker, and applicable e2e:portable-runtimes edge-worker. Include client checks if schema/type inputs affect it. E2E files share state: use configured full E2E targets, not individual files.
Save complete slow-check output and exit status. On failure, diagnose the named marker and use the repository's bounded focused reproduction/recovery process. Do not retry until green, extend deadlines as a fix, or skip a required applicable gate because #694 is open. SQL proof can progress while a runtime gate stays explicitly open; the epic is not fully complete while that required gate is open.
Acceptance and handoff
- Typed internal bridge uses the actual executor/client/database; no mock-only success or new public default path.
- The named response-loss AFTER COMMIT, committed restart, stale/conflict, fatal, and generation/race boundaries pass; all output/message effects remain once per accepted transition.
- Singleton admission and reporting deadline/attempt/shutdown/late-response checks match Dirty Runs: freeze the bounded A → B protocol and proof envelope #700. Reporting cannot hang on its first in-flight request, and definite protocol responses are not retried.
- Numeric envelope checks and unsupported-feature rejection match Dirty Runs: freeze the bounded A → B protocol and proof envelope #700 at start and result boundaries. Disabled/deferred features cannot accidentally run through v1.
- Exact revision, finalized migration/type artifacts, commands, complete evidence, and open limitations are recorded in a repository result note. Compare the post-commit tree with the tested candidate.
- The result concludes proceed with graph/recovery expansion, revise, or stop. It does not claim beta readiness, unrestricted semantics, production liveness, Terminalize tasks after the stalled-task requeue limit #689/Design strict worker ownership and fencing for safe automatic replacement #697/Investigate safe handling of uncertain external effects across retries and worker recovery #698 completion, or authorization for production migration/release.
No code deployment, release, production data write, or hub/journal change is authorized by this evidence gate.
Activity
fix(worker): preserve outcomes across result reporting failures (#708)