SKIPPY: Skippy tested as Nick uses him — every door, memory, files, hand-offs, two speeds

The actual documents the agents read and work from, shown exactly as they are on disk — not a summary. See the progress view instead · All projects

Plan PLAN.md

# PLAN.md — SKIPPY TESTING: Skippy holds a real conversation on every door and finishes what he is asked

**🔴🔴 THIS IS THE ONLY PLANNING DOCUMENT FOR THIS PROJECT. Do not create a second plan, tracker, summary, or scratch state file — extend THIS file or its STATE.md companion.**

**NORTH STAR:** Nick, 2026-09-14: "make him sound amazing and hold down natural human conversations like two people talking - codex voice is the target quality benchmark" and "he needs to be able to act like you or any other agent i talk to here in the claude code app - do not let a test end until he has done what you asked". Finished looks like this: Nick talks to Skippy on whichever door is in his hand — by text on Slack, WhatsApp or Gmail, or by voice in the family app or the Hub (§3a: those two are the ONLY voice surfaces) — about one real thing in his week, for as many turns as it takes, and Skippy talks back like a sharp colleague who remembers the thread, does the thing asked (a to-do, a calendar change, a note to Chantelle, a hand-off to an agent), proves it from the real store, and reports back when a hand-off finishes — in seconds, not paragraphs.
**FINISH LINE:** SIX outcomes, and this list REPLACES the twelve written before the 2026-09-14 replan — the old list still demanded the three-day memory rewrite and the door-edge suites that §3c cuts, so two readers could obey two different definitions of done. (1) Skippy opens and works on every surface Nick uses — phone, Mac window, Hub; (2) he holds the family conversation on ALL FOUR doors, graded on the real to-do store by item id — 🔴 CORRECTED BY NICK 2026-09-14: ten turns is a FLOOR on the three text doors (Slack, WhatsApp, Gmail), never the bar — the exchange keeps going back and forth past ten with context retained across the whole conversation; on the voice app the floor is FORTY messages, and past those he still answers from an extended memory file of the conversation rather than forgetting ("the voice app is 40 message plus an extended memory file that he can reference beyond those messages") — and a listener who built none of it scores warmth, relevance, continuity and humanness at least 4 of 5; (3) a spoken turn's substantive answer lands within four seconds on the pinned recordings; (4) ordinary turns run 15–45 words with no tool talk, no inventories and no leaked test labels; (5) real work lands and delegated work returns to the conversation it came from, including a card on Nick's board; (6) a thread started by typing continues by voice without repeating itself, files pass both ways, and the model tiers Nick set are the ones actually serving. Anything found after an outcome passes goes on the NEXT list and is not worked.

**Owner:** Fable 2 (this session) · **Overseer:** Fable 2 for building lanes; Astra (Codex gpt-6-astra, senior-engineer profile, read-only) as the independent reviewer on every step — NICK-ASKED: "lets do a proper regroup and create a new plan for you and astra to do the testing skippy needs" (2026-09-14) · **Design authority:** none (nothing new is drawn)
> **STEP 0 — ARM THE LOOP, BEFORE ANYTHING ELSE.** Set a 5-minute loop. Every time it fires, answer
> these five in order and CORRECT any failure before doing anything else:
> 1. **NORTH STAR** — is what I am doing this minute moving this plan's North Star? If not, drop it.
> 2. **FAN-OUT** — declare the whole actual roster, dispatch useful ready work, and shed your own unnecessary processes. Coordinate through peers or the launching dispatcher; no numeric cap or load-wait rule applies.
> 3. **CHEAP** — are cheap models doing the building AND the per-step checking? If anything on
>    Anthropic or OpenAI is building or checking a step, move it down now (§M).
> 4. **STUCK** — for anything I have called blocked: name the input that does not exist yet, or the
>    three concrete things I tried. If I cannot, it is not blocked — drive through it now.
> 5. **NEXT** — did something just finish? Then the next step whose inputs exist starts THIS minute.
>    A finished step is never a place to stop, a report is never a reason to wait, and Nick being
>    away or asleep is the reason to keep going, not to pause.
> Then keep building. The loop never stops until the FINISH LINE is proven.

**Rule: a step starts the moment its named inputs exist, whatever its number. A step closes on ONE independent check by a different model. Nothing waits on Nick to test.**

## START HERE — you are the session that runs this, and you were handed it cold

**HANDOFF CLEARED 2026-09-14 by SIX INDEPENDENT COLD READS.** Codex (`gpt-6-astra`, read-only) read this plan as you, six times, and refused to call it ready five times. Its final verdict: *"ready to begin. Hand it over now."* Those reviews are in `evidence/astra-coldread*.txt` — **read the last one before you start**, because it tells you exactly what was proven and what was not.

🔴 **WHAT THOSE SIX ROUNDS WERE ACTUALLY ABOUT, because it is the one thing to carry into every step you build.** Each round, the reviewer forged a pass out of the gate that decides whether a test can be trusted — with a script that ran no test at all. It exited non-zero like any unrecognised command. It printed a sentence containing the words "negative control". It printed a help line describing the receipt. It read the filename. It compared file creation times. Every version of the gate had asked the instrument about ITSELF, and an instrument's account of itself is never evidence — which is what rule 17 already says about pasted output, and it is as true of code as of agents. The gate now writes both inputs itself, in separate directories, in random order, breaking a different property each run. **When you build the remaining seven instruments, expect to be wrong about yours in the same way.**


**Run this first. Not as a formality — it is the difference between driving this plan and reporting a healthy product broken.**

```
node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/_preflight.mjs
```

It reads seventeen things this plan needs inside its first hour and touches nothing. Verified READY on 2026-09-14 from the machine that wrote it.

🔴 **IF SEVERAL CHECKS FAIL AT ONCE, SUSPECT THE MACHINE, NOT THE PLAN.** The tokens, the vault key and the Codex accounts live under one macOS user on one Mac. A different Claude ACCOUNT on that same Mac inherits all of it; a different MACHINE inherits none of it, and the symptom is never a clean error — it is a test reporting a working product broken, which is the exact class of false claim this lane exists to stop.

🔴 **COMMIT EVERY EDIT THE MOMENT YOU MAKE IT.** On 2026-09-14 another session overwrote this plan file and one of the test files while they were being worked on, and two finished pieces of work were lost and had to be written twice. There is no lock. Re-read a file before editing it if minutes have passed since you last looked at it.

🔴 **THE CONVERSATION TEST SENDS REAL MESSAGES TO NICK.** `tests/ten-turn.mjs --door all` posts ten questions into his own Slack, his own WhatsApp and his own inbox, and writes to his real family to-do list. Test sends to him are pre-approved and unlimited and every turn is labelled, so this is allowed — but it is not free, and it is not something to fire while working out whether a flag exists. Run it when you mean to measure, read the evidence file afterwards, and never loop it: a retry loop around a Hub call put ten junk cards on his board on 2026-09-14.

**THEN, IN THIS ORDER — and this ordering WINS over the general rule that any step may start when its inputs exist.** That rule still governs STEPs 1 to 6 among themselves; it does not license starting a step whose instrument STEP 0 has not built yet, because the plan will not let such a step close.
1. **Read §3e before you write a single test.** It is thirteen things Skippy actually said to Nick in Slack, verbatim. Nick, 2026-09-14: *"make sure we review all these threads tests for skippy instead of just starting over cold - everything we determine in these threads needs to be a part of the plan"*. Starting from a blank page re-discovers, expensively, what a week of real conversation already settled.
2. **STEP 0 builds the instruments.** Seven of nine do not exist. Nothing below STEP 0 can be proved until they do, and the plan will not let a step close on a proof that cannot fail.
3. **Then STEP 2's voice adapter**, which is the only thing between here and a finished answer on all four doors.

**WHO YOU CALL.** Codex (`gpt-6-astra`) is the independent checker on STEPs 1, 2 and 4 — NICK-ASKED, 2026-09-14. One read-only call at a time, never a fleet:
```
projects/ops/skippy-jobs/lib/astra-review.sh ~/.codex2 <brief-file> <out-file> <log-file>
```
Cheap vendors (zai, deepseek, qwen) build; Sonnet checks where a step names it.

🔴 **WHAT "YOU DO NOT BUILD" MEANS HERE, because it reads as a contradiction and a cold reviewer flagged it.** You WRITE the test contract for a step — the exact cases, the pass line, the output that would fail it — because that is a judgement about what done means, and the model matrix keeps it above the cheap tier. You do NOT write the product code, and you do not write the bulk of the instrument: you hand the contract to a cheap vendor and check what comes back. When a cheap run fails twice on the same step, suspect the brief before the vendor.

## Already true (facts, not story)

- Slack, and it is TWO runs, not one — corrected by an independent verifier on 2026-09-14, which re-opened both files: (a) a ten-turn same-topic thread holds the conversation and ADDS the to-do — all ten answered, one reply per turn, on topic, day picked, added to the store, read back, opener quoted verbatim on turn ten, test provenance on the envelope, never "no tool"; its own verdict records `todoRenamedInStore:false` and `todoClearedInStore:false`, because at that hour the rename tool did not exist. (b) a later four-turn run, after the rename shipped, is what proves the actions: `allActionsDoneInStore:true` across add → read back → rename (same item id) → mark done, attempts [1,1,3,1]. Writing these as one claim overstated it. — evidence: `projects/ops/life-os/REGROUP-2026-09-08/plans/VOICE/evidence/fable2-2026-09-13/step29-slack-topic-conversation-2.json` (a), `step29-slack-todo-actions-2.json` (b)
- WhatsApp: a tag from Nick's own number or Chantelle's verified number is answered in that chat in ~8 s; Gmail: a tag anywhere in the new text or the subject is answered in-thread and Skippy's own replies never re-trigger — evidence: VOICE `PROGRESS.txt` entries 03:20Z and 03:35Z
- The brain answers on the subscriptions again (the "all eight accounts limited" claim was the Claude Code identity-line gate) — evidence: `GLOBAL-CLAUDE-RULES.md` last section; `/data/skippy-cloud-lane-log.jsonl` rows after 03:29Z
- The conversation contract leads Skippy's prompt; the closing guard strips offers only; what's-running speaks like a person; `update_todo` can rename; his whole to-do list reaches the model — evidence: skippy-code-publish commits bb980f3 … 1afe4e6e515d (live stamp), `_test-closing-guard.mjs` 27/27
- A hand-off from the cloud brain now reaches the Mac (outbox row) and carries its origin; the drain reports the result back into the same thread — evidence: skippy-code-publish commit 269dc88 (Fly release v534), outer commit f2e64204cc, `_test-code-agent-drain.mjs` 71/71 (live proof owed: STEP 3)
- Astra's review of how he talks, with its build order — evidence: `plans/VOICE/evidence/fable2-2026-09-13/astra-conversation-quality-1.txt`
- 🔴 NOT TRUE ANY MORE, AND IT CHANGES STEP 1: the harnesses that produced every proof above are GONE. They lived in a session scratchpad and the 2026-09-14 machine restart erased it — verified empty that morning: `slack-topic-conversation-2.mjs`, `slack-todo-actions-2.mjs`, `proof-mail.mjs`, `proof-wa-tag.mjs`, `live-voice-walk.mjs`, `code-stamp.mjs`. The evidence JSON survives because it was committed; the instruments were not. So no proof in this lane can be RE-RUN until STEP 1 writes them into `tests/` — STEP 1 is "write", never "move" — and an instrument this lane builds never lives anywhere but this lane's own folder.

## 0 · Gate Zero receipts (the plan may not exist without these)
- Failure Mode Registry loaded: 2026-09-14, 60+ entries; exposed to: "A claim about the user/system was made without its source", "A UI reported success while the backend silently failed", "A conclusion was drawn from a partial read", "A capability was declared impossible from a stale or unverified claim", "Expectations/manifest rows carried no grounding", "A serial multi-step operation blew its time budget", "Work was written to a queue no reader ever visits", "Concurrent sessions clobbered each other's work in a shared file" — measures in §4
- Canonical specs loaded: `projects/ops/agents/CODE-STANDARD.md` (code), `projects/ops/HANDBACK-GATE-SPEC.md` + `DEV-QA-SPEC.md` (QA); design N/A
- Ownership check: registry rows `life-os-the-voice-app` (VOICE lane, DOORS phase — STEPs 29/32/33 closed there) and `life-os-skippy-capabilities` cover the doors as BUILT; no row covers Skippy TESTED AS CONVERSATION across doors with store grading — this lane is that, and the VOICE lane's open STEPs 30/31 hand here (STEP 4 and STEP 7 below)
- Expected inputs confirmed to exist: the four doors (checked live 2026-09-14); Nick's family to-do store door (`/api/todo-list`, `/api/todo-store-write` with rename, live 03:55Z); the brain's turn record (`skippy-code-publish/lib/conversation-ledger.mjs`); 🔴 TWO INPUTS THIS PLAN FIRST CLAIMED AND DOES NOT HAVE, corrected by a cold reader 2026-09-14: the headless voice walk rig (`live-voice-walk.mjs`) is GONE with the erased scratchpad — STEP 5 builds it from scratch, and its estimate says so; Astra's launch path was also erased and has been REBUILT in the repo as `projects/ops/skippy-jobs/lib/astra-review.sh` (read-only, senior-engineer profile, retries through "model at capacity", rotates accounts by CODEX_HOME), so the steps that name Astra as checker can actually summon him; the Mac code-agent drain (`projects/ops/skippy-jobs/jobs/code-agent-drain.mjs`, every minute)
- PLAN AUTHOR: Fable 2 (session 0eac6675), 2026-09-14
- COLD READER: Astra (gpt-6-astra, read-only) — the first task of STEP 1 is its cold read of this file; disputes land in PLAN-CHANGES.md
- PROMPT-SPEC scan (P1–P7): P1 "super deep" (which questions) — resolved as the brain's deep register plus Nick's explicit ask, §1a row 3; P4 "every door" — Slack, WhatsApp, Gmail, voice/Talk; the Hub's Talk tab shares the family panel and is covered by the Talk door; nothing else is a door (§1a row 1)

