# Practice review runtime

The practices module owns reviews, assignments, results and feedback history. The runtime owns job claims, attempts, preparation, scripts and transient evidence. A review can outlive every execution job that produced it.

## Execution ownership

The server selects and persists a review before runtime execution. A worker claims its job through the PostgreSQL queue. The server and the workers share no other channel. The webhook role receives provider input and does not execute reviews. Only the worker owns sandbox access.

An ITEM review executes its assigned item. A SCAN review can own many bounded file jobs, with one active job at a time. Each job has an independent UUID and a workspace-scoped review reference. A database index also permits only one active scan per workspace.

Claims carry an attempt fence. A requeue after preparation always moves the job to the next attempt number. Thus, no evidence folder, sandbox Job name or job token is used twice.

Two kinds of requeue spend no retry, because they are not the review's fault. A worker's drain counts in `drain_count`, at most 3 times. A sandbox runtime without room counts in `room_refusals`, with no limit. Only starvation or a quota that is too small ends such a review. `ReviewJob.spentAttempts()` subtracts both, and every retry-budget check reads it.

Admission locks the review before its job and assignment rows. Cancellation follows the same order and prevents later admission from publishing through the old attempt. Classified preparation reasons describe work, source access, pinned versions and capture failures without raw exception text.

## Scripts and models

Each assigned practice runs its custom script or the built-in script. The host stages one `<slug>.inputs.json` file under the script input directory. The script returns one candidate result. A custom child process has no provider credential. It calls host capabilities through typed IPC.

The host owns the attempt credential, governed model requests, deadline and usage limits. Its model assignment follows account-wide AI choice and source-person authorization. The method snapshot retains all model slots and an epoch after job cleanup. No second runtime serializer computes the method digest.

The [script runner](/contributor/practice-script-runner.md) owns the executable contract. The [AI provider guide](/admin/ai-providers.md) owns model assignment, prices and ceilings.

## Admission and composition

The worker submits candidates and trusted receipts for its owned attempt. The server returns allocated result and problem identities with verified citations. Composition can refer only to those admitted records. An ids-only admission response cannot authorize an invented problem reference.

The [workspace ABI](/contributor/agent/agent-workspace-abi.md) owns the exact result and history paths. A history refusal is not an empty result list. Source custody is checked before confirmed historical words enter the sandbox.

Preparation commits exact feedback and physical copy records before egress. Runtime completion and feedback delivery have separate states. A stopped private composition does not erase admitted results or a prepared public proposal. The [pipeline](/contributor/practice-review-pipeline.md) owns these stage boundaries.

## Recovery

A failed attempt cannot overwrite its original admitted results. A retry runs under a new fence and reuses durable assignment state.

A running attempt holds a lease (`review_job.leased_until`) on the database clock. The claim sets it, and the worker's heartbeat renews it (`WorkerLivenessReporter`). `ReviewJobZombieSweeper` recovers an attempt whose lease expired one renewal interval before its previous check, and checks the lease again under the row's lock. An attempt without a lease came from a version before leases, which no longer runs, so it is recovered too.

After a start or a stall, the sweeper recovers nothing for one renewal interval. A stall is a gap longer than `STALL_GAP` from the end of one check until the next check reads the database clock. The recoveries of a slow check do not count, so a slow check cannot postpone recovery.

Delivery recovery reads persisted copies rather than re-running a writer from raw result text. Unknown visibility permits readback, not automatic reposting.

An upgrade to a different runtime contract cancels retained queued or running work with CONTRACT\_CHANGED. The migration keeps prior proof and physical write receipts. A fresh review has new identity and current practice versions. No decoder for the previous runtime contract remains.

## Retention

Transient job payloads expire after 14 days by default. Terminal jobs expire after 90 days independently of reviews, results and feedback. Unacknowledged physical erasure receipts cannot expire with their former job. Usage keeps a durable review reference after job deletion.

The [operations reference](/admin/practice-review-operations.md) owns configurable limits and metrics. The [data map](/admin/dsms/personal-data-map.md) owns personal-data retention and erasure.
