Practice review operations
Use this reference to configure the runtime and monitor a deployed instance. Workspace administrators should start with Practice Review.
Deployment configuration
Configuration metadata in the server is the source of truth for property names, types, and defaults. The reference Compose files are the source of truth for which environment variables they forward; do not copy those inventories into another deployment manifest from this page.
A working deployment must:
- enable the agent runtime on both the submitting server and claiming worker;
- make repository checkout and the shared fabric volume available to every worker that captures repository evidence;
- set campaign, request-rate, retry, and retention limits appropriate to its budget and governance policy.
Who gets practice review is not among them. There is no instance-wide population flag: each workspace turns itself on, and decides its own coverage.
See the server configuration and reference Compose files before changing an environment variable. Unknown or unforwarded variables do not configure the application.
Repository checkouts, replay metadata, and content-addressed evidence share the fabric root. A split or multi-host deployment must mount the same durable read-write filesystem on every server and worker, with cross-process locks, atomic rename, and access controls suitable for source content.
ADR 0039 defines the accepted 1.0 replacement; current releases still require this mount.
Source authorization is not a deployment toggle. The shipped artifact-source contract fixes which governed sources each purpose may use; integrations only determine which authorized sources are available. See Artifact-source governance.
Running instance
Nothing on this page configures a workspace. Model readiness, coverage, delivery status, autonomy, spend and the per-artifact trace are all workspace-administrator screens, and Practice review is the guide to them.
Queue health
The job queue exposes its own signals — alert off these rather than reading application logs.
agent.queue.oldest_age_seconds— age of the oldest eligible queued job,0when empty. This is the one to alert on: a briefly busy queue and a stuck one both show non-zero depth, but only a stuck queue shows a climbing age.agent.queue.depth— queued jobs eligible to run now.agent.queue.held— jobs parked on an exhausted budget.agent.queue.running— jobs running fleet-wide.agent.queue.health.sampler.failures— failed samples; the gauges keep their last-good value rather than reporting a false empty queue.agent.job.claim.latency— time between a job becoming eligible and being claimed.agent.job.execution.duration— tagged byjobTypeand outcomestatus.agent.job.delivery.recovered— deliveries stuck by an executor crash and successfully re-attempted.agent.job.retention.stripped/agent.job.retention.deleted— rows pruned by the retention sweep.llm.budget.exhausted/llm.budget.blocked— a cap crossed, and work refused at a cap.practice.review.refused— refused reviews, tagged byphase(submissionorexecution) andreason.practice.feedback.dispatch— durable-dispatch outcomes, tagged by boundeddestinationandstate. Alert on sustainedUNCERTAINorFAILEDoutcomes.UNCERTAINmeans delivery is not yet confirmed;FAILEDis terminal after the retry limit or an unrecoverable dispatch record.
Query /actuator/health/readiness for aggregate readiness. An authorized response includes the
practiceReview component. An enabled review worker reports OUT_OF_SERVICE with
GIT_CHECKOUT_DISABLED when repository checkout is disabled, or SOURCE_AUTHORIZATION_EXPIRED when an
automated-review source authorization has expired. Missing model bindings are workspace-specific and remain
visible in Review activity and the refusal counter; they do not remove the worker from service.
Gauges are sampled periodically; timers and counters are recorded when the corresponding event occurs. Metric names in the instrumented code are the source of truth for dashboards and alerts.
Log correlation
The application emits one JSON object per log line, so worker logs filter by the correlation keys
under mdc with the tools already in the shipped Compose stack. From the directory you deploy from:
# All log lines for one agent job
docker compose logs --no-log-prefix application-worker \
| jq -cR 'fromjson? | select(.mdc."job.id" == "<job-uuid>")'
# All errors for one workspace
docker compose logs --no-log-prefix application-worker \
| jq -cR 'fromjson? | select(.mdc."workspace.id" == "<workspace-id>" and .level == "ERROR")'
A deployment that ships logs to its own collector can key dashboards and alerts on the same mdc
fields; label names there are deployment-specific.
Retention. Terminal job payloads are stripped before their rows are deleted, so row retention shorter than payload retention is incoherent — the application refuses to start rather than accept it. Treat the fabric root as sensitive storage. Delivery-policy evaluations and dispatch intents follow their owning review ledger. Disconnect, person erasure, and workspace purge remove their matching copies. Once a sent or withheld dispatch has been projected into that ledger, its duplicate summary and inline-comment payload is erased while the destination key and provider references remain as the idempotency record. A failed dispatch keeps its package because an administrator can still retry it. Selected coverage targets follow their workspace membership or monitored repository.
Dispatch recovery. One dispatch owns the exact summary and inline comments in a review. Before each
provider create, it reconciles the stable marker or recurrence key already stored with the provider. A
found placement is preserved, a definitive not-found permits the first write, and an inconclusive lookup
leaves the package UNCERTAIN rather than risking a duplicate. The dispatch becomes SENT only after the
whole package converges.
Two consequences to plan for:
- Sustained
UNCERTAINmeans Hephaestus cannot prove whether the provider accepted the write, not that feedback is queued. Fix provider connectivity or credentials so reconciliation can continue. - A dispatch interrupted mid-write can outlive its retry budget without reaching
FAILED. It is deliberately not failed, because one of its provider objects may be live, and remains uncertain until provider lookup can confirm the outcome.
Do not repair an UNCERTAIN dispatch by editing its row. Restore provider lookup instead; the state, write
fence, retry count, and lease together prevent duplicate provider writes.
Limits you should know about
Configuration metadata and the artifact-source catalog are the source of truth for current values. These behaviors matter independently of their exact defaults:
- Background task cadences are fixed in code. Their thresholds may be configurable even when their polling schedules are not.
- Retryable occurrences eventually lapse. A workspace left misconfigured can accumulate retries and then go quiet when their deadline passes.
- Nothing is ever deleted from the occurrence ledger, in any state, including retired rows. It is the record of what was not done, and it only grows. Size it accordingly on a busy instance.
- The repository-tree capture is bounded, by file count, total size, and per-file size
(
GIT_TREE_MAX_FILES,GIT_TREE_MAX_TOTAL_SIZE,GIT_TREE_MAX_FILE_SIZE). When a bound bites, the capture reports itself partial and names which bound it hit rather than silently truncating. The values in force are the ones declared in the artifact-source catalog's selection scope for that source — read them there rather than from a copy. None of the three is forwarded by the shipped Compose files. - Linked Outline documents are retrieval-limited, and the mentor and review paths do not agree. A review resolves documents linked from the work first and only tops up a small number by search; the mentor searches the whole corpus and truncates each document. Neither path can report that it found everything, and neither is a substitute for the other when you are diagnosing missing context.
- No screen edits what the model is told. What Hephaestus observes is shaped by each practice's criteria; the wording it then chooses is shaped by a prompt that ships with the release. Changing the latter is a code change.
Rollback
Before upgrading, create and verify a database snapshot as described in Backup and restore. To return to the previous release after this migration, stop all Hephaestus roles, restore the snapshot, then deploy the previous version. Do not run the previous version against the migrated schema.