# Blind Reprice Protocol (via SSH)

**Last updated:** 2026-05-10  
**When to use:** Rocky says "blind reprice", "fresh reprice", "don't look at the old price", or "don't check anything that could influence it". Also used for A/B test integrity on repricing jobs.

**Core rule:** lfp (pricer) must NOT see any prior tender documents — no previous xlsx, no prior rate buildups, no prior RM emails, no comparator pricing. Isolation is enforced via `blind=true` in state.json.

---

## Before You Start

1. Confirm SSH works: `ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "hostname"`
2. Confirm job folder has source files: `lfcs-inbound-artefacts/<job-id>/`
3. Confirm daemon log path: `C:\Users\mclou\lfcs-handoff\daemon.log`

---

## Step 1 — Probe Current Daemon State

```bash
ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "powershell -Command \"Get-Content 'C:\Users\mclou\lfcs-handoff\state.json'\""
ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_hermes_ed25519 mclou@laptop-cd8df7fs "powershell -Command \"Get-Content 'C:\Users\mclou\lfcs-handoff\daemon.log' | Select-Object -Last 10\""
```

What to look for:

| Field | Normal running | Stalled |
|---|---|---|
| `current_phase` | `phase-1-intake` → `phase-7-close` | `phase-3-worker` |
| `active_bid_id` | current job id | last job id |
| `last_pricer_seen_orch_input_index` | increasing | static for days |
| daemon.log | recent timestamp | last entry May 8 or earlier |

**Stalled example (from 2627 Airey Park, 2026-05-10):**
- daemon.log last entry: 2026-05-08T08:47:20
- current_phase: `phase-3-worker` (not `phase-7-close`)
- iteration_count: stopped at low number
- This needs a full reset, not just a touch.

---

## Step 2 — Reset state.json

Write a clean state.json for the job. Key fields:

```json
{
  "active_bid_id": "2627",
  "current_phase": "phase-1-intake",
  "rocky_gate_active": false,
  "rocky_gate_question": null,
  "iteration_count": 0,
  "daemon_mode": "autonomous-live",
  "schema_version": 3,
  "blind_reprice": true,
  "comparator_handle": "Comparator-A",
  "comparator_blind": true,
  "last_orch_to_pricer_mtime": null,
  "last_pricer_to_orch_mtime": null,
  "last_pricer_seen_orch_input_index": 0,
  "bcs_active": true,
  "session_id": "<generate new UUID>",
  "predecessor_session_ids": ["<previous session ids>"],
  "_phase_history": []
}
```

PowerShell JSON write (escape carefully):
```bash
ssh ... mclou@laptop-cd8df7fs "powershell -Command \"@'
{...json...}
'@ | Set-Content 'C:\Users\mclou\lfcs-handoff\state.json'\""
```

---

## Step 3 — Archive Old Handoff Files

```bash
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
ssh ... "powershell -Command \" \
  \$ts='$TIMESTAMP'; \
  Move-Item 'C:\Users\mclou\lfcs-handoff\orch-to-pricer.md' 'C:\Users\mclou\lfcs-handoff\processed\orch-to-pricer-\$ts.md' -ErrorAction SilentlyContinue; \
  Move-Item 'C:\Users\mclou\lfcs-handoff\pricer-to-orch.md' 'C:\Users\mclou\lfcs-handoff\processed\pricer-to-orch-\$ts.md' -ErrorAction SilentlyContinue \
\""
```

Or touch new blank files if archive dir doesn't exist:
```bash
ssh ... "powershell -Command \" \
  '' | Out-File 'C:\Users\mclou\lfcs-handoff\orch-to-pricer.md' -Encoding UTF8; \
  '' | Out-File 'C:\Users\mclou\lfcs-handoff\pricer-to-orch.md' -Encoding UTF8 \
\""
```

---

## Step 4 — Touch orch-to-pricer.md to Trigger Daemon

```bash
ssh ... "powershell -Command \"(Get-Item 'C:\Users\mclou\lfcs-handoff\orch-to-pricer.md').LastWriteTime = [DateTime]::Now\""
```

The daemon detects mtime change → spawns lfo orchestrator → lfo reads inbound artefacts → lfp runs blind.

---

## Step 5 — Monitor

```bash
# Stream daemon log (last 30 lines, wait for new entries)
ssh ... "powershell -Command \"Get-Content 'C:\Users\mclou\lfcs-handoff\daemon.log' -Wait -Tail 30\""
```

Expected sequence after touch:
1. `[AUTO] daemon starting (mode=autonomous)` — daemon restarted
2. `[AUTO] orch-to-pricer.md changed` → spawn pricer
3. `spawn_agent target=pricer` → lfp running
4. `pricer-to-orch.md changed` → spawn orch
5. `spawn_agent target=orch` → lfo running

---

## Step 6 — Post-Reprice Drive Upload

When reprice completes (phase-6-submit or phase-7-close):
- Laptop uses OAuth (Max subscription) — no API key needed
- lfo uploads to LFCS Drive via gws CLI (uses `opsman.systems@gmail.com` auth)
- For work email and RateRight email auth: Rocky does browser OAuth on VPS
  ```bash
  gws auth login --email <work-email>
  gws auth login --email <rateright-email>
  ```

---

## Gmail/Drive Multi-Account Summary

| Account | Auth method | Where configured |
|---|---|---|
| opsman.systems@gmail.com | gws OAuth | VPS (already done) |
| Work email | gws OAuth | VPS — Rocky does browser flow |
| RateRight email | gws OAuth | VPS — Rocky does browser flow |
| Laptop CC (Max subscription) | OAuth desktop session | Laptop — already working |

---

## Pitfalls

1. **Don't read prior tender docs yourself** — If you (Hermes) read the previous xlsx before starting the reprice, you'll contaminate the blind condition. Only read source files that are legitimately in `lfcs-inbound-artefacts/<job-id>/`.
2. **Daemon stalled = full reset needed** — A simple touch won't fix a stalled daemon. Must reset state.json + archive handoff files.
3. **`tailscale ssh` broken on Windows** — Always use plain SSH with hostname `laptop-cd8df7fs`.
4. **PowerShell path escaping** — Use `powershell -Command "..."` with single quotes around paths. Double-quote the outer command when passing via SSH `""`.