# Offline Bundle Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Build a self-contained offline delivery bundle for `store_dwell_alert_108` that can be unpacked on a `.108`-class machine, installed without internet, and run after the operator edits `scripts/run.sh`. **Architecture:** Add a delivery layer around the existing runtime by introducing a bundle staging pipeline, a locked requirements file, an offline wheelhouse, portable install/run scripts, and a relocatable service template. Keep the application logic unchanged and isolate all new behavior to packaging, deployment, and documentation. **Tech Stack:** Bash, Python virtual environments, pip wheelhouse installs, tar.gz packaging, systemd, existing `ultralytics` runtime. --- ### Task 1: Audit runtime inputs and delivery assets **Files:** - Modify: `README.md` - Create: `docs/plans/2026-04-16-offline-bundle-design.md` - Create: `docs/plans/2026-04-16-offline-bundle.md` **Step 1: Verify the current runtime entrypoints and required assets** Check `app/main.py`, `requirements.txt`, `config/config.example.yaml`, `scripts/run_local.sh`, and `deploy/store-dwell-alert.service` to identify everything the bundle must include. **Step 2: Update the top-level README scope if needed** Add a short note that the project now supports building an offline delivery bundle for compatible hosts. **Step 3: Commit** ```bash git add README.md docs/plans/2026-04-16-offline-bundle-design.md docs/plans/2026-04-16-offline-bundle.md git commit -m "docs: add offline bundle design and plan" ``` ### Task 2: Add bundle-facing deployment files **Files:** - Create: `deploy/store-dwell-alert.service.tpl` - Create: `scripts/install.sh` - Create: `scripts/run.sh` - Create: `scripts/install_service.sh` - Test: `tests/test_bundle_layout.py` **Step 1: Write the failing tests** Add tests that assert: - the new scripts exist - `run.sh` contains a placeholder `RTSP_URL` - the service template contains placeholder tokens rather than a host-pinned path **Step 2: Run the tests to verify they fail** Run: `pytest tests/test_bundle_layout.py -v` **Step 3: Write the minimal implementation** Create the installer, runner, and service template files with portable placeholders and safe shell behavior. **Step 4: Run the tests to verify they pass** Run: `pytest tests/test_bundle_layout.py -v` **Step 5: Commit** ```bash git add deploy/store-dwell-alert.service.tpl scripts/install.sh scripts/run.sh scripts/install_service.sh tests/test_bundle_layout.py git commit -m "feat: add offline bundle deployment scripts" ``` ### Task 3: Lock Python dependencies for offline delivery **Files:** - Create: `requirements.lock.txt` - Modify: `requirements.txt` - Test: `tests/test_bundle_layout.py` **Step 1: Write the failing tests** Extend bundle layout tests to assert: - `requirements.lock.txt` exists - it pins exact versions for the runtime packages needed by the bundle **Step 2: Run the tests to verify they fail** Run: `pytest tests/test_bundle_layout.py -v` **Step 3: Write the minimal implementation** Add a checked-in `requirements.lock.txt` aligned with the known-good runtime stack and keep `requirements.txt` as the human-edited high-level list if needed. **Step 4: Run the tests to verify they pass** Run: `pytest tests/test_bundle_layout.py -v` **Step 5: Commit** ```bash git add requirements.txt requirements.lock.txt tests/test_bundle_layout.py git commit -m "build: lock offline bundle dependencies" ``` ### Task 4: Add bundle staging and archive generation **Files:** - Create: `scripts/package_bundle.sh` - Modify: `README.md` - Test: `tests/test_bundle_layout.py` **Step 1: Write the failing tests** Add tests that assert: - `scripts/package_bundle.sh` exists - it references the expected bundle contents - it excludes host-specific config such as `config/108.local.yaml` **Step 2: Run the tests to verify they fail** Run: `pytest tests/test_bundle_layout.py -v` **Step 3: Write the minimal implementation** Create `scripts/package_bundle.sh` to stage the bundle into `dist/store_dwell_alert_bundle/` and archive it as `dist/store_dwell_alert_bundle_.tar.gz`. **Step 4: Run the tests to verify they pass** Run: `pytest tests/test_bundle_layout.py -v` **Step 5: Commit** ```bash git add scripts/package_bundle.sh README.md tests/test_bundle_layout.py git commit -m "build: add offline bundle packaging script" ``` ### Task 5: Vendor weights and prepare runtime directories **Files:** - Create: `weights/.gitkeep` - Create: `data/staff_gallery/.gitkeep` - Create: `data/runtime/.gitkeep` - Modify: `README.md` - Test: `tests/test_bundle_layout.py` **Step 1: Write the failing tests** Add tests that assert the bundle pipeline expects: - `weights/` - `data/staff_gallery/` - `data/runtime/` **Step 2: Run the tests to verify they fail** Run: `pytest tests/test_bundle_layout.py -v` **Step 3: Write the minimal implementation** Create the tracked directories and document that `weights/yolo11n.pt` must exist before packaging. **Step 4: Run the tests to verify they pass** Run: `pytest tests/test_bundle_layout.py -v` **Step 5: Commit** ```bash git add weights/.gitkeep data/staff_gallery/.gitkeep data/runtime/.gitkeep README.md tests/test_bundle_layout.py git commit -m "chore: track offline bundle asset directories" ``` ### Task 6: Document operator workflow **Files:** - Modify: `README.md` - Test: `tests/test_main_smoke.py` **Step 1: Write the failing test** If practical, add a smoke-level documentation assertion or adjust an existing smoke test so the offline scripts are covered by a simple presence/usage check. **Step 2: Run the test to verify it fails** Run: `pytest tests/test_main_smoke.py -v` **Step 3: Write the minimal implementation** Document: - how to build the bundle - how to transfer it - how to run `scripts/install.sh` - how to edit `scripts/run.sh` - how to optionally install the service **Step 4: Run the tests to verify they pass** Run: `pytest tests/test_main_smoke.py -v` **Step 5: Commit** ```bash git add README.md tests/test_main_smoke.py git commit -m "docs: add offline bundle operator workflow" ``` ### Task 7: Produce and verify a real bundle locally **Files:** - Modify: `scripts/package_bundle.sh` - Modify: `README.md` **Step 1: Run the packaging script** Run: `bash scripts/package_bundle.sh` Expected: - `dist/store_dwell_alert_bundle/` is created - `dist/store_dwell_alert_bundle_.tar.gz` is created **Step 2: Inspect the archive contents** Run: `tar -tzf dist/store_dwell_alert_bundle_.tar.gz` Expected: - bundled scripts, config template, service template, app code, `requirements.lock.txt`, and tracked runtime directories are present **Step 3: Fix any path or omission bugs** Adjust the packaging script until the archive layout matches the design. **Step 4: Run the full test suite** Run: `pytest -q` Expected: PASS **Step 5: Commit** ```bash git add scripts/package_bundle.sh README.md git commit -m "build: verify offline bundle artifact generation" ```