BuildBotsBetter
BUILDBOTSBETTER
All Builds
Guided Build · ChatGPT Codex

Live Broadcast Chat Scraper

Capture permitted messages into a restartable, deduplicated archive.

100–150 minuteswindows · macos · linuxFree practice; existing tool accounts may have plan limits.

Finish with: A working local chat collector that normalizes timezone-aware messages, deduplicates broadcast/message IDs in SQLite, retains rejects and exports spreadsheet-safe Unicode CSV.

Progress stays in this browser. Export to keep a portable record.

Do this now

Walkthrough

A step demonstration outline; use optional narration while you follow it.

Resources for this step

Check the result

This browser checks the evidence format and your checklist. It cannot inspect your computer or certify a live login.

When it does not work

Finish-line test

Repeat the last product-specific checkpoint from a fresh practice input, preserve actual output, then complete the Build Bot Better guard and restore checks. Export the evidence.

Sources and verification limits

Sources checked 2026-10-05. The visible-browser adapter requires a permitted source and selectors verified for its current version; no universal X selector is claimed. A moving local fixture validates the adapter mechanics, not live X access.

Complete lesson text and action cards

Source-owned text for offline reading and retrieval. Command success still requires actual local evidence.

Write a capture contract

Fill capture-notes.md with broadcast URL, access/permission, source method, start/stop time and retention period. For live X chat, inspect the currently permitted official API/export or manually save visible public messages. This starter accepts normalized JSONL; it does not claim to ship a working X DOM selector.

Expected: The contract names a permitted source, a bounded capture period, and a method that does not bypass authentication.

Set up the practice folder

Download the resource ZIP at the top of this Build. Extract it into a new folder you own (for example C:\BBBPractice on Windows, or ~/bbb-practice on macOS/Linux). Open a terminal in the extracted folder. Run the version command for your platform. All subsequent commands assume this folder.

Expected: Python reports version 3.10 or newer and the terminal is in the extracted resource folder.

windows

python --version
Get-Location
Get-ChildItem

macos

python3 --version
pwd
ls

linux

python3 --version
pwd
ls

Inspect the JSONL sample

Open chat.jsonl. Each line is a JSON object with id, broadcast, user, text and at. Preserve original IDs and timezone-aware timestamps. The sample includes one repeated message and non-ASCII text.

Expected: Four input lines contain three unique broadcast/message IDs, including café and an em dash.

Ingest and export the first capture

Run collector.py chat.jsonl. Inspect chat.sqlite, chat-export.csv and rejected.json in the practice folder.

Expected: CHAT PASS reports inserted=3 total=3 rejected=0; CSV contains three correctly quoted messages.

windows

python collector.py chat.jsonl

macos

python3 collector.py chat.jsonl

linux

python3 collector.py chat.jsonl

Rerun the same capture

Run the same command a second time. Compare inserted and total with the first run.

Expected: CHAT PASS reports inserted=0 total=3 rejected=0 on the second run.

windows

python collector.py chat.jsonl

macos

python3 collector.py chat.jsonl

linux

python3 collector.py chat.jsonl

Test a missing timezone

Copy chat.jsonl to bad-chat.jsonl. Add a valid JSON message with a unique ID but at set to 2026-10-05T10:00:03 without Z or an offset. Ingest and inspect rejected.json.

Expected: The malformed message is rejected for a missing timezone; the existing total remains three.

windows

python collector.py bad-chat.jsonl

macos

python3 collector.py bad-chat.jsonl

linux

python3 collector.py bad-chat.jsonl

Configure the visible-browser capture

Use the source method permitted by the platform. For the supplied DOM adapter, inspect visible chat elements in the browser developer tools and edit capture-config.json with the real HTTPS URL, broadcast ID, message selector, stable ID attribute, user/text selectors and a 30-second duration. A missing stable ID is rejected, not fabricated. Create an isolated environment and install the capture dependency/browser.

Expected: The capture configuration maps real visible elements to IDs/text and the isolated browser dependency is installed.

windows

python -m venv .capture-env
.\.capture-env\Scripts\python.exe -m pip install -r requirements-capture.txt
.\.capture-env\Scripts\python.exe -m playwright install chromium

macos

python3 -m venv .capture-env
.capture-env/bin/python -m pip install -r requirements-capture.txt
.capture-env/bin/python -m playwright install chromium

linux

