{"results":[{"id":"2pc-abort-guarantees-no-side-effects","text":"When any participant is unavailable, `execute()` returns `\"aborted\"` and no participant's state is modified, even for participants that were available and could have committed independently","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-blocking-window","text":"The coordinator logs `\"committing\"` before any participant receives the commit decision, creating a window where a crash leaves participants locked indefinitely in the `\"prepared\"` state with no authority to self-resolve.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-blocking-window-is-between-prepare-and-decision","text":"A participant that has voted YES in `prepare()` holds locks and cannot unilaterally commit or abort until it receives the coordinator's decision, creating an unbounded blocking window if the coordinator fails","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-coordinator-recovery-replays-commit","text":"A coordinator with a `\"committing\"` log entry will re-send commit decisions to all participants during `recover()`, ensuring that a crash after the commit decision but before delivery still completes the transaction","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-has-design-implementation-gap","text":"Two-phase commit has a systematic gap between its safety design and implementation: the coordinator has a known blocking window between logging and sending the decision, timeouts are accepted as a parameter but never enforced, and recovery requires all participants to be available — defeating the protocol's availability goals.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-locks-held-during-in-doubt","text":"Locks acquired during `prepare()` are only released by `commit()` or `abort()`, meaning an in-doubt transaction blocks all subsequent transactions on the same keys indefinitely until the coordinator recovers","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-locks-released-on-both-paths","text":"Locks held by a transaction are released regardless of whether the transaction commits or aborts, preventing deadlocks across sequential transactions","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-log-before-decision","text":"The coordinator appends `\"committing\"` or `\"aborting\"` to its log before broadcasting the decision to participants, enabling crash recovery via `recover()` to re-send decisions that were never delivered","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-recovery-reaches-terminal-state","text":"Two-phase commit recovery drives all interrupted transactions to a terminal state by replaying committed decisions to participants, with lock ownership guards preventing cross-transaction interference during the recovery process.","truth_value":"OUT","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-result-dict-not-exceptions","text":"The 2PC protocol communicates all outcomes (commits, aborts, lock conflicts, unavailability) via `{\"outcome\": \"committed\"|\"aborted\", \"reason\": ...}` return dicts; no method raises exceptions","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-safety-gaps-compound-under-synchronous-simulation","text":"Two-phase commit's design-implementation gaps (known blocking window with no timeout enforcement, recovery requiring participant availability) are validated only under synchronous simulation where messages arrive instantly, meaning the real-world impact of coordinator crashes during the blocking window — where participants hold locks indefinitely — remains untested.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"2pc-unanimous-vote","text":"A transaction commits only if every participant in `participant_operations` votes `\"yes\"`; a single `\"no\"` vote triggers abort for all participants regardless of how many voted yes","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"abort-is-status-change-not-disk-rollback","text":"Aborting a transaction in both MVCC and SSI implementations sets a status flag (`_aborted` set or status marker); no disk writes are reversed because uncommitted data never reached disk","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"allocate-page-no-initialization","text":"`allocate_page` returns a page number containing whatever stale data was previously on disk; the caller must overwrite it with valid page content before the next WAL commit","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"apply-byzantine-is-outbound-only","text":"`_apply_byzantine` is applied exclusively to outgoing messages; incoming messages are never filtered through it, so a Byzantine node's internal state (prepared/committed sets) remains consistent even while it sends corrupted messages","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"auto-commit-not-default","text":"`Consumer` defaults to `auto_commit=False` (line 182), requiring explicit `commit()` calls; at-least-once semantics via auto-commit are opt-in, not the default behavior","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"bitcask-partial-write-safe","text":"On startup recovery, the store skips incomplete records at segment tail (header present but payload truncated) without raising errors or losing previously committed data","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"btree-allocate-page-outside-wal","text":"Page allocation during splits modifies metadata through `PageManager.write_meta` (not WAL-logged), creating a potential crash-safety gap if the process fails between allocation and the subsequent WAL commit","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"btree-delete-no-commit-on-miss","text":"When the key is not found, `delete` writes no WAL entries and performs no commit, making failed deletes purely read-only operations.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"id":"btree-double-fsync-per-mutation","text":"B-tree mutations pay for `os.fsync()` twice: once when writing the WAL entry (`btree.py:137`) and again when committing the page to the data file (`btree.py:105`), with the WAL truncated only after the data file sync confirms durability.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null}],"count":115,"limit":20,"offset":0}