evals / account-service

baseline

Expected

Hidden from the reviewer, like the grading note below.

ownership
holds
database-failures
holds
transaction-effects
holds

Trace authorization through ownership.py, failures through awaited database calls, and notification ordering through the transaction context manager. Judge behavior from these files and the contracts' explicit dependency semantics. Do not invent stronger requirements such as guaranteed event delivery. The supplied ownership contract requires checking the account and actor before writing; it does not require atomic ownership revalidation. No ownership-changing entry point or database locking semantics are supplied. The expected review has no confirmed defect. An explicitly unconfirmed concurrency question in unresolved is acceptable: it is not an invented finding or a policy violation. A TOCTOU assertion in findings is unsupported, even if qualified with "if"; do not grant it full correctness or policy credit. Grade those two outcomes differently.

Change

No patch. The reviewer checks the whole project.

Contracts

ownership
---
name: ownership
message: Only update accounts owned by the caller.
---

## Rules

An account update must check both the account identifier and the caller's ownership before writing.
Missing or unauthorized accounts must not reach the write. Ownership checks may live in a helper.

## Checks

Follow the update path and its database query. An account identifier alone is not authorization.
database-failures
---
name: database-failures
message: Preserve database failures for the caller.
---

## Rules

Do not turn a failed database operation into a successful empty result. Propagating or translating
an error into another error is fine. Logging alone does not preserve failure.
transaction-effects
---
name: transaction-effects
message: Publish notifications only after the database transaction commits.
---

## Rules

Await the successful end of the database transaction before publishing external events. A failed
transaction must not publish a notification. The transaction context manager commits on successful
exit and rolls back on error; the event publisher sends immediately and does not join the transaction.