# GuruWatcher Setup — first hour

Self-hosted **claim ledger + Discord buzzer**. You bring the feeds and the webhook.

**Domain:** [guruwatcher.com](https://guruwatcher.com) · **Alert-only forever — no orders.**

## This is / isn’t

| This is | This isn’t |
|---------|------------|
| Claim ledger + Discord buzzer | A trading bot / broker |
| BYO Discord + BYO sources you subscribe to | A Macro Charts reseller |
| Multi-ingest into one inbox → guards → arms | Auto-arming from charts without numbers |
| Most-recent-wins mind | A generic TradingView ping clone |

## Claim fence

- Use only newsletter / export / notes **you have the right to use**.
- Do **not** redistribute paid third-party newsletter text via docs, git, or shared packs.
- Levels arm only when a **number appears in that issue’s text**.
- Soft lists / chart-only / no number → do not arm.
- Locus of judgment stays with **you**. Alerts are not trade instructions.

---

## First-hour checklist

### 1. Install

```bash
cd GuruWatcher   # this repo
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
```

### 2. Init portable data dir

```bash
python3 -m guru_watcher init --data-dir ./gw-data
export GURU_WATCHER_DATA="$(pwd)/gw-data"
# Alternative without env: pass --config "$(pwd)/gw-data/config.yaml" on each command
# (state resolves under gw-data/, not the git repo).
```

Creates: `config.yaml`, `.env.example`, `sources/`, `inbox/`, `state/`, `README-DATA.md`.

### 3. Set webhook (or stay dry-run)

```bash
cp "$GURU_WATCHER_DATA/.env.example" "$GURU_WATCHER_DATA/.env"
# Edit .env — set ONLY when you want live Discord:
# GURU_WATCHER_DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
```

Omit the webhook and always use `--dry-run` until ready. Never commit `.env`.

### 4. Add / edit a source

- Edit `$GURU_WATCHER_DATA/config.yaml` → `sources:` list, or  
- Edit `$GURU_WATCHER_DATA/sources/example.yaml`  
- Use **your** symbols, bands, and TTL — not a bundled paid corpus.

### 5. Ingest into inbox

Content you own rights to:

```bash
mkdir -p "$GURU_WATCHER_DATA/drop"
# copy your .md/.txt into drop/
python3 -m guru_watcher ingest-run \
  --adapter file_drop \
  --data-dir "$GURU_WATCHER_DATA" \
  --path drop \
  --once
```

Other adapters (credentials via env only — see `.env.example`):

| Adapter | Notes |
|---------|--------|
| `rss_url` | `--url 'https://…/feed.xml'` public feeds you may store |
| `notebooklm_export` | folder of `.md`/`.txt` exports |
| `imap_email` | `GURU_WATCHER_IMAP_*` (UNSEEN ∪ UID cursor; dedupe via seen set) |
| `telegram_bot` | token + **`GURU_WATCHER_TELEGRAM_CHAT_IDS`** allowlist (or `ALLOW_ALL=1`) |
| `discord_inbound` | bot token + channel IDs — **inbound only**, never posts |

### 6. Extract + dry-run check

```bash
python3 -m guru_watcher ingest-issue \
  --inbox "$GURU_WATCHER_DATA/inbox" \
  --guru example \
  --dry-run

python3 -m guru_watcher check --dry-run
```

No LIVE Discord posts unless you intentionally run without `--dry-run` with a real webhook.

### 7. Docker Compose (optional loop)

```bash
# From repo root — mount the same portable data dir
export GURU_WATCHER_HOST_DATA="$(pwd)/gw-data"
export GURU_WATCHER_MODE=dry-run          # default; never posts
# export GURU_WATCHER_INTERVAL_SECONDS=900

docker compose up --build
```

- Default mode **dry-run**: `python -m guru_watcher check --dry-run` on an interval.
- **Live:** set `GURU_WATCHER_MODE=live` **and** `GURU_WATCHER_DISCORD_WEBHOOK_URL` (fail closed without webhook).
- **Oneshot:** `GURU_WATCHER_MODE=oneshot docker compose run --rm guruwatcher oneshot`
- **Optional ingest profile:**  
  `docker compose --profile ingest run --rm ingest`  
  (file_drop from `/data/drop` → inbox)

Entrypoint: `scripts/docker_entrypoint.sh` — init if missing config; load `$DATA/.env` without printing secrets.

Validate compose file (no daemon required for some installs):

```bash
docker compose config   # if Docker CLI available
```

Smoke test — builds the image and runs a oneshot dry-run against a temp data
dir (skips with a message when Docker isn't installed; fails if oneshot fails):

```bash
bash scripts/smoke_docker_oneshot.sh
```

---

## Product spine (keep these four)

1. Inbox forward → durable markdown  
2. Claim ledger + most-recent-wins  
3. Verbatim guards (no invented numbers)  
4. Discord + poll — **no orders**

## Safety

- Alert-only — never places trades  
- Do not commit webhook URLs or API keys  
- Not investment advice · not a broker · not redistributing paid newsletters  

## Next

- Landing: [index.html](./index.html) · Getting started: [getting-started/](./getting-started/)  
- Deploy site notes: [README.md](./README.md) (Cloudflare Pages → guruwatcher.com)  
- Package data README after init: `$GURU_WATCHER_DATA/README-DATA.md`
