# Upgrade Guide — v0.15.0

<!-- bump: minor -->

## What Changed

### Machine-Scoped Job Scheduling

Jobs can now be restricted to specific machines. Add a `machines` field to any job definition in `jobs.json` — an array of machine IDs (`m_...`) or machine names (case-insensitive).

```json
{
  "slug": "adriana-checkin",
  "machines": ["lunas-macbook"],
  "schedule": "0 9 * * *",
  ...
}
```

**Behavior:**
- Jobs **without** a `machines` field run on all machines (unchanged, fully backwards-compatible)
- Jobs **with** a `machines` field only run on machines whose ID or name matches
- Machine name matching is case-insensitive (`"Lunas-MacBook"` matches `"lunas-macbook"`)
- Both machine IDs (`m_abc123...`) and human-friendly names work
- Skipped jobs are tracked in the skip ledger with reason `machine-scope`
- At startup, the scheduler logs which jobs were filtered out by machine scope

**API changes:**
- `GET /jobs` — each job now includes a `runsOnThisMachine` boolean indicating whether the job is active on this machine
- `POST /jobs/:slug/trigger` — returns `"skipped"` if the job is scoped to a different machine

**New type field:**
```typescript
interface JobDefinition {
  // ... existing fields ...
  machines?: string[];  // Machine IDs or names — omit to run everywhere
}
```

**New skip reason:**
```typescript
type SkipReason = '...' | 'machine-scope';
```

**How machine identity is resolved:**
The scheduler reads the local machine identity from the MultiMachineCoordinator at startup. For agents without multi-machine configured, no filtering occurs (all jobs run). Machine names come from `identity.json` (typically auto-detected from `os.hostname()` or user-provided during `instar pair`).

## What to Tell Your User

- "If you're running me on multiple machines, you can now mark specific jobs to only run on certain machines. Just let me know which jobs should be machine-specific and I'll set it up."
- "Your existing jobs aren't affected — everything keeps running everywhere unless you tell me to restrict it."

## Summary of New Capabilities

| Capability | How to Use |
|-----------|-----------|
| Machine-scoped jobs | Add `"machines": ["machine-name"]` to a job in jobs.json |
| Machine scope visibility | `GET /jobs` includes `runsOnThisMachine` per job |
| Skip tracking | Skip ledger tracks `machine-scope` skips |