## 1 · Goal and definition of done
- **What we're building, one paragraph.** A standing test of Skippy as a conversation partner — the same ten-turn family topic on every door, graded by what changed in the real stores and by measured shape (words per turn, tool talk, follow-ups, latency) — and the fixes that test surfaces, worked in order: hand-offs that run and report back, the voice app's spare round trip and blob audio, files both ways, memory that carries dated decisions, the Gmail/Slack/WhatsApp edges, and the model tiers Nick set. Fable 2 builds through cheap workers; Astra reviews every step's evidence cold.
- **HOW IT'S USED:** Nick talks to Skippy on his phone (WhatsApp, Slack, the family app by voice) or by email, about his week, and asks for things. · HOW WE KNOW: his own tests 2026-09-14 (the Slack thread screenshot; "I tag Skippy … because I want Skippy active"; the WhatsApp/Gmail rulings in VOICE PROGRESS 00:30Z)
- **WHAT IT LOOKS LIKE:** short spoken-shape answers, one follow-up at most, actions confirmed from results ("Changed it to three thirty. Still Friday, still an hour."), files in and out, a hand-off's result back in the thread; nothing new is drawn. · HOW WE KNOW: the CONVERSATION_CONTRACT in `server.js` and Astra's examples
- **WHERE IT LIVES:** the brain skippy-cloud (Fly), the doors in `projects/personal/skippy-app/{channels,wa}/`, the family app (`projects/personal/family-app`), the Mac drain in `projects/ops/skippy-jobs/jobs/`, this lane's `tests/` folder; opened by Nick on every door, and by Chantelle in WhatsApp. · HOW WE KNOW: the doors' own files and the live runs
- **WHAT IT MUST DO:** (rewritten by the 2026-09-14 replan; the thirteen-item version this replaces still demanded the memory rewrite and the door-edge suites that §3c CUTS, so two readers could obey two different definitions of done): 1 the family conversation on all four doors, store-graded — ten turns the FLOOR on the text doors, forty messages the floor on voice, context held throughout (Nick, 2026-09-14) · 2 a thread started by typing continued by voice, no transcript passed · 3 measured answer shape, including no leaked test label · 4 real work done and delegated work returned to the conversation it came from, a Hub card included · 5 the model tiers Nick set, correlated against serving records · 6 a spoken substantive answer within four seconds on the pinned recordings · 7 files both ways on every door · 8 Skippy opening and working on phone, Mac window and Hub · HOW WE KNOW: §6
- **NOT in scope:** (a) redesigning any screen — nothing is drawn, the family app's look is on hold for Chantelle's UX pass; (b) security or privacy work of any kind — one line to `projects/ops/sp-sec/PLAN.md` if seen; (c) the Hub's Talk tab as a separate door — it mounts the family panel, so the Talk/voice door covers it; (d) a SECOND memory store — 🔴 CORRECTED 2026-09-14 after reading the LIVE brain, not the stale working copy: the extended memory file Nick means ALREADY EXISTS and is live. It is the per-person turn record (`nick-turns.jsonl` on the cloud disk, 430 events on 2026-09-14). The voice app carries its own last 40 messages, and before EVERY turn on EVERY surface the brain adds what the app lacks from the last THREE DAYS of that record — the newest six hours word for word, the rest as one line per turn with its id — inside a 12,000-token budget; the record itself keeps 30 days. So STEP 2 TESTS this memory (a question past the fortieth message, and a question in a fresh session, both answered from the three-day record) and does not build it; (e) ElevenLabs or a voice change — Cedar at 1.3x stays this pass (Astra: the delays are structural); (f) Gracie's Slack presence — she has no posting key on the Mac; that is the ASSISTANTS lane's.
- **Trip-over protocol:** a lane that finds something outside the fence writes one handover line to its named owner (VOICE plan for app UI; ASSISTANTS plan for Gracie/Neeko identity and Gracie's Slack key; `sp-sec/PLAN.md` for anything security-shaped), then returns to its step.

## 1a · Critical variables — the confirmation sheet is GENERATED from this table

| # | The variable, in plain words | Value chosen | Alternatives rejected | Class | HOW WE KNOW | Cost if wrong | CONFIRMED |
|---|---|---|---|---|---|---|---|
| 1 | **SURFACE — which screen this lands on, and who opens it** | Skippy on four doors: Slack (Nick's DM and any channel his bot is in), WhatsApp (Nick's chats and groups, Chantelle's number), Gmail (mail Nick sends), the family app Talk tab by voice; opened by Nick, and by Chantelle on WhatsApp | The Hub Talk tab as its own door (it is the same panel) | V1 | Nick, 2026-09-14, "if I tag Skippy in a channel it's because I want Skippy active in that channel period"; "uploading images or photos or files via slack is important and ideally he can do that on gmail and whatsapp" | Tests pass on a door he does not use | Nick, 2026-09-14, "combine testing so that its emulating how i use this system" |
| 2 | Who plays Nick in a test | An agent posting as itself through one of Nick's own token apps, marked "[agent-test]", answered as Nick's identity; test turns kept out of his memory | Nick testing by hand; a fake user | V1 | Nick, 2026-09-14: "just test as you and not my name set the testing so it can happen like that" | Tests silently enter his memory, or never run | Nick, 2026-09-14, "just test as you" |
| 3 | Which model answers | Sonnet 5 everyday; Opus 5 deep (his body, money, family decisions, "go deep"); Fable 5.1 super-deep (the heaviest calls, or when he asks) — all subscription-first | Opus on every turn; one model | V1 | Nick, 2026-09-14: "sonnet for everyday opus for deep fable for super deep unless otherwise specified" | Slow everyday turns, or shallow deep ones | Nick, 2026-09-14, "sonnet for everyday opus for deep fable for super deep" |
| 4 | The bar for a conversation test | Text doors (Slack, WhatsApp, Gmail): at least ten turns on ONE topic — a FLOOR, not the bar — the harness keeps going back and forth past ten with context retained across the whole exchange, ending in a real action proven in the real store, the opener recalled at the end; voice app: at least FORTY messages, and past forty he still answers from an extended memory file of the conversation (Nick, 2026-09-14); the harness pushes back like a person and never ends until the store shows the action | Single-question probes; grading by answer words | V1 | Nick, 2026-09-14: "set bar at minimum 10 turn conversations in slack"; "prove that on the 10th turn he can remember the original message"; "do not let a test end until he has done what you asked" | A green test that proves nothing | Nick, 2026-09-14, "do not let a test end until he has done what you asked" |
| 5 | The family topic used everywhere | Willow wanting one-on-one time with Noah this week: find the slot, pick the day, add the to-do, correct the time, one line for Chantelle, recall the opener, clear the test item | A business topic (Chantelle and the kids are who he talks about most) | V2 | opened `step29-slack-topic-conversation-2.json`, 2026-09-14, saw: the ten turns and his answers | Wrong test shape — a different topic is a change here, not a risk | opened the evidence, 2026-09-14, saw the run |
| 6 | Where a test's action lands | Nick's family to-do list (test items named "(agent-test <stamp>)", completed off the list by the harness at the end) and his calendar read-only | The Hub (business), Monday (never) | V2 | opened `todo-list`/`todo-store-write` doors live 03:55Z, saw: add, rename, complete round-trip | A test item left on his real list | opened the door, 2026-09-14, saw the round-trip |

- V1 confirmation reads `<name>, <date>, "<their own words>"` — the date is required.
- V2 confirmation reads `opened <what>, <date>, saw: <what was actually there>`.

**Considered and ruled NOT critical:**
- `which Codex account Astra runs on` — `astra-review.sh` rotates across all four itself and treats a usage limit as a routing event, so any of them is fine. Quota is per account AND per model: one saying no proves nothing about the others.
- `words-per-turn thresholds (15–45, flag >60)` — Astra's proposed measure; a threshold change is a lane-internal delta

## 1b · Subproject decomposition — could a piece of this ship on its own?

- **SINGLE SUBPROJECT:** `one brain, four doors, one test set — every step lands in the same running Skippy, and no piece is useful to Nick alone before the conversation test passes on his doors`

**Carve-out rule:** anything left out of every subproject's scope is named with a real owner in the same edit, or it may not be left out. Carved out here: Gracie's and Neeko's own conversation quality and Gracie's Slack posting key → ASSISTANTS lane; the family app's look → VOICE lane / Chantelle's UX pass.

## 2 · The complete UX map (this becomes the test manifest verbatim)

| Id | Screen / entry point | State (default·empty·error·loading) | Element / interaction | Expected behavior | Navigation from → to |
|---|---|---|---|---|---|
| U1 | Slack DM with Skippy | default | family thread of at least ten turns (the floor), tagged, continued past ten by the pinned continuation bank in `tests/ten-turn.mjs` | every turn answered once, in 15–45 words, action turns change the to-do store, every continuity check answered with the earlier decision, opener quoted on the last turn | thread → same thread |
| U2 | Slack channel Skippy is in | default | tag then untagged follow-up in the thread | both answered; a client-facing (cc/ic) channel refused | channel → thread |
| U3 | WhatsApp, Nick's chat and a family group | default | the same at-least-ten turns from Nick's number; a tag from Chantelle's number | answered in that chat, signed Skippy, ack then answer, action proven in store | chat → same chat |
| U4 | Gmail, mail Nick sends | default | tag in body or subject; a reply in the thread | answered in-thread; no self-reply; subject read; thread past 20 messages still answered | mail → same thread |
| U5 | Family app Talk tab, voice | default·loading | at least twenty-two turns (forty-four messages) spoken through the mic stub, so the opener has left the app's own forty-message window before it is quoted; a correction mid-answer | first substantive audio ≤ 4 s on a simple turn; correction replaces the earlier choice; no acknowledgement after the answer | Talk → Talk |
| U6 | Slack → voice | default | turns 1–5 in Slack, 6–10 by voice, no transcript passed | turn 6 refers to the Friday slot picked in Slack; turn 9 quotes the opener | Slack → Talk |
| U7 | Any door, a hand-off | default·error | "get a sonnet agent to …" | the agent runs on the Mac within two minutes; its one-line result comes back into the same thread; a failure comes back as a failure | thread → same thread |
| U8 | Any door, a file in | default·error | a PDF, a document, a captionless photo | the file is read and answered on; an unreadable file is named as unreadable, never "looked at" | door → same door |
| U9 | Talk tab, a file out | default | Skippy sends a screen/file into Talk | a card with an Open control appears in Talk on the family app and the Hub | brain → Talk |
| U10 | Any door, a deep question | default | "go deep on …" / a health or money question | Opus 5 (or Fable 5.1 on the heaviest) answers; the everyday turn stays on Sonnet 5 | — |
| U11 | Any door, an outage | error | all eight subscription accounts refuse in one turn | one paid turn, loudly logged with eight refusal rows; otherwise never paid | — |

DESIGN FIDELITY GATE: N/A — nothing rendered

## 3 · Lanes and frozen contracts

| Lane | Scope (in / out) | Owner | Definition of done | Builder (cheap, named) | Backup builder | Checker (different model) | Backup checker |
|---|---|---|---|---|---|---|---|
| TEST | the four-door ten-turn harness, cross-surface run, shape metrics (in); fixing what it finds (out — that is the other lanes) | Fable 2 | STEPs 1–2 closed | qwen (test execution; authoring stays on Fable 2 per the matrix) | deepseek | Astra (gpt-6-astra) — NICK-ASKED | Sonnet |
| BRAIN | hand-off report-back, model tiers, memory shape, paid-lane receipts, read/act tools (in); doors' own code (out) | Fable 2 | STEPs 3, 4, 8, 12 closed | zai | deepseek | Sonnet | Astra |
| VOICE-APP | the spare routing round, audio streaming, acknowledgements (in); look and feel (out) | Fable 2 | STEPs 5–6 closed | zai | qwen | Sonnet | Astra |
| DOORS | files both ways, Gmail/Slack/WhatsApp edges (in); Gracie/Neeko identity (out → ASSISTANTS) | Fable 2 | STEPs 7, 9–11 closed | zai | deepseek | Sonnet | Astra |
| POLISH | old suites, Slack recovery honesty, postmortem | Fable 2 | STEPs 13–14 closed | deepseek | qwen | Sonnet | — |

**Contracts between lanes (FROZEN at plan time):** every test posts as "[agent-test]" through Nick's own token apps and sends `testTurn:true` to the brain · a test's to-do items carry "(agent-test <stamp>)" and are completed off the list by the harness · the brain's `/api/chat` body carries `clientTurnId`, `conversationId`, `surface`, `testTurn` from every door (live) · a dispatch row carries `origin {surface, conversationId, clientTurnId}` and the Mac drain reports back by it (live, unproven) · the family to-do door's actions are add/complete/reopen/date/someday/rename (live) · the turn record is the single memory (no second store) · results land as JSON in `plans/SKIPPY-TESTING/evidence/` with the run's transcript, store snapshots and metrics.

## 3a · 🔴 WHERE VOICE LIVES — NICK'S RULING, 2026-09-14

**Verbatim: "slack isnt a voice surface / voice only is hub or family app".**

- **Voice happens in exactly two places: the Hub and the family app.** The voice adapter drives those two and nothing else. A test that tries to speak anywhere else is testing something that does not exist.
- **Slack, WhatsApp and Gmail are TEXT doors.** They carry typed conversation and files. They never carry voice, and no step may report a voice result from one of them.
- **This does not weaken the cross-surface step.** Starting a thread by typing in Slack and finishing it by speaking in the family app is continuity between a text door and a voice surface, which is exactly the thing being tested. What it is not, and must never be written as, is "voice on Slack".
- **The Hub's Talk tab is not a separate door from the family app's** — it mounts the same panel — but it IS a separate surface, so STEP 1 opens both and STEP 2 must be able to run its spoken conversation in either.

## 3e · 🔴 WHAT NICK'S OWN THREADS ALREADY PROVED — THE TEST MATERIAL, NOT A FRESH START

**Nick, 2026-09-14: "make sure we review all these threads tests for skippy instead of just starting over cold - everything we determine in these threads needs to be a part of the plan".**

These are not hypotheses. Every line below is Skippy's own words to Nick in Slack, and each one is owned by a step. A replan that ignored them would be re-discovering, at cost, what a week of real conversation already established. This section is the answer to his standing rule that human conversation is the basis of testing.

| # | What Skippy actually said | What it proves | Owned by |
|---|---|---|---|
| T1 | *"The Hub is available as of 2026-09-14, but U0BPHR3QHFB is not in the current client records."* | 🔴 **A raw Slack user id reached a CLIENT-NAME lookup.** The mention string for Skippy's own bot was read as the name of a company. He then reported a clean, confident, entirely wrong answer. | STEP 3 |
| T2 | *"The Hub is available as of 2026-09-14, but Hub is not in the current client records."* | Same fault, different input: the word "Hub" taken as a client name. A read tool that answers about whatever noun it was handed will always answer, and will often be wrong. | STEP 3 |
| T3 | *"That call came back as an hours read, not a task creation"* | A request to create a task was routed into an hours query. He noticed and said so, which is right, but the routing itself is the defect. | STEP 3 |
| T4 | *"No — I can only send Slack messages, not read them. I don't have a tool that lets me see what's posted in a channel or a thread"* — said IN a Slack reply, TO a message he had just read | 🔴 **A false statement about his own capabilities, delivered with total confidence, while doing the thing he said he could not do.** This is the single worst line in the whole record: it would make Nick stop asking. | STEP 2 |
| T5 | *"I don't have a record of an earlier question from you in this thread — what did you ask?"* | Memory inside ONE thread failed, two messages apart. | STEP 2 |
| T6 | *"Got it — '@U0BPHR3QHFB you need to just link to it or drop it here this isnt helpful'. Nothing of Skippy's is mid-conversation right now, so it's on the pickup list"* | He echoed Nick's own complaint back at him, raw user id included, and called that an answer. | STEP 2 |
| T7 | *"[agent-test] Tuesday's the day after that"* and *"[agent-test] @U0BPHR3QHFB Wednesday's the standout day"* | 🔴 **He copied the harness's own test label into his replies**, and a raw user id with it. The test changed the thing it was measuring. | STEP 2 |
| T8 | *"Filed and hit a wall — there's no confirmation queue set up for Frazer yet, so I can't route it to him directly"*, answering *"just put it on the agenda for this week"* | "Put it on the agenda" was read as "route it to a person's queue". The agenda is a Hub card; the queue is a different thing he reached for and did not have. | STEP 3 |
| T9 | *"I haven't added it, so it's not on the agenda yet. Someone with Hub access (Nick, Dean, or one of the team) will need to add it directly"* | The four-fault Hub write, now fixed and proven end to end. **Kept here because the SENTENCE is the test**: the finished bar is that this sentence never appears again, not that an internal call returns 200. | STEP 3 |
| T10 | *"It's not there — never was, and the 'mark it done' call reported success but there's nothing on the actual list to show for it"* | The to-do write path reporting success over a no-op. Fixed; the ten-turn conversation now grades by item id precisely because of this. | STEP 2 |
| T11 | *"Skippy couldn't reach its brain just then (20:51:50)"* | The subscription lane refusing every turn. Fixed — it was the Claude Code identity line, never a spent account. | STEP 2 |
| T12 | *"It's a smooth gradient — pink and purple up in the top left, fading through blue in the middle"* | ✅ **Working, and the bar for STEP 5.** A captionless picture on Slack, answered usefully with no prompting. | STEP 5 |
| T13 | Ten turns about Willow and Noah, ending *"Willow's been asking for more one-on-one time with Noah this week…"* quoted verbatim | ✅ Working on Slack, WhatsApp and Gmail, first attempt on every turn. | STEP 2 |

🔴 **THE PATTERN ACROSS T1, T2, T3, T4 AND T8, AND IT IS ONE FAULT WEARING FIVE COATS: HE ANSWERS FROM THE NEAREST TOOL RATHER THAN SAYING HE CANNOT.** A client lookup handed a Slack id, an hours reader handed a task request, a capability question answered from a guess. Every one produced a fluent, confident, wrong sentence. This is the same shape as the to-do bug and the Hub bug, and it is why STEP 2's bar is not "the answer was nice" but "the store moved".

**So two things every step inherits from this section:**
1. **A wrong answer delivered confidently is worse than a refusal**, and must be gradeable as a failure. A step whose proof only checks that a reply arrived cannot see any of T1 to T8.
2. **The test must not leak into the thing tested** (T7). Test labels belong on the way IN, never in Skippy's mouth on the way out — the ten-turn harness now counts a reply carrying its own label as a defect.

## 3b · Execution map — the Step map, then one STEP block per row

A task is DONE only when its review-ledger row is CLOSED by a reviewer that is not the builder.

**Step map (read this first):** SIX steps, merged 2026-09-14 from this lane's fifteen and the VOICE lane's twelve by Codex (gpt-6-astra) on Nick's instruction "now is fine then right into a full replan with codex to get this thing DONE". The cut list is §3c; nothing is deleted, it is recorded as CUT and not worked. The VOICE lane's competing execution list is retired — this file governs.

| Stage | # | Task (step name) | Carries | Needs (named artefact, or `none — start now`) | EXECUTOR | EXECUTOR BACKUP | CHECKER (never the builder) | CHECKER BACKUP | DONE-PROOF (runnable command) |
|---|---|---|---|---|---|---|---|---|---|
| Surfaces | 1 | Open the current Skippy everywhere | voice 1, 2, 7 (function only) | none — start now | zai | deepseek | Astra | Sonnet | `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/surfaces.mjs`  (CREATED BY STEP 0) |
| Talk | 2 | Hold a natural spoken conversation and do the family task | this lane 1, 5, 6, 15; voice 4, 5, and the kept behaviour of 9 and 10 | the surviving voice rig `projects/personal/family-app/_test-voice-rig.mjs` | Fable 2 authors; zai runs | deepseek | Astra | Sonnet | `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/ten-turn.mjs --door all` |
| Doing | 3 | Finish ordinary work and return delegated results | this lane 3; voice 3, 6; the Hub write fault | none — start now | zai | deepseek | Sonnet | Astra | `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/handoff.mjs`  (CREATED BY STEP 0) |
| Continuity | 4 | Continue without repeating yourself | this lane 2; voice 8 | `tests/doors/voice.mjs` (CREATED BY STEP 0); STEP 1's installed-app driver | zai | qwen | Astra | Sonnet | `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/cross-surface.mjs`  (CREATED BY STEP 0) |
| Files | 5 | Read files and return something usable | this lane 7 | none — the three text doors start now | zai | deepseek | Sonnet | Astra | `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/files.mjs`  (CREATED BY STEP 0) |
| Tiers | 6 | Use Nick's chosen model depth | this lane 4 | none — start now | zai | deepseek | Sonnet | Astra | `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/tiers.mjs`  (CREATED BY STEP 0) |

### STEP 0 — Build the six instruments everything below is measured with
**FOR NICK:** nothing you would notice. This is the toolkit that makes every line below provable instead of assertable, and it exists as its own step for one reason: the last plan let each step build the tool that judged it, and nine of twelve ended up with a proof that could never fail. · **Tier:** POLISH
**Start when:** none — start now. The three text-door adapters and the conversation runner already exist and are not rebuilt.
**Builder:** zai · **Builder backup:** deepseek · **Checker:** Sonnet · **Checker backup:** Astra
**Files you may touch:** everything under `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/`. **Never** the brain, the doors, or `js/voice.js`.

🔴 **A STEP MAY NOT BUILD THE THING THAT GRADES IT.** That is not a style preference: the plan checker refuses the pattern by name, because deferring a harness into the step that needs it is what collapsed the 2026-08-29 night. So every instrument is built here, and every step below cites one that already exists.

**Build these six, each with a NEGATIVE CONTROL proving the grader rejects its own named failure:**
1. `tests/surfaces.mjs` — the three surfaces and the real installed application.
2. `tests/doors/voice.mjs` — the fourth door, on the surviving rig, repointed out of the erased scratchpad.
3. `tests/voice-latency.mjs` — speech-end to playback onset on ONE clock, acknowledgement and answer reported separately.
4. `tests/handoff.mjs` — one connected conversation that does real work and gets the result back.
5. `tests/cross-surface.mjs` — continuity without an injected transcript.
6. `tests/files.mjs` and `tests/tiers.mjs` — files both ways, and the served model per turn.

Also repair `tests/sound-grade.mjs`, which extracts ten EMPTY questions today and has no fixed four-door denominator.

**DEFINITION OF DONE:** each instrument runs, and each one FAILS on a deliberately broken input.
**PROOF:** `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/_selftest.mjs` (CREATED BY STEP 0) · **FAILS IF:** any instrument is missing, or any grader passes its own negative control.

### STEP 1 — Open the current Skippy everywhere
**FOR NICK:** your phone, your Mac window and the Hub all open a working Talk screen with controls that do what they say. · **Tier:** FRONT
**Start when:** none — start now.
**Carries:** the old voice lane's STEP 1 and STEP 2, and the working half of its STEP 7.
**Builder:** zai · **Builder backup:** deepseek · **Checker:** Astra (gpt-6-astra, read-only) · **Checker backup:** Sonnet
**Files you may touch:** `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/surfaces.mjs` (NEW), `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/evidence/`. The desktop packaging repair is the one exception, and it is named in the step.

**Do exactly this:**
1. BUILD `tests/surfaces.mjs`, reusing the existing menu tests but pointing them at the PUBLISHED family app and Hub pages and at the REAL INSTALLED APPLICATION. 🔴 The current menu proof runs on fixtures, and its installed-window mode launches a SOURCE TEST COPY rather than the installed app — so it has never measured the thing Nick opens. Capture the running executable's own path, the served asset hashes, the microphone entry and the menu behaviour.
2. Repair the stale desktop package and install. Both hops read stale today, re-measured 2026-09-14.
3. 🔴 Sign in before reading anything behind the family app's password wall. It answers an unauthenticated request with 200 and the LOGIN PAGE, never a 401, so an unsigned read reports a healthy surface broken.

🔴 **NICK, 2026-09-14: "mac ap is held until the other surfaces are proven as itll be an easy mirror once done."** The Mac window half of this step (point 1's installed-application capture and point 2's desktop repair) is HELD and starts only after STEPs 2 to 6 are closed on the phone and the Hub. Until then this step proves the phone and the Hub only.

**DEFINITION OF DONE:** the phone and the Hub exercised now, assets current, and menu, clear and close all behave; the installed Mac app confirmed by its own path LAST, after the other surfaces are proven.
**PROOF:** `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/surfaces.mjs` · **FAILS IF:** any surface is missing, a source copy stands in for the installed app, assets are stale, or a control fails. (CREATED BY STEP 0)

### STEP 2 — Hold a natural spoken conversation and do the family task
**FOR NICK:** you can talk to him normally, correct yourself mid-sentence, get a useful answer quickly, and see the right task actually change. · **Tier:** FRONT
**Start when:** none — the voice rig survives at `projects/personal/family-app/_test-voice-rig.mjs`, confirmed present 2026-09-14.
**Carries:** the old STEPs 1, 5, 6 and 15 of this lane, the voice lane's STEPs 4 and 5, and what was worth keeping in its 9 and 10.
**Builder:** Fable 2 authors the test contracts, zai runs · **Builder backup:** deepseek · **Checker:** Astra · **Checker backup:** Sonnet
**Files you may touch:** `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/doors/voice.mjs` (CREATED BY STEP 0), `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/ten-turn.mjs`, `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/voice-latency.mjs` (NEW), `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/sound-grade.mjs`, `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/evidence/`. **Never** `js/voice.js` or any shared product file — report a product fault, do not fix it here.

**ALREADY TRUE, measured 2026-09-14:** three of the four doors PASS the ten-turn FLOOR, first attempt on every turn (the longer back-and-forth past ten is owed — the harness now carries it), graded on the family to-do store by item id — Slack, WhatsApp and Gmail. MEDIAN 23 words a reply. The means differ per door — 34.3 Slack, 34.0 WhatsApp, 36.2 Gmail — and two replies on every door run past 60 words, so "he averages 23" is wrong and was said to Nick once before it was checked. 6, 13 and 62 seconds respectively. Evidence: `evidence/ten-turn-slack-2026-09-14.json`, `evidence/ten-turn-whatsapp-2026-09-14.json`, `evidence/ten-turn-gmail-2026-09-14.json`. **Those doors are not rebuilt.** What is owed is the fourth door and the listening grade.

🔴 **WHO BUILDS WHAT, BECAUSE STEP 0 AND THIS STEP BOTH NAME THESE FILES.** STEP 0 WRITES the instruments and proves each can fail. This step USES them and owns the measuring decisions inside them — what counts as a cue, which clock a number came from, what the pinned recordings are. If a file below does not exist yet, it belongs to STEP 0 and is not started here.

**Do exactly this:**
1. STEP 0 builds `tests/doors/voice.mjs` on the surviving rig. 🔴 `live-voice-walk.mjs` survives but still reads its recordings and writes its output through the erased scratchpad — repoint both into this lane before trusting it.
2. BUILD `tests/voice-latency.mjs` around the existing audio detector. 🔴 Measure speech-end to detected playback onset ON ONE CLOCK, and report the acknowledgement and the answer SEPARATELY. Tie streamed answer audio to its own turn rather than to a finished HTTP response. The honest label for what this measures is CONTROLLED DIGITAL PLAYBACK ONSET — not physical speaker latency, and not necessarily the first intelligible word. Say that in the output.
3. Repair `sound-grade.mjs`: it currently extracts TEN EMPTY QUESTIONS because the receipts carried no question text, and its report has no fixed four-door denominator. The receipts now record the question.
4. Commit the ten read-only phrase recordings, or the recipe that regenerates them. They are present but untracked, which is how this lane lost six instruments already.

🔴 **VOICE COVERAGE, SETTLED: the family app is the one that must PASS; the Hub must OPEN and take a turn.** They mount the same panel, so requiring a full ten-turn run on both buys a second measurement of the same code. STEP 1 proves the Hub opens and works; this step runs the conversation in the family app.

🔴 **COUNTING, PINNED (Astra, 2026-09-14):** a MESSAGE is one message object as the app counts them — Nick's and Skippy's both count — so forty messages is twenty exchanges; a TURN is one exchange. The continuation past ten is not improvised: it is the pinned bank in `tests/ten-turn.mjs` (`extensionBank`), inserted between the Chantelle line and the completion, with continuity checks (`recallTime`, `recallDuration`, `recallDay`, `quotedHalf`) graded from the answer text against what Skippy himself said on turn three.

🔴 **MEMORY PROVENANCE, SO A PASS CANNOT COME FROM THE APP'S OWN WINDOW (Astra, 2026-09-14):** the voice adapter records, for every turn, the outgoing payload's message count and whether ANY message in it still carries the opener sentence; the grader requires the last turn to show the opener OUTSIDE the payload (`clientWindow.openerIncluded === false`, `messagesSent ≤ 40`) before a correct quote counts. Fresh-session recall is graded the same way with an empty payload.

🔴 **THE TEST IDENTITY AND THE RECORD (Astra, 2026-09-14):** the brain deliberately writes NO turn for `testTurn:true`, so as written a test could never exercise the memory file. Resolution: a TEST-SCOPED record — `testTurn` turns are written to and read from `<person>-test-turns.jsonl` beside the real one, through the same code path and the same three-day window, never into Nick's own record. Built in the brain (BRAIN lane), proven by the ledger's own test, published the moment it passes (Nick, 2026-09-14: "if a change makes something better it goes live").

**DEFINITION OF DONE:** the three text doors each pass a conversation of AT LEAST ten turns (the floor) that keeps going back and forth with context retained across the whole exchange; the voice app passes a conversation of AT LEAST forty messages, and a question asked AFTER the fortieth about something said early on is answered from the extended memory file with the opener proven outside the app's payload; a fresh session the next day recalls an earlier decision the same way; a turn older than six hours whose distinctive words sit past the one-line summary's cut is recovered in full when asked (the "ask for a turn by its id" promise in the memory block — today no tool honours it; STEP 2 adds `turn_words` to the brain and tests it); the substantive answer arrives within four seconds on the pinned simple-question recordings; and a listener who built none of it scores the whole conversation at least 4 of 5 on warmth, relevance, continuity and sounding like a person.
**PROOF:** `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/ten-turn.mjs --door all` · `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/voice-latency.mjs` · `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/sound-grade.mjs --report` · **FAILS IF:** any turn unanswered, a wrong task or id or date, a failed recall, context lost anywhere across the exchange, a voice question past the fortieth message answered without the earlier decision, a voice pass whose opener was still inside the app's payload, a fresh-session recall that fails, an older turn's full words not recovered on request, a nagging closer, a lost correction, an acknowledgement that begins after the answer has started, a missing audio measurement, or a substantive answer over four seconds. (CREATED BY STEP 0)
**Note on names:** include the Forgefire phrase, which is heard as "for jeffyre" today. Require the name right; do not require exact punctuation across a whole spoken turn.
🔴 **Nick's ear can reopen the quality bar at any time. His attendance is never a dependency of this step.**

### STEP 3 — Finish ordinary work and return delegated results
**FOR NICK:** tasks, calendar changes and reminders actually happen, and work he hands off comes back into the conversation he asked from. · **Tier:** FRONT
**Start when:** none — start now.
**Carries:** the old STEP 3 of this lane and the voice lane's STEPs 3 and 6, plus the Hub write fault.
**Builder:** zai · **Builder backup:** deepseek · **Checker:** Sonnet · **Checker backup:** Astra
**Files you may touch:** `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/handoff.mjs` (NEW), `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/evidence/`.

**ALREADY TRUE, proven end to end 2026-09-14 18:12Z:** Skippy creates a card on Nick's board through his own signed session. `HTTP 200 {"ok":true,"task":{"id":"nt-20260914-181254-02d2","assignee":"nick","due_date":"2026-09-18"}}`. FOUR faults had to be fixed for that one line, and each hid the next:
1. the write tool was not in Skippy's tool list at all, only the team assistant's;
2. its name gate listed the team and not Nick;
3. its trigger words were ones nobody says, so a read-only tool always won — fixed by putting it in his core set;
4. 🔴 **the board's own write door never forwarded a due date**, and the board requires one from a robot, so a create could never have succeeded even once. Invisible until (1)–(3) were fixed, because nothing reached that far. A test in the build asserted the missing field as a thing that must REMAIN true, so the build refused the fix until that test was inverted.
The refusal message is also corrected: it said "I can't tell which person is asking", which is the one thing that door does know by then, and it sent two investigations after a sign-in that was working.

🔴 **A FINDING THIS STEP MUST NOT ROUTE AROUND:** the board refuses to let any agent move a card to Done — "only the task owner can move it to Done — agents stop at In Progress". That is a deliberate guard and it stays. It means this step's harness CANNOT tidy up after itself on the Hub the way it does on the family list, so its test cards must be named unmistakably and left for a person, or created somewhere that is not Nick's real board.

**Do exactly this:**
1. BUILD `tests/handoff.mjs` as ONE connected conversation covering a family task, a calendar event moved by id, a reminder, a Hub card, and one bounded piece of delegated work.
2. Prove the result comes back on all four doors. Use a message to the test identity as transport proof. 🔴 This never certifies an unapproved message sent as Nick to another person — that is one of the four things only he decides.

**DEFINITION OF DONE:** every destination reads back what was asked, the Hub card appears in Nick's own view, the delegated work returns to the conversation it came from, and a deliberately failed worker returns an honest failure rather than silence.
**PROOF:** `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/handoff.mjs` · **FAILS IF:** a readback disagrees, a card is missing from his view, the agent only queues, the result lands in another conversation, or the round trip exceeds ten minutes. (CREATED BY STEP 0)

### STEP 4 — Continue without repeating yourself
**FOR NICK:** you can start a thing in Slack or on your phone and finish it by voice at your desk, without saying it twice. · **Tier:** FRONT
**Start when:** `tests/doors/voice.mjs` (CREATED BY STEP 0) exists, and STEP 1's installed-app driver for the Mac half.
**Carries:** the old STEP 2 of this lane and the voice lane's STEP 8.
**Builder:** zai · **Builder backup:** qwen · **Checker:** Astra · **Checker backup:** Sonnet
**Files you may touch:** `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/cross-surface.mjs` (NEW), `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/evidence/`.

🔴 **TWO ACCEPTANCE STATES, because the Mac app is HELD (Nick, 2026-09-14) and this step must still close (Astra, 2026-09-14):** PRE-MAC acceptance is Slack → the family app's Talk tab by voice (phone-sized viewport) and back, and it CLOSES this step. FINAL acceptance adds phone ↔ the installed Mac app both ways, and is run when STEP 1's Mac half lifts; until then it is recorded as HELD, never as failed.

**Do exactly this:** BUILD `tests/cross-surface.mjs` on the existing continuity machinery. Test Slack to Talk now; phone to the installed Mac app both ways when the Mac hold lifts. 🔴 Ask a follow-up that CANNOT be answered without the earlier decision. Showing history on screen is not continuity, and the harness must never inject a transcript — that is the whole thing being tested.

**DEFINITION OF DONE:** the second surface answers using the first surface's decision, with no repeated turn, no duplicated record and no change of speaker.
**PROOF:** `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/cross-surface.mjs` · **FAILS IF:** the decision or opener is lost, a turn duplicates, the speaker changes, or the harness supplied the history. (CREATED BY STEP 0)

### STEP 5 — Read files and return something usable
**FOR NICK:** you can send him a document or a photo and open whatever he makes back. · **Tier:** FRONT
**Start when:** none — the three text doors start now.
**Carries:** the old STEP 7 of this lane.
**Builder:** zai · **Builder backup:** deepseek · **Checker:** Sonnet · **Checker backup:** Astra
**Files you may touch:** `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/files.mjs` (NEW), `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/fixtures/`, `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/evidence/`.

**Do exactly this:** BUILD `tests/files.mjs` on the existing door adapters, with one PDF, one document and one captionless photo whose content can be checked independently. Keep all four doors. Include an UNREADABLE file as a control. Open the returned Talk attachment in both the family app and the Hub.

**DEFINITION OF DONE:** the content answer is right on every door, the attachment arrives, and Open retrieves the intended file.
**PROOF:** `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/files.mjs` · **FAILS IF:** a wrong content answer, an attachment that never arrives, unreadable content described as read, or an Open that fetches the wrong thing. (CREATED BY STEP 0)

### STEP 6 — Use Nick's chosen model depth
**FOR NICK:** everyday questions stay quick, and the deep ones use the models you named. · **Tier:** POLISH
**Start when:** none — start now. No dependency on voice or the Hub.
**Carries:** the old STEP 4 of this lane.
**Builder:** zai · **Builder backup:** deepseek · **Checker:** Sonnet · **Checker backup:** Astra
**Files you may touch:** `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/tiers.mjs` (NEW), `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/evidence/`.

**Do exactly this:** BUILD `tests/tiers.mjs` correlating four turns — ordinary, explicitly deep, explicitly super-deep, and an explicit model override — with the SERVING RECORDS, never with what the answer claims.
**DEFINITION OF DONE:** Sonnet 5 serves everyday, Opus 5 deep, Fable 5.1 super-deep, and an override is honoured.
**PROOF:** `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/tiers.mjs` · **FAILS IF:** the wrong model served, no correlation recorded, an override ignored, or a silent substitution. 🔴 A Fable refusal is recorded as UNAVAILABLE and never counted as a Fable pass. (CREATED BY STEP 0)

## 3c · CUT — in an earlier plan, not worked, recorded once

Nick, 2026-09-14: "get this thing DONE". Cut by Codex against the finish line, each with its reason. **A cut is not a claim that the work passed.** If one of these bites later it goes on the NEXT list, not back into this plan.

| From | What | Why it is cut |
|---|---|---|
| this lane 8 | The memory rewrite: prescribed summaries, token budget, three-day test | 🔴 REINSTATED AS A TEST, NOT A BUILD (Nick 2026-09-14): the three-day memory file already exists and is live (see NOT-in-scope (d)); STEP 2 must PROVE it — past forty messages and across a fresh session — rather than rebuild it |
| this lane 9 | Gmail edge suite: 22-message threads, ambiguous-send reconciliation | Ordinary email conversations stay required; the edges are deferred |
| this lane 10 | Slack edge suite: unknown users, 40-message histories, Gracie's attachments | Same reason |
| this lane 11 | WhatsApp edge suite: restart reconciliation, assistant selection | Sender attribution is still exercised by the retained tests |
| this lane 12 | Rebuilding the paid-lane failover | The spending controls already exist, and rebuilding them proves nothing about how he talks |
| this lane 13 | Old-suite housekeeping | Repair only what the retained changes actually break |
| this lane 14 | A separate postmortem | Three sentences inside close-out; counting registry mentions proves nothing |
| voice 7 | Pixel-matching the approved Hub screens | Opening and using Talk inside the Hub is retained; the pixel bar is deferred |
| voice 9 | Twenty first-words under two seconds | Replaced by a measured substantive-answer latency, which is what he actually waits for |
| voice 10 | A collection of twelve rotating acknowledgements | Replaced by: it sounds natural, and it never talks over the answer |
| voice 11 | Alexa | The fifth entrance waits until the four he uses are finished |
| voice 12 | A second close-out system with 35 historical rows | One completion system, not two |
| voice 1 | The fidelity half | Deferred; the outcome is kept, the pixel measurement is not |
| this lane 5 | A mandatory provider-call count | The outcome is speed; how it is achieved is chosen after measuring |
| this lane 6 | A mandatory streaming implementation | Same |

## 3d · THE TWO STRUCTURAL FIXES — why this plan cannot lie the way the last one did

🔴 **THE DISEASE, NAMED.** NINE of the voice lane's twelve proofs were a PHRASE IN ANGLE BRACKETS where a command should be — `<the lane's request harness> --gate --fresh`, `<the lane's Echo proof>`. A proof that cannot run cannot fail, so it always reads done: three of those steps were recorded at one hundred per cent. Two more steps recorded at one hundred per cent FAILED on a live re-run the same week. That is not carelessness, it is a structure that rewards it.

**FIX A — a proof that cannot fail must not be able to close a step.** Extend the existing `check_plan.py --gate-progress`; do not build a second audit tool. Closing a step requires ALL of: the instrument present in version control · a successful run with real measured results for every pinned case · an independent checker's receipt · and A NEGATIVE CONTROL showing that the same grader REJECTS the named failure. Missing instruments, unknown flags, skipped doors, empty samples and fixture-only evidence for a live claim each reject closure. Prove the extension rejects a missing voice door and a malformed receipt before trusting it.
`python3 -B projects/ops/agents/check_plan.py --gate-progress "projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/PLAN.md"`

**FIX B — completion is derived and revocable, never typed.** Remove hand-entered percentages from the governing path. State is derived from receipts carrying the command, the instrument and input hashes, the served build identity, the timestamp, the case count and the independent verdict. A changed dependency makes a receipt STALE. A newer failed run makes the step FAILED whatever older passes say. RUNNING is written BEFORE execution, so a crashed re-check cannot leave a green behind. Prove it with a pass-then-changed-build control and a pass-then-failed-rerun control.

## 4 · Regret Check (the registry failures this build is actually exposed to)

| Failure mode (registry entry) | The measure in THIS plan that prevents it | Where it lives (section / artifact / gate) |
|---|---|---|
| A UI reported success while the backend silently failed | every action is graded by the store by item id, never by the answer's words; a hand-off is graded by the file it wrote and the reply that came back | STEP 1, STEP 3, §1a row 4 |
| Work was written to a queue no reader ever visits | the cloud dispatcher hands its row to the outbox the Mac drains; STEP 3 proves it live on two doors | STEP 3 |
| A claim about the user/system was made without its source | the "all eight accounts limited" claim is the registry example; STEP 12 requires eight recorded refusal rows before a claim or a payment | STEP 12, GLOBAL rule |
| A conclusion was drawn from a partial read | the to-do read hands the whole list (the 12-row cap); STEP 10 paginates Slack history | Already true; STEP 10 |
| Expectations/manifest rows carried no grounding | every manifest row is a door Nick uses, with the store or log that proves it | §2 |
| A serial multi-step operation blew its time budget | STEPs 5–6 measure provider calls and first audio per turn with a four-second bar | STEPs 5–6 |
| Concurrent sessions clobbered each other's work in a shared file | one file fence per step; family publishes from a fresh detached copy of main; the brain publishes only committed work (another session's unstaged hunks are set aside by tag, never shipped) | §3b fences, STEP 5 step 3 |
| A capability was declared impossible from a stale or unverified claim | Fable 5.1 on the subscription is PROBED before the tier is written (STEP 4) | STEP 4 |

## 5 · Topology and roles
- **OVERSEER-AUTHORITY:** Fable 2 for this lane (no seat named in OVERSEER-AUTHORITY.md for it). The four approval classes (money leaving · credential rotation · irreversible destruction · a message sent as Nick to another human) stay Nick's; nothing here needs one — every test sends as Skippy or as the agent, to Nick or Chantelle only.
- Thread layout: one overseer thread (this session); builders and checkers as cheap dispatches through `projects/ops/route-build.mjs` / `cheap-task.mjs`; Astra through `projects/ops/skippy-jobs/lib/astra-review.sh` (read-only, one run per step's evidence). 🔴 NOT `scratchpad/astra-retry.sh`, which this plan named until 2026-09-14 and which the machine restart erased — an instrument a plan depends on lives in the repo.
- Overseer: Fable 5.1 · Workers: zai, deepseek, qwen; Sonnet as checker where named · Cap: 8 per session, ~40 machine-wide
- State files location: this file only — the file-governance gate refuses a second .md beside a plan (measured 2026-09-14), so state, questions, assumptions and changes are sections of THIS file (see PLAN CHANGES at the end)
- **Board card id:** none yet
- **Artefact consumers:** evidence JSON → Astra (checker) and the VOICE lane's PROGRESS (handoff lines); PLAN-CHANGES.md → Nick's morning report line.
- **Write-contention:** TEST lane writes only `tests/` and `evidence/`; BRAIN writes `skippy-code-publish/` and `projects/ops/skippy-jobs/jobs/code-agent-drain.mjs`; VOICE-APP writes `family-app/js/voice.js`, `functions/api/skippy-tts.js`, `voice-session-openai.js`; DOORS writes `channels/`, `wa/`, `lib/picture-intake.mjs`, `share-visual.mjs`, `panel.js`; POLISH writes the named suites and `slack-recover.mjs`. Checkout proven writable 2026-09-14 (commits f841b377d4 … f2e64204cc).

| Stage | Overseer | Sub-overseers | Workers |
|---|---|---|---|
| Tests | 1 | 0 | 2 |
| Fixes | 1 | 0 | 6 |
| Proof | 1 | 0 | 1 |

- **STATE FILE:** `projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/STATE.md`
- **HEARTBEAT ROW:** `skippy-testing-2026-09-14` in `projects/personal/skippy-app/ala-state/work-threads.json`
- **MORNING-REPORT LINE:** "Skippy testing — N of 14 steps closed; last: <step name>"

## 6 · Evals — what "working" means, decided now

| Capability | Check (exact command or procedure) | Pass looks like |
|---|---|---|
| 1 the conversation on four doors — ten turns the floor on text, forty messages on voice | `node …/tests/ten-turn.mjs --door all` (text doors default to the floor; `--turns N` extends; voice defaults to 22) | four VERDICTs all true, every continuity check held, median words 15–45, voice opener quoted from outside the app's window |
| 2 cross-surface | `node …/tests/cross-surface.mjs` | both recalls true, no transcript passed (CREATED BY STEP 0) |
| 3 answer shape | metrics inside the ten-turn evidence | toolTalk 0, inventories 0, followUps ≤ 1 per turn |
| 4 hand-off runs and reports back | `node …/tests/handoff.mjs` | both doors reported within ten minutes (CREATED BY STEP 0) |
| 5 model tiers | `node …/tests/tiers.mjs` | Sonnet / Opus / Fable (or Opus with recorded reason) (CREATED BY STEP 0) |
| 6 spoken answer | `node …/tests/voice-latency.mjs` (CREATED BY STEP 0) | substantive answer ≤ 4000 ms on the pinned recordings. 🔴 The provider-call ceiling that used to sit here is CUT (§3c): the outcome is how long Nick waits, and how that is achieved is chosen after measuring, not prescribed before |
| 7 files both ways | `node …/tests/files.mjs` | every door true; Talk card with Open (CREATED BY STEP 0) |
| 8 surfaces | `node …/tests/surfaces.mjs` (CREATED BY STEP 0) | three surfaces, the installed app, current assets |

🔴 **ROWS 9 TO 13 ARE CUT AND ARE NOT EVALUATED — see §3c.** They were the Gmail, Slack and WhatsApp edge suites, the paid-lane rebuild and the old-suite housekeeping. They stayed in this table after the cut list was written, so a cold builder reading down the page still received them as requirements: two readers, two definitions of done, which is the exact fault §3d exists to end. Recall from memory is exercised inside the conversations themselves (row 2) rather than as its own row.

## If you get stuck (all steps)

Before writing "blocked": (1) re-read the step's START WHEN line — most "stuck" is a misread gate, (2) try a concrete workaround, (3) write one line to the overseer naming the ONE missing artefact. Then move to the next step whose inputs exist.

## Your loop

Every pass: every step whose START WHEN inputs exist and which is not yet CLOSED is running, up to the cap → each builder runs its own PROOF, hands to its checker → PASS closes it, FAIL loops it → the next step starts the same minute. Astra reads each closed step's evidence cold; a dispute is a dated PLAN-CHANGES.md line, never a re-run of a closed step.

## Postmortem — the 2026-09-14 regroup that opened this lane

**Added by the second 2026-09-14 regroup pass, which re-ran this lane's own proofs later the same day:** the lesson below about scratchpad proofs was written, adopted as this lane's governing rule, and then not followed — nine of the fourteen steps still name a test file in `tests/` that was never created. (The folder itself DOES exist and holds two other files — an earlier draft of this line said otherwise and was wrong.) Writing the rule and obeying the rule are separate acts, and only the second one leaves evidence. The one instrument that did exist and could be re-run (the paid-lane guard) is also the only place a real defect was found, which is the argument for the rule rather than against it.

Written at lane-open rather than lane-close, because a regroup re-ran this plan's own claims the morning after it was written and two of seven did not hold. Kept here so the same faults are not repeated inside this lane.

- **A proof that lives in a scratchpad is not a proof.** Every harness that produced this lane's evidence was written into a session scratchpad and erased by one machine restart: the ten-turn runner, the four-turn action runner, the Gmail and WhatsApp proofs, the voice walk, the brain fingerprint check. The evidence JSON survived only because it was committed. Consequence for this lane: **every instrument it builds lives in `tests/` in this folder, in the repo, from the first line** — never a temporary directory, never a scratchpad, not even for one run. STEP 1 is "write", not "move", for exactly this reason.
- **A bundled sentence overstates without anyone lying.** "A ten-turn conversation ends in real actions" was one run for the conversation and a different, later run for the actions. An independent reader caught it in fourteen minutes. Consequence: one claim per run, per §0e of the regroup doctrine; a verdict that covers two artefacts is two verdicts.
- **Compare the committed code, never the working copy.** A fingerprint check said the live brain was behind; it was hashing a working copy that carried a peer session's unfinished edits. Five sessions share this checkout routinely. The rebuilt check (`projects/ops/skippy-jobs/lib/brain-code-stamp.mjs`) compares HEAD and reports the working copy separately.
- **A 200 is not an answer from behind the password wall.** The family app returns 200 with the login page for any unauthenticated path, so a checker that reads the body without signing in reports a healthy surface broken. Every door adapter in STEP 1 signs in with `mintCookie` first.
- **What went well, and is worth keeping:** the doors themselves re-proved on the code with no fixes needed, and the subscription-lane fix held in production — the live lane log shows the last thirty turns served free and none paid. Verifiers that cannot write, briefed with a named falsifier per item, found the faults in this session's own work within minutes and said so plainly.

## SUMMARY — a few plain-English lines, read by the status generator

**REGROUPED 2026-09-15 14:50 ON NICK'S WORD ("assume your recent findings were all recorded and we dont want to retest everything - we want to build on top of that work with new updates tests").** This lane's findings stand as recorded in the dated PLAN CHANGES lines below and are not re-run. Build work continues in TWO new lanes that cite this one: SKIPPY-NEXT (the brain and the Mac worker: look-ups in under a minute with a running commentary, where Skippy reads "where things stand", receipts as links, warm hand-offs, computed time claims) and TALK-APP-LAYER (Astra-led: the Talk screens and the whole voice path). This lane keeps its instruments and evidence as the graders both new lanes are measured with; STEP 7's two-speed chain is proven twice (Slack 27 min, voice 13 min, no tap for a look-only dig) and its 15-minute bar moves to SKIPPY-NEXT as "under a minute". STEP 9 (the runner cannot be frozen) is closed and live. Nothing here needs Nick.

**TRUE NOW (2026-09-14, after the regroup re-ran every proof first-hand and Codex merged this lane's fifteen steps with the voice lane's twelve into six).** Skippy holds a real ten-turn family conversation on THREE of his four doors — Slack, WhatsApp and email — first attempt on every turn, every time. That is graded on Nick's actual to-do list by item id rather than on anything Skippy says: the task is added word for word, renamed on the SAME item when Nick changes his mind, and taken off when he is done, and the last turn quotes his opening question back. His MEDIAN reply is 23 words on all three doors; the mean is nearer 34 and the longest runs past 80, so "averages 23" is wrong. Replies take six seconds on WhatsApp, thirteen on Slack and sixty-two by email — the door, not him. He can also now put a card on the Hub board himself: two separate faults there were reproduced and fixed today, one being that the board's own writer list held the team and left out the owner of the business.

**LEFT.** Voice is the only door never measured, and it cannot be until its adapter is built. Seven of the nine instruments this plan is judged by do not exist yet, and the plan says so out loud rather than implying otherwise: a test of the tests runs today and reports ONE of nine real (it said two until the gate itself was caught over-counting: an instrument that merely did not understand the flag was being read as one that refused). Everything else is one of six outcome steps — opening the current Skippy on every surface, the spoken conversation, real work and delegated work coming back, continuing a thread across surfaces, files both ways, and the model tiers.

**NEXT PICKUP.** Build the instruments, starting with the voice door adapter, because it is the only thing standing between here and a finished answer on all four doors. Then take the measured voice fault that most damages the conversation — the read-only recordings needed for that already exist, so it costs nobody's evening. Third, the proof that real work and hand-offs actually land. 🔴 One hazard: several steps may want the same core server file at once and there is no lock between them. One builder at a time on that file.

**Nothing here needs Nick.** Every open item is undone work, not a blocked decision.

## STEPS

```
1. [Surfaces] Open the current Skippy everywhere — 100% of the pre-Mac acceptance (the Mac window is HELD by Nick's ruling)
   DEFINITION OF DONE: all three surfaces exercised, the installed executable confirmed by its own path, assets current, menu/clear/close all behave
   PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/surfaces.mjs`
   2026-09-15 · surfaces.mjs PASS (evidence/surfaces-2026-09-15-mu1xwoo2.json): the phone's Talk and the Hub's Talk open, listen and answer ("Monday."), served assets match the repo, and the three-dot menu proof runs live against a real thread on the board (Rename · Clear thread · Close, first-tap, both widths). The Mac window stays HELD.
   REPLAN 2026-09-14 · instrument NOT BUILT. Carries voice 1, 2 and the working half of 7. The current menu proof runs on fixtures and its installed-window mode launches a source test copy, so the thing Nick opens has never been measured. Both desktop freshness hops read stale. NICK 2026-09-14: the Mac app is HELD until the other surfaces are proven — phone and Hub first.
2. [Talk] Hold a natural spoken conversation and do the family task — 75%
   DEFINITION OF DONE: the three text doors pass a conversation of at least ten turns (a floor) with context retained across the whole exchange; the voice app passes at least forty messages and answers past the fortieth from the extended memory file; the substantive answer lands within four seconds on the pinned recordings; an independent listener scores warmth, relevance, continuity and humanness at least 4 of 5
   PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/ten-turn.mjs --door all`
   REPLAN 2026-09-14 · THREE OF FOUR DOORS PASS the ten-turn floor, first attempt on all ten turns, graded on the family to-do store by item id — Slack, WhatsApp, Gmail. Median 23 words; 6, 13 and 62 seconds. Evidence: evidence/ten-turn-slack-2026-09-14.json, evidence/ten-turn-whatsapp-2026-09-14.json, evidence/ten-turn-gmail-2026-09-14.json.
   2026-09-14 evening · the harness now runs PAST ten (--turns, continuity checks, voice defaults to 22). The VOICE DOOR IS BUILT (tests/doors/voice.mjs: the live Talk tab headless, speech synthesised per turn, testTurn marked from inside the page, the app's payload recorded) and a spoken turn goes round end to end; first ten-turn voice run pending. The memory file is now TESTABLE: test turns live in a test-scoped record on the cloud (proven: 8 events in nick-test-turns.jsonl, 0 in Nick's). turn_words is live for the "ask by id" promise. voice-latency.mjs built; first measurement on one calendar question: acknowledgement 3.8 s, answer sound 11.8 s — over the four-second bar, which is the product finding this step exists to surface. OWED: the ten-turn voice pass, the latency run on the ten pinned recordings, the repaired sound grader, the listening grade, the fresh-session recall.
3. [Doing] Finish ordinary work and return delegated results — 30%
   DEFINITION OF DONE: every destination reads back what was asked, the Hub card appears in Nick's own view, delegated work returns to the conversation it came from, and a failed worker returns an honest failure
   PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/handoff.mjs`
   REPLAN 2026-09-14 · The Hub write fault it was blocked on is REPRODUCED AND FIXED: the board's writer list held the team and not Nick, and behind that the door never forwarded a due date the board requires from a robot, so a create could never have succeeded. Both live.
   2026-09-15 · two runs FAILED (pelican91, falcon83): the Hub card never appeared by name, the delegated result never came back to the thread, the failing worker returned silence — all three sit on the business-budget faults fixed in builds 13–15 and the drain's exit-code report; re-run queued behind build 15.
   2026-09-14 evening · handoff.mjs BUILT (one Slack conversation: to-do, calendar create + move read back from Google, reminder with a Friday due date, Hub card, a Sonnet hand-off carrying a nonce, a deliberately failing worker, cleanup). A card created inside a test conversation now carries the board's test-card slip (brain change, live), so the harness can close what it made. First live run in progress. KNOWN GAP the run will show: the Mac drain reports a finished hand-off back to Slack and WhatsApp only — a Gmail-origin hand-off reports nowhere (drain code, this Mac).
4. [Continuity] Continue without repeating yourself — 40%
   DEFINITION OF DONE: the second surface answers using the first surface's decision, with no repeated turn, no duplicated record and no change of speaker
   PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/cross-surface.mjs`
   REPLAN 2026-09-14 · instrument NOT BUILT. Needs STEP 2's voice adapter for the pre-Mac acceptance (Slack → Talk), which closes the step; the installed-app half is HELD with the Mac app, never blocking.
   2026-09-15 · cross-surface.mjs BUILT and run (evidence/cross-surface-2026-09-15-pelican70.json): five Slack turns then four spoken; the spoken side answered from the Slack decision (Friday, one hour) but named a time from another run — the test conversations all share one script and ran side by side, and the memory block, over budget, DROPPED the Slack turns; fixed in the brain (compaction now demotes to one-liners, publish #15) and in the instrument (the payload check keys on the Slack opener). Re-run queued alone.
5. [Files] Read files and return something usable — 70%
   DEFINITION OF DONE: the content answer is right on every door, the attachment arrives, and Open retrieves the intended file
   PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/files.mjs`
   REPLAN 2026-09-14 · instrument NOT BUILT. The three text doors can start now on the existing adapters.
   2026-09-15 · files.mjs BUILT and run on Talk, Slack and WhatsApp: the picture, the PDF (invoice 4471, $318.40, due 30 Sept) and the text note (parent evening, The Iron Giant) answered right on Talk and Slack; the unreadable file named unreadable on both; the file HANDED BACK (shopping list) drawn as a card with Open on Talk and retrieved. WhatsApp proven for pictures only (its test route carries pictures). Gmail files not yet run. Talk PASS (pelican98), WhatsApp PASS (maple97), Slack one wording miss fixed in the instrument.
6. [Tiers] Use Nick's chosen model depth — 100%
   DEFINITION OF DONE: Sonnet 5 serves everyday, Opus 5 deep, Fable 5.1 super-deep, and an explicit override is honoured, correlated against serving records
   PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/tiers.mjs`
   CLOSED 2026-09-14 · the brain had NO super-deep tier and NO way to name a model — built (MODEL_SUPER claude-fable-5-1, the "super deep" register, "use opus for this" honoured, a Fable refusal falls to Opus once) and every finished turn now carries model + served in the turn record. Live run: Sonnet / Opus / Fable / Opus, each provider-confirmed, all in the test scope (evidence/tiers-2026-09-14-d64fbb.json). Independent check by Sonnet, run cold: CLOSES (evidence/check-step6-tiers-sonnet-2026-09-14.txt); its one finding — a disguised model name passed the grader — fixed the same hour (exact names, anchored).
7. [Two speeds] Quick when quick will do; an investigator when it will not — 60% (the chain is proven twice; the 15-minute bar is not met and moves to SKIPPY-NEXT as "under a minute for a look-up")
   DEFINITION OF DONE: an open-ended ask on any door (Slack, WhatsApp, Gmail, spoken) gets, within seconds, one line that restates the task and promises a return ("On it — I'll check X and come back here in a few minutes"), then the real result — cause, evidence of what was checked, what was done or the one decision Nick must make — in the SAME thread/chat/mail/spoken session, minutes later, from an Opus worker with the whole workspace; a quick ask ("what's the weather", "add milk") stays seconds on Sonnet with no "on it"; every "on it" is a tracked task with an origin and a deadline, and a task nobody picks up comes back as one honest line by its deadline, never silence; no tool is withheld from a turn because of a word in the sentence, and no canned sentence ever replaces an answer.
   PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/investigate.mjs` — Nick's exact Anatoly ask replayed on Slack (ack within 30 s, evidenced result in-thread within 15 min), the weather control (seconds, no "on it"), the stopped-worker control (honest line by the deadline), and the same ask spoken on the Talk page with the result spoken back.
   OPENED 2026-09-15 · Nick: "my goal is that he's capable, like he's like you guys, but on the services that I operate on and also via voice" · "yes short fast cheap is good for most things … but i need him to be able to do more if needed" · "opus for open ended tasks for sure though" · "this is the highest priority for me". Two cold reviewers (Astra: evidence/astra-smarter-skippy-2026-09-15.txt; Fable: evidence/fable-smarter-skippy-2026-09-15.txt) both: GO WITH AMENDMENTS — the model decides at the top of the turn with a mechanical safety net (a hop or time ceiling, or a would-be "not found / I couldn't", converts to "on it" + hand-off, never a canned line); the ack restates the task and names a band, sent only after the task is recorded with its return route; the existing Mac hand-off (defaulting to Opus, asking nothing) is the first route, a cloud "second breath" later; every tool every turn, the word-triggered picker and the business budget retired as restrictions; a watchdog for the deadline; "not found" reported as "I couldn't find X in Y", never as a fact. Built as four packages: A the brain (decision, ack, task record, escalation net, all tools, Opus routing, the return route into the Talk page); B the Mac worker (status and progress back to the cloud, honest failure, cancellation); C the Talk pages (a returned result shown and spoken; the spoken answer no longer queues behind the "kind" line); D the instrument.
8. [The middle speed] A look-up answers in under a minute, with a running commentary, without booting a session — 0%
   DEFINITION OF DONE: an ask that only needs reading (where a post stands, what a card says, what a file contains, where a lane left off) is answered by the brain itself in the turn, with its own tools, in under 60 seconds end to end on Slack/WhatsApp/Gmail and under 90 on voice; while it works the person hears or sees what it is doing every 10–15 seconds ("reading the Captus cards… checking Anatoly's link… nearly there"); the acknowledgement says WHAT it will check, WHERE it will look and what, if anything, it is handing to a separate worker; a separate Opus session is started only for work that changes things or genuinely needs a builder, and when it is, the worker's two-minute progress lines reach the person, a standing per-machine workspace copy replaces the five-minute copy, and a "start here" pointer in the brief puts its first useful action under a minute; the four kinds of "where does X stand" read their own sources with their age stated (the lane plan for build state, the Hub board for cards and posts, the running-sessions list for "is anyone on it", conversation memory for what was said)
   PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/lookup-speed.mjs` (CREATED BY STEP 0) — Nick's Captus ask replayed on Slack and spoken: first useful words within 60 s, the commentary counted, the answer graded against the board; the weather control; one genuine build ask that still goes to a worker with its progress relayed; the four source classes (`--sources`)
   OPENED 2026-09-15 · Nick, verbatim: "this is completely unacceptable - no agent would take this long to find something so simple - not even 3 minutes it should take 1 min … this needs its own deep dive planning as a part of the next run as this cant be a thing or hes basically useless beyond simple tasks". Measured: 27 min (Slack) and 13 min (voice) for a read-only Captus status — 5 min copying the 50,749-file workspace, ~10 min the worker hunting for where Captus lives, the rest an Opus session reading with throwaway scripts. Asked the same day: does he check back (yes, the result lands by itself); does he say "working on it" every 10–15 s (no — one line, then silence until the deadline); does he say where he will look (no — only what). Astra's design (evidence/astra-plan-middle-speed-voice-app-2026-09-15.txt, sections A and D) is the build order: A1 in-turn investigations with a read budget, A2 progress events every 12 s per door, A3 a standing worktree and a generated "start here", D1 the dated reads (read_project_status, read_work_items). THE NEXT RUN OPENS WITH THIS STEP.
9. [Never frozen] The job runner cannot be stalled by one job, and a stalled carrier is noticed and restarted within fifteen minutes — 100%
   DEFINITION OF DONE: a job whose file hangs or fails at load is isolated to its own row and the runner boots anyway, with the row saying the module is still running; a nightly check imports every scheduled job in its own child with a 20-second ceiling and fails on one that hangs; a watchdog outside the runner, on the machine that owns the jobs role only, restarts it when both hand-off carriers have had no successful run for fifteen minutes (judged on the runner's own local log, never the shared heartbeat file), at most three times an hour with a 20-minute cooldown, then raises a signal to a person; every restart is written into the runner's own self-restart record; the watchdog is declared in the machine's approved services
   PROOF: `node projects/ops/skippy-jobs/_test-jobs-import-in-time.mjs` (every scheduled job loads in time) and `node projects/ops/skippy-jobs/jobs/jobs-liveness-watch.mjs --self-test` (the restart decision and the budget) · FAILS IF: the runner writes no boot manifest with a hung job present, the watchdog restarts a runner with a carrier row under fifteen minutes old, or the guard fails on the real folder for something that is not a defect
   CLOSED 2026-09-15 · Nick: "how do we make sure it never gets frozen again it happens too often". TRIAD-REVIEWED (a skeptic: proceed with 14 changes; a cold verifier: agree with 5 named changes) — what the review changed: the watchdog reads the runner's LOCAL log, not HEARTBEAT.md (git-tracked, lock-written, rewritten by auto-pull); it judges on the last SUCCESSFUL run, not row freshness (a job broken by its own code beats FAIL every minute); fifteen minutes, because the largest healthy gap measured 12–15 Sep was 7.8 minutes and the two gaps over ten were both real outages (70 min on 13 Sep, 104 min on 15 Sep); an owner-machine gate; a restart budget with escalation (the shape gracie-health already uses); the stub's wording says a timed-out module is STILL RUNNING inside the daemon; the guard passes a real argv[1] (its first run had wrongly named outbox-approval-cards, a healthy job — 17 job files decide "am I the script" that way); "nightly" is real only because the guard is a scheduled job of the runner itself (the suite runner that sweeps _test-*.mjs is switched off). Guard 79/79; watchdog self-test 10/10; live dry run "runner alive"; commit 3862088dee; plist written by sync-jobs and loaded; declared in machine-roles.json (chrome-twin-guard was loaded since 2026-09-11 and never declared — fixed in the same edit). A synchronous top-level loop is NOT caught by the import race (no timer fires); the child-process guard and the watchdog cover that shape.
10. [Receipts as links] Every confirmation carries the thing it changed, not a description of the checking — 0%
    DEFINITION OF DONE: when Skippy confirms an action, the reply carries the link to what changed — the Hub card, the item on the family list, the calendar entry, the thread a message went into — as a link under the sentence on Slack, WhatsApp and Gmail and as a tap-to-open chip on the Talk page (the same shape as the file hand-back card), with the spoken line unchanged; the words stay human ("Renamed." / "It's on there for Friday.") and the proof rides alongside; behind a switch so it can come off once trusted
    PROOF: `node projects/ops/life-os/REGROUP-2026-09-08/plans/SKIPPY-TESTING/tests/handoff.mjs` (the action turns of the existing instrument, graded for a link that opens the right record; CREATED BY STEP 0 for the new grading) · FAILS IF: a confirmation names no link, a link opens the wrong record, or the words return to report-speak
    OPENED 2026-09-15 · Nick, verbatim: "is there a way for it to prove it instead of say it like attach the link etc for now until i can see it happen several times and trust its acting as indicated?" The claim guard's completion receipts already carry the target of each action; this step hands the target's link back with the receipt.
```

## PLAN CHANGES — dated, one line each, newest last (the plan named a PLAN-CHANGES.md; the governance gate refuses a second file, so they live here)

- 2026-09-14 · Nick, verbatim: "the ten turns thing is a baseline floor for slack whatsapp and gmail context he needs to go abck and forth there and reatin context acorss the conversation" — ten turns is a FLOOR on the three text doors, not the bar; context retained across the whole exchange. Finish line (2), §1a row 4, STEP 2 done-line and fails-if, STEPS block row 2 corrected.
- 2026-09-14 · Nick, verbatim: "the voice app is 40 message plus an extended memory file that he can reference beyond those messages" — the plan had said ten turns on voice and had CUT the memory work (§3c row 8). Voice floor is now FORTY messages, and answers past the fortieth must come from the extended memory file. 🔴 A FIRST VERSION OF THIS LINE WAS WRONG: it measured the stale working copy (`skippy-code/lib/conversation-ledger.mjs`, 2,000-character read) and concluded the memory needed building. Nick: "look for how its set up currently we already have the momory file that clears after 3 days". The LIVE brain (`skippy-code-publish`, confirmed on the cloud box) already has it: `buildRecentContext` reads a 72-hour window of the per-person turn record before every turn — newest six hours verbatim, older turns one line each with their id, 12,000-token budget — on top of the app's own 40 messages; the record keeps 30 days. So STEP 2 TESTS this memory and does not build it. §3c row 8 reinstated as a test; NOT-in-scope (d) rewritten to say so.
- 2026-09-14 · Nick, verbatim: "mac ap is held until the other surfaces are proven as itll be an easy mirror once done" — STEP 1's Mac-window half is HELD until STEPs 2–6 close on the phone and the Hub.
- 2026-09-14 · Astra's cold read of the corrected plan (`evidence/astra-replan-corrections-2026-09-14.txt`, NOT READY, six findings) — all six taken: (A) every stale "ten-turn" requirement rewritten to the floor (finish line, §1 item 1, U1/U3/U5, STEP 2 already-true, §6 row 1); (B) memory provenance pinned — the voice adapter must show the opener outside the app's outgoing payload before a quote counts; (B/D) the test identity is kept out of Nick's record by design, so a TEST-SCOPED record is built in the brain for `testTurn` turns; (C) the "ask for a turn by its id" promise has no tool — `turn_words` is added to the brain and tested; (D) STEP 4 gets a pre-Mac acceptance that closes it and a final one held with the Mac app; (D) a message is one message object as the app counts, both speakers count, and the continuation schedule is the pinned bank in `tests/ten-turn.mjs`. The harness itself now carries `--turns`, the bank, kind-located grading and the voice window check (commit bfd30f6eb2).
- 2026-09-14 evening · Nick: "when this all lands do the fixes automatically get applied to neeko and gracie … since they are both skippy underneath?" — YES, by construction: one brain, three faces. The test-scoped record, turn_words, the served-model stamp and the Hub write door landed for all three at once (turn_words sits in Nick's AND Chantelle's core sets). The deliberate exceptions are not plumbing: Neeko has no personal memory block and stays on the everyday brain always (his corpus is parked, NEEKO-DONE-CRITERIA #9); Gracie has no Slack posting key (ASSISTANTS lane). A test that passes for Skippy is not a test that passed for Gracie — her doors are her own and are the ASSISTANTS lane's to prove.
- 2026-09-14 evening · STEP 6 CLOSED (see STEPS). The brain repo's stale checkout is retired: skippy-code now sits on a fresh per-machine branch at main; skippy-code-publish stays on main; brains/2026-09-09 kept on the remote, untouched (its three real commits were already redone on main).
- 2026-09-14 evening · Nick: "you need to make the tests handled long drawn out human conversations especially on voice — assume i will do speach to text and long dran out rambles - look at my own message histroy acorss everything i have doen and come up with testing that makes him work how i will use him". Taken as a standing requirement of STEP 2: the ten-turn script is the FLOOR; the shape above it is `tests/ramble.mjs` with `tests/fixtures/rambles.json` — seven long spoken turns written in the shape of his own recorded words (the 2026-09-12 verbatim record: fillers, run-ons, "actually no, hold that thought", three asks in one breath, "switching gears completely", "what have you actually done for me?"), every ask graded where it lands (the family list by exact name, the Hub board by name, the answer by what it must contain), a fallback line or a tool-lack line a defect, replies capped at spoken length. Mined for the corpus: his Slack DMs to Skippy (four long ones), the cloud turn record (54 long real turns), his verbatim file. Runs on all four doors; voice by default.
- 2026-09-14 evening · WHAT THE FIRST LIVE RUNS FOUND, AND WHAT IS FIXED (each a product change, live): (1) asked to "put a card on the Hub board" Skippy called the read-only records tool and said he had no working path — one more hop now names hub_write when a card was asked for and none was created; (2) he echoed the harness's "[agent-test …]" label into two Slack replies — the label is now stripped from every outgoing answer; (3) asked to read a to-do's wording back, he quoted it AND added a second copy — add_todo is now idempotent by name; (4) two Slack hand-offs were acknowledged ("an agent has it in thread ca-…") and never existed on the Mac — the outbox drain appended the row as empty text and marked it seen; fixed on this Mac, the next hand-off run is the live proof; (5) a fresh voice session seeded his last forty real messages, so "the first thing I asked" was a real Slack message of his — a test conversation now starts empty like a new thread; (6) on a 22-turn spoken run the opener had left the app's window (proven from the payload) and he quoted the SECOND turn as the first — the memory block now marks a conversation's first turn as its start, and every turn's record carries the ids of the turns it was given, so provenance is read from the record. VOICE 22-turn: 21 of 22 answered, all three actions in store, four continuity checks held, opener outside the window; two misses (one dropped utterance, the wrong opener) — re-run pending. WhatsApp: PASS on twelve turns with a continuity check. Gmail twelve-turn run in progress.
- 2026-09-14 late · ROOT CAUSE OF EVERY HUB-CARD MISS, FOUND AND FIXED (live): any sentence carrying the word "hub" put the brain into its business-lookup phase, whose tool list was READ-ONLY — hub_write was not offered on that turn at all (Skippy, on Slack, verbatim: "there's no hub_write tool in this session"). The filter now keeps the Hub's write door on business turns; the retired Monday writer (create_monday_task, which the model reached for instead and which answered 401) is off Nick's face entirely; a card asked for and not created gets one more hop naming hub_write. The Hub's own agent door, called directly with a cloud identity token, creates a card in one call (probe, 22:57Z). Eleven leftover test cards from earlier proofs closed through the test-card slip; TWO remain that were born without the slip (nt-20260914-181254-02d2, nt-20260914-181222-de46) and only Nick can close them — by design.
- 2026-09-14 late · Astra's evening review (evidence/astra-evening-review-2026-09-14.txt): STEP 6 CLOSES; every other step STAYS OPEN, with six findings — all six taken the same hour: the gate now applies EVERY declared break plus two of its own (a cut receipt; every answer blanked) so a content-blind grader cannot pass; ramble.mjs is on the gate's list, its asks are pinned from the corpus (a receipt cannot drop them), it scores what the front desk heard against what was said, and the missing shape — his long complaint that ends "write this down verbatim and hand me the note" — is the eighth turn (a file handed back through share_file, opened and read); tiers expectations are pinned in code, not read from the receipt; the voice provenance now also reads each turn's recorded memory context (the ids the brain was given) through /api/turn-state. Still owed from that review: the failing-worker proof in handoff.mjs needs a real process failure (drain exit-code capture), and the next-day / older-than-six-hours recall runs.
- 2026-09-14 late · FIRST VOICE RAMBLE (evidence/ramble-voice-2026-09-14-falcon63.json): seven long rambles spoken end to end — 130-word turns heard whole, the dentist to-do added mid-detour, Friday picked with Tuesday ruled out, the rename kept the same row, the recap held, the day recalled. Three misses, all now fixed in the brain or the door: the Hub card (Monday writer + read-only phase, above), one status-only answer the door could not read (it lives in the subtitle line, now read there), replies over the spoken-length cap on the three-ask turns. Gmail twelve-turn: ten of twelve answered, the last two timed out at seven minutes each — re-run in progress. Voice 22-turn re-run in progress with the opener fix.
- 2026-09-14 late · THE HAND-OFF THAT VANISHED, ROOT CAUSE (STEP 3): a delegated row rode the cloud's outbox with its own fields spread onto the entry, so the row's `kind` ("sonnet") overwrote the entry's kind ("code-agent-queue") and the Mac drain never recognised it — it appended nothing and marked the id seen. Proven with a unit probe against a temporary queue, then fixed on both ends (the cloud nests the row; the drain accepts both shapes). Also on the Mac: every delegated session now records its exit code, and a non-zero exit or an empty last line reports "did not finish" instead of "Done" (Astra, finding 3); a hand-off asked for by email now reports back into the same email thread (it reported nowhere). Third hand-off run chained behind the publish.
- 2026-09-14 late · THE WRONG "FIRST THING" ON VOICE, ROOT CAUSE (STEP 2): the memory block is per person across every conversation of the last three days; a day of test conversations gave it a dozen START lines, and the brain quoted another conversation's turn (three runs, three different wrong openers). The block now shows THIS conversation apart, from its start, before the others, and says in words that the messages on the turn are only its latest part. The record of each turn carries the ids it was given, so a test reads provenance instead of trusting words. 22-turn voice re-run chained behind the publish.
- 2026-09-14 late · FILES (STEP 5), first live run on Talk: the picture answered right (red left, blue right) and THE PDF READ RIGHT (invoice 4471, 318.40, due September 30) — PDFs are read now, on the app and on the three text doors. The document and the unreadable control could not be uploaded because the family app's file store took pictures and PDFs only; text-shaped files are now accepted (sniffed by content), which also unblocks share_file's hand-back — family app deploy in progress from a clean private worktree (the shared checkout carries other sessions' unfinished files and the deploy rightly refused to ship them). The Hub's Talk file card is committed and its deploy is retrying behind another session's browser hold.
- 2026-09-14 night · THE SLACK DOOR'S THREE SILENCES (STEP 2, twelve-turn run walnut49: 11 of 12 answered, continuity held, the to-do added, quoted, renamed, done): (1) the very first message got no reply — a rate-limited thread read fell back to channel history and glued a picture question from an earlier thread onto Nick's opener; the brain answered both; then the send firewall refused the reply for containing the word "attached" ("there's no picture attached") — fixed: the fallback drops a stale trailing turn, and rule 7 is now a per-sentence CLAIM check ("attached is the report" still blocked; "the invoice you attached comes to $318.40" and "no picture attached" pass; 14/14 red-green); (2) a text file (.md) posted from Nick's own account arrives as a Slack snippet stamped with his app id AND a bot id and was refused as a foreign app — now his own post; (3) the file instrument itself looked for threaded uploads in the wrong place — Slack HAD answered the PDF (invoice 4471, $318.40, due 30 Sept) and named the unreadable file unreadable. Listener reloaded; re-run chained.
- 2026-09-14 night · THE MAIL DOOR'S SILENCE AFTER TEN TURNS (STEP 2, twelve-turn run cobalt77: 10 answered at ~2 min each, then nothing): a thread past twenty messages was refused whole ("exceeds the 20-message cap") — Nick's floor is ten turns and he keeps going. Fixed: the thread is validated whole and the newest forty messages travel as the transcript (the voice window), the transcript opening on the person; the WhatsApp reader's window widened to forty the same way. Watcher reloaded; re-run queued.
- 2026-09-14 night · THE SPOKEN RAMBLE'S WRAP-UP, ROOT CAUSE (STEP 2/3, ramble juniper70): "the Willow and Noah to-do can come off … and close that Hub card" — the word "hub" made the business LOOKUP budget active, which refused the to-do tool as "unrelated", flipped the turn to final-only, cut the card close short, and answered with a fallback sentence ("Willow is not in the current client records"). Fixed in the brain (publish #13): the budget counts lookups only; action tools run on any turn; the final phase cuts short only a hop that asks for nothing but more lookups.
- 2026-09-14 night · A FALSE "DONE" CAUGHT (ramble juniper70 turn 6): "Both are off the list — dentist call and school fees are marked done" with both still open. Fixed (publish #13): a completion is a claim like a send or a hand-off — it stands only on a completion receipt from THIS turn (a to-do marked done with changed:true, a card moved to done); otherwise "I have not actually done that". Red-green 17/17 (_test-claim-guard-completed.mjs); the hand-off guard still 15/15.
- 2026-09-14 night · THE VOICE OPENER, STRUCTURAL FIX (STEP 2, 22-turn runs juniper60/harbor65: 22/22 answered, continuity 4/4, opener misquoted twice): told in the memory block where the thread began, the brain still quoted the first message it could SEE. Publish #13: this conversation's earlier turns rejoin the transcript as real user/assistant turns (6,000-token budget, oldest first; overflow stays in the block under START). Ledger test 45/45 with the new case.
- 2026-09-14 night · HUB TALK DRAWS SKIPPY'S FILE HAND-BACK AS A CARD (STEP 5): deployed (647e33c9). The build's browser tier was skipped with a recorded reason: harness-visualD reports five pre-existing defects on main in screens this change does not touch (finance "unresolved-join" copy, home-card bleed, 375px tab labels, nav-more, block-gap) — they belong to the HUB lane and the post-publish visual sweep carries them there.
- 2026-09-14 night · VOICE LATENCY, FIRST MEASUREMENT (voice-latency mu1vsohv, 10 probes): the brain answers in ~3 s and the ack lands in ~2 s, but the FIRST SOUND of the answer comes at 7–18 s (median 11.6 s) — the gap is speech synthesis, not thinking. Also in the probes: "Who is assigned to Captus?" answered "Captus is not in the current client records" — checked against the Hub: Captus is Nick's own writing project (his CAPTUS cards), not a client, so that answer is right. The wait is the one open item: the answer's speech queues behind the opener and the "kind" line by design (VOICE lane, STEP 9/10), so it lands 4–10 s after it is ready.
- 2026-09-15 · SMARTER SKIPPY — Nick, verbatim: "I have context about all this different stuff everywhere, all the time, always. And right now he acts like he is like very short and very narrow focused … my goal is that he's capable, like he's like you guys, but on the services that I operate on and also via voice" · "yes short fast cheap is good for most things we dont need to boot a whole session each time i ask for the weather but i need him to be able to do more if needed" · "opus for open ended tasks for sure though" · "are you able to divide and conquere deploy multuple other astra agents or whatever you need to do to get skippy dialled in - we have fable and astra available and this is the highest priority for me". His own thread the same night (23:22–23:25): asked to check why Anatoly can't see a post and fix it, Skippy answered the wrong thing, then read the running-jobs board, then "the Hub is available as of …, but U0BPHR3QHFB is not in the current client records" (the word "client" latched the lookup budget; his own Slack mention taken for a client's name; the next attempt cut off and replaced by the canned line). STEP 7 opened (see STEPS): both cold reviewers say go with amendments; four build packages (A brain, B Mac worker, C Talk pages, D instrument) run in parallel — A by this session, B/C/D by Fable builders, each reviewed cold by Astra. The mention-as-name bug is fixed in build 15.
- 2026-09-15 01:30 · STEP 7 BUILD LANDING: package B (the Mac worker reports running/progress/done/failed/cancelled to the cloud's task door, 31/31 red-then-green, live on the Mac) and package D (tests/investigate.mjs — the Anatoly ask, the weather control, the stopped-worker control, the spoken ask; 15/15 forgeries refused; READY in the gate) are on main; package A (the brain: the two-speed rule, every tool every turn, the task record with its watchdog, the escalation net, the 'on it' claim rule, the returned-result notice) is publishing as build 16 and its first live run is chained behind it; package C (the Talk pages draw and speak a returned result) is still being built. TWO MORE ROOT CAUSES from the re-runs: (1) a Slack test post made with Nick's own user token carried no app id, so the door filed every Slack test conversation in his REAL three-day memory (196 test turns; moved out tonight, a backup kept beside the record) and the spoken side, reading the test record, never saw the Slack turns — fixed (a marked post is a test post) and the listener reloaded; (2) leftover same-named test cards and to-dos from failed runs made the tools pick an older twin ("that Hub card's closed" closed a different card; "mark that done" completed another run's item) — 19 leftover test cards closed, to-do matching now collapses spaces and prefers the newest twin; three older cards without the test slip still need Nick. THE MAP Nick asked for (evidence/sphere-map-2026-09-15.txt, a read-only sweep of every plan): talking to a running agent from the Status tab by TYPING works today (about a second to deliver); by VOICE it is tap-to-record dictation plus a read-aloud of the answer — ASSISTANTS STEP 15, 0%, "spoken half not measurable" because an idle session never absorbs an injected message; a continuous spoken conversation with a named agent in a thread is in NO plan yet; Alexa is BUILT and PARKED by Nick's word (VOICE STEP 11, cut 2026-09-14); this lane is NOT on the progress screen (not in the registry) and the VOICE plan's STEPS block stops at 12 so its later steps never show there.
- 2026-09-15 01:45 · STEP 7, THE FIRST LIVE HAND-OFF AND ASTRA'S COLD REVIEW. Live on Slack (walnut64): the brain decided in one breath, handed the Anatoly ask to an Opus worker with the restated line "why Anatoly can't see that post on his client link, and the fix", wrote the task line, and answered in 32 s — but with the old "Handed off … an agent has it in thread ca-…" sentence, and the row never reached the Studio: ANOTHER MAC DRAINING THE SAME OUTBOX TOOK IT (the claim handed everything pending to whichever Mac asked first). Both fixed and live in builds 17–18: the reply is "On it — I'll check X and come back here in a few minutes", and an outbox row is addressed to the person's worker machine and handed only to that machine's claim (9/9). Astra's cold review of the build (evidence/astra-step7-build-review-2026-09-15.txt): DO NOT SHIP, 30+ findings — taken the same hour: no task line → no hand-off and no "on it"; a failed outbox append is a failed hand-off; the watchdog's Slack line goes only into the person's own DM; "quick / weather / add to list" never look like investigations; out-of-hops escalates only an investigation-shaped ask and never twice in a turn; the escalation brief names the right person; a test task's returned result goes to a TEST reload copy the instrument reads by scope (never Nick's screen); the Mac worker's four defects (a dead wrapper reported done, a lost final report never retried, the in-thread report cut to one line, cancel before the process is gone) are with a Fable builder (package B2). Package C (the Talk pages draw and speak a returned result; the spoken answer no longer waits behind the "kind" line; 14/14) is deploying to the family app and the Hub. STILL OPEN from the review, for Nick: the 2026-08-23 tap-only rule means a hand-off from the Talk page still waits for one tap; Astra also flags that a spoken BUSINESS ask bypasses that tap today (an older condition) — decide whether investigations from the Talk page go without a tap.
- 2026-09-15 01:57 · STEP 7, WHY THE FIRST LIVE HAND-OFF DIED, AND WHAT IS NOW LIVE. The Studio claimed task ca-…-949f at 01:47 (after the jobs daemon was restarted so it read the machine-addressed queue) and reported FAILED at 01:49: the worker cuts a fresh copy of the whole workspace (50,749 files) for every session and the two-minute ceiling killed git at 'Updating files' — uncontended the copy takes 56 s, but with builders' git work running alongside it did not finish; the failure text kept the first 300 characters of git's progress spam, not the reason. Fixed on the Mac (commit 39f4a613ca: ten minutes, reason kept, half-made copies pruned; drain guards 71/71 and 67/67; daemon restarted 01:55). Also found: 949f was not Nick's ask — it was born from the watchdog's 'not picked up' line for the EARLIER lost row, posted through Nick's own Slack token and read back by the listener as a new message from Nick (the task's recorded ask is that very sentence). That path is already closed (the watchdog's Slack line goes through the outbox as the assistant bot). Package B2 (Astra's four Mac-worker fixes: a dead wrapper reports failed, a lost final report is re-sent every tick until the cloud accepts it, the in-thread report is the full text up to 2,000 characters, cancel waits for the process to be gone and a cancelled task never turns done) is on main (d806cb74b6) and live since the 01:55 restart, 67/67. Brain build 20 is live (33d00ce36396). Hub deploy #5 was BLOCKED by the tier-1 gate harness-allviewAZ with three failures that do not reproduce (the harness passes on both the working tree and committed HEAD at 01:54) — deploy #6 started 01:55. The pre-fix instrument run (investigate maple86, stage 1 'NEVER CAME' on the old build) was stopped at 01:58 so the voice-timing measurement (package C2) and a clean investigate #3 can run on the current build.
- 2026-09-15 02:10 · HUB TALK 'CAME BACK' VIEW IS LIVE (STEP 7 package C, Hub half): the panel served at hub.heroesandsidekicks.io/js/neeko-talk-panel.js carries the came-back marker and the doorbell re-raise; the commit (04ff4f4b) went out on a teammate's Hub deploy after this lane pushed it — this lane's own deploys #5–#9 each stopped on a DIFFERENT browser gate (allviewAZ ×2, calendar-drag, interrupt) that passes when run alone on a clean copy: two sessions were deploying the same Hub at once (the gate-skips log shows the other session's proof runs at 02:05), and the browser gates are timing-sensitive under that load. Lesson recorded: one deployer per app at a time; check the live file before deploying again. SOUND GRADE IS COMPLETE (STEP 2): Astra judged Gmail cold (warmth 4 · relevance 4 · continuity 4 · humanness 3), so the four-door table is slack 4/4/4/3 · whatsapp 4/4/4/3 · gmail 4/4/4/3 · voice 4/3/2/3 — verdict FAIL on humanness everywhere (the judge's word: 'rehearsed' — the same selling points repeated across follow-ups, 'confirmed gone in the read-back', a 12:30–4:00 window blurred into 'straight through to six') and on voice continuity (an agreed hour overlapped by 'fitness right after at four'). The 'HOW A PERSON SAYS IT' rule (build 15) targets exactly the repeats; the judged transcripts predate it, so fresh WhatsApp and Gmail runs on the current build were started at 02:04–02:08 for a re-judge. INCIDENT, OWN GOAL: at 01:58 this lane killed headless Chrome processes by pattern to clear a stopped instrument and took down the WhatsApp Web session with them (heartbeat stopped 01:57:21, watcher logged STALE, first WhatsApp re-run 'session is not ready'); the watcher was restarted at 02:05:32 and was READY at 02:06:40 — never kill browsers by pattern.
- 2026-09-15 02:50 · THE FULL TWO-SPEED CHAIN WORKED END TO END FOR THE FIRST TIME, AND WHAT IT EXPOSED. A working-conversation run in Nick's own rambling shape (tests/working-conversations.mjs, run falcon13, seven Slack turns) asked for a proper dig into this week's Captus posts: the brain decided in one breath, wrote the task line (ca-…-b77a), the Studio claimed it, copied the workspace (5 min under load), ran an Opus session that reported running and progress every two minutes, and delivered a real evidenced result to the cloud record at 02:38 ('Nothing has gone out for Captus since 8 September … two posts carry a false approval and a fake comment' — read-only, nothing changed). Verdict of the run itself: FAIL, and rightly: (1) the Slack ack was the OLD sentence ('Handed off: … an agent has it in thread ca-…') because the text-door answer loop never stored the restated line — fixed on the brain (a9a5bcf), guard 2f; (2) turn 7's honest 'still on it, I'll come back here' was rewritten by the claim guard to 'I have not actually done that' — a task open in the person's record now licenses that line (guards 2g–2i); (3) the dig took 27 minutes against an ack that promised 'a few minutes' and an instrument bar of 15 — the line now says 'when I have it, usually within half an hour' (af845ee) and the workspace copy per session (5 of those minutes) is a follow-up; (4) turn 3 answered 'School's mid-build' from a stale picture (the school app went live 2026-09-14) — a knowledge-freshness defect, open; (5) the weather asked in the same breath as the hand-off was not answered now — open. Whether the Mac's in-thread Slack report landed is the builder's watch. LIVE VOICE WITH SOUND, ON NICK'S WORD: at 02:16 he said the whole point of the tester was live voice on the app; the written RULE 42 (muted by default) has an amendment — ask him in one sentence and proceed on his yes — and he granted 8 hours at 02:29 ('you have full auth for it for the next 8 hours speakers and mic are yours'). The chrome-twin-guard now honours a dated grant file (66c24c4ab4; self-test 31/31) and logs ALLOWED; before that it had killed every unmuted browser within 3 s. A scratch sound-on door (headed Chrome for Testing, unmuted, the REAL microphone, questions spoken into the room in the app's own OpenAI voice — Nick at 02:36: 'use the open ai voice for testing, the stock robot voice sounds bad' — converted from the speech door's Ogg/Opus with ffmpeg) drives a 13-turn conversation with three hand-offs (file tracking, the plan's STEP 7, the four approval acts). Measured: the page heard the room and answered aloud (weather turn 50.5 s including the ~15 s spoken question); pickup from the room is not yet reliable turn to turn (one retry needed on some turns) and the first answer of a fresh voice session opened with a leftover line for Chantelle from an earlier test conversation in the same memory — a carry-over defect, open. Astra's cold re-judge of a fresh WhatsApp run on build 20: warmth 3 · relevance 4 · continuity 4 · humanness 3 ('and I checked: it's not in the open items anymore') — the style rule now forbids narrating the checking and stock advice lines (96b8eac); all of the above brain changes are build 21, to publish once the live spoken run is off the brain.
- 2026-09-15 03:58 · LIVE SPOKEN CONVERSATION #1 (13 turns, three digs, speakers on, receipt voice-live-conversation-2026-09-15-live*.json): every quick turn answered aloud and well — the oldest to-do and an honest 'still worth doing', where tasks go (Hub/family list, Monday retired), the opener recalled word for word, the four approval acts read out of the actual file on the spot — but all THREE digs stopped at 'Before I hand this off… Tap Confirm' (the 2026-08-23 tap-only rule on the Talk page) so none was queued and none came back, and the calendar ask that followed a tap prompt was swallowed. On Nick's words tonight ('use it to test the new format of going to opus for things beyond a quick answer … track down files … do pretty much anything you can do') a spoken dig that only LOOKS now goes to the worker without a tap; a hand-off whose brief would change anything (post, send, close, delete, pay, deploy …) still waits for Confirm — build 22 (df0c84d, guards 3c/3d). Also in build 21/22: quick answers stay in front of the 'On it' line; 'I'll get someone to pull it' is a hand-off claim; the watchdog says 'still on it, running long' once at the deadline; the hand-off line promises 'usually within half an hour'; the style rule forbids narrated checking. Builds 21 (03:04, ad819f05159e) and 22 (03:57, c632e0ab46a5) are live. The Mac now posts a finished dig's report into its Slack thread the moment it is filed (310237a9f2; the b77a report was posted by hand at 03:03, 25 minutes late, because the scheduled poster is off). SOUND TABLE on build 20 (Astra, cold): slack 4/4/4/3 · whatsapp 3/4/4/3 · gmail 4/4/5/3 · voice 4/3/2/3 — humanness 3 on every door ('Renamed — it now reads', 'I checked: it's not in the open items anymore'); the build-21 style rule targets exactly those lines; re-judge after the next runs. VOICE TIMING (package C2): the builder's work is on main (voice.js v73, sw v857 after an app.js drift bump; _test-voice-answer-first 26/26) and family deploy #12 is publishing it; its after-measurement (voice-latency) runs once the deploy lands. The builder was cut off by the account's session limit before its hand-back. A second spoken run (fed mic, speakers on) started 03:58 on build 22 to prove the digs come back on the Talk page. Real-mic pickup from the room worked twice (02:33 macOS voice, 02:43 OpenAI voice) and failed on later fresh sessions — the fed microphone is the reliable path and the room still hears both sides.
- 2026-09-15 04:45 · SPOKEN RUN ON BUILD 24 (liven5qx) AND THE STUDIO'S DEAD DRAINS. On build 24 the spoken Captus dig went straight to the worker with no tap ('On it — I'll check where each Captus post for this week stands … and come back here when I have it, usually within half an hour'), its task line was written at 04:17:32 and its row queued in the cloud outbox — and it never reached the Studio, because BOTH Mac drains (the outbox drain and the code-agent drain) had been dead since 03:03: the jobs daemon re-imports a job file the moment its hash changes, caught the code-agent-drain file between two writes of the same edit (an `await` inside a not-yet-async function), logged 'failed to load at daemon startup: Unexpected reserved word', and every daemon restart since (03:03:46, 04:25:55) has hung INSIDE its import loop before recording its boot manifest — the last 'recorded the N code files' line is 02:02:50. Every job module imports cleanly on its own in under a second; a per-job import probe with a 20-second ceiling is running to find the one that hangs in the daemon's context. The two other spoken digs in that run still tapped: 'find the school lane's plan file … what the latest step says' and 'where did that leave off' were not dig-shaped — widened on the brain (40e56ba, to publish as build 25 with the daemon fixed). Turn 11 read the four approval acts straight out of the rulebook on the spot. Nothing from this run came back on the Talk page; the 'came back' notice path is still unproven live on voice. Memory: the runner reloads a job on change — write a job file once, then prove a RAN line after the kickstart.
- 2026-09-15 04:48 · THE DAEMON HANG, FOUND AND FIXED: a per-job import probe (20-second ceiling on each of the 78 scheduled modules) named it — jobs/captus-review.mjs, a teammate's new Captus job committed tonight, ran its once-a-minute forever loop AT IMPORT, so the daemon's boot-time `await import()` never returned; every daemon since 03:03 hung there before its boot manifest and neither Skippy drain ran. The loop now runs only when the file is its own program and the daemon calls its run() once a minute (407fe8a455; import proven in under a second; its own self-test 12 of 12). Daemon restarted 04:44:40 and booted (outbox drain RAN 04:45:52); the spoken dig from build 24 (ca-…-bf81, asked at 04:17) reached the Studio and its Opus session started at 04:45:53 — the first spoken hand-off ever to run without a tap. Build 25 is live (04:47, 5c5a9df2a492): 'find the … file' and 'where did that leave off' count as digs.
- 2026-09-15 04:55 · VOICE TIMING, THE REAL ANATOMY (package C3, receipts voice-latency-2026-09-15-mu26tofs/mu2749k6 with full timelines; fcf545276b): the 'answer body at ~3.6 s' every earlier receipt reported was the chat door's response HEADERS, not the words — the brain's first text lands 5.0–12.6 s after Nick's last word (brain time request→text median 3.4–4.8 s, because the Talk tab's chat is NOT streamed and the brain does its Hub lookups then emits the whole answer at the end), the speech service then takes 0.9–1.8 s per clip, and the page's own cost between text and first audible sample is a median 26 ms. So packages C and C2 could not move the number and did not: median answer sound 6.9–8.8 s, no page-side cause exists (a new guard case (e) proves the page requests speech within 100 ms of the text and plays within 100 ms of the audio). The 4-second bar (STEP 5) can only be reached outside the page: (1) an early first sentence from the brain on voice turns (turn streaming on for voice-originated turns — the streaming tap-gate leg exists but is untested live — or have the brain speak a one-line lead before its lookups), (2) streamed speech audio (first sound ~0.3–0.5 s after the request instead of ~1.4 s; a cloud + proxy + page change), (3) the 1.5 s end-of-speech window (turn-taking Nick approved in v851). Nothing was deployed for C3 — voice.js, index.html and sw.js are byte-for-byte unchanged (v857/v73 stays live). STEP 5's percentage stays where it is; the measurement, not the fix, is what this night produced, and the earlier 'the answer waits behind the opener and kind line' reading is retired.
- 2026-09-15 05:02 · THE FIRST SPOKEN DIG CAME BACK ON THE TALK PAGE — AND SHOWED TWO MORE DEFECTS. Task ca-…-bf81 (asked aloud at 04:17, no tap, on build 24) ran on the Studio 04:45:53–04:58:41 and its result was drawn on the Talk page's test copy as a 'came back' notice — the chain now works on voice end to end. But the page also carried, for the same ask, the watchdog's 'I couldn't get to this one — say the word' (the deadline passed while the drains were dead) and 'Still on it — taking longer than I said', and the result notice was only the LAST paragraph of the worker's message ('…the three decisions above stand' — with the decisions gone). Fixed on the Mac (44df432738; guards 71/71 and 67/67; daemon restarted 05:01): a task the cloud has already given up on is never started later (given up is given up — the person was told to ask again); the report is the worker's whole final message capped on a sentence; and the worker is told its final message is the only one the person sees, so it must stand alone and fold a checker's answer in before finishing. The worker's own read of the Captus board (nothing out since 8 September; six posts waiting on Anatoly; two carrying a test run's false approval and fake comment) stands from the 02:38 dig and is Nick's call to act on.
- 2026-09-15 14:25 · NICK'S THREE ANSWERS, DONE. (1) 'yes remove': the Hub's content door gained an owner move that takes back, inside a named window and on Nick's own words, the marks an automated test run left on a real post (dc086ba0; fixtures 14/14); published through the quick lane (the tier-2 visual sweep fails on five defects already on main in screens this change never touches; it runs after publish in the runner's own job) and run on the two posts at 14:24: the $275M post has its original words back and its false approval gone; the 'your GC' post's fake comment is hidden with a note; each post's trail says what was taken back and on whose word. (2) 'yes but needs a full plan': the TALK-APP-LAYER lane exists (plans/TALK-APP-LAYER/PLAN.md, 148d8fec47, checker PASS, registered as life-os-talk-app-layer) with the file fence and frozen contracts from Astra's design. (3) the three leftover agent-test cards were closed through the board's nick_said route at 13:45. Also today: STEP 9 closed (triad-reviewed watchdog live, three healthy checks logged), STEP 8 and STEP 10 opened, Astra's four-part plan on file, the runner rebooted cleanly with the import race.
- 2026-09-15 14:35 · SOUND RE-JUDGE ON BUILD 25 (Slack, fresh ten-turn, Astra cold): warmth 4 · relevance 4 · continuity 2 · humanness 3. The narrated-checking lines are gone from the transcript (the build-21 rule held) but two new tells: a dense 'Here's the afternoon shape for the rest of the week:' report where a person would say one line, and — the continuity 2 — a confident FALSE reassurance, 'That also clears the overlap with your fitness block at four', when the revised 3:30–4:30 slot still overlaps four by half an hour, plus 'the only afternoon with a real uninterrupted block' contradicting 'Saturday and Sunday are essentially clear'. That is a time-arithmetic slip asserted as fact. Goes into STEP 8's scope: a claim about times (clears / overlaps / fits / before / after) is COMPUTED from the times already established and stated with the numbers, never asserted; and a schedule answer is one line unless the person asked for the week. Four-door table now: slack 4/4/2/3 · whatsapp 3/4/4/3 · gmail 4/4/5/3 · voice 4/3/2/3 — humanness 3 on every door still; the bar (every axis ≥4) is not met and the next run's STEP 8 build is where it moves.