HKUDS/Vibe-Trading · critical · LedgerCorruptionError

{verification.first_break}

Error message

{verification.first_break}

What it means

append_record verifies the existing chain before extending it; if a prior record was edited, deleted, or corrupted, it raises LedgerCorruptionError with the first break's description instead of appending onto unknown history.

Source

Thrown at agent/src/governance/ledger.py:441

            # began at genesis would report every rotated ledger as corrupt.
            # Continuing from the newest segment is also what makes deleting a
            # whole segment leave a detectable seam.
            start_seq, start_prev = 1, GENESIS_PREV_HASH
            segments = archive_segments(path)
            if segments:
                tail = _read_raw_records(segments[-1])
                if tail:
                    start_seq = int(tail[-1]["seq"]) + 1
                    start_prev = str(tail[-1]["record_hash"])

            verification, last_seq, last_hash = _walk_chain(
                _iter_parsed_lines(existing_text.splitlines()),
                start_seq=start_seq,
                start_prev_hash=start_prev,
            )
            if not verification.ok:
                assert verification.first_break is not None
                raise LedgerCorruptionError(verification.first_break)

            seq = last_seq + 1
            record_hash = compute_record_hash(seq, last_hash, payload)
            full_record: dict[str, Any] = {
                **payload,
                "seq": seq,
                "prev_record_hash": last_hash,
                "record_hash": record_hash,
            }
            line = (json.dumps(full_record, ensure_ascii=False) + "\n").encode("utf-8")

            handle.seek(0, os.SEEK_END)
            handle.write(line)
            handle.flush()
            if fsync:
                try:
                    os.fsync(handle.fileno())
                except OSError as exc:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Quarantine the corrupt file and start a fresh ledger, preserving the original for forensics
  2. If the tail is a truncated partial record from a crash, remove the incomplete line and re-verify (only if you can prove the break is truncation at the end)
  3. Audit writers to ensure only append_record touches the file; enable fsync

Example fix

# before
append_record(ledger_path, payload)  # raises LedgerCorruptionError
# after (quarantine + restart)
shutil.move(ledger_path, quarantine_dir / ledger_path.name)
append_record(ledger_path, payload)  # fresh chain, old file preserved
Defensive patterns

Strategy: fallback

Validate before calling

result = verify_chain(path)
if not result.ok:
    quarantine(path)  # move aside before any append

Type guard

def ledger_is_healthy(path) -> bool:
    return verify_chain(path).ok

Try / catch

except LedgerCorruptionError as e: log first_break, quarantine the file, start a fresh ledger, alert — never overwrite the corrupt file

Prevention

When it happens

Trigger: append_record on a ledger file where some line was modified, a middle record removed, or the file was truncated/corrupted (e.g. partial write, manual edit).

Common situations: Disk issues or interrupted writes; someone edited the .jsonl ledger by hand; buggy tooling rewrote the file losing a record.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/279f87ad072b2eab. Report an issue: GitHub.