# Notify Setup

One-way supervision pings from your orchestrator to Telegram.
`notify.ps1` is fail-silent: if no credentials are present it exits 0 silently
and makes no network call. The opt-in redaction guard is off by default --
projects supply their own sensitive-term patterns.

---

## Step 1: Create a bot via @BotFather

1. In Telegram, open a chat with **@BotFather**.
2. Send `/newbot` and follow the prompts (pick a name and username).
3. BotFather responds with a **bot token** -- a string like `123456789:ABCdef...`.
4. Copy the token; you will use it in Step 3.

## Step 2: Get your chat ID

1. Open Telegram and send `/start` to your new bot (this creates the chat session).
2. In a browser, open:
   `https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates`
3. In the JSON response find the `message.chat.id` field (a number like `987654321`).
4. Copy the chat ID.

## Step 3: Configure credentials

**Option A -- environment variables (preferred for CI / shared machines):**

```powershell
$env:NOTIFY_TG_BOT_TOKEN = "123456789:ABCdef..."
$env:NOTIFY_TG_CHAT_ID   = "987654321"
```

Add these to your profile (`$PROFILE`) or your CI secrets store so they persist.

**Option B -- local JSON file (developer workstation):**

Create the file `.claude/notify.local.json` (gitignored -- never commit credentials):

```json
{
  "BotToken": "123456789:ABCdef...",
  "ChatId":   "987654321"
}
```

Note: the kit does not ship a `.claude/notify.local.json.example` to avoid
accidentally committing a file with placeholder values. Create it manually with
the structure above.

`.claude/notify.local.json` must appear in your `.gitignore` (or `.claude/`
must be gitignored). Verify before committing.

---

## Step 4: Install the hook

Copy the template into your project's hooks directory:

```powershell
Copy-Item Constitution-Kit/templates/notify.ps1 .claude/hooks/notify.ps1
```

---

## Step 5: Wire the Notification hook (opt-in)

Add the following to `.claude/settings.json` under the `hooks` key (additive --
alongside any existing verify or preflight hooks):

```json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "powershell -NoProfile -ExecutionPolicy Bypass -File \"$CLAUDE_PROJECT_DIR/.claude/hooks/notify.ps1\" -Kind waiting -Title \"Claude needs attention\""
          }
        ]
      }
    ]
  }
}
```

Hooks are advisory: a hook failure never blocks Claude Code.

**Optional label prefix:** set `$env:NOTIFY_LABEL` to prepend a project name to
the message footer, e.g. `$env:NOTIFY_LABEL = "MyProject"` yields
`MyProject main 2026-01-01 09:00` in the footer. Omit for bare `branch stamp`.

---

## Step 6: Test the connection

```powershell
powershell -NoProfile -File .claude/hooks/notify.ps1 -Kind progress -Title 'Setup OK' -Body 'Notifications wired.'
```

If credentials are configured, the message appears in Telegram within a few
seconds. If not configured, the script exits 0 silently -- no error, no network
call.

---

## Opt-in redaction guard

The redaction guard is **off by default**. To enable it, supply your own
sensitive-term patterns -- the notifier has no hardcoded patterns.

**Supply patterns via environment variable (semicolon-separated regexes):**

```powershell
$env:NOTIFY_REDACT_PATTERNS = 'SECRET-\d+;INTERNAL-[A-Z]+'
```

**Or supply patterns via a file `.claude/notify.redact.txt`** (one regex per
line; `#` lines and blank lines are ignored; gitignore this file if it contains
sensitive policy details):

```
# Sensitive terms -- project-specific; adjust to your data classification policy
SECRET-\d+
INTERNAL-[A-Z]+
```

If neither `NOTIFY_REDACT_PATTERNS` nor `.claude/notify.redact.txt` yields any
patterns, the guard is off and text is sent unchanged.

**Modes** (set via `$env:NOTIFY_REDACT_MODE`; default is `redact`):

| Mode     | Behavior |
|---|---|
| `redact` | Replace every pattern match in the message with `[redacted]`, then send. |
| `refuse` | If any pattern matches, return without sending (fail-closed; nothing leaves). |

Example -- enable refuse mode:

```powershell
$env:NOTIFY_REDACT_MODE = 'refuse'
```

---

## Message kinds

| `-Kind`    | Emoji | When to use |
|---|---|---|
| `progress` | check mark   | Milestone reached, task done |
| `blocker`  | stop sign    | Gate failed, needs human attention |
| `question` | question mark | Orchestrator is paused, awaiting input |
| `waiting`  | pause button  | Auto-ping: turn idle (sent by onstop.ps1) |

The `-Severity` param is accepted for future use but not currently rendered.

---

## Troubleshooting

- **No message received, no error:** credentials not configured (fail-silent is
  working correctly), or the redaction guard returned early in `refuse` mode.
  Check whether any pattern in `NOTIFY_REDACT_PATTERNS` / `notify.redact.txt`
  matches the message body.
- **`401 Unauthorized`:** bot token is wrong or expired -- re-run `/newbot` in
  @BotFather.
- **`400 Bad Request: chat not found`:** you have not sent `/start` to the bot
  yet, or the chat ID is wrong.
- **Network error:** `notify.ps1` swallows all errors and exits 0 -- check your
  internet connection manually.
