vault-sync: 2026-10-02 07:10 (jimmy)

This commit is contained in:
jimmy
2026-10-02 07:10:57 -07:00
parent a9100905dd
commit 5f406ba6b9
89 changed files with 7374 additions and 745 deletions
@@ -0,0 +1,102 @@
# Phoenix name-change remediation — living review loop
**Slug:** `phoenix-salon`
**Updated:** 2026-09-20 ~12:08 PT (CoS)
**Sibling:** [surface-checklist.md](./surface-checklist.md) (what is open/done) · [sop-email-follow-up.md](./sop-email-follow-up.md) (email silence + nudges)
**This file:** what we *tried*, what landed, what we cut — reviewed after each batch
Keep this glanceable. One row per action. Update after every Job Card / batch — do not wait for end of project.
---
## Triage framing (who feels the friction)
Sort work in this order. Prefer the top of the list when choosing the next batch.
| Priority | Who feels it | Examples | Bias |
|----------|--------------|----------|------|
| **1 — Customers** | People trying to find / book / trust Phoenix | GBP/Maps, site NAP, IG, Yelp, stale “La Mae / Flying C” on directories customers actually click | Highest impact; fix or email first |
| **2 — Vendors / partners** | Platforms, directories, aggregators, review networks | Birdeye, MapQuest tickets, Superpages, FindGlocal, hairsalonsinusa | Batch email/ticket; park Cloudflare / no-contact |
| **3 — Back-office** | Us / Ashley ops friction | Onboarding folder, auth, GBP Manager invite, VeriMail process lessons | Do when it unblocks 1–2; don’t let it crowd out customer surfaces |
---
## How to use (30-second ritual)
After each batch:
1. Add rows under **Batch log** (copy a blank row if needed).
2. Mark **Worked?** `yes` / `partial` / `no` / `too-soon`.
3. Fill **Keep** (repeat next time) and **Cut** (never again / demote).
4. If a pattern shows twice, write one line under **Patterns**.
5. Sync status into `surface-checklist.md`.
---
## Patterns (fill as we learn)
| Seen | Keep / Cut | Since |
|------|------------|-------|
| _(empty — first patterns after 2–3 batches)_ | | |
**Seed from Gate 3 pilot (not a full batch review yet):**
- Keep: on-disk send receipt + `.eml` before claiming SENT.
- Keep: Method A with hermes `.venv` python (system Python312 burns a run).
- Cut: treating Cloudflare/no-contact scrapers as email targets (WONT-DO fast).
- Cut: Anthony personally chasing aggregators day-to-day.
---
## Batch log
### Batch 0 — Gate 3 email pilot (2026-09-19 → inbox check 2026-09-20)
| # | What we did | Channel / audience | Priority | Worked? | Keep | Cut | Evidence |
|---|-------------|--------------------|----------|---------|------|-----|----------|
| 1 | Checked FindGlocal listing | Vendor directory (public) | 2 | yes — already canonical | Fast “already green → WONT-DO” | Spending time on claim/contact forms when NAP is right | `gate3-pilot/2026-09-19/evidence/findglocal-*.html` |
| 2 | Hit hairsalonsinusa | Vendor directory | 2 | no — CF 403 | Immediate WONT-DO when CF blocks + no mailto | Retry loops / browser rabbit holes same day | `.../hairsalonsinusa-*.html` |
| 3 | Emailed Birdeye remove/update La Mae | Vendor: `profiles@birdeye.com` via VeriMail `ashbotphoenix@` | 2 (customer-facing stale NAP on aggregator) | too-soon — SENT, no reply as of 2026-09-20 | Receipt + mid-week inbox re-scan before nudge | Same-day human chase | `gate3-pilot/2026-09-19-birdeye-send/evidence/` |
| 4 | VeriMail inbox pass for listing returns | Back-office + response channel | 3→feeds 2 | yes — NONE_FOUND clear | Job Card + artifact `inbox-scan.md` | Claiming done on STATUS alone | `mail/2026-09-20-inbox/evidence/` |
**Batch 0 review note:** Pilot proved the thin email pipe. Highest remaining *customer* friction is still human (IG) + vendor waits (Yelp/MapQuest), not more cold emails today.
---
### Batch 1 — _(next)_ — date: ____
| # | What we did | Channel / audience | Priority (1/2/3) | Worked? | Keep | Cut | Evidence |
|---|-------------|--------------------|------------------|---------|------|-----|----------|
| 1 | | | | | | | |
| 2 | | | | | | | |
| 3 | | | | | | | |
**Batch 1 review note:** _(what to do more of / less of)_
---
### Batch 2 — _(ready)_ — date: ____
| # | What we did | Channel / audience | Priority (1/2/3) | Worked? | Keep | Cut | Evidence |
|---|-------------|--------------------|------------------|---------|------|-----|----------|
| 1 | | | | | | | |
| 2 | | | | | | | |
**Batch 2 review note:**
---
## Suggested next batch (not started — needs Gatekeeper go)
Ordered by triage:
1. **Customer:** Ashley IG bio + Vagaro + guest screenshot (human).
2. **Customer/vendor:** Yellow Pages confirm or WONT-DO (human).
3. **Vendor wait:** leave Yelp + MapQuest alone until they move.
4. **Vendor:** mid-week Birdeye inbox re-scan (VeriMail Job Card) before any nudge.
5. **Back-office:** onboarding green (auth + GBP Manager) when it unblocks proof letter.
6. **Vendor parked list:** only after Job Card — BestPros / wheree / etc.
---
*CoS updates this after each batch. Hermes does not invent Keep/Cut without evidence paths.*
@@ -0,0 +1,196 @@
# SOP — Phoenix name-change remediation: email follow-up
**Slug:** `phoenix-salon`
**Version:** 1.0 · **Effective:** 2026-09-20
**Owner:** CoS (Grok Bot) · **Gatekeeper:** Anthony
**Sits with:** [remediation-review-loop.md](./remediation-review-loop.md) · [surface-checklist.md](./surface-checklist.md)
**Mail desk:** VeriMail via `ashbotphoenix@agentmail.to` · CC `tonyjbala@gmail.com` on reply threads
Hand this to anyone running listing outreach. Do not improvise silence windows or nudge counts outside this doc unless Gatekeeper overrides in chat.
---
## 0. Preconditions (every send)
1. Item is on `surface-checklist.md` (or added there in the same batch).
2. **Job Card** posted in Grok Bot chat → Anthony says **go**.
3. Send only via VeriMail Method A (hermes `.venv` python).
4. On-disk artifacts required before claiming SENT: `send-receipt.md` + `.eml` (or equivalent).
5. Log the send in **§2 Send log** *and* a row in the review loop batch table.
6. No cold send without a real public contact (mailto / published support address). Cloudflare / no-contact → mark **WONT-DO**, do not invent recipients.
---
## 1. How to pick the correct recipient
### 1.1 Audience tier first
| Tier | Who | Typical email target | Do **not** email |
|------|-----|----------------------|------------------|
| **1 — Customers** | People who find/book Phoenix | Rarely “customer email.” Prefer *fix the surface* (IG, site, GBP). Email only if a **directory customers use** lists a public correction address | Random reviewers; personal customer inboxes |
| **2 — Vendors / partners** | Directories, aggregators, review platforms | Published listing-support / profiles / data-quality address on that site (or ticket system if email isn’t offered) | Scraped personal staff emails; form-only sites with no mailto (use ticket or WONT-DO) |
| **3 — Back-office** | Us / Ashley ops | Internal notes, Job Cards, CC Anthony — not cold vendor mail | Using vendor inboxes for internal process chat |
### 1.2 Recipient decision tree
1. Open the remediation item (URL + what’s wrong vs canonical NAP).
2. Assign tier **1 / 2 / 3** using the triage table in the review loop.
3. Find contact in this order — stop at the first valid one:
a. Official “update listing / report inaccuracy / profiles@ / support@” published on the **same domain**
b. Platform ticket/help form (if no email — file ticket, log as **TICKET** not EMAIL)
c. None → **WONT-DO** + reason (e.g. CF 403, JS-only form, no contact)
4. Prefer one canonical address per platform (e.g. Birdeye → `profiles@birdeye.com`). Do not spray multiple guesses.
5. From identity: always `ashbotphoenix@agentmail.to` (Phoenix listing desk).
6. If the item is **human-owned** (IG bio, YP confirm Ashley already mailed) → no VeriMail cold send; mark OPEN for Ashley/Anthony.
### 1.3 Subject line pattern
`Phoenix Salon + Spa (Cameron Park) — [action]: [old name/listing] → canonical NAP`
Example: `Authorized listing partner for Phoenix Salon + Spa — remove/update outdated La Mae listing`
---
## 2. Send notation / log
Every outbound remediation email gets one row. Living file: same folder, table below (append; don’t delete history).
Also keep the job folder evidence: `.../gate3-pilot|mail/<date>-*/evidence/send-receipt.md`
### Send log
| Sent (PT) | Rem. item / surface | Tier | To | Subject | Job / evidence path | Silence clock starts |
|-----------|---------------------|------|----|---------|---------------------|----------------------|
| 2026-09-19 14:28 | Birdeye — La Mae / Flying C | 2 | profiles@birdeye.com | Authorized listing partner… outdated La Mae listing | gate3-pilot/2026-09-19-birdeye-send/evidence/ | 2026-09-19 |
| | | | | | | |
**Minimum fields:** datetime PT · surface · tier · recipient · subject · evidence path · clock start date.
---
## 3. Silence window before a nudge
### 3.1 Defaults
| Tier | Default silence before **Nudge 1** | Notes |
|------|--------------------------------------|-------|
| **1 — Customer-facing directories** | **5 business days** | Faster if the bad listing is actively confusing bookers (Gatekeeper may shorten) |
| **2 — Vendors / aggregators** | **7 calendar days** | Default for Birdeye-class profile mail |
| **3 — Back-office** | N/A for vendor nudge | Use internal chase, not this SOP |
Weekends/holidays: business-day windows skip Sat–Sun; calendar-day windows count them.
### 3.2 Per-item overrides
Record override on the send-log row or checklist notes, e.g.:
- `silence_override: 10d` (slow enterprise support)
- `silence_override: 3bd` (hot customer damage)
- `no_nudge: true` (ticket-only platform; wait on their SLA)
**Birdeye (current):** use default **7 calendar days** from 2026-09-19 → first nudge eligible **2026-09-26** unless Gatekeeper says otherwise. Always run a VeriMail **inbox scan** the same day before nudging.
---
## 4. Nudge sequence
### 4.1 Caps
| Step | When | Max |
|------|------|-----|
| Original send | Day 0 | 1 |
| **Nudge 1** | After silence window (+ override) | 1 |
| **Nudge 2** (final) | **5 business days** after Nudge 1 with still no useful reply | 1 |
| Then | Escalate or close per §5 | — |
**Hard cap:** 1 original + **2 nudges** = 3 outbound touches. No fourth email without a new Gatekeeper decision.
### 4.2 How nudge differs from original
| | Original | Nudge 1 | Nudge 2 (final) |
|-|----------|---------|-----------------|
| Tone | Full request + canonical NAP + authority | Short bump; assume they have the thread | Final bump; state close/escalate path |
| Body | Full detail, links, old vs new | 4–6 sentences; quote date of original; restate one ask | 3–5 sentences; “closing our file on date X unless you need more info” |
| Attachments | As needed | None unless they asked | None |
| Subject | Full pattern (§1.3) | `Re: [original subject]` or `Follow-up: [original subject]` | `Final follow-up: [original subject]` |
**Nudge 1 skeleton**
> Following up on our message of [date] from ashbotphoenix@agentmail.to… regarding [surface / old listing].
> Please confirm you can [remove | update] to: Phoenix Salon + Spa, 3460 Robin Ln Suite 4, Cameron Park CA 95682, (530) 350-9197, phoenixcameronpark.com.
> Happy to provide anything else you need. — Phoenix listing desk (CC Anthony)
**Nudge 2 skeleton**
> Final follow-up on [date] request ([Message-ID or subject]). If we don’t hear back by [date + 5bd], we will mark this item closed on our side / escalate via [ticket|alternate channel]. Canonical NAP remains: [one line]. Thank you.
### 4.3 Before every nudge
1. VeriMail inbox Job Card → confirm **no reply** (artifact).
2. Job Card for the nudge → Anthony **go**.
3. Same thread/subject discipline; same From; CC rules if it’s a reply.
4. Log as a new send-log row with `type: nudge-1` or `nudge-2`.
---
## 5. Stop conditions (resolved vs abandoned)
Mark the surface on `surface-checklist.md` and add a one-liner to the review loop.
### 5.1 RESOLVED (done)
Any one of:
- Live listing shows **canonical NAP** (evidence HTML/screenshot dated).
- Vendor email/ticket confirms fixed or removed.
- Duplicate/merged into the correct Phoenix listing and old name gone.
→ Status **GREEN**. Review loop: Worked? `yes`.
### 5.2 WAITING (still open, clock running)
- Original or nudge sent; inside silence window.
- Or vendor acknowledged (“we’ll update in 2 weeks”) — set `silence_override` to their date.
→ Status **SENT** / **WAITING**. Do not nudge early.
### 5.3 ABANDONED / WONT-DO (close without fix)
Any one of:
- Nudge 2 sent + **5 business days** more silence → close as **ABANDONED-NO-REPLY** (document date).
- No valid recipient / CF / no contact → **WONT-DO** at discovery (no nudges).
- Gatekeeper says stop.
- Risk/legal: stop and escalate to Anthony only.
→ Status **WONT-DO** or **ABANDONED**. Review loop: Worked? `no` + Cut note (“email dead-end on this platform”).
### 5.4 ESCALATE (instead of more email)
After Nudge 1 or 2, if the platform has a better channel:
- File a support ticket (log ticket ID).
- Ashley Primary Owner login path.
- Pause and re-triage as customer-surface fix (e.g. GBP) rather than aggregator mail.
Escalation still needs Gatekeeper **go** if it spends Ashley’s time or money.
---
## 6. Quick checklist (copy per item)
- [ ] Tier assigned (1/2/3)
- [ ] Recipient from decision tree (or WONT-DO)
- [ ] Job Card + go
- [ ] Sent + receipt + send-log row
- [ ] Silence window / override recorded
- [ ] Inbox scan before each nudge
- [ ] ≤2 nudges
- [ ] Stop: RESOLVED / ABANDONED / WONT-DO / escalated
- [ ] Review loop row updated
---
*v1.0 CoS 2026-09-20. Change silence defaults only with Gatekeeper approval; bump version when you do.*
@@ -0,0 +1,80 @@
# Phoenix Salon + Spa — surface checklist (living)
**Slug:** `phoenix-salon`
**Updated:** 2026-09-23 ~09:40 PT (CoS)
**Canonical NAP:** Phoenix Salon + Spa · 3460 Robin Ln Suite 4, Cameron Park CA 95682 · (530) 350-9197 · phoenixcameronpark.com · hours Mon–Sat 9–6 / Sun closed
**Mail desk:** `ashbotphoenix@agentmail.to` (VeriMail) · CC Anthony `tonyjbala@gmail.com` on listing reply threads
**Close-out bar (2026-09-23):** Finish everything we control today. Leave open only items that need a vendor to email/ticket back for remediation to be final.
**Review loop:** [remediation-review-loop.md](./remediation-review-loop.md)
How to read status: **GREEN** done · **WAITING** vendor reply · **SENT** email out · **WONT-DO** parked with reason · **OPEN** needs human · **PARKED** out of scope for this close
---
## A. Already green
| Surface | Status | Notes |
|--------|--------|-------|
| Website hours / schema | GREEN | Canonical hours locked |
| GBP / Maps hours | GREEN | Hours aligned |
| Flying C cleanup (where done) | GREEN | |
| Facebook hours | GREEN | |
| Vagaro hours | GREEN | |
| Nextdoor Flying C | GREEN | |
| Gate 4 domain path | GREEN | |
| FindGlocal | GREEN / WONT-DO | Already canonical (Gate 3 pilot) |
| hairsalonsinusa | WONT-DO | Cloudflare 403; no contact |
---
## B. Waiting on vendor reply (OK to leave open for close-out)
| Surface | Status | Evidence / next |
|--------|--------|-----------------|
| Birdeye (La Mae / Flying C) | SENT → WAITING reply | Emailed `profiles@birdeye.com` 2026-09-19 14:28 PT. Last inbox scan NONE_FOUND 2026-09-20. Re-scan due today before documenting silence. |
| Yelp — Beauty By Ashley | WAITING | Claim filed; waiting on Yelp. |
| MapQuest | WAITING | Ticket **#3210162**; waiting on MapQuest. |
---
## C. Needs Ashley / Anthony today (blocks "we control" close)
| Surface | Status | Next |
|--------|--------|------|
| Instagram bio + Vagaro link + guest screenshot | OPEN | Ashley login. Regis Job Card approved 2026-09-20 for *artifacts only* — **no deliverables found** on hermes/Drive yet. Either land pack then Ashley posts, or Ashley edits bio from a one-pager. |
| Yellow Pages / YP | OPEN | Confirm Ashley emailed `ypcsupport@yp.com` **or** mark WONT-DO for this close. |
---
## D. Gate 3 email pilot (historical)
| Surface | Status | Evidence |
|--------|--------|----------|
| Birdeye | SENT 2026-09-19 | `gate3-pilot/2026-09-19-birdeye-send/evidence/` |
| FindGlocal | WONT-DO | already canonical |
| hairsalonsinusa | WONT-DO | CF 403 |
---
## E. Parked leftovers (out of scope for this close)
No email without a new Job Card. Not waiting on vendor replies — never started.
BestPros, Loc8NearMe, wheree, Giftly, Superpages, LinkedIn (Beauty By Ashley / La Mae), MyLocalServices, Opendi, CityOf, Giverrang, short Nextdoor leftovers.
---
## F. Close-letter checklist (this bar)
- [ ] IG bio done **or** documented owner-owned with steps handed to Ashley
- [ ] YP confirm **or** WONT-DO
- [ ] Birdeye re-scan today → keep WAITING (vendor reply) or note silence in letter
- [x] Yelp / MapQuest left WAITING (vendor)
- [x] Leftover aggregators PARKED (out of scope)
- [ ] Close letter drafted for Gatekeeper go
- [ ] Onboarding folder green — **separate lane**, not required for this close-out bar
---
*CoS owns updates. Hermes seats do not invent new surfaces without evidence.*
@@ -0,0 +1,5 @@
# Ashbot CC Anthony on listing return emails
Standing: when directories reply to Ashbot Phoenix outreach (`ashbotphoenix@agentmail.to`), Ashbot CCs `tonyjbala@gmail.com` on the reply thread.
Encoded in ashbot `SOUL.md` + CoS standing rules.
@@ -0,0 +1,66 @@
# 2026-09-19 — Ashbot Gate3 dispatch stumble (SOCKS + false "started")
## What happened
Anthony waited ~10+ min with "Nothing." CoS had said Ashbot was dispatched. She never ran. No iMessage. No job folder at first.
## Root causes (ordered)
1. **Silent false start:** CoS reported "dispatching" before the relay actually succeeded. First attempt died in ~5s on Tailscale SOCKS (`AssertionError` in socks5 handshake). Job folder never created. User saw silence.
2. **Detached Windows launch unreliable over SSH:** `start /B` and `Start-Process` of a `.bat` did not execute (empty `_launch.log`, no BAT_START). Looked "dispatched" when nothing ran.
3. **Wrong default profile:** Desktop `active_profile` was `jimmy` until CoS explicitly wrote `ashbot`. Env `HERMES_PROFILE` alone is not enough — set `active_profile` file too.
4. **Argv mangling risk:** Long briefs via `cli.py -q "<huge prompt>"` still risky on Windows. Prefer file brief (`_cos_brief.txt`) read by launcher.
## Locked workflow (Ashbot / any Hermes oneshot from CoS)
1. **Prove path before claiming start**
- SOCKS `:1055` up → SSH `fight@100.64.0.1` OK → SFTP write job folder → only THEN tell Anthony "started."
2. **Job folder first (evidence before inference)**
- Create `hermes\workspace\<client>\<job>\YYYY-MM-DD\`
- Write `STATUS.md` (`starting`), `_cos_brief.txt`, set `ACTIVE_JOB.txt`, set `active_profile` to target seat.
3. **Launch pattern (proven)**
- SSH **sync** exec of launcher Python (real `cpython-3.11.16\python.exe` + `_launch.py`).
- Do **not** rely on `start /B` / `Start-Process` for oneshots until proven with log line `BAT_START`.
- Launcher must log `LAUNCH … pid=` into `_launch.log` and flip STATUS to `working` with pid.
4. **Ashbot iMessage contract (non-negotiable)**
- Brief first action: iMessage Anthony that directions received / work starting.
- Brief last action: iMessage done + evidence path.
- CoS also pings Grok Bot chat on true dispatch (folder+pid confirmed).
5. **No silent waits**
- Mid-job: STATUS ping ~every 5 min from `STATUS.md` until `done`/`blocked`.
- If launch fails: ping Anthony immediately with failure mode (SOCKS/SSH/profile/exit), not after they ask "Nothing."
## What worked
- File brief + `_launch.py` + SSH sync channel → `LAUNCH2 ashbot chars=… active=ashbot` + `pid=` + STATUS `working`.
- Method A fallback: real Python + `cli.py` (not `hermes.exe` over SSH).
## Follow-ups
- [ ] Add this into Gitea `docs/agents/` or org v1 relay section when next syncing.
- [ ] Optional: STATUS watcher routine only when `ACTIVE_JOB.txt` points at a live job.
- [ ] Re-test detached launch later; until then SSH-sync is the standard.
## Second stumble same job — iMessage never left Ashbot
After the job *did* run (13:36–13:52 PT), both required iMessages failed:
- Photon free-tier shared line: `"Target not allowed for this project"`
- Free lines can only **reply** after Anthony texts that number first that day.
- Inbound gateway was healthy; outbound blocked until he opens the thread.
### Locked rule (Ashbot ↔ Anthony iMessage)
1. Before expecting Ashbot start/done texts: Anthony sends any iMessage to the Ashbot Photon number (opens the free-tier allow).
2. If CoS needs Anthony notified and iMessage is blocked: CoS pings Grok Bot chat immediately (do not wait on Photon).
3. Treat "iMessage contract" as best-effort on free tier; chat ping is the guaranteed channel.
## Third stumble — email capability gap
Ashbot drafted `email-birdeye.txt` but could not send (`send_mail` not available in that oneshot session) despite Anthony enabling email on the profile earlier.
- Locked: after enabling a Hermes capability, CoS verifies it in the *oneshot* path (same env/profile as Method A), not only Desktop interactive.
- Until verified: CoS routes "send this draft" as Gatekeeper click / Anthony relay, or re-brief with explicit send tool check.
## Job outcome (for the record)
- Birdeye: stale La Mae @ Flying C confirmed; email draft ready, not sent.
- FindGlocal: already canonical → WONT-DO.
- hairsalonsinusa: Cloudflare 403 → WONT-DO (needs browser retry).
## Fourth stumble — CoS silent after done
Birdeye send finished ~14:28 PT (STATUS done, email accepted). CoS did not ping Anthony until he wrote "It's been a long time" (~14:39).
### Locked rule
On Hermes `done`/`blocked`, CoS pings Grok Bot chat **immediately** with TLDR + evidence path. Mid-job 5-min pings while `working`; terminal ping is mandatory, not optional.
@@ -0,0 +1,31 @@
# 2026-09-19 — Ashbot inbox pass: credential hunt spiral
## Job
Inbox pass: read returns to Phoenix listing outreach, reply with CC tonyjbala@gmail.com.
## Process she actually ran
1. Memory write (identity + NAP)
2. mkdir workspace; try `himalaya` → missing (127)
3. Photon/iMessage check → unavailable (expected)
4. Read prior Birdeye send artifacts (good)
5. Long hunt for AGENTMAIL_API_KEY (blocked repeatedly by safety)
6. Source-dive hermes-agent email plugin / secret_scope (~minutes, including 143s grep)
7. Write `_check_mail.py` / `_check_inbox.py` for IMAP
8. Scripts exit 1 — key not in oneshot env / .env path miss
9. STATUS stuck at `working`; evidence empty; no replies-log
## Stumbles (ordered)
1. **Oneshot env gap (root):** Method A `_launch.py` does not inject `AGENTMAIL_API_KEY` into the child. Gateway/Desktop sessions may have it; SSH oneshot does not. Outbound Birdeye earlier worked via a session that had SMTP/key; this inbox pass did not inherit it.
2. **Safety blocks:** grep/cat of .bashrc/.env, powershell env dumps, execute_code — blocked. She adapted by writing files + read_file, but burned tokens.
3. **Tooling gaps:** `himalaya` not installed; uv python broken; had to discover `Python312` path.
4. **No STATUS discipline while blocked:** stayed `working` instead of flipping to `blocked: missing AGENTMAIL in oneshot env` after ~2 failed key checks.
5. **Credential archaeology over escalate:** should have STATUS=blocked and ping CoS after first confirmed KEY_MISSING, not 10+ minutes of source greps.
## Locked rules
1. Ashbot oneshot launcher MUST load profile `.env` (or pass `AGENTMAIL_API_KEY`) before `cli.py --oneshot`.
2. If mail key absent after one safe check → STATUS `blocked` + stop; CoS fixes env; do not source-dive.
3. Prefer Hermes email platform tools when available; raw IMAP is fallback only with injected key.
4. CoS mid-job STATUS watcher every 5m (now on) surfaces these stalls.
## Still open on this run
Job may still be spinning on key hunt. CoS should stop or reinject env and redispatch.
@@ -0,0 +1,109 @@
# 2026-09-19 — Post-mortem: Ashbot Gate 3 / inbox day (CoS + Hermes)
**Scope:** Phoenix Salon Gate 3 pilot → Birdeye send → inbox replies → STATUS watcher.
**Outcome:** Birdeye email SENT; inbox pass found no returns; several process failures burned time and trust.
**Author:** CoS (Chief of Staff) for Gatekeeper Anthony.
---
## 1. Timeline (PT, 2026-09-19)
| Time (approx) | Event |
|---|---|
| ~1:20 | Anthony: "Nothing" — expected Ashbot iMessage after Gate 3 assign |
| ~1:21 | First Gate 3 dispatch **failed in ~5s** (Tailscale SOCKS AssertionError). CoS had implied start; folder never created |
| ~1:32–1:36 | Diagnose → redispatch. Detached `start /B` / Start-Process **did not run**. SSH-sync `_launch.py` finally worked (pid 38648) |
| ~1:36–1:52 | Gate 3 pilot **done**: FindGlocal WONT-DO (canonical); hairsalonsinusa Cloudflare WONT-DO; Birdeye draft only (no send_mail in that session). iMessage blocked (Photon free-tier / sidecar) |
| ~2:23–2:28 | Birdeye **SENT** via SMTP from `ashbotphoenix@agentmail.to` (after username fix from rejected `ashbot@`) |
| ~2:40–2:42 | Park Phoenix domain mailbox; lock AshBot Phoenix = AgentMail identity; patch config username |
| ~2:58 | Close-out list for Anthony (IG / YP / Gate 3 leftovers) |
| ~2:59 | Standing rule: CC `tonyjbala@gmail.com` on listing reply threads |
| ~3:00 | Inbox pass dispatched — **oneshot missing AGENTMAIL_API_KEY** |
| ~3:00–3:14 | Ashbot credential-hunt spiral (himalaya missing, safety blocks, 143s source grep). STATUS stuck `working` |
| ~3:08+ | STATUS watcher created (@every 5m) after Anthony demanded visibility |
| ~3:12–3:14 | Trace analysis; Anthony: intervene as superior |
| ~3:15 | CoS killed pid 36384; redispatched **v2** with `.env` inject (`key_present=True`, pid 38988) |
| ~3:26 | Mid-job ping: curling AgentMail inbox |
| ~3:32 | **Inbox v2 done**: 4 msgs scanned, **NONE_FOUND** (no Birdeye/listing returns). ACTIVE_JOB cleared |
| ~3:39–4:16 | Desktop often unreachable; watcher correctly stayed silent (idle) but kept waking CoS every 5m |
---
## 2. What "went off the rails"
### A. False starts / silent failures
- Claimed or implied Ashbot "started" before SOCKS/SSH/folder/pid were real.
- Windows detached launch looked dispatched with empty logs.
- Anthony waited with "Nothing" / "It's been a long time" because CoS did not fail-loud or done-ping on time.
### B. Ashbot oneshot environment gap (root technical failure)
- Method A `_launch.py` did **not** load `profiles/ashbot/.env`.
- Gateway/Desktop sessions had AgentMail; SSH oneshot did not.
- Birdeye send luckily had key in that session; inbox pass did not → multi-minute dead-end hunt.
- Ashbot did not flip STATUS to `blocked` after first KEY_MISSING; CoS was slow to intervene.
### C. Visibility debt
- No reliable mid-job channel until STATUS watcher.
- iMessage contract failed (Photon free-tier + sidecar down) — chat ping is the real guarantee.
- Watcher later correct for idle, but **@every 5m forever** creates noise when no job (and when desktop offline).
### D. Scope / attention scatter
- Retro Revolution paste briefly looked like wrong-thread pollution.
- Desktop Local dropped after inbox done → watcher "offline" ticks (silent to Anthony, still wake tax).
### E. What actually worked
- File-brief + SSH-sync launch (once SOCKS up).
- Birdeye outbound SMTP with `ashbotphoenix@agentmail.to`.
- Intervene rule applied: kill spiral → inject key → v2 completed cleanly.
- Lessons filed in Obsidian; several standing rules locked in CoS memory.
---
## 3. Root causes (ordered)
1. **CoS process immature:** announce before prove; late intervene; late done-ping.
2. **Launcher incomplete:** oneshot must always inject AgentMail (and profile) from ashbot `.env`.
3. **Hermes worker defaults:** will source-dive instead of STATUS=blocked + stop.
4. **Notify path fragile:** Photon not reliable; chat must be primary.
5. **Watcher cadence too aggressive when idle.**
---
## 4. Locked rules (do not regress)
1. Never say Hermes "started" until folder + STATUS pid + launch log LAUNCH line.
2. SSH-sync `_launch.py` + `_cos_brief.txt`; no `start /B` until proven.
3. Inject `AGENTMAIL_API_KEY` from ashbot `.env` before every mail oneshot.
4. Key missing once → STATUS blocked + stop; CoS fixes; no source archaeology.
5. Dead-end path → CoS intervenes immediately (superior).
6. Done/blocked → CoS pings Anthony in chat immediately.
7. Mid-job ~5m STATUS pings only while ACTIVE_JOB points at live work.
8. Ashbot From = `ashbotphoenix@agentmail.to`; CC Anthony on listing reply threads.
9. Phoenix domain mailbox parked; do not block on `assistant@phoenixcameronpark.com`.
---
## 5. Corrective actions (next)
| Action | Owner | Status |
|---|---|---|
| Standardize hermes-relay / `_launch.py` with .env inject | CoS | Partially done (v2 pattern) — promote to default template |
| Pause STATUS watcher when ACTIVE_JOB empty; resume on dispatch | CoS | Do now |
| Optional: daily/idle inbox poll for Birdeye replies (with key inject) | CoS | Not started |
| Anthony: IG + YP confirm (close letter blockers) | Gatekeeper | Open |
| Mirror lessons into Gitea `docs/agents/` | CoS | Pending |
---
## 6. Honest scorecard
| Goal | Result |
|---|---|
| Gate 3 3-URL pilot | Done (2 WONT-DO + Birdeye draft→sent) |
| Birdeye email out | **Success** |
| Inbox replies + CC Anthony | N/A — no returns yet (pass succeeded) |
| iMessage start/done | Failed (infrastructure) |
| Gatekeeper experience | **Poor mid-day** — silence, false starts, late intervene |
| Learning loop | **Strong** — traces → lessons → rules → intervene |
**Bottom line:** The company work mostly completed; the *operating system* for CoS↔Hermes nearly failed Anthony’s trust. Paying attention to traces was correct. Default path forward is thin CoS, injected env, intervene early, chat as source of truth.