# Phase 25.2: Doyle cluster fix candidates — Discussion Log

> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

**Date:** 2026-05-22
**Phase:** 25.2-doyle-cluster-fix-candidates-blast-radius-sanity-check-acros
**Areas discussed:** Wave/plan granularity; #3 wrapper-state read race; #5 deliver-then-die contract; #6 haiku compression posture (dropped from scope)

---

## Wave/plan granularity

### How to slice 6 candidates into plans?

| Option | Description | Selected |
|--------|-------------|----------|
| 3 plans by roadmap groups | Plan 1: #1+#3+#4 wrapper-path. Plan 2: #5+#6 signoff-preservation. Plan 3: #2 ghost cleanup. | ✓ |
| 6 plans, one per candidate | Finer-grained; cross-cutting via gsd-integration-checker. | |
| Audit + 3 sweep plans (4 total) | Separate AUDIT.md before sweep plans. | |

**User's choice:** 3 plans by roadmap groups.

### Wave ordering?

| Option | Description | Selected |
|--------|-------------|----------|
| Parallel — all 3 independent | No file overlap; can ship in parallel waves. | ✓ |
| Sequential by risk | Wave 1: #2. Wave 2: #1+#3+#4. Wave 3: #5+#6. | |
| Wrapper-path first | Wave 1: #1+#3+#4. Wave 2: #5+#6+#2 parallel. | |

**User's choice:** Parallel — all 3 independent.

### Audit deliverable location?

| Option | Description | Selected |
|--------|-------------|----------|
| Inline in each plan's task 1 | Plan task 1 enumerates affected sites. | ✓ |
| Single shared AUDIT.md sibling doc | Centralized cross-listing. | |
| Skip — ROADMAP is the audit | Plans straight to fix tasks. | |

**User's choice:** Inline in each plan's task 1.

### Verification posture?

| Option | Description | Selected |
|--------|-------------|----------|
| Operator UAT + targeted integration tests | Smoke checkpoint + 1-2 integration tests per candidate. | ✓ |
| Integration tests only | Pure automation. | |
| Operator UAT only | Manual smoke; less regression coverage. | |

**User's choice:** Operator UAT + targeted integration tests per candidate.

---

## #3 wrapper-state read race

### Primary mechanism?

| Option | Description | Selected |
|--------|-------------|----------|
| Raise MAX_ATTEMPTS to 80 (20s) | Simplest; matches observed cold-claude-p p99 latency. | ✓ |
| Sentinel-file signal from wrapper | New file lifecycle; eliminates polling. | |
| Hybrid: 30 + sentinel fast-path | Most code; backward compat for mid-flight wrappers. | |

**User's choice:** Raise MAX_ATTEMPTS to 80 (20s budget).

### Apply uniformly across consumers?

| Option | Description | Selected |
|--------|-------------|----------|
| Shared const everywhere | Single WRAPPER_STATE_MAX_ATTEMPTS const; all consumers import. | ✓ |
| Per-site tuning | Different budgets per call site. | |
| Shared const + per-site override | Hybrid. | |

**User's choice:** Shared const everywhere.

### On exhaustion behavior?

| Option | Description | Selected |
|--------|-------------|----------|
| Skip the row + structured warning | Current behavior preserved. | ✓ |
| Skip + retry on next listener iter | New sentinel + recovery state machine. | |
| Block listener until UUID lands | Risk of stall on wrapper crash. | |

**User's choice:** Skip the row + structured warning.

### Observability?

| Option | Description | Selected |
|--------|-------------|----------|
| Log elapsed-ms always | Cheap; surfaces drift before next outage. | ✓ |
| Log only on slow path | Reduces noise; misses gradual drift. | |
| No new logging | Existing exhaustion warning is enough. | |

**User's choice:** Log elapsed-ms on every successful read, not just slow path.

---

## #5 deliver-then-die contract

### Delivery vector for the rescued signoff body?

| Option | Description | Selected |
|--------|-------------|----------|
| Spool INIT_SIGNOFF envelope | Standard envelope; reuses Phase 30 flow. | |
| Separate pending-file in psyche perch | Bypasses spool. | |
| Preserve in place + consumed-marker | Idempotent presence + gen-dedup. | |
| **Other (user-typed):** Forward as commune (TCP/REST to wrapper) | INIT_SIGNOFF would shut down wrapper and confuse psyche on subsequent commune. | ✓ |

