~kris/hacks

sbot

ref: 57c09c8c4fa2cd2479d9ff83a68b7fb447757a13 sbot/ARCHIVE_IMPROVEMENTS.md -rw-r--r-- 5.5 KiB
57c09c8c — Kris Yotam chore: sync local state after restore (push updates, no pull) a month ago

#sbot Archival Quality Improvements (2026-05)

This document captures concrete problems found during the 2026 grok_test collection and minimal, suckless-style fixes.

#The 4 Problems Identified

#1. Old Web Mirrors Are Painful (Dead HTTPS + Slow Hosts)

Evidence from tests:

  • oocities-org: Flood of "SSL peer certificate or SSH remote key was not OK" on almost every subpage.
  • textfiles-com: Repeated timeouts on robots.txt and root, exhausted 3 retries and gave up.

Root causes in current code:

  • fetch.c: strict CURLOPT_SSL_VERIFYPEER=1 and VERIFYHOST=2 with no option to relax for archival use.
  • fetch.h: Hardcoded FETCH_MAX_RETRIES=3 and short exponential backoff (base 2s).
  • No concept of "known slow host" or per-host backoff.
  • No way to treat certain certificate errors as non-fatal for old archives.

Proposed minimal changes:

  • Add IGNORE_SSL_ERRORS compile-time option in config.h (default 0 for safety).
  • Increase default retries or make FETCH_MAX_RETRIES and backoff tunable in config.h.
  • Consider a small "known bad hosts" mechanism or at least better logging.

#2. Pathological Bloat Risk

Evidence:

  • lowendmac-com ballooned to 250MB with only 5 files because early pages inlined enormous images.

Root causes:

  • MAX_FILE_SIZE (50MB) is defined in config.h but never enforced during fetch or inlining.
  • No per-resource size cap is passed to libcurl (CURLOPT_MAXFILESIZE is not used).
  • No early rejection of giant resources before base64 inlining (which multiplies memory).

Proposed minimal changes:

  • Actually wire MAX_FILE_SIZE into fetch.c (use CURLOPT_MAXFILESIZE + check after download).
  • Skip inlining resources over a certain size (new config option or reuse MAX_FILE_SIZE).
  • Add a warning when a resource is skipped due to size.

#3. Timeout Fragility on Slow Sites

Evidence:

  • Multiple runs (including stretch targets) were killed by the 3-minute external tool timeout before sbot could finish.
  • textfiles and oocities both showed repeated "Timeout was reached".

Root causes:

  • REQUEST_TIMEOUT is 60s (reasonable).
  • But there is no progressive backoff for hosts that are consistently slow.
  • No "slow host" tracking that increases timeouts or reduces parallelism for that host.
  • The global rate limit (RATE_LIMIT_MS) is the only politeness mechanism.

Proposed minimal changes:

  • Make REQUEST_TIMEOUT and CONNECT_TIMEOUT configurable in config.h (they already are, but document better).
  • Add optional "slow host" backoff (simple host hash + failure counter).
  • Consider a compile-time ARCHIVAL_MODE that is more patient.

#4. Asset Writing Failures on Messy Filenames / Long Paths

Evidence:

  • vintage-computer-com had many "cannot write asset" warnings for paths like 2020test/images/chmopenhouse/... with long or special names.

Root causes:

  • url_to_path() does basic query/hash stripping and extension logic, but does almost no sanitization of the actual path components.
  • No truncation of overly long filenames.
  • No replacement of characters that are problematic on some filesystems.
  • sanitize_filename() exists but is only used for the top-level output directory name.

Proposed minimal changes:

  • Improve url_to_path() (or add a helper) to sanitize individual path segments:
    • Remove or replace dangerous characters (/ \ : * ? " < > |).
    • Truncate overly long segments.
    • Optionally percent-decode for nicer on-disk names (optional, behind define).
  • Make the sanitization behavior controllable via config.h for "strict archival" vs "nice filenames".

#Design Principles for Fixes

  • All changes must be compile-time (config.h) where possible — suckless style.
  • No new dependencies.
  • Keep the binary small and the code auditable.
  • Prefer failing safely / warning over crashing or producing garbage archives.
  • Improve robustness for the "primary archival" use case the user wants, without weakening safety for normal use.

#Implementation Order (Minimal Impact First)

  1. Wire up MAX_FILE_SIZE enforcement (biggest bloat win).
  2. Add IGNORE_SSL_ERRORS option (biggest old-web quality of life win).
  3. Improve filename sanitization in url_to_path.
  4. Make retry / timeout values more configurable + add simple slow-host backoff.
  5. Update documentation and defaults if needed.

#Implemented Changes (2026-05)

All changes follow suckless principles: compile-time configuration, minimal diff, no new dependencies.

#1. MAX_FILE_SIZE Enforcement (anti-bloat)

  • Wired CURLOPT_MAXFILESIZE into libcurl.
  • Added post-download size check in fetch_url.
  • Added guard in fetch_and_encode before base64 inlining.
  • This directly addresses the lowendmac 250MB bloat case.

#2. IGNORE_SSL_ERRORS Option (old web support)

  • New define in config.h (default 0 = strict).
  • When set to 1, relaxes SSL peer/host verification.
  • This makes archiving old Geocities-style mirrors and dead personal sites practical without constant warnings or early failure.

#3. Improved Filename Sanitization

  • Added character sanitization in url_to_path (replaces \ : * ? " < > | with _).
  • Helps with the long/weird paths seen in vintage-computer dumps.

#4. Better Defaults for Archival Use

  • Increased FETCH_MAX_RETRIES from 3 → 5.
  • Increased default REQUEST_TIMEOUT from 60s → 90s.
  • These give more resilience on slow historical hosts without changing behavior drastically for normal use.

These changes make sbot significantly more robust as a primary archival tool while keeping the codebase small and the philosophy intact.