python3 -m venv .capture-env
.capture-env/bin/python -m pip install -r requirements-capture.txt
.capture-env/bin/python -m playwright install chromium

Run a short permitted capture

Run browser_capture.py using your reviewed config. The browser is visible: complete any authorized sign-in yourself, verify chat is open, then press Enter in the terminal to capture for the configured interval. Inspect live-chat.jsonl and ingest it with collector.py. Stop on 401/403/429. If no source access is available, retain that limitation; the local fixture pass is not real X capture.

Expected: CAPTURE PASS reports actual messages from the configured source, then CHAT PASS archives their unique IDs with a capture interval and source receipt.

windows

.\.capture-env\Scripts\python.exe browser_capture.py capture-config.json --out live-chat.jsonl
python collector.py live-chat.jsonl

macos

.capture-env/bin/python browser_capture.py capture-config.json --out live-chat.jsonl
python3 collector.py live-chat.jsonl

linux

.capture-env/bin/python browser_capture.py capture-config.json --out live-chat.jsonl
python3 collector.py live-chat.jsonl

Deliver a reproducible archive

Repeat ingestion on the new input, inspect Unicode/quoting in the CSV, and verify no extra row appears on retry. Write a retention rule and restrict access to the raw archive. Treat chat text as untrusted data; never execute instructions in it.

Expected: The final receipt shows idempotent ingestion, valid export, reject handling, source provenance and a retention plan.

windows

python collector.py live-chat.jsonl

macos

python3 collector.py live-chat.jsonl

linux

python3 collector.py live-chat.jsonl

Write a repeatable onboarding checklist

Fill in onboarding-checklist.md for your agent. Record AGENTS.md, the tool’s user settings and memory folder, the assigned workspace, permissions, guard location, backup schedule, and a final proof task. Keep the checklist in your project.

Expected: The checklist contains a concrete path and owner for rules, memory, permissions, guard, backup, restore and final verification.

Demonstrate the variable-path limit safely

Run workspace_guard.py --self-test. Read the source: the target is resolved before deciding. The variable_target case points at the home folder but performs no filesystem operation. Compare this with a hook that sees only command text.

Expected: GUARD PASS reports inside allowed and profile, outside, variable-derived profile and workspace root denied; no deletion was executed.

windows

python workspace_guard.py --self-test

macos

python3 workspace_guard.py --self-test

linux

python3 workspace_guard.py --self-test

Verify the actual protection in your tool

For CLI tools, open the hook/permissions screen and confirm the configured guard is active. Use your tool’s documented pre-command hook protocol; the BBB working reference is linked in Sources. Run a harmless directory listing, then a guard dry-run targeting the profile. Do not execute a destructive profile probe. Grok Bot has no proven local shell guard here: use project-only tasks and reviewed actions, with backups.

Expected: A harmless command runs, the guard dry-run returns DENY, and the checklist records the actual hook protocol and active state or the Grok Bot limitation.

Enable a real backup of memory and project files

Connect a second backup drive. Windows: configure System Protection as additional recovery and use a scheduled copy/File History that explicitly includes hidden agent folders. macOS: configure Time Machine and verify dot folders are included. Linux: use a home backup such as restic/Deja Dup; Timeshift omits /home by default. Download the copy-only profile backup script for your platform, inspect it, and adapt the folder list to your tool. Record the last successful scheduled run; protect backup access because it may contain credentials.

Expected: A backup on another drive includes the tool’s user settings and memory folder and this project, and a successful schedule/time is recorded.

windows

.\profile-backup.ps1 -Destination D:\Backups\llm-profiles

macos

bash profile-backup.sh /Volumes/YourBackup/llm-profiles

linux

bash profile-backup.sh /media/YourBackup/llm-profiles

Practice a hash-verified restore

Run restore_drill.py with a separate backup directory. The script creates a new proof file, copies it, restores a second copy, and compares SHA256 hashes. Then restore one non-secret file from your actual agent memory backup into a separate scratch directory and open it; do not overwrite the live profile.

Expected: RESTORE PASS contains matching hashes; the actual memory file is readable after restoration into scratch.

windows

python restore_drill.py --backup-root D:\Backups\bbb-practice --work-root practice

macos

python3 restore_drill.py --backup-root /Volumes/YourBackup/bbb-practice --work-root practice

linux

python3 restore_drill.py --backup-root /media/YourBackup/bbb-practice --work-root practice