**User's choice (free-text):** Forward rescued signoff as a regular commune — NOT INIT_SIGNOFF. INIT_SIGNOFF triggers wrapper shutdown; commune keeps wrapper alive and lets Psyche absorb naturally.

### Commune delivery path?

| Option | Description | Selected |
|--------|-------------|----------|
| TCP to wrapper, spool fallback | Mirrors existing $LIVE commune; file delete only after queue confirmed. | ✓ |
| Always spool | Skip TCP; loses immediate-delivery property. | |
| TCP only, error if offline | Hard fail if wrapper not listening. | |

**User's choice:** TCP first, spool fallback.

### Envelope shape?

| Option | Description | Selected |
|--------|-------------|----------|
| Tagged commune (RESCUED_SIGNOFF subtype) | `<rescued-signoff source=...>` wrapper. | |
| Plain commune, no tag | Verbatim body; loses provenance. | |
| Plain commune + prefixed header line | `[RESCUED FROM ...]` prefix. | |
| **Other (user-typed):** `<EVENT type="rescued signoff" ...>` envelope, matching commune/echo-commune EVENT convention | Reuses existing envelope shape. | ✓ |

**User's choice (free-text):** `<EVENT type="rescued signoff" ...>` envelope matching commune/echo-commune EVENT shape. Later renamed `"rescued signoff"` → **`"latent signoff"`** during the area-completion checkpoint.

### Coordination with wrapper's drain_stale_init_signoffs?

| Option | Description | Selected |
|--------|-------------|----------|
| No coordination needed | Drain matches INIT_SIGNOFF envelope shape only; latent-signoff EVENT is different shape. | ✓ |
| Add explicit allowlist to drain predicate | Belt-and-suspenders. | |
| Suppress drain via env var | Most invasive. | |

**User's choice:** No coordination needed (different envelope shape; drain auto-ignores).

---

## #6 haiku compression posture (DROPPED)

### Scope of #6 fix?

| Option | Description | Selected |
|--------|-------------|----------|
| Prompt strengthening only | Update psyche.md `<init_signoff>` verbatim-preserve rule. | |
| Prompt + commune-absorption parallel fix | Same haiku, same risk; both handlers updated. | |
| Prompt + commune + backfill from sessions.log | Reconstruct compressed live_context.md for affected agents. | |
| **Other (user-typed):** No-op. Meant to flag as ignoreable; got rolled into the phase by mistake. | | ✓ |

**User's choice (free-text):** #6 is not actually an issue. User intended to flag it as ignoreable but it got rolled into the phase. **Dropped from scope.** Phase 25.2 = 5 candidates, not 6.

---

## Re-slice after #6 dropped

| Option | Description | Selected |
|--------|-------------|----------|
| Keep 3 plans — shrink Plan 2 to just #5 | No structural change; Plan 2 just smaller. | ✓ |
| Collapse to 2 plans (lump #2+#5) | Fewer artifacts. | |
| Split Plan 1 — 4 plans | Finer-grained per-candidate. | |

**User's choice:** Keep 3 plans; Plan 2 = #5 only.

---

## Claude's Discretion

- Exact line numbers + wording for the per-plan audit task 1 deliverables — planner pulls from ROADMAP §639 + debug-doc blast radius bullets.
- Test names + golden fixture layout for #1 stale-lock probe.
- Whether to introduce a shared helper for the `latent signoff` EVENT-envelope build vs inlining at the `drain_stale_signoff_file` call site.
- Whether `D-08` elapsed-ms logging gets a threshold floor (e.g., skip log if <50ms) — defer based on observed log volume.
- Whether Plan 3 (#2) ghost cleanup runs unconditionally per `migrate_legacy_if_needed` or behind a one-shot `tracked/.git/.cleaned-up` sentinel.

---

## Deferred Ideas

- **#6 Haiku signoff-absorption compression** — dropped by user; not a structural defect. If revisited later: `psyche.md` `<init_signoff>` + `<context_save>` prompt edit, optionally with sessions.log raw-row backfill.
- **Migration coexistence convention** — try-nested-first-fall-back-flat policy from #4 might warrant lifting into `.planning/CONVENTIONS.md` if it becomes a project-wide pattern beyond this phase.
- **`$OWL doctor --sweep-stale-locks` subcommand** — cross-agent stale-lock sweep; useful operationally; not in phase scope.
- **`drain_stale_init_signoffs` generalization** — predicate-based drain could handle any deliver-then-die envelope. Future hardening.
