Complete lesson text and action cards
Source-owned text for offline reading and retrieval. Command success still requires actual local evidence.
Choose symbols, dates and adjustment policy
Open data-dictionary.md. Record the intended symbols, exchange/session dates, daily interval and whether you need unadjusted or adjusted prices. This starter stores unadjusted OHLCV; use the synthetic DEMO series first.
Expected: The contract identifies daily session dates, unadjusted prices, volume, source and retrieval UTC.
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
Validate the sample bars
Open prices.json. Check low <= open/close <= high, positive finite prices, nonnegative volume and unique symbol/date pairs. These DEMO records are not market quotes.
Expected: Two synthetic daily bars satisfy the OHLC/volume/date contract.
Store the fixture
Run finance_collector.py with --fixture prices.json. Inspect prices.sqlite and retain the printed source label.
Expected: FINANCE PASS reports written=2 total=2 source=synthetic-fixture.
windows
python finance_collector.py --fixture prices.json
macos
python3 finance_collector.py --fixture prices.json
linux
python3 finance_collector.py --fixture prices.json
Prove retries are idempotent
Run the same fixture again. Confirm total remains 2. The upsert replaces the same source/symbol/date values and refreshes retrieved_utc; it does not append duplicates.
Expected: The second run still reports total=2.
windows
python finance_collector.py --fixture prices.json
macos
python3 finance_collector.py --fixture prices.json
linux
python3 finance_collector.py --fixture prices.json
Create an isolated environment
For live retrieval only, create a virtual environment and install requirements-live.txt. Check the yfinance project documentation and Yahoo data terms for your permitted use. Record the installed dependency versions; fixtures do not need this package.
Expected: The isolated environment imports yfinance and its installed version is recorded.
windows
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements-live.txt
.\.venv\Scripts\python.exe -m pip freeze
macos
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-live.txt
.venv/bin/python -m pip freeze
linux
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-live.txt
.venv/bin/python -m pip freeze
Request one symbol and inspect provenance
If your use is permitted, run the live command for one symbol. Inspect the last five available session bars. Capture retrieval time, source and actual date range. A closed market or holiday can reduce rows; do not invent current quotes.
Expected: A nonempty live result is labeled yahoo-unadjusted, or a concrete access/network failure is retained without being called a success.
windows
.\.venv\Scripts\python.exe finance_collector.py --live MSFT --db live-prices.sqlite
macos
.venv/bin/python finance_collector.py --live MSFT --db live-prices.sqlite
linux
.venv/bin/python finance_collector.py --live MSFT --db live-prices.sqlite
Exercise an invalid bar
Copy prices.json to prices-bad.json and set one high below its close. Run the collector against a separate bad-prices.sqlite. Confirm it fails visibly. For a live error, record symbol, package version and status; use bounded retry/backoff and respect rate limits.
Expected: The invalid OHLC range produces an error and no successful FINANCE PASS receipt.
windows
python finance_collector.py --fixture prices-bad.json --db bad-prices.sqlite
macos
python3 finance_collector.py --fixture prices-bad.json --db bad-prices.sqlite
linux
python3 finance_collector.py --fixture prices-bad.json --db bad-prices.sqlite
Repeat and document the final run
Run the chosen fixture or approved live path twice. Verify stable row counts and source labels. Save the contract, version record, last successful receipt and one failure case. A scheduler is an optional later step requiring a bounded interval and failure alert.
Expected: The collector has repeatable storage, correct provenance, visible failures and documented scope.
windows
python finance_collector.py --fixture prices.json
macos
python3 finance_collector.py --fixture prices.json
linux
python3 finance_collector.py --fixture prices.json
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