Failed OpenClaw cold-archive reads are still not charged against the settlement byte budget

Aperta
#2,270 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
javascript, sqlite
Ambito
backend, databases

Direzione di ricerca

Start in hypaware-core/plugins-workspace/openclaw/src/session_db.js, especially coldEvents (lines 157–204) and its call from readSqliteSession (line 225); compare the cold-archive error path with the hot transcript_events accounting added in #2269. First settle whether failed reads should charge verified transferred bytes or declared decoded bytes, since the issue identifies this as an open design choice. Add a regression test showing that a flush stops reading several large corrupt cold archives when the byte budget is exhausted.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Source: #2269 at 88e0bac8835af5eeb446dd7e1d478e7f095c06da
Location: hypaware-core/plugins-workspace/openclaw/src/session_db.js:225 (coldEvents call) and 157-204 (coldEvents)
Severity: minor

Evidence

#2269 charges a failed candidate read against the settlement byte budget, but
only on the hot transcript_events path. The cold-archive branch of
readSqliteSession is untouched, and every throw inside coldEvents
(invalid_or_oversized_archive, archive_size_mismatch,
unsupported_archive_storage, archive_digest_mismatch,
invalid_archive_event, archive_identity_mismatch,
archive_metadata_mismatch) still reaches readOpenclawSessionIndex with the
OpenclawStorageError default bytes = 0, so budget.remaining does not move.

Every one of those throws happens after SELECT * FROM session_transcript_cold_archives has pulled the whole archive_blob out of
SQLite, and most of them after decompress(bytes, maxBytes) has expanded it
toward the 64 MiB cap and JSON.parse has walked it line by line. A cold
archive is the larger per-candidate transfer of the two paths: 64 MiB versus
the 4 MiB EVENT_MAX_BYTES a hot event is capped at.

Measured (12 candidates, each an 8.4 MiB cold archive with a valid SHA-256 and
a valid header but a wrong event_count, so the read fails at the last check
in coldEvents, settlement enricher driven directly, decode instrumented at
zlib.zstdDecompressSync):

tree decodes decoded ms peak RSS
ce99a436 (base) 12 100.7 MB 168 160 MB
88e0bac8 (#2269) 12 100.7 MB 175 159 MB

Byte-identical: #2269 does not narrow this path at all. Because
budget.remaining never moves, the per-archive pre-checks
(archive_bytes > maxBytes, raw_bytes > maxBytes, blob_bytes > maxBytes)
never tighten either, so each of up to 32 candidates can transfer and expand a
fresh 64 MiB against a budget that stays at its opening 64 MiB.

Expected behavior

A failed cold-archive read charges what it transferred against
budget.remaining, the same way #2269 made a failed hot read charge
transferredBytes(lines), so LLP 0444#reads' 64 MiB bound on "the total SQLite
payload" tracks real I/O on both branches.

Why deferral is safe

Not a regression from #2269: base and head are byte-identical here. Each single
archive read is still individually capped at 64 MiB by the maxBytes
pre-checks and the bounded decompress, the flush still walks at most 32
candidates, and nothing grows with uptime. The repair also carries a real
design question that does not belong in a byte-accounting bug fix: the honest
charge is either the verified transferred bytes (archive_bytes, checked
against fstat/length(archive_blob), but small when compression is good) or
the declared decoded bytes (raw_bytes, the same currency the success path
charges via transferredBytes(events), but a number a corrupt store asserts
rather than one this code verifies). Over-charging on a store's own claim can
drop rows, so the choice wants settling on its own.

Acceptance condition

A failed cold-archive read subtracts the bytes it moved from
budget.remaining, and a regression test shows a flush of several large
corrupt cold archives stops issuing reads once the budget is exhausted, on the
same shape the table above measures.

Evidenced behavioral defect; eligible for automatic repair.

Lingua principale
JavaScript
Stelle
11
Fork
0
Merge medio
2h 55m
PR unite (30g)
294

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di hyparam/hypaware

Tutte le issue di hyparam/hypaware

Issue simili

Altre issue su JavaScